From: Jinjie Ruan <[email protected]>

Move the power-on initialisation out of realize into
mpam_msc_state_init() (shared with the new legacy reset callback):
selection state and ECR/ESR cleared, per-RIS partition and monitor
storage zeroed, the PARTID narrowing map identity-wrapped so the
indirection is always in range before the driver programs it, and
MBW_MAX reset to 0xffff (full bandwidth) -- an unprogrammed PARTID
must not read as zero bandwidth.

Also fix the realize error message for num-partid == 0, which
repeated the num-ris text.

Signed-off-by: Jinjie Ruan <[email protected]>
---
 hw/arm/mpam.c | 78 +++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 60 insertions(+), 18 deletions(-)

diff --git a/hw/arm/mpam.c b/hw/arm/mpam.c
index fe78adb..c4a7567 100644
--- a/hw/arm/mpam.c
+++ b/hw/arm/mpam.c
@@ -1041,6 +1041,63 @@ static const MemoryRegionOps mpam_msc_ops = {
     },
 };
 
+
+/*
+ * Power-on state of the MSC, shared between realize and reset: ID narrowing
+ * map identity-wrapped, partition config at reset values, monitors off.
+ */
+static void mpam_msc_state_init(MPAMMSCState *s)
+{
+    int i;
+
+    s->ris = 0;
+    s->part_sel = 0;
+    s->internal_part_sel = false;
+    s->mon_sel = 0;
+    s->ecr = 0;
+    s->esr = 0;
+
+    for (i = 0; i < s->num_ris; i++) {
+        Mpamf *mpamf = &s->mpamf[i];
+        int p;
+
+        mpamf->ecr = 0;
+        mpamf->esr = 0;
+        memset(mpamf->per_nrw_id, 0,
+               sizeof(MpamfPerNrwId) * s->num_int_partid);
+        memset(mpamf->cfg_intpartid, 0,
+               sizeof(uint32_t) * s->num_partid);
+        memset(mpamf->mbwu_mons, 0,
+               sizeof(MpamMbwuMon) * s->num_mbwu_mon);
+        memset(mpamf->csu_mons, 0, sizeof(MpamCsuMon) * s->num_csu_mon);
+
+        /*
+         * Until resctrl programs the map, wrap each request PARTID onto an
+         * internal PARTID so the narrowing indirection is always in range.
+         */
+        for (p = 0; p < s->num_partid; p++) {
+            mpamf->cfg_intpartid[p] = p % s->num_int_partid;
+        }
+        /*
+         * per_nrw_id is indexed by INTERNAL PARTID: it has
+         * num_int_partid entries, not num_partid.  Writing it with the
+         * request-PARTID count overflowed the allocation by 224 entries
+         * (malloc(): corrupted top size once the struct grew).
+         */
+        for (p = 0; p < s->num_int_partid; p++) {
+            /* MBW_MAX resets to full bandwidth on real hardware */
+            mpamf->per_nrw_id[p].cfg_mbw_max = 0xffff;
+        }
+    }
+}
+
+static void mpam_msc_reset(DeviceState *dev)
+{
+    MPAMMSCState *s = MPAM_MSC_DEVICE(dev);
+
+    mpam_msc_state_init(s);
+}
+
 static void mpam_msc_realize(DeviceState *dev, Error **errp)
 {
     MPAMMSCState *s = MPAM_MSC_DEVICE(dev);
@@ -1052,7 +1109,7 @@ static void mpam_msc_realize(DeviceState *dev, Error 
**errp)
         return;
     }
     if (s->num_partid == 0) {
-        error_setg(errp, "num-ris must be <= 16");
+        error_setg(errp, "num-partid must be nonzero");
         return;
     }
     if (s->num_int_partid == 0) {
@@ -1061,28 +1118,12 @@ static void mpam_msc_realize(DeviceState *dev, Error 
**errp)
 
     s->mpamf = g_new0(Mpamf, s->num_ris);
     for (i = 0; i < s->num_ris; i++) {
-        int p;
-
         s->mpamf[i].per_nrw_id = g_new0(MpamfPerNrwId, s->num_int_partid);
         s->mpamf[i].cfg_intpartid = g_new0(uint32_t, s->num_partid);
         s->mpamf[i].mbwu_mons = g_new0(MpamMbwuMon, s->num_mbwu_mon);
         s->mpamf[i].csu_mons = g_new0(MpamCsuMon, s->num_csu_mon);
-        /*
-         * Until resctrl programs the map, wrap each request PARTID onto an
-         * internal PARTID so the narrowing indirection is always in range.
-         */
-        for (p = 0; p < s->num_partid; p++) {
-            s->mpamf[i].cfg_intpartid[p] = p % s->num_int_partid;
-        }
-        /*
-         * per_nrw_id is indexed by INTERNAL PARTID: it has num_int_partid
-         * entries, not num_partid.
-         */
-        for (p = 0; p < s->num_int_partid; p++) {
-            /* MBW_MAX resets to full bandwidth on real hardware */
-            s->mpamf[i].per_nrw_id[p].cfg_mbw_max = 0xffff;
-        }
     }
+    mpam_msc_state_init(s);
 
     memory_region_init_io(&s->mr, OBJECT(s), &mpam_msc_ops, s, "mpam_msc",
                           MPAM_SIZE);
@@ -1301,6 +1342,7 @@ static void mpam_msc_init(ObjectClass *klass, const void 
*data)
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     device_class_set_props(dc, mpam_msc_props);
+    device_class_set_legacy_reset(dc, mpam_msc_reset);
 }
 
 static void mpam_msc_mem_init(ObjectClass *klass, const void *data)
-- 
2.43.0


Reply via email to