438d86274cdc5dd9069682fe86490fcefa2fb108
[riscv-isa-sim.git] / riscv / htif.cc
1 #include "htif.h"
2 #include "sim.h"
3 #include <unistd.h>
4 #include <stdexcept>
5 #include <stdlib.h>
6 #include <errno.h>
7 #include <assert.h>
8 #include <stddef.h>
9 #include <poll.h>
10
11 htif_isasim_t::htif_isasim_t(sim_t* _sim, const std::vector<std::string>& args)
12 : htif_pthread_t(args), sim(_sim), reset(true), seqno(1)
13 {
14 }
15
16 void htif_isasim_t::tick()
17 {
18 do tick_once(); while (reset);
19 }
20
21 void htif_isasim_t::tick_once()
22 {
23 packet_header_t hdr;
24 recv(&hdr, sizeof(hdr));
25
26 char buf[hdr.get_packet_size()];
27 memcpy(buf, &hdr, sizeof(hdr));
28 recv(buf + sizeof(hdr), hdr.get_payload_size());
29 packet_t p(buf);
30
31 assert(hdr.seqno == seqno);
32
33 switch (hdr.cmd)
34 {
35 case HTIF_CMD_READ_MEM:
36 {
37 packet_header_t ack(HTIF_CMD_ACK, seqno, hdr.data_size, 0);
38 send(&ack, sizeof(ack));
39
40 uint64_t buf[hdr.data_size];
41 for (size_t i = 0; i < hdr.data_size; i++)
42 buf[i] = sim->mmu->load_uint64((hdr.addr+i)*HTIF_DATA_ALIGN);
43 send(buf, hdr.data_size * sizeof(buf[0]));
44 break;
45 }
46 case HTIF_CMD_WRITE_MEM:
47 {
48 const uint64_t* buf = (const uint64_t*)p.get_payload();
49 for (size_t i = 0; i < hdr.data_size; i++)
50 sim->mmu->store_uint64((hdr.addr+i)*HTIF_DATA_ALIGN, buf[i]);
51
52 packet_header_t ack(HTIF_CMD_ACK, seqno, 0, 0);
53 send(&ack, sizeof(ack));
54 break;
55 }
56 case HTIF_CMD_READ_CONTROL_REG:
57 case HTIF_CMD_WRITE_CONTROL_REG:
58 {
59 reg_t coreid = hdr.addr >> 20;
60 reg_t regno = hdr.addr & ((1<<20)-1);
61 assert(hdr.data_size == 1);
62
63 packet_header_t ack(HTIF_CMD_ACK, seqno, 1, 0);
64 send(&ack, sizeof(ack));
65
66 if (coreid == 0xFFFFF) // system control register space
67 {
68 uint64_t scr = sim->get_scr(regno);
69 send(&scr, sizeof(scr));
70 break;
71 }
72
73 assert(coreid < sim->num_cores());
74 uint64_t old_val = sim->procs[coreid]->get_pcr(regno);
75 send(&old_val, sizeof(old_val));
76
77 if (regno == PCR_TOHOST)
78 sim->procs[coreid]->tohost = 0;
79
80 if (hdr.cmd == HTIF_CMD_WRITE_CONTROL_REG)
81 {
82 uint64_t new_val;
83 memcpy(&new_val, p.get_payload(), sizeof(new_val));
84 if (regno == PCR_RESET)
85 {
86 if (reset && !(new_val & 1))
87 reset = false;
88 sim->procs[coreid]->reset(new_val & 1);
89 }
90 else if (regno == PCR_FROMHOST && old_val != 0)
91 ; // ignore host writes to fromhost if target hasn't yet consumed
92 else
93 sim->procs[coreid]->set_pcr(regno, new_val);
94 }
95 break;
96 }
97 default:
98 abort();
99 }
100 seqno++;
101 }
102
103 bool htif_isasim_t::done()
104 {
105 if (reset)
106 return false;
107 for (size_t i = 0; i < sim->num_cores(); i++)
108 if (sim->procs[i]->running())
109 return false;
110 return true;
111 }