forked from Mirrors/opensbi
lib: Extend sbi_hart_switch_mode() to support hypervisor extension
This patch extends sbi_hart_switch_mode() to support entering VS/VU modes when hypervisor extension is available. Signed-off-by: Anup Patel <anup.patel@wdc.com>
This commit is contained in:
@@ -38,8 +38,21 @@
|
|||||||
#define MSTATUS_TW 0x00200000
|
#define MSTATUS_TW 0x00200000
|
||||||
#define MSTATUS_TSR 0x00400000
|
#define MSTATUS_TSR 0x00400000
|
||||||
#define MSTATUS32_SD 0x80000000
|
#define MSTATUS32_SD 0x80000000
|
||||||
|
#if __riscv_xlen == 64
|
||||||
#define MSTATUS_UXL 0x0000000300000000
|
#define MSTATUS_UXL 0x0000000300000000
|
||||||
#define MSTATUS_SXL 0x0000000C00000000
|
#define MSTATUS_SXL 0x0000000C00000000
|
||||||
|
#define MSTATUS_MTL 0x0000004000000000
|
||||||
|
#define MSTATUS_MTL_SHIFT 38
|
||||||
|
#define MSTATUS_MPV 0x0000008000000000
|
||||||
|
#define MSTATUS_MPV_HIFT 39
|
||||||
|
#else
|
||||||
|
#define MSTATUSH_UXL 0x00000003
|
||||||
|
#define MSTATUSH_SXL 0x0000000C
|
||||||
|
#define MSTATUSH_MTL 0x00000040
|
||||||
|
#define MSTATUSH_MTL_SHIFT 6
|
||||||
|
#define MSTATUSH_MPV 0x00000080
|
||||||
|
#define MSTATUSH_MPV_HIFT 7
|
||||||
|
#endif
|
||||||
#define MSTATUS64_SD 0x8000000000000000
|
#define MSTATUS64_SD 0x8000000000000000
|
||||||
|
|
||||||
#define SSTATUS_UIE 0x00000001
|
#define SSTATUS_UIE 0x00000001
|
||||||
@@ -256,6 +269,7 @@
|
|||||||
#define CSR_MIE 0x304
|
#define CSR_MIE 0x304
|
||||||
#define CSR_MTVEC 0x305
|
#define CSR_MTVEC 0x305
|
||||||
#define CSR_MCOUNTEREN 0x306
|
#define CSR_MCOUNTEREN 0x306
|
||||||
|
#define CSR_MSTATUSH 0x310
|
||||||
#define CSR_MSCRATCH 0x340
|
#define CSR_MSCRATCH 0x340
|
||||||
#define CSR_MEPC 0x341
|
#define CSR_MEPC 0x341
|
||||||
#define CSR_MCAUSE 0x342
|
#define CSR_MCAUSE 0x342
|
||||||
|
@@ -26,7 +26,8 @@ void __attribute__((noreturn)) sbi_hart_hang(void);
|
|||||||
|
|
||||||
void __attribute__((noreturn))
|
void __attribute__((noreturn))
|
||||||
sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
|
sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
|
||||||
unsigned long next_addr, unsigned long next_mode);
|
unsigned long next_addr, unsigned long next_mode,
|
||||||
|
bool next_virt);
|
||||||
|
|
||||||
void sbi_hart_mark_available(u32 hartid);
|
void sbi_hart_mark_available(u32 hartid);
|
||||||
|
|
||||||
|
@@ -241,9 +241,14 @@ void __attribute__((noreturn)) sbi_hart_hang(void)
|
|||||||
|
|
||||||
void __attribute__((noreturn))
|
void __attribute__((noreturn))
|
||||||
sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
|
sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
|
||||||
unsigned long next_addr, unsigned long next_mode)
|
unsigned long next_addr, unsigned long next_mode,
|
||||||
|
bool next_virt)
|
||||||
{
|
{
|
||||||
|
#if __riscv_xlen == 32
|
||||||
|
unsigned long val, valH;
|
||||||
|
#else
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (next_mode) {
|
switch (next_mode) {
|
||||||
case PRV_M:
|
case PRV_M:
|
||||||
@@ -263,7 +268,25 @@ sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
|
|||||||
val = csr_read(CSR_MSTATUS);
|
val = csr_read(CSR_MSTATUS);
|
||||||
val = INSERT_FIELD(val, MSTATUS_MPP, next_mode);
|
val = INSERT_FIELD(val, MSTATUS_MPP, next_mode);
|
||||||
val = INSERT_FIELD(val, MSTATUS_MPIE, 0);
|
val = INSERT_FIELD(val, MSTATUS_MPIE, 0);
|
||||||
|
#if __riscv_xlen == 32
|
||||||
|
if (misa_extension('H')) {
|
||||||
|
valH = csr_read(CSR_MSTATUSH);
|
||||||
|
valH = INSERT_FIELD(valH, MSTATUSH_MTL, 0);
|
||||||
|
if (next_virt)
|
||||||
|
valH = INSERT_FIELD(valH, MSTATUSH_MPV, 1);
|
||||||
|
else
|
||||||
|
valH = INSERT_FIELD(valH, MSTATUSH_MPV, 0);
|
||||||
|
csr_write(CSR_MSTATUSH, valH);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (misa_extension('H')) {
|
||||||
|
val = INSERT_FIELD(val, MSTATUS_MTL, 0);
|
||||||
|
if (next_virt)
|
||||||
|
val = INSERT_FIELD(val, MSTATUS_MPV, 1);
|
||||||
|
else
|
||||||
|
val = INSERT_FIELD(val, MSTATUS_MPV, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
csr_write(CSR_MSTATUS, val);
|
csr_write(CSR_MSTATUS, val);
|
||||||
csr_write(CSR_MEPC, next_addr);
|
csr_write(CSR_MEPC, next_addr);
|
||||||
|
|
||||||
|
@@ -102,7 +102,7 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
|
|||||||
sbi_hart_wake_coldboot_harts(scratch, hartid);
|
sbi_hart_wake_coldboot_harts(scratch, hartid);
|
||||||
sbi_hart_mark_available(hartid);
|
sbi_hart_mark_available(hartid);
|
||||||
sbi_hart_switch_mode(hartid, scratch->next_arg1, scratch->next_addr,
|
sbi_hart_switch_mode(hartid, scratch->next_arg1, scratch->next_addr,
|
||||||
scratch->next_mode);
|
scratch->next_mode, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __noreturn init_warmboot(struct sbi_scratch *scratch, u32 hartid)
|
static void __noreturn init_warmboot(struct sbi_scratch *scratch, u32 hartid)
|
||||||
@@ -147,7 +147,8 @@ static void __noreturn init_warmboot(struct sbi_scratch *scratch, u32 hartid)
|
|||||||
sbi_hart_hang();
|
sbi_hart_hang();
|
||||||
else
|
else
|
||||||
sbi_hart_switch_mode(hartid, scratch->next_arg1,
|
sbi_hart_switch_mode(hartid, scratch->next_arg1,
|
||||||
scratch->next_addr, scratch->next_mode);
|
scratch->next_addr,
|
||||||
|
scratch->next_mode, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static atomic_t coldboot_lottery = ATOMIC_INITIALIZER(0);
|
static atomic_t coldboot_lottery = ATOMIC_INITIALIZER(0);
|
||||||
|
Reference in New Issue
Block a user