From: Jinjie Ruan <[email protected]>

Add the DEN0065 MSC node builders for the MPAM table: the
interrupt entry (flags 0 = wired, level per Table 5; GSIV 0 means
not present) and the memory-controller and cache-controller node
layouts (fixed 72-byte header plus one 24-byte resource node per
RIS, MAX_NRDY_USEC 100) with the matching locators (proximity
domain for memory, PPTT cache id for caches).

Static helpers; wired into the generated table by the next patch.

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

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index d368913..871ee45 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -52,6 +52,7 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/pci-host/gpex.h"
 #include "hw/arm/virt.h"
+#include "hw/arm/mpam.h"
 #include "hw/intc/arm_gicv3_its_common.h"
 #include "hw/mem/nvdimm.h"
 #include "hw/core/platform-bus.h"
@@ -855,6 +856,135 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
     acpi_table_end(linker, &table);
 }
 
+/*
+ * DEN0065 3.0 Table 5: interrupt flags bit0 = mode (0 level, 1 edge),
+ * bits[2:1] = type (00b wired), bit4 = affinity valid (must be 0 for an
+ * SPI).  The MSC model signals both interrupts level, so flags are 0.
+ * GSIV 0 means the interrupt is not present.
+ */
+/*
+ * DEN0065 4.0: an MSC node is a 72-byte fixed header plus one 24-byte
+ * resource node per RIS.  MAX_NRDY_USEC 100 is the default ready-time.
+ */
+#define MPAM_MSC_NODE_HDR_LEN   72
+#define MPAM_MSC_RIS_ENTRY_LEN   24
+#define MPAM_MSC_MAX_NRDY_USEC  100
+
+static void build_msc_interrupt(GArray *table_data, uint32_t gsiv)
+{
+    build_append_int_noprefix(table_data, gsiv, 4);
+    build_append_int_noprefix(table_data, 0 /* wired, level */, 4);
+}
+
+static void build_msc_memory_controller(GArray *table_data, int identifier,
+                                        hwaddr base_addr, uint32_t mpam_id,
+                                        int num_ris, uint64_t *nodes,
+                                        uint32_t oflow_gsiv,
+                                        uint32_t err_gsiv)
+{
+    int length = MPAM_MSC_NODE_HDR_LEN + MPAM_MSC_RIS_ENTRY_LEN * num_ris;
+    int i;
+
+    build_append_int_noprefix(table_data, length, 2);
+    /* Interface Type */
+    build_append_int_noprefix(table_data, 0 /* MMIO */, 1);
+    /* Reserved */
+    build_append_int_noprefix(table_data, 0, 1);
+    build_append_int_noprefix(table_data, identifier, 4);
+    build_append_int_noprefix(table_data, base_addr, 8);
+    build_append_int_noprefix(table_data, MPAM_SIZE, 4);
+    /* Overflow interrupt */
+    build_msc_interrupt(table_data, oflow_gsiv);
+    /* Reserved */
+    build_append_int_noprefix(table_data, 0, 4);
+    /* Overflow Int Affinity */
+    build_append_int_noprefix(table_data, 0, 4);
+    /* Error interrupt */
+    build_msc_interrupt(table_data, err_gsiv);
+    /* More reserved */
+    build_append_int_noprefix(table_data, 0, 4);
+    /* Error Int Affinity */
+    build_append_int_noprefix(table_data, 0, 4);
+    /* MAX_NRDY_USEC */
+    build_append_int_noprefix(table_data, MPAM_MSC_MAX_NRDY_USEC, 4);
+    /* Linked Device - none for now */
+    build_append_int_noprefix(table_data, 0, 8);
+    /* _UID of linked device */
+    build_append_int_noprefix(table_data, 0, 4);
+    build_append_int_noprefix(table_data, num_ris, 4);
+    /* Build a memory controller resource */
+    for (i = 0; i < num_ris; i++) {
+        build_append_int_noprefix(table_data, mpam_id, 4);
+        build_append_int_noprefix(table_data, i, 1);
+        /* Reserved1 */
+        build_append_int_noprefix(table_data, 0, 2);
+        /* Locator type - 1 = Memory */
+        build_append_int_noprefix(table_data, 1, 1);
+        /* Locator part 1 Node */
+        build_append_int_noprefix(table_data, nodes[i], 8);
+        /* Locator part 2 reserved */
+        build_append_int_noprefix(table_data, 0, 4);
+        /* Num functional dependencies */
+        build_append_int_noprefix(table_data, 0, 4);
+    }
+}
+
+static void build_msc_cache_controller(GArray *table_data, int identifier,
+                                       hwaddr base_addr, uint32_t mpam_id,
+                                       int num_ris, uint64_t *cache_id,
+                                       uint32_t oflow_gsiv,
+                                       uint32_t err_gsiv)
+{
+    int length = MPAM_MSC_NODE_HDR_LEN + MPAM_MSC_RIS_ENTRY_LEN * num_ris;
+    int i;
+
+    build_append_int_noprefix(table_data, length, 2);
+    /* Interface Type */
+    build_append_int_noprefix(table_data, 0 /* MMIO */, 1);
+    /* Reserved */
+    build_append_int_noprefix(table_data, 0, 1);
+    build_append_int_noprefix(table_data, identifier, 4);
+    build_append_int_noprefix(table_data, base_addr, 8);
+    build_append_int_noprefix(table_data, MPAM_SIZE, 4);
+    /* Overflow interrupt */
+    build_msc_interrupt(table_data, oflow_gsiv);
+    /* Reserved */
+    build_append_int_noprefix(table_data, 0, 4);
+    /* Overflow Int Affinity */
+    build_append_int_noprefix(table_data, 0, 4);
+    /* Error interrupt */
+    build_msc_interrupt(table_data, err_gsiv);
+    /* More reserved */
+    build_append_int_noprefix(table_data, 0, 4);
+    /* Error Int Affinity */
+    build_append_int_noprefix(table_data, 0, 4);
+    /* MAX_NRDY_USEC */
+    build_append_int_noprefix(table_data, MPAM_MSC_MAX_NRDY_USEC, 4);
+    /* Linked Device - none for now */
+    build_append_int_noprefix(table_data, 0, 8);
+    /* _UID of linked device */
+    build_append_int_noprefix(table_data, 0, 4);
+    /* Num resource nodes */
+    build_append_int_noprefix(table_data, num_ris, 4);
+    /* Build a cache resource */
+    for (i = 0; i < num_ris; i++) {
+        /* Identifier */
+        build_append_int_noprefix(table_data, mpam_id, 4);
+        /* RIS index */
+        build_append_int_noprefix(table_data, i, 1);
+        /* Reserved1 */
+        build_append_int_noprefix(table_data, 0, 2);
+        /* Locator type - 0 = Cache */
+        build_append_int_noprefix(table_data, 0, 1);
+        /* Locator part 1 PPTT ID */
+        build_append_int_noprefix(table_data, cache_id[i], 8);
+        /* Locator part 2 reserved */
+        build_append_int_noprefix(table_data, 0, 4);
+        /* Num functional dependencies */
+        build_append_int_noprefix(table_data, 0, 4);
+    }
+}
+
 /*
  * ACPI spec, Revision 6.5
  * 5.2.25 Generic Timer Description Table (GTDT)
-- 
2.43.0


Reply via email to