[Skiboot] [PATCH v3 5/9] Nest unit parser and Nest MCS unit support functions

Madhavan Srinivasan maddy at linux.vnet.ibm.com
Mon Aug 3 17:33:44 AEST 2015


Add catalog parser function to detect Nest units. Add
support functions for Nest Memory Control (MCS) unit.
Support function will add device tree entry for each
event supported by MCS unit and also a corresponding
event unit and event file to pass on information to kernel.

Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
---
 hw/nest.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/hw/nest.c b/hw/nest.c
index 2ed0c33f8919..1733f08af06a 100644
--- a/hw/nest.c
+++ b/hw/nest.c
@@ -25,6 +25,8 @@
 #include <opal-api.h>
 #include <io.h>
 
+#define MAX_NAME_SIZE	64
+
 /*
  * Pointer holding the Catalogue file in memory
  */
@@ -38,6 +40,112 @@ struct nest_catalogue_ptr *c_ptr;
  */
 struct nest_catalog_page_0 *page0_ptr;
 
+static u32 get_chip_event_offset(int idx )
+{
+	char *marker = CHIP_EVENT_ENTRY(c_ptr);
+	struct nest_catalogue_event_data *ev;
+	int i;
+
+	ev = (struct nest_catalogue_event_data *) marker;
+	for (i=0; i < idx ; i++) {
+		marker += ev->length;
+		ev = (struct nest_catalogue_event_data *) marker;
+	}
+
+	return (ev->event_group_record_offs + ev->event_counter_offs);
+}
+
+int dt_create_nest_chip_mcs_event(struct dt_node *ima, int idx, u32 offset)
+{
+	char ev_name[MAX_NAME_SIZE];
+	const char *unit = "MiB", *scale = "1.2207e-4";
+
+	snprintf(ev_name, MAX_NAME_SIZE, "MCS_0%d", idx);
+	dt_add_property_cells(ima, ev_name, offset);
+
+	/* Unit for the Event */
+	snprintf(ev_name, MAX_NAME_SIZE, "unit.MCS_0%d.unit", idx);
+	dt_add_property_string(ima, ev_name, unit);
+
+	/* Scale for the Event */
+	snprintf(ev_name, MAX_NAME_SIZE, "scale.MCS_0%d.scale", idx);
+	dt_add_property_string(ima, ev_name, scale);
+
+	return 0;
+}
+
+int dt_create_nest_chip_mcs_type( struct dt_node *ima,
+		struct nest_catalogue_group_data *gptr, char *name)
+{
+	struct dt_node *type;
+	int idx;
+	u32 offset;
+
+	type = dt_new(ima, name);
+	if (!type) {
+		prlog(PR_DEBUG, "nest_ima %s type creation failed \n", name);
+		return -1;
+	}
+
+	/*
+	 *  Create DT entry for only first 4 events in this group
+	 *  Looks like each group as repeated same events.
+	 */
+	dt_add_property_string(type, "device_type", "nest-ima-unit");
+	for (idx=0; idx < (gptr->event_count / 2); idx++) {
+		offset = get_chip_event_offset( gptr->event_index[idx]);
+		dt_create_nest_chip_mcs_event(type, idx, offset);
+	}
+
+	return 0;
+}
+
+/*
+ * Wrapper Function to call Corresponding Nest unit functions
+ * for event dt creation. Not all the Chip Groups in the Catalog are
+ * supported at this point.
+ */
+int dt_create_nest_chip_type(struct dt_node *ima,
+		struct nest_catalogue_group_data *gptr)
+{
+	char *name;
+
+	name = malloc(gptr->group_name_len);
+	if (!name)
+		return OPAL_NO_MEM;
+
+	memcpy((void *)name, (void *)gptr->remainder, gptr->group_name_len);
+	if (strstr(name, "MCS_")) {
+		if (dt_create_nest_chip_mcs_type(ima, gptr,name))
+			goto out;
+	}
+
+	return OPAL_SUCCESS;
+
+out:
+	free(name);
+	return OPAL_RESOURCE;
+}
+
+int dt_create_nest_chip_types(struct dt_node *ima)
+{
+	struct nest_catalogue_group_data *group_ptr;
+	char *marker;
+	int rc = CHIP_EVENTS_NOT_SUPPORTED;
+
+	marker = CHIP_GROUP_ENTRY(c_ptr);
+	group_ptr = (struct nest_catalogue_group_data *) marker;
+	while (group_ptr->domain == DOMAIN_CHIP) {
+		rc = dt_create_nest_chip_type (ima, group_ptr);
+		if (rc)
+			break;
+		marker += group_ptr->length;
+		group_ptr = (struct nest_catalogue_group_data *) marker;
+	};
+
+	return rc;
+}
+
 int preload_catalogue_lid()
 {
 	size_t size = NEST_CATALOGUE_SIZE;
@@ -179,5 +287,12 @@ void nest_pmu_init(int loaded)
 		break;
 	}
 
+	/*
+	 * Now we parse the catalogue and create device tree entries for
+	 * supported Nest units.
+	 */
+	if (dt_create_nest_chip_types(dev))
+		dt_free(dev);
+
 	return;
 }
-- 
1.9.1



More information about the Skiboot mailing list