|
1 |
| -#include "processor.h" |
2 | 1 | #include "debug_defines.h"
|
| 2 | +#include "processor.h" |
| 3 | +// clang-format off |
3 | 4 |
|
4 | 5 | void state_t::add_csr(reg_t addr, const csr_t_p& csr)
|
5 | 6 | {
|
@@ -35,11 +36,11 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
|
35 | 36 |
|
36 | 37 | const reg_t minstretcfg_mask = !proc->extension_enabled_const(EXT_SMCNTRPMF) ? 0 :
|
37 | 38 | MHPMEVENT_MINH | MHPMEVENT_SINH | MHPMEVENT_UINH | MHPMEVENT_VSINH | MHPMEVENT_VUINH;
|
38 |
| - auto minstretcfg = std::make_shared<smcntrpmf_csr_t>(proc, CSR_MINSTRETCFG, minstretcfg_mask, 0); |
39 |
| - auto mcyclecfg = std::make_shared<smcntrpmf_csr_t>(proc, CSR_MCYCLECFG, minstretcfg_mask, 0); |
| 39 | + auto _minstretcfg = std::make_shared<smcntrpmf_csr_t>(proc, CSR_MINSTRETCFG, minstretcfg_mask, 0); |
| 40 | + auto _mcyclecfg = std::make_shared<smcntrpmf_csr_t>(proc, CSR_MCYCLECFG, minstretcfg_mask, 0); |
40 | 41 |
|
41 |
| - minstret = std::make_shared<wide_counter_csr_t>(proc, CSR_MINSTRET, minstretcfg); |
42 |
| - mcycle = std::make_shared<wide_counter_csr_t>(proc, CSR_MCYCLE, mcyclecfg); |
| 42 | + minstret = std::make_shared<wide_counter_csr_t>(proc, CSR_MINSTRET, _minstretcfg); |
| 43 | + mcycle = std::make_shared<wide_counter_csr_t>(proc, CSR_MCYCLE, _mcyclecfg); |
43 | 44 | time = std::make_shared<time_counter_csr_t>(proc, CSR_TIME);
|
44 | 45 | if (proc->extension_enabled_const(EXT_ZICNTR)) {
|
45 | 46 | add_csr(CSR_INSTRET, std::make_shared<counter_proxy_csr_t>(proc, CSR_INSTRET, minstret));
|
@@ -251,7 +252,8 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
|
251 | 252 | (proc->extension_enabled(EXT_SSTC) ? MENVCFG_STCE : 0) |
|
252 | 253 | (proc->extension_enabled(EXT_ZICFILP) ? MENVCFG_LPE : 0) |
|
253 | 254 | (proc->extension_enabled(EXT_ZICFISS) ? MENVCFG_SSE : 0) |
|
254 |
| - (proc->extension_enabled(EXT_SSDBLTRP) ? MENVCFG_DTE : 0); |
| 255 | + (proc->extension_enabled(EXT_SSDBLTRP) ? MENVCFG_DTE : 0) | |
| 256 | + (proc->extension_enabled(EXT_SMCDELEG) ? MENVCFG_CDE : 0); |
255 | 257 | menvcfg = std::make_shared<envcfg_csr_t>(proc, CSR_MENVCFG, menvcfg_mask, 0);
|
256 | 258 | if (xlen == 32) {
|
257 | 259 | add_user_csr(CSR_MENVCFG, std::make_shared<rv32_low_csr_t>(proc, CSR_MENVCFG, menvcfg));
|
@@ -373,16 +375,78 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
|
373 | 375 |
|
374 | 376 | if (proc->extension_enabled_const(EXT_SMCNTRPMF)) {
|
375 | 377 | if (xlen == 32) {
|
376 |
| - add_csr(CSR_MCYCLECFG, std::make_shared<rv32_low_csr_t>(proc, CSR_MCYCLECFG, mcyclecfg)); |
377 |
| - add_csr(CSR_MCYCLECFGH, std::make_shared<rv32_high_csr_t>(proc, CSR_MCYCLECFGH, mcyclecfg)); |
378 |
| - add_csr(CSR_MINSTRETCFG, std::make_shared<rv32_low_csr_t>(proc, CSR_MINSTRETCFG, minstretcfg)); |
379 |
| - add_csr(CSR_MINSTRETCFGH, std::make_shared<rv32_high_csr_t>(proc, CSR_MINSTRETCFGH, minstretcfg)); |
| 378 | + add_csr(CSR_MCYCLECFG, mcyclecfg = std::make_shared<rv32_low_csr_t>(proc, CSR_MCYCLECFG, _mcyclecfg)); |
| 379 | + add_csr(CSR_MCYCLECFGH, std::make_shared<rv32_high_csr_t>(proc, CSR_MCYCLECFGH, _mcyclecfg)); |
| 380 | + add_csr(CSR_MINSTRETCFG, minstretcfg = std::make_shared<rv32_low_csr_t>(proc, CSR_MINSTRETCFG, _minstretcfg)); |
| 381 | + add_csr(CSR_MINSTRETCFGH, std::make_shared<rv32_high_csr_t>(proc, CSR_MINSTRETCFGH, _minstretcfg)); |
380 | 382 | } else {
|
381 |
| - add_csr(CSR_MCYCLECFG, mcyclecfg); |
382 |
| - add_csr(CSR_MINSTRETCFG, minstretcfg); |
| 383 | + add_csr(CSR_MCYCLECFG, mcyclecfg = _mcyclecfg); |
| 384 | + add_csr(CSR_MINSTRETCFG, minstretcfg = _minstretcfg); |
383 | 385 | }
|
384 | 386 | }
|
385 | 387 |
|
386 | 388 | const reg_t srmcfg_mask = SRMCFG_MCID | SRMCFG_RCID;
|
387 | 389 | add_const_ext_csr(EXT_SSQOSID, CSR_SRMCFG, std::make_shared<srmcfg_csr_t>(proc, CSR_SRMCFG, srmcfg_mask, 0));
|
| 390 | + |
| 391 | + if (proc->extension_enabled_const(EXT_SMCDELEG) && proc->extension_enabled_const(EXT_SSCSRIND)) { |
| 392 | + add_supervisor_csr(CSR_SCOUNTINHIBIT, std::make_shared<scountinhibit_csr_t>(proc, CSR_SCOUNTINHIBIT)); |
| 393 | + auto sireg = std::dynamic_pointer_cast<virtualized_indirect_csr_t>(csrmap.at(CSR_SIREG)); |
| 394 | + auto sireg2 = std::dynamic_pointer_cast<virtualized_indirect_csr_t>(csrmap.at(CSR_SIREG2)); |
| 395 | + auto sireg3 = std::dynamic_pointer_cast<virtualized_indirect_csr_t>(csrmap.at(CSR_SIREG3)); |
| 396 | + auto sireg4 = std::dynamic_pointer_cast<virtualized_indirect_csr_t>(csrmap.at(CSR_SIREG4)); |
| 397 | + auto sireg5 = std::dynamic_pointer_cast<virtualized_indirect_csr_t>(csrmap.at(CSR_SIREG5)); |
| 398 | + auto sireg6 = std::dynamic_pointer_cast<virtualized_indirect_csr_t>(csrmap.at(CSR_SIREG6)); |
| 399 | + auto add_proxy = [&proc, this](std::shared_ptr<virtualized_indirect_csr_t> ireg, |
| 400 | + reg_t select, |
| 401 | + reg_t csr_proxy) { |
| 402 | + assert(ireg); |
| 403 | + const auto exists = csrmap.find(csr_proxy) != csrmap.end(); |
| 404 | + const auto dummy = std::make_shared<basic_csr_t>(proc, 0xdeafbeef, 0); |
| 405 | + |
| 406 | + auto smc_obj_orig = std::make_shared<smcdeleg_indir_csr_t>( |
| 407 | + proc, ireg->address, select, exists ? csrmap.at(csr_proxy) : dummy , !exists); |
| 408 | + auto orig_csr = std::dynamic_pointer_cast<sscsrind_reg_csr_t>(ireg->get_orig_csr()); |
| 409 | + assert(orig_csr); |
| 410 | + orig_csr->add_ireg_proxy(select, smc_obj_orig); |
| 411 | + |
| 412 | + auto smc_obj_virt = std::make_shared<smcdeleg_indir_csr_t>( |
| 413 | + proc, ireg->address + 0x100, select, exists ? csrmap.at(csr_proxy) : dummy, !exists); |
| 414 | + auto virt_csr = std::dynamic_pointer_cast<sscsrind_reg_csr_t>(ireg->get_virt_csr()); |
| 415 | + assert(virt_csr); |
| 416 | + virt_csr->add_ireg_proxy(select, smc_obj_virt); |
| 417 | + }; |
| 418 | + |
| 419 | + // We need to add all CSRs to be able to throw virtual on them, otherwise when csrind |
| 420 | + // looks for the select value it won't find any csr and thus throw illegal. |
| 421 | + // The spec states that an access to any sireg* in VS mode should raise virtual if menvcfg.cde = 1. |
| 422 | + // Most likely the motivation for this is to not leak information about which extensions the |
| 423 | + // underlying machine has implemented. |
| 424 | + add_proxy(sireg, SISELECT_SMCDELEG_START, CSR_MCYCLE); |
| 425 | + add_proxy(sireg, SISELECT_SMCDELEG_UNUSED, 0xDEADBEEF); |
| 426 | + add_proxy(sireg, SISELECT_SMCDELEG_INSTRET, CSR_MINSTRET); |
| 427 | + |
| 428 | + add_proxy(sireg2, SISELECT_SMCDELEG_START, CSR_MCYCLECFG); |
| 429 | + add_proxy(sireg2, SISELECT_SMCDELEG_UNUSED, 0xDEADBEEF); |
| 430 | + add_proxy(sireg2, SISELECT_SMCDELEG_INSTRETCFG, CSR_MINSTRETCFG); |
| 431 | + |
| 432 | + add_proxy(sireg4, SISELECT_SMCDELEG_START, CSR_MCYCLEH); |
| 433 | + add_proxy(sireg4, SISELECT_SMCDELEG_UNUSED, 0xDEADBEEF); |
| 434 | + add_proxy(sireg4, SISELECT_SMCDELEG_INSTRET, CSR_MINSTRETH); |
| 435 | + |
| 436 | + add_proxy(sireg5, SISELECT_SMCDELEG_START, CSR_MCYCLECFGH); |
| 437 | + add_proxy(sireg5, SISELECT_SMCDELEG_UNUSED, 0xDEADBEEF); |
| 438 | + add_proxy(sireg5, SISELECT_SMCDELEG_INSTRETCFG, CSR_MINSTRETCFGH); |
| 439 | + |
| 440 | + // Dummies... |
| 441 | + for (auto i = 0; i < 32; i++){ |
| 442 | + add_proxy(sireg3, SISELECT_SMCDELEG_START+i, 0xDEADBEEF); |
| 443 | + add_proxy(sireg6, SISELECT_SMCDELEG_START+i, 0xDEADBEEF); |
| 444 | + } |
| 445 | + for (auto cnt = 0; cnt < 29; cnt++) { |
| 446 | + add_proxy(sireg, SISELECT_SMCDELEG_HPMCOUNTER_3 + cnt, CSR_HPMCOUNTER3 + cnt); |
| 447 | + add_proxy(sireg2, SISELECT_SMCDELEG_HPMEVENT_3 + cnt, CSR_MHPMEVENT3 + cnt); |
| 448 | + add_proxy(sireg4, SISELECT_SMCDELEG_HPMCOUNTER_3 + cnt, CSR_HPMCOUNTER3H + cnt); |
| 449 | + add_proxy(sireg5, SISELECT_SMCDELEG_HPMEVENT_3 + cnt, CSR_MHPMEVENT3H + cnt); |
| 450 | + } |
| 451 | + } |
388 | 452 | }
|
0 commit comments