1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <program_loading.h>
6 #include <arch/encoding.h>
7 #include <arch/smp/atomic.h>
8 #include <console/console.h>
11 /* Run OpenSBI and let OpenSBI hand over control to the payload */
12 void run_payload_opensbi(struct prog
*prog
, void *fdt
, struct prog
*opensbi
, int payload_mode
)
14 int hart_id
= read_csr(mhartid
);
15 uintptr_t status
= read_csr(mstatus
);
16 status
= INSERT_FIELD(status
, MSTATUS_MPIE
, 0);
19 * In case of OpenSBI we always run it in M-Mode.
20 * OpenSBI will switch to payload_mode when done.
23 status
= INSERT_FIELD(status
, MSTATUS_MPP
, PRV_M
);
24 /* Trap vector base address point to the payload */
25 write_csr(mtvec
, prog_entry(opensbi
));
26 /* disable M-Mode interrupt */
28 write_csr(mstatus
, status
);
30 run_opensbi(hart_id
, fdt
, prog_entry(opensbi
), prog_entry(prog
), payload_mode
);
33 /* Runs the payload without OpenSBI integration */
34 void run_payload(struct prog
*prog
, void *fdt
, int payload_mode
)
36 void (*doit
)(int hart_id
, void *fdt
) = prog_entry(prog
);
37 int hart_id
= read_csr(mhartid
);
38 uintptr_t status
= read_csr(mstatus
);
39 status
= INSERT_FIELD(status
, MSTATUS_MPIE
, 0);
41 switch (payload_mode
) {
42 case RISCV_PAYLOAD_MODE_U
:
43 status
= INSERT_FIELD(status
, MSTATUS_MPP
, PRV_U
);
44 /* Trap vector base address point to the payload */
45 write_csr(utvec
, doit
);
46 /* disable U-Mode interrupt */
49 case RISCV_PAYLOAD_MODE_S
:
50 status
= INSERT_FIELD(status
, MSTATUS_MPP
, PRV_S
);
51 /* Trap vector base address point to the payload */
52 write_csr(stvec
, doit
);
53 /* disable S-Mode interrupt */
58 case RISCV_PAYLOAD_MODE_M
:
59 status
= INSERT_FIELD(status
, MSTATUS_MPP
, PRV_M
);
60 /* Trap vector base address point to the payload */
61 write_csr(mtvec
, doit
);
62 /* disable M-Mode interrupt */
66 die("wrong privilege level for payload");
69 write_csr(mstatus
, status
);
70 write_csr(mepc
, doit
);
74 "mret" ::"r"(hart_id
),