1 // See LICENSE for license details.
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)
20 bool htif_isasim_t::tick()
25 do tick_once(); while (reset
);
30 void htif_isasim_t::tick_once()
33 recv(&hdr
, sizeof(hdr
));
35 char buf
[hdr
.get_packet_size()];
36 memcpy(buf
, &hdr
, sizeof(hdr
));
37 recv(buf
+ sizeof(hdr
), hdr
.get_payload_size());
40 assert(hdr
.seqno
== seqno
);
44 case HTIF_CMD_READ_MEM
:
46 packet_header_t
ack(HTIF_CMD_ACK
, seqno
, hdr
.data_size
, 0);
47 send(&ack
, sizeof(ack
));
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
;
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
);
59 send(buf
, hdr
.data_size
* sizeof(buf
[0]));
62 case HTIF_CMD_WRITE_MEM
:
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
;
68 sim
->debug_mmu
->store_uint64(addr
, buf
[i
]);
69 } catch (trap_load_access_fault
& e
) {
70 fprintf(stderr
, "HTIF: attempt to write to illegal address 0x%" PRIx64
"\n", addr
);
74 packet_header_t
ack(HTIF_CMD_ACK
, seqno
, 0, 0);
75 send(&ack
, sizeof(ack
));
78 case HTIF_CMD_READ_CONTROL_REG
:
79 case HTIF_CMD_WRITE_CONTROL_REG
:
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 */;
86 packet_header_t
ack(HTIF_CMD_ACK
, seqno
, 1, 0);
87 send(&ack
, sizeof(ack
));
89 processor_t
* proc
= sim
->get_core(coreid
);
90 bool write
= hdr
.cmd
== HTIF_CMD_WRITE_CONTROL_REG
;
92 memcpy(&new_val
, p
.get_payload(), sizeof(new_val
));
97 old_val
= proc
->get_state()->tohost
;
99 proc
->get_state()->tohost
= new_val
;
102 old_val
= proc
->get_state()->fromhost
;
103 if (write
&& old_val
== 0)
104 proc
->set_csr(CSR_MFROMHOST
, new_val
);
107 old_val
= !proc
->running();
110 reset
= reset
& (new_val
& 1);
111 proc
->reset(new_val
& 1);
118 send(&old_val
, sizeof(old_val
));
127 bool htif_isasim_t::done()
131 return !sim
->running();