arm/acpi: Add the TPM2.0 device under the DSDT
[qemu/ar7.git] / target / riscv / csr.c
blob383be0a955aec9fa5d6832730ac0751333dd8bd6
1 /*
2 * RISC-V Control and Status Registers.
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2017-2018 SiFive, Inc.
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.
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.
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/>.
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"
26 /* CSR function table */
27 static riscv_csr_operations csr_ops[];
29 /* CSR function table constants */
30 enum {
31 CSR_TABLE_SIZE = 0x1000
34 /* CSR function table public API */
35 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
37 *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
40 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
42 csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
45 /* Predicates */
46 static int fs(CPURISCVState *env, int csrno)
48 #if !defined(CONFIG_USER_ONLY)
49 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
50 return -1;
52 #endif
53 return 0;
56 static int ctr(CPURISCVState *env, int csrno)
58 #if !defined(CONFIG_USER_ONLY)
59 CPUState *cs = env_cpu(env);
60 RISCVCPU *cpu = RISCV_CPU(cs);
62 if (!cpu->cfg.ext_counters) {
63 /* The Counters extensions is not enabled */
64 return -1;
66 #endif
67 return 0;
70 #if !defined(CONFIG_USER_ONLY)
71 static int any(CPURISCVState *env, int csrno)
73 return 0;
76 static int smode(CPURISCVState *env, int csrno)
78 return -!riscv_has_ext(env, RVS);
81 static int hmode(CPURISCVState *env, int csrno)
83 if (riscv_has_ext(env, RVS) &&
84 riscv_has_ext(env, RVH)) {
85 /* Hypervisor extension is supported */
86 if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
87 env->priv == PRV_M) {
88 return 0;
92 return -1;
95 static int pmp(CPURISCVState *env, int csrno)
97 return -!riscv_feature(env, RISCV_FEATURE_PMP);
99 #endif
101 /* User Floating-Point CSRs */
102 static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
104 #if !defined(CONFIG_USER_ONLY)
105 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
106 return -1;
108 #endif
109 *val = riscv_cpu_get_fflags(env);
110 return 0;
113 static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
115 #if !defined(CONFIG_USER_ONLY)
116 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
117 return -1;
119 env->mstatus |= MSTATUS_FS;
120 #endif
121 riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
122 return 0;
125 static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
127 #if !defined(CONFIG_USER_ONLY)
128 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
129 return -1;
131 #endif
132 *val = env->frm;
133 return 0;
136 static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
138 #if !defined(CONFIG_USER_ONLY)
139 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
140 return -1;
142 env->mstatus |= MSTATUS_FS;
143 #endif
144 env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
145 return 0;
148 static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
150 #if !defined(CONFIG_USER_ONLY)
151 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
152 return -1;
154 #endif
155 *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
156 | (env->frm << FSR_RD_SHIFT);
157 return 0;
160 static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
162 #if !defined(CONFIG_USER_ONLY)
163 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
164 return -1;
166 env->mstatus |= MSTATUS_FS;
167 #endif
168 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
169 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
170 return 0;
173 /* User Timers and Counters */
174 static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
176 #if !defined(CONFIG_USER_ONLY)
177 if (use_icount) {
178 *val = cpu_get_icount();
179 } else {
180 *val = cpu_get_host_ticks();
182 #else
183 *val = cpu_get_host_ticks();
184 #endif
185 return 0;
188 #if defined(TARGET_RISCV32)
189 static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
191 #if !defined(CONFIG_USER_ONLY)
192 if (use_icount) {
193 *val = cpu_get_icount() >> 32;
194 } else {
195 *val = cpu_get_host_ticks() >> 32;
197 #else
198 *val = cpu_get_host_ticks() >> 32;
199 #endif
200 return 0;
202 #endif /* TARGET_RISCV32 */
204 #if defined(CONFIG_USER_ONLY)
205 static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
207 *val = cpu_get_host_ticks();
208 return 0;
211 #if defined(TARGET_RISCV32)
212 static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
214 *val = cpu_get_host_ticks() >> 32;
215 return 0;
217 #endif
219 #else /* CONFIG_USER_ONLY */
221 static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
223 uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
225 if (!env->rdtime_fn) {
226 return -1;
229 *val = env->rdtime_fn() + delta;
230 return 0;
233 #if defined(TARGET_RISCV32)
234 static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
236 uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
238 if (!env->rdtime_fn) {
239 return -1;
242 *val = (env->rdtime_fn() + delta) >> 32;
243 return 0;
245 #endif
247 /* Machine constants */
249 #define M_MODE_INTERRUPTS (MIP_MSIP | MIP_MTIP | MIP_MEIP)
250 #define S_MODE_INTERRUPTS (MIP_SSIP | MIP_STIP | MIP_SEIP)
251 #define VS_MODE_INTERRUPTS (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)
253 static const target_ulong delegable_ints = S_MODE_INTERRUPTS |
254 VS_MODE_INTERRUPTS;
255 static const target_ulong all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
256 VS_MODE_INTERRUPTS;
257 static const target_ulong delegable_excps =
258 (1ULL << (RISCV_EXCP_INST_ADDR_MIS)) |
259 (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) |
260 (1ULL << (RISCV_EXCP_ILLEGAL_INST)) |
261 (1ULL << (RISCV_EXCP_BREAKPOINT)) |
262 (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) |
263 (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) |
264 (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) |
265 (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) |
266 (1ULL << (RISCV_EXCP_U_ECALL)) |
267 (1ULL << (RISCV_EXCP_S_ECALL)) |
268 (1ULL << (RISCV_EXCP_VS_ECALL)) |
269 (1ULL << (RISCV_EXCP_M_ECALL)) |
270 (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) |
271 (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) |
272 (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) |
273 (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
274 (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
275 (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT));
276 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
277 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
278 SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
279 static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
280 static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
281 static const target_ulong vsip_writable_mask = MIP_VSSIP;
283 #if defined(TARGET_RISCV32)
284 static const char valid_vm_1_10[16] = {
285 [VM_1_10_MBARE] = 1,
286 [VM_1_10_SV32] = 1
288 #elif defined(TARGET_RISCV64)
289 static const char valid_vm_1_10[16] = {
290 [VM_1_10_MBARE] = 1,
291 [VM_1_10_SV39] = 1,
292 [VM_1_10_SV48] = 1,
293 [VM_1_10_SV57] = 1
295 #endif /* CONFIG_USER_ONLY */
297 /* Machine Information Registers */
298 static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
300 return *val = 0;
303 static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val)
305 *val = env->mhartid;
306 return 0;
309 /* Machine Trap Setup */
310 static int read_mstatus(CPURISCVState *env, int csrno, target_ulong *val)
312 *val = env->mstatus;
313 return 0;
316 static int validate_vm(CPURISCVState *env, target_ulong vm)
318 return valid_vm_1_10[vm & 0xf];
321 static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
323 target_ulong mstatus = env->mstatus;
324 target_ulong mask = 0;
325 int dirty;
327 /* flush tlb on mstatus fields that affect VM */
328 if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
329 MSTATUS_MPRV | MSTATUS_SUM)) {
330 tlb_flush(env_cpu(env));
332 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
333 MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
334 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
335 MSTATUS_TW;
336 #if defined(TARGET_RISCV64)
338 * RV32: MPV and MTL are not in mstatus. The current plan is to
339 * add them to mstatush. For now, we just don't support it.
341 mask |= MSTATUS_MTL | MSTATUS_MPV;
342 #endif
344 mstatus = (mstatus & ~mask) | (val & mask);
346 dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
347 ((mstatus & MSTATUS_XS) == MSTATUS_XS);
348 mstatus = set_field(mstatus, MSTATUS_SD, dirty);
349 env->mstatus = mstatus;
351 return 0;
354 #ifdef TARGET_RISCV32
355 static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
357 *val = env->mstatush;
358 return 0;
361 static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
363 if ((val ^ env->mstatush) & (MSTATUS_MPV)) {
364 tlb_flush(env_cpu(env));
367 val &= MSTATUS_MPV | MSTATUS_MTL;
369 env->mstatush = val;
371 return 0;
373 #endif
375 static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
377 *val = env->misa;
378 return 0;
381 static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
383 if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
384 /* drop write to misa */
385 return 0;
388 /* 'I' or 'E' must be present */
389 if (!(val & (RVI | RVE))) {
390 /* It is not, drop write to misa */
391 return 0;
394 /* 'E' excludes all other extensions */
395 if (val & RVE) {
396 /* when we support 'E' we can do "val = RVE;" however
397 * for now we just drop writes if 'E' is present.
399 return 0;
402 /* Mask extensions that are not supported by this hart */
403 val &= env->misa_mask;
405 /* Mask extensions that are not supported by QEMU */
406 val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
408 /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
409 if ((val & RVD) && !(val & RVF)) {
410 val &= ~RVD;
413 /* Suppress 'C' if next instruction is not aligned
414 * TODO: this should check next_pc
416 if ((val & RVC) && (GETPC() & ~3) != 0) {
417 val &= ~RVC;
420 /* misa.MXL writes are not supported by QEMU */
421 val = (env->misa & MISA_MXL) | (val & ~MISA_MXL);
423 /* flush translation cache */
424 if (val != env->misa) {
425 tb_flush(env_cpu(env));
428 env->misa = val;
430 return 0;
433 static int read_medeleg(CPURISCVState *env, int csrno, target_ulong *val)
435 *val = env->medeleg;
436 return 0;
439 static int write_medeleg(CPURISCVState *env, int csrno, target_ulong val)
441 env->medeleg = (env->medeleg & ~delegable_excps) | (val & delegable_excps);
442 return 0;
445 static int read_mideleg(CPURISCVState *env, int csrno, target_ulong *val)
447 *val = env->mideleg;
448 return 0;
451 static int write_mideleg(CPURISCVState *env, int csrno, target_ulong val)
453 env->mideleg = (env->mideleg & ~delegable_ints) | (val & delegable_ints);
454 if (riscv_has_ext(env, RVH)) {
455 env->mideleg |= VS_MODE_INTERRUPTS;
457 return 0;
460 static int read_mie(CPURISCVState *env, int csrno, target_ulong *val)
462 *val = env->mie;
463 return 0;
466 static int write_mie(CPURISCVState *env, int csrno, target_ulong val)
468 env->mie = (env->mie & ~all_ints) | (val & all_ints);
469 return 0;
472 static int read_mtvec(CPURISCVState *env, int csrno, target_ulong *val)
474 *val = env->mtvec;
475 return 0;
478 static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
480 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
481 if ((val & 3) < 2) {
482 env->mtvec = val;
483 } else {
484 qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
486 return 0;
489 static int read_mcounteren(CPURISCVState *env, int csrno, target_ulong *val)
491 *val = env->mcounteren;
492 return 0;
495 static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val)
497 env->mcounteren = val;
498 return 0;
501 /* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
502 static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
504 if (env->priv_ver < PRIV_VERSION_1_11_0) {
505 return -1;
507 *val = env->mcounteren;
508 return 0;
511 /* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
512 static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val)
514 if (env->priv_ver < PRIV_VERSION_1_11_0) {
515 return -1;
517 env->mcounteren = val;
518 return 0;
521 /* Machine Trap Handling */
522 static int read_mscratch(CPURISCVState *env, int csrno, target_ulong *val)
524 *val = env->mscratch;
525 return 0;
528 static int write_mscratch(CPURISCVState *env, int csrno, target_ulong val)
530 env->mscratch = val;
531 return 0;
534 static int read_mepc(CPURISCVState *env, int csrno, target_ulong *val)
536 *val = env->mepc;
537 return 0;
540 static int write_mepc(CPURISCVState *env, int csrno, target_ulong val)
542 env->mepc = val;
543 return 0;
546 static int read_mcause(CPURISCVState *env, int csrno, target_ulong *val)
548 *val = env->mcause;
549 return 0;
552 static int write_mcause(CPURISCVState *env, int csrno, target_ulong val)
554 env->mcause = val;
555 return 0;
558 static int read_mbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
560 *val = env->mbadaddr;
561 return 0;
564 static int write_mbadaddr(CPURISCVState *env, int csrno, target_ulong val)
566 env->mbadaddr = val;
567 return 0;
570 static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
571 target_ulong new_value, target_ulong write_mask)
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;
578 if (mask) {
579 old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask));
580 } else {
581 old_mip = env->mip;
584 if (ret_value) {
585 *ret_value = old_mip;
588 return 0;
591 /* Supervisor Trap Setup */
592 static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val)
594 target_ulong mask = (sstatus_v1_10_mask);
595 *val = env->mstatus & mask;
596 return 0;
599 static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
601 target_ulong mask = (sstatus_v1_10_mask);
602 target_ulong newval = (env->mstatus & ~mask) | (val & mask);
603 return write_mstatus(env, CSR_MSTATUS, newval);
606 static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
608 if (riscv_cpu_virt_enabled(env)) {
609 /* Tell the guest the VS bits, shifted to the S bit locations */
610 *val = (env->mie & env->mideleg & VS_MODE_INTERRUPTS) >> 1;
611 } else {
612 *val = env->mie & env->mideleg;
614 return 0;
617 static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
619 target_ulong newval;
621 if (riscv_cpu_virt_enabled(env)) {
622 /* Shift the guests S bits to VS */
623 newval = (env->mie & ~VS_MODE_INTERRUPTS) |
624 ((val << 1) & VS_MODE_INTERRUPTS);
625 } else {
626 newval = (env->mie & ~S_MODE_INTERRUPTS) | (val & S_MODE_INTERRUPTS);
629 return write_mie(env, CSR_MIE, newval);
632 static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
634 *val = env->stvec;
635 return 0;
638 static int write_stvec(CPURISCVState *env, int csrno, target_ulong val)
640 /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
641 if ((val & 3) < 2) {
642 env->stvec = val;
643 } else {
644 qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
646 return 0;
649 static int read_scounteren(CPURISCVState *env, int csrno, target_ulong *val)
651 *val = env->scounteren;
652 return 0;
655 static int write_scounteren(CPURISCVState *env, int csrno, target_ulong val)
657 env->scounteren = val;
658 return 0;
661 /* Supervisor Trap Handling */
662 static int read_sscratch(CPURISCVState *env, int csrno, target_ulong *val)
664 *val = env->sscratch;
665 return 0;
668 static int write_sscratch(CPURISCVState *env, int csrno, target_ulong val)
670 env->sscratch = val;
671 return 0;
674 static int read_sepc(CPURISCVState *env, int csrno, target_ulong *val)
676 *val = env->sepc;
677 return 0;
680 static int write_sepc(CPURISCVState *env, int csrno, target_ulong val)
682 env->sepc = val;
683 return 0;
686 static int read_scause(CPURISCVState *env, int csrno, target_ulong *val)
688 *val = env->scause;
689 return 0;
692 static int write_scause(CPURISCVState *env, int csrno, target_ulong val)
694 env->scause = val;
695 return 0;
698 static int read_sbadaddr(CPURISCVState *env, int csrno, target_ulong *val)
700 *val = env->sbadaddr;
701 return 0;
704 static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
706 env->sbadaddr = val;
707 return 0;
710 static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
711 target_ulong new_value, target_ulong write_mask)
713 int ret;
715 if (riscv_cpu_virt_enabled(env)) {
716 /* Shift the new values to line up with the VS bits */
717 ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value << 1,
718 (write_mask & sip_writable_mask) << 1 & env->mideleg);
719 ret &= vsip_writable_mask;
720 ret >>= 1;
721 } else {
722 ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
723 write_mask & env->mideleg & sip_writable_mask);
726 *ret_value &= env->mideleg;
727 return ret;
730 /* Supervisor Protection and Translation */
731 static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
733 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
734 *val = 0;
735 return 0;
738 if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
739 return -1;
740 } else {
741 *val = env->satp;
744 return 0;
747 static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
749 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
750 return 0;
752 if (validate_vm(env, get_field(val, SATP_MODE)) &&
753 ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
755 if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
756 return -1;
757 } else {
758 if((val ^ env->satp) & SATP_ASID) {
759 tlb_flush(env_cpu(env));
761 env->satp = val;
764 return 0;
767 /* Hypervisor Extensions */
768 static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
770 *val = env->hstatus;
771 return 0;
774 static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val)
776 env->hstatus = val;
777 return 0;
780 static int read_hedeleg(CPURISCVState *env, int csrno, target_ulong *val)
782 *val = env->hedeleg;
783 return 0;
786 static int write_hedeleg(CPURISCVState *env, int csrno, target_ulong val)
788 env->hedeleg = val;
789 return 0;
792 static int read_hideleg(CPURISCVState *env, int csrno, target_ulong *val)
794 *val = env->hideleg;
795 return 0;
798 static int write_hideleg(CPURISCVState *env, int csrno, target_ulong val)
800 env->hideleg = val;
801 return 0;
804 static int rmw_hip(CPURISCVState *env, int csrno, target_ulong *ret_value,
805 target_ulong new_value, target_ulong write_mask)
807 int ret = rmw_mip(env, 0, ret_value, new_value,
808 write_mask & hip_writable_mask);
810 return ret;
813 static int read_hie(CPURISCVState *env, int csrno, target_ulong *val)
815 *val = env->mie & VS_MODE_INTERRUPTS;
816 return 0;
819 static int write_hie(CPURISCVState *env, int csrno, target_ulong val)
821 target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) | (val & VS_MODE_INTERRUPTS);
822 return write_mie(env, CSR_MIE, newval);
825 static int read_hcounteren(CPURISCVState *env, int csrno, target_ulong *val)
827 *val = env->hcounteren;
828 return 0;
831 static int write_hcounteren(CPURISCVState *env, int csrno, target_ulong val)
833 env->hcounteren = val;
834 return 0;
837 static int read_htval(CPURISCVState *env, int csrno, target_ulong *val)
839 *val = env->htval;
840 return 0;
843 static int write_htval(CPURISCVState *env, int csrno, target_ulong val)
845 env->htval = val;
846 return 0;
849 static int read_htinst(CPURISCVState *env, int csrno, target_ulong *val)
851 *val = env->htinst;
852 return 0;
855 static int write_htinst(CPURISCVState *env, int csrno, target_ulong val)
857 env->htinst = val;
858 return 0;
861 static int read_hgatp(CPURISCVState *env, int csrno, target_ulong *val)
863 *val = env->hgatp;
864 return 0;
867 static int write_hgatp(CPURISCVState *env, int csrno, target_ulong val)
869 env->hgatp = val;
870 return 0;
873 static int read_htimedelta(CPURISCVState *env, int csrno, target_ulong *val)
875 if (!env->rdtime_fn) {
876 return -1;
879 #if defined(TARGET_RISCV32)
880 *val = env->htimedelta & 0xffffffff;
881 #else
882 *val = env->htimedelta;
883 #endif
884 return 0;
887 static int write_htimedelta(CPURISCVState *env, int csrno, target_ulong val)
889 if (!env->rdtime_fn) {
890 return -1;
893 #if defined(TARGET_RISCV32)
894 env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
895 #else
896 env->htimedelta = val;
897 #endif
898 return 0;
901 #if defined(TARGET_RISCV32)
902 static int read_htimedeltah(CPURISCVState *env, int csrno, target_ulong *val)
904 if (!env->rdtime_fn) {
905 return -1;
908 *val = env->htimedelta >> 32;
909 return 0;
912 static int write_htimedeltah(CPURISCVState *env, int csrno, target_ulong val)
914 if (!env->rdtime_fn) {
915 return -1;
918 env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
919 return 0;
921 #endif
923 /* Virtual CSR Registers */
924 static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
926 *val = env->vsstatus;
927 return 0;
930 static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
932 env->vsstatus = val;
933 return 0;
936 static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
937 target_ulong new_value, target_ulong write_mask)
939 int ret = rmw_mip(env, 0, ret_value, new_value,
940 write_mask & env->mideleg & vsip_writable_mask);
941 return ret;
944 static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
946 *val = env->mie & env->mideleg & VS_MODE_INTERRUPTS;
947 return 0;
950 static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
952 target_ulong newval = (env->mie & ~env->mideleg) | (val & env->mideleg & MIP_VSSIP);
953 return write_mie(env, CSR_MIE, newval);
956 static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
958 *val = env->vstvec;
959 return 0;
962 static int write_vstvec(CPURISCVState *env, int csrno, target_ulong val)
964 env->vstvec = val;
965 return 0;
968 static int read_vsscratch(CPURISCVState *env, int csrno, target_ulong *val)
970 *val = env->vsscratch;
971 return 0;
974 static int write_vsscratch(CPURISCVState *env, int csrno, target_ulong val)
976 env->vsscratch = val;
977 return 0;
980 static int read_vsepc(CPURISCVState *env, int csrno, target_ulong *val)
982 *val = env->vsepc;
983 return 0;
986 static int write_vsepc(CPURISCVState *env, int csrno, target_ulong val)
988 env->vsepc = val;
989 return 0;
992 static int read_vscause(CPURISCVState *env, int csrno, target_ulong *val)
994 *val = env->vscause;
995 return 0;
998 static int write_vscause(CPURISCVState *env, int csrno, target_ulong val)
1000 env->vscause = val;
1001 return 0;
1004 static int read_vstval(CPURISCVState *env, int csrno, target_ulong *val)
1006 *val = env->vstval;
1007 return 0;
1010 static int write_vstval(CPURISCVState *env, int csrno, target_ulong val)
1012 env->vstval = val;
1013 return 0;
1016 static int read_vsatp(CPURISCVState *env, int csrno, target_ulong *val)
1018 *val = env->vsatp;
1019 return 0;
1022 static int write_vsatp(CPURISCVState *env, int csrno, target_ulong val)
1024 env->vsatp = val;
1025 return 0;
1028 static int read_mtval2(CPURISCVState *env, int csrno, target_ulong *val)
1030 *val = env->mtval2;
1031 return 0;
1034 static int write_mtval2(CPURISCVState *env, int csrno, target_ulong val)
1036 env->mtval2 = val;
1037 return 0;
1040 static int read_mtinst(CPURISCVState *env, int csrno, target_ulong *val)
1042 *val = env->mtinst;
1043 return 0;
1046 static int write_mtinst(CPURISCVState *env, int csrno, target_ulong val)
1048 env->mtinst = val;
1049 return 0;
1052 /* Physical Memory Protection */
1053 static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val)
1055 *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
1056 return 0;
1059 static int write_pmpcfg(CPURISCVState *env, int csrno, target_ulong val)
1061 pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
1062 return 0;
1065 static int read_pmpaddr(CPURISCVState *env, int csrno, target_ulong *val)
1067 *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
1068 return 0;
1071 static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
1073 pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
1074 return 0;
1077 #endif
1080 * riscv_csrrw - read and/or update control and status register
1082 * csrr <-> riscv_csrrw(env, csrno, ret_value, 0, 0);
1083 * csrrw <-> riscv_csrrw(env, csrno, ret_value, value, -1);
1084 * csrrs <-> riscv_csrrw(env, csrno, ret_value, -1, value);
1085 * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value);
1088 int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
1089 target_ulong new_value, target_ulong write_mask)
1091 int ret;
1092 target_ulong old_value;
1093 RISCVCPU *cpu = env_archcpu(env);
1095 /* check privileges and return -1 if check fails */
1096 #if !defined(CONFIG_USER_ONLY)
1097 int effective_priv = env->priv;
1098 int read_only = get_field(csrno, 0xC00) == 3;
1100 if (riscv_has_ext(env, RVH) &&
1101 env->priv == PRV_S &&
1102 !riscv_cpu_virt_enabled(env)) {
1104 * We are in S mode without virtualisation, therefore we are in HS Mode.
1105 * Add 1 to the effective privledge level to allow us to access the
1106 * Hypervisor CSRs.
1108 effective_priv++;
1111 if ((write_mask && read_only) ||
1112 (!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
1113 return -1;
1115 #endif
1117 /* ensure the CSR extension is enabled. */
1118 if (!cpu->cfg.ext_icsr) {
1119 return -1;
1122 /* check predicate */
1123 if (!csr_ops[csrno].predicate || csr_ops[csrno].predicate(env, csrno) < 0) {
1124 return -1;
1127 /* execute combined read/write operation if it exists */
1128 if (csr_ops[csrno].op) {
1129 return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
1132 /* if no accessor exists then return failure */
1133 if (!csr_ops[csrno].read) {
1134 return -1;
1137 /* read old value */
1138 ret = csr_ops[csrno].read(env, csrno, &old_value);
1139 if (ret < 0) {
1140 return ret;
1143 /* write value if writable and write mask set, otherwise drop writes */
1144 if (write_mask) {
1145 new_value = (old_value & ~write_mask) | (new_value & write_mask);
1146 if (csr_ops[csrno].write) {
1147 ret = csr_ops[csrno].write(env, csrno, new_value);
1148 if (ret < 0) {
1149 return ret;
1154 /* return old value */
1155 if (ret_value) {
1156 *ret_value = old_value;
1159 return 0;
1163 * Debugger support. If not in user mode, set env->debugger before the
1164 * riscv_csrrw call and clear it after the call.
1166 int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
1167 target_ulong new_value, target_ulong write_mask)
1169 int ret;
1170 #if !defined(CONFIG_USER_ONLY)
1171 env->debugger = true;
1172 #endif
1173 ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
1174 #if !defined(CONFIG_USER_ONLY)
1175 env->debugger = false;
1176 #endif
1177 return ret;
1180 /* Control and Status Register function table */
1181 static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
1182 /* User Floating-Point CSRs */
1183 [CSR_FFLAGS] = { fs, read_fflags, write_fflags },
1184 [CSR_FRM] = { fs, read_frm, write_frm },
1185 [CSR_FCSR] = { fs, read_fcsr, write_fcsr },
1187 /* User Timers and Counters */
1188 [CSR_CYCLE] = { ctr, read_instret },
1189 [CSR_INSTRET] = { ctr, read_instret },
1190 #if defined(TARGET_RISCV32)
1191 [CSR_CYCLEH] = { ctr, read_instreth },
1192 [CSR_INSTRETH] = { ctr, read_instreth },
1193 #endif
1195 /* In privileged mode, the monitor will have to emulate TIME CSRs only if
1196 * rdtime callback is not provided by machine/platform emulation */
1197 [CSR_TIME] = { ctr, read_time },
1198 #if defined(TARGET_RISCV32)
1199 [CSR_TIMEH] = { ctr, read_timeh },
1200 #endif
1202 #if !defined(CONFIG_USER_ONLY)
1203 /* Machine Timers and Counters */
1204 [CSR_MCYCLE] = { any, read_instret },
1205 [CSR_MINSTRET] = { any, read_instret },
1206 #if defined(TARGET_RISCV32)
1207 [CSR_MCYCLEH] = { any, read_instreth },
1208 [CSR_MINSTRETH] = { any, read_instreth },
1209 #endif
1211 /* Machine Information Registers */
1212 [CSR_MVENDORID] = { any, read_zero },
1213 [CSR_MARCHID] = { any, read_zero },
1214 [CSR_MIMPID] = { any, read_zero },
1215 [CSR_MHARTID] = { any, read_mhartid },
1217 /* Machine Trap Setup */
1218 [CSR_MSTATUS] = { any, read_mstatus, write_mstatus },
1219 [CSR_MISA] = { any, read_misa, write_misa },
1220 [CSR_MIDELEG] = { any, read_mideleg, write_mideleg },
1221 [CSR_MEDELEG] = { any, read_medeleg, write_medeleg },
1222 [CSR_MIE] = { any, read_mie, write_mie },
1223 [CSR_MTVEC] = { any, read_mtvec, write_mtvec },
1224 [CSR_MCOUNTEREN] = { any, read_mcounteren, write_mcounteren },
1226 #if defined(TARGET_RISCV32)
1227 [CSR_MSTATUSH] = { any, read_mstatush, write_mstatush },
1228 #endif
1230 [CSR_MSCOUNTEREN] = { any, read_mscounteren, write_mscounteren },
1232 /* Machine Trap Handling */
1233 [CSR_MSCRATCH] = { any, read_mscratch, write_mscratch },
1234 [CSR_MEPC] = { any, read_mepc, write_mepc },
1235 [CSR_MCAUSE] = { any, read_mcause, write_mcause },
1236 [CSR_MBADADDR] = { any, read_mbadaddr, write_mbadaddr },
1237 [CSR_MIP] = { any, NULL, NULL, rmw_mip },
1239 /* Supervisor Trap Setup */
1240 [CSR_SSTATUS] = { smode, read_sstatus, write_sstatus },
1241 [CSR_SIE] = { smode, read_sie, write_sie },
1242 [CSR_STVEC] = { smode, read_stvec, write_stvec },
1243 [CSR_SCOUNTEREN] = { smode, read_scounteren, write_scounteren },
1245 /* Supervisor Trap Handling */
1246 [CSR_SSCRATCH] = { smode, read_sscratch, write_sscratch },
1247 [CSR_SEPC] = { smode, read_sepc, write_sepc },
1248 [CSR_SCAUSE] = { smode, read_scause, write_scause },
1249 [CSR_SBADADDR] = { smode, read_sbadaddr, write_sbadaddr },
1250 [CSR_SIP] = { smode, NULL, NULL, rmw_sip },
1252 /* Supervisor Protection and Translation */
1253 [CSR_SATP] = { smode, read_satp, write_satp },
1255 [CSR_HSTATUS] = { hmode, read_hstatus, write_hstatus },
1256 [CSR_HEDELEG] = { hmode, read_hedeleg, write_hedeleg },
1257 [CSR_HIDELEG] = { hmode, read_hideleg, write_hideleg },
1258 [CSR_HIP] = { hmode, NULL, NULL, rmw_hip },
1259 [CSR_HIE] = { hmode, read_hie, write_hie },
1260 [CSR_HCOUNTEREN] = { hmode, read_hcounteren, write_hcounteren },
1261 [CSR_HTVAL] = { hmode, read_htval, write_htval },
1262 [CSR_HTINST] = { hmode, read_htinst, write_htinst },
1263 [CSR_HGATP] = { hmode, read_hgatp, write_hgatp },
1264 [CSR_HTIMEDELTA] = { hmode, read_htimedelta, write_htimedelta },
1265 #if defined(TARGET_RISCV32)
1266 [CSR_HTIMEDELTAH] = { hmode, read_htimedeltah, write_htimedeltah},
1267 #endif
1269 [CSR_VSSTATUS] = { hmode, read_vsstatus, write_vsstatus },
1270 [CSR_VSIP] = { hmode, NULL, NULL, rmw_vsip },
1271 [CSR_VSIE] = { hmode, read_vsie, write_vsie },
1272 [CSR_VSTVEC] = { hmode, read_vstvec, write_vstvec },
1273 [CSR_VSSCRATCH] = { hmode, read_vsscratch, write_vsscratch },
1274 [CSR_VSEPC] = { hmode, read_vsepc, write_vsepc },
1275 [CSR_VSCAUSE] = { hmode, read_vscause, write_vscause },
1276 [CSR_VSTVAL] = { hmode, read_vstval, write_vstval },
1277 [CSR_VSATP] = { hmode, read_vsatp, write_vsatp },
1279 [CSR_MTVAL2] = { hmode, read_mtval2, write_mtval2 },
1280 [CSR_MTINST] = { hmode, read_mtinst, write_mtinst },
1282 /* Physical Memory Protection */
1283 [CSR_PMPCFG0 ... CSR_PMPADDR9] = { pmp, read_pmpcfg, write_pmpcfg },
1284 [CSR_PMPADDR0 ... CSR_PMPADDR15] = { pmp, read_pmpaddr, write_pmpaddr },
1286 /* Performance Counters */
1287 [CSR_HPMCOUNTER3 ... CSR_HPMCOUNTER31] = { ctr, read_zero },
1288 [CSR_MHPMCOUNTER3 ... CSR_MHPMCOUNTER31] = { any, read_zero },
1289 [CSR_MHPMEVENT3 ... CSR_MHPMEVENT31] = { any, read_zero },
1290 #if defined(TARGET_RISCV32)
1291 [CSR_HPMCOUNTER3H ... CSR_HPMCOUNTER31H] = { ctr, read_zero },
1292 [CSR_MHPMCOUNTER3H ... CSR_MHPMCOUNTER31H] = { any, read_zero },
1293 #endif
1294 #endif /* !CONFIG_USER_ONLY */