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