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