1 // See LICENSE for license details.
2
3 #include "arith.h"
4 #include "processor.h"
5 #include "extension.h"
6 #include "common.h"
7 #include "config.h"
8 #include "simif.h"
9 #include "mmu.h"
10 #include "disasm.h"
11 #include "platform.h"
12 #include <cinttypes>
13 #include <cmath>
14 #include <cstdlib>
15 #include <iostream>
16 #include <iomanip>
17 #include <assert.h>
18 #include <limits.h>
19 #include <stdexcept>
20 #include <string>
21 #include <algorithm>
22
23 #undef STATE
24 #define STATE state
25
processor_t(const char * isa,const char * priv,const char * varch,simif_t * sim,uint32_t id,bool halt_on_reset,FILE * log_file,std::ostream & sout_)26 processor_t::processor_t(const char* isa, const char* priv, const char* varch,
27 simif_t* sim, uint32_t id, bool halt_on_reset,
28 FILE* log_file, std::ostream& sout_)
29 : debug(false), halt_request(HR_NONE), sim(sim), id(id), xlen(0),
30 histogram_enabled(false), log_commits_enabled(false),
31 log_file(log_file), sout_(sout_.rdbuf()), halt_on_reset(halt_on_reset),
32 extension_table(256, false), impl_table(256, false), last_pc(1), executions(1)
33 {
34 VU.p = this;
35
36 parse_isa_string(isa);
37 parse_priv_string(priv);
38 parse_varch_string(varch);
39
40 register_base_instructions();
41 mmu = new mmu_t(sim, this);
42
43 disassembler = new disassembler_t(max_xlen);
44 for (auto e : custom_extensions)
45 for (auto disasm_insn : e.second->get_disasms())
46 disassembler->add_insn(disasm_insn);
47
48 set_pmp_granularity(1 << PMP_SHIFT);
49 set_pmp_num(state.max_pmp);
50
51 if (max_xlen == 32)
52 set_mmu_capability(IMPL_MMU_SV32);
53 else if (max_xlen == 64)
54 set_mmu_capability(IMPL_MMU_SV48);
55
56 reset();
57 }
58
~processor_t()59 processor_t::~processor_t()
60 {
61 #ifdef RISCV_ENABLE_HISTOGRAM
62 if (histogram_enabled)
63 {
64 fprintf(stderr, "PC Histogram size:%zu\n", pc_histogram.size());
65 for (auto it : pc_histogram)
66 fprintf(stderr, "%0" PRIx64 " %" PRIu64 "\n", it.first, it.second);
67 }
68 #endif
69
70 delete mmu;
71 delete disassembler;
72 }
73
bad_option_string(const char * option,const char * value,const char * msg)74 static void bad_option_string(const char *option, const char *value,
75 const char *msg)
76 {
77 fprintf(stderr, "error: bad %s option '%s'. %s\n", option, value, msg);
78 abort();
79 }
80
bad_isa_string(const char * isa,const char * msg)81 static void bad_isa_string(const char* isa, const char* msg)
82 {
83 bad_option_string("--isa", isa, msg);
84 }
85
bad_priv_string(const char * priv)86 static void bad_priv_string(const char* priv)
87 {
88 fprintf(stderr, "error: bad --priv option %s\n", priv);
89 abort();
90 }
91
bad_varch_string(const char * varch,const char * msg)92 static void bad_varch_string(const char* varch, const char *msg)
93 {
94 bad_option_string("--varch", varch, msg);
95 }
96
get_string_token(std::string str,const char delimiter,size_t & pos)97 static std::string get_string_token(std::string str, const char delimiter, size_t& pos)
98 {
99 size_t _pos = pos;
100 while (pos < str.length() && str[pos] != delimiter) ++pos;
101 return str.substr(_pos, pos - _pos);
102 }
103
get_int_token(std::string str,const char delimiter,size_t & pos)104 static int get_int_token(std::string str, const char delimiter, size_t& pos)
105 {
106 size_t _pos = pos;
107 while (pos < str.length() && str[pos] != delimiter) {
108 if (!isdigit(str[pos]))
109 bad_varch_string(str.c_str(), "Unsupported value"); // An integer is expected
110 ++pos;
111 }
112 return (pos == _pos) ? 0 : stoi(str.substr(_pos, pos - _pos));
113 }
114
check_pow2(int val)115 static bool check_pow2(int val)
116 {
117 return ((val & (val - 1))) == 0;
118 }
119
parse_varch_string(const char * s)120 void processor_t::parse_varch_string(const char* s)
121 {
122 std::string str, tmp;
123 for (const char *r = s; *r; r++)
124 str += std::tolower(*r);
125
126 size_t pos = 0;
127 size_t len = str.length();
128 int vlen = 0;
129 int elen = 0;
130 int vstart_alu = 0;
131
132 while (pos < len) {
133 std::string attr = get_string_token(str, ':', pos);
134
135 ++pos;
136
137 if (attr == "vlen")
138 vlen = get_int_token(str, ',', pos);
139 else if (attr == "elen")
140 elen = get_int_token(str, ',', pos);
141 else if (attr == "vstartalu")
142 vstart_alu = get_int_token(str, ',', pos);
143 else
144 bad_varch_string(s, "Unsupported token");
145
146 ++pos;
147 }
148
149 // The integer should be the power of 2
150 if (!check_pow2(vlen) || !check_pow2(elen)){
151 bad_varch_string(s, "The integer value should be the power of 2");
152 }
153
154 /* Vector spec requirements. */
155 if (vlen < elen)
156 bad_varch_string(s, "vlen must be >= elen");
157
158 /* spike requirements. */
159 if (vlen > 4096)
160 bad_varch_string(s, "vlen must be <= 4096");
161
162 VU.VLEN = vlen;
163 VU.ELEN = elen;
164 VU.vlenb = vlen / 8;
165 VU.vstart_alu = vstart_alu;
166 }
167
strtolower(const char * str)168 static std::string strtolower(const char* str)
169 {
170 std::string res;
171 for (const char *r = str; *r; r++)
172 res += std::tolower(*r);
173 return res;
174 }
175
parse_priv_string(const char * str)176 void processor_t::parse_priv_string(const char* str)
177 {
178 std::string lowercase = strtolower(str);
179 bool user = false, supervisor = false;
180
181 if (lowercase == "m")
182 ;
183 else if (lowercase == "mu")
184 user = true;
185 else if (lowercase == "msu")
186 user = supervisor = true;
187 else
188 bad_priv_string(str);
189
190 if (user) {
191 max_isa |= reg_t(user) << ('u' - 'a');
192 extension_table['U'] = true;
193 }
194
195 if (supervisor) {
196 max_isa |= reg_t(supervisor) << ('s' - 'a');
197 extension_table['S'] = true;
198 }
199 }
200
parse_isa_string(const char * str)201 void processor_t::parse_isa_string(const char* str)
202 {
203 isa_string = strtolower(str);
204 const char* all_subsets = "imafdqchp"
205 #ifdef __SIZEOF_INT128__
206 "v"
207 #endif
208 "";
209
210 max_isa = reg_t(2) << 62;
211 if (isa_string.compare(0, 4, "rv32") == 0)
212 max_xlen = 32, max_isa = reg_t(1) << 30;
213 else if (isa_string.compare(0, 4, "rv64") == 0)
214 max_xlen = 64;
215 else
216 bad_isa_string(str, "Spike supports either RV32I or RV64I");
217 if (isa_string[4] == 'g')
218 isa_string = isa_string.substr(0, 4) + "imafd" + isa_string.substr(5);
219 if (isa_string[4] != 'i')
220 bad_isa_string(str, "'I' extension is required");
221
222 auto p = isa_string.begin();
223 for (p += 4; islower(*p) && !strchr("zsx", *p); ++p) {
224 while (*all_subsets && (*p != *all_subsets))
225 ++all_subsets;
226 if (!*all_subsets)
227 bad_isa_string(str, "Wrong order");
228 switch (*p) {
229 case 'p': extension_table[EXT_ZBPBO] = true;
230 extension_table[EXT_ZPN] = true;
231 extension_table[EXT_ZPSFOPERAND] = true;
232 extension_table[EXT_ZMMUL] = true; break;
233 case 'q': max_isa |= 1L << ('d' - 'a');
234 case 'd': max_isa |= 1L << ('f' - 'a');
235 }
236 max_isa |= 1L << (*p - 'a');
237 extension_table[toupper(*p)] = true;
238 while (isdigit(*(p + 1))) {
239 ++p; // skip major version, point, and minor version if presented
240 if (*(p + 1) == 'p') ++p;
241 }
242 p += *(p + 1) == '_'; // underscores may be used to improve readability
243 }
244
245 while (islower(*p) || (*p == '_')) {
246 p += *p == '_'; // first underscore is optional
247 auto end = p;
248 do ++end; while (*end && *end != '_');
249 auto ext_str = std::string(p, end);
250 if (ext_str == "zfh") {
251 if (!((max_isa >> ('f' - 'a')) & 1))
252 bad_isa_string(str, "'Zfh' extension requires 'F'");
253 extension_table[EXT_ZFH] = true;
254 } else if (ext_str == "zicsr") {
255 // Spike necessarily has Zicsr, because
256 // Zicsr is implied by the privileged architecture
257 } else if (ext_str == "zmmul") {
258 extension_table[EXT_ZMMUL] = true;
259 } else if (ext_str == "zba") {
260 extension_table[EXT_ZBA] = true;
261 } else if (ext_str == "zbb") {
262 extension_table[EXT_ZBB] = true;
263 } else if (ext_str == "zbc") {
264 extension_table[EXT_ZBC] = true;
265 } else if (ext_str == "zbs") {
266 extension_table[EXT_ZBS] = true;
267 } else if (ext_str == "zbkb") {
268 extension_table[EXT_ZBKB] = true;
269 } else if (ext_str == "zbkc") {
270 extension_table[EXT_ZBKC] = true;
271 } else if (ext_str == "zbkx") {
272 extension_table[EXT_ZBKX] = true;
273 } else if (ext_str == "zk") {
274 extension_table[EXT_ZBKB] = true;
275 extension_table[EXT_ZBKC] = true;
276 extension_table[EXT_ZBKX] = true;
277 extension_table[EXT_ZKND] = true;
278 extension_table[EXT_ZKNE] = true;
279 extension_table[EXT_ZKNH] = true;
280 extension_table[EXT_ZKR] = true;
281 } else if (ext_str == "zkn") {
282 extension_table[EXT_ZBKB] = true;
283 extension_table[EXT_ZBKC] = true;
284 extension_table[EXT_ZBKX] = true;
285 extension_table[EXT_ZKND] = true;
286 extension_table[EXT_ZKNE] = true;
287 extension_table[EXT_ZKNH] = true;
288 } else if (ext_str == "zknd") {
289 extension_table[EXT_ZKND] = true;
290 } else if (ext_str == "zkne") {
291 extension_table[EXT_ZKNE] = true;
292 } else if (ext_str == "zknh") {
293 extension_table[EXT_ZKNH] = true;
294 } else if (ext_str == "zks") {
295 extension_table[EXT_ZBKB] = true;
296 extension_table[EXT_ZBKC] = true;
297 extension_table[EXT_ZBKX] = true;
298 extension_table[EXT_ZKSED] = true;
299 extension_table[EXT_ZKSH] = true;
300 } else if (ext_str == "zksed") {
301 extension_table[EXT_ZKSED] = true;
302 } else if (ext_str == "zksh") {
303 extension_table[EXT_ZKSH] = true;
304 } else if (ext_str == "zkr") {
305 extension_table[EXT_ZKR] = true;
306 } else if (ext_str == "zkt") {
307 } else if (ext_str == "svnapot") {
308 extension_table[EXT_SVNAPOT] = true;
309 } else if (ext_str == "svpbmt") {
310 extension_table[EXT_SVPBMT] = true;
311 } else if (ext_str == "svinval") {
312 extension_table[EXT_SVINVAL] = true;
313 } else if (ext_str[0] == 'x') {
314 max_isa |= 1L << ('x' - 'a');
315 extension_table[toupper('x')] = true;
316 if (ext_str == "xbitmanip") {
317 extension_table[EXT_XBITMANIP] = true;
318 } else if (ext_str.size() == 1) {
319 bad_isa_string(str, "single 'X' is not a proper name");
320 } else if (ext_str != "xdummy") {
321 register_extension(find_extension(ext_str.substr(1).c_str())());
322 }
323 } else {
324 bad_isa_string(str, ("unsupported extension: " + ext_str).c_str());
325 }
326 p = end;
327 }
328 if (*p) {
329 bad_isa_string(str, ("can't parse: " + std::string(p, isa_string.end())).c_str());
330 }
331 }
332
xlen_to_uxl(int xlen)333 static int xlen_to_uxl(int xlen)
334 {
335 if (xlen == 32)
336 return 1;
337 if (xlen == 64)
338 return 2;
339 abort();
340 }
341
reset(processor_t * const proc,reg_t max_isa)342 void state_t::reset(processor_t* const proc, reg_t max_isa)
343 {
344 pc = DEFAULT_RSTVEC;
345 XPR.reset();
346 FPR.reset();
347
348 // This assumes xlen is always max_xlen, which is true today (see
349 // mstatus_csr_t::unlogged_write()):
350 auto xlen = proc->get_max_xlen();
351
352 prv = PRV_M;
353 v = false;
354 csrmap[CSR_MISA] = misa = std::make_shared<misa_csr_t>(proc, CSR_MISA, max_isa);
355 csrmap[CSR_MSTATUS] = mstatus = std::make_shared<mstatus_csr_t>(proc, CSR_MSTATUS);
356 if (xlen == 32) csrmap[CSR_MSTATUSH] = std::make_shared<mstatush_csr_t>(proc, CSR_MSTATUSH, mstatus);
357 csrmap[CSR_MEPC] = mepc = std::make_shared<epc_csr_t>(proc, CSR_MEPC);
358 csrmap[CSR_MTVAL] = mtval = std::make_shared<basic_csr_t>(proc, CSR_MTVAL, 0);
359 csrmap[CSR_MSCRATCH] = std::make_shared<basic_csr_t>(proc, CSR_MSCRATCH, 0);
360 csrmap[CSR_MTVEC] = mtvec = std::make_shared<tvec_csr_t>(proc, CSR_MTVEC);
361 csrmap[CSR_MCAUSE] = mcause = std::make_shared<cause_csr_t>(proc, CSR_MCAUSE);
362 csrmap[CSR_MINSTRET] = minstret = std::make_shared<minstret_csr_t>(proc, CSR_MINSTRET);
363 csrmap[CSR_MCYCLE] = std::make_shared<proxy_csr_t>(proc, CSR_MCYCLE, minstret);
364 csrmap[CSR_INSTRET] = std::make_shared<counter_proxy_csr_t>(proc, CSR_INSTRET, minstret);
365 csrmap[CSR_CYCLE] = std::make_shared<counter_proxy_csr_t>(proc, CSR_CYCLE, minstret);
366 if (xlen == 32) {
367 minstreth_csr_t_p minstreth;
368 csrmap[CSR_MINSTRETH] = minstreth = std::make_shared<minstreth_csr_t>(proc, CSR_MINSTRETH, minstret);
369 csrmap[CSR_MCYCLEH] = std::make_shared<proxy_csr_t>(proc, CSR_MCYCLEH, minstreth);
370 csrmap[CSR_INSTRETH] = std::make_shared<counter_proxy_csr_t>(proc, CSR_INSTRETH, minstreth);
371 csrmap[CSR_CYCLEH] = std::make_shared<counter_proxy_csr_t>(proc, CSR_CYCLEH, minstreth);
372 }
373 for (reg_t i=3; i<=31; ++i) {
374 const reg_t which_mevent = CSR_MHPMEVENT3 + i - 3;
375 const reg_t which_mcounter = CSR_MHPMCOUNTER3 + i - 3;
376 const reg_t which_mcounterh = CSR_MHPMCOUNTER3H + i - 3;
377 const reg_t which_counter = CSR_HPMCOUNTER3 + i - 3;
378 const reg_t which_counterh = CSR_HPMCOUNTER3H + i - 3;
379 auto mevent = std::make_shared<const_csr_t>(proc, which_mevent, 0);
380 auto mcounter = std::make_shared<const_csr_t>(proc, which_mcounter, 0);
381 auto counter = std::make_shared<counter_proxy_csr_t>(proc, which_counter, mcounter);
382 csrmap[which_mevent] = mevent;
383 csrmap[which_mcounter] = mcounter;
384 csrmap[which_counter] = counter;
385 if (xlen == 32) {
386 auto mcounterh = std::make_shared<const_csr_t>(proc, which_mcounterh, 0);
387 auto counterh = std::make_shared<counter_proxy_csr_t>(proc, which_counterh, mcounterh);
388 csrmap[which_mcounterh] = mcounterh;
389 csrmap[which_counterh] = counterh;
390 }
391 }
392 csrmap[CSR_MCOUNTINHIBIT] = std::make_shared<const_csr_t>(proc, CSR_MCOUNTINHIBIT, 0);
393 csrmap[CSR_MIE] = mie = std::make_shared<mie_csr_t>(proc, CSR_MIE);
394 csrmap[CSR_MIP] = mip = std::make_shared<mip_csr_t>(proc, CSR_MIP);
395 auto sip_sie_accr = std::make_shared<generic_int_accessor_t>(this,
396 ~MIP_HS_MASK, // read_mask
397 MIP_SSIP, // ip_write_mask
398 ~MIP_HS_MASK, // ie_write_mask
399 true, // mask_mideleg
400 false, // mask_hideleg
401 0); // shiftamt
402
403 auto hip_hie_accr = std::make_shared<generic_int_accessor_t>(this,
404 MIP_HS_MASK, // read_mask
405 MIP_VSSIP, // ip_write_mask
406 MIP_HS_MASK, // ie_write_mask
407 false, // mask_mideleg
408 false, // mask_hideleg
409 0);
410
411 auto hvip_accr = std::make_shared<generic_int_accessor_t>(this,
412 MIP_VS_MASK, // read_mask
413 MIP_VS_MASK, // ip_write_mask
414 MIP_VS_MASK, // ie_write_mask
415 false, // mask_mideleg
416 false, // mask_hideleg
417 0); // shiftamt
418
419 auto vsip_vsie_accr = std::make_shared<generic_int_accessor_t>(this,
420 MIP_VS_MASK, // read_mask
421 MIP_VSSIP, // ip_write_mask
422 MIP_VS_MASK, // ie_write_mask
423 false, // mask_mideleg
424 true, // mask_hideleg
425 1); // shiftamt
426
427 auto nonvirtual_sip = std::make_shared<mip_proxy_csr_t>(proc, CSR_SIP, sip_sie_accr);
428 auto vsip = std::make_shared<mip_proxy_csr_t>(proc, CSR_VSIP, vsip_vsie_accr);
429 csrmap[CSR_VSIP] = vsip;
430 csrmap[CSR_SIP] = std::make_shared<virtualized_csr_t>(proc, nonvirtual_sip, vsip);
431 csrmap[CSR_HIP] = std::make_shared<mip_proxy_csr_t>(proc, CSR_HIP, hip_hie_accr);
432 csrmap[CSR_HVIP] = std::make_shared<mip_proxy_csr_t>(proc, CSR_HVIP, hvip_accr);
433
434 auto nonvirtual_sie = std::make_shared<mie_proxy_csr_t>(proc, CSR_SIE, sip_sie_accr);
435 auto vsie = std::make_shared<mie_proxy_csr_t>(proc, CSR_VSIE, vsip_vsie_accr);
436 csrmap[CSR_VSIE] = vsie;
437 csrmap[CSR_SIE] = std::make_shared<virtualized_csr_t>(proc, nonvirtual_sie, vsie);
438 csrmap[CSR_HIE] = std::make_shared<mie_proxy_csr_t>(proc, CSR_HIE, hip_hie_accr);
439
440 csrmap[CSR_MEDELEG] = medeleg = std::make_shared<medeleg_csr_t>(proc, CSR_MEDELEG);
441 csrmap[CSR_MIDELEG] = mideleg = std::make_shared<mideleg_csr_t>(proc, CSR_MIDELEG);
442 const reg_t counteren_mask = 0xffffffffULL;
443 mcounteren = std::make_shared<masked_csr_t>(proc, CSR_MCOUNTEREN, counteren_mask, 0);
444 if (proc->extension_enabled_const('U')) csrmap[CSR_MCOUNTEREN] = mcounteren;
445 csrmap[CSR_SCOUNTEREN] = scounteren = std::make_shared<masked_csr_t>(proc, CSR_SCOUNTEREN, counteren_mask, 0);
446 auto nonvirtual_sepc = std::make_shared<epc_csr_t>(proc, CSR_SEPC);
447 csrmap[CSR_VSEPC] = vsepc = std::make_shared<epc_csr_t>(proc, CSR_VSEPC);
448 csrmap[CSR_SEPC] = sepc = std::make_shared<virtualized_csr_t>(proc, nonvirtual_sepc, vsepc);
449 auto nonvirtual_stval = std::make_shared<basic_csr_t>(proc, CSR_STVAL, 0);
450 csrmap[CSR_VSTVAL] = vstval = std::make_shared<basic_csr_t>(proc, CSR_VSTVAL, 0);
451 csrmap[CSR_STVAL] = stval = std::make_shared<virtualized_csr_t>(proc, nonvirtual_stval, vstval);
452 auto sscratch = std::make_shared<basic_csr_t>(proc, CSR_SSCRATCH, 0);
453 auto vsscratch = std::make_shared<basic_csr_t>(proc, CSR_VSSCRATCH, 0);
454 // Note: if max_isa does not include H, we don't really need this virtualized_csr_t at all (though it doesn't hurt):
455 csrmap[CSR_SSCRATCH] = std::make_shared<virtualized_csr_t>(proc, sscratch, vsscratch);
456 csrmap[CSR_VSSCRATCH] = vsscratch;
457 auto nonvirtual_stvec = std::make_shared<tvec_csr_t>(proc, CSR_STVEC);
458 csrmap[CSR_VSTVEC] = vstvec = std::make_shared<tvec_csr_t>(proc, CSR_VSTVEC);
459 csrmap[CSR_STVEC] = stvec = std::make_shared<virtualized_csr_t>(proc, nonvirtual_stvec, vstvec);
460 auto nonvirtual_satp = std::make_shared<satp_csr_t>(proc, CSR_SATP);
461 csrmap[CSR_VSATP] = vsatp = std::make_shared<base_atp_csr_t>(proc, CSR_VSATP);
462 csrmap[CSR_SATP] = satp = std::make_shared<virtualized_satp_csr_t>(proc, nonvirtual_satp, vsatp);
463 auto nonvirtual_scause = std::make_shared<cause_csr_t>(proc, CSR_SCAUSE);
464 csrmap[CSR_VSCAUSE] = vscause = std::make_shared<cause_csr_t>(proc, CSR_VSCAUSE);
465 csrmap[CSR_SCAUSE] = scause = std::make_shared<virtualized_csr_t>(proc, nonvirtual_scause, vscause);
466 csrmap[CSR_MTVAL2] = mtval2 = std::make_shared<hypervisor_csr_t>(proc, CSR_MTVAL2);
467 csrmap[CSR_MTINST] = mtinst = std::make_shared<hypervisor_csr_t>(proc, CSR_MTINST);
468 const reg_t hstatus_init = set_field((reg_t)0, HSTATUS_VSXL, xlen_to_uxl(proc->get_const_xlen()));
469 const reg_t hstatus_mask = HSTATUS_VTSR | HSTATUS_VTW
470 | (proc->supports_impl(IMPL_MMU) ? HSTATUS_VTVM : 0)
471 | HSTATUS_HU | HSTATUS_SPVP | HSTATUS_SPV | HSTATUS_GVA;
472 csrmap[CSR_HSTATUS] = hstatus = std::make_shared<masked_csr_t>(proc, CSR_HSTATUS, hstatus_mask, hstatus_init);
473 csrmap[CSR_HGEIE] = std::make_shared<const_csr_t>(proc, CSR_HGEIE, 0);
474 csrmap[CSR_HGEIP] = std::make_shared<const_csr_t>(proc, CSR_HGEIP, 0);
475 csrmap[CSR_HIDELEG] = hideleg = std::make_shared<masked_csr_t>(proc, CSR_HIDELEG, MIP_VS_MASK, 0);
476 const reg_t hedeleg_mask =
477 (1 << CAUSE_MISALIGNED_FETCH) |
478 (1 << CAUSE_FETCH_ACCESS) |
479 (1 << CAUSE_ILLEGAL_INSTRUCTION) |
480 (1 << CAUSE_BREAKPOINT) |
481 (1 << CAUSE_MISALIGNED_LOAD) |
482 (1 << CAUSE_LOAD_ACCESS) |
483 (1 << CAUSE_MISALIGNED_STORE) |
484 (1 << CAUSE_STORE_ACCESS) |
485 (1 << CAUSE_USER_ECALL) |
486 (1 << CAUSE_FETCH_PAGE_FAULT) |
487 (1 << CAUSE_LOAD_PAGE_FAULT) |
488 (1 << CAUSE_STORE_PAGE_FAULT);
489 csrmap[CSR_HEDELEG] = hedeleg = std::make_shared<masked_csr_t>(proc, CSR_HEDELEG, hedeleg_mask, 0);
490 csrmap[CSR_HCOUNTEREN] = hcounteren = std::make_shared<masked_csr_t>(proc, CSR_HCOUNTEREN, counteren_mask, 0);
491 csrmap[CSR_HTVAL] = htval = std::make_shared<basic_csr_t>(proc, CSR_HTVAL, 0);
492 csrmap[CSR_HTINST] = htinst = std::make_shared<basic_csr_t>(proc, CSR_HTINST, 0);
493 csrmap[CSR_HGATP] = hgatp = std::make_shared<hgatp_csr_t>(proc, CSR_HGATP);
494 auto nonvirtual_sstatus = std::make_shared<sstatus_proxy_csr_t>(proc, CSR_SSTATUS, mstatus);
495 csrmap[CSR_VSSTATUS] = vsstatus = std::make_shared<vsstatus_csr_t>(proc, CSR_VSSTATUS);
496 csrmap[CSR_SSTATUS] = sstatus = std::make_shared<sstatus_csr_t>(proc, nonvirtual_sstatus, vsstatus);
497
498 csrmap[CSR_DPC] = dpc = std::make_shared<dpc_csr_t>(proc, CSR_DPC);
499 csrmap[CSR_DSCRATCH0] = std::make_shared<debug_mode_csr_t>(proc, CSR_DSCRATCH0);
500 csrmap[CSR_DSCRATCH1] = std::make_shared<debug_mode_csr_t>(proc, CSR_DSCRATCH1);
501 csrmap[CSR_DCSR] = dcsr = std::make_shared<dcsr_csr_t>(proc, CSR_DCSR);
502
503 csrmap[CSR_TSELECT] = tselect = std::make_shared<tselect_csr_t>(proc, CSR_TSELECT);
504 memset(this->mcontrol, 0, sizeof(this->mcontrol));
505 for (auto &item : mcontrol)
506 item.type = 2;
507
508 csrmap[CSR_TDATA1] = std::make_shared<tdata1_csr_t>(proc, CSR_TDATA1);
509 csrmap[CSR_TDATA2] = tdata2 = std::make_shared<tdata2_csr_t>(proc, CSR_TDATA2, num_triggers);
510 csrmap[CSR_TDATA3] = std::make_shared<const_csr_t>(proc, CSR_TDATA3, 0);
511 debug_mode = false;
512 single_step = STEP_NONE;
513
514 for (int i=0; i < max_pmp; ++i) {
515 csrmap[CSR_PMPADDR0 + i] = pmpaddr[i] = std::make_shared<pmpaddr_csr_t>(proc, CSR_PMPADDR0 + i);
516 }
517 for (int i=0; i < max_pmp; i += xlen/8) {
518 reg_t addr = CSR_PMPCFG0 + i/4;
519 csrmap[addr] = std::make_shared<pmpcfg_csr_t>(proc, addr);
520 }
521
522 csrmap[CSR_FFLAGS] = fflags = std::make_shared<float_csr_t>(proc, CSR_FFLAGS, FSR_AEXC >> FSR_AEXC_SHIFT, 0);
523 csrmap[CSR_FRM] = frm = std::make_shared<float_csr_t>(proc, CSR_FRM, FSR_RD >> FSR_RD_SHIFT, 0);
524 assert(FSR_AEXC_SHIFT == 0); // composite_csr_t assumes fflags begins at bit 0
525 csrmap[CSR_FCSR] = std::make_shared<composite_csr_t>(proc, CSR_FCSR, frm, fflags, FSR_RD_SHIFT);
526
527 csrmap[CSR_SENTROPY] = std::make_shared<sentropy_csr_t>(proc, CSR_SENTROPY);
528
529 csrmap[CSR_MARCHID] = std::make_shared<const_csr_t>(proc, CSR_MARCHID, 5);
530 csrmap[CSR_MIMPID] = std::make_shared<const_csr_t>(proc, CSR_MIMPID, 0);
531 csrmap[CSR_MVENDORID] = std::make_shared<const_csr_t>(proc, CSR_MVENDORID, 0);
532 csrmap[CSR_MHARTID] = std::make_shared<const_csr_t>(proc, CSR_MHARTID, proc->get_id());
533
534 serialized = false;
535
536 #ifdef RISCV_ENABLE_COMMITLOG
537 log_reg_write.clear();
538 log_mem_read.clear();
539 log_mem_write.clear();
540 last_inst_priv = 0;
541 last_inst_xlen = 0;
542 last_inst_flen = 0;
543 #endif
544 }
545
reset()546 void processor_t::vectorUnit_t::reset(){
547 free(reg_file);
548 VLEN = get_vlen();
549 ELEN = get_elen();
550 reg_file = malloc(NVPR * vlenb);
551 memset(reg_file, 0, NVPR * vlenb);
552
553 auto& csrmap = p->get_state()->csrmap;
554 csrmap[CSR_VXSAT] = vxsat = std::make_shared<vxsat_csr_t>(p, CSR_VXSAT);
555 csrmap[CSR_VSTART] = vstart = std::make_shared<vector_csr_t>(p, CSR_VSTART, /*mask*/ VLEN - 1);
556 csrmap[CSR_VXRM] = vxrm = std::make_shared<vector_csr_t>(p, CSR_VXRM, /*mask*/ 0x3ul);
557 csrmap[CSR_VL] = vl = std::make_shared<vector_csr_t>(p, CSR_VL, /*mask*/ 0);
558 csrmap[CSR_VTYPE] = vtype = std::make_shared<vector_csr_t>(p, CSR_VTYPE, /*mask*/ 0);
559 csrmap[CSR_VLENB] = std::make_shared<vector_csr_t>(p, CSR_VLENB, /*mask*/ 0, /*init*/ vlenb);
560 assert(VCSR_VXSAT_SHIFT == 0); // composite_csr_t assumes vxsat begins at bit 0
561 csrmap[CSR_VCSR] = std::make_shared<composite_csr_t>(p, CSR_VCSR, vxrm, vxsat, VCSR_VXRM_SHIFT);
562
563 vtype->write_raw(0);
564 set_vl(0, 0, 0, -1); // default to illegal configuration
565 }
566
set_vl(int rd,int rs1,reg_t reqVL,reg_t newType)567 reg_t processor_t::vectorUnit_t::set_vl(int rd, int rs1, reg_t reqVL, reg_t newType){
568 int new_vlmul = 0;
569 if (vtype->read() != newType){
570 vtype->write_raw(newType);
571 vsew = 1 << (extract64(newType, 3, 3) + 3);
572 new_vlmul = int8_t(extract64(newType, 0, 3) << 5) >> 5;
573 vflmul = new_vlmul >= 0 ? 1 << new_vlmul : 1.0 / (1 << -new_vlmul);
574 vlmax = (VLEN/vsew) * vflmul;
575 vta = extract64(newType, 6, 1);
576 vma = extract64(newType, 7, 1);
577
578 vill = !(vflmul >= 0.125 && vflmul <= 8)
579 || vsew > std::min(vflmul, 1.0f) * ELEN
580 || (newType >> 8) != 0;
581
582 if (vill) {
583 vlmax = 0;
584 vtype->write_raw(UINT64_MAX << (p->get_xlen() - 1));
585 }
586 }
587
588 // set vl
589 if (vlmax == 0) {
590 vl->write_raw(0);
591 } else if (rd == 0 && rs1 == 0) {
592 vl->write_raw(vl->read() > vlmax ? vlmax : vl->read());
593 } else if (rd != 0 && rs1 == 0) {
594 vl->write_raw(vlmax);
595 } else if (rs1 != 0) {
596 vl->write_raw(reqVL > vlmax ? vlmax : reqVL);
597 }
598
599 vstart->write_raw(0);
600 setvl_count++;
601 return vl->read();
602 }
603
set_debug(bool value)604 void processor_t::set_debug(bool value)
605 {
606 debug = value;
607
608 for (auto e : custom_extensions)
609 e.second->set_debug(value);
610 }
611
set_histogram(bool value)612 void processor_t::set_histogram(bool value)
613 {
614 histogram_enabled = value;
615 #ifndef RISCV_ENABLE_HISTOGRAM
616 if (value) {
617 fprintf(stderr, "PC Histogram support has not been properly enabled;");
618 fprintf(stderr, " please re-build the riscv-isa-sim project using \"configure --enable-histogram\".\n");
619 abort();
620 }
621 #endif
622 }
623
624 #ifdef RISCV_ENABLE_COMMITLOG
enable_log_commits()625 void processor_t::enable_log_commits()
626 {
627 log_commits_enabled = true;
628 }
629 #endif
630
reset()631 void processor_t::reset()
632 {
633 xlen = max_xlen;
634 state.reset(this, max_isa);
635 state.dcsr->halt = halt_on_reset;
636 halt_on_reset = false;
637 VU.reset();
638
639 if (n_pmp > 0) {
640 // For backwards compatibility with software that is unaware of PMP,
641 // initialize PMP to permit unprivileged access to all of memory.
642 set_csr(CSR_PMPADDR0, ~reg_t(0));
643 set_csr(CSR_PMPCFG0, PMP_R | PMP_W | PMP_X | PMP_NAPOT);
644 }
645
646 for (auto e : custom_extensions) // reset any extensions
647 e.second->reset();
648
649 if (sim)
650 sim->proc_reset(id);
651 }
652
get_extension()653 extension_t* processor_t::get_extension()
654 {
655 switch (custom_extensions.size()) {
656 case 0: return NULL;
657 case 1: return custom_extensions.begin()->second;
658 default:
659 fprintf(stderr, "processor_t::get_extension() is ambiguous when multiple extensions\n");
660 fprintf(stderr, "are present!\n");
661 abort();
662 }
663 }
664
get_extension(const char * name)665 extension_t* processor_t::get_extension(const char* name)
666 {
667 auto it = custom_extensions.find(name);
668 if (it == custom_extensions.end())
669 abort();
670 return it->second;
671 }
672
set_pmp_num(reg_t n)673 void processor_t::set_pmp_num(reg_t n)
674 {
675 // check the number of pmp is in a reasonable range
676 if (n > state.max_pmp) {
677 fprintf(stderr, "error: bad number of pmp regions: '%ld' from the dtb\n", (unsigned long)n);
678 abort();
679 }
680 n_pmp = n;
681 }
682
set_pmp_granularity(reg_t gran)683 void processor_t::set_pmp_granularity(reg_t gran) {
684 // check the pmp granularity is set from dtb(!=0) and is power of 2
685 if (gran < (1 << PMP_SHIFT) || (gran & (gran - 1)) != 0) {
686 fprintf(stderr, "error: bad pmp granularity '%ld' from the dtb\n", (unsigned long)gran);
687 abort();
688 }
689
690 lg_pmp_granularity = ctz(gran);
691 }
692
set_mmu_capability(int cap)693 void processor_t::set_mmu_capability(int cap)
694 {
695 switch (cap) {
696 case IMPL_MMU_SV32:
697 set_impl(cap, true);
698 set_impl(IMPL_MMU, true);
699 break;
700 case IMPL_MMU_SV39:
701 set_impl(cap, true);
702 set_impl(IMPL_MMU, true);
703 break;
704 case IMPL_MMU_SV48:
705 set_impl(cap, true);
706 set_impl(IMPL_MMU_SV39, true);
707 set_impl(IMPL_MMU, true);
708 break;
709 default:
710 set_impl(IMPL_MMU_SV32, false);
711 set_impl(IMPL_MMU_SV39, false);
712 set_impl(IMPL_MMU_SV48, false);
713 set_impl(IMPL_MMU, false);
714 break;
715 }
716 }
717
take_interrupt(reg_t pending_interrupts)718 void processor_t::take_interrupt(reg_t pending_interrupts)
719 {
720 // Do nothing if no pending interrupts
721 if (!pending_interrupts) {
722 return;
723 }
724
725 // M-ints have higher priority over HS-ints and VS-ints
726 const reg_t mie = get_field(state.mstatus->read(), MSTATUS_MIE);
727 const reg_t m_enabled = state.prv < PRV_M || (state.prv == PRV_M && mie);
728 reg_t enabled_interrupts = pending_interrupts & ~state.mideleg->read() & -m_enabled;
729 if (enabled_interrupts == 0) {
730 // HS-ints have higher priority over VS-ints
731 const reg_t deleg_to_hs = state.mideleg->read() & ~state.hideleg->read();
732 const reg_t sie = get_field(state.sstatus->read(), MSTATUS_SIE);
733 const reg_t hs_enabled = state.v || state.prv < PRV_S || (state.prv == PRV_S && sie);
734 enabled_interrupts = pending_interrupts & deleg_to_hs & -hs_enabled;
735 if (state.v && enabled_interrupts == 0) {
736 // VS-ints have least priority and can only be taken with virt enabled
737 const reg_t deleg_to_vs = state.mideleg->read() & state.hideleg->read();
738 const reg_t vs_enabled = state.prv < PRV_S || (state.prv == PRV_S && sie);
739 enabled_interrupts = pending_interrupts & deleg_to_vs & -vs_enabled;
740 }
741 }
742
743 if (!state.debug_mode && enabled_interrupts) {
744 // nonstandard interrupts have highest priority
745 if (enabled_interrupts >> (IRQ_M_EXT + 1))
746 enabled_interrupts = enabled_interrupts >> (IRQ_M_EXT + 1) << (IRQ_M_EXT + 1);
747 // standard interrupt priority is MEI, MSI, MTI, SEI, SSI, STI
748 else if (enabled_interrupts & MIP_MEIP)
749 enabled_interrupts = MIP_MEIP;
750 else if (enabled_interrupts & MIP_MSIP)
751 enabled_interrupts = MIP_MSIP;
752 else if (enabled_interrupts & MIP_MTIP)
753 enabled_interrupts = MIP_MTIP;
754 else if (enabled_interrupts & MIP_SEIP)
755 enabled_interrupts = MIP_SEIP;
756 else if (enabled_interrupts & MIP_SSIP)
757 enabled_interrupts = MIP_SSIP;
758 else if (enabled_interrupts & MIP_STIP)
759 enabled_interrupts = MIP_STIP;
760 else if (enabled_interrupts & MIP_VSEIP)
761 enabled_interrupts = MIP_VSEIP;
762 else if (enabled_interrupts & MIP_VSSIP)
763 enabled_interrupts = MIP_VSSIP;
764 else if (enabled_interrupts & MIP_VSTIP)
765 enabled_interrupts = MIP_VSTIP;
766 else
767 abort();
768
769 throw trap_t(((reg_t)1 << (max_xlen-1)) | ctz(enabled_interrupts));
770 }
771 }
772
legalize_privilege(reg_t prv)773 reg_t processor_t::legalize_privilege(reg_t prv)
774 {
775 assert(prv <= PRV_M);
776
777 if (!extension_enabled('U'))
778 return PRV_M;
779
780 if (prv == PRV_HS || (prv == PRV_S && !extension_enabled('S')))
781 return PRV_U;
782
783 return prv;
784 }
785
set_privilege(reg_t prv)786 void processor_t::set_privilege(reg_t prv)
787 {
788 mmu->flush_tlb();
789 state.prv = legalize_privilege(prv);
790 }
791
set_virt(bool virt)792 void processor_t::set_virt(bool virt)
793 {
794 reg_t tmp, mask;
795
796 if (state.prv == PRV_M)
797 return;
798
799 if (state.v != virt) {
800 /*
801 * Ideally, we should flush TLB here but we don't need it because
802 * set_virt() is always used in conjucter with set_privilege() and
803 * set_privilege() will flush TLB unconditionally.
804 *
805 * The virtualized sstatus register also relies on this TLB flush,
806 * since changing V might change sstatus.MXR and sstatus.SUM.
807 */
808 state.v = virt;
809 }
810 }
811
enter_debug_mode(uint8_t cause)812 void processor_t::enter_debug_mode(uint8_t cause)
813 {
814 state.debug_mode = true;
815 state.dcsr->write_cause_and_prv(cause, state.prv);
816 set_privilege(PRV_M);
817 state.dpc->write(state.pc);
818 state.pc = DEBUG_ROM_ENTRY;
819 }
820
debug_output_log(std::stringstream * s)821 void processor_t::debug_output_log(std::stringstream *s)
822 {
823 if (log_file==stderr) {
824 std::ostream out(sout_.rdbuf());
825 out << s->str(); // handles command line options -d -s -l
826 } else {
827 fputs(s->str().c_str(), log_file); // handles command line option --log
828 }
829 }
830
take_trap(trap_t & t,reg_t epc)831 void processor_t::take_trap(trap_t& t, reg_t epc)
832 {
833 if (debug) {
834 std::stringstream s; // first put everything in a string, later send it to output
835 s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id
836 << ": exception " << t.name() << ", epc 0x"
837 << std::hex << std::setfill('0') << std::setw(max_xlen/4) << zext(epc, max_xlen) << std::endl;
838 if (t.has_tval())
839 s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id
840 << ": tval 0x" << std::hex << std::setfill('0') << std::setw(max_xlen/4)
841 << zext(t.get_tval(), max_xlen) << std::endl;
842 debug_output_log(&s);
843 }
844
845 if (state.debug_mode) {
846 if (t.cause() == CAUSE_BREAKPOINT) {
847 state.pc = DEBUG_ROM_ENTRY;
848 } else {
849 state.pc = DEBUG_ROM_TVEC;
850 }
851 return;
852 }
853
854 if (t.cause() == CAUSE_BREAKPOINT && (
855 (state.prv == PRV_M && state.dcsr->ebreakm) ||
856 (state.prv == PRV_S && state.dcsr->ebreaks) ||
857 (state.prv == PRV_U && state.dcsr->ebreaku))) {
858 enter_debug_mode(DCSR_CAUSE_SWBP);
859 return;
860 }
861
862 // By default, trap to M-mode, unless delegated to HS-mode or VS-mode
863 reg_t vsdeleg, hsdeleg;
864 reg_t bit = t.cause();
865 bool curr_virt = state.v;
866 bool interrupt = (bit & ((reg_t)1 << (max_xlen-1))) != 0;
867 if (interrupt) {
868 vsdeleg = (curr_virt && state.prv <= PRV_S) ? (state.mideleg->read() & state.hideleg->read()) : 0;
869 hsdeleg = (state.prv <= PRV_S) ? state.mideleg->read() : 0;
870 bit &= ~((reg_t)1 << (max_xlen-1));
871 } else {
872 vsdeleg = (curr_virt && state.prv <= PRV_S) ? (state.medeleg->read() & state.hedeleg->read()) : 0;
873 hsdeleg = (state.prv <= PRV_S) ? state.medeleg->read() : 0;
874 }
875 if (state.prv <= PRV_S && bit < max_xlen && ((vsdeleg >> bit) & 1)) {
876 // Handle the trap in VS-mode
877 reg_t vector = (state.vstvec->read() & 1) && interrupt ? 4*bit : 0;
878 state.pc = (state.vstvec->read() & ~(reg_t)1) + vector;
879 state.vscause->write((interrupt) ? (t.cause() - 1) : t.cause());
880 state.vsepc->write(epc);
881 state.vstval->write(t.get_tval());
882
883 reg_t s = state.sstatus->read();
884 s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
885 s = set_field(s, MSTATUS_SPP, state.prv);
886 s = set_field(s, MSTATUS_SIE, 0);
887 state.sstatus->write(s);
888 set_privilege(PRV_S);
889 } else if (state.prv <= PRV_S && bit < max_xlen && ((hsdeleg >> bit) & 1)) {
890 // Handle the trap in HS-mode
891 set_virt(false);
892 reg_t vector = (state.stvec->read() & 1) && interrupt ? 4*bit : 0;
893 state.pc = (state.stvec->read() & ~(reg_t)1) + vector;
894 state.scause->write(t.cause());
895 state.sepc->write(epc);
896 state.stval->write(t.get_tval());
897 state.htval->write(t.get_tval2());
898 state.htinst->write(t.get_tinst());
899
900 reg_t s = state.sstatus->read();
901 s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
902 s = set_field(s, MSTATUS_SPP, state.prv);
903 s = set_field(s, MSTATUS_SIE, 0);
904 state.sstatus->write(s);
905 if (extension_enabled('H')) {
906 s = state.hstatus->read();
907 if (curr_virt)
908 s = set_field(s, HSTATUS_SPVP, state.prv);
909 s = set_field(s, HSTATUS_SPV, curr_virt);
910 s = set_field(s, HSTATUS_GVA, t.has_gva());
911 state.hstatus->write(s);
912 }
913 set_privilege(PRV_S);
914 } else {
915 // Handle the trap in M-mode
916 set_virt(false);
917 reg_t vector = (state.mtvec->read() & 1) && interrupt ? 4*bit : 0;
918 state.pc = (state.mtvec->read() & ~(reg_t)1) + vector;
919 state.mepc->write(epc);
920 state.mcause->write(t.cause());
921 state.mtval->write(t.get_tval());
922 state.mtval2->write(t.get_tval2());
923 state.mtinst->write(t.get_tinst());
924
925 reg_t s = state.mstatus->read();
926 s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
927 s = set_field(s, MSTATUS_MPP, state.prv);
928 s = set_field(s, MSTATUS_MIE, 0);
929 s = set_field(s, MSTATUS_MPV, curr_virt);
930 s = set_field(s, MSTATUS_GVA, t.has_gva());
931 state.mstatus->write(s);
932 set_privilege(PRV_M);
933 }
934 }
935
disasm(insn_t insn)936 void processor_t::disasm(insn_t insn)
937 {
938 uint64_t bits = insn.bits() & ((1ULL << (8 * insn_length(insn.bits()))) - 1);
939 if (last_pc != state.pc || last_bits != bits) {
940 std::stringstream s; // first put everything in a string, later send it to output
941
942 #ifdef RISCV_ENABLE_COMMITLOG
943 const char* sym = get_symbol(state.pc);
944 if (sym != nullptr)
945 {
946 s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id
947 << ": >>>> " << sym << std::endl;
948 }
949 #endif
950
951 if (executions != 1) {
952 s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id
953 << ": Executed " << executions << " times" << std::endl;
954 }
955
956 s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id
957 << std::hex << ": 0x" << std::setfill('0') << std::setw(max_xlen/4)
958 << zext(state.pc, max_xlen) << " (0x" << std::setw(8) << bits << ") "
959 << disassembler->disassemble(insn) << std::endl;
960
961 debug_output_log(&s);
962
963 last_pc = state.pc;
964 last_bits = bits;
965 executions = 1;
966 } else {
967 executions++;
968 }
969 }
970
paddr_bits()971 int processor_t::paddr_bits()
972 {
973 assert(xlen == max_xlen);
974 return max_xlen == 64 ? 50 : 34;
975 }
976
set_csr(int which,reg_t val)977 void processor_t::set_csr(int which, reg_t val)
978 {
979 val = zext_xlen(val);
980 auto search = state.csrmap.find(which);
981 if (search != state.csrmap.end()) {
982 search->second->write(val);
983 return;
984 }
985 }
986
987 // Note that get_csr is sometimes called when read side-effects should not
988 // be actioned. In other words, Spike cannot currently support CSRs with
989 // side effects on reads.
get_csr(int which,insn_t insn,bool write,bool peek)990 reg_t processor_t::get_csr(int which, insn_t insn, bool write, bool peek)
991 {
992 auto search = state.csrmap.find(which);
993 if (search != state.csrmap.end()) {
994 if (!peek)
995 search->second->verify_permissions(insn, write);
996 return search->second->read();
997 }
998 // If we get here, the CSR doesn't exist. Unimplemented CSRs always throw
999 // illegal-instruction exceptions, not virtual-instruction exceptions.
1000 throw trap_illegal_instruction(insn.bits());
1001 }
1002
illegal_instruction(processor_t * p,insn_t insn,reg_t pc)1003 reg_t illegal_instruction(processor_t* p, insn_t insn, reg_t pc)
1004 {
1005 throw trap_illegal_instruction(insn.bits());
1006 }
1007
decode_insn(insn_t insn)1008 insn_func_t processor_t::decode_insn(insn_t insn)
1009 {
1010 // look up opcode in hash table
1011 size_t idx = insn.bits() % OPCODE_CACHE_SIZE;
1012 insn_desc_t desc = opcode_cache[idx];
1013
1014 if (unlikely(insn.bits() != desc.match || !(xlen == 64 ? desc.rv64 : desc.rv32))) {
1015 // fall back to linear search
1016 int cnt = 0;
1017 insn_desc_t* p = &instructions[0];
1018 while ((insn.bits() & p->mask) != p->match || !(xlen == 64 ? p->rv64 : p->rv32))
1019 p++, cnt++;
1020 desc = *p;
1021
1022 if (p->mask != 0 && p > &instructions[0]) {
1023 if (p->match != (p-1)->match && p->match != (p+1)->match) {
1024 // move to front of opcode list to reduce miss penalty
1025 while (--p >= &instructions[0])
1026 *(p+1) = *p;
1027 instructions[0] = desc;
1028 }
1029 }
1030
1031 opcode_cache[idx] = desc;
1032 opcode_cache[idx].match = insn.bits();
1033 }
1034
1035 return xlen == 64 ? desc.rv64 : desc.rv32;
1036 }
1037
register_insn(insn_desc_t desc)1038 void processor_t::register_insn(insn_desc_t desc)
1039 {
1040 instructions.push_back(desc);
1041 }
1042
build_opcode_map()1043 void processor_t::build_opcode_map()
1044 {
1045 struct cmp {
1046 bool operator()(const insn_desc_t& lhs, const insn_desc_t& rhs) {
1047 if (lhs.match == rhs.match)
1048 return lhs.mask > rhs.mask;
1049 return lhs.match > rhs.match;
1050 }
1051 };
1052 std::sort(instructions.begin(), instructions.end(), cmp());
1053
1054 for (size_t i = 0; i < OPCODE_CACHE_SIZE; i++)
1055 opcode_cache[i] = {0, 0, &illegal_instruction, &illegal_instruction};
1056 }
1057
register_extension(extension_t * x)1058 void processor_t::register_extension(extension_t* x)
1059 {
1060 for (auto insn : x->get_instructions())
1061 register_insn(insn);
1062 build_opcode_map();
1063
1064 if (disassembler)
1065 for (auto disasm_insn : x->get_disasms())
1066 disassembler->add_insn(disasm_insn);
1067
1068 if (!custom_extensions.insert(std::make_pair(x->name(), x)).second) {
1069 fprintf(stderr, "extensions must have unique names (got two named \"%s\"!)\n", x->name());
1070 abort();
1071 }
1072
1073 x->set_processor(this);
1074 }
1075
register_base_instructions()1076 void processor_t::register_base_instructions()
1077 {
1078 #define DECLARE_INSN(name, match, mask) \
1079 insn_bits_t name##_match = (match), name##_mask = (mask);
1080 #include "encoding.h"
1081 #undef DECLARE_INSN
1082
1083 #define DEFINE_INSN(name) \
1084 extern reg_t rv32_##name(processor_t*, insn_t, reg_t); \
1085 extern reg_t rv64_##name(processor_t*, insn_t, reg_t); \
1086 register_insn((insn_desc_t){ \
1087 name##_match, \
1088 name##_mask, \
1089 rv32_##name, \
1090 rv64_##name});
1091 #include "insn_list.h"
1092 #undef DEFINE_INSN
1093
1094 register_insn({0, 0, &illegal_instruction, &illegal_instruction});
1095 build_opcode_map();
1096 }
1097
load(reg_t addr,size_t len,uint8_t * bytes)1098 bool processor_t::load(reg_t addr, size_t len, uint8_t* bytes)
1099 {
1100 switch (addr)
1101 {
1102 case 0:
1103 if (len <= 4) {
1104 memset(bytes, 0, len);
1105 bytes[0] = get_field(state.mip->read(), MIP_MSIP);
1106 return true;
1107 }
1108 break;
1109 }
1110
1111 return false;
1112 }
1113
store(reg_t addr,size_t len,const uint8_t * bytes)1114 bool processor_t::store(reg_t addr, size_t len, const uint8_t* bytes)
1115 {
1116 switch (addr)
1117 {
1118 case 0:
1119 if (len <= 4) {
1120 state.mip->write_with_mask(MIP_MSIP, bytes[0] << IRQ_M_SOFT);
1121 return true;
1122 }
1123 break;
1124 }
1125
1126 return false;
1127 }
1128
trigger_updated()1129 void processor_t::trigger_updated()
1130 {
1131 mmu->flush_tlb();
1132 mmu->check_triggers_fetch = false;
1133 mmu->check_triggers_load = false;
1134 mmu->check_triggers_store = false;
1135
1136 for (unsigned i = 0; i < state.num_triggers; i++) {
1137 if (state.mcontrol[i].execute) {
1138 mmu->check_triggers_fetch = true;
1139 }
1140 if (state.mcontrol[i].load) {
1141 mmu->check_triggers_load = true;
1142 }
1143 if (state.mcontrol[i].store) {
1144 mmu->check_triggers_store = true;
1145 }
1146 }
1147 }
1148