[Skiboot] [RFC PATCH 4/5] plat/bmc: Add infrastructure for slot tables

Benjamin Herrenschmidt benh at kernel.crashing.org
Thu Aug 20 11:29:29 AEST 2015


This adds some basic infrastructure for simple slot tables allowing
us to name slots and built-in devices on OPP machines.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 platforms/astbmc/Makefile.inc |  2 +-
 platforms/astbmc/astbmc.h     | 18 +++++++++
 platforms/astbmc/slots.c      | 85 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+), 1 deletion(-)
 create mode 100644 platforms/astbmc/slots.c

diff --git a/platforms/astbmc/Makefile.inc b/platforms/astbmc/Makefile.inc
index d0151d2..8c749e8 100644
--- a/platforms/astbmc/Makefile.inc
+++ b/platforms/astbmc/Makefile.inc
@@ -1,6 +1,6 @@
 SUBDIRS += $(PLATDIR)/astbmc
 
-ASTBMC_OBJS = palmetto.o habanero.o firestone.o garrison.o pnor.o common.o
+ASTBMC_OBJS = palmetto.o habanero.o firestone.o garrison.o pnor.o common.o slots.o
 ASTBMC = $(PLATDIR)/astbmc/built-in.o
 $(ASTBMC): $(ASTBMC_OBJS:%=$(PLATDIR)/astbmc/%)
 
diff --git a/platforms/astbmc/astbmc.h b/platforms/astbmc/astbmc.h
index 489ffd2..23c31c7 100644
--- a/platforms/astbmc/astbmc.h
+++ b/platforms/astbmc/astbmc.h
@@ -18,6 +18,21 @@
 #ifndef __ASTBMC_H
 #define __ASTBMC_H
 
+#define ST_LOC_PHB(chip_id, phb_idx)    ((chip_id) << 16 | (phb_idx))
+#define ST_LOC_DEVFN(dev, fn)	        ((dev) << 3 | (fn))
+
+struct slot_table_entry {
+	enum slot_table_etype {
+		st_end,		/* End of list */
+		st_phb,
+		st_pluggable_slot,
+		st_builtin_dev,
+	} etype;
+	uint32_t location;
+	const char *name;
+	const struct slot_table_entry *children;
+};
+
 extern void astbmc_early_init(void);
 extern int64_t astbmc_ipmi_reboot(void);
 extern int64_t astbmc_ipmi_power_down(uint64_t request);
@@ -25,4 +40,7 @@ extern void astbmc_init(void);
 extern void astbmc_ext_irq_serirq_cpld(unsigned int chip_id);
 extern int pnor_init(void);
 
+extern void slot_table_init(const struct slot_table_entry *top_table);
+extern void slot_table_get_slot_info(struct phb *phb, struct pci_device * pd);
+
 #endif /* __ASTBMC_H */
diff --git a/platforms/astbmc/slots.c b/platforms/astbmc/slots.c
new file mode 100644
index 0000000..a3aa476
--- /dev/null
+++ b/platforms/astbmc/slots.c
@@ -0,0 +1,85 @@
+#include <skiboot.h>
+#include <device.h>
+#include <console.h>
+#include <chip.h>
+#include <pci.h>
+
+#include "astbmc.h"
+
+static const struct slot_table_entry *slot_top_table;
+
+void slot_table_init(const struct slot_table_entry *top_table)
+{
+	slot_top_table = top_table;
+}
+
+static const struct slot_table_entry *match_slot_phb_entry(struct phb *phb)
+{
+	uint32_t chip_id = dt_get_chip_id(phb->dt_node);
+	uint32_t phb_idx = dt_prop_get_u32_def(phb->dt_node,
+					       "ibm,phb-index", 0);
+	const struct slot_table_entry *ent;
+
+	if (!slot_top_table)
+		return NULL;
+
+	for (ent = slot_top_table; ent->etype != st_end; ent++) {
+		if (ent->etype != st_phb) {
+			prerror("SLOT: Bad DEV entry type in table !\n");
+			continue;
+		}
+		if (ent->location == ST_LOC_PHB(chip_id, phb_idx))
+			return ent;
+	}
+	return NULL;
+}
+
+static const struct slot_table_entry *match_slot_dev_entry(struct phb *phb,
+							 struct pci_device *pd)
+{
+	const struct slot_table_entry *parent, *ent;
+
+	/* Find a parent recursively */
+	if (pd->parent)
+		parent = match_slot_dev_entry(phb, pd->parent);
+	else {
+		/* No parent, this is a root complex, find the PHB */
+		parent = match_slot_phb_entry(phb);
+	}
+	/* No parent ? Oops ... */
+	if (!parent || !parent->children)
+		return NULL;
+	for (ent = parent->children; ent->etype != st_end; ent++) {
+		if (ent->etype == st_phb) {
+			prerror("SLOT: Bad PHB entry type in table !\n");
+			continue;
+		}
+		if (ent->location == (pd->bdfn & 0xff))
+			return ent;
+	}
+	return NULL;
+}
+
+void slot_table_get_slot_info(struct phb *phb, struct pci_device * pd)
+{
+	const struct slot_table_entry *ent;
+	struct pci_slot_info *si;
+	
+	if (!pd || pd->slot_info)
+		return;
+	ent = match_slot_dev_entry(phb, pd);
+	if (!ent || !ent->name)
+		return;
+	pd->slot_info = si = zalloc(sizeof(struct pci_slot_info));
+	assert(pd->slot_info);	
+	strncpy(si->label, ent->name, sizeof(si->label) - 1);
+	si->pluggable = ent->etype == st_pluggable_slot;
+	si->power_ctl = false;
+	si->wired_lanes = -1;
+	si->bus_clock = -1;
+	si->connector_type = -1;
+	si->card_desc = -1;
+	si->card_mech = -1;
+	si->pwr_led_ctl = -1;
+	si->attn_led_ctl = -1;
+}
-- 
2.4.3



More information about the Skiboot mailing list