1dc5bd18fSMichael Clark /* 2dc5bd18fSMichael Clark * QEMU RISC-V CPU 3dc5bd18fSMichael Clark * 4dc5bd18fSMichael Clark * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu 5dc5bd18fSMichael Clark * Copyright (c) 2017-2018 SiFive, Inc. 6dc5bd18fSMichael Clark * 7dc5bd18fSMichael Clark * This program is free software; you can redistribute it and/or modify it 8dc5bd18fSMichael Clark * under the terms and conditions of the GNU General Public License, 9dc5bd18fSMichael Clark * version 2 or later, as published by the Free Software Foundation. 10dc5bd18fSMichael Clark * 11dc5bd18fSMichael Clark * This program is distributed in the hope it will be useful, but WITHOUT 12dc5bd18fSMichael Clark * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13dc5bd18fSMichael Clark * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14dc5bd18fSMichael Clark * more details. 15dc5bd18fSMichael Clark * 16dc5bd18fSMichael Clark * You should have received a copy of the GNU General Public License along with 17dc5bd18fSMichael Clark * this program. If not, see <http://www.gnu.org/licenses/>. 18dc5bd18fSMichael Clark */ 19dc5bd18fSMichael Clark 20dc5bd18fSMichael Clark #include "qemu/osdep.h" 210442428aSMarkus Armbruster #include "qemu/qemu-print.h" 22856dfd8aSMarkus Armbruster #include "qemu/ctype.h" 23dc5bd18fSMichael Clark #include "qemu/log.h" 24dc5bd18fSMichael Clark #include "cpu.h" 2595bd8daaSChristoph Müllner #include "cpu_vendorid.h" 2614664483SAtish Patra #include "pmu.h" 27f7697f0eSYifei Jiang #include "internals.h" 2843888c2fSAtish Patra #include "time_helper.h" 29dc5bd18fSMichael Clark #include "exec/exec-all.h" 30dc5bd18fSMichael Clark #include "qapi/error.h" 316f23aaebSAlexandre Ghiti #include "qapi/visitor.h" 32b55d7d34SAlistair Francis #include "qemu/error-report.h" 33c4e95030SAlistair Francis #include "hw/qdev-properties.h" 34dc5bd18fSMichael Clark #include "migration/vmstate.h" 35135b03cbSAlex Bennée #include "fpu/softfloat-helpers.h" 36ad40be27SYifei Jiang #include "sysemu/kvm.h" 37eddabb6bSDaniel Henrique Barboza #include "sysemu/tcg.h" 38ad40be27SYifei Jiang #include "kvm_riscv.h" 390489d5bdSAnton Johansson #include "tcg/tcg.h" 40dc5bd18fSMichael Clark 41dc5bd18fSMichael Clark /* RISC-V CPU definitions */ 420e2c3770STsukasa OI static const char riscv_single_letter_exts[] = "IEMAFDQCPVH"; 43dc5bd18fSMichael Clark 44a775398bSAtish Patra struct isa_ext_data { 45a775398bSAtish Patra const char *name; 469a1f054dSAnup Patel int min_version; 479a1f054dSAnup Patel int ext_enable_offset; 48a775398bSAtish Patra }; 49a775398bSAtish Patra 50ccc84a75SDaniel Henrique Barboza #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \ 51ccc84a75SDaniel Henrique Barboza {#_name, _min_ver, offsetof(struct RISCVCPUConfig, _prop)} 529a1f054dSAnup Patel 533b57254dSWeiwei Li /* 54b227f6a8SIvan Klokov * From vector_helper.c 55b227f6a8SIvan Klokov * Note that vector data is stored in host-endian 64-bit chunks, 56b227f6a8SIvan Klokov * so addressing bytes needs a host-endian fixup. 57b227f6a8SIvan Klokov */ 58b227f6a8SIvan Klokov #if HOST_BIG_ENDIAN 59b227f6a8SIvan Klokov #define BYTE(x) ((x) ^ 7) 60b227f6a8SIvan Klokov #else 61b227f6a8SIvan Klokov #define BYTE(x) (x) 62b227f6a8SIvan Klokov #endif 63b227f6a8SIvan Klokov 64b227f6a8SIvan Klokov /* 659a1f054dSAnup Patel * Here are the ordering rules of extension naming defined by RISC-V 669a1f054dSAnup Patel * specification : 679a1f054dSAnup Patel * 1. All extensions should be separated from other multi-letter extensions 689a1f054dSAnup Patel * by an underscore. 699a1f054dSAnup Patel * 2. The first letter following the 'Z' conventionally indicates the most 709a1f054dSAnup Patel * closely related alphabetical extension category, IMAFDQLCBKJTPVH. 719a1f054dSAnup Patel * If multiple 'Z' extensions are named, they should be ordered first 729a1f054dSAnup Patel * by category, then alphabetically within a category. 739a1f054dSAnup Patel * 3. Standard supervisor-level extensions (starts with 'S') should be 749a1f054dSAnup Patel * listed after standard unprivileged extensions. If multiple 759a1f054dSAnup Patel * supervisor-level extensions are listed, they should be ordered 769a1f054dSAnup Patel * alphabetically. 779a1f054dSAnup Patel * 4. Non-standard extensions (starts with 'X') must be listed after all 789a1f054dSAnup Patel * standard extensions. They must be separated from other multi-letter 799a1f054dSAnup Patel * extensions by an underscore. 806508272aSDaniel Henrique Barboza * 816508272aSDaniel Henrique Barboza * Single letter extensions are checked in riscv_cpu_validate_misa_priv() 826508272aSDaniel Henrique Barboza * instead. 839a1f054dSAnup Patel */ 849a1f054dSAnup Patel static const struct isa_ext_data isa_edata_arr[] = { 85ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_icbom), 86ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_icboz), 87ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond), 88ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr), 89ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei), 90ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause), 9150f94649SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul), 92ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs), 93a47842d1SChristoph Müllner ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa), 94889caa44SWeiwei Li ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin), 95ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zfh, PRIV_VERSION_1_11_0, ext_zfh), 96ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zfhmin, PRIV_VERSION_1_11_0, ext_zfhmin), 97ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zfinx, PRIV_VERSION_1_12_0, ext_zfinx), 98ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zdinx, PRIV_VERSION_1_12_0, ext_zdinx), 99ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zca, PRIV_VERSION_1_12_0, ext_zca), 100ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zcb, PRIV_VERSION_1_12_0, ext_zcb), 101ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zcf, PRIV_VERSION_1_12_0, ext_zcf), 102ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zcd, PRIV_VERSION_1_12_0, ext_zcd), 103ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zce, PRIV_VERSION_1_12_0, ext_zce), 104ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zcmp, PRIV_VERSION_1_12_0, ext_zcmp), 105ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zcmt, PRIV_VERSION_1_12_0, ext_zcmt), 106ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zba, PRIV_VERSION_1_12_0, ext_zba), 107ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zbb, PRIV_VERSION_1_12_0, ext_zbb), 108ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zbc, PRIV_VERSION_1_12_0, ext_zbc), 109ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zbkb, PRIV_VERSION_1_12_0, ext_zbkb), 110ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zbkc, PRIV_VERSION_1_12_0, ext_zbkc), 111ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zbkx, PRIV_VERSION_1_12_0, ext_zbkx), 112ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zbs, PRIV_VERSION_1_12_0, ext_zbs), 113ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zk, PRIV_VERSION_1_12_0, ext_zk), 114ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zkn, PRIV_VERSION_1_12_0, ext_zkn), 115ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zknd, PRIV_VERSION_1_12_0, ext_zknd), 116ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zkne, PRIV_VERSION_1_12_0, ext_zkne), 117ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zknh, PRIV_VERSION_1_12_0, ext_zknh), 118ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zkr, PRIV_VERSION_1_12_0, ext_zkr), 119ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zks, PRIV_VERSION_1_12_0, ext_zks), 120ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed), 121ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh), 122ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt), 123*06028472SDickon Hood ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb), 124e13c7d3bSLawrence Hunter ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc), 125ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f), 126ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f), 127ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d), 128889caa44SWeiwei Li ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin), 129889caa44SWeiwei Li ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma), 130ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh), 131ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin), 132ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx), 133ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin), 134ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia), 13503d7bbfdSDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp), 1363594e3e5SMayuresh Chitale ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen), 137ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia), 138ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf), 139ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc), 140ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu), 141ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), 142ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), 143ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), 144ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), 145ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), 146ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), 147ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadcmo, PRIV_VERSION_1_11_0, ext_xtheadcmo), 148ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadcondmov, PRIV_VERSION_1_11_0, ext_xtheadcondmov), 149ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadfmemidx, PRIV_VERSION_1_11_0, ext_xtheadfmemidx), 150ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadfmv, PRIV_VERSION_1_11_0, ext_xtheadfmv), 151ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadmac, PRIV_VERSION_1_11_0, ext_xtheadmac), 152ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadmemidx, PRIV_VERSION_1_11_0, ext_xtheadmemidx), 153ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair), 154ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync), 155ccc84a75SDaniel Henrique Barboza ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, ext_XVentanaCondOps), 1569a1f054dSAnup Patel }; 1579a1f054dSAnup Patel 1589a1f054dSAnup Patel static bool isa_ext_is_enabled(RISCVCPU *cpu, 1599a1f054dSAnup Patel const struct isa_ext_data *edata) 1609a1f054dSAnup Patel { 1619a1f054dSAnup Patel bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset; 1629a1f054dSAnup Patel 1639a1f054dSAnup Patel return *ext_enabled; 1649a1f054dSAnup Patel } 1659a1f054dSAnup Patel 1669a1f054dSAnup Patel static void isa_ext_update_enabled(RISCVCPU *cpu, 1679a1f054dSAnup Patel const struct isa_ext_data *edata, bool en) 1689a1f054dSAnup Patel { 1699a1f054dSAnup Patel bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset; 1709a1f054dSAnup Patel 1719a1f054dSAnup Patel *ext_enabled = en; 1729a1f054dSAnup Patel } 1739a1f054dSAnup Patel 174dc5bd18fSMichael Clark const char * const riscv_int_regnames[] = { 175a9f37afaSAtish Patra "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1", 176a9f37afaSAtish Patra "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3", 177a9f37afaSAtish Patra "x14/a4", "x15/a5", "x16/a6", "x17/a7", "x18/s2", "x19/s3", "x20/s4", 178a9f37afaSAtish Patra "x21/s5", "x22/s6", "x23/s7", "x24/s8", "x25/s9", "x26/s10", "x27/s11", 179a9f37afaSAtish Patra "x28/t3", "x29/t4", "x30/t5", "x31/t6" 180dc5bd18fSMichael Clark }; 181dc5bd18fSMichael Clark 1822b547084SFrédéric Pétrot const char * const riscv_int_regnamesh[] = { 1832b547084SFrédéric Pétrot "x0h/zeroh", "x1h/rah", "x2h/sph", "x3h/gph", "x4h/tph", "x5h/t0h", 1842b547084SFrédéric Pétrot "x6h/t1h", "x7h/t2h", "x8h/s0h", "x9h/s1h", "x10h/a0h", "x11h/a1h", 1852b547084SFrédéric Pétrot "x12h/a2h", "x13h/a3h", "x14h/a4h", "x15h/a5h", "x16h/a6h", "x17h/a7h", 1862b547084SFrédéric Pétrot "x18h/s2h", "x19h/s3h", "x20h/s4h", "x21h/s5h", "x22h/s6h", "x23h/s7h", 1872b547084SFrédéric Pétrot "x24h/s8h", "x25h/s9h", "x26h/s10h", "x27h/s11h", "x28h/t3h", "x29h/t4h", 1882b547084SFrédéric Pétrot "x30h/t5h", "x31h/t6h" 1892b547084SFrédéric Pétrot }; 1902b547084SFrédéric Pétrot 191dc5bd18fSMichael Clark const char * const riscv_fpr_regnames[] = { 192a9f37afaSAtish Patra "f0/ft0", "f1/ft1", "f2/ft2", "f3/ft3", "f4/ft4", "f5/ft5", 193a9f37afaSAtish Patra "f6/ft6", "f7/ft7", "f8/fs0", "f9/fs1", "f10/fa0", "f11/fa1", 194a9f37afaSAtish Patra "f12/fa2", "f13/fa3", "f14/fa4", "f15/fa5", "f16/fa6", "f17/fa7", 195a9f37afaSAtish Patra "f18/fs2", "f19/fs3", "f20/fs4", "f21/fs5", "f22/fs6", "f23/fs7", 196a9f37afaSAtish Patra "f24/fs8", "f25/fs9", "f26/fs10", "f27/fs11", "f28/ft8", "f29/ft9", 197a9f37afaSAtish Patra "f30/ft10", "f31/ft11" 198dc5bd18fSMichael Clark }; 199dc5bd18fSMichael Clark 200b227f6a8SIvan Klokov const char * const riscv_rvv_regnames[] = { 201b227f6a8SIvan Klokov "v0", "v1", "v2", "v3", "v4", "v5", "v6", 202b227f6a8SIvan Klokov "v7", "v8", "v9", "v10", "v11", "v12", "v13", 203b227f6a8SIvan Klokov "v14", "v15", "v16", "v17", "v18", "v19", "v20", 204b227f6a8SIvan Klokov "v21", "v22", "v23", "v24", "v25", "v26", "v27", 205b227f6a8SIvan Klokov "v28", "v29", "v30", "v31" 206b227f6a8SIvan Klokov }; 207b227f6a8SIvan Klokov 2089a575d33SBin Meng static const char * const riscv_excp_names[] = { 209dc5bd18fSMichael Clark "misaligned_fetch", 210dc5bd18fSMichael Clark "fault_fetch", 211dc5bd18fSMichael Clark "illegal_instruction", 212dc5bd18fSMichael Clark "breakpoint", 213dc5bd18fSMichael Clark "misaligned_load", 214dc5bd18fSMichael Clark "fault_load", 215dc5bd18fSMichael Clark "misaligned_store", 216dc5bd18fSMichael Clark "fault_store", 217dc5bd18fSMichael Clark "user_ecall", 218dc5bd18fSMichael Clark "supervisor_ecall", 219dc5bd18fSMichael Clark "hypervisor_ecall", 220dc5bd18fSMichael Clark "machine_ecall", 221dc5bd18fSMichael Clark "exec_page_fault", 222dc5bd18fSMichael Clark "load_page_fault", 223dc5bd18fSMichael Clark "reserved", 224fd990e86SPalmer Dabbelt "store_page_fault", 225ab67a1d0SAlistair Francis "reserved", 226ab67a1d0SAlistair Francis "reserved", 227ab67a1d0SAlistair Francis "reserved", 228ab67a1d0SAlistair Francis "reserved", 229ab67a1d0SAlistair Francis "guest_exec_page_fault", 230ab67a1d0SAlistair Francis "guest_load_page_fault", 231ab67a1d0SAlistair Francis "reserved", 232fd990e86SPalmer Dabbelt "guest_store_page_fault", 233dc5bd18fSMichael Clark }; 234dc5bd18fSMichael Clark 2359a575d33SBin Meng static const char * const riscv_intr_names[] = { 236dc5bd18fSMichael Clark "u_software", 237dc5bd18fSMichael Clark "s_software", 238205377f8SAlistair Francis "vs_software", 239dc5bd18fSMichael Clark "m_software", 240dc5bd18fSMichael Clark "u_timer", 241dc5bd18fSMichael Clark "s_timer", 242205377f8SAlistair Francis "vs_timer", 243dc5bd18fSMichael Clark "m_timer", 244dc5bd18fSMichael Clark "u_external", 2456cfcf775SEmmanuel Blot "s_external", 246205377f8SAlistair Francis "vs_external", 247dc5bd18fSMichael Clark "m_external", 248426f0348SMichael Clark "reserved", 249426f0348SMichael Clark "reserved", 250426f0348SMichael Clark "reserved", 251426f0348SMichael Clark "reserved" 252dc5bd18fSMichael Clark }; 253dc5bd18fSMichael Clark 254dd8f244fSDaniel Henrique Barboza static void riscv_cpu_add_user_properties(Object *obj); 25526b2bc58SAlistair Francis 256c51a3f5dSYifei Jiang const char *riscv_cpu_get_trap_name(target_ulong cause, bool async) 257c51a3f5dSYifei Jiang { 258c51a3f5dSYifei Jiang if (async) { 259c51a3f5dSYifei Jiang return (cause < ARRAY_SIZE(riscv_intr_names)) ? 260c51a3f5dSYifei Jiang riscv_intr_names[cause] : "(unknown)"; 261c51a3f5dSYifei Jiang } else { 262c51a3f5dSYifei Jiang return (cause < ARRAY_SIZE(riscv_excp_names)) ? 263c51a3f5dSYifei Jiang riscv_excp_names[cause] : "(unknown)"; 264c51a3f5dSYifei Jiang } 265c51a3f5dSYifei Jiang } 266c51a3f5dSYifei Jiang 267e91a7227SRichard Henderson static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext) 268dc5bd18fSMichael Clark { 269e91a7227SRichard Henderson env->misa_mxl_max = env->misa_mxl = mxl; 270e91a7227SRichard Henderson env->misa_ext_mask = env->misa_ext = ext; 271dc5bd18fSMichael Clark } 272dc5bd18fSMichael Clark 2736f23aaebSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 2746f23aaebSAlexandre Ghiti static uint8_t satp_mode_from_str(const char *satp_mode_str) 2756f23aaebSAlexandre Ghiti { 2766f23aaebSAlexandre Ghiti if (!strncmp(satp_mode_str, "mbare", 5)) { 2776f23aaebSAlexandre Ghiti return VM_1_10_MBARE; 2786f23aaebSAlexandre Ghiti } 2796f23aaebSAlexandre Ghiti 2806f23aaebSAlexandre Ghiti if (!strncmp(satp_mode_str, "sv32", 4)) { 2816f23aaebSAlexandre Ghiti return VM_1_10_SV32; 2826f23aaebSAlexandre Ghiti } 2836f23aaebSAlexandre Ghiti 2846f23aaebSAlexandre Ghiti if (!strncmp(satp_mode_str, "sv39", 4)) { 2856f23aaebSAlexandre Ghiti return VM_1_10_SV39; 2866f23aaebSAlexandre Ghiti } 2876f23aaebSAlexandre Ghiti 2886f23aaebSAlexandre Ghiti if (!strncmp(satp_mode_str, "sv48", 4)) { 2896f23aaebSAlexandre Ghiti return VM_1_10_SV48; 2906f23aaebSAlexandre Ghiti } 2916f23aaebSAlexandre Ghiti 2926f23aaebSAlexandre Ghiti if (!strncmp(satp_mode_str, "sv57", 4)) { 2936f23aaebSAlexandre Ghiti return VM_1_10_SV57; 2946f23aaebSAlexandre Ghiti } 2956f23aaebSAlexandre Ghiti 2966f23aaebSAlexandre Ghiti if (!strncmp(satp_mode_str, "sv64", 4)) { 2976f23aaebSAlexandre Ghiti return VM_1_10_SV64; 2986f23aaebSAlexandre Ghiti } 2996f23aaebSAlexandre Ghiti 3006f23aaebSAlexandre Ghiti g_assert_not_reached(); 3016f23aaebSAlexandre Ghiti } 3026f23aaebSAlexandre Ghiti 3036f23aaebSAlexandre Ghiti uint8_t satp_mode_max_from_map(uint32_t map) 3046f23aaebSAlexandre Ghiti { 3056f23aaebSAlexandre Ghiti /* map here has at least one bit set, so no problem with clz */ 3066f23aaebSAlexandre Ghiti return 31 - __builtin_clz(map); 3076f23aaebSAlexandre Ghiti } 3086f23aaebSAlexandre Ghiti 3096f23aaebSAlexandre Ghiti const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit) 3106f23aaebSAlexandre Ghiti { 3116f23aaebSAlexandre Ghiti if (is_32_bit) { 3126f23aaebSAlexandre Ghiti switch (satp_mode) { 3136f23aaebSAlexandre Ghiti case VM_1_10_SV32: 3146f23aaebSAlexandre Ghiti return "sv32"; 3156f23aaebSAlexandre Ghiti case VM_1_10_MBARE: 3166f23aaebSAlexandre Ghiti return "none"; 3176f23aaebSAlexandre Ghiti } 3186f23aaebSAlexandre Ghiti } else { 3196f23aaebSAlexandre Ghiti switch (satp_mode) { 3206f23aaebSAlexandre Ghiti case VM_1_10_SV64: 3216f23aaebSAlexandre Ghiti return "sv64"; 3226f23aaebSAlexandre Ghiti case VM_1_10_SV57: 3236f23aaebSAlexandre Ghiti return "sv57"; 3246f23aaebSAlexandre Ghiti case VM_1_10_SV48: 3256f23aaebSAlexandre Ghiti return "sv48"; 3266f23aaebSAlexandre Ghiti case VM_1_10_SV39: 3276f23aaebSAlexandre Ghiti return "sv39"; 3286f23aaebSAlexandre Ghiti case VM_1_10_MBARE: 3296f23aaebSAlexandre Ghiti return "none"; 3306f23aaebSAlexandre Ghiti } 3316f23aaebSAlexandre Ghiti } 3326f23aaebSAlexandre Ghiti 3336f23aaebSAlexandre Ghiti g_assert_not_reached(); 3346f23aaebSAlexandre Ghiti } 3356f23aaebSAlexandre Ghiti 3366df3747aSAlexandre Ghiti static void set_satp_mode_max_supported(RISCVCPU *cpu, 3376df3747aSAlexandre Ghiti uint8_t satp_mode) 3386f23aaebSAlexandre Ghiti { 3396f23aaebSAlexandre Ghiti bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32; 3406df3747aSAlexandre Ghiti const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64; 3416f23aaebSAlexandre Ghiti 3426df3747aSAlexandre Ghiti for (int i = 0; i <= satp_mode; ++i) { 3436df3747aSAlexandre Ghiti if (valid_vm[i]) { 3446df3747aSAlexandre Ghiti cpu->cfg.satp_mode.supported |= (1 << i); 3456f23aaebSAlexandre Ghiti } 3466f23aaebSAlexandre Ghiti } 3476df3747aSAlexandre Ghiti } 3486df3747aSAlexandre Ghiti 3496df3747aSAlexandre Ghiti /* Set the satp mode to the max supported */ 3506df3747aSAlexandre Ghiti static void set_satp_mode_default_map(RISCVCPU *cpu) 3516df3747aSAlexandre Ghiti { 3526df3747aSAlexandre Ghiti cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported; 3536df3747aSAlexandre Ghiti } 3546f23aaebSAlexandre Ghiti #endif 3556f23aaebSAlexandre Ghiti 356dc5bd18fSMichael Clark static void riscv_any_cpu_init(Object *obj) 357dc5bd18fSMichael Clark { 3587f0bdfb5SDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(obj); 3597f0bdfb5SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 3603820602fSAlistair Francis #if defined(TARGET_RISCV32) 361e91a7227SRichard Henderson set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU); 3623820602fSAlistair Francis #elif defined(TARGET_RISCV64) 363e91a7227SRichard Henderson set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU); 3643820602fSAlistair Francis #endif 3656df3747aSAlexandre Ghiti 3666df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 3676df3747aSAlexandre Ghiti set_satp_mode_max_supported(RISCV_CPU(obj), 3686df3747aSAlexandre Ghiti riscv_cpu_mxl(&RISCV_CPU(obj)->env) == MXL_RV32 ? 3696df3747aSAlexandre Ghiti VM_1_10_SV32 : VM_1_10_SV57); 3706df3747aSAlexandre Ghiti #endif 3716df3747aSAlexandre Ghiti 372b9a2b98eSDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_LATEST; 3737f0bdfb5SDaniel Henrique Barboza 3747f0bdfb5SDaniel Henrique Barboza /* inherited from parent obj via riscv_cpu_init() */ 3757f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_ifencei = true; 3767f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_icsr = true; 3777f0bdfb5SDaniel Henrique Barboza cpu->cfg.mmu = true; 3787f0bdfb5SDaniel Henrique Barboza cpu->cfg.pmp = true; 379dc5bd18fSMichael Clark } 380dc5bd18fSMichael Clark 381094b072cSAlistair Francis #if defined(TARGET_RISCV64) 382094b072cSAlistair Francis static void rv64_base_cpu_init(Object *obj) 3838903bf6eSAlistair Francis { 3848903bf6eSAlistair Francis CPURISCVState *env = &RISCV_CPU(obj)->env; 385b55d7d34SAlistair Francis /* We set this in the realise function */ 386e91a7227SRichard Henderson set_misa(env, MXL_RV64, 0); 387dd8f244fSDaniel Henrique Barboza riscv_cpu_add_user_properties(obj); 38818800095SAnup Patel /* Set latest version of privileged specification */ 389b9a2b98eSDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_LATEST; 3906df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 3916df3747aSAlexandre Ghiti set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); 3926df3747aSAlexandre Ghiti #endif 3938903bf6eSAlistair Francis } 3948903bf6eSAlistair Francis 395114baacaSAlistair Francis static void rv64_sifive_u_cpu_init(Object *obj) 396dc5bd18fSMichael Clark { 3977f0bdfb5SDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(obj); 3987f0bdfb5SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 399e91a7227SRichard Henderson set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); 4008c6eeb50SDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_1_10_0; 4016df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 4026df3747aSAlexandre Ghiti set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39); 4036df3747aSAlexandre Ghiti #endif 4047f0bdfb5SDaniel Henrique Barboza 4057f0bdfb5SDaniel Henrique Barboza /* inherited from parent obj via riscv_cpu_init() */ 4067f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_ifencei = true; 4077f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_icsr = true; 4087f0bdfb5SDaniel Henrique Barboza cpu->cfg.mmu = true; 4097f0bdfb5SDaniel Henrique Barboza cpu->cfg.pmp = true; 410dc5bd18fSMichael Clark } 411dc5bd18fSMichael Clark 412114baacaSAlistair Francis static void rv64_sifive_e_cpu_init(Object *obj) 413d8e72bd1SBin Meng { 414d8e72bd1SBin Meng CPURISCVState *env = &RISCV_CPU(obj)->env; 41526b2bc58SAlistair Francis RISCVCPU *cpu = RISCV_CPU(obj); 41626b2bc58SAlistair Francis 417e91a7227SRichard Henderson set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU); 4188c6eeb50SDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_1_10_0; 4196df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 4206df3747aSAlexandre Ghiti set_satp_mode_max_supported(cpu, VM_1_10_MBARE); 4216df3747aSAlexandre Ghiti #endif 4227f0bdfb5SDaniel Henrique Barboza 4237f0bdfb5SDaniel Henrique Barboza /* inherited from parent obj via riscv_cpu_init() */ 4247f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_ifencei = true; 4257f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_icsr = true; 4267f0bdfb5SDaniel Henrique Barboza cpu->cfg.pmp = true; 427d8e72bd1SBin Meng } 428332dab68SFrédéric Pétrot 42995bd8daaSChristoph Müllner static void rv64_thead_c906_cpu_init(Object *obj) 43095bd8daaSChristoph Müllner { 43195bd8daaSChristoph Müllner CPURISCVState *env = &RISCV_CPU(obj)->env; 43295bd8daaSChristoph Müllner RISCVCPU *cpu = RISCV_CPU(obj); 43395bd8daaSChristoph Müllner 4344f13abcbSDaniel Henrique Barboza set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU); 4358c6eeb50SDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_1_11_0; 43695bd8daaSChristoph Müllner 437a47842d1SChristoph Müllner cpu->cfg.ext_zfa = true; 43895bd8daaSChristoph Müllner cpu->cfg.ext_zfh = true; 43995bd8daaSChristoph Müllner cpu->cfg.mmu = true; 44095bd8daaSChristoph Müllner cpu->cfg.ext_xtheadba = true; 44195bd8daaSChristoph Müllner cpu->cfg.ext_xtheadbb = true; 44295bd8daaSChristoph Müllner cpu->cfg.ext_xtheadbs = true; 44395bd8daaSChristoph Müllner cpu->cfg.ext_xtheadcmo = true; 44495bd8daaSChristoph Müllner cpu->cfg.ext_xtheadcondmov = true; 44595bd8daaSChristoph Müllner cpu->cfg.ext_xtheadfmemidx = true; 44695bd8daaSChristoph Müllner cpu->cfg.ext_xtheadmac = true; 44795bd8daaSChristoph Müllner cpu->cfg.ext_xtheadmemidx = true; 44895bd8daaSChristoph Müllner cpu->cfg.ext_xtheadmempair = true; 44995bd8daaSChristoph Müllner cpu->cfg.ext_xtheadsync = true; 45095bd8daaSChristoph Müllner 45195bd8daaSChristoph Müllner cpu->cfg.mvendorid = THEAD_VENDOR_ID; 4526df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 4536df3747aSAlexandre Ghiti set_satp_mode_max_supported(cpu, VM_1_10_SV39); 4546df3747aSAlexandre Ghiti #endif 4557f0bdfb5SDaniel Henrique Barboza 4567f0bdfb5SDaniel Henrique Barboza /* inherited from parent obj via riscv_cpu_init() */ 4577f0bdfb5SDaniel Henrique Barboza cpu->cfg.pmp = true; 45895bd8daaSChristoph Müllner } 45995bd8daaSChristoph Müllner 460e1d084a8SRahul Pathak static void rv64_veyron_v1_cpu_init(Object *obj) 461e1d084a8SRahul Pathak { 462e1d084a8SRahul Pathak CPURISCVState *env = &RISCV_CPU(obj)->env; 463e1d084a8SRahul Pathak RISCVCPU *cpu = RISCV_CPU(obj); 464e1d084a8SRahul Pathak 465e1d084a8SRahul Pathak set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU | RVH); 466e1d084a8SRahul Pathak env->priv_ver = PRIV_VERSION_1_12_0; 467e1d084a8SRahul Pathak 468e1d084a8SRahul Pathak /* Enable ISA extensions */ 469e1d084a8SRahul Pathak cpu->cfg.mmu = true; 470029f5feeSDaniel Henrique Barboza cpu->cfg.ext_ifencei = true; 471029f5feeSDaniel Henrique Barboza cpu->cfg.ext_icsr = true; 472029f5feeSDaniel Henrique Barboza cpu->cfg.pmp = true; 473e1d084a8SRahul Pathak cpu->cfg.ext_icbom = true; 474e1d084a8SRahul Pathak cpu->cfg.cbom_blocksize = 64; 475e1d084a8SRahul Pathak cpu->cfg.cboz_blocksize = 64; 476e1d084a8SRahul Pathak cpu->cfg.ext_icboz = true; 477e1d084a8SRahul Pathak cpu->cfg.ext_smaia = true; 478e1d084a8SRahul Pathak cpu->cfg.ext_ssaia = true; 479e1d084a8SRahul Pathak cpu->cfg.ext_sscofpmf = true; 480e1d084a8SRahul Pathak cpu->cfg.ext_sstc = true; 481e1d084a8SRahul Pathak cpu->cfg.ext_svinval = true; 482e1d084a8SRahul Pathak cpu->cfg.ext_svnapot = true; 483e1d084a8SRahul Pathak cpu->cfg.ext_svpbmt = true; 484e1d084a8SRahul Pathak cpu->cfg.ext_smstateen = true; 485e1d084a8SRahul Pathak cpu->cfg.ext_zba = true; 486e1d084a8SRahul Pathak cpu->cfg.ext_zbb = true; 487e1d084a8SRahul Pathak cpu->cfg.ext_zbc = true; 488e1d084a8SRahul Pathak cpu->cfg.ext_zbs = true; 489e1d084a8SRahul Pathak cpu->cfg.ext_XVentanaCondOps = true; 490e1d084a8SRahul Pathak 491e1d084a8SRahul Pathak cpu->cfg.mvendorid = VEYRON_V1_MVENDORID; 492e1d084a8SRahul Pathak cpu->cfg.marchid = VEYRON_V1_MARCHID; 493e1d084a8SRahul Pathak cpu->cfg.mimpid = VEYRON_V1_MIMPID; 494e1d084a8SRahul Pathak 495e1d084a8SRahul Pathak #ifndef CONFIG_USER_ONLY 496e1d084a8SRahul Pathak set_satp_mode_max_supported(cpu, VM_1_10_SV48); 497e1d084a8SRahul Pathak #endif 498e1d084a8SRahul Pathak } 499e1d084a8SRahul Pathak 500332dab68SFrédéric Pétrot static void rv128_base_cpu_init(Object *obj) 501332dab68SFrédéric Pétrot { 502332dab68SFrédéric Pétrot if (qemu_tcg_mttcg_enabled()) { 503332dab68SFrédéric Pétrot /* Missing 128-bit aligned atomics */ 504332dab68SFrédéric Pétrot error_report("128-bit RISC-V currently does not work with Multi " 505332dab68SFrédéric Pétrot "Threaded TCG. Please use: -accel tcg,thread=single"); 506332dab68SFrédéric Pétrot exit(EXIT_FAILURE); 507332dab68SFrédéric Pétrot } 508332dab68SFrédéric Pétrot CPURISCVState *env = &RISCV_CPU(obj)->env; 509332dab68SFrédéric Pétrot /* We set this in the realise function */ 510332dab68SFrédéric Pétrot set_misa(env, MXL_RV128, 0); 511dd8f244fSDaniel Henrique Barboza riscv_cpu_add_user_properties(obj); 51218800095SAnup Patel /* Set latest version of privileged specification */ 513b9a2b98eSDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_LATEST; 5146df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 5156df3747aSAlexandre Ghiti set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); 5166df3747aSAlexandre Ghiti #endif 517332dab68SFrédéric Pétrot } 518114baacaSAlistair Francis #else 519094b072cSAlistair Francis static void rv32_base_cpu_init(Object *obj) 520094b072cSAlistair Francis { 521094b072cSAlistair Francis CPURISCVState *env = &RISCV_CPU(obj)->env; 522094b072cSAlistair Francis /* We set this in the realise function */ 523e91a7227SRichard Henderson set_misa(env, MXL_RV32, 0); 524dd8f244fSDaniel Henrique Barboza riscv_cpu_add_user_properties(obj); 52518800095SAnup Patel /* Set latest version of privileged specification */ 526b9a2b98eSDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_LATEST; 5276df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 5286df3747aSAlexandre Ghiti set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); 5296df3747aSAlexandre Ghiti #endif 530094b072cSAlistair Francis } 531094b072cSAlistair Francis 532114baacaSAlistair Francis static void rv32_sifive_u_cpu_init(Object *obj) 533114baacaSAlistair Francis { 5347f0bdfb5SDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(obj); 5357f0bdfb5SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 536e91a7227SRichard Henderson set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); 5378c6eeb50SDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_1_10_0; 5386df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 5396df3747aSAlexandre Ghiti set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32); 5406df3747aSAlexandre Ghiti #endif 5417f0bdfb5SDaniel Henrique Barboza 5427f0bdfb5SDaniel Henrique Barboza /* inherited from parent obj via riscv_cpu_init() */ 5437f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_ifencei = true; 5447f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_icsr = true; 5457f0bdfb5SDaniel Henrique Barboza cpu->cfg.mmu = true; 5467f0bdfb5SDaniel Henrique Barboza cpu->cfg.pmp = true; 547114baacaSAlistair Francis } 548d8e72bd1SBin Meng 549114baacaSAlistair Francis static void rv32_sifive_e_cpu_init(Object *obj) 550114baacaSAlistair Francis { 551114baacaSAlistair Francis CPURISCVState *env = &RISCV_CPU(obj)->env; 55226b2bc58SAlistair Francis RISCVCPU *cpu = RISCV_CPU(obj); 55326b2bc58SAlistair Francis 554e91a7227SRichard Henderson set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU); 5558c6eeb50SDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_1_10_0; 5566df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 5576df3747aSAlexandre Ghiti set_satp_mode_max_supported(cpu, VM_1_10_MBARE); 5586df3747aSAlexandre Ghiti #endif 5597f0bdfb5SDaniel Henrique Barboza 5607f0bdfb5SDaniel Henrique Barboza /* inherited from parent obj via riscv_cpu_init() */ 5617f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_ifencei = true; 5627f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_icsr = true; 5637f0bdfb5SDaniel Henrique Barboza cpu->cfg.pmp = true; 564114baacaSAlistair Francis } 5654c56793fSBin Meng 566e8905c6cSBin Meng static void rv32_ibex_cpu_init(Object *obj) 56736b80ad9SAlistair Francis { 56836b80ad9SAlistair Francis CPURISCVState *env = &RISCV_CPU(obj)->env; 56926b2bc58SAlistair Francis RISCVCPU *cpu = RISCV_CPU(obj); 57026b2bc58SAlistair Francis 571e91a7227SRichard Henderson set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU); 5728c6eeb50SDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_1_11_0; 5736df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 5746df3747aSAlexandre Ghiti set_satp_mode_max_supported(cpu, VM_1_10_MBARE); 5756df3747aSAlexandre Ghiti #endif 57626b2bc58SAlistair Francis cpu->cfg.epmp = true; 5777f0bdfb5SDaniel Henrique Barboza 5787f0bdfb5SDaniel Henrique Barboza /* inherited from parent obj via riscv_cpu_init() */ 5797f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_ifencei = true; 5807f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_icsr = true; 5817f0bdfb5SDaniel Henrique Barboza cpu->cfg.pmp = true; 58236b80ad9SAlistair Francis } 58336b80ad9SAlistair Francis 5842fdd2c09SBin Meng static void rv32_imafcu_nommu_cpu_init(Object *obj) 585d784733bSCorey Wharton { 586d784733bSCorey Wharton CPURISCVState *env = &RISCV_CPU(obj)->env; 58726b2bc58SAlistair Francis RISCVCPU *cpu = RISCV_CPU(obj); 58826b2bc58SAlistair Francis 589e91a7227SRichard Henderson set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU); 5908c6eeb50SDaniel Henrique Barboza env->priv_ver = PRIV_VERSION_1_10_0; 5916df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 5926df3747aSAlexandre Ghiti set_satp_mode_max_supported(cpu, VM_1_10_MBARE); 5936df3747aSAlexandre Ghiti #endif 5947f0bdfb5SDaniel Henrique Barboza 5957f0bdfb5SDaniel Henrique Barboza /* inherited from parent obj via riscv_cpu_init() */ 5967f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_ifencei = true; 5977f0bdfb5SDaniel Henrique Barboza cpu->cfg.ext_icsr = true; 5987f0bdfb5SDaniel Henrique Barboza cpu->cfg.pmp = true; 599d784733bSCorey Wharton } 600eab15862SMichael Clark #endif 601dc5bd18fSMichael Clark 60210f1ca27SYifei Jiang #if defined(CONFIG_KVM) 60310f1ca27SYifei Jiang static void riscv_host_cpu_init(Object *obj) 60410f1ca27SYifei Jiang { 60510f1ca27SYifei Jiang CPURISCVState *env = &RISCV_CPU(obj)->env; 60610f1ca27SYifei Jiang #if defined(TARGET_RISCV32) 60710f1ca27SYifei Jiang set_misa(env, MXL_RV32, 0); 60810f1ca27SYifei Jiang #elif defined(TARGET_RISCV64) 60910f1ca27SYifei Jiang set_misa(env, MXL_RV64, 0); 61010f1ca27SYifei Jiang #endif 611dd8f244fSDaniel Henrique Barboza riscv_cpu_add_user_properties(obj); 61210f1ca27SYifei Jiang } 6139638cbdeSPhilippe Mathieu-Daudé #endif /* CONFIG_KVM */ 61410f1ca27SYifei Jiang 615dc5bd18fSMichael Clark static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model) 616dc5bd18fSMichael Clark { 617dc5bd18fSMichael Clark ObjectClass *oc; 618dc5bd18fSMichael Clark char *typename; 619dc5bd18fSMichael Clark char **cpuname; 620dc5bd18fSMichael Clark 621dc5bd18fSMichael Clark cpuname = g_strsplit(cpu_model, ",", 1); 622dc5bd18fSMichael Clark typename = g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname[0]); 623dc5bd18fSMichael Clark oc = object_class_by_name(typename); 624dc5bd18fSMichael Clark g_strfreev(cpuname); 625dc5bd18fSMichael Clark g_free(typename); 626dc5bd18fSMichael Clark if (!oc || !object_class_dynamic_cast(oc, TYPE_RISCV_CPU) || 627dc5bd18fSMichael Clark object_class_is_abstract(oc)) { 628dc5bd18fSMichael Clark return NULL; 629dc5bd18fSMichael Clark } 630dc5bd18fSMichael Clark return oc; 631dc5bd18fSMichael Clark } 632dc5bd18fSMichael Clark 63390c84c56SMarkus Armbruster static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) 634dc5bd18fSMichael Clark { 635dc5bd18fSMichael Clark RISCVCPU *cpu = RISCV_CPU(cs); 636dc5bd18fSMichael Clark CPURISCVState *env = &cpu->env; 637b227f6a8SIvan Klokov int i, j; 638b227f6a8SIvan Klokov uint8_t *p; 639dc5bd18fSMichael Clark 640df30e652SAlistair Francis #if !defined(CONFIG_USER_ONLY) 641df30e652SAlistair Francis if (riscv_has_ext(env, RVH)) { 64238256529SWeiwei Li qemu_fprintf(f, " %s %d\n", "V = ", env->virt_enabled); 643df30e652SAlistair Francis } 644df30e652SAlistair Francis #endif 64590c84c56SMarkus Armbruster qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc ", env->pc); 646dc5bd18fSMichael Clark #ifndef CONFIG_USER_ONLY 647665b90d8SRichard Henderson { 648665b90d8SRichard Henderson static const int dump_csrs[] = { 649665b90d8SRichard Henderson CSR_MHARTID, 650665b90d8SRichard Henderson CSR_MSTATUS, 651665b90d8SRichard Henderson CSR_MSTATUSH, 652bc7dca13SBin Meng /* 653bc7dca13SBin Meng * CSR_SSTATUS is intentionally omitted here as its value 654bc7dca13SBin Meng * can be figured out by looking at CSR_MSTATUS 655bc7dca13SBin Meng */ 656665b90d8SRichard Henderson CSR_HSTATUS, 657665b90d8SRichard Henderson CSR_VSSTATUS, 658665b90d8SRichard Henderson CSR_MIP, 659665b90d8SRichard Henderson CSR_MIE, 660665b90d8SRichard Henderson CSR_MIDELEG, 661665b90d8SRichard Henderson CSR_HIDELEG, 662665b90d8SRichard Henderson CSR_MEDELEG, 663665b90d8SRichard Henderson CSR_HEDELEG, 664665b90d8SRichard Henderson CSR_MTVEC, 665665b90d8SRichard Henderson CSR_STVEC, 666665b90d8SRichard Henderson CSR_VSTVEC, 667665b90d8SRichard Henderson CSR_MEPC, 668665b90d8SRichard Henderson CSR_SEPC, 669665b90d8SRichard Henderson CSR_VSEPC, 670665b90d8SRichard Henderson CSR_MCAUSE, 671665b90d8SRichard Henderson CSR_SCAUSE, 672665b90d8SRichard Henderson CSR_VSCAUSE, 673665b90d8SRichard Henderson CSR_MTVAL, 674665b90d8SRichard Henderson CSR_STVAL, 675665b90d8SRichard Henderson CSR_HTVAL, 676665b90d8SRichard Henderson CSR_MTVAL2, 677665b90d8SRichard Henderson CSR_MSCRATCH, 678665b90d8SRichard Henderson CSR_SSCRATCH, 679665b90d8SRichard Henderson CSR_SATP, 680bd5594caSAlexey Baturo CSR_MMTE, 681bd5594caSAlexey Baturo CSR_UPMBASE, 682bd5594caSAlexey Baturo CSR_UPMMASK, 683bd5594caSAlexey Baturo CSR_SPMBASE, 684bd5594caSAlexey Baturo CSR_SPMMASK, 685bd5594caSAlexey Baturo CSR_MPMBASE, 686bd5594caSAlexey Baturo CSR_MPMMASK, 687665b90d8SRichard Henderson }; 688665b90d8SRichard Henderson 689665b90d8SRichard Henderson for (int i = 0; i < ARRAY_SIZE(dump_csrs); ++i) { 690665b90d8SRichard Henderson int csrno = dump_csrs[i]; 691665b90d8SRichard Henderson target_ulong val = 0; 692665b90d8SRichard Henderson RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0); 693665b90d8SRichard Henderson 694665b90d8SRichard Henderson /* 695665b90d8SRichard Henderson * Rely on the smode, hmode, etc, predicates within csr.c 696665b90d8SRichard Henderson * to do the filtering of the registers that are present. 697665b90d8SRichard Henderson */ 698665b90d8SRichard Henderson if (res == RISCV_EXCP_NONE) { 699665b90d8SRichard Henderson qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n", 700665b90d8SRichard Henderson csr_ops[csrno].name, val); 7015c5a47f1SAlistair Francis } 702df30e652SAlistair Francis } 703df30e652SAlistair Francis } 704dc5bd18fSMichael Clark #endif 705dc5bd18fSMichael Clark 706dc5bd18fSMichael Clark for (i = 0; i < 32; i++) { 707e573a7f3STravis Geiselbrecht qemu_fprintf(f, " %-8s " TARGET_FMT_lx, 708dc5bd18fSMichael Clark riscv_int_regnames[i], env->gpr[i]); 709dc5bd18fSMichael Clark if ((i & 3) == 3) { 71090c84c56SMarkus Armbruster qemu_fprintf(f, "\n"); 711dc5bd18fSMichael Clark } 712dc5bd18fSMichael Clark } 71386ea1880SRichard Henderson if (flags & CPU_DUMP_FPU) { 714dc5bd18fSMichael Clark for (i = 0; i < 32; i++) { 715e573a7f3STravis Geiselbrecht qemu_fprintf(f, " %-8s %016" PRIx64, 716dc5bd18fSMichael Clark riscv_fpr_regnames[i], env->fpr[i]); 717dc5bd18fSMichael Clark if ((i & 3) == 3) { 71890c84c56SMarkus Armbruster qemu_fprintf(f, "\n"); 719dc5bd18fSMichael Clark } 720dc5bd18fSMichael Clark } 721dc5bd18fSMichael Clark } 722b227f6a8SIvan Klokov if (riscv_has_ext(env, RVV) && (flags & CPU_DUMP_VPU)) { 723b227f6a8SIvan Klokov static const int dump_rvv_csrs[] = { 724b227f6a8SIvan Klokov CSR_VSTART, 725b227f6a8SIvan Klokov CSR_VXSAT, 726b227f6a8SIvan Klokov CSR_VXRM, 727b227f6a8SIvan Klokov CSR_VCSR, 728b227f6a8SIvan Klokov CSR_VL, 729b227f6a8SIvan Klokov CSR_VTYPE, 730b227f6a8SIvan Klokov CSR_VLENB, 731b227f6a8SIvan Klokov }; 732b227f6a8SIvan Klokov for (int i = 0; i < ARRAY_SIZE(dump_rvv_csrs); ++i) { 733b227f6a8SIvan Klokov int csrno = dump_rvv_csrs[i]; 734b227f6a8SIvan Klokov target_ulong val = 0; 735b227f6a8SIvan Klokov RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0); 736b227f6a8SIvan Klokov 737b227f6a8SIvan Klokov /* 738b227f6a8SIvan Klokov * Rely on the smode, hmode, etc, predicates within csr.c 739b227f6a8SIvan Klokov * to do the filtering of the registers that are present. 740b227f6a8SIvan Klokov */ 741b227f6a8SIvan Klokov if (res == RISCV_EXCP_NONE) { 742b227f6a8SIvan Klokov qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n", 743b227f6a8SIvan Klokov csr_ops[csrno].name, val); 744b227f6a8SIvan Klokov } 745b227f6a8SIvan Klokov } 746b227f6a8SIvan Klokov uint16_t vlenb = cpu->cfg.vlen >> 3; 747b227f6a8SIvan Klokov 748b227f6a8SIvan Klokov for (i = 0; i < 32; i++) { 749b227f6a8SIvan Klokov qemu_fprintf(f, " %-8s ", riscv_rvv_regnames[i]); 750b227f6a8SIvan Klokov p = (uint8_t *)env->vreg; 751b227f6a8SIvan Klokov for (j = vlenb - 1 ; j >= 0; j--) { 752b227f6a8SIvan Klokov qemu_fprintf(f, "%02x", *(p + i * vlenb + BYTE(j))); 753b227f6a8SIvan Klokov } 754b227f6a8SIvan Klokov qemu_fprintf(f, "\n"); 755b227f6a8SIvan Klokov } 756b227f6a8SIvan Klokov } 75786ea1880SRichard Henderson } 758dc5bd18fSMichael Clark 759dc5bd18fSMichael Clark static void riscv_cpu_set_pc(CPUState *cs, vaddr value) 760dc5bd18fSMichael Clark { 761dc5bd18fSMichael Clark RISCVCPU *cpu = RISCV_CPU(cs); 762dc5bd18fSMichael Clark CPURISCVState *env = &cpu->env; 763bf9e776eSLIU Zhiwei 764bf9e776eSLIU Zhiwei if (env->xl == MXL_RV32) { 765bf9e776eSLIU Zhiwei env->pc = (int32_t)value; 766bf9e776eSLIU Zhiwei } else { 767dc5bd18fSMichael Clark env->pc = value; 768dc5bd18fSMichael Clark } 769bf9e776eSLIU Zhiwei } 770dc5bd18fSMichael Clark 771e4fdf9dfSRichard Henderson static vaddr riscv_cpu_get_pc(CPUState *cs) 772e4fdf9dfSRichard Henderson { 773e4fdf9dfSRichard Henderson RISCVCPU *cpu = RISCV_CPU(cs); 774e4fdf9dfSRichard Henderson CPURISCVState *env = &cpu->env; 775e4fdf9dfSRichard Henderson 776e4fdf9dfSRichard Henderson /* Match cpu_get_tb_cpu_state. */ 777e4fdf9dfSRichard Henderson if (env->xl == MXL_RV32) { 778e4fdf9dfSRichard Henderson return env->pc & UINT32_MAX; 779e4fdf9dfSRichard Henderson } 780e4fdf9dfSRichard Henderson return env->pc; 781e4fdf9dfSRichard Henderson } 782e4fdf9dfSRichard Henderson 78304a37d4cSRichard Henderson static void riscv_cpu_synchronize_from_tb(CPUState *cs, 78404a37d4cSRichard Henderson const TranslationBlock *tb) 785dc5bd18fSMichael Clark { 786356c13f9SWeiwei Li if (!(tb_cflags(tb) & CF_PCREL)) { 787dc5bd18fSMichael Clark RISCVCPU *cpu = RISCV_CPU(cs); 788dc5bd18fSMichael Clark CPURISCVState *env = &cpu->env; 789bf9e776eSLIU Zhiwei RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL); 790bf9e776eSLIU Zhiwei 7910489d5bdSAnton Johansson tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL)); 7920489d5bdSAnton Johansson 793bf9e776eSLIU Zhiwei if (xl == MXL_RV32) { 7940489d5bdSAnton Johansson env->pc = (int32_t) tb->pc; 795bf9e776eSLIU Zhiwei } else { 7960489d5bdSAnton Johansson env->pc = tb->pc; 797dc5bd18fSMichael Clark } 798bf9e776eSLIU Zhiwei } 799356c13f9SWeiwei Li } 800dc5bd18fSMichael Clark 801dc5bd18fSMichael Clark static bool riscv_cpu_has_work(CPUState *cs) 802dc5bd18fSMichael Clark { 803dc5bd18fSMichael Clark #ifndef CONFIG_USER_ONLY 804dc5bd18fSMichael Clark RISCVCPU *cpu = RISCV_CPU(cs); 805dc5bd18fSMichael Clark CPURISCVState *env = &cpu->env; 806dc5bd18fSMichael Clark /* 807dc5bd18fSMichael Clark * Definition of the WFI instruction requires it to ignore the privilege 808dc5bd18fSMichael Clark * mode and delegation registers, but respect individual enables 809dc5bd18fSMichael Clark */ 8108f42415fSAndrew Bresticker return riscv_cpu_all_pending(env) != 0; 811dc5bd18fSMichael Clark #else 812dc5bd18fSMichael Clark return true; 813dc5bd18fSMichael Clark #endif 814dc5bd18fSMichael Clark } 815dc5bd18fSMichael Clark 816ad1e84f5SRichard Henderson static void riscv_restore_state_to_opc(CPUState *cs, 817ad1e84f5SRichard Henderson const TranslationBlock *tb, 818ad1e84f5SRichard Henderson const uint64_t *data) 819dc5bd18fSMichael Clark { 820ad1e84f5SRichard Henderson RISCVCPU *cpu = RISCV_CPU(cs); 821ad1e84f5SRichard Henderson CPURISCVState *env = &cpu->env; 822bf9e776eSLIU Zhiwei RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL); 823356c13f9SWeiwei Li target_ulong pc; 824356c13f9SWeiwei Li 825356c13f9SWeiwei Li if (tb_cflags(tb) & CF_PCREL) { 826356c13f9SWeiwei Li pc = (env->pc & TARGET_PAGE_MASK) | data[0]; 827356c13f9SWeiwei Li } else { 828356c13f9SWeiwei Li pc = data[0]; 829356c13f9SWeiwei Li } 830ad1e84f5SRichard Henderson 831bf9e776eSLIU Zhiwei if (xl == MXL_RV32) { 832356c13f9SWeiwei Li env->pc = (int32_t)pc; 833bf9e776eSLIU Zhiwei } else { 834356c13f9SWeiwei Li env->pc = pc; 835dc5bd18fSMichael Clark } 83662cf0245SAnup Patel env->bins = data[1]; 837bf9e776eSLIU Zhiwei } 838dc5bd18fSMichael Clark 8394fa485a7SPeter Maydell static void riscv_cpu_reset_hold(Object *obj) 840dc5bd18fSMichael Clark { 84143dc93afSAnup Patel #ifndef CONFIG_USER_ONLY 84243dc93afSAnup Patel uint8_t iprio; 84343dc93afSAnup Patel int i, irq, rdzero; 84443dc93afSAnup Patel #endif 8454fa485a7SPeter Maydell CPUState *cs = CPU(obj); 846dc5bd18fSMichael Clark RISCVCPU *cpu = RISCV_CPU(cs); 847dc5bd18fSMichael Clark RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); 848dc5bd18fSMichael Clark CPURISCVState *env = &cpu->env; 849dc5bd18fSMichael Clark 8504fa485a7SPeter Maydell if (mcc->parent_phases.hold) { 8514fa485a7SPeter Maydell mcc->parent_phases.hold(obj); 8524fa485a7SPeter Maydell } 853dc5bd18fSMichael Clark #ifndef CONFIG_USER_ONLY 854e91a7227SRichard Henderson env->misa_mxl = env->misa_mxl_max; 855dc5bd18fSMichael Clark env->priv = PRV_M; 856dc5bd18fSMichael Clark env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV); 85792371bd9SRichard Henderson if (env->misa_mxl > MXL_RV32) { 85892371bd9SRichard Henderson /* 85992371bd9SRichard Henderson * The reset status of SXL/UXL is undefined, but mstatus is WARL 86092371bd9SRichard Henderson * and we must ensure that the value after init is valid for read. 86192371bd9SRichard Henderson */ 86292371bd9SRichard Henderson env->mstatus = set_field(env->mstatus, MSTATUS64_SXL, env->misa_mxl); 86392371bd9SRichard Henderson env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, env->misa_mxl); 8645a2ae235SLIU Zhiwei if (riscv_has_ext(env, RVH)) { 8655a2ae235SLIU Zhiwei env->vsstatus = set_field(env->vsstatus, 8665a2ae235SLIU Zhiwei MSTATUS64_SXL, env->misa_mxl); 8675a2ae235SLIU Zhiwei env->vsstatus = set_field(env->vsstatus, 8685a2ae235SLIU Zhiwei MSTATUS64_UXL, env->misa_mxl); 8695a2ae235SLIU Zhiwei env->mstatus_hs = set_field(env->mstatus_hs, 8705a2ae235SLIU Zhiwei MSTATUS64_SXL, env->misa_mxl); 8715a2ae235SLIU Zhiwei env->mstatus_hs = set_field(env->mstatus_hs, 8725a2ae235SLIU Zhiwei MSTATUS64_UXL, env->misa_mxl); 8735a2ae235SLIU Zhiwei } 87492371bd9SRichard Henderson } 875dc5bd18fSMichael Clark env->mcause = 0; 876881df35dSAnup Patel env->miclaim = MIP_SGEIP; 877dc5bd18fSMichael Clark env->pc = env->resetvec; 87862cf0245SAnup Patel env->bins = 0; 879ec352d0cSGeorg Kotheimer env->two_stage_lookup = false; 88043dc93afSAnup Patel 8810af3f115SWeiwei Li env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) | 8820af3f115SWeiwei Li (cpu->cfg.ext_svadu ? MENVCFG_HADE : 0); 8830af3f115SWeiwei Li env->henvcfg = (cpu->cfg.ext_svpbmt ? HENVCFG_PBMTE : 0) | 8840af3f115SWeiwei Li (cpu->cfg.ext_svadu ? HENVCFG_HADE : 0); 8857a6613daSWeiwei Li 88643dc93afSAnup Patel /* Initialized default priorities of local interrupts. */ 88743dc93afSAnup Patel for (i = 0; i < ARRAY_SIZE(env->miprio); i++) { 88843dc93afSAnup Patel iprio = riscv_cpu_default_priority(i); 88943dc93afSAnup Patel env->miprio[i] = (i == IRQ_M_EXT) ? 0 : iprio; 89043dc93afSAnup Patel env->siprio[i] = (i == IRQ_S_EXT) ? 0 : iprio; 89143dc93afSAnup Patel env->hviprio[i] = 0; 89243dc93afSAnup Patel } 89343dc93afSAnup Patel i = 0; 89443dc93afSAnup Patel while (!riscv_cpu_hviprio_index2irq(i, &irq, &rdzero)) { 89543dc93afSAnup Patel if (!rdzero) { 89643dc93afSAnup Patel env->hviprio[irq] = env->miprio[irq]; 89743dc93afSAnup Patel } 89843dc93afSAnup Patel i++; 89943dc93afSAnup Patel } 9004bbe8033SAlexey Baturo /* mmte is supposed to have pm.current hardwired to 1 */ 90142967f40SLIU Zhiwei env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); 902dc5bd18fSMichael Clark #endif 903440544e1SLIU Zhiwei env->xl = riscv_cpu_mxl(env); 90440bfa5f6SLIU Zhiwei riscv_cpu_update_mask(env); 905330d2ae3SAlistair Francis cs->exception_index = RISCV_EXCP_NONE; 906c13b169fSJoel Sing env->load_res = -1; 907dc5bd18fSMichael Clark set_default_nan_mode(1, &env->fp_status); 908ad40be27SYifei Jiang 909ad40be27SYifei Jiang #ifndef CONFIG_USER_ONLY 910cdfb2905SDaniel Henrique Barboza if (cpu->cfg.debug) { 911b6092544SBin Meng riscv_trigger_init(env); 912b6092544SBin Meng } 913b6092544SBin Meng 914ad40be27SYifei Jiang if (kvm_enabled()) { 915ad40be27SYifei Jiang kvm_riscv_reset_vcpu(cpu); 916ad40be27SYifei Jiang } 917ad40be27SYifei Jiang #endif 918dc5bd18fSMichael Clark } 919dc5bd18fSMichael Clark 920dc5bd18fSMichael Clark static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) 921dc5bd18fSMichael Clark { 9225c5a47f1SAlistair Francis RISCVCPU *cpu = RISCV_CPU(s); 92394692c3aSLIU Zhiwei CPURISCVState *env = &cpu->env; 924454c2201SWeiwei Li info->target_info = &cpu->cfg; 925db23e5d9SRichard Henderson 92694692c3aSLIU Zhiwei switch (env->xl) { 927db23e5d9SRichard Henderson case MXL_RV32: 928dc5bd18fSMichael Clark info->print_insn = print_insn_riscv32; 929db23e5d9SRichard Henderson break; 930db23e5d9SRichard Henderson case MXL_RV64: 931dc5bd18fSMichael Clark info->print_insn = print_insn_riscv64; 932db23e5d9SRichard Henderson break; 933332dab68SFrédéric Pétrot case MXL_RV128: 934332dab68SFrédéric Pétrot info->print_insn = print_insn_riscv128; 935332dab68SFrédéric Pétrot break; 936db23e5d9SRichard Henderson default: 937db23e5d9SRichard Henderson g_assert_not_reached(); 9385c5a47f1SAlistair Francis } 939dc5bd18fSMichael Clark } 940dc5bd18fSMichael Clark 941d63be184SDaniel Henrique Barboza static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, 942d63be184SDaniel Henrique Barboza Error **errp) 943d63be184SDaniel Henrique Barboza { 944d63be184SDaniel Henrique Barboza int vext_version = VEXT_VERSION_1_00_0; 945d63be184SDaniel Henrique Barboza 946d63be184SDaniel Henrique Barboza if (!is_power_of_2(cfg->vlen)) { 947d63be184SDaniel Henrique Barboza error_setg(errp, "Vector extension VLEN must be power of 2"); 948d63be184SDaniel Henrique Barboza return; 949d63be184SDaniel Henrique Barboza } 950d63be184SDaniel Henrique Barboza if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) { 951d63be184SDaniel Henrique Barboza error_setg(errp, 952d63be184SDaniel Henrique Barboza "Vector extension implementation only supports VLEN " 953d63be184SDaniel Henrique Barboza "in the range [128, %d]", RV_VLEN_MAX); 954d63be184SDaniel Henrique Barboza return; 955d63be184SDaniel Henrique Barboza } 956d63be184SDaniel Henrique Barboza if (!is_power_of_2(cfg->elen)) { 957d63be184SDaniel Henrique Barboza error_setg(errp, "Vector extension ELEN must be power of 2"); 958d63be184SDaniel Henrique Barboza return; 959d63be184SDaniel Henrique Barboza } 960d63be184SDaniel Henrique Barboza if (cfg->elen > 64 || cfg->elen < 8) { 961d63be184SDaniel Henrique Barboza error_setg(errp, 962d63be184SDaniel Henrique Barboza "Vector extension implementation only supports ELEN " 963d63be184SDaniel Henrique Barboza "in the range [8, 64]"); 964d63be184SDaniel Henrique Barboza return; 965d63be184SDaniel Henrique Barboza } 966d63be184SDaniel Henrique Barboza if (cfg->vext_spec) { 967d63be184SDaniel Henrique Barboza if (!g_strcmp0(cfg->vext_spec, "v1.0")) { 968d63be184SDaniel Henrique Barboza vext_version = VEXT_VERSION_1_00_0; 969d63be184SDaniel Henrique Barboza } else { 970d63be184SDaniel Henrique Barboza error_setg(errp, "Unsupported vector spec version '%s'", 971d63be184SDaniel Henrique Barboza cfg->vext_spec); 972d63be184SDaniel Henrique Barboza return; 973d63be184SDaniel Henrique Barboza } 974d63be184SDaniel Henrique Barboza } else { 975d63be184SDaniel Henrique Barboza qemu_log("vector version is not specified, " 976d63be184SDaniel Henrique Barboza "use the default value v1.0\n"); 977d63be184SDaniel Henrique Barboza } 9782238c9d1SDaniel Henrique Barboza env->vext_ver = vext_version; 979d63be184SDaniel Henrique Barboza } 980d63be184SDaniel Henrique Barboza 981bd305595SDaniel Henrique Barboza static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp) 982bd305595SDaniel Henrique Barboza { 983bd305595SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 984bd305595SDaniel Henrique Barboza int priv_version = -1; 985bd305595SDaniel Henrique Barboza 986bd305595SDaniel Henrique Barboza if (cpu->cfg.priv_spec) { 987bd305595SDaniel Henrique Barboza if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) { 988bd305595SDaniel Henrique Barboza priv_version = PRIV_VERSION_1_12_0; 989bd305595SDaniel Henrique Barboza } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) { 990bd305595SDaniel Henrique Barboza priv_version = PRIV_VERSION_1_11_0; 991bd305595SDaniel Henrique Barboza } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) { 992bd305595SDaniel Henrique Barboza priv_version = PRIV_VERSION_1_10_0; 993bd305595SDaniel Henrique Barboza } else { 994bd305595SDaniel Henrique Barboza error_setg(errp, 995bd305595SDaniel Henrique Barboza "Unsupported privilege spec version '%s'", 996bd305595SDaniel Henrique Barboza cpu->cfg.priv_spec); 997bd305595SDaniel Henrique Barboza return; 998bd305595SDaniel Henrique Barboza } 999bd305595SDaniel Henrique Barboza 1000bd305595SDaniel Henrique Barboza env->priv_ver = priv_version; 1001bd305595SDaniel Henrique Barboza } 1002bd305595SDaniel Henrique Barboza } 1003bd305595SDaniel Henrique Barboza 1004bd305595SDaniel Henrique Barboza static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) 1005bd305595SDaniel Henrique Barboza { 1006bd305595SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 1007bd305595SDaniel Henrique Barboza int i; 1008bd305595SDaniel Henrique Barboza 1009bd305595SDaniel Henrique Barboza /* Force disable extensions if priv spec version does not match */ 1010bd305595SDaniel Henrique Barboza for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { 1011bd305595SDaniel Henrique Barboza if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) && 1012bd305595SDaniel Henrique Barboza (env->priv_ver < isa_edata_arr[i].min_version)) { 1013bd305595SDaniel Henrique Barboza isa_ext_update_enabled(cpu, &isa_edata_arr[i], false); 1014bd305595SDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY 1015bd305595SDaniel Henrique Barboza warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx 1016bd305595SDaniel Henrique Barboza " because privilege spec version does not match", 1017bd305595SDaniel Henrique Barboza isa_edata_arr[i].name, env->mhartid); 1018bd305595SDaniel Henrique Barboza #else 1019bd305595SDaniel Henrique Barboza warn_report("disabling %s extension because " 1020bd305595SDaniel Henrique Barboza "privilege spec version does not match", 1021bd305595SDaniel Henrique Barboza isa_edata_arr[i].name); 1022bd305595SDaniel Henrique Barboza #endif 1023bd305595SDaniel Henrique Barboza } 1024bd305595SDaniel Henrique Barboza } 1025bd305595SDaniel Henrique Barboza } 1026bd305595SDaniel Henrique Barboza 1027f5664064SDaniel Henrique Barboza static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp) 1028f5664064SDaniel Henrique Barboza { 1029f5664064SDaniel Henrique Barboza RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); 1030f5664064SDaniel Henrique Barboza CPUClass *cc = CPU_CLASS(mcc); 1031f5664064SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 1032f5664064SDaniel Henrique Barboza 1033f5664064SDaniel Henrique Barboza /* Validate that MISA_MXL is set properly. */ 1034f5664064SDaniel Henrique Barboza switch (env->misa_mxl_max) { 1035f5664064SDaniel Henrique Barboza #ifdef TARGET_RISCV64 1036f5664064SDaniel Henrique Barboza case MXL_RV64: 1037f5664064SDaniel Henrique Barboza case MXL_RV128: 1038f5664064SDaniel Henrique Barboza cc->gdb_core_xml_file = "riscv-64bit-cpu.xml"; 1039f5664064SDaniel Henrique Barboza break; 1040f5664064SDaniel Henrique Barboza #endif 1041f5664064SDaniel Henrique Barboza case MXL_RV32: 1042f5664064SDaniel Henrique Barboza cc->gdb_core_xml_file = "riscv-32bit-cpu.xml"; 1043f5664064SDaniel Henrique Barboza break; 1044f5664064SDaniel Henrique Barboza default: 1045f5664064SDaniel Henrique Barboza g_assert_not_reached(); 1046f5664064SDaniel Henrique Barboza } 1047f5664064SDaniel Henrique Barboza 1048f5664064SDaniel Henrique Barboza if (env->misa_mxl_max != env->misa_mxl) { 1049f5664064SDaniel Henrique Barboza error_setg(errp, "misa_mxl_max must be equal to misa_mxl"); 1050f5664064SDaniel Henrique Barboza return; 1051f5664064SDaniel Henrique Barboza } 1052f5664064SDaniel Henrique Barboza } 1053f5664064SDaniel Henrique Barboza 10545da9514eSHou Weiying /* 10555ab10952SDaniel Henrique Barboza * Check consistency between chosen extensions while setting 10561ffa805cSDaniel Henrique Barboza * cpu->cfg accordingly. 10575da9514eSHou Weiying */ 1058faf3b5d8SDaniel Henrique Barboza void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) 10595ab10952SDaniel Henrique Barboza { 10605ab10952SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 1061d63be184SDaniel Henrique Barboza Error *local_err = NULL; 1062e91a7227SRichard Henderson 1063b55d7d34SAlistair Francis /* Do some ISA extension error checking */ 10644f13abcbSDaniel Henrique Barboza if (riscv_has_ext(env, RVG) && 10654f13abcbSDaniel Henrique Barboza !(riscv_has_ext(env, RVI) && riscv_has_ext(env, RVM) && 10664f13abcbSDaniel Henrique Barboza riscv_has_ext(env, RVA) && riscv_has_ext(env, RVF) && 10674b33598fSDaniel Henrique Barboza riscv_has_ext(env, RVD) && 10689f6b7da5STsukasa OI cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) { 10699f6b7da5STsukasa OI warn_report("Setting G will also set IMAFD_Zicsr_Zifencei"); 10709f6b7da5STsukasa OI cpu->cfg.ext_icsr = true; 10719f6b7da5STsukasa OI cpu->cfg.ext_ifencei = true; 10721ffa805cSDaniel Henrique Barboza 10731ffa805cSDaniel Henrique Barboza env->misa_ext |= RVI | RVM | RVA | RVF | RVD; 1074faf3b5d8SDaniel Henrique Barboza env->misa_ext_mask |= RVI | RVM | RVA | RVF | RVD; 1075b55d7d34SAlistair Francis } 1076b55d7d34SAlistair Francis 1077427d8e7dSDaniel Henrique Barboza if (riscv_has_ext(env, RVI) && riscv_has_ext(env, RVE)) { 1078bb06941fSWeiwei Li error_setg(errp, 1079bb06941fSWeiwei Li "I and E extensions are incompatible"); 1080bb06941fSWeiwei Li return; 1081bb06941fSWeiwei Li } 1082bb06941fSWeiwei Li 1083427d8e7dSDaniel Henrique Barboza if (!riscv_has_ext(env, RVI) && !riscv_has_ext(env, RVE)) { 1084bb06941fSWeiwei Li error_setg(errp, 1085bb06941fSWeiwei Li "Either I or E extension must be set"); 1086bb06941fSWeiwei Li return; 1087bb06941fSWeiwei Li } 1088bb06941fSWeiwei Li 1089e17801e1SDaniel Henrique Barboza if (riscv_has_ext(env, RVS) && !riscv_has_ext(env, RVU)) { 10900b572c81SWeiwei Li error_setg(errp, 10910b572c81SWeiwei Li "Setting S extension without U extension is illegal"); 10920b572c81SWeiwei Li return; 10930b572c81SWeiwei Li } 10940b572c81SWeiwei Li 1095b5c042e8SDaniel Henrique Barboza if (riscv_has_ext(env, RVH) && !riscv_has_ext(env, RVI)) { 1096756b0374SWeiwei Li error_setg(errp, 1097756b0374SWeiwei Li "H depends on an I base integer ISA with 32 x registers"); 1098756b0374SWeiwei Li return; 1099756b0374SWeiwei Li } 1100756b0374SWeiwei Li 1101b5c042e8SDaniel Henrique Barboza if (riscv_has_ext(env, RVH) && !riscv_has_ext(env, RVS)) { 110262a09b9bSWeiwei Li error_setg(errp, "H extension implicitly requires S-mode"); 110362a09b9bSWeiwei Li return; 110462a09b9bSWeiwei Li } 110562a09b9bSWeiwei Li 11064b33598fSDaniel Henrique Barboza if (riscv_has_ext(env, RVF) && !cpu->cfg.ext_icsr) { 11071086504cSTsukasa OI error_setg(errp, "F extension requires Zicsr"); 11081086504cSTsukasa OI return; 11091086504cSTsukasa OI } 11101086504cSTsukasa OI 11114c759943SDaniel Henrique Barboza if ((cpu->cfg.ext_zawrs) && !riscv_has_ext(env, RVA)) { 1112260b594dSChristoph Muellner error_setg(errp, "Zawrs extension requires A extension"); 1113260b594dSChristoph Muellner return; 1114260b594dSChristoph Muellner } 1115260b594dSChristoph Muellner 1116a47842d1SChristoph Müllner if (cpu->cfg.ext_zfa && !riscv_has_ext(env, RVF)) { 1117a47842d1SChristoph Müllner error_setg(errp, "Zfa extension requires F extension"); 1118a47842d1SChristoph Müllner return; 1119a47842d1SChristoph Müllner } 1120a47842d1SChristoph Müllner 11211d2cb5a8SWeiwei Li if (cpu->cfg.ext_zfh) { 11221d2cb5a8SWeiwei Li cpu->cfg.ext_zfhmin = true; 11231d2cb5a8SWeiwei Li } 11241d2cb5a8SWeiwei Li 11254b33598fSDaniel Henrique Barboza if (cpu->cfg.ext_zfhmin && !riscv_has_ext(env, RVF)) { 11261086504cSTsukasa OI error_setg(errp, "Zfh/Zfhmin extensions require F extension"); 11271086504cSTsukasa OI return; 11281086504cSTsukasa OI } 11291086504cSTsukasa OI 11304556fdaaSWeiwei Li if (cpu->cfg.ext_zfbfmin && !riscv_has_ext(env, RVF)) { 11314556fdaaSWeiwei Li error_setg(errp, "Zfbfmin extension depends on F extension"); 11324556fdaaSWeiwei Li return; 11334556fdaaSWeiwei Li } 11344556fdaaSWeiwei Li 11354b33598fSDaniel Henrique Barboza if (riscv_has_ext(env, RVD) && !riscv_has_ext(env, RVF)) { 11361086504cSTsukasa OI error_setg(errp, "D extension requires F extension"); 11371086504cSTsukasa OI return; 11381086504cSTsukasa OI } 11391086504cSTsukasa OI 11403e7674fdSDaniel Henrique Barboza if (riscv_has_ext(env, RVV)) { 1141d63be184SDaniel Henrique Barboza riscv_cpu_validate_v(env, &cpu->cfg, &local_err); 1142d63be184SDaniel Henrique Barboza if (local_err != NULL) { 1143d63be184SDaniel Henrique Barboza error_propagate(errp, local_err); 1144d63be184SDaniel Henrique Barboza return; 1145d63be184SDaniel Henrique Barboza } 1146d63be184SDaniel Henrique Barboza 1147d63be184SDaniel Henrique Barboza /* The V vector extension depends on the Zve64d extension */ 1148e7f0a803SWeiwei Li cpu->cfg.ext_zve64d = true; 1149e7f0a803SWeiwei Li } 1150e7f0a803SWeiwei Li 1151e7f0a803SWeiwei Li /* The Zve64d extension depends on the Zve64f extension */ 1152e7f0a803SWeiwei Li if (cpu->cfg.ext_zve64d) { 1153e7f0a803SWeiwei Li cpu->cfg.ext_zve64f = true; 1154e7f0a803SWeiwei Li } 1155e7f0a803SWeiwei Li 1156e7f0a803SWeiwei Li /* The Zve64f extension depends on the Zve32f extension */ 1157e7f0a803SWeiwei Li if (cpu->cfg.ext_zve64f) { 1158e7f0a803SWeiwei Li cpu->cfg.ext_zve32f = true; 1159e7f0a803SWeiwei Li } 1160e7f0a803SWeiwei Li 1161ffffd954SDaniel Henrique Barboza if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) { 1162e7f0a803SWeiwei Li error_setg(errp, "Zve64d/V extensions require D extension"); 11631086504cSTsukasa OI return; 11641086504cSTsukasa OI } 11651086504cSTsukasa OI 11664b33598fSDaniel Henrique Barboza if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) { 1167bc573816STsukasa OI error_setg(errp, "Zve32f/Zve64f extensions require F extension"); 1168bc573816STsukasa OI return; 1169bc573816STsukasa OI } 1170bc573816STsukasa OI 11712e60f9ecSWeiwei Li if (cpu->cfg.ext_zvfh) { 11722e60f9ecSWeiwei Li cpu->cfg.ext_zvfhmin = true; 11732e60f9ecSWeiwei Li } 11742e60f9ecSWeiwei Li 11752e60f9ecSWeiwei Li if (cpu->cfg.ext_zvfhmin && !cpu->cfg.ext_zve32f) { 11762e60f9ecSWeiwei Li error_setg(errp, "Zvfh/Zvfhmin extensions require Zve32f extension"); 11772e60f9ecSWeiwei Li return; 11782e60f9ecSWeiwei Li } 11792e60f9ecSWeiwei Li 11802e60f9ecSWeiwei Li if (cpu->cfg.ext_zvfh && !cpu->cfg.ext_zfhmin) { 11812e60f9ecSWeiwei Li error_setg(errp, "Zvfh extensions requires Zfhmin extension"); 11822e60f9ecSWeiwei Li return; 11832e60f9ecSWeiwei Li } 11842e60f9ecSWeiwei Li 11854556fdaaSWeiwei Li if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zfbfmin) { 11864556fdaaSWeiwei Li error_setg(errp, "Zvfbfmin extension depends on Zfbfmin extension"); 11874556fdaaSWeiwei Li return; 11884556fdaaSWeiwei Li } 11894556fdaaSWeiwei Li 11904556fdaaSWeiwei Li if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zve32f) { 11914556fdaaSWeiwei Li error_setg(errp, "Zvfbfmin extension depends on Zve32f extension"); 11924556fdaaSWeiwei Li return; 11934556fdaaSWeiwei Li } 11944556fdaaSWeiwei Li 11954556fdaaSWeiwei Li if (cpu->cfg.ext_zvfbfwma && !cpu->cfg.ext_zvfbfmin) { 11964556fdaaSWeiwei Li error_setg(errp, "Zvfbfwma extension depends on Zvfbfmin extension"); 11974556fdaaSWeiwei Li return; 11984556fdaaSWeiwei Li } 11994556fdaaSWeiwei Li 1200bc573816STsukasa OI /* Set the ISA extensions, checks should have happened above */ 1201a0d805f0SWeiwei Li if (cpu->cfg.ext_zhinx) { 1202a0d805f0SWeiwei Li cpu->cfg.ext_zhinxmin = true; 1203a0d805f0SWeiwei Li } 1204a0d805f0SWeiwei Li 12059ba63f94SWeiwei Li if ((cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) && !cpu->cfg.ext_zfinx) { 12069ba63f94SWeiwei Li error_setg(errp, "Zdinx/Zhinx/Zhinxmin extensions require Zfinx"); 12079ba63f94SWeiwei Li return; 120889ffdcecSWeiwei Li } 120989ffdcecSWeiwei Li 1210bc573816STsukasa OI if (cpu->cfg.ext_zfinx) { 1211bc573816STsukasa OI if (!cpu->cfg.ext_icsr) { 12121086504cSTsukasa OI error_setg(errp, "Zfinx extension requires Zicsr"); 12131086504cSTsukasa OI return; 12141086504cSTsukasa OI } 12154b33598fSDaniel Henrique Barboza if (riscv_has_ext(env, RVF)) { 1216bc573816STsukasa OI error_setg(errp, 1217bc573816STsukasa OI "Zfinx cannot be supported together with F extension"); 1218bc573816STsukasa OI return; 1219bc573816STsukasa OI } 1220bc573816STsukasa OI } 12211086504cSTsukasa OI 122200d312bdSWeiwei Li if (cpu->cfg.ext_zce) { 122300d312bdSWeiwei Li cpu->cfg.ext_zca = true; 122400d312bdSWeiwei Li cpu->cfg.ext_zcb = true; 122500d312bdSWeiwei Li cpu->cfg.ext_zcmp = true; 122600d312bdSWeiwei Li cpu->cfg.ext_zcmt = true; 12274b33598fSDaniel Henrique Barboza if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) { 122800d312bdSWeiwei Li cpu->cfg.ext_zcf = true; 122900d312bdSWeiwei Li } 123000d312bdSWeiwei Li } 123100d312bdSWeiwei Li 123255ea4739SDaniel Henrique Barboza /* zca, zcd and zcf has a PRIV 1.12.0 restriction */ 123355ea4739SDaniel Henrique Barboza if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) { 12342288a5ceSWeiwei Li cpu->cfg.ext_zca = true; 12354b33598fSDaniel Henrique Barboza if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) { 12362288a5ceSWeiwei Li cpu->cfg.ext_zcf = true; 12372288a5ceSWeiwei Li } 1238ffffd954SDaniel Henrique Barboza if (riscv_has_ext(env, RVD)) { 12392288a5ceSWeiwei Li cpu->cfg.ext_zcd = true; 12402288a5ceSWeiwei Li } 12412288a5ceSWeiwei Li } 12422288a5ceSWeiwei Li 12432288a5ceSWeiwei Li if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) { 12442288a5ceSWeiwei Li error_setg(errp, "Zcf extension is only relevant to RV32"); 12452288a5ceSWeiwei Li return; 12462288a5ceSWeiwei Li } 12472288a5ceSWeiwei Li 12484b33598fSDaniel Henrique Barboza if (!riscv_has_ext(env, RVF) && cpu->cfg.ext_zcf) { 12492288a5ceSWeiwei Li error_setg(errp, "Zcf extension requires F extension"); 12502288a5ceSWeiwei Li return; 12512288a5ceSWeiwei Li } 12522288a5ceSWeiwei Li 1253ffffd954SDaniel Henrique Barboza if (!riscv_has_ext(env, RVD) && cpu->cfg.ext_zcd) { 12542288a5ceSWeiwei Li error_setg(errp, "Zcd extension requires D extension"); 12552288a5ceSWeiwei Li return; 12562288a5ceSWeiwei Li } 12572288a5ceSWeiwei Li 12582288a5ceSWeiwei Li if ((cpu->cfg.ext_zcf || cpu->cfg.ext_zcd || cpu->cfg.ext_zcb || 12592288a5ceSWeiwei Li cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) && !cpu->cfg.ext_zca) { 12602288a5ceSWeiwei Li error_setg(errp, "Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca " 12612288a5ceSWeiwei Li "extension"); 12622288a5ceSWeiwei Li return; 12632288a5ceSWeiwei Li } 12642288a5ceSWeiwei Li 12652288a5ceSWeiwei Li if (cpu->cfg.ext_zcd && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) { 12662288a5ceSWeiwei Li error_setg(errp, "Zcmp/Zcmt extensions are incompatible with " 12672288a5ceSWeiwei Li "Zcd extension"); 12682288a5ceSWeiwei Li return; 12692288a5ceSWeiwei Li } 12702288a5ceSWeiwei Li 12712288a5ceSWeiwei Li if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_icsr) { 12722288a5ceSWeiwei Li error_setg(errp, "Zcmt extension requires Zicsr extension"); 12732288a5ceSWeiwei Li return; 12742288a5ceSWeiwei Li } 12752288a5ceSWeiwei Li 1276*06028472SDickon Hood /* 1277*06028472SDickon Hood * In principle Zve*x would also suffice here, were they supported 1278*06028472SDickon Hood * in qemu 1279*06028472SDickon Hood */ 1280*06028472SDickon Hood if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) { 1281*06028472SDickon Hood error_setg(errp, 1282*06028472SDickon Hood "Vector crypto extensions require V or Zve* extensions"); 1283*06028472SDickon Hood return; 1284*06028472SDickon Hood } 1285*06028472SDickon Hood 1286e13c7d3bSLawrence Hunter if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) { 1287e13c7d3bSLawrence Hunter error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions"); 1288e13c7d3bSLawrence Hunter return; 1289e13c7d3bSLawrence Hunter } 1290e13c7d3bSLawrence Hunter 1291eef82872SWeiwei Li if (cpu->cfg.ext_zk) { 1292eef82872SWeiwei Li cpu->cfg.ext_zkn = true; 1293eef82872SWeiwei Li cpu->cfg.ext_zkr = true; 1294eef82872SWeiwei Li cpu->cfg.ext_zkt = true; 1295eef82872SWeiwei Li } 1296eef82872SWeiwei Li 1297eef82872SWeiwei Li if (cpu->cfg.ext_zkn) { 1298eef82872SWeiwei Li cpu->cfg.ext_zbkb = true; 1299eef82872SWeiwei Li cpu->cfg.ext_zbkc = true; 1300eef82872SWeiwei Li cpu->cfg.ext_zbkx = true; 1301eef82872SWeiwei Li cpu->cfg.ext_zkne = true; 1302eef82872SWeiwei Li cpu->cfg.ext_zknd = true; 1303eef82872SWeiwei Li cpu->cfg.ext_zknh = true; 1304eef82872SWeiwei Li } 1305eef82872SWeiwei Li 1306eef82872SWeiwei Li if (cpu->cfg.ext_zks) { 1307eef82872SWeiwei Li cpu->cfg.ext_zbkb = true; 1308eef82872SWeiwei Li cpu->cfg.ext_zbkc = true; 1309eef82872SWeiwei Li cpu->cfg.ext_zbkx = true; 1310eef82872SWeiwei Li cpu->cfg.ext_zksed = true; 1311eef82872SWeiwei Li cpu->cfg.ext_zksh = true; 1312eef82872SWeiwei Li } 1313bd305595SDaniel Henrique Barboza 1314bd305595SDaniel Henrique Barboza /* 1315bd305595SDaniel Henrique Barboza * Disable isa extensions based on priv spec after we 1316bd305595SDaniel Henrique Barboza * validated and set everything we need. 1317bd305595SDaniel Henrique Barboza */ 1318bd305595SDaniel Henrique Barboza riscv_cpu_disable_priv_spec_isa_exts(cpu); 1319b55d7d34SAlistair Francis } 1320b55d7d34SAlistair Francis 13216f23aaebSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 13226f23aaebSAlexandre Ghiti static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp) 13236f23aaebSAlexandre Ghiti { 13246f23aaebSAlexandre Ghiti bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32; 13256df3747aSAlexandre Ghiti uint8_t satp_mode_map_max; 13266df3747aSAlexandre Ghiti uint8_t satp_mode_supported_max = 13276df3747aSAlexandre Ghiti satp_mode_max_from_map(cpu->cfg.satp_mode.supported); 13286f23aaebSAlexandre Ghiti 13296f23aaebSAlexandre Ghiti if (cpu->cfg.satp_mode.map == 0) { 13306f23aaebSAlexandre Ghiti if (cpu->cfg.satp_mode.init == 0) { 13316f23aaebSAlexandre Ghiti /* If unset by the user, we fallback to the default satp mode. */ 13326f23aaebSAlexandre Ghiti set_satp_mode_default_map(cpu); 13336f23aaebSAlexandre Ghiti } else { 13346f23aaebSAlexandre Ghiti /* 13356f23aaebSAlexandre Ghiti * Find the lowest level that was disabled and then enable the 13366f23aaebSAlexandre Ghiti * first valid level below which can be found in 13376f23aaebSAlexandre Ghiti * valid_vm_1_10_32/64. 13386f23aaebSAlexandre Ghiti */ 13396f23aaebSAlexandre Ghiti for (int i = 1; i < 16; ++i) { 13406df3747aSAlexandre Ghiti if ((cpu->cfg.satp_mode.init & (1 << i)) && 13416df3747aSAlexandre Ghiti (cpu->cfg.satp_mode.supported & (1 << i))) { 13426f23aaebSAlexandre Ghiti for (int j = i - 1; j >= 0; --j) { 13436df3747aSAlexandre Ghiti if (cpu->cfg.satp_mode.supported & (1 << j)) { 13446f23aaebSAlexandre Ghiti cpu->cfg.satp_mode.map |= (1 << j); 13456f23aaebSAlexandre Ghiti break; 13466f23aaebSAlexandre Ghiti } 13476f23aaebSAlexandre Ghiti } 13486f23aaebSAlexandre Ghiti break; 13496f23aaebSAlexandre Ghiti } 13506f23aaebSAlexandre Ghiti } 13516f23aaebSAlexandre Ghiti } 13526f23aaebSAlexandre Ghiti } 13536f23aaebSAlexandre Ghiti 13546df3747aSAlexandre Ghiti satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map); 13556df3747aSAlexandre Ghiti 13566df3747aSAlexandre Ghiti /* Make sure the user asked for a supported configuration (HW and qemu) */ 13576df3747aSAlexandre Ghiti if (satp_mode_map_max > satp_mode_supported_max) { 13586df3747aSAlexandre Ghiti error_setg(errp, "satp_mode %s is higher than hw max capability %s", 13596df3747aSAlexandre Ghiti satp_mode_str(satp_mode_map_max, rv32), 13606df3747aSAlexandre Ghiti satp_mode_str(satp_mode_supported_max, rv32)); 13616f23aaebSAlexandre Ghiti return; 13626f23aaebSAlexandre Ghiti } 13636f23aaebSAlexandre Ghiti 13646f23aaebSAlexandre Ghiti /* 13656f23aaebSAlexandre Ghiti * Make sure the user did not ask for an invalid configuration as per 13666f23aaebSAlexandre Ghiti * the specification. 13676f23aaebSAlexandre Ghiti */ 13686f23aaebSAlexandre Ghiti if (!rv32) { 13696df3747aSAlexandre Ghiti for (int i = satp_mode_map_max - 1; i >= 0; --i) { 13706f23aaebSAlexandre Ghiti if (!(cpu->cfg.satp_mode.map & (1 << i)) && 13716f23aaebSAlexandre Ghiti (cpu->cfg.satp_mode.init & (1 << i)) && 13726df3747aSAlexandre Ghiti (cpu->cfg.satp_mode.supported & (1 << i))) { 13736f23aaebSAlexandre Ghiti error_setg(errp, "cannot disable %s satp mode if %s " 13746f23aaebSAlexandre Ghiti "is enabled", satp_mode_str(i, false), 13756df3747aSAlexandre Ghiti satp_mode_str(satp_mode_map_max, false)); 13766f23aaebSAlexandre Ghiti return; 13776f23aaebSAlexandre Ghiti } 13786f23aaebSAlexandre Ghiti } 13796f23aaebSAlexandre Ghiti } 13806f23aaebSAlexandre Ghiti 13816f23aaebSAlexandre Ghiti /* Finally expand the map so that all valid modes are set */ 13826df3747aSAlexandre Ghiti for (int i = satp_mode_map_max - 1; i >= 0; --i) { 13836df3747aSAlexandre Ghiti if (cpu->cfg.satp_mode.supported & (1 << i)) { 13846f23aaebSAlexandre Ghiti cpu->cfg.satp_mode.map |= (1 << i); 13856f23aaebSAlexandre Ghiti } 13866f23aaebSAlexandre Ghiti } 13876f23aaebSAlexandre Ghiti } 13886f23aaebSAlexandre Ghiti #endif 13896f23aaebSAlexandre Ghiti 13906f23aaebSAlexandre Ghiti static void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp) 13916f23aaebSAlexandre Ghiti { 13926f23aaebSAlexandre Ghiti #ifndef CONFIG_USER_ONLY 13936f23aaebSAlexandre Ghiti Error *local_err = NULL; 13946f23aaebSAlexandre Ghiti 13956f23aaebSAlexandre Ghiti riscv_cpu_satp_mode_finalize(cpu, &local_err); 13966f23aaebSAlexandre Ghiti if (local_err != NULL) { 13976f23aaebSAlexandre Ghiti error_propagate(errp, local_err); 13986f23aaebSAlexandre Ghiti return; 13996f23aaebSAlexandre Ghiti } 14006f23aaebSAlexandre Ghiti #endif 14016f23aaebSAlexandre Ghiti } 14026f23aaebSAlexandre Ghiti 14036508272aSDaniel Henrique Barboza static void riscv_cpu_validate_misa_priv(CPURISCVState *env, Error **errp) 14046508272aSDaniel Henrique Barboza { 14056508272aSDaniel Henrique Barboza if (riscv_has_ext(env, RVH) && env->priv_ver < PRIV_VERSION_1_12_0) { 14066508272aSDaniel Henrique Barboza error_setg(errp, "H extension requires priv spec 1.12.0"); 14076508272aSDaniel Henrique Barboza return; 14086508272aSDaniel Henrique Barboza } 14096508272aSDaniel Henrique Barboza } 14106508272aSDaniel Henrique Barboza 1411eddabb6bSDaniel Henrique Barboza static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp) 14125ab10952SDaniel Henrique Barboza { 14135ab10952SDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(dev); 14145ab10952SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 14155ab10952SDaniel Henrique Barboza Error *local_err = NULL; 14165ab10952SDaniel Henrique Barboza 1417782ee711SDaniel Henrique Barboza if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) { 1418782ee711SDaniel Henrique Barboza error_setg(errp, "'host' CPU is not compatible with TCG acceleration"); 1419782ee711SDaniel Henrique Barboza return; 1420782ee711SDaniel Henrique Barboza } 1421782ee711SDaniel Henrique Barboza 1422f5664064SDaniel Henrique Barboza riscv_cpu_validate_misa_mxl(cpu, &local_err); 1423f5664064SDaniel Henrique Barboza if (local_err != NULL) { 1424f5664064SDaniel Henrique Barboza error_propagate(errp, local_err); 1425f5664064SDaniel Henrique Barboza return; 1426f5664064SDaniel Henrique Barboza } 1427f5664064SDaniel Henrique Barboza 1428bd305595SDaniel Henrique Barboza riscv_cpu_validate_priv_spec(cpu, &local_err); 1429bd305595SDaniel Henrique Barboza if (local_err != NULL) { 1430bd305595SDaniel Henrique Barboza error_propagate(errp, local_err); 14315ab10952SDaniel Henrique Barboza return; 14325ab10952SDaniel Henrique Barboza } 14335ab10952SDaniel Henrique Barboza 14346508272aSDaniel Henrique Barboza riscv_cpu_validate_misa_priv(env, &local_err); 14356508272aSDaniel Henrique Barboza if (local_err != NULL) { 14366508272aSDaniel Henrique Barboza error_propagate(errp, local_err); 14376508272aSDaniel Henrique Barboza return; 14386508272aSDaniel Henrique Barboza } 14396508272aSDaniel Henrique Barboza 14406a3ffda2SDaniel Henrique Barboza if (cpu->cfg.epmp && !cpu->cfg.pmp) { 14415ab10952SDaniel Henrique Barboza /* 14425ab10952SDaniel Henrique Barboza * Enhanced PMP should only be available 14435ab10952SDaniel Henrique Barboza * on harts with PMP support 14445ab10952SDaniel Henrique Barboza */ 144509631441SDaniel Henrique Barboza error_setg(errp, "Invalid configuration: EPMP requires PMP support"); 144609631441SDaniel Henrique Barboza return; 14475ab10952SDaniel Henrique Barboza } 14485ab10952SDaniel Henrique Barboza 14495ab10952SDaniel Henrique Barboza riscv_cpu_validate_set_extensions(cpu, &local_err); 14505ab10952SDaniel Henrique Barboza if (local_err != NULL) { 14515ab10952SDaniel Henrique Barboza error_propagate(errp, local_err); 14525ab10952SDaniel Henrique Barboza return; 14535ab10952SDaniel Henrique Barboza } 14545ab10952SDaniel Henrique Barboza 145514664483SAtish Patra #ifndef CONFIG_USER_ONLY 1456eddabb6bSDaniel Henrique Barboza CPU(dev)->tcg_cflags |= CF_PCREL; 1457356c13f9SWeiwei Li 1458e2fa85f4SDaniel Henrique Barboza if (cpu->cfg.ext_sstc) { 1459e2fa85f4SDaniel Henrique Barboza riscv_timer_init(cpu); 1460e2fa85f4SDaniel Henrique Barboza } 1461e2fa85f4SDaniel Henrique Barboza 146214664483SAtish Patra if (cpu->cfg.pmu_num) { 146314664483SAtish Patra if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) { 146414664483SAtish Patra cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 146514664483SAtish Patra riscv_pmu_timer_cb, cpu); 146614664483SAtish Patra } 146714664483SAtish Patra } 146814664483SAtish Patra #endif 1469eddabb6bSDaniel Henrique Barboza } 1470eddabb6bSDaniel Henrique Barboza 1471eddabb6bSDaniel Henrique Barboza static void riscv_cpu_realize(DeviceState *dev, Error **errp) 1472eddabb6bSDaniel Henrique Barboza { 1473eddabb6bSDaniel Henrique Barboza CPUState *cs = CPU(dev); 1474eddabb6bSDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(dev); 1475eddabb6bSDaniel Henrique Barboza RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); 1476eddabb6bSDaniel Henrique Barboza Error *local_err = NULL; 1477eddabb6bSDaniel Henrique Barboza 1478eddabb6bSDaniel Henrique Barboza cpu_exec_realizefn(cs, &local_err); 1479eddabb6bSDaniel Henrique Barboza if (local_err != NULL) { 1480eddabb6bSDaniel Henrique Barboza error_propagate(errp, local_err); 1481eddabb6bSDaniel Henrique Barboza return; 1482eddabb6bSDaniel Henrique Barboza } 1483eddabb6bSDaniel Henrique Barboza 1484eddabb6bSDaniel Henrique Barboza if (tcg_enabled()) { 1485eddabb6bSDaniel Henrique Barboza riscv_cpu_realize_tcg(dev, &local_err); 1486eddabb6bSDaniel Henrique Barboza if (local_err != NULL) { 1487eddabb6bSDaniel Henrique Barboza error_propagate(errp, local_err); 1488eddabb6bSDaniel Henrique Barboza return; 1489eddabb6bSDaniel Henrique Barboza } 1490eddabb6bSDaniel Henrique Barboza } 149114664483SAtish Patra 14926f23aaebSAlexandre Ghiti riscv_cpu_finalize_features(cpu, &local_err); 14936f23aaebSAlexandre Ghiti if (local_err != NULL) { 14946f23aaebSAlexandre Ghiti error_propagate(errp, local_err); 14956f23aaebSAlexandre Ghiti return; 14966f23aaebSAlexandre Ghiti } 14976f23aaebSAlexandre Ghiti 14985371f5cdSJim Wilson riscv_cpu_register_gdb_regs_for_features(cs); 14995371f5cdSJim Wilson 1500dc5bd18fSMichael Clark qemu_init_vcpu(cs); 1501dc5bd18fSMichael Clark cpu_reset(cs); 1502dc5bd18fSMichael Clark 1503dc5bd18fSMichael Clark mcc->parent_realize(dev, errp); 1504dc5bd18fSMichael Clark } 1505dc5bd18fSMichael Clark 15060f0b70eeSAlistair Francis #ifndef CONFIG_USER_ONLY 15076f23aaebSAlexandre Ghiti static void cpu_riscv_get_satp(Object *obj, Visitor *v, const char *name, 15086f23aaebSAlexandre Ghiti void *opaque, Error **errp) 15096f23aaebSAlexandre Ghiti { 15106f23aaebSAlexandre Ghiti RISCVSATPMap *satp_map = opaque; 15116f23aaebSAlexandre Ghiti uint8_t satp = satp_mode_from_str(name); 15126f23aaebSAlexandre Ghiti bool value; 15136f23aaebSAlexandre Ghiti 15146f23aaebSAlexandre Ghiti value = satp_map->map & (1 << satp); 15156f23aaebSAlexandre Ghiti 15166f23aaebSAlexandre Ghiti visit_type_bool(v, name, &value, errp); 15176f23aaebSAlexandre Ghiti } 15186f23aaebSAlexandre Ghiti 15196f23aaebSAlexandre Ghiti static void cpu_riscv_set_satp(Object *obj, Visitor *v, const char *name, 15206f23aaebSAlexandre Ghiti void *opaque, Error **errp) 15216f23aaebSAlexandre Ghiti { 15226f23aaebSAlexandre Ghiti RISCVSATPMap *satp_map = opaque; 15236f23aaebSAlexandre Ghiti uint8_t satp = satp_mode_from_str(name); 15246f23aaebSAlexandre Ghiti bool value; 15256f23aaebSAlexandre Ghiti 15266f23aaebSAlexandre Ghiti if (!visit_type_bool(v, name, &value, errp)) { 15276f23aaebSAlexandre Ghiti return; 15286f23aaebSAlexandre Ghiti } 15296f23aaebSAlexandre Ghiti 15306f23aaebSAlexandre Ghiti satp_map->map = deposit32(satp_map->map, satp, 1, value); 15316f23aaebSAlexandre Ghiti satp_map->init |= 1 << satp; 15326f23aaebSAlexandre Ghiti } 15336f23aaebSAlexandre Ghiti 15346f23aaebSAlexandre Ghiti static void riscv_add_satp_mode_properties(Object *obj) 15356f23aaebSAlexandre Ghiti { 15366f23aaebSAlexandre Ghiti RISCVCPU *cpu = RISCV_CPU(obj); 15376f23aaebSAlexandre Ghiti 15386f23aaebSAlexandre Ghiti if (cpu->env.misa_mxl == MXL_RV32) { 15396f23aaebSAlexandre Ghiti object_property_add(obj, "sv32", "bool", cpu_riscv_get_satp, 15406f23aaebSAlexandre Ghiti cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode); 15416f23aaebSAlexandre Ghiti } else { 15426f23aaebSAlexandre Ghiti object_property_add(obj, "sv39", "bool", cpu_riscv_get_satp, 15436f23aaebSAlexandre Ghiti cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode); 15446f23aaebSAlexandre Ghiti object_property_add(obj, "sv48", "bool", cpu_riscv_get_satp, 15456f23aaebSAlexandre Ghiti cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode); 15466f23aaebSAlexandre Ghiti object_property_add(obj, "sv57", "bool", cpu_riscv_get_satp, 15476f23aaebSAlexandre Ghiti cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode); 15486f23aaebSAlexandre Ghiti object_property_add(obj, "sv64", "bool", cpu_riscv_get_satp, 15496f23aaebSAlexandre Ghiti cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode); 15506f23aaebSAlexandre Ghiti } 15516f23aaebSAlexandre Ghiti } 15526f23aaebSAlexandre Ghiti 15530f0b70eeSAlistair Francis static void riscv_cpu_set_irq(void *opaque, int irq, int level) 15540f0b70eeSAlistair Francis { 15550f0b70eeSAlistair Francis RISCVCPU *cpu = RISCV_CPU(opaque); 1556cd032fe7SAnup Patel CPURISCVState *env = &cpu->env; 15570f0b70eeSAlistair Francis 1558cd032fe7SAnup Patel if (irq < IRQ_LOCAL_MAX) { 15590f0b70eeSAlistair Francis switch (irq) { 15600f0b70eeSAlistair Francis case IRQ_U_SOFT: 15610f0b70eeSAlistair Francis case IRQ_S_SOFT: 15620f0b70eeSAlistair Francis case IRQ_VS_SOFT: 15630f0b70eeSAlistair Francis case IRQ_M_SOFT: 15640f0b70eeSAlistair Francis case IRQ_U_TIMER: 15650f0b70eeSAlistair Francis case IRQ_S_TIMER: 15660f0b70eeSAlistair Francis case IRQ_VS_TIMER: 15670f0b70eeSAlistair Francis case IRQ_M_TIMER: 15680f0b70eeSAlistair Francis case IRQ_U_EXT: 15690f0b70eeSAlistair Francis case IRQ_VS_EXT: 15700f0b70eeSAlistair Francis case IRQ_M_EXT: 15712b650fbbSYifei Jiang if (kvm_enabled()) { 15722b650fbbSYifei Jiang kvm_riscv_set_irq(cpu, irq, level); 15732b650fbbSYifei Jiang } else { 1574bbb9fc25SWeiwei Li riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level)); 15752b650fbbSYifei Jiang } 15760f0b70eeSAlistair Francis break; 157733fe584fSAlistair Francis case IRQ_S_EXT: 157833fe584fSAlistair Francis if (kvm_enabled()) { 157933fe584fSAlistair Francis kvm_riscv_set_irq(cpu, irq, level); 158033fe584fSAlistair Francis } else { 158133fe584fSAlistair Francis env->external_seip = level; 1582bbb9fc25SWeiwei Li riscv_cpu_update_mip(env, 1 << irq, 158333fe584fSAlistair Francis BOOL_TO_MASK(level | env->software_seip)); 158433fe584fSAlistair Francis } 158533fe584fSAlistair Francis break; 15860f0b70eeSAlistair Francis default: 15870f0b70eeSAlistair Francis g_assert_not_reached(); 15880f0b70eeSAlistair Francis } 1589cd032fe7SAnup Patel } else if (irq < (IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX)) { 1590cd032fe7SAnup Patel /* Require H-extension for handling guest local interrupts */ 1591cd032fe7SAnup Patel if (!riscv_has_ext(env, RVH)) { 1592cd032fe7SAnup Patel g_assert_not_reached(); 1593cd032fe7SAnup Patel } 1594cd032fe7SAnup Patel 1595cd032fe7SAnup Patel /* Compute bit position in HGEIP CSR */ 1596cd032fe7SAnup Patel irq = irq - IRQ_LOCAL_MAX + 1; 1597cd032fe7SAnup Patel if (env->geilen < irq) { 1598cd032fe7SAnup Patel g_assert_not_reached(); 1599cd032fe7SAnup Patel } 1600cd032fe7SAnup Patel 1601cd032fe7SAnup Patel /* Update HGEIP CSR */ 1602cd032fe7SAnup Patel env->hgeip &= ~((target_ulong)1 << irq); 1603cd032fe7SAnup Patel if (level) { 1604cd032fe7SAnup Patel env->hgeip |= (target_ulong)1 << irq; 1605cd032fe7SAnup Patel } 1606cd032fe7SAnup Patel 1607cd032fe7SAnup Patel /* Update mip.SGEIP bit */ 1608bbb9fc25SWeiwei Li riscv_cpu_update_mip(env, MIP_SGEIP, 1609cd032fe7SAnup Patel BOOL_TO_MASK(!!(env->hgeie & env->hgeip))); 1610cd032fe7SAnup Patel } else { 1611cd032fe7SAnup Patel g_assert_not_reached(); 1612cd032fe7SAnup Patel } 16130f0b70eeSAlistair Francis } 16140f0b70eeSAlistair Francis #endif /* CONFIG_USER_ONLY */ 16150f0b70eeSAlistair Francis 1616dc5bd18fSMichael Clark static void riscv_cpu_init(Object *obj) 1617dc5bd18fSMichael Clark { 1618dc5bd18fSMichael Clark RISCVCPU *cpu = RISCV_CPU(obj); 1619dc5bd18fSMichael Clark 16207506ed90SRichard Henderson cpu_set_cpustate_pointers(cpu); 16210f0b70eeSAlistair Francis 16220f0b70eeSAlistair Francis #ifndef CONFIG_USER_ONLY 1623cd032fe7SAnup Patel qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, 1624cd032fe7SAnup Patel IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); 16250f0b70eeSAlistair Francis #endif /* CONFIG_USER_ONLY */ 1626dc5bd18fSMichael Clark } 1627dc5bd18fSMichael Clark 1628b3df64c8SDaniel Henrique Barboza typedef struct RISCVCPUMisaExtConfig { 1629b3df64c8SDaniel Henrique Barboza const char *name; 1630b3df64c8SDaniel Henrique Barboza const char *description; 1631b3df64c8SDaniel Henrique Barboza target_ulong misa_bit; 1632b3df64c8SDaniel Henrique Barboza bool enabled; 1633b3df64c8SDaniel Henrique Barboza } RISCVCPUMisaExtConfig; 1634b3df64c8SDaniel Henrique Barboza 1635b3df64c8SDaniel Henrique Barboza static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name, 1636b3df64c8SDaniel Henrique Barboza void *opaque, Error **errp) 1637b3df64c8SDaniel Henrique Barboza { 1638b3df64c8SDaniel Henrique Barboza const RISCVCPUMisaExtConfig *misa_ext_cfg = opaque; 1639b3df64c8SDaniel Henrique Barboza target_ulong misa_bit = misa_ext_cfg->misa_bit; 1640b3df64c8SDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(obj); 1641b3df64c8SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 1642b3df64c8SDaniel Henrique Barboza bool value; 1643b3df64c8SDaniel Henrique Barboza 1644b3df64c8SDaniel Henrique Barboza if (!visit_type_bool(v, name, &value, errp)) { 1645b3df64c8SDaniel Henrique Barboza return; 1646b3df64c8SDaniel Henrique Barboza } 1647b3df64c8SDaniel Henrique Barboza 1648b3df64c8SDaniel Henrique Barboza if (value) { 1649b3df64c8SDaniel Henrique Barboza env->misa_ext |= misa_bit; 1650b3df64c8SDaniel Henrique Barboza env->misa_ext_mask |= misa_bit; 1651b3df64c8SDaniel Henrique Barboza } else { 1652b3df64c8SDaniel Henrique Barboza env->misa_ext &= ~misa_bit; 1653b3df64c8SDaniel Henrique Barboza env->misa_ext_mask &= ~misa_bit; 1654b3df64c8SDaniel Henrique Barboza } 1655b3df64c8SDaniel Henrique Barboza } 1656b3df64c8SDaniel Henrique Barboza 1657b3df64c8SDaniel Henrique Barboza static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name, 1658b3df64c8SDaniel Henrique Barboza void *opaque, Error **errp) 1659b3df64c8SDaniel Henrique Barboza { 1660b3df64c8SDaniel Henrique Barboza const RISCVCPUMisaExtConfig *misa_ext_cfg = opaque; 1661b3df64c8SDaniel Henrique Barboza target_ulong misa_bit = misa_ext_cfg->misa_bit; 1662b3df64c8SDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(obj); 1663b3df64c8SDaniel Henrique Barboza CPURISCVState *env = &cpu->env; 1664b3df64c8SDaniel Henrique Barboza bool value; 1665b3df64c8SDaniel Henrique Barboza 1666b3df64c8SDaniel Henrique Barboza value = env->misa_ext & misa_bit; 1667b3df64c8SDaniel Henrique Barboza 1668b3df64c8SDaniel Henrique Barboza visit_type_bool(v, name, &value, errp); 1669b3df64c8SDaniel Henrique Barboza } 1670b3df64c8SDaniel Henrique Barboza 1671ed7e6182SDaniel Henrique Barboza typedef struct misa_ext_info { 1672ed7e6182SDaniel Henrique Barboza const char *name; 1673ed7e6182SDaniel Henrique Barboza const char *description; 1674ed7e6182SDaniel Henrique Barboza } MISAExtInfo; 1675ed7e6182SDaniel Henrique Barboza 1676ed7e6182SDaniel Henrique Barboza #define MISA_INFO_IDX(_bit) \ 1677ed7e6182SDaniel Henrique Barboza __builtin_ctz(_bit) 1678ed7e6182SDaniel Henrique Barboza 1679ed7e6182SDaniel Henrique Barboza #define MISA_EXT_INFO(_bit, _propname, _descr) \ 1680ed7e6182SDaniel Henrique Barboza [MISA_INFO_IDX(_bit)] = {.name = _propname, .description = _descr} 1681ed7e6182SDaniel Henrique Barboza 1682ed7e6182SDaniel Henrique Barboza static const MISAExtInfo misa_ext_info_arr[] = { 1683ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVA, "a", "Atomic instructions"), 1684ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVC, "c", "Compressed instructions"), 1685ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVD, "d", "Double-precision float point"), 1686ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVF, "f", "Single-precision float point"), 1687ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVI, "i", "Base integer instruction set"), 1688ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVE, "e", "Base integer instruction set (embedded)"), 1689ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVM, "m", "Integer multiplication and division"), 1690ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"), 1691ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVU, "u", "User-level instructions"), 1692ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVH, "h", "Hypervisor"), 1693ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"), 1694ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVV, "v", "Vector operations"), 1695ed7e6182SDaniel Henrique Barboza MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), 1696ed7e6182SDaniel Henrique Barboza }; 1697ed7e6182SDaniel Henrique Barboza 1698ed7e6182SDaniel Henrique Barboza static int riscv_validate_misa_info_idx(uint32_t bit) 1699ed7e6182SDaniel Henrique Barboza { 1700ed7e6182SDaniel Henrique Barboza int idx; 1701ed7e6182SDaniel Henrique Barboza 1702ed7e6182SDaniel Henrique Barboza /* 1703ed7e6182SDaniel Henrique Barboza * Our lowest valid input (RVA) is 1 and 1704ed7e6182SDaniel Henrique Barboza * __builtin_ctz() is UB with zero. 1705ed7e6182SDaniel Henrique Barboza */ 1706ed7e6182SDaniel Henrique Barboza g_assert(bit != 0); 1707ed7e6182SDaniel Henrique Barboza idx = MISA_INFO_IDX(bit); 1708ed7e6182SDaniel Henrique Barboza 1709ed7e6182SDaniel Henrique Barboza g_assert(idx < ARRAY_SIZE(misa_ext_info_arr)); 1710ed7e6182SDaniel Henrique Barboza return idx; 1711ed7e6182SDaniel Henrique Barboza } 1712ed7e6182SDaniel Henrique Barboza 1713ed7e6182SDaniel Henrique Barboza const char *riscv_get_misa_ext_name(uint32_t bit) 1714ed7e6182SDaniel Henrique Barboza { 1715ed7e6182SDaniel Henrique Barboza int idx = riscv_validate_misa_info_idx(bit); 1716ed7e6182SDaniel Henrique Barboza const char *val = misa_ext_info_arr[idx].name; 1717ed7e6182SDaniel Henrique Barboza 1718ed7e6182SDaniel Henrique Barboza g_assert(val != NULL); 1719ed7e6182SDaniel Henrique Barboza return val; 1720ed7e6182SDaniel Henrique Barboza } 1721ed7e6182SDaniel Henrique Barboza 1722ed7e6182SDaniel Henrique Barboza const char *riscv_get_misa_ext_description(uint32_t bit) 1723ed7e6182SDaniel Henrique Barboza { 1724ed7e6182SDaniel Henrique Barboza int idx = riscv_validate_misa_info_idx(bit); 1725ed7e6182SDaniel Henrique Barboza const char *val = misa_ext_info_arr[idx].description; 1726ed7e6182SDaniel Henrique Barboza 1727ed7e6182SDaniel Henrique Barboza g_assert(val != NULL); 1728ed7e6182SDaniel Henrique Barboza return val; 1729ed7e6182SDaniel Henrique Barboza } 1730ed7e6182SDaniel Henrique Barboza 1731ed7e6182SDaniel Henrique Barboza #define MISA_CFG(_bit, _enabled) \ 1732ed7e6182SDaniel Henrique Barboza {.misa_bit = _bit, .enabled = _enabled} 1733ed7e6182SDaniel Henrique Barboza 1734ed7e6182SDaniel Henrique Barboza static RISCVCPUMisaExtConfig misa_ext_cfgs[] = { 1735ed7e6182SDaniel Henrique Barboza MISA_CFG(RVA, true), 1736ed7e6182SDaniel Henrique Barboza MISA_CFG(RVC, true), 1737ed7e6182SDaniel Henrique Barboza MISA_CFG(RVD, true), 1738ed7e6182SDaniel Henrique Barboza MISA_CFG(RVF, true), 1739ed7e6182SDaniel Henrique Barboza MISA_CFG(RVI, true), 1740ed7e6182SDaniel Henrique Barboza MISA_CFG(RVE, false), 1741ed7e6182SDaniel Henrique Barboza MISA_CFG(RVM, true), 1742ed7e6182SDaniel Henrique Barboza MISA_CFG(RVS, true), 1743ed7e6182SDaniel Henrique Barboza MISA_CFG(RVU, true), 1744ed7e6182SDaniel Henrique Barboza MISA_CFG(RVH, true), 1745ed7e6182SDaniel Henrique Barboza MISA_CFG(RVJ, false), 1746ed7e6182SDaniel Henrique Barboza MISA_CFG(RVV, false), 1747ed7e6182SDaniel Henrique Barboza MISA_CFG(RVG, false), 17484c759943SDaniel Henrique Barboza }; 1749b3df64c8SDaniel Henrique Barboza 1750b3df64c8SDaniel Henrique Barboza static void riscv_cpu_add_misa_properties(Object *cpu_obj) 1751b3df64c8SDaniel Henrique Barboza { 1752b3df64c8SDaniel Henrique Barboza int i; 1753b3df64c8SDaniel Henrique Barboza 1754b3df64c8SDaniel Henrique Barboza for (i = 0; i < ARRAY_SIZE(misa_ext_cfgs); i++) { 1755ed7e6182SDaniel Henrique Barboza RISCVCPUMisaExtConfig *misa_cfg = &misa_ext_cfgs[i]; 1756ed7e6182SDaniel Henrique Barboza int bit = misa_cfg->misa_bit; 1757ed7e6182SDaniel Henrique Barboza 1758ed7e6182SDaniel Henrique Barboza misa_cfg->name = riscv_get_misa_ext_name(bit); 1759ed7e6182SDaniel Henrique Barboza misa_cfg->description = riscv_get_misa_ext_description(bit); 1760b3df64c8SDaniel Henrique Barboza 176192becce5SDaniel Henrique Barboza /* Check if KVM already created the property */ 176292becce5SDaniel Henrique Barboza if (object_property_find(cpu_obj, misa_cfg->name)) { 176392becce5SDaniel Henrique Barboza continue; 176492becce5SDaniel Henrique Barboza } 176592becce5SDaniel Henrique Barboza 1766b3df64c8SDaniel Henrique Barboza object_property_add(cpu_obj, misa_cfg->name, "bool", 1767b3df64c8SDaniel Henrique Barboza cpu_get_misa_ext_cfg, 1768b3df64c8SDaniel Henrique Barboza cpu_set_misa_ext_cfg, 1769b3df64c8SDaniel Henrique Barboza NULL, (void *)misa_cfg); 1770b3df64c8SDaniel Henrique Barboza object_property_set_description(cpu_obj, misa_cfg->name, 1771b3df64c8SDaniel Henrique Barboza misa_cfg->description); 1772b3df64c8SDaniel Henrique Barboza object_property_set_bool(cpu_obj, misa_cfg->name, 1773b3df64c8SDaniel Henrique Barboza misa_cfg->enabled, NULL); 1774b3df64c8SDaniel Henrique Barboza } 1775b3df64c8SDaniel Henrique Barboza } 1776b3df64c8SDaniel Henrique Barboza 177726b2bc58SAlistair Francis static Property riscv_cpu_extensions[] = { 17789d3d60b7SAlistair Francis /* Defaults for standard extensions */ 177918d6d89eSAtish Patra DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16), 178014664483SAtish Patra DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false), 17819d3d60b7SAlistair Francis DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), 17829d3d60b7SAlistair Francis DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), 17834696f0abSDao Lu DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true), 1784260b594dSChristoph Muellner DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true), 1785a47842d1SChristoph Müllner DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true), 178613fb8c7bSFrank Chang DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false), 1787e5237730SFrank Chang DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false), 17882fc1b44dSFrank Chang DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false), 1789bfefe406SFrank Chang DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false), 1790058d9d30SWeiwei Li DEFINE_PROP_BOOL("Zve64d", RISCVCPU, cfg.ext_zve64d, false), 17919d3d60b7SAlistair Francis DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true), 17929d3d60b7SAlistair Francis DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true), 179343888c2fSAtish Patra DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true), 17949d3d60b7SAlistair Francis 17959d3d60b7SAlistair Francis DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec), 17969ec6622dSFrank Chang DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), 17979ec6622dSFrank Chang DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), 17989ec6622dSFrank Chang DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), 17999d3d60b7SAlistair Francis 18003594e3e5SMayuresh Chitale DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false), 180162108f05SWeiwei Li DEFINE_PROP_BOOL("svadu", RISCVCPU, cfg.ext_svadu, true), 1802c5d77dddSWeiwei Li DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false), 18032bacb224SWeiwei Li DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false), 1804bbce8ba8SWeiwei Li DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false), 18052bacb224SWeiwei Li 18060643c12eSVineet Gupta DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true), 18070643c12eSVineet Gupta DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true), 18080643c12eSVineet Gupta DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true), 1809cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zbkb", RISCVCPU, cfg.ext_zbkb, false), 1810cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zbkc", RISCVCPU, cfg.ext_zbkc, false), 1811cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zbkx", RISCVCPU, cfg.ext_zbkx, false), 18120643c12eSVineet Gupta DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true), 1813cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zk", RISCVCPU, cfg.ext_zk, false), 1814cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zkn", RISCVCPU, cfg.ext_zkn, false), 1815cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zknd", RISCVCPU, cfg.ext_zknd, false), 1816cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zkne", RISCVCPU, cfg.ext_zkne, false), 1817cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zknh", RISCVCPU, cfg.ext_zknh, false), 1818cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zkr", RISCVCPU, cfg.ext_zkr, false), 1819cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zks", RISCVCPU, cfg.ext_zks, false), 1820cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zksed", RISCVCPU, cfg.ext_zksed, false), 1821cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zksh", RISCVCPU, cfg.ext_zksh, false), 1822cf7ed971SWeiwei Li DEFINE_PROP_BOOL("zkt", RISCVCPU, cfg.ext_zkt, false), 1823dfdb46a3SPhilipp Tomsich 18246b1accefSWeiwei Li DEFINE_PROP_BOOL("zdinx", RISCVCPU, cfg.ext_zdinx, false), 18256b1accefSWeiwei Li DEFINE_PROP_BOOL("zfinx", RISCVCPU, cfg.ext_zfinx, false), 18266b1accefSWeiwei Li DEFINE_PROP_BOOL("zhinx", RISCVCPU, cfg.ext_zhinx, false), 18276b1accefSWeiwei Li DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false), 18286b1accefSWeiwei Li 1829e05da09bSChristoph Muellner DEFINE_PROP_BOOL("zicbom", RISCVCPU, cfg.ext_icbom, true), 1830e05da09bSChristoph Muellner DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64), 1831a939c500SChristoph Muellner DEFINE_PROP_BOOL("zicboz", RISCVCPU, cfg.ext_icboz, true), 1832a939c500SChristoph Muellner DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64), 1833a939c500SChristoph Muellner 18346d00ffadSWeiwei Li DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false), 18356d00ffadSWeiwei Li 18366672e29dSWeiwei Li DEFINE_PROP_BOOL("zca", RISCVCPU, cfg.ext_zca, false), 18376672e29dSWeiwei Li DEFINE_PROP_BOOL("zcb", RISCVCPU, cfg.ext_zcb, false), 18386672e29dSWeiwei Li DEFINE_PROP_BOOL("zcd", RISCVCPU, cfg.ext_zcd, false), 18396672e29dSWeiwei Li DEFINE_PROP_BOOL("zce", RISCVCPU, cfg.ext_zce, false), 18406672e29dSWeiwei Li DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false), 18416672e29dSWeiwei Li DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false), 18426672e29dSWeiwei Li DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false), 18436672e29dSWeiwei Li 18440d429bd2SPhilipp Tomsich /* Vendor-specific custom extensions */ 1845c9410a68SChristoph Müllner DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false), 1846426c0491SChristoph Müllner DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false), 1847fa134585SChristoph Müllner DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false), 184849a7f3aaSChristoph Müllner DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false), 184932909338SChristoph Müllner DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false), 1850d4d90115SChristoph Müllner DEFINE_PROP_BOOL("xtheadfmemidx", RISCVCPU, cfg.ext_xtheadfmemidx, false), 1851578086baSChristoph Müllner DEFINE_PROP_BOOL("xtheadfmv", RISCVCPU, cfg.ext_xtheadfmv, false), 1852b8a5832bSChristoph Müllner DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false), 185345f9df86SChristoph Müllner DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false), 1854af99aa72SChristoph Müllner DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false), 1855134c3ffaSChristoph Müllner DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false), 18560d429bd2SPhilipp Tomsich DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false), 18570d429bd2SPhilipp Tomsich 1858dfdb46a3SPhilipp Tomsich /* These are experimental so mark with 'x-' */ 1859b8e1f32cSWeiwei Li DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false), 1860d364c0abSWeiwei Li 1861a44da25aSAlistair Francis /* ePMP 0.9.3 */ 18625da9514eSHou Weiying DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), 1863dc9acc9cSAnup Patel DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false), 1864dc9acc9cSAnup Patel DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false), 18655da9514eSHou Weiying 1866058d9d30SWeiwei Li DEFINE_PROP_BOOL("x-zvfh", RISCVCPU, cfg.ext_zvfh, false), 1867058d9d30SWeiwei Li DEFINE_PROP_BOOL("x-zvfhmin", RISCVCPU, cfg.ext_zvfhmin, false), 1868058d9d30SWeiwei Li 1869889caa44SWeiwei Li DEFINE_PROP_BOOL("x-zfbfmin", RISCVCPU, cfg.ext_zfbfmin, false), 1870889caa44SWeiwei Li DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false), 1871889caa44SWeiwei Li DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false), 1872889caa44SWeiwei Li 1873e13c7d3bSLawrence Hunter /* Vector cryptography extensions */ 1874*06028472SDickon Hood DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false), 1875e13c7d3bSLawrence Hunter DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false), 1876e13c7d3bSLawrence Hunter 187726b2bc58SAlistair Francis DEFINE_PROP_END_OF_LIST(), 187826b2bc58SAlistair Francis }; 187926b2bc58SAlistair Francis 188056f0e992SDaniel Henrique Barboza 188156f0e992SDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY 188256f0e992SDaniel Henrique Barboza static void cpu_set_cfg_unavailable(Object *obj, Visitor *v, 188356f0e992SDaniel Henrique Barboza const char *name, 188456f0e992SDaniel Henrique Barboza void *opaque, Error **errp) 188556f0e992SDaniel Henrique Barboza { 188656f0e992SDaniel Henrique Barboza const char *propname = opaque; 188756f0e992SDaniel Henrique Barboza bool value; 188856f0e992SDaniel Henrique Barboza 188956f0e992SDaniel Henrique Barboza if (!visit_type_bool(v, name, &value, errp)) { 189056f0e992SDaniel Henrique Barboza return; 189156f0e992SDaniel Henrique Barboza } 189256f0e992SDaniel Henrique Barboza 189356f0e992SDaniel Henrique Barboza if (value) { 189456f0e992SDaniel Henrique Barboza error_setg(errp, "extension %s is not available with KVM", 189556f0e992SDaniel Henrique Barboza propname); 189656f0e992SDaniel Henrique Barboza } 189756f0e992SDaniel Henrique Barboza } 189856f0e992SDaniel Henrique Barboza #endif 189956f0e992SDaniel Henrique Barboza 1900c66ffcd5SDaniel Henrique Barboza /* 1901dd8f244fSDaniel Henrique Barboza * Add CPU properties with user-facing flags. 1902dd8f244fSDaniel Henrique Barboza * 1903dd8f244fSDaniel Henrique Barboza * This will overwrite existing env->misa_ext values with the 1904dd8f244fSDaniel Henrique Barboza * defaults set via riscv_cpu_add_misa_properties(). 1905c66ffcd5SDaniel Henrique Barboza */ 1906dd8f244fSDaniel Henrique Barboza static void riscv_cpu_add_user_properties(Object *obj) 190726b2bc58SAlistair Francis { 190826b2bc58SAlistair Francis Property *prop; 1909c01756a7SAlexandre Ghiti DeviceState *dev = DEVICE(obj); 191026b2bc58SAlistair Francis 1911492265aeSDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY 1912b71f9dcaSDaniel Henrique Barboza riscv_add_satp_mode_properties(obj); 1913b71f9dcaSDaniel Henrique Barboza 1914492265aeSDaniel Henrique Barboza if (kvm_enabled()) { 1915492265aeSDaniel Henrique Barboza kvm_riscv_init_user_properties(obj); 1916492265aeSDaniel Henrique Barboza } 1917492265aeSDaniel Henrique Barboza #endif 1918492265aeSDaniel Henrique Barboza 1919b3df64c8SDaniel Henrique Barboza riscv_cpu_add_misa_properties(obj); 1920b3df64c8SDaniel Henrique Barboza 192126b2bc58SAlistair Francis for (prop = riscv_cpu_extensions; prop && prop->name; prop++) { 1922f7a69fa6SDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY 1923f7a69fa6SDaniel Henrique Barboza if (kvm_enabled()) { 1924f7a69fa6SDaniel Henrique Barboza /* Check if KVM created the property already */ 1925f7a69fa6SDaniel Henrique Barboza if (object_property_find(obj, prop->name)) { 1926f7a69fa6SDaniel Henrique Barboza continue; 1927f7a69fa6SDaniel Henrique Barboza } 192856f0e992SDaniel Henrique Barboza 192956f0e992SDaniel Henrique Barboza /* 193056f0e992SDaniel Henrique Barboza * Set the default to disabled for every extension 193156f0e992SDaniel Henrique Barboza * unknown to KVM and error out if the user attempts 193256f0e992SDaniel Henrique Barboza * to enable any of them. 193356f0e992SDaniel Henrique Barboza * 193456f0e992SDaniel Henrique Barboza * We're giving a pass for non-bool properties since they're 193556f0e992SDaniel Henrique Barboza * not related to the availability of extensions and can be 193656f0e992SDaniel Henrique Barboza * safely ignored as is. 193756f0e992SDaniel Henrique Barboza */ 193856f0e992SDaniel Henrique Barboza if (prop->info == &qdev_prop_bool) { 193956f0e992SDaniel Henrique Barboza object_property_add(obj, prop->name, "bool", 194056f0e992SDaniel Henrique Barboza NULL, cpu_set_cfg_unavailable, 194156f0e992SDaniel Henrique Barboza NULL, (void *)prop->name); 194256f0e992SDaniel Henrique Barboza continue; 194356f0e992SDaniel Henrique Barboza } 1944f7a69fa6SDaniel Henrique Barboza } 1945f7a69fa6SDaniel Henrique Barboza #endif 194626b2bc58SAlistair Francis qdev_property_add_static(dev, prop); 194726b2bc58SAlistair Francis } 194826b2bc58SAlistair Francis } 194926b2bc58SAlistair Francis 195026b2bc58SAlistair Francis static Property riscv_cpu_properties[] = { 195126b2bc58SAlistair Francis DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true), 195226b2bc58SAlistair Francis 1953277b210dSAlistair Francis #ifndef CONFIG_USER_ONLY 1954277b210dSAlistair Francis DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC), 1955277b210dSAlistair Francis #endif 1956a4a9a443STsukasa OI 1957a4a9a443STsukasa OI DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false), 1958b8312675SeopXD 1959b8312675SeopXD DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false), 19601ad3f9bdSeopXD DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false), 196154bd9b6eSDaniel Henrique Barboza 196254bd9b6eSDaniel Henrique Barboza /* 196354bd9b6eSDaniel Henrique Barboza * write_misa() is marked as experimental for now so mark 196454bd9b6eSDaniel Henrique Barboza * it with -x and default to 'false'. 196554bd9b6eSDaniel Henrique Barboza */ 196654bd9b6eSDaniel Henrique Barboza DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false), 1967c4e95030SAlistair Francis DEFINE_PROP_END_OF_LIST(), 1968c4e95030SAlistair Francis }; 1969c4e95030SAlistair Francis 1970edf64786SSylvain Pelissier static gchar *riscv_gdb_arch_name(CPUState *cs) 1971edf64786SSylvain Pelissier { 1972edf64786SSylvain Pelissier RISCVCPU *cpu = RISCV_CPU(cs); 1973edf64786SSylvain Pelissier CPURISCVState *env = &cpu->env; 1974edf64786SSylvain Pelissier 1975db23e5d9SRichard Henderson switch (riscv_cpu_mxl(env)) { 1976db23e5d9SRichard Henderson case MXL_RV32: 1977edf64786SSylvain Pelissier return g_strdup("riscv:rv32"); 1978db23e5d9SRichard Henderson case MXL_RV64: 1979332dab68SFrédéric Pétrot case MXL_RV128: 1980edf64786SSylvain Pelissier return g_strdup("riscv:rv64"); 1981db23e5d9SRichard Henderson default: 1982db23e5d9SRichard Henderson g_assert_not_reached(); 1983edf64786SSylvain Pelissier } 1984edf64786SSylvain Pelissier } 1985edf64786SSylvain Pelissier 1986b93777e1SBin Meng static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) 1987b93777e1SBin Meng { 1988b93777e1SBin Meng RISCVCPU *cpu = RISCV_CPU(cs); 1989b93777e1SBin Meng 1990b93777e1SBin Meng if (strcmp(xmlname, "riscv-csr.xml") == 0) { 1991b93777e1SBin Meng return cpu->dyn_csr_xml; 1992719d3561SHsiangkai Wang } else if (strcmp(xmlname, "riscv-vector.xml") == 0) { 1993719d3561SHsiangkai Wang return cpu->dyn_vreg_xml; 1994b93777e1SBin Meng } 1995b93777e1SBin Meng 1996b93777e1SBin Meng return NULL; 1997b93777e1SBin Meng } 1998b93777e1SBin Meng 19998b80bd28SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY 2000f1bd6f8eSMayuresh Chitale static int64_t riscv_get_arch_id(CPUState *cs) 2001f1bd6f8eSMayuresh Chitale { 2002f1bd6f8eSMayuresh Chitale RISCVCPU *cpu = RISCV_CPU(cs); 2003f1bd6f8eSMayuresh Chitale 2004f1bd6f8eSMayuresh Chitale return cpu->env.mhartid; 2005f1bd6f8eSMayuresh Chitale } 2006f1bd6f8eSMayuresh Chitale 20078b80bd28SPhilippe Mathieu-Daudé #include "hw/core/sysemu-cpu-ops.h" 20088b80bd28SPhilippe Mathieu-Daudé 20098b80bd28SPhilippe Mathieu-Daudé static const struct SysemuCPUOps riscv_sysemu_ops = { 201008928c6dSPhilippe Mathieu-Daudé .get_phys_page_debug = riscv_cpu_get_phys_page_debug, 2011715e3c1aSPhilippe Mathieu-Daudé .write_elf64_note = riscv_cpu_write_elf64_note, 2012715e3c1aSPhilippe Mathieu-Daudé .write_elf32_note = riscv_cpu_write_elf32_note, 2013feece4d0SPhilippe Mathieu-Daudé .legacy_vmsd = &vmstate_riscv_cpu, 20148b80bd28SPhilippe Mathieu-Daudé }; 20158b80bd28SPhilippe Mathieu-Daudé #endif 20168b80bd28SPhilippe Mathieu-Daudé 201778271684SClaudio Fontana #include "hw/core/tcg-cpu-ops.h" 201878271684SClaudio Fontana 201911906557SRichard Henderson static const struct TCGCPUOps riscv_tcg_ops = { 202078271684SClaudio Fontana .initialize = riscv_translate_init, 202178271684SClaudio Fontana .synchronize_from_tb = riscv_cpu_synchronize_from_tb, 2022ad1e84f5SRichard Henderson .restore_state_to_opc = riscv_restore_state_to_opc, 202378271684SClaudio Fontana 202478271684SClaudio Fontana #ifndef CONFIG_USER_ONLY 2025263e2ab2SRichard Henderson .tlb_fill = riscv_cpu_tlb_fill, 202617b3c353SPhilippe Mathieu-Daudé .cpu_exec_interrupt = riscv_cpu_exec_interrupt, 202778271684SClaudio Fontana .do_interrupt = riscv_cpu_do_interrupt, 202878271684SClaudio Fontana .do_transaction_failed = riscv_cpu_do_transaction_failed, 202978271684SClaudio Fontana .do_unaligned_access = riscv_cpu_do_unaligned_access, 2030b5f6379dSBin Meng .debug_excp_handler = riscv_cpu_debug_excp_handler, 2031b5f6379dSBin Meng .debug_check_breakpoint = riscv_cpu_debug_check_breakpoint, 2032b5f6379dSBin Meng .debug_check_watchpoint = riscv_cpu_debug_check_watchpoint, 203378271684SClaudio Fontana #endif /* !CONFIG_USER_ONLY */ 203478271684SClaudio Fontana }; 203578271684SClaudio Fontana 20361e341500SDaniel Henrique Barboza static bool riscv_cpu_is_dynamic(Object *cpu_obj) 20371e341500SDaniel Henrique Barboza { 20381e341500SDaniel Henrique Barboza return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL; 20391e341500SDaniel Henrique Barboza } 20401e341500SDaniel Henrique Barboza 20411e341500SDaniel Henrique Barboza static void cpu_set_mvendorid(Object *obj, Visitor *v, const char *name, 20421e341500SDaniel Henrique Barboza void *opaque, Error **errp) 20431e341500SDaniel Henrique Barboza { 20441e341500SDaniel Henrique Barboza bool dynamic_cpu = riscv_cpu_is_dynamic(obj); 20451e341500SDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(obj); 20461e341500SDaniel Henrique Barboza uint32_t prev_val = cpu->cfg.mvendorid; 20471e341500SDaniel Henrique Barboza uint32_t value; 20481e341500SDaniel Henrique Barboza 20491e341500SDaniel Henrique Barboza if (!visit_type_uint32(v, name, &value, errp)) { 20501e341500SDaniel Henrique Barboza return; 20511e341500SDaniel Henrique Barboza } 20521e341500SDaniel Henrique Barboza 20531e341500SDaniel Henrique Barboza if (!dynamic_cpu && prev_val != value) { 20541e341500SDaniel Henrique Barboza error_setg(errp, "Unable to change %s mvendorid (0x%x)", 20551e341500SDaniel Henrique Barboza object_get_typename(obj), prev_val); 20561e341500SDaniel Henrique Barboza return; 20571e341500SDaniel Henrique Barboza } 20581e341500SDaniel Henrique Barboza 20591e341500SDaniel Henrique Barboza cpu->cfg.mvendorid = value; 20601e341500SDaniel Henrique Barboza } 20611e341500SDaniel Henrique Barboza 20621e341500SDaniel Henrique Barboza static void cpu_get_mvendorid(Object *obj, Visitor *v, const char *name, 20631e341500SDaniel Henrique Barboza void *opaque, Error **errp) 20641e341500SDaniel Henrique Barboza { 20651e341500SDaniel Henrique Barboza bool value = RISCV_CPU(obj)->cfg.mvendorid; 20661e341500SDaniel Henrique Barboza 20671e341500SDaniel Henrique Barboza visit_type_bool(v, name, &value, errp); 20681e341500SDaniel Henrique Barboza } 20691e341500SDaniel Henrique Barboza 2070a1863ad3SDaniel Henrique Barboza static void cpu_set_mimpid(Object *obj, Visitor *v, const char *name, 2071a1863ad3SDaniel Henrique Barboza void *opaque, Error **errp) 2072a1863ad3SDaniel Henrique Barboza { 2073a1863ad3SDaniel Henrique Barboza bool dynamic_cpu = riscv_cpu_is_dynamic(obj); 2074a1863ad3SDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(obj); 2075a1863ad3SDaniel Henrique Barboza uint64_t prev_val = cpu->cfg.mimpid; 2076a1863ad3SDaniel Henrique Barboza uint64_t value; 2077a1863ad3SDaniel Henrique Barboza 2078a1863ad3SDaniel Henrique Barboza if (!visit_type_uint64(v, name, &value, errp)) { 2079a1863ad3SDaniel Henrique Barboza return; 2080a1863ad3SDaniel Henrique Barboza } 2081a1863ad3SDaniel Henrique Barboza 2082a1863ad3SDaniel Henrique Barboza if (!dynamic_cpu && prev_val != value) { 2083a1863ad3SDaniel Henrique Barboza error_setg(errp, "Unable to change %s mimpid (0x%" PRIu64 ")", 2084a1863ad3SDaniel Henrique Barboza object_get_typename(obj), prev_val); 2085a1863ad3SDaniel Henrique Barboza return; 2086a1863ad3SDaniel Henrique Barboza } 2087a1863ad3SDaniel Henrique Barboza 2088a1863ad3SDaniel Henrique Barboza cpu->cfg.mimpid = value; 2089a1863ad3SDaniel Henrique Barboza } 2090a1863ad3SDaniel Henrique Barboza 2091a1863ad3SDaniel Henrique Barboza static void cpu_get_mimpid(Object *obj, Visitor *v, const char *name, 2092a1863ad3SDaniel Henrique Barboza void *opaque, Error **errp) 2093a1863ad3SDaniel Henrique Barboza { 2094a1863ad3SDaniel Henrique Barboza bool value = RISCV_CPU(obj)->cfg.mimpid; 2095a1863ad3SDaniel Henrique Barboza 2096a1863ad3SDaniel Henrique Barboza visit_type_bool(v, name, &value, errp); 2097a1863ad3SDaniel Henrique Barboza } 2098a1863ad3SDaniel Henrique Barboza 2099d6a427e2SDaniel Henrique Barboza static void cpu_set_marchid(Object *obj, Visitor *v, const char *name, 2100d6a427e2SDaniel Henrique Barboza void *opaque, Error **errp) 2101d6a427e2SDaniel Henrique Barboza { 2102d6a427e2SDaniel Henrique Barboza bool dynamic_cpu = riscv_cpu_is_dynamic(obj); 2103d6a427e2SDaniel Henrique Barboza RISCVCPU *cpu = RISCV_CPU(obj); 2104d6a427e2SDaniel Henrique Barboza uint64_t prev_val = cpu->cfg.marchid; 2105d6a427e2SDaniel Henrique Barboza uint64_t value, invalid_val; 2106d6a427e2SDaniel Henrique Barboza uint32_t mxlen = 0; 2107d6a427e2SDaniel Henrique Barboza 2108d6a427e2SDaniel Henrique Barboza if (!visit_type_uint64(v, name, &value, errp)) { 2109d6a427e2SDaniel Henrique Barboza return; 2110d6a427e2SDaniel Henrique Barboza } 2111d6a427e2SDaniel Henrique Barboza 2112d6a427e2SDaniel Henrique Barboza if (!dynamic_cpu && prev_val != value) { 2113d6a427e2SDaniel Henrique Barboza error_setg(errp, "Unable to change %s marchid (0x%" PRIu64 ")", 2114d6a427e2SDaniel Henrique Barboza object_get_typename(obj), prev_val); 2115d6a427e2SDaniel Henrique Barboza return; 2116d6a427e2SDaniel Henrique Barboza } 2117d6a427e2SDaniel Henrique Barboza 2118d6a427e2SDaniel Henrique Barboza switch (riscv_cpu_mxl(&cpu->env)) { 2119d6a427e2SDaniel Henrique Barboza case MXL_RV32: 2120d6a427e2SDaniel Henrique Barboza mxlen = 32; 2121d6a427e2SDaniel Henrique Barboza break; 2122d6a427e2SDaniel Henrique Barboza case MXL_RV64: 2123d6a427e2SDaniel Henrique Barboza case MXL_RV128: 2124d6a427e2SDaniel Henrique Barboza mxlen = 64; 2125d6a427e2SDaniel Henrique Barboza break; 2126d6a427e2SDaniel Henrique Barboza default: 2127d6a427e2SDaniel Henrique Barboza g_assert_not_reached(); 2128d6a427e2SDaniel Henrique Barboza } 2129d6a427e2SDaniel Henrique Barboza 2130d6a427e2SDaniel Henrique Barboza invalid_val = 1LL << (mxlen - 1); 2131d6a427e2SDaniel Henrique Barboza 2132d6a427e2SDaniel Henrique Barboza if (value == invalid_val) { 2133d6a427e2SDaniel Henrique Barboza error_setg(errp, "Unable to set marchid with MSB (%u) bit set " 2134d6a427e2SDaniel Henrique Barboza "and the remaining bits zero", mxlen); 2135d6a427e2SDaniel Henrique Barboza return; 2136d6a427e2SDaniel Henrique Barboza } 2137d6a427e2SDaniel Henrique Barboza 2138d6a427e2SDaniel Henrique Barboza cpu->cfg.marchid = value; 2139d6a427e2SDaniel Henrique Barboza } 2140d6a427e2SDaniel Henrique Barboza 2141d6a427e2SDaniel Henrique Barboza static void cpu_get_marchid(Object *obj, Visitor *v, const char *name, 2142d6a427e2SDaniel Henrique Barboza void *opaque, Error **errp) 2143d6a427e2SDaniel Henrique Barboza { 2144d6a427e2SDaniel Henrique Barboza bool value = RISCV_CPU(obj)->cfg.marchid; 2145d6a427e2SDaniel Henrique Barboza 2146d6a427e2SDaniel Henrique Barboza visit_type_bool(v, name, &value, errp); 2147d6a427e2SDaniel Henrique Barboza } 2148d6a427e2SDaniel Henrique Barboza 2149dc5bd18fSMichael Clark static void riscv_cpu_class_init(ObjectClass *c, void *data) 2150dc5bd18fSMichael Clark { 2151dc5bd18fSMichael Clark RISCVCPUClass *mcc = RISCV_CPU_CLASS(c); 2152dc5bd18fSMichael Clark CPUClass *cc = CPU_CLASS(c); 2153dc5bd18fSMichael Clark DeviceClass *dc = DEVICE_CLASS(c); 21544fa485a7SPeter Maydell ResettableClass *rc = RESETTABLE_CLASS(c); 2155dc5bd18fSMichael Clark 215641fbbba7SMao Zhongyi device_class_set_parent_realize(dc, riscv_cpu_realize, 215741fbbba7SMao Zhongyi &mcc->parent_realize); 2158dc5bd18fSMichael Clark 21594fa485a7SPeter Maydell resettable_class_set_parent_phases(rc, NULL, riscv_cpu_reset_hold, NULL, 21604fa485a7SPeter Maydell &mcc->parent_phases); 2161dc5bd18fSMichael Clark 2162dc5bd18fSMichael Clark cc->class_by_name = riscv_cpu_class_by_name; 2163dc5bd18fSMichael Clark cc->has_work = riscv_cpu_has_work; 2164dc5bd18fSMichael Clark cc->dump_state = riscv_cpu_dump_state; 2165dc5bd18fSMichael Clark cc->set_pc = riscv_cpu_set_pc; 2166e4fdf9dfSRichard Henderson cc->get_pc = riscv_cpu_get_pc; 2167dc5bd18fSMichael Clark cc->gdb_read_register = riscv_cpu_gdb_read_register; 2168dc5bd18fSMichael Clark cc->gdb_write_register = riscv_cpu_gdb_write_register; 21695371f5cdSJim Wilson cc->gdb_num_core_regs = 33; 2170dc5bd18fSMichael Clark cc->gdb_stop_before_watchpoint = true; 2171dc5bd18fSMichael Clark cc->disas_set_info = riscv_cpu_disas_set_info; 21728a4ca3c1SRichard Henderson #ifndef CONFIG_USER_ONLY 21738b80bd28SPhilippe Mathieu-Daudé cc->sysemu_ops = &riscv_sysemu_ops; 2174f1bd6f8eSMayuresh Chitale cc->get_arch_id = riscv_get_arch_id; 2175dc5bd18fSMichael Clark #endif 2176edf64786SSylvain Pelissier cc->gdb_arch_name = riscv_gdb_arch_name; 2177b93777e1SBin Meng cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml; 217878271684SClaudio Fontana cc->tcg_ops = &riscv_tcg_ops; 21796a3d2e7cSClaudio Fontana 21801e341500SDaniel Henrique Barboza object_class_property_add(c, "mvendorid", "uint32", cpu_get_mvendorid, 21811e341500SDaniel Henrique Barboza cpu_set_mvendorid, NULL, NULL); 21821e341500SDaniel Henrique Barboza 2183a1863ad3SDaniel Henrique Barboza object_class_property_add(c, "mimpid", "uint64", cpu_get_mimpid, 2184a1863ad3SDaniel Henrique Barboza cpu_set_mimpid, NULL, NULL); 2185a1863ad3SDaniel Henrique Barboza 2186d6a427e2SDaniel Henrique Barboza object_class_property_add(c, "marchid", "uint64", cpu_get_marchid, 2187d6a427e2SDaniel Henrique Barboza cpu_set_marchid, NULL, NULL); 2188d6a427e2SDaniel Henrique Barboza 21894f67d30bSMarc-André Lureau device_class_set_props(dc, riscv_cpu_properties); 2190dc5bd18fSMichael Clark } 2191dc5bd18fSMichael Clark 2192246f8796SWeiwei Li static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, 2193246f8796SWeiwei Li int max_str_len) 2194a775398bSAtish Patra { 2195a775398bSAtish Patra char *old = *isa_str; 2196a775398bSAtish Patra char *new = *isa_str; 2197a775398bSAtish Patra int i; 2198a775398bSAtish Patra 2199a775398bSAtish Patra for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { 220063c7eedcSDaniel Henrique Barboza if (isa_ext_is_enabled(cpu, &isa_edata_arr[i])) { 2201a775398bSAtish Patra new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL); 2202a775398bSAtish Patra g_free(old); 2203a775398bSAtish Patra old = new; 2204a775398bSAtish Patra } 2205a775398bSAtish Patra } 2206a775398bSAtish Patra 2207a775398bSAtish Patra *isa_str = new; 2208a775398bSAtish Patra } 2209a775398bSAtish Patra 2210dc5bd18fSMichael Clark char *riscv_isa_string(RISCVCPU *cpu) 2211dc5bd18fSMichael Clark { 2212dc5bd18fSMichael Clark int i; 22130e2c3770STsukasa OI const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts); 2214d1fd31f8SMichael Clark char *isa_str = g_new(char, maxlen); 2215d1fd31f8SMichael Clark char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS); 22160e2c3770STsukasa OI for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) { 22170e2c3770STsukasa OI if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) { 22180e2c3770STsukasa OI *p++ = qemu_tolower(riscv_single_letter_exts[i]); 2219dc5bd18fSMichael Clark } 2220dc5bd18fSMichael Clark } 2221d1fd31f8SMichael Clark *p = '\0'; 2222a4a9a443STsukasa OI if (!cpu->cfg.short_isa_string) { 2223a775398bSAtish Patra riscv_isa_string_ext(cpu, &isa_str, maxlen); 2224a4a9a443STsukasa OI } 2225d1fd31f8SMichael Clark return isa_str; 2226dc5bd18fSMichael Clark } 2227dc5bd18fSMichael Clark 2228eab15862SMichael Clark static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b) 2229eab15862SMichael Clark { 2230eab15862SMichael Clark ObjectClass *class_a = (ObjectClass *)a; 2231eab15862SMichael Clark ObjectClass *class_b = (ObjectClass *)b; 2232eab15862SMichael Clark const char *name_a, *name_b; 2233eab15862SMichael Clark 2234eab15862SMichael Clark name_a = object_class_get_name(class_a); 2235eab15862SMichael Clark name_b = object_class_get_name(class_b); 2236eab15862SMichael Clark return strcmp(name_a, name_b); 2237eab15862SMichael Clark } 2238eab15862SMichael Clark 2239eab15862SMichael Clark static void riscv_cpu_list_entry(gpointer data, gpointer user_data) 2240eab15862SMichael Clark { 2241eab15862SMichael Clark const char *typename = object_class_get_name(OBJECT_CLASS(data)); 2242eab15862SMichael Clark int len = strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX); 2243eab15862SMichael Clark 22440442428aSMarkus Armbruster qemu_printf("%.*s\n", len, typename); 2245eab15862SMichael Clark } 2246eab15862SMichael Clark 22470442428aSMarkus Armbruster void riscv_cpu_list(void) 2248dc5bd18fSMichael Clark { 2249eab15862SMichael Clark GSList *list; 2250dc5bd18fSMichael Clark 2251eab15862SMichael Clark list = object_class_get_list(TYPE_RISCV_CPU, false); 2252eab15862SMichael Clark list = g_slist_sort(list, riscv_cpu_list_compare); 22530442428aSMarkus Armbruster g_slist_foreach(list, riscv_cpu_list_entry, NULL); 2254eab15862SMichael Clark g_slist_free(list); 2255dc5bd18fSMichael Clark } 2256dc5bd18fSMichael Clark 2257eab15862SMichael Clark #define DEFINE_CPU(type_name, initfn) \ 2258eab15862SMichael Clark { \ 2259eab15862SMichael Clark .name = type_name, \ 2260eab15862SMichael Clark .parent = TYPE_RISCV_CPU, \ 2261eab15862SMichael Clark .instance_init = initfn \ 2262eab15862SMichael Clark } 2263eab15862SMichael Clark 22649e1a30d3SDaniel Henrique Barboza #define DEFINE_DYNAMIC_CPU(type_name, initfn) \ 22659e1a30d3SDaniel Henrique Barboza { \ 22669e1a30d3SDaniel Henrique Barboza .name = type_name, \ 22679e1a30d3SDaniel Henrique Barboza .parent = TYPE_RISCV_DYNAMIC_CPU, \ 22689e1a30d3SDaniel Henrique Barboza .instance_init = initfn \ 22699e1a30d3SDaniel Henrique Barboza } 22709e1a30d3SDaniel Henrique Barboza 2271eab15862SMichael Clark static const TypeInfo riscv_cpu_type_infos[] = { 2272dc5bd18fSMichael Clark { 2273eab15862SMichael Clark .name = TYPE_RISCV_CPU, 2274eab15862SMichael Clark .parent = TYPE_CPU, 2275eab15862SMichael Clark .instance_size = sizeof(RISCVCPU), 22765de5b99bSRichard Henderson .instance_align = __alignof__(RISCVCPU), 2277eab15862SMichael Clark .instance_init = riscv_cpu_init, 2278eab15862SMichael Clark .abstract = true, 2279eab15862SMichael Clark .class_size = sizeof(RISCVCPUClass), 2280eab15862SMichael Clark .class_init = riscv_cpu_class_init, 2281eab15862SMichael Clark }, 22829e1a30d3SDaniel Henrique Barboza { 22839e1a30d3SDaniel Henrique Barboza .name = TYPE_RISCV_DYNAMIC_CPU, 22849e1a30d3SDaniel Henrique Barboza .parent = TYPE_RISCV_CPU, 22859e1a30d3SDaniel Henrique Barboza .abstract = true, 22869e1a30d3SDaniel Henrique Barboza }, 22879e1a30d3SDaniel Henrique Barboza DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init), 228810f1ca27SYifei Jiang #if defined(CONFIG_KVM) 228910f1ca27SYifei Jiang DEFINE_CPU(TYPE_RISCV_CPU_HOST, riscv_host_cpu_init), 229010f1ca27SYifei Jiang #endif 2291eab15862SMichael Clark #if defined(TARGET_RISCV32) 22929e1a30d3SDaniel Henrique Barboza DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32, rv32_base_cpu_init), 2293e8905c6cSBin Meng DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init), 2294114baacaSAlistair Francis DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init), 22952fdd2c09SBin Meng DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init), 2296114baacaSAlistair Francis DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init), 2297eab15862SMichael Clark #elif defined(TARGET_RISCV64) 22989e1a30d3SDaniel Henrique Barboza DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init), 2299114baacaSAlistair Francis DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init), 2300114baacaSAlistair Francis DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init), 23016ddc7069SVijai Kumar K DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init), 230295bd8daaSChristoph Müllner DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init), 2303e1d084a8SRahul Pathak DEFINE_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init), 23049e1a30d3SDaniel Henrique Barboza DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init), 2305eab15862SMichael Clark #endif 2306eab15862SMichael Clark }; 2307dc5bd18fSMichael Clark 2308eab15862SMichael Clark DEFINE_TYPES(riscv_cpu_type_infos) 2309