[Skiboot] [PATCH v6 6/9] nest mcs unit support

Madhavan Srinivasan maddy at linux.vnet.ibm.com
Fri Feb 19 03:45:14 AEDT 2016


Add support functions for nest memory control subsystem (mcs) unit.
Support function will add device tree node for each
event supported by mcs unit and corresponding reg, id, unit and scale
entries to pass on information about the event.

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

diff --git a/hw/nest.c b/hw/nest.c
index e09ce3af5fdb..896fd088b7f6 100644
--- a/hw/nest.c
+++ b/hw/nest.c
@@ -76,6 +76,91 @@ dt_add_device_node(struct dt_node *ptr, const char *name)
 	return type;
 }
 
+static u32 get_chip_event_offset(int idx, int domain)
+{
+	char *marker;
+	struct nest_catalog_events_data *ev;
+	int i;
+
+	if (domain == DOMAIN_CHIP)
+		marker = CHIP_EVENT_ENTRY(catalog_desc);
+	else
+		marker = CORE_EVENT_ENTRY(catalog_desc);
+
+	ev = (struct nest_catalog_events_data *)marker;
+	for (i = 0; i < idx ; i++) {
+		marker += ev->length;
+		ev = (struct nest_catalog_events_data *)marker;
+	}
+
+	return (ev->event_group_record_offs + ev->event_counter_offs);
+}
+
+static int dt_create_nest_unit_events(struct dt_node *pt, int index, u32 offset,
+					const char *name, const char *scale,
+					const char *unit)
+{
+	struct dt_node *type;
+
+	/*
+	 * Create an event node to pass event information.
+	 * "reg" property is must for event and rest of the properties
+	 * such as id, scale, unit are optional.
+	 */
+	type = dt_new_addr(pt, name, offset);
+	if (!type)
+		return -1;
+
+	/*
+	 * "reg" property:
+	 *
+	 * event offset where counter data gets accumulated
+	 */
+	dt_add_property_cells(type, "reg", offset, sizeof(u64));
+
+	/*
+	 * "id" property:
+	 *
+	 * event id to be appended to the event name. In some units like abus,
+	 * we have events such as abus0, abus1 and abus2. Since having numbers
+	 * in the dt node name are not suggested, we pass these numbers as
+	 * id peroperty.
+	 */
+	if (index >= 0)
+		 dt_add_property_cells(type, "id", index);
+
+	/*
+	 * "unit" and "scale" property:
+	 *
+	 * unit and scale properties, when used on raw counter value,
+	 * provide metric information.
+	 */
+	if (unit)
+		dt_add_property_string(type, "unit", unit);
+
+	if (scale)
+		dt_add_property_string(type, "scale", scale);
+
+	return 0;
+}
+
+static int dt_create_nest_mcs_node(struct dt_node *type,
+				struct nest_catalog_group_data *gptr)
+{
+	int idx;
+	u32 offset;
+	const char *unit = "MiB", *scale = "1.2207e-4";
+
+	for (idx = 0; idx < (gptr->event_count); idx++) {
+		offset = get_chip_event_offset(gptr->event_index[idx],
+								DOMAIN_CHIP);
+		if (dt_create_nest_unit_events(type, idx, offset, "mcs", scale, unit))
+			return -1;
+	}
+
+	return 0;
+}
+
 /*
  * Wrapper function to call corresponding nest unit functions
  * for event dt creation. Not all the chip groups in the catalog are
@@ -84,7 +169,26 @@ dt_add_device_node(struct dt_node *ptr, const char *name)
 static int dt_create_nest_unit(struct dt_node *ima,
 				struct nest_catalog_group_data *gptr, int id)
 {
+	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_Read_BW")) {
+		if (dt_create_nest_mcs_node(ima, gptr))
+			goto out;
+	} else if (strstr(name, "MCS_Write_BW")) {
+		if (dt_create_nest_mcs_node(ima, gptr))
+			goto out;
+	} else
+		free(name);
+
+	return OPAL_SUCCESS;
+out:
+	free(name);
+	return OPAL_RESOURCE;
 }
 
 static void update_catalog_to_devices(struct nest_catalog_group_data *gptr)
-- 
1.9.1



More information about the Skiboot mailing list