aboutsummaryrefslogtreecommitdiff
path: root/platforms
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-08-20 11:29:29 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-09-01 16:18:35 +1000
commit9fb3a04fd25d18b4865e44d461e6a8993b7717a0 (patch)
tree56d2eefbb6c5893aa468ab087ad8ac38fcdbef19 /platforms
parent58ccf6a977ade80e4475d7d350c4c076ab1accad (diff)
downloadskiboot-9fb3a04fd25d18b4865e44d461e6a8993b7717a0.zip
skiboot-9fb3a04fd25d18b4865e44d461e6a8993b7717a0.tar.gz
skiboot-9fb3a04fd25d18b4865e44d461e6a8993b7717a0.tar.bz2
plat/bmc: Add infrastructure for slot tables
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@kernel.crashing.org> [stewart@linux.vnet.ibm.com: add IBM (C) in new file, trim trailing whitespace] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'platforms')
-rw-r--r--platforms/astbmc/Makefile.inc2
-rw-r--r--platforms/astbmc/astbmc.h18
-rw-r--r--platforms/astbmc/slots.c100
3 files changed, 119 insertions, 1 deletions
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..2144112
--- /dev/null
+++ b/platforms/astbmc/slots.c
@@ -0,0 +1,100 @@
+/* Copyright 2015 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#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;
+}