From: Andrew Waterman Date: Wed, 9 May 2012 10:08:15 +0000 (-0700) Subject: per-core tohost/fromhost registers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=546ceaee914e8d87fbbfdb04f5923fe002a9b9c7;p=riscv-isa-sim.git per-core tohost/fromhost registers update your fesvr --- diff --git a/riscv/htif.cc b/riscv/htif.cc index 8a9cd30..0ba995a 100644 --- a/riscv/htif.cc +++ b/riscv/htif.cc @@ -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; } diff --git a/riscv/htif.h b/riscv/htif.h index 5d026f7..628c3a3 100644 --- a/riscv/htif.h +++ b/riscv/htif.h @@ -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 diff --git a/riscv/processor.cc b/riscv/processor.cc index 322bf32..bc235fe 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -3,6 +3,7 @@ #include "config.h" #include "sim.h" #include "disasm.h" +#include #include #include #include @@ -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; } diff --git a/riscv/processor.h b/riscv/processor.h index db26f7e..a00487f 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -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 diff --git a/riscv/sim.cc b/riscv/sim.cc index 0d0b555..27933b7 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -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); diff --git a/riscv/sim.h b/riscv/sim.h index 0d384c4..8109b50 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -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);