4b282f6042ab9984bdc33d20673a1c522fdfb736
[riscv-isa-sim.git] / riscv / processor.cc
1 // See LICENSE for license details.
2
3 #include "processor.h"
4 #include "extension.h"
5 #include "common.h"
6 #include "config.h"
7 #include "sim.h"
8 #include "htif.h"
9 #include "disasm.h"
10 #include "icache.h"
11 #include <cinttypes>
12 #include <cmath>
13 #include <cstdlib>
14 #include <iostream>
15 #include <assert.h>
16 #include <limits.h>
17 #include <stdexcept>
18 #include <algorithm>
19
20 #undef STATE
21 #define STATE state
22
23 processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id)
24 : sim(_sim), mmu(_mmu), ext(NULL), disassembler(new disassembler_t),
25 id(_id), run(false), debug(false)
26 {
27 reset(true);
28 mmu->set_processor(this);
29
30 #define DECLARE_INSN(name, match, mask) REGISTER_INSN(this, name, match, mask)
31 #include "encoding.h"
32 #undef DECLARE_INSN
33 build_opcode_map();
34 }
35
36 processor_t::~processor_t()
37 {
38 delete disassembler;
39 }
40
41 void state_t::reset()
42 {
43 // the ISA guarantees on boot that the PC is 0x2000 and the the processor
44 // is in supervisor mode, and in 64-bit mode, if supported, with traps
45 // and virtual memory disabled.
46 sr = SR_S | SR_S64 | SR_U64;
47 pc = 0x2000;
48
49 // the following state is undefined upon boot-up,
50 // but we zero it for determinism
51 XPR.reset();
52 FPR.reset();
53
54 epc = 0;
55 badvaddr = 0;
56 evec = 0;
57 ptbr = 0;
58 pcr_k0 = 0;
59 pcr_k1 = 0;
60 cause = 0;
61 tohost = 0;
62 fromhost = 0;
63 count = 0;
64 compare = 0;
65 fflags = 0;
66 frm = 0;
67
68 load_reservation = -1;
69 }
70
71 void processor_t::set_debug(bool value)
72 {
73 debug = value;
74 if (ext)
75 ext->set_debug(value);
76 }
77
78 void processor_t::reset(bool value)
79 {
80 if (run == !value)
81 return;
82 run = !value;
83
84 state.reset(); // reset the core
85 set_pcr(CSR_STATUS, state.sr);
86
87 if (ext)
88 ext->reset(); // reset the extension
89 }
90
91 void processor_t::take_interrupt()
92 {
93 uint32_t interrupts = (state.sr & SR_IP) >> SR_IP_SHIFT;
94 interrupts &= (state.sr & SR_IM) >> SR_IM_SHIFT;
95
96 if (interrupts && (state.sr & SR_EI))
97 for (int i = 0; ; i++, interrupts >>= 1)
98 if (interrupts & 1)
99 throw trap_t((1ULL << ((state.sr & SR_S64) ? 63 : 31)) + i);
100 }
101
102 static void commit_log(state_t* state, insn_t insn)
103 {
104 #ifdef RISCV_ENABLE_COMMITLOG
105 if (state->sr & SR_EI) {
106 if (state->log_reg_write.addr) {
107 fprintf(stderr, "0x%016" PRIx64 " (0x%08" PRIx32 ") %c%2u 0x%016" PRIx64 "\n",
108 state->pc, insn.bits(),
109 state->log_reg_write.addr & 1 ? 'f' : 'x',
110 state->log_reg_write.addr >> 1, state->log_reg_write.data);
111 }
112 else {
113 fprintf(stderr, "0x%016" PRIx64 " (0x%08" PRIx32 ")\n",
114 state->pc, insn.bits());
115 }
116 }
117 state->log_reg_write.addr = 0;
118 #endif
119 }
120
121 static inline void execute_insn(processor_t* p, state_t* st, insn_fetch_t fetch)
122 {
123 reg_t npc = fetch.func(p, fetch.insn.insn, st->pc);
124 commit_log(st, fetch.insn.insn);
125 st->pc = npc;
126 }
127
128 void processor_t::step(size_t n0)
129 {
130 if(!run)
131 return;
132
133 mmu_t* _mmu = mmu;
134 auto count32 = decltype(state.compare)(state.count);
135 bool count_le_compare = count32 <= state.compare;
136 ssize_t n = std::min(ssize_t(n0), ssize_t((state.compare - count32) | 1));
137
138 try
139 {
140 take_interrupt();
141
142 if (debug) // print out instructions as we go
143 {
144 for (ssize_t i = 0; i < n; state.count++, i++)
145 {
146 insn_fetch_t fetch = mmu->load_insn(state.pc);
147 disasm(fetch.insn.insn);
148 execute_insn(this, &state, fetch);
149 }
150 }
151 else while (n > 0)
152 {
153 size_t idx = (state.pc / sizeof(insn_t)) % ICACHE_SIZE;
154 auto ic_entry = _mmu->access_icache(state.pc), ic_entry_init = ic_entry;
155
156 #define ICACHE_ACCESS(idx) { \
157 insn_fetch_t fetch = ic_entry->data; \
158 ic_entry++; \
159 execute_insn(this, &state, fetch); \
160 if (idx < ICACHE_SIZE-1 && unlikely(ic_entry->tag != state.pc)) break; \
161 }
162
163 switch (idx)
164 {
165 ICACHE_SWITCH; // auto-generated into icache.h
166 }
167
168 size_t i = ic_entry - ic_entry_init;
169 state.count += i;
170 n -= i;
171 }
172 }
173 catch(trap_t& t)
174 {
175 take_trap(t);
176 }
177
178 bool count_ge_compare =
179 uint64_t(n) + decltype(state.compare)(state.count) >= state.compare;
180 if (count_le_compare && count_ge_compare)
181 set_interrupt(IRQ_TIMER, true);
182 }
183
184 void processor_t::take_trap(trap_t& t)
185 {
186 if (debug)
187 fprintf(stderr, "core %3d: exception %s, epc 0x%016" PRIx64 "\n",
188 id, t.name(), state.pc);
189
190 // switch to supervisor, set previous supervisor bit, disable interrupts
191 set_pcr(CSR_STATUS, (((state.sr & ~SR_EI) | SR_S) & ~SR_PS & ~SR_PEI) |
192 ((state.sr & SR_S) ? SR_PS : 0) |
193 ((state.sr & SR_EI) ? SR_PEI : 0));
194
195 yield_load_reservation();
196 state.cause = t.cause();
197 state.epc = state.pc;
198 state.pc = state.evec;
199
200 t.side_effects(&state); // might set badvaddr etc.
201 }
202
203 void processor_t::deliver_ipi()
204 {
205 if (run)
206 set_pcr(CSR_CLEAR_IPI, 1);
207 }
208
209 void processor_t::disasm(insn_t insn)
210 {
211 // the disassembler is stateless, so we share it
212 fprintf(stderr, "core %3d: 0x%016" PRIx64 " (0x%08" PRIx32 ") %s\n",
213 id, state.pc, insn.bits(), disassembler->disassemble(insn).c_str());
214 }
215
216 reg_t processor_t::set_pcr(int which, reg_t val)
217 {
218 reg_t old_pcr = get_pcr(which);
219
220 switch (which)
221 {
222 case CSR_FFLAGS:
223 state.fflags = val & (FSR_AEXC >> FSR_AEXC_SHIFT);
224 break;
225 case CSR_FRM:
226 state.frm = val & (FSR_RD >> FSR_RD_SHIFT);
227 break;
228 case CSR_FCSR:
229 state.fflags = (val & FSR_AEXC) >> FSR_AEXC_SHIFT;
230 state.frm = (val & FSR_RD) >> FSR_RD_SHIFT;
231 break;
232 case CSR_STATUS:
233 state.sr = (val & ~SR_IP) | (state.sr & SR_IP);
234 #ifndef RISCV_ENABLE_64BIT
235 state.sr &= ~(SR_S64 | SR_U64);
236 #endif
237 #ifndef RISCV_ENABLE_FPU
238 state.sr &= ~SR_EF;
239 #endif
240 if (!ext)
241 state.sr &= ~SR_EA;
242 state.sr &= ~SR_ZERO;
243 rv64 = (state.sr & SR_S) ? (state.sr & SR_S64) : (state.sr & SR_U64);
244 mmu->flush_tlb();
245 break;
246 case CSR_EPC:
247 state.epc = val;
248 break;
249 case CSR_EVEC:
250 state.evec = val & ~3;
251 break;
252 case CSR_COUNT:
253 state.count = val;
254 break;
255 case CSR_COUNTH:
256 state.count = (val << 32) | (uint32_t)state.count;
257 break;
258 case CSR_COMPARE:
259 set_interrupt(IRQ_TIMER, false);
260 state.compare = val;
261 break;
262 case CSR_PTBR:
263 state.ptbr = val & ~(PGSIZE-1);
264 break;
265 case CSR_SEND_IPI:
266 sim->send_ipi(val);
267 break;
268 case CSR_CLEAR_IPI:
269 set_interrupt(IRQ_IPI, val & 1);
270 break;
271 case CSR_SUP0:
272 state.pcr_k0 = val;
273 break;
274 case CSR_SUP1:
275 state.pcr_k1 = val;
276 break;
277 case CSR_TOHOST:
278 if (state.tohost == 0)
279 state.tohost = val;
280 break;
281 case CSR_FROMHOST:
282 set_fromhost(val);
283 break;
284 }
285
286 return old_pcr;
287 }
288
289 void processor_t::set_fromhost(reg_t val)
290 {
291 set_interrupt(IRQ_HOST, val != 0);
292 state.fromhost = val;
293 }
294
295 reg_t processor_t::get_pcr(int which)
296 {
297 switch (which)
298 {
299 case CSR_FFLAGS:
300 require_fp;
301 return state.fflags;
302 case CSR_FRM:
303 require_fp;
304 return state.frm;
305 case CSR_FCSR:
306 require_fp;
307 return (state.fflags << FSR_AEXC_SHIFT) | (state.frm << FSR_RD_SHIFT);
308 case CSR_STATUS:
309 return state.sr;
310 case CSR_EPC:
311 return state.epc;
312 case CSR_BADVADDR:
313 return state.badvaddr;
314 case CSR_EVEC:
315 return state.evec;
316 case CSR_CYCLE:
317 case CSR_TIME:
318 case CSR_INSTRET:
319 case CSR_COUNT:
320 return state.count;
321 case CSR_CYCLEH:
322 case CSR_TIMEH:
323 case CSR_INSTRETH:
324 case CSR_COUNTH:
325 if (rv64)
326 break;
327 return state.count >> 32;
328 case CSR_COMPARE:
329 return state.compare;
330 case CSR_CAUSE:
331 return state.cause;
332 case CSR_PTBR:
333 return state.ptbr;
334 case CSR_SEND_IPI:
335 case CSR_CLEAR_IPI:
336 return 0;
337 case CSR_ASID:
338 return 0;
339 case CSR_FATC:
340 mmu->flush_tlb();
341 return 0;
342 case CSR_HARTID:
343 return id;
344 case CSR_IMPL:
345 return 1;
346 case CSR_SUP0:
347 return state.pcr_k0;
348 case CSR_SUP1:
349 return state.pcr_k1;
350 case CSR_TOHOST:
351 sim->get_htif()->tick(); // not necessary, but faster
352 return state.tohost;
353 case CSR_FROMHOST:
354 sim->get_htif()->tick(); // not necessary, but faster
355 return state.fromhost;
356 case CSR_UARCH0:
357 case CSR_UARCH1:
358 case CSR_UARCH2:
359 case CSR_UARCH3:
360 case CSR_UARCH4:
361 case CSR_UARCH5:
362 case CSR_UARCH6:
363 case CSR_UARCH7:
364 case CSR_UARCH8:
365 case CSR_UARCH9:
366 case CSR_UARCH10:
367 case CSR_UARCH11:
368 case CSR_UARCH12:
369 case CSR_UARCH13:
370 case CSR_UARCH14:
371 case CSR_UARCH15:
372 return 0;
373 }
374 throw trap_illegal_instruction();
375 }
376
377 void processor_t::set_interrupt(int which, bool on)
378 {
379 uint32_t mask = (1 << (which + SR_IP_SHIFT)) & SR_IP;
380 if (on)
381 state.sr |= mask;
382 else
383 state.sr &= ~mask;
384 }
385
386 reg_t illegal_instruction(processor_t* p, insn_t insn, reg_t pc)
387 {
388 throw trap_illegal_instruction();
389 }
390
391 insn_func_t processor_t::decode_insn(insn_t insn)
392 {
393 size_t mask = opcode_map.size()-1;
394 insn_desc_t* desc = opcode_map[insn.bits() & mask];
395
396 while ((insn.bits() & desc->mask) != desc->match)
397 desc++;
398
399 return rv64 ? desc->rv64 : desc->rv32;
400 }
401
402 void processor_t::register_insn(insn_desc_t desc)
403 {
404 assert(desc.mask & 1);
405 instructions.push_back(desc);
406 }
407
408 void processor_t::build_opcode_map()
409 {
410 size_t buckets = -1;
411 for (auto& inst : instructions)
412 while ((inst.mask & buckets) != buckets)
413 buckets /= 2;
414 buckets++;
415
416 struct cmp {
417 decltype(insn_desc_t::match) mask;
418 cmp(decltype(mask) mask) : mask(mask) {}
419 bool operator()(const insn_desc_t& lhs, const insn_desc_t& rhs) {
420 if ((lhs.match & mask) != (rhs.match & mask))
421 return (lhs.match & mask) < (rhs.match & mask);
422 return lhs.match < rhs.match;
423 }
424 };
425 std::sort(instructions.begin(), instructions.end(), cmp(buckets-1));
426
427 opcode_map.resize(buckets);
428 opcode_store.resize(instructions.size() + 1);
429
430 size_t j = 0;
431 for (size_t b = 0, i = 0; b < buckets; b++)
432 {
433 opcode_map[b] = &opcode_store[j];
434 while (i < instructions.size() && b == (instructions[i].match & (buckets-1)))
435 opcode_store[j++] = instructions[i++];
436 }
437
438 assert(j == opcode_store.size()-1);
439 opcode_store[j].match = opcode_store[j].mask = 0;
440 opcode_store[j].rv32 = &illegal_instruction;
441 opcode_store[j].rv64 = &illegal_instruction;
442 }
443
444 void processor_t::register_extension(extension_t* x)
445 {
446 for (auto insn : x->get_instructions())
447 register_insn(insn);
448 build_opcode_map();
449 for (auto disasm_insn : x->get_disasms())
450 disassembler->add_insn(disasm_insn);
451 if (ext != NULL)
452 throw std::logic_error("only one extension may be registered");
453 ext = x;
454 x->set_processor(this);
455 }