[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