[Skiboot] [RFC PATCH 4/4]ibm-fsp/firenze: Nest Intrumentation code

Madhavan Srinivasan maddy at linux.vnet.ibm.com
Thu Mar 19 20:28:33 AEDT 2015


This patch addes Nest instrumentation OPAL side code.
Patch does two things. 1) At the time of boot, it detects
the Nest instrumentation feature and created device-tree
entries to pass the information to kernel. Secondly, it
implements an opal call to control the PORE Thread Scheduler
(PTS) from kernel.

Currently we do not have the Nest instrumentation detection
mechanism ready. This should happen via LID file. Currently
the LID file is under developement and does not contain
the Chip level events or the layout for the chip level events.

So, have added comments and TODOs in the code that needs changes
once the LID file is ready.

Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
---
 hw/Makefile.inc |   2 +-
 hw/uncore.c     | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 251 insertions(+), 1 deletion(-)
 create mode 100644 hw/uncore.c

diff --git a/hw/Makefile.inc b/hw/Makefile.inc
index 395a65f..7c4cac8 100644
--- a/hw/Makefile.inc
+++ b/hw/Makefile.inc
@@ -2,7 +2,7 @@
 
 SUBDIRS += hw
 HW_OBJS  = xscom.o chiptod.o gx.o cec.o lpc.o lpc-uart.o psi.o
-HW_OBJS += homer.o slw.o occ.o fsi-master.o centaur.o
+HW_OBJS += homer.o slw.o occ.o fsi-master.o centaur.o uncore.o
 HW_OBJS += nx.o nx-rng.o nx-crypto.o nx-842.o
 HW_OBJS += p7ioc.o p7ioc-inits.o p7ioc-phb.o p5ioc2.o p5ioc2-phb.o
 HW_OBJS += phb3.o sfc-ctrl.o fake-rtc.o bt.o p8-i2c.o prd.o
diff --git a/hw/uncore.c b/hw/uncore.c
new file mode 100644
index 0000000..793496a
--- /dev/null
+++ b/hw/uncore.c
@@ -0,0 +1,250 @@
+/* Copyright 2015 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * Locking notes:
+ */
+
+#include <skiboot.h>
+#include <device.h>
+#include <uncore.h>
+#include <chip.h>
+#include <cpu.h>
+#include <xscom.h>
+#include <timebase.h>
+#include <opal-api.h>
+
+/*
+ * Fixed offsets for memory controller read and write events.
+ * Data from PORE_SLW_IMA team, since catalog lid is
+ * under developement
+ */
+static u32 uncore_mcs_read_controller_offset[] =
+				{0x118, 0x120, 0x128, 0x130};
+static u32 uncore_mcs_write_controller_offset[] =
+				{0x198, 0x1A0, 0x1A8, 0x1B0};
+
+int setup_scom (uint32_t , uint64_t );
+
+static int dt_create_uncore_mcs(struct dt_node *ima)
+{
+	int i;
+	struct dt_node *subdev;
+	const char *unit = "MiB/s", *scale = "8";
+
+	/*
+	 * Create dt entry for each Unit.
+	 */
+	for(i=0; i<P8_IMA_MCS_COUNT; i++) {
+		subdev = dt_new_addr(ima, "mcs", i);
+		if(!subdev) {
+                        prlog(PR_DEBUG, "uncore subdev creation failed \n");
+                        return -1;
+		}
+
+		/*
+		 * Events Supported by this Unit
+		 * TODO:
+		 * Offset value should come from Catalog lid.
+		 */
+		dt_add_property_cells(subdev, "mcs_read", uncore_mcs_read_controller_offset[i]);
+		dt_add_property_string(subdev, "unit.mcs_read.unit", unit);
+		dt_add_property_string(subdev, "scale.mcs_read.scale", scale);
+		dt_add_property_cells(subdev, "mcs_write", uncore_mcs_write_controller_offset[i]);
+		dt_add_property_string(subdev, "unit.mcs_write.unit", unit);
+		dt_add_property_string(subdev, "scale.mcs_write.scale", scale);
+		dt_add_property_cells(subdev, "ibm,dev-id", i);
+	}
+
+	return 0;
+}
+
+static int dt_create_uncore_mcs_type (struct dt_node *uncore)
+{
+	struct dt_node *type;
+
+	/*
+	 * Create a Memory Controller Type (MCS)
+	 */
+	type = dt_new(uncore, "mcs");
+	if (!type) {
+		prlog(PR_DEBUG, "uncore mcs type creation failed \n");
+		return -1;
+	}
+
+	dt_add_property_string(type, "compatible", "ibm,uncore-mcs");
+	dt_add_property_cells(type, "sub_units", 0x4);
+
+	/*
+	 * Now create a sub node to add events and
+	 * other data.
+	 */
+	if (dt_create_uncore_mcs(type)) {
+		dt_free(type);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Each Nest unit will have a type folder
+ * and sub-folder for events and offset.
+ */
+static int dt_create_uncore_types(struct dt_node *uncore)
+{
+	/*
+	 * Currently will information about Memory
+	 * Controller (MCS Unit)
+	 * TODO:
+	 * Need to fix this by parsing Catalog lid.
+	 */
+	if (dt_create_uncore_mcs_type(uncore))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * powerpc Nest instrumentation support init.
+ */
+void uncore_init(void)
+{
+	struct proc_chip *chip;
+	struct dt_node *dev;
+	const char *compat = "ibm,uncore-v1";
+	u64 addr=0;
+
+	/*
+	 * TODO:
+	 * Currently patch assumes we have Nest
+         * instrumentation enabled in the processor
+	 * it runs.
+	 *
+	 * Feature Detection:
+	 * Nest instrumentation feature detection
+	 * has to happen via a LID (81e00610).
+	 * This is ilid, called as "24x7 catalog", should
+	 * have information about both Core level and Chip
+	 * level events.
+	 *
+	 * But the catalog is under-development. We have
+	 * the LID as part of the FW, but it does not
+	 * contain any information about Chip level events
+	 * currently.
+	 *
+	 * load_catalog_lid()
+	 */
+
+	/*
+	 * Design is to pass the Nest counter information
+	 * to kernel via Device-tree. Top level node
+	 * ("uncore@<chip -id>") under "/" (root) created
+	 * to have all the nest data in one place. Since
+	 * Nest counters are per-chip, hence "@<chip-id>"
+	 *
+	 * Each Nest unit will have a sub node like mcs, pb
+	 * (Nest units) with information such as events,
+	 * offsets in Homer for counter data, unit, scale
+	 * and so on.
+	 */
+	for_each_chip(chip) {
+		dev = dt_new_addr(dt_root, "uncore", chip->id);
+		if(!dev) {
+			prlog(PR_DEBUG,"uncore dev creation failed \n");
+			return;
+		}
+
+		/*
+		 * Design:
+		 * PORE_SLW_IMA Engine will program
+		 * Nest counters with pre-defined set of
+		 * events (provided in catalog) and dump
+		 * counter data in a fixed HOMER offset 
+		 * (also provided in catalog).
+		 *
+		 * HOMER Region has reserved memory for
+		 * PORE_SLW_IMA from 0x320000 to 0x39FFFF 
+		 * 
+		 * PORE_SLW_IMA uses this region to dump
+		 * different Nest unit counter data.
+		 * This address is passed to kernel as base
+		 * address to map.
+		 *
+		 * Individual counter offsets are passed in
+		 * the event file of that unit.
+		 */
+		addr = chip->homer_base + SLW_IMA_OFFSET;
+
+		/*
+		 * Entry to search for uncore in kernel
+		 */
+		dt_add_property(dev, "ibm,uncore", NULL, 0);
+
+		/*
+		 * Only expose the Counter storage space in HOMER.
+		 */
+		dt_add_property_u64(dev, "reg", addr);
+		dt_add_property_cells(dev, "size", SLW_IMA_SIZE);
+		dt_add_property_string(dev, "compatible", compat);
+		dt_add_property_cells(dev, "#address-cells", 1);
+		dt_add_property_cells(dev, "#size-cells", 0);
+		dt_add_property_cells(dev, "ibm,chip-id", chip->id);
+
+		/*
+		 * TODO:
+		 * Parse the Catalog lid and get each Nest Unit
+		 * supported to create a DT node here.
+		 */
+		if(dt_create_uncore_types(dev)) {
+			dt_free(dev);
+			break;
+		}
+	}
+}
+
+/*
+ * PORE Thread Scheduler (PTS) schedules PORE Engine Threads
+ * such as PORE_SLW_IMA. Writing to specific scom controls
+ * PTS (big ON/OFF switch).
+ */
+int pore_slw_ima_scom (uint32_t chip_id, uint32_t command)
+{
+	int rc;
+
+	if (command)
+		rc = xscom_write(chip_id, IMA_PTS_SCOM, IMA_PTS_ENABLE);
+	else
+		rc = xscom_write(chip_id, IMA_PTS_SCOM, IMA_PTS_DISABLE);
+
+	return rc;
+}
+
+/*
+ * OPAL call to start and stop PTS.
+ */
+static int64_t opal_uncore_control(uint32_t value)
+{
+	struct proc_chip *chip;
+	int rc = IMA_PTS_ERROR;
+
+	chip = get_chip(pir_to_chip_id(this_cpu()->pir));
+
+	if (value)
+		rc = pore_slw_ima_scom(chip->id, IMA_PTS_START);
+	 else
+		rc = pore_slw_ima_scom(chip->id, IMA_PTS_STOP);
+
+	return rc;
+}
+opal_call (OPAL_UNCORE_CONTROL, opal_uncore_control, 1);
-- 
1.9.1



More information about the Skiboot mailing list