xref: /qemu/target/riscv/tcg/tcg-cpu.c (revision 84307cd6027c4602913177ff09aeefa4743b7234)
1 /*
2  * riscv TCG cpu class initialization
3  *
4  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5  * Copyright (c) 2017-2018 SiFive, Inc.
6  *
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.
10  *
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
14  * more details.
15  *
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/>.
18  */
19 
20 #include "qemu/osdep.h"
21 #include "exec/translation-block.h"
22 #include "tcg-cpu.h"
23 #include "cpu.h"
24 #include "exec/target_page.h"
25 #include "internals.h"
26 #include "pmu.h"
27 #include "time_helper.h"
28 #include "qapi/error.h"
29 #include "qapi/visitor.h"
30 #include "qemu/accel.h"
31 #include "qemu/error-report.h"
32 #include "qemu/log.h"
33 #include "accel/accel-cpu-target.h"
34 #include "accel/tcg/cpu-ops.h"
35 #include "tcg/tcg.h"
36 #ifndef CONFIG_USER_ONLY
37 #include "hw/boards.h"
38 #include "system/tcg.h"
39 #endif
40 
41 /* Hash that stores user set extensions */
42 static GHashTable *multi_ext_user_opts;
43 static GHashTable *misa_ext_user_opts;
44 
45 static GHashTable *multi_ext_implied_rules;
46 static GHashTable *misa_ext_implied_rules;
47 
48 static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
49 {
50     return g_hash_table_contains(multi_ext_user_opts,
51                                  GUINT_TO_POINTER(ext_offset));
52 }
53 
54 static bool cpu_misa_ext_is_user_set(uint32_t misa_bit)
55 {
56     return g_hash_table_contains(misa_ext_user_opts,
57                                  GUINT_TO_POINTER(misa_bit));
58 }
59 
60 static void cpu_cfg_ext_add_user_opt(uint32_t ext_offset, bool value)
61 {
62     g_hash_table_insert(multi_ext_user_opts, GUINT_TO_POINTER(ext_offset),
63                         (gpointer)value);
64 }
65 
66 static void cpu_misa_ext_add_user_opt(uint32_t bit, bool value)
67 {
68     g_hash_table_insert(misa_ext_user_opts, GUINT_TO_POINTER(bit),
69                         (gpointer)value);
70 }
71 
72 static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit,
73                                      bool enabled)
74 {
75     CPURISCVState *env = &cpu->env;
76 
77     if (enabled) {
78         env->misa_ext |= bit;
79         env->misa_ext_mask |= bit;
80     } else {
81         env->misa_ext &= ~bit;
82         env->misa_ext_mask &= ~bit;
83     }
84 }
85 
86 static const char *cpu_priv_ver_to_str(int priv_ver)
87 {
88     const char *priv_spec_str = priv_spec_to_str(priv_ver);
89 
90     g_assert(priv_spec_str);
91 
92     return priv_spec_str;
93 }
94 
95 static int riscv_cpu_mmu_index(CPUState *cs, bool ifetch)
96 {
97     return riscv_env_mmu_index(cpu_env(cs), ifetch);
98 }
99 
100 static void riscv_cpu_synchronize_from_tb(CPUState *cs,
101                                           const TranslationBlock *tb)
102 {
103     if (!(tb_cflags(tb) & CF_PCREL)) {
104         RISCVCPU *cpu = RISCV_CPU(cs);
105         CPURISCVState *env = &cpu->env;
106         RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
107 
108         tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
109 
110         if (xl == MXL_RV32) {
111             env->pc = (int32_t) tb->pc;
112         } else {
113             env->pc = tb->pc;
114         }
115     }
116 }
117 
118 static void riscv_restore_state_to_opc(CPUState *cs,
119                                        const TranslationBlock *tb,
120                                        const uint64_t *data)
121 {
122     RISCVCPU *cpu = RISCV_CPU(cs);
123     CPURISCVState *env = &cpu->env;
124     RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
125     target_ulong pc;
126 
127     if (tb_cflags(tb) & CF_PCREL) {
128         pc = (env->pc & TARGET_PAGE_MASK) | data[0];
129     } else {
130         pc = data[0];
131     }
132 
133     if (xl == MXL_RV32) {
134         env->pc = (int32_t)pc;
135     } else {
136         env->pc = pc;
137     }
138     env->bins = data[1];
139     env->excp_uw2 = data[2];
140 }
141 
142 const TCGCPUOps riscv_tcg_ops = {
143     .mttcg_supported = true,
144     .guest_default_memory_order = 0,
145 
146     .initialize = riscv_translate_init,
147     .translate_code = riscv_translate_code,
148     .synchronize_from_tb = riscv_cpu_synchronize_from_tb,
149     .restore_state_to_opc = riscv_restore_state_to_opc,
150     .mmu_index = riscv_cpu_mmu_index,
151 
152 #ifndef CONFIG_USER_ONLY
153     .tlb_fill = riscv_cpu_tlb_fill,
154     .cpu_exec_interrupt = riscv_cpu_exec_interrupt,
155     .cpu_exec_halt = riscv_cpu_has_work,
156     .do_interrupt = riscv_cpu_do_interrupt,
157     .do_transaction_failed = riscv_cpu_do_transaction_failed,
158     .do_unaligned_access = riscv_cpu_do_unaligned_access,
159     .debug_excp_handler = riscv_cpu_debug_excp_handler,
160     .debug_check_breakpoint = riscv_cpu_debug_check_breakpoint,
161     .debug_check_watchpoint = riscv_cpu_debug_check_watchpoint,
162 #endif /* !CONFIG_USER_ONLY */
163 };
164 
165 static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
166 {
167     const RISCVIsaExtData *edata;
168 
169     for (edata = isa_edata_arr; edata && edata->name; edata++) {
170         if (edata->ext_enable_offset != ext_offset) {
171             continue;
172         }
173 
174         return edata->min_version;
175     }
176 
177     g_assert_not_reached();
178 }
179 
180 static const char *cpu_cfg_ext_get_name(uint32_t ext_offset)
181 {
182     const RISCVCPUMultiExtConfig *feat;
183     const RISCVIsaExtData *edata;
184 
185     for (edata = isa_edata_arr; edata->name != NULL; edata++) {
186         if (edata->ext_enable_offset == ext_offset) {
187             return edata->name;
188         }
189     }
190 
191     for (feat = riscv_cpu_named_features; feat->name != NULL; feat++) {
192         if (feat->offset == ext_offset) {
193             return feat->name;
194         }
195     }
196 
197     g_assert_not_reached();
198 }
199 
200 static bool cpu_cfg_offset_is_named_feat(uint32_t ext_offset)
201 {
202     const RISCVCPUMultiExtConfig *feat;
203 
204     for (feat = riscv_cpu_named_features; feat->name != NULL; feat++) {
205         if (feat->offset == ext_offset) {
206             return true;
207         }
208     }
209 
210     return false;
211 }
212 
213 static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, uint32_t feat_offset)
214 {
215      /*
216       * All other named features are already enabled
217       * in riscv_tcg_cpu_instance_init().
218       */
219     switch (feat_offset) {
220     case CPU_CFG_OFFSET(ext_zic64b):
221         cpu->cfg.cbom_blocksize = 64;
222         cpu->cfg.cbop_blocksize = 64;
223         cpu->cfg.cboz_blocksize = 64;
224         break;
225     case CPU_CFG_OFFSET(ext_sha):
226         if (!cpu_misa_ext_is_user_set(RVH)) {
227             riscv_cpu_write_misa_bit(cpu, RVH, true);
228         }
229         /* fallthrough */
230     case CPU_CFG_OFFSET(ext_ssstateen):
231         cpu->cfg.ext_smstateen = true;
232         break;
233     }
234 }
235 
236 static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env,
237                                         uint32_t ext_offset)
238 {
239     int ext_priv_ver;
240 
241     if (env->priv_ver == PRIV_VERSION_LATEST) {
242         return;
243     }
244 
245     ext_priv_ver = cpu_cfg_ext_get_min_version(ext_offset);
246 
247     if (env->priv_ver < ext_priv_ver) {
248         /*
249          * Note: the 'priv_spec' command line option, if present,
250          * will take precedence over this priv_ver bump.
251          */
252         env->priv_ver = ext_priv_ver;
253     }
254 }
255 
256 static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset,
257                                     bool value)
258 {
259     CPURISCVState *env = &cpu->env;
260     bool prev_val = isa_ext_is_enabled(cpu, ext_offset);
261     int min_version;
262 
263     if (prev_val == value) {
264         return;
265     }
266 
267     if (cpu_cfg_ext_is_user_set(ext_offset)) {
268         return;
269     }
270 
271     if (value && env->priv_ver != PRIV_VERSION_LATEST) {
272         /* Do not enable it if priv_ver is older than min_version */
273         min_version = cpu_cfg_ext_get_min_version(ext_offset);
274         if (env->priv_ver < min_version) {
275             return;
276         }
277     }
278 
279     isa_ext_update_enabled(cpu, ext_offset, value);
280 }
281 
282 static void riscv_cpu_validate_misa_priv(CPURISCVState *env, Error **errp)
283 {
284     if (riscv_has_ext(env, RVH) && env->priv_ver < PRIV_VERSION_1_12_0) {
285         error_setg(errp, "H extension requires priv spec 1.12.0");
286         return;
287     }
288 }
289 
290 static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
291                                  Error **errp)
292 {
293     uint32_t vlen = cfg->vlenb << 3;
294 
295     if (vlen > RV_VLEN_MAX || vlen < 128) {
296         error_setg(errp,
297                    "Vector extension implementation only supports VLEN "
298                    "in the range [128, %d]", RV_VLEN_MAX);
299         return;
300     }
301 
302     if (cfg->elen > 64 || cfg->elen < 8) {
303         error_setg(errp,
304                    "Vector extension implementation only supports ELEN "
305                    "in the range [8, 64]");
306         return;
307     }
308 }
309 
310 static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
311 {
312     CPURISCVState *env = &cpu->env;
313     const RISCVIsaExtData *edata;
314 
315     /* Force disable extensions if priv spec version does not match */
316     for (edata = isa_edata_arr; edata && edata->name; edata++) {
317         if (isa_ext_is_enabled(cpu, edata->ext_enable_offset) &&
318             (env->priv_ver < edata->min_version)) {
319             /*
320              * These two extensions are always enabled as they were supported
321              * by QEMU before they were added as extensions in the ISA.
322              */
323             if (!strcmp(edata->name, "zicntr") ||
324                 !strcmp(edata->name, "zihpm")) {
325                 continue;
326             }
327 
328             isa_ext_update_enabled(cpu, edata->ext_enable_offset, false);
329 
330             /*
331              * Do not show user warnings for named features that users
332              * can't enable/disable in the command line. See commit
333              * 68c9e54bea for more info.
334              */
335             if (cpu_cfg_offset_is_named_feat(edata->ext_enable_offset)) {
336                 continue;
337             }
338 #ifndef CONFIG_USER_ONLY
339             warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
340                         " because privilege spec version does not match",
341                         edata->name, env->mhartid);
342 #else
343             warn_report("disabling %s extension because "
344                         "privilege spec version does not match",
345                         edata->name);
346 #endif
347         }
348     }
349 }
350 
351 static void riscv_cpu_update_named_features(RISCVCPU *cpu)
352 {
353     if (cpu->env.priv_ver >= PRIV_VERSION_1_11_0) {
354         cpu->cfg.has_priv_1_11 = true;
355     }
356 
357     if (cpu->env.priv_ver >= PRIV_VERSION_1_12_0) {
358         cpu->cfg.has_priv_1_12 = true;
359     }
360 
361     if (cpu->env.priv_ver >= PRIV_VERSION_1_13_0) {
362         cpu->cfg.has_priv_1_13 = true;
363     }
364 
365     cpu->cfg.ext_zic64b = cpu->cfg.cbom_blocksize == 64 &&
366                           cpu->cfg.cbop_blocksize == 64 &&
367                           cpu->cfg.cboz_blocksize == 64;
368 
369     cpu->cfg.ext_ssstateen = cpu->cfg.ext_smstateen;
370 
371     cpu->cfg.ext_sha = riscv_has_ext(&cpu->env, RVH) &&
372                        cpu->cfg.ext_ssstateen;
373 
374     cpu->cfg.ext_ziccrse = cpu->cfg.has_priv_1_11;
375 }
376 
377 static void riscv_cpu_validate_g(RISCVCPU *cpu)
378 {
379     const char *warn_msg = "RVG mandates disabled extension %s";
380     uint32_t g_misa_bits[] = {RVI, RVM, RVA, RVF, RVD};
381     bool send_warn = cpu_misa_ext_is_user_set(RVG);
382 
383     for (int i = 0; i < ARRAY_SIZE(g_misa_bits); i++) {
384         uint32_t bit = g_misa_bits[i];
385 
386         if (riscv_has_ext(&cpu->env, bit)) {
387             continue;
388         }
389 
390         if (!cpu_misa_ext_is_user_set(bit)) {
391             riscv_cpu_write_misa_bit(cpu, bit, true);
392             continue;
393         }
394 
395         if (send_warn) {
396             warn_report(warn_msg, riscv_get_misa_ext_name(bit));
397         }
398     }
399 
400     if (!cpu->cfg.ext_zicsr) {
401         if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicsr))) {
402             cpu->cfg.ext_zicsr = true;
403         } else if (send_warn) {
404             warn_report(warn_msg, "zicsr");
405         }
406     }
407 
408     if (!cpu->cfg.ext_zifencei) {
409         if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zifencei))) {
410             cpu->cfg.ext_zifencei = true;
411         } else if (send_warn) {
412             warn_report(warn_msg, "zifencei");
413         }
414     }
415 }
416 
417 static void riscv_cpu_validate_b(RISCVCPU *cpu)
418 {
419     const char *warn_msg = "RVB mandates disabled extension %s";
420 
421     if (!cpu->cfg.ext_zba) {
422         if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zba))) {
423             cpu->cfg.ext_zba = true;
424         } else {
425             warn_report(warn_msg, "zba");
426         }
427     }
428 
429     if (!cpu->cfg.ext_zbb) {
430         if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zbb))) {
431             cpu->cfg.ext_zbb = true;
432         } else {
433             warn_report(warn_msg, "zbb");
434         }
435     }
436 
437     if (!cpu->cfg.ext_zbs) {
438         if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zbs))) {
439             cpu->cfg.ext_zbs = true;
440         } else {
441             warn_report(warn_msg, "zbs");
442         }
443     }
444 }
445 
446 /*
447  * Check consistency between chosen extensions while setting
448  * cpu->cfg accordingly.
449  */
450 void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
451 {
452     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
453     CPURISCVState *env = &cpu->env;
454     Error *local_err = NULL;
455 
456     if (riscv_has_ext(env, RVG)) {
457         riscv_cpu_validate_g(cpu);
458     }
459 
460     if (riscv_has_ext(env, RVB)) {
461         riscv_cpu_validate_b(cpu);
462     }
463 
464     if (riscv_has_ext(env, RVI) && riscv_has_ext(env, RVE)) {
465         error_setg(errp,
466                    "I and E extensions are incompatible");
467         return;
468     }
469 
470     if (!riscv_has_ext(env, RVI) && !riscv_has_ext(env, RVE)) {
471         error_setg(errp,
472                    "Either I or E extension must be set");
473         return;
474     }
475 
476     if (riscv_has_ext(env, RVS) && !riscv_has_ext(env, RVU)) {
477         error_setg(errp,
478                    "Setting S extension without U extension is illegal");
479         return;
480     }
481 
482     if (riscv_has_ext(env, RVH) && !riscv_has_ext(env, RVI)) {
483         error_setg(errp,
484                    "H depends on an I base integer ISA with 32 x registers");
485         return;
486     }
487 
488     if (riscv_has_ext(env, RVH) && !riscv_has_ext(env, RVS)) {
489         error_setg(errp, "H extension implicitly requires S-mode");
490         return;
491     }
492 
493     if (riscv_has_ext(env, RVF) && !cpu->cfg.ext_zicsr) {
494         error_setg(errp, "F extension requires Zicsr");
495         return;
496     }
497 
498     if ((cpu->cfg.ext_zacas) && !riscv_has_ext(env, RVA)) {
499         error_setg(errp, "Zacas extension requires A extension");
500         return;
501     }
502 
503     if ((cpu->cfg.ext_zawrs) && !riscv_has_ext(env, RVA)) {
504         error_setg(errp, "Zawrs extension requires A extension");
505         return;
506     }
507 
508     if (cpu->cfg.ext_zfa && !riscv_has_ext(env, RVF)) {
509         error_setg(errp, "Zfa extension requires F extension");
510         return;
511     }
512 
513     if (cpu->cfg.ext_zfhmin && !riscv_has_ext(env, RVF)) {
514         error_setg(errp, "Zfh/Zfhmin extensions require F extension");
515         return;
516     }
517 
518     if (cpu->cfg.ext_zfbfmin && !riscv_has_ext(env, RVF)) {
519         error_setg(errp, "Zfbfmin extension depends on F extension");
520         return;
521     }
522 
523     if (riscv_has_ext(env, RVD) && !riscv_has_ext(env, RVF)) {
524         error_setg(errp, "D extension requires F extension");
525         return;
526     }
527 
528     if (riscv_has_ext(env, RVV)) {
529         riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
530         if (local_err != NULL) {
531             error_propagate(errp, local_err);
532             return;
533         }
534     }
535 
536     /* The Zve64d extension depends on the Zve64f extension */
537     if (cpu->cfg.ext_zve64d) {
538         if (!riscv_has_ext(env, RVD)) {
539             error_setg(errp, "Zve64d/V extensions require D extension");
540             return;
541         }
542     }
543 
544     /* The Zve32f extension depends on the Zve32x extension */
545     if (cpu->cfg.ext_zve32f) {
546         if (!riscv_has_ext(env, RVF)) {
547             error_setg(errp, "Zve32f/Zve64f extensions require F extension");
548             return;
549         }
550     }
551 
552     if (cpu->cfg.ext_zvfhmin && !cpu->cfg.ext_zve32f) {
553         error_setg(errp, "Zvfh/Zvfhmin extensions require Zve32f extension");
554         return;
555     }
556 
557     if (cpu->cfg.ext_zvfh && !cpu->cfg.ext_zfhmin) {
558         error_setg(errp, "Zvfh extensions requires Zfhmin extension");
559         return;
560     }
561 
562     if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zve32f) {
563         error_setg(errp, "Zvfbfmin extension depends on Zve32f extension");
564         return;
565     }
566 
567     if (cpu->cfg.ext_zvfbfwma && !cpu->cfg.ext_zvfbfmin) {
568         error_setg(errp, "Zvfbfwma extension depends on Zvfbfmin extension");
569         return;
570     }
571 
572     if ((cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) && !cpu->cfg.ext_zfinx) {
573         error_setg(errp, "Zdinx/Zhinx/Zhinxmin extensions require Zfinx");
574         return;
575     }
576 
577     if (cpu->cfg.ext_zfinx) {
578         if (!cpu->cfg.ext_zicsr) {
579             error_setg(errp, "Zfinx extension requires Zicsr");
580             return;
581         }
582         if (riscv_has_ext(env, RVF)) {
583             error_setg(errp,
584                        "Zfinx cannot be supported together with F extension");
585             return;
586         }
587     }
588 
589     if (cpu->cfg.ext_zcmop && !cpu->cfg.ext_zca) {
590         error_setg(errp, "Zcmop extensions require Zca");
591         return;
592     }
593 
594     if (mcc->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
595         error_setg(errp, "Zcf extension is only relevant to RV32");
596         return;
597     }
598 
599     if (!riscv_has_ext(env, RVF) && cpu->cfg.ext_zcf) {
600         error_setg(errp, "Zcf extension requires F extension");
601         return;
602     }
603 
604     if (!riscv_has_ext(env, RVD) && cpu->cfg.ext_zcd) {
605         error_setg(errp, "Zcd extension requires D extension");
606         return;
607     }
608 
609     if ((cpu->cfg.ext_zcf || cpu->cfg.ext_zcd || cpu->cfg.ext_zcb ||
610          cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) && !cpu->cfg.ext_zca) {
611         error_setg(errp, "Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca "
612                          "extension");
613         return;
614     }
615 
616     if (cpu->cfg.ext_zcd && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) {
617         error_setg(errp, "Zcmp/Zcmt extensions are incompatible with "
618                          "Zcd extension");
619         return;
620     }
621 
622     if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_zicsr) {
623         error_setg(errp, "Zcmt extension requires Zicsr extension");
624         return;
625     }
626 
627     if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg ||
628          cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed ||
629          cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32x) {
630         error_setg(errp,
631                    "Vector crypto extensions require V or Zve* extensions");
632         return;
633     }
634 
635     if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
636         error_setg(
637             errp,
638             "Zvbc and Zvknhb extensions require V or Zve64x extensions");
639         return;
640     }
641 
642     if (cpu->cfg.ext_zicntr && !cpu->cfg.ext_zicsr) {
643         if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicntr))) {
644             error_setg(errp, "zicntr requires zicsr");
645             return;
646         }
647         cpu->cfg.ext_zicntr = false;
648     }
649 
650     if (cpu->cfg.ext_zihpm && !cpu->cfg.ext_zicsr) {
651         if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zihpm))) {
652             error_setg(errp, "zihpm requires zicsr");
653             return;
654         }
655         cpu->cfg.ext_zihpm = false;
656     }
657 
658     if (cpu->cfg.ext_zicfiss) {
659         if (!cpu->cfg.ext_zicsr) {
660             error_setg(errp, "zicfiss extension requires zicsr extension");
661             return;
662         }
663         if (!riscv_has_ext(env, RVA)) {
664             error_setg(errp, "zicfiss extension requires A extension");
665             return;
666         }
667         if (!riscv_has_ext(env, RVS)) {
668             error_setg(errp, "zicfiss extension requires S");
669             return;
670         }
671         if (!cpu->cfg.ext_zimop) {
672             error_setg(errp, "zicfiss extension requires zimop extension");
673             return;
674         }
675         if (cpu->cfg.ext_zca && !cpu->cfg.ext_zcmop) {
676             error_setg(errp, "zicfiss with zca requires zcmop extension");
677             return;
678         }
679     }
680 
681     if (!cpu->cfg.ext_zihpm) {
682         cpu->cfg.pmu_mask = 0;
683         cpu->pmu_avail_ctrs = 0;
684     }
685 
686     if (cpu->cfg.ext_zicfilp && !cpu->cfg.ext_zicsr) {
687         error_setg(errp, "zicfilp extension requires zicsr extension");
688         return;
689     }
690 
691     if (mcc->misa_mxl_max == MXL_RV32 && cpu->cfg.ext_svukte) {
692         error_setg(errp, "svukte is not supported for RV32");
693         return;
694     }
695 
696     if ((cpu->cfg.ext_smctr || cpu->cfg.ext_ssctr) &&
697         (!riscv_has_ext(env, RVS) || !cpu->cfg.ext_sscsrind)) {
698         if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_smctr)) ||
699             cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_ssctr))) {
700             error_setg(errp, "Smctr and Ssctr require S-mode and Sscsrind");
701             return;
702         }
703         cpu->cfg.ext_smctr = false;
704         cpu->cfg.ext_ssctr = false;
705     }
706 
707     /*
708      * Disable isa extensions based on priv spec after we
709      * validated and set everything we need.
710      */
711     riscv_cpu_disable_priv_spec_isa_exts(cpu);
712 }
713 
714 #ifndef CONFIG_USER_ONLY
715 static bool riscv_cpu_validate_profile_satp(RISCVCPU *cpu,
716                                             RISCVCPUProfile *profile,
717                                             bool send_warn)
718 {
719     int satp_max = satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
720 
721     if (profile->satp_mode > satp_max) {
722         if (send_warn) {
723             bool is_32bit = riscv_cpu_is_32bit(cpu);
724             const char *req_satp = satp_mode_str(profile->satp_mode, is_32bit);
725             const char *cur_satp = satp_mode_str(satp_max, is_32bit);
726 
727             warn_report("Profile %s requires satp mode %s, "
728                         "but satp mode %s was set", profile->name,
729                         req_satp, cur_satp);
730         }
731 
732         return false;
733     }
734 
735     return true;
736 }
737 #endif
738 
739 static void riscv_cpu_check_parent_profile(RISCVCPU *cpu,
740                                            RISCVCPUProfile *profile,
741                                            RISCVCPUProfile *parent)
742 {
743     const char *parent_name;
744     bool parent_enabled;
745 
746     if (!profile->enabled || !parent) {
747         return;
748     }
749 
750     parent_name = parent->name;
751     parent_enabled = object_property_get_bool(OBJECT(cpu), parent_name, NULL);
752     profile->enabled = parent_enabled;
753 }
754 
755 static void riscv_cpu_validate_profile(RISCVCPU *cpu,
756                                        RISCVCPUProfile *profile)
757 {
758     CPURISCVState *env = &cpu->env;
759     const char *warn_msg = "Profile %s mandates disabled extension %s";
760     bool send_warn = profile->user_set && profile->enabled;
761     bool profile_impl = true;
762     int i;
763 
764 #ifndef CONFIG_USER_ONLY
765     if (profile->satp_mode != RISCV_PROFILE_ATTR_UNUSED) {
766         profile_impl = riscv_cpu_validate_profile_satp(cpu, profile,
767                                                        send_warn);
768     }
769 #endif
770 
771     if (profile->priv_spec != RISCV_PROFILE_ATTR_UNUSED &&
772         profile->priv_spec > env->priv_ver) {
773         profile_impl = false;
774 
775         if (send_warn) {
776             warn_report("Profile %s requires priv spec %s, "
777                         "but priv ver %s was set", profile->name,
778                         cpu_priv_ver_to_str(profile->priv_spec),
779                         cpu_priv_ver_to_str(env->priv_ver));
780         }
781     }
782 
783     for (i = 0; misa_bits[i] != 0; i++) {
784         uint32_t bit = misa_bits[i];
785 
786         if (!(profile->misa_ext & bit)) {
787             continue;
788         }
789 
790         if (!riscv_has_ext(&cpu->env, bit)) {
791             profile_impl = false;
792 
793             if (send_warn) {
794                 warn_report(warn_msg, profile->name,
795                             riscv_get_misa_ext_name(bit));
796             }
797         }
798     }
799 
800     for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
801         int ext_offset = profile->ext_offsets[i];
802 
803         if (!isa_ext_is_enabled(cpu, ext_offset)) {
804             profile_impl = false;
805 
806             if (send_warn) {
807                 warn_report(warn_msg, profile->name,
808                             cpu_cfg_ext_get_name(ext_offset));
809             }
810         }
811     }
812 
813     profile->enabled = profile_impl;
814 
815     riscv_cpu_check_parent_profile(cpu, profile, profile->u_parent);
816     riscv_cpu_check_parent_profile(cpu, profile, profile->s_parent);
817 }
818 
819 static void riscv_cpu_validate_profiles(RISCVCPU *cpu)
820 {
821     for (int i = 0; riscv_profiles[i] != NULL; i++) {
822         riscv_cpu_validate_profile(cpu, riscv_profiles[i]);
823     }
824 }
825 
826 static void riscv_cpu_init_implied_exts_rules(void)
827 {
828     RISCVCPUImpliedExtsRule *rule;
829 #ifndef CONFIG_USER_ONLY
830     MachineState *ms = MACHINE(qdev_get_machine());
831 #endif
832     static bool initialized;
833     int i;
834 
835     /* Implied rules only need to be initialized once. */
836     if (initialized) {
837         return;
838     }
839 
840     for (i = 0; (rule = riscv_misa_ext_implied_rules[i]); i++) {
841 #ifndef CONFIG_USER_ONLY
842         rule->enabled = bitmap_new(ms->smp.cpus);
843 #endif
844         g_hash_table_insert(misa_ext_implied_rules,
845                             GUINT_TO_POINTER(rule->ext), (gpointer)rule);
846     }
847 
848     for (i = 0; (rule = riscv_multi_ext_implied_rules[i]); i++) {
849 #ifndef CONFIG_USER_ONLY
850         rule->enabled = bitmap_new(ms->smp.cpus);
851 #endif
852         g_hash_table_insert(multi_ext_implied_rules,
853                             GUINT_TO_POINTER(rule->ext), (gpointer)rule);
854     }
855 
856     initialized = true;
857 }
858 
859 static void cpu_enable_implied_rule(RISCVCPU *cpu,
860                                     RISCVCPUImpliedExtsRule *rule)
861 {
862     CPURISCVState *env = &cpu->env;
863     RISCVCPUImpliedExtsRule *ir;
864     bool enabled = false;
865     int i;
866 
867 #ifndef CONFIG_USER_ONLY
868     enabled = test_bit(cpu->env.mhartid, rule->enabled);
869 #endif
870 
871     if (!enabled) {
872         /* Enable the implied MISAs. */
873         if (rule->implied_misa_exts) {
874             for (i = 0; misa_bits[i] != 0; i++) {
875                 if (rule->implied_misa_exts & misa_bits[i]) {
876                     /*
877                      * If the user disabled the misa_bit do not re-enable it
878                      * and do not apply any implied rules related to it.
879                      */
880                     if (cpu_misa_ext_is_user_set(misa_bits[i]) &&
881                         !(env->misa_ext & misa_bits[i])) {
882                         continue;
883                     }
884 
885                     riscv_cpu_set_misa_ext(env, env->misa_ext | misa_bits[i]);
886                     ir = g_hash_table_lookup(misa_ext_implied_rules,
887                                              GUINT_TO_POINTER(misa_bits[i]));
888 
889                     if (ir) {
890                         cpu_enable_implied_rule(cpu, ir);
891                     }
892                 }
893             }
894         }
895 
896         /* Enable the implied extensions. */
897         for (i = 0;
898              rule->implied_multi_exts[i] != RISCV_IMPLIED_EXTS_RULE_END; i++) {
899             cpu_cfg_ext_auto_update(cpu, rule->implied_multi_exts[i], true);
900 
901             ir = g_hash_table_lookup(multi_ext_implied_rules,
902                                      GUINT_TO_POINTER(
903                                          rule->implied_multi_exts[i]));
904 
905             if (ir) {
906                 cpu_enable_implied_rule(cpu, ir);
907             }
908         }
909 
910 #ifndef CONFIG_USER_ONLY
911         bitmap_set(rule->enabled, cpu->env.mhartid, 1);
912 #endif
913     }
914 }
915 
916 /* Zc extension has special implied rules that need to be handled separately. */
917 static void cpu_enable_zc_implied_rules(RISCVCPU *cpu)
918 {
919     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
920     CPURISCVState *env = &cpu->env;
921 
922     if (cpu->cfg.ext_zce) {
923         cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zca), true);
924         cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcb), true);
925         cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcmp), true);
926         cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcmt), true);
927 
928         if (riscv_has_ext(env, RVF) && mcc->misa_mxl_max == MXL_RV32) {
929             cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcf), true);
930         }
931     }
932 
933     /* Zca, Zcd and Zcf has a PRIV 1.12.0 restriction */
934     if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) {
935         cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zca), true);
936 
937         if (riscv_has_ext(env, RVF) && mcc->misa_mxl_max == MXL_RV32) {
938             cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcf), true);
939         }
940 
941         if (riscv_has_ext(env, RVD)) {
942             cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcd), true);
943         }
944     }
945 }
946 
947 static void riscv_cpu_enable_implied_rules(RISCVCPU *cpu)
948 {
949     RISCVCPUImpliedExtsRule *rule;
950     int i;
951 
952     /* Enable the implied extensions for Zc. */
953     cpu_enable_zc_implied_rules(cpu);
954 
955     /* Enable the implied MISAs. */
956     for (i = 0; (rule = riscv_misa_ext_implied_rules[i]); i++) {
957         if (riscv_has_ext(&cpu->env, rule->ext)) {
958             cpu_enable_implied_rule(cpu, rule);
959         }
960     }
961 
962     /* Enable the implied extensions. */
963     for (i = 0; (rule = riscv_multi_ext_implied_rules[i]); i++) {
964         if (isa_ext_is_enabled(cpu, rule->ext)) {
965             cpu_enable_implied_rule(cpu, rule);
966         }
967     }
968 }
969 
970 void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
971 {
972     CPURISCVState *env = &cpu->env;
973     Error *local_err = NULL;
974 
975     riscv_cpu_init_implied_exts_rules();
976     riscv_cpu_enable_implied_rules(cpu);
977 
978     riscv_cpu_validate_misa_priv(env, &local_err);
979     if (local_err != NULL) {
980         error_propagate(errp, local_err);
981         return;
982     }
983 
984     riscv_cpu_update_named_features(cpu);
985     riscv_cpu_validate_profiles(cpu);
986 
987     if (cpu->cfg.ext_smepmp && !cpu->cfg.pmp) {
988         /*
989          * Enhanced PMP should only be available
990          * on harts with PMP support
991          */
992         error_setg(errp, "Invalid configuration: Smepmp requires PMP support");
993         return;
994     }
995 
996     riscv_cpu_validate_set_extensions(cpu, &local_err);
997     if (local_err != NULL) {
998         error_propagate(errp, local_err);
999         return;
1000     }
1001 #ifndef CONFIG_USER_ONLY
1002     if (cpu->cfg.pmu_mask) {
1003         riscv_pmu_init(cpu, &local_err);
1004         if (local_err != NULL) {
1005             error_propagate(errp, local_err);
1006             return;
1007         }
1008 
1009         if (cpu->cfg.ext_sscofpmf) {
1010             cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
1011                                           riscv_pmu_timer_cb, cpu);
1012         }
1013     }
1014 #endif
1015 }
1016 
1017 void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
1018 {
1019     GPtrArray *dynamic_decoders;
1020     dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
1021     for (size_t i = 0; i < decoder_table_size; ++i) {
1022         if (decoder_table[i].guard_func &&
1023             decoder_table[i].guard_func(&cpu->cfg)) {
1024             g_ptr_array_add(dynamic_decoders,
1025                             (gpointer)decoder_table[i].riscv_cpu_decode_fn);
1026         }
1027     }
1028 
1029     cpu->decoders = dynamic_decoders;
1030 }
1031 
1032 bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
1033 {
1034     return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
1035 }
1036 
1037 static bool riscv_cpu_is_generic(Object *cpu_obj)
1038 {
1039     return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
1040 }
1041 
1042 /*
1043  * We'll get here via the following path:
1044  *
1045  * riscv_cpu_realize()
1046  *   -> cpu_exec_realizefn()
1047  *      -> tcg_cpu_realize() (via accel_cpu_common_realize())
1048  */
1049 static bool riscv_tcg_cpu_realize(CPUState *cs, Error **errp)
1050 {
1051     RISCVCPU *cpu = RISCV_CPU(cs);
1052 
1053     if (!riscv_cpu_tcg_compatible(cpu)) {
1054         g_autofree char *name = riscv_cpu_get_name(cpu);
1055         error_setg(errp, "'%s' CPU is not compatible with TCG acceleration",
1056                    name);
1057         return false;
1058     }
1059 
1060 #ifndef CONFIG_USER_ONLY
1061     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
1062 
1063     if (mcc->misa_mxl_max >= MXL_RV128 && qemu_tcg_mttcg_enabled()) {
1064         /* Missing 128-bit aligned atomics */
1065         error_setg(errp,
1066                    "128-bit RISC-V currently does not work with Multi "
1067                    "Threaded TCG. Please use: -accel tcg,thread=single");
1068         return false;
1069     }
1070 
1071     CPURISCVState *env = &cpu->env;
1072 
1073     tcg_cflags_set(CPU(cs), CF_PCREL);
1074 
1075     if (cpu->cfg.ext_sstc) {
1076         riscv_timer_init(cpu);
1077     }
1078 
1079     /* With H-Ext, VSSIP, VSTIP, VSEIP and SGEIP are hardwired to one. */
1080     if (riscv_has_ext(env, RVH)) {
1081         env->mideleg = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP | MIP_SGEIP;
1082     }
1083 #endif
1084 
1085     return true;
1086 }
1087 
1088 typedef struct RISCVCPUMisaExtConfig {
1089     target_ulong misa_bit;
1090     bool enabled;
1091 } RISCVCPUMisaExtConfig;
1092 
1093 static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
1094                                  void *opaque, Error **errp)
1095 {
1096     const RISCVCPUMisaExtConfig *misa_ext_cfg = opaque;
1097     target_ulong misa_bit = misa_ext_cfg->misa_bit;
1098     RISCVCPU *cpu = RISCV_CPU(obj);
1099     CPURISCVState *env = &cpu->env;
1100     bool vendor_cpu = riscv_cpu_is_vendor(obj);
1101     bool prev_val, value;
1102 
1103     if (!visit_type_bool(v, name, &value, errp)) {
1104         return;
1105     }
1106 
1107     cpu_misa_ext_add_user_opt(misa_bit, value);
1108 
1109     prev_val = env->misa_ext & misa_bit;
1110 
1111     if (value == prev_val) {
1112         return;
1113     }
1114 
1115     if (value) {
1116         if (vendor_cpu) {
1117             g_autofree char *cpuname = riscv_cpu_get_name(cpu);
1118             error_setg(errp, "'%s' CPU does not allow enabling extensions",
1119                        cpuname);
1120             return;
1121         }
1122 
1123         if (misa_bit == RVH && env->priv_ver < PRIV_VERSION_1_12_0) {
1124             /*
1125              * Note: the 'priv_spec' command line option, if present,
1126              * will take precedence over this priv_ver bump.
1127              */
1128             env->priv_ver = PRIV_VERSION_1_12_0;
1129         }
1130     }
1131 
1132     riscv_cpu_write_misa_bit(cpu, misa_bit, value);
1133 }
1134 
1135 static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
1136                                  void *opaque, Error **errp)
1137 {
1138     const RISCVCPUMisaExtConfig *misa_ext_cfg = opaque;
1139     target_ulong misa_bit = misa_ext_cfg->misa_bit;
1140     RISCVCPU *cpu = RISCV_CPU(obj);
1141     CPURISCVState *env = &cpu->env;
1142     bool value;
1143 
1144     value = env->misa_ext & misa_bit;
1145 
1146     visit_type_bool(v, name, &value, errp);
1147 }
1148 
1149 #define MISA_CFG(_bit, _enabled) \
1150     {.misa_bit = _bit, .enabled = _enabled}
1151 
1152 static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
1153     MISA_CFG(RVA, true),
1154     MISA_CFG(RVC, true),
1155     MISA_CFG(RVD, true),
1156     MISA_CFG(RVF, true),
1157     MISA_CFG(RVI, true),
1158     MISA_CFG(RVE, false),
1159     MISA_CFG(RVM, true),
1160     MISA_CFG(RVS, true),
1161     MISA_CFG(RVU, true),
1162     MISA_CFG(RVH, true),
1163     MISA_CFG(RVV, false),
1164     MISA_CFG(RVG, false),
1165     MISA_CFG(RVB, false),
1166 };
1167 
1168 /*
1169  * We do not support user choice tracking for MISA
1170  * extensions yet because, so far, we do not silently
1171  * change MISA bits during realize() (RVG enables MISA
1172  * bits but the user is warned about it).
1173  */
1174 static void riscv_cpu_add_misa_properties(Object *cpu_obj)
1175 {
1176     bool use_def_vals = riscv_cpu_is_generic(cpu_obj);
1177     int i;
1178 
1179     for (i = 0; i < ARRAY_SIZE(misa_ext_cfgs); i++) {
1180         const RISCVCPUMisaExtConfig *misa_cfg = &misa_ext_cfgs[i];
1181         int bit = misa_cfg->misa_bit;
1182         const char *name = riscv_get_misa_ext_name(bit);
1183         const char *desc = riscv_get_misa_ext_description(bit);
1184 
1185         /* Check if KVM already created the property */
1186         if (object_property_find(cpu_obj, name)) {
1187             continue;
1188         }
1189 
1190         object_property_add(cpu_obj, name, "bool",
1191                             cpu_get_misa_ext_cfg,
1192                             cpu_set_misa_ext_cfg,
1193                             NULL, (void *)misa_cfg);
1194         object_property_set_description(cpu_obj, name, desc);
1195         if (use_def_vals) {
1196             riscv_cpu_write_misa_bit(RISCV_CPU(cpu_obj), bit,
1197                                      misa_cfg->enabled);
1198         }
1199     }
1200 }
1201 
1202 static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
1203                             void *opaque, Error **errp)
1204 {
1205     RISCVCPUProfile *profile = opaque;
1206     RISCVCPU *cpu = RISCV_CPU(obj);
1207     bool value;
1208     int i, ext_offset;
1209 
1210     if (riscv_cpu_is_vendor(obj)) {
1211         error_setg(errp, "Profile %s is not available for vendor CPUs",
1212                    profile->name);
1213         return;
1214     }
1215 
1216     if (cpu->env.misa_mxl != MXL_RV64) {
1217         error_setg(errp, "Profile %s only available for 64 bit CPUs",
1218                    profile->name);
1219         return;
1220     }
1221 
1222     if (!visit_type_bool(v, name, &value, errp)) {
1223         return;
1224     }
1225 
1226     profile->user_set = true;
1227     profile->enabled = value;
1228 
1229     if (profile->u_parent != NULL) {
1230         object_property_set_bool(obj, profile->u_parent->name,
1231                                  profile->enabled, NULL);
1232     }
1233 
1234     if (profile->s_parent != NULL) {
1235         object_property_set_bool(obj, profile->s_parent->name,
1236                                  profile->enabled, NULL);
1237     }
1238 
1239     if (profile->enabled) {
1240         cpu->env.priv_ver = profile->priv_spec;
1241     }
1242 
1243 #ifndef CONFIG_USER_ONLY
1244     if (profile->satp_mode != RISCV_PROFILE_ATTR_UNUSED) {
1245         object_property_set_bool(obj, "mmu", true, NULL);
1246         const char *satp_prop = satp_mode_str(profile->satp_mode,
1247                                               riscv_cpu_is_32bit(cpu));
1248         object_property_set_bool(obj, satp_prop, profile->enabled, NULL);
1249     }
1250 #endif
1251 
1252     for (i = 0; misa_bits[i] != 0; i++) {
1253         uint32_t bit = misa_bits[i];
1254 
1255         if  (!(profile->misa_ext & bit)) {
1256             continue;
1257         }
1258 
1259         if (bit == RVI && !profile->enabled) {
1260             /*
1261              * Disabling profiles will not disable the base
1262              * ISA RV64I.
1263              */
1264             continue;
1265         }
1266 
1267         cpu_misa_ext_add_user_opt(bit, profile->enabled);
1268         riscv_cpu_write_misa_bit(cpu, bit, profile->enabled);
1269     }
1270 
1271     for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
1272         ext_offset = profile->ext_offsets[i];
1273 
1274         if (profile->enabled) {
1275             if (cpu_cfg_offset_is_named_feat(ext_offset)) {
1276                 riscv_cpu_enable_named_feat(cpu, ext_offset);
1277             }
1278 
1279             cpu_bump_multi_ext_priv_ver(&cpu->env, ext_offset);
1280         }
1281 
1282         cpu_cfg_ext_add_user_opt(ext_offset, profile->enabled);
1283         isa_ext_update_enabled(cpu, ext_offset, profile->enabled);
1284     }
1285 }
1286 
1287 static void cpu_get_profile(Object *obj, Visitor *v, const char *name,
1288                             void *opaque, Error **errp)
1289 {
1290     RISCVCPUProfile *profile = opaque;
1291     bool value = profile->enabled;
1292 
1293     visit_type_bool(v, name, &value, errp);
1294 }
1295 
1296 static void riscv_cpu_add_profiles(Object *cpu_obj)
1297 {
1298     for (int i = 0; riscv_profiles[i] != NULL; i++) {
1299         const RISCVCPUProfile *profile = riscv_profiles[i];
1300 
1301         object_property_add(cpu_obj, profile->name, "bool",
1302                             cpu_get_profile, cpu_set_profile,
1303                             NULL, (void *)profile);
1304 
1305         /*
1306          * CPUs might enable a profile right from the start.
1307          * Enable its mandatory extensions right away in this
1308          * case.
1309          */
1310         if (profile->enabled) {
1311             object_property_set_bool(cpu_obj, profile->name, true, NULL);
1312         }
1313     }
1314 }
1315 
1316 static bool cpu_ext_is_deprecated(const char *ext_name)
1317 {
1318     return isupper(ext_name[0]);
1319 }
1320 
1321 /*
1322  * String will be allocated in the heap. Caller is responsible
1323  * for freeing it.
1324  */
1325 static char *cpu_ext_to_lower(const char *ext_name)
1326 {
1327     char *ret = g_malloc0(strlen(ext_name) + 1);
1328 
1329     strcpy(ret, ext_name);
1330     ret[0] = tolower(ret[0]);
1331 
1332     return ret;
1333 }
1334 
1335 static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
1336                                   void *opaque, Error **errp)
1337 {
1338     const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
1339     RISCVCPU *cpu = RISCV_CPU(obj);
1340     bool vendor_cpu = riscv_cpu_is_vendor(obj);
1341     bool prev_val, value;
1342 
1343     if (!visit_type_bool(v, name, &value, errp)) {
1344         return;
1345     }
1346 
1347     if (cpu_ext_is_deprecated(multi_ext_cfg->name)) {
1348         g_autofree char *lower = cpu_ext_to_lower(multi_ext_cfg->name);
1349 
1350         warn_report("CPU property '%s' is deprecated. Please use '%s' instead",
1351                     multi_ext_cfg->name, lower);
1352     }
1353 
1354     cpu_cfg_ext_add_user_opt(multi_ext_cfg->offset, value);
1355 
1356     prev_val = isa_ext_is_enabled(cpu, multi_ext_cfg->offset);
1357 
1358     if (value == prev_val) {
1359         return;
1360     }
1361 
1362     if (value && vendor_cpu) {
1363         g_autofree char *cpuname = riscv_cpu_get_name(cpu);
1364         error_setg(errp, "'%s' CPU does not allow enabling extensions",
1365                    cpuname);
1366         return;
1367     }
1368 
1369     if (value) {
1370         cpu_bump_multi_ext_priv_ver(&cpu->env, multi_ext_cfg->offset);
1371     }
1372 
1373     isa_ext_update_enabled(cpu, multi_ext_cfg->offset, value);
1374 }
1375 
1376 static void cpu_get_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
1377                                   void *opaque, Error **errp)
1378 {
1379     const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
1380     bool value = isa_ext_is_enabled(RISCV_CPU(obj), multi_ext_cfg->offset);
1381 
1382     visit_type_bool(v, name, &value, errp);
1383 }
1384 
1385 static void cpu_add_multi_ext_prop(Object *cpu_obj,
1386                                    const RISCVCPUMultiExtConfig *multi_cfg)
1387 {
1388     bool generic_cpu = riscv_cpu_is_generic(cpu_obj);
1389     bool deprecated_ext = cpu_ext_is_deprecated(multi_cfg->name);
1390 
1391     object_property_add(cpu_obj, multi_cfg->name, "bool",
1392                         cpu_get_multi_ext_cfg,
1393                         cpu_set_multi_ext_cfg,
1394                         NULL, (void *)multi_cfg);
1395 
1396     if (!generic_cpu || deprecated_ext) {
1397         return;
1398     }
1399 
1400     /*
1401      * Set def val directly instead of using
1402      * object_property_set_bool() to save the set()
1403      * callback hash for user inputs.
1404      */
1405     isa_ext_update_enabled(RISCV_CPU(cpu_obj), multi_cfg->offset,
1406                            multi_cfg->enabled);
1407 }
1408 
1409 static void riscv_cpu_add_multiext_prop_array(Object *obj,
1410                                         const RISCVCPUMultiExtConfig *array)
1411 {
1412     const RISCVCPUMultiExtConfig *prop;
1413 
1414     g_assert(array);
1415 
1416     for (prop = array; prop && prop->name; prop++) {
1417         cpu_add_multi_ext_prop(obj, prop);
1418     }
1419 }
1420 
1421 /*
1422  * Add CPU properties with user-facing flags.
1423  *
1424  * This will overwrite existing env->misa_ext values with the
1425  * defaults set via riscv_cpu_add_misa_properties().
1426  */
1427 static void riscv_cpu_add_user_properties(Object *obj)
1428 {
1429 #ifndef CONFIG_USER_ONLY
1430     riscv_add_satp_mode_properties(obj);
1431 #endif
1432 
1433     riscv_cpu_add_misa_properties(obj);
1434 
1435     riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_extensions);
1436     riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_vendor_exts);
1437     riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_experimental_exts);
1438 
1439     riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_deprecated_exts);
1440 
1441     riscv_cpu_add_profiles(obj);
1442 }
1443 
1444 /*
1445  * The 'max' type CPU will have all possible ratified
1446  * non-vendor extensions enabled.
1447  */
1448 static void riscv_init_max_cpu_extensions(Object *obj)
1449 {
1450     RISCVCPU *cpu = RISCV_CPU(obj);
1451     CPURISCVState *env = &cpu->env;
1452     const RISCVCPUMultiExtConfig *prop;
1453 
1454     /* Enable RVG and RVV that are disabled by default */
1455     riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVV);
1456 
1457     for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
1458         isa_ext_update_enabled(cpu, prop->offset, true);
1459     }
1460 
1461     /*
1462      * Some extensions can't be added without backward compatibilty concerns.
1463      * Disable those, the user can still opt in to them on the command line.
1464      */
1465     cpu->cfg.ext_svade = false;
1466 
1467     /* set vector version */
1468     env->vext_ver = VEXT_VERSION_1_00_0;
1469 
1470     /* Zfinx is not compatible with F. Disable it */
1471     isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zfinx), false);
1472     isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zdinx), false);
1473     isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinx), false);
1474     isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinxmin), false);
1475 
1476     isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zce), false);
1477     isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmp), false);
1478     isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmt), false);
1479 
1480     if (env->misa_mxl != MXL_RV32) {
1481         isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcf), false);
1482     }
1483 
1484     /*
1485      * TODO: ext_smrnmi requires OpenSBI changes that our current
1486      * image does not have. Disable it for now.
1487      */
1488     if (cpu->cfg.ext_smrnmi) {
1489         isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_smrnmi), false);
1490     }
1491 
1492     /*
1493      * TODO: ext_smdbltrp requires the firmware to clear MSTATUS.MDT on startup
1494      * to avoid generating a double trap. OpenSBI does not currently support it,
1495      * disable it for now.
1496      */
1497     if (cpu->cfg.ext_smdbltrp) {
1498         isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_smdbltrp), false);
1499     }
1500 }
1501 
1502 static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
1503 {
1504     return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
1505 }
1506 
1507 static void riscv_tcg_cpu_instance_init(CPUState *cs)
1508 {
1509     RISCVCPU *cpu = RISCV_CPU(cs);
1510     Object *obj = OBJECT(cpu);
1511 
1512     misa_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
1513     multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
1514 
1515     if (!misa_ext_implied_rules) {
1516         misa_ext_implied_rules = g_hash_table_new(NULL, g_direct_equal);
1517     }
1518 
1519     if (!multi_ext_implied_rules) {
1520         multi_ext_implied_rules = g_hash_table_new(NULL, g_direct_equal);
1521     }
1522 
1523     riscv_cpu_add_user_properties(obj);
1524 
1525     if (riscv_cpu_has_max_extensions(obj)) {
1526         riscv_init_max_cpu_extensions(obj);
1527     }
1528 }
1529 
1530 static void riscv_tcg_cpu_accel_class_init(ObjectClass *oc, const void *data)
1531 {
1532     AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
1533 
1534     acc->cpu_instance_init = riscv_tcg_cpu_instance_init;
1535     acc->cpu_target_realize = riscv_tcg_cpu_realize;
1536 }
1537 
1538 static const TypeInfo riscv_tcg_cpu_accel_type_info = {
1539     .name = ACCEL_CPU_NAME("tcg"),
1540 
1541     .parent = TYPE_ACCEL_CPU,
1542     .class_init = riscv_tcg_cpu_accel_class_init,
1543     .abstract = true,
1544 };
1545 
1546 static void riscv_tcg_cpu_accel_register_types(void)
1547 {
1548     type_register_static(&riscv_tcg_cpu_accel_type_info);
1549 }
1550 type_init(riscv_tcg_cpu_accel_register_types);
1551