blob: a59f9d15ec53c0848ef407babefae21e2b8db057 [file] [log] [blame]
Patrick Georgid1e50f92020-03-04 15:00:05 +01001/* SPDX-License-Identifier: GPL-2.0-only */
Ronald G. Minniche0e784a2014-11-26 19:25:47 +00002
Aaron Durbin04654a22015-03-17 11:43:44 -05003#include <program_loading.h>
Ronald G. Minnichf47f5fb2015-09-22 15:53:32 -07004#include <vm.h>
Jonathan Neuschäfer042a8332018-02-16 13:36:47 +01005#include <arch/boot.h>
Ronald G. Minnichf47f5fb2015-09-22 15:53:32 -07006#include <arch/encoding.h>
Xiang Wang26f725e2018-10-11 17:42:49 +08007#include <arch/smp/smp.h>
Xiang Wang820dcfc2018-07-19 17:35:39 +08008#include <mcall.h>
Julius Werner98eeb962019-12-11 15:47:42 -08009#include <cbfs.h>
Xiang Wanga6f9eab2019-03-28 12:19:30 +080010#include <console/console.h>
11
12struct arch_prog_run_args {
13 struct prog *prog;
14 struct prog *opensbi;
15};
Ronald G. Minniche0e784a2014-11-26 19:25:47 +000016
Jonathan Neuschäfer042a8332018-02-16 13:36:47 +010017/*
18 * A pointer to the Flattened Device Tree passed to coreboot by the boot ROM.
19 * Presumably this FDT is also in ROM.
20 *
21 * This pointer is only used in ramstage!
22 */
Jonathan Neuschäfer042a8332018-02-16 13:36:47 +010023
Xiang Wanga6f9eab2019-03-28 12:19:30 +080024static void do_arch_prog_run(struct arch_prog_run_args *args)
Ronald G. Minniche0e784a2014-11-26 19:25:47 +000025{
Arthur Heymans55069d12019-11-01 21:53:36 +010026 int hart_id = HLS()->hart_id;
Xiang Wanga6f9eab2019-03-28 12:19:30 +080027 struct prog *prog = args->prog;
Arthur Heymans763eeec2019-11-03 12:24:48 +010028 void *fdt = HLS()->fdt;
Xiang Wang820dcfc2018-07-19 17:35:39 +080029
Julius Werner00572622022-05-26 20:29:42 -070030 if (prog_cbfs_type(prog) == CBFS_TYPE_FIT_PAYLOAD)
Arthur Heymans763eeec2019-11-03 12:24:48 +010031 fdt = prog_entry_arg(prog);
Aaron Durbinb3847e62015-03-20 15:55:08 -050032
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060033 if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) {
Xiang Wanga6f9eab2019-03-28 12:19:30 +080034 if (CONFIG(RISCV_OPENSBI))
35 run_payload_opensbi(prog, fdt, args->opensbi, RISCV_PAYLOAD_MODE_S);
36 else
37 run_payload(prog, fdt, RISCV_PAYLOAD_MODE_S);
38 } else {
Arthur Heymans55069d12019-11-01 21:53:36 +010039 void (*doit)(int hart_id, void *fdt, void *arg) = prog_entry(prog);
40 doit(hart_id, fdt, prog_entry_arg(prog));
Ronald G. Minnichf47f5fb2015-09-22 15:53:32 -070041 }
Jonathan Neuschäfer455c3c92016-07-07 20:53:29 +020042
Xiang Wanga6f9eab2019-03-28 12:19:30 +080043 die("Failed to run stage");
Aaron Durbinb3847e62015-03-20 15:55:08 -050044}
Xiang Wang26f725e2018-10-11 17:42:49 +080045
46void arch_prog_run(struct prog *prog)
47{
Xiang Wanga6f9eab2019-03-28 12:19:30 +080048 struct arch_prog_run_args args = {};
49
50 args.prog = prog;
51
52 /* In case of OpenSBI we have to load it before resuming all HARTs */
53 if (ENV_RAMSTAGE && CONFIG(RISCV_OPENSBI)) {
54 struct prog sbi = PROG_INIT(PROG_OPENSBI, CONFIG_CBFS_PREFIX"/opensbi");
55
Xiang Wanga6f9eab2019-03-28 12:19:30 +080056 if (!selfload_check(&sbi, BM_MEM_OPENSBI))
57 die("OpenSBI load failed");
58
59 args.opensbi = &sbi;
60 }
61
62 smp_resume((void (*)(void *))do_arch_prog_run, &args);
Xiang Wang26f725e2018-10-11 17:42:49 +080063}