forked from Mirrors/opensbi
lib: Add RISC-V hypervisor v0.6.1 support
To support RISC-V hypervisor v0.6.1, we: 1. Don't need to explicitly forward WFI traps from VS/VU-mode 2. Have to delegate virtual instruction trap to HS-mode 3. Have to update trap redirection for changes in HSTATUS CSR Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
This commit is contained in:
@@ -61,12 +61,20 @@
|
|||||||
#define SSTATUS64_UXL MSTATUS_UXL
|
#define SSTATUS64_UXL MSTATUS_UXL
|
||||||
#define SSTATUS64_SD MSTATUS64_SD
|
#define SSTATUS64_SD MSTATUS64_SD
|
||||||
|
|
||||||
|
#if __riscv_xlen == 64
|
||||||
|
#define HSTATUS_VSXL _UL(0x300000000)
|
||||||
|
#define HSTATUS_VSXL_SHIFT 32
|
||||||
|
#endif
|
||||||
#define HSTATUS_VTSR _UL(0x00400000)
|
#define HSTATUS_VTSR _UL(0x00400000)
|
||||||
|
#define HSTATUS_VTW _UL(0x00200000)
|
||||||
#define HSTATUS_VTVM _UL(0x00100000)
|
#define HSTATUS_VTVM _UL(0x00100000)
|
||||||
#define HSTATUS_SP2V _UL(0x00000200)
|
#define HSTATUS_VGEIN _UL(0x0003f000)
|
||||||
#define HSTATUS_SP2P _UL(0x00000100)
|
#define HSTATUS_VGEIN_SHIFT 12
|
||||||
|
#define HSTATUS_HU _UL(0x00000200)
|
||||||
|
#define HSTATUS_SPVP _UL(0x00000100)
|
||||||
#define HSTATUS_SPV _UL(0x00000080)
|
#define HSTATUS_SPV _UL(0x00000080)
|
||||||
#define HSTATUS_SPRV _UL(0x00000001)
|
#define HSTATUS_GVA _UL(0x00000040)
|
||||||
|
#define HSTATUS_VSBE _UL(0x00000020)
|
||||||
|
|
||||||
#define IRQ_S_SOFT 1
|
#define IRQ_S_SOFT 1
|
||||||
#define IRQ_VS_SOFT 2
|
#define IRQ_VS_SOFT 2
|
||||||
@@ -424,6 +432,7 @@
|
|||||||
#define CAUSE_STORE_PAGE_FAULT 0xf
|
#define CAUSE_STORE_PAGE_FAULT 0xf
|
||||||
#define CAUSE_FETCH_GUEST_PAGE_FAULT 0x14
|
#define CAUSE_FETCH_GUEST_PAGE_FAULT 0x14
|
||||||
#define CAUSE_LOAD_GUEST_PAGE_FAULT 0x15
|
#define CAUSE_LOAD_GUEST_PAGE_FAULT 0x15
|
||||||
|
#define CAUSE_VIRTUAL_INST_FAULT 0x16
|
||||||
#define CAUSE_STORE_GUEST_PAGE_FAULT 0x17
|
#define CAUSE_STORE_GUEST_PAGE_FAULT 0x17
|
||||||
|
|
||||||
#define INSN_MATCH_LB 0x3
|
#define INSN_MATCH_LB 0x3
|
||||||
|
@@ -110,6 +110,7 @@ static int delegate_traps(struct sbi_scratch *scratch, u32 hartid)
|
|||||||
exceptions |= (1U << CAUSE_SUPERVISOR_ECALL);
|
exceptions |= (1U << CAUSE_SUPERVISOR_ECALL);
|
||||||
exceptions |= (1U << CAUSE_FETCH_GUEST_PAGE_FAULT);
|
exceptions |= (1U << CAUSE_FETCH_GUEST_PAGE_FAULT);
|
||||||
exceptions |= (1U << CAUSE_LOAD_GUEST_PAGE_FAULT);
|
exceptions |= (1U << CAUSE_LOAD_GUEST_PAGE_FAULT);
|
||||||
|
exceptions |= (1U << CAUSE_VIRTUAL_INST_FAULT);
|
||||||
exceptions |= (1U << CAUSE_STORE_GUEST_PAGE_FAULT);
|
exceptions |= (1U << CAUSE_STORE_GUEST_PAGE_FAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,17 +38,7 @@ static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
|
|||||||
int csr_num = (u32)insn >> 20;
|
int csr_num = (u32)insn >> 20;
|
||||||
ulong csr_val, new_csr_val;
|
ulong csr_val, new_csr_val;
|
||||||
|
|
||||||
/*
|
/* TODO: Ensure that we got CSR read/write instruction */
|
||||||
* WFI always traps as illegal instruction when executed from
|
|
||||||
* VS/VU mode so we just forward it to HS-mode.
|
|
||||||
*/
|
|
||||||
#if __riscv_xlen == 32
|
|
||||||
if ((regs->mstatusH & MSTATUSH_MPV) &&
|
|
||||||
#else
|
|
||||||
if ((regs->mstatus & MSTATUS_MPV) &&
|
|
||||||
#endif
|
|
||||||
(insn & INSN_MASK_WFI) == INSN_MATCH_WFI)
|
|
||||||
return truly_illegal_insn(insn, regs);
|
|
||||||
|
|
||||||
if (sbi_emulate_csr_read(csr_num, regs, &csr_val))
|
if (sbi_emulate_csr_read(csr_num, regs, &csr_val))
|
||||||
return truly_illegal_insn(insn, regs);
|
return truly_illegal_insn(insn, regs);
|
||||||
|
@@ -120,12 +120,10 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
|
|||||||
|
|
||||||
/* Update HSTATUS for VS/VU-mode to HS-mode transition */
|
/* Update HSTATUS for VS/VU-mode to HS-mode transition */
|
||||||
if (misa_extension('H') && prev_virt && !next_virt) {
|
if (misa_extension('H') && prev_virt && !next_virt) {
|
||||||
/* Update HSTATUS SP2P, SP2V, and SPV bits */
|
/* Update HSTATUS SPVP and SPV bits */
|
||||||
hstatus = csr_read(CSR_HSTATUS);
|
hstatus = csr_read(CSR_HSTATUS);
|
||||||
hstatus &= ~HSTATUS_SP2P;
|
hstatus &= ~HSTATUS_SPVP;
|
||||||
hstatus |= (regs->mstatus & MSTATUS_SPP) ? HSTATUS_SP2P : 0;
|
hstatus |= (regs->mstatus & MSTATUS_SPP) ? HSTATUS_SPVP : 0;
|
||||||
hstatus &= ~HSTATUS_SP2V;
|
|
||||||
hstatus |= (hstatus & HSTATUS_SPV) ? HSTATUS_SP2V : 0;
|
|
||||||
hstatus &= ~HSTATUS_SPV;
|
hstatus &= ~HSTATUS_SPV;
|
||||||
hstatus |= (prev_virt) ? HSTATUS_SPV : 0;
|
hstatus |= (prev_virt) ? HSTATUS_SPV : 0;
|
||||||
csr_write(CSR_HSTATUS, hstatus);
|
csr_write(CSR_HSTATUS, hstatus);
|
||||||
|
Reference in New Issue
Block a user