2 * riscv TCG cpu class initialization
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2017-2018 SiFive, Inc.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2 or later, as published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
21 #include "exec/exec-all.h"
25 #include "time_helper.h"
26 #include "qapi/error.h"
27 #include "qapi/visitor.h"
28 #include "qemu/accel.h"
29 #include "qemu/error-report.h"
31 #include "hw/core/accel-cpu.h"
32 #include "hw/core/tcg-cpu-ops.h"
35 /* Hash that stores user set extensions */
36 static GHashTable
*multi_ext_user_opts
;
38 static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset
)
40 return g_hash_table_contains(multi_ext_user_opts
,
41 GUINT_TO_POINTER(ext_offset
));
44 static void riscv_cpu_synchronize_from_tb(CPUState
*cs
,
45 const TranslationBlock
*tb
)
47 if (!(tb_cflags(tb
) & CF_PCREL
)) {
48 RISCVCPU
*cpu
= RISCV_CPU(cs
);
49 CPURISCVState
*env
= &cpu
->env
;
50 RISCVMXL xl
= FIELD_EX32(tb
->flags
, TB_FLAGS
, XL
);
52 tcg_debug_assert(!(cs
->tcg_cflags
& CF_PCREL
));
55 env
->pc
= (int32_t) tb
->pc
;
62 static void riscv_restore_state_to_opc(CPUState
*cs
,
63 const TranslationBlock
*tb
,
66 RISCVCPU
*cpu
= RISCV_CPU(cs
);
67 CPURISCVState
*env
= &cpu
->env
;
68 RISCVMXL xl
= FIELD_EX32(tb
->flags
, TB_FLAGS
, XL
);
71 if (tb_cflags(tb
) & CF_PCREL
) {
72 pc
= (env
->pc
& TARGET_PAGE_MASK
) | data
[0];
78 env
->pc
= (int32_t)pc
;
85 static const struct TCGCPUOps riscv_tcg_ops
= {
86 .initialize
= riscv_translate_init
,
87 .synchronize_from_tb
= riscv_cpu_synchronize_from_tb
,
88 .restore_state_to_opc
= riscv_restore_state_to_opc
,
90 #ifndef CONFIG_USER_ONLY
91 .tlb_fill
= riscv_cpu_tlb_fill
,
92 .cpu_exec_interrupt
= riscv_cpu_exec_interrupt
,
93 .do_interrupt
= riscv_cpu_do_interrupt
,
94 .do_transaction_failed
= riscv_cpu_do_transaction_failed
,
95 .do_unaligned_access
= riscv_cpu_do_unaligned_access
,
96 .debug_excp_handler
= riscv_cpu_debug_excp_handler
,
97 .debug_check_breakpoint
= riscv_cpu_debug_check_breakpoint
,
98 .debug_check_watchpoint
= riscv_cpu_debug_check_watchpoint
,
99 #endif /* !CONFIG_USER_ONLY */
102 static int cpu_cfg_ext_get_min_version(uint32_t ext_offset
)
104 const RISCVIsaExtData
*edata
;
106 for (edata
= isa_edata_arr
; edata
&& edata
->name
; edata
++) {
107 if (edata
->ext_enable_offset
!= ext_offset
) {
111 return edata
->min_version
;
114 g_assert_not_reached();
117 static void cpu_cfg_ext_auto_update(RISCVCPU
*cpu
, uint32_t ext_offset
,
120 CPURISCVState
*env
= &cpu
->env
;
121 bool prev_val
= isa_ext_is_enabled(cpu
, ext_offset
);
124 if (prev_val
== value
) {
128 if (cpu_cfg_ext_is_user_set(ext_offset
)) {
132 if (value
&& env
->priv_ver
!= PRIV_VERSION_LATEST
) {
133 /* Do not enable it if priv_ver is older than min_version */
134 min_version
= cpu_cfg_ext_get_min_version(ext_offset
);
135 if (env
->priv_ver
< min_version
) {
140 isa_ext_update_enabled(cpu
, ext_offset
, value
);
143 static void riscv_cpu_validate_misa_priv(CPURISCVState
*env
, Error
**errp
)
145 if (riscv_has_ext(env
, RVH
) && env
->priv_ver
< PRIV_VERSION_1_12_0
) {
146 error_setg(errp
, "H extension requires priv spec 1.12.0");
151 static void riscv_cpu_validate_misa_mxl(RISCVCPU
*cpu
, Error
**errp
)
153 RISCVCPUClass
*mcc
= RISCV_CPU_GET_CLASS(cpu
);
154 CPUClass
*cc
= CPU_CLASS(mcc
);
155 CPURISCVState
*env
= &cpu
->env
;
157 /* Validate that MISA_MXL is set properly. */
158 switch (env
->misa_mxl_max
) {
159 #ifdef TARGET_RISCV64
162 cc
->gdb_core_xml_file
= "riscv-64bit-cpu.xml";
166 cc
->gdb_core_xml_file
= "riscv-32bit-cpu.xml";
169 g_assert_not_reached();
172 if (env
->misa_mxl_max
!= env
->misa_mxl
) {
173 error_setg(errp
, "misa_mxl_max must be equal to misa_mxl");
178 static void riscv_cpu_validate_priv_spec(RISCVCPU
*cpu
, Error
**errp
)
180 CPURISCVState
*env
= &cpu
->env
;
181 int priv_version
= -1;
183 if (cpu
->cfg
.priv_spec
) {
184 if (!g_strcmp0(cpu
->cfg
.priv_spec
, "v1.12.0")) {
185 priv_version
= PRIV_VERSION_1_12_0
;
186 } else if (!g_strcmp0(cpu
->cfg
.priv_spec
, "v1.11.0")) {
187 priv_version
= PRIV_VERSION_1_11_0
;
188 } else if (!g_strcmp0(cpu
->cfg
.priv_spec
, "v1.10.0")) {
189 priv_version
= PRIV_VERSION_1_10_0
;
192 "Unsupported privilege spec version '%s'",
197 env
->priv_ver
= priv_version
;
201 static void riscv_cpu_validate_v(CPURISCVState
*env
, RISCVCPUConfig
*cfg
,
204 if (!is_power_of_2(cfg
->vlen
)) {
205 error_setg(errp
, "Vector extension VLEN must be power of 2");
209 if (cfg
->vlen
> RV_VLEN_MAX
|| cfg
->vlen
< 128) {
211 "Vector extension implementation only supports VLEN "
212 "in the range [128, %d]", RV_VLEN_MAX
);
216 if (!is_power_of_2(cfg
->elen
)) {
217 error_setg(errp
, "Vector extension ELEN must be power of 2");
221 if (cfg
->elen
> 64 || cfg
->elen
< 8) {
223 "Vector extension implementation only supports ELEN "
224 "in the range [8, 64]");
228 if (cfg
->vext_spec
) {
229 if (!g_strcmp0(cfg
->vext_spec
, "v1.0")) {
230 env
->vext_ver
= VEXT_VERSION_1_00_0
;
232 error_setg(errp
, "Unsupported vector spec version '%s'",
236 } else if (env
->vext_ver
== 0) {
237 qemu_log("vector version is not specified, "
238 "use the default value v1.0\n");
240 env
->vext_ver
= VEXT_VERSION_1_00_0
;
244 static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU
*cpu
)
246 CPURISCVState
*env
= &cpu
->env
;
247 const RISCVIsaExtData
*edata
;
249 /* Force disable extensions if priv spec version does not match */
250 for (edata
= isa_edata_arr
; edata
&& edata
->name
; edata
++) {
251 if (isa_ext_is_enabled(cpu
, edata
->ext_enable_offset
) &&
252 (env
->priv_ver
< edata
->min_version
)) {
253 isa_ext_update_enabled(cpu
, edata
->ext_enable_offset
, false);
254 #ifndef CONFIG_USER_ONLY
255 warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
256 " because privilege spec version does not match",
257 edata
->name
, env
->mhartid
);
259 warn_report("disabling %s extension because "
260 "privilege spec version does not match",
268 * Check consistency between chosen extensions while setting
269 * cpu->cfg accordingly.
271 void riscv_cpu_validate_set_extensions(RISCVCPU
*cpu
, Error
**errp
)
273 CPURISCVState
*env
= &cpu
->env
;
274 Error
*local_err
= NULL
;
276 /* Do some ISA extension error checking */
277 if (riscv_has_ext(env
, RVG
) &&
278 !(riscv_has_ext(env
, RVI
) && riscv_has_ext(env
, RVM
) &&
279 riscv_has_ext(env
, RVA
) && riscv_has_ext(env
, RVF
) &&
280 riscv_has_ext(env
, RVD
) &&
281 cpu
->cfg
.ext_zicsr
&& cpu
->cfg
.ext_zifencei
)) {
283 if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicsr
)) &&
284 !cpu
->cfg
.ext_zicsr
) {
285 error_setg(errp
, "RVG requires Zicsr but user set Zicsr to false");
289 if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zifencei
)) &&
290 !cpu
->cfg
.ext_zifencei
) {
291 error_setg(errp
, "RVG requires Zifencei but user set "
292 "Zifencei to false");
296 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zicsr
), true);
297 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zifencei
), true);
299 env
->misa_ext
|= RVI
| RVM
| RVA
| RVF
| RVD
;
300 env
->misa_ext_mask
|= RVI
| RVM
| RVA
| RVF
| RVD
;
303 if (riscv_has_ext(env
, RVI
) && riscv_has_ext(env
, RVE
)) {
305 "I and E extensions are incompatible");
309 if (!riscv_has_ext(env
, RVI
) && !riscv_has_ext(env
, RVE
)) {
311 "Either I or E extension must be set");
315 if (riscv_has_ext(env
, RVS
) && !riscv_has_ext(env
, RVU
)) {
317 "Setting S extension without U extension is illegal");
321 if (riscv_has_ext(env
, RVH
) && !riscv_has_ext(env
, RVI
)) {
323 "H depends on an I base integer ISA with 32 x registers");
327 if (riscv_has_ext(env
, RVH
) && !riscv_has_ext(env
, RVS
)) {
328 error_setg(errp
, "H extension implicitly requires S-mode");
332 if (riscv_has_ext(env
, RVF
) && !cpu
->cfg
.ext_zicsr
) {
333 error_setg(errp
, "F extension requires Zicsr");
337 if ((cpu
->cfg
.ext_zawrs
) && !riscv_has_ext(env
, RVA
)) {
338 error_setg(errp
, "Zawrs extension requires A extension");
342 if (cpu
->cfg
.ext_zfa
&& !riscv_has_ext(env
, RVF
)) {
343 error_setg(errp
, "Zfa extension requires F extension");
347 if (cpu
->cfg
.ext_zfh
) {
348 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zfhmin
), true);
351 if (cpu
->cfg
.ext_zfhmin
&& !riscv_has_ext(env
, RVF
)) {
352 error_setg(errp
, "Zfh/Zfhmin extensions require F extension");
356 if (cpu
->cfg
.ext_zfbfmin
&& !riscv_has_ext(env
, RVF
)) {
357 error_setg(errp
, "Zfbfmin extension depends on F extension");
361 if (riscv_has_ext(env
, RVD
) && !riscv_has_ext(env
, RVF
)) {
362 error_setg(errp
, "D extension requires F extension");
366 if (riscv_has_ext(env
, RVV
)) {
367 riscv_cpu_validate_v(env
, &cpu
->cfg
, &local_err
);
368 if (local_err
!= NULL
) {
369 error_propagate(errp
, local_err
);
373 /* The V vector extension depends on the Zve64d extension */
374 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zve64d
), true);
377 /* The Zve64d extension depends on the Zve64f extension */
378 if (cpu
->cfg
.ext_zve64d
) {
379 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zve64f
), true);
382 /* The Zve64f extension depends on the Zve32f extension */
383 if (cpu
->cfg
.ext_zve64f
) {
384 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zve32f
), true);
387 if (cpu
->cfg
.ext_zve64d
&& !riscv_has_ext(env
, RVD
)) {
388 error_setg(errp
, "Zve64d/V extensions require D extension");
392 if (cpu
->cfg
.ext_zve32f
&& !riscv_has_ext(env
, RVF
)) {
393 error_setg(errp
, "Zve32f/Zve64f extensions require F extension");
397 if (cpu
->cfg
.ext_zvfh
) {
398 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zvfhmin
), true);
401 if (cpu
->cfg
.ext_zvfhmin
&& !cpu
->cfg
.ext_zve32f
) {
402 error_setg(errp
, "Zvfh/Zvfhmin extensions require Zve32f extension");
406 if (cpu
->cfg
.ext_zvfh
&& !cpu
->cfg
.ext_zfhmin
) {
407 error_setg(errp
, "Zvfh extensions requires Zfhmin extension");
411 if (cpu
->cfg
.ext_zvfbfmin
&& !cpu
->cfg
.ext_zfbfmin
) {
412 error_setg(errp
, "Zvfbfmin extension depends on Zfbfmin extension");
416 if (cpu
->cfg
.ext_zvfbfmin
&& !cpu
->cfg
.ext_zve32f
) {
417 error_setg(errp
, "Zvfbfmin extension depends on Zve32f extension");
421 if (cpu
->cfg
.ext_zvfbfwma
&& !cpu
->cfg
.ext_zvfbfmin
) {
422 error_setg(errp
, "Zvfbfwma extension depends on Zvfbfmin extension");
426 /* Set the ISA extensions, checks should have happened above */
427 if (cpu
->cfg
.ext_zhinx
) {
428 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zca
), true);
431 if ((cpu
->cfg
.ext_zdinx
|| cpu
->cfg
.ext_zhinxmin
) && !cpu
->cfg
.ext_zfinx
) {
432 error_setg(errp
, "Zdinx/Zhinx/Zhinxmin extensions require Zfinx");
436 if (cpu
->cfg
.ext_zfinx
) {
437 if (!cpu
->cfg
.ext_zicsr
) {
438 error_setg(errp
, "Zfinx extension requires Zicsr");
441 if (riscv_has_ext(env
, RVF
)) {
443 "Zfinx cannot be supported together with F extension");
448 if (cpu
->cfg
.ext_zce
) {
449 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zca
), true);
450 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zcb
), true);
451 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zcmp
), true);
452 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zcmt
), true);
453 if (riscv_has_ext(env
, RVF
) && env
->misa_mxl_max
== MXL_RV32
) {
454 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zcf
), true);
458 /* zca, zcd and zcf has a PRIV 1.12.0 restriction */
459 if (riscv_has_ext(env
, RVC
) && env
->priv_ver
>= PRIV_VERSION_1_12_0
) {
460 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zca
), true);
461 if (riscv_has_ext(env
, RVF
) && env
->misa_mxl_max
== MXL_RV32
) {
462 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zcf
), true);
464 if (riscv_has_ext(env
, RVD
)) {
465 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zcd
), true);
469 if (env
->misa_mxl_max
!= MXL_RV32
&& cpu
->cfg
.ext_zcf
) {
470 error_setg(errp
, "Zcf extension is only relevant to RV32");
474 if (!riscv_has_ext(env
, RVF
) && cpu
->cfg
.ext_zcf
) {
475 error_setg(errp
, "Zcf extension requires F extension");
479 if (!riscv_has_ext(env
, RVD
) && cpu
->cfg
.ext_zcd
) {
480 error_setg(errp
, "Zcd extension requires D extension");
484 if ((cpu
->cfg
.ext_zcf
|| cpu
->cfg
.ext_zcd
|| cpu
->cfg
.ext_zcb
||
485 cpu
->cfg
.ext_zcmp
|| cpu
->cfg
.ext_zcmt
) && !cpu
->cfg
.ext_zca
) {
486 error_setg(errp
, "Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca "
491 if (cpu
->cfg
.ext_zcd
&& (cpu
->cfg
.ext_zcmp
|| cpu
->cfg
.ext_zcmt
)) {
492 error_setg(errp
, "Zcmp/Zcmt extensions are incompatible with "
497 if (cpu
->cfg
.ext_zcmt
&& !cpu
->cfg
.ext_zicsr
) {
498 error_setg(errp
, "Zcmt extension requires Zicsr extension");
503 * In principle Zve*x would also suffice here, were they supported
506 if ((cpu
->cfg
.ext_zvbb
|| cpu
->cfg
.ext_zvkg
|| cpu
->cfg
.ext_zvkned
||
507 cpu
->cfg
.ext_zvknha
|| cpu
->cfg
.ext_zvksed
|| cpu
->cfg
.ext_zvksh
) &&
508 !cpu
->cfg
.ext_zve32f
) {
510 "Vector crypto extensions require V or Zve* extensions");
514 if ((cpu
->cfg
.ext_zvbc
|| cpu
->cfg
.ext_zvknhb
) && !cpu
->cfg
.ext_zve64f
) {
517 "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
521 if (cpu
->cfg
.ext_zk
) {
522 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zkn
), true);
523 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zkr
), true);
524 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zkt
), true);
527 if (cpu
->cfg
.ext_zkn
) {
528 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zbkb
), true);
529 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zbkc
), true);
530 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zbkx
), true);
531 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zkne
), true);
532 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zknd
), true);
533 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zknh
), true);
536 if (cpu
->cfg
.ext_zks
) {
537 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zbkb
), true);
538 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zbkc
), true);
539 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zbkx
), true);
540 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zksed
), true);
541 cpu_cfg_ext_auto_update(cpu
, CPU_CFG_OFFSET(ext_zksh
), true);
544 if (cpu
->cfg
.ext_zicntr
&& !cpu
->cfg
.ext_zicsr
) {
545 if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicntr
))) {
546 error_setg(errp
, "zicntr requires zicsr");
549 cpu
->cfg
.ext_zicntr
= false;
552 if (cpu
->cfg
.ext_zihpm
&& !cpu
->cfg
.ext_zicsr
) {
553 if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zihpm
))) {
554 error_setg(errp
, "zihpm requires zicsr");
557 cpu
->cfg
.ext_zihpm
= false;
560 if (!cpu
->cfg
.ext_zihpm
) {
561 cpu
->cfg
.pmu_num
= 0;
562 cpu
->pmu_avail_ctrs
= 0;
566 * Disable isa extensions based on priv spec after we
567 * validated and set everything we need.
569 riscv_cpu_disable_priv_spec_isa_exts(cpu
);
572 void riscv_tcg_cpu_finalize_features(RISCVCPU
*cpu
, Error
**errp
)
574 CPURISCVState
*env
= &cpu
->env
;
575 Error
*local_err
= NULL
;
577 riscv_cpu_validate_priv_spec(cpu
, &local_err
);
578 if (local_err
!= NULL
) {
579 error_propagate(errp
, local_err
);
583 riscv_cpu_validate_misa_priv(env
, &local_err
);
584 if (local_err
!= NULL
) {
585 error_propagate(errp
, local_err
);
589 if (cpu
->cfg
.ext_smepmp
&& !cpu
->cfg
.pmp
) {
591 * Enhanced PMP should only be available
592 * on harts with PMP support
594 error_setg(errp
, "Invalid configuration: Smepmp requires PMP support");
598 riscv_cpu_validate_set_extensions(cpu
, &local_err
);
599 if (local_err
!= NULL
) {
600 error_propagate(errp
, local_err
);
605 bool riscv_cpu_tcg_compatible(RISCVCPU
*cpu
)
607 return object_dynamic_cast(OBJECT(cpu
), TYPE_RISCV_CPU_HOST
) == NULL
;
610 static bool riscv_cpu_is_generic(Object
*cpu_obj
)
612 return object_dynamic_cast(cpu_obj
, TYPE_RISCV_DYNAMIC_CPU
) != NULL
;
616 * We'll get here via the following path:
618 * riscv_cpu_realize()
619 * -> cpu_exec_realizefn()
620 * -> tcg_cpu_realize() (via accel_cpu_common_realize())
622 static bool tcg_cpu_realize(CPUState
*cs
, Error
**errp
)
624 RISCVCPU
*cpu
= RISCV_CPU(cs
);
625 Error
*local_err
= NULL
;
627 if (!riscv_cpu_tcg_compatible(cpu
)) {
628 g_autofree
char *name
= riscv_cpu_get_name(cpu
);
629 error_setg(errp
, "'%s' CPU is not compatible with TCG acceleration",
634 riscv_cpu_validate_misa_mxl(cpu
, &local_err
);
635 if (local_err
!= NULL
) {
636 error_propagate(errp
, local_err
);
640 #ifndef CONFIG_USER_ONLY
641 CPURISCVState
*env
= &cpu
->env
;
643 CPU(cs
)->tcg_cflags
|= CF_PCREL
;
645 if (cpu
->cfg
.ext_sstc
) {
646 riscv_timer_init(cpu
);
649 if (cpu
->cfg
.pmu_num
) {
650 if (!riscv_pmu_init(cpu
, cpu
->cfg
.pmu_num
) && cpu
->cfg
.ext_sscofpmf
) {
651 cpu
->pmu_timer
= timer_new_ns(QEMU_CLOCK_VIRTUAL
,
652 riscv_pmu_timer_cb
, cpu
);
656 /* With H-Ext, VSSIP, VSTIP, VSEIP and SGEIP are hardwired to one. */
657 if (riscv_has_ext(env
, RVH
)) {
658 env
->mideleg
= MIP_VSSIP
| MIP_VSTIP
| MIP_VSEIP
| MIP_SGEIP
;
665 typedef struct RISCVCPUMisaExtConfig
{
666 target_ulong misa_bit
;
668 } RISCVCPUMisaExtConfig
;
670 static void cpu_set_misa_ext_cfg(Object
*obj
, Visitor
*v
, const char *name
,
671 void *opaque
, Error
**errp
)
673 const RISCVCPUMisaExtConfig
*misa_ext_cfg
= opaque
;
674 target_ulong misa_bit
= misa_ext_cfg
->misa_bit
;
675 RISCVCPU
*cpu
= RISCV_CPU(obj
);
676 CPURISCVState
*env
= &cpu
->env
;
677 bool generic_cpu
= riscv_cpu_is_generic(obj
);
678 bool prev_val
, value
;
680 if (!visit_type_bool(v
, name
, &value
, errp
)) {
684 prev_val
= env
->misa_ext
& misa_bit
;
686 if (value
== prev_val
) {
692 g_autofree
char *cpuname
= riscv_cpu_get_name(cpu
);
693 error_setg(errp
, "'%s' CPU does not allow enabling extensions",
698 env
->misa_ext
|= misa_bit
;
699 env
->misa_ext_mask
|= misa_bit
;
701 env
->misa_ext
&= ~misa_bit
;
702 env
->misa_ext_mask
&= ~misa_bit
;
706 static void cpu_get_misa_ext_cfg(Object
*obj
, Visitor
*v
, const char *name
,
707 void *opaque
, Error
**errp
)
709 const RISCVCPUMisaExtConfig
*misa_ext_cfg
= opaque
;
710 target_ulong misa_bit
= misa_ext_cfg
->misa_bit
;
711 RISCVCPU
*cpu
= RISCV_CPU(obj
);
712 CPURISCVState
*env
= &cpu
->env
;
715 value
= env
->misa_ext
& misa_bit
;
717 visit_type_bool(v
, name
, &value
, errp
);
720 #define MISA_CFG(_bit, _enabled) \
721 {.misa_bit = _bit, .enabled = _enabled}
723 static const RISCVCPUMisaExtConfig misa_ext_cfgs
[] = {
729 MISA_CFG(RVE
, false),
734 MISA_CFG(RVJ
, false),
735 MISA_CFG(RVV
, false),
736 MISA_CFG(RVG
, false),
740 * We do not support user choice tracking for MISA
741 * extensions yet because, so far, we do not silently
742 * change MISA bits during realize() (RVG enables MISA
743 * bits but the user is warned about it).
745 static void riscv_cpu_add_misa_properties(Object
*cpu_obj
)
747 bool use_def_vals
= riscv_cpu_is_generic(cpu_obj
);
750 for (i
= 0; i
< ARRAY_SIZE(misa_ext_cfgs
); i
++) {
751 const RISCVCPUMisaExtConfig
*misa_cfg
= &misa_ext_cfgs
[i
];
752 int bit
= misa_cfg
->misa_bit
;
753 const char *name
= riscv_get_misa_ext_name(bit
);
754 const char *desc
= riscv_get_misa_ext_description(bit
);
756 /* Check if KVM already created the property */
757 if (object_property_find(cpu_obj
, name
)) {
761 object_property_add(cpu_obj
, name
, "bool",
762 cpu_get_misa_ext_cfg
,
763 cpu_set_misa_ext_cfg
,
764 NULL
, (void *)misa_cfg
);
765 object_property_set_description(cpu_obj
, name
, desc
);
767 object_property_set_bool(cpu_obj
, name
, misa_cfg
->enabled
, NULL
);
772 static bool cpu_ext_is_deprecated(const char *ext_name
)
774 return isupper(ext_name
[0]);
778 * String will be allocated in the heap. Caller is responsible
781 static char *cpu_ext_to_lower(const char *ext_name
)
783 char *ret
= g_malloc0(strlen(ext_name
) + 1);
785 strcpy(ret
, ext_name
);
786 ret
[0] = tolower(ret
[0]);
791 static void cpu_set_multi_ext_cfg(Object
*obj
, Visitor
*v
, const char *name
,
792 void *opaque
, Error
**errp
)
794 const RISCVCPUMultiExtConfig
*multi_ext_cfg
= opaque
;
795 RISCVCPU
*cpu
= RISCV_CPU(obj
);
796 bool generic_cpu
= riscv_cpu_is_generic(obj
);
797 bool prev_val
, value
;
799 if (!visit_type_bool(v
, name
, &value
, errp
)) {
803 if (cpu_ext_is_deprecated(multi_ext_cfg
->name
)) {
804 g_autofree
char *lower
= cpu_ext_to_lower(multi_ext_cfg
->name
);
806 warn_report("CPU property '%s' is deprecated. Please use '%s' instead",
807 multi_ext_cfg
->name
, lower
);
810 g_hash_table_insert(multi_ext_user_opts
,
811 GUINT_TO_POINTER(multi_ext_cfg
->offset
),
814 prev_val
= isa_ext_is_enabled(cpu
, multi_ext_cfg
->offset
);
816 if (value
== prev_val
) {
820 if (value
&& !generic_cpu
) {
821 g_autofree
char *cpuname
= riscv_cpu_get_name(cpu
);
822 error_setg(errp
, "'%s' CPU does not allow enabling extensions",
827 isa_ext_update_enabled(cpu
, multi_ext_cfg
->offset
, value
);
830 static void cpu_get_multi_ext_cfg(Object
*obj
, Visitor
*v
, const char *name
,
831 void *opaque
, Error
**errp
)
833 const RISCVCPUMultiExtConfig
*multi_ext_cfg
= opaque
;
834 bool value
= isa_ext_is_enabled(RISCV_CPU(obj
), multi_ext_cfg
->offset
);
836 visit_type_bool(v
, name
, &value
, errp
);
839 static void cpu_add_multi_ext_prop(Object
*cpu_obj
,
840 const RISCVCPUMultiExtConfig
*multi_cfg
)
842 bool generic_cpu
= riscv_cpu_is_generic(cpu_obj
);
843 bool deprecated_ext
= cpu_ext_is_deprecated(multi_cfg
->name
);
845 object_property_add(cpu_obj
, multi_cfg
->name
, "bool",
846 cpu_get_multi_ext_cfg
,
847 cpu_set_multi_ext_cfg
,
848 NULL
, (void *)multi_cfg
);
850 if (!generic_cpu
|| deprecated_ext
) {
855 * Set def val directly instead of using
856 * object_property_set_bool() to save the set()
857 * callback hash for user inputs.
859 isa_ext_update_enabled(RISCV_CPU(cpu_obj
), multi_cfg
->offset
,
863 static void riscv_cpu_add_multiext_prop_array(Object
*obj
,
864 const RISCVCPUMultiExtConfig
*array
)
866 const RISCVCPUMultiExtConfig
*prop
;
870 for (prop
= array
; prop
&& prop
->name
; prop
++) {
871 cpu_add_multi_ext_prop(obj
, prop
);
876 * Add CPU properties with user-facing flags.
878 * This will overwrite existing env->misa_ext values with the
879 * defaults set via riscv_cpu_add_misa_properties().
881 static void riscv_cpu_add_user_properties(Object
*obj
)
883 #ifndef CONFIG_USER_ONLY
884 riscv_add_satp_mode_properties(obj
);
887 riscv_cpu_add_misa_properties(obj
);
889 riscv_cpu_add_multiext_prop_array(obj
, riscv_cpu_extensions
);
890 riscv_cpu_add_multiext_prop_array(obj
, riscv_cpu_vendor_exts
);
891 riscv_cpu_add_multiext_prop_array(obj
, riscv_cpu_experimental_exts
);
893 riscv_cpu_add_multiext_prop_array(obj
, riscv_cpu_deprecated_exts
);
895 for (Property
*prop
= riscv_cpu_options
; prop
&& prop
->name
; prop
++) {
896 qdev_property_add_static(DEVICE(obj
), prop
);
901 * The 'max' type CPU will have all possible ratified
902 * non-vendor extensions enabled.
904 static void riscv_init_max_cpu_extensions(Object
*obj
)
906 RISCVCPU
*cpu
= RISCV_CPU(obj
);
907 CPURISCVState
*env
= &cpu
->env
;
908 const RISCVCPUMultiExtConfig
*prop
;
910 /* Enable RVG, RVJ and RVV that are disabled by default */
911 riscv_cpu_set_misa(env
, env
->misa_mxl
, env
->misa_ext
| RVG
| RVJ
| RVV
);
913 for (prop
= riscv_cpu_extensions
; prop
&& prop
->name
; prop
++) {
914 isa_ext_update_enabled(cpu
, prop
->offset
, true);
917 /* set vector version */
918 env
->vext_ver
= VEXT_VERSION_1_00_0
;
920 /* Zfinx is not compatible with F. Disable it */
921 isa_ext_update_enabled(cpu
, CPU_CFG_OFFSET(ext_zfinx
), false);
922 isa_ext_update_enabled(cpu
, CPU_CFG_OFFSET(ext_zdinx
), false);
923 isa_ext_update_enabled(cpu
, CPU_CFG_OFFSET(ext_zhinx
), false);
924 isa_ext_update_enabled(cpu
, CPU_CFG_OFFSET(ext_zhinxmin
), false);
926 isa_ext_update_enabled(cpu
, CPU_CFG_OFFSET(ext_zce
), false);
927 isa_ext_update_enabled(cpu
, CPU_CFG_OFFSET(ext_zcmp
), false);
928 isa_ext_update_enabled(cpu
, CPU_CFG_OFFSET(ext_zcmt
), false);
930 if (env
->misa_mxl
!= MXL_RV32
) {
931 isa_ext_update_enabled(cpu
, CPU_CFG_OFFSET(ext_zcf
), false);
935 static bool riscv_cpu_has_max_extensions(Object
*cpu_obj
)
937 return object_dynamic_cast(cpu_obj
, TYPE_RISCV_CPU_MAX
) != NULL
;
940 static void tcg_cpu_instance_init(CPUState
*cs
)
942 RISCVCPU
*cpu
= RISCV_CPU(cs
);
943 Object
*obj
= OBJECT(cpu
);
945 multi_ext_user_opts
= g_hash_table_new(NULL
, g_direct_equal
);
946 riscv_cpu_add_user_properties(obj
);
948 if (riscv_cpu_has_max_extensions(obj
)) {
949 riscv_init_max_cpu_extensions(obj
);
953 static void tcg_cpu_init_ops(AccelCPUClass
*accel_cpu
, CPUClass
*cc
)
956 * All cpus use the same set of operations.
958 cc
->tcg_ops
= &riscv_tcg_ops
;
961 static void tcg_cpu_class_init(CPUClass
*cc
)
963 cc
->init_accel_cpu
= tcg_cpu_init_ops
;
966 static void tcg_cpu_accel_class_init(ObjectClass
*oc
, void *data
)
968 AccelCPUClass
*acc
= ACCEL_CPU_CLASS(oc
);
970 acc
->cpu_class_init
= tcg_cpu_class_init
;
971 acc
->cpu_instance_init
= tcg_cpu_instance_init
;
972 acc
->cpu_target_realize
= tcg_cpu_realize
;
975 static const TypeInfo tcg_cpu_accel_type_info
= {
976 .name
= ACCEL_CPU_NAME("tcg"),
978 .parent
= TYPE_ACCEL_CPU
,
979 .class_init
= tcg_cpu_accel_class_init
,
983 static void tcg_cpu_accel_register_types(void)
985 type_register_static(&tcg_cpu_accel_type_info
);
987 type_init(tcg_cpu_accel_register_types
);