xref: /openbmc/qemu/target/loongarch/tcg/csr_helper.c (revision 195801d7)
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