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