[Skiboot] [PATCH v6 4/9] Catalog parser function to detect Nest units
Madhavan Srinivasan
maddy at linux.vnet.ibm.com
Fri Feb 19 03:45:12 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 node for a nest units and all the
events supported by that nest units should end up under it.
Two data structures are added:
1)struct "lookup_grp_name_to_device_name"
2)struct "nest_catalog_grps_device"
Function detect_nest_units(), scans all the chip groups in the
catalog file and passes each chip group to update_catalog_to_devices().
update_catalog_to_devices() routine using lookup table identify the
group to a nest unit. Function then save the group address in
the "nest_catalog_grps_device" structure under the identified nest unit.
Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
---
hw/nest.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/nest.h | 29 +++++++++++++++++++++
2 files changed, 108 insertions(+)
diff --git a/hw/nest.c b/hw/nest.c
index 4aa5fa0e5332..23a61d80f101 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 lookup_grp_name_to_device_name lookup_table[] = {
+ {"PowerBus", "powerbus", 8, POWERBUS},
+ {"Pumps_and_Retries", "powerbus", 17, POWERBUS},
+ {"MCS_Read", "mcs_read",8, MCS_READ},
+ {"MCS_Write", "mcs_write", 9, MCS_WRITE},
+ {"X-link", "xbus", 6, XBUS},
+ {"A-link", "abus", 6, ABUS},
+};
+
+/*
+ * Structure to hold catalog groups information for each nest unit
+ */
+struct nest_catalog_grps_device 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 update_catalog_to_devices(struct nest_catalog_group_data *gptr)
+{
+ int i, rc, dev_id, 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) {
+ dev_id = lookup_table[i].devices_id;
+ cnt = dev_grp_map[dev_id].nest_device_grps_cnt;
+ dev_grp_map[dev_id].grp_ptr_arr[cnt] = (u64) gptr;
+ dev_grp_map[dev_id].nest_device_grps_cnt++;
+
+ /*
+ * Link the device name if not linked already.
+ * This is needed when creating the device tree.
+ */
+ if (!dev_grp_map[dev_id].name)
+ dev_grp_map[dev_id].name = lookup_table[i].dt_device_name;
+ }
+ }
+}
+
+static int detect_nest_units(struct dt_node *ima)
+{
+ struct nest_catalog_group_data *group_ptr;
+ char *marker;
+ int rc = 0;
+
+ /*
+ * Scan all available groups in the chip domain from
+ * the CATALOG and update the nest_catalog_grps_device struct.
+ * Reason for this 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_ptr = (struct nest_catalog_group_data *)marker;
+ while(group_ptr->domain == DOMAIN_CHIP) {
+ update_catalog_to_devices(group_ptr);
+ marker += group_ptr->length;
+ group_ptr = (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);
+
+ /*
+ * Now parse catalog and add nest units and their events
+ * to the device tree.
+ */
+ if (detect_nest_units(chip_dev))
+ goto fail;
}
return;
diff --git a/include/nest.h b/include/nest.h
index a27907fdf62a..b464e5b72c0e 100644
--- a/include/nest.h
+++ b/include/nest.h
@@ -204,6 +204,35 @@ struct nest_catalog_desc {
/*Size of Nest Catalog LID (256KBytes) */
#define NEST_CATALOG_SIZE 0x40000
+/* Max number of groups for a nest units in catalog */
+#define MAX_GRPS_PER_DEVICE 5
+
+/*
+ * If new nest units are added to catalog then append to the enum.
+ */
+enum nest_dt_devices {
+ POWERBUS,
+ MCS_READ,
+ MCS_WRITE,
+ XBUS,
+ ABUS,
+ NEST_DT_DEVICE_MAX,
+};
+
+struct lookup_grp_name_to_device_name {
+ char catalog_grp_name[32];
+ char dt_device_name[32];
+ u32 length;
+ u32 devices_id;
+};
+
+struct nest_catalog_grps_device {
+ char *name;
+ u64 grp_ptr_arr[MAX_GRPS_PER_DEVICE];
+ u32 nest_device_grps_cnt;
+ struct dt_node *ptr;
+};
+
/*
* Function prototypes
*/
--
1.9.1
More information about the Skiboot
mailing list