[Skiboot] [PATCH v7 4/9] Catalog parser function to detect Nest units
Madhavan Srinivasan
maddy at linux.vnet.ibm.com
Tue Mar 1 21:40:28 AEDT 2016
Catalog have "group" structure to group events with similiar functions.
All the events within a group will be from same nest unit or domain.
A Nest unit can have multiple groups for its events in the catalog.
But, device tree will have only one dt node for a nest unit and all the
events supported by that nest unit should end up under it.
Two data structures are added:
1)struct "map_grp_name_to_dt_name"
2)struct "catalog_grp_to_dt_node"
Function detect_nest_units(), scans all the chip groups in the
catalog file and passes each chip group to add_grp_to_nest_unit_table().
add_grp_to_nest_unit_table() routine using lookup table identify the
group to a nest unit. Function then save the group address in
the "catalog_grp_to_dt_node" structure under the identified nest unit.
Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
---
hw/nest.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/nest.h | 28 +++++++++++++++++++++
2 files changed, 107 insertions(+)
diff --git a/hw/nest.c b/hw/nest.c
index 46d930384649..71ef52211db5 100644
--- a/hw/nest.c
+++ b/hw/nest.c
@@ -33,6 +33,24 @@
struct nest_catalog_desc *catalog_desc;
/*
+ * Lookup table to map the catalog nest group to
+ * hardware nest unit.
+ */
+struct map_grp_name_to_dt_name lookup_table[] = {
+ {"PowerBus", "powerbus", 8, POWERBUS},
+ {"Pumps_and_Retries", "powerbus", 17, POWERBUS},
+ {"MCS_Read", "mcs", 8, MCS},
+ {"MCS_Write", "mcs", 9, MCS},
+ {"X-link", "xbus", 6, XBUS},
+ {"A-link", "abus", 6, ABUS},
+};
+
+/*
+ * Structure to hold catalog groups information for each nest unit
+ */
+struct catalog_grp_to_dt_node dev_grp_map[NEST_DT_DEVICE_MAX];
+
+/*
* Catalog Page-0 (each page is 4K bytes long) contains
* information about event, group, formula structure offsets
* in the catalog. Cache these offsets in struct nest_catalog_page_0
@@ -40,6 +58,60 @@ struct nest_catalog_desc *catalog_desc;
*/
struct nest_catalog_page_0 *page0_desc;
+static void add_grp_to_nest_unit_table(struct nest_catalog_group_data *gptr)
+{
+ int i, rc, unit, cnt;
+ int len;
+
+ for (i = 0; i < NEST_DT_DEVICE_MAX; i++) {
+ len = lookup_table[i].length;
+ if (len > gptr->group_name_len)
+ len = gptr->group_name_len;
+
+ rc = strncmp(gptr->remainder, lookup_table[i].catalog_grp_name, len);
+ if (!rc) {
+ unit = lookup_table[i].unit_id;
+ cnt = dev_grp_map[unit].grp_count;
+ dev_grp_map[unit].groups[cnt] = (u64) gptr;
+ dev_grp_map[unit].grp_count++;
+
+ /*
+ * Link the device name if not linked already.
+ * This is needed when creating the device tree.
+ */
+ if (!dev_grp_map[unit].nest_unit_name)
+ dev_grp_map[unit].nest_unit_name = lookup_table[i].dt_unit_name;
+ }
+ }
+}
+
+static int detect_nest_units(struct dt_node *ima)
+{
+ struct nest_catalog_group_data *group;
+ char *marker;
+ int rc = 0;
+
+ /*
+ * Scan all available groups in the chip domain from
+ * the CATALOG and update the catalog_grp_to_dt_node table.
+ * Note that 1) Catalog can have multiple groups for a
+ * same nest unit. 2) All the events for a nest unit should end up
+ * in the same dt node even though they are placed in different groups.
+ * ex. Catalog could have groups like "X-link_data" and "X-link_idle",
+ * but events from both these groups should end up in the device tree
+ * node of "xbus".
+ */
+ marker = CHIP_GROUP_ENTRY(catalog_desc);
+ group = (struct nest_catalog_group_data *)marker;
+ while (group->domain == DOMAIN_CHIP) {
+ add_grp_to_nest_unit_table(group);
+ marker += group->length;
+ group = (struct nest_catalog_group_data *)marker;
+ };
+
+ return rc;
+}
+
int preload_catalog_lid()
{
struct proc_chip *chip = get_chip(this_cpu()->chip_id);
@@ -177,6 +249,13 @@ void nest_pmu_init(int loaded)
dt_add_property_cells(chip_dev, "#size-cells", 1);
dt_add_property_cells(chip_dev, "ranges", 0, hi32(addr),
lo32(addr), SLW_IMA_SIZE);
+
+ /*
+ * Call catalog parser to create nest unit dt nodes and
+ * add events to it.
+ */
+ if (detect_nest_units(chip_dev))
+ goto fail;
}
return;
diff --git a/include/nest.h b/include/nest.h
index 4fbaa41b4e0b..e5187a985fe1 100644
--- a/include/nest.h
+++ b/include/nest.h
@@ -204,6 +204,34 @@ struct nest_catalog_desc {
/* Size of Nest Catalog LID (256KBytes) */
#define NEST_CATALOG_SIZE 0x40000
+/* Max number of groups for a nest unit in catalog */
+#define MAX_CATALOG_GROUPS_PER_NEST_UNIT 5
+
+/*
+ * If new nest units are added to catalog then append to the enum.
+ */
+enum nest_unit_id {
+ POWERBUS,
+ MCS,
+ XBUS,
+ ABUS,
+ NEST_DT_DEVICE_MAX,
+};
+
+struct map_grp_name_to_dt_name {
+ char catalog_grp_name[32];
+ char dt_unit_name[32];
+ u32 length;
+ u32 unit_id;
+};
+
+struct catalog_grp_to_dt_node {
+ char *nest_unit_name;
+ u64 groups[MAX_CATALOG_GROUPS_PER_NEST_UNIT];
+ u32 grp_count;
+ struct dt_node *dt_node;
+};
+
/*
* Function prototypes
*/
--
1.9.1
More information about the Skiboot
mailing list