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