Hi Peter,

>On Tue, 22 Oct 2024 at 21:34, Matthieu Castet <castet.matth...@free.fr> wrote:
>>
>> Signed-off-by: Matthieu Castet<castet.matth...@free.fr>
>
>Hi; thanks for this patch. I have some initial code review comments,
>but the change looks broadly correct to me and I don't think
>there's anything obvious missing.
>
>The commit message body here is empty. Commits should
>almost always have some description in the body of
>what they are doing and why.

Thanks for the review. When I sent the patch, I didn't put my
last version and some of your comment were already fixed.
Sorry for that.

>
>(You don't need a separate cover-letter email for
>single-patch patches, by the way -- only for multi-patch series.)
>

ok

>> ---
>>  hw/intc/armv7m_nvic.c    | 38 +++++++++++++++++++++++++++++++++-----
>>  target/arm/cpu.c         |  4 ++--
>>  target/arm/ptw.c         | 23 +++++++++++++++++++----
>>  target/arm/tcg/cpu-v7m.c | 21 ++++++++++++++++++++-
>>  4 files changed, 74 insertions(+), 12 deletions(-)
>>
>> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
>> index 98f3cf59bc..ed084e9db3 100644
>> --- a/hw/intc/armv7m_nvic.c
>> +++ b/hw/intc/armv7m_nvic.c
>> @@ -1386,7 +1386,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t 
>> offset, MemTxAttrs attrs)
>>          }
>>          return (cpu->env.pmsav7.drbar[region] & ~0x1f) | (region & 0xf);
>>      }
>> -    case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
>> +    case 0xda0: /* MPU_RASR (v6M/v7M), MPU_RLAR (v8M) */
>>      case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
>>      case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
>>      case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
>
>The v6M spec says that it doesn't have the _A* aliases
>for RBAR and RASR so we should have a check to make those
>goto bad_offset in both read and write functions.

ok, I will add the bad_offset to read



>
>> @@ -1876,6 +1876,14 @@ static void nvic_writel(NVICState *s, uint32_t 
>> offset, uint32_t value,
>>              return;
>>          }
>>
>> +        if (!arm_feature(&s->cpu->env, ARM_FEATURE_V7)) {
>> +                if (offset != 0xd9c)
>> +                        goto bad_offset;
>
>Our coding style says all if() statements need braces, even
>one-line ones. The indentation here also seems to be off --
>our indent is four-space.
>

I will fix the code

>> +
>> +                /* do not support size less than 256 */
>> +                value &= ~0xe0;
>
>This line doesn't look like it does what the comment suggests.
>A region size of 256 bytes would be a SIZE field of 7, where
>the size field is bits [5:1]. This &= ~0xe0 will (unless I've
>got confused) zero bits [3:1], which would turn a SIZE of 7
>into an invalid SIZE of 0.

The code is checking region address alignement, not region size.
ADDR is encoded on bits [31:8] on armv6-m and bits [31:5]
on armv7-m.

I will update the comment to 

                /* armv6-m do not support region address with alignement 
                 * less than 256. Force alignement.
                 */


>
>More generally: in QEMU if we're enforcing limits on the
>values a register field can hold we typically do it on the
>guest-write path. Then the read path can just return the
>value in the register, which we already know to be in-range.

Ok



>> -    case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
>> -    case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
>> -    case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
>> -    case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
>> +    case 0xda0: /* MPU_RASR (v6M/v7M), MPU_RLAR (v8M) */
>> +    case 0xda8: /* MPU_RASR_A1 (v6M/v7M), MPU_RLAR_A1 (v8M) */
>> +    case 0xdb0: /* MPU_RASR_A2 (v6M/v7M), MPU_RLAR_A2 (v8M) */
>> +    case 0xdb8: /* MPU_RASR_A3 (v6M/v7M), MPU_RLAR_A3 (v8M) */
>
>v6M doesn't have the RASR_A* aliases, so those lines shouldn't change.

ok


>
>>      {
>>          int region = cpu->env.pmsav7.rnr[attrs.secure];
>> +        int rsize;
>>
>>          if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
>>              /* PMSAv8M handling of the aliases is different from v7M:
>> @@ -1926,6 +1935,25 @@ static void nvic_writel(NVICState *s, uint32_t 
>> offset, uint32_t value,
>>              return;
>>          }
>>
>> +        rsize = extract32(value, 1, 5);
>> +        if (!arm_feature(&s->cpu->env, ARM_FEATURE_V7)) {
>> +            if (offset != 0xda0)
>> +                goto bad_offset;
>> +            /* for armv6-m rsize >= 7 (min 256) */
>> +            if (rsize < 7) {
>> +                qemu_log_mask(LOG_GUEST_ERROR,
>> +                        "MPU region size too small %d\n", rsize);
>> +                return;
>> +            }
>> +        }
>> +
>> +        /* for armv7-m rsize >= 4 (min 32) */
>> +        if (rsize < 4) {
>> +            qemu_log_mask(LOG_GUEST_ERROR,
>> +                    "MPU region size too small %d\n", rsize);
>> +            return;
>> +        }
>
>You don't need to handle and log too-large region
>sizes both in the register-set codepath and then again
>later when we do the address translation. If you're ruling
>them out here then they'll never happen later.

Ok, let's handle it here in the write path.


>
>Duplicating the qemu_log_mask() line is awkward -- maybe
>better to have
>  rsize_min = arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 4 : 7;
>  if (rsize < rsize_min) {
>      qemu_log_mask(...)
>  }
>

Ok, I will do that



>> +
>>          if (region >= cpu->pmsav7_dregion) {
>>              return;
>>          }
>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>> index 1320fd8c8f..875e3aab69 100644
>> --- a/target/arm/cpu.c
>> +++ b/target/arm/cpu.c
>> @@ -508,7 +508,7 @@ static void arm_cpu_reset_hold(Object *obj, ResetType 
>> type)
>>                             sizeof(*env->pmsav8.rlar[M_REG_S])
>>                             * cpu->pmsav7_dregion);
>>                  }
>> -            } else if (arm_feature(env, ARM_FEATURE_V7)) {
>> +            } else if (arm_feature(env, ARM_FEATURE_M)) {
>>                  memset(env->pmsav7.drbar, 0,
>>                         sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
>>                  memset(env->pmsav7.drsr, 0,
>> @@ -2454,7 +2454,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
>> **errp)
>>      }
>>
>>      if (arm_feature(env, ARM_FEATURE_PMSA) &&
>> -        arm_feature(env, ARM_FEATURE_V7)) {
>> +        arm_feature(env, ARM_FEATURE_M)) {
>>          uint32_t nr = cpu->pmsav7_dregion;
>>
>>          if (nr > 0xff) {
>
>These changes don't look correct -- they will break the handling
>of R-profile PMSAv7 CPUs like the Cortex-R5.

You are right, I changed it to : 



@@ -508,7 +508,8 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type)
                            sizeof(*env->pmsav8.rlar[M_REG_S])
                            * cpu->pmsav7_dregion);
                 }
-            } else if (arm_feature(env, ARM_FEATURE_V7)) {
+            } else if (arm_feature(env, ARM_FEATURE_V7) ||
+                       arm_feature(env, ARM_FEATURE_M)) {
                 memset(env->pmsav7.drbar, 0,
                        sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
                 memset(env->pmsav7.drsr, 0,
@@ -2454,7 +2455,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
     }
 
     if (arm_feature(env, ARM_FEATURE_PMSA) &&
-        arm_feature(env, ARM_FEATURE_V7)) {
+        (arm_feature(env, ARM_FEATURE_V7) || arm_feature(env, ARM_FEATURE_M))) 
{
         uint32_t nr = cpu->pmsav7_dregion;
 
         if (nr > 0xff) {


Is that correct ?

>
>> diff --git a/target/arm/ptw.c b/target/arm/ptw.c
>> index dd40268397..fa771907e3 100644
>> --- a/target/arm/ptw.c
>> +++ b/target/arm/ptw.c
>> @@ -2383,6 +2383,13 @@ static bool pmsav7_use_background_region(ARMCPU *cpu, 
>> ARMMMUIdx mmu_idx,
>>      return regime_sctlr(env, mmu_idx) & SCTLR_BR;
>>  }
>>
>> +/* armv6m PMSAv6 is mostly compatible with PMSAv7,
>> + * main difference :
>> + * - min region size is 256 instead of 32
>> + * - TEX can be only 0 (Tex not used by qemu)
>> + * - no alias register
>> + * - HardFault instead of MemManage
>> + */
>
>Our coding style for multiline comments says
>/*
> * they look like this, with the opening and closing markers on
> * lines of their own
> */

I will changed that.

It do not seem to be followed in In hw/intc/armv7m_nvic.c, but my new comment 
should also follow
this rule in this file ?


>
>This comment might be better placed at the point below where
>we call get_phys_addr_psav7(), because it is the explanation
>for why on M-profile we call that function even if we don't
>have PMSAv7.

ok

>
>>  static bool get_phys_addr_pmsav7(CPUARMState *env,
>>                                   S1Translate *ptw,
>>                                   uint32_t address,
>> @@ -2423,11 +2430,19 @@ static bool get_phys_addr_pmsav7(CPUARMState *env,
>>                  continue;
>>              }
>>
>> -            if (!rsize) {
>> +            /* Issue warning for invalid values
>> +             * for armv7-m rsize >= 4 (min 32)
>> +             * for armv6-m rsize >= 7 (min 256)
>> +             */
>> +            if (!rsize ||
>> +                (arm_feature(env, ARM_FEATURE_M) && (
>> +                       rsize < 7 ||
>> +                       (rsize < 4 && !arm_feature(env, ARM_FEATURE_V7))))) {
>>                  qemu_log_mask(LOG_GUEST_ERROR,
>> -                              "DRSR[%d]: Rsize field cannot be 0\n", n);
>> +                              "DRSR[%d]: Rsize field cannot be %d\n", n, 
>> rsize);
>>                  continue;
>>              }
>> +
>>              rsize++;
>>              rmask = (1ull << rsize) - 1;

I will remove this modification. Size check is done in write.


>>
>> @@ -3515,8 +3530,8 @@ static bool get_phys_addr_nogpc(CPUARMState *env, 
>> S1Translate *ptw,
>>              /* PMSAv8 */
>>              ret = get_phys_addr_pmsav8(env, ptw, address, access_type,
>>                                         result, fi);
>> -        } else if (arm_feature(env, ARM_FEATURE_V7)) {
>> -            /* PMSAv7 */
>> +        } else if (arm_feature(env, ARM_FEATURE_V7) || arm_feature(env, 
>> ARM_FEATURE_M)) {
>> +            /* PMSAv7 or PMSAv6 */
>
>This is specifically M-profile PMSAv6. R-profile PMSAv6
>(which we do not implement) is a bit different.

I change the comment to "armv6-m PMSAv6".



>>  static void cortex_m3_initfn(Object *obj)
>>  {
>>      ARMCPU *cpu = ARM_CPU(obj);
>> @@ -111,6 +125,7 @@ static void cortex_m4_initfn(Object *obj)
>>      set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
>>      cpu->midr = 0x410fc240; /* r0p0 */
>>      cpu->pmsav7_dregion = 8;
>> +    /* VFPv4-SP */
>>      cpu->isar.mvfr0 = 0x10110021;
>>      cpu->isar.mvfr1 = 0x11000011;
>>      cpu->isar.mvfr2 = 0x00000000;
>> @@ -141,6 +156,7 @@ static void cortex_m7_initfn(Object *obj)
>>      set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
>>      cpu->midr = 0x411fc272; /* r1p2 */
>>      cpu->pmsav7_dregion = 8;
>> +    /* VFPv5 DP */
>>      cpu->isar.mvfr0 = 0x10110221;
>>      cpu->isar.mvfr1 = 0x12000011;
>>      cpu->isar.mvfr2 = 0x00000040;
>> @@ -173,6 +189,7 @@ static void cortex_m33_initfn(Object *obj)
>>      cpu->midr = 0x410fd213; /* r0p3 */
>>      cpu->pmsav7_dregion = 16;
>>      cpu->sau_sregion = 8;
>> +    /* VFPv5 DP */
>>      cpu->isar.mvfr0 = 0x10110021;
>>      cpu->isar.mvfr1 = 0x11000011;
>>      cpu->isar.mvfr2 = 0x00000040;
>> @@ -209,7 +226,7 @@ static void cortex_m55_initfn(Object *obj)
>>      cpu->revidr = 0;
>>      cpu->pmsav7_dregion = 16;
>>      cpu->sau_sregion = 8;
>> -    /* These are the MVFR* values for the FPU + full MVE configuration */
>> +    /* These are the MVFR* values for the FPv5-D16-M + full MVE 
>> configuration */
>>      cpu->isar.mvfr0 = 0x10110221;
>>      cpu->isar.mvfr1 = 0x12100211;
>>      cpu->isar.mvfr2 = 0x00000040;
>
>These comment additions/changes don't seem to be related to the
>Cortex-M0+. If you want to make them, put them in a
>separate commit with its own commit message saying why.

I will remove this comments, and may be send them in extra patch.

If everything is ok, I will send a V2 patch with your review.

Thanks

Matthieu

Reply via email to