xref: /openbmc/qemu/target/riscv/th_csr.c (revision d67a6e054b92e5e1cbb7b0bd5782a670cc7f0df7)
1*fd53ee26SChristoph Müllner /*
2*fd53ee26SChristoph Müllner  * T-Head-specific CSRs.
3*fd53ee26SChristoph Müllner  *
4*fd53ee26SChristoph Müllner  * Copyright (c) 2024 VRULL GmbH
5*fd53ee26SChristoph Müllner  *
6*fd53ee26SChristoph Müllner  * This program is free software; you can redistribute it and/or modify it
7*fd53ee26SChristoph Müllner  * under the terms and conditions of the GNU General Public License,
8*fd53ee26SChristoph Müllner  * version 2 or later, as published by the Free Software Foundation.
9*fd53ee26SChristoph Müllner  *
10*fd53ee26SChristoph Müllner  * This program is distributed in the hope it will be useful, but WITHOUT
11*fd53ee26SChristoph Müllner  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12*fd53ee26SChristoph Müllner  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13*fd53ee26SChristoph Müllner  * more details.
14*fd53ee26SChristoph Müllner  *
15*fd53ee26SChristoph Müllner  * You should have received a copy of the GNU General Public License along with
16*fd53ee26SChristoph Müllner  * this program.  If not, see <http://www.gnu.org/licenses/>.
17*fd53ee26SChristoph Müllner  */
18*fd53ee26SChristoph Müllner 
19*fd53ee26SChristoph Müllner #include "qemu/osdep.h"
20*fd53ee26SChristoph Müllner #include "cpu.h"
21*fd53ee26SChristoph Müllner #include "cpu_vendorid.h"
22*fd53ee26SChristoph Müllner 
23*fd53ee26SChristoph Müllner #define CSR_TH_SXSTATUS 0x5c0
24*fd53ee26SChristoph Müllner 
25*fd53ee26SChristoph Müllner /* TH_SXSTATUS bits */
26*fd53ee26SChristoph Müllner #define TH_SXSTATUS_UCME        BIT(16)
27*fd53ee26SChristoph Müllner #define TH_SXSTATUS_MAEE        BIT(21)
28*fd53ee26SChristoph Müllner #define TH_SXSTATUS_THEADISAEE  BIT(22)
29*fd53ee26SChristoph Müllner 
30*fd53ee26SChristoph Müllner typedef struct {
31*fd53ee26SChristoph Müllner     int csrno;
32*fd53ee26SChristoph Müllner     int (*insertion_test)(RISCVCPU *cpu);
33*fd53ee26SChristoph Müllner     riscv_csr_operations csr_ops;
34*fd53ee26SChristoph Müllner } riscv_csr;
35*fd53ee26SChristoph Müllner 
smode(CPURISCVState * env,int csrno)36*fd53ee26SChristoph Müllner static RISCVException smode(CPURISCVState *env, int csrno)
37*fd53ee26SChristoph Müllner {
38*fd53ee26SChristoph Müllner     if (riscv_has_ext(env, RVS)) {
39*fd53ee26SChristoph Müllner         return RISCV_EXCP_NONE;
40*fd53ee26SChristoph Müllner     }
41*fd53ee26SChristoph Müllner 
42*fd53ee26SChristoph Müllner     return RISCV_EXCP_ILLEGAL_INST;
43*fd53ee26SChristoph Müllner }
44*fd53ee26SChristoph Müllner 
test_thead_mvendorid(RISCVCPU * cpu)45*fd53ee26SChristoph Müllner static int test_thead_mvendorid(RISCVCPU *cpu)
46*fd53ee26SChristoph Müllner {
47*fd53ee26SChristoph Müllner     if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
48*fd53ee26SChristoph Müllner         return -1;
49*fd53ee26SChristoph Müllner     }
50*fd53ee26SChristoph Müllner 
51*fd53ee26SChristoph Müllner     return 0;
52*fd53ee26SChristoph Müllner }
53*fd53ee26SChristoph Müllner 
read_th_sxstatus(CPURISCVState * env,int csrno,target_ulong * val)54*fd53ee26SChristoph Müllner static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
55*fd53ee26SChristoph Müllner                                        target_ulong *val)
56*fd53ee26SChristoph Müllner {
57*fd53ee26SChristoph Müllner     /* We don't set MAEE here, because QEMU does not implement MAEE. */
58*fd53ee26SChristoph Müllner     *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
59*fd53ee26SChristoph Müllner     return RISCV_EXCP_NONE;
60*fd53ee26SChristoph Müllner }
61*fd53ee26SChristoph Müllner 
62*fd53ee26SChristoph Müllner static riscv_csr th_csr_list[] = {
63*fd53ee26SChristoph Müllner     {
64*fd53ee26SChristoph Müllner         .csrno = CSR_TH_SXSTATUS,
65*fd53ee26SChristoph Müllner         .insertion_test = test_thead_mvendorid,
66*fd53ee26SChristoph Müllner         .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
67*fd53ee26SChristoph Müllner     }
68*fd53ee26SChristoph Müllner };
69*fd53ee26SChristoph Müllner 
th_register_custom_csrs(RISCVCPU * cpu)70*fd53ee26SChristoph Müllner void th_register_custom_csrs(RISCVCPU *cpu)
71*fd53ee26SChristoph Müllner {
72*fd53ee26SChristoph Müllner     for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
73*fd53ee26SChristoph Müllner         int csrno = th_csr_list[i].csrno;
74*fd53ee26SChristoph Müllner         riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
75*fd53ee26SChristoph Müllner         if (!th_csr_list[i].insertion_test(cpu)) {
76*fd53ee26SChristoph Müllner             riscv_set_csr_ops(csrno, csr_ops);
77*fd53ee26SChristoph Müllner         }
78*fd53ee26SChristoph Müllner     }
79*fd53ee26SChristoph Müllner }
80