xref: /openbmc/qemu/target/riscv/csr.c (revision 988717b46b6424907618cb845ace9d69062703af)
1  /*
2   * RISC-V Control and Status Registers.
3   *
4   * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5   * Copyright (c) 2017-2018 SiFive, Inc.
6   *
7   * This program is free software; you can redistribute it and/or modify it
8   * under the terms and conditions of the GNU General Public License,
9   * version 2 or later, as published by the Free Software Foundation.
10   *
11   * This program is distributed in the hope it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14   * more details.
15   *
16   * You should have received a copy of the GNU General Public License along with
17   * this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  #include "qemu/osdep.h"
21  #include "qemu/log.h"
22  #include "cpu.h"
23  #include "qemu/main-loop.h"
24  #include "exec/exec-all.h"
25  
26  /* CSR function table */
27  static riscv_csr_operations csr_ops[];
28  
29  /* CSR function table constants */
30  enum {
31      CSR_TABLE_SIZE = 0x1000
32  };
33  
34  /* CSR function table public API */
35  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
36  {
37      *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
38  }
39  
40  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
41  {
42      csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
43  }
44  
45  /* Predicates */
46  static int fs(CPURISCVState *env, int csrno)
47  {
48  #if !defined(CONFIG_USER_ONLY)
49      if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
50          return -1;
51      }
52  #endif
53      return 0;
54  }
55  
56  static int ctr(CPURISCVState *env, int csrno)
57  {
58  #if !defined(CONFIG_USER_ONLY)
59      CPUState *cs = env_cpu(env);
60      RISCVCPU *cpu = RISCV_CPU(cs);
61      uint32_t ctr_en = ~0u;
62  
63      if (!cpu->cfg.ext_counters) {
64          /* The Counters extensions is not enabled */
65          return -1;
66      }
67  
68      /*
69       * The counters are always enabled at run time on newer priv specs, as the
70       * CSR has changed from controlling that the counters can be read to
71       * controlling that the counters increment.
72       */
73      if (env->priv_ver > PRIV_VERSION_1_09_1) {
74          return 0;
75      }
76  
77      if (env->priv < PRV_M) {
78          ctr_en &= env->mcounteren;
79      }
80      if (env->priv < PRV_S) {
81          ctr_en &= env->scounteren;
82      }
83      if (!(ctr_en & (1u << (csrno & 31)))) {
84          return -1;
85      }
86  #endif
87      return 0;
88  }
89  
90  #if !defined(CONFIG_USER_ONLY)
91  static int any(CPURISCVState *env, int csrno)
92  {
93      return 0;
94  }
95  
96  static int smode(CPURISCVState *env, int csrno)
97  {
98      return -!riscv_has_ext(env, RVS);
99  }
100  
101  static int pmp(CPURISCVState *env, int csrno)
102  {
103      return -!riscv_feature(env, RISCV_FEATURE_PMP);
104  }
105  #endif
106  
107  /* User Floating-Point CSRs */
108  static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
109  {
110  #if !defined(CONFIG_USER_ONLY)
111      if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
112          return -1;
113      }
114  #endif
115      *val = riscv_cpu_get_fflags(env);
116      return 0;
117  }
118  
119  static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
120  {
121  #if !defined(CONFIG_USER_ONLY)
122      if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
123          return -1;
124      }
125      env->mstatus |= MSTATUS_FS;
126  #endif
127      riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
128      return 0;
129  }
130  
131  static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
132  {
133  #if !defined(CONFIG_USER_ONLY)
134      if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
135          return -1;
136      }
137  #endif
138      *val = env->frm;
139      return 0;
140  }
141  
142  static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
143  {
144  #if !defined(CONFIG_USER_ONLY)
145      if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
146          return -1;
147      }
148      env->mstatus |= MSTATUS_FS;
149  #endif
150      env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
151      return 0;
152  }
153  
154  static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
155  {
156  #if !defined(CONFIG_USER_ONLY)
157      if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
158          return -1;
159      }
160  #endif
161      *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
162          | (env->frm << FSR_RD_SHIFT);
163      return 0;
164  }
165  
166  static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
167  {
168  #if !defined(CONFIG_USER_ONLY)
169      if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
170          return -1;
171      }
172      env->mstatus |= MSTATUS_FS;
173  #endif
174      env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
175      riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
176      return 0;
177  }
178  
179  /* User Timers and Counters */
180  static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
181  {
182  #if !defined(CONFIG_USER_ONLY)
183      if (use_icount) {
184          *val = cpu_get_icount();
185      } else {
186          *val = cpu_get_host_ticks();
187      }
188  #else
189      *val = cpu_get_host_ticks();
190  #endif
191      return 0;
192  }
193  
194  #if defined(TARGET_RISCV32)
195  static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
196  {
197  #if !defined(CONFIG_USER_ONLY)
198      if (use_icount) {
199          *val = cpu_get_icount() >> 32;
200      } else {
201          *val = cpu_get_host_ticks() >> 32;
202      }
203  #else
204      *val = cpu_get_host_ticks() >> 32;
205  #endif
206      return 0;
207  }
208  #endif /* TARGET_RISCV32 */
209  
210  #if defined(CONFIG_USER_ONLY)
211  static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
212  {
213      *val = cpu_get_host_ticks();
214      return 0;
215  }
216  
217  #if defined(TARGET_RISCV32)
218  static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
219  {
220      *val = cpu_get_host_ticks() >> 32;
221      return 0;
222  }
223  #endif
224  
225  #else /* CONFIG_USER_ONLY */
226  
227  /* Machine constants */
228  
229  #define M_MODE_INTERRUPTS (MIP_MSIP | MIP_MTIP | MIP_MEIP)
230  #define S_MODE_INTERRUPTS (MIP_SSIP | MIP_STIP | MIP_SEIP)
231  
232  static const target_ulong delegable_ints = S_MODE_INTERRUPTS;
233  static const target_ulong all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS;
234  static const target_ulong delegable_excps =
235      (1ULL << (RISCV_EXCP_INST_ADDR_MIS)) |
236      (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) |
237      (1ULL << (RISCV_EXCP_ILLEGAL_INST)) |
238      (1ULL << (RISCV_EXCP_BREAKPOINT)) |
239      (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) |
240      (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) |
241      (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) |
242      (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) |
243      (1ULL << (RISCV_EXCP_U_ECALL)) |
244      (1ULL << (RISCV_EXCP_S_ECALL)) |
245      (1ULL << (RISCV_EXCP_H_ECALL)) |
246      (1ULL << (RISCV_EXCP_M_ECALL)) |
247      (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) |
248      (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) |
249      (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT));
250  static const target_ulong sstatus_v1_9_mask = SSTATUS_SIE | SSTATUS_SPIE |
251      SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
252      SSTATUS_SUM | SSTATUS_SD;
253  static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
254      SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
255      SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
256  static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
257  
258  #if defined(TARGET_RISCV32)
259  static const char valid_vm_1_09[16] = {
260      [VM_1_09_MBARE] = 1,
261      [VM_1_09_SV32] = 1,
262  };
263  static const char valid_vm_1_10[16] = {
264      [VM_1_10_MBARE] = 1,
265      [VM_1_10_SV32] = 1
266  };
267  #elif defined(TARGET_RISCV64)
268  static const char valid_vm_1_09[16] = {
269      [VM_1_09_MBARE] = 1,
270      [VM_1_09_SV39] = 1,
271      [VM_1_09_SV48] = 1,
272  };
273  static const char valid_vm_1_10[16] = {
274      [VM_1_10_MBARE] = 1,
275      [VM_1_10_SV39] = 1,
276      [VM_1_10_SV48] = 1,
277      [VM_1_10_SV57] = 1
278  };
279  #endif /* CONFIG_USER_ONLY */
280  
281  /* Machine Information Registers */
282  static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
283  {
284      return *val = 0;
285  }
286  
287  static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val)
288  {
289      *val = env->mhartid;
290      return 0;
291  }
292  
293  /* Machine Trap Setup */
294  static int read_mstatus(CPURISCVState *env, int csrno, target_ulong *val)
295  {
296      *val = env->mstatus;
297      return 0;
298  }
299  
300  static int validate_vm(CPURISCVState *env, target_ulong vm)
301  {
302      return (env->priv_ver >= PRIV_VERSION_1_10_0) ?
303          valid_vm_1_10[vm & 0xf] : valid_vm_1_09[vm & 0xf];
304  }
305  
306  static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
307  {
308      target_ulong mstatus = env->mstatus;
309      target_ulong mask = 0;
310      int dirty;
311  
312      /* flush tlb on mstatus fields that affect VM */
313      if (env->priv_ver <= PRIV_VERSION_1_09_1) {
314          if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP |
315                  MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_VM)) {
316              tlb_flush(env_cpu(env));
317          }
318          mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
319              MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
320              MSTATUS_MPP | MSTATUS_MXR |
321              (validate_vm(env, get_field(val, MSTATUS_VM)) ?
322                  MSTATUS_VM : 0);
323      }
324      if (env->priv_ver >= PRIV_VERSION_1_10_0) {
325          if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
326                  MSTATUS_MPRV | MSTATUS_SUM)) {
327              tlb_flush(env_cpu(env));
328          }
329          mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
330              MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
331              MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
332              MSTATUS_TW;
333  #if defined(TARGET_RISCV64)
334              /*
335               * RV32: MPV and MTL are not in mstatus. The current plan is to
336               * add them to mstatush. For now, we just don't support it.
337               */
338              mask |= MSTATUS_MTL | MSTATUS_MPV;
339  #endif
340      }
341  
342      mstatus = (mstatus & ~mask) | (val & mask);
343  
344      dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
345              ((mstatus & MSTATUS_XS) == MSTATUS_XS);
346      mstatus = set_field(mstatus, MSTATUS_SD, dirty);
347      env->mstatus = mstatus;
348  
349      return 0;
350  }
351  
352  static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
353  {
354      *val = env->misa;
355      return 0;
356  }
357  
358  static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
359  {
360      if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
361          /* drop write to misa */
362          return 0;
363      }
364  
365      /* 'I' or 'E' must be present */
366      if (!(val & (RVI | RVE))) {
367          /* It is not, drop write to misa */
368          return 0;
369      }
370  
371      /* 'E' excludes all other extensions */
372      if (val & RVE) {
373          /* when we support 'E' we can do "val = RVE;" however
374           * for now we just drop writes if 'E' is present.
375           */
376          return 0;
377      }
378  
379      /* Mask extensions that are not supported by this hart */
380      val &= env->misa_mask;
381  
382      /* Mask extensions that are not supported by QEMU */
383      val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
384  
385      /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
386      if ((val & RVD) && !(val & RVF)) {
387          val &= ~RVD;
388      }
389  
390      /* Suppress 'C' if next instruction is not aligned
391       * TODO: this should check next_pc
392       */
393      if ((val & RVC) && (GETPC() & ~3) != 0) {
394          val &= ~RVC;
395      }
396  
397      /* misa.MXL writes are not supported by QEMU */
398      val = (env->misa & MISA_MXL) | (val & ~MISA_MXL);
399  
400      /* flush translation cache */
401      if (val != env->misa) {
402          tb_flush(env_cpu(env));
403      }
404  
405      env->misa = val;
406  
407      return 0;
408  }
409  
410  static int read_medeleg(CPURISCVState *env, int csrno, target_ulong *val)
411  {
412      *val = env->medeleg;
413      return 0;
414  }
415  
416  static int write_medeleg(CPURISCVState *env, int csrno, target_ulong val)
417  {
418      env->medeleg = (env->medeleg & ~delegable_excps) | (val & delegable_excps);
419      return 0;
420  }
421  
422  static int read_mideleg(CPURISCVState *env, int csrno, target_ulong *val)
423  {
424      *val = env->mideleg;
425      return 0;
426  }
427  
428  static int write_mideleg(CPURISCVState *env, int csrno, target_ulong val)
429  {
430      env->mideleg = (env->mideleg & ~delegable_ints) | (val & delegable_ints);
431      return 0;
432  }
433  
434  static int read_mie(CPURISCVState *env, int csrno, target_ulong *val)
435  {
436      *val = env->mie;
437      return 0;
438  }
439  
440  static int write_mie(CPURISCVState *env, int csrno, target_ulong val)
441  {
442      env->mie = (env->mie & ~all_ints) | (val & all_ints);
443      return 0;
444  }
445  
446  static int read_mtvec(CPURISCVState *env, int csrno, target_ulong *val)
447  {
448      *val = env->mtvec;
449      return 0;
450  }
451  
452  static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
453  {
454      /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
455      if ((val & 3) < 2) {
456          env->mtvec = val;
457      } else {
458          qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
459      }
460      return 0;
461  }
462  
463  static int read_mcounteren(CPURISCVState *env, int csrno, target_ulong *val)
464  {
465      if (env->priv_ver < PRIV_VERSION_1_10_0) {
466          return -1;
467      }
468      *val = env->mcounteren;
469      return 0;
470  }
471  
472  static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val)
473  {
474      if (env->priv_ver < PRIV_VERSION_1_10_0) {
475          return -1;
476      }
477      env->mcounteren = val;
478      return 0;
479  }
480  
481  /* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
482  static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
483  {
484      if (env->priv_ver > PRIV_VERSION_1_09_1
485          && env->priv_ver < PRIV_VERSION_1_11_0) {
486          return -1;
487      }
488      *val = env->mcounteren;
489      return 0;
490  }
491  
492  /* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
493  static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val)
494  {
495      if (env->priv_ver > PRIV_VERSION_1_09_1
496          && env->priv_ver < PRIV_VERSION_1_11_0) {
497          return -1;
498      }
499      env->mcounteren = val;
500      return 0;
501  }
502  
503  static int read_mucounteren(CPURISCVState *env, int csrno, target_ulong *val)
504  {
505      if (env->priv_ver > PRIV_VERSION_1_09_1) {
506          return -1;
507      }
508      *val = env->scounteren;
509      return 0;
510  }
511  
512  static int write_mucounteren(CPURISCVState *env, int csrno, target_ulong val)
513  {
514      if (env->priv_ver > PRIV_VERSION_1_09_1) {
515          return -1;
516      }
517      env->scounteren = val;
518      return 0;
519  }
520  
521  /* Machine Trap Handling */
522  static int read_mscratch(CPURISCVState *env, int csrno, target_ulong *val)
523  {
524      *val = env->mscratch;
525      return 0;
526  }
527  
528  static int write_mscratch(CPURISCVState *env, int csrno, target_ulong val)
529  {
530      env->mscratch = val;
531      return 0;
532  }
533  
534  static int read_mepc(CPURISCVState *env, int csrno, target_ulong *val)
535  {
536      *val = env->mepc;
537      return 0;
538  }
539  
540  static int write_mepc(CPURISCVState *env, int csrno, target_ulong val)
541  {
542      env->mepc = val;
543      return 0;
544  }
545  
546  static int read_mcause(CPURISCVState *env, int csrno, target_ulong *val)
547  {
548      *val = env->mcause;
549      return 0;
550  }
551  
552  static int write_mcause(CPURISCVState *env, int csrno, target_ulong val)
553  {
554      env->mcause = val;
555      return 0;
556  }
557  
558  static int read_mbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
559  {
560      *val = env->mbadaddr;
561      return 0;
562  }
563  
564  static int write_mbadaddr(CPURISCVState *env, int csrno, target_ulong val)
565  {
566      env->mbadaddr = val;
567      return 0;
568  }
569  
570  static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
571                     target_ulong new_value, target_ulong write_mask)
572  {
573      RISCVCPU *cpu = env_archcpu(env);
574      /* Allow software control of delegable interrupts not claimed by hardware */
575      target_ulong mask = write_mask & delegable_ints & ~env->miclaim;
576      uint32_t old_mip;
577  
578      if (mask) {
579          old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask));
580      } else {
581          old_mip = env->mip;
582      }
583  
584      if (ret_value) {
585          *ret_value = old_mip;
586      }
587  
588      return 0;
589  }
590  
591  /* Supervisor Trap Setup */
592  static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val)
593  {
594      target_ulong mask = ((env->priv_ver >= PRIV_VERSION_1_10_0) ?
595                           sstatus_v1_10_mask : sstatus_v1_9_mask);
596      *val = env->mstatus & mask;
597      return 0;
598  }
599  
600  static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
601  {
602      target_ulong mask = ((env->priv_ver >= PRIV_VERSION_1_10_0) ?
603                           sstatus_v1_10_mask : sstatus_v1_9_mask);
604      target_ulong newval = (env->mstatus & ~mask) | (val & mask);
605      return write_mstatus(env, CSR_MSTATUS, newval);
606  }
607  
608  static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
609  {
610      *val = env->mie & env->mideleg;
611      return 0;
612  }
613  
614  static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
615  {
616      target_ulong newval = (env->mie & ~env->mideleg) | (val & env->mideleg);
617      return write_mie(env, CSR_MIE, newval);
618  }
619  
620  static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
621  {
622      *val = env->stvec;
623      return 0;
624  }
625  
626  static int write_stvec(CPURISCVState *env, int csrno, target_ulong val)
627  {
628      /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
629      if ((val & 3) < 2) {
630          env->stvec = val;
631      } else {
632          qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
633      }
634      return 0;
635  }
636  
637  static int read_scounteren(CPURISCVState *env, int csrno, target_ulong *val)
638  {
639      if (env->priv_ver < PRIV_VERSION_1_10_0) {
640          return -1;
641      }
642      *val = env->scounteren;
643      return 0;
644  }
645  
646  static int write_scounteren(CPURISCVState *env, int csrno, target_ulong val)
647  {
648      if (env->priv_ver < PRIV_VERSION_1_10_0) {
649          return -1;
650      }
651      env->scounteren = val;
652      return 0;
653  }
654  
655  /* Supervisor Trap Handling */
656  static int read_sscratch(CPURISCVState *env, int csrno, target_ulong *val)
657  {
658      *val = env->sscratch;
659      return 0;
660  }
661  
662  static int write_sscratch(CPURISCVState *env, int csrno, target_ulong val)
663  {
664      env->sscratch = val;
665      return 0;
666  }
667  
668  static int read_sepc(CPURISCVState *env, int csrno, target_ulong *val)
669  {
670      *val = env->sepc;
671      return 0;
672  }
673  
674  static int write_sepc(CPURISCVState *env, int csrno, target_ulong val)
675  {
676      env->sepc = val;
677      return 0;
678  }
679  
680  static int read_scause(CPURISCVState *env, int csrno, target_ulong *val)
681  {
682      *val = env->scause;
683      return 0;
684  }
685  
686  static int write_scause(CPURISCVState *env, int csrno, target_ulong val)
687  {
688      env->scause = val;
689      return 0;
690  }
691  
692  static int read_sbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
693  {
694      *val = env->sbadaddr;
695      return 0;
696  }
697  
698  static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
699  {
700      env->sbadaddr = val;
701      return 0;
702  }
703  
704  static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
705                     target_ulong new_value, target_ulong write_mask)
706  {
707      int ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
708                        write_mask & env->mideleg & sip_writable_mask);
709      *ret_value &= env->mideleg;
710      return ret;
711  }
712  
713  /* Supervisor Protection and Translation */
714  static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
715  {
716      if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
717          *val = 0;
718      } else if (env->priv_ver >= PRIV_VERSION_1_10_0) {
719          if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
720              return -1;
721          } else {
722              *val = env->satp;
723          }
724      } else {
725          *val = env->sptbr;
726      }
727      return 0;
728  }
729  
730  static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
731  {
732      if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
733          return 0;
734      }
735      if (env->priv_ver <= PRIV_VERSION_1_09_1 && (val ^ env->sptbr)) {
736          tlb_flush(env_cpu(env));
737          env->sptbr = val & (((target_ulong)
738              1 << (TARGET_PHYS_ADDR_SPACE_BITS - PGSHIFT)) - 1);
739      }
740      if (env->priv_ver >= PRIV_VERSION_1_10_0 &&
741          validate_vm(env, get_field(val, SATP_MODE)) &&
742          ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
743      {
744          if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
745              return -1;
746          } else {
747              if((val ^ env->satp) & SATP_ASID) {
748                  tlb_flush(env_cpu(env));
749              }
750              env->satp = val;
751          }
752      }
753      return 0;
754  }
755  
756  /* Physical Memory Protection */
757  static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val)
758  {
759      *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
760      return 0;
761  }
762  
763  static int write_pmpcfg(CPURISCVState *env, int csrno, target_ulong val)
764  {
765      pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
766      return 0;
767  }
768  
769  static int read_pmpaddr(CPURISCVState *env, int csrno, target_ulong *val)
770  {
771      *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
772      return 0;
773  }
774  
775  static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
776  {
777      pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
778      return 0;
779  }
780  
781  #endif
782  
783  /*
784   * riscv_csrrw - read and/or update control and status register
785   *
786   * csrr   <->  riscv_csrrw(env, csrno, ret_value, 0, 0);
787   * csrrw  <->  riscv_csrrw(env, csrno, ret_value, value, -1);
788   * csrrs  <->  riscv_csrrw(env, csrno, ret_value, -1, value);
789   * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
790   */
791  
792  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
793                  target_ulong new_value, target_ulong write_mask)
794  {
795      int ret;
796      target_ulong old_value;
797      RISCVCPU *cpu = env_archcpu(env);
798  
799      /* check privileges and return -1 if check fails */
800  #if !defined(CONFIG_USER_ONLY)
801      int csr_priv = get_field(csrno, 0x300);
802      int read_only = get_field(csrno, 0xC00) == 3;
803      if ((!env->debugger) && (env->priv < csr_priv)) {
804          return -1;
805      }
806      if (write_mask && read_only) {
807          return -1;
808      }
809  #endif
810  
811      /* ensure the CSR extension is enabled. */
812      if (!cpu->cfg.ext_icsr) {
813          return -1;
814      }
815  
816      /* check predicate */
817      if (!csr_ops[csrno].predicate || csr_ops[csrno].predicate(env, csrno) < 0) {
818          return -1;
819      }
820  
821      /* execute combined read/write operation if it exists */
822      if (csr_ops[csrno].op) {
823          return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
824      }
825  
826      /* if no accessor exists then return failure */
827      if (!csr_ops[csrno].read) {
828          return -1;
829      }
830  
831      /* read old value */
832      ret = csr_ops[csrno].read(env, csrno, &old_value);
833      if (ret < 0) {
834          return ret;
835      }
836  
837      /* write value if writable and write mask set, otherwise drop writes */
838      if (write_mask) {
839          new_value = (old_value & ~write_mask) | (new_value & write_mask);
840          if (csr_ops[csrno].write) {
841              ret = csr_ops[csrno].write(env, csrno, new_value);
842              if (ret < 0) {
843                  return ret;
844              }
845          }
846      }
847  
848      /* return old value */
849      if (ret_value) {
850          *ret_value = old_value;
851      }
852  
853      return 0;
854  }
855  
856  /*
857   * Debugger support.  If not in user mode, set env->debugger before the
858   * riscv_csrrw call and clear it after the call.
859   */
860  int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
861                  target_ulong new_value, target_ulong write_mask)
862  {
863      int ret;
864  #if !defined(CONFIG_USER_ONLY)
865      env->debugger = true;
866  #endif
867      ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
868  #if !defined(CONFIG_USER_ONLY)
869      env->debugger = false;
870  #endif
871      return ret;
872  }
873  
874  /* Control and Status Register function table */
875  static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
876      /* User Floating-Point CSRs */
877      [CSR_FFLAGS] =              { fs,   read_fflags,      write_fflags      },
878      [CSR_FRM] =                 { fs,   read_frm,         write_frm         },
879      [CSR_FCSR] =                { fs,   read_fcsr,        write_fcsr        },
880  
881      /* User Timers and Counters */
882      [CSR_CYCLE] =               { ctr,  read_instret                        },
883      [CSR_INSTRET] =             { ctr,  read_instret                        },
884  #if defined(TARGET_RISCV32)
885      [CSR_CYCLEH] =              { ctr,  read_instreth                       },
886      [CSR_INSTRETH] =            { ctr,  read_instreth                       },
887  #endif
888  
889      /* User-level time CSRs are only available in linux-user
890       * In privileged mode, the monitor emulates these CSRs */
891  #if defined(CONFIG_USER_ONLY)
892      [CSR_TIME] =                { ctr,  read_time                           },
893  #if defined(TARGET_RISCV32)
894      [CSR_TIMEH] =               { ctr,  read_timeh                          },
895  #endif
896  #endif
897  
898  #if !defined(CONFIG_USER_ONLY)
899      /* Machine Timers and Counters */
900      [CSR_MCYCLE] =              { any,  read_instret                        },
901      [CSR_MINSTRET] =            { any,  read_instret                        },
902  #if defined(TARGET_RISCV32)
903      [CSR_MCYCLEH] =             { any,  read_instreth                       },
904      [CSR_MINSTRETH] =           { any,  read_instreth                       },
905  #endif
906  
907      /* Machine Information Registers */
908      [CSR_MVENDORID] =           { any,  read_zero                           },
909      [CSR_MARCHID] =             { any,  read_zero                           },
910      [CSR_MIMPID] =              { any,  read_zero                           },
911      [CSR_MHARTID] =             { any,  read_mhartid                        },
912  
913      /* Machine Trap Setup */
914      [CSR_MSTATUS] =             { any,  read_mstatus,     write_mstatus     },
915      [CSR_MISA] =                { any,  read_misa,        write_misa        },
916      [CSR_MIDELEG] =             { any,  read_mideleg,     write_mideleg     },
917      [CSR_MEDELEG] =             { any,  read_medeleg,     write_medeleg     },
918      [CSR_MIE] =                 { any,  read_mie,         write_mie         },
919      [CSR_MTVEC] =               { any,  read_mtvec,       write_mtvec       },
920      [CSR_MCOUNTEREN] =          { any,  read_mcounteren,  write_mcounteren  },
921  
922      /* Legacy Counter Setup (priv v1.9.1) */
923      [CSR_MUCOUNTEREN] =         { any,  read_mucounteren, write_mucounteren },
924      [CSR_MSCOUNTEREN] =         { any,  read_mscounteren, write_mscounteren },
925  
926      /* Machine Trap Handling */
927      [CSR_MSCRATCH] =            { any,  read_mscratch,    write_mscratch    },
928      [CSR_MEPC] =                { any,  read_mepc,        write_mepc        },
929      [CSR_MCAUSE] =              { any,  read_mcause,      write_mcause      },
930      [CSR_MBADADDR] =            { any,  read_mbadaddr,    write_mbadaddr    },
931      [CSR_MIP] =                 { any,  NULL,     NULL,     rmw_mip         },
932  
933      /* Supervisor Trap Setup */
934      [CSR_SSTATUS] =             { smode, read_sstatus,     write_sstatus     },
935      [CSR_SIE] =                 { smode, read_sie,         write_sie         },
936      [CSR_STVEC] =               { smode, read_stvec,       write_stvec       },
937      [CSR_SCOUNTEREN] =          { smode, read_scounteren,  write_scounteren  },
938  
939      /* Supervisor Trap Handling */
940      [CSR_SSCRATCH] =            { smode, read_sscratch,    write_sscratch    },
941      [CSR_SEPC] =                { smode, read_sepc,        write_sepc        },
942      [CSR_SCAUSE] =              { smode, read_scause,      write_scause      },
943      [CSR_SBADADDR] =            { smode, read_sbadaddr,    write_sbadaddr    },
944      [CSR_SIP] =                 { smode, NULL,     NULL,     rmw_sip         },
945  
946      /* Supervisor Protection and Translation */
947      [CSR_SATP] =                { smode, read_satp,        write_satp        },
948  
949      /* Physical Memory Protection */
950      [CSR_PMPCFG0  ... CSR_PMPADDR9] =  { pmp,   read_pmpcfg,  write_pmpcfg   },
951      [CSR_PMPADDR0 ... CSR_PMPADDR15] = { pmp,   read_pmpaddr, write_pmpaddr  },
952  
953      /* Performance Counters */
954      [CSR_HPMCOUNTER3   ... CSR_HPMCOUNTER31] =    { ctr,  read_zero          },
955      [CSR_MHPMCOUNTER3  ... CSR_MHPMCOUNTER31] =   { any,  read_zero          },
956      [CSR_MHPMEVENT3    ... CSR_MHPMEVENT31] =     { any,  read_zero          },
957  #if defined(TARGET_RISCV32)
958      [CSR_HPMCOUNTER3H  ... CSR_HPMCOUNTER31H] =   { ctr,  read_zero          },
959      [CSR_MHPMCOUNTER3H ... CSR_MHPMCOUNTER31H] =  { any,  read_zero          },
960  #endif
961  #endif /* !CONFIG_USER_ONLY */
962  };
963