per-core tohost/fromhost registers
authorAndrew Waterman <waterman@eecs.berkeley.edu>
Wed, 9 May 2012 10:08:15 +0000 (03:08 -0700)
committerAndrew Waterman <waterman@eecs.berkeley.edu>
Wed, 9 May 2012 10:08:15 +0000 (03:08 -0700)
update your fesvr

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

index 8a9cd306d9108ed0b00d9d9ae09ac63412f462d8..0ba995a5497c3ce26ee22881dfd5b64cd21e7f65 100644 (file)
@@ -54,16 +54,6 @@ void htif_t::wait_for_start()
     wait_for_packet();
 }
 
-void htif_t::wait_for_tohost_write()
-{
-  while(wait_for_packet() != APP_CMD_READ_CONTROL_REG);
-}
-
-void htif_t::wait_for_fromhost_write()
-{
-  while(wait_for_packet() != APP_CMD_WRITE_CONTROL_REG);
-}
-
 void htif_t::send_packet(packet* p)
 {
   size_t data_size = p->data_size*HTIF_DATA_ALIGN;
@@ -82,17 +72,6 @@ void htif_t::nack(uint8_t nack_seqno)
   send_packet(&p);
 }
 
-void htif_t::poll()
-{
-  struct pollfd pfd;
-  pfd.fd = fromhost_fd;
-  pfd.events = POLLIN;
-  pfd.revents = 0;
-
-  if (::poll(&pfd, 1, 0) > 0)
-    wait_for_packet();
-}
-
 int htif_t::wait_for_packet()
 {
   while(1)
@@ -113,6 +92,8 @@ int htif_t::wait_for_packet()
     }
 
     packet ackpacket = {APP_CMD_ACK,0,seqno,0};
+    reg_t pcr_coreid = p.addr >> 20;
+    reg_t pcr_reg = p.addr & ((1<<20)-1);
 
     switch(p.cmd)
     {
@@ -135,23 +116,36 @@ 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 == PCR_TOHOST);
+      {
+        assert(pcr_coreid < sim->num_cores());
         assert(p.data_size == 1);
         ackpacket.data_size = 1;
-        memcpy(ackpacket.data, &sim->tohost, sizeof(reg_t));
+        reg_t pcr = sim->procs[pcr_coreid]->get_pcr(pcr_reg);
+        memcpy(ackpacket.data, &pcr, sizeof(pcr));
         break;
+      }
       case APP_CMD_WRITE_CONTROL_REG:
-        assert(p.addr == PCR_FROMHOST || p.addr == PCR_RESET);
+        assert(pcr_coreid < sim->num_cores());
         assert(p.data_size == 1);
-        sim->tohost = 0;
-        if (p.addr == PCR_FROMHOST)
-          memcpy(&sim->fromhost, p.data, sizeof(reg_t));
-        else if (p.addr == PCR_RESET)
+        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();
+          }
+        }
+        else
         {
-          bool next_reset = p.data[0] & 1;
-          if (!reset && next_reset)
-            sim->stop();
-          reset = next_reset;
+          reg_t pcr;
+          memcpy(&pcr, p.data, sizeof(pcr));
+          sim->procs[pcr_coreid]->set_pcr(pcr_reg, pcr);
         }
         break;
     }
index 5d026f7ea16a75c33c78616c1017a2ad658767ed..628c3a30d566d52e612aa3832d6d2f199ead2295 100644 (file)
@@ -14,16 +14,8 @@ public:
   ~htif_t();
   void init(sim_t* _sim);
 
-  // wait for host to send start command
   void wait_for_start();
-
-  // we block on the host if the target machine reads the fromhost register,
-  // which provides determinism in tohost/fromhost communication.
-  void wait_for_tohost_write();
-  void wait_for_fromhost_write();
-
-  // check to see if there's a pending packet and process it if so
-  void poll();
+  int wait_for_packet();
 
 private:
   sim_t* sim;
@@ -34,7 +26,6 @@ private:
 
   void nack(uint8_t seqno);
   void send_packet(packet* p);
-  int wait_for_packet();
 };
 
 #endif
index 322bf325ad2613cae190a63c8e1793f21df1393a..bc235fe68881664c38d13d2ca021de6388e62489 100644 (file)
@@ -3,6 +3,7 @@
 #include "config.h"
 #include "sim.h"
 #include "disasm.h"
+#include <inttypes.h>
 #include <cmath>
 #include <cstdlib>
 #include <iostream>
@@ -183,8 +184,14 @@ void processor_t::step(size_t n, 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(trap_t(t)), (unsigned long long)pc);
+  {
+    if ((sreg_t)t < 0)
+      printf("core %3d: interrupt %lld, pc 0x%016llx\n",
+             id, (long long)(t << 1 >> 1), (unsigned long long)pc);
+    else
+      printf("core %3d: trap %s, pc 0x%016llx\n",
+             id, trap_name(trap_t(t)), (unsigned long long)pc);
+  }
 
   // switch to supervisor, set previous supervisor bit, disable traps
   set_pcr(PCR_SR, (((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
@@ -196,7 +203,7 @@ void processor_t::take_trap(reg_t t, bool noisy)
 
 void processor_t::deliver_ipi()
 {
-  interrupts_pending |= 1 << IRQ_IPI;
+  set_pcr(PCR_CLR_IPI, 1);
   run = true;
 }
 
@@ -253,7 +260,10 @@ void processor_t::set_pcr(int which, reg_t val)
       sim.send_ipi(val);
       break;
     case PCR_CLR_IPI:
-      interrupts_pending &= ~(1 << IRQ_IPI);
+      if (val & 1)
+        interrupts_pending |= (1 << IRQ_IPI);
+      else
+        interrupts_pending &= ~(1 << IRQ_IPI);
       break;
     case PCR_K0:
       pcr_k0 = val;
@@ -266,7 +276,12 @@ void processor_t::set_pcr(int which, reg_t val)
       vecbanks_count = __builtin_popcountll(vecbanks);
       break;
     case PCR_TOHOST:
-      sim.set_tohost(val);
+      fromhost = 0;
+      tohost = val;
+      break;
+    case PCR_FROMHOST:
+      fromhost = val;
+      tohost = 0;
       break;
   }
 }
@@ -302,9 +317,9 @@ reg_t processor_t::get_pcr(int which)
     case PCR_VECBANK:
       return vecbanks;
     case PCR_TOHOST:
-      return sim.get_tohost();
+      return tohost;
     case PCR_FROMHOST:
-      return sim.get_fromhost();
+      return fromhost;
   }
   return -1;
 }
index db26f7ea8f3c634fca2c04a8fc1afce071334d9b..a00487fc9ffe858e930a8def9e4a3a71880e8786 100644 (file)
@@ -20,8 +20,12 @@ public:
   processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id);
   ~processor_t();
 
+  void reset();
   void step(size_t n, bool noisy); // run for n cycles
   void deliver_ipi(); // register an interprocessor interrupt
+  bool running() { return run; }
+  void set_pcr(int which, reg_t val);
+  reg_t get_pcr(int which);
 
 private:
   sim_t& sim;
@@ -42,6 +46,8 @@ private:
   reg_t pcr_k0;
   reg_t pcr_k1;
   reg_t cause;
+  reg_t tohost;
+  reg_t fromhost;
   uint32_t interrupts_pending;
   uint32_t id;
   uint32_t sr; // only modify the status register using set_pcr()
@@ -56,10 +62,7 @@ private:
   bool run;
 
   // 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_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(reg_t t, bool noisy); // take an exception
   void disasm(insn_t insn, reg_t pc); // disassemble and print an instruction
index 0d0b55552678051be19c64092cd7d5aaf9e986f1..27933b7f4aca39e81eae5df2e7629bbab7d979c8 100644 (file)
@@ -56,24 +56,6 @@ sim_t::~sim_t()
   munmap(mem, memsz);
 }
 
-void sim_t::set_tohost(reg_t val)
-{
-  fromhost = 0;
-  tohost = 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();
-  return fromhost;
-}
-
 void sim_t::send_ipi(reg_t who)
 {
   if(who < num_cores())
@@ -82,32 +64,25 @@ void sim_t::send_ipi(reg_t who)
 
 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);
+  //htif->wait_for_start();
 
   for(running = true; running; )
   {
-    for (int i = 0; i < 1000; i++)
-    {
-      if(!debug)
-        step_all(100,100,false);
-      else
-        interactive();
-    }
-
-    htif->poll();
+    if(!debug)
+      step_all(10000, 100, false);
+    else
+      interactive();
   }
 }
 
 void sim_t::step_all(size_t n, size_t interleave, bool noisy)
 {
+  htif->wait_for_packet();
   for(size_t j = 0; j < n; j+=interleave)
     for(int i = 0; i < (int)num_cores(); i++)
       procs[i]->step(interleave,noisy);
index 0d384c46ae8c669b5faabb29719ac0c134037fa1..8109b5001f11b4b1747c535b6ea1a101baf9fd41 100644 (file)
@@ -18,11 +18,6 @@ public:
   // run the simulation to completion
   void run(bool debug);
 
-  // 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
   void send_ipi(reg_t who);