riscv: use mret to invoke M-mode payload and disable interrupts
Fixes a logic error that sets MPIE, but didn't use mret to return to the payload. This left MIE set to an undefined value. Now all modes are handled the same way: - Trap vector base address point to the payload - Disable Interrupt - Return to payload using mret TEST=Run an M-mode payload Change-Id: Iaab595f916949c57104ec00f8b06ea047fe76bba Signed-off-by: Xiang Wang <wxjstz@126.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/33462 Reviewed-by: Philipp Hug <philipp@hug.cx> Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-by: Patrick Rudolph <siro@das-labor.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
3280aa7df2
commit
b1e6654d86
|
@ -19,23 +19,38 @@
|
||||||
#include <arch/boot.h>
|
#include <arch/boot.h>
|
||||||
#include <arch/encoding.h>
|
#include <arch/encoding.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
#include <vm.h>
|
||||||
|
|
||||||
void run_payload(struct prog *prog, void *fdt, int payload_mode)
|
void run_payload(struct prog *prog, void *fdt, int payload_mode)
|
||||||
{
|
{
|
||||||
void (*doit)(int hart_id, void *fdt) = prog_entry(prog);
|
void (*doit)(int hart_id, void *fdt) = prog_entry(prog);
|
||||||
int hart_id = read_csr(mhartid);
|
int hart_id = read_csr(mhartid);
|
||||||
uintptr_t status = read_csr(mstatus);
|
uintptr_t status = read_csr(mstatus);
|
||||||
status &= ~MSTATUS_MPIE;
|
status = INSERT_FIELD(status, MSTATUS_MPIE, 0);
|
||||||
status &= ~MSTATUS_MPP;
|
|
||||||
switch (payload_mode) {
|
switch (payload_mode) {
|
||||||
case RISCV_PAYLOAD_MODE_U:
|
case RISCV_PAYLOAD_MODE_U:
|
||||||
|
status = INSERT_FIELD(status, MSTATUS_MPP, PRV_U);
|
||||||
|
/* Trap vector base address point to the payload */
|
||||||
|
write_csr(utvec, doit);
|
||||||
|
/* disable U-Mode interrupt */
|
||||||
|
write_csr(uie, 0);
|
||||||
break;
|
break;
|
||||||
case RISCV_PAYLOAD_MODE_S:
|
case RISCV_PAYLOAD_MODE_S:
|
||||||
status |= MSTATUS_SPP;
|
status = INSERT_FIELD(status, MSTATUS_MPP, PRV_S);
|
||||||
|
/* Trap vector base address point to the payload */
|
||||||
|
write_csr(stvec, doit);
|
||||||
|
/* disable S-Mode interrupt */
|
||||||
|
write_csr(sie, 0);
|
||||||
|
/* disable MMU */
|
||||||
|
write_csr(satp, 0);
|
||||||
break;
|
break;
|
||||||
case RISCV_PAYLOAD_MODE_M:
|
case RISCV_PAYLOAD_MODE_M:
|
||||||
doit(hart_id, fdt);
|
status = INSERT_FIELD(status, MSTATUS_MPP, PRV_M);
|
||||||
return;
|
/* Trap vector base address point to the payload */
|
||||||
|
write_csr(mtvec, doit);
|
||||||
|
/* disable M-Mode interrupt */
|
||||||
|
write_csr(mie, 0);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
die("wrong privilege level for payload");
|
die("wrong privilege level for payload");
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue