diff mbox series

[for-8.1,v4,11/25] target/riscv/cpu.c: set cpu config in set_misa()

Message ID 20230322222004.357013-12-dbarboza@ventanamicro.com (mailing list archive)
State New, archived
Headers show
Series target/riscv: rework CPU extensions validation | expand

Commit Message

Daniel Henrique Barboza March 22, 2023, 10:19 p.m. UTC
set_misa() is setting all 'misa' related env states and nothing else.
But other functions, namely riscv_cpu_validate_set_extensions(), uses
the config object to do its job.

This creates a need to set the single letter extensions in the cfg
object to keep both in sync. At this moment this is being done by
register_cpu_props(), forcing every CPU to do a call to this function.

Let's beef up set_misa() and make the function do the sync for us. This
will relieve named CPUs to having to call register_cpu_props(), which
will then be redesigned to a more specialized role next.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 43 ++++++++++++++++++++++++++++++++-----------
 target/riscv/cpu.h |  4 ++--
 2 files changed, 34 insertions(+), 13 deletions(-)

Comments

LIU Zhiwei March 23, 2023, 2:14 a.m. UTC | #1
On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
> set_misa() is setting all 'misa' related env states and nothing else.
> But other functions, namely riscv_cpu_validate_set_extensions(), uses
> the config object to do its job.
>
> This creates a need to set the single letter extensions in the cfg
> object to keep both in sync. At this moment this is being done by
> register_cpu_props(), forcing every CPU to do a call to this function.
>
> Let's beef up set_misa() and make the function do the sync for us. This
> will relieve named CPUs to having to call register_cpu_props(), which
> will then be redesigned to a more specialized role next.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 43 ++++++++++++++++++++++++++++++++-----------
>   target/riscv/cpu.h |  4 ++--
>   2 files changed, 34 insertions(+), 13 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 36c55abda0..df5c0bda70 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -236,8 +236,40 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
>   
>   static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
>   {
> +    RISCVCPU *cpu;
> +
>       env->misa_mxl_max = env->misa_mxl = mxl;
>       env->misa_ext_mask = env->misa_ext = ext;
> +
> +    /*
> +     * ext = 0 will only be a thing during cpu_init() functions
> +     * as a way of setting an extension-agnostic CPU. We do
> +     * not support clearing misa_ext* and the ext_N flags in
> +     * RISCVCPUConfig in regular circunstances.
> +     */
> +    if (ext == 0) {
> +        return;
> +    }
> +
> +    /*
> +     * We can't use riscv_cpu_cfg() in this case because it is
> +     * a read-only inline and we're going to change the values
> +     * of cpu->cfg.
> +     */
> +    cpu = env_archcpu(env);
> +
> +    cpu->cfg.ext_i = ext & RVI;
> +    cpu->cfg.ext_e = ext & RVE;
> +    cpu->cfg.ext_m = ext & RVM;
> +    cpu->cfg.ext_a = ext & RVA;
> +    cpu->cfg.ext_f = ext & RVF;
> +    cpu->cfg.ext_d = ext & RVD;
> +    cpu->cfg.ext_v = ext & RVV;
> +    cpu->cfg.ext_c = ext & RVC;
> +    cpu->cfg.ext_s = ext & RVS;
> +    cpu->cfg.ext_u = ext & RVU;
> +    cpu->cfg.ext_h = ext & RVH;
> +    cpu->cfg.ext_j = ext & RVJ;
>   }
>   
>   #ifndef CONFIG_USER_ONLY
> @@ -340,7 +372,6 @@ static void riscv_any_cpu_init(Object *obj)
>   #endif
>   
>       env->priv_ver = PRIV_VERSION_LATEST;
> -    register_cpu_props(obj);

This patch will break the original logic. We can only can a empty CPU here.

>   
>       /* inherited from parent obj via riscv_cpu_init() */
>       cpu->cfg.ext_ifencei = true;
> @@ -368,7 +399,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>       CPURISCVState *env = &cpu->env;
>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
> @@ -387,7 +417,6 @@ static void rv64_sifive_e_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
> @@ -408,9 +437,6 @@ static void rv64_thead_c906_cpu_init(Object *obj)
>       env->priv_ver = PRIV_VERSION_1_11_0;
>   
>       cpu->cfg.ext_g = true;
> -    cpu->cfg.ext_c = true;
> -    cpu->cfg.ext_u = true;
> -    cpu->cfg.ext_s = true;

Why specially for these configurations?

Zhiwei

>       cpu->cfg.ext_icsr = true;
>       cpu->cfg.ext_zfh = true;
>       cpu->cfg.mmu = true;
> @@ -472,8 +498,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>       CPURISCVState *env = &cpu->env;
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> -
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
> @@ -492,7 +516,6 @@ static void rv32_sifive_e_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
> @@ -510,7 +533,6 @@ static void rv32_ibex_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
>       set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_11_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
> @@ -529,7 +551,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 76f81c6b68..ebe0fff668 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -66,8 +66,8 @@
>   #define RV(x) ((target_ulong)1 << (x - 'A'))
>   
>   /*
> - * Consider updating register_cpu_props() when adding
> - * new MISA bits here.
> + * Consider updating set_misa() when adding new
> + * MISA bits here.
>    */
>   #define RVI RV('I')
>   #define RVE RV('E') /* E and I are mutually exclusive */
LIU Zhiwei March 23, 2023, 2:18 a.m. UTC | #2
On 2023/3/23 10:14, LIU Zhiwei wrote:
>
> On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
>> set_misa() is setting all 'misa' related env states and nothing else.
>> But other functions, namely riscv_cpu_validate_set_extensions(), uses
>> the config object to do its job.
>>
>> This creates a need to set the single letter extensions in the cfg
>> object to keep both in sync. At this moment this is being done by
>> register_cpu_props(), forcing every CPU to do a call to this function.
>>
>> Let's beef up set_misa() and make the function do the sync for us. This
>> will relieve named CPUs to having to call register_cpu_props(), which
>> will then be redesigned to a more specialized role next.
>>
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>>   target/riscv/cpu.c | 43 ++++++++++++++++++++++++++++++++-----------
>>   target/riscv/cpu.h |  4 ++--
>>   2 files changed, 34 insertions(+), 13 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 36c55abda0..df5c0bda70 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -236,8 +236,40 @@ const char *riscv_cpu_get_trap_name(target_ulong 
>> cause, bool async)
>>     static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
>>   {
>> +    RISCVCPU *cpu;
>> +
>>       env->misa_mxl_max = env->misa_mxl = mxl;
>>       env->misa_ext_mask = env->misa_ext = ext;
>> +
>> +    /*
>> +     * ext = 0 will only be a thing during cpu_init() functions
>> +     * as a way of setting an extension-agnostic CPU. We do
>> +     * not support clearing misa_ext* and the ext_N flags in
>> +     * RISCVCPUConfig in regular circunstances.
>> +     */
>> +    if (ext == 0) {
>> +        return;
>> +    }
>> +
>> +    /*
>> +     * We can't use riscv_cpu_cfg() in this case because it is
>> +     * a read-only inline and we're going to change the values
>> +     * of cpu->cfg.
>> +     */
>> +    cpu = env_archcpu(env);
>> +
>> +    cpu->cfg.ext_i = ext & RVI;
>> +    cpu->cfg.ext_e = ext & RVE;
>> +    cpu->cfg.ext_m = ext & RVM;
>> +    cpu->cfg.ext_a = ext & RVA;
>> +    cpu->cfg.ext_f = ext & RVF;
>> +    cpu->cfg.ext_d = ext & RVD;
>> +    cpu->cfg.ext_v = ext & RVV;
>> +    cpu->cfg.ext_c = ext & RVC;
>> +    cpu->cfg.ext_s = ext & RVS;
>> +    cpu->cfg.ext_u = ext & RVU;
>> +    cpu->cfg.ext_h = ext & RVH;
>> +    cpu->cfg.ext_j = ext & RVJ;
>>   }
>>     #ifndef CONFIG_USER_ONLY
>> @@ -340,7 +372,6 @@ static void riscv_any_cpu_init(Object *obj)
>>   #endif
>>         env->priv_ver = PRIV_VERSION_LATEST;
>> -    register_cpu_props(obj);
>
> This patch will break the original logic. We can only can a empty CPU 
> here.

Oops. I mistook it as a general cpu. Just ignore this comment.

Zhiwei

>
>>         /* inherited from parent obj via riscv_cpu_init() */
>>       cpu->cfg.ext_ifencei = true;
>> @@ -368,7 +399,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       CPURISCVState *env = &cpu->env;
>>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS 
>> | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
>> @@ -387,7 +417,6 @@ static void rv64_sifive_e_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>         set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -408,9 +437,6 @@ static void rv64_thead_c906_cpu_init(Object *obj)
>>       env->priv_ver = PRIV_VERSION_1_11_0;
>>         cpu->cfg.ext_g = true;
>> -    cpu->cfg.ext_c = true;
>> -    cpu->cfg.ext_u = true;
>> -    cpu->cfg.ext_s = true;
>
> Why specially for these configurations?
>
> Zhiwei
>
>>       cpu->cfg.ext_icsr = true;
>>       cpu->cfg.ext_zfh = true;
>>       cpu->cfg.mmu = true;
>> @@ -472,8 +498,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       CPURISCVState *env = &cpu->env;
>>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS 
>> | RVU);
>> -
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
>> @@ -492,7 +516,6 @@ static void rv32_sifive_e_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>         set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -510,7 +533,6 @@ static void rv32_ibex_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>         set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_11_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -529,7 +551,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>         set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> index 76f81c6b68..ebe0fff668 100644
>> --- a/target/riscv/cpu.h
>> +++ b/target/riscv/cpu.h
>> @@ -66,8 +66,8 @@
>>   #define RV(x) ((target_ulong)1 << (x - 'A'))
>>     /*
>> - * Consider updating register_cpu_props() when adding
>> - * new MISA bits here.
>> + * Consider updating set_misa() when adding new
>> + * MISA bits here.
>>    */
>>   #define RVI RV('I')
>>   #define RVE RV('E') /* E and I are mutually exclusive */
Daniel Henrique Barboza March 23, 2023, 11:23 p.m. UTC | #3
On 3/22/23 23:14, LIU Zhiwei wrote:
> 
> On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
>> set_misa() is setting all 'misa' related env states and nothing else.
>> But other functions, namely riscv_cpu_validate_set_extensions(), uses
>> the config object to do its job.
>>
>> This creates a need to set the single letter extensions in the cfg
>> object to keep both in sync. At this moment this is being done by
>> register_cpu_props(), forcing every CPU to do a call to this function.
>>
>> Let's beef up set_misa() and make the function do the sync for us. This
>> will relieve named CPUs to having to call register_cpu_props(), which
>> will then be redesigned to a more specialized role next.
>>
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>>   target/riscv/cpu.c | 43 ++++++++++++++++++++++++++++++++-----------
>>   target/riscv/cpu.h |  4 ++--
>>   2 files changed, 34 insertions(+), 13 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 36c55abda0..df5c0bda70 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -236,8 +236,40 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
>>   static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
>>   {
>> +    RISCVCPU *cpu;
>> +
>>       env->misa_mxl_max = env->misa_mxl = mxl;
>>       env->misa_ext_mask = env->misa_ext = ext;
>> +
>> +    /*
>> +     * ext = 0 will only be a thing during cpu_init() functions
>> +     * as a way of setting an extension-agnostic CPU. We do
>> +     * not support clearing misa_ext* and the ext_N flags in
>> +     * RISCVCPUConfig in regular circunstances.
>> +     */
>> +    if (ext == 0) {
>> +        return;
>> +    }
>> +
>> +    /*
>> +     * We can't use riscv_cpu_cfg() in this case because it is
>> +     * a read-only inline and we're going to change the values
>> +     * of cpu->cfg.
>> +     */
>> +    cpu = env_archcpu(env);
>> +
>> +    cpu->cfg.ext_i = ext & RVI;
>> +    cpu->cfg.ext_e = ext & RVE;
>> +    cpu->cfg.ext_m = ext & RVM;
>> +    cpu->cfg.ext_a = ext & RVA;
>> +    cpu->cfg.ext_f = ext & RVF;
>> +    cpu->cfg.ext_d = ext & RVD;
>> +    cpu->cfg.ext_v = ext & RVV;
>> +    cpu->cfg.ext_c = ext & RVC;
>> +    cpu->cfg.ext_s = ext & RVS;
>> +    cpu->cfg.ext_u = ext & RVU;
>> +    cpu->cfg.ext_h = ext & RVH;
>> +    cpu->cfg.ext_j = ext & RVJ;
>>   }
>>   #ifndef CONFIG_USER_ONLY
>> @@ -340,7 +372,6 @@ static void riscv_any_cpu_init(Object *obj)
>>   #endif
>>       env->priv_ver = PRIV_VERSION_LATEST;
>> -    register_cpu_props(obj);
> 
> This patch will break the original logic. We can only can a empty CPU here.
> 
>>       /* inherited from parent obj via riscv_cpu_init() */
>>       cpu->cfg.ext_ifencei = true;
>> @@ -368,7 +399,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       CPURISCVState *env = &cpu->env;
>>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
>> @@ -387,7 +417,6 @@ static void rv64_sifive_e_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -408,9 +437,6 @@ static void rv64_thead_c906_cpu_init(Object *obj)
>>       env->priv_ver = PRIV_VERSION_1_11_0;
>>       cpu->cfg.ext_g = true;
>> -    cpu->cfg.ext_c = true;
>> -    cpu->cfg.ext_u = true;
>> -    cpu->cfg.ext_s = true;
> 
> Why specially for these configurations?

Because there is a set_misa() call right before:

set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);

And since set_misa() is now syncing with cpu->cfg these are unneeded. There
are no other cases like that in other cpu_init() functions. I'll make sure to
mention this in the commit message in the next version.

Patch 14 is going to do the same thing for ext_g in this same function.


Thanks,

Daniel

> 
> Zhiwei
> 
>>       cpu->cfg.ext_icsr = true;
>>       cpu->cfg.ext_zfh = true;
>>       cpu->cfg.mmu = true;
>> @@ -472,8 +498,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       CPURISCVState *env = &cpu->env;
>>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>> -
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
>> @@ -492,7 +516,6 @@ static void rv32_sifive_e_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -510,7 +533,6 @@ static void rv32_ibex_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_11_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -529,7 +551,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> index 76f81c6b68..ebe0fff668 100644
>> --- a/target/riscv/cpu.h
>> +++ b/target/riscv/cpu.h
>> @@ -66,8 +66,8 @@
>>   #define RV(x) ((target_ulong)1 << (x - 'A'))
>>   /*
>> - * Consider updating register_cpu_props() when adding
>> - * new MISA bits here.
>> + * Consider updating set_misa() when adding new
>> + * MISA bits here.
>>    */
>>   #define RVI RV('I')
>>   #define RVE RV('E') /* E and I are mutually exclusive */
diff mbox series

Patch

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 36c55abda0..df5c0bda70 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -236,8 +236,40 @@  const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
 
 static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
 {
+    RISCVCPU *cpu;
+
     env->misa_mxl_max = env->misa_mxl = mxl;
     env->misa_ext_mask = env->misa_ext = ext;
+
+    /*
+     * ext = 0 will only be a thing during cpu_init() functions
+     * as a way of setting an extension-agnostic CPU. We do
+     * not support clearing misa_ext* and the ext_N flags in
+     * RISCVCPUConfig in regular circunstances.
+     */
+    if (ext == 0) {
+        return;
+    }
+
+    /*
+     * We can't use riscv_cpu_cfg() in this case because it is
+     * a read-only inline and we're going to change the values
+     * of cpu->cfg.
+     */
+    cpu = env_archcpu(env);
+
+    cpu->cfg.ext_i = ext & RVI;
+    cpu->cfg.ext_e = ext & RVE;
+    cpu->cfg.ext_m = ext & RVM;
+    cpu->cfg.ext_a = ext & RVA;
+    cpu->cfg.ext_f = ext & RVF;
+    cpu->cfg.ext_d = ext & RVD;
+    cpu->cfg.ext_v = ext & RVV;
+    cpu->cfg.ext_c = ext & RVC;
+    cpu->cfg.ext_s = ext & RVS;
+    cpu->cfg.ext_u = ext & RVU;
+    cpu->cfg.ext_h = ext & RVH;
+    cpu->cfg.ext_j = ext & RVJ;
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -340,7 +372,6 @@  static void riscv_any_cpu_init(Object *obj)
 #endif
 
     env->priv_ver = PRIV_VERSION_LATEST;
-    register_cpu_props(obj);
 
     /* inherited from parent obj via riscv_cpu_init() */
     cpu->cfg.ext_ifencei = true;
@@ -368,7 +399,6 @@  static void rv64_sifive_u_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
     CPURISCVState *env = &cpu->env;
     set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
@@ -387,7 +417,6 @@  static void rv64_sifive_e_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -408,9 +437,6 @@  static void rv64_thead_c906_cpu_init(Object *obj)
     env->priv_ver = PRIV_VERSION_1_11_0;
 
     cpu->cfg.ext_g = true;
-    cpu->cfg.ext_c = true;
-    cpu->cfg.ext_u = true;
-    cpu->cfg.ext_s = true;
     cpu->cfg.ext_icsr = true;
     cpu->cfg.ext_zfh = true;
     cpu->cfg.mmu = true;
@@ -472,8 +498,6 @@  static void rv32_sifive_u_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
     CPURISCVState *env = &cpu->env;
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
@@ -492,7 +516,6 @@  static void rv32_sifive_e_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -510,7 +533,6 @@  static void rv32_ibex_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_11_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -529,7 +551,6 @@  static void rv32_imafcu_nommu_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 76f81c6b68..ebe0fff668 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -66,8 +66,8 @@ 
 #define RV(x) ((target_ulong)1 << (x - 'A'))
 
 /*
- * Consider updating register_cpu_props() when adding
- * new MISA bits here.
+ * Consider updating set_misa() when adding new
+ * MISA bits here.
  */
 #define RVI RV('I')
 #define RVE RV('E') /* E and I are mutually exclusive */