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>
19 #include <console/console.h>
22 #include <stage_cache.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)
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)
55 stage_cache_external_region(&base
, &size
);
56 imd_handle_init(imd
, (void *)(size
+ (uintptr_t)base
));
58 printk(BIOS_DEBUG
, "Unable to recover external stage cache.\n");
61 void stage_cache_add(int stage_id
, const struct prog
*stage
)
64 const struct imd_entry
*e
;
65 struct stage_cache
*meta
;
69 e
= imd_entry_add(imd
, CBMEM_ID_STAGEx_META
+ stage_id
, sizeof(*meta
));
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
,
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
)
93 struct stage_cache
*meta
;
94 const struct imd_entry
*e
;
99 e
= imd_entry_find(imd
, CBMEM_ID_STAGEx_META
+ stage_id
);
103 meta
= imd_entry_at(imd
, e
);
105 e
= imd_entry_find(imd
, CBMEM_ID_STAGEx_CACHE
+ stage_id
);
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
)
122 stage_cache_recover();
124 stage_cache_create_empty();
127 ROMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup
)
128 RAMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup
)