1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <program_loading.h>
6 #include <arch/encoding.h>
8 #include <arch/smp/atomic.h>
9 #include <console/console.h>
13 /* Run OpenSBI and let OpenSBI hand over control to the payload */
14 void run_payload_opensbi(struct prog
*prog
, void *fdt
, struct prog
*opensbi
, int payload_mode
)
16 int hart_id
= read_csr(mhartid
);
17 uintptr_t status
= read_csr(mstatus
);
18 status
= INSERT_FIELD(status
, MSTATUS_MPIE
, 0);
21 * In case of OpenSBI we always run it in M-Mode.
22 * OpenSBI will switch to payload_mode when done.
25 status
= INSERT_FIELD(status
, MSTATUS_MPP
, PRV_M
);
26 /* Trap vector base address point to the payload */
27 write_csr(mtvec
, prog_entry(opensbi
));
28 /* disable M-Mode interrupt */
30 write_csr(mstatus
, status
);
32 run_opensbi(hart_id
, fdt
, prog_entry(opensbi
), prog_entry(prog
), payload_mode
);
35 /* Runs the payload without OpenSBI integration */
36 void run_payload(struct prog
*prog
, void *fdt
, int payload_mode
)
38 void (*doit
)(int hart_id
, void *fdt
) = prog_entry(prog
);
39 int hart_id
= read_csr(mhartid
);
40 uintptr_t status
= read_csr(mstatus
);
41 extern void *_text
, *_estack
;
42 status
= INSERT_FIELD(status
, MSTATUS_MPIE
, 0);
44 switch (payload_mode
) {
45 case RISCV_PAYLOAD_MODE_S
:
47 * Set up a PMP to protect coreboot, then close the PMPs.
48 * If a mainboard or SoC needs other ranges
49 * set up, they should do so before this point,
50 * as close_pmp puts in a "match all" entry, and
51 * PMPs are processed in linear order.
55 * On this code path, coreboot is providing the coreboot SBI, and must
56 * protect the ramstage, from _text to _estack, from S and U
57 * modes. Because the number of PMP registers may be very
58 * small, make this an NAPOT area. The linker scripts
59 * should round _text and _estack to 4K.
61 setup_pmp((u64
)(uintptr_t) _text
,
62 (u64
)(uintptr_t) _estack
- (u64
)(uintptr_t) _text
, 0);
65 * All pmp operations should be finished when close_pmp is called.
66 * Presently, this requirement is not enforced.
70 status
= INSERT_FIELD(status
, MSTATUS_MPP
, PRV_S
);
71 /* Trap vector base address point to the payload */
72 write_csr(stvec
, doit
);
73 /* disable S-Mode interrupt */
77 /* save stack to mscratch so trap_entry can use that as exception stack */
78 write_csr(mscratch
, MACHINE_STACK_TOP());
80 case RISCV_PAYLOAD_MODE_M
:
81 status
= INSERT_FIELD(status
, MSTATUS_MPP
, PRV_M
);
82 /* Trap vector base address point to the payload */
83 write_csr(mtvec
, doit
);
84 /* disable M-Mode interrupt */
88 die("wrong privilege level for payload");
91 write_csr(mstatus
, status
);
92 write_csr(mepc
, doit
);
96 "mret" ::"r"(hart_id
),