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
get_csr(unsigned int csr_num)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
set_csr_flag(unsigned int csr_num,int flag)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