15c23704eSSong Gao /* SPDX-License-Identifier: GPL-2.0-or-later */
25c23704eSSong Gao /*
35c23704eSSong Gao * LoongArch emulation helpers for CSRs
45c23704eSSong Gao *
55c23704eSSong Gao * Copyright (c) 2021 Loongson Technology Corporation Limited
65c23704eSSong Gao */
75c23704eSSong Gao
85c23704eSSong Gao #include "qemu/osdep.h"
95c23704eSSong Gao #include "qemu/main-loop.h"
105c23704eSSong Gao #include "cpu.h"
115c23704eSSong Gao #include "internals.h"
125c23704eSSong Gao #include "qemu/host-utils.h"
135c23704eSSong Gao #include "exec/helper-proto.h"
145c23704eSSong Gao #include "exec/exec-all.h"
155c23704eSSong Gao #include "exec/cpu_ldst.h"
165c23704eSSong Gao #include "hw/irq.h"
175c23704eSSong Gao #include "cpu-csr.h"
185c23704eSSong Gao
helper_csrrd_pgd(CPULoongArchState * env)195c23704eSSong Gao target_ulong helper_csrrd_pgd(CPULoongArchState *env)
205c23704eSSong Gao {
215c23704eSSong Gao int64_t v;
225c23704eSSong Gao
235c23704eSSong Gao if (env->CSR_TLBRERA & 0x1) {
245c23704eSSong Gao v = env->CSR_TLBRBADV;
255c23704eSSong Gao } else {
265c23704eSSong Gao v = env->CSR_BADV;
275c23704eSSong Gao }
285c23704eSSong Gao
295c23704eSSong Gao if ((v >> 63) & 0x1) {
305c23704eSSong Gao v = env->CSR_PGDH;
315c23704eSSong Gao } else {
325c23704eSSong Gao v = env->CSR_PGDL;
335c23704eSSong Gao }
345c23704eSSong Gao
355c23704eSSong Gao return v;
365c23704eSSong Gao }
375c23704eSSong Gao
helper_csrrd_cpuid(CPULoongArchState * env)385c23704eSSong Gao target_ulong helper_csrrd_cpuid(CPULoongArchState *env)
395c23704eSSong Gao {
405c23704eSSong Gao LoongArchCPU *lac = env_archcpu(env);
415c23704eSSong Gao
425c23704eSSong Gao env->CSR_CPUID = CPU(lac)->cpu_index;
435c23704eSSong Gao
445c23704eSSong Gao return env->CSR_CPUID;
455c23704eSSong Gao }
465c23704eSSong Gao
helper_csrrd_tval(CPULoongArchState * env)475c23704eSSong Gao target_ulong helper_csrrd_tval(CPULoongArchState *env)
485c23704eSSong Gao {
495c23704eSSong Gao LoongArchCPU *cpu = env_archcpu(env);
505c23704eSSong Gao
515c23704eSSong Gao return cpu_loongarch_get_constant_timer_ticks(cpu);
525c23704eSSong Gao }
535c23704eSSong Gao
helper_csrwr_estat(CPULoongArchState * env,target_ulong val)545c23704eSSong Gao target_ulong helper_csrwr_estat(CPULoongArchState *env, target_ulong val)
555c23704eSSong Gao {
565c23704eSSong Gao int64_t old_v = env->CSR_ESTAT;
575c23704eSSong Gao
585c23704eSSong Gao /* Only IS[1:0] can be written */
595c23704eSSong Gao env->CSR_ESTAT = deposit64(env->CSR_ESTAT, 0, 2, val);
605c23704eSSong Gao
615c23704eSSong Gao return old_v;
625c23704eSSong Gao }
635c23704eSSong Gao
helper_csrwr_asid(CPULoongArchState * env,target_ulong val)645c23704eSSong Gao target_ulong helper_csrwr_asid(CPULoongArchState *env, target_ulong val)
655c23704eSSong Gao {
665c23704eSSong Gao int64_t old_v = env->CSR_ASID;
675c23704eSSong Gao
685c23704eSSong Gao /* Only ASID filed of CSR_ASID can be written */
695c23704eSSong Gao env->CSR_ASID = deposit64(env->CSR_ASID, 0, 10, val);
705c23704eSSong Gao if (old_v != env->CSR_ASID) {
715c23704eSSong Gao tlb_flush(env_cpu(env));
725c23704eSSong Gao }
735c23704eSSong Gao return old_v;
745c23704eSSong Gao }
755c23704eSSong Gao
helper_csrwr_tcfg(CPULoongArchState * env,target_ulong val)765c23704eSSong Gao target_ulong helper_csrwr_tcfg(CPULoongArchState *env, target_ulong val)
775c23704eSSong Gao {
785c23704eSSong Gao LoongArchCPU *cpu = env_archcpu(env);
795c23704eSSong Gao int64_t old_v = env->CSR_TCFG;
805c23704eSSong Gao
815c23704eSSong Gao cpu_loongarch_store_constant_timer_config(cpu, val);
825c23704eSSong Gao
835c23704eSSong Gao return old_v;
845c23704eSSong Gao }
855c23704eSSong Gao
helper_csrwr_ticlr(CPULoongArchState * env,target_ulong val)865c23704eSSong Gao target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val)
875c23704eSSong Gao {
885c23704eSSong Gao LoongArchCPU *cpu = env_archcpu(env);
895c23704eSSong Gao int64_t old_v = 0;
905c23704eSSong Gao
915c23704eSSong Gao if (val & 0x1) {
92*195801d7SStefan Hajnoczi bql_lock();
935c23704eSSong Gao loongarch_cpu_set_irq(cpu, IRQ_TIMER, 0);
94*195801d7SStefan Hajnoczi bql_unlock();
955c23704eSSong Gao }
965c23704eSSong Gao return old_v;
975c23704eSSong Gao }
98