Support 'G' in ISA strings
[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 register_base_instructions();
34 }
35
36 processor_t::~processor_t()
37 {
38 #ifdef RISCV_ENABLE_HISTOGRAM
39 if (histogram_enabled)
40 {
41 fprintf(stderr, "PC Histogram size:%lu\n", pc_histogram.size());
42 for(auto iterator = pc_histogram.begin(); iterator != pc_histogram.end(); ++iterator) {
43 fprintf(stderr, "%0lx %lu\n", (iterator->first << 2), iterator->second);
44 }
45 }
46 #endif
47
48 delete mmu;
49 delete disassembler;
50 }
51
52 static void bad_isa_string(const char* isa)
53 {
54 fprintf(stderr, "error: bad --isa option %s\n", isa);
55 abort();
56 }
57
58 void processor_t::parse_isa_string(const char* isa)
59 {
60 const char* p = isa;
61 const char* all_subsets = "IMAFDC";
62 std::string tmp;
63
64 max_xlen = 64;
65 cpuid = reg_t(2) << 62;
66
67 if (strncmp(p, "RV32", 4) == 0)
68 max_xlen = 32, cpuid = 0, 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 == 'G') { // treat "G" as "IMAFD"
77 tmp = std::string("IMAFD") + (p+1);
78 p = &tmp[0];
79 } else if (*p != 'I') {
80 bad_isa_string(isa);
81 }
82
83 cpuid |= 1L << ('S' - 'A'); // advertise support for supervisor mode
84
85 while (*p) {
86 cpuid |= 1L << (*p - 'A');
87
88 if (auto next = strchr(all_subsets, *p)) {
89 all_subsets = next + 1;
90 p++;
91 } else if (*p == 'X') {
92 const char* ext = p+1, *end = ext;
93 while (islower(*end))
94 end++;
95 register_extension(find_extension(std::string(ext, end - ext).c_str())());
96 p = end;
97 } else {
98 bad_isa_string(isa);
99 }
100 }
101
102 if (supports_extension('D') && !supports_extension('F'))
103 bad_isa_string(isa);
104 }
105
106 void state_t::reset()
107 {
108 memset(this, 0, sizeof(*this));
109 mstatus = set_field(mstatus, MSTATUS_PRV, PRV_M);
110 mstatus = set_field(mstatus, MSTATUS_PRV1, PRV_S);
111 mstatus = set_field(mstatus, MSTATUS_PRV2, PRV_S);
112 pc = DEFAULT_MTVEC + 0x100;
113 load_reservation = -1;
114 }
115
116 void processor_t::set_debug(bool value)
117 {
118 debug = value;
119 if (ext)
120 ext->set_debug(value);
121 }
122
123 void processor_t::set_histogram(bool value)
124 {
125 histogram_enabled = value;
126 #ifndef RISCV_ENABLE_HISTOGRAM
127 if (value) {
128 fprintf(stderr, "PC Histogram support has not been properly enabled;");
129 fprintf(stderr, " please re-build the riscv-isa-run project using \"configure --enable-histogram\".\n");
130 }
131 #endif
132 }
133
134 void processor_t::reset(bool value)
135 {
136 if (run == !value)
137 return;
138 run = !value;
139
140 state.reset();
141 set_csr(CSR_MSTATUS, state.mstatus);
142
143 if (ext)
144 ext->reset(); // reset the extension
145 }
146
147 void processor_t::raise_interrupt(reg_t which)
148 {
149 throw trap_t(((reg_t)1 << (max_xlen-1)) | which);
150 }
151
152 void processor_t::take_interrupt()
153 {
154 int priv = get_field(state.mstatus, MSTATUS_PRV);
155 int ie = get_field(state.mstatus, MSTATUS_IE);
156 reg_t interrupts = state.mie & state.mip;
157
158 if (priv < PRV_M || (priv == PRV_M && ie)) {
159 if (interrupts & MIP_MSIP)
160 raise_interrupt(IRQ_SOFT);
161
162 if (interrupts & MIP_MTIP)
163 raise_interrupt(IRQ_TIMER);
164
165 if (state.fromhost != 0)
166 raise_interrupt(IRQ_HOST);
167 }
168
169 if (priv < PRV_S || (priv == PRV_S && ie)) {
170 if (interrupts & MIP_SSIP)
171 raise_interrupt(IRQ_SOFT);
172
173 if (interrupts & MIP_STIP)
174 raise_interrupt(IRQ_TIMER);
175 }
176 }
177
178 void processor_t::check_timer()
179 {
180 if (sim->rtc >= state.mtimecmp)
181 state.mip |= MIP_MTIP;
182 }
183
184 void processor_t::push_privilege_stack()
185 {
186 reg_t s = state.mstatus;
187 s = set_field(s, MSTATUS_PRV2, get_field(state.mstatus, MSTATUS_PRV1));
188 s = set_field(s, MSTATUS_IE2, get_field(state.mstatus, MSTATUS_IE1));
189 s = set_field(s, MSTATUS_PRV1, get_field(state.mstatus, MSTATUS_PRV));
190 s = set_field(s, MSTATUS_IE1, get_field(state.mstatus, MSTATUS_IE));
191 s = set_field(s, MSTATUS_PRV, PRV_M);
192 s = set_field(s, MSTATUS_MPRV, 0);
193 s = set_field(s, MSTATUS_IE, 0);
194 set_csr(CSR_MSTATUS, s);
195 }
196
197 void processor_t::pop_privilege_stack()
198 {
199 reg_t s = state.mstatus;
200 s = set_field(s, MSTATUS_PRV, get_field(state.mstatus, MSTATUS_PRV1));
201 s = set_field(s, MSTATUS_IE, get_field(state.mstatus, MSTATUS_IE1));
202 s = set_field(s, MSTATUS_PRV1, get_field(state.mstatus, MSTATUS_PRV2));
203 s = set_field(s, MSTATUS_IE1, get_field(state.mstatus, MSTATUS_IE2));
204 s = set_field(s, MSTATUS_PRV2, PRV_U);
205 s = set_field(s, MSTATUS_IE2, 1);
206 set_csr(CSR_MSTATUS, s);
207 }
208
209 void processor_t::take_trap(trap_t& t, reg_t epc)
210 {
211 if (debug)
212 fprintf(stderr, "core %3d: exception %s, epc 0x%016" PRIx64 "\n",
213 id, t.name(), epc);
214
215 state.pc = DEFAULT_MTVEC + 0x40 * get_field(state.mstatus, MSTATUS_PRV);
216 push_privilege_stack();
217 yield_load_reservation();
218 state.mcause = t.cause();
219 state.mepc = epc;
220 t.side_effects(&state); // might set badvaddr etc.
221 }
222
223 void processor_t::deliver_ipi()
224 {
225 state.mip |= MIP_MSIP;
226 }
227
228 void processor_t::disasm(insn_t insn)
229 {
230 uint64_t bits = insn.bits() & ((1ULL << (8 * insn_length(insn.bits()))) - 1);
231 fprintf(stderr, "core %3d: 0x%016" PRIx64 " (0x%08" PRIx64 ") %s\n",
232 id, state.pc, bits, disassembler->disassemble(insn).c_str());
233 }
234
235 static bool validate_priv(reg_t priv)
236 {
237 return priv == PRV_U || priv == PRV_S || priv == PRV_M;
238 }
239
240 static bool validate_vm(int max_xlen, reg_t vm)
241 {
242 if (max_xlen == 64 && (vm == VM_SV39 || vm == VM_SV48))
243 return true;
244 if (max_xlen == 32 && vm == VM_SV32)
245 return true;
246 return vm == VM_MBARE;
247 }
248
249 void processor_t::set_csr(int which, reg_t val)
250 {
251 switch (which)
252 {
253 case CSR_FFLAGS:
254 dirty_fp_state;
255 state.fflags = val & (FSR_AEXC >> FSR_AEXC_SHIFT);
256 break;
257 case CSR_FRM:
258 dirty_fp_state;
259 state.frm = val & (FSR_RD >> FSR_RD_SHIFT);
260 break;
261 case CSR_FCSR:
262 dirty_fp_state;
263 state.fflags = (val & FSR_AEXC) >> FSR_AEXC_SHIFT;
264 state.frm = (val & FSR_RD) >> FSR_RD_SHIFT;
265 break;
266 case CSR_MTIME:
267 case CSR_STIMEW:
268 // this implementation ignores writes to MTIME
269 break;
270 case CSR_MTIMEH:
271 case CSR_STIMEHW:
272 // this implementation ignores writes to MTIME
273 break;
274 case CSR_TIMEW:
275 val -= sim->rtc;
276 if (xlen == 32)
277 state.sutime_delta = (uint32_t)val | (state.sutime_delta >> 32 << 32);
278 else
279 state.sutime_delta = val;
280 break;
281 case CSR_TIMEHW:
282 val = ((val << 32) - sim->rtc) >> 32;
283 state.sutime_delta = (val << 32) | (uint32_t)state.sutime_delta;
284 break;
285 case CSR_CYCLEW:
286 case CSR_INSTRETW:
287 val -= state.minstret;
288 if (xlen == 32)
289 state.suinstret_delta = (uint32_t)val | (state.suinstret_delta >> 32 << 32);
290 else
291 state.suinstret_delta = val;
292 break;
293 case CSR_CYCLEHW:
294 case CSR_INSTRETHW:
295 val = ((val << 32) - state.minstret) >> 32;
296 state.suinstret_delta = (val << 32) | (uint32_t)state.suinstret_delta;
297 break;
298 case CSR_MSTATUS: {
299 if ((val ^ state.mstatus) & (MSTATUS_VM | MSTATUS_PRV | MSTATUS_PRV1 | MSTATUS_MPRV))
300 mmu->flush_tlb();
301
302 reg_t mask = MSTATUS_IE | MSTATUS_IE1 | MSTATUS_IE2 | MSTATUS_MPRV
303 | MSTATUS_FS | (ext ? MSTATUS_XS : 0);
304
305 if (validate_vm(max_xlen, get_field(val, MSTATUS_VM)))
306 mask |= MSTATUS_VM;
307 if (validate_priv(get_field(val, MSTATUS_PRV)))
308 mask |= MSTATUS_PRV;
309 if (validate_priv(get_field(val, MSTATUS_PRV1)))
310 mask |= MSTATUS_PRV1;
311 if (validate_priv(get_field(val, MSTATUS_PRV2)))
312 mask |= MSTATUS_PRV2;
313
314 state.mstatus = (state.mstatus & ~mask) | (val & mask);
315
316 bool dirty = (state.mstatus & MSTATUS_FS) == MSTATUS_FS;
317 dirty |= (state.mstatus & MSTATUS_XS) == MSTATUS_XS;
318 if (max_xlen == 32)
319 state.mstatus = set_field(state.mstatus, MSTATUS32_SD, dirty);
320 else
321 state.mstatus = set_field(state.mstatus, MSTATUS64_SD, dirty);
322
323 // spike supports the notion of xlen < max_xlen, but current priv spec
324 // doesn't provide a mechanism to run RV32 software on an RV64 machine
325 xlen = max_xlen;
326 break;
327 }
328 case CSR_MIP: {
329 reg_t mask = MIP_SSIP | MIP_MSIP | MIP_STIP;
330 state.mip = (state.mip & ~mask) | (val & mask);
331 break;
332 }
333 case CSR_MIE: {
334 reg_t mask = MIP_SSIP | MIP_MSIP | MIP_STIP | MIP_MTIP;
335 state.mie = (state.mie & ~mask) | (val & mask);
336 break;
337 }
338 case CSR_SSTATUS: {
339 reg_t ms = state.mstatus;
340 ms = set_field(ms, MSTATUS_IE, get_field(val, SSTATUS_IE));
341 ms = set_field(ms, MSTATUS_IE1, get_field(val, SSTATUS_PIE));
342 ms = set_field(ms, MSTATUS_PRV1, get_field(val, SSTATUS_PS));
343 ms = set_field(ms, MSTATUS_FS, get_field(val, SSTATUS_FS));
344 ms = set_field(ms, MSTATUS_XS, get_field(val, SSTATUS_XS));
345 ms = set_field(ms, MSTATUS_MPRV, get_field(val, SSTATUS_MPRV));
346 return set_csr(CSR_MSTATUS, ms);
347 }
348 case CSR_SIP: {
349 reg_t mask = MIP_SSIP;
350 state.mip = (state.mip & ~mask) | (val & mask);
351 break;
352 }
353 case CSR_SIE: {
354 reg_t mask = MIP_SSIP | MIP_STIP;
355 state.mie = (state.mie & ~mask) | (val & mask);
356 break;
357 }
358 case CSR_SEPC: state.sepc = val; break;
359 case CSR_STVEC: state.stvec = val >> 2 << 2; break;
360 case CSR_SPTBR: state.sptbr = zext_xlen(val & -PGSIZE); break;
361 case CSR_SSCRATCH: state.sscratch = val; break;
362 case CSR_MEPC: state.mepc = val; break;
363 case CSR_MSCRATCH: state.mscratch = val; break;
364 case CSR_MCAUSE: state.mcause = val; break;
365 case CSR_MBADADDR: state.mbadaddr = val; break;
366 case CSR_MTIMECMP:
367 state.mip &= ~MIP_MTIP;
368 state.mtimecmp = val;
369 break;
370 case CSR_SEND_IPI: sim->send_ipi(val); break;
371 case CSR_MTOHOST:
372 if (state.tohost == 0)
373 state.tohost = val;
374 break;
375 case CSR_MFROMHOST: state.fromhost = val; break;
376 }
377 }
378
379 reg_t processor_t::get_csr(int which)
380 {
381 switch (which)
382 {
383 case CSR_FFLAGS:
384 require_fp;
385 if (!supports_extension('F'))
386 break;
387 return state.fflags;
388 case CSR_FRM:
389 require_fp;
390 if (!supports_extension('F'))
391 break;
392 return state.frm;
393 case CSR_FCSR:
394 require_fp;
395 if (!supports_extension('F'))
396 break;
397 return (state.fflags << FSR_AEXC_SHIFT) | (state.frm << FSR_RD_SHIFT);
398 case CSR_MTIME:
399 case CSR_STIME:
400 case CSR_STIMEW:
401 return sim->rtc;
402 case CSR_MTIMEH:
403 case CSR_STIMEH:
404 case CSR_STIMEHW:
405 return sim->rtc >> 32;
406 case CSR_TIME:
407 case CSR_TIMEW:
408 return sim->rtc + state.sutime_delta;
409 case CSR_CYCLE:
410 case CSR_CYCLEW:
411 case CSR_INSTRET:
412 case CSR_INSTRETW:
413 return state.minstret + state.suinstret_delta;
414 case CSR_TIMEH:
415 case CSR_TIMEHW:
416 if (xlen == 64)
417 break;
418 return (sim->rtc + state.sutime_delta) >> 32;
419 case CSR_CYCLEH:
420 case CSR_INSTRETH:
421 case CSR_CYCLEHW:
422 case CSR_INSTRETHW:
423 if (xlen == 64)
424 break;
425 return (state.minstret + state.suinstret_delta) >> 32;
426 case CSR_SSTATUS: {
427 reg_t ss = 0;
428 ss = set_field(ss, SSTATUS_IE, get_field(state.mstatus, MSTATUS_IE));
429 ss = set_field(ss, SSTATUS_PIE, get_field(state.mstatus, MSTATUS_IE1));
430 ss = set_field(ss, SSTATUS_PS, get_field(state.mstatus, MSTATUS_PRV1));
431 ss = set_field(ss, SSTATUS_FS, get_field(state.mstatus, MSTATUS_FS));
432 ss = set_field(ss, SSTATUS_XS, get_field(state.mstatus, MSTATUS_XS));
433 ss = set_field(ss, SSTATUS_MPRV, get_field(state.mstatus, MSTATUS_MPRV));
434 if (get_field(state.mstatus, MSTATUS64_SD))
435 ss = set_field(ss, (xlen == 32 ? SSTATUS32_SD : SSTATUS64_SD), 1);
436 return ss;
437 }
438 case CSR_SIP: return state.mip & (MIP_SSIP | MIP_STIP);
439 case CSR_SIE: return state.mie & (MIP_SSIP | MIP_STIP);
440 case CSR_SEPC: return state.sepc;
441 case CSR_SBADADDR: return state.sbadaddr;
442 case CSR_STVEC: return state.stvec;
443 case CSR_SCAUSE:
444 if (max_xlen > xlen)
445 return state.scause | ((state.scause >> (max_xlen-1)) << (xlen-1));
446 return state.scause;
447 case CSR_SPTBR: return state.sptbr;
448 case CSR_SASID: return 0;
449 case CSR_SSCRATCH: return state.sscratch;
450 case CSR_MSTATUS: return state.mstatus;
451 case CSR_MIP: return state.mip;
452 case CSR_MIE: return state.mie;
453 case CSR_MEPC: return state.mepc;
454 case CSR_MSCRATCH: return state.mscratch;
455 case CSR_MCAUSE: return state.mcause;
456 case CSR_MBADADDR: return state.mbadaddr;
457 case CSR_MTIMECMP: return state.mtimecmp;
458 case CSR_MCPUID: return cpuid;
459 case CSR_MIMPID: return IMPL_ROCKET;
460 case CSR_MHARTID: return id;
461 case CSR_MTVEC: return DEFAULT_MTVEC;
462 case CSR_MTDELEG: return 0;
463 case CSR_MTOHOST:
464 sim->get_htif()->tick(); // not necessary, but faster
465 return state.tohost;
466 case CSR_MFROMHOST:
467 sim->get_htif()->tick(); // not necessary, but faster
468 return state.fromhost;
469 case CSR_SEND_IPI: return 0;
470 case CSR_UARCH0:
471 case CSR_UARCH1:
472 case CSR_UARCH2:
473 case CSR_UARCH3:
474 case CSR_UARCH4:
475 case CSR_UARCH5:
476 case CSR_UARCH6:
477 case CSR_UARCH7:
478 case CSR_UARCH8:
479 case CSR_UARCH9:
480 case CSR_UARCH10:
481 case CSR_UARCH11:
482 case CSR_UARCH12:
483 case CSR_UARCH13:
484 case CSR_UARCH14:
485 case CSR_UARCH15:
486 return 0;
487 }
488 throw trap_illegal_instruction();
489 }
490
491 reg_t illegal_instruction(processor_t* p, insn_t insn, reg_t pc)
492 {
493 throw trap_illegal_instruction();
494 }
495
496 insn_func_t processor_t::decode_insn(insn_t insn)
497 {
498 // look up opcode in hash table
499 size_t idx = insn.bits() % OPCODE_CACHE_SIZE;
500 insn_desc_t desc = opcode_cache[idx];
501
502 if (unlikely(insn.bits() != desc.match)) {
503 // fall back to linear search
504 insn_desc_t* p = &instructions[0];
505 while ((insn.bits() & p->mask) != p->match)
506 p++;
507 desc = *p;
508
509 if (p->mask != 0 && p > &instructions[0]) {
510 if (p->match != (p-1)->match && p->match != (p+1)->match) {
511 // move to front of opcode list to reduce miss penalty
512 while (--p >= &instructions[0])
513 *(p+1) = *p;
514 instructions[0] = desc;
515 }
516 }
517
518 opcode_cache[idx] = desc;
519 opcode_cache[idx].match = insn.bits();
520 }
521
522 return xlen == 64 ? desc.rv64 : desc.rv32;
523 }
524
525 void processor_t::register_insn(insn_desc_t desc)
526 {
527 instructions.push_back(desc);
528 }
529
530 void processor_t::build_opcode_map()
531 {
532 struct cmp {
533 bool operator()(const insn_desc_t& lhs, const insn_desc_t& rhs) {
534 if (lhs.match == rhs.match)
535 return lhs.mask > rhs.mask;
536 return lhs.match > rhs.match;
537 }
538 };
539 std::sort(instructions.begin(), instructions.end(), cmp());
540
541 for (size_t i = 0; i < OPCODE_CACHE_SIZE; i++)
542 opcode_cache[i] = {1, 0, &illegal_instruction, &illegal_instruction};
543 }
544
545 void processor_t::register_extension(extension_t* x)
546 {
547 for (auto insn : x->get_instructions())
548 register_insn(insn);
549 build_opcode_map();
550 for (auto disasm_insn : x->get_disasms())
551 disassembler->add_insn(disasm_insn);
552 if (ext != NULL)
553 throw std::logic_error("only one extension may be registered");
554 ext = x;
555 x->set_processor(this);
556 }
557
558 void processor_t::register_base_instructions()
559 {
560 std::map<std::string, std::pair<insn_bits_t, insn_bits_t>> opcodes;
561
562 #define DECLARE_INSN(name, match, mask) \
563 opcodes[#name] = std::make_pair(match, mask);
564 #include "encoding.h"
565 #undef DECLARE_INSN
566
567 #define DEFINE_INSN(name) \
568 if (!opcodes.count(#name)) \
569 throw std::logic_error("opcode for " #name " not found"); \
570 REGISTER_INSN(this, name, opcodes[#name].first, opcodes[#name].second)
571 #include "insn_list.h"
572 #undef DEFINE_INSN
573
574 register_insn({0, 0, &illegal_instruction, &illegal_instruction});
575 build_opcode_map();
576 }