new supervisor mode
authorAndrew Waterman <waterman@eecs.berkeley.edu>
Sat, 24 Mar 2012 19:54:03 +0000 (12:54 -0700)
committerAndrew Waterman <waterman@eecs.berkeley.edu>
Sat, 24 Mar 2012 19:54:03 +0000 (12:54 -0700)
18 files changed:
riscv/decode.h
riscv/disasm.cc
riscv/htif.cc
riscv/insns/clearpcr.h [new file with mode: 0644]
riscv/insns/di.h [deleted file]
riscv/insns/ei.h [deleted file]
riscv/insns/eret.h
riscv/insns/mfpcr.h
riscv/insns/mtpcr.h
riscv/insns/setpcr.h [new file with mode: 0644]
riscv/mmu.cc
riscv/opcodes.h
riscv/pcr.h [new file with mode: 0644]
riscv/processor.cc
riscv/processor.h
riscv/sim.cc
riscv/sim.h
riscv/trap.h

index d7e91f29cabb62b61540e04253da3b4916bfff51..3256f1b470a35bebd7cf403e1a0152edfa2ab6c1 100644 (file)
@@ -3,6 +3,7 @@
 
 #define __STDC_LIMIT_MACROS
 #include <stdint.h>
+#include "pcr.h"
 
 typedef int int128_t __attribute__((mode(TI)));
 typedef unsigned int uint128_t __attribute__((mode(TI)));
@@ -31,21 +32,6 @@ const int BIGIMM_BITS = 20;
 const int BRANCH_ALIGN_BITS = 1;
 const int JUMP_ALIGN_BITS = 1;
 
-#define SR_ET    0x0000000000000001ULL
-#define SR_EF    0x0000000000000002ULL
-#define SR_EV    0x0000000000000004ULL
-#define SR_EC    0x0000000000000008ULL
-#define SR_PS    0x0000000000000010ULL
-#define SR_S     0x0000000000000020ULL
-#define SR_UX    0x0000000000000040ULL
-#define SR_SX    0x0000000000000080ULL
-#define SR_IM    0x000000000000FF00ULL
-#define SR_VM    0x0000000000010000ULL
-#define SR_ZERO  ~(SR_ET|SR_EF|SR_EV|SR_EC|SR_PS|SR_S|SR_UX|SR_SX|SR_IM|SR_VM)
-#define SR_IM_SHIFT 8
-#define IPI_IRQ 5
-#define TIMER_IRQ 7
-
 #define FP_RD_NE  0
 #define FP_RD_0   1
 #define FP_RD_DN  2
index 3de97415a44e14ed4ebabd11fd3079828c0666e2..07c7bcc5be8128cdf0b8c390d80f53258ef5b991 100644 (file)
@@ -219,7 +219,7 @@ class pcr_reg_t : public arg_t
   virtual std::string to_string(insn_t insn) const
   {
     std::stringstream s;
-    s << "pcr" << insn.rtype.rs2;
+    s << "pcr" << insn.rtype.rs1;
     return s.str();
   }
 };
@@ -565,19 +565,19 @@ disassembler::disassembler()
   DEFINE_DTYPE(rdtime);
   DEFINE_DTYPE(rdinstret);
 
-  add_insn(new disasm_insn_t("mtpcr", match_mtpcr, mask_mtpcr, xrs1_reg, pcr_reg));
+  add_insn(new disasm_insn_t("mtpcr", match_mtpcr, mask_mtpcr | mask_rd, xrs2_reg, pcr_reg));
+  add_insn(new disasm_insn_t("mtpcr", match_mtpcr, mask_mtpcr, xrd_reg, xrs2_reg, pcr_reg));
   add_insn(new disasm_insn_t("mfpcr", match_mfpcr, mask_mfpcr, xrd_reg, pcr_reg));
-  DEFINE_NOARG(cflush)
+  add_insn(new disasm_insn_t("setpcr", match_setpcr, mask_setpcr, xrd_reg, pcr_reg, imm));
+  add_insn(new disasm_insn_t("clearpcr", match_clearpcr, mask_clearpcr, xrd_reg, pcr_reg, imm));
   DEFINE_NOARG(eret)
-  DEFINE_DTYPE(ei)
-  DEFINE_DTYPE(di)
+  DEFINE_NOARG(cflush)
 
   DEFINE_RS1(vxcptsave);
   DEFINE_RS1(vxcptrestore);
   DEFINE_NOARG(vxcptkill);
 
   DEFINE_RS1(vxcptevac);
-  DEFINE_NOARG(vxcptwait);
   DEFINE_NOARG(vxcpthold);
   DEFINE_RS1_RS2(venqcmd);
   DEFINE_RS1_RS2(venqimm1);
index 9aa9a7c22cf0bb1a5c60ba72c88410fa1ebbb1b8..8a9cd306d9108ed0b00d9d9ae09ac63412f462d8 100644 (file)
@@ -135,18 +135,18 @@ int htif_t::wait_for_packet()
           sim->mmu->store_uint64((p.addr+i)*HTIF_DATA_ALIGN, p.data[i]);
         break;
       case APP_CMD_READ_CONTROL_REG:
-        assert(p.addr == 16);
+        assert(p.addr == PCR_TOHOST);
         assert(p.data_size == 1);
         ackpacket.data_size = 1;
         memcpy(ackpacket.data, &sim->tohost, sizeof(reg_t));
         break;
       case APP_CMD_WRITE_CONTROL_REG:
-        assert(p.addr == 17 || p.addr == 15);
+        assert(p.addr == PCR_FROMHOST || p.addr == PCR_RESET);
         assert(p.data_size == 1);
         sim->tohost = 0;
-        if (p.addr == 17)
+        if (p.addr == PCR_FROMHOST)
           memcpy(&sim->fromhost, p.data, sizeof(reg_t));
-        else if (p.addr == 15)
+        else if (p.addr == PCR_RESET)
         {
           bool next_reset = p.data[0] & 1;
           if (!reset && next_reset)
diff --git a/riscv/insns/clearpcr.h b/riscv/insns/clearpcr.h
new file mode 100644 (file)
index 0000000..7acf221
--- /dev/null
@@ -0,0 +1,4 @@
+require_supervisor;
+reg_t temp = get_pcr(insn.rtype.rs1);
+set_pcr(insn.rtype.rs1, temp & ~SIMM);
+RD = temp;
diff --git a/riscv/insns/di.h b/riscv/insns/di.h
deleted file mode 100644 (file)
index 31280d5..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-require_supervisor;
-uint32_t temp = sr;
-set_sr(sr & ~SR_ET);
-RD = temp;
diff --git a/riscv/insns/ei.h b/riscv/insns/ei.h
deleted file mode 100644 (file)
index 8306aeb..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-require_supervisor;
-uint32_t temp = sr;
-set_sr(sr | SR_ET);
-RD = temp;
index 46d5bed27ef40a8f8af61607c67933ff30b73c46..cd968bdeb41c4b60d947880d8aedbb7066d5e2e0 100644 (file)
@@ -1,5 +1,5 @@
 require_supervisor;
 if(sr & SR_ET)
   throw trap_illegal_instruction;
-set_sr(((sr & SR_PS) ? sr : (sr & ~SR_S)) | SR_ET);
+set_pcr(PCR_SR, ((sr & SR_PS) ? sr : (sr & ~SR_S)) | SR_ET);
 set_pc(epc);
index c6866699c701addd80cf9462091eb5c941ebdde6..f7aea9f4201fd651436b68f9d1fd78855a93b859 100644 (file)
@@ -1,55 +1,2 @@
 require_supervisor;
-
-reg_t val;
-
-switch(insn.rtype.rs2)
-{
-  case 0:
-    val = sr;
-    break;
-  case 1:
-    val = epc;
-    break;
-  case 2:
-    val = badvaddr;
-    break;
-  case 3:
-    val = evec;
-    break;
-  case 4:
-    val = count;
-    break;
-  case 5:
-    val = compare;
-    break;
-  case 6:
-    val = cause;
-    break;
-  case 7:
-    val = mmu.get_ptbr();
-    break;
-
-  case 10:
-    val = id;
-    break;
-
-  case 12:
-    val = pcr_k0;
-    break;
-  case 13:
-    val = pcr_k1;
-    break;
-
-  case 17:
-    val = sim.get_fromhost();
-    break;
-
-  case 18:
-    val = vecbanks;
-    break;
-
-  default:
-    val = -1;
-}
-
-RD = sext_xprlen(val);
+RD = get_pcr(insn.rtype.rs1);
index f06fcf30ebcf117b561a0da5c1d57c06f9f474eb..5cd0134e0ba933c08df7daebe9b953354508b747 100644 (file)
@@ -1,47 +1,4 @@
 require_supervisor;
-
-switch(insn.rtype.rs2)
-{
-  case 0:
-    set_sr(RS1);
-    break;
-  case 1:
-    epc = RS1;
-    break;
-  case 3:
-    evec = RS1;
-    break;
-  case 4:
-    count = RS1;
-    break;
-  case 5:
-    interrupts_pending &= ~(1 << TIMER_IRQ);
-    compare = RS1;
-    break;
-  case 7:
-    mmu.set_ptbr(RS1);
-    break;
-
-  case 8:
-    sim.send_ipi(RS1);
-    break;
-  case 9:
-    interrupts_pending &= ~(1 << IPI_IRQ);
-    break;
-
-  case 12:
-    pcr_k0 = RS1;
-    break;
-  case 13:
-    pcr_k1 = RS1;
-    break;
-
-  case 16:
-    sim.set_tohost(RS1);
-    break;
-
-  case 18:
-    vecbanks = RS1 & 0xff;
-    vecbanks_count = __builtin_popcountll(vecbanks);
-    break;
-}
+reg_t val = get_pcr(insn.rtype.rs1);
+set_pcr(insn.rtype.rs1, RS2);
+RD = val;
diff --git a/riscv/insns/setpcr.h b/riscv/insns/setpcr.h
new file mode 100644 (file)
index 0000000..d645626
--- /dev/null
@@ -0,0 +1,4 @@
+require_supervisor;
+reg_t temp = get_pcr(insn.rtype.rs1);
+set_pcr(insn.rtype.rs1, temp | SIMM);
+RD = temp;
index 55273f328d7f5222ae9c417b24f603997baccf93..c8eec16a6f4156ce0c253f3b92d37e4a0f18354d 100644 (file)
@@ -63,7 +63,7 @@ pte_t mmu_t::walk(reg_t addr)
 
   // the address must be a canonical sign-extended VA_BITS-bit number
   int shift = 8*sizeof(reg_t) - VA_BITS;
-  if (((sreg_t)addr << shift >> shift) != addr)
+  if (((sreg_t)addr << shift >> shift) != (sreg_t)addr)
     ;
   else if(!vm_enabled)
   {
index feeca92e7616593d2e2a8f4eed12c045bc5cd725..52af654179248ce1a37c3f46d9d635b0d618b949 100644 (file)
@@ -23,7 +23,7 @@ DECLARE_INSN(fcvt_d_w, 0xe0d3, 0x3ff1ff)
 DECLARE_INSN(lw, 0x103, 0x3ff)
 DECLARE_INSN(add, 0x33, 0x1ffff)
 DECLARE_INSN(fcvt_d_s, 0x100d3, 0x3ff1ff)
-DECLARE_INSN(mfpcr, 0x17b, 0x7c1ffff)
+DECLARE_INSN(mfpcr, 0x17b, 0x3fffff)
 DECLARE_INSN(c_fsd, 0x18, 0x1f)
 DECLARE_INSN(fmax_d, 0x190d3, 0x1ffff)
 DECLARE_INSN(bne, 0xe3, 0x3ff)
@@ -33,10 +33,10 @@ DECLARE_INSN(vlh, 0x8b, 0x3fffff)
 DECLARE_INSN(bgeu, 0x3e3, 0x3ff)
 DECLARE_INSN(vflstd, 0x158b, 0x1ffff)
 DECLARE_INSN(c_li, 0x0, 0x1f)
-DECLARE_INSN(di, 0xfb, 0x7ffffff)
+DECLARE_INSN(fadd_d, 0xd3, 0x1f1ff)
 DECLARE_INSN(sltiu, 0x193, 0x3ff)
-DECLARE_INSN(mtpcr, 0x1fb, 0xf801ffff)
-DECLARE_INSN(vxcptwait, 0x180fb, 0xffffffff)
+DECLARE_INSN(mtpcr, 0x1fb, 0x1ffff)
+DECLARE_INSN(vlb, 0xb, 0x3fffff)
 DECLARE_INSN(stop, 0x177, 0xffffffff)
 DECLARE_INSN(vld, 0x18b, 0x3fffff)
 DECLARE_INSN(c_slli, 0x19, 0x1c1f)
@@ -46,7 +46,7 @@ DECLARE_INSN(fcvt_s_w, 0xe053, 0x3ff1ff)
 DECLARE_INSN(vflstw, 0x150b, 0x1ffff)
 DECLARE_INSN(mul, 0x433, 0x1ffff)
 DECLARE_INSN(c_lw, 0xa, 0x1f)
-DECLARE_INSN(vxcptevac, 0x1807b, 0xf83fffff)
+DECLARE_INSN(vxcptevac, 0x237b, 0xf83fffff)
 DECLARE_INSN(vlw, 0x10b, 0x3fffff)
 DECLARE_INSN(vssegstw, 0x90f, 0xfff)
 DECLARE_INSN(amominu_d, 0x19ab, 0x1ffff)
@@ -70,7 +70,6 @@ DECLARE_INSN(mftx_s, 0x1c053, 0x3fffff)
 DECLARE_INSN(vssegsth, 0x88f, 0xfff)
 DECLARE_INSN(vvcfgivl, 0xf3, 0x3ff)
 DECLARE_INSN(j, 0x67, 0x7f)
-DECLARE_INSN(ei, 0x7b, 0x7ffffff)
 DECLARE_INSN(fence, 0x12f, 0x3ff)
 DECLARE_INSN(vsw, 0x10f, 0x3fffff)
 DECLARE_INSN(fnmsub_s, 0x4b, 0x1ff)
@@ -86,7 +85,6 @@ DECLARE_INSN(vsetvl, 0x2f3, 0x3fffff)
 DECLARE_INSN(fle_d, 0x170d3, 0x1ffff)
 DECLARE_INSN(fence_i, 0xaf, 0x3ff)
 DECLARE_INSN(vlsegbu, 0x220b, 0x1ffff)
-DECLARE_INSN(vlsegstb, 0x80b, 0xfff)
 DECLARE_INSN(fnmsub_d, 0xcb, 0x1ff)
 DECLARE_INSN(addw, 0x3b, 0x1ffff)
 DECLARE_INSN(sll, 0xb3, 0x1ffff)
@@ -127,13 +125,14 @@ DECLARE_INSN(c_add3, 0x1c, 0x31f)
 DECLARE_INSN(sraiw, 0x1029b, 0x3f83ff)
 DECLARE_INSN(vssegd, 0x218f, 0x1ffff)
 DECLARE_INSN(srl, 0x2b3, 0x1ffff)
-DECLARE_INSN(venqcmd, 0x181fb, 0xf801ffff)
+DECLARE_INSN(venqcmd, 0x2b7b, 0xf801ffff)
 DECLARE_INSN(vfmts, 0x1973, 0x1ffff)
-DECLARE_INSN(venqimm1, 0x1827b, 0xf801ffff)
+DECLARE_INSN(venqimm1, 0x2f7b, 0xf801ffff)
 DECLARE_INSN(fsgnjx_s, 0x7053, 0x1ffff)
 DECLARE_INSN(vfmsv, 0x973, 0x3fffff)
-DECLARE_INSN(venqimm2, 0x182fb, 0xf801ffff)
+DECLARE_INSN(venqimm2, 0x337b, 0xf801ffff)
 DECLARE_INSN(fcvt_d_wu, 0xf0d3, 0x3ff1ff)
+DECLARE_INSN(vxcptrestore, 0x77b, 0xf83fffff)
 DECLARE_INSN(vmts, 0x1873, 0x1ffff)
 DECLARE_INSN(or, 0x333, 0x1ffff)
 DECLARE_INSN(rdinstret, 0xa77, 0x7ffffff)
@@ -156,7 +155,8 @@ DECLARE_INSN(vlstd, 0x118b, 0x1ffff)
 DECLARE_INSN(c_ld0, 0x8012, 0x801f)
 DECLARE_INSN(rdtime, 0x677, 0x7ffffff)
 DECLARE_INSN(andi, 0x393, 0x3ff)
-DECLARE_INSN(venqcnt, 0x1837b, 0xf801ffff)
+DECLARE_INSN(clearpcr, 0x7b, 0x3ff)
+DECLARE_INSN(venqcnt, 0x377b, 0xf801ffff)
 DECLARE_INSN(fsgnjn_d, 0x60d3, 0x1ffff)
 DECLARE_INSN(fnmadd_s, 0x4f, 0x1ff)
 DECLARE_INSN(jal, 0x6f, 0x7f)
@@ -216,8 +216,8 @@ DECLARE_INSN(vfmvv, 0x173, 0x3fffff)
 DECLARE_INSN(vlstwu, 0x130b, 0x1ffff)
 DECLARE_INSN(c_sub3, 0x11c, 0x31f)
 DECLARE_INSN(vsh, 0x8f, 0x3fffff)
-DECLARE_INSN(vlb, 0xb, 0x3fffff)
-DECLARE_INSN(vxcptsave, 0x1007b, 0xf83fffff)
+DECLARE_INSN(vlsegstb, 0x80b, 0xfff)
+DECLARE_INSN(vxcptsave, 0x37b, 0xf83fffff)
 DECLARE_INSN(vlsegstd, 0x98b, 0xfff)
 DECLARE_INSN(vflsegd, 0x258b, 0x1ffff)
 DECLARE_INSN(vflsegw, 0x250b, 0x1ffff)
@@ -229,10 +229,9 @@ DECLARE_INSN(mulhu, 0x5b3, 0x1ffff)
 DECLARE_INSN(fence_v_g, 0x2af, 0x3ff)
 DECLARE_INSN(vmsv, 0x873, 0x3fffff)
 DECLARE_INSN(vmst, 0x1073, 0x1ffff)
-DECLARE_INSN(fadd_d, 0xd3, 0x1f1ff)
-DECLARE_INSN(vxcptrestore, 0x100fb, 0xf83fffff)
+DECLARE_INSN(setpcr, 0xfb, 0x3ff)
 DECLARE_INSN(rdnpc, 0x26b, 0x7ffffff)
-DECLARE_INSN(vxcpthold, 0x1817b, 0xffffffff)
+DECLARE_INSN(vxcpthold, 0x277b, 0xffffffff)
 DECLARE_INSN(fcvt_s_l, 0xc053, 0x3ff1ff)
 DECLARE_INSN(vflsegstd, 0xd8b, 0xfff)
 DECLARE_INSN(c_add, 0x1a, 0x801f)
@@ -243,7 +242,7 @@ DECLARE_INSN(fmadd_s, 0x43, 0x1ff)
 DECLARE_INSN(fcvt_w_s, 0xa053, 0x3ff1ff)
 DECLARE_INSN(vssegh, 0x208f, 0x1ffff)
 DECLARE_INSN(fsqrt_s, 0x4053, 0x3ff1ff)
-DECLARE_INSN(vxcptkill, 0x1017b, 0xffffffff)
+DECLARE_INSN(vxcptkill, 0xb7b, 0xffffffff)
 DECLARE_INSN(c_srai, 0x1019, 0x1c1f)
 DECLARE_INSN(amomin_w, 0x112b, 0x1ffff)
 DECLARE_INSN(fsgnjn_s, 0x6053, 0x1ffff)
diff --git a/riscv/pcr.h b/riscv/pcr.h
new file mode 100644 (file)
index 0000000..7659a97
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef _RISCV_PCR_H
+#define _RISCV_PCR_H
+
+#define SR_ET    0x00000001
+#define SR_EF    0x00000002
+#define SR_EV    0x00000004
+#define SR_EC    0x00000008
+#define SR_PS    0x00000010
+#define SR_S     0x00000020
+#define SR_U64   0x00000040
+#define SR_S64   0x00000080
+#define SR_VM    0x00000100
+#define SR_IM    0x00FF0000
+#define SR_ZERO  ~(SR_ET|SR_EF|SR_EV|SR_EC|SR_PS|SR_S|SR_U64|SR_S64|SR_VM|SR_IM)
+#define SR_IM_SHIFT 16
+
+#define PCR_SR       0
+#define PCR_EPC      1
+#define PCR_BADVADDR 2
+#define PCR_EVEC     3
+#define PCR_COUNT    4
+#define PCR_COMPARE  5
+#define PCR_CAUSE    6
+#define PCR_PTBR     7
+#define PCR_SEND_IPI 8
+#define PCR_CLR_IPI  9
+#define PCR_COREID   10
+#define PCR_IMPL     11
+#define PCR_K0       12
+#define PCR_K1       13
+#define PCR_VECBANK  18
+#define PCR_VECCFG   19
+#define PCR_RESET    29
+#define PCR_TOHOST   30
+#define PCR_FROMHOST 31
+
+#define IRQ_IPI   5
+#define IRQ_TIMER 7
+
+#define CAUSE_MISALIGNED_FETCH 0
+#define CAUSE_FAULT_FETCH 1
+#define CAUSE_ILLEGAL_INSTRUCTION 2
+#define CAUSE_PRIVILEGED_INSTRUCTION 3
+#define CAUSE_FP_DISABLED 4
+#define CAUSE_SYSCALL 6
+#define CAUSE_BREAKPOINT 7
+#define CAUSE_MISALIGNED_LOAD 8
+#define CAUSE_MISALIGNED_STORE 9
+#define CAUSE_FAULT_LOAD 10
+#define CAUSE_FAULT_STORE 11
+#define CAUSE_VECTOR_DISABLED 12
+#define CAUSE_VECTOR_BANK 13
+
+#define CAUSE_VECTOR_MISALIGNED_FETCH 24
+#define CAUSE_VECTOR_FAULT_FETCH 25
+#define CAUSE_VECTOR_ILLEGAL_INSTRUCTION 26
+#define CAUSE_VECTOR_ILLEGAL_COMMAND 27
+#define CAUSE_VECTOR_MISALIGNED_LOAD 28
+#define CAUSE_VECTOR_MISALIGNED_STORE 29
+#define CAUSE_VECTOR_FAULT_LOAD 30
+#define CAUSE_VECTOR_FAULT_STORE 31
+
+#ifdef __riscv
+
+#define ASM_CR(r)   _ASM_CR(r)
+#define _ASM_CR(r)  cr##r
+
+#ifndef __ASSEMBLER__
+
+#define mtpcr(reg,val) ({ long __tmp = (long)(val), __tmp2; \
+          asm volatile ("mtpcr %0,%1,cr%2" : "=r"(__tmp2) : "r"(__tmp),"i"(reg)); \
+          __tmp2; })
+
+#define mfpcr(reg) ({ long __tmp; \
+          asm volatile ("mfpcr %0,cr%1" : "=r"(__tmp) : "i"(reg)); \
+          __tmp; })
+
+#define setpcr(reg,val) ({ long __tmp; \
+          asm volatile ("setpcr %0,cr%2,%1" : "=r"(__tmp) : "i"(val), "i"(reg)); \
+          __tmp; })
+
+#define clearpcr(reg,val) ({ long __tmp; \
+          asm volatile ("clearpcr %0,cr%2,%1" : "=r"(__tmp) : "i"(val), "i"(reg)); \
+          __tmp; })
+
+#endif
+
+#endif
+
+#endif
index 9785799f974f85efef64929e48ab5dc611d3a3d8..322bf325ad2613cae190a63c8e1793f21df1393a 100644 (file)
@@ -23,7 +23,7 @@ processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id,
   : sim(*_sim), mmu(*_mmu), id(_id)
 {
   reset();
-  set_sr(sr | SR_EF | SR_EV);
+  set_pcr(PCR_SR, sr | SR_EF | SR_EV);
   utidx = _utidx;
 
   // microthreads don't possess their own microthreads
@@ -43,7 +43,7 @@ void processor_t::reset()
   // is in supervisor mode, and in 64-bit mode, if supported, with traps
   // and virtual memory disabled.  we accomplish this by setting EVEC to
   // 0x2000 and *enabling* traps, then sending the core an IPI.
-  set_sr(SR_S | SR_SX | SR_ET | SR_IM);
+  set_pcr(PCR_SR, SR_S | SR_S64 | SR_ET | SR_IM);
   evec = 0x2000;
 
   // the following state is undefined upon boot-up,
@@ -73,32 +73,6 @@ void processor_t::reset()
   nfpr_use = 32;
 }
 
-void processor_t::set_sr(uint32_t val)
-{
-  sr = val & ~SR_ZERO; // clear SR bits that read as zero
-
-#ifndef RISCV_ENABLE_64BIT
-  sr &= ~(SR_SX | SR_UX); // SX=UX=0 for RV32 implementations
-#endif
-#ifndef RISCV_ENABLE_FPU
-  sr &= ~SR_EF;
-#endif
-#ifndef RISCV_ENABLE_RVC
-  sr &= ~SR_EC;
-#endif
-#ifndef RISCV_ENABLE_VEC
-  sr &= ~SR_EV;
-#endif
-
-  // update MMU state and flush TLB
-  mmu.set_vm_enabled(sr & SR_VM);
-  mmu.set_supervisor(sr & SR_S);
-  mmu.flush_tlb();
-
-  // set the fixed-point register length
-  xprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
-}
-
 void processor_t::set_fsr(uint32_t val)
 {
   fsr = val & ~FSR_ZERO; // clear FSR bits that read as zero
@@ -127,7 +101,7 @@ void processor_t::take_interrupt()
   if(interrupts && (sr & SR_ET))
     for(int i = 0; ; i++, interrupts >>= 1)
       if(interrupts & 1)
-        throw (trap_t)(trap_irq0 + i);
+        throw interrupt_t(i);
 }
 
 void processor_t::step(size_t n, bool noisy)
@@ -178,6 +152,11 @@ void processor_t::step(size_t n, bool noisy)
     i++;
     take_trap(t,noisy);
   }
+  catch(interrupt_t t)
+  {
+    i++;
+    take_trap((1ULL << (8*sizeof(reg_t)-1)) + t.i, noisy);
+  }
   catch(vt_command_t cmd)
   {
     // this microthread has finished
@@ -198,17 +177,17 @@ void processor_t::step(size_t n, bool noisy)
   uint32_t old_count = count;
   count += i;
   if(old_count < compare && uint64_t(old_count) + i >= compare)
-    interrupts_pending |= 1 << TIMER_IRQ;
+    interrupts_pending |= 1 << IRQ_TIMER;
 }
 
-void processor_t::take_trap(trap_t t, bool noisy)
+void processor_t::take_trap(reg_t t, bool noisy)
 {
   if(noisy)
     printf("core %3d: trap %s, pc 0x%016llx\n",
-           id, trap_name(t), (unsigned long long)pc);
+           id, trap_name(trap_t(t)), (unsigned long long)pc);
 
   // switch to supervisor, set previous supervisor bit, disable traps
-  set_sr((((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
+  set_pcr(PCR_SR, (((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
   cause = t;
   epc = pc;
   pc = evec;
@@ -217,7 +196,7 @@ void processor_t::take_trap(trap_t t, bool noisy)
 
 void processor_t::deliver_ipi()
 {
-  interrupts_pending |= 1 << IPI_IRQ;
+  interrupts_pending |= 1 << IRQ_IPI;
   run = true;
 }
 
@@ -228,3 +207,104 @@ void processor_t::disasm(insn_t insn, reg_t pc)
   printf("core %3d: 0x%016llx (0x%08x) %s\n", id, (unsigned long long)pc,
          insn.bits, disasm.disassemble(insn).c_str());
 }
+
+void processor_t::set_pcr(int which, reg_t val)
+{
+  switch (which)
+  {
+    case PCR_SR:
+      sr = val & ~SR_ZERO; // clear SR bits that read as zero
+#ifndef RISCV_ENABLE_64BIT
+      sr &= ~(SR_S64 | SR_U64);
+#endif
+#ifndef RISCV_ENABLE_FPU
+      sr &= ~SR_EF;
+#endif
+#ifndef RISCV_ENABLE_RVC
+      sr &= ~SR_EC;
+#endif
+#ifndef RISCV_ENABLE_VEC
+      sr &= ~SR_EV;
+#endif
+      // update MMU state and flush TLB
+      mmu.set_vm_enabled(sr & SR_VM);
+      mmu.set_supervisor(sr & SR_S);
+      mmu.flush_tlb();
+      // set the fixed-point register length
+      xprlen = ((sr & SR_S) ? (sr & SR_S64) : (sr & SR_U64)) ? 64 : 32;
+      break;
+    case PCR_EPC:
+      epc = val;
+      break;
+    case PCR_EVEC: 
+      evec = val;
+      break;
+    case PCR_COUNT:
+      count = val;
+      break;
+    case PCR_COMPARE:
+      interrupts_pending &= ~(1 << IRQ_TIMER);
+      compare = val;
+      break;
+    case PCR_PTBR:
+      mmu.set_ptbr(val);
+      break;
+    case PCR_SEND_IPI:
+      sim.send_ipi(val);
+      break;
+    case PCR_CLR_IPI:
+      interrupts_pending &= ~(1 << IRQ_IPI);
+      break;
+    case PCR_K0:
+      pcr_k0 = val;
+      break;
+    case PCR_K1:
+      pcr_k1 = val;
+      break;
+    case PCR_VECBANK:
+      vecbanks = val & 0xff;
+      vecbanks_count = __builtin_popcountll(vecbanks);
+      break;
+    case PCR_TOHOST:
+      sim.set_tohost(val);
+      break;
+  }
+}
+
+reg_t processor_t::get_pcr(int which)
+{
+  switch (which)
+  {
+    case PCR_SR:
+      return sr;
+    case PCR_EPC:
+      return epc;
+    case PCR_BADVADDR:
+      return badvaddr;
+    case PCR_EVEC:
+      return evec;
+    case PCR_COUNT:
+      return count;
+    case PCR_COMPARE:
+      return compare;
+    case PCR_CAUSE:
+      return cause;
+    case PCR_PTBR:
+      return mmu.get_ptbr();
+    case PCR_COREID:
+      return id;
+    case PCR_IMPL:
+      return 1;
+    case PCR_K0:
+      return pcr_k0;
+    case PCR_K1:
+      return pcr_k1;
+    case PCR_VECBANK:
+      return vecbanks;
+    case PCR_TOHOST:
+      return sim.get_tohost();
+    case PCR_FROMHOST:
+      return sim.get_fromhost();
+  }
+  return -1;
+}
index 09fac00277b6796023b359e868ddd5192c21b57c..db26f7ea8f3c634fca2c04a8fc1afce071334d9b 100644 (file)
@@ -41,10 +41,10 @@ private:
   reg_t evec;
   reg_t pcr_k0;
   reg_t pcr_k1;
-  uint32_t cause;
+  reg_t cause;
   uint32_t interrupts_pending;
   uint32_t id;
-  uint32_t sr; // only modify the status register using set_sr()
+  uint32_t sr; // only modify the status register using set_pcr()
   uint32_t fsr;
   uint32_t count;
   uint32_t compare;
@@ -58,9 +58,10 @@ private:
   // functions
   void reset(); // resets architected state; halts processor if it was running
   void take_interrupt(); // take a trap if any interrupts are pending
-  void set_sr(uint32_t val); // set the status register
+  void set_pcr(int which, reg_t val);
+  reg_t get_pcr(int which);
   void set_fsr(uint32_t val); // set the floating-point status register
-  void take_trap(trap_t t, bool noisy); // take an exception
+  void take_trap(reg_t t, bool noisy); // take an exception
   void disasm(insn_t insn, reg_t pc); // disassemble and print an instruction
 
   // vector stuff
index fb533a8898d7d3eb830699eef2c9342b1f2f5d2a..0d0b55552678051be19c64092cd7d5aaf9e986f1 100644 (file)
@@ -63,6 +63,11 @@ void sim_t::set_tohost(reg_t val)
   htif->wait_for_tohost_write();
 }
 
+reg_t sim_t::get_tohost()
+{
+  return tohost;
+}
+
 reg_t sim_t::get_fromhost()
 {
   htif->wait_for_fromhost_write();
index c4058d386bfea9a5f71ea51c393cd01c4b6d6c8b..0d384c46ae8c669b5faabb29719ac0c134037fa1 100644 (file)
@@ -20,6 +20,7 @@ public:
 
   // communicate with the host machine
   void set_tohost(reg_t val);
+  reg_t get_tohost();
   reg_t get_fromhost();
 
   // deliver an IPI to a specific processor
index 8e43c2ccb0b11101494a2f404867dd84c727589f..d09da3f703ad1b0566726ecf899694b07be12f75 100644 (file)
   DECLARE_TRAP(vector_bank), \
   DECLARE_TRAP(vector_illegal_instruction), \
   DECLARE_TRAP(reserved1), \
-  DECLARE_TRAP(irq0), \
-  DECLARE_TRAP(irq1), \
-  DECLARE_TRAP(irq2), \
-  DECLARE_TRAP(irq3), \
-  DECLARE_TRAP(irq4), \
-  DECLARE_TRAP(irq5), \
-  DECLARE_TRAP(irq6), \
-  DECLARE_TRAP(irq7), \
 
 #define DECLARE_TRAP(x) trap_##x
 enum trap_t
@@ -35,6 +27,7 @@ enum trap_t
 };
 #undef DECLARE_TRAP
 
+struct interrupt_t { interrupt_t(int which) : i(which) {} int i; };
 struct halt_t {}; // thrown to stop the processor from running
 
 extern "C" const char* trap_name(trap_t t);