| /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
 | /* | 
 |  * Copyright (c) 2025 Loongson Technology Corporation Limited | 
 |  */ | 
 | #include <stddef.h> | 
 | #include "qemu/osdep.h" | 
 | #include "cpu.h" | 
 | #include "csr.h" | 
 |  | 
 | #define CSR_OFF_FUNCS(NAME, FL, RD, WR)                    \ | 
 |     [LOONGARCH_CSR_##NAME] = {                             \ | 
 |         .name   = (stringify(NAME)),                       \ | 
 |         .offset = offsetof(CPULoongArchState, CSR_##NAME), \ | 
 |         .flags = FL, .readfn = RD, .writefn = WR           \ | 
 |     } | 
 |  | 
 | #define CSR_OFF_ARRAY(NAME, N)                                \ | 
 |     [LOONGARCH_CSR_##NAME(N)] = {                             \ | 
 |         .name   = (stringify(NAME##N)),                       \ | 
 |         .offset = offsetof(CPULoongArchState, CSR_##NAME[N]), \ | 
 |         .flags = 0, .readfn = NULL, .writefn = NULL           \ | 
 |     } | 
 |  | 
 | #define CSR_OFF_FLAGS(NAME, FL)   CSR_OFF_FUNCS(NAME, FL, NULL, NULL) | 
 | #define CSR_OFF(NAME)             CSR_OFF_FLAGS(NAME, 0) | 
 |  | 
 | static CSRInfo csr_info[] = { | 
 |     CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB), | 
 |     CSR_OFF(PRMD), | 
 |     CSR_OFF_FLAGS(EUEN, CSRFL_EXITTB), | 
 |     CSR_OFF_FLAGS(MISC, CSRFL_READONLY), | 
 |     CSR_OFF(ECFG), | 
 |     CSR_OFF_FLAGS(ESTAT, CSRFL_EXITTB), | 
 |     CSR_OFF(ERA), | 
 |     CSR_OFF(BADV), | 
 |     CSR_OFF_FLAGS(BADI, CSRFL_READONLY), | 
 |     CSR_OFF(EENTRY), | 
 |     CSR_OFF(TLBIDX), | 
 |     CSR_OFF(TLBEHI), | 
 |     CSR_OFF(TLBELO0), | 
 |     CSR_OFF(TLBELO1), | 
 |     CSR_OFF_FLAGS(ASID, CSRFL_EXITTB), | 
 |     CSR_OFF(PGDL), | 
 |     CSR_OFF(PGDH), | 
 |     CSR_OFF_FLAGS(PGD, CSRFL_READONLY), | 
 |     CSR_OFF(PWCL), | 
 |     CSR_OFF(PWCH), | 
 |     CSR_OFF(STLBPS), | 
 |     CSR_OFF(RVACFG), | 
 |     CSR_OFF_FLAGS(CPUID, CSRFL_READONLY), | 
 |     CSR_OFF_FLAGS(PRCFG1, CSRFL_READONLY), | 
 |     CSR_OFF_FLAGS(PRCFG2, CSRFL_READONLY), | 
 |     CSR_OFF_FLAGS(PRCFG3, CSRFL_READONLY), | 
 |     CSR_OFF_ARRAY(SAVE, 0), | 
 |     CSR_OFF_ARRAY(SAVE, 1), | 
 |     CSR_OFF_ARRAY(SAVE, 2), | 
 |     CSR_OFF_ARRAY(SAVE, 3), | 
 |     CSR_OFF_ARRAY(SAVE, 4), | 
 |     CSR_OFF_ARRAY(SAVE, 5), | 
 |     CSR_OFF_ARRAY(SAVE, 6), | 
 |     CSR_OFF_ARRAY(SAVE, 7), | 
 |     CSR_OFF_ARRAY(SAVE, 8), | 
 |     CSR_OFF_ARRAY(SAVE, 9), | 
 |     CSR_OFF_ARRAY(SAVE, 10), | 
 |     CSR_OFF_ARRAY(SAVE, 11), | 
 |     CSR_OFF_ARRAY(SAVE, 12), | 
 |     CSR_OFF_ARRAY(SAVE, 13), | 
 |     CSR_OFF_ARRAY(SAVE, 14), | 
 |     CSR_OFF_ARRAY(SAVE, 15), | 
 |     CSR_OFF(TID), | 
 |     CSR_OFF_FLAGS(TCFG, CSRFL_IO), | 
 |     CSR_OFF_FLAGS(TVAL, CSRFL_READONLY | CSRFL_IO), | 
 |     CSR_OFF(CNTC), | 
 |     CSR_OFF_FLAGS(TICLR, CSRFL_IO), | 
 |     CSR_OFF(LLBCTL), | 
 |     CSR_OFF(IMPCTL1), | 
 |     CSR_OFF(IMPCTL2), | 
 |     CSR_OFF(TLBRENTRY), | 
 |     CSR_OFF(TLBRBADV), | 
 |     CSR_OFF(TLBRERA), | 
 |     CSR_OFF(TLBRSAVE), | 
 |     CSR_OFF(TLBRELO0), | 
 |     CSR_OFF(TLBRELO1), | 
 |     CSR_OFF(TLBREHI), | 
 |     CSR_OFF(TLBRPRMD), | 
 |     CSR_OFF(MERRCTL), | 
 |     CSR_OFF(MERRINFO1), | 
 |     CSR_OFF(MERRINFO2), | 
 |     CSR_OFF(MERRENTRY), | 
 |     CSR_OFF(MERRERA), | 
 |     CSR_OFF(MERRSAVE), | 
 |     CSR_OFF(CTAG), | 
 |     CSR_OFF_ARRAY(DMW, 0), | 
 |     CSR_OFF_ARRAY(DMW, 1), | 
 |     CSR_OFF_ARRAY(DMW, 2), | 
 |     CSR_OFF_ARRAY(DMW, 3), | 
 |     CSR_OFF(DBG), | 
 |     CSR_OFF(DERA), | 
 |     CSR_OFF(DSAVE), | 
 | }; | 
 |  | 
 | CSRInfo *get_csr(unsigned int csr_num) | 
 | { | 
 |     CSRInfo *csr; | 
 |  | 
 |     if (csr_num >= ARRAY_SIZE(csr_info)) { | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     csr = &csr_info[csr_num]; | 
 |     if (csr->offset == 0) { | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     return csr; | 
 | } | 
 |  | 
 | bool set_csr_flag(unsigned int csr_num, int flag) | 
 | { | 
 |     CSRInfo *csr; | 
 |  | 
 |     csr = get_csr(csr_num); | 
 |     if (!csr) { | 
 |         return false; | 
 |     } | 
 |  | 
 |     csr->flags |= flag; | 
 |     return true; | 
 | } |