coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
payload.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
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>
10 
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)
13 {
14  int hart_id = read_csr(mhartid);
15  uintptr_t status = read_csr(mstatus);
16  status = INSERT_FIELD(status, MSTATUS_MPIE, 0);
17 
18  /*
19  * In case of OpenSBI we always run it in M-Mode.
20  * OpenSBI will switch to payload_mode when done.
21  */
22 
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);
29 
30  run_opensbi(hart_id, fdt, prog_entry(opensbi), prog_entry(prog), payload_mode);
31 }
32 
33 /* Runs the payload without OpenSBI integration */
34 void run_payload(struct prog *prog, void *fdt, int payload_mode)
35 {
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);
40 
41  switch (payload_mode) {
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;
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;
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;
68  }
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");
77 }
void __noreturn die(const char *fmt,...)
Definition: die.c:17
#define PRV_U
Definition: encoding.h:111
#define MSTATUS_MPIE
Definition: encoding.h:13
#define MSTATUS_MPP
Definition: encoding.h:16
#define PRV_S
Definition: encoding.h:112
#define PRV_M
Definition: encoding.h:114
void run_payload_opensbi(struct prog *prog, void *fdt, struct prog *opensbi, int payload_mode)
Definition: payload.c:12
void run_payload(struct prog *prog, void *fdt, int payload_mode)
Definition: payload.c:34
static void * prog_entry(const struct prog *prog)
#define RISCV_PAYLOAD_MODE_S
Definition: boot.h:7
#define RISCV_PAYLOAD_MODE_M
Definition: boot.h:8
void run_opensbi(const int hart_id, const void *opensbi, const void *fdt, const void *payload, const int payload_mode)
Definition: opensbi.c:7
#define RISCV_PAYLOAD_MODE_U
Definition: boot.h:6
unsigned long uintptr_t
Definition: stdint.h:21
#define INSERT_FIELD(val, which, fieldval)
Definition: vm.h:11
typedef void(X86APIP X86EMU_intrFuncs)(int num)