1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2020-2023 Loongson Technology Corporation Limited 4 */ 5 6 #ifndef __ASM_LOONGARCH_KVM_CSR_H__ 7 #define __ASM_LOONGARCH_KVM_CSR_H__ 8 9 #include <linux/uaccess.h> 10 #include <linux/kvm_host.h> 11 #include <asm/loongarch.h> 12 #include <asm/kvm_vcpu.h> 13 14 #define gcsr_read(csr) \ 15 ({ \ 16 register unsigned long __v; \ 17 __asm__ __volatile__( \ 18 " gcsrrd %[val], %[reg]\n\t" \ 19 : [val] "=r" (__v) \ 20 : [reg] "i" (csr) \ 21 : "memory"); \ 22 __v; \ 23 }) 24 25 #define gcsr_write(v, csr) \ 26 ({ \ 27 register unsigned long __v = v; \ 28 __asm__ __volatile__ ( \ 29 " gcsrwr %[val], %[reg]\n\t" \ 30 : [val] "+r" (__v) \ 31 : [reg] "i" (csr) \ 32 : "memory"); \ 33 }) 34 35 #define gcsr_xchg(v, m, csr) \ 36 ({ \ 37 register unsigned long __v = v; \ 38 __asm__ __volatile__( \ 39 " gcsrxchg %[val], %[mask], %[reg]\n\t" \ 40 : [val] "+r" (__v) \ 41 : [mask] "r" (m), [reg] "i" (csr) \ 42 : "memory"); \ 43 __v; \ 44 }) 45 46 /* Guest CSRS read and write */ 47 #define read_gcsr_crmd() gcsr_read(LOONGARCH_CSR_CRMD) 48 #define write_gcsr_crmd(val) gcsr_write(val, LOONGARCH_CSR_CRMD) 49 #define read_gcsr_prmd() gcsr_read(LOONGARCH_CSR_PRMD) 50 #define write_gcsr_prmd(val) gcsr_write(val, LOONGARCH_CSR_PRMD) 51 #define read_gcsr_euen() gcsr_read(LOONGARCH_CSR_EUEN) 52 #define write_gcsr_euen(val) gcsr_write(val, LOONGARCH_CSR_EUEN) 53 #define read_gcsr_misc() gcsr_read(LOONGARCH_CSR_MISC) 54 #define write_gcsr_misc(val) gcsr_write(val, LOONGARCH_CSR_MISC) 55 #define read_gcsr_ecfg() gcsr_read(LOONGARCH_CSR_ECFG) 56 #define write_gcsr_ecfg(val) gcsr_write(val, LOONGARCH_CSR_ECFG) 57 #define read_gcsr_estat() gcsr_read(LOONGARCH_CSR_ESTAT) 58 #define write_gcsr_estat(val) gcsr_write(val, LOONGARCH_CSR_ESTAT) 59 #define read_gcsr_era() gcsr_read(LOONGARCH_CSR_ERA) 60 #define write_gcsr_era(val) gcsr_write(val, LOONGARCH_CSR_ERA) 61 #define read_gcsr_badv() gcsr_read(LOONGARCH_CSR_BADV) 62 #define write_gcsr_badv(val) gcsr_write(val, LOONGARCH_CSR_BADV) 63 #define read_gcsr_badi() gcsr_read(LOONGARCH_CSR_BADI) 64 #define write_gcsr_badi(val) gcsr_write(val, LOONGARCH_CSR_BADI) 65 #define read_gcsr_eentry() gcsr_read(LOONGARCH_CSR_EENTRY) 66 #define write_gcsr_eentry(val) gcsr_write(val, LOONGARCH_CSR_EENTRY) 67 68 #define read_gcsr_asid() gcsr_read(LOONGARCH_CSR_ASID) 69 #define write_gcsr_asid(val) gcsr_write(val, LOONGARCH_CSR_ASID) 70 #define read_gcsr_pgdl() gcsr_read(LOONGARCH_CSR_PGDL) 71 #define write_gcsr_pgdl(val) gcsr_write(val, LOONGARCH_CSR_PGDL) 72 #define read_gcsr_pgdh() gcsr_read(LOONGARCH_CSR_PGDH) 73 #define write_gcsr_pgdh(val) gcsr_write(val, LOONGARCH_CSR_PGDH) 74 #define write_gcsr_pgd(val) gcsr_write(val, LOONGARCH_CSR_PGD) 75 #define read_gcsr_pgd() gcsr_read(LOONGARCH_CSR_PGD) 76 #define read_gcsr_pwctl0() gcsr_read(LOONGARCH_CSR_PWCTL0) 77 #define write_gcsr_pwctl0(val) gcsr_write(val, LOONGARCH_CSR_PWCTL0) 78 #define read_gcsr_pwctl1() gcsr_read(LOONGARCH_CSR_PWCTL1) 79 #define write_gcsr_pwctl1(val) gcsr_write(val, LOONGARCH_CSR_PWCTL1) 80 #define read_gcsr_stlbpgsize() gcsr_read(LOONGARCH_CSR_STLBPGSIZE) 81 #define write_gcsr_stlbpgsize(val) gcsr_write(val, LOONGARCH_CSR_STLBPGSIZE) 82 #define read_gcsr_rvacfg() gcsr_read(LOONGARCH_CSR_RVACFG) 83 #define write_gcsr_rvacfg(val) gcsr_write(val, LOONGARCH_CSR_RVACFG) 84 85 #define read_gcsr_cpuid() gcsr_read(LOONGARCH_CSR_CPUID) 86 #define write_gcsr_cpuid(val) gcsr_write(val, LOONGARCH_CSR_CPUID) 87 #define read_gcsr_prcfg1() gcsr_read(LOONGARCH_CSR_PRCFG1) 88 #define write_gcsr_prcfg1(val) gcsr_write(val, LOONGARCH_CSR_PRCFG1) 89 #define read_gcsr_prcfg2() gcsr_read(LOONGARCH_CSR_PRCFG2) 90 #define write_gcsr_prcfg2(val) gcsr_write(val, LOONGARCH_CSR_PRCFG2) 91 #define read_gcsr_prcfg3() gcsr_read(LOONGARCH_CSR_PRCFG3) 92 #define write_gcsr_prcfg3(val) gcsr_write(val, LOONGARCH_CSR_PRCFG3) 93 94 #define read_gcsr_kscratch0() gcsr_read(LOONGARCH_CSR_KS0) 95 #define write_gcsr_kscratch0(val) gcsr_write(val, LOONGARCH_CSR_KS0) 96 #define read_gcsr_kscratch1() gcsr_read(LOONGARCH_CSR_KS1) 97 #define write_gcsr_kscratch1(val) gcsr_write(val, LOONGARCH_CSR_KS1) 98 #define read_gcsr_kscratch2() gcsr_read(LOONGARCH_CSR_KS2) 99 #define write_gcsr_kscratch2(val) gcsr_write(val, LOONGARCH_CSR_KS2) 100 #define read_gcsr_kscratch3() gcsr_read(LOONGARCH_CSR_KS3) 101 #define write_gcsr_kscratch3(val) gcsr_write(val, LOONGARCH_CSR_KS3) 102 #define read_gcsr_kscratch4() gcsr_read(LOONGARCH_CSR_KS4) 103 #define write_gcsr_kscratch4(val) gcsr_write(val, LOONGARCH_CSR_KS4) 104 #define read_gcsr_kscratch5() gcsr_read(LOONGARCH_CSR_KS5) 105 #define write_gcsr_kscratch5(val) gcsr_write(val, LOONGARCH_CSR_KS5) 106 #define read_gcsr_kscratch6() gcsr_read(LOONGARCH_CSR_KS6) 107 #define write_gcsr_kscratch6(val) gcsr_write(val, LOONGARCH_CSR_KS6) 108 #define read_gcsr_kscratch7() gcsr_read(LOONGARCH_CSR_KS7) 109 #define write_gcsr_kscratch7(val) gcsr_write(val, LOONGARCH_CSR_KS7) 110 111 #define read_gcsr_timerid() gcsr_read(LOONGARCH_CSR_TMID) 112 #define write_gcsr_timerid(val) gcsr_write(val, LOONGARCH_CSR_TMID) 113 #define read_gcsr_timercfg() gcsr_read(LOONGARCH_CSR_TCFG) 114 #define write_gcsr_timercfg(val) gcsr_write(val, LOONGARCH_CSR_TCFG) 115 #define read_gcsr_timertick() gcsr_read(LOONGARCH_CSR_TVAL) 116 #define write_gcsr_timertick(val) gcsr_write(val, LOONGARCH_CSR_TVAL) 117 #define read_gcsr_timeroffset() gcsr_read(LOONGARCH_CSR_CNTC) 118 #define write_gcsr_timeroffset(val) gcsr_write(val, LOONGARCH_CSR_CNTC) 119 120 #define read_gcsr_llbctl() gcsr_read(LOONGARCH_CSR_LLBCTL) 121 #define write_gcsr_llbctl(val) gcsr_write(val, LOONGARCH_CSR_LLBCTL) 122 123 #define read_gcsr_tlbidx() gcsr_read(LOONGARCH_CSR_TLBIDX) 124 #define write_gcsr_tlbidx(val) gcsr_write(val, LOONGARCH_CSR_TLBIDX) 125 #define read_gcsr_tlbrentry() gcsr_read(LOONGARCH_CSR_TLBRENTRY) 126 #define write_gcsr_tlbrentry(val) gcsr_write(val, LOONGARCH_CSR_TLBRENTRY) 127 #define read_gcsr_tlbrbadv() gcsr_read(LOONGARCH_CSR_TLBRBADV) 128 #define write_gcsr_tlbrbadv(val) gcsr_write(val, LOONGARCH_CSR_TLBRBADV) 129 #define read_gcsr_tlbrera() gcsr_read(LOONGARCH_CSR_TLBRERA) 130 #define write_gcsr_tlbrera(val) gcsr_write(val, LOONGARCH_CSR_TLBRERA) 131 #define read_gcsr_tlbrsave() gcsr_read(LOONGARCH_CSR_TLBRSAVE) 132 #define write_gcsr_tlbrsave(val) gcsr_write(val, LOONGARCH_CSR_TLBRSAVE) 133 #define read_gcsr_tlbrelo0() gcsr_read(LOONGARCH_CSR_TLBRELO0) 134 #define write_gcsr_tlbrelo0(val) gcsr_write(val, LOONGARCH_CSR_TLBRELO0) 135 #define read_gcsr_tlbrelo1() gcsr_read(LOONGARCH_CSR_TLBRELO1) 136 #define write_gcsr_tlbrelo1(val) gcsr_write(val, LOONGARCH_CSR_TLBRELO1) 137 #define read_gcsr_tlbrehi() gcsr_read(LOONGARCH_CSR_TLBREHI) 138 #define write_gcsr_tlbrehi(val) gcsr_write(val, LOONGARCH_CSR_TLBREHI) 139 #define read_gcsr_tlbrprmd() gcsr_read(LOONGARCH_CSR_TLBRPRMD) 140 #define write_gcsr_tlbrprmd(val) gcsr_write(val, LOONGARCH_CSR_TLBRPRMD) 141 142 #define read_gcsr_directwin0() gcsr_read(LOONGARCH_CSR_DMWIN0) 143 #define write_gcsr_directwin0(val) gcsr_write(val, LOONGARCH_CSR_DMWIN0) 144 #define read_gcsr_directwin1() gcsr_read(LOONGARCH_CSR_DMWIN1) 145 #define write_gcsr_directwin1(val) gcsr_write(val, LOONGARCH_CSR_DMWIN1) 146 #define read_gcsr_directwin2() gcsr_read(LOONGARCH_CSR_DMWIN2) 147 #define write_gcsr_directwin2(val) gcsr_write(val, LOONGARCH_CSR_DMWIN2) 148 #define read_gcsr_directwin3() gcsr_read(LOONGARCH_CSR_DMWIN3) 149 #define write_gcsr_directwin3(val) gcsr_write(val, LOONGARCH_CSR_DMWIN3) 150 151 /* Guest related CSRs */ 152 #define read_csr_gtlbc() csr_read64(LOONGARCH_CSR_GTLBC) 153 #define write_csr_gtlbc(val) csr_write64(val, LOONGARCH_CSR_GTLBC) 154 #define read_csr_trgp() csr_read64(LOONGARCH_CSR_TRGP) 155 #define read_csr_gcfg() csr_read64(LOONGARCH_CSR_GCFG) 156 #define write_csr_gcfg(val) csr_write64(val, LOONGARCH_CSR_GCFG) 157 #define read_csr_gstat() csr_read64(LOONGARCH_CSR_GSTAT) 158 #define write_csr_gstat(val) csr_write64(val, LOONGARCH_CSR_GSTAT) 159 #define read_csr_gintc() csr_read64(LOONGARCH_CSR_GINTC) 160 #define write_csr_gintc(val) csr_write64(val, LOONGARCH_CSR_GINTC) 161 #define read_csr_gcntc() csr_read64(LOONGARCH_CSR_GCNTC) 162 #define write_csr_gcntc(val) csr_write64(val, LOONGARCH_CSR_GCNTC) 163 164 #define __BUILD_GCSR_OP(name) __BUILD_CSR_COMMON(gcsr_##name) 165 166 __BUILD_CSR_OP(gcfg) 167 __BUILD_CSR_OP(gstat) 168 __BUILD_CSR_OP(gtlbc) 169 __BUILD_CSR_OP(gintc) 170 __BUILD_GCSR_OP(llbctl) 171 __BUILD_GCSR_OP(tlbidx) 172 173 #define set_gcsr_estat(val) \ 174 gcsr_xchg(val, val, LOONGARCH_CSR_ESTAT) 175 #define clear_gcsr_estat(val) \ 176 gcsr_xchg(~(val), val, LOONGARCH_CSR_ESTAT) 177 178 #define kvm_read_hw_gcsr(id) gcsr_read(id) 179 #define kvm_write_hw_gcsr(id, val) gcsr_write(val, id) 180 181 #define kvm_save_hw_gcsr(csr, gid) (csr->csrs[gid] = gcsr_read(gid)) 182 #define kvm_restore_hw_gcsr(csr, gid) (gcsr_write(csr->csrs[gid], gid)) 183 184 int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu); 185 186 static __always_inline unsigned long kvm_read_sw_gcsr(struct loongarch_csrs *csr, int gid) 187 { 188 return csr->csrs[gid]; 189 } 190 191 static __always_inline void kvm_write_sw_gcsr(struct loongarch_csrs *csr, int gid, unsigned long val) 192 { 193 csr->csrs[gid] = val; 194 } 195 196 static __always_inline void kvm_set_sw_gcsr(struct loongarch_csrs *csr, 197 int gid, unsigned long val) 198 { 199 csr->csrs[gid] |= val; 200 } 201 202 static __always_inline void kvm_change_sw_gcsr(struct loongarch_csrs *csr, 203 int gid, unsigned long mask, unsigned long val) 204 { 205 unsigned long _mask = mask; 206 207 csr->csrs[gid] &= ~_mask; 208 csr->csrs[gid] |= val & _mask; 209 } 210 211 #endif /* __ASM_LOONGARCH_KVM_CSR_H__ */ 212