#include "htif.h"
#include "sim.h"
+#include "mmu.h"
+#include "encoding.h"
#include <unistd.h>
#include <stdexcept>
#include <stdlib.h>
{
}
-void htif_isasim_t::tick()
+bool htif_isasim_t::tick()
{
+ if (done())
+ return false;
+
do tick_once(); while (reset);
+
+ return true;
}
void htif_isasim_t::tick_once()
send(&ack, sizeof(ack));
uint64_t buf[hdr.data_size];
- for (size_t i = 0; i < hdr.data_size; i++)
- buf[i] = sim->mmu->load_uint64((hdr.addr+i)*HTIF_DATA_ALIGN);
+ for (size_t i = 0; i < hdr.data_size; i++) {
+ reg_t addr = (hdr.addr + i) * HTIF_DATA_ALIGN;
+ try {
+ buf[i] = sim->debug_mmu->load_uint64(addr);
+ } catch (trap_load_access_fault& e) {
+ fprintf(stderr, "HTIF: attempt to read from illegal address 0x%" PRIx64 "\n", addr);
+ exit(-1);
+ }
+ }
send(buf, hdr.data_size * sizeof(buf[0]));
break;
}
case HTIF_CMD_WRITE_MEM:
{
const uint64_t* buf = (const uint64_t*)p.get_payload();
- for (size_t i = 0; i < hdr.data_size; i++)
- sim->mmu->store_uint64((hdr.addr+i)*HTIF_DATA_ALIGN, buf[i]);
-
+ for (size_t i = 0; i < hdr.data_size; i++) {
+ reg_t addr = (hdr.addr + i) * HTIF_DATA_ALIGN;
+ try {
+ sim->debug_mmu->store_uint64(addr, buf[i]);
+ } catch (trap_load_access_fault& e) {
+ fprintf(stderr, "HTIF: attempt to write to illegal address 0x%" PRIx64 "\n", addr);
+ exit(-1);
+ }
+ }
packet_header_t ack(HTIF_CMD_ACK, seqno, 0, 0);
send(&ack, sizeof(ack));
break;
case HTIF_CMD_READ_CONTROL_REG:
case HTIF_CMD_WRITE_CONTROL_REG:
{
+ assert(hdr.data_size == 1);
reg_t coreid = hdr.addr >> 20;
reg_t regno = hdr.addr & ((1<<20)-1);
- assert(hdr.data_size == 1);
+ uint64_t old_val, new_val = 0 /* shut up gcc */;
packet_header_t ack(HTIF_CMD_ACK, seqno, 1, 0);
send(&ack, sizeof(ack));
break;
}
- assert(coreid < sim->num_cores());
- uint64_t old_val = sim->procs[coreid]->get_pcr(regno);
- send(&old_val, sizeof(old_val));
-
- if (regno == PCR_TOHOST)
- sim->procs[coreid]->tohost = 0;
+ processor_t* proc = sim->get_core(coreid);
+ bool write = hdr.cmd == HTIF_CMD_WRITE_CONTROL_REG;
+ if (write)
+ memcpy(&new_val, p.get_payload(), sizeof(new_val));
- if (hdr.cmd == HTIF_CMD_WRITE_CONTROL_REG)
+ switch (regno)
{
- uint64_t new_val;
- memcpy(&new_val, p.get_payload(), sizeof(new_val));
- if (regno == PCR_RESET)
- {
- if (reset && !(new_val & 1))
- reset = false;
- sim->procs[coreid]->reset(new_val & 1);
- }
- else if (regno == PCR_FROMHOST && old_val != 0)
- ; // ignore host writes to fromhost if target hasn't yet consumed
- else
- sim->procs[coreid]->set_pcr(regno, new_val);
+ case CSR_MTOHOST:
+ old_val = proc->get_state()->tohost;
+ if (write)
+ proc->get_state()->tohost = new_val;
+ break;
+ case CSR_MFROMHOST:
+ old_val = proc->get_state()->fromhost;
+ if (write && old_val == 0)
+ proc->set_csr(CSR_MFROMHOST, new_val);
+ break;
+ case CSR_MRESET:
+ old_val = !proc->running();
+ if (write)
+ {
+ reset = reset & (new_val & 1);
+ proc->reset(new_val & 1);
+ }
+ break;
+ default:
+ abort();
}
+
+ send(&old_val, sizeof(old_val));
break;
}
default: