xref: /openbmc/qemu/target/riscv/cpu.c (revision 08c6ed47e6fee0c4c536e1202c643a0ce36f48be)
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"
26f7697f0eSYifei Jiang #include "internals.h"
27dc5bd18fSMichael Clark #include "exec/exec-all.h"
28dc5bd18fSMichael Clark #include "qapi/error.h"
296f23aaebSAlexandre Ghiti #include "qapi/visitor.h"
30b55d7d34SAlistair Francis #include "qemu/error-report.h"
31c4e95030SAlistair Francis #include "hw/qdev-properties.h"
32fae0b533SDaniel Henrique Barboza #include "hw/core/qdev-prop-internal.h"
33dc5bd18fSMichael Clark #include "migration/vmstate.h"
34135b03cbSAlex Bennée #include "fpu/softfloat-helpers.h"
351c8e491cSConor Dooley #include "sysemu/device_tree.h"
36ad40be27SYifei Jiang #include "sysemu/kvm.h"
37eddabb6bSDaniel Henrique Barboza #include "sysemu/tcg.h"
38fb80f333SDaniel Henrique Barboza #include "kvm/kvm_riscv.h"
39a13a6082SDaniel Henrique Barboza #include "tcg/tcg-cpu.h"
400489d5bdSAnton Johansson #include "tcg/tcg.h"
41dc5bd18fSMichael Clark 
42dc5bd18fSMichael Clark /* RISC-V CPU definitions */
432317ba9fSRob Bradford static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
44efa365b7SDaniel Henrique Barboza const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV,
452317ba9fSRob Bradford                               RVC, RVS, RVU, RVH, RVJ, RVG, RVB, 0};
46dc5bd18fSMichael Clark 
473b57254dSWeiwei Li /*
48b227f6a8SIvan Klokov  * From vector_helper.c
49b227f6a8SIvan Klokov  * Note that vector data is stored in host-endian 64-bit chunks,
50b227f6a8SIvan Klokov  * so addressing bytes needs a host-endian fixup.
51b227f6a8SIvan Klokov  */
52b227f6a8SIvan Klokov #if HOST_BIG_ENDIAN
53b227f6a8SIvan Klokov #define BYTE(x)   ((x) ^ 7)
54b227f6a8SIvan Klokov #else
55b227f6a8SIvan Klokov #define BYTE(x)   (x)
56b227f6a8SIvan Klokov #endif
57b227f6a8SIvan Klokov 
riscv_cpu_is_32bit(RISCVCPU * cpu)58e7acc1cbSDaniel Henrique Barboza bool riscv_cpu_is_32bit(RISCVCPU *cpu)
59e7acc1cbSDaniel Henrique Barboza {
60e7acc1cbSDaniel Henrique Barboza     return riscv_cpu_mxl(&cpu->env) == MXL_RV32;
61e7acc1cbSDaniel Henrique Barboza }
62e7acc1cbSDaniel Henrique Barboza 
63d167a224SDaniel Henrique Barboza /* Hash that stores general user set numeric options */
64d167a224SDaniel Henrique Barboza static GHashTable *general_user_opts;
65d167a224SDaniel Henrique Barboza 
cpu_option_add_user_setting(const char * optname,uint32_t value)66d167a224SDaniel Henrique Barboza static void cpu_option_add_user_setting(const char *optname, uint32_t value)
67d167a224SDaniel Henrique Barboza {
68d167a224SDaniel Henrique Barboza     g_hash_table_insert(general_user_opts, (gpointer)optname,
69d167a224SDaniel Henrique Barboza                         GUINT_TO_POINTER(value));
70d167a224SDaniel Henrique Barboza }
71d167a224SDaniel Henrique Barboza 
riscv_cpu_option_set(const char * optname)72bbef9140SDaniel Henrique Barboza bool riscv_cpu_option_set(const char *optname)
73bbef9140SDaniel Henrique Barboza {
74bbef9140SDaniel Henrique Barboza     return g_hash_table_contains(general_user_opts, optname);
75bbef9140SDaniel Henrique Barboza }
76bbef9140SDaniel Henrique Barboza 
777935e2c4SDaniel Henrique Barboza #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
787935e2c4SDaniel Henrique Barboza     {#_name, _min_ver, CPU_CFG_OFFSET(_prop)}
797935e2c4SDaniel Henrique Barboza 
80b227f6a8SIvan Klokov /*
819a1f054dSAnup Patel  * Here are the ordering rules of extension naming defined by RISC-V
829a1f054dSAnup Patel  * specification :
839a1f054dSAnup Patel  * 1. All extensions should be separated from other multi-letter extensions
849a1f054dSAnup Patel  *    by an underscore.
859a1f054dSAnup Patel  * 2. The first letter following the 'Z' conventionally indicates the most
869a1f054dSAnup Patel  *    closely related alphabetical extension category, IMAFDQLCBKJTPVH.
879a1f054dSAnup Patel  *    If multiple 'Z' extensions are named, they should be ordered first
889a1f054dSAnup Patel  *    by category, then alphabetically within a category.
899a1f054dSAnup Patel  * 3. Standard supervisor-level extensions (starts with 'S') should be
909a1f054dSAnup Patel  *    listed after standard unprivileged extensions.  If multiple
919a1f054dSAnup Patel  *    supervisor-level extensions are listed, they should be ordered
929a1f054dSAnup Patel  *    alphabetically.
939a1f054dSAnup Patel  * 4. Non-standard extensions (starts with 'X') must be listed after all
949a1f054dSAnup Patel  *    standard extensions. They must be separated from other multi-letter
959a1f054dSAnup Patel  *    extensions by an underscore.
966508272aSDaniel Henrique Barboza  *
976508272aSDaniel Henrique Barboza  * Single letter extensions are checked in riscv_cpu_validate_misa_priv()
986508272aSDaniel Henrique Barboza  * instead.
999a1f054dSAnup Patel  */
1007935e2c4SDaniel Henrique Barboza const RISCVIsaExtData isa_edata_arr[] = {
1013b802226SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zic64b, PRIV_VERSION_1_12_0, ext_zic64b),
102a326a2b0SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
103cc2bf69aSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
104e57039ddSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
10568c9e54bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(ziccamoa, PRIV_VERSION_1_11_0, has_priv_1_11),
10668c9e54bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(ziccif, PRIV_VERSION_1_11_0, has_priv_1_11),
10768c9e54bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zicclsm, PRIV_VERSION_1_11_0, has_priv_1_11),
10868c9e54bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(ziccrse, PRIV_VERSION_1_11_0, has_priv_1_11),
109ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zicfilp, PRIV_VERSION_1_12_0, ext_zicfilp),
110c0040993SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zicfiss, PRIV_VERSION_1_13_0, ext_zicfiss),
111960b389bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
11212b12a14SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr),
1130228aca2SJason Chien     ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_zicsr),
114ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_zifencei),
11508241216SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
1166eab278dSLIU Zhiwei     ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
11750f94649SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
11868c9e54bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zimop, PRIV_VERSION_1_13_0, ext_zimop),
11979b50e2cSRob Bradford     ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
1208aebaa25SLIU Zhiwei     ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_12),
121b52d49e9SWeiwei Li     ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
122a60ce58fSLIU Zhiwei     ISA_EXT_DATA_ENTRY(zabha, PRIV_VERSION_1_13_0, ext_zabha),
12379b50e2cSRob Bradford     ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
124ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zama16b, PRIV_VERSION_1_13_0, ext_zama16b),
125a47842d1SChristoph Müllner     ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
126889caa44SWeiwei Li     ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
127ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
128ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
129ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zfh, PRIV_VERSION_1_11_0, ext_zfh),
130ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zfhmin, PRIV_VERSION_1_11_0, ext_zfhmin),
131ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zfinx, PRIV_VERSION_1_12_0, ext_zfinx),
132ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zdinx, PRIV_VERSION_1_12_0, ext_zdinx),
133ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zca, PRIV_VERSION_1_12_0, ext_zca),
134ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zcb, PRIV_VERSION_1_12_0, ext_zcb),
135ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zcf, PRIV_VERSION_1_12_0, ext_zcf),
136197e4d29SLIU Zhiwei     ISA_EXT_DATA_ENTRY(zcd, PRIV_VERSION_1_12_0, ext_zcd),
137ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zce, PRIV_VERSION_1_12_0, ext_zce),
138ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zcmop, PRIV_VERSION_1_13_0, ext_zcmop),
139ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zcmp, PRIV_VERSION_1_12_0, ext_zcmp),
140ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zcmt, PRIV_VERSION_1_12_0, ext_zcmt),
141ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zba, PRIV_VERSION_1_12_0, ext_zba),
142ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zbb, PRIV_VERSION_1_12_0, ext_zbb),
143ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zbc, PRIV_VERSION_1_12_0, ext_zbc),
144ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zbkb, PRIV_VERSION_1_12_0, ext_zbkb),
145ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zbkc, PRIV_VERSION_1_12_0, ext_zbkc),
146ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zbkx, PRIV_VERSION_1_12_0, ext_zbkx),
147ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zbs, PRIV_VERSION_1_12_0, ext_zbs),
148ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zk, PRIV_VERSION_1_12_0, ext_zk),
149ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zkn, PRIV_VERSION_1_12_0, ext_zkn),
150ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zknd, PRIV_VERSION_1_12_0, ext_zknd),
151ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zkne, PRIV_VERSION_1_12_0, ext_zkne),
152ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zknh, PRIV_VERSION_1_12_0, ext_zknh),
153ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zkr, PRIV_VERSION_1_12_0, ext_zkr),
154ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zks, PRIV_VERSION_1_12_0, ext_zks),
155ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
15609c4e887SPalmer Dabbelt     ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
15706028472SDickon Hood     ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
158e13c7d3bSLawrence Hunter     ISA_EXT_DATA_ENTRY(ztso, PRIV_VERSION_1_12_0, ext_ztso),
159ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
1609fb41a44SJason Chien     ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
161ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
162ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
163e7dc5e16SJason Chien     ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
164889caa44SWeiwei Li     ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
165889caa44SWeiwei Li     ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
166ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
167ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
168f209cb0aSMax Chou     ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
169767eb035SNazar Kazakov     ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
17023aaefb9SMax Chou     ISA_EXT_DATA_ENTRY(zvkb, PRIV_VERSION_1_12_0, ext_zvkb),
17123aaefb9SMax Chou     ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
172e972bf22SNazar Kazakov     ISA_EXT_DATA_ENTRY(zvkn, PRIV_VERSION_1_12_0, ext_zvkn),
17323aaefb9SMax Chou     ISA_EXT_DATA_ENTRY(zvknc, PRIV_VERSION_1_12_0, ext_zvknc),
174fcf19433SKiran Ostrolenk     ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
175fcf19433SKiran Ostrolenk     ISA_EXT_DATA_ENTRY(zvkng, PRIV_VERSION_1_12_0, ext_zvkng),
176b43419f2SMax Chou     ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
177b43419f2SMax Chou     ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
1788b045ff4SMax Chou     ISA_EXT_DATA_ENTRY(zvks, PRIV_VERSION_1_12_0, ext_zvks),
179b43419f2SMax Chou     ISA_EXT_DATA_ENTRY(zvksc, PRIV_VERSION_1_12_0, ext_zvksc),
1802350881cSLawrence Hunter     ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed),
1811c32b630SMax Chou     ISA_EXT_DATA_ENTRY(zvksg, PRIV_VERSION_1_12_0, ext_zvksg),
182ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
183ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zvkt, PRIV_VERSION_1_12_0, ext_zvkt),
184ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
185251dccc0SKaiwen Xue     ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
186095fe72aSHimanshu Chauhan     ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
1873594e3e5SMayuresh Chitale     ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
188ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
18968c9e54bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
190ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
19168c9e54bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11),
192ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
19368c9e54bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
19468c9e54bSDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
1953b802226SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
196ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
197ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade),
198ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
199ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
200ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
201ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
202ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(svvptc, PRIV_VERSION_1_13_0, ext_svvptc),
203ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
204ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
205ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs),
206ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadcmo, PRIV_VERSION_1_11_0, ext_xtheadcmo),
207ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadcondmov, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
208ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadfmemidx, PRIV_VERSION_1_11_0, ext_xtheadfmemidx),
209ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadfmv, PRIV_VERSION_1_11_0, ext_xtheadfmv),
210ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadmac, PRIV_VERSION_1_11_0, ext_xtheadmac),
211ccc84a75SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadmemidx, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
2127935e2c4SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair),
2137935e2c4SDaniel Henrique Barboza     ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync),
2149a1f054dSAnup Patel     ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
2159a1f054dSAnup Patel 
21636c1118dSDaniel Henrique Barboza     DEFINE_PROP_END_OF_LIST(),
2179a1f054dSAnup Patel };
2185f2c80f1SDaniel Henrique Barboza 
isa_ext_is_enabled(RISCVCPU * cpu,uint32_t ext_offset)2199a1f054dSAnup Patel bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
2209a1f054dSAnup Patel {
2219a1f054dSAnup Patel     bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
2229a1f054dSAnup Patel 
22336c1118dSDaniel Henrique Barboza     return *ext_enabled;
2249a1f054dSAnup Patel }
2255f2c80f1SDaniel Henrique Barboza 
isa_ext_update_enabled(RISCVCPU * cpu,uint32_t ext_offset,bool en)2269a1f054dSAnup Patel void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en)
2279a1f054dSAnup Patel {
2289a1f054dSAnup Patel     bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
2299a1f054dSAnup Patel 
230b62b86a1SDaniel Henrique Barboza     *ext_enabled = en;
231b62b86a1SDaniel Henrique Barboza }
232b62b86a1SDaniel Henrique Barboza 
riscv_cpu_is_vendor(Object * cpu_obj)233b62b86a1SDaniel Henrique Barboza bool riscv_cpu_is_vendor(Object *cpu_obj)
234b62b86a1SDaniel Henrique Barboza {
235dc5bd18fSMichael Clark     return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL;
236a9f37afaSAtish Patra }
237a9f37afaSAtish Patra 
238a9f37afaSAtish Patra const char * const riscv_int_regnames[] = {
239a9f37afaSAtish Patra     "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
240a9f37afaSAtish Patra     "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
241dc5bd18fSMichael Clark     "x14/a4",  "x15/a5", "x16/a6", "x17/a7", "x18/s2", "x19/s3",  "x20/s4",
242dc5bd18fSMichael Clark     "x21/s5",  "x22/s6", "x23/s7", "x24/s8", "x25/s9", "x26/s10", "x27/s11",
2432b547084SFrédéric Pétrot     "x28/t3",  "x29/t4", "x30/t5", "x31/t6"
2442b547084SFrédéric Pétrot };
2452b547084SFrédéric Pétrot 
2462b547084SFrédéric Pétrot const char * const riscv_int_regnamesh[] = {
2472b547084SFrédéric Pétrot     "x0h/zeroh", "x1h/rah",  "x2h/sph",   "x3h/gph",   "x4h/tph",  "x5h/t0h",
2482b547084SFrédéric Pétrot     "x6h/t1h",   "x7h/t2h",  "x8h/s0h",   "x9h/s1h",   "x10h/a0h", "x11h/a1h",
2492b547084SFrédéric Pétrot     "x12h/a2h",  "x13h/a3h", "x14h/a4h",  "x15h/a5h",  "x16h/a6h", "x17h/a7h",
2502b547084SFrédéric Pétrot     "x18h/s2h",  "x19h/s3h", "x20h/s4h",  "x21h/s5h",  "x22h/s6h", "x23h/s7h",
2512b547084SFrédéric Pétrot     "x24h/s8h",  "x25h/s9h", "x26h/s10h", "x27h/s11h", "x28h/t3h", "x29h/t4h",
252dc5bd18fSMichael Clark     "x30h/t5h",  "x31h/t6h"
253a9f37afaSAtish Patra };
254a9f37afaSAtish Patra 
255a9f37afaSAtish Patra const char * const riscv_fpr_regnames[] = {
256a9f37afaSAtish Patra     "f0/ft0",   "f1/ft1",  "f2/ft2",   "f3/ft3",   "f4/ft4",  "f5/ft5",
257a9f37afaSAtish Patra     "f6/ft6",   "f7/ft7",  "f8/fs0",   "f9/fs1",   "f10/fa0", "f11/fa1",
258a9f37afaSAtish Patra     "f12/fa2",  "f13/fa3", "f14/fa4",  "f15/fa5",  "f16/fa6", "f17/fa7",
259dc5bd18fSMichael Clark     "f18/fs2",  "f19/fs3", "f20/fs4",  "f21/fs5",  "f22/fs6", "f23/fs7",
260dc5bd18fSMichael Clark     "f24/fs8",  "f25/fs9", "f26/fs10", "f27/fs11", "f28/ft8", "f29/ft9",
261b227f6a8SIvan Klokov     "f30/ft10", "f31/ft11"
262b227f6a8SIvan Klokov };
263b227f6a8SIvan Klokov 
264b227f6a8SIvan Klokov const char * const riscv_rvv_regnames[] = {
265b227f6a8SIvan Klokov   "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",
266b227f6a8SIvan Klokov   "v7",  "v8",  "v9",  "v10", "v11", "v12", "v13",
267b227f6a8SIvan Klokov   "v14", "v15", "v16", "v17", "v18", "v19", "v20",
268b227f6a8SIvan Klokov   "v21", "v22", "v23", "v24", "v25", "v26", "v27",
2699a575d33SBin Meng   "v28", "v29", "v30", "v31"
270dc5bd18fSMichael Clark };
271dc5bd18fSMichael Clark 
272dc5bd18fSMichael Clark static const char * const riscv_excp_names[] = {
273dc5bd18fSMichael Clark     "misaligned_fetch",
274dc5bd18fSMichael Clark     "fault_fetch",
275dc5bd18fSMichael Clark     "illegal_instruction",
276dc5bd18fSMichael Clark     "breakpoint",
277dc5bd18fSMichael Clark     "misaligned_load",
278dc5bd18fSMichael Clark     "fault_load",
279dc5bd18fSMichael Clark     "misaligned_store",
280dc5bd18fSMichael Clark     "fault_store",
281dc5bd18fSMichael Clark     "user_ecall",
282dc5bd18fSMichael Clark     "supervisor_ecall",
283dc5bd18fSMichael Clark     "hypervisor_ecall",
284dc5bd18fSMichael Clark     "machine_ecall",
285fd990e86SPalmer Dabbelt     "exec_page_fault",
286ab67a1d0SAlistair Francis     "load_page_fault",
287ab67a1d0SAlistair Francis     "reserved",
288ab67a1d0SAlistair Francis     "store_page_fault",
289ab67a1d0SAlistair Francis     "reserved",
290ab67a1d0SAlistair Francis     "reserved",
291ab67a1d0SAlistair Francis     "reserved",
292ab67a1d0SAlistair Francis     "reserved",
293fd990e86SPalmer Dabbelt     "guest_exec_page_fault",
294dc5bd18fSMichael Clark     "guest_load_page_fault",
295dc5bd18fSMichael Clark     "reserved",
2969a575d33SBin Meng     "guest_store_page_fault",
297dc5bd18fSMichael Clark };
298dc5bd18fSMichael Clark 
299205377f8SAlistair Francis static const char * const riscv_intr_names[] = {
300dc5bd18fSMichael Clark     "u_software",
301dc5bd18fSMichael Clark     "s_software",
302dc5bd18fSMichael Clark     "vs_software",
303205377f8SAlistair Francis     "m_software",
304dc5bd18fSMichael Clark     "u_timer",
305dc5bd18fSMichael Clark     "s_timer",
3066cfcf775SEmmanuel Blot     "vs_timer",
307205377f8SAlistair Francis     "m_timer",
308dc5bd18fSMichael Clark     "u_external",
309426f0348SMichael Clark     "s_external",
310426f0348SMichael Clark     "vs_external",
311426f0348SMichael Clark     "m_external",
312426f0348SMichael Clark     "reserved",
313dc5bd18fSMichael Clark     "reserved",
314dc5bd18fSMichael Clark     "reserved",
315c51a3f5dSYifei Jiang     "reserved"
316c51a3f5dSYifei Jiang };
317c51a3f5dSYifei Jiang 
riscv_cpu_get_trap_name(target_ulong cause,bool async)318c51a3f5dSYifei Jiang const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
319c51a3f5dSYifei Jiang {
320c51a3f5dSYifei Jiang     if (async) {
321c51a3f5dSYifei Jiang         return (cause < ARRAY_SIZE(riscv_intr_names)) ?
322c51a3f5dSYifei Jiang                riscv_intr_names[cause] : "(unknown)";
323c51a3f5dSYifei Jiang     } else {
324c51a3f5dSYifei Jiang         return (cause < ARRAY_SIZE(riscv_excp_names)) ?
325c51a3f5dSYifei Jiang                riscv_excp_names[cause] : "(unknown)";
326742cc269SAkihiko Odaki     }
327dc5bd18fSMichael Clark }
328e91a7227SRichard Henderson 
riscv_cpu_set_misa_ext(CPURISCVState * env,uint32_t ext)329dc5bd18fSMichael Clark void riscv_cpu_set_misa_ext(CPURISCVState *env, uint32_t ext)
330dc5bd18fSMichael Clark {
331afa42c21SConor Dooley     env->misa_ext_mask = env->misa_ext = ext;
332afa42c21SConor Dooley }
333afa42c21SConor Dooley 
riscv_cpu_max_xlen(RISCVCPUClass * mcc)334afa42c21SConor Dooley int riscv_cpu_max_xlen(RISCVCPUClass *mcc)
335afa42c21SConor Dooley {
3366f23aaebSAlexandre Ghiti     return 16 << mcc->misa_mxl_max;
3376f23aaebSAlexandre Ghiti }
3386f23aaebSAlexandre Ghiti 
3396f23aaebSAlexandre Ghiti #ifndef CONFIG_USER_ONLY
satp_mode_from_str(const char * satp_mode_str)3406f23aaebSAlexandre Ghiti static uint8_t satp_mode_from_str(const char *satp_mode_str)
3416f23aaebSAlexandre Ghiti {
3426f23aaebSAlexandre Ghiti     if (!strncmp(satp_mode_str, "mbare", 5)) {
3436f23aaebSAlexandre Ghiti         return VM_1_10_MBARE;
3446f23aaebSAlexandre Ghiti     }
3456f23aaebSAlexandre Ghiti 
3466f23aaebSAlexandre Ghiti     if (!strncmp(satp_mode_str, "sv32", 4)) {
3476f23aaebSAlexandre Ghiti         return VM_1_10_SV32;
3486f23aaebSAlexandre Ghiti     }
3496f23aaebSAlexandre Ghiti 
3506f23aaebSAlexandre Ghiti     if (!strncmp(satp_mode_str, "sv39", 4)) {
3516f23aaebSAlexandre Ghiti         return VM_1_10_SV39;
3526f23aaebSAlexandre Ghiti     }
3536f23aaebSAlexandre Ghiti 
3546f23aaebSAlexandre Ghiti     if (!strncmp(satp_mode_str, "sv48", 4)) {
3556f23aaebSAlexandre Ghiti         return VM_1_10_SV48;
3566f23aaebSAlexandre Ghiti     }
3576f23aaebSAlexandre Ghiti 
3586f23aaebSAlexandre Ghiti     if (!strncmp(satp_mode_str, "sv57", 4)) {
3596f23aaebSAlexandre Ghiti         return VM_1_10_SV57;
3606f23aaebSAlexandre Ghiti     }
3616f23aaebSAlexandre Ghiti 
3626f23aaebSAlexandre Ghiti     if (!strncmp(satp_mode_str, "sv64", 4)) {
3636f23aaebSAlexandre Ghiti         return VM_1_10_SV64;
3646f23aaebSAlexandre Ghiti     }
3656f23aaebSAlexandre Ghiti 
3666f23aaebSAlexandre Ghiti     g_assert_not_reached();
3676f23aaebSAlexandre Ghiti }
3683a2fc235SDaniel Henrique Barboza 
satp_mode_max_from_map(uint32_t map)3693a2fc235SDaniel Henrique Barboza uint8_t satp_mode_max_from_map(uint32_t map)
3703a2fc235SDaniel Henrique Barboza {
3713a2fc235SDaniel Henrique Barboza     /*
3723a2fc235SDaniel Henrique Barboza      * 'map = 0' will make us return (31 - 32), which C will
3733a2fc235SDaniel Henrique Barboza      * happily overflow to UINT_MAX. There's no good result to
3743a2fc235SDaniel Henrique Barboza      * return if 'map = 0' (e.g. returning 0 will be ambiguous
3753a2fc235SDaniel Henrique Barboza      * with the result for 'map = 1').
3763a2fc235SDaniel Henrique Barboza      *
3773a2fc235SDaniel Henrique Barboza      * Assert out if map = 0. Callers will have to deal with
3783a2fc235SDaniel Henrique Barboza      * it outside of this function.
3796f23aaebSAlexandre Ghiti      */
3806f23aaebSAlexandre Ghiti     g_assert(map > 0);
3816f23aaebSAlexandre Ghiti 
3826f23aaebSAlexandre Ghiti     /* map here has at least one bit set, so no problem with clz */
3836f23aaebSAlexandre Ghiti     return 31 - __builtin_clz(map);
3846f23aaebSAlexandre Ghiti }
3856f23aaebSAlexandre Ghiti 
satp_mode_str(uint8_t satp_mode,bool is_32_bit)3866f23aaebSAlexandre Ghiti const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit)
3876f23aaebSAlexandre Ghiti {
3886f23aaebSAlexandre Ghiti     if (is_32_bit) {
3896f23aaebSAlexandre Ghiti         switch (satp_mode) {
3906f23aaebSAlexandre Ghiti         case VM_1_10_SV32:
3916f23aaebSAlexandre Ghiti             return "sv32";
3926f23aaebSAlexandre Ghiti         case VM_1_10_MBARE:
3936f23aaebSAlexandre Ghiti             return "none";
3946f23aaebSAlexandre Ghiti         }
3956f23aaebSAlexandre Ghiti     } else {
3966f23aaebSAlexandre Ghiti         switch (satp_mode) {
3976f23aaebSAlexandre Ghiti         case VM_1_10_SV64:
3986f23aaebSAlexandre Ghiti             return "sv64";
3996f23aaebSAlexandre Ghiti         case VM_1_10_SV57:
4006f23aaebSAlexandre Ghiti             return "sv57";
4016f23aaebSAlexandre Ghiti         case VM_1_10_SV48:
4026f23aaebSAlexandre Ghiti             return "sv48";
4036f23aaebSAlexandre Ghiti         case VM_1_10_SV39:
4046f23aaebSAlexandre Ghiti             return "sv39";
4056f23aaebSAlexandre Ghiti         case VM_1_10_MBARE:
4066f23aaebSAlexandre Ghiti             return "none";
4076f23aaebSAlexandre Ghiti         }
4086f23aaebSAlexandre Ghiti     }
4096f23aaebSAlexandre Ghiti 
4106df3747aSAlexandre Ghiti     g_assert_not_reached();
4116df3747aSAlexandre Ghiti }
4126f23aaebSAlexandre Ghiti 
set_satp_mode_max_supported(RISCVCPU * cpu,uint8_t satp_mode)4136f23aaebSAlexandre Ghiti static void set_satp_mode_max_supported(RISCVCPU *cpu,
4146df3747aSAlexandre Ghiti                                         uint8_t satp_mode)
4156f23aaebSAlexandre Ghiti {
4166df3747aSAlexandre Ghiti     bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
4176df3747aSAlexandre Ghiti     const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
4186df3747aSAlexandre Ghiti 
4196f23aaebSAlexandre Ghiti     for (int i = 0; i <= satp_mode; ++i) {
4206f23aaebSAlexandre Ghiti         if (valid_vm[i]) {
4216df3747aSAlexandre Ghiti             cpu->cfg.satp_mode.supported |= (1 << i);
4226df3747aSAlexandre Ghiti         }
4236df3747aSAlexandre Ghiti     }
4246df3747aSAlexandre Ghiti }
4256df3747aSAlexandre Ghiti 
426d379c748SDaniel Henrique Barboza /* Set the satp mode to the max supported */
set_satp_mode_default_map(RISCVCPU * cpu)427d379c748SDaniel Henrique Barboza static void set_satp_mode_default_map(RISCVCPU *cpu)
428d379c748SDaniel Henrique Barboza {
429d379c748SDaniel Henrique Barboza     /*
430d379c748SDaniel Henrique Barboza      * Bare CPUs do not default to the max available.
431d379c748SDaniel Henrique Barboza      * Users must set a valid satp_mode in the command
432d379c748SDaniel Henrique Barboza      * line.
433d379c748SDaniel Henrique Barboza      */
434d379c748SDaniel Henrique Barboza     if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) {
435d379c748SDaniel Henrique Barboza         warn_report("No satp mode set. Defaulting to 'bare'");
436d379c748SDaniel Henrique Barboza         cpu->cfg.satp_mode.map = (1 << VM_1_10_MBARE);
4376df3747aSAlexandre Ghiti         return;
4386df3747aSAlexandre Ghiti     }
4396f23aaebSAlexandre Ghiti 
4406f23aaebSAlexandre Ghiti     cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
441dc5bd18fSMichael Clark }
442dc5bd18fSMichael Clark #endif
4437f0bdfb5SDaniel Henrique Barboza 
riscv_max_cpu_init(Object * obj)4447f0bdfb5SDaniel Henrique Barboza static void riscv_max_cpu_init(Object *obj)
445742cc269SAkihiko Odaki {
4466df3747aSAlexandre Ghiti     RISCVCPU *cpu = RISCV_CPU(obj);
4476df3747aSAlexandre Ghiti     CPURISCVState *env = &cpu->env;
4486df3747aSAlexandre Ghiti 
4496df3747aSAlexandre Ghiti     cpu->cfg.mmu = true;
4506df3747aSAlexandre Ghiti     cpu->cfg.pmp = true;
4516df3747aSAlexandre Ghiti 
4526df3747aSAlexandre Ghiti     env->priv_ver = PRIV_VERSION_LATEST;
453b9a2b98eSDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
4547f0bdfb5SDaniel Henrique Barboza     set_satp_mode_max_supported(RISCV_CPU(obj),
4557f0bdfb5SDaniel Henrique Barboza         riscv_cpu_mxl(&RISCV_CPU(obj)->env) == MXL_RV32 ?
45612b12a14SDaniel Henrique Barboza         VM_1_10_SV32 : VM_1_10_SV57);
457960b389bSDaniel Henrique Barboza #endif
4587f0bdfb5SDaniel Henrique Barboza }
4597f0bdfb5SDaniel Henrique Barboza 
460dc5bd18fSMichael Clark #if defined(TARGET_RISCV64)
rv64_base_cpu_init(Object * obj)461dc5bd18fSMichael Clark static void rv64_base_cpu_init(Object *obj)
462b97e5a6bSDaniel Henrique Barboza {
463b97e5a6bSDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
464b97e5a6bSDaniel Henrique Barboza     CPURISCVState *env = &cpu->env;
465b97e5a6bSDaniel Henrique Barboza 
466b97e5a6bSDaniel Henrique Barboza     cpu->cfg.mmu = true;
467d06f28dbSDaniel Henrique Barboza     cpu->cfg.pmp = true;
46811097be4SDaniel Henrique Barboza 
469d06f28dbSDaniel Henrique Barboza     /* Set latest version of privileged specification */
470b97e5a6bSDaniel Henrique Barboza     env->priv_ver = PRIV_VERSION_LATEST;
471b97e5a6bSDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
472742cc269SAkihiko Odaki     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
473742cc269SAkihiko Odaki #endif
474742cc269SAkihiko Odaki }
475742cc269SAkihiko Odaki 
rv64_sifive_u_cpu_init(Object * obj)476742cc269SAkihiko Odaki static void rv64_sifive_u_cpu_init(Object *obj)
477b97e5a6bSDaniel Henrique Barboza {
478b97e5a6bSDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
479b97e5a6bSDaniel Henrique Barboza     CPURISCVState *env = &cpu->env;
480094b072cSAlistair Francis     riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
481094b072cSAlistair Francis     env->priv_ver = PRIV_VERSION_1_10_0;
4828903bf6eSAlistair Francis #ifndef CONFIG_USER_ONLY
483d06f28dbSDaniel Henrique Barboza     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
484d06f28dbSDaniel Henrique Barboza #endif
485d06f28dbSDaniel Henrique Barboza 
486d06f28dbSDaniel Henrique Barboza     /* inherited from parent obj via riscv_cpu_init() */
48711097be4SDaniel Henrique Barboza     cpu->cfg.ext_zifencei = true;
488d06f28dbSDaniel Henrique Barboza     cpu->cfg.ext_zicsr = true;
48918800095SAnup Patel     cpu->cfg.mmu = true;
490b9a2b98eSDaniel Henrique Barboza     cpu->cfg.pmp = true;
4916df3747aSAlexandre Ghiti }
4926df3747aSAlexandre Ghiti 
rv64_sifive_e_cpu_init(Object * obj)4936df3747aSAlexandre Ghiti static void rv64_sifive_e_cpu_init(Object *obj)
4948903bf6eSAlistair Francis {
4958903bf6eSAlistair Francis     CPURISCVState *env = &RISCV_CPU(obj)->env;
496114baacaSAlistair Francis     RISCVCPU *cpu = RISCV_CPU(obj);
497dc5bd18fSMichael Clark 
4987f0bdfb5SDaniel Henrique Barboza     riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVC | RVU);
4997f0bdfb5SDaniel Henrique Barboza     env->priv_ver = PRIV_VERSION_1_10_0;
500742cc269SAkihiko Odaki #ifndef CONFIG_USER_ONLY
5018c6eeb50SDaniel Henrique Barboza     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
5026df3747aSAlexandre Ghiti #endif
5036df3747aSAlexandre Ghiti 
5046df3747aSAlexandre Ghiti     /* inherited from parent obj via riscv_cpu_init() */
5057f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_zifencei = true;
5067f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_zicsr = true;
50712b12a14SDaniel Henrique Barboza     cpu->cfg.pmp = true;
508960b389bSDaniel Henrique Barboza }
5097f0bdfb5SDaniel Henrique Barboza 
rv64_thead_c906_cpu_init(Object * obj)5107f0bdfb5SDaniel Henrique Barboza static void rv64_thead_c906_cpu_init(Object *obj)
511dc5bd18fSMichael Clark {
512dc5bd18fSMichael Clark     CPURISCVState *env = &RISCV_CPU(obj)->env;
513114baacaSAlistair Francis     RISCVCPU *cpu = RISCV_CPU(obj);
514d8e72bd1SBin Meng 
515d8e72bd1SBin Meng     riscv_cpu_set_misa_ext(env, RVG | RVC | RVS | RVU);
51626b2bc58SAlistair Francis     env->priv_ver = PRIV_VERSION_1_11_0;
51726b2bc58SAlistair Francis 
518742cc269SAkihiko Odaki     cpu->cfg.ext_zfa = true;
5198c6eeb50SDaniel Henrique Barboza     cpu->cfg.ext_zfh = true;
5206df3747aSAlexandre Ghiti     cpu->cfg.mmu = true;
5216df3747aSAlexandre Ghiti     cpu->cfg.ext_xtheadba = true;
5226df3747aSAlexandre Ghiti     cpu->cfg.ext_xtheadbb = true;
5237f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_xtheadbs = true;
5247f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_xtheadcmo = true;
52512b12a14SDaniel Henrique Barboza     cpu->cfg.ext_xtheadcondmov = true;
526960b389bSDaniel Henrique Barboza     cpu->cfg.ext_xtheadfmemidx = true;
5277f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_xtheadmac = true;
528d8e72bd1SBin Meng     cpu->cfg.ext_xtheadmemidx = true;
529332dab68SFrédéric Pétrot     cpu->cfg.ext_xtheadmempair = true;
53095bd8daaSChristoph Müllner     cpu->cfg.ext_xtheadsync = true;
53195bd8daaSChristoph Müllner 
53295bd8daaSChristoph Müllner     cpu->cfg.mvendorid = THEAD_VENDOR_ID;
53395bd8daaSChristoph Müllner #ifndef CONFIG_USER_ONLY
53495bd8daaSChristoph Müllner     set_satp_mode_max_supported(cpu, VM_1_10_SV39);
535742cc269SAkihiko Odaki     th_register_custom_csrs(cpu);
5368c6eeb50SDaniel Henrique Barboza #endif
53795bd8daaSChristoph Müllner 
538a47842d1SChristoph Müllner     /* inherited from parent obj via riscv_cpu_init() */
53995bd8daaSChristoph Müllner     cpu->cfg.pmp = true;
54095bd8daaSChristoph Müllner }
54195bd8daaSChristoph Müllner 
rv64_veyron_v1_cpu_init(Object * obj)54295bd8daaSChristoph Müllner static void rv64_veyron_v1_cpu_init(Object *obj)
54395bd8daaSChristoph Müllner {
54495bd8daaSChristoph Müllner     CPURISCVState *env = &RISCV_CPU(obj)->env;
54595bd8daaSChristoph Müllner     RISCVCPU *cpu = RISCV_CPU(obj);
54695bd8daaSChristoph Müllner 
54795bd8daaSChristoph Müllner     riscv_cpu_set_misa_ext(env, RVG | RVC | RVS | RVU | RVH);
54895bd8daaSChristoph Müllner     env->priv_ver = PRIV_VERSION_1_12_0;
54995bd8daaSChristoph Müllner 
55095bd8daaSChristoph Müllner     /* Enable ISA extensions */
55195bd8daaSChristoph Müllner     cpu->cfg.mmu = true;
55295bd8daaSChristoph Müllner     cpu->cfg.ext_zifencei = true;
5536df3747aSAlexandre Ghiti     cpu->cfg.ext_zicsr = true;
5546df3747aSAlexandre Ghiti     cpu->cfg.pmp = true;
555fd53ee26SChristoph Müllner     cpu->cfg.ext_zicbom = true;
5566df3747aSAlexandre Ghiti     cpu->cfg.cbom_blocksize = 64;
5577f0bdfb5SDaniel Henrique Barboza     cpu->cfg.cboz_blocksize = 64;
5587f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_zicboz = true;
5597f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_smaia = true;
56095bd8daaSChristoph Müllner     cpu->cfg.ext_ssaia = true;
56195bd8daaSChristoph Müllner     cpu->cfg.ext_sscofpmf = true;
562e1d084a8SRahul Pathak     cpu->cfg.ext_sstc = true;
563e1d084a8SRahul Pathak     cpu->cfg.ext_svinval = true;
564e1d084a8SRahul Pathak     cpu->cfg.ext_svnapot = true;
565e1d084a8SRahul Pathak     cpu->cfg.ext_svpbmt = true;
566e1d084a8SRahul Pathak     cpu->cfg.ext_smstateen = true;
567742cc269SAkihiko Odaki     cpu->cfg.ext_zba = true;
568e1d084a8SRahul Pathak     cpu->cfg.ext_zbb = true;
569e1d084a8SRahul Pathak     cpu->cfg.ext_zbc = true;
570e1d084a8SRahul Pathak     cpu->cfg.ext_zbs = true;
571e1d084a8SRahul Pathak     cpu->cfg.ext_XVentanaCondOps = true;
57212b12a14SDaniel Henrique Barboza 
573960b389bSDaniel Henrique Barboza     cpu->cfg.mvendorid = VEYRON_V1_MVENDORID;
574029f5feeSDaniel Henrique Barboza     cpu->cfg.marchid = VEYRON_V1_MARCHID;
575a326a2b0SDaniel Henrique Barboza     cpu->cfg.mimpid = VEYRON_V1_MIMPID;
576e1d084a8SRahul Pathak 
577e1d084a8SRahul Pathak #ifndef CONFIG_USER_ONLY
578e57039ddSDaniel Henrique Barboza     set_satp_mode_max_supported(cpu, VM_1_10_SV48);
579e1d084a8SRahul Pathak #endif
580e1d084a8SRahul Pathak }
581e1d084a8SRahul Pathak 
582e1d084a8SRahul Pathak #ifdef CONFIG_TCG
rv128_base_cpu_init(Object * obj)583e1d084a8SRahul Pathak static void rv128_base_cpu_init(Object *obj)
584e1d084a8SRahul Pathak {
585e1d084a8SRahul Pathak     RISCVCPU *cpu = RISCV_CPU(obj);
586e1d084a8SRahul Pathak     CPURISCVState *env = &cpu->env;
587e1d084a8SRahul Pathak 
588e1d084a8SRahul Pathak     if (qemu_tcg_mttcg_enabled()) {
589e1d084a8SRahul Pathak         /* Missing 128-bit aligned atomics */
590e1d084a8SRahul Pathak         error_report("128-bit RISC-V currently does not work with Multi "
591e1d084a8SRahul Pathak                      "Threaded TCG. Please use: -accel tcg,thread=single");
592e1d084a8SRahul Pathak         exit(EXIT_FAILURE);
593e1d084a8SRahul Pathak     }
594e1d084a8SRahul Pathak 
595e1d084a8SRahul Pathak     cpu->cfg.mmu = true;
596e1d084a8SRahul Pathak     cpu->cfg.pmp = true;
597e1d084a8SRahul Pathak 
598e1d084a8SRahul Pathak     /* Set latest version of privileged specification */
599e1d084a8SRahul Pathak     env->priv_ver = PRIV_VERSION_LATEST;
600e1d084a8SRahul Pathak #ifndef CONFIG_USER_ONLY
601e1d084a8SRahul Pathak     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
60214482b13SPhilippe Mathieu-Daudé #endif
603332dab68SFrédéric Pétrot }
604332dab68SFrédéric Pétrot #endif /* CONFIG_TCG */
605d06f28dbSDaniel Henrique Barboza 
rv64i_bare_cpu_init(Object * obj)606d06f28dbSDaniel Henrique Barboza static void rv64i_bare_cpu_init(Object *obj)
607d06f28dbSDaniel Henrique Barboza {
608332dab68SFrédéric Pétrot     CPURISCVState *env = &RISCV_CPU(obj)->env;
609332dab68SFrédéric Pétrot     riscv_cpu_set_misa_ext(env, RVI);
610332dab68SFrédéric Pétrot }
611332dab68SFrédéric Pétrot 
rv64e_bare_cpu_init(Object * obj)612332dab68SFrédéric Pétrot static void rv64e_bare_cpu_init(Object *obj)
613332dab68SFrédéric Pétrot {
614d06f28dbSDaniel Henrique Barboza     CPURISCVState *env = &RISCV_CPU(obj)->env;
615d06f28dbSDaniel Henrique Barboza     riscv_cpu_set_misa_ext(env, RVE);
61611097be4SDaniel Henrique Barboza }
617d06f28dbSDaniel Henrique Barboza 
61818800095SAnup Patel #endif /* !TARGET_RISCV64 */
619b9a2b98eSDaniel Henrique Barboza 
6206df3747aSAlexandre Ghiti #if defined(TARGET_RISCV32) || \
6216df3747aSAlexandre Ghiti     (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
6226df3747aSAlexandre Ghiti 
rv32_base_cpu_init(Object * obj)623332dab68SFrédéric Pétrot static void rv32_base_cpu_init(Object *obj)
62414482b13SPhilippe Mathieu-Daudé {
625d379c748SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
626d379c748SDaniel Henrique Barboza     CPURISCVState *env = &cpu->env;
627d379c748SDaniel Henrique Barboza 
628d379c748SDaniel Henrique Barboza     cpu->cfg.mmu = true;
629742cc269SAkihiko Odaki     cpu->cfg.pmp = true;
630d379c748SDaniel Henrique Barboza 
631deb0ff0cSDaniel Henrique Barboza     /* Set latest version of privileged specification */
632deb0ff0cSDaniel Henrique Barboza     env->priv_ver = PRIV_VERSION_LATEST;
633deb0ff0cSDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
634deb0ff0cSDaniel Henrique Barboza     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
635deb0ff0cSDaniel Henrique Barboza #endif
636deb0ff0cSDaniel Henrique Barboza }
63714482b13SPhilippe Mathieu-Daudé 
rv32_sifive_u_cpu_init(Object * obj)63814482b13SPhilippe Mathieu-Daudé static void rv32_sifive_u_cpu_init(Object *obj)
63914482b13SPhilippe Mathieu-Daudé {
640094b072cSAlistair Francis     RISCVCPU *cpu = RISCV_CPU(obj);
641094b072cSAlistair Francis     CPURISCVState *env = &cpu->env;
642d06f28dbSDaniel Henrique Barboza     riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
643d06f28dbSDaniel Henrique Barboza     env->priv_ver = PRIV_VERSION_1_10_0;
644d06f28dbSDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
645d06f28dbSDaniel Henrique Barboza     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
64611097be4SDaniel Henrique Barboza #endif
647d06f28dbSDaniel Henrique Barboza 
64818800095SAnup Patel     /* inherited from parent obj via riscv_cpu_init() */
649b9a2b98eSDaniel Henrique Barboza     cpu->cfg.ext_zifencei = true;
6506df3747aSAlexandre Ghiti     cpu->cfg.ext_zicsr = true;
6516df3747aSAlexandre Ghiti     cpu->cfg.mmu = true;
6526df3747aSAlexandre Ghiti     cpu->cfg.pmp = true;
653094b072cSAlistair Francis }
654094b072cSAlistair Francis 
rv32_sifive_e_cpu_init(Object * obj)655114baacaSAlistair Francis static void rv32_sifive_e_cpu_init(Object *obj)
656114baacaSAlistair Francis {
6577f0bdfb5SDaniel Henrique Barboza     CPURISCVState *env = &RISCV_CPU(obj)->env;
6587f0bdfb5SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
659742cc269SAkihiko Odaki 
6608c6eeb50SDaniel Henrique Barboza     riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVC | RVU);
6616df3747aSAlexandre Ghiti     env->priv_ver = PRIV_VERSION_1_10_0;
6626df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY
6636df3747aSAlexandre Ghiti     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
6647f0bdfb5SDaniel Henrique Barboza #endif
6657f0bdfb5SDaniel Henrique Barboza 
66612b12a14SDaniel Henrique Barboza     /* inherited from parent obj via riscv_cpu_init() */
667960b389bSDaniel Henrique Barboza     cpu->cfg.ext_zifencei = true;
6687f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_zicsr = true;
6697f0bdfb5SDaniel Henrique Barboza     cpu->cfg.pmp = true;
670114baacaSAlistair Francis }
671d8e72bd1SBin Meng 
rv32_ibex_cpu_init(Object * obj)672114baacaSAlistair Francis static void rv32_ibex_cpu_init(Object *obj)
673114baacaSAlistair Francis {
674114baacaSAlistair Francis     CPURISCVState *env = &RISCV_CPU(obj)->env;
67526b2bc58SAlistair Francis     RISCVCPU *cpu = RISCV_CPU(obj);
67626b2bc58SAlistair Francis 
677742cc269SAkihiko Odaki     riscv_cpu_set_misa_ext(env, RVI | RVM | RVC | RVU);
6788c6eeb50SDaniel Henrique Barboza     env->priv_ver = PRIV_VERSION_1_12_0;
6796df3747aSAlexandre Ghiti #ifndef CONFIG_USER_ONLY
6806df3747aSAlexandre Ghiti     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
6816df3747aSAlexandre Ghiti #endif
6827f0bdfb5SDaniel Henrique Barboza     /* inherited from parent obj via riscv_cpu_init() */
6837f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_zifencei = true;
68412b12a14SDaniel Henrique Barboza     cpu->cfg.ext_zicsr = true;
685960b389bSDaniel Henrique Barboza     cpu->cfg.pmp = true;
6867f0bdfb5SDaniel Henrique Barboza     cpu->cfg.ext_smepmp = true;
687114baacaSAlistair Francis 
6884c56793fSBin Meng     cpu->cfg.ext_zba = true;
689e8905c6cSBin Meng     cpu->cfg.ext_zbb = true;
69036b80ad9SAlistair Francis     cpu->cfg.ext_zbc = true;
69136b80ad9SAlistair Francis     cpu->cfg.ext_zbs = true;
69226b2bc58SAlistair Francis }
69326b2bc58SAlistair Francis 
rv32_imafcu_nommu_cpu_init(Object * obj)694742cc269SAkihiko Odaki static void rv32_imafcu_nommu_cpu_init(Object *obj)
695c541b07dSAlistair Francis {
6966df3747aSAlexandre Ghiti     CPURISCVState *env = &RISCV_CPU(obj)->env;
6976df3747aSAlexandre Ghiti     RISCVCPU *cpu = RISCV_CPU(obj);
6986df3747aSAlexandre Ghiti 
6997f0bdfb5SDaniel Henrique Barboza     riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVF | RVC | RVU);
70012b12a14SDaniel Henrique Barboza     env->priv_ver = PRIV_VERSION_1_10_0;
701960b389bSDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
7027f0bdfb5SDaniel Henrique Barboza     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
703095fe72aSHimanshu Chauhan #endif
70436b80ad9SAlistair Francis 
70536b80ad9SAlistair Francis     /* inherited from parent obj via riscv_cpu_init() */
7062fdd2c09SBin Meng     cpu->cfg.ext_zifencei = true;
707d784733bSCorey Wharton     cpu->cfg.ext_zicsr = true;
708d784733bSCorey Wharton     cpu->cfg.pmp = true;
70926b2bc58SAlistair Francis }
71026b2bc58SAlistair Francis 
rv32i_bare_cpu_init(Object * obj)711742cc269SAkihiko Odaki static void rv32i_bare_cpu_init(Object *obj)
7128c6eeb50SDaniel Henrique Barboza {
7136df3747aSAlexandre Ghiti     CPURISCVState *env = &RISCV_CPU(obj)->env;
7146df3747aSAlexandre Ghiti     riscv_cpu_set_misa_ext(env, RVI);
7156df3747aSAlexandre Ghiti }
7167f0bdfb5SDaniel Henrique Barboza 
rv32e_bare_cpu_init(Object * obj)7177f0bdfb5SDaniel Henrique Barboza static void rv32e_bare_cpu_init(Object *obj)
71812b12a14SDaniel Henrique Barboza {
719960b389bSDaniel Henrique Barboza     CPURISCVState *env = &RISCV_CPU(obj)->env;
7207f0bdfb5SDaniel Henrique Barboza     riscv_cpu_set_misa_ext(env, RVE);
721d784733bSCorey Wharton }
722deb0ff0cSDaniel Henrique Barboza #endif
723deb0ff0cSDaniel Henrique Barboza 
riscv_cpu_class_by_name(const char * cpu_model)724deb0ff0cSDaniel Henrique Barboza static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
725deb0ff0cSDaniel Henrique Barboza {
726deb0ff0cSDaniel Henrique Barboza     ObjectClass *oc;
727deb0ff0cSDaniel Henrique Barboza     char *typename;
728deb0ff0cSDaniel Henrique Barboza     char **cpuname;
729deb0ff0cSDaniel Henrique Barboza 
730deb0ff0cSDaniel Henrique Barboza     cpuname = g_strsplit(cpu_model, ",", 1);
731deb0ff0cSDaniel Henrique Barboza     typename = g_strdup_printf(RISCV_CPU_TYPE_NAME("%s"), cpuname[0]);
732deb0ff0cSDaniel Henrique Barboza     oc = object_class_by_name(typename);
733deb0ff0cSDaniel Henrique Barboza     g_strfreev(cpuname);
734eab15862SMichael Clark     g_free(typename);
735dc5bd18fSMichael Clark 
736dc5bd18fSMichael Clark     return oc;
737dc5bd18fSMichael Clark }
738dc5bd18fSMichael Clark 
riscv_cpu_get_name(RISCVCPU * cpu)739dc5bd18fSMichael Clark char *riscv_cpu_get_name(RISCVCPU *cpu)
740dc5bd18fSMichael Clark {
741dc5bd18fSMichael Clark     RISCVCPUClass *rcc = RISCV_CPU_GET_CLASS(cpu);
742dc5bd18fSMichael Clark     const char *typename = object_class_get_name(OBJECT_CLASS(rcc));
743dc5bd18fSMichael Clark 
744dc5bd18fSMichael Clark     g_assert(g_str_has_suffix(typename, RISCV_CPU_TYPE_SUFFIX));
745dc5bd18fSMichael Clark 
746dc5bd18fSMichael Clark     return cpu_model_from_type(typename);
747d5be19f5SPhilippe Mathieu-Daudé }
748dc5bd18fSMichael Clark 
riscv_cpu_dump_state(CPUState * cs,FILE * f,int flags)749dc5bd18fSMichael Clark static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
750dc5bd18fSMichael Clark {
751b933720bSDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(cs);
752b933720bSDaniel Henrique Barboza     CPURISCVState *env = &cpu->env;
753b933720bSDaniel Henrique Barboza     int i, j;
754b933720bSDaniel Henrique Barboza     uint8_t *p;
755b933720bSDaniel Henrique Barboza 
756b933720bSDaniel Henrique Barboza #if !defined(CONFIG_USER_ONLY)
757b933720bSDaniel Henrique Barboza     if (riscv_has_ext(env, RVH)) {
7584b26aa9fSGavin Shan         qemu_fprintf(f, " %s %d\n", "V      =  ", env->virt_enabled);
759b933720bSDaniel Henrique Barboza     }
760b933720bSDaniel Henrique Barboza #endif
76190c84c56SMarkus Armbruster     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc      ", env->pc);
762dc5bd18fSMichael Clark #ifndef CONFIG_USER_ONLY
763dc5bd18fSMichael Clark     {
764dc5bd18fSMichael Clark         static const int dump_csrs[] = {
765b227f6a8SIvan Klokov             CSR_MHARTID,
766b227f6a8SIvan Klokov             CSR_MSTATUS,
767dc5bd18fSMichael Clark             CSR_MSTATUSH,
768df30e652SAlistair Francis             /*
769df30e652SAlistair Francis              * CSR_SSTATUS is intentionally omitted here as its value
77038256529SWeiwei Li              * can be figured out by looking at CSR_MSTATUS
771df30e652SAlistair Francis              */
772df30e652SAlistair Francis             CSR_HSTATUS,
77390c84c56SMarkus Armbruster             CSR_VSSTATUS,
774dc5bd18fSMichael Clark             CSR_MIP,
775665b90d8SRichard Henderson             CSR_MIE,
776665b90d8SRichard Henderson             CSR_MIDELEG,
777665b90d8SRichard Henderson             CSR_HIDELEG,
778665b90d8SRichard Henderson             CSR_MEDELEG,
779665b90d8SRichard Henderson             CSR_HEDELEG,
780bc7dca13SBin Meng             CSR_MTVEC,
781bc7dca13SBin Meng             CSR_STVEC,
782bc7dca13SBin Meng             CSR_VSTVEC,
783bc7dca13SBin Meng             CSR_MEPC,
784665b90d8SRichard Henderson             CSR_SEPC,
785665b90d8SRichard Henderson             CSR_VSEPC,
786665b90d8SRichard Henderson             CSR_MCAUSE,
787665b90d8SRichard Henderson             CSR_SCAUSE,
788665b90d8SRichard Henderson             CSR_VSCAUSE,
789665b90d8SRichard Henderson             CSR_MTVAL,
790665b90d8SRichard Henderson             CSR_STVAL,
791665b90d8SRichard Henderson             CSR_HTVAL,
792665b90d8SRichard Henderson             CSR_MTVAL2,
793665b90d8SRichard Henderson             CSR_MSCRATCH,
794665b90d8SRichard Henderson             CSR_SSCRATCH,
795665b90d8SRichard Henderson             CSR_SATP,
796665b90d8SRichard Henderson             CSR_MMTE,
797665b90d8SRichard Henderson             CSR_UPMBASE,
798665b90d8SRichard Henderson             CSR_UPMMASK,
799665b90d8SRichard Henderson             CSR_SPMBASE,
800665b90d8SRichard Henderson             CSR_SPMMASK,
801665b90d8SRichard Henderson             CSR_MPMBASE,
802665b90d8SRichard Henderson             CSR_MPMMASK,
803665b90d8SRichard Henderson         };
804665b90d8SRichard Henderson 
805665b90d8SRichard Henderson         for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
806665b90d8SRichard Henderson             int csrno = dump_csrs[i];
807665b90d8SRichard Henderson             target_ulong val = 0;
808bd5594caSAlexey Baturo             RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
809bd5594caSAlexey Baturo 
810bd5594caSAlexey Baturo             /*
811bd5594caSAlexey Baturo              * Rely on the smode, hmode, etc, predicates within csr.c
812bd5594caSAlexey Baturo              * to do the filtering of the registers that are present.
813bd5594caSAlexey Baturo              */
814bd5594caSAlexey Baturo             if (res == RISCV_EXCP_NONE) {
815665b90d8SRichard Henderson                 qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n",
816665b90d8SRichard Henderson                              csr_ops[csrno].name, val);
81729332994SAlistair Francis             }
818665b90d8SRichard Henderson         }
819665b90d8SRichard Henderson     }
820665b90d8SRichard Henderson #endif
821665b90d8SRichard Henderson 
822665b90d8SRichard Henderson     for (i = 0; i < 32; i++) {
823665b90d8SRichard Henderson         qemu_fprintf(f, " %-8s " TARGET_FMT_lx,
824665b90d8SRichard Henderson                      riscv_int_regnames[i], env->gpr[i]);
825665b90d8SRichard Henderson         if ((i & 3) == 3) {
826665b90d8SRichard Henderson             qemu_fprintf(f, "\n");
827665b90d8SRichard Henderson         }
828665b90d8SRichard Henderson     }
8295c5a47f1SAlistair Francis     if (flags & CPU_DUMP_FPU) {
830df30e652SAlistair Francis         target_ulong val = 0;
831df30e652SAlistair Francis         RISCVException res = riscv_csrrw_debug(env, CSR_FCSR, &val, 0, 0);
832dc5bd18fSMichael Clark         if (res == RISCV_EXCP_NONE) {
833dc5bd18fSMichael Clark             qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n",
834dc5bd18fSMichael Clark                     csr_ops[CSR_FCSR].name, val);
835e573a7f3STravis Geiselbrecht         }
836dc5bd18fSMichael Clark         for (i = 0; i < 32; i++) {
837dc5bd18fSMichael Clark             qemu_fprintf(f, " %-8s %016" PRIx64,
83890c84c56SMarkus Armbruster                          riscv_fpr_regnames[i], env->fpr[i]);
839dc5bd18fSMichael Clark             if ((i & 3) == 3) {
840dc5bd18fSMichael Clark                 qemu_fprintf(f, "\n");
84186ea1880SRichard Henderson             }
842dc5bd18fSMichael Clark         }
843e573a7f3STravis Geiselbrecht     }
844dc5bd18fSMichael Clark     if (riscv_has_ext(env, RVV) && (flags & CPU_DUMP_VPU)) {
845dc5bd18fSMichael Clark         static const int dump_rvv_csrs[] = {
84690c84c56SMarkus Armbruster                     CSR_VSTART,
847dc5bd18fSMichael Clark                     CSR_VXSAT,
848dc5bd18fSMichael Clark                     CSR_VXRM,
849dc5bd18fSMichael Clark                     CSR_VCSR,
850b227f6a8SIvan Klokov                     CSR_VL,
851b227f6a8SIvan Klokov                     CSR_VTYPE,
852b227f6a8SIvan Klokov                     CSR_VLENB,
853b227f6a8SIvan Klokov                 };
854b227f6a8SIvan Klokov         for (i = 0; i < ARRAY_SIZE(dump_rvv_csrs); ++i) {
855b227f6a8SIvan Klokov             int csrno = dump_rvv_csrs[i];
856b227f6a8SIvan Klokov             target_ulong val = 0;
857b227f6a8SIvan Klokov             RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
858b227f6a8SIvan Klokov 
859b227f6a8SIvan Klokov             /*
86029332994SAlistair Francis              * Rely on the smode, hmode, etc, predicates within csr.c
861b227f6a8SIvan Klokov              * to do the filtering of the registers that are present.
862b227f6a8SIvan Klokov              */
863b227f6a8SIvan Klokov             if (res == RISCV_EXCP_NONE) {
864b227f6a8SIvan Klokov                 qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n",
865b227f6a8SIvan Klokov                              csr_ops[csrno].name, val);
866b227f6a8SIvan Klokov             }
867b227f6a8SIvan Klokov         }
868b227f6a8SIvan Klokov         uint16_t vlenb = cpu->cfg.vlenb;
869b227f6a8SIvan Klokov 
870b227f6a8SIvan Klokov         for (i = 0; i < 32; i++) {
871b227f6a8SIvan Klokov             qemu_fprintf(f, " %-8s ", riscv_rvv_regnames[i]);
872b227f6a8SIvan Klokov             p = (uint8_t *)env->vreg;
873b227f6a8SIvan Klokov             for (j = vlenb - 1 ; j >= 0; j--) {
87404eb30a0SDaniel Henrique Barboza                 qemu_fprintf(f, "%02x", *(p + i * vlenb + BYTE(j)));
875b227f6a8SIvan Klokov             }
876b227f6a8SIvan Klokov             qemu_fprintf(f, "\n");
877b227f6a8SIvan Klokov         }
878b227f6a8SIvan Klokov     }
879b227f6a8SIvan Klokov }
880b227f6a8SIvan Klokov 
riscv_cpu_set_pc(CPUState * cs,vaddr value)881b227f6a8SIvan Klokov static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
882b227f6a8SIvan Klokov {
883b227f6a8SIvan Klokov     RISCVCPU *cpu = RISCV_CPU(cs);
884b227f6a8SIvan Klokov     CPURISCVState *env = &cpu->env;
88586ea1880SRichard Henderson 
886dc5bd18fSMichael Clark     if (env->xl == MXL_RV32) {
887dc5bd18fSMichael Clark         env->pc = (int32_t)value;
888dc5bd18fSMichael Clark     } else {
889dc5bd18fSMichael Clark         env->pc = value;
890dc5bd18fSMichael Clark     }
891bf9e776eSLIU Zhiwei }
892bf9e776eSLIU Zhiwei 
riscv_cpu_get_pc(CPUState * cs)893bf9e776eSLIU Zhiwei static vaddr riscv_cpu_get_pc(CPUState *cs)
894bf9e776eSLIU Zhiwei {
895dc5bd18fSMichael Clark     RISCVCPU *cpu = RISCV_CPU(cs);
896dc5bd18fSMichael Clark     CPURISCVState *env = &cpu->env;
897bf9e776eSLIU Zhiwei 
898dc5bd18fSMichael Clark     /* Match cpu_get_tb_cpu_state. */
899e4fdf9dfSRichard Henderson     if (env->xl == MXL_RV32) {
900e4fdf9dfSRichard Henderson         return env->pc & UINT32_MAX;
901e4fdf9dfSRichard Henderson     }
902e4fdf9dfSRichard Henderson     return env->pc;
903e4fdf9dfSRichard Henderson }
904e4fdf9dfSRichard Henderson 
riscv_cpu_has_work(CPUState * cs)905e4fdf9dfSRichard Henderson bool riscv_cpu_has_work(CPUState *cs)
906e4fdf9dfSRichard Henderson {
907e4fdf9dfSRichard Henderson #ifndef CONFIG_USER_ONLY
908e4fdf9dfSRichard Henderson     RISCVCPU *cpu = RISCV_CPU(cs);
909e4fdf9dfSRichard Henderson     CPURISCVState *env = &cpu->env;
910e4fdf9dfSRichard Henderson     /*
9114f7b1ecbSPeter Maydell      * Definition of the WFI instruction requires it to ignore the privilege
912dc5bd18fSMichael Clark      * mode and delegation registers, but respect individual enables
913dc5bd18fSMichael Clark      */
914dc5bd18fSMichael Clark     return riscv_cpu_all_pending(env) != 0 ||
915dc5bd18fSMichael Clark         riscv_cpu_sirq_pending(env) != RISCV_EXCP_NONE ||
916dc5bd18fSMichael Clark         riscv_cpu_vsirq_pending(env) != RISCV_EXCP_NONE;
917dc5bd18fSMichael Clark #else
918dc5bd18fSMichael Clark     return true;
919dc5bd18fSMichael Clark #endif
9201697837eSRajnesh Kanwal }
92140336d5bSRajnesh Kanwal 
riscv_cpu_mmu_index(CPUState * cs,bool ifetch)92240336d5bSRajnesh Kanwal static int riscv_cpu_mmu_index(CPUState *cs, bool ifetch)
923dc5bd18fSMichael Clark {
924dc5bd18fSMichael Clark     return riscv_env_mmu_index(cpu_env(cs), ifetch);
925dc5bd18fSMichael Clark }
926dc5bd18fSMichael Clark 
riscv_cpu_reset_hold(Object * obj,ResetType type)927dc5bd18fSMichael Clark static void riscv_cpu_reset_hold(Object *obj, ResetType type)
928a5c77974SRichard Henderson {
929a5c77974SRichard Henderson #ifndef CONFIG_USER_ONLY
930a5c77974SRichard Henderson     uint8_t iprio;
931a5c77974SRichard Henderson     int i, irq, rdzero;
932a5c77974SRichard Henderson #endif
933ad80e367SPeter Maydell     CPUState *cs = CPU(obj);
934dc5bd18fSMichael Clark     RISCVCPU *cpu = RISCV_CPU(cs);
93543dc93afSAnup Patel     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(obj);
93643dc93afSAnup Patel     CPURISCVState *env = &cpu->env;
93743dc93afSAnup Patel 
93843dc93afSAnup Patel     if (mcc->parent_phases.hold) {
9394fa485a7SPeter Maydell         mcc->parent_phases.hold(obj, type);
940dc5bd18fSMichael Clark     }
941348802b5SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY
942dc5bd18fSMichael Clark     env->misa_mxl = mcc->misa_mxl_max;
943dc5bd18fSMichael Clark     env->priv = PRV_M;
9444fa485a7SPeter Maydell     env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
945ad80e367SPeter Maydell     if (env->misa_mxl > MXL_RV32) {
9464fa485a7SPeter Maydell         /*
947dc5bd18fSMichael Clark          * The reset status of SXL/UXL is undefined, but mstatus is WARL
948742cc269SAkihiko Odaki          * and we must ensure that the value after init is valid for read.
949dc5bd18fSMichael Clark          */
950dc5bd18fSMichael Clark         env->mstatus = set_field(env->mstatus, MSTATUS64_SXL, env->misa_mxl);
95192371bd9SRichard Henderson         env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, env->misa_mxl);
95292371bd9SRichard Henderson         if (riscv_has_ext(env, RVH)) {
95392371bd9SRichard Henderson             env->vsstatus = set_field(env->vsstatus,
95492371bd9SRichard Henderson                                       MSTATUS64_SXL, env->misa_mxl);
95592371bd9SRichard Henderson             env->vsstatus = set_field(env->vsstatus,
95692371bd9SRichard Henderson                                       MSTATUS64_UXL, env->misa_mxl);
95792371bd9SRichard Henderson             env->mstatus_hs = set_field(env->mstatus_hs,
9585a2ae235SLIU Zhiwei                                         MSTATUS64_SXL, env->misa_mxl);
9595a2ae235SLIU Zhiwei             env->mstatus_hs = set_field(env->mstatus_hs,
9605a2ae235SLIU Zhiwei                                         MSTATUS64_UXL, env->misa_mxl);
9615a2ae235SLIU Zhiwei         }
9625a2ae235SLIU Zhiwei     }
9635a2ae235SLIU Zhiwei     env->mcause = 0;
9645a2ae235SLIU Zhiwei     env->miclaim = MIP_SGEIP;
9655a2ae235SLIU Zhiwei     env->pc = env->resetvec;
9665a2ae235SLIU Zhiwei     env->bins = 0;
9675a2ae235SLIU Zhiwei     env->two_stage_lookup = false;
96892371bd9SRichard Henderson 
969dc5bd18fSMichael Clark     env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) |
970881df35dSAnup Patel                    (!cpu->cfg.ext_svade && cpu->cfg.ext_svadu ?
971dc5bd18fSMichael Clark                     MENVCFG_ADUE : 0);
97262cf0245SAnup Patel     env->henvcfg = 0;
973ec352d0cSGeorg Kotheimer 
97443dc93afSAnup Patel     /* Initialized default priorities of local interrupts. */
9750af3f115SWeiwei Li     for (i = 0; i < ARRAY_SIZE(env->miprio); i++) {
97670d22fd9SAndrew Jones         iprio = riscv_cpu_default_priority(i);
97770d22fd9SAndrew Jones         env->miprio[i] = (i == IRQ_M_EXT) ? 0 : iprio;
978148189ffSAndrew Jones         env->siprio[i] = (i == IRQ_S_EXT) ? 0 : iprio;
9797a6613daSWeiwei Li         env->hviprio[i] = 0;
98043dc93afSAnup Patel     }
98143dc93afSAnup Patel     i = 0;
98243dc93afSAnup Patel     while (!riscv_cpu_hviprio_index2irq(i, &irq, &rdzero)) {
98343dc93afSAnup Patel         if (!rdzero) {
98443dc93afSAnup Patel             env->hviprio[irq] = env->miprio[irq];
98543dc93afSAnup Patel         }
98643dc93afSAnup Patel         i++;
98743dc93afSAnup Patel     }
98843dc93afSAnup Patel     /* mmte is supposed to have pm.current hardwired to 1 */
98943dc93afSAnup Patel     env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT);
99043dc93afSAnup Patel 
99143dc93afSAnup Patel     /*
99243dc93afSAnup Patel      * Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor
99343dc93afSAnup Patel      * extension is enabled.
9944bbe8033SAlexey Baturo      */
99542967f40SLIU Zhiwei     if (riscv_has_ext(env, RVH)) {
9964bf501dcSMayuresh Chitale         env->mideleg |= HS_MODE_INTERRUPTS;
9974bf501dcSMayuresh Chitale     }
99871b76da3SAlistair Francis 
99971b76da3SAlistair Francis     /*
100071b76da3SAlistair Francis      * Clear mseccfg and unlock all the PMP entries upon reset.
100171b76da3SAlistair Francis      * This is allowed as per the priv and smepmp specifications
100271b76da3SAlistair Francis      * and is needed to clear stale entries across reboots.
100371b76da3SAlistair Francis      */
100471b76da3SAlistair Francis     if (riscv_cpu_cfg(env)->ext_smepmp) {
100571b76da3SAlistair Francis         env->mseccfg = 0;
10064bf501dcSMayuresh Chitale     }
10074bf501dcSMayuresh Chitale 
10084bf501dcSMayuresh Chitale     pmp_unlock_entries(env);
10094bf501dcSMayuresh Chitale #else
10104bf501dcSMayuresh Chitale     env->priv = PRV_U;
10114bf501dcSMayuresh Chitale     env->senvcfg = 0;
10124bf501dcSMayuresh Chitale     env->menvcfg = 0;
10134bf501dcSMayuresh Chitale #endif
10144bf501dcSMayuresh Chitale 
1015dc5bd18fSMichael Clark     /* on reset elp is clear */
1016440544e1SLIU Zhiwei     env->elp = false;
101740bfa5f6SLIU Zhiwei     /* on reset ssp is set to 0 */
1018330d2ae3SAlistair Francis     env->ssp = 0;
1019c13b169fSJoel Sing 
1020dc5bd18fSMichael Clark     env->xl = riscv_cpu_mxl(env);
1021*08c6ed47SRob Bradford     riscv_cpu_update_mask(env);
1022ad40be27SYifei Jiang     cs->exception_index = RISCV_EXCP_NONE;
1023ad40be27SYifei Jiang     env->load_res = -1;
1024cdfb2905SDaniel Henrique Barboza     set_default_nan_mode(1, &env->fp_status);
1025a7c272dfSAkihiko Odaki     env->vill = true;
1026b6092544SBin Meng 
1027b6092544SBin Meng #ifndef CONFIG_USER_ONLY
1028ad40be27SYifei Jiang     if (cpu->cfg.debug) {
1029ad40be27SYifei Jiang         riscv_trigger_reset_hold(env);
1030ad40be27SYifei Jiang     }
1031ad40be27SYifei Jiang 
1032dc5bd18fSMichael Clark     if (kvm_enabled()) {
1033dc5bd18fSMichael Clark         kvm_riscv_reset_vcpu(cpu);
1034dc5bd18fSMichael Clark     }
1035dc5bd18fSMichael Clark #endif
10365c5a47f1SAlistair Francis }
103794692c3aSLIU Zhiwei 
riscv_cpu_disas_set_info(CPUState * s,disassemble_info * info)1038454c2201SWeiwei Li static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
1039db23e5d9SRichard Henderson {
104094692c3aSLIU Zhiwei     RISCVCPU *cpu = RISCV_CPU(s);
1041db23e5d9SRichard Henderson     CPURISCVState *env = &cpu->env;
1042dc5bd18fSMichael Clark     info->target_info = &cpu->cfg;
1043db23e5d9SRichard Henderson 
1044db23e5d9SRichard Henderson     switch (env->xl) {
1045dc5bd18fSMichael Clark     case MXL_RV32:
1046db23e5d9SRichard Henderson         info->print_insn = print_insn_riscv32;
1047332dab68SFrédéric Pétrot         break;
1048332dab68SFrédéric Pétrot     case MXL_RV64:
1049332dab68SFrédéric Pétrot         info->print_insn = print_insn_riscv64;
1050db23e5d9SRichard Henderson         break;
1051db23e5d9SRichard Henderson     case MXL_RV128:
10525c5a47f1SAlistair Francis         info->print_insn = print_insn_riscv128;
1053dc5bd18fSMichael Clark         break;
1054dc5bd18fSMichael Clark     default:
10556f23aaebSAlexandre Ghiti         g_assert_not_reached();
10566f23aaebSAlexandre Ghiti     }
10576f23aaebSAlexandre Ghiti }
1058e7acc1cbSDaniel Henrique Barboza 
10593a2fc235SDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
riscv_cpu_satp_mode_finalize(RISCVCPU * cpu,Error ** errp)10603a2fc235SDaniel Henrique Barboza static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
10613a2fc235SDaniel Henrique Barboza {
10623a2fc235SDaniel Henrique Barboza     bool rv32 = riscv_cpu_is_32bit(cpu);
10633a2fc235SDaniel Henrique Barboza     uint8_t satp_mode_map_max, satp_mode_supported_max;
10643a2fc235SDaniel Henrique Barboza 
10653a2fc235SDaniel Henrique Barboza     /* The CPU wants the OS to decide which satp mode to use */
10663a2fc235SDaniel Henrique Barboza     if (cpu->cfg.satp_mode.supported == 0) {
10676df3747aSAlexandre Ghiti         return;
10686f23aaebSAlexandre Ghiti     }
10696f23aaebSAlexandre Ghiti 
10706f23aaebSAlexandre Ghiti     satp_mode_supported_max =
10716f23aaebSAlexandre Ghiti                     satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
10726f23aaebSAlexandre Ghiti 
10736f23aaebSAlexandre Ghiti     if (cpu->cfg.satp_mode.map == 0) {
10746f23aaebSAlexandre Ghiti         if (cpu->cfg.satp_mode.init == 0) {
10756f23aaebSAlexandre Ghiti             /* If unset by the user, we fallback to the default satp mode. */
10766f23aaebSAlexandre Ghiti             set_satp_mode_default_map(cpu);
10776f23aaebSAlexandre Ghiti         } else {
10786f23aaebSAlexandre Ghiti             /*
10796f23aaebSAlexandre Ghiti              * Find the lowest level that was disabled and then enable the
10806df3747aSAlexandre Ghiti              * first valid level below which can be found in
10816df3747aSAlexandre Ghiti              * valid_vm_1_10_32/64.
10826f23aaebSAlexandre Ghiti              */
10836df3747aSAlexandre Ghiti             for (int i = 1; i < 16; ++i) {
10846f23aaebSAlexandre Ghiti                 if ((cpu->cfg.satp_mode.init & (1 << i)) &&
10856f23aaebSAlexandre Ghiti                     (cpu->cfg.satp_mode.supported & (1 << i))) {
10866f23aaebSAlexandre Ghiti                     for (int j = i - 1; j >= 0; --j) {
10876f23aaebSAlexandre Ghiti                         if (cpu->cfg.satp_mode.supported & (1 << j)) {
10886f23aaebSAlexandre Ghiti                             cpu->cfg.satp_mode.map |= (1 << j);
10896f23aaebSAlexandre Ghiti                             break;
10906f23aaebSAlexandre Ghiti                         }
10916f23aaebSAlexandre Ghiti                     }
10926f23aaebSAlexandre Ghiti                     break;
10936f23aaebSAlexandre Ghiti                 }
10946df3747aSAlexandre Ghiti             }
10956df3747aSAlexandre Ghiti         }
10966df3747aSAlexandre Ghiti     }
10976df3747aSAlexandre Ghiti 
10986df3747aSAlexandre Ghiti     satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
10996df3747aSAlexandre Ghiti 
11006df3747aSAlexandre Ghiti     /* Make sure the user asked for a supported configuration (HW and qemu) */
11016f23aaebSAlexandre Ghiti     if (satp_mode_map_max > satp_mode_supported_max) {
11026f23aaebSAlexandre Ghiti         error_setg(errp, "satp_mode %s is higher than hw max capability %s",
11036f23aaebSAlexandre Ghiti                    satp_mode_str(satp_mode_map_max, rv32),
11046f23aaebSAlexandre Ghiti                    satp_mode_str(satp_mode_supported_max, rv32));
11056f23aaebSAlexandre Ghiti         return;
11066f23aaebSAlexandre Ghiti     }
11076f23aaebSAlexandre Ghiti 
11086f23aaebSAlexandre Ghiti     /*
11096df3747aSAlexandre Ghiti      * Make sure the user did not ask for an invalid configuration as per
11106f23aaebSAlexandre Ghiti      * the specification.
11116f23aaebSAlexandre Ghiti      */
11126df3747aSAlexandre Ghiti     if (!rv32) {
11136f23aaebSAlexandre Ghiti         for (int i = satp_mode_map_max - 1; i >= 0; --i) {
11146f23aaebSAlexandre Ghiti             if (!(cpu->cfg.satp_mode.map & (1 << i)) &&
11156df3747aSAlexandre Ghiti                 (cpu->cfg.satp_mode.init & (1 << i)) &&
11166f23aaebSAlexandre Ghiti                 (cpu->cfg.satp_mode.supported & (1 << i))) {
11176f23aaebSAlexandre Ghiti                 error_setg(errp, "cannot disable %s satp mode if %s "
11186f23aaebSAlexandre Ghiti                            "is enabled", satp_mode_str(i, false),
11196f23aaebSAlexandre Ghiti                            satp_mode_str(satp_mode_map_max, false));
11206f23aaebSAlexandre Ghiti                 return;
11216f23aaebSAlexandre Ghiti             }
11226df3747aSAlexandre Ghiti         }
11236df3747aSAlexandre Ghiti     }
11246f23aaebSAlexandre Ghiti 
11256f23aaebSAlexandre Ghiti     /* Finally expand the map so that all valid modes are set */
11266f23aaebSAlexandre Ghiti     for (int i = satp_mode_map_max - 1; i >= 0; --i) {
11276f23aaebSAlexandre Ghiti         if (cpu->cfg.satp_mode.supported & (1 << i)) {
11286f23aaebSAlexandre Ghiti             cpu->cfg.satp_mode.map |= (1 << i);
11296f23aaebSAlexandre Ghiti         }
1130a13a6082SDaniel Henrique Barboza     }
11316f23aaebSAlexandre Ghiti }
11326f23aaebSAlexandre Ghiti #endif
11336f23aaebSAlexandre Ghiti 
riscv_cpu_finalize_features(RISCVCPU * cpu,Error ** errp)1134ab77a9d5SDaniel Henrique Barboza void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
1135ab77a9d5SDaniel Henrique Barboza {
1136ab77a9d5SDaniel Henrique Barboza     Error *local_err = NULL;
1137ab77a9d5SDaniel Henrique Barboza 
1138ab77a9d5SDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
1139ab77a9d5SDaniel Henrique Barboza     riscv_cpu_satp_mode_finalize(cpu, &local_err);
1140ab77a9d5SDaniel Henrique Barboza     if (local_err != NULL) {
1141ab77a9d5SDaniel Henrique Barboza         error_propagate(errp, local_err);
1142a13a6082SDaniel Henrique Barboza         return;
1143a13a6082SDaniel Henrique Barboza     }
1144a13a6082SDaniel Henrique Barboza #endif
1145a13a6082SDaniel Henrique Barboza 
1146a13a6082SDaniel Henrique Barboza     if (tcg_enabled()) {
1147a13a6082SDaniel Henrique Barboza         riscv_tcg_cpu_finalize_features(cpu, &local_err);
11488c8a7cd6SHuang Tao         if (local_err != NULL) {
1149bbef9140SDaniel Henrique Barboza             error_propagate(errp, local_err);
1150bbef9140SDaniel Henrique Barboza             return;
1151bbef9140SDaniel Henrique Barboza         }
1152bbef9140SDaniel Henrique Barboza         riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
1153bbef9140SDaniel Henrique Barboza     } else if (kvm_enabled()) {
1154bbef9140SDaniel Henrique Barboza         riscv_kvm_cpu_finalize_features(cpu, &local_err);
1155a13a6082SDaniel Henrique Barboza         if (local_err != NULL) {
11566f23aaebSAlexandre Ghiti             error_propagate(errp, local_err);
11576f23aaebSAlexandre Ghiti             return;
1158eddabb6bSDaniel Henrique Barboza         }
1159eddabb6bSDaniel Henrique Barboza     }
1160eddabb6bSDaniel Henrique Barboza }
1161eddabb6bSDaniel Henrique Barboza 
riscv_cpu_realize(DeviceState * dev,Error ** errp)1162eddabb6bSDaniel Henrique Barboza static void riscv_cpu_realize(DeviceState *dev, Error **errp)
1163eddabb6bSDaniel Henrique Barboza {
1164eddabb6bSDaniel Henrique Barboza     CPUState *cs = CPU(dev);
1165f57d5f80SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(dev);
1166f57d5f80SDaniel Henrique Barboza     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
1167f57d5f80SDaniel Henrique Barboza     Error *local_err = NULL;
1168f57d5f80SDaniel Henrique Barboza 
1169f57d5f80SDaniel Henrique Barboza     cpu_exec_realizefn(cs, &local_err);
1170eddabb6bSDaniel Henrique Barboza     if (local_err != NULL) {
1171eddabb6bSDaniel Henrique Barboza         error_propagate(errp, local_err);
1172eddabb6bSDaniel Henrique Barboza         return;
1173eddabb6bSDaniel Henrique Barboza     }
1174eddabb6bSDaniel Henrique Barboza 
1175eddabb6bSDaniel Henrique Barboza     riscv_cpu_finalize_features(cpu, &local_err);
11766f23aaebSAlexandre Ghiti     if (local_err != NULL) {
11776f23aaebSAlexandre Ghiti         error_propagate(errp, local_err);
11786f23aaebSAlexandre Ghiti         return;
11796f23aaebSAlexandre Ghiti     }
11806f23aaebSAlexandre Ghiti 
11816f23aaebSAlexandre Ghiti     riscv_cpu_register_gdb_regs_for_features(cs);
11825371f5cdSJim Wilson 
11835371f5cdSJim Wilson #ifndef CONFIG_USER_ONLY
1184a7c272dfSAkihiko Odaki     if (cpu->cfg.debug) {
1185a7c272dfSAkihiko Odaki         riscv_trigger_realize(&cpu->env);
1186a7c272dfSAkihiko Odaki     }
1187a7c272dfSAkihiko Odaki #endif
1188a7c272dfSAkihiko Odaki 
1189a7c272dfSAkihiko Odaki     qemu_init_vcpu(cs);
1190dc5bd18fSMichael Clark     cpu_reset(cs);
1191dc5bd18fSMichael Clark 
1192dc5bd18fSMichael Clark     mcc->parent_realize(dev, errp);
1193dc5bd18fSMichael Clark }
1194dc5bd18fSMichael Clark 
riscv_cpu_accelerator_compatible(RISCVCPU * cpu)1195dc5bd18fSMichael Clark bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu)
1196ef58fad0SDaniel Henrique Barboza {
1197ef58fad0SDaniel Henrique Barboza     if (tcg_enabled()) {
1198ef58fad0SDaniel Henrique Barboza         return riscv_cpu_tcg_compatible(cpu);
1199ef58fad0SDaniel Henrique Barboza     }
1200ef58fad0SDaniel Henrique Barboza 
1201ef58fad0SDaniel Henrique Barboza     return true;
1202ef58fad0SDaniel Henrique Barboza }
1203ef58fad0SDaniel Henrique Barboza 
1204ef58fad0SDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
cpu_riscv_get_satp(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)12050f0b70eeSAlistair Francis static void cpu_riscv_get_satp(Object *obj, Visitor *v, const char *name,
12066f23aaebSAlexandre Ghiti                                void *opaque, Error **errp)
12076f23aaebSAlexandre Ghiti {
12086f23aaebSAlexandre Ghiti     RISCVSATPMap *satp_map = opaque;
12096f23aaebSAlexandre Ghiti     uint8_t satp = satp_mode_from_str(name);
12106f23aaebSAlexandre Ghiti     bool value;
12116f23aaebSAlexandre Ghiti 
12126f23aaebSAlexandre Ghiti     value = satp_map->map & (1 << satp);
12136f23aaebSAlexandre Ghiti 
12146f23aaebSAlexandre Ghiti     visit_type_bool(v, name, &value, errp);
12156f23aaebSAlexandre Ghiti }
12166f23aaebSAlexandre Ghiti 
cpu_riscv_set_satp(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)12176f23aaebSAlexandre Ghiti static void cpu_riscv_set_satp(Object *obj, Visitor *v, const char *name,
12186f23aaebSAlexandre Ghiti                                void *opaque, Error **errp)
12196f23aaebSAlexandre Ghiti {
12206f23aaebSAlexandre Ghiti     RISCVSATPMap *satp_map = opaque;
12216f23aaebSAlexandre Ghiti     uint8_t satp = satp_mode_from_str(name);
12226f23aaebSAlexandre Ghiti     bool value;
12236f23aaebSAlexandre Ghiti 
12246f23aaebSAlexandre Ghiti     if (!visit_type_bool(v, name, &value, errp)) {
12256f23aaebSAlexandre Ghiti         return;
12266f23aaebSAlexandre Ghiti     }
12276f23aaebSAlexandre Ghiti 
12286f23aaebSAlexandre Ghiti     satp_map->map = deposit32(satp_map->map, satp, 1, value);
12296f23aaebSAlexandre Ghiti     satp_map->init |= 1 << satp;
12306f23aaebSAlexandre Ghiti }
12316f23aaebSAlexandre Ghiti 
riscv_add_satp_mode_properties(Object * obj)12326f23aaebSAlexandre Ghiti void riscv_add_satp_mode_properties(Object *obj)
12337d0c302cSDaniel Henrique Barboza {
12346f23aaebSAlexandre Ghiti     RISCVCPU *cpu = RISCV_CPU(obj);
12356f23aaebSAlexandre Ghiti 
12366f23aaebSAlexandre Ghiti     if (cpu->env.misa_mxl == MXL_RV32) {
12376f23aaebSAlexandre Ghiti         object_property_add(obj, "sv32", "bool", cpu_riscv_get_satp,
12386f23aaebSAlexandre Ghiti                             cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
12396f23aaebSAlexandre Ghiti     } else {
12406f23aaebSAlexandre Ghiti         object_property_add(obj, "sv39", "bool", cpu_riscv_get_satp,
12416f23aaebSAlexandre Ghiti                             cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
12426f23aaebSAlexandre Ghiti         object_property_add(obj, "sv48", "bool", cpu_riscv_get_satp,
12436f23aaebSAlexandre Ghiti                             cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
12446f23aaebSAlexandre Ghiti         object_property_add(obj, "sv57", "bool", cpu_riscv_get_satp,
12456f23aaebSAlexandre Ghiti                             cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
12466f23aaebSAlexandre Ghiti         object_property_add(obj, "sv64", "bool", cpu_riscv_get_satp,
12476f23aaebSAlexandre Ghiti                             cpu_riscv_set_satp, NULL, &cpu->cfg.satp_mode);
12486f23aaebSAlexandre Ghiti     }
12496f23aaebSAlexandre Ghiti }
12506f23aaebSAlexandre Ghiti 
riscv_cpu_set_irq(void * opaque,int irq,int level)12516f23aaebSAlexandre Ghiti static void riscv_cpu_set_irq(void *opaque, int irq, int level)
12520f0b70eeSAlistair Francis {
12530f0b70eeSAlistair Francis     RISCVCPU *cpu = RISCV_CPU(opaque);
12540f0b70eeSAlistair Francis     CPURISCVState *env = &cpu->env;
1255cd032fe7SAnup Patel 
12560f0b70eeSAlistair Francis     if (irq < IRQ_LOCAL_MAX) {
1257cd032fe7SAnup Patel         switch (irq) {
12580f0b70eeSAlistair Francis         case IRQ_U_SOFT:
12590f0b70eeSAlistair Francis         case IRQ_S_SOFT:
12600f0b70eeSAlistair Francis         case IRQ_VS_SOFT:
12610f0b70eeSAlistair Francis         case IRQ_M_SOFT:
12620f0b70eeSAlistair Francis         case IRQ_U_TIMER:
12630f0b70eeSAlistair Francis         case IRQ_S_TIMER:
12640f0b70eeSAlistair Francis         case IRQ_VS_TIMER:
12650f0b70eeSAlistair Francis         case IRQ_M_TIMER:
12660f0b70eeSAlistair Francis         case IRQ_U_EXT:
12670f0b70eeSAlistair Francis         case IRQ_VS_EXT:
12680f0b70eeSAlistair Francis         case IRQ_M_EXT:
12690f0b70eeSAlistair Francis             if (kvm_enabled()) {
12702b650fbbSYifei Jiang                 kvm_riscv_set_irq(cpu, irq, level);
12712b650fbbSYifei Jiang             } else {
12722b650fbbSYifei Jiang                 riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level));
1273bbb9fc25SWeiwei Li             }
12742b650fbbSYifei Jiang              break;
12750f0b70eeSAlistair Francis         case IRQ_S_EXT:
127633fe584fSAlistair Francis             if (kvm_enabled()) {
127733fe584fSAlistair Francis                 kvm_riscv_set_irq(cpu, irq, level);
127833fe584fSAlistair Francis             } else {
127933fe584fSAlistair Francis                 env->external_seip = level;
128033fe584fSAlistair Francis                 riscv_cpu_update_mip(env, 1 << irq,
1281bbb9fc25SWeiwei Li                                      BOOL_TO_MASK(level | env->software_seip));
128233fe584fSAlistair Francis             }
128333fe584fSAlistair Francis             break;
128433fe584fSAlistair Francis         default:
12850f0b70eeSAlistair Francis             g_assert_not_reached();
12860f0b70eeSAlistair Francis         }
12870f0b70eeSAlistair Francis     } else if (irq < (IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX)) {
1288cd032fe7SAnup Patel         /* Require H-extension for handling guest local interrupts */
1289cd032fe7SAnup Patel         if (!riscv_has_ext(env, RVH)) {
1290cd032fe7SAnup Patel             g_assert_not_reached();
1291cd032fe7SAnup Patel         }
1292cd032fe7SAnup Patel 
1293cd032fe7SAnup Patel         /* Compute bit position in HGEIP CSR */
1294cd032fe7SAnup Patel         irq = irq - IRQ_LOCAL_MAX + 1;
1295cd032fe7SAnup Patel         if (env->geilen < irq) {
1296cd032fe7SAnup Patel             g_assert_not_reached();
1297cd032fe7SAnup Patel         }
1298cd032fe7SAnup Patel 
1299cd032fe7SAnup Patel         /* Update HGEIP CSR */
1300cd032fe7SAnup Patel         env->hgeip &= ~((target_ulong)1 << irq);
1301cd032fe7SAnup Patel         if (level) {
1302cd032fe7SAnup Patel             env->hgeip |= (target_ulong)1 << irq;
1303cd032fe7SAnup Patel         }
1304cd032fe7SAnup Patel 
1305cd032fe7SAnup Patel         /* Update mip.SGEIP bit */
1306cd032fe7SAnup Patel         riscv_cpu_update_mip(env, MIP_SGEIP,
1307bbb9fc25SWeiwei Li                              BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
1308cd032fe7SAnup Patel     } else {
1309cd032fe7SAnup Patel         g_assert_not_reached();
1310cd032fe7SAnup Patel     }
1311cd032fe7SAnup Patel }
13120f0b70eeSAlistair Francis #endif /* CONFIG_USER_ONLY */
13130f0b70eeSAlistair Francis 
riscv_cpu_is_dynamic(Object * cpu_obj)13140f0b70eeSAlistair Francis static bool riscv_cpu_is_dynamic(Object *cpu_obj)
1315977bbb04SDaniel Henrique Barboza {
1316977bbb04SDaniel Henrique Barboza     return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
1317977bbb04SDaniel Henrique Barboza }
1318977bbb04SDaniel Henrique Barboza 
riscv_cpu_post_init(Object * obj)1319977bbb04SDaniel Henrique Barboza static void riscv_cpu_post_init(Object *obj)
1320977bbb04SDaniel Henrique Barboza {
1321977bbb04SDaniel Henrique Barboza     accel_cpu_instance_init(CPU(obj));
1322d86c25b2SDaniel Henrique Barboza }
1323977bbb04SDaniel Henrique Barboza 
riscv_cpu_init(Object * obj)1324977bbb04SDaniel Henrique Barboza static void riscv_cpu_init(Object *obj)
1325dc5bd18fSMichael Clark {
1326dc5bd18fSMichael Clark     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(obj);
1327742cc269SAkihiko Odaki     RISCVCPU *cpu = RISCV_CPU(obj);
1328d167a224SDaniel Henrique Barboza     CPURISCVState *env = &cpu->env;
1329742cc269SAkihiko Odaki 
1330742cc269SAkihiko Odaki     env->misa_mxl = mcc->misa_mxl_max;
1331742cc269SAkihiko Odaki 
1332d167a224SDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
13330f0b70eeSAlistair Francis     qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
13348fa08d7eSRichard Henderson                       IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
1335cd032fe7SAnup Patel #endif /* CONFIG_USER_ONLY */
13360f0b70eeSAlistair Francis 
1337c0040993SDaniel Henrique Barboza     general_user_opts = g_hash_table_new(g_str_hash, g_str_equal);
1338d167a224SDaniel Henrique Barboza 
1339d167a224SDaniel Henrique Barboza     /*
1340c0040993SDaniel Henrique Barboza      * The timer and performance counters extensions were supported
1341c0040993SDaniel Henrique Barboza      * in QEMU before they were added as discrete extensions in the
1342c0040993SDaniel Henrique Barboza      * ISA. To keep compatibility we'll always default them to 'true'
1343c0040993SDaniel Henrique Barboza      * for all CPUs. Each accelerator will decide what to do when
1344c0040993SDaniel Henrique Barboza      * users disable them.
1345c0040993SDaniel Henrique Barboza      */
1346c0040993SDaniel Henrique Barboza     RISCV_CPU(obj)->cfg.ext_zicntr = true;
1347c0040993SDaniel Henrique Barboza     RISCV_CPU(obj)->cfg.ext_zihpm = true;
134808241216SDaniel Henrique Barboza 
1349d167a224SDaniel Henrique Barboza     /* Default values for non-bool cpu properties */
1350d167a224SDaniel Henrique Barboza     cpu->cfg.pmu_mask = MAKE_64BIT_MASK(3, 16);
1351d167a224SDaniel Henrique Barboza     cpu->cfg.vlenb = 128 >> 3;
135204eb30a0SDaniel Henrique Barboza     cpu->cfg.elen = 64;
13539d1173d2SDaniel Henrique Barboza     cpu->cfg.cbom_blocksize = 64;
1354b84efa39SDaniel Henrique Barboza     cpu->cfg.cbop_blocksize = 64;
1355811ef853SDaniel Henrique Barboza     cpu->cfg.cboz_blocksize = 64;
135682f7b1d4SDaniel Henrique Barboza     cpu->env.vext_ver = VEXT_VERSION_1_00_0;
135741f2b94eSDaniel Henrique Barboza }
1358dc5bd18fSMichael Clark 
riscv_bare_cpu_init(Object * obj)1359dc5bd18fSMichael Clark static void riscv_bare_cpu_init(Object *obj)
1360b077aec9SDaniel Henrique Barboza {
1361b077aec9SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
1362b077aec9SDaniel Henrique Barboza 
1363b077aec9SDaniel Henrique Barboza     /*
1364b077aec9SDaniel Henrique Barboza      * Bare CPUs do not inherit the timer and performance
1365b077aec9SDaniel Henrique Barboza      * counters from the parent class (see riscv_cpu_init()
1366b077aec9SDaniel Henrique Barboza      * for info on why the parent enables them).
1367b077aec9SDaniel Henrique Barboza      *
1368b077aec9SDaniel Henrique Barboza      * Users have to explicitly enable these counters for
1369b077aec9SDaniel Henrique Barboza      * bare CPUs.
1370b077aec9SDaniel Henrique Barboza      */
1371b077aec9SDaniel Henrique Barboza     cpu->cfg.ext_zicntr = false;
1372b077aec9SDaniel Henrique Barboza     cpu->cfg.ext_zihpm = false;
1373b077aec9SDaniel Henrique Barboza 
1374b077aec9SDaniel Henrique Barboza     /* Set to QEMU's first supported priv version */
1375b077aec9SDaniel Henrique Barboza     cpu->env.priv_ver = PRIV_VERSION_1_10_0;
1376b077aec9SDaniel Henrique Barboza 
1377b077aec9SDaniel Henrique Barboza     /*
1378b077aec9SDaniel Henrique Barboza      * Support all available satp_mode settings. The default
1379b077aec9SDaniel Henrique Barboza      * value will be set to MBARE if the user doesn't set
1380b077aec9SDaniel Henrique Barboza      * satp_mode manually (see set_satp_mode_default()).
1381b077aec9SDaniel Henrique Barboza      */
1382b077aec9SDaniel Henrique Barboza #ifndef CONFIG_USER_ONLY
1383b077aec9SDaniel Henrique Barboza     set_satp_mode_max_supported(cpu, VM_1_10_SV64);
1384b077aec9SDaniel Henrique Barboza #endif
1385b077aec9SDaniel Henrique Barboza }
1386b077aec9SDaniel Henrique Barboza 
1387b077aec9SDaniel Henrique Barboza typedef struct misa_ext_info {
1388ed7e6182SDaniel Henrique Barboza     const char *name;
1389ed7e6182SDaniel Henrique Barboza     const char *description;
1390ed7e6182SDaniel Henrique Barboza } MISAExtInfo;
1391ed7e6182SDaniel Henrique Barboza 
1392ed7e6182SDaniel Henrique Barboza #define MISA_INFO_IDX(_bit) \
1393ed7e6182SDaniel Henrique Barboza     __builtin_ctz(_bit)
1394ed7e6182SDaniel Henrique Barboza 
1395ed7e6182SDaniel Henrique Barboza #define MISA_EXT_INFO(_bit, _propname, _descr) \
1396ed7e6182SDaniel Henrique Barboza     [MISA_INFO_IDX(_bit)] = {.name = _propname, .description = _descr}
1397ed7e6182SDaniel Henrique Barboza 
1398ed7e6182SDaniel Henrique Barboza static const MISAExtInfo misa_ext_info_arr[] = {
1399ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVA, "a", "Atomic instructions"),
1400ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVC, "c", "Compressed instructions"),
1401ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVD, "d", "Double-precision float point"),
1402ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVF, "f", "Single-precision float point"),
1403ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVI, "i", "Base integer instruction set"),
1404ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVE, "e", "Base integer instruction set (embedded)"),
1405ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVM, "m", "Integer multiplication and division"),
1406ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"),
1407ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVU, "u", "User-level instructions"),
1408ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVH, "h", "Hypervisor"),
1409ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
1410ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVV, "v", "Vector operations"),
1411ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
1412ed7e6182SDaniel Henrique Barboza     MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
141373ef14b1SRob Bradford };
1414ed7e6182SDaniel Henrique Barboza 
riscv_cpu_validate_misa_mxl(RISCVCPUClass * mcc)1415ed7e6182SDaniel Henrique Barboza static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
14161563cdb4SAkihiko Odaki {
14171563cdb4SAkihiko Odaki     CPUClass *cc = CPU_CLASS(mcc);
14181563cdb4SAkihiko Odaki 
14191563cdb4SAkihiko Odaki     /* Validate that MISA_MXL is set properly. */
14201563cdb4SAkihiko Odaki     switch (mcc->misa_mxl_max) {
14211563cdb4SAkihiko Odaki #ifdef TARGET_RISCV64
14221563cdb4SAkihiko Odaki     case MXL_RV64:
14231563cdb4SAkihiko Odaki     case MXL_RV128:
14241563cdb4SAkihiko Odaki         cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
14251563cdb4SAkihiko Odaki         break;
14261563cdb4SAkihiko Odaki #endif
14271563cdb4SAkihiko Odaki     case MXL_RV32:
14281563cdb4SAkihiko Odaki         cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
14291563cdb4SAkihiko Odaki         break;
14301563cdb4SAkihiko Odaki     default:
14311563cdb4SAkihiko Odaki         g_assert_not_reached();
14321563cdb4SAkihiko Odaki     }
14331563cdb4SAkihiko Odaki }
14341563cdb4SAkihiko Odaki 
riscv_validate_misa_info_idx(uint32_t bit)14351563cdb4SAkihiko Odaki static int riscv_validate_misa_info_idx(uint32_t bit)
1436ed7e6182SDaniel Henrique Barboza {
1437ed7e6182SDaniel Henrique Barboza     int idx;
1438ed7e6182SDaniel Henrique Barboza 
1439ed7e6182SDaniel Henrique Barboza     /*
1440ed7e6182SDaniel Henrique Barboza      * Our lowest valid input (RVA) is 1 and
1441ed7e6182SDaniel Henrique Barboza      * __builtin_ctz() is UB with zero.
1442ed7e6182SDaniel Henrique Barboza      */
1443ed7e6182SDaniel Henrique Barboza     g_assert(bit != 0);
1444ed7e6182SDaniel Henrique Barboza     idx = MISA_INFO_IDX(bit);
1445ed7e6182SDaniel Henrique Barboza 
1446ed7e6182SDaniel Henrique Barboza     g_assert(idx < ARRAY_SIZE(misa_ext_info_arr));
1447ed7e6182SDaniel Henrique Barboza     return idx;
1448ed7e6182SDaniel Henrique Barboza }
1449ed7e6182SDaniel Henrique Barboza 
riscv_get_misa_ext_name(uint32_t bit)1450ed7e6182SDaniel Henrique Barboza const char *riscv_get_misa_ext_name(uint32_t bit)
1451ed7e6182SDaniel Henrique Barboza {
1452ed7e6182SDaniel Henrique Barboza     int idx = riscv_validate_misa_info_idx(bit);
1453ed7e6182SDaniel Henrique Barboza     const char *val = misa_ext_info_arr[idx].name;
1454ed7e6182SDaniel Henrique Barboza 
1455ed7e6182SDaniel Henrique Barboza     g_assert(val != NULL);
1456ed7e6182SDaniel Henrique Barboza     return val;
1457ed7e6182SDaniel Henrique Barboza }
1458ed7e6182SDaniel Henrique Barboza 
riscv_get_misa_ext_description(uint32_t bit)1459ed7e6182SDaniel Henrique Barboza const char *riscv_get_misa_ext_description(uint32_t bit)
1460ed7e6182SDaniel Henrique Barboza {
1461ed7e6182SDaniel Henrique Barboza     int idx = riscv_validate_misa_info_idx(bit);
1462ed7e6182SDaniel Henrique Barboza     const char *val = misa_ext_info_arr[idx].description;
1463ed7e6182SDaniel Henrique Barboza 
1464ed7e6182SDaniel Henrique Barboza     g_assert(val != NULL);
1465ed7e6182SDaniel Henrique Barboza     return val;
1466ed7e6182SDaniel Henrique Barboza }
1467ed7e6182SDaniel Henrique Barboza 
1468ed7e6182SDaniel Henrique Barboza #define MULTI_EXT_CFG_BOOL(_name, _prop, _defval) \
1469549cbf78SDaniel Henrique Barboza     {.name = _name, .offset = CPU_CFG_OFFSET(_prop), \
1470549cbf78SDaniel Henrique Barboza      .enabled = _defval}
1471549cbf78SDaniel Henrique Barboza 
1472549cbf78SDaniel Henrique Barboza const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
147332fa1776SDaniel Henrique Barboza     /* Defaults for standard extensions */
14749d3d60b7SAlistair Francis     MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
1475549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("smcntrpmf", ext_smcntrpmf, false),
14766f6592d6SAtish Patra     MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
147712b12a14SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zicfilp", ext_zicfilp, false),
1478960b389bSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zicfiss", ext_zicfiss, false),
14798043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
14808043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
14816eab278dSLIU Zhiwei     MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true),
1482197e4d29SLIU Zhiwei     MULTI_EXT_CFG_BOOL("zimop", ext_zimop, false),
1483b52d49e9SWeiwei Li     MULTI_EXT_CFG_BOOL("zcmop", ext_zcmop, false),
1484a60ce58fSLIU Zhiwei     MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
14858aebaa25SLIU Zhiwei     MULTI_EXT_CFG_BOOL("zama16b", ext_zama16b, false),
1486249e0905SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zabha", ext_zabha, false),
1487249e0905SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zaamo", ext_zaamo, false),
14888043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zalrsc", ext_zalrsc, false),
14898043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
1490249e0905SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zfa", ext_zfa, true),
14918043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zfbfmin", ext_zfbfmin, false),
14928043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
14938043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
14949fb41a44SJason Chien     MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
14958043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
14968043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
1497e7dc5e16SJason Chien     MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
1498249e0905SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
1499249e0905SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
1500249e0905SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
1501249e0905SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
1502549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zvfhmin", ext_zvfhmin, false),
15039d3d60b7SAlistair Francis     MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true),
1504249e0905SDaniel Henrique Barboza 
1505095fe72aSHimanshu Chauhan     MULTI_EXT_CFG_BOOL("smaia", ext_smaia, false),
1506549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("smepmp", ext_smepmp, false),
1507249e0905SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
1508adb49752SAndrew Jones     MULTI_EXT_CFG_BOOL("ssaia", ext_ssaia, false),
1509549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("svade", ext_svade, false),
1510549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("svadu", ext_svadu, true),
1511549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("svinval", ext_svinval, false),
1512549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false),
15132bacb224SWeiwei Li     MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false),
1514c0040993SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("svvptc", ext_svvptc, true),
151508241216SDaniel Henrique Barboza 
1516c0040993SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zicntr", ext_zicntr, true),
1517549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zihpm", ext_zihpm, true),
1518549cbf78SDaniel Henrique Barboza 
1519549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zba", ext_zba, true),
1520549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zbb", ext_zbb, true),
1521549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zbc", ext_zbc, true),
1522549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zbkb", ext_zbkb, false),
1523549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zbkc", ext_zbkc, false),
1524549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zbkx", ext_zbkx, false),
1525549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zbs", ext_zbs, true),
1526549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zk", ext_zk, false),
1527549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zkn", ext_zkn, false),
1528549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zknd", ext_zknd, false),
1529549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zkne", ext_zkne, false),
1530549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zknh", ext_zknh, false),
1531549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zkr", ext_zkr, false),
1532549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zks", ext_zks, false),
1533549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zksed", ext_zksed, false),
153409c4e887SPalmer Dabbelt     MULTI_EXT_CFG_BOOL("zksh", ext_zksh, false),
1535dfdb46a3SPhilipp Tomsich     MULTI_EXT_CFG_BOOL("zkt", ext_zkt, false),
1536549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("ztso", ext_ztso, false),
1537549cbf78SDaniel Henrique Barboza 
1538549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zdinx", ext_zdinx, false),
1539549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zfinx", ext_zfinx, false),
15406b1accefSWeiwei Li     MULTI_EXT_CFG_BOOL("zhinx", ext_zhinx, false),
1541a326a2b0SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zhinxmin", ext_zhinxmin, false),
1542cc2bf69aSDaniel Henrique Barboza 
1543e57039ddSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zicbom", ext_zicbom, true),
1544a939c500SChristoph Muellner     MULTI_EXT_CFG_BOOL("zicbop", ext_zicbop, true),
1545549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zicboz", ext_zicboz, true),
15466d00ffadSWeiwei Li 
1547549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false),
1548549cbf78SDaniel Henrique Barboza 
1549549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zca", ext_zca, false),
1550549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false),
1551549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false),
1552549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zce", ext_zce, false),
1553549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zcf", ext_zcf, false),
1554549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zcmp", ext_zcmp, false),
15556672e29dSWeiwei Li     MULTI_EXT_CFG_BOOL("zcmt", ext_zcmt, false),
1556ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zicond", ext_zicond, false),
1557ea61ef70SMax Chou 
1558ea61ef70SMax Chou     /* Vector cryptography extensions */
1559ff33b7a9SYangyu Chen     MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
1560ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
1561ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
1562ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
1563ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
1564ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
1565ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvknhb", ext_zvknhb, false),
1566ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvksed", ext_zvksed, false),
1567ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvksh", ext_zvksh, false),
1568ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvkt", ext_zvkt, false),
1569ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvkn", ext_zvkn, false),
1570ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvknc", ext_zvknc, false),
1571ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvkng", ext_zvkng, false),
1572ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvks", ext_zvks, false),
1573ea61ef70SMax Chou     MULTI_EXT_CFG_BOOL("zvksc", ext_zvksc, false),
157482822b5dSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zvksg", ext_zvksg, false),
157582822b5dSDaniel Henrique Barboza 
157682822b5dSDaniel Henrique Barboza     DEFINE_PROP_END_OF_LIST(),
157732fa1776SDaniel Henrique Barboza };
1578549cbf78SDaniel Henrique Barboza 
1579549cbf78SDaniel Henrique Barboza const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
1580549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadba", ext_xtheadba, false),
1581549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadbb", ext_xtheadbb, false),
1582549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadbs", ext_xtheadbs, false),
1583549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadcmo", ext_xtheadcmo, false),
1584549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadcondmov", ext_xtheadcondmov, false),
1585549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadfmemidx", ext_xtheadfmemidx, false),
1586549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadfmv", ext_xtheadfmv, false),
1587549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadmac", ext_xtheadmac, false),
1588549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadmemidx", ext_xtheadmemidx, false),
1589549cbf78SDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
15900d429bd2SPhilipp Tomsich     MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
1591b955fd1aSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
1592b955fd1aSDaniel Henrique Barboza 
1593d364c0abSWeiwei Li     DEFINE_PROP_END_OF_LIST(),
1594b955fd1aSDaniel Henrique Barboza };
159532fa1776SDaniel Henrique Barboza 
159626b2bc58SAlistair Francis /* These are experimental so mark with 'x-' */
159726b2bc58SAlistair Francis const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
159826b2bc58SAlistair Francis     DEFINE_PROP_END_OF_LIST(),
15993b802226SDaniel Henrique Barboza };
16003b802226SDaniel Henrique Barboza 
16013b802226SDaniel Henrique Barboza /*
16023b802226SDaniel Henrique Barboza  * 'Named features' is the name we give to extensions that we
16033b802226SDaniel Henrique Barboza  * don't want to expose to users. They are either immutable
16043b802226SDaniel Henrique Barboza  * (always enabled/disable) or they'll vary depending on
16053b802226SDaniel Henrique Barboza  * the resulting CPU state. They have riscv,isa strings
16065fe2800bSDaniel Henrique Barboza  * and priv_ver like regular extensions.
16073b802226SDaniel Henrique Barboza  */
16085fe2800bSDaniel Henrique Barboza const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
16095fe2800bSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
16105fe2800bSDaniel Henrique Barboza 
16115fe2800bSDaniel Henrique Barboza     DEFINE_PROP_END_OF_LIST(),
16128043effdSDaniel Henrique Barboza };
16138043effdSDaniel Henrique Barboza 
161412b12a14SDaniel Henrique Barboza /* Deprecated entries marked for future removal */
1615960b389bSDaniel Henrique Barboza const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[] = {
16168043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zifencei", ext_zifencei, true),
16178043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zicsr", ext_zicsr, true),
16188043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zihintntl", ext_zihintntl, true),
16198043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zihintpause", ext_zihintpause, true),
16208043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zawrs", ext_zawrs, true),
16218043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zfa", ext_zfa, true),
16228043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zfh", ext_zfh, false),
16238043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zfhmin", ext_zfhmin, false),
16248043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zve32f", ext_zve32f, false),
16258043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zve64f", ext_zve64f, false),
16268043effdSDaniel Henrique Barboza     MULTI_EXT_CFG_BOOL("Zve64d", ext_zve64d, false),
16278043effdSDaniel Henrique Barboza 
16288043effdSDaniel Henrique Barboza     DEFINE_PROP_END_OF_LIST(),
1629d167a224SDaniel Henrique Barboza };
1630d167a224SDaniel Henrique Barboza 
cpu_set_prop_err(RISCVCPU * cpu,const char * propname,Error ** errp)1631d167a224SDaniel Henrique Barboza static void cpu_set_prop_err(RISCVCPU *cpu, const char *propname,
1632d167a224SDaniel Henrique Barboza                              Error **errp)
1633d167a224SDaniel Henrique Barboza {
1634d167a224SDaniel Henrique Barboza     g_autofree char *cpuname = riscv_cpu_get_name(cpu);
1635d167a224SDaniel Henrique Barboza     error_setg(errp, "CPU '%s' does not allow changing the value of '%s'",
1636d167a224SDaniel Henrique Barboza                cpuname, propname);
163769b3849bSRob Bradford }
163869b3849bSRob Bradford 
prop_pmu_num_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)163969b3849bSRob Bradford static void prop_pmu_num_set(Object *obj, Visitor *v, const char *name,
164069b3849bSRob Bradford                              void *opaque, Error **errp)
1641d167a224SDaniel Henrique Barboza {
1642d167a224SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
164369b3849bSRob Bradford     uint8_t pmu_num, curr_pmu_num;
164469b3849bSRob Bradford     uint32_t pmu_mask;
164569b3849bSRob Bradford 
1646d167a224SDaniel Henrique Barboza     visit_type_uint8(v, name, &pmu_num, errp);
1647d167a224SDaniel Henrique Barboza 
1648d167a224SDaniel Henrique Barboza     curr_pmu_num = ctpop32(cpu->cfg.pmu_mask);
1649d167a224SDaniel Henrique Barboza 
1650d167a224SDaniel Henrique Barboza     if (pmu_num != curr_pmu_num && riscv_cpu_is_vendor(obj)) {
1651d167a224SDaniel Henrique Barboza         cpu_set_prop_err(cpu, name, errp);
1652d167a224SDaniel Henrique Barboza         error_append_hint(errp, "Current '%s' val: %u\n",
1653d167a224SDaniel Henrique Barboza                           name, curr_pmu_num);
1654d167a224SDaniel Henrique Barboza         return;
165569b3849bSRob Bradford     }
165669b3849bSRob Bradford 
165769b3849bSRob Bradford     if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
165869b3849bSRob Bradford         error_setg(errp, "Number of counters exceeds maximum available");
165969b3849bSRob Bradford         return;
166069b3849bSRob Bradford     }
1661d167a224SDaniel Henrique Barboza 
166269b3849bSRob Bradford     if (pmu_num == 0) {
1663d167a224SDaniel Henrique Barboza         pmu_mask = 0;
166469b3849bSRob Bradford     } else {
166569b3849bSRob Bradford         pmu_mask = MAKE_64BIT_MASK(3, pmu_num);
166669b3849bSRob Bradford     }
1667d167a224SDaniel Henrique Barboza 
1668d167a224SDaniel Henrique Barboza     warn_report("\"pmu-num\" property is deprecated; use \"pmu-mask\"");
166969b3849bSRob Bradford     cpu->cfg.pmu_mask = pmu_mask;
167069b3849bSRob Bradford     cpu_option_add_user_setting("pmu-mask", pmu_mask);
167169b3849bSRob Bradford }
167269b3849bSRob Bradford 
prop_pmu_num_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)167369b3849bSRob Bradford static void prop_pmu_num_get(Object *obj, Visitor *v, const char *name,
167469b3849bSRob Bradford                              void *opaque, Error **errp)
167569b3849bSRob Bradford {
167669b3849bSRob Bradford     RISCVCPU *cpu = RISCV_CPU(obj);
167769b3849bSRob Bradford     uint8_t pmu_num = ctpop32(cpu->cfg.pmu_mask);
167869b3849bSRob Bradford 
167969b3849bSRob Bradford     visit_type_uint8(v, name, &pmu_num, errp);
1680d167a224SDaniel Henrique Barboza }
168169b3849bSRob Bradford 
168269b3849bSRob Bradford static const PropertyInfo prop_pmu_num = {
168369b3849bSRob Bradford     .name = "pmu-num",
168469b3849bSRob Bradford     .get = prop_pmu_num_get,
168569b3849bSRob Bradford     .set = prop_pmu_num_set,
1686d167a224SDaniel Henrique Barboza };
1687d167a224SDaniel Henrique Barboza 
prop_pmu_mask_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1688d167a224SDaniel Henrique Barboza static void prop_pmu_mask_set(Object *obj, Visitor *v, const char *name,
1689d167a224SDaniel Henrique Barboza                              void *opaque, Error **errp)
1690d167a224SDaniel Henrique Barboza {
1691d167a224SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
16928ea3fcefSDaniel Henrique Barboza     uint32_t value;
1693d167a224SDaniel Henrique Barboza     uint8_t pmu_num;
1694d167a224SDaniel Henrique Barboza 
1695d167a224SDaniel Henrique Barboza     visit_type_uint32(v, name, &value, errp);
1696d167a224SDaniel Henrique Barboza 
1697d167a224SDaniel Henrique Barboza     if (value != cpu->cfg.pmu_mask && riscv_cpu_is_vendor(obj)) {
1698d167a224SDaniel Henrique Barboza         cpu_set_prop_err(cpu, name, errp);
1699d167a224SDaniel Henrique Barboza         error_append_hint(errp, "Current '%s' val: %x\n",
1700d167a224SDaniel Henrique Barboza                           name, cpu->cfg.pmu_mask);
1701d167a224SDaniel Henrique Barboza         return;
1702d167a224SDaniel Henrique Barboza     }
1703d167a224SDaniel Henrique Barboza 
1704d167a224SDaniel Henrique Barboza     pmu_num = ctpop32(value);
1705d167a224SDaniel Henrique Barboza 
1706d167a224SDaniel Henrique Barboza     if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
1707d167a224SDaniel Henrique Barboza         error_setg(errp, "Number of counters exceeds maximum available");
1708d167a224SDaniel Henrique Barboza         return;
1709d167a224SDaniel Henrique Barboza     }
1710d167a224SDaniel Henrique Barboza 
1711d167a224SDaniel Henrique Barboza     cpu_option_add_user_setting(name, value);
1712d167a224SDaniel Henrique Barboza     cpu->cfg.pmu_mask = value;
1713d167a224SDaniel Henrique Barboza }
1714d167a224SDaniel Henrique Barboza 
prop_pmu_mask_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1715d167a224SDaniel Henrique Barboza static void prop_pmu_mask_get(Object *obj, Visitor *v, const char *name,
1716d167a224SDaniel Henrique Barboza                              void *opaque, Error **errp)
1717d167a224SDaniel Henrique Barboza {
1718d167a224SDaniel Henrique Barboza     uint8_t pmu_mask = RISCV_CPU(obj)->cfg.pmu_mask;
1719d167a224SDaniel Henrique Barboza 
1720d167a224SDaniel Henrique Barboza     visit_type_uint8(v, name, &pmu_mask, errp);
1721d167a224SDaniel Henrique Barboza }
1722d167a224SDaniel Henrique Barboza 
1723d167a224SDaniel Henrique Barboza static const PropertyInfo prop_pmu_mask = {
1724d167a224SDaniel Henrique Barboza     .name = "pmu-mask",
1725d167a224SDaniel Henrique Barboza     .get = prop_pmu_mask_get,
1726d167a224SDaniel Henrique Barboza     .set = prop_pmu_mask_set,
1727d06f28dbSDaniel Henrique Barboza };
1728d06f28dbSDaniel Henrique Barboza 
prop_mmu_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1729d06f28dbSDaniel Henrique Barboza static void prop_mmu_set(Object *obj, Visitor *v, const char *name,
1730d06f28dbSDaniel Henrique Barboza                          void *opaque, Error **errp)
1731d06f28dbSDaniel Henrique Barboza {
1732d06f28dbSDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
1733d06f28dbSDaniel Henrique Barboza     bool value;
1734d06f28dbSDaniel Henrique Barboza 
1735d06f28dbSDaniel Henrique Barboza     visit_type_bool(v, name, &value, errp);
1736d06f28dbSDaniel Henrique Barboza 
1737d06f28dbSDaniel Henrique Barboza     if (cpu->cfg.mmu != value && riscv_cpu_is_vendor(obj)) {
1738d06f28dbSDaniel Henrique Barboza         cpu_set_prop_err(cpu, "mmu", errp);
1739d06f28dbSDaniel Henrique Barboza         return;
1740d06f28dbSDaniel Henrique Barboza     }
1741d06f28dbSDaniel Henrique Barboza 
1742d06f28dbSDaniel Henrique Barboza     cpu_option_add_user_setting(name, value);
1743d06f28dbSDaniel Henrique Barboza     cpu->cfg.mmu = value;
1744d06f28dbSDaniel Henrique Barboza }
1745d06f28dbSDaniel Henrique Barboza 
prop_mmu_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1746d06f28dbSDaniel Henrique Barboza static void prop_mmu_get(Object *obj, Visitor *v, const char *name,
1747d06f28dbSDaniel Henrique Barboza                          void *opaque, Error **errp)
1748d06f28dbSDaniel Henrique Barboza {
1749d06f28dbSDaniel Henrique Barboza     bool value = RISCV_CPU(obj)->cfg.mmu;
1750d06f28dbSDaniel Henrique Barboza 
1751d06f28dbSDaniel Henrique Barboza     visit_type_bool(v, name, &value, errp);
1752d06f28dbSDaniel Henrique Barboza }
1753d06f28dbSDaniel Henrique Barboza 
1754d06f28dbSDaniel Henrique Barboza static const PropertyInfo prop_mmu = {
1755d06f28dbSDaniel Henrique Barboza     .name = "mmu",
1756d06f28dbSDaniel Henrique Barboza     .get = prop_mmu_get,
1757d06f28dbSDaniel Henrique Barboza     .set = prop_mmu_set,
175811097be4SDaniel Henrique Barboza };
175911097be4SDaniel Henrique Barboza 
prop_pmp_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)176011097be4SDaniel Henrique Barboza static void prop_pmp_set(Object *obj, Visitor *v, const char *name,
176111097be4SDaniel Henrique Barboza                          void *opaque, Error **errp)
176211097be4SDaniel Henrique Barboza {
17638ea3fcefSDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
176411097be4SDaniel Henrique Barboza     bool value;
176511097be4SDaniel Henrique Barboza 
176611097be4SDaniel Henrique Barboza     visit_type_bool(v, name, &value, errp);
176711097be4SDaniel Henrique Barboza 
176811097be4SDaniel Henrique Barboza     if (cpu->cfg.pmp != value && riscv_cpu_is_vendor(obj)) {
176911097be4SDaniel Henrique Barboza         cpu_set_prop_err(cpu, name, errp);
177011097be4SDaniel Henrique Barboza         return;
177111097be4SDaniel Henrique Barboza     }
177211097be4SDaniel Henrique Barboza 
177311097be4SDaniel Henrique Barboza     cpu_option_add_user_setting(name, value);
177411097be4SDaniel Henrique Barboza     cpu->cfg.pmp = value;
177511097be4SDaniel Henrique Barboza }
177611097be4SDaniel Henrique Barboza 
prop_pmp_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)177711097be4SDaniel Henrique Barboza static void prop_pmp_get(Object *obj, Visitor *v, const char *name,
177811097be4SDaniel Henrique Barboza                          void *opaque, Error **errp)
177911097be4SDaniel Henrique Barboza {
178011097be4SDaniel Henrique Barboza     bool value = RISCV_CPU(obj)->cfg.pmp;
178111097be4SDaniel Henrique Barboza 
178211097be4SDaniel Henrique Barboza     visit_type_bool(v, name, &value, errp);
178311097be4SDaniel Henrique Barboza }
178411097be4SDaniel Henrique Barboza 
178511097be4SDaniel Henrique Barboza static const PropertyInfo prop_pmp = {
178611097be4SDaniel Henrique Barboza     .name = "pmp",
178711097be4SDaniel Henrique Barboza     .get = prop_pmp_get,
178811097be4SDaniel Henrique Barboza     .set = prop_pmp_set,
1789fefc294bSDaniel Henrique Barboza };
1790fefc294bSDaniel Henrique Barboza 
priv_spec_from_str(const char * priv_spec_str)1791fefc294bSDaniel Henrique Barboza static int priv_spec_from_str(const char *priv_spec_str)
1792fefc294bSDaniel Henrique Barboza {
17933adf4defSFea.Wang     int priv_version = -1;
17943adf4defSFea.Wang 
17953adf4defSFea.Wang     if (!g_strcmp0(priv_spec_str, PRIV_VER_1_13_0_STR)) {
1796fefc294bSDaniel Henrique Barboza         priv_version = PRIV_VERSION_1_13_0;
1797fefc294bSDaniel Henrique Barboza     } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_12_0_STR)) {
1798fefc294bSDaniel Henrique Barboza         priv_version = PRIV_VERSION_1_12_0;
1799fefc294bSDaniel Henrique Barboza     } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_11_0_STR)) {
1800fefc294bSDaniel Henrique Barboza         priv_version = PRIV_VERSION_1_11_0;
1801fefc294bSDaniel Henrique Barboza     } else if (!g_strcmp0(priv_spec_str, PRIV_VER_1_10_0_STR)) {
1802fefc294bSDaniel Henrique Barboza         priv_version = PRIV_VERSION_1_10_0;
1803fefc294bSDaniel Henrique Barboza     }
1804fefc294bSDaniel Henrique Barboza 
1805fefc294bSDaniel Henrique Barboza     return priv_version;
1806a1a8e776SJim Shu }
1807fefc294bSDaniel Henrique Barboza 
priv_spec_to_str(int priv_version)1808fefc294bSDaniel Henrique Barboza const char *priv_spec_to_str(int priv_version)
1809fefc294bSDaniel Henrique Barboza {
1810fefc294bSDaniel Henrique Barboza     switch (priv_version) {
1811fefc294bSDaniel Henrique Barboza     case PRIV_VERSION_1_10_0:
1812fefc294bSDaniel Henrique Barboza         return PRIV_VER_1_10_0_STR;
1813fefc294bSDaniel Henrique Barboza     case PRIV_VERSION_1_11_0:
1814fefc294bSDaniel Henrique Barboza         return PRIV_VER_1_11_0_STR;
18153adf4defSFea.Wang     case PRIV_VERSION_1_12_0:
18163adf4defSFea.Wang         return PRIV_VER_1_12_0_STR;
1817fefc294bSDaniel Henrique Barboza     case PRIV_VERSION_1_13_0:
1818fefc294bSDaniel Henrique Barboza         return PRIV_VER_1_13_0_STR;
1819fefc294bSDaniel Henrique Barboza     default:
1820fefc294bSDaniel Henrique Barboza         return NULL;
1821fefc294bSDaniel Henrique Barboza     }
1822fefc294bSDaniel Henrique Barboza }
1823fefc294bSDaniel Henrique Barboza 
prop_priv_spec_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1824fefc294bSDaniel Henrique Barboza static void prop_priv_spec_set(Object *obj, Visitor *v, const char *name,
1825fefc294bSDaniel Henrique Barboza                                void *opaque, Error **errp)
1826fefc294bSDaniel Henrique Barboza {
1827fefc294bSDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
1828fefc294bSDaniel Henrique Barboza     g_autofree char *value = NULL;
1829fefc294bSDaniel Henrique Barboza     int priv_version = -1;
1830fefc294bSDaniel Henrique Barboza 
1831fefc294bSDaniel Henrique Barboza     visit_type_str(v, name, &value, errp);
1832fefc294bSDaniel Henrique Barboza 
1833fefc294bSDaniel Henrique Barboza     priv_version = priv_spec_from_str(value);
1834fefc294bSDaniel Henrique Barboza     if (priv_version < 0) {
1835fefc294bSDaniel Henrique Barboza         error_setg(errp, "Unsupported privilege spec version '%s'", value);
1836fefc294bSDaniel Henrique Barboza         return;
1837fefc294bSDaniel Henrique Barboza     }
1838fefc294bSDaniel Henrique Barboza 
1839fefc294bSDaniel Henrique Barboza     if (priv_version != cpu->env.priv_ver && riscv_cpu_is_vendor(obj)) {
1840fefc294bSDaniel Henrique Barboza         cpu_set_prop_err(cpu, name, errp);
1841fefc294bSDaniel Henrique Barboza         error_append_hint(errp, "Current '%s' val: %s\n", name,
1842fefc294bSDaniel Henrique Barboza                           object_property_get_str(obj, name, NULL));
1843fefc294bSDaniel Henrique Barboza         return;
1844fefc294bSDaniel Henrique Barboza     }
1845fefc294bSDaniel Henrique Barboza 
1846fefc294bSDaniel Henrique Barboza     cpu_option_add_user_setting(name, priv_version);
1847fefc294bSDaniel Henrique Barboza     cpu->env.priv_ver = priv_version;
1848fefc294bSDaniel Henrique Barboza }
1849fefc294bSDaniel Henrique Barboza 
prop_priv_spec_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1850fefc294bSDaniel Henrique Barboza static void prop_priv_spec_get(Object *obj, Visitor *v, const char *name,
1851fefc294bSDaniel Henrique Barboza                                void *opaque, Error **errp)
1852fefc294bSDaniel Henrique Barboza {
1853fefc294bSDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
1854fefc294bSDaniel Henrique Barboza     const char *value = priv_spec_to_str(cpu->env.priv_ver);
1855fefc294bSDaniel Henrique Barboza 
1856fefc294bSDaniel Henrique Barboza     visit_type_str(v, name, (char **)&value, errp);
1857fefc294bSDaniel Henrique Barboza }
1858fefc294bSDaniel Henrique Barboza 
1859fefc294bSDaniel Henrique Barboza static const PropertyInfo prop_priv_spec = {
1860fefc294bSDaniel Henrique Barboza     .name = "priv_spec",
1861fefc294bSDaniel Henrique Barboza     .get = prop_priv_spec_get,
1862fefc294bSDaniel Henrique Barboza     .set = prop_priv_spec_set,
186341f2b94eSDaniel Henrique Barboza };
186441f2b94eSDaniel Henrique Barboza 
prop_vext_spec_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)186541f2b94eSDaniel Henrique Barboza static void prop_vext_spec_set(Object *obj, Visitor *v, const char *name,
186641f2b94eSDaniel Henrique Barboza                                void *opaque, Error **errp)
186741f2b94eSDaniel Henrique Barboza {
18688ea3fcefSDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
186941f2b94eSDaniel Henrique Barboza     g_autofree char *value = NULL;
187041f2b94eSDaniel Henrique Barboza 
187141f2b94eSDaniel Henrique Barboza     visit_type_str(v, name, &value, errp);
187241f2b94eSDaniel Henrique Barboza 
187341f2b94eSDaniel Henrique Barboza     if (g_strcmp0(value, VEXT_VER_1_00_0_STR) != 0) {
187441f2b94eSDaniel Henrique Barboza         error_setg(errp, "Unsupported vector spec version '%s'", value);
187541f2b94eSDaniel Henrique Barboza         return;
187641f2b94eSDaniel Henrique Barboza     }
187741f2b94eSDaniel Henrique Barboza 
187841f2b94eSDaniel Henrique Barboza     cpu_option_add_user_setting(name, VEXT_VERSION_1_00_0);
187941f2b94eSDaniel Henrique Barboza     cpu->env.vext_ver = VEXT_VERSION_1_00_0;
188041f2b94eSDaniel Henrique Barboza }
188141f2b94eSDaniel Henrique Barboza 
prop_vext_spec_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)188241f2b94eSDaniel Henrique Barboza static void prop_vext_spec_get(Object *obj, Visitor *v, const char *name,
188341f2b94eSDaniel Henrique Barboza                                void *opaque, Error **errp)
188441f2b94eSDaniel Henrique Barboza {
188541f2b94eSDaniel Henrique Barboza     const char *value = VEXT_VER_1_00_0_STR;
188641f2b94eSDaniel Henrique Barboza 
188741f2b94eSDaniel Henrique Barboza     visit_type_str(v, name, (char **)&value, errp);
188841f2b94eSDaniel Henrique Barboza }
188941f2b94eSDaniel Henrique Barboza 
189041f2b94eSDaniel Henrique Barboza static const PropertyInfo prop_vext_spec = {
189141f2b94eSDaniel Henrique Barboza     .name = "vext_spec",
189241f2b94eSDaniel Henrique Barboza     .get = prop_vext_spec_get,
189341f2b94eSDaniel Henrique Barboza     .set = prop_vext_spec_set,
1894fae0b533SDaniel Henrique Barboza };
1895fae0b533SDaniel Henrique Barboza 
prop_vlen_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1896fae0b533SDaniel Henrique Barboza static void prop_vlen_set(Object *obj, Visitor *v, const char *name,
1897fae0b533SDaniel Henrique Barboza                          void *opaque, Error **errp)
1898fae0b533SDaniel Henrique Barboza {
1899fae0b533SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
1900fae0b533SDaniel Henrique Barboza     uint16_t value;
1901fae0b533SDaniel Henrique Barboza 
1902fae0b533SDaniel Henrique Barboza     if (!visit_type_uint16(v, name, &value, errp)) {
1903fae0b533SDaniel Henrique Barboza         return;
1904fae0b533SDaniel Henrique Barboza     }
1905fae0b533SDaniel Henrique Barboza 
1906fae0b533SDaniel Henrique Barboza     if (!is_power_of_2(value)) {
1907fae0b533SDaniel Henrique Barboza         error_setg(errp, "Vector extension VLEN must be power of 2");
1908fae0b533SDaniel Henrique Barboza         return;
19094f6d036cSDaniel Henrique Barboza     }
1910fae0b533SDaniel Henrique Barboza 
1911fae0b533SDaniel Henrique Barboza     if (value != cpu->cfg.vlenb && riscv_cpu_is_vendor(obj)) {
19124f6d036cSDaniel Henrique Barboza         cpu_set_prop_err(cpu, name, errp);
1913fae0b533SDaniel Henrique Barboza         error_append_hint(errp, "Current '%s' val: %u\n",
1914fae0b533SDaniel Henrique Barboza                           name, cpu->cfg.vlenb << 3);
1915fae0b533SDaniel Henrique Barboza         return;
1916fae0b533SDaniel Henrique Barboza     }
191704eb30a0SDaniel Henrique Barboza 
1918fae0b533SDaniel Henrique Barboza     cpu_option_add_user_setting(name, value);
1919fae0b533SDaniel Henrique Barboza     cpu->cfg.vlenb = value >> 3;
1920fae0b533SDaniel Henrique Barboza }
1921fae0b533SDaniel Henrique Barboza 
prop_vlen_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1922fae0b533SDaniel Henrique Barboza static void prop_vlen_get(Object *obj, Visitor *v, const char *name,
19234f6d036cSDaniel Henrique Barboza                          void *opaque, Error **errp)
1924fae0b533SDaniel Henrique Barboza {
1925fae0b533SDaniel Henrique Barboza     uint16_t value = RISCV_CPU(obj)->cfg.vlenb << 3;
1926fae0b533SDaniel Henrique Barboza 
1927fae0b533SDaniel Henrique Barboza     visit_type_uint16(v, name, &value, errp);
1928fae0b533SDaniel Henrique Barboza }
1929fae0b533SDaniel Henrique Barboza 
1930fae0b533SDaniel Henrique Barboza static const PropertyInfo prop_vlen = {
1931fae0b533SDaniel Henrique Barboza     .name = "vlen",
1932fae0b533SDaniel Henrique Barboza     .get = prop_vlen_get,
1933fae0b533SDaniel Henrique Barboza     .set = prop_vlen_set,
19349d1173d2SDaniel Henrique Barboza };
19359d1173d2SDaniel Henrique Barboza 
prop_elen_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)19369d1173d2SDaniel Henrique Barboza static void prop_elen_set(Object *obj, Visitor *v, const char *name,
19379d1173d2SDaniel Henrique Barboza                          void *opaque, Error **errp)
19389d1173d2SDaniel Henrique Barboza {
19398ea3fcefSDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
19409d1173d2SDaniel Henrique Barboza     uint16_t value;
19419d1173d2SDaniel Henrique Barboza 
19429d1173d2SDaniel Henrique Barboza     if (!visit_type_uint16(v, name, &value, errp)) {
19439d1173d2SDaniel Henrique Barboza         return;
19449d1173d2SDaniel Henrique Barboza     }
19459d1173d2SDaniel Henrique Barboza 
19469d1173d2SDaniel Henrique Barboza     if (!is_power_of_2(value)) {
19479d1173d2SDaniel Henrique Barboza         error_setg(errp, "Vector extension ELEN must be power of 2");
19489d1173d2SDaniel Henrique Barboza         return;
19499d1173d2SDaniel Henrique Barboza     }
19509d1173d2SDaniel Henrique Barboza 
19519d1173d2SDaniel Henrique Barboza     if (value != cpu->cfg.elen && riscv_cpu_is_vendor(obj)) {
19529d1173d2SDaniel Henrique Barboza         cpu_set_prop_err(cpu, name, errp);
19539d1173d2SDaniel Henrique Barboza         error_append_hint(errp, "Current '%s' val: %u\n",
19549d1173d2SDaniel Henrique Barboza                           name, cpu->cfg.elen);
19559d1173d2SDaniel Henrique Barboza         return;
19569d1173d2SDaniel Henrique Barboza     }
19579d1173d2SDaniel Henrique Barboza 
19589d1173d2SDaniel Henrique Barboza     cpu_option_add_user_setting(name, value);
19599d1173d2SDaniel Henrique Barboza     cpu->cfg.elen = value;
19609d1173d2SDaniel Henrique Barboza }
19619d1173d2SDaniel Henrique Barboza 
prop_elen_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)19629d1173d2SDaniel Henrique Barboza static void prop_elen_get(Object *obj, Visitor *v, const char *name,
19639d1173d2SDaniel Henrique Barboza                          void *opaque, Error **errp)
19649d1173d2SDaniel Henrique Barboza {
19659d1173d2SDaniel Henrique Barboza     uint16_t value = RISCV_CPU(obj)->cfg.elen;
19669d1173d2SDaniel Henrique Barboza 
19679d1173d2SDaniel Henrique Barboza     visit_type_uint16(v, name, &value, errp);
19689d1173d2SDaniel Henrique Barboza }
19699d1173d2SDaniel Henrique Barboza 
19709d1173d2SDaniel Henrique Barboza static const PropertyInfo prop_elen = {
19719d1173d2SDaniel Henrique Barboza     .name = "elen",
19729d1173d2SDaniel Henrique Barboza     .get = prop_elen_get,
19739d1173d2SDaniel Henrique Barboza     .set = prop_elen_set,
1974b84efa39SDaniel Henrique Barboza };
1975b84efa39SDaniel Henrique Barboza 
prop_cbom_blksize_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1976b84efa39SDaniel Henrique Barboza static void prop_cbom_blksize_set(Object *obj, Visitor *v, const char *name,
1977b84efa39SDaniel Henrique Barboza                                   void *opaque, Error **errp)
1978b84efa39SDaniel Henrique Barboza {
1979b84efa39SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
1980b84efa39SDaniel Henrique Barboza     uint16_t value;
1981b84efa39SDaniel Henrique Barboza 
1982b84efa39SDaniel Henrique Barboza     if (!visit_type_uint16(v, name, &value, errp)) {
1983b84efa39SDaniel Henrique Barboza         return;
1984b84efa39SDaniel Henrique Barboza     }
1985b84efa39SDaniel Henrique Barboza 
1986b84efa39SDaniel Henrique Barboza     if (value != cpu->cfg.cbom_blocksize && riscv_cpu_is_vendor(obj)) {
1987b84efa39SDaniel Henrique Barboza         cpu_set_prop_err(cpu, name, errp);
1988b84efa39SDaniel Henrique Barboza         error_append_hint(errp, "Current '%s' val: %u\n",
1989b84efa39SDaniel Henrique Barboza                           name, cpu->cfg.cbom_blocksize);
1990b84efa39SDaniel Henrique Barboza         return;
1991b84efa39SDaniel Henrique Barboza     }
1992b84efa39SDaniel Henrique Barboza 
1993b84efa39SDaniel Henrique Barboza     cpu_option_add_user_setting(name, value);
1994b84efa39SDaniel Henrique Barboza     cpu->cfg.cbom_blocksize = value;
1995b84efa39SDaniel Henrique Barboza }
1996b84efa39SDaniel Henrique Barboza 
prop_cbom_blksize_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)1997b84efa39SDaniel Henrique Barboza static void prop_cbom_blksize_get(Object *obj, Visitor *v, const char *name,
1998b84efa39SDaniel Henrique Barboza                          void *opaque, Error **errp)
1999b84efa39SDaniel Henrique Barboza {
2000b84efa39SDaniel Henrique Barboza     uint16_t value = RISCV_CPU(obj)->cfg.cbom_blocksize;
2001b84efa39SDaniel Henrique Barboza 
2002b84efa39SDaniel Henrique Barboza     visit_type_uint16(v, name, &value, errp);
2003b84efa39SDaniel Henrique Barboza }
2004b84efa39SDaniel Henrique Barboza 
2005b84efa39SDaniel Henrique Barboza static const PropertyInfo prop_cbom_blksize = {
2006b84efa39SDaniel Henrique Barboza     .name = "cbom_blocksize",
2007b84efa39SDaniel Henrique Barboza     .get = prop_cbom_blksize_get,
2008b84efa39SDaniel Henrique Barboza     .set = prop_cbom_blksize_set,
2009811ef853SDaniel Henrique Barboza };
2010811ef853SDaniel Henrique Barboza 
prop_cbop_blksize_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)2011811ef853SDaniel Henrique Barboza static void prop_cbop_blksize_set(Object *obj, Visitor *v, const char *name,
2012811ef853SDaniel Henrique Barboza                                   void *opaque, Error **errp)
2013811ef853SDaniel Henrique Barboza {
2014811ef853SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
2015811ef853SDaniel Henrique Barboza     uint16_t value;
2016811ef853SDaniel Henrique Barboza 
2017811ef853SDaniel Henrique Barboza     if (!visit_type_uint16(v, name, &value, errp)) {
2018811ef853SDaniel Henrique Barboza         return;
2019811ef853SDaniel Henrique Barboza     }
2020811ef853SDaniel Henrique Barboza 
2021811ef853SDaniel Henrique Barboza     if (value != cpu->cfg.cbop_blocksize && riscv_cpu_is_vendor(obj)) {
2022811ef853SDaniel Henrique Barboza         cpu_set_prop_err(cpu, name, errp);
2023811ef853SDaniel Henrique Barboza         error_append_hint(errp, "Current '%s' val: %u\n",
2024811ef853SDaniel Henrique Barboza                           name, cpu->cfg.cbop_blocksize);
2025811ef853SDaniel Henrique Barboza         return;
2026811ef853SDaniel Henrique Barboza     }
2027811ef853SDaniel Henrique Barboza 
2028811ef853SDaniel Henrique Barboza     cpu_option_add_user_setting(name, value);
2029811ef853SDaniel Henrique Barboza     cpu->cfg.cbop_blocksize = value;
2030811ef853SDaniel Henrique Barboza }
2031811ef853SDaniel Henrique Barboza 
prop_cbop_blksize_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)2032811ef853SDaniel Henrique Barboza static void prop_cbop_blksize_get(Object *obj, Visitor *v, const char *name,
2033811ef853SDaniel Henrique Barboza                          void *opaque, Error **errp)
2034811ef853SDaniel Henrique Barboza {
2035811ef853SDaniel Henrique Barboza     uint16_t value = RISCV_CPU(obj)->cfg.cbop_blocksize;
2036811ef853SDaniel Henrique Barboza 
2037811ef853SDaniel Henrique Barboza     visit_type_uint16(v, name, &value, errp);
2038811ef853SDaniel Henrique Barboza }
2039811ef853SDaniel Henrique Barboza 
2040811ef853SDaniel Henrique Barboza static const PropertyInfo prop_cbop_blksize = {
2041811ef853SDaniel Henrique Barboza     .name = "cbop_blocksize",
2042811ef853SDaniel Henrique Barboza     .get = prop_cbop_blksize_get,
2043811ef853SDaniel Henrique Barboza     .set = prop_cbop_blksize_set,
204482f7b1d4SDaniel Henrique Barboza };
204582f7b1d4SDaniel Henrique Barboza 
prop_cboz_blksize_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)204682f7b1d4SDaniel Henrique Barboza static void prop_cboz_blksize_set(Object *obj, Visitor *v, const char *name,
204782f7b1d4SDaniel Henrique Barboza                                   void *opaque, Error **errp)
204882f7b1d4SDaniel Henrique Barboza {
204982f7b1d4SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
205082f7b1d4SDaniel Henrique Barboza     uint16_t value;
205182f7b1d4SDaniel Henrique Barboza 
205282f7b1d4SDaniel Henrique Barboza     if (!visit_type_uint16(v, name, &value, errp)) {
205382f7b1d4SDaniel Henrique Barboza         return;
205482f7b1d4SDaniel Henrique Barboza     }
205582f7b1d4SDaniel Henrique Barboza 
205682f7b1d4SDaniel Henrique Barboza     if (value != cpu->cfg.cboz_blocksize && riscv_cpu_is_vendor(obj)) {
205782f7b1d4SDaniel Henrique Barboza         cpu_set_prop_err(cpu, name, errp);
205882f7b1d4SDaniel Henrique Barboza         error_append_hint(errp, "Current '%s' val: %u\n",
205982f7b1d4SDaniel Henrique Barboza                           name, cpu->cfg.cboz_blocksize);
206082f7b1d4SDaniel Henrique Barboza         return;
206182f7b1d4SDaniel Henrique Barboza     }
206282f7b1d4SDaniel Henrique Barboza 
206382f7b1d4SDaniel Henrique Barboza     cpu_option_add_user_setting(name, value);
206482f7b1d4SDaniel Henrique Barboza     cpu->cfg.cboz_blocksize = value;
206582f7b1d4SDaniel Henrique Barboza }
206682f7b1d4SDaniel Henrique Barboza 
prop_cboz_blksize_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)206782f7b1d4SDaniel Henrique Barboza static void prop_cboz_blksize_get(Object *obj, Visitor *v, const char *name,
206882f7b1d4SDaniel Henrique Barboza                          void *opaque, Error **errp)
206982f7b1d4SDaniel Henrique Barboza {
207082f7b1d4SDaniel Henrique Barboza     uint16_t value = RISCV_CPU(obj)->cfg.cboz_blocksize;
207182f7b1d4SDaniel Henrique Barboza 
207282f7b1d4SDaniel Henrique Barboza     visit_type_uint16(v, name, &value, errp);
207382f7b1d4SDaniel Henrique Barboza }
207482f7b1d4SDaniel Henrique Barboza 
207582f7b1d4SDaniel Henrique Barboza static const PropertyInfo prop_cboz_blksize = {
207682f7b1d4SDaniel Henrique Barboza     .name = "cboz_blocksize",
207782f7b1d4SDaniel Henrique Barboza     .get = prop_cboz_blksize_get,
207882f7b1d4SDaniel Henrique Barboza     .set = prop_cboz_blksize_set,
2079a9a25939SDaniel Henrique Barboza };
2080a9a25939SDaniel Henrique Barboza 
prop_mvendorid_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)2081a9a25939SDaniel Henrique Barboza static void prop_mvendorid_set(Object *obj, Visitor *v, const char *name,
2082a9a25939SDaniel Henrique Barboza                                void *opaque, Error **errp)
2083a9a25939SDaniel Henrique Barboza {
2084a9a25939SDaniel Henrique Barboza     bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
2085a9a25939SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
2086a9a25939SDaniel Henrique Barboza     uint32_t prev_val = cpu->cfg.mvendorid;
2087a9a25939SDaniel Henrique Barboza     uint32_t value;
2088a9a25939SDaniel Henrique Barboza 
2089a9a25939SDaniel Henrique Barboza     if (!visit_type_uint32(v, name, &value, errp)) {
2090a9a25939SDaniel Henrique Barboza         return;
2091a9a25939SDaniel Henrique Barboza     }
2092a9a25939SDaniel Henrique Barboza 
2093a9a25939SDaniel Henrique Barboza     if (!dynamic_cpu && prev_val != value) {
2094a9a25939SDaniel Henrique Barboza         error_setg(errp, "Unable to change %s mvendorid (0x%x)",
2095a9a25939SDaniel Henrique Barboza                    object_get_typename(obj), prev_val);
2096a9a25939SDaniel Henrique Barboza         return;
2097a9a25939SDaniel Henrique Barboza     }
2098a9a25939SDaniel Henrique Barboza 
2099a9a25939SDaniel Henrique Barboza     cpu->cfg.mvendorid = value;
2100a9a25939SDaniel Henrique Barboza }
2101a9a25939SDaniel Henrique Barboza 
prop_mvendorid_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)2102a9a25939SDaniel Henrique Barboza static void prop_mvendorid_get(Object *obj, Visitor *v, const char *name,
2103a9a25939SDaniel Henrique Barboza                                void *opaque, Error **errp)
2104a9a25939SDaniel Henrique Barboza {
2105a9a25939SDaniel Henrique Barboza     uint32_t value = RISCV_CPU(obj)->cfg.mvendorid;
2106a9a25939SDaniel Henrique Barboza 
2107a9a25939SDaniel Henrique Barboza     visit_type_uint32(v, name, &value, errp);
2108a9a25939SDaniel Henrique Barboza }
2109a9a25939SDaniel Henrique Barboza 
2110a9a25939SDaniel Henrique Barboza static const PropertyInfo prop_mvendorid = {
2111a9a25939SDaniel Henrique Barboza     .name = "mvendorid",
2112a9a25939SDaniel Henrique Barboza     .get = prop_mvendorid_get,
2113a9a25939SDaniel Henrique Barboza     .set = prop_mvendorid_set,
21149bb9d424SDaniel Henrique Barboza };
21159bb9d424SDaniel Henrique Barboza 
prop_mimpid_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)21169bb9d424SDaniel Henrique Barboza static void prop_mimpid_set(Object *obj, Visitor *v, const char *name,
21179bb9d424SDaniel Henrique Barboza                             void *opaque, Error **errp)
21189bb9d424SDaniel Henrique Barboza {
21199bb9d424SDaniel Henrique Barboza     bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
21209bb9d424SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
21219bb9d424SDaniel Henrique Barboza     uint64_t prev_val = cpu->cfg.mimpid;
21229bb9d424SDaniel Henrique Barboza     uint64_t value;
21239bb9d424SDaniel Henrique Barboza 
21249bb9d424SDaniel Henrique Barboza     if (!visit_type_uint64(v, name, &value, errp)) {
21259bb9d424SDaniel Henrique Barboza         return;
21269bb9d424SDaniel Henrique Barboza     }
21279bb9d424SDaniel Henrique Barboza 
21289bb9d424SDaniel Henrique Barboza     if (!dynamic_cpu && prev_val != value) {
21299bb9d424SDaniel Henrique Barboza         error_setg(errp, "Unable to change %s mimpid (0x%" PRIu64 ")",
21309bb9d424SDaniel Henrique Barboza                    object_get_typename(obj), prev_val);
21319bb9d424SDaniel Henrique Barboza         return;
21329bb9d424SDaniel Henrique Barboza     }
21339bb9d424SDaniel Henrique Barboza 
21349bb9d424SDaniel Henrique Barboza     cpu->cfg.mimpid = value;
21359bb9d424SDaniel Henrique Barboza }
21369bb9d424SDaniel Henrique Barboza 
prop_mimpid_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)21379bb9d424SDaniel Henrique Barboza static void prop_mimpid_get(Object *obj, Visitor *v, const char *name,
21389bb9d424SDaniel Henrique Barboza                             void *opaque, Error **errp)
21399bb9d424SDaniel Henrique Barboza {
21409bb9d424SDaniel Henrique Barboza     uint64_t value = RISCV_CPU(obj)->cfg.mimpid;
21419bb9d424SDaniel Henrique Barboza 
21429bb9d424SDaniel Henrique Barboza     visit_type_uint64(v, name, &value, errp);
21439bb9d424SDaniel Henrique Barboza }
21449bb9d424SDaniel Henrique Barboza 
21459bb9d424SDaniel Henrique Barboza static const PropertyInfo prop_mimpid = {
21469bb9d424SDaniel Henrique Barboza     .name = "mimpid",
21479bb9d424SDaniel Henrique Barboza     .get = prop_mimpid_get,
21489bb9d424SDaniel Henrique Barboza     .set = prop_mimpid_set,
214910efbe01SDaniel Henrique Barboza };
215010efbe01SDaniel Henrique Barboza 
prop_marchid_set(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)215110efbe01SDaniel Henrique Barboza static void prop_marchid_set(Object *obj, Visitor *v, const char *name,
215210efbe01SDaniel Henrique Barboza                              void *opaque, Error **errp)
215310efbe01SDaniel Henrique Barboza {
215410efbe01SDaniel Henrique Barboza     bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
215510efbe01SDaniel Henrique Barboza     RISCVCPU *cpu = RISCV_CPU(obj);
215610efbe01SDaniel Henrique Barboza     uint64_t prev_val = cpu->cfg.marchid;
215710efbe01SDaniel Henrique Barboza     uint64_t value, invalid_val;
215810efbe01SDaniel Henrique Barboza     uint32_t mxlen = 0;
215910efbe01SDaniel Henrique Barboza 
216010efbe01SDaniel Henrique Barboza     if (!visit_type_uint64(v, name, &value, errp)) {
216110efbe01SDaniel Henrique Barboza         return;
216210efbe01SDaniel Henrique Barboza     }
216310efbe01SDaniel Henrique Barboza 
216410efbe01SDaniel Henrique Barboza     if (!dynamic_cpu && prev_val != value) {
216510efbe01SDaniel Henrique Barboza         error_setg(errp, "Unable to change %s marchid (0x%" PRIu64 ")",
216610efbe01SDaniel Henrique Barboza                    object_get_typename(obj), prev_val);
216710efbe01SDaniel Henrique Barboza         return;
216810efbe01SDaniel Henrique Barboza     }
216910efbe01SDaniel Henrique Barboza 
217010efbe01SDaniel Henrique Barboza     switch (riscv_cpu_mxl(&cpu->env)) {
217110efbe01SDaniel Henrique Barboza     case MXL_RV32:
217210efbe01SDaniel Henrique Barboza         mxlen = 32;
217310efbe01SDaniel Henrique Barboza         break;
217410efbe01SDaniel Henrique Barboza     case MXL_RV64:
217510efbe01SDaniel Henrique Barboza     case MXL_RV128:
217610efbe01SDaniel Henrique Barboza         mxlen = 64;
217710efbe01SDaniel Henrique Barboza         break;
217810efbe01SDaniel Henrique Barboza     default:
217910efbe01SDaniel Henrique Barboza         g_assert_not_reached();
218010efbe01SDaniel Henrique Barboza     }
218110efbe01SDaniel Henrique Barboza 
218210efbe01SDaniel Henrique Barboza     invalid_val = 1LL << (mxlen - 1);
218310efbe01SDaniel Henrique Barboza 
218410efbe01SDaniel Henrique Barboza     if (value == invalid_val) {
218510efbe01SDaniel Henrique Barboza         error_setg(errp, "Unable to set marchid with MSB (%u) bit set "
218610efbe01SDaniel Henrique Barboza                          "and the remaining bits zero", mxlen);
218710efbe01SDaniel Henrique Barboza         return;
218810efbe01SDaniel Henrique Barboza     }
218910efbe01SDaniel Henrique Barboza 
219010efbe01SDaniel Henrique Barboza     cpu->cfg.marchid = value;
219110efbe01SDaniel Henrique Barboza }
219210efbe01SDaniel Henrique Barboza 
prop_marchid_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)219310efbe01SDaniel Henrique Barboza static void prop_marchid_get(Object *obj, Visitor *v, const char *name,
219410efbe01SDaniel Henrique Barboza                              void *opaque, Error **errp)
219510efbe01SDaniel Henrique Barboza {
219610efbe01SDaniel Henrique Barboza     uint64_t value = RISCV_CPU(obj)->cfg.marchid;
219710efbe01SDaniel Henrique Barboza 
219810efbe01SDaniel Henrique Barboza     visit_type_uint64(v, name, &value, errp);
219910efbe01SDaniel Henrique Barboza }
220010efbe01SDaniel Henrique Barboza 
220110efbe01SDaniel Henrique Barboza static const PropertyInfo prop_marchid = {
220210efbe01SDaniel Henrique Barboza     .name = "marchid",
220310efbe01SDaniel Henrique Barboza     .get = prop_marchid_get,
220410efbe01SDaniel Henrique Barboza     .set = prop_marchid_set,
22053f361847SDaniel Henrique Barboza };
2206a0952c15SDaniel Henrique Barboza 
2207a0952c15SDaniel Henrique Barboza /*
2208a0952c15SDaniel Henrique Barboza  * RVA22U64 defines some 'named features' that are cache
2209a0952c15SDaniel Henrique Barboza  * related: Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa
22103f361847SDaniel Henrique Barboza  * and Zicclsm. They are always implemented in TCG and
22113f361847SDaniel Henrique Barboza  * doesn't need to be manually enabled by the profile.
221279593ca4SDaniel Henrique Barboza  */
22133f361847SDaniel Henrique Barboza static RISCVCPUProfile RVA22U64 = {
22143f361847SDaniel Henrique Barboza     .parent = NULL,
22151a7d4fcbSDaniel Henrique Barboza     .name = "rva22u64",
221655398025SDaniel Henrique Barboza     .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU,
22173f361847SDaniel Henrique Barboza     .priv_spec = RISCV_PROFILE_ATTR_UNUSED,
22183f361847SDaniel Henrique Barboza     .satp_mode = RISCV_PROFILE_ATTR_UNUSED,
22193f361847SDaniel Henrique Barboza     .ext_offsets = {
22203f361847SDaniel Henrique Barboza         CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause),
22213f361847SDaniel Henrique Barboza         CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),
22223f361847SDaniel Henrique Barboza         CPU_CFG_OFFSET(ext_zbs), CPU_CFG_OFFSET(ext_zfhmin),
22233f361847SDaniel Henrique Barboza         CPU_CFG_OFFSET(ext_zkt), CPU_CFG_OFFSET(ext_zicntr),
22243f361847SDaniel Henrique Barboza         CPU_CFG_OFFSET(ext_zihpm), CPU_CFG_OFFSET(ext_zicbom),
22253f361847SDaniel Henrique Barboza         CPU_CFG_OFFSET(ext_zicbop), CPU_CFG_OFFSET(ext_zicboz),
22263b802226SDaniel Henrique Barboza 
22273f361847SDaniel Henrique Barboza         /* mandatory named features for this profile */
22283f361847SDaniel Henrique Barboza         CPU_CFG_OFFSET(ext_zic64b),
22293f361847SDaniel Henrique Barboza 
22303f361847SDaniel Henrique Barboza         RISCV_PROFILE_EXT_LIST_END
22313f361847SDaniel Henrique Barboza     }
2232af651969SDaniel Henrique Barboza };
2233af651969SDaniel Henrique Barboza 
2234af651969SDaniel Henrique Barboza /*
2235af651969SDaniel Henrique Barboza  * As with RVA22U64, RVA22S64 also defines 'named features'.
2236af651969SDaniel Henrique Barboza  *
2237af651969SDaniel Henrique Barboza  * Cache related features that we consider enabled since we don't
2238af651969SDaniel Henrique Barboza  * implement cache: Ssccptr
2239af651969SDaniel Henrique Barboza  *
2240af651969SDaniel Henrique Barboza  * Other named features that we already implement: Sstvecd, Sstvala,
2241af651969SDaniel Henrique Barboza  * Sscounterenw
2242af651969SDaniel Henrique Barboza  *
2243af651969SDaniel Henrique Barboza  * The remaining features/extensions comes from RVA22U64.
2244af651969SDaniel Henrique Barboza  */
2245af651969SDaniel Henrique Barboza static RISCVCPUProfile RVA22S64 = {
2246af651969SDaniel Henrique Barboza     .parent = &RVA22U64,
2247af651969SDaniel Henrique Barboza     .name = "rva22s64",
2248af651969SDaniel Henrique Barboza     .misa_ext = RVS,
2249af651969SDaniel Henrique Barboza     .priv_spec = PRIV_VERSION_1_12_0,
2250af651969SDaniel Henrique Barboza     .satp_mode = VM_1_10_SV39,
2251af651969SDaniel Henrique Barboza     .ext_offsets = {
2252adb49752SAndrew Jones         /* rva22s64 exts */
2253af651969SDaniel Henrique Barboza         CPU_CFG_OFFSET(ext_zifencei), CPU_CFG_OFFSET(ext_svpbmt),
2254af651969SDaniel Henrique Barboza         CPU_CFG_OFFSET(ext_svinval), CPU_CFG_OFFSET(ext_svade),
2255af651969SDaniel Henrique Barboza 
2256af651969SDaniel Henrique Barboza         RISCV_PROFILE_EXT_LIST_END
2257af651969SDaniel Henrique Barboza     }
22583f361847SDaniel Henrique Barboza };
22593f361847SDaniel Henrique Barboza 
2260af651969SDaniel Henrique Barboza RISCVCPUProfile *riscv_profiles[] = {
22613f361847SDaniel Henrique Barboza     &RVA22U64,
22623f361847SDaniel Henrique Barboza     &RVA22S64,
22633f361847SDaniel Henrique Barboza     NULL,
226417177339SFrank Chang };
226517177339SFrank Chang 
226617177339SFrank Chang static RISCVCPUImpliedExtsRule RVA_IMPLIED = {
226717177339SFrank Chang     .is_misa = true,
226817177339SFrank Chang     .ext = RVA,
226917177339SFrank Chang     .implied_multi_exts = {
227017177339SFrank Chang         CPU_CFG_OFFSET(ext_zalrsc), CPU_CFG_OFFSET(ext_zaamo),
227117177339SFrank Chang 
227217177339SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
227317177339SFrank Chang     },
227417177339SFrank Chang };
227517177339SFrank Chang 
227617177339SFrank Chang static RISCVCPUImpliedExtsRule RVD_IMPLIED = {
227717177339SFrank Chang     .is_misa = true,
227817177339SFrank Chang     .ext = RVD,
227917177339SFrank Chang     .implied_misa_exts = RVF,
228017177339SFrank Chang     .implied_multi_exts = { RISCV_IMPLIED_EXTS_RULE_END },
228117177339SFrank Chang };
228217177339SFrank Chang 
228317177339SFrank Chang static RISCVCPUImpliedExtsRule RVF_IMPLIED = {
228417177339SFrank Chang     .is_misa = true,
228517177339SFrank Chang     .ext = RVF,
228617177339SFrank Chang     .implied_multi_exts = {
228717177339SFrank Chang         CPU_CFG_OFFSET(ext_zicsr),
228817177339SFrank Chang 
228917177339SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
229017177339SFrank Chang     },
229117177339SFrank Chang };
229217177339SFrank Chang 
229317177339SFrank Chang static RISCVCPUImpliedExtsRule RVM_IMPLIED = {
229417177339SFrank Chang     .is_misa = true,
229517177339SFrank Chang     .ext = RVM,
229617177339SFrank Chang     .implied_multi_exts = {
229717177339SFrank Chang         CPU_CFG_OFFSET(ext_zmmul),
229817177339SFrank Chang 
229917177339SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
230017177339SFrank Chang     },
230117177339SFrank Chang };
230217177339SFrank Chang 
230317177339SFrank Chang static RISCVCPUImpliedExtsRule RVV_IMPLIED = {
230417177339SFrank Chang     .is_misa = true,
230517177339SFrank Chang     .ext = RVV,
230617177339SFrank Chang     .implied_multi_exts = {
230717177339SFrank Chang         CPU_CFG_OFFSET(ext_zve64d),
230817177339SFrank Chang 
230917177339SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
231017177339SFrank Chang     },
2311340c3ca5SFrank Chang };
2312340c3ca5SFrank Chang 
2313340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZCB_IMPLIED = {
2314340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zcb),
2315340c3ca5SFrank Chang     .implied_multi_exts = {
2316340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zca),
2317340c3ca5SFrank Chang 
2318340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2319340c3ca5SFrank Chang     },
2320340c3ca5SFrank Chang };
2321340c3ca5SFrank Chang 
2322340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZCD_IMPLIED = {
2323340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zcd),
2324340c3ca5SFrank Chang     .implied_misa_exts = RVD,
2325340c3ca5SFrank Chang     .implied_multi_exts = {
2326340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zca),
2327340c3ca5SFrank Chang 
2328340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2329340c3ca5SFrank Chang     },
2330340c3ca5SFrank Chang };
2331340c3ca5SFrank Chang 
2332340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZCE_IMPLIED = {
2333340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zce),
2334340c3ca5SFrank Chang     .implied_multi_exts = {
2335340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zcb), CPU_CFG_OFFSET(ext_zcmp),
2336340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zcmt),
2337340c3ca5SFrank Chang 
2338340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2339340c3ca5SFrank Chang     },
2340340c3ca5SFrank Chang };
2341340c3ca5SFrank Chang 
2342340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZCF_IMPLIED = {
2343340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zcf),
2344340c3ca5SFrank Chang     .implied_misa_exts = RVF,
2345340c3ca5SFrank Chang     .implied_multi_exts = {
2346340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zca),
2347340c3ca5SFrank Chang 
2348340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2349340c3ca5SFrank Chang     },
2350340c3ca5SFrank Chang };
2351340c3ca5SFrank Chang 
2352340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZCMP_IMPLIED = {
2353340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zcmp),
2354340c3ca5SFrank Chang     .implied_multi_exts = {
2355340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zca),
2356340c3ca5SFrank Chang 
2357340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2358340c3ca5SFrank Chang     },
2359340c3ca5SFrank Chang };
2360340c3ca5SFrank Chang 
2361340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZCMT_IMPLIED = {
2362340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zcmt),
2363340c3ca5SFrank Chang     .implied_multi_exts = {
2364340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zca), CPU_CFG_OFFSET(ext_zicsr),
2365340c3ca5SFrank Chang 
2366340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2367340c3ca5SFrank Chang     },
2368340c3ca5SFrank Chang };
2369340c3ca5SFrank Chang 
2370340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZDINX_IMPLIED = {
2371340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zdinx),
2372340c3ca5SFrank Chang     .implied_multi_exts = {
2373340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zfinx),
2374340c3ca5SFrank Chang 
2375340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2376340c3ca5SFrank Chang     },
2377340c3ca5SFrank Chang };
2378340c3ca5SFrank Chang 
2379340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZFA_IMPLIED = {
2380340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zfa),
2381340c3ca5SFrank Chang     .implied_misa_exts = RVF,
2382340c3ca5SFrank Chang     .implied_multi_exts = { RISCV_IMPLIED_EXTS_RULE_END },
2383340c3ca5SFrank Chang };
2384340c3ca5SFrank Chang 
2385340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZFBFMIN_IMPLIED = {
2386340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zfbfmin),
2387340c3ca5SFrank Chang     .implied_misa_exts = RVF,
2388340c3ca5SFrank Chang     .implied_multi_exts = { RISCV_IMPLIED_EXTS_RULE_END },
2389340c3ca5SFrank Chang };
2390340c3ca5SFrank Chang 
2391340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZFH_IMPLIED = {
2392340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zfh),
2393340c3ca5SFrank Chang     .implied_multi_exts = {
2394340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zfhmin),
2395340c3ca5SFrank Chang 
2396340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2397340c3ca5SFrank Chang     },
2398340c3ca5SFrank Chang };
2399340c3ca5SFrank Chang 
2400340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZFHMIN_IMPLIED = {
2401340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zfhmin),
2402340c3ca5SFrank Chang     .implied_misa_exts = RVF,
2403340c3ca5SFrank Chang     .implied_multi_exts = { RISCV_IMPLIED_EXTS_RULE_END },
2404340c3ca5SFrank Chang };
2405340c3ca5SFrank Chang 
2406340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZFINX_IMPLIED = {
2407340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zfinx),
2408340c3ca5SFrank Chang     .implied_multi_exts = {
2409340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zicsr),
2410340c3ca5SFrank Chang 
2411340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2412340c3ca5SFrank Chang     },
2413340c3ca5SFrank Chang };
2414340c3ca5SFrank Chang 
2415340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZHINX_IMPLIED = {
2416340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zhinx),
2417340c3ca5SFrank Chang     .implied_multi_exts = {
2418340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zhinxmin),
2419340c3ca5SFrank Chang 
2420340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2421340c3ca5SFrank Chang     },
2422340c3ca5SFrank Chang };
2423340c3ca5SFrank Chang 
2424340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZHINXMIN_IMPLIED = {
2425340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zhinxmin),
2426340c3ca5SFrank Chang     .implied_multi_exts = {
2427340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zfinx),
2428340c3ca5SFrank Chang 
2429340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2430340c3ca5SFrank Chang     },
2431340c3ca5SFrank Chang };
2432340c3ca5SFrank Chang 
2433340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZICNTR_IMPLIED = {
2434340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zicntr),
2435340c3ca5SFrank Chang     .implied_multi_exts = {
2436340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zicsr),
2437340c3ca5SFrank Chang 
2438340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2439340c3ca5SFrank Chang     },
2440340c3ca5SFrank Chang };
2441340c3ca5SFrank Chang 
2442340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZIHPM_IMPLIED = {
2443340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zihpm),
2444340c3ca5SFrank Chang     .implied_multi_exts = {
2445340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zicsr),
2446340c3ca5SFrank Chang 
2447340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2448340c3ca5SFrank Chang     },
2449340c3ca5SFrank Chang };
2450340c3ca5SFrank Chang 
2451340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZK_IMPLIED = {
2452340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zk),
2453340c3ca5SFrank Chang     .implied_multi_exts = {
2454340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zkn), CPU_CFG_OFFSET(ext_zkr),
2455340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zkt),
2456340c3ca5SFrank Chang 
2457340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2458340c3ca5SFrank Chang     },
2459340c3ca5SFrank Chang };
2460340c3ca5SFrank Chang 
2461340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZKN_IMPLIED = {
2462340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zkn),
2463340c3ca5SFrank Chang     .implied_multi_exts = {
2464340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zbkb), CPU_CFG_OFFSET(ext_zbkc),
2465340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zbkx), CPU_CFG_OFFSET(ext_zkne),
2466340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zknd), CPU_CFG_OFFSET(ext_zknh),
2467340c3ca5SFrank Chang 
2468340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2469340c3ca5SFrank Chang     },
2470340c3ca5SFrank Chang };
2471340c3ca5SFrank Chang 
2472340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZKS_IMPLIED = {
2473340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zks),
2474340c3ca5SFrank Chang     .implied_multi_exts = {
2475340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zbkb), CPU_CFG_OFFSET(ext_zbkc),
2476340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zbkx), CPU_CFG_OFFSET(ext_zksed),
2477340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zksh),
2478340c3ca5SFrank Chang 
2479340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2480340c3ca5SFrank Chang     },
2481340c3ca5SFrank Chang };
2482340c3ca5SFrank Chang 
2483340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVBB_IMPLIED = {
2484340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvbb),
2485340c3ca5SFrank Chang     .implied_multi_exts = {
2486340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvkb),
2487340c3ca5SFrank Chang 
2488340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2489340c3ca5SFrank Chang     },
2490340c3ca5SFrank Chang };
2491340c3ca5SFrank Chang 
2492340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVE32F_IMPLIED = {
2493340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zve32f),
2494340c3ca5SFrank Chang     .implied_misa_exts = RVF,
2495340c3ca5SFrank Chang     .implied_multi_exts = {
2496340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zve32x),
2497340c3ca5SFrank Chang 
2498340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2499340c3ca5SFrank Chang     },
2500340c3ca5SFrank Chang };
2501340c3ca5SFrank Chang 
2502340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVE32X_IMPLIED = {
2503340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zve32x),
2504340c3ca5SFrank Chang     .implied_multi_exts = {
2505340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zicsr),
2506340c3ca5SFrank Chang 
2507340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2508340c3ca5SFrank Chang     },
2509340c3ca5SFrank Chang };
2510340c3ca5SFrank Chang 
2511340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVE64D_IMPLIED = {
2512340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zve64d),
2513340c3ca5SFrank Chang     .implied_misa_exts = RVD,
2514340c3ca5SFrank Chang     .implied_multi_exts = {
2515340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zve64f),
2516340c3ca5SFrank Chang 
2517340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2518340c3ca5SFrank Chang     },
2519340c3ca5SFrank Chang };
2520340c3ca5SFrank Chang 
2521340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVE64F_IMPLIED = {
2522340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zve64f),
2523340c3ca5SFrank Chang     .implied_misa_exts = RVF,
2524340c3ca5SFrank Chang     .implied_multi_exts = {
2525340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zve32f), CPU_CFG_OFFSET(ext_zve64x),
2526340c3ca5SFrank Chang 
2527340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2528340c3ca5SFrank Chang     },
2529340c3ca5SFrank Chang };
2530340c3ca5SFrank Chang 
2531340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVE64X_IMPLIED = {
2532340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zve64x),
2533340c3ca5SFrank Chang     .implied_multi_exts = {
2534340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zve32x),
2535340c3ca5SFrank Chang 
2536340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2537340c3ca5SFrank Chang     },
2538340c3ca5SFrank Chang };
2539340c3ca5SFrank Chang 
2540340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVFBFMIN_IMPLIED = {
2541340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvfbfmin),
2542340c3ca5SFrank Chang     .implied_multi_exts = {
2543340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zve32f),
2544340c3ca5SFrank Chang 
2545340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2546340c3ca5SFrank Chang     },
2547340c3ca5SFrank Chang };
2548340c3ca5SFrank Chang 
2549340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVFBFWMA_IMPLIED = {
2550340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvfbfwma),
2551340c3ca5SFrank Chang     .implied_multi_exts = {
2552340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvfbfmin), CPU_CFG_OFFSET(ext_zfbfmin),
2553340c3ca5SFrank Chang 
2554340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2555340c3ca5SFrank Chang     },
2556340c3ca5SFrank Chang };
2557340c3ca5SFrank Chang 
2558340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVFH_IMPLIED = {
2559340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvfh),
2560340c3ca5SFrank Chang     .implied_multi_exts = {
2561340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvfhmin), CPU_CFG_OFFSET(ext_zfhmin),
2562340c3ca5SFrank Chang 
2563340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2564340c3ca5SFrank Chang     },
2565340c3ca5SFrank Chang };
2566340c3ca5SFrank Chang 
2567340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVFHMIN_IMPLIED = {
2568340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvfhmin),
2569340c3ca5SFrank Chang     .implied_multi_exts = {
2570340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zve32f),
2571340c3ca5SFrank Chang 
2572340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2573340c3ca5SFrank Chang     },
2574340c3ca5SFrank Chang };
2575340c3ca5SFrank Chang 
2576340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVKN_IMPLIED = {
2577340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvkn),
2578340c3ca5SFrank Chang     .implied_multi_exts = {
2579340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvkned), CPU_CFG_OFFSET(ext_zvknhb),
2580340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvkb), CPU_CFG_OFFSET(ext_zvkt),
2581340c3ca5SFrank Chang 
2582340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2583340c3ca5SFrank Chang     },
2584340c3ca5SFrank Chang };
2585340c3ca5SFrank Chang 
2586340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVKNC_IMPLIED = {
2587340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvknc),
2588340c3ca5SFrank Chang     .implied_multi_exts = {
2589340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvkn), CPU_CFG_OFFSET(ext_zvbc),
2590340c3ca5SFrank Chang 
2591340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2592340c3ca5SFrank Chang     },
2593340c3ca5SFrank Chang };
2594340c3ca5SFrank Chang 
2595340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVKNG_IMPLIED = {
2596340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvkng),
2597340c3ca5SFrank Chang     .implied_multi_exts = {
2598340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvkn), CPU_CFG_OFFSET(ext_zvkg),
2599340c3ca5SFrank Chang 
2600340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2601340c3ca5SFrank Chang     },
2602340c3ca5SFrank Chang };
2603340c3ca5SFrank Chang 
2604340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVKNHB_IMPLIED = {
2605340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvknhb),
2606340c3ca5SFrank Chang     .implied_multi_exts = {
2607340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zve64x),
2608340c3ca5SFrank Chang 
2609340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2610340c3ca5SFrank Chang     },
2611340c3ca5SFrank Chang };
2612340c3ca5SFrank Chang 
2613340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVKS_IMPLIED = {
2614340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvks),
2615340c3ca5SFrank Chang     .implied_multi_exts = {
2616340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvksed), CPU_CFG_OFFSET(ext_zvksh),
2617340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvkb), CPU_CFG_OFFSET(ext_zvkt),
2618340c3ca5SFrank Chang 
2619340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2620340c3ca5SFrank Chang     },
2621340c3ca5SFrank Chang };
2622340c3ca5SFrank Chang 
2623340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVKSC_IMPLIED = {
2624340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvksc),
2625340c3ca5SFrank Chang     .implied_multi_exts = {
2626340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvks), CPU_CFG_OFFSET(ext_zvbc),
2627340c3ca5SFrank Chang 
2628340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2629340c3ca5SFrank Chang     },
2630340c3ca5SFrank Chang };
2631340c3ca5SFrank Chang 
2632340c3ca5SFrank Chang static RISCVCPUImpliedExtsRule ZVKSG_IMPLIED = {
2633340c3ca5SFrank Chang     .ext = CPU_CFG_OFFSET(ext_zvksg),
2634340c3ca5SFrank Chang     .implied_multi_exts = {
2635340c3ca5SFrank Chang         CPU_CFG_OFFSET(ext_zvks), CPU_CFG_OFFSET(ext_zvkg),
2636340c3ca5SFrank Chang 
2637340c3ca5SFrank Chang         RISCV_IMPLIED_EXTS_RULE_END
2638340c3ca5SFrank Chang     },
2639f04f7709SFrank Chang };
264017177339SFrank Chang 
264117177339SFrank Chang RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[] = {
2642f04f7709SFrank Chang     &RVA_IMPLIED, &RVD_IMPLIED, &RVF_IMPLIED,
2643f04f7709SFrank Chang     &RVM_IMPLIED, &RVV_IMPLIED, NULL
2644f04f7709SFrank Chang };
2645340c3ca5SFrank Chang 
2646340c3ca5SFrank Chang RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = {
2647340c3ca5SFrank Chang     &ZCB_IMPLIED, &ZCD_IMPLIED, &ZCE_IMPLIED,
2648340c3ca5SFrank Chang     &ZCF_IMPLIED, &ZCMP_IMPLIED, &ZCMT_IMPLIED,
2649340c3ca5SFrank Chang     &ZDINX_IMPLIED, &ZFA_IMPLIED, &ZFBFMIN_IMPLIED,
2650340c3ca5SFrank Chang     &ZFH_IMPLIED, &ZFHMIN_IMPLIED, &ZFINX_IMPLIED,
2651340c3ca5SFrank Chang     &ZHINX_IMPLIED, &ZHINXMIN_IMPLIED, &ZICNTR_IMPLIED,
2652340c3ca5SFrank Chang     &ZIHPM_IMPLIED, &ZK_IMPLIED, &ZKN_IMPLIED,
2653340c3ca5SFrank Chang     &ZKS_IMPLIED, &ZVBB_IMPLIED, &ZVE32F_IMPLIED,
2654340c3ca5SFrank Chang     &ZVE32X_IMPLIED, &ZVE64D_IMPLIED, &ZVE64F_IMPLIED,
2655340c3ca5SFrank Chang     &ZVE64X_IMPLIED, &ZVFBFMIN_IMPLIED, &ZVFBFWMA_IMPLIED,
2656340c3ca5SFrank Chang     &ZVFH_IMPLIED, &ZVFHMIN_IMPLIED, &ZVKN_IMPLIED,
2657f04f7709SFrank Chang     &ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED,
2658f04f7709SFrank Chang     &ZVKS_IMPLIED,  &ZVKSC_IMPLIED, &ZVKSG_IMPLIED,
2659f04f7709SFrank Chang     NULL
266026b2bc58SAlistair Francis };
266126b2bc58SAlistair Francis 
266226b2bc58SAlistair Francis static Property riscv_cpu_properties[] = {
2663d167a224SDaniel Henrique Barboza     DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
2664d167a224SDaniel Henrique Barboza 
2665d167a224SDaniel Henrique Barboza     {.name = "pmu-mask", .info = &prop_pmu_mask},
2666d06f28dbSDaniel Henrique Barboza     {.name = "pmu-num", .info = &prop_pmu_num}, /* Deprecated */
266711097be4SDaniel Henrique Barboza 
2668d06f28dbSDaniel Henrique Barboza     {.name = "mmu", .info = &prop_mmu},
2669fefc294bSDaniel Henrique Barboza     {.name = "pmp", .info = &prop_pmp},
267041f2b94eSDaniel Henrique Barboza 
2671fefc294bSDaniel Henrique Barboza     {.name = "priv_spec", .info = &prop_priv_spec},
2672fae0b533SDaniel Henrique Barboza     {.name = "vext_spec", .info = &prop_vext_spec},
26739d1173d2SDaniel Henrique Barboza 
2674fae0b533SDaniel Henrique Barboza     {.name = "vlen", .info = &prop_vlen},
2675b84efa39SDaniel Henrique Barboza     {.name = "elen", .info = &prop_elen},
2676811ef853SDaniel Henrique Barboza 
267782f7b1d4SDaniel Henrique Barboza     {.name = "cbom_blocksize", .info = &prop_cbom_blksize},
2678b84efa39SDaniel Henrique Barboza     {.name = "cbop_blocksize", .info = &prop_cbop_blksize},
2679a9a25939SDaniel Henrique Barboza     {.name = "cboz_blocksize", .info = &prop_cboz_blksize},
26809bb9d424SDaniel Henrique Barboza 
268110efbe01SDaniel Henrique Barboza      {.name = "mvendorid", .info = &prop_mvendorid},
2682a9a25939SDaniel Henrique Barboza      {.name = "mimpid", .info = &prop_mimpid},
2683277b210dSAlistair Francis      {.name = "marchid", .info = &prop_marchid},
2684277b210dSAlistair Francis 
2685277b210dSAlistair Francis #ifndef CONFIG_USER_ONLY
2686a4a9a443STsukasa OI     DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
2687a4a9a443STsukasa OI #endif
2688b8312675SeopXD 
2689b8312675SeopXD     DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
26901ad3f9bdSeopXD 
269154bd9b6eSDaniel Henrique Barboza     DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
269254bd9b6eSDaniel Henrique Barboza     DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false),
269354bd9b6eSDaniel Henrique Barboza     DEFINE_PROP_BOOL("rvv_vl_half_avl", RISCVCPU, cfg.rvv_vl_half_avl, false),
269454bd9b6eSDaniel Henrique Barboza 
269554bd9b6eSDaniel Henrique Barboza     /*
269654bd9b6eSDaniel Henrique Barboza      * write_misa() is marked as experimental for now so mark
2697c4e95030SAlistair Francis      * it with -x and default to 'false'.
2698c4e95030SAlistair Francis      */
2699c4e95030SAlistair Francis     DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false),
2700fba92a92SDaniel Henrique Barboza     DEFINE_PROP_END_OF_LIST(),
2701fba92a92SDaniel Henrique Barboza };
2702fba92a92SDaniel Henrique Barboza 
2703fba92a92SDaniel Henrique Barboza #if defined(TARGET_RISCV64)
rva22u64_profile_cpu_init(Object * obj)2704fba92a92SDaniel Henrique Barboza static void rva22u64_profile_cpu_init(Object *obj)
2705fba92a92SDaniel Henrique Barboza {
2706fba92a92SDaniel Henrique Barboza     rv64i_bare_cpu_init(obj);
2707dfa3c4c5SDaniel Henrique Barboza 
2708dfa3c4c5SDaniel Henrique Barboza     RVA22U64.enabled = true;
2709dfa3c4c5SDaniel Henrique Barboza }
2710dfa3c4c5SDaniel Henrique Barboza 
rva22s64_profile_cpu_init(Object * obj)2711dfa3c4c5SDaniel Henrique Barboza static void rva22s64_profile_cpu_init(Object *obj)
2712dfa3c4c5SDaniel Henrique Barboza {
2713dfa3c4c5SDaniel Henrique Barboza     rv64i_bare_cpu_init(obj);
2714fba92a92SDaniel Henrique Barboza 
2715fba92a92SDaniel Henrique Barboza     RVA22S64.enabled = true;
2716a6506838SAkihiko Odaki }
2717edf64786SSylvain Pelissier #endif
2718edf64786SSylvain Pelissier 
riscv_gdb_arch_name(CPUState * cs)2719edf64786SSylvain Pelissier static const gchar *riscv_gdb_arch_name(CPUState *cs)
2720edf64786SSylvain Pelissier {
2721db23e5d9SRichard Henderson     RISCVCPU *cpu = RISCV_CPU(cs);
2722db23e5d9SRichard Henderson     CPURISCVState *env = &cpu->env;
2723a6506838SAkihiko Odaki 
2724db23e5d9SRichard Henderson     switch (riscv_cpu_mxl(env)) {
2725332dab68SFrédéric Pétrot     case MXL_RV32:
2726a6506838SAkihiko Odaki         return "riscv:rv32";
2727db23e5d9SRichard Henderson     case MXL_RV64:
2728db23e5d9SRichard Henderson     case MXL_RV128:
2729edf64786SSylvain Pelissier         return "riscv:rv64";
2730edf64786SSylvain Pelissier     default:
2731edf64786SSylvain Pelissier         g_assert_not_reached();
27328b80bd28SPhilippe Mathieu-Daudé     }
2733f1bd6f8eSMayuresh Chitale }
2734f1bd6f8eSMayuresh Chitale 
2735f1bd6f8eSMayuresh Chitale #ifndef CONFIG_USER_ONLY
riscv_get_arch_id(CPUState * cs)2736f1bd6f8eSMayuresh Chitale static int64_t riscv_get_arch_id(CPUState *cs)
2737f1bd6f8eSMayuresh Chitale {
2738f1bd6f8eSMayuresh Chitale     RISCVCPU *cpu = RISCV_CPU(cs);
2739f1bd6f8eSMayuresh Chitale 
27408b80bd28SPhilippe Mathieu-Daudé     return cpu->env.mhartid;
27418b80bd28SPhilippe Mathieu-Daudé }
27428b80bd28SPhilippe Mathieu-Daudé 
274308928c6dSPhilippe Mathieu-Daudé #include "hw/core/sysemu-cpu-ops.h"
2744715e3c1aSPhilippe Mathieu-Daudé 
2745715e3c1aSPhilippe Mathieu-Daudé static const struct SysemuCPUOps riscv_sysemu_ops = {
2746feece4d0SPhilippe Mathieu-Daudé     .get_phys_page_debug = riscv_cpu_get_phys_page_debug,
27478b80bd28SPhilippe Mathieu-Daudé     .write_elf64_note = riscv_cpu_write_elf64_note,
27488b80bd28SPhilippe Mathieu-Daudé     .write_elf32_note = riscv_cpu_write_elf32_note,
27498b80bd28SPhilippe Mathieu-Daudé     .legacy_vmsd = &vmstate_riscv_cpu,
2750742cc269SAkihiko Odaki };
2751dc5bd18fSMichael Clark #endif
2752dc5bd18fSMichael Clark 
riscv_cpu_common_class_init(ObjectClass * c,void * data)2753dc5bd18fSMichael Clark static void riscv_cpu_common_class_init(ObjectClass *c, void *data)
2754dc5bd18fSMichael Clark {
27554fa485a7SPeter Maydell     RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
2756dc5bd18fSMichael Clark     CPUClass *cc = CPU_CLASS(c);
275741fbbba7SMao Zhongyi     DeviceClass *dc = DEVICE_CLASS(c);
275841fbbba7SMao Zhongyi     ResettableClass *rc = RESETTABLE_CLASS(c);
2759dc5bd18fSMichael Clark 
27604fa485a7SPeter Maydell     device_class_set_parent_realize(dc, riscv_cpu_realize,
27614fa485a7SPeter Maydell                                     &mcc->parent_realize);
2762dc5bd18fSMichael Clark 
2763dc5bd18fSMichael Clark     resettable_class_set_parent_phases(rc, NULL, riscv_cpu_reset_hold, NULL,
2764dc5bd18fSMichael Clark                                        &mcc->parent_phases);
2765a5c77974SRichard Henderson 
2766dc5bd18fSMichael Clark     cc->class_by_name = riscv_cpu_class_by_name;
2767dc5bd18fSMichael Clark     cc->has_work = riscv_cpu_has_work;
2768e4fdf9dfSRichard Henderson     cc->mmu_index = riscv_cpu_mmu_index;
2769dc5bd18fSMichael Clark     cc->dump_state = riscv_cpu_dump_state;
2770dc5bd18fSMichael Clark     cc->set_pc = riscv_cpu_set_pc;
2771dc5bd18fSMichael Clark     cc->get_pc = riscv_cpu_get_pc;
2772dc5bd18fSMichael Clark     cc->gdb_read_register = riscv_cpu_gdb_read_register;
27738a4ca3c1SRichard Henderson     cc->gdb_write_register = riscv_cpu_gdb_write_register;
27748b80bd28SPhilippe Mathieu-Daudé     cc->gdb_stop_before_watchpoint = true;
2775f1bd6f8eSMayuresh Chitale     cc->disas_set_info = riscv_cpu_disas_set_info;
2776dc5bd18fSMichael Clark #ifndef CONFIG_USER_ONLY
2777edf64786SSylvain Pelissier     cc->sysemu_ops = &riscv_sysemu_ops;
27786a3d2e7cSClaudio Fontana     cc->get_arch_id = riscv_get_arch_id;
27794f67d30bSMarc-André Lureau #endif
2780dc5bd18fSMichael Clark     cc->gdb_arch_name = riscv_gdb_arch_name;
2781dc5bd18fSMichael Clark 
2782742cc269SAkihiko Odaki     device_class_set_props(dc, riscv_cpu_properties);
2783742cc269SAkihiko Odaki }
2784742cc269SAkihiko Odaki 
riscv_cpu_class_init(ObjectClass * c,void * data)2785742cc269SAkihiko Odaki static void riscv_cpu_class_init(ObjectClass *c, void *data)
2786742cc269SAkihiko Odaki {
27871563cdb4SAkihiko Odaki     RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
2788742cc269SAkihiko Odaki 
2789742cc269SAkihiko Odaki     mcc->misa_mxl_max = (uint32_t)(uintptr_t)data;
2790246f8796SWeiwei Li     riscv_cpu_validate_misa_mxl(mcc);
2791246f8796SWeiwei Li }
2792a775398bSAtish Patra 
riscv_isa_string_ext(RISCVCPU * cpu,char ** isa_str,int max_str_len)27937935e2c4SDaniel Henrique Barboza static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
2794a775398bSAtish Patra                                  int max_str_len)
2795a775398bSAtish Patra {
2796a775398bSAtish Patra     const RISCVIsaExtData *edata;
27977935e2c4SDaniel Henrique Barboza     char *old = *isa_str;
27987935e2c4SDaniel Henrique Barboza     char *new = *isa_str;
27997935e2c4SDaniel Henrique Barboza 
2800a775398bSAtish Patra     for (edata = isa_edata_arr; edata && edata->name; edata++) {
2801a775398bSAtish Patra         if (isa_ext_is_enabled(cpu, edata->ext_enable_offset)) {
2802a775398bSAtish Patra             new = g_strconcat(old, "_", edata->name, NULL);
2803a775398bSAtish Patra             g_free(old);
2804a775398bSAtish Patra             old = new;
2805a775398bSAtish Patra         }
2806a775398bSAtish Patra     }
2807a775398bSAtish Patra 
2808dc5bd18fSMichael Clark     *isa_str = new;
2809dc5bd18fSMichael Clark }
2810afa42c21SConor Dooley 
riscv_isa_string(RISCVCPU * cpu)2811dc5bd18fSMichael Clark char *riscv_isa_string(RISCVCPU *cpu)
28120e2c3770STsukasa OI {
2813d1fd31f8SMichael Clark     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
2814afa42c21SConor Dooley     int i;
2815afa42c21SConor Dooley     const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts);
2816afa42c21SConor Dooley     char *isa_str = g_new(char, maxlen);
28170e2c3770STsukasa OI     int xlen = riscv_cpu_max_xlen(mcc);
28180e2c3770STsukasa OI     char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", xlen);
28190e2c3770STsukasa OI 
2820dc5bd18fSMichael Clark     for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
2821dc5bd18fSMichael Clark         if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
2822d1fd31f8SMichael Clark             *p++ = qemu_tolower(riscv_single_letter_exts[i]);
2823a4a9a443STsukasa OI         }
2824a775398bSAtish Patra     }
2825a4a9a443STsukasa OI     *p = '\0';
2826d1fd31f8SMichael Clark     if (!cpu->cfg.short_isa_string) {
2827dc5bd18fSMichael Clark         riscv_isa_string_ext(cpu, &isa_str, maxlen);
2828dc5bd18fSMichael Clark     }
28291c8e491cSConor Dooley     return isa_str;
28301c8e491cSConor Dooley }
28311c8e491cSConor Dooley 
28321c8e491cSConor Dooley #ifndef CONFIG_USER_ONLY
riscv_isa_extensions_list(RISCVCPU * cpu,int * count)28331c8e491cSConor Dooley static char **riscv_isa_extensions_list(RISCVCPU *cpu, int *count)
28341c8e491cSConor Dooley {
28351c8e491cSConor Dooley     int maxlen = ARRAY_SIZE(riscv_single_letter_exts) + ARRAY_SIZE(isa_edata_arr);
28361c8e491cSConor Dooley     char **extensions = g_new(char *, maxlen);
28371c8e491cSConor Dooley 
28381c8e491cSConor Dooley     for (int i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
28391c8e491cSConor Dooley         if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
28401c8e491cSConor Dooley             extensions[*count] = g_new(char, 2);
28411c8e491cSConor Dooley             snprintf(extensions[*count], 2, "%c",
28421c8e491cSConor Dooley                      qemu_tolower(riscv_single_letter_exts[i]));
28431c8e491cSConor Dooley             (*count)++;
28441c8e491cSConor Dooley         }
28451c8e491cSConor Dooley     }
28461c8e491cSConor Dooley 
28471c8e491cSConor Dooley     for (const RISCVIsaExtData *edata = isa_edata_arr; edata->name; edata++) {
28481c8e491cSConor Dooley         if (isa_ext_is_enabled(cpu, edata->ext_enable_offset)) {
28491c8e491cSConor Dooley             extensions[*count] = g_strdup(edata->name);
28501c8e491cSConor Dooley             (*count)++;
28511c8e491cSConor Dooley         }
28521c8e491cSConor Dooley     }
28531c8e491cSConor Dooley 
28541c8e491cSConor Dooley     return extensions;
28551c8e491cSConor Dooley }
28561c8e491cSConor Dooley 
riscv_isa_write_fdt(RISCVCPU * cpu,void * fdt,char * nodename)28571c8e491cSConor Dooley void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, char *nodename)
28581c8e491cSConor Dooley {
28591c8e491cSConor Dooley     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
28601c8e491cSConor Dooley     const size_t maxlen = sizeof("rv128i");
28611c8e491cSConor Dooley     g_autofree char *isa_base = g_new(char, maxlen);
28621c8e491cSConor Dooley     g_autofree char *riscv_isa;
28631c8e491cSConor Dooley     char **isa_extensions;
28641c8e491cSConor Dooley     int count = 0;
28651c8e491cSConor Dooley     int xlen = riscv_cpu_max_xlen(mcc);
28661c8e491cSConor Dooley 
28671c8e491cSConor Dooley     riscv_isa = riscv_isa_string(cpu);
28681c8e491cSConor Dooley     qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", riscv_isa);
28691c8e491cSConor Dooley 
28701c8e491cSConor Dooley     snprintf(isa_base, maxlen, "rv%di", xlen);
28711c8e491cSConor Dooley     qemu_fdt_setprop_string(fdt, nodename, "riscv,isa-base", isa_base);
28721c8e491cSConor Dooley 
28731c8e491cSConor Dooley     isa_extensions = riscv_isa_extensions_list(cpu, &count);
28741c8e491cSConor Dooley     qemu_fdt_setprop_string_array(fdt, nodename, "riscv,isa-extensions",
28751c8e491cSConor Dooley                                   isa_extensions, count);
28761c8e491cSConor Dooley 
28771c8e491cSConor Dooley     for (int i = 0; i < count; i++) {
28781c8e491cSConor Dooley         g_free(isa_extensions[i]);
28791c8e491cSConor Dooley     }
28801c8e491cSConor Dooley 
28811c8e491cSConor Dooley     g_free(isa_extensions);
2882742cc269SAkihiko Odaki }
2883eab15862SMichael Clark #endif
2884742cc269SAkihiko Odaki 
2885eab15862SMichael Clark #define DEFINE_CPU(type_name, misa_mxl_max, initfn)         \
2886742cc269SAkihiko Odaki     {                                                       \
2887742cc269SAkihiko Odaki         .name = (type_name),                                \
2888742cc269SAkihiko Odaki         .parent = TYPE_RISCV_CPU,                           \
2889eab15862SMichael Clark         .instance_init = (initfn),                          \
2890eab15862SMichael Clark         .class_init = riscv_cpu_class_init,                 \
2891742cc269SAkihiko Odaki         .class_data = (void *)(misa_mxl_max)                \
28929e1a30d3SDaniel Henrique Barboza     }
2893742cc269SAkihiko Odaki 
28949e1a30d3SDaniel Henrique Barboza #define DEFINE_DYNAMIC_CPU(type_name, misa_mxl_max, initfn) \
2895742cc269SAkihiko Odaki     {                                                       \
2896742cc269SAkihiko Odaki         .name = (type_name),                                \
2897742cc269SAkihiko Odaki         .parent = TYPE_RISCV_DYNAMIC_CPU,                   \
28989e1a30d3SDaniel Henrique Barboza         .instance_init = (initfn),                          \
28999e1a30d3SDaniel Henrique Barboza         .class_init = riscv_cpu_class_init,                 \
2900742cc269SAkihiko Odaki         .class_data = (void *)(misa_mxl_max)                \
2901ee557ad5SDaniel Henrique Barboza     }
2902742cc269SAkihiko Odaki 
2903ee557ad5SDaniel Henrique Barboza #define DEFINE_VENDOR_CPU(type_name, misa_mxl_max, initfn)  \
2904742cc269SAkihiko Odaki     {                                                       \
2905742cc269SAkihiko Odaki         .name = (type_name),                                \
2906742cc269SAkihiko Odaki         .parent = TYPE_RISCV_VENDOR_CPU,                    \
2907ee557ad5SDaniel Henrique Barboza         .instance_init = (initfn),                          \
2908ee557ad5SDaniel Henrique Barboza         .class_init = riscv_cpu_class_init,                 \
2909742cc269SAkihiko Odaki         .class_data = (void *)(misa_mxl_max)                \
2910d379c748SDaniel Henrique Barboza     }
2911742cc269SAkihiko Odaki 
2912d379c748SDaniel Henrique Barboza #define DEFINE_BARE_CPU(type_name, misa_mxl_max, initfn)    \
2913742cc269SAkihiko Odaki     {                                                       \
2914742cc269SAkihiko Odaki         .name = (type_name),                                \
2915742cc269SAkihiko Odaki         .parent = TYPE_RISCV_BARE_CPU,                      \
2916d379c748SDaniel Henrique Barboza         .instance_init = (initfn),                          \
2917d379c748SDaniel Henrique Barboza         .class_init = riscv_cpu_class_init,                 \
2918742cc269SAkihiko Odaki         .class_data = (void *)(misa_mxl_max)                \
2919fba92a92SDaniel Henrique Barboza     }
2920742cc269SAkihiko Odaki 
2921fba92a92SDaniel Henrique Barboza #define DEFINE_PROFILE_CPU(type_name, misa_mxl_max, initfn) \
2922742cc269SAkihiko Odaki     {                                                       \
2923742cc269SAkihiko Odaki         .name = (type_name),                                \
2924742cc269SAkihiko Odaki         .parent = TYPE_RISCV_BARE_CPU,                      \
2925fba92a92SDaniel Henrique Barboza         .instance_init = (initfn),                          \
2926fba92a92SDaniel Henrique Barboza         .class_init = riscv_cpu_class_init,                 \
2927eab15862SMichael Clark         .class_data = (void *)(misa_mxl_max)                \
2928dc5bd18fSMichael Clark     }
2929eab15862SMichael Clark 
2930eab15862SMichael Clark static const TypeInfo riscv_cpu_type_infos[] = {
2931eab15862SMichael Clark     {
2932f669c992SRichard Henderson         .name = TYPE_RISCV_CPU,
2933eab15862SMichael Clark         .parent = TYPE_CPU,
2934977bbb04SDaniel Henrique Barboza         .instance_size = sizeof(RISCVCPU),
2935eab15862SMichael Clark         .instance_align = __alignof(RISCVCPU),
2936eab15862SMichael Clark         .instance_init = riscv_cpu_init,
2937742cc269SAkihiko Odaki         .instance_post_init = riscv_cpu_post_init,
2938eab15862SMichael Clark         .abstract = true,
29399e1a30d3SDaniel Henrique Barboza         .class_size = sizeof(RISCVCPUClass),
29409e1a30d3SDaniel Henrique Barboza         .class_init = riscv_cpu_common_class_init,
29419e1a30d3SDaniel Henrique Barboza     },
29429e1a30d3SDaniel Henrique Barboza     {
29439e1a30d3SDaniel Henrique Barboza         .name = TYPE_RISCV_DYNAMIC_CPU,
2944ee557ad5SDaniel Henrique Barboza         .parent = TYPE_RISCV_CPU,
2945ee557ad5SDaniel Henrique Barboza         .abstract = true,
2946ee557ad5SDaniel Henrique Barboza     },
2947ee557ad5SDaniel Henrique Barboza     {
2948ee557ad5SDaniel Henrique Barboza         .name = TYPE_RISCV_VENDOR_CPU,
2949d379c748SDaniel Henrique Barboza         .parent = TYPE_RISCV_CPU,
2950d379c748SDaniel Henrique Barboza         .abstract = true,
2951d379c748SDaniel Henrique Barboza     },
2952b077aec9SDaniel Henrique Barboza     {
2953d379c748SDaniel Henrique Barboza         .name = TYPE_RISCV_BARE_CPU,
2954d379c748SDaniel Henrique Barboza         .parent = TYPE_RISCV_CPU,
2955eab15862SMichael Clark         .instance_init = riscv_bare_cpu_init,
2956742cc269SAkihiko Odaki         .abstract = true,
2957742cc269SAkihiko Odaki     },
2958742cc269SAkihiko Odaki #if defined(TARGET_RISCV32)
2959742cc269SAkihiko Odaki     DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,       MXL_RV32,  riscv_max_cpu_init),
2960742cc269SAkihiko Odaki #elif defined(TARGET_RISCV64)
2961742cc269SAkihiko Odaki     DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,       MXL_RV64,  riscv_max_cpu_init),
2962742cc269SAkihiko Odaki #endif
2963deb0ff0cSDaniel Henrique Barboza 
2964deb0ff0cSDaniel Henrique Barboza #if defined(TARGET_RISCV32) || \
2965eab15862SMichael Clark     (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
2966742cc269SAkihiko Odaki     DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32,    MXL_RV32,  rv32_base_cpu_init),
2967742cc269SAkihiko Odaki     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_IBEX,       MXL_RV32,  rv32_ibex_cpu_init),
2968742cc269SAkihiko Odaki     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31, MXL_RV32,  rv32_sifive_e_cpu_init),
2969742cc269SAkihiko Odaki     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34, MXL_RV32,  rv32_imafcu_nommu_cpu_init),
2970742cc269SAkihiko Odaki     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34, MXL_RV32,  rv32_sifive_u_cpu_init),
2971742cc269SAkihiko Odaki     DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV32I,        MXL_RV32,  rv32i_bare_cpu_init),
2972742cc269SAkihiko Odaki     DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV32E,        MXL_RV32,  rv32e_bare_cpu_init),
2973742cc269SAkihiko Odaki #endif
297414482b13SPhilippe Mathieu-Daudé 
2975742cc269SAkihiko Odaki #if (defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
297614482b13SPhilippe Mathieu-Daudé     DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX32,     MXL_RV32,  riscv_max_cpu_init),
2977742cc269SAkihiko Odaki #endif
2978deb0ff0cSDaniel Henrique Barboza 
2979742cc269SAkihiko Odaki #if defined(TARGET_RISCV64)
2980742cc269SAkihiko Odaki     DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64,    MXL_RV64,  rv64_base_cpu_init),
298114482b13SPhilippe Mathieu-Daudé     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E51, MXL_RV64,  rv64_sifive_e_cpu_init),
2982eab15862SMichael Clark     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54, MXL_RV64,  rv64_sifive_u_cpu_init),
2983dc5bd18fSMichael Clark     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C,   MXL_RV64,  rv64_sifive_u_cpu_init),
2984eab15862SMichael Clark     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, MXL_RV64,  rv64_thead_c906_cpu_init),
2985     DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1,  MXL_RV64,  rv64_veyron_v1_cpu_init),
2986 #ifdef CONFIG_TCG
2987     DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,   MXL_RV128, rv128_base_cpu_init),
2988 #endif /* CONFIG_TCG */
2989     DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I,        MXL_RV64,  rv64i_bare_cpu_init),
2990     DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64E,        MXL_RV64,  rv64e_bare_cpu_init),
2991     DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64,  MXL_RV64,  rva22u64_profile_cpu_init),
2992     DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64,  MXL_RV64,  rva22s64_profile_cpu_init),
2993 #endif /* TARGET_RISCV64 */
2994 };
2995 
2996 DEFINE_TYPES(riscv_cpu_type_infos)
2997