1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Copyright (c) 2025 Loongson Technology Corporation Limited 4 */ 5 #include <stddef.h> 6 #include "qemu/osdep.h" 7 #include "cpu.h" 8 #include "csr.h" 9 10 #define CSR_OFF_FUNCS(NAME, FL, RD, WR) \ 11 [LOONGARCH_CSR_##NAME] = { \ 12 .name = (stringify(NAME)), \ 13 .offset = offsetof(CPULoongArchState, CSR_##NAME), \ 14 .flags = FL, .readfn = RD, .writefn = WR \ 15 } 16 17 #define CSR_OFF_ARRAY(NAME, N) \ 18 [LOONGARCH_CSR_##NAME(N)] = { \ 19 .name = (stringify(NAME##N)), \ 20 .offset = offsetof(CPULoongArchState, CSR_##NAME[N]), \ 21 .flags = 0, .readfn = NULL, .writefn = NULL \ 22 } 23 24 #define CSR_OFF_FLAGS(NAME, FL) CSR_OFF_FUNCS(NAME, FL, NULL, NULL) 25 #define CSR_OFF(NAME) CSR_OFF_FLAGS(NAME, 0) 26 27 static CSRInfo csr_info[] = { 28 CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB), 29 CSR_OFF(PRMD), 30 CSR_OFF_FLAGS(EUEN, CSRFL_EXITTB), 31 CSR_OFF_FLAGS(MISC, CSRFL_READONLY), 32 CSR_OFF(ECFG), 33 CSR_OFF_FLAGS(ESTAT, CSRFL_EXITTB), 34 CSR_OFF(ERA), 35 CSR_OFF(BADV), 36 CSR_OFF_FLAGS(BADI, CSRFL_READONLY), 37 CSR_OFF(EENTRY), 38 CSR_OFF(TLBIDX), 39 CSR_OFF(TLBEHI), 40 CSR_OFF(TLBELO0), 41 CSR_OFF(TLBELO1), 42 CSR_OFF_FLAGS(ASID, CSRFL_EXITTB), 43 CSR_OFF(PGDL), 44 CSR_OFF(PGDH), 45 CSR_OFF_FLAGS(PGD, CSRFL_READONLY), 46 CSR_OFF(PWCL), 47 CSR_OFF(PWCH), 48 CSR_OFF(STLBPS), 49 CSR_OFF(RVACFG), 50 CSR_OFF_FLAGS(CPUID, CSRFL_READONLY), 51 CSR_OFF_FLAGS(PRCFG1, CSRFL_READONLY), 52 CSR_OFF_FLAGS(PRCFG2, CSRFL_READONLY), 53 CSR_OFF_FLAGS(PRCFG3, CSRFL_READONLY), 54 CSR_OFF_ARRAY(SAVE, 0), 55 CSR_OFF_ARRAY(SAVE, 1), 56 CSR_OFF_ARRAY(SAVE, 2), 57 CSR_OFF_ARRAY(SAVE, 3), 58 CSR_OFF_ARRAY(SAVE, 4), 59 CSR_OFF_ARRAY(SAVE, 5), 60 CSR_OFF_ARRAY(SAVE, 6), 61 CSR_OFF_ARRAY(SAVE, 7), 62 CSR_OFF_ARRAY(SAVE, 8), 63 CSR_OFF_ARRAY(SAVE, 9), 64 CSR_OFF_ARRAY(SAVE, 10), 65 CSR_OFF_ARRAY(SAVE, 11), 66 CSR_OFF_ARRAY(SAVE, 12), 67 CSR_OFF_ARRAY(SAVE, 13), 68 CSR_OFF_ARRAY(SAVE, 14), 69 CSR_OFF_ARRAY(SAVE, 15), 70 CSR_OFF(TID), 71 CSR_OFF_FLAGS(TCFG, CSRFL_IO), 72 CSR_OFF_FLAGS(TVAL, CSRFL_READONLY | CSRFL_IO), 73 CSR_OFF(CNTC), 74 CSR_OFF_FLAGS(TICLR, CSRFL_IO), 75 CSR_OFF(LLBCTL), 76 CSR_OFF(IMPCTL1), 77 CSR_OFF(IMPCTL2), 78 CSR_OFF(TLBRENTRY), 79 CSR_OFF(TLBRBADV), 80 CSR_OFF(TLBRERA), 81 CSR_OFF(TLBRSAVE), 82 CSR_OFF(TLBRELO0), 83 CSR_OFF(TLBRELO1), 84 CSR_OFF(TLBREHI), 85 CSR_OFF(TLBRPRMD), 86 CSR_OFF(MERRCTL), 87 CSR_OFF(MERRINFO1), 88 CSR_OFF(MERRINFO2), 89 CSR_OFF(MERRENTRY), 90 CSR_OFF(MERRERA), 91 CSR_OFF(MERRSAVE), 92 CSR_OFF(CTAG), 93 CSR_OFF_ARRAY(DMW, 0), 94 CSR_OFF_ARRAY(DMW, 1), 95 CSR_OFF_ARRAY(DMW, 2), 96 CSR_OFF_ARRAY(DMW, 3), 97 CSR_OFF(DBG), 98 CSR_OFF(DERA), 99 CSR_OFF(DSAVE), 100 }; 101 102 CSRInfo *get_csr(unsigned int csr_num) 103 { 104 CSRInfo *csr; 105 106 if (csr_num >= ARRAY_SIZE(csr_info)) { 107 return NULL; 108 } 109 110 csr = &csr_info[csr_num]; 111 if (csr->offset == 0) { 112 return NULL; 113 } 114 115 return csr; 116 } 117 118 bool set_csr_flag(unsigned int csr_num, int flag) 119 { 120 CSRInfo *csr; 121 122 csr = get_csr(csr_num); 123 if (!csr) { 124 return false; 125 } 126 127 csr->flags |= flag; 128 return true; 129 } 130