/ src / lib / prog_loaders.c
prog_loaders.c
  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 <romstage_common.h>
 13  #include <security/vboot/vboot_common.h>
 14  #include <stage_cache.h>
 15  #include <symbols.h>
 16  #include <timestamp.h>
 17  
 18  void run_romstage(void)
 19  {
 20  	if (!CONFIG(SEPARATE_ROMSTAGE)) {
 21  		/* Call romstage instead of loading it as a cbfs file. */
 22  		timestamp_add_now(TS_ROMSTAGE_START);
 23  		romstage_main();
 24  		dead_code();
 25  	}
 26  
 27  	struct prog romstage =
 28  		PROG_INIT(PROG_ROMSTAGE, CONFIG_CBFS_PREFIX "/romstage");
 29  
 30  	vboot_run_logic();
 31  
 32  	timestamp_add_now(TS_COPYROM_START);
 33  
 34  	if (ENV_X86 && CONFIG(BOOTBLOCK_NORMAL)) {
 35  		if (legacy_romstage_select_and_load(&romstage) != CB_SUCCESS)
 36  			goto fail;
 37  	} else {
 38  		if (cbfs_prog_stage_load(&romstage))
 39  			goto fail;
 40  	}
 41  
 42  	timestamp_add_now(TS_COPYROM_END);
 43  
 44  	console_time_report();
 45  
 46  	prog_run(&romstage);
 47  
 48  fail:
 49  	if (CONFIG(BOOTBLOCK_CONSOLE))
 50  		die_with_post_code(POSTCODE_INVALID_ROM,
 51  				   "Couldn't load romstage.\n");
 52  	halt();
 53  }
 54  
 55  int __weak prog_locate_hook(struct prog *prog) { return 0; }
 56  
 57  static void run_ramstage_from_resume(struct prog *ramstage)
 58  {
 59  	/* Load the cached ramstage to runtime location. */
 60  	stage_cache_load_stage(STAGE_RAMSTAGE, ramstage);
 61  
 62  	ramstage->cbfs_type = CBFS_TYPE_STAGE;
 63  	prog_set_arg(ramstage, (void *)cbmem_top());
 64  
 65  	if (prog_entry(ramstage) != NULL) {
 66  		printk(BIOS_DEBUG, "Jumping to image.\n");
 67  		prog_run(ramstage);
 68  	}
 69  
 70  	printk(BIOS_ERR, "ramstage cache invalid.\n");
 71  	board_reset();
 72  }
 73  
 74  static int load_relocatable_ramstage(struct prog *ramstage)
 75  {
 76  	struct rmod_stage_load rmod_ram = {
 77  		.cbmem_id = CBMEM_ID_RAMSTAGE,
 78  		.prog = ramstage,
 79  	};
 80  
 81  	return rmodule_stage_load(&rmod_ram);
 82  }
 83  void preload_ramstage(void)
 84  {
 85  	if (!CONFIG(CBFS_PRELOAD))
 86  		return;
 87  
 88  	printk(BIOS_DEBUG, "Preloading ramstage\n");
 89  
 90  	cbfs_preload(CONFIG_CBFS_PREFIX "/ramstage");
 91  }
 92  void __noreturn run_ramstage(void)
 93  {
 94  	struct prog ramstage =
 95  		PROG_INIT(PROG_RAMSTAGE, CONFIG_CBFS_PREFIX "/ramstage");
 96  
 97  	/* Call "end of romstage" here if postcar stage doesn't exist */
 98  	if (ENV_POSTCAR)
 99  		timestamp_add_now(TS_POSTCAR_END);
100  	else
101  		timestamp_add_now(TS_ROMSTAGE_END);
102  
103  	vboot_run_logic();
104  
105  	/*
106  	 * Only x86 systems using ramstage stage cache currently take the same
107  	 * firmware path on resume.
108  	 */
109  	if (ENV_X86 && resume_from_stage_cache())
110  		run_ramstage_from_resume(&ramstage);
111  
112  	timestamp_add_now(TS_COPYRAM_START);
113  
114  	if (ENV_X86) {
115  		if (load_relocatable_ramstage(&ramstage))
116  			goto fail;
117  	} else {
118  		if (cbfs_prog_stage_load(&ramstage))
119  			goto fail;
120  	}
121  
122  	stage_cache_add(STAGE_RAMSTAGE, &ramstage);
123  
124  	timestamp_add_now(TS_COPYRAM_END);
125  
126  	console_time_report();
127  
128  	/* This overrides the arg fetched from the relocatable module */
129  	prog_set_arg(&ramstage, (void *)cbmem_top());
130  
131  	prog_run(&ramstage);
132  
133  fail:
134  	die_with_post_code(POSTCODE_INVALID_ROM, "Ramstage was not loaded!\n");
135  }
136  
137  #if ENV_PAYLOAD_LOADER // gc-sections should take care of this
138  
139  static struct prog global_payload =
140  	PROG_INIT(PROG_PAYLOAD, CONFIG_CBFS_PREFIX "/payload");
141  
142  void payload_preload(void)
143  {
144  	if (!CONFIG(CBFS_PRELOAD))
145  		return;
146  
147  	cbfs_preload(global_payload.name);
148  }
149  
150  void payload_load(void)
151  {
152  	struct prog *payload = &global_payload;
153  	void *mapping;
154  
155  	timestamp_add_now(TS_LOAD_PAYLOAD);
156  
157  	if (prog_locate_hook(payload))
158  		goto out;
159  
160  	payload->cbfs_type = CBFS_TYPE_QUERY;
161  	mapping = cbfs_type_map(prog_name(payload), NULL, &payload->cbfs_type);
162  
163  	if (!mapping)
164  		goto out;
165  
166  	switch (prog_cbfs_type(payload)) {
167  	case CBFS_TYPE_SELF: /* Simple ELF */
168  		selfload_mapped(payload, mapping, BM_MEM_RAM);
169  		break;
170  	case CBFS_TYPE_FIT_PAYLOAD: /* Flattened image tree */
171  		if (CONFIG(PAYLOAD_FIT_SUPPORT)) {
172  			fit_payload(payload, mapping);
173  			break;
174  		}
175  		__fallthrough;
176  	default:
177  		die_with_post_code(POSTCODE_INVALID_ROM,
178  				   "Unsupported payload type %d.\n", payload->cbfs_type);
179  		break;
180  	}
181  
182  	cbfs_unmap(mapping);
183  out:
184  	if (prog_entry(payload) == NULL)
185  		die_with_post_code(POSTCODE_INVALID_ROM, "Payload not loaded.\n");
186  }
187  
188  void payload_run(void)
189  {
190  	struct prog *payload = &global_payload;
191  
192  	/* Reset to booting from this image as late as possible */
193  	boot_successful();
194  
195  	printk(BIOS_DEBUG, "Jumping to boot code at %p(%p)\n",
196  		prog_entry(payload), prog_entry_arg(payload));
197  
198  	post_code(POSTCODE_ENTER_ELF_BOOT);
199  
200  	timestamp_add_now(TS_SELFBOOT_JUMP);
201  
202  	/* Before we go off to run the payload, see if
203  	 * we stayed within our bounds.
204  	 */
205  	checkstack(_estack, 0);
206  
207  	prog_run(payload);
208  }
209  
210  #endif