summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/mv/mv_pci.c55
-rw-r--r--sys/dev/fdt/fdt_common.h10
-rw-r--r--sys/dev/fdt/fdt_pci.c367
-rw-r--r--sys/dev/ofw/ofw_bus_subr.c15
-rw-r--r--sys/dev/ofw/ofw_bus_subr.h2
-rw-r--r--sys/dev/ofw/ofw_fdt.c18
-rw-r--r--sys/dev/uart/uart_cpu_powerpc.c4
-rw-r--r--sys/powerpc/aim/trap_subr32.S3
-rw-r--r--sys/powerpc/aim/trap_subr64.S3
-rw-r--r--sys/powerpc/booke/platform_bare.c8
-rw-r--r--sys/powerpc/include/fdt.h8
-rw-r--r--sys/powerpc/include/ofw_machdep.h2
-rw-r--r--sys/powerpc/mpc85xx/platform_mpc85xx.c8
-rw-r--r--sys/powerpc/ofw/ofw_machdep.c236
-rw-r--r--sys/powerpc/ofw/ofw_pci.c17
-rw-r--r--sys/powerpc/ofw/ofw_pcib_pci.c17
-rw-r--r--sys/powerpc/powermac/platform_powermac.c60
-rw-r--r--sys/powerpc/powerpc/copyinout.c12
-rw-r--r--sys/powerpc/powerpc/platform.c94
-rw-r--r--sys/powerpc/powerpc/platform_if.m4
-rw-r--r--sys/powerpc/ps3/platform_ps3.c60
-rw-r--r--sys/powerpc/pseries/platform_chrp.c106
-rw-r--r--sys/powerpc/wii/platform_wii.c15
-rw-r--r--sys/sparc64/ebus/ebus.c3
-rw-r--r--sys/sparc64/isa/ofw_isa.c3
-rw-r--r--sys/sparc64/pci/fire.c3
-rw-r--r--sys/sparc64/pci/ofw_pcib_subr.c3
-rw-r--r--sys/sparc64/pci/psycho.c3
-rw-r--r--sys/sparc64/pci/schizo.c3
29 files changed, 388 insertions, 754 deletions
diff --git a/sys/arm/mv/mv_pci.c b/sys/arm/mv/mv_pci.c
index f708b90..ff12974 100644
--- a/sys/arm/mv/mv_pci.c
+++ b/sys/arm/mv/mv_pci.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_pci.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@@ -142,7 +143,7 @@ struct mv_pcib_softc {
int sc_type;
int sc_mode; /* Endpoint / Root Complex */
- struct fdt_pci_intr sc_intr_info;
+ struct ofw_bus_iinfo sc_pci_iinfo;
};
/* Local forward prototypes */
@@ -155,7 +156,6 @@ static void mv_pcib_hw_cfgwrite(struct mv_pcib_softc *, u_int, u_int,
static int mv_pcib_init(struct mv_pcib_softc *, int, int);
static int mv_pcib_init_all_bars(struct mv_pcib_softc *, int, int, int, int);
static void mv_pcib_init_bridge(struct mv_pcib_softc *, int, int, int);
-static int mv_pcib_intr_info(phandle_t, struct mv_pcib_softc *);
static inline void pcib_write_irq_mask(struct mv_pcib_softc *, uint32_t);
static void mv_pcib_enable(struct mv_pcib_softc *, uint32_t);
static int mv_pcib_mem_init(struct mv_pcib_softc *);
@@ -243,8 +243,8 @@ mv_pcib_probe(device_t self)
if (!fdt_is_type(node, "pci"))
return (ENXIO);
- if (!(fdt_is_compatible(node, "mrvl,pcie") ||
- fdt_is_compatible(node, "mrvl,pci")))
+ if (!(ofw_bus_is_compatible(self, "mrvl,pcie") ||
+ ofw_bus_is_compatible(self, "mrvl,pci")))
return (ENXIO);
device_set_desc(self, "Marvell Integrated PCI/PCI-E Controller");
@@ -299,11 +299,8 @@ mv_pcib_attach(device_t self)
/*
* Get PCI interrupt info.
*/
- if ((sc->sc_mode == MV_MODE_ROOT) &&
- (mv_pcib_intr_info(node, sc) != 0)) {
- device_printf(self, "could not retrieve interrupt info\n");
- return (ENXIO);
- }
+ if (sc->sc_mode == MV_MODE_ROOT)
+ ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(pcell_t));
/*
* Configure decode windows for PCI(E) access.
@@ -881,19 +878,32 @@ mv_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func,
}
static int
-mv_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
+mv_pcib_route_interrupt(device_t bus, device_t dev, int pin)
{
struct mv_pcib_softc *sc;
- int err, interrupt;
+ struct ofw_pci_register reg;
+ uint32_t pintr, mintr;
+ phandle_t iparent;
+
+ sc = device_get_softc(bus);
+ pintr = pin;
+
+ /* Fabricate imap information in case this isn't an OFW device */
+ bzero(&reg, sizeof(reg));
+ reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) |
+ (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
+ (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
- sc = device_get_softc(pcib);
+ if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
+ sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
+ &iparent))
+ return (ofw_bus_map_intr(dev, iparent, mintr));
- err = fdt_pci_route_intr(pci_get_bus(dev), pci_get_slot(dev),
- pci_get_function(dev), pin, &sc->sc_intr_info, &interrupt);
- if (err == 0)
- return (interrupt);
+ /* Maybe it's a real interrupt, not an intpin */
+ if (pin > 4)
+ return (pin);
- device_printf(pcib, "could not route pin %d for device %d.%d\n",
+ device_printf(bus, "could not route pin %d for device %d.%d\n",
pin, pci_get_slot(dev), pci_get_function(dev));
return (PCI_INVALID_IRQ);
}
@@ -938,17 +948,6 @@ mv_pcib_decode_win(phandle_t node, struct mv_pcib_softc *sc)
return (0);
}
-static int
-mv_pcib_intr_info(phandle_t node, struct mv_pcib_softc *sc)
-{
- int error;
-
- if ((error = fdt_pci_intr_info(node, &sc->sc_intr_info)) != 0)
- return (error);
-
- return (0);
-}
-
#if defined(SOC_MV_ARMADAXP)
static int
mv_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr,
diff --git a/sys/dev/fdt/fdt_common.h b/sys/dev/fdt/fdt_common.h
index 8c16257..499d1f8 100644
--- a/sys/dev/fdt/fdt_common.h
+++ b/sys/dev/fdt/fdt_common.h
@@ -47,14 +47,6 @@ struct fdt_pci_range {
u_long len;
};
-struct fdt_pci_intr {
- int addr_cells;
- int intr_cells;
- int map_len;
- pcell_t *map;
- pcell_t *mask;
-};
-
struct fdt_sense_level {
enum intr_trigger trig;
enum intr_polarity pol;
@@ -110,11 +102,9 @@ int fdt_is_enabled(phandle_t);
int fdt_pm_is_enabled(phandle_t);
int fdt_is_type(phandle_t, const char *);
int fdt_parent_addr_cells(phandle_t);
-int fdt_pci_intr_info(phandle_t, struct fdt_pci_intr *);
int fdt_pci_ranges(phandle_t, struct fdt_pci_range *, struct fdt_pci_range *);
int fdt_pci_ranges_decode(phandle_t, struct fdt_pci_range *,
struct fdt_pci_range *);
-int fdt_pci_route_intr(int, int, int, int, struct fdt_pci_intr *, int *);
int fdt_ranges_verify(pcell_t *, int, int, int, int);
int fdt_reg_to_rl(phandle_t, struct resource_list *);
int fdt_pm(phandle_t);
diff --git a/sys/dev/fdt/fdt_pci.c b/sys/dev/fdt/fdt_pci.c
index fae5f07..d4f4b6c 100644
--- a/sys/dev/fdt/fdt_pci.c
+++ b/sys/dev/fdt/fdt_pci.c
@@ -180,159 +180,6 @@ fdt_pci_ranges(phandle_t node, struct fdt_pci_range *io_space,
return (0);
}
-static int
-fdt_addr_cells(phandle_t node, int *addr_cells)
-{
- pcell_t cell;
- int cell_size;
-
- cell_size = sizeof(cell);
- if (OF_getprop(node, "#address-cells", &cell, cell_size) < cell_size)
- return (EINVAL);
- *addr_cells = fdt32_to_cpu((int)cell);
-
- if (*addr_cells > 3)
- return (ERANGE);
- return (0);
-}
-
-static int
-fdt_interrupt_cells(phandle_t node)
-{
- pcell_t intr_cells;
-
- if (OF_getprop(node, "#interrupt-cells", &intr_cells,
- sizeof(intr_cells)) <= 0) {
- debugf("no intr-cells defined, defaulting to 1\n");
- intr_cells = 1;
- }
- intr_cells = fdt32_to_cpu(intr_cells);
-
- return ((int)intr_cells);
-}
-
-int
-fdt_pci_intr_info(phandle_t node, struct fdt_pci_intr *intr_info)
-{
- void *map, *mask;
- int acells, icells;
- int error, len;
-
- error = fdt_addr_cells(node, &acells);
- if (error)
- return (error);
-
- icells = fdt_interrupt_cells(node);
-
- /*
- * Retrieve the interrupt map and mask properties.
- */
- len = OF_getprop_alloc(node, "interrupt-map-mask", 1, &mask);
- if (len / sizeof(pcell_t) != (acells + icells)) {
- debugf("bad mask len = %d\n", len);
- goto err;
- }
-
- len = OF_getprop_alloc(node, "interrupt-map", 1, &map);
- if (len <= 0) {
- debugf("bad map len = %d\n", len);
- goto err;
- }
-
- intr_info->map_len = len;
- intr_info->map = map;
- intr_info->mask = mask;
- intr_info->addr_cells = acells;
- intr_info->intr_cells = icells;
-
- debugf("acells=%u, icells=%u, map_len=%u\n", acells, icells, len);
- return (0);
-
-err:
- free(mask, M_OFWPROP);
- return (ENXIO);
-}
-
-int
-fdt_pci_route_intr(int bus, int slot, int func, int pin,
- struct fdt_pci_intr *intr_info, int *interrupt)
-{
- pcell_t child_spec[4], masked[4];
- phandle_t iph;
- pcell_t intr_par;
- pcell_t *map_ptr;
- uint32_t addr;
- int i, j, map_len;
- int par_intr_cells, par_addr_cells, child_spec_cells, row_cells;
- int par_idx, spec_idx, err, trig, pol;
-
- child_spec_cells = intr_info->addr_cells + intr_info->intr_cells;
- if (child_spec_cells > sizeof(child_spec) / sizeof(pcell_t))
- return (ENOMEM);
-
- addr = (bus << 16) | (slot << 11) | (func << 8);
- child_spec[0] = addr;
- child_spec[1] = 0;
- child_spec[2] = 0;
- child_spec[3] = pin;
-
- map_len = intr_info->map_len;
- map_ptr = intr_info->map;
-
- par_idx = child_spec_cells;
- i = 0;
- while (i < map_len) {
- iph = fdt32_to_cpu(map_ptr[par_idx]);
- intr_par = OF_xref_phandle(iph);
-
- err = fdt_addr_cells(intr_par, &par_addr_cells);
- if (err != 0) {
- debugf("could not retrieve intr parent #addr-cells\n");
- return (err);
- }
- par_intr_cells = fdt_interrupt_cells(intr_par);
-
- row_cells = child_spec_cells + 1 + par_addr_cells +
- par_intr_cells;
-
- /*
- * Apply mask and look up the entry in interrupt map.
- */
- for (j = 0; j < child_spec_cells; j++) {
- masked[j] = child_spec[j] &
- fdt32_to_cpu(intr_info->mask[j]);
-
- if (masked[j] != fdt32_to_cpu(map_ptr[j]))
- goto next;
- }
-
- /*
- * Decode interrupt of the parent intr controller.
- */
- spec_idx = child_spec_cells + 1 + par_addr_cells;
- err = fdt_intr_decode(intr_par, &map_ptr[spec_idx],
- interrupt, &trig, &pol);
- if (err != 0) {
- debugf("could not decode interrupt\n");
- return (err);
- }
- debugf("decoded intr = %d, trig = %d, pol = %d\n", *interrupt,
- trig, pol);
-
-#if defined(__powerpc__)
- powerpc_config_intr(FDT_MAP_IRQ(iph, *interrupt), trig,
- pol);
-#endif
- return (0);
-
-next:
- map_ptr += row_cells;
- i += (row_cells * sizeof(pcell_t));
- }
-
- return (ENXIO);
-}
-
#if defined(__arm__)
int
fdt_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap, vm_offset_t io_va,
@@ -360,217 +207,3 @@ fdt_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap, vm_offset_t io_v
}
#endif
-#if 0
-static int
-fdt_pci_config_bar(device_t dev, int bus, int slot, int func, int bar)
-{
-}
-
-static int
-fdt_pci_config_normal(device_t dev, int bus, int slot, int func)
-{
- int bar;
- uint8_t command, intline, intpin;
-
- command = PCIB_READ_CONFIG(dev, bus, slot, func, PCIR_COMMAND, 1);
- command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
- PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
-
- /* Program the base address registers. */
- bar = 0;
- while (bar <= PCIR_MAX_BAR_0)
- bar += fdt_pci_config_bar(dev, bus, slot, func, bar);
-
- /* Perform interrupt routing. */
- intpin = PCIB_READ_CONFIG(dev, bus, slot, func, PCIR_INTPIN, 1);
- intline = fsl_pcib_route_int(dev, bus, slot, func, intpin);
- PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_INTLINE, intline, 1);
-
- command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
- PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
-}
-
-static int
-fdt_pci_config_bridge(device_t dev, int bus, int secbus, int slot, int func)
-{
- int maxbar;
- uint8_t command;
-
- command = PCIB_READ_CONFIG(dev, bus, slot, func, PCIR_COMMAND, 1);
- command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
- PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
-
- /* Program the base address registers. */
- maxbar = (hdrtype & PCIM_HDRTYPE) ? 1 : 6;
- bar = 0;
- while (bar < maxbar)
- bar += fsl_pcib_init_bar(sc, bus, slot, func,
- bar);
-
- /* Perform interrupt routing. */
- intpin = fsl_pcib_read_config(sc->sc_dev, bus, slot,
- func, PCIR_INTPIN, 1);
- intline = fsl_pcib_route_int(sc, bus, slot, func,
- intpin);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_INTLINE, intline, 1);
-
- command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_COMMAND, command, 1);
-
- /*
- * Handle PCI-PCI bridges
- */
- class = fsl_pcib_read_config(sc->sc_dev, bus, slot,
- func, PCIR_CLASS, 1);
- subclass = fsl_pcib_read_config(sc->sc_dev, bus, slot,
- func, PCIR_SUBCLASS, 1);
-
- /* Allow only proper PCI-PCI briges */
- if (class != PCIC_BRIDGE)
- continue;
- if (subclass != PCIS_BRIDGE_PCI)
- continue;
-
- secbus++;
-
- /* Program I/O decoder. */
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_IOBASEL_1, sc->sc_ioport.rm_start >> 8, 1);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_IOLIMITL_1, sc->sc_ioport.rm_end >> 8, 1);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_IOBASEH_1, sc->sc_ioport.rm_start >> 16, 2);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_IOLIMITH_1, sc->sc_ioport.rm_end >> 16, 2);
-
- /* Program (non-prefetchable) memory decoder. */
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_MEMBASE_1, sc->sc_iomem.rm_start >> 16, 2);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_MEMLIMIT_1, sc->sc_iomem.rm_end >> 16, 2);
-
- /* Program prefetchable memory decoder. */
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_PMBASEL_1, 0x0010, 2);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_PMLIMITL_1, 0x000f, 2);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_PMBASEH_1, 0x00000000, 4);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_PMLIMITH_1, 0x00000000, 4);
-
- /* Read currect bus register configuration */
- old_pribus = fsl_pcib_read_config(sc->sc_dev, bus,
- slot, func, PCIR_PRIBUS_1, 1);
- old_secbus = fsl_pcib_read_config(sc->sc_dev, bus,
- slot, func, PCIR_SECBUS_1, 1);
- old_subbus = fsl_pcib_read_config(sc->sc_dev, bus,
- slot, func, PCIR_SUBBUS_1, 1);
-
- if (bootverbose)
- printf("PCI: reading firmware bus numbers for "
- "secbus = %d (bus/sec/sub) = (%d/%d/%d)\n",
- secbus, old_pribus, old_secbus, old_subbus);
-
- new_pribus = bus;
- new_secbus = secbus;
-
- secbus = fsl_pcib_init(sc, secbus,
- (subclass == PCIS_BRIDGE_PCI) ? PCI_SLOTMAX : 0);
-
- new_subbus = secbus;
-
- if (bootverbose)
- printf("PCI: translate firmware bus numbers "
- "for secbus %d (%d/%d/%d) -> (%d/%d/%d)\n",
- secbus, old_pribus, old_secbus, old_subbus,
- new_pribus, new_secbus, new_subbus);
-
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_PRIBUS_1, new_pribus, 1);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_SECBUS_1, new_secbus, 1);
- fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
- PCIR_SUBBUS_1, new_subbus, 1);
-
-}
-
-static int
-fdt_pci_config_slot(device_t dev, int bus, int secbus, int slot)
-{
- int func, maxfunc;
- uint16_t vendor;
- uint8_t hdrtype;
-
- maxfunc = 0;
- for (func = 0; func <= maxfunc; func++) {
- hdrtype = PCIB_READ_CONFIG(dev, bus, slot, func,
- PCIR_HDRTYPE, 1);
- if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
- continue;
- if (func == 0 && (hdrtype & PCIM_MFDEV))
- maxfunc = PCI_FUNCMAX;
-
- vendor = PCIB_READ_CONFIG(dev, bus, slot, func,
- PCIR_VENDOR, 2);
- if (vendor == 0xffff)
- continue;
-
- if ((hdrtype & PCIM_HDRTYPE) == PCIM_HDRTYPE_NORMAL)
- fdt_pci_config_normal(dev, bus, slot, func);
- else
- secbus = fdt_pci_config_bridge(dev, bus, secbus,
- slot, func);
- }
-
- return (secbus);
-}
-
-static int
-fdt_pci_config_bus(device_t dev, int bus, int maxslot)
-{
- int func, maxfunc, secbus, slot;
-
- secbus = bus;
- for (slot = 0; slot <= maxslot; slot++)
- secbus = fdt_pci_config_slot(dev, bus, secbus, slot);
-
- return (secbus);
-}
-
-int
-fdt_pci_config_domain(device_t dev)
-{
- pcell_t bus_range[2];
- phandle_t root;
- int bus, error, maxslot;
-
- root = ofw_bus_get_node(dev);
- if (root == 0)
- return (EINVAL);
- if (!fdt_is_type(root, "pci"))
- return (EINVAL);
-
- /*
- * Determine the bus number of the root in this domain.
- * Lacking any information, this will be bus 0.
- * Write the bus number to the bus device, using the IVAR.
- */
- if ((OF_getprop(root, "bus-range", bus_range, sizeof(bus_range)) <= 0)
- bus = 0;
- else
- bus = fdt32_to_cpu(bus_range[0]);
-
- error = BUS_WRITE_IVAR(dev, NULL, PCIB_IVAR_BUS, bus);
- if (error)
- return (error);
-
- /* Get the maximum slot number for bus-enumeration. */
- maxslot = PCIB_MAXSLOTS(dev);
-
- bus = fdt_pci_config_bus(dev, bus, maxslot);
- return (0);
-}
-#endif
diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c
index 26a6759..bf552a8 100644
--- a/sys/dev/ofw/ofw_bus_subr.c
+++ b/sys/dev/ofw/ofw_bus_subr.c
@@ -251,8 +251,9 @@ ofw_bus_setup_iinfo(phandle_t node, struct ofw_bus_iinfo *ii, int intrsz)
int
ofw_bus_lookup_imap(phandle_t node, struct ofw_bus_iinfo *ii, void *reg,
int regsz, void *pintr, int pintrsz, void *mintr, int mintrsz,
- phandle_t *iparent, void *maskbuf)
+ phandle_t *iparent)
{
+ uint8_t maskbuf[regsz + pintrsz];
int rv;
if (ii->opi_imapsz <= 0)
@@ -285,7 +286,7 @@ ofw_bus_lookup_imap(phandle_t node, struct ofw_bus_iinfo *ii, void *reg,
* maskbuf must point to a buffer of length physsz + intrsz.
* The interrupt is returned in result, which must point to a buffer of length
* rintrsz (which gives the expected size of the mapped interrupt).
- * Returns 1 if a mapping was found, 0 otherwise.
+ * Returns number of cells in the interrupt if a mapping was found, 0 otherwise.
*/
int
ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
@@ -325,19 +326,13 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
tsz = physsz + intrsz + sizeof(phandle_t) + pintrsz;
KASSERT(i >= tsz, ("ofw_bus_search_intrmap: truncated map"));
- /*
- * XXX: Apple hardware uses a second cell to set information
- * on the interrupt trigger type. This information should
- * be used somewhere to program the PIC.
- */
-
if (bcmp(ref, mptr, physsz + intrsz) == 0) {
bcopy(mptr + physsz + intrsz + sizeof(parent),
- result, rintrsz);
+ result, MIN(rintrsz, pintrsz));
if (iparent != NULL)
*iparent = parent;
- return (1);
+ return (pintrsz/sizeof(pcell_t));
}
mptr += tsz;
i -= tsz;
diff --git a/sys/dev/ofw/ofw_bus_subr.h b/sys/dev/ofw/ofw_bus_subr.h
index 184ab07..e9ef5e4 100644
--- a/sys/dev/ofw/ofw_bus_subr.h
+++ b/sys/dev/ofw/ofw_bus_subr.h
@@ -68,7 +68,7 @@ bus_child_pnpinfo_str_t ofw_bus_gen_child_pnpinfo_str;
/* Routines for processing firmware interrupt maps */
void ofw_bus_setup_iinfo(phandle_t, struct ofw_bus_iinfo *, int);
int ofw_bus_lookup_imap(phandle_t, struct ofw_bus_iinfo *, void *, int,
- void *, int, void *, int, phandle_t *, void *);
+ void *, int, void *, int, phandle_t *);
int ofw_bus_search_intrmap(void *, int, void *, int, void *, int, void *,
void *, void *, int, phandle_t *);
diff --git a/sys/dev/ofw/ofw_fdt.c b/sys/dev/ofw/ofw_fdt.c
index b53bdab..617d2a3 100644
--- a/sys/dev/ofw/ofw_fdt.c
+++ b/sys/dev/ofw/ofw_fdt.c
@@ -207,7 +207,8 @@ static phandle_t
ofw_fdt_instance_to_package(ofw_t ofw, ihandle_t instance)
{
- return (-1);
+ /* Where real OF uses ihandles in the tree, FDT uses xref phandles */
+ return (OF_xref_phandle(instance));
}
/* Get the length of a property of a package. */
@@ -266,8 +267,10 @@ ofw_fdt_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf,
}
/*
- * Get the next property of a package. Return the actual len of retrieved
- * prop name.
+ * Get the next property of a package. Return values:
+ * -1: package or previous property does not exist
+ * 0: no more properties
+ * 1: success
*/
static int
ofw_fdt_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf,
@@ -309,7 +312,7 @@ ofw_fdt_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf,
strncpy(buf, fdt_string(fdtp, fdt32_to_cpu(prop->nameoff)), size);
- return (strlen(buf));
+ return (1);
}
/* Set the value of a property of a package. */
@@ -350,8 +353,13 @@ ofw_fdt_finddevice(ofw_t ofw, const char *device)
static ssize_t
ofw_fdt_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len)
{
+ phandle_t phandle;
- return (-1);
+ phandle = OF_instance_to_package(instance);
+ if (phandle == -1)
+ return (-1);
+
+ return (OF_package_to_path(phandle, buf, len));
}
/* Return the fully qualified pathname corresponding to a package. */
diff --git a/sys/dev/uart/uart_cpu_powerpc.c b/sys/dev/uart/uart_cpu_powerpc.c
index 44f6338..0791c77 100644
--- a/sys/dev/uart/uart_cpu_powerpc.c
+++ b/sys/dev/uart/uart_cpu_powerpc.c
@@ -89,13 +89,13 @@ ofw_get_console_phandle_path(phandle_t node, phandle_t *result,
return (ENXIO);
OF_getprop(node, prop, &field, sizeof(field));
- /* This property might be a phandle or might be a path. Hooray. */
+ /* This property might be either a ihandle or path. Hooray. */
output = -1;
if (field.buf[size - 1] == 0)
output = OF_finddevice(field.buf);
if (output == -1 && size == 4)
- output = OF_xref_phandle(field.ref);
+ output = OF_instance_to_package(field.ref);
if (output != -1) {
*result = output;
diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S
index 1eb35ec..fccca03 100644
--- a/sys/powerpc/aim/trap_subr32.S
+++ b/sys/powerpc/aim/trap_subr32.S
@@ -672,11 +672,12 @@ disitrap:
stw %r31,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1)
#ifdef KDB
- /* Try and detect a kernel stack overflow */
+ /* Try to detect a kernel stack overflow */
mfsrr1 %r31
mtcr %r31
bt 17,realtrap /* branch is user mode */
mfsprg1 %r31 /* get old SP */
+ clrrwi %r31,%r31,11 /* Round SP down to nearest page */
sub. %r30,%r31,%r30 /* SP - DAR */
bge 1f
neg %r30,%r30 /* modulo value */
diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S
index f05e30d..611a0ec 100644
--- a/sys/powerpc/aim/trap_subr64.S
+++ b/sys/powerpc/aim/trap_subr64.S
@@ -580,11 +580,12 @@ disitrap:
std %r31,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1)
#ifdef KDB
- /* Try and detect a kernel stack overflow */
+ /* Try to detect a kernel stack overflow */
mfsrr1 %r31
mtcr %r31
bt 17,realtrap /* branch is user mode */
mfsprg1 %r31 /* get old SP */
+ clrrdi %r31,%r31,11 /* Round SP down to nearest page */
sub. %r30,%r31,%r30 /* SP - DAR */
bge 1f
neg %r30,%r30 /* modulo value */
diff --git a/sys/powerpc/booke/platform_bare.c b/sys/powerpc/booke/platform_bare.c
index 7449732..c11620a 100644
--- a/sys/powerpc/booke/platform_bare.c
+++ b/sys/powerpc/booke/platform_bare.c
@@ -45,8 +45,8 @@ __FBSDID("$FreeBSD$");
extern uint32_t *bootinfo;
static int bare_probe(platform_t);
-static void bare_mem_regions(platform_t, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz);
+static void bare_mem_regions(platform_t, struct mem_region *phys, int *physsz,
+ struct mem_region *avail, int *availsz);
static u_long bare_timebase_freq(platform_t, struct cpuref *cpuref);
static void bare_reset(platform_t);
@@ -80,8 +80,8 @@ bare_probe(platform_t plat)
}
void
-bare_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz)
+bare_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
+ struct mem_region *avail, int *availsz)
{
ofw_mem_regions(phys, physsz, avail, availsz);
diff --git a/sys/powerpc/include/fdt.h b/sys/powerpc/include/fdt.h
index 116f562..955e3c7 100644
--- a/sys/powerpc/include/fdt.h
+++ b/sys/powerpc/include/fdt.h
@@ -35,15 +35,7 @@
#include <machine/bus.h>
#include <machine/intr_machdep.h>
-/* Max interrupt number */
-#define FDT_INTR_MAX INTR_VECTORS
-
/* Map phandle/intpin pair to global IRQ number */
#define FDT_MAP_IRQ(node, pin) powerpc_get_irq(node, pin)
-/*
- * Bus space tag. XXX endianess info needs to be derived from the blob.
- */
-#define fdtbus_bs_tag (&bs_be_tag)
-
#endif /* _MACHINE_FDT_H_ */
diff --git a/sys/powerpc/include/ofw_machdep.h b/sys/powerpc/include/ofw_machdep.h
index 023fa4c..0ee75f4 100644
--- a/sys/powerpc/include/ofw_machdep.h
+++ b/sys/powerpc/include/ofw_machdep.h
@@ -45,7 +45,7 @@ boolean_t OF_bootstrap(void);
void OF_reboot(void);
-void ofw_mem_regions(struct mem_region **, int *, struct mem_region **, int *);
+void ofw_mem_regions(struct mem_region *, int *, struct mem_region *, int *);
void ofw_quiesce(void); /* Must be called before VM is up! */
void ofw_save_trap_vec(char *);
diff --git a/sys/powerpc/mpc85xx/platform_mpc85xx.c b/sys/powerpc/mpc85xx/platform_mpc85xx.c
index b190392..a7724cf 100644
--- a/sys/powerpc/mpc85xx/platform_mpc85xx.c
+++ b/sys/powerpc/mpc85xx/platform_mpc85xx.c
@@ -72,8 +72,8 @@ static int cpu, maxcpu;
static int mpc85xx_probe(platform_t);
static int mpc85xx_attach(platform_t);
-static void mpc85xx_mem_regions(platform_t, struct mem_region **phys,
- int *physsz, struct mem_region **avail, int *availsz);
+static void mpc85xx_mem_regions(platform_t, struct mem_region *phys,
+ int *physsz, struct mem_region *avail, int *availsz);
static u_long mpc85xx_timebase_freq(platform_t, struct cpuref *cpuref);
static int mpc85xx_smp_first_cpu(platform_t, struct cpuref *cpuref);
static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref);
@@ -201,8 +201,8 @@ mpc85xx_attach(platform_t plat)
}
void
-mpc85xx_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz)
+mpc85xx_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
+ struct mem_region *avail, int *availsz)
{
ofw_mem_regions(phys, physsz, avail, availsz);
diff --git a/sys/powerpc/ofw/ofw_machdep.c b/sys/powerpc/ofw/ofw_machdep.c
index 4969ec0..02a3d4a 100644
--- a/sys/powerpc/ofw/ofw_machdep.c
+++ b/sys/powerpc/ofw/ofw_machdep.c
@@ -61,11 +61,6 @@ __FBSDID("$FreeBSD$");
#include <machine/ofw_machdep.h>
#include <machine/trap.h>
-static struct mem_region OFmem[PHYS_AVAIL_SZ], OFavail[PHYS_AVAIL_SZ];
-static struct mem_region OFfree[PHYS_AVAIL_SZ];
-
-static int apple_hacks;
-
#ifdef AIM
extern register_t ofmsr[5];
extern void *openfirmware_entry;
@@ -80,7 +75,7 @@ static int openfirmware(void *args);
__inline void
ofw_save_trap_vec(char *save_trap_vec)
{
- if (apple_hacks)
+ if (!ofw_real_mode)
return;
bcopy((void *)EXC_RST, save_trap_vec, EXC_LAST - EXC_RST);
@@ -89,7 +84,7 @@ ofw_save_trap_vec(char *save_trap_vec)
static __inline void
ofw_restore_trap_vec(char *restore_trap_vec)
{
- if (apple_hacks)
+ if (!ofw_real_mode)
return;
bcopy(restore_trap_vec, (void *)EXC_RST, EXC_LAST - EXC_RST);
@@ -104,7 +99,7 @@ register_t ofw_sprg0_save;
static __inline void
ofw_sprg_prepare(void)
{
- if (!apple_hacks)
+ if (ofw_real_mode)
return;
/*
@@ -126,8 +121,10 @@ ofw_sprg_prepare(void)
static __inline void
ofw_sprg_restore(void)
{
- if (!apple_hacks)
+#if 0
+ if (ofw_real_mode)
return;
+#endif
/*
* Note that SPRG1-3 contents are irrelevant. They are scratch
@@ -140,50 +137,6 @@ ofw_sprg_restore(void)
}
#endif
-/*
- * Memory region utilities: determine if two regions overlap,
- * and merge two overlapping regions into one
- */
-static int
-memr_overlap(struct mem_region *r1, struct mem_region *r2)
-{
- if ((r1->mr_start + r1->mr_size) < r2->mr_start ||
- (r2->mr_start + r2->mr_size) < r1->mr_start)
- return (FALSE);
-
- return (TRUE);
-}
-
-static void
-memr_merge(struct mem_region *from, struct mem_region *to)
-{
- vm_offset_t end;
- end = ulmax(to->mr_start + to->mr_size, from->mr_start + from->mr_size);
- to->mr_start = ulmin(from->mr_start, to->mr_start);
- to->mr_size = end - to->mr_start;
-}
-
-/*
- * Quick sort callout for comparing memory regions.
- */
-static int mr_cmp(const void *a, const void *b);
-
-static int
-mr_cmp(const void *a, const void *b)
-{
- const struct mem_region *regiona;
- const struct mem_region *regionb;
-
- regiona = a;
- regionb = b;
- if (regiona->mr_start < regionb->mr_start)
- return (-1);
- else if (regiona->mr_start > regionb->mr_start)
- return (1);
- else
- return (0);
-}
-
static int
parse_ofw_memory(phandle_t node, const char *prop, struct mem_region *output)
{
@@ -209,14 +162,6 @@ parse_ofw_memory(phandle_t node, const char *prop, struct mem_region *output)
size_cells = 1;
/*
- * On Apple hardware, address_cells is always 1 for "available",
- * even when it is explicitly set to 2. All memory above 4 GB
- * also needs to be added by hand to the available list.
- */
- if (strcmp(prop, "available") == 0 && apple_hacks)
- address_cells = 1;
-
- /*
* Get memory.
*/
if (node == -1 || (sz = OF_getprop(node, prop,
@@ -267,103 +212,9 @@ parse_ofw_memory(phandle_t node, const char *prop, struct mem_region *output)
}
sz = j*sizeof(output[0]);
- #ifdef __powerpc64__
- if (strcmp(prop, "available") == 0 && apple_hacks) {
- /* Add in regions above 4 GB to the available list */
- struct mem_region himem[16];
- int hisz;
-
- hisz = parse_ofw_memory(node, "reg", himem);
- for (i = 0; i < hisz/sizeof(himem[0]); i++) {
- if (himem[i].mr_start > BUS_SPACE_MAXADDR_32BIT) {
- output[j].mr_start = himem[i].mr_start;
- output[j].mr_size = himem[i].mr_size;
- j++;
- }
- }
- sz = j*sizeof(output[0]);
- }
- #endif
-
return (sz);
}
-static int
-parse_drconf_memory(int *msz, int *asz, struct mem_region *ofmem,
- struct mem_region *ofavail)
-{
- phandle_t phandle;
- vm_offset_t base;
- int i, idx, len, lasz, lmsz, res;
- uint32_t lmb_size[2];
- unsigned long *dmem, flags;
-
- lmsz = *msz;
- lasz = *asz;
-
- phandle = OF_finddevice("/ibm,dynamic-reconfiguration-memory");
- if (phandle == -1)
- /* No drconf node, return. */
- return (0);
-
- res = OF_getprop(phandle, "ibm,lmb-size", lmb_size, sizeof(lmb_size));
- if (res == -1)
- return (0);
- printf("Logical Memory Block size: %d MB\n", lmb_size[1] >> 20);
-
- /* Parse the /ibm,dynamic-memory.
- The first position gives the # of entries. The next two words
- reflect the address of the memory block. The next four words are
- the DRC index, reserved, list index and flags.
- (see PAPR C.6.6.2 ibm,dynamic-reconfiguration-memory)
-
- #el Addr DRC-idx res list-idx flags
- -------------------------------------------------
- | 4 | 8 | 4 | 4 | 4 | 4 |....
- -------------------------------------------------
- */
-
- len = OF_getproplen(phandle, "ibm,dynamic-memory");
- if (len > 0) {
-
- /* We have to use a variable length array on the stack
- since we have very limited stack space.
- */
- cell_t arr[len/sizeof(cell_t)];
-
- res = OF_getprop(phandle, "ibm,dynamic-memory", &arr,
- sizeof(arr));
- if (res == -1)
- return (0);
-
- /* Number of elements */
- idx = arr[0];
-
- /* First address. */
- dmem = (void*)&arr[1];
-
- for (i = 0; i < idx; i++) {
- base = *dmem;
- dmem += 2;
- flags = *dmem;
- /* Use region only if available and not reserved. */
- if ((flags & 0x8) && !(flags & 0x80)) {
- ofmem[lmsz].mr_start = base;
- ofmem[lmsz].mr_size = (vm_size_t)lmb_size[1];
- ofavail[lasz].mr_start = base;
- ofavail[lasz].mr_size = (vm_size_t)lmb_size[1];
- lmsz++;
- lasz++;
- }
- dmem++;
- }
- }
-
- *msz = lmsz;
- *asz = lasz;
-
- return (1);
-}
/*
* This is called during powerpc_init, before the system is really initialized.
* It shall provide the total and the available regions of RAM.
@@ -372,14 +223,12 @@ parse_drconf_memory(int *msz, int *asz, struct mem_region *ofmem,
* to provide space for two additional entry beyond the terminating one.
*/
void
-ofw_mem_regions(struct mem_region **memp, int *memsz,
- struct mem_region **availp, int *availsz)
+ofw_mem_regions(struct mem_region *memp, int *memsz,
+ struct mem_region *availp, int *availsz)
{
phandle_t phandle;
- vm_offset_t maxphysaddr;
- int asz, msz, fsz;
- int i, j, res;
- int still_merging;
+ int asz, msz;
+ int res;
char name[31];
asz = msz = 0;
@@ -394,72 +243,18 @@ ofw_mem_regions(struct mem_region **memp, int *memsz,
if (strncmp(name, "memory", sizeof(name)) != 0)
continue;
- res = parse_ofw_memory(phandle, "reg", &OFmem[msz]);
+ res = parse_ofw_memory(phandle, "reg", &memp[msz]);
msz += res/sizeof(struct mem_region);
if (OF_getproplen(phandle, "available") >= 0)
res = parse_ofw_memory(phandle, "available",
- &OFavail[asz]);
+ &availp[asz]);
else
- res = parse_ofw_memory(phandle, "reg", &OFavail[asz]);
+ res = parse_ofw_memory(phandle, "reg", &availp[asz]);
asz += res/sizeof(struct mem_region);
}
- /* Check for memory in ibm,dynamic-reconfiguration-memory */
- parse_drconf_memory(&msz, &asz, OFmem, OFavail);
-
- qsort(OFmem, msz, sizeof(*OFmem), mr_cmp);
- qsort(OFavail, asz, sizeof(*OFavail), mr_cmp);
-
- *memp = OFmem;
*memsz = msz;
-
- /*
- * On some firmwares (SLOF), some memory may be marked available that
- * doesn't actually exist. This manifests as an extension of the last
- * available segment past the end of physical memory, so truncate that
- * one.
- */
- maxphysaddr = 0;
- for (i = 0; i < msz; i++)
- if (OFmem[i].mr_start + OFmem[i].mr_size > maxphysaddr)
- maxphysaddr = OFmem[i].mr_start + OFmem[i].mr_size;
-
- if (OFavail[asz - 1].mr_start + OFavail[asz - 1].mr_size > maxphysaddr)
- OFavail[asz - 1].mr_size = maxphysaddr -
- OFavail[asz - 1].mr_start;
-
- /*
- * OFavail may have overlapping regions - collapse these
- * and copy out remaining regions to OFfree
- */
- do {
- still_merging = FALSE;
- for (i = 0; i < asz; i++) {
- if (OFavail[i].mr_size == 0)
- continue;
- for (j = i+1; j < asz; j++) {
- if (OFavail[j].mr_size == 0)
- continue;
- if (memr_overlap(&OFavail[j], &OFavail[i])) {
- memr_merge(&OFavail[j], &OFavail[i]);
- /* mark inactive */
- OFavail[j].mr_size = 0;
- still_merging = TRUE;
- }
- }
- }
- } while (still_merging == TRUE);
-
- /* evict inactive ranges */
- for (i = 0, fsz = 0; i < asz; i++) {
- if (OFavail[i].mr_size != 0) {
- OFfree[fsz] = OFavail[i];
- fsz++;
- }
- }
-
- *availp = OFfree;
- *availsz = fsz;
+ *availsz = asz;
}
#ifdef AIM
@@ -509,9 +304,6 @@ OF_bootstrap()
OF_init(fdt);
}
- /* Apple firmware has some bugs. Check for a "mac-io" alias. */
- apple_hacks = (OF_finddevice("mac-io") != -1) ? 1 : 0;
-
return (status);
}
diff --git a/sys/powerpc/ofw/ofw_pci.c b/sys/powerpc/ofw/ofw_pci.c
index 957a8ca..692b1ab 100644
--- a/sys/powerpc/ofw/ofw_pci.c
+++ b/sys/powerpc/ofw/ofw_pci.c
@@ -256,9 +256,9 @@ ofw_pci_route_interrupt(device_t bus, device_t dev, int pin)
{
struct ofw_pci_softc *sc;
struct ofw_pci_register reg;
- uint32_t pintr, mintr;
+ uint32_t pintr, mintr[2];
+ int intrcells;
phandle_t iparent;
- uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
sc = device_get_softc(bus);
pintr = pin;
@@ -269,10 +269,15 @@ ofw_pci_route_interrupt(device_t bus, device_t dev, int pin)
(pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
(pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
- if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
- sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- &iparent, maskbuf))
- return (ofw_bus_map_intr(dev, iparent, mintr));
+ intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev),
+ &sc->sc_pci_iinfo, &reg, sizeof(reg), &pintr, sizeof(pintr),
+ mintr, sizeof(mintr), &iparent);
+ if (intrcells) {
+ pintr = ofw_bus_map_intr(dev, iparent, mintr[0]);
+ if (intrcells == 2)
+ ofw_bus_config_intr(dev, pintr, mintr[1]);
+ return (pintr);
+ }
/* Maybe it's a real interrupt, not an intpin */
if (pin > 4)
diff --git a/sys/powerpc/ofw/ofw_pcib_pci.c b/sys/powerpc/ofw/ofw_pcib_pci.c
index 6e3faea..df274c4 100644
--- a/sys/powerpc/ofw/ofw_pcib_pci.c
+++ b/sys/powerpc/ofw/ofw_pcib_pci.c
@@ -134,9 +134,9 @@ ofw_pcib_pci_route_interrupt(device_t bridge, device_t dev, int intpin)
struct ofw_pcib_softc *sc;
struct ofw_bus_iinfo *ii;
struct ofw_pci_register reg;
- cell_t pintr, mintr;
+ cell_t pintr, mintr[2];
+ int intrcells;
phandle_t iparent;
- uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
sc = device_get_softc(bridge);
ii = &sc->ops_iinfo;
@@ -149,15 +149,20 @@ ofw_pcib_pci_route_interrupt(device_t bridge, device_t dev, int intpin)
(pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
(pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
- if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), ii, &reg,
- sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- &iparent, maskbuf)) {
+ intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev), ii, &reg,
+ sizeof(reg), &pintr, sizeof(pintr), mintr, sizeof(mintr),
+ &iparent);
+ if (intrcells) {
/*
* If we've found a mapping, return it and don't map
* it again on higher levels - that causes problems
* in some cases, and never seems to be required.
*/
- return (ofw_bus_map_intr(dev, iparent, mintr));
+ mintr[0] = ofw_bus_map_intr(dev, iparent, mintr[0]);
+ if (intrcells == 2)
+ ofw_bus_config_intr(dev, mintr[0], mintr[1]);
+
+ return (mintr[0]);
}
} else if (intpin >= 1 && intpin <= 4) {
/*
diff --git a/sys/powerpc/powermac/platform_powermac.c b/sys/powerpc/powermac/platform_powermac.c
index ce73622..3e1bf7a 100644
--- a/sys/powerpc/powermac/platform_powermac.c
+++ b/sys/powerpc/powermac/platform_powermac.c
@@ -58,8 +58,8 @@ extern void *ap_pcpu;
static int powermac_probe(platform_t);
static int powermac_attach(platform_t);
-void powermac_mem_regions(platform_t, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz);
+void powermac_mem_regions(platform_t, struct mem_region *phys, int *physsz,
+ struct mem_region *avail, int *availsz);
static u_long powermac_timebase_freq(platform_t, struct cpuref *cpuref);
static int powermac_smp_first_cpu(platform_t, struct cpuref *cpuref);
static int powermac_smp_next_cpu(platform_t, struct cpuref *cpuref);
@@ -117,10 +117,60 @@ powermac_probe(platform_t plat)
}
void
-powermac_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz)
+powermac_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
+ struct mem_region *avail, int *availsz)
{
- ofw_mem_regions(phys,physsz,avail,availsz);
+ phandle_t memory;
+ cell_t memoryprop[PHYS_AVAIL_SZ * 2];
+ ssize_t propsize, i, j;
+ int physacells = 1;
+
+ memory = OF_finddevice("/memory");
+
+ /* "reg" has variable #address-cells, but #size-cells is always 1 */
+ OF_getprop(OF_parent(memory), "#address-cells", &physacells,
+ sizeof(physacells));
+
+ propsize = OF_getprop(memory, "reg", memoryprop, sizeof(memoryprop));
+ propsize /= sizeof(cell_t);
+ for (i = 0, j = 0; i < propsize; i += physacells+1, j++) {
+ phys[j].mr_start = memoryprop[i];
+ if (physacells == 2) {
+#ifndef __powerpc64__
+ /* On 32-bit PPC, ignore regions starting above 4 GB */
+ if (memoryprop[i] != 0) {
+ j--;
+ continue;
+ }
+#else
+ phys[j].mr_start <<= 32;
+#endif
+ phys[j].mr_start |= memoryprop[i+1];
+ }
+ phys[j].mr_size = memoryprop[i + physacells];
+ }
+ *physsz = j;
+
+ /* "available" always has #address-cells = 1 */
+ propsize = OF_getprop(memory, "available", memoryprop,
+ sizeof(memoryprop));
+ propsize /= sizeof(cell_t);
+ for (i = 0, j = 0; i < propsize; i += 2, j++) {
+ avail[j].mr_start = memoryprop[i];
+ avail[j].mr_size = memoryprop[i + 1];
+ }
+
+#ifdef __powerpc64__
+ /* Add in regions above 4 GB to the available list */
+ for (i = 0; i < *physsz; i++) {
+ if (phys[i].mr_start > BUS_SPACE_MAXADDR_32BIT) {
+ avail[j].mr_start = phys[i].mr_start;
+ avail[j].mr_size = phys[i].mr_size;
+ j++;
+ }
+ }
+#endif
+ *availsz = j;
}
static int
diff --git a/sys/powerpc/powerpc/copyinout.c b/sys/powerpc/powerpc/copyinout.c
index a1c0456..a8108d6 100644
--- a/sys/powerpc/powerpc/copyinout.c
+++ b/sys/powerpc/powerpc/copyinout.c
@@ -250,22 +250,11 @@ copyin(const void *udaddr, void *kaddr, size_t len)
int
copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done)
{
- struct thread *td;
- pmap_t pm;
- faultbuf env;
const char *up;
char *kp;
size_t l;
int rv, c;
- td = curthread;
- pm = &td->td_proc->p_vmspace->vm_pmap;
-
- if (setfault(env)) {
- td->td_pcb->pcb_onfault = NULL;
- return (EFAULT);
- }
-
kp = kaddr;
up = udaddr;
@@ -288,7 +277,6 @@ copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done)
*done = l;
}
- td->td_pcb->pcb_onfault = NULL;
return (rv);
}
diff --git a/sys/powerpc/powerpc/platform.c b/sys/powerpc/powerpc/platform.c
index 6fae2e8..c7ab51f 100644
--- a/sys/powerpc/powerpc/platform.c
+++ b/sys/powerpc/powerpc/platform.c
@@ -64,17 +64,93 @@ static char plat_name[64] = "";
SYSCTL_STRING(_hw, OID_AUTO, platform, CTLFLAG_RD | CTLFLAG_TUN,
plat_name, 0, "Platform currently in use");
-static struct mem_region *pregions = NULL;
-static struct mem_region *aregions = NULL;
+static struct mem_region pregions[PHYS_AVAIL_SZ];
+static struct mem_region aregions[PHYS_AVAIL_SZ];
static int npregions, naregions;
+/*
+ * Memory region utilities: determine if two regions overlap,
+ * and merge two overlapping regions into one
+ */
+static int
+memr_overlap(struct mem_region *r1, struct mem_region *r2)
+{
+ if ((r1->mr_start + r1->mr_size) < r2->mr_start ||
+ (r2->mr_start + r2->mr_size) < r1->mr_start)
+ return (FALSE);
+
+ return (TRUE);
+}
+
+static void
+memr_merge(struct mem_region *from, struct mem_region *to)
+{
+ vm_offset_t end;
+ end = ulmax(to->mr_start + to->mr_size, from->mr_start + from->mr_size);
+ to->mr_start = ulmin(from->mr_start, to->mr_start);
+ to->mr_size = end - to->mr_start;
+}
+
+/*
+ * Quick sort callout for comparing memory regions.
+ */
+static int
+mr_cmp(const void *a, const void *b)
+{
+ const struct mem_region *regiona, *regionb;
+
+ regiona = a;
+ regionb = b;
+ if (regiona->mr_start < regionb->mr_start)
+ return (-1);
+ else if (regiona->mr_start > regionb->mr_start)
+ return (1);
+ else
+ return (0);
+}
+
void
mem_regions(struct mem_region **phys, int *physsz, struct mem_region **avail,
int *availsz)
{
- if (pregions == NULL)
- PLATFORM_MEM_REGIONS(plat_obj, &pregions, &npregions,
- &aregions, &naregions);
+ int i, j, still_merging;
+
+ if (npregions == 0) {
+ PLATFORM_MEM_REGIONS(plat_obj, &pregions[0], &npregions,
+ aregions, &naregions);
+ qsort(pregions, npregions, sizeof(*pregions), mr_cmp);
+ qsort(aregions, naregions, sizeof(*aregions), mr_cmp);
+
+ /* Remove overlapping available regions */
+ do {
+ still_merging = FALSE;
+ for (i = 0; i < naregions; i++) {
+ if (aregions[i].mr_size == 0)
+ continue;
+ for (j = i+1; j < naregions; j++) {
+ if (aregions[j].mr_size == 0)
+ continue;
+ if (!memr_overlap(&aregions[j],
+ &aregions[i]))
+ continue;
+
+ memr_merge(&aregions[j], &aregions[i]);
+ /* mark inactive */
+ aregions[j].mr_size = 0;
+ still_merging = TRUE;
+ }
+ }
+ } while (still_merging == TRUE);
+
+ /* Collapse zero-length available regions */
+ for (i = 0; i < naregions; i++) {
+ if (aregions[i].mr_size == 0) {
+ memcpy(&aregions[i], &aregions[i+1],
+ (naregions - i - 1)*sizeof(*aregions));
+ naregions--;
+ }
+ }
+ }
*phys = pregions;
*avail = aregions;
@@ -87,9 +163,11 @@ mem_valid(vm_offset_t addr, int len)
{
int i;
- if (pregions == NULL)
- PLATFORM_MEM_REGIONS(plat_obj, &pregions, &npregions,
- &aregions, &naregions);
+ if (npregions == 0) {
+ struct mem_region *p, *a;
+ int na, np;
+ mem_regions(&p, &np, &a, &na);
+ }
for (i = 0; i < npregions; i++)
if ((addr >= pregions[i].mr_start)
diff --git a/sys/powerpc/powerpc/platform_if.m b/sys/powerpc/powerpc/platform_if.m
index 55f9ae6..dfa2be1 100644
--- a/sys/powerpc/powerpc/platform_if.m
+++ b/sys/powerpc/powerpc/platform_if.m
@@ -120,9 +120,9 @@ METHOD int attach {
METHOD void mem_regions {
platform_t _plat;
- struct mem_region **_memp;
+ struct mem_region *_memp;
int *_memsz;
- struct mem_region **_availp;
+ struct mem_region *_availp;
int *_availsz;
};
diff --git a/sys/powerpc/ps3/platform_ps3.c b/sys/powerpc/ps3/platform_ps3.c
index 207382d..c772a8d 100644
--- a/sys/powerpc/ps3/platform_ps3.c
+++ b/sys/powerpc/ps3/platform_ps3.c
@@ -58,8 +58,8 @@ extern void *ap_pcpu;
static int ps3_probe(platform_t);
static int ps3_attach(platform_t);
-static void ps3_mem_regions(platform_t, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz);
+static void ps3_mem_regions(platform_t, struct mem_region *phys, int *physsz,
+ struct mem_region *avail, int *availsz);
static vm_offset_t ps3_real_maxaddr(platform_t);
static u_long ps3_timebase_freq(platform_t, struct cpuref *cpuref);
#ifdef SMP
@@ -107,12 +107,31 @@ ps3_probe(platform_t plat)
return (BUS_PROBE_NOWILDCARD);
}
-#define MEM_REGIONS 2
-static struct mem_region avail_regions[MEM_REGIONS];
-
static int
ps3_attach(platform_t plat)
{
+ uint64_t junk;
+ int count;
+ struct mem_region avail_regions[2];
+
+ ps3_mem_regions(plat, NULL, NULL, avail_regions, &count);
+
+ lv1_allocate_memory(avail_regions[1].mr_size, 24 /* 16 MB pages */,
+ 0, 0x04 /* any address */, &avail_regions[1].mr_start, &junk);
+
+ pmap_mmu_install("mmu_ps3", BUS_PROBE_SPECIFIC);
+ cpu_idle_hook = ps3_cpu_idle;
+
+ /* Set a breakpoint to make NULL an invalid address */
+ lv1_set_dabr(0x7 /* read and write, MMU on */, 2 /* kernel accesses */);
+
+ return (0);
+}
+
+void
+ps3_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
+ struct mem_region *avail_regions, int *availsz)
+{
uint64_t lpar_id, junk, ppe_id;
/* Get real mode memory region */
@@ -133,26 +152,12 @@ ps3_attach(platform_t plat)
/* Convert to maximum amount we can allocate in 16 MB pages */
avail_regions[1].mr_size -= avail_regions[0].mr_size;
avail_regions[1].mr_size -= avail_regions[1].mr_size % (16*1024*1024);
+ *availsz = 2;
- lv1_allocate_memory(avail_regions[1].mr_size, 24 /* 16 MB pages */,
- 0, 0x04 /* any address */, &avail_regions[1].mr_start, &junk);
-
- pmap_mmu_install("mmu_ps3", BUS_PROBE_SPECIFIC);
- cpu_idle_hook = ps3_cpu_idle;
-
- /* Set a breakpoint to make NULL an invalid address */
- lv1_set_dabr(0x7 /* read and write, MMU on */, 2 /* kernel accesses */);
-
- return (0);
-}
-
-void
-ps3_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz)
-{
-
- *phys = *avail = avail_regions;
- *physsz = *availsz = MEM_REGIONS;
+ if (phys != NULL) {
+ memcpy(phys, avail_regions, sizeof(*phys)*2);
+ *physsz = 2;
+ }
}
static u_long
@@ -241,7 +246,12 @@ ps3_reset(platform_t plat)
static vm_offset_t
ps3_real_maxaddr(platform_t plat)
{
- return (avail_regions[0].mr_start + avail_regions[0].mr_size);
+ struct mem_region *phys, *avail;
+ int nphys, navail;
+
+ mem_regions(&phys, &nphys, &avail, &navail);
+
+ return (phys[0].mr_start + phys[0].mr_size);
}
static void
diff --git a/sys/powerpc/pseries/platform_chrp.c b/sys/powerpc/pseries/platform_chrp.c
index 3112ddc..f668b9a 100644
--- a/sys/powerpc/pseries/platform_chrp.c
+++ b/sys/powerpc/pseries/platform_chrp.c
@@ -65,8 +65,8 @@ static vm_offset_t realmaxaddr = VM_MAX_ADDRESS;
static int chrp_probe(platform_t);
static int chrp_attach(platform_t);
-void chrp_mem_regions(platform_t, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz);
+void chrp_mem_regions(platform_t, struct mem_region *phys, int *physsz,
+ struct mem_region *avail, int *availsz);
static vm_offset_t chrp_real_maxaddr(platform_t);
static u_long chrp_timebase_freq(platform_t, struct cpuref *cpuref);
static int chrp_smp_first_cpu(platform_t, struct cpuref *cpuref);
@@ -157,11 +157,107 @@ chrp_attach(platform_t plat)
return (0);
}
+static int
+parse_drconf_memory(int *msz, int *asz, struct mem_region *ofmem,
+ struct mem_region *ofavail)
+{
+ phandle_t phandle;
+ vm_offset_t base;
+ int i, idx, len, lasz, lmsz, res;
+ uint32_t lmb_size[2];
+ unsigned long *dmem, flags;
+
+ lmsz = *msz;
+ lasz = *asz;
+
+ phandle = OF_finddevice("/ibm,dynamic-reconfiguration-memory");
+ if (phandle == -1)
+ /* No drconf node, return. */
+ return (0);
+
+ res = OF_getprop(phandle, "ibm,lmb-size", lmb_size, sizeof(lmb_size));
+ if (res == -1)
+ return (0);
+ printf("Logical Memory Block size: %d MB\n", lmb_size[1] >> 20);
+
+ /* Parse the /ibm,dynamic-memory.
+ The first position gives the # of entries. The next two words
+ reflect the address of the memory block. The next four words are
+ the DRC index, reserved, list index and flags.
+ (see PAPR C.6.6.2 ibm,dynamic-reconfiguration-memory)
+
+ #el Addr DRC-idx res list-idx flags
+ -------------------------------------------------
+ | 4 | 8 | 4 | 4 | 4 | 4 |....
+ -------------------------------------------------
+ */
+
+ len = OF_getproplen(phandle, "ibm,dynamic-memory");
+ if (len > 0) {
+
+ /* We have to use a variable length array on the stack
+ since we have very limited stack space.
+ */
+ cell_t arr[len/sizeof(cell_t)];
+
+ res = OF_getprop(phandle, "ibm,dynamic-memory", &arr,
+ sizeof(arr));
+ if (res == -1)
+ return (0);
+
+ /* Number of elements */
+ idx = arr[0];
+
+ /* First address. */
+ dmem = (void*)&arr[1];
+
+ for (i = 0; i < idx; i++) {
+ base = *dmem;
+ dmem += 2;
+ flags = *dmem;
+ /* Use region only if available and not reserved. */
+ if ((flags & 0x8) && !(flags & 0x80)) {
+ ofmem[lmsz].mr_start = base;
+ ofmem[lmsz].mr_size = (vm_size_t)lmb_size[1];
+ ofavail[lasz].mr_start = base;
+ ofavail[lasz].mr_size = (vm_size_t)lmb_size[1];
+ lmsz++;
+ lasz++;
+ }
+ dmem++;
+ }
+ }
+
+ *msz = lmsz;
+ *asz = lasz;
+
+ return (1);
+}
+
void
-chrp_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz)
+chrp_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
+ struct mem_region *avail, int *availsz)
{
- ofw_mem_regions(phys,physsz,avail,availsz);
+ vm_offset_t maxphysaddr;
+ int i;
+
+ ofw_mem_regions(phys, physsz, avail, availsz);
+ parse_drconf_memory(physsz, availsz, phys, avail);
+
+ /*
+ * On some firmwares (SLOF), some memory may be marked available that
+ * doesn't actually exist. This manifests as an extension of the last
+ * available segment past the end of physical memory, so truncate that
+ * one.
+ */
+ maxphysaddr = 0;
+ for (i = 0; i < *physsz; i++)
+ if (phys[i].mr_start + phys[i].mr_size > maxphysaddr)
+ maxphysaddr = phys[i].mr_start + phys[i].mr_size;
+
+ for (i = 0; i < *availsz; i++)
+ if (avail[i].mr_start + avail[i].mr_size > maxphysaddr)
+ avail[i].mr_size = maxphysaddr - avail[i].mr_start;
}
static vm_offset_t
diff --git a/sys/powerpc/wii/platform_wii.c b/sys/powerpc/wii/platform_wii.c
index f43ee91..c5709f4 100644
--- a/sys/powerpc/wii/platform_wii.c
+++ b/sys/powerpc/wii/platform_wii.c
@@ -56,8 +56,8 @@ __FBSDID("$FreeBSD$");
static int wii_probe(platform_t);
static int wii_attach(platform_t);
-static void wii_mem_regions(platform_t, struct mem_region **,
- int *, struct mem_region **, int *);
+static void wii_mem_regions(platform_t, struct mem_region *,
+ int *, struct mem_region *, int *);
static unsigned long wii_timebase_freq(platform_t, struct cpuref *);
static void wii_reset(platform_t);
static void wii_cpu_idle(sbintime_t);
@@ -107,12 +107,9 @@ wii_attach(platform_t plat)
return (0);
}
-#define MEM_REGIONS 2
-static struct mem_region avail_regions[MEM_REGIONS];
-
static void
-wii_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
- struct mem_region **avail, int *availsz)
+wii_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
+ struct mem_region *avail_regions, int *availsz)
{
/* 24MB 1T-SRAM */
avail_regions[0].mr_start = 0x00000000;
@@ -139,8 +136,8 @@ wii_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
*/
avail_regions[1].mr_size -= WIIIPC_IOH_LEN + 1;
- *phys = *avail = avail_regions;
- *physsz = *availsz = MEM_REGIONS;
+ memcpy(phys, avail_regions, 2*sizeof(*avail_regions));
+ *physsz = *availsz = 2;
}
static u_long
diff --git a/sys/sparc64/ebus/ebus.c b/sys/sparc64/ebus/ebus.c
index 677e31d..93ad342 100644
--- a/sys/sparc64/ebus/ebus.c
+++ b/sys/sparc64/ebus/ebus.c
@@ -638,7 +638,6 @@ ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node)
uint64_t start;
uint32_t rintr;
int i, nintr, nreg, rv;
- uint8_t maskbuf[sizeof(reg) + sizeof(intr)];
edi = malloc(sizeof(*edi), M_DEVBUF, M_ZERO | M_WAITOK);
if (ofw_bus_gen_setup_devinfo(&edi->edi_obdinfo, node) != 0) {
@@ -673,7 +672,7 @@ ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node)
intr = intrs[i];
rv = ofw_bus_lookup_imap(node, &sc->sc_iinfo, &reg,
sizeof(reg), &intr, sizeof(intr), &rintr,
- sizeof(rintr), NULL, maskbuf);
+ sizeof(rintr), NULL);
#ifndef SUN4V
if (rv != 0)
rintr = INTMAP_VEC(sc->sc_ign, rintr);
diff --git a/sys/sparc64/isa/ofw_isa.c b/sys/sparc64/isa/ofw_isa.c
index 0d0f5b6..dbe5d8a 100644
--- a/sys/sparc64/isa/ofw_isa.c
+++ b/sys/sparc64/isa/ofw_isa.c
@@ -129,7 +129,6 @@ ofw_isa_route_intr(device_t bridge, phandle_t node, struct ofw_bus_iinfo *ii,
ofw_isa_intr_t intr)
{
struct isa_regs reg;
- uint8_t maskbuf[sizeof(reg) + sizeof(intr)];
device_t pbridge;
ofw_isa_intr_t mintr;
@@ -139,7 +138,7 @@ ofw_isa_route_intr(device_t bridge, phandle_t node, struct ofw_bus_iinfo *ii,
* fully specified, so we may not continue to map.
*/
if (!ofw_bus_lookup_imap(node, ii, &reg, sizeof(reg),
- &intr, sizeof(intr), &mintr, sizeof(mintr), NULL, maskbuf)) {
+ &intr, sizeof(intr), &mintr, sizeof(mintr), NULL)) {
/* Try routing at the parent bridge. */
mintr = PCIB_ROUTE_INTERRUPT(pbridge, bridge, intr);
}
diff --git a/sys/sparc64/pci/fire.c b/sys/sparc64/pci/fire.c
index 4209f84..84526f0 100644
--- a/sys/sparc64/pci/fire.c
+++ b/sys/sparc64/pci/fire.c
@@ -1472,13 +1472,12 @@ fire_route_interrupt(device_t bridge, device_t dev, int pin)
struct fire_softc *sc;
struct ofw_pci_register reg;
ofw_pci_intr_t pintr, mintr;
- uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
sc = device_get_softc(bridge);
pintr = pin;
if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
&reg, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- NULL, maskbuf) != 0)
+ NULL) != 0)
return (mintr);
device_printf(bridge, "could not route pin %d for device %d.%d\n",
diff --git a/sys/sparc64/pci/ofw_pcib_subr.c b/sys/sparc64/pci/ofw_pcib_subr.c
index 2ffb32d..14fa72b 100644
--- a/sys/sparc64/pci/ofw_pcib_subr.c
+++ b/sys/sparc64/pci/ofw_pcib_subr.c
@@ -70,7 +70,6 @@ ofw_pcib_gen_route_interrupt(device_t bridge, device_t dev, int intpin)
struct ofw_bus_iinfo *ii;
struct ofw_pci_register reg;
ofw_pci_intr_t pintr, mintr;
- uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
sc = device_get_softc(bridge);
ii = &sc->ops_iinfo;
@@ -78,7 +77,7 @@ ofw_pcib_gen_route_interrupt(device_t bridge, device_t dev, int intpin)
pintr = intpin;
if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), ii, &reg,
sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- NULL, maskbuf)) {
+ NULL)) {
/*
* If we've found a mapping, return it and don't map
* it again on higher levels - that causes problems
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index 8717426..4881d1f 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -1048,13 +1048,12 @@ psycho_route_interrupt(device_t bridge, device_t dev, int pin)
struct ofw_pci_register reg;
bus_addr_t intrmap;
ofw_pci_intr_t pintr, mintr;
- uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
sc = device_get_softc(bridge);
pintr = pin;
if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
&reg, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- NULL, maskbuf))
+ NULL))
return (mintr);
/*
* If this is outside of the range for an intpin, it's likely a full
diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index f92aa78..b89c7c0 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -1121,13 +1121,12 @@ schizo_route_interrupt(device_t bridge, device_t dev, int pin)
struct schizo_softc *sc;
struct ofw_pci_register reg;
ofw_pci_intr_t pintr, mintr;
- uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
sc = device_get_softc(bridge);
pintr = pin;
if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
&reg, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- NULL, maskbuf))
+ NULL))
return (mintr);
device_printf(bridge, "could not route pin %d for device %d.%d\n",
OpenPOWER on IntegriCloud