xref: /qemu/target/loongarch/csr.c (revision 8b647bd352505234cab2acd2422aba183a1aa1fd)
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