aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2015-07-05 16:52:05 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2015-07-05 16:52:05 -0700
commita6da37f21720d12f0295876ce426bc081a62a7d8 (patch)
treece3a531905b52858899a470eca3bfb43050de536
parent027ba300cbeaa425218fd472e1fcf45c785f645c (diff)
downloadpk-a6da37f21720d12f0295876ce426bc081a62a7d8.zip
pk-a6da37f21720d12f0295876ce426bc081a62a7d8.tar.gz
pk-a6da37f21720d12f0295876ce426bc081a62a7d8.tar.bz2
New M-mode timer and SBI call to use it
-rw-r--r--pk/encoding.h78
-rw-r--r--pk/mcall.h1
-rw-r--r--pk/mentry.S34
-rw-r--r--pk/minit.c6
-rw-r--r--pk/mtrap.c15
-rw-r--r--pk/sbi.S1
-rw-r--r--pk/sbi.h1
-rw-r--r--pk/sbi_entry.S6
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
diff --git a/pk/mcall.h b/pk/mcall.h
index bae7aa6..2c56023 100644
--- a/pk/mcall.h
+++ b/pk/mcall.h
@@ -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.
diff --git a/pk/minit.c b/pk/minit.c
index a040e2b..b8a0b48 100644
--- a/pk/minit.c
+++ b/pk/minit.c
@@ -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();
}
diff --git a/pk/mtrap.c b/pk/mtrap.c
index 77b562a..ab7134b 100644
--- a/pk/mtrap.c
+++ b/pk/mtrap.c
@@ -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;
diff --git a/pk/sbi.S b/pk/sbi.S
index 08d19e4..7c3bfcc 100644
--- a/pk/sbi.S
+++ b/pk/sbi.S
@@ -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
diff --git a/pk/sbi.h b/pk/sbi.h
index 7c25588..2d8daeb 100644
--- a/pk/sbi.h
+++ b/pk/sbi.h
@@ -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