On Mon, 14 Sept 2026 at 20:25, Gilles Grimaud
<[email protected]> wrote:
>
> The Armv6-M Unprivileged/Privileged Extension is optional. Cortex-M0 does
> not implement it, while Cortex-M0+ may implement it. The RP2040 Cortex-M0+
> configuration provides the extension.
>
> Add an ARM feature bit and a cortex-m0plus CPU type that enables it. Permit
> privileged writes to CONTROL.nPRIV when either the Main Extension or the
> optional privilege extension is present.
>
> Update the microbit Cortex-M0 test to verify that writes to nPRIV are
> ignored.
>
> Signed-off-by: Gilles Grimaud <[email protected]>
> ---
>  target/arm/cpu.h                           |  1 +
>  target/arm/tcg/cpu-v7m.c                   | 11 ++++
>  target/arm/tcg/m_helper.c                  |  4 +-
>  tests/tcg/arm/system/meson.build           |  6 ++
>  tests/tcg/arm/system/test-armv6m-control.S | 66 ++++++++++++++++++++++
>  5 files changed, 87 insertions(+), 1 deletion(-)
>  create mode 100644 tests/tcg/arm/system/test-armv6m-control.S
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index e3f931dba2..66606b3444 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -2168,6 +2168,7 @@ enum arm_features {
>      ARM_FEATURE_VBAR, /* has cp15 VBAR */
>      ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
>      ARM_FEATURE_M_MAIN, /* M profile Main Extension */
> +    ARM_FEATURE_M_UNPRIV, /* M profile Unprivileged/Privileged Extension */
>      ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
>      /*
>       * ARM_FEATURE_BACKCOMPAT_CNTFRQ makes the CPU default cntfrq be 62.5MHz
> diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
> index 48b31d5eac..ac99c93ec3 100644
> --- a/target/arm/tcg/cpu-v7m.c
> +++ b/target/arm/tcg/cpu-v7m.c
> @@ -76,6 +76,15 @@ static void cortex_m0_initfn(Object *obj)
>      SET_IDREG(isar, ID_ISAR6, 0x00000000);
>  }
>
> +static void cortex_m0plus_initfn(Object *obj)
> +{
> +    ARMCPU *cpu = ARM_CPU(obj);
> +
> +    cortex_m0_initfn(obj);
> +    set_feature(&cpu->env, ARM_FEATURE_M_UNPRIV);
> +    cpu->midr = 0x410cc601;
> +}

This patch should only add the feature; it shouldn't add the M0+
CPU type as well.

> diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c
> index 33c9e7c55b..f8461a4d66 100644
> --- a/target/arm/tcg/m_helper.c
> +++ b/target/arm/tcg/m_helper.c
> @@ -2775,7 +2775,9 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t 
> maskreg, uint32_t val)
>                             !arm_v7m_is_handler_mode(env))) {
>              write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 
> 0);
>          }
> -        if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
> +        if (cur_el > 0 &&
> +            (arm_feature(env, ARM_FEATURE_M_MAIN) ||
> +             arm_feature(env, ARM_FEATURE_M_UNPRIV))) {

We should make ARM_FEATURE_M_MAIN imply ARM_FEATURE_M_UNPRIV
(in arm_cpu_propagate_feature_implications()) so here we only
need to test ARM_FEATURE_M_MAIN.

>              env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
>              env->v7m.control[env->v7m.secure] |= val & 
> R_V7M_CONTROL_NPRIV_MASK;
>          }

thanks
-- PMM

Reply via email to