From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001
From: Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com>
Date: Tue, 10 Oct 2023 14:33:42 +0000
Subject: Add submodule dependency files

Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
---
 roms/skiboot/core/affinity.c | 125 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)
 create mode 100644 roms/skiboot/core/affinity.c

(limited to 'roms/skiboot/core/affinity.c')

diff --git a/roms/skiboot/core/affinity.c b/roms/skiboot/core/affinity.c
new file mode 100644
index 000000000..0209d3cd9
--- /dev/null
+++ b/roms/skiboot/core/affinity.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/* Copyright 2013-2019 IBM Corp. */
+
+/*
+ *
+ * We currently construct our associativity properties as such:
+ *
+ * - For "chip" devices (bridges, memory, ...), 4 entries:
+ *
+ *     - CCM node ID
+ *     - HW card ID
+ *     - HW module ID
+ *     - Chip ID
+ *
+ *   The information is constructed based on the chip ID which (unlike
+ *   pHyp) is our HW chip ID (aka "XSCOM" chip ID). We use it to retrieve
+ *   the other properties from the corresponding chip/xscom node in the
+ *   device-tree. If those properties are absent, 0 is used.
+ *
+ * - For "core" devices, we add a 5th entry:
+ *
+ *     - Core ID
+ *
+ *   Here too, we do not use the "cooked" HW processor ID from HDAT but
+ *   instead use the real HW core ID which is basically the interrupt
+ *   server number of thread 0 on that core.
+ *
+ *
+ * The ibm,associativity-reference-points property is currently set to
+ * 4,4 indicating that the chip ID is our only reference point. This
+ * should be extended to encompass the node IDs eventually.
+ */
+#include <skiboot.h>
+#include <opal.h>
+#include <device.h>
+#include <console.h>
+#include <trace.h>
+#include <chip.h>
+#include <cpu.h>
+#include <affinity.h>
+
+static uint32_t get_chip_node_id(struct proc_chip *chip)
+{
+	/* If the xscom node has an ibm,ccm-node-id property, use it */
+	if (dt_has_node_property(chip->devnode, "ibm,ccm-node-id", NULL))
+		return dt_prop_get_u32(chip->devnode, "ibm,ccm-node-id");
+
+	/*
+	 * Else use the 3 top bits of the chip ID which should be
+	 * the node on P8
+	 */
+	return chip->id >> 3;
+}
+
+void add_associativity_ref_point(void)
+{
+	int ref2 = 0x4;
+
+	/*
+	 * Note about our use of reference points:
+	 *
+	 * Linux currently supports up to three levels of NUMA. We use the
+	 * first reference point for the node ID and the second reference
+	 * point for a second level of affinity. We always use the chip ID
+	 * (4) for the first reference point.
+	 *
+	 * Choosing the second level of affinity is model specific
+	 * unfortunately. Current POWER8E models should use the DCM
+	 * as a second level of NUMA.
+	 *
+	 * If there is a way to obtain this information from the FSP
+	 * that would be ideal, but for now hardwire our POWER8E setting.
+	 *
+	 * For GPU nodes we add a third level of NUMA, such that the
+	 * distance of the GPU node from all other nodes is uniformly
+	 * the highest.
+	 */
+	if (PVR_TYPE(mfspr(SPR_PVR)) == PVR_TYPE_P8E)
+		ref2 = 0x3;
+
+	dt_add_property_cells(opal_node, "ibm,associativity-reference-points",
+			      0x4, ref2, 0x2);
+}
+
+void add_chip_dev_associativity(struct dt_node *dev)
+{
+	uint32_t chip_id = dt_get_chip_id(dev);
+	struct proc_chip *chip = get_chip(chip_id);
+	uint32_t hw_cid, hw_mid;
+
+	if (!chip)
+		return;
+
+	hw_cid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-card-id", 0);
+	hw_mid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-module-id", 0);
+
+	dt_add_property_cells(dev, "ibm,associativity", 4,
+			      get_chip_node_id(chip),
+			      hw_cid, hw_mid, chip_id);
+}
+
+void add_core_associativity(struct cpu_thread *cpu)
+{
+	struct proc_chip *chip = get_chip(cpu->chip_id);
+	uint32_t hw_cid, hw_mid, core_id;
+
+	if (!chip)
+		return;
+
+	if (proc_gen == proc_gen_p8)
+		core_id = (cpu->pir >> 3) & 0xf;
+	else if (proc_gen == proc_gen_p9)
+		core_id = (cpu->pir >> 2) & 0x1f;
+	else if (proc_gen == proc_gen_p10)
+		core_id = (cpu->pir >> 2) & 0x1f;
+	else
+		return;
+
+	hw_cid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-card-id", 0);
+	hw_mid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-module-id", 0);
+
+	dt_add_property_cells(cpu->node, "ibm,associativity", 5,
+			      get_chip_node_id(chip),
+			      hw_cid, hw_mid, chip->id, core_id);
+}
-- 
cgit