coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
postcar_loader.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/romstage.h>
4 #include <cbmem.h>
5 #include <console/console.h>
6 #include <cpu/x86/msr.h>
7 #include <cpu/x86/mtrr.h>
8 #include <cpu/x86/smm.h>
9 #include <program_loading.h>
10 #include <reset.h>
11 #include <rmodule.h>
12 #include <stage_cache.h>
13 #include <timestamp.h>
15 
16 static inline void stack_push(struct postcar_frame *pcf, uint32_t val)
17 {
18  uint32_t *ptr;
19 
20  pcf->stack -= sizeof(val);
21  ptr = (void *)pcf->stack;
22  *ptr = val;
23 }
24 
25 static void postcar_frame_prepare(struct postcar_frame *pcf)
26 {
27  var_mtrr_context_init(&pcf->ctx, pcf);
28 }
29 
30 int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size)
31 {
32  void *stack;
33 
34  /*
35  * Use default postcar stack size of 4 KiB. This value should
36  * not be decreased, because if mainboards use vboot, 1 KiB will
37  * not be enough anymore.
38  */
39 
40  if (stack_size == 0)
41  stack_size = 4 * KiB;
42 
43  stack = cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK, stack_size);
44  if (stack == NULL) {
45  printk(BIOS_ERR, "Couldn't add %zd byte stack in cbmem.\n",
46  stack_size);
47  return -1;
48  }
49 
51  pcf->stack = (uintptr_t)stack;
52  pcf->stack += stack_size;
53  return 0;
54 }
55 
56 static void postcar_var_mtrr_set(const struct var_mtrr_context *ctx,
57  uintptr_t addr, size_t size,
59 {
60  struct postcar_frame *pcf = ctx->arg;
61 
62  printk(BIOS_DEBUG, "MTRR Range: Start=%lx End=%lx (Size %zx)\n",
63  addr, addr + size - 1, size);
64 
65  stack_push(pcf, mask.hi);
66  stack_push(pcf, mask.lo);
67  stack_push(pcf, base.hi);
68  stack_push(pcf, base.lo);
69 }
70 
72  uintptr_t addr, size_t size, int type)
73 {
75 }
76 
78 {
79  if (!CONFIG(BOOT_DEVICE_MEMORY_MAPPED))
80  return;
82 }
83 
84 static void postcar_frame_common_mtrrs(struct postcar_frame *pcf)
85 {
86  if (pcf->skip_common_mtrr)
87  return;
88 
89  /* Cache the ROM as WP just below 4GiB. */
91 }
92 
93 /* prepare_and_run_postcar() determines the stack to use after
94  * cache-as-ram is torn down as well as the MTRR settings to use. */
96 {
97  if (postcar_frame_init(pcf, 0))
98  die("Unable to initialize postcar frame.\n");
99 
100  fill_postcar_frame(pcf);
101 
103 
104  run_postcar_phase(pcf);
105  /* We do not return here. */
106 }
107 
108 static void postcar_commit_mtrrs(struct postcar_frame *pcf)
109 {
110  /*
111  * Place the number of used variable MTRRs on stack then max number
112  * of variable MTRRs supported in the system.
113  */
114  stack_push(pcf, pcf->ctx.used_var_mtrrs);
115  stack_push(pcf, pcf->ctx.max_var_mtrrs);
116 }
117 
118 static void finalize_load(uintptr_t *stack_top_ptr, uintptr_t stack_top)
119 {
120  *stack_top_ptr = stack_top;
121  /*
122  * Signal to rest of system that another update was made to the
123  * postcar program prior to running it.
124  */
125  prog_segment_loaded((uintptr_t)stack_top_ptr, sizeof(uintptr_t),
126  SEG_FINAL);
127 }
128 
129 static void load_postcar_cbfs(struct prog *prog, struct postcar_frame *pcf)
130 {
131  struct rmod_stage_load rsl = {
133  .prog = prog,
134  };
135 
136  vboot_run_logic();
137 
138  if (rmodule_stage_load(&rsl))
140  "Failed to load after CAR program.\n");
141 
142  /* Set the stack pointer within parameters of the program loaded. */
143  if (rsl.params == NULL)
145  "No parameters found in after CAR program.\n");
146 
147  finalize_load(rsl.params, pcf->stack);
148 
150 }
151 
152 /*
153  * Cache the TSEG region at the top of ram. This region is
154  * not restricted to SMM mode until SMM has been relocated.
155  * By setting the region to cacheable it provides faster access
156  * when relocating the SMM handler as well as using the TSEG
157  * region for other purposes.
158  */
160 {
161  uintptr_t smm_base;
162  size_t smm_size;
163 
164  smm_region(&smm_base, &smm_size);
165  postcar_frame_add_mtrr(pcf, smm_base, smm_size,
167 }
168 
169 static void postcar_cache_invalid(void)
170 {
171  printk(BIOS_ERR, "postcar cache invalid.\n");
172  board_reset();
173 }
174 
176 {
177  struct prog prog =
178  PROG_INIT(PROG_POSTCAR, CONFIG_CBFS_PREFIX "/postcar");
179 
181 
182  if (resume_from_stage_cache()) {
184  /* This is here to allow platforms to pass different stack
185  parameters between S3 resume and normal boot. On the
186  platforms where the values are the same it's a nop. */
187  finalize_load(prog.arg, pcf->stack);
188 
189  if (prog_entry(&prog) == NULL)
191  } else
192  load_postcar_cbfs(&prog, pcf);
193 
194  /* As postcar exist, it's end of romstage here */
196 
198 
200 
201  prog_run(&prog);
202 }
void fill_postcar_frame(struct postcar_frame *pcf)
Definition: car.c:13
#define KiB
Definition: helpers.h:75
void * cbmem_top(void)
Definition: imd_cbmem.c:18
void * cbmem_add(u32 id, u64 size)
Definition: imd_cbmem.c:144
#define CBMEM_ID_ROMSTAGE_RAM_STACK
Definition: cbmem_id.h:52
#define CBMEM_ID_AFTER_CAR
Definition: cbmem_id.h:12
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
void console_time_report(void)
Definition: printk.c:36
#define die_with_post_code(value, fmt,...)
Definition: console.h:21
@ CONFIG
Definition: dsi_common.h:201
void var_mtrr_context_init(struct var_mtrr_context *ctx, void *arg)
Definition: earlymtrr.c:9
int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type, void(*callback)(const struct var_mtrr_context *ctx, uintptr_t base_addr, size_t size, msr_t base, msr_t mask))
Definition: earlymtrr.c:17
void smm_region(uintptr_t *start, size_t *size)
Definition: memmap.c:50
__noreturn void board_reset(void)
Definition: reset.c:8
unsigned int type
Definition: edid.c:57
void timestamp_add_now(enum timestamp_id id)
Definition: timestamp.c:141
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define POST_INVALID_ROM
Invalid or corrupt ROM.
Definition: post_codes.h:323
void prepare_and_run_postcar(struct postcar_frame *pcf)
void run_postcar_phase(struct postcar_frame *pcf)
static void load_postcar_cbfs(struct prog *prog, struct postcar_frame *pcf)
static void postcar_frame_common_mtrrs(struct postcar_frame *pcf)
int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size)
static void postcar_frame_prepare(struct postcar_frame *pcf)
static void postcar_var_mtrr_set(const struct var_mtrr_context *ctx, uintptr_t addr, size_t size, msr_t base, msr_t mask)
static void finalize_load(uintptr_t *stack_top_ptr, uintptr_t stack_top)
void postcar_frame_add_mtrr(struct postcar_frame *pcf, uintptr_t addr, size_t size, int type)
static void postcar_commit_mtrrs(struct postcar_frame *pcf)
void postcar_enable_tseg_cache(struct postcar_frame *pcf)
static void stack_push(struct postcar_frame *pcf, uint32_t val)
static void postcar_cache_invalid(void)
void postcar_frame_add_romcache(struct postcar_frame *pcf, int type)
static void prog_set_arg(struct prog *prog, void *arg)
static void * prog_entry(const struct prog *prog)
#define PROG_INIT(type_, name_)
@ SEG_FINAL
void prog_segment_loaded(uintptr_t start, size_t size, int flags)
Definition: prog_ops.c:6
void prog_run(struct prog *prog)
Definition: prog_ops.c:24
@ PROG_POSTCAR
int rmodule_stage_load(struct rmod_stage_load *rsl)
Definition: rmodule.c:249
static uintptr_t stack_top
uintptr_t base
Definition: uart.c:17
static const int mask[4]
Definition: gpio.c:308
@ STAGE_POSTCAR
Definition: stage_cache.h:15
static void stage_cache_load_stage(int stage_id, struct prog *stage)
Definition: stage_cache.h:36
static int resume_from_stage_cache(void)
Definition: stage_cache.h:42
static void stage_cache_add(int stage_id, const struct prog *stage)
Definition: stage_cache.h:35
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
int skip_common_mtrr
Definition: romstage.h:20
uintptr_t stack
Definition: romstage.h:19
struct var_mtrr_context ctx
Definition: romstage.h:21
void * arg
struct prog * prog
Definition: rmodule.h:44
uint32_t cbmem_id
Definition: rmodule.h:43
void * params
Definition: rmodule.h:45
int max_var_mtrrs
Definition: mtrr.h:123
void * arg
Definition: mtrr.h:125
int used_var_mtrrs
Definition: mtrr.h:124
u8 val
Definition: sys.c:300
@ TS_ROMSTAGE_END
void vboot_run_logic(void)
Definition: vboot_loader.c:42
#define MTRR_TYPE_WRPROT
Definition: mtrr.h:13
#define CACHE_ROM_SIZE
Definition: mtrr.h:223
#define CACHE_ROM_BASE
Definition: mtrr.h:226
#define MTRR_TYPE_WRBACK
Definition: mtrr.h:14