coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
prog_loaders.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <cbfs.h>
4 #include <cbmem.h>
5 #include <console/console.h>
6 #include <fallback.h>
7 #include <halt.h>
8 #include <lib.h>
9 #include <program_loading.h>
10 #include <reset.h>
11 #include <rmodule.h>
12 #include <stage_cache.h>
13 #include <symbols.h>
14 #include <thread.h>
15 #include <timestamp.h>
17 
18 void run_romstage(void)
19 {
20  struct prog romstage =
21  PROG_INIT(PROG_ROMSTAGE, CONFIG_CBFS_PREFIX "/romstage");
22 
24 
26 
27  if (ENV_X86 && CONFIG(BOOTBLOCK_NORMAL)) {
29  goto fail;
30  } else {
32  goto fail;
33  }
34 
36 
38 
40 
41 fail:
42  if (CONFIG(BOOTBLOCK_CONSOLE))
44  "Couldn't load romstage.\n");
45  halt();
46 }
47 
48 int __weak prog_locate_hook(struct prog *prog) { return 0; }
49 
50 static void run_ramstage_from_resume(struct prog *ramstage)
51 {
52  /* Load the cached ramstage to runtime location. */
54 
55  ramstage->cbfs_type = CBFS_TYPE_STAGE;
56  prog_set_arg(ramstage, cbmem_top());
57 
58  if (prog_entry(ramstage) != NULL) {
59  printk(BIOS_DEBUG, "Jumping to image.\n");
60  prog_run(ramstage);
61  }
62 
63  printk(BIOS_ERR, "ramstage cache invalid.\n");
64  board_reset();
65 }
66 
67 static int load_relocatable_ramstage(struct prog *ramstage)
68 {
69  struct rmod_stage_load rmod_ram = {
71  .prog = ramstage,
72  };
73 
74  return rmodule_stage_load(&rmod_ram);
75 }
76 void preload_ramstage(void)
77 {
78  if (!CONFIG(CBFS_PRELOAD))
79  return;
80 
81  printk(BIOS_DEBUG, "Preloading ramstage\n");
82 
83  cbfs_preload(CONFIG_CBFS_PREFIX "/ramstage");
84 }
85 void run_ramstage(void)
86 {
87  struct prog ramstage =
88  PROG_INIT(PROG_RAMSTAGE, CONFIG_CBFS_PREFIX "/ramstage");
89 
90  /* Call "end of romstage" here if postcar stage doesn't exist */
91  if (ENV_POSTCAR)
93  else
95 
96  /*
97  * Only x86 systems using ramstage stage cache currently take the same
98  * firmware path on resume.
99  */
101  run_ramstage_from_resume(&ramstage);
102 
103  vboot_run_logic();
104 
106 
107  if (ENV_X86) {
108  if (load_relocatable_ramstage(&ramstage))
109  goto fail;
110  } else {
111  if (cbfs_prog_stage_load(&ramstage))
112  goto fail;
113  }
114 
115  stage_cache_add(STAGE_RAMSTAGE, &ramstage);
116 
118 
120 
121  /* This overrides the arg fetched from the relocatable module */
122  prog_set_arg(&ramstage, cbmem_top());
123 
124  prog_run(&ramstage);
125 
126 fail:
127  die_with_post_code(POST_INVALID_ROM, "Ramstage was not loaded!\n");
128 }
129 
130 #if ENV_PAYLOAD_LOADER // gc-sections should take care of this
131 
132 static struct prog global_payload =
133  PROG_INIT(PROG_PAYLOAD, CONFIG_CBFS_PREFIX "/payload");
134 
135 void payload_preload(void)
136 {
137  if (!CONFIG(CBFS_PRELOAD))
138  return;
139 
140  cbfs_preload(global_payload.name);
141 }
142 
143 void payload_load(void)
144 {
145  struct prog *payload = &global_payload;
146  void *mapping;
147 
149 
150  if (prog_locate_hook(payload))
151  goto out;
152 
153  payload->cbfs_type = CBFS_TYPE_QUERY;
154  mapping = cbfs_type_map(prog_name(payload), NULL, &payload->cbfs_type);
155 
156  if (!mapping)
157  goto out;
158 
159  switch (prog_cbfs_type(payload)) {
160  case CBFS_TYPE_SELF: /* Simple ELF */
161  selfload_mapped(payload, mapping, BM_MEM_RAM);
162  break;
163  case CBFS_TYPE_FIT: /* Flattened image tree */
164  if (CONFIG(PAYLOAD_FIT_SUPPORT)) {
165  fit_payload(payload, mapping);
166  break;
167  }
169  default:
171  "Unsupported payload type %d.\n", payload->cbfs_type);
172  break;
173  }
174 
175  cbfs_unmap(mapping);
176 out:
177  if (prog_entry(payload) == NULL)
178  die_with_post_code(POST_INVALID_ROM, "Payload not loaded.\n");
179 }
180 
181 void payload_run(void)
182 {
183  struct prog *payload = &global_payload;
184 
185  /* Reset to booting from this image as late as possible */
186  boot_successful();
187 
188  printk(BIOS_DEBUG, "Jumping to boot code at %p(%p)\n",
189  prog_entry(payload), prog_entry_arg(payload));
190 
192 
194 
195  /* Before we go off to run the payload, see if
196  * we stayed within our bounds.
197  */
198  checkstack(_estack, 0);
199 
200  prog_run(payload);
201 }
202 
203 #endif
enum cb_err legacy_romstage_select_and_load(struct prog *romstage)
@ BM_MEM_RAM
Definition: bootmem.h:23
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
void cbfs_unmap(void *mapping)
Definition: cbfs.c:86
enum cb_err cbfs_prog_stage_load(struct prog *prog)
Definition: cbfs.c:523
static void * cbfs_type_map(const char *name, size_t *size_out, enum cbfs_type *type)
Definition: cbfs.h:256
void cbfs_preload(const char *name)
Definition: cbfs.c:299
@ CBFS_TYPE_SELF
@ CBFS_TYPE_STAGE
@ CBFS_TYPE_QUERY
@ CBFS_TYPE_FIT
void * cbmem_top(void)
Definition: imd_cbmem.c:18
#define CBMEM_ID_RAMSTAGE
Definition: cbmem_id.h:45
#define printk(level,...)
Definition: stdlib.h:16
#define __fallthrough
Definition: compiler.h:39
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 boot_successful(void)
Definition: fallback_boot.c:7
void __noreturn halt(void)
halt the system reliably
Definition: halt.c:6
__noreturn void board_reset(void)
Definition: reset.c:8
void timestamp_add_now(enum timestamp_id id)
Definition: timestamp.c:141
int checkstack(void *top_of_stack, int core)
Definition: stack.c:30
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
static void romstage(void)
Definition: romstage.c:24
#define post_code(value)
Definition: post_code.h:12
#define POST_INVALID_ROM
Invalid or corrupt ROM.
Definition: post_codes.h:323
#define POST_ENTER_ELF_BOOT
Entry into elf boot.
Definition: post_codes.h:400
static void run_ramstage_from_resume(struct prog *ramstage)
Definition: prog_loaders.c:50
void run_romstage(void)
Definition: prog_loaders.c:18
static int load_relocatable_ramstage(struct prog *ramstage)
Definition: prog_loaders.c:67
void run_ramstage(void)
Definition: prog_loaders.c:85
void preload_ramstage(void)
Definition: prog_loaders.c:76
int __weak prog_locate_hook(struct prog *prog)
Definition: prog_loaders.c:48
static void prog_set_arg(struct prog *prog, void *arg)
void payload_run(void)
bool selfload_mapped(struct prog *payload, void *mapping, enum bootmem_type dest_type)
Definition: selfboot.c:237
static void * prog_entry(const struct prog *prog)
#define PROG_INIT(type_, name_)
void fit_payload(struct prog *payload, void *data)
Definition: fit_payload.c:169
static void * prog_entry_arg(const struct prog *prog)
static enum cbfs_type prog_cbfs_type(const struct prog *prog)
void payload_preload(void)
void payload_load(void)
static const char * prog_name(const struct prog *prog)
void prog_run(struct prog *prog)
Definition: prog_ops.c:24
@ PROG_ROMSTAGE
@ PROG_RAMSTAGE
@ PROG_PAYLOAD
int rmodule_stage_load(struct rmod_stage_load *rsl)
Definition: rmodule.c:249
#define ENV_X86
Definition: rules.h:248
#define ENV_POSTCAR
Definition: rules.h:154
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
@ STAGE_RAMSTAGE
Definition: stage_cache.h:13
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
const char * name
enum cbfs_type cbfs_type
uint32_t cbmem_id
Definition: rmodule.h:43
@ TS_COPYRAM_END
@ TS_COPYROM_END
@ TS_ROMSTAGE_END
@ TS_SELFBOOT_JUMP
@ TS_POSTCAR_END
@ TS_LOAD_PAYLOAD
@ TS_COPYRAM_START
@ TS_COPYROM_START
void vboot_run_logic(void)
Definition: vboot_loader.c:42