1 // See LICENSE for license details. 2 #ifndef _RISCV_CSRS_H 3 #define _RISCV_CSRS_H 4 5 // For reg_t: 6 #include "decode.h" 7 // For std::shared_ptr 8 #include <memory> 9 // For access_type: 10 #include "memtracer.h" 11 12 class processor_t; 13 struct state_t; 14 15 // Parent, abstract class for all CSRs 16 class csr_t { 17 public: 18 csr_t(processor_t* const proc, const reg_t addr); 19 20 // Throw exception if read/write disallowed. 21 virtual void verify_permissions(insn_t insn, bool write) const; 22 23 // read() returns the architectural value of this CSR. No permission 24 // checking needed or allowed. Side effects not allowed. 25 virtual reg_t read() const noexcept = 0; 26 27 // write() updates the architectural value of this CSR. No 28 // permission checking needed or allowed. 29 // Child classes must implement unlogged_write() 30 void write(const reg_t val) noexcept; 31 32 virtual ~csr_t(); 33 34 protected: 35 // Return value indicates success; false means no write actually occurred 36 virtual bool unlogged_write(const reg_t val) noexcept = 0; 37 38 // Record this CSR update (which has already happened) in the commit log 39 void log_write() const noexcept; 40 41 // Record a write to an alternate CSR (e.g. minstreth instead of minstret) 42 void log_special_write(const reg_t address, const reg_t val) const noexcept; 43 44 // What value was written to this reg? Default implementation simply 45 // calls read(), but a few CSRs are special. 46 virtual reg_t written_value() const noexcept; 47 48 processor_t* const proc; 49 state_t* const state; 50 public: 51 const reg_t address; 52 private: 53 const unsigned csr_priv; 54 const bool csr_read_only; 55 }; 56 57 typedef std::shared_ptr<csr_t> csr_t_p; 58 59 60 // Basic CSRs, with XLEN bits fully readable and writable. 61 class basic_csr_t: public csr_t { 62 public: 63 basic_csr_t(processor_t* const proc, const reg_t addr, const reg_t init); 64 virtual reg_t read() const noexcept override; 65 protected: 66 virtual bool unlogged_write(const reg_t val) noexcept override; 67 private: 68 reg_t val; 69 }; 70 71 72 class pmpaddr_csr_t: public csr_t { 73 public: 74 pmpaddr_csr_t(processor_t* const proc, const reg_t addr); 75 virtual void verify_permissions(insn_t insn, bool write) const override; 76 virtual reg_t read() const noexcept override; 77 78 // Does a 4-byte access at the specified address match this PMP entry? 79 bool match4(reg_t addr) const noexcept; 80 81 // Does the specified range match only a proper subset of this page? 82 bool subset_match(reg_t addr, reg_t len) const noexcept; 83 84 // Is the specified access allowed given the pmpcfg privileges? 85 bool access_ok(access_type type, reg_t mode) const noexcept; 86 87 protected: 88 virtual bool unlogged_write(const reg_t val) noexcept override; 89 private: 90 // Assuming this is configured as TOR, return address for top of 91 // range. Also forms bottom-of-range for next-highest pmpaddr 92 // register if that one is TOR. 93 reg_t tor_paddr() const noexcept; 94 95 // Assuming this is configured as TOR, return address for bottom of 96 // range. This is tor_paddr() from the previous pmpaddr register. 97 reg_t tor_base_paddr() const noexcept; 98 99 // Assuming this is configured as NAPOT or NA4, return mask for paddr. 100 // E.g. for 4KiB region, returns 0xffffffff_fffff000. 101 reg_t napot_mask() const noexcept; 102 103 bool next_locked_and_tor() const noexcept; 104 reg_t val; 105 friend class pmpcfg_csr_t; // so he can access cfg 106 uint8_t cfg; 107 const size_t pmpidx; 108 }; 109 110 typedef std::shared_ptr<pmpaddr_csr_t> pmpaddr_csr_t_p; 111 112 class pmpcfg_csr_t: public csr_t { 113 public: 114 pmpcfg_csr_t(processor_t* const proc, const reg_t addr); 115 virtual reg_t read() const noexcept override; 116 protected: 117 virtual bool unlogged_write(const reg_t val) noexcept override; 118 }; 119 120 121 // For CSRs that have a virtualized copy under another name. Each 122 // instance of virtualized_csr_t will read/write one of two CSRs, 123 // based on state.v. E.g. sscratch, stval, etc. 124 // 125 // Example: sscratch and vsscratch are both instances of basic_csr_t. 126 // The csrmap will contain a virtualized_csr_t under sscratch's 127 // address, plus the vsscratch basic_csr_t under its address. 128 129 class virtualized_csr_t: public csr_t { 130 public: 131 virtualized_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt); 132 133 virtual reg_t read() const noexcept override; 134 // Instead of using state.v, explicitly request original or virtual: 135 reg_t readvirt(bool virt) const noexcept; 136 protected: 137 virtual bool unlogged_write(const reg_t val) noexcept override; 138 csr_t_p orig_csr; 139 csr_t_p virt_csr; 140 }; 141 142 typedef std::shared_ptr<virtualized_csr_t> virtualized_csr_t_p; 143 144 // For mepc, sepc, and vsepc 145 class epc_csr_t: public csr_t { 146 public: 147 epc_csr_t(processor_t* const proc, const reg_t addr); 148 149 virtual reg_t read() const noexcept override; 150 protected: 151 virtual bool unlogged_write(const reg_t val) noexcept override; 152 private: 153 reg_t val; 154 }; 155 156 157 // For mtvec, stvec, and vstvec 158 class tvec_csr_t: public csr_t { 159 public: 160 tvec_csr_t(processor_t* const proc, const reg_t addr); 161 162 virtual reg_t read() const noexcept override; 163 protected: 164 virtual bool unlogged_write(const reg_t val) noexcept override; 165 private: 166 reg_t val; 167 }; 168 169 170 // For mcause, scause, and vscause 171 class cause_csr_t: public basic_csr_t { 172 public: 173 cause_csr_t(processor_t* const proc, const reg_t addr); 174 175 virtual reg_t read() const noexcept override; 176 }; 177 178 179 // For *status family of CSRs 180 class base_status_csr_t: public csr_t { 181 public: 182 base_status_csr_t(processor_t* const proc, const reg_t addr); 183 // Return true if the specified bits are not 00 (Off) 184 bool enabled(const reg_t which); 185 protected: 186 reg_t adjust_sd(const reg_t val) const noexcept; 187 void maybe_flush_tlb(const reg_t newval) noexcept; 188 const bool has_page; 189 const reg_t sstatus_write_mask; 190 const reg_t sstatus_read_mask; 191 private: 192 reg_t compute_sstatus_write_mask() const noexcept; 193 }; 194 195 typedef std::shared_ptr<base_status_csr_t> base_status_csr_t_p; 196 197 198 // For vsstatus, which is its own separate architectural register 199 // (unlike sstatus) 200 class vsstatus_csr_t: public base_status_csr_t { 201 public: 202 vsstatus_csr_t(processor_t* const proc, const reg_t addr); 203 virtual reg_t read() const noexcept override; 204 protected: 205 virtual bool unlogged_write(const reg_t val) noexcept override; 206 private: 207 reg_t val; 208 }; 209 210 typedef std::shared_ptr<vsstatus_csr_t> vsstatus_csr_t_p; 211 212 213 class sstatus_proxy_csr_t: public base_status_csr_t { 214 public: 215 sstatus_proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p mstatus); 216 virtual reg_t read() const noexcept override; 217 protected: 218 virtual bool unlogged_write(const reg_t val) noexcept override; 219 private: 220 csr_t_p mstatus; 221 }; 222 223 224 class mstatus_csr_t: public base_status_csr_t { 225 public: 226 mstatus_csr_t(processor_t* const proc, const reg_t addr); 227 virtual reg_t read() const noexcept override; 228 protected: 229 virtual bool unlogged_write(const reg_t val) noexcept override; 230 private: 231 reg_t val; 232 friend class mstatush_csr_t; 233 }; 234 235 typedef std::shared_ptr<mstatus_csr_t> mstatus_csr_t_p; 236 237 238 class mstatush_csr_t: public csr_t { 239 public: 240 mstatush_csr_t(processor_t* const proc, const reg_t addr, mstatus_csr_t_p mstatus); 241 virtual reg_t read() const noexcept override; 242 protected: 243 virtual bool unlogged_write(const reg_t val) noexcept override; 244 private: 245 mstatus_csr_t_p mstatus; 246 const reg_t mask; 247 }; 248 249 250 class sstatus_csr_t: public virtualized_csr_t { 251 public: 252 sstatus_csr_t(processor_t* const proc, base_status_csr_t_p orig, base_status_csr_t_p virt); 253 254 // Set FS, VS, or XS bits to dirty 255 void dirty(const reg_t dirties); 256 // Return true if the specified bits are not 00 (Off) 257 bool enabled(const reg_t which); 258 private: 259 base_status_csr_t_p orig_sstatus; 260 base_status_csr_t_p virt_sstatus; 261 }; 262 263 typedef std::shared_ptr<sstatus_csr_t> sstatus_csr_t_p; 264 265 266 class misa_csr_t: public basic_csr_t { 267 public: 268 misa_csr_t(processor_t* const proc, const reg_t addr, const reg_t max_isa); 269 bool extension_enabled(unsigned char ext) const noexcept; 270 bool extension_enabled_const(unsigned char ext) const noexcept; 271 protected: 272 virtual bool unlogged_write(const reg_t val) noexcept override; 273 private: 274 const reg_t max_isa; 275 const reg_t write_mask; 276 }; 277 278 typedef std::shared_ptr<misa_csr_t> misa_csr_t_p; 279 280 281 class mip_or_mie_csr_t: public csr_t { 282 public: 283 mip_or_mie_csr_t(processor_t* const proc, const reg_t addr); 284 virtual reg_t read() const noexcept override final; 285 286 void write_with_mask(const reg_t mask, const reg_t val) noexcept; 287 288 protected: 289 virtual bool unlogged_write(const reg_t val) noexcept override final; 290 reg_t val; 291 private: 292 virtual reg_t write_mask() const noexcept = 0; 293 }; 294 295 296 // mip is special because some of the bits are driven by hardware pins 297 class mip_csr_t: public mip_or_mie_csr_t { 298 public: 299 mip_csr_t(processor_t* const proc, const reg_t addr); 300 301 // Does not log. Used by external things (clint) that wiggle bits in mip. 302 void backdoor_write_with_mask(const reg_t mask, const reg_t val) noexcept; 303 private: 304 virtual reg_t write_mask() const noexcept override; 305 }; 306 307 typedef std::shared_ptr<mip_csr_t> mip_csr_t_p; 308 309 310 class mie_csr_t: public mip_or_mie_csr_t { 311 public: 312 mie_csr_t(processor_t* const proc, const reg_t addr); 313 private: 314 virtual reg_t write_mask() const noexcept override; 315 }; 316 317 typedef std::shared_ptr<mie_csr_t> mie_csr_t_p; 318 319 320 // For sip, hip, hvip, vsip, sie, hie, vsie which are all just (masked 321 // & shifted) views into mip or mie. Each pair will have one of these 322 // objects describing the view, e.g. one for sip+sie, one for hip+hie, 323 // etc. 324 class generic_int_accessor_t { 325 public: 326 generic_int_accessor_t(state_t* const state, 327 const reg_t read_mask, 328 const reg_t ip_write_mask, 329 const reg_t ie_write_mask, 330 const bool mask_mideleg, 331 const bool mask_hideleg, 332 const int shiftamt); 333 reg_t ip_read() const noexcept; 334 void ip_write(const reg_t val) noexcept; 335 reg_t ie_read() const noexcept; 336 void ie_write(const reg_t val) noexcept; 337 private: 338 state_t* const state; 339 const reg_t read_mask; 340 const reg_t ip_write_mask; 341 const reg_t ie_write_mask; 342 const bool mask_mideleg; 343 const bool mask_hideleg; 344 const int shiftamt; 345 reg_t deleg_mask() const; 346 }; 347 348 typedef std::shared_ptr<generic_int_accessor_t> generic_int_accessor_t_p; 349 350 351 // For all CSRs that are simply (masked & shifted) views into mip 352 class mip_proxy_csr_t: public csr_t { 353 public: 354 mip_proxy_csr_t(processor_t* const proc, const reg_t addr, generic_int_accessor_t_p accr); 355 virtual reg_t read() const noexcept override; 356 protected: 357 virtual bool unlogged_write(const reg_t val) noexcept override; 358 private: 359 generic_int_accessor_t_p accr; 360 }; 361 362 // For all CSRs that are simply (masked & shifted) views into mie 363 class mie_proxy_csr_t: public csr_t { 364 public: 365 mie_proxy_csr_t(processor_t* const proc, const reg_t addr, generic_int_accessor_t_p accr); 366 virtual reg_t read() const noexcept override; 367 protected: 368 virtual bool unlogged_write(const reg_t val) noexcept override; 369 private: 370 generic_int_accessor_t_p accr; 371 }; 372 373 374 375 class mideleg_csr_t: public basic_csr_t { 376 public: 377 mideleg_csr_t(processor_t* const proc, const reg_t addr); 378 virtual void verify_permissions(insn_t insn, bool write) const override; 379 virtual reg_t read() const noexcept override; 380 protected: 381 virtual bool unlogged_write(const reg_t val) noexcept override; 382 }; 383 384 385 class medeleg_csr_t: public basic_csr_t { 386 public: 387 medeleg_csr_t(processor_t* const proc, const reg_t addr); 388 virtual void verify_permissions(insn_t insn, bool write) const override; 389 protected: 390 virtual bool unlogged_write(const reg_t val) noexcept override; 391 private: 392 const reg_t hypervisor_exceptions; 393 }; 394 395 396 // For CSRs with certain bits hardwired 397 class masked_csr_t: public basic_csr_t { 398 public: 399 masked_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init); 400 protected: 401 virtual bool unlogged_write(const reg_t val) noexcept override; 402 private: 403 const reg_t mask; 404 }; 405 406 407 // For satp and vsatp 408 // These are three classes in order to handle the [V]TVM bits permission checks 409 class base_atp_csr_t: public basic_csr_t { 410 public: 411 base_atp_csr_t(processor_t* const proc, const reg_t addr); 412 bool satp_valid(reg_t val) const noexcept; 413 protected: 414 virtual bool unlogged_write(const reg_t val) noexcept override; 415 private: 416 reg_t compute_new_satp(reg_t val) const noexcept; 417 }; 418 419 class satp_csr_t: public base_atp_csr_t { 420 public: 421 satp_csr_t(processor_t* const proc, const reg_t addr); 422 virtual void verify_permissions(insn_t insn, bool write) const override; 423 }; 424 425 typedef std::shared_ptr<satp_csr_t> satp_csr_t_p; 426 427 class virtualized_satp_csr_t: public virtualized_csr_t { 428 public: 429 virtualized_satp_csr_t(processor_t* const proc, satp_csr_t_p orig, csr_t_p virt); 430 virtual void verify_permissions(insn_t insn, bool write) const override; 431 protected: 432 virtual bool unlogged_write(const reg_t val) noexcept override; 433 private: 434 satp_csr_t_p orig_satp; 435 }; 436 437 438 // For minstret, which is always 64 bits, but in RV32 is split into 439 // high and low halves. The first class always holds the full 64-bit 440 // value. 441 class minstret_csr_t: public csr_t { 442 public: 443 minstret_csr_t(processor_t* const proc, const reg_t addr); 444 // Always returns full 64-bit value 445 virtual reg_t read() const noexcept override; 446 void bump(const reg_t howmuch) noexcept; 447 void write_upper_half(const reg_t val) noexcept; 448 protected: 449 virtual bool unlogged_write(const reg_t val) noexcept override; 450 virtual reg_t written_value() const noexcept override; 451 private: 452 reg_t val; 453 }; 454 455 typedef std::shared_ptr<minstret_csr_t> minstret_csr_t_p; 456 457 458 // A simple proxy to read/write the upper half of minstret 459 class minstreth_csr_t: public csr_t { 460 public: 461 minstreth_csr_t(processor_t* const proc, const reg_t addr, minstret_csr_t_p minstret); 462 virtual reg_t read() const noexcept override; 463 protected: 464 virtual bool unlogged_write(const reg_t val) noexcept override; 465 private: 466 minstret_csr_t_p minstret; 467 }; 468 469 typedef std::shared_ptr<minstreth_csr_t> minstreth_csr_t_p; 470 471 472 // For a CSR that is an alias of another 473 class proxy_csr_t: public csr_t { 474 public: 475 proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate); 476 virtual reg_t read() const noexcept override; 477 protected: 478 bool unlogged_write(const reg_t val) noexcept override; 479 private: 480 csr_t_p delegate; 481 }; 482 483 484 // For a CSR with a fixed, unchanging value 485 class const_csr_t: public csr_t { 486 public: 487 const_csr_t(processor_t* const proc, const reg_t addr, reg_t val); 488 virtual reg_t read() const noexcept override; 489 protected: 490 bool unlogged_write(const reg_t val) noexcept override; 491 private: 492 const reg_t val; 493 }; 494 495 496 // For a CSR that is an unprivileged accessor of a privileged counter 497 class counter_proxy_csr_t: public proxy_csr_t { 498 public: 499 counter_proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate); 500 virtual void verify_permissions(insn_t insn, bool write) const override; 501 private: 502 bool myenable(csr_t_p counteren) const noexcept; 503 }; 504 505 506 // For machine-level CSRs that only exist with Hypervisor 507 class hypervisor_csr_t: public basic_csr_t { 508 public: 509 hypervisor_csr_t(processor_t* const proc, const reg_t addr); 510 virtual void verify_permissions(insn_t insn, bool write) const override; 511 }; 512 513 514 class hgatp_csr_t: public basic_csr_t { 515 public: 516 hgatp_csr_t(processor_t* const proc, const reg_t addr); 517 virtual void verify_permissions(insn_t insn, bool write) const override; 518 protected: 519 virtual bool unlogged_write(const reg_t val) noexcept override; 520 }; 521 522 523 class tselect_csr_t: public basic_csr_t { 524 public: 525 tselect_csr_t(processor_t* const proc, const reg_t addr); 526 protected: 527 virtual bool unlogged_write(const reg_t val) noexcept override; 528 }; 529 530 531 class tdata1_csr_t: public csr_t { 532 public: 533 tdata1_csr_t(processor_t* const proc, const reg_t addr); 534 virtual reg_t read() const noexcept override; 535 protected: 536 virtual bool unlogged_write(const reg_t val) noexcept override; 537 }; 538 539 class tdata2_csr_t: public csr_t { 540 public: 541 tdata2_csr_t(processor_t* const proc, const reg_t addr, const size_t count); 542 virtual reg_t read() const noexcept override; 543 reg_t read(const size_t idx) const noexcept; 544 protected: 545 virtual bool unlogged_write(const reg_t val) noexcept override; 546 private: 547 std::vector<reg_t> vals; 548 }; 549 550 // For CSRs that are only writable from debug mode 551 class debug_mode_csr_t: public basic_csr_t { 552 public: 553 debug_mode_csr_t(processor_t* const proc, const reg_t addr); 554 virtual void verify_permissions(insn_t insn, bool write) const override; 555 }; 556 557 typedef std::shared_ptr<tdata2_csr_t> tdata2_csr_t_p; 558 559 560 class dpc_csr_t: public epc_csr_t { 561 public: 562 dpc_csr_t(processor_t* const proc, const reg_t addr); 563 virtual void verify_permissions(insn_t insn, bool write) const override; 564 }; 565 566 class dcsr_csr_t: public csr_t { 567 public: 568 dcsr_csr_t(processor_t* const proc, const reg_t addr); 569 virtual void verify_permissions(insn_t insn, bool write) const override; 570 virtual reg_t read() const noexcept override; 571 void write_cause_and_prv(uint8_t cause, reg_t prv) noexcept; 572 protected: 573 virtual bool unlogged_write(const reg_t val) noexcept override; 574 public: 575 uint8_t prv; 576 bool step; 577 bool ebreakm; 578 bool ebreakh; 579 bool ebreaks; 580 bool ebreaku; 581 bool halt; 582 uint8_t cause; 583 }; 584 585 typedef std::shared_ptr<dcsr_csr_t> dcsr_csr_t_p; 586 587 588 class float_csr_t: public masked_csr_t { 589 public: 590 float_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init); 591 virtual void verify_permissions(insn_t insn, bool write) const override; 592 protected: 593 virtual bool unlogged_write(const reg_t val) noexcept override; 594 }; 595 596 597 // For a CSR like FCSR, that is actually a view into multiple 598 // underlying registers. 599 class composite_csr_t: public csr_t { 600 public: 601 // We assume the lower_csr maps to bit 0. 602 composite_csr_t(processor_t* const proc, const reg_t addr, csr_t_p upper_csr, csr_t_p lower_csr, const unsigned upper_lsb); 603 virtual void verify_permissions(insn_t insn, bool write) const override; 604 virtual reg_t read() const noexcept override; 605 protected: 606 virtual bool unlogged_write(const reg_t val) noexcept override; 607 private: 608 csr_t_p upper_csr; 609 csr_t_p lower_csr; 610 const unsigned upper_lsb; 611 }; 612 613 614 class sentropy_csr_t: public csr_t { 615 public: 616 sentropy_csr_t(processor_t* const proc, const reg_t addr); 617 virtual void verify_permissions(insn_t insn, bool write) const override; 618 virtual reg_t read() const noexcept override; 619 protected: 620 virtual bool unlogged_write(const reg_t val) noexcept override; 621 }; 622 623 624 class vector_csr_t: public basic_csr_t { 625 public: 626 vector_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init=0); 627 virtual void verify_permissions(insn_t insn, bool write) const override; 628 // Write without regard to mask, and without touching mstatus.VS 629 void write_raw(const reg_t val) noexcept; 630 protected: 631 virtual bool unlogged_write(const reg_t val) noexcept override; 632 private: 633 reg_t mask; 634 }; 635 636 typedef std::shared_ptr<vector_csr_t> vector_csr_t_p; 637 638 639 // For CSRs shared between Vector and P extensions (vxsat) 640 class vxsat_csr_t: public masked_csr_t { 641 public: 642 vxsat_csr_t(processor_t* const proc, const reg_t addr); 643 virtual void verify_permissions(insn_t insn, bool write) const override; 644 protected: 645 virtual bool unlogged_write(const reg_t val) noexcept override; 646 }; 647 648 #endif 649