master
c 434 lines 13.6 KB
Raw
1 /*
2 * T-Head-specific CSRs.
3 *
4 * Copyright (c) 2024 VRULL GmbH
5 * Copyright (c) 2025 Chao Liu <chao.liu.zevorn@gmail.com>
6 *
7 * For more information, see XuanTie-C908-UserManual_xrvm_20240530.pdf
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2 or later, as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "qemu/osdep.h"
23 #include "cpu.h"
24 #include "cpu_vendorid.h"
25 #include "target/riscv/tcg/csr.h"
26
27 /* Extended M-mode control registers of T-Head */
28 #define CSR_TH_MXSTATUS 0x7c0
29 #define CSR_TH_MHCR 0x7c1
30 #define CSR_TH_MCOR 0x7c2
31 #define CSR_TH_MCCR2 0x7c3
32 #define CSR_TH_MHINT 0x7c5
33 #define CSR_TH_MRVBR 0x7c7
34 #define CSR_TH_MCOUNTERWEN 0x7c9
35 #define CSR_TH_MCOUNTERINTEN 0x7ca
36 #define CSR_TH_MCOUNTEROF 0x7cb
37 #define CSR_TH_MCINS 0x7d2
38 #define CSR_TH_MCINDEX 0x7d3
39 #define CSR_TH_MCDATA0 0x7d4
40 #define CSR_TH_MCDATA1 0x7d5
41 #define CSR_TH_MSMPR 0x7f3
42 #define CSR_TH_CPUID 0xfc0
43 #define CSR_TH_MAPBADDR 0xfc1
44
45 /* TH_MXSTATUS bits */
46 #define TH_MXSTATUS_UCME BIT(16)
47 #define TH_MXSTATUS_MAEE BIT(21)
48 #define TH_MXSTATUS_THEADISAEE BIT(22)
49
50 /* Extended S-mode control registers of T-Head */
51 #define CSR_TH_SXSTATUS 0x5c0
52 #define CSR_TH_SHCR 0x5c1
53 #define CSR_TH_SCER2 0x5c2
54 #define CSR_TH_SCER 0x5c3
55 #define CSR_TH_SCOUNTERINTEN 0x5c4
56 #define CSR_TH_SCOUNTEROF 0x5c5
57 #define CSR_TH_SCYCLE 0x5e0
58 #define CSR_TH_SHPMCOUNTER3 0x5e3
59 #define CSR_TH_SHPMCOUNTER4 0x5e4
60 #define CSR_TH_SHPMCOUNTER5 0x5e5
61 #define CSR_TH_SHPMCOUNTER6 0x5e6
62 #define CSR_TH_SHPMCOUNTER7 0x5e7
63 #define CSR_TH_SHPMCOUNTER8 0x5e8
64 #define CSR_TH_SHPMCOUNTER9 0x5e9
65 #define CSR_TH_SHPMCOUNTER10 0x5ea
66 #define CSR_TH_SHPMCOUNTER11 0x5eb
67 #define CSR_TH_SHPMCOUNTER12 0x5ec
68 #define CSR_TH_SHPMCOUNTER13 0x5ed
69 #define CSR_TH_SHPMCOUNTER14 0x5ee
70 #define CSR_TH_SHPMCOUNTER15 0x5ef
71 #define CSR_TH_SHPMCOUNTER16 0x5f0
72 #define CSR_TH_SHPMCOUNTER17 0x5f1
73 #define CSR_TH_SHPMCOUNTER18 0x5f2
74 #define CSR_TH_SHPMCOUNTER19 0x5f3
75 #define CSR_TH_SHPMCOUNTER20 0x5f4
76 #define CSR_TH_SHPMCOUNTER21 0x5f5
77 #define CSR_TH_SHPMCOUNTER22 0x5f6
78 #define CSR_TH_SHPMCOUNTER23 0x5f7
79 #define CSR_TH_SHPMCOUNTER24 0x5f8
80 #define CSR_TH_SHPMCOUNTER25 0x5f9
81 #define CSR_TH_SHPMCOUNTER26 0x5fa
82 #define CSR_TH_SHPMCOUNTER27 0x5fb
83 #define CSR_TH_SHPMCOUNTER28 0x5fc
84 #define CSR_TH_SHPMCOUNTER29 0x5fd
85 #define CSR_TH_SHPMCOUNTER30 0x5fe
86 #define CSR_TH_SHPMCOUNTER31 0x5ff
87 #define CSR_TH_SMIR 0x9c0
88 #define CSR_TH_SMLO0 0x9c1
89 #define CSR_TH_SMEH 0x9c2
90 #define CSR_TH_SMCIR 0x9c3
91
92 /* Extended U-mode control registers of T-Head */
93 #define CSR_TH_FXCR 0x800
94
95 /* TH_SXSTATUS bits */
96 #define TH_SXSTATUS_UCME BIT(16)
97 #define TH_SXSTATUS_MAEE BIT(21)
98 #define TH_SXSTATUS_THEADISAEE BIT(22)
99
100 static RISCVException mmode(CPURISCVState *env, int csrno)
101 {
102 return RISCV_EXCP_NONE;
103 }
104
105 static RISCVException smode(CPURISCVState *env, int csrno)
106 {
107 if (riscv_has_ext(env, RVS)) {
108 return RISCV_EXCP_NONE;
109 }
110
111 return RISCV_EXCP_ILLEGAL_INST;
112 }
113
114 static RISCVException any(CPURISCVState *env, int csrno)
115 {
116 return RISCV_EXCP_NONE;
117 }
118
119 static bool test_thead_mvendorid(RISCVCPU *cpu)
120 {
121 return cpu->cfg.mvendorid == THEAD_VENDOR_ID;
122 }
123
124 static RISCVException read_th_mxstatus(CPURISCVState *env, int csrno,
125 target_ulong *val)
126 {
127 /* We don't set MAEE here, because QEMU does not implement MAEE. */
128 *val = TH_MXSTATUS_UCME | TH_MXSTATUS_THEADISAEE;
129 return RISCV_EXCP_NONE;
130 }
131
132 static RISCVException read_unimp_th_csr(CPURISCVState *env, int csrno,
133 target_ulong *val)
134 {
135 *val = 0;
136 return RISCV_EXCP_NONE;
137 }
138
139 static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
140 target_ulong *val)
141 {
142 /* We don't set MAEE here, because QEMU does not implement MAEE. */
143 *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
144 return RISCV_EXCP_NONE;
145 }
146
147 const RISCVCSR th_csr_list[] = {
148 {
149 .csrno = CSR_TH_MXSTATUS,
150 .insertion_test = test_thead_mvendorid,
151 .csr_ops = { "th.mxstatus", mmode, read_th_mxstatus }
152 },
153 {
154 .csrno = CSR_TH_MHCR,
155 .insertion_test = test_thead_mvendorid,
156 .csr_ops = { "th.mhcr", mmode, read_unimp_th_csr }
157 },
158 {
159 .csrno = CSR_TH_MCOR,
160 .insertion_test = test_thead_mvendorid,
161 .csr_ops = { "th.mcor", mmode, read_unimp_th_csr }
162 },
163 {
164 .csrno = CSR_TH_MCCR2,
165 .insertion_test = test_thead_mvendorid,
166 .csr_ops = { "th.mccr2", mmode, read_unimp_th_csr }
167 },
168 {
169 .csrno = CSR_TH_MHINT,
170 .insertion_test = test_thead_mvendorid,
171 .csr_ops = { "th.mhint", mmode, read_unimp_th_csr }
172 },
173 {
174 .csrno = CSR_TH_MRVBR,
175 .insertion_test = test_thead_mvendorid,
176 .csr_ops = { "th.mrvbr", mmode, read_unimp_th_csr }
177 },
178 {
179 .csrno = CSR_TH_MCOUNTERWEN,
180 .insertion_test = test_thead_mvendorid,
181 .csr_ops = { "th.mcounterwen", mmode, read_unimp_th_csr }
182 },
183 {
184 .csrno = CSR_TH_MCOUNTERINTEN,
185 .insertion_test = test_thead_mvendorid,
186 .csr_ops = { "th.mcounterinten", mmode, read_unimp_th_csr }
187 },
188 {
189 .csrno = CSR_TH_MCOUNTEROF,
190 .insertion_test = test_thead_mvendorid,
191 .csr_ops = { "th.mcounterof", mmode, read_unimp_th_csr }
192 },
193 {
194 .csrno = CSR_TH_MCINS,
195 .insertion_test = test_thead_mvendorid,
196 .csr_ops = { "th.mcins", mmode, read_unimp_th_csr }
197 },
198 {
199 .csrno = CSR_TH_MCINDEX,
200 .insertion_test = test_thead_mvendorid,
201 .csr_ops = { "th.mcindex", mmode, read_unimp_th_csr }
202 },
203 {
204 .csrno = CSR_TH_MCDATA0,
205 .insertion_test = test_thead_mvendorid,
206 .csr_ops = { "th.mcdata0", mmode, read_unimp_th_csr }
207 },
208 {
209 .csrno = CSR_TH_MCDATA1,
210 .insertion_test = test_thead_mvendorid,
211 .csr_ops = { "th.mcdata1", mmode, read_unimp_th_csr }
212 },
213 {
214 .csrno = CSR_TH_MSMPR,
215 .insertion_test = test_thead_mvendorid,
216 .csr_ops = { "th.msmpr", mmode, read_unimp_th_csr }
217 },
218 {
219 .csrno = CSR_TH_CPUID,
220 .insertion_test = test_thead_mvendorid,
221 .csr_ops = { "th.cpuid", mmode, read_unimp_th_csr }
222 },
223 {
224 .csrno = CSR_TH_MAPBADDR,
225 .insertion_test = test_thead_mvendorid,
226 .csr_ops = { "th.mapbaddr", mmode, read_unimp_th_csr }
227 },
228 {
229 .csrno = CSR_TH_SXSTATUS,
230 .insertion_test = test_thead_mvendorid,
231 .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
232 },
233 {
234 .csrno = CSR_TH_SHCR,
235 .insertion_test = test_thead_mvendorid,
236 .csr_ops = { "th.shcr", smode, read_unimp_th_csr }
237 },
238 {
239 .csrno = CSR_TH_SCER2,
240 .insertion_test = test_thead_mvendorid,
241 .csr_ops = { "th.scer2", smode, read_unimp_th_csr }
242 },
243 {
244 .csrno = CSR_TH_SCER,
245 .insertion_test = test_thead_mvendorid,
246 .csr_ops = { "th.scer", smode, read_unimp_th_csr }
247 },
248 {
249 .csrno = CSR_TH_SCOUNTERINTEN,
250 .insertion_test = test_thead_mvendorid,
251 .csr_ops = { "th.scounterinten", smode, read_unimp_th_csr }
252 },
253 {
254 .csrno = CSR_TH_SCOUNTEROF,
255 .insertion_test = test_thead_mvendorid,
256 .csr_ops = { "th.scounterof", smode, read_unimp_th_csr }
257 },
258 {
259 .csrno = CSR_TH_SCYCLE,
260 .insertion_test = test_thead_mvendorid,
261 .csr_ops = { "th.scycle", smode, read_unimp_th_csr }
262 },
263 {
264 .csrno = CSR_TH_SHPMCOUNTER3,
265 .insertion_test = test_thead_mvendorid,
266 .csr_ops = { "th.shpmcounter3", smode, read_unimp_th_csr }
267 },
268 {
269 .csrno = CSR_TH_SHPMCOUNTER4,
270 .insertion_test = test_thead_mvendorid,
271 .csr_ops = { "th.shpmcounter4", smode, read_unimp_th_csr }
272 },
273 {
274 .csrno = CSR_TH_SHPMCOUNTER5,
275 .insertion_test = test_thead_mvendorid,
276 .csr_ops = { "th.shpmcounter5", smode, read_unimp_th_csr }
277 },
278 {
279 .csrno = CSR_TH_SHPMCOUNTER6,
280 .insertion_test = test_thead_mvendorid,
281 .csr_ops = { "th.shpmcounter6", smode, read_unimp_th_csr }
282 },
283 {
284 .csrno = CSR_TH_SHPMCOUNTER7,
285 .insertion_test = test_thead_mvendorid,
286 .csr_ops = { "th.shpmcounter7", smode, read_unimp_th_csr }
287 },
288 {
289 .csrno = CSR_TH_SHPMCOUNTER8,
290 .insertion_test = test_thead_mvendorid,
291 .csr_ops = { "th.shpmcounter8", smode, read_unimp_th_csr }
292 },
293 {
294 .csrno = CSR_TH_SHPMCOUNTER9,
295 .insertion_test = test_thead_mvendorid,
296 .csr_ops = { "th.shpmcounter9", smode, read_unimp_th_csr }
297 },
298 {
299 .csrno = CSR_TH_SHPMCOUNTER10,
300 .insertion_test = test_thead_mvendorid,
301 .csr_ops = { "th.shpmcounter10", smode, read_unimp_th_csr }
302 },
303 {
304 .csrno = CSR_TH_SHPMCOUNTER11,
305 .insertion_test = test_thead_mvendorid,
306 .csr_ops = { "th.shpmcounter11", smode, read_unimp_th_csr }
307 },
308 {
309 .csrno = CSR_TH_SHPMCOUNTER12,
310 .insertion_test = test_thead_mvendorid,
311 .csr_ops = { "th.shpmcounter12", smode, read_unimp_th_csr }
312 },
313 {
314 .csrno = CSR_TH_SHPMCOUNTER13,
315 .insertion_test = test_thead_mvendorid,
316 .csr_ops = { "th.shpmcounter13", smode, read_unimp_th_csr }
317 },
318 {
319 .csrno = CSR_TH_SHPMCOUNTER14,
320 .insertion_test = test_thead_mvendorid,
321 .csr_ops = { "th.shpmcounter14", smode, read_unimp_th_csr }
322 },
323 {
324 .csrno = CSR_TH_SHPMCOUNTER15,
325 .insertion_test = test_thead_mvendorid,
326 .csr_ops = { "th.shpmcounter15", smode, read_unimp_th_csr }
327 },
328 {
329 .csrno = CSR_TH_SHPMCOUNTER16,
330 .insertion_test = test_thead_mvendorid,
331 .csr_ops = { "th.shpmcounter16", smode, read_unimp_th_csr }
332 },
333 {
334 .csrno = CSR_TH_SHPMCOUNTER17,
335 .insertion_test = test_thead_mvendorid,
336 .csr_ops = { "th.shpmcounter17", smode, read_unimp_th_csr }
337 },
338 {
339 .csrno = CSR_TH_SHPMCOUNTER18,
340 .insertion_test = test_thead_mvendorid,
341 .csr_ops = { "th.shpmcounter18", smode, read_unimp_th_csr }
342 },
343 {
344 .csrno = CSR_TH_SHPMCOUNTER19,
345 .insertion_test = test_thead_mvendorid,
346 .csr_ops = { "th.shpmcounter19", smode, read_unimp_th_csr }
347 },
348 {
349 .csrno = CSR_TH_SHPMCOUNTER20,
350 .insertion_test = test_thead_mvendorid,
351 .csr_ops = { "th.shpmcounter20", smode, read_unimp_th_csr }
352 },
353 {
354 .csrno = CSR_TH_SHPMCOUNTER21,
355 .insertion_test = test_thead_mvendorid,
356 .csr_ops = { "th.shpmcounter21", smode, read_unimp_th_csr }
357 },
358 {
359 .csrno = CSR_TH_SHPMCOUNTER22,
360 .insertion_test = test_thead_mvendorid,
361 .csr_ops = { "th.shpmcounter22", smode, read_unimp_th_csr }
362 },
363 {
364 .csrno = CSR_TH_SHPMCOUNTER23,
365 .insertion_test = test_thead_mvendorid,
366 .csr_ops = { "th.shpmcounter23", smode, read_unimp_th_csr }
367 },
368 {
369 .csrno = CSR_TH_SHPMCOUNTER24,
370 .insertion_test = test_thead_mvendorid,
371 .csr_ops = { "th.shpmcounter24", smode, read_unimp_th_csr }
372 },
373 {
374 .csrno = CSR_TH_SHPMCOUNTER25,
375 .insertion_test = test_thead_mvendorid,
376 .csr_ops = { "th.shpmcounter25", smode, read_unimp_th_csr }
377 },
378 {
379 .csrno = CSR_TH_SHPMCOUNTER26,
380 .insertion_test = test_thead_mvendorid,
381 .csr_ops = { "th.shpmcounter26", smode, read_unimp_th_csr }
382 },
383 {
384 .csrno = CSR_TH_SHPMCOUNTER27,
385 .insertion_test = test_thead_mvendorid,
386 .csr_ops = { "th.shpmcounter27", smode, read_unimp_th_csr }
387 },
388 {
389 .csrno = CSR_TH_SHPMCOUNTER28,
390 .insertion_test = test_thead_mvendorid,
391 .csr_ops = { "th.shpmcounter28", smode, read_unimp_th_csr }
392 },
393 {
394 .csrno = CSR_TH_SHPMCOUNTER29,
395 .insertion_test = test_thead_mvendorid,
396 .csr_ops = { "th.shpmcounter29", smode, read_unimp_th_csr }
397 },
398 {
399 .csrno = CSR_TH_SHPMCOUNTER30,
400 .insertion_test = test_thead_mvendorid,
401 .csr_ops = { "th.shpmcounter30", smode, read_unimp_th_csr }
402 },
403 {
404 .csrno = CSR_TH_SHPMCOUNTER31,
405 .insertion_test = test_thead_mvendorid,
406 .csr_ops = { "th.shpmcounter31", smode, read_unimp_th_csr }
407 },
408 {
409 .csrno = CSR_TH_SMIR,
410 .insertion_test = test_thead_mvendorid,
411 .csr_ops = { "th.smir", smode, read_unimp_th_csr }
412 },
413 {
414 .csrno = CSR_TH_SMLO0,
415 .insertion_test = test_thead_mvendorid,
416 .csr_ops = { "th.smlo0", smode, read_unimp_th_csr }
417 },
418 {
419 .csrno = CSR_TH_SMEH,
420 .insertion_test = test_thead_mvendorid,
421 .csr_ops = { "th.smeh", smode, read_unimp_th_csr }
422 },
423 {
424 .csrno = CSR_TH_SMCIR,
425 .insertion_test = test_thead_mvendorid,
426 .csr_ops = { "th.smcir", smode, read_unimp_th_csr }
427 },
428 {
429 .csrno = CSR_TH_FXCR,
430 .insertion_test = test_thead_mvendorid,
431 .csr_ops = { "th.fxcr", any, read_unimp_th_csr }
432 },
433 { }
434 };