mb/**/hda_verb.c: Drop empty files
[coreboot.git] / src / arch / riscv / payload.c
blob3097ad1bf8ba37bcd4a8f876ae385206e601b72d
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <program_loading.h>
4 #include <stdint.h>
5 #include <arch/boot.h>
6 #include <arch/encoding.h>
7 #include <arch/smp/atomic.h>
8 #include <console/console.h>
9 #include <vm.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 */
27 write_csr(mie, 0);
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 */
47 write_csr(uie, 0);
48 break;
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 */
54 write_csr(sie, 0);
55 /* disable MMU */
56 write_csr(satp, 0);
57 break;
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 */
63 write_csr(mie, 0);
64 break;
65 default:
66 die("wrong privilege level for payload");
67 break;
69 write_csr(mstatus, status);
70 write_csr(mepc, doit);
71 asm volatile(
72 "mv a0, %0\n\t"
73 "mv a1, %1\n\t"
74 "mret" ::"r"(hart_id),
75 "r"(fdt)
76 : "a0", "a1");