From: Jinjie Ruan <[email protected]>

Add read/write handling for the MPAMCFG_PART_SEL selector: the
RIS field switches the per-RIS register bank (rejecting RIS
values beyond num-ris, and nonzero RIS on an MSC without RIS
support), and PARTID_SEL/INTERNAL record the selected partition
for the configuration registers.  Writes are stored per RIS so
the selector reads back as written.

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

diff --git a/hw/arm/mpam.c b/hw/arm/mpam.c
index 17ca286..c21a737 100644
--- a/hw/arm/mpam.c
+++ b/hw/arm/mpam.c
@@ -329,6 +329,8 @@ static uint64_t mpam_msc_read_reg(void *opaque, hwaddr 
offset,
         return mpamf->csumon_idr;
     case A_MPAMF_MBWUMON_IDR:
         return mpamf->mbwumon_idr;
+    case A_MPAMF_CFG_PART_SEL:
+        return mpamf->cfg_part_sel;
     default:
         qemu_log_mask(LOG_UNIMP,
                       "MPAM: Unexpected read of %lx\n", offset);
@@ -339,7 +341,37 @@ static uint64_t mpam_msc_read_reg(void *opaque, hwaddr 
offset,
 static void mpam_msc_write_reg(void *opaque, hwaddr offset, uint64_t value,
                                unsigned size)
 {
+    MPAMMSCState *s = MPAM_MSC_DEVICE(opaque);
+    /* Update in the ris setting path */
+    Mpamf *mpamf = &s->mpamf[s->ris];
+
     switch (offset) {
+    case A_MPAMF_CFG_PART_SEL:
+        if (value & ~MPAMF_CFG_PART_SEL_WRITE_MASK) {
+            qemu_log_mask(LOG_UNIMP,
+                          "MPAM: Unexpected write to CFG_PART_SEL Mask=%x 
Value=%lx\n",
+                          MPAMF_CFG_PART_SEL_WRITE_MASK, value);
+        }
+        /* Field matches for all RIS */
+        if (!FIELD_EX64(mpamf->idr, MPAMF_IDR, HAS_RIS) &&
+            FIELD_EX32(value, MPAMF_CFG_PART_SEL, RIS) != 0) {
+            qemu_log_mask(LOG_UNIMP,
+                          "MPAM: Unexpected write of non 0 RIS on MSC with 
!HAS_RIS\n");
+            return;
+        }
+        if (FIELD_EX32(value, MPAMF_CFG_PART_SEL, RIS) >= s->num_ris) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "MPAM: RIS %d out of range (num-ris %d)\n",
+                          FIELD_EX32(value, MPAMF_CFG_PART_SEL, RIS),
+                          s->num_ris);
+            return;
+        }
+        s->ris = FIELD_EX32(value, MPAMF_CFG_PART_SEL, RIS);
+        s->part_sel = FIELD_EX32(value, MPAMF_CFG_PART_SEL, PARTID_SEL);
+        s->internal_part_sel = FIELD_EX32(value, MPAMF_CFG_PART_SEL, INTERNAL);
+        mpamf = &s->mpamf[s->ris];
+        mpamf->cfg_part_sel = value;
+        return;
     default:
         qemu_log_mask(LOG_UNIMP,
                       "MPAM: Write to unexpected register Addr %lx 
Value=%lx\n",
-- 
2.43.0


Reply via email to