/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (c) 2025 Loongson Technology Corporation Limited */ #include #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; }