diff options
-rw-r--r-- | pk/encoding.h | 78 | ||||
-rw-r--r-- | pk/mcall.h | 1 | ||||
-rw-r--r-- | pk/mentry.S | 34 | ||||
-rw-r--r-- | pk/minit.c | 6 | ||||
-rw-r--r-- | pk/mtrap.c | 15 | ||||
-rw-r--r-- | pk/sbi.S | 1 | ||||
-rw-r--r-- | pk/sbi.h | 1 | ||||
-rw-r--r-- | pk/sbi_entry.S | 6 |
8 files changed, 100 insertions, 42 deletions
diff --git a/pk/encoding.h b/pk/encoding.h index 1fcfaea..f9f4bfb 100644 --- a/pk/encoding.h +++ b/pk/encoding.h @@ -221,47 +221,63 @@ #define MASK_BLTU 0x707f #define MATCH_BNE 0x1063 #define MASK_BNE 0x707f -#define MATCH_C_ADD 0x6000 +#define MATCH_C_ADD 0x1000 #define MASK_C_ADD 0xf003 -#define MATCH_C_ADDI 0x8000 +#define MATCH_C_ADD3 0xa000 +#define MASK_C_ADD3 0xe063 +#define MATCH_C_ADDI 0xc002 #define MASK_C_ADDI 0xe003 -#define MATCH_C_ADDI4 0xa000 -#define MASK_C_ADDI4 0xe003 -#define MATCH_C_ADDIW 0xe000 +#define MATCH_C_ADDI4SPN 0xa001 +#define MASK_C_ADDI4SPN 0xe003 +#define MATCH_C_ADDIW 0xe002 #define MASK_C_ADDIW 0xe003 -#define MATCH_C_ADDW 0x7000 +#define MATCH_C_ADDW 0x9000 #define MASK_C_ADDW 0xf003 -#define MATCH_C_BEQZ 0x2002 +#define MATCH_C_AND3 0xa060 +#define MASK_C_AND3 0xe063 +#define MATCH_C_BEQZ 0x4002 #define MASK_C_BEQZ 0xe003 #define MATCH_C_BNEZ 0x6002 #define MASK_C_BNEZ 0xe003 -#define MATCH_C_J 0xa002 +#define MATCH_C_J 0x2 #define MASK_C_J 0xe003 -#define MATCH_C_JALR 0x5000 -#define MASK_C_JALR 0xf003 -#define MATCH_C_LD 0x2001 +#define MATCH_C_JAL 0x2002 +#define MASK_C_JAL 0xe003 +#define MATCH_C_LD 0xe000 #define MASK_C_LD 0xe003 -#define MATCH_C_LDSP 0xc001 +#define MATCH_C_LDSP 0xe001 #define MASK_C_LDSP 0xe003 -#define MATCH_C_LI 0x0 +#define MATCH_C_LI 0x8002 #define MASK_C_LI 0xe003 -#define MATCH_C_LUI 0x2000 +#define MATCH_C_LUI 0xa002 #define MASK_C_LUI 0xe003 -#define MATCH_C_LW 0x1 +#define MATCH_C_LW 0xc000 #define MASK_C_LW 0xe003 -#define MATCH_C_LWSP 0x8001 +#define MATCH_C_LWSP 0xc001 #define MASK_C_LWSP 0xe003 -#define MATCH_C_MV 0x4000 +#define MATCH_C_MV 0x0 #define MASK_C_MV 0xf003 -#define MATCH_C_SD 0x6001 +#define MATCH_C_OR3 0xa040 +#define MASK_C_OR3 0xe063 +#define MATCH_C_SD 0x6000 #define MASK_C_SD 0xe003 -#define MATCH_C_SDSP 0xe001 +#define MATCH_C_SDSP 0x6001 #define MASK_C_SDSP 0xe003 -#define MATCH_C_SLLI 0xc000 +#define MATCH_C_SLLI 0x1 #define MASK_C_SLLI 0xe003 -#define MATCH_C_SW 0x4001 +#define MATCH_C_SLLIW 0x8001 +#define MASK_C_SLLIW 0xe003 +#define MATCH_C_SRAI 0x2000 +#define MASK_C_SRAI 0xe003 +#define MATCH_C_SRLI 0x2001 +#define MASK_C_SRLI 0xe003 +#define MATCH_C_SUB 0x8000 +#define MASK_C_SUB 0xf003 +#define MATCH_C_SUB3 0xa020 +#define MASK_C_SUB3 0xe063 +#define MATCH_C_SW 0x4000 #define MASK_C_SW 0xe003 -#define MATCH_C_SWSP 0xa001 +#define MATCH_C_SWSP 0x4001 #define MASK_C_SWSP 0xe003 #define MATCH_CSRRC 0x3073 #define MASK_CSRRC 0x707f @@ -551,7 +567,6 @@ #define CSR_SSTATUS 0x100 #define CSR_STVEC 0x101 #define CSR_SIE 0x104 -#define CSR_STIMECMP 0x121 #define CSR_SSCRATCH 0x140 #define CSR_SEPC 0x141 #define CSR_SIP 0x144 @@ -590,6 +605,7 @@ #define CSR_INSTRETHW 0x982 #define CSR_STIMEH 0xd81 #define CSR_STIMEHW 0xa81 +#define CSR_MTIMECMPH 0x361 #define CSR_MTIMEH 0x741 #define CAUSE_MISALIGNED_FETCH 0x0 #define CAUSE_FAULT_FETCH 0x1 @@ -637,14 +653,16 @@ DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) +DECLARE_INSN(c_add3, MATCH_C_ADD3, MASK_C_ADD3) DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) -DECLARE_INSN(c_addi4, MATCH_C_ADDI4, MASK_C_ADDI4) +DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) +DECLARE_INSN(c_and3, MATCH_C_AND3, MASK_C_AND3) DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) -DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) +DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) @@ -652,9 +670,15 @@ DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) +DECLARE_INSN(c_or3, MATCH_C_OR3, MASK_C_OR3) DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) +DECLARE_INSN(c_slliw, MATCH_C_SLLIW, MASK_C_SLLIW) +DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) +DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) +DECLARE_INSN(c_sub3, MATCH_C_SUB3, MASK_C_SUB3) DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) @@ -816,7 +840,6 @@ DECLARE_CSR(uarch15, CSR_UARCH15) DECLARE_CSR(sstatus, CSR_SSTATUS) DECLARE_CSR(stvec, CSR_STVEC) DECLARE_CSR(sie, CSR_SIE) -DECLARE_CSR(stimecmp, CSR_STIMECMP) DECLARE_CSR(sscratch, CSR_SSCRATCH) DECLARE_CSR(sepc, CSR_SEPC) DECLARE_CSR(sip, CSR_SIP) @@ -855,6 +878,7 @@ DECLARE_CSR(timehw, CSR_TIMEHW) DECLARE_CSR(instrethw, CSR_INSTRETHW) DECLARE_CSR(stimeh, CSR_STIMEH) DECLARE_CSR(stimehw, CSR_STIMEHW) +DECLARE_CSR(mtimecmph, CSR_MTIMECMPH) DECLARE_CSR(mtimeh, CSR_MTIMEH) #endif #ifdef DECLARE_CAUSE @@ -884,7 +908,6 @@ DECLARE_CAUSE("uarch15", CAUSE_UARCH15) DECLARE_CAUSE("sstatus", CAUSE_SSTATUS) DECLARE_CAUSE("stvec", CAUSE_STVEC) DECLARE_CAUSE("sie", CAUSE_SIE) -DECLARE_CAUSE("stimecmp", CAUSE_STIMECMP) DECLARE_CAUSE("sscratch", CAUSE_SSCRATCH) DECLARE_CAUSE("sepc", CAUSE_SEPC) DECLARE_CAUSE("sip", CAUSE_SIP) @@ -923,5 +946,6 @@ DECLARE_CAUSE("timehw", CAUSE_TIMEHW) DECLARE_CAUSE("instrethw", CAUSE_INSTRETHW) DECLARE_CAUSE("stimeh", CAUSE_STIMEH) DECLARE_CAUSE("stimehw", CAUSE_STIMEHW) +DECLARE_CAUSE("mtimecmph", CAUSE_MTIMECMPH) DECLARE_CAUSE("mtimeh", CAUSE_MTIMEH) #endif @@ -8,6 +8,7 @@ #define MCALL_SEND_IPI 4 #define MCALL_CLEAR_IPI 5 #define MCALL_SHUTDOWN 6 +#define MCALL_SET_TIMER 7 #ifndef __ASSEMBLER__ diff --git a/pk/mentry.S b/pk/mentry.S index e9e794b..0c1ee6a 100644 --- a/pk/mentry.S +++ b/pk/mentry.S @@ -162,23 +162,21 @@ mentry: .Linterrupt: sll a0, a0, 1 # discard MSB + # See if this is a timer interrupt; post a supervisor interrupt if so. li a1, IRQ_TIMER * 2 - # Send timer interrupts to the OS. - beq a0, a1, .Lmrts - - # See if this is an IPI; register a supervisor SW interrupt if so. -#if IRQ_SOFT != 0 -#error -#endif - bnez a0, 1f - csrr a0, mstatus - csrc mip, MIP_MSIP - csrs mip, MIP_SSIP - + bne a0, a1, 1f + li a0, MIP_MTIP + csrc mip, a0 + li a1, MIP_STIP + csrc mie, a0 + csrs mip, a1 + +.Linterrupt_supervisor: # There are three cases: PRV1=U; PRV1=S and IE1=1; and PRV1=S and IE1=0. # For cases 1-2, do an MRTS; for case 3, we can't, so ERET. - and a0, a0, MSTATUS_PRV1 | MSTATUS_IE1 + csrr a0, mstatus li a1, (MSTATUS_PRV1 & ~(MSTATUS_PRV1<<1)) * PRV_S + and a0, a0, MSTATUS_PRV1 | MSTATUS_IE1 bne a0, a1, .Lmrts # And then go back whence we came. @@ -186,6 +184,16 @@ mentry: LOAD a1, 11*REGBYTES(sp) csrrw sp, mscratch, sp eret + +1: + # See if this is an IPI; register a supervisor SW interrupt if so. +#if IRQ_SOFT != 0 +#error +#endif + bnez a0, 1f + csrc mip, MIP_MSIP + csrs mip, MIP_SSIP + j .Linterrupt_supervisor 1: # See if this is an HTIF interrupt; if so, handle it in machine mode. @@ -79,8 +79,10 @@ static void init_other_hart() write_csr(sptbr, root_page_table); // then make sure we're in bounds - if (HLS()->hart_id >= num_harts) - panic("too many harts"); + if (HLS()->hart_id >= num_harts) { + while (1) + wfi(); + } boot_other_hart(); } @@ -207,6 +207,18 @@ static uintptr_t mcall_shutdown() return 0; } +static uintptr_t mcall_set_timer(unsigned long long when) +{ + // bbl/pk don't use the timer, so there's no need to virtualize it + write_csr(mtimecmp, when); +#ifndef __riscv64 + write_csr(mtimecmph, when >> 32); +#endif + clear_csr(mip, MIP_STIP); + set_csr(mie, MIP_MTIP); + return 0; +} + uintptr_t mcall_trap(uintptr_t mcause, uintptr_t* regs) { uintptr_t n = regs[17], arg0 = regs[10], retval; @@ -233,6 +245,9 @@ uintptr_t mcall_trap(uintptr_t mcause, uintptr_t* regs) case MCALL_SHUTDOWN: retval = mcall_shutdown(); break; + case MCALL_SET_TIMER: + retval = mcall_set_timer(arg0); + break; default: retval = -ENOSYS; break; @@ -8,3 +8,4 @@ .globl sbi_clear_ipi; sbi_clear_ipi = -1936 .globl sbi_timebase; sbi_timebase = -1920 .globl sbi_shutdown; sbi_shutdown = -1904 +.globl sbi_set_timer; sbi_set_timer = -1888 @@ -12,6 +12,7 @@ unsigned long sbi_query_memory(unsigned long id, memory_block_info *p); unsigned long sbi_hart_id(void); unsigned long sbi_num_harts(void); unsigned long sbi_timebase(void); +void sbi_set_timer(unsigned long long stime_value); void sbi_send_ipi(unsigned long hart_id); unsigned long sbi_clear_ipi(void); void sbi_console_putchar(unsigned long ch); diff --git a/pk/sbi_entry.S b/pk/sbi_entry.S index 3d5292f..4fbac8f 100644 --- a/pk/sbi_entry.S +++ b/pk/sbi_entry.S @@ -65,6 +65,12 @@ sbi_base: li a7, MCALL_SHUTDOWN ecall + # set_timer + .align 4 + li a7, MCALL_SET_TIMER + ecall + ret + # end of SBI trampolines .globl do_mcall |