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