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 19 target_ulong helper_csrrd_pgd(CPULoongArchState *env) 20 { 21 int64_t v; 22 23 if (env->CSR_TLBRERA & 0x1) { 24 v = env->CSR_TLBRBADV; 25 } else { 26 v = env->CSR_BADV; 27 } 28 29 if ((v >> 63) & 0x1) { 30 v = env->CSR_PGDH; 31 } else { 32 v = env->CSR_PGDL; 33 } 34 35 return v; 36 } 37 38 target_ulong helper_csrrd_cpuid(CPULoongArchState *env) 39 { 40 LoongArchCPU *lac = env_archcpu(env); 41 42 env->CSR_CPUID = CPU(lac)->cpu_index; 43 44 return env->CSR_CPUID; 45 } 46 47 target_ulong helper_csrrd_tval(CPULoongArchState *env) 48 { 49 LoongArchCPU *cpu = env_archcpu(env); 50 51 return cpu_loongarch_get_constant_timer_ticks(cpu); 52 } 53 54 target_ulong helper_csrwr_estat(CPULoongArchState *env, target_ulong val) 55 { 56 int64_t old_v = env->CSR_ESTAT; 57 58 /* Only IS[1:0] can be written */ 59 env->CSR_ESTAT = deposit64(env->CSR_ESTAT, 0, 2, val); 60 61 return old_v; 62 } 63 64 target_ulong helper_csrwr_asid(CPULoongArchState *env, target_ulong val) 65 { 66 int64_t old_v = env->CSR_ASID; 67 68 /* Only ASID filed of CSR_ASID can be written */ 69 env->CSR_ASID = deposit64(env->CSR_ASID, 0, 10, val); 70 if (old_v != env->CSR_ASID) { 71 tlb_flush(env_cpu(env)); 72 } 73 return old_v; 74 } 75 76 target_ulong helper_csrwr_tcfg(CPULoongArchState *env, target_ulong val) 77 { 78 LoongArchCPU *cpu = env_archcpu(env); 79 int64_t old_v = env->CSR_TCFG; 80 81 cpu_loongarch_store_constant_timer_config(cpu, val); 82 83 return old_v; 84 } 85 86 target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val) 87 { 88 LoongArchCPU *cpu = env_archcpu(env); 89 int64_t old_v = 0; 90 91 if (val & 0x1) { 92 bql_lock(); 93 loongarch_cpu_set_irq(cpu, IRQ_TIMER, 0); 94 bql_unlock(); 95 } 96 return old_v; 97 } 98