csr_helper.c (1989B)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * LoongArch emulation helpers for CSRs 4 * 5 * Copyright (c) 2021 Loongson Technology Corporation Limited 6 */ 7 8 #include "qemu/osdep.h" 9 #include "qemu/main-loop.h" 10 #include "cpu.h" 11 #include "internals.h" 12 #include "qemu/host-utils.h" 13 #include "exec/helper-proto.h" 14 #include "exec/exec-all.h" 15 #include "exec/cpu_ldst.h" 16 #include "hw/irq.h" 17 #include "cpu-csr.h" 18 #include "tcg/tcg-ldst.h" 19 20 target_ulong helper_csrrd_pgd(CPULoongArchState *env) 21 { 22 int64_t v; 23 24 if (env->CSR_TLBRERA & 0x1) { 25 v = env->CSR_TLBRBADV; 26 } else { 27 v = env->CSR_BADV; 28 } 29 30 if ((v >> 63) & 0x1) { 31 v = env->CSR_PGDH; 32 } else { 33 v = env->CSR_PGDL; 34 } 35 36 return v; 37 } 38 39 target_ulong helper_csrrd_tval(CPULoongArchState *env) 40 { 41 LoongArchCPU *cpu = env_archcpu(env); 42 43 return cpu_loongarch_get_constant_timer_ticks(cpu); 44 } 45 46 target_ulong helper_csrwr_estat(CPULoongArchState *env, target_ulong val) 47 { 48 int64_t old_v = env->CSR_ESTAT; 49 50 /* Only IS[1:0] can be written */ 51 env->CSR_ESTAT = deposit64(env->CSR_ESTAT, 0, 2, val); 52 53 return old_v; 54 } 55 56 target_ulong helper_csrwr_asid(CPULoongArchState *env, target_ulong val) 57 { 58 int64_t old_v = env->CSR_ASID; 59 60 /* Only ASID filed of CSR_ASID can be written */ 61 env->CSR_ASID = deposit64(env->CSR_ASID, 0, 10, val); 62 if (old_v != env->CSR_ASID) { 63 tlb_flush(env_cpu(env)); 64 } 65 return old_v; 66 } 67 68 target_ulong helper_csrwr_tcfg(CPULoongArchState *env, target_ulong val) 69 { 70 LoongArchCPU *cpu = env_archcpu(env); 71 int64_t old_v = env->CSR_TCFG; 72 73 cpu_loongarch_store_constant_timer_config(cpu, val); 74 75 return old_v; 76 } 77 78 target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val) 79 { 80 LoongArchCPU *cpu = env_archcpu(env); 81 int64_t old_v = 0; 82 83 if (val & 0x1) { 84 qemu_mutex_lock_iothread(); 85 loongarch_cpu_set_irq(cpu, IRQ_TIMER, 0); 86 qemu_mutex_unlock_iothread(); 87 } 88 return old_v; 89 }