6277de027d5716fa8ed07197fc50c0f3dea0827c
[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 <cinttypes>
11 #include <cmath>
12 #include <cstdlib>
13 #include <iostream>
14 #include <assert.h>
15 #include <limits.h>
16 #include <stdexcept>
17 #include <algorithm>
18
19 #undef STATE
20 #define STATE state
21
22 processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id)
23 : sim(sim), ext(NULL), disassembler(new disassembler_t),
24 id(id), run(false), debug(false)
25 {
26 parse_isa_string(isa);
27
28 mmu = new mmu_t(sim->mem, sim->memsz);
29 mmu->set_processor(this);
30
31 reset(true);
32
33 #define DECLARE_INSN(name, match, mask) REGISTER_INSN(this, name, match, mask)
34 #include "encoding.h"
35 #undef DECLARE_INSN
36 build_opcode_map();
37 }
38
39 processor_t::~processor_t()
40 {
41 #ifdef RISCV_ENABLE_HISTOGRAM
42 if (histogram_enabled)
43 {
44 fprintf(stderr, "PC Histogram size:%lu\n", pc_histogram.size());
45 for(auto iterator = pc_histogram.begin(); iterator != pc_histogram.end(); ++iterator) {
46 fprintf(stderr, "%0lx %lu\n", (iterator->first << 2), iterator->second);
47 }
48 }
49 #endif
50
51 delete mmu;
52 delete disassembler;
53 }
54
55 static void bad_isa_string(const char* isa)
56 {
57 fprintf(stderr, "error: bad --isa option %s\n", isa);
58 abort();
59 }
60
61 void processor_t::parse_isa_string(const char* isa)
62 {
63 const char* p = isa;
64 const char* all_subsets = "IMAFDC";
65
66 max_xlen = 64;
67 if (strncmp(p, "RV32", 4) == 0)
68 max_xlen = 32, p += 4;
69 else if (strncmp(p, "RV64", 4) == 0)
70 p += 4;
71 else if (strncmp(p, "RV", 2) == 0)
72 p += 2;
73
74 if (!*p)
75 p = all_subsets;
76 else if (*p != 'I')
77 bad_isa_string(isa);
78
79 memset(subsets, 0, sizeof(subsets));
80
81 while (*p) {
82 if (auto next = strchr(all_subsets, *p)) {
83 subsets[(int)*p] = true;
84 all_subsets = next + 1;
85 p++;
86 } else if (*p == 'X') {
87 const char* ext = p+1, *end = ext;
88 while (islower(*end))
89 end++;
90 register_extension(find_extension(std::string(ext, end - ext).c_str())());
91 p = end;
92 } else {
93 bad_isa_string(isa);
94 }
95 }
96
97 if (supports_extension('D') && !supports_extension('F'))
98 bad_isa_string(isa);
99 }
100
101 void state_t::reset()
102 {
103 memset(this, 0, sizeof(*this));
104 mstatus = set_field(mstatus, MSTATUS_PRV, PRV_M);
105 mstatus = set_field(mstatus, MSTATUS_PRV1, PRV_S);
106 mstatus = set_field(mstatus, MSTATUS_PRV2, PRV_S);
107 pc = 0x100;
108 load_reservation = -1;
109 }
110
111 void processor_t::set_debug(bool value)
112 {
113 debug = value;
114 if (ext)
115 ext->set_debug(value);
116 }
117
118 void processor_t::set_histogram(bool value)
119 {
120 histogram_enabled = value;
121 }
122
123 void processor_t::reset(bool value)
124 {
125 if (run == !value)
126 return;
127 run = !value;
128
129 state.reset();
130 set_csr(CSR_MSTATUS, state.mstatus);
131
132 if (ext)
133 ext->reset(); // reset the extension
134 }
135
136 void processor_t::raise_interrupt(reg_t which)
137 {
138 throw trap_t(((reg_t)1 << (max_xlen-1)) | which);
139 }
140
141 void processor_t::take_interrupt()
142 {
143 int priv = get_field(state.mstatus, MSTATUS_PRV);
144 int ie = get_field(state.mstatus, MSTATUS_IE);
145
146 if (priv < PRV_M || (priv == PRV_M && ie)) {
147 if (get_field(state.mstatus, MSTATUS_MSIP))
148 raise_interrupt(IRQ_IPI);
149
150 if (state.fromhost != 0)
151 raise_interrupt(IRQ_HOST);
152 }
153
154 if (priv < PRV_S || (priv == PRV_S && ie)) {
155 if (get_field(state.mstatus, MSTATUS_SSIP))
156 raise_interrupt(IRQ_IPI);
157
158 if (state.stip && get_field(state.mstatus, MSTATUS_STIE))
159 raise_interrupt(IRQ_TIMER);
160 }
161 }
162
163 static void commit_log(state_t* state, reg_t pc, insn_t insn)
164 {
165 #ifdef RISCV_ENABLE_COMMITLOG
166 if (get_field(state->mstatus, MSTATUS_IE)) {
167 uint64_t mask = (insn.length() == 8 ? uint64_t(0) : (uint64_t(1) << (insn.length() * 8))) - 1;
168 if (state->log_reg_write.addr) {
169 fprintf(stderr, "0x%016" PRIx64 " (0x%08" PRIx64 ") %c%2" PRIu64 " 0x%016" PRIx64 "\n",
170 pc,
171 insn.bits() & mask,
172 state->log_reg_write.addr & 1 ? 'f' : 'x',
173 state->log_reg_write.addr >> 1,
174 state->log_reg_write.data);
175 } else {
176 fprintf(stderr, "0x%016" PRIx64 " (0x%08" PRIx64 ")\n", pc, insn.bits() & mask);
177 }
178 }
179 state->log_reg_write.addr = 0;
180 #endif
181 }
182
183 inline void processor_t::update_histogram(size_t pc)
184 {
185 #ifdef RISCV_ENABLE_HISTOGRAM
186 size_t idx = pc >> 2;
187 pc_histogram[idx]++;
188 #endif
189 }
190
191 static reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch)
192 {
193 reg_t npc = fetch.func(p, fetch.insn, pc);
194 if (npc != PC_SERIALIZE) {
195 commit_log(p->get_state(), pc, fetch.insn);
196 p->update_histogram(pc);
197 }
198 return npc;
199 }
200
201 static void update_timer(state_t* state, size_t instret)
202 {
203 uint64_t count0 = (uint64_t)(uint32_t)state->scount;
204 state->scount += instret;
205 uint64_t before = count0 - state->stimecmp;
206 if (int64_t(before ^ (before + instret)) < 0)
207 state->stip = true;
208 }
209
210 static size_t next_timer(state_t* state)
211 {
212 return state->stimecmp - (uint32_t)state->scount;
213 }
214
215 void processor_t::step(size_t n)
216 {
217 size_t instret = 0;
218 reg_t pc = state.pc;
219 mmu_t* _mmu = mmu;
220
221 if (unlikely(!run || !n))
222 return;
223 n = std::min(n, next_timer(&state) | 1U);
224
225 #define maybe_serialize() \
226 if (unlikely(pc == PC_SERIALIZE)) { \
227 pc = state.pc; \
228 state.serialized = true; \
229 continue; \
230 }
231
232 try
233 {
234 take_interrupt();
235
236 if (unlikely(debug))
237 {
238 while (instret < n)
239 {
240 insn_fetch_t fetch = mmu->load_insn(pc);
241 if (!state.serialized)
242 disasm(fetch.insn);
243 pc = execute_insn(this, pc, fetch);
244 maybe_serialize();
245 instret++;
246 state.pc = pc;
247 }
248 }
249 else while (instret < n)
250 {
251 size_t idx = _mmu->icache_index(pc);
252 auto ic_entry = _mmu->access_icache(pc);
253
254 #define ICACHE_ACCESS(idx) { \
255 insn_fetch_t fetch = ic_entry->data; \
256 ic_entry++; \
257 pc = execute_insn(this, pc, fetch); \
258 if (idx == mmu_t::ICACHE_ENTRIES-1) break; \
259 if (unlikely(ic_entry->tag != pc)) break; \
260 instret++; \
261 state.pc = pc; \
262 }
263
264 switch (idx) {
265 #include "icache.h"
266 }
267
268 maybe_serialize();
269 instret++;
270 state.pc = pc;
271 }
272 }
273 catch(trap_t& t)
274 {
275 state.pc = take_trap(t, pc);
276 }
277
278 update_timer(&state, instret);
279 }
280
281 void processor_t::push_privilege_stack()
282 {
283 reg_t s = state.mstatus;
284 s = set_field(s, MSTATUS_PRV2, get_field(state.mstatus, MSTATUS_PRV1));
285 s = set_field(s, MSTATUS_IE2, get_field(state.mstatus, MSTATUS_IE1));
286 s = set_field(s, MSTATUS_PRV1, get_field(state.mstatus, MSTATUS_PRV));
287 s = set_field(s, MSTATUS_IE1, get_field(state.mstatus, MSTATUS_IE));
288 s = set_field(s, MSTATUS_PRV, PRV_M);
289 s = set_field(s, MSTATUS_MPRV, PRV_M);
290 s = set_field(s, MSTATUS_IE, 0);
291 set_csr(CSR_MSTATUS, s);
292 }
293
294 void processor_t::pop_privilege_stack()
295 {
296 reg_t s = state.mstatus;
297 s = set_field(s, MSTATUS_PRV, get_field(state.mstatus, MSTATUS_PRV1));
298 s = set_field(s, MSTATUS_IE, get_field(state.mstatus, MSTATUS_IE1));
299 s = set_field(s, MSTATUS_PRV1, get_field(state.mstatus, MSTATUS_PRV2));
300 s = set_field(s, MSTATUS_IE1, get_field(state.mstatus, MSTATUS_IE2));
301 s = set_field(s, MSTATUS_PRV2, PRV_U);
302 s = set_field(s, MSTATUS_IE2, 1);
303 set_csr(CSR_MSTATUS, s);
304 }
305
306 reg_t processor_t::take_trap(trap_t& t, reg_t epc)
307 {
308 if (debug)
309 fprintf(stderr, "core %3d: exception %s, epc 0x%016" PRIx64 "\n",
310 id, t.name(), epc);
311
312 reg_t tvec = 0x40 * get_field(state.mstatus, MSTATUS_PRV);
313 push_privilege_stack();
314 yield_load_reservation();
315 state.mcause = t.cause();
316 state.mepc = epc;
317 t.side_effects(&state); // might set badvaddr etc.
318 return tvec;
319 }
320
321 void processor_t::deliver_ipi()
322 {
323 state.mstatus |= MSTATUS_MSIP;
324 }
325
326 void processor_t::disasm(insn_t insn)
327 {
328 uint64_t bits = insn.bits() & ((1ULL << (8 * insn_length(insn.bits()))) - 1);
329 fprintf(stderr, "core %3d: 0x%016" PRIx64 " (0x%08" PRIx64 ") %s\n",
330 id, state.pc, bits, disassembler->disassemble(insn).c_str());
331 }
332
333 static bool validate_priv(reg_t priv)
334 {
335 return priv == PRV_U || priv == PRV_S || priv == PRV_M;
336 }
337
338 static bool validate_arch(int max_xlen, reg_t arch)
339 {
340 if (max_xlen == 64 && arch == UA_RV64)
341 return true;
342 return arch == UA_RV32;
343 }
344
345 static bool validate_vm(int max_xlen, reg_t vm)
346 {
347 if (max_xlen == 64 && vm == VM_SV39)
348 return true;
349 if (max_xlen == 32 && vm == VM_SV32)
350 return true;
351 return vm == VM_MBARE;
352 }
353
354 void processor_t::set_csr(int which, reg_t val)
355 {
356 switch (which)
357 {
358 case CSR_FFLAGS:
359 dirty_fp_state;
360 state.fflags = val & (FSR_AEXC >> FSR_AEXC_SHIFT);
361 break;
362 case CSR_FRM:
363 dirty_fp_state;
364 state.frm = val & (FSR_RD >> FSR_RD_SHIFT);
365 break;
366 case CSR_FCSR:
367 dirty_fp_state;
368 state.fflags = (val & FSR_AEXC) >> FSR_AEXC_SHIFT;
369 state.frm = (val & FSR_RD) >> FSR_RD_SHIFT;
370 break;
371 case CSR_SCYCLE:
372 case CSR_STIME:
373 case CSR_SINSTRET:
374 state.scount = val; break;
375 case CSR_SCYCLEH:
376 case CSR_STIMEH:
377 case CSR_SINSTRETH:
378 state.scount = (val << 32) | (uint32_t)state.scount;
379 break;
380 case CSR_MSTATUS:
381 {
382 if ((val ^ state.mstatus) & (MSTATUS_VM | MSTATUS_PRV | MSTATUS_MPRV))
383 mmu->flush_tlb();
384
385 reg_t mask = MSTATUS_SSIP | MSTATUS_MSIP | MSTATUS_IE | MSTATUS_IE1
386 | MSTATUS_IE2 | MSTATUS_IE3 | MSTATUS_STIE | MSTATUS_FS;
387 if (ext)
388 mask |= MSTATUS_XS;
389 state.mstatus = (state.mstatus & ~mask) | (val & mask);
390
391 if (validate_vm(max_xlen, get_field(val, MSTATUS_VM)))
392 state.mstatus = (state.mstatus & ~MSTATUS_VM) | (val & MSTATUS_VM);
393 if (validate_priv(get_field(val, MSTATUS_MPRV)))
394 state.mstatus = (state.mstatus & ~MSTATUS_MPRV) | (val & MSTATUS_MPRV);
395 if (validate_priv(get_field(val, MSTATUS_PRV)))
396 state.mstatus = (state.mstatus & ~MSTATUS_PRV) | (val & MSTATUS_PRV);
397 if (validate_priv(get_field(val, MSTATUS_PRV1)))
398 state.mstatus = (state.mstatus & ~MSTATUS_PRV1) | (val & MSTATUS_PRV1);
399 if (validate_priv(get_field(val, MSTATUS_PRV2)))
400 state.mstatus = (state.mstatus & ~MSTATUS_PRV2) | (val & MSTATUS_PRV2);
401 if (validate_priv(get_field(val, MSTATUS_PRV3)))
402 state.mstatus = (state.mstatus & ~MSTATUS_PRV3) | (val & MSTATUS_PRV3);
403
404 bool dirty = (state.mstatus & MSTATUS_FS) == MSTATUS_FS;
405 dirty |= (state.mstatus & MSTATUS_XS) == MSTATUS_XS;
406 xlen = 32;
407 if (max_xlen == 32) {
408 state.mstatus = set_field(state.mstatus, MSTATUS32_SD, dirty);
409 } else {
410 state.mstatus = set_field(state.mstatus, MSTATUS64_SD, dirty);
411
412 if (validate_arch(max_xlen, get_field(val, MSTATUS64_UA)))
413 state.mstatus = (state.mstatus & ~MSTATUS64_UA) | (val & MSTATUS64_UA);
414 if (validate_arch(max_xlen, get_field(val, MSTATUS64_SA)))
415 state.mstatus = (state.mstatus & ~MSTATUS64_SA) | (val & MSTATUS64_SA);
416 switch (get_field(state.mstatus, MSTATUS_PRV)) {
417 case PRV_U: if (get_field(state.mstatus, MSTATUS64_UA)) xlen = 64; break;
418 case PRV_S: if (get_field(state.mstatus, MSTATUS64_SA)) xlen = 64; break;
419 case PRV_M: xlen = 64; break;
420 default: abort();
421 }
422 }
423 break;
424 }
425 case CSR_SSTATUS:
426 {
427 reg_t ms = state.mstatus;
428 ms = set_field(ms, MSTATUS_SSIP, get_field(val, SSTATUS_SIP));
429 ms = set_field(ms, MSTATUS_IE, get_field(val, SSTATUS_IE));
430 ms = set_field(ms, MSTATUS_IE1, get_field(val, SSTATUS_PIE));
431 ms = set_field(ms, MSTATUS_PRV1, get_field(val, SSTATUS_PS));
432 ms = set_field(ms, MSTATUS64_UA, get_field(val, SSTATUS_UA));
433 ms = set_field(ms, MSTATUS_STIE, get_field(val, SSTATUS_TIE));
434 ms = set_field(ms, MSTATUS_FS, get_field(val, SSTATUS_FS));
435 ms = set_field(ms, MSTATUS_XS, get_field(val, SSTATUS_XS));
436 return set_csr(CSR_MSTATUS, ms);
437 }
438 case CSR_SEPC: state.sepc = val; break;
439 case CSR_STVEC: state.stvec = val & ~3; break;
440 case CSR_STIMECMP:
441 state.stip = false;
442 state.stimecmp = val;
443 break;
444 case CSR_SPTBR: state.sptbr = val & ~(PGSIZE-1); break;
445 case CSR_SSCRATCH: state.sscratch = val; break;
446 case CSR_MEPC: state.mepc = val; break;
447 case CSR_MSCRATCH: state.mscratch = val; break;
448 case CSR_MCAUSE: state.mcause = val; break;
449 case CSR_MBADADDR: state.mbadaddr = val; break;
450 case CSR_SEND_IPI: sim->send_ipi(val); break;
451 case CSR_TOHOST:
452 if (state.tohost == 0)
453 state.tohost = val;
454 break;
455 case CSR_FROMHOST: state.fromhost = val; break;
456 }
457 }
458
459 reg_t processor_t::get_csr(int which)
460 {
461 switch (which)
462 {
463 case CSR_FFLAGS:
464 require_fp;
465 if (!supports_extension('F'))
466 break;
467 return state.fflags;
468 case CSR_FRM:
469 require_fp;
470 if (!supports_extension('F'))
471 break;
472 return state.frm;
473 case CSR_FCSR:
474 require_fp;
475 if (!supports_extension('F'))
476 break;
477 return (state.fflags << FSR_AEXC_SHIFT) | (state.frm << FSR_RD_SHIFT);
478 case CSR_CYCLE:
479 case CSR_TIME:
480 case CSR_INSTRET:
481 case CSR_SCYCLE:
482 case CSR_STIME:
483 case CSR_SINSTRET:
484 return state.scount;
485 case CSR_CYCLEH:
486 case CSR_TIMEH:
487 case CSR_INSTRETH:
488 case CSR_SCYCLEH:
489 case CSR_STIMEH:
490 case CSR_SINSTRETH:
491 if (xlen == 64)
492 break;
493 return state.scount >> 32;
494 case CSR_SSTATUS:
495 {
496 reg_t ss = 0;
497 ss = set_field(ss, SSTATUS_SIP, get_field(state.mstatus, MSTATUS_SSIP));
498 ss = set_field(ss, SSTATUS_IE, get_field(state.mstatus, MSTATUS_IE));
499 ss = set_field(ss, SSTATUS_PIE, get_field(state.mstatus, MSTATUS_IE1));
500 ss = set_field(ss, SSTATUS_PS, get_field(state.mstatus, MSTATUS_PRV1));
501 ss = set_field(ss, SSTATUS_UA, get_field(state.mstatus, MSTATUS64_UA));
502 ss = set_field(ss, SSTATUS_TIE, get_field(state.mstatus, MSTATUS_STIE));
503 ss = set_field(ss, SSTATUS_TIP, state.stip);
504 ss = set_field(ss, SSTATUS_FS, get_field(state.mstatus, MSTATUS_FS));
505 ss = set_field(ss, SSTATUS_XS, get_field(state.mstatus, MSTATUS_XS));
506 if (get_field(state.mstatus, MSTATUS64_SD))
507 ss = set_field(ss, (xlen == 32 ? SSTATUS32_SD : SSTATUS64_SD), 1);
508 return ss;
509 }
510 case CSR_SEPC: return state.sepc;
511 case CSR_SBADADDR: return state.sbadaddr;
512 case CSR_STVEC: return state.stvec;
513 case CSR_STIMECMP: return state.stimecmp;
514 case CSR_SCAUSE:
515 if (max_xlen > xlen)
516 return state.scause | ((state.scause >> (max_xlen-1)) << (xlen-1));
517 return state.scause;
518 case CSR_SPTBR: return state.sptbr;
519 case CSR_SASID: return 0;
520 case CSR_SSCRATCH: return state.sscratch;
521 case CSR_MSTATUS: return state.mstatus;
522 case CSR_MEPC: return state.mepc;
523 case CSR_MSCRATCH: return state.mscratch;
524 case CSR_MCAUSE: return state.mcause;
525 case CSR_MBADADDR: return state.mbadaddr;
526 case CSR_TOHOST:
527 sim->get_htif()->tick(); // not necessary, but faster
528 return state.tohost;
529 case CSR_FROMHOST:
530 sim->get_htif()->tick(); // not necessary, but faster
531 return state.fromhost;
532 case CSR_SEND_IPI: return 0;
533 case CSR_HARTID: return id;
534 case CSR_UARCH0:
535 case CSR_UARCH1:
536 case CSR_UARCH2:
537 case CSR_UARCH3:
538 case CSR_UARCH4:
539 case CSR_UARCH5:
540 case CSR_UARCH6:
541 case CSR_UARCH7:
542 case CSR_UARCH8:
543 case CSR_UARCH9:
544 case CSR_UARCH10:
545 case CSR_UARCH11:
546 case CSR_UARCH12:
547 case CSR_UARCH13:
548 case CSR_UARCH14:
549 case CSR_UARCH15:
550 return 0;
551 }
552 throw trap_illegal_instruction();
553 }
554
555 reg_t illegal_instruction(processor_t* p, insn_t insn, reg_t pc)
556 {
557 throw trap_illegal_instruction();
558 }
559
560 insn_func_t processor_t::decode_insn(insn_t insn)
561 {
562 size_t mask = opcode_map.size()-1;
563 insn_desc_t* desc = opcode_map[insn.bits() & mask];
564
565 while ((insn.bits() & desc->mask) != desc->match)
566 desc++;
567
568 return xlen == 64 ? desc->rv64 : desc->rv32;
569 }
570
571 void processor_t::register_insn(insn_desc_t desc)
572 {
573 assert(desc.mask & 1);
574 instructions.push_back(desc);
575 }
576
577 void processor_t::build_opcode_map()
578 {
579 size_t buckets = -1;
580 for (auto& inst : instructions)
581 while ((inst.mask & buckets) != buckets)
582 buckets /= 2;
583 buckets++;
584
585 struct cmp {
586 decltype(insn_desc_t::match) mask;
587 cmp(decltype(mask) mask) : mask(mask) {}
588 bool operator()(const insn_desc_t& lhs, const insn_desc_t& rhs) {
589 if ((lhs.match & mask) != (rhs.match & mask))
590 return (lhs.match & mask) < (rhs.match & mask);
591 return lhs.match < rhs.match;
592 }
593 };
594 std::sort(instructions.begin(), instructions.end(), cmp(buckets-1));
595
596 opcode_map.resize(buckets);
597 opcode_store.resize(instructions.size() + 1);
598
599 size_t j = 0;
600 for (size_t b = 0, i = 0; b < buckets; b++)
601 {
602 opcode_map[b] = &opcode_store[j];
603 while (i < instructions.size() && b == (instructions[i].match & (buckets-1)))
604 opcode_store[j++] = instructions[i++];
605 }
606
607 assert(j == opcode_store.size()-1);
608 opcode_store[j].match = opcode_store[j].mask = 0;
609 opcode_store[j].rv32 = &illegal_instruction;
610 opcode_store[j].rv64 = &illegal_instruction;
611 }
612
613 void processor_t::register_extension(extension_t* x)
614 {
615 for (auto insn : x->get_instructions())
616 register_insn(insn);
617 build_opcode_map();
618 for (auto disasm_insn : x->get_disasms())
619 disassembler->add_insn(disasm_insn);
620 if (ext != NULL)
621 throw std::logic_error("only one extension may be registered");
622 ext = x;
623 x->set_processor(this);
624 }