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