diff options
Diffstat (limited to 'target/riscv/cpu.c')
-rw-r--r-- | target/riscv/cpu.c | 91 |
1 files changed, 64 insertions, 27 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index ccacdee215..a91253d4bd 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -37,7 +37,7 @@ #define RISCV_CPU_MARCHID ((QEMU_VERSION_MAJOR << 16) | \ (QEMU_VERSION_MINOR << 8) | \ (QEMU_VERSION_MICRO)) -#define RISCV_CPU_MIPID RISCV_CPU_MARCHID +#define RISCV_CPU_MIMPID RISCV_CPU_MARCHID static const char riscv_single_letter_exts[] = "IEMAFDQCPVH"; @@ -406,6 +406,7 @@ void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb, } else { env->pc = data[0]; } + env->bins = data[1]; } static void riscv_cpu_reset(DeviceState *dev) @@ -445,6 +446,7 @@ static void riscv_cpu_reset(DeviceState *dev) env->mcause = 0; env->miclaim = MIP_SGEIP; env->pc = env->resetvec; + env->bins = 0; env->two_stage_lookup = false; /* Initialized default priorities of local interrupts. */ @@ -584,6 +586,20 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) uint32_t ext = 0; /* Do some ISA extension error checking */ + if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m && + cpu->cfg.ext_a && cpu->cfg.ext_f && + cpu->cfg.ext_d && + cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) { + warn_report("Setting G will also set IMAFD_Zicsr_Zifencei"); + cpu->cfg.ext_i = true; + cpu->cfg.ext_m = true; + cpu->cfg.ext_a = true; + cpu->cfg.ext_f = true; + cpu->cfg.ext_d = true; + cpu->cfg.ext_icsr = true; + cpu->cfg.ext_ifencei = true; + } + if (cpu->cfg.ext_i && cpu->cfg.ext_e) { error_setg(errp, "I and E extensions are incompatible"); @@ -596,22 +612,49 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } - if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & - cpu->cfg.ext_a & cpu->cfg.ext_f & - cpu->cfg.ext_d)) { - warn_report("Setting G will also set IMAFD"); - cpu->cfg.ext_i = true; - cpu->cfg.ext_m = true; - cpu->cfg.ext_a = true; - cpu->cfg.ext_f = true; - cpu->cfg.ext_d = true; + if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) { + error_setg(errp, "F extension requires Zicsr"); + return; + } + + if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) { + error_setg(errp, "Zfh/Zfhmin extensions require F extension"); + return; + } + + if (cpu->cfg.ext_d && !cpu->cfg.ext_f) { + error_setg(errp, "D extension requires F extension"); + return; + } + + if (cpu->cfg.ext_v && !cpu->cfg.ext_d) { + error_setg(errp, "V extension requires D extension"); + return; } + if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) { + error_setg(errp, "Zve32f/Zve64f extensions require F extension"); + return; + } + + /* Set the ISA extensions, checks should have happened above */ if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx || cpu->cfg.ext_zhinxmin) { cpu->cfg.ext_zfinx = true; } + if (cpu->cfg.ext_zfinx) { + if (!cpu->cfg.ext_icsr) { + error_setg(errp, "Zfinx extension requires Zicsr"); + return; + } + if (cpu->cfg.ext_f) { + error_setg(errp, + "Zfinx cannot be supported together with F extension"); + return; + } + } + if (cpu->cfg.ext_zk) { cpu->cfg.ext_zkn = true; cpu->cfg.ext_zkr = true; @@ -635,7 +678,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) cpu->cfg.ext_zksh = true; } - /* Set the ISA extensions, checks should have happened above */ if (cpu->cfg.ext_i) { ext |= RVI; } @@ -706,20 +748,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } set_vext_version(env, vext_version); } - if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) { - error_setg(errp, "Zve32f/Zve64f extension depends upon RVF."); - return; - } if (cpu->cfg.ext_j) { ext |= RVJ; } - if (cpu->cfg.ext_zfinx && ((ext & (RVF | RVD)) || cpu->cfg.ext_zfh || - cpu->cfg.ext_zfhmin)) { - error_setg(errp, - "'Zfinx' cannot be supported together with 'F', 'D', 'Zfh'," - " 'Zfhmin'"); - return; - } set_misa(env, env->misa_mxl, ext); } @@ -812,7 +843,7 @@ static Property riscv_cpu_properties[] = { /* Defaults for standard extensions */ DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true), DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false), - DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, true), + DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, false), DEFINE_PROP_BOOL("m", RISCVCPU, cfg.ext_m, true), DEFINE_PROP_BOOL("a", RISCVCPU, cfg.ext_a, true), DEFINE_PROP_BOOL("f", RISCVCPU, cfg.ext_f, true), @@ -840,7 +871,7 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_UINT32("mvendorid", RISCVCPU, cfg.mvendorid, 0), DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, RISCV_CPU_MARCHID), - DEFINE_PROP_UINT64("mipid", RISCVCPU, cfg.mipid, RISCV_CPU_MIPID), + DEFINE_PROP_UINT64("mimpid", RISCVCPU, cfg.mimpid, RISCV_CPU_MIMPID), DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false), DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false), @@ -879,6 +910,8 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false), DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC), + + DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false), DEFINE_PROP_END_OF_LIST(), }; @@ -996,11 +1029,11 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len) * extensions by an underscore. */ struct isa_ext_data isa_edata_arr[] = { + ISA_EDATA_ENTRY(zicsr, ext_icsr), + ISA_EDATA_ENTRY(zifencei, ext_ifencei), ISA_EDATA_ENTRY(zfh, ext_zfh), ISA_EDATA_ENTRY(zfhmin, ext_zfhmin), ISA_EDATA_ENTRY(zfinx, ext_zfinx), - ISA_EDATA_ENTRY(zhinx, ext_zhinx), - ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin), ISA_EDATA_ENTRY(zdinx, ext_zdinx), ISA_EDATA_ENTRY(zba, ext_zba), ISA_EDATA_ENTRY(zbb, ext_zbb), @@ -1021,6 +1054,8 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len) ISA_EDATA_ENTRY(zkt, ext_zkt), ISA_EDATA_ENTRY(zve32f, ext_zve32f), ISA_EDATA_ENTRY(zve64f, ext_zve64f), + ISA_EDATA_ENTRY(zhinx, ext_zhinx), + ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin), ISA_EDATA_ENTRY(svinval, ext_svinval), ISA_EDATA_ENTRY(svnapot, ext_svnapot), ISA_EDATA_ENTRY(svpbmt, ext_svpbmt), @@ -1049,7 +1084,9 @@ char *riscv_isa_string(RISCVCPU *cpu) } } *p = '\0'; - riscv_isa_string_ext(cpu, &isa_str, maxlen); + if (!cpu->cfg.short_isa_string) { + riscv_isa_string_ext(cpu, &isa_str, maxlen); + } return isa_str; } |