From: Jonathan Cameron <[email protected]>

Implement the query-mpam-cache QMP command: walk the QOM tree for
mpam-msc-cache devices and report each via mpam_cache_fill_info()
(with the per-RIS register state and the configured CPBM bitmaps),
building on the generated header now included from the device
contract header.

Based on an RFC series by Jonathan Cameron, adapted to the current
qapi documentation rules.

Signed-off-by: Jonathan Cameron <[email protected]>
Signed-off-by: Jinjie Ruan <[email protected]>
---
 hw/arm/meson.build    |  5 ++--
 hw/arm/mpam-qapi.c    | 62 ++++++++++++++++++++++++++++++++++++++++
 hw/arm/mpam.c         | 66 +++++++++++++++++++++++++++++++++++++++++++
 include/hw/arm/mpam.h |  3 ++
 4 files changed, 134 insertions(+), 2 deletions(-)
 create mode 100644 hw/arm/mpam-qapi.c

diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index adf9146..da73546 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -106,8 +106,9 @@ arm_common_ss.add(when: 'CONFIG_NETDUINO2', if_true: 
files('netduino2.c'))
 arm_common_ss.add(when: 'CONFIG_RASPI', if_true: 
files('bcm2835_peripherals.c'))
 arm_common_ss.add(when: 'CONFIG_RASPI', if_true: 
files('bcm2838_peripherals.c'))
 arm_common_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c'))
-arm_common_ss.add(when: 'CONFIG_MPAM', if_true: files('mpam.c'))
-arm_common_ss.add(files('mpam-qapi-stubs.c'))
+arm_common_ss.add(when: 'CONFIG_MPAM', if_true: files('mpam.c', 'mpam-qapi.c'))
+arm_common_ss.add(when: 'CONFIG_MPAM', if_false: files('mpam-qapi-stubs.c'))
+arm_common_ss.add(when: 'CONFIG_ALL', if_true: files('mpam-qapi-stubs.c'))
 arm_common_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c'))
 arm_common_ss.add(when: 'CONFIG_VERSATILE', if_true: files('versatilepb.c'))
 arm_common_ss.add(when: 'CONFIG_VEXPRESS', if_true: files('vexpress.c'))
diff --git a/hw/arm/mpam-qapi.c b/hw/arm/mpam-qapi.c
new file mode 100644
index 0000000..ceed734
--- /dev/null
+++ b/hw/arm/mpam-qapi.c
@@ -0,0 +1,62 @@
+/*
+ * QEMU MPAM QMP commands
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/arm/mpam.h"
+#include "qom/object.h"
+#include "qapi/qapi-commands-mpam.h"
+
+typedef struct MPAMQueryState {
+    Error **errp;
+    MpamCacheInfoList **head;
+    bool level_filter_on;
+    int level;
+} MPAMQueryState;
+
+static int mpam_query_cache(Object *obj, void *opaque)
+{
+    MPAMQueryState *state = opaque;
+    MpamCacheInfoList *infolist;
+    MpamCacheInfo *info;
+
+    if (!object_dynamic_cast(obj, TYPE_MPAM_MSC_CACHE)) {
+        return 0;
+    }
+    if (state->level_filter_on &&
+        object_property_get_uint(obj, "cache-level", state->errp) !=
+        state->level) {
+        return 0;
+    }
+
+    infolist = g_malloc0(sizeof(*infolist));
+    info = g_malloc0(sizeof(*info));
+
+    mpam_cache_fill_info(obj, info);
+
+    infolist->value = info;
+
+    *state->head = infolist;
+    state->head = &infolist->next;
+
+    return 0;
+}
+
+MpamCacheInfoList *qmp_query_mpam_cache(bool has_level, int64_t level,
+                                        Error **errp)
+{
+
+    MpamCacheInfoList *head = NULL;
+    MPAMQueryState state = {
+        .errp = errp,
+        .head = &head,
+        .level_filter_on = has_level,
+        .level = level,
+    };
+
+    object_child_foreach_recursive(object_get_root(), mpam_query_cache, 
&state);
+
+    return head;
+}
diff --git a/hw/arm/mpam.c b/hw/arm/mpam.c
index 6c43e3e..f4f40ca 100644
--- a/hw/arm/mpam.c
+++ b/hw/arm/mpam.c
@@ -645,6 +645,72 @@ DECLARE_INSTANCE_CHECKER(MPAMMSCMemState, 
MPAM_MSC_MEM_DEVICE,
 DECLARE_INSTANCE_CHECKER(MPAMMSCCacheState, MPAM_MSC_CACHE_DEVICE,
                          TYPE_MPAM_MSC_CACHE);
 
+void mpam_cache_fill_info(Object *obj, MpamCacheInfo *info)
+{
+    MPAMMSCCacheState *cs = MPAM_MSC_CACHE_DEVICE(obj);
+    MPAMMSCState *s = MPAM_MSC_DEVICE(obj);
+    MpamRegsList *reg_list = NULL, **r_next = &reg_list;
+    int i, p, b;
+
+    info->cpu = cs->cpu;
+    info->level = cs->cache_level;
+    info->type = cs->cache_level;
+    for (i = 0; i < s->num_ris; i++) {
+        MpamRegsList *regs;
+        MpamRegs *r;
+        MpamBmList *bm_list = NULL, **bm_next = &bm_list;
+
+        Mpamf *mpamf = &s->mpamf[i];
+
+        r = g_malloc0(sizeof(*r));
+        regs = g_malloc0(sizeof(*regs));
+        regs->value = r;
+
+        *r = (MpamRegs) {
+            .idr = mpamf->idr,
+            .iidr = mpamf->iidr,
+            .aidr = mpamf->aidr,
+            .cpor_idr = mpamf->cpor_idr,
+            .ccap_idr = mpamf->ccap_idr,
+            .mbw_idr = mpamf->mbw_idr,
+            .pri_idr = mpamf->pri_idr,
+            .partid_nrw_idr = mpamf->partid_nrw_idr,
+            .msmon_idr = mpamf->msmon_idr,
+            .csumon_idr = mpamf->csumon_idr,
+            .mbwumon_idr = mpamf->mbwumon_idr,
+            .ecr = mpamf->ecr,
+            .esr = mpamf->esr,
+            .cfg_part_sel = mpamf->cfg_part_sel, /* Garbage */
+        };
+
+        /* This is annoyingly complex */
+        for (p = 0; p < s->num_int_partid; p++) {
+            intList *w_list = NULL, **w_next = &w_list;
+            MpamBm *bm = g_malloc0(sizeof(*bm));
+            MpamBmList *bml = g_malloc0(sizeof(*bml));
+
+            bml->value = bm;
+
+            for (b = 0; b < (MPAM_CACHE_PART + 31) / 32; b++) {
+                intList *il = g_malloc0(sizeof(*il));
+
+                il->value = mpamf->per_nrw_id[p].cfg_cpbm[b];
+                *w_next = il;
+                w_next = &il->next;
+
+            }
+            *bm_next = bml;
+            bm_next = &bml->next;
+            bm->words = w_list;
+        }
+        r->cfg_cpbm = bm_list;
+        *r_next = regs;
+        r_next = &regs->next;
+    }
+    info->regs = reg_list;
+
+}
+
 static uint64_t mpam_msc_read_reg(void *opaque, hwaddr offset,
                                   unsigned size)
 {
diff --git a/include/hw/arm/mpam.h b/include/hw/arm/mpam.h
index e7557a9..cb1c106 100644
--- a/include/hw/arm/mpam.h
+++ b/include/hw/arm/mpam.h
@@ -7,6 +7,7 @@
 #define _MPAM_H_
 
 #include "qom/object.h"
+#include "qapi/qapi-commands-mpam.h"
 
 #define TYPE_MPAM_MSC_MEM "mpam-msc-mem"
 #define TYPE_MPAM_MSC_CACHE "mpam-msc-cache"
@@ -17,4 +18,6 @@
  */
 #define MPAM_SIZE 0x4000
 
+void mpam_cache_fill_info(Object *obj, MpamCacheInfo *info);
+
 #endif /* _MPAM_H_ */
-- 
2.43.0


Reply via email to