Pārlūkot izejas kodu

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>
Anup Patel 4 gadi atpakaļ
vecāks
revīzija
1b8c0128f1
4 mainītis faili ar 17 papildinājumiem un 19 dzēšanām
  1. 12 3
      include/sbi/riscv_encoding.h
  2. 1 0
      lib/sbi/sbi_hart.c
  3. 1 11
      lib/sbi/sbi_illegal_insn.c
  4. 3 5
      lib/sbi/sbi_trap.c

+ 12 - 3
include/sbi/riscv_encoding.h

@@ -61,12 +61,20 @@
 #define SSTATUS64_UXL			MSTATUS_UXL
 #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_VTW			_UL(0x00200000)
 #define HSTATUS_VTVM			_UL(0x00100000)
-#define HSTATUS_SP2V			_UL(0x00000200)
-#define HSTATUS_SP2P			_UL(0x00000100)
+#define HSTATUS_VGEIN			_UL(0x0003f000)
+#define HSTATUS_VGEIN_SHIFT		12
+#define HSTATUS_HU			_UL(0x00000200)
+#define HSTATUS_SPVP			_UL(0x00000100)
 #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_VS_SOFT			2
@@ -424,6 +432,7 @@
 #define CAUSE_STORE_PAGE_FAULT		0xf
 #define CAUSE_FETCH_GUEST_PAGE_FAULT	0x14
 #define CAUSE_LOAD_GUEST_PAGE_FAULT	0x15
+#define CAUSE_VIRTUAL_INST_FAULT	0x16
 #define CAUSE_STORE_GUEST_PAGE_FAULT	0x17
 
 #define INSN_MATCH_LB			0x3

+ 1 - 0
lib/sbi/sbi_hart.c

@@ -110,6 +110,7 @@ static int delegate_traps(struct sbi_scratch *scratch, u32 hartid)
 		exceptions |= (1U << CAUSE_SUPERVISOR_ECALL);
 		exceptions |= (1U << CAUSE_FETCH_GUEST_PAGE_FAULT);
 		exceptions |= (1U << CAUSE_LOAD_GUEST_PAGE_FAULT);
+		exceptions |= (1U << CAUSE_VIRTUAL_INST_FAULT);
 		exceptions |= (1U << CAUSE_STORE_GUEST_PAGE_FAULT);
 	}
 

+ 1 - 11
lib/sbi/sbi_illegal_insn.c

@@ -38,17 +38,7 @@ static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
 	int csr_num   = (u32)insn >> 20;
 	ulong csr_val, new_csr_val;
 
-	/*
-	 * 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);
+	/* TODO: Ensure that we got CSR read/write instruction */
 
 	if (sbi_emulate_csr_read(csr_num, regs, &csr_val))
 		return truly_illegal_insn(insn, regs);

+ 3 - 5
lib/sbi/sbi_trap.c

@@ -120,12 +120,10 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
 
 	/* Update HSTATUS for VS/VU-mode to HS-mode transition */
 	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 &= ~HSTATUS_SP2P;
-		hstatus |= (regs->mstatus & MSTATUS_SPP) ? HSTATUS_SP2P : 0;
-		hstatus &= ~HSTATUS_SP2V;
-		hstatus |= (hstatus & HSTATUS_SPV) ? HSTATUS_SP2V : 0;
+		hstatus &= ~HSTATUS_SPVP;
+		hstatus |= (regs->mstatus & MSTATUS_SPP) ? HSTATUS_SPVP : 0;
 		hstatus &= ~HSTATUS_SPV;
 		hstatus |= (prev_virt) ? HSTATUS_SPV : 0;
 		csr_write(CSR_HSTATUS, hstatus);