correct HTIF reset behavior
authorAndrew Waterman <waterman@eecs.berkeley.edu>
Mon, 23 Jul 2012 04:01:18 +0000 (21:01 -0700)
committerAndrew Waterman <waterman@eecs.berkeley.edu>
Mon, 23 Jul 2012 04:01:18 +0000 (21:01 -0700)
cores' reset signals can be independently toggled

riscv/htif.cc
riscv/processor.cc
riscv/processor.h

index 0ba995a5497c3ce26ee22881dfd5b64cd21e7f65..1be8d87ecbcca36c16aaf52cd46c7478eb636b24 100644 (file)
@@ -129,17 +129,8 @@ int htif_t::wait_for_packet()
         assert(p.data_size == 1);
         if (pcr_reg == PCR_RESET)
         {
-          if (p.data[0] & 1)
-          {
-            sim->procs[pcr_coreid]->reset();
-            if (pcr_coreid == 0 && sim->procs[0]->running())
-              sim->stop();
-          }
-          else if (!sim->procs[pcr_coreid]->running())
-          {
-            reset = false;
-            sim->procs[pcr_coreid]->deliver_ipi();
-          }
+          reset = p.data[0] & 1;
+          sim->procs[pcr_coreid]->reset(reset);
         }
         else
         {
index bc235fe68881664c38d13d2ca021de6388e62489..c11657556f6e2b3539c3319500dde2ad4aff4978 100644 (file)
@@ -12,7 +12,7 @@
 processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id)
   : sim(*_sim), mmu(*_mmu), id(_id), utidx(0)
 {
-  reset();
+  reset(true);
 
   // create microthreads
   for (int i=0; i<MAX_UTS; i++)
@@ -23,7 +23,7 @@ processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id,
                          uint32_t _utidx)
   : sim(*_sim), mmu(*_mmu), id(_id)
 {
-  reset();
+  reset(true);
   set_pcr(PCR_SR, sr | SR_EF | SR_EV);
   utidx = _utidx;
 
@@ -36,23 +36,24 @@ processor_t::~processor_t()
 {
 }
 
-void processor_t::reset()
+void processor_t::reset(bool value)
 {
-  run = false;
+  if (run == !value)
+    return;
+  run = !value;
 
   // 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_pcr(PCR_SR, SR_S | SR_S64 | SR_ET | SR_IM);
-  evec = 0x2000;
+  // and virtual memory disabled.
+  set_pcr(PCR_SR, SR_S | SR_S64 | SR_IM);
+  pc = 0x2000;
 
   // the following state is undefined upon boot-up,
   // but we zero it for determinism
   XPR.reset();
   FPR.reset();
 
-  pc = 0;
+  evec = 0;
   epc = 0;
   badvaddr = 0;
   cause = 0;
@@ -165,12 +166,6 @@ void processor_t::step(size_t n, bool noisy)
     assert(cmd == vt_command_stop);
     break;
   }
-  catch(halt_t t)
-  {
-    // sleep until IPI
-    reset();
-    return;
-  }
 
   cycle += i;
 
@@ -203,8 +198,8 @@ void processor_t::take_trap(reg_t t, bool noisy)
 
 void processor_t::deliver_ipi()
 {
-  set_pcr(PCR_CLR_IPI, 1);
-  run = true;
+  if (run)
+    set_pcr(PCR_CLR_IPI, 1);
 }
 
 void processor_t::disasm(insn_t insn, reg_t pc)
index a00487fc9ffe858e930a8def9e4a3a71880e8786..927f06c74c85aaeaa55105a6ac1dda0142992276 100644 (file)
@@ -20,7 +20,7 @@ public:
   processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id);
   ~processor_t();
 
-  void reset();
+  void reset(bool value);
   void step(size_t n, bool noisy); // run for n cycles
   void deliver_ipi(); // register an interprocessor interrupt
   bool running() { return run; }
@@ -58,8 +58,7 @@ private:
   // # of bits in an XPR (32 or 64). (redundant with sr)
   int xprlen;
 
-  // is this processor running? (deliver_ipi() sets this)
-  bool run;
+  bool run; // !reset
 
   // functions
   void take_interrupt(); // take a trap if any interrupts are pending