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