Changed supervisor mode
authorAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Fri, 11 Nov 2011 08:02:01 +0000 (00:02 -0800)
committerAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Fri, 11 Nov 2011 08:02:01 +0000 (00:02 -0800)
- initial PC is 0x2000
- PCRs renumbered
- clearing IPIs now requires a write to a different PCR
- IRQs are each given their own cause #

riscv/decode.h
riscv/insns/mfpcr.h
riscv/insns/mtpcr.h
riscv/processor.cc
riscv/processor.h
riscv/sim.cc
riscv/trap.h

index f78c8f40081cb1bd5692032b7d36856157f7c1fe..9c364f67088d07829aa5eab523d10b11233ede7e 100644 (file)
@@ -48,11 +48,6 @@ const int JUMP_ALIGN_BITS = 1;
 #define IPI_IRQ 5
 #define TIMER_IRQ 7
 
-#define CAUSE_EXCCODE 0x000000FF
-#define CAUSE_IP      0x0000FF00
-#define CAUSE_EXCCODE_SHIFT 0
-#define CAUSE_IP_SHIFT      8
-
 #define FP_RD_NE  0
 #define FP_RD_0   1
 #define FP_RD_DN  2
index 7de089ea90037ced377a4af8e88dfa1b65e5ea1e..c6866699c701addd80cf9462091eb5c941ebdde6 100644 (file)
@@ -26,15 +26,6 @@ switch(insn.rtype.rs2)
     val = cause;
     break;
   case 7:
-    val = 0;
-    cause &= ~(1 << (IPI_IRQ+CAUSE_IP_SHIFT));
-    break;
-
-  case 8:
-    val = mmu.memsz >> PGSHIFT;
-    break;
-
-  case 9:
     val = mmu.get_ptbr();
     break;
 
@@ -42,23 +33,19 @@ switch(insn.rtype.rs2)
     val = id;
     break;
 
-  case 11:
-    val = vecbanks;
-    break;
-
   case 12:
-    val = sim.num_cores();
+    val = pcr_k0;
+    break;
+  case 13:
+    val = pcr_k1;
     break;
 
   case 17:
     val = sim.get_fromhost();
     break;
 
-  case 24:
-    val = pcr_k0;
-    break;
-  case 25:
-    val = pcr_k1;
+  case 18:
+    val = vecbanks;
     break;
 
   default:
index 59f864fd20895558a8b7ce0572137c94cfc4b8f3..f06fcf30ebcf117b561a0da5c1d57c06f9f474eb 100644 (file)
@@ -15,31 +15,33 @@ switch(insn.rtype.rs2)
     count = RS1;
     break;
   case 5:
-    cause &= ~(1 << (TIMER_IRQ+CAUSE_IP_SHIFT));
+    interrupts_pending &= ~(1 << TIMER_IRQ);
     compare = RS1;
     break;
-
   case 7:
-    sim.send_ipi(RS1);
+    mmu.set_ptbr(RS1);
     break;
 
+  case 8:
+    sim.send_ipi(RS1);
+    break;
   case 9:
-    mmu.set_ptbr(RS1);
+    interrupts_pending &= ~(1 << IPI_IRQ);
     break;
 
-  case 11:
-    vecbanks = RS1 & 0xff;
-    vecbanks_count = __builtin_popcountll(vecbanks);
+  case 12:
+    pcr_k0 = RS1;
+    break;
+  case 13:
+    pcr_k1 = RS1;
     break;
 
   case 16:
     sim.set_tohost(RS1);
     break;
 
-  case 24:
-    pcr_k0 = RS1;
-    break;
-  case 25:
-    pcr_k1 = RS1;
+  case 18:
+    vecbanks = RS1 & 0xff;
+    vecbanks_count = __builtin_popcountll(vecbanks);
     break;
 }
index 2a53cca579ecfa6654dabc5a8e2d91069f50272a..cce526bc74407d0abafa975be1251ba5fe8dfe26 100644 (file)
@@ -39,16 +39,19 @@ void processor_t::reset()
 {
   run = false;
 
-  // the ISA guarantees the following initial state
-  set_sr(SR_S | SR_SX);
-  pc = 0;
+  // the ISA guarantees on boot that the PC is 0x2000 and the the processor
+  // 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);
+  evec = 0x2000;
 
   // the following state is undefined upon boot-up,
   // but we zero it for determinism
   memset(XPR,0,sizeof(XPR));
   memset(FPR,0,sizeof(FPR));
 
-  evec = 0;
+  pc = 0;
   epc = 0;
   badvaddr = 0;
   cause = 0;
@@ -118,11 +121,13 @@ void processor_t::setvl(int vlapp)
 
 void processor_t::take_interrupt()
 {
-  uint32_t interrupts = (cause & CAUSE_IP) >> CAUSE_IP_SHIFT;
+  uint32_t interrupts = interrupts_pending;
   interrupts &= (sr & SR_IM) >> SR_IM_SHIFT;
 
   if(interrupts && (sr & SR_ET))
-    throw trap_interrupt;
+    for(int i = 0; ; i++, interrupts >>= 1)
+      if(interrupts & 1)
+        throw (trap_t)(trap_irq0 + i);
 }
 
 void processor_t::step(size_t n, bool noisy)
@@ -193,7 +198,7 @@ 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)
-    cause |= 1 << (TIMER_IRQ+CAUSE_IP_SHIFT);
+    interrupts_pending |= 1 << TIMER_IRQ;
 }
 
 void processor_t::take_trap(trap_t t, bool noisy)
@@ -204,7 +209,7 @@ void processor_t::take_trap(trap_t t, bool noisy)
 
   // switch to supervisor, set previous supervisor bit, disable traps
   set_sr((((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
-  cause = (cause & ~CAUSE_EXCCODE) | (t << CAUSE_EXCCODE_SHIFT);
+  cause = t;
   epc = pc;
   pc = evec;
   badvaddr = mmu.get_badvaddr();
@@ -212,7 +217,7 @@ void processor_t::take_trap(trap_t t, bool noisy)
 
 void processor_t::deliver_ipi()
 {
-  cause |= 1 << (IPI_IRQ+CAUSE_IP_SHIFT);
+  interrupts_pending |= 1 << IPI_IRQ;
   run = true;
 }
 
index 3bc1177933b0fbae7432fbaad3228ec24c4a964e..a6751410be8e12c10d1ba973b23d71131f407e3e 100644 (file)
@@ -30,7 +30,6 @@ private:
   reg_t XPR[NXPR];
   freg_t FPR[NFPR];
   reg_t pc;
-  uint32_t fsr;
 
   // counters
   reg_t cycle;
@@ -38,12 +37,14 @@ private:
   // privileged control registers
   reg_t epc;
   reg_t badvaddr;
-  reg_t cause;
   reg_t evec;
   reg_t pcr_k0;
   reg_t pcr_k1;
+  uint32_t cause;
+  uint32_t interrupts_pending;
   uint32_t id;
   uint32_t sr; // only modify the status register using set_sr()
+  uint32_t fsr;
   uint32_t count;
   uint32_t compare;
 
index 9020da4554082c147fecc9f9daf3bdf12ff9ffb9..f1c1b3b790f2ef76e7feb47da7ead3653d74089b 100644 (file)
@@ -77,6 +77,11 @@ void sim_t::run(bool debug)
 {
   htif->wait_for_start();
 
+  // word 0 of memory contains the memory capacity in MB
+  mmu->store_uint32(0, memsz >> 20);
+  // word 1 of memory contains the core count
+  mmu->store_uint32(4, num_cores());
+
   // start core 0
   send_ipi(0);
 
index ad5491a29b3e0e4f77de3a0cf571a345c79d522a..8e43c2ccb0b11101494a2f404867dd84c727589f 100644 (file)
@@ -7,7 +7,7 @@
   DECLARE_TRAP(illegal_instruction), \
   DECLARE_TRAP(privileged_instruction), \
   DECLARE_TRAP(fp_disabled), \
-  DECLARE_TRAP(interrupt), \
+  DECLARE_TRAP(reserved0), \
   DECLARE_TRAP(syscall), \
   DECLARE_TRAP(breakpoint), \
   DECLARE_TRAP(load_address_misaligned), \
   DECLARE_TRAP(vector_bank), \
   DECLARE_TRAP(vector_illegal_instruction), \
   DECLARE_TRAP(reserved1), \
-  DECLARE_TRAP(reserved2), \
-  DECLARE_TRAP(reserved3), \
-  DECLARE_TRAP(int0), \
-  DECLARE_TRAP(int1), \
-  DECLARE_TRAP(int2), \
-  DECLARE_TRAP(int3), \
-  DECLARE_TRAP(int4), \
-  DECLARE_TRAP(int5), \
-  DECLARE_TRAP(int6), \
-  DECLARE_TRAP(int7), \
+  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