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