soc/intel/skylake: Correct address of I2C5 Device
[coreboot.git] / src / lib / ext_stage_cache.c
blob770097f6664b0e1f5c64a347061b9dd398364853
1 /*
2 * This file is part of the coreboot project.
4 * Copyright 2015 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <arch/early_variables.h>
17 #include <bootstate.h>
18 #include <cbmem.h>
19 #include <console/console.h>
20 #include <imd.h>
21 #include <rules.h>
22 #include <stage_cache.h>
23 #include <string.h>
25 static struct imd imd_stage_cache CAR_GLOBAL = { };
27 static inline struct imd *imd_get(void)
29 return car_get_var_ptr(&imd_stage_cache);
32 static void stage_cache_create_empty(void)
34 struct imd *imd;
35 void *base;
36 size_t size;
38 imd = imd_get();
39 stage_cache_external_region(&base, &size);
40 imd_handle_init(imd, (void *)(size + (uintptr_t)base));
42 printk(BIOS_DEBUG, "External stage cache:\n");
43 imd_create_tiered_empty(imd, 4096, 4096, 1024, 32);
44 if (imd_limit_size(imd, size))
45 printk(BIOS_DEBUG, "Could not limit stage cache size.\n");
48 static void stage_cache_recover(void)
50 struct imd *imd;
51 void *base;
52 size_t size;
54 imd = imd_get();
55 stage_cache_external_region(&base, &size);
56 imd_handle_init(imd, (void *)(size + (uintptr_t)base));
57 if (imd_recover(imd))
58 printk(BIOS_DEBUG, "Unable to recover external stage cache.\n");
61 void stage_cache_add(int stage_id, const struct prog *stage)
63 struct imd *imd;
64 const struct imd_entry *e;
65 struct stage_cache *meta;
66 void *c;
68 imd = imd_get();
69 e = imd_entry_add(imd, CBMEM_ID_STAGEx_META + stage_id, sizeof(*meta));
71 if (e == NULL)
72 return;
74 meta = imd_entry_at(imd, e);
76 meta->load_addr = (uintptr_t)prog_start(stage);
77 meta->entry_addr = (uintptr_t)prog_entry(stage);
79 e = imd_entry_add(imd, CBMEM_ID_STAGEx_CACHE + stage_id,
80 prog_size(stage));
82 if (e == NULL)
83 return;
85 c = imd_entry_at(imd, e);
87 memcpy(c, prog_start(stage), prog_size(stage));
90 void stage_cache_load_stage(int stage_id, struct prog *stage)
92 struct imd *imd;
93 struct stage_cache *meta;
94 const struct imd_entry *e;
95 void *c;
96 size_t size;
98 imd = imd_get();
99 e = imd_entry_find(imd, CBMEM_ID_STAGEx_META + stage_id);
100 if (e == NULL)
101 return;
103 meta = imd_entry_at(imd, e);
105 e = imd_entry_find(imd, CBMEM_ID_STAGEx_CACHE + stage_id);
107 if (e == NULL)
108 return;
110 c = imd_entry_at(imd, e);
111 size = imd_entry_size(imd, e);
113 memcpy((void *)(uintptr_t)meta->load_addr, c, size);
115 prog_set_area(stage, (void *)(uintptr_t)meta->load_addr, size);
116 prog_set_entry(stage, (void *)(uintptr_t)meta->entry_addr, NULL);
119 static void stage_cache_setup(int is_recovery)
121 if (is_recovery)
122 stage_cache_recover();
123 else
124 stage_cache_create_empty();
127 ROMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup)
128 RAMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup)