1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
6 #include <stage_cache.h>
9 static struct imd imd_stage_cache
;
11 static void stage_cache_create_empty(void)
17 imd
= &imd_stage_cache
;
18 stage_cache_external_region(&base
, &size
);
19 imd_handle_init(imd
, (void *)(size
+ (uintptr_t)base
));
21 printk(BIOS_DEBUG
, "External stage cache:\n");
22 imd_create_tiered_empty(imd
, 4096, 4096, 1024, 32);
23 if (imd_limit_size(imd
, size
))
24 printk(BIOS_DEBUG
, "Could not limit stage cache size.\n");
27 static void stage_cache_recover(void)
33 imd
= &imd_stage_cache
;
34 stage_cache_external_region(&base
, &size
);
35 imd_handle_init(imd
, (void *)(size
+ (uintptr_t)base
));
37 printk(BIOS_DEBUG
, "Unable to recover external stage cache.\n");
40 void stage_cache_add(int stage_id
, const struct prog
*stage
)
43 const struct imd_entry
*e
;
44 struct stage_cache
*meta
;
47 imd
= &imd_stage_cache
;
48 e
= imd_entry_add(imd
, CBMEM_ID_STAGEx_META
+ stage_id
, sizeof(*meta
));
51 printk(BIOS_DEBUG
, "Error: Can't add %x metadata to imd\n",
52 CBMEM_ID_STAGEx_META
+ stage_id
);
56 meta
= imd_entry_at(imd
, e
);
58 meta
->load_addr
= (uintptr_t)prog_start(stage
);
59 meta
->entry_addr
= (uintptr_t)prog_entry(stage
);
60 meta
->arg
= (uintptr_t)prog_entry_arg(stage
);
62 e
= imd_entry_add(imd
, CBMEM_ID_STAGEx_CACHE
+ stage_id
,
66 printk(BIOS_DEBUG
, "Error: Can't add stage_cache %x to imd\n",
67 CBMEM_ID_STAGEx_CACHE
+ stage_id
);
71 c
= imd_entry_at(imd
, e
);
73 memcpy(c
, prog_start(stage
), prog_size(stage
));
76 void stage_cache_add_raw(int stage_id
, const void *base
, const size_t size
)
79 const struct imd_entry
*e
;
82 imd
= &imd_stage_cache
;
83 e
= imd_entry_add(imd
, CBMEM_ID_STAGEx_RAW
+ stage_id
, size
);
85 printk(BIOS_DEBUG
, "Error: Can't add %x raw data to imd\n",
86 CBMEM_ID_STAGEx_RAW
+ stage_id
);
90 c
= imd_entry_at(imd
, e
);
92 printk(BIOS_DEBUG
, "Error: Can't get %x raw entry in imd\n",
93 CBMEM_ID_STAGEx_RAW
+ stage_id
);
97 memcpy(c
, base
, size
);
100 void stage_cache_get_raw(int stage_id
, void **base
, size_t *size
)
103 const struct imd_entry
*e
;
105 imd
= &imd_stage_cache
;
106 e
= imd_entry_find(imd
, CBMEM_ID_STAGEx_RAW
+ stage_id
);
108 printk(BIOS_DEBUG
, "Error: Can't find %x raw data to imd\n",
109 CBMEM_ID_STAGEx_RAW
+ stage_id
);
113 *base
= imd_entry_at(imd
, e
);
114 *size
= imd_entry_size(e
);
117 void stage_cache_load_stage(int stage_id
, struct prog
*stage
)
120 struct stage_cache
*meta
;
121 const struct imd_entry
*e
;
125 imd
= &imd_stage_cache
;
126 e
= imd_entry_find(imd
, CBMEM_ID_STAGEx_META
+ stage_id
);
128 printk(BIOS_DEBUG
, "Error: Can't find %x metadata in imd\n",
129 CBMEM_ID_STAGEx_META
+ stage_id
);
133 meta
= imd_entry_at(imd
, e
);
135 e
= imd_entry_find(imd
, CBMEM_ID_STAGEx_CACHE
+ stage_id
);
138 printk(BIOS_DEBUG
, "Error: Can't find stage_cache %x in imd\n",
139 CBMEM_ID_STAGEx_CACHE
+ stage_id
);
143 c
= imd_entry_at(imd
, e
);
144 size
= imd_entry_size(e
);
146 memcpy((void *)(uintptr_t)meta
->load_addr
, c
, size
);
148 prog_set_area(stage
, (void *)(uintptr_t)meta
->load_addr
, size
);
149 prog_set_entry(stage
, (void *)(uintptr_t)meta
->entry_addr
,
150 (void *)(uintptr_t)meta
->arg
);
153 static void stage_cache_setup(int is_recovery
)
156 stage_cache_recover();
158 stage_cache_create_empty();
161 ROMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup
)
162 RAMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup
)
163 POSTCAR_CBMEM_INIT_HOOK(stage_cache_setup
)