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