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