summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ofw/ofw_bus_subr.c11
-rw-r--r--sys/powerpc/booke/machdep.c9
-rw-r--r--sys/powerpc/booke/pmap.c2
-rw-r--r--sys/powerpc/ofw/ofw_pci.c27
-rw-r--r--sys/powerpc/ofw/ofw_pci.h2
-rw-r--r--sys/powerpc/ofw/ofw_pcib_pci.c8
-rw-r--r--sys/powerpc/ofw/ofw_pcibus.c11
-rw-r--r--sys/powerpc/powerpc/clock.c4
-rw-r--r--sys/powerpc/powerpc/nexus.c166
9 files changed, 77 insertions, 163 deletions
diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c
index 86426ca..890e378 100644
--- a/sys/dev/ofw/ofw_bus_subr.c
+++ b/sys/dev/ofw/ofw_bus_subr.c
@@ -223,7 +223,6 @@ ofw_bus_has_prop(device_t dev, const char *propname)
return (OF_hasprop(node, propname));
}
-#ifndef FDT
void
ofw_bus_setup_iinfo(phandle_t node, struct ofw_bus_iinfo *ii, int intrsz)
{
@@ -261,9 +260,11 @@ ofw_bus_lookup_imap(phandle_t node, struct ofw_bus_iinfo *ii, void *reg,
KASSERT(regsz >= ii->opi_addrc,
("ofw_bus_lookup_imap: register size too small: %d < %d",
regsz, ii->opi_addrc));
- rv = OF_getprop(node, "reg", reg, regsz);
- if (rv < regsz)
- panic("ofw_bus_lookup_imap: could not get reg property");
+ if (node != -1) {
+ rv = OF_getprop(node, "reg", reg, regsz);
+ if (rv < regsz)
+ panic("ofw_bus_lookup_imap: cannot get reg property");
+ }
return (ofw_bus_search_intrmap(pintr, pintrsz, reg, ii->opi_addrc,
ii->opi_imap, ii->opi_imapsz, ii->opi_imapmsk, maskbuf, mintr,
mintrsz, iparent));
@@ -343,4 +344,4 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
}
return (0);
}
-#endif /* !FDT */
+
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index e9a2d52..340c7a0d 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -192,7 +192,8 @@ extern int elf32_nxstack;
static void
cpu_booke_startup(void *dummy)
{
- int indx, size;
+ int indx;
+ unsigned long size;
/* Initialise the decrementer-based clock. */
decr_init();
@@ -200,7 +201,7 @@ cpu_booke_startup(void *dummy)
/* Good {morning,afternoon,evening,night}. */
cpu_setup(PCPU_GET(cpuid));
- printf("real memory = %ld (%ld MB)\n", ptoa(physmem),
+ printf("real memory = %lu (%ld MB)\n", ptoa(physmem),
ptoa(physmem) / 1048576);
realmem = physmem;
@@ -210,7 +211,7 @@ cpu_booke_startup(void *dummy)
for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
size = phys_avail[indx + 1] - phys_avail[indx];
- printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n",
+ printf("0x%08x - 0x%08x, %lu bytes (%lu pages)\n",
phys_avail[indx], phys_avail[indx + 1] - 1,
size, size / PAGE_SIZE);
}
@@ -218,7 +219,7 @@ cpu_booke_startup(void *dummy)
vm_ksubmap_init(&kmi);
- printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count),
+ printf("avail memory = %lu (%ld MB)\n", ptoa(cnt.v_free_count),
ptoa(cnt.v_free_count) / 1048576);
/* Set up buffers, so they can be used to read disk labels. */
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index 7b9a5d3..9406a4a 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -2613,6 +2613,8 @@ mmu_booke_mapdev(mmu_t mmu, vm_paddr_t pa, vm_size_t size)
va = (pa >= 0x80000000) ? pa : (0xe2000000 + pa);
res = (void *)va;
+ if (size < PAGE_SIZE)
+ size = PAGE_SIZE;
do {
sz = 1 << (ilog2(size) & ~1);
diff --git a/sys/powerpc/ofw/ofw_pci.c b/sys/powerpc/ofw/ofw_pci.c
index 46d483d..f3e9e78 100644
--- a/sys/powerpc/ofw/ofw_pci.c
+++ b/sys/powerpc/ofw/ofw_pci.c
@@ -124,7 +124,7 @@ static device_method_t ofw_pci_methods[] = {
DEFINE_CLASS_0(ofw_pci, ofw_pci_driver, ofw_pci_methods, 0);
int
-ofw_pci_attach(device_t dev)
+ofw_pci_init(device_t dev)
{
struct ofw_pci_softc *sc;
phandle_t node;
@@ -134,6 +134,7 @@ ofw_pci_attach(device_t dev)
node = ofw_bus_get_node(dev);
sc = device_get_softc(dev);
+ sc->sc_initialized = 1;
if (OF_getprop(node, "reg", &sc->sc_pcir, sizeof(sc->sc_pcir)) == -1)
return (ENXIO);
@@ -217,13 +218,28 @@ ofw_pci_attach(device_t dev)
"error = %d\n", rp->pci_hi &
OFW_PCI_PHYS_HI_SPACEMASK, rp->pci,
rp->pci + rp->size - 1, error);
- panic("AHOY");
return (error);
}
}
ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t));
+ return (error);
+}
+
+int
+ofw_pci_attach(device_t dev)
+{
+ struct ofw_pci_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ if (!sc->sc_initialized) {
+ error = ofw_pci_init(dev);
+ if (error)
+ return (error);
+ }
+
device_add_child(dev, "pci", device_get_unit(dev));
return (bus_generic_attach(dev));
}
@@ -246,6 +262,13 @@ ofw_pci_route_interrupt(device_t bus, device_t dev, int pin)
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);
+
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))
diff --git a/sys/powerpc/ofw/ofw_pci.h b/sys/powerpc/ofw/ofw_pci.h
index dd277e9..388aa12 100644
--- a/sys/powerpc/ofw/ofw_pci.h
+++ b/sys/powerpc/ofw/ofw_pci.h
@@ -52,6 +52,7 @@ struct ofw_pci_softc {
device_t sc_dev;
phandle_t sc_node;
int sc_bus;
+ int sc_initialized;
int sc_quirks;
@@ -68,6 +69,7 @@ struct ofw_pci_softc {
struct ofw_bus_iinfo sc_pci_iinfo;
};
+int ofw_pci_init(device_t dev);
int ofw_pci_attach(device_t dev);
#endif // POWERPC_OFW_OFW_PCI_H
diff --git a/sys/powerpc/ofw/ofw_pcib_pci.c b/sys/powerpc/ofw/ofw_pcib_pci.c
index d6c4168..fb0a488 100644
--- a/sys/powerpc/ofw/ofw_pcib_pci.c
+++ b/sys/powerpc/ofw/ofw_pcib_pci.c
@@ -29,6 +29,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/malloc.h>
@@ -141,6 +142,13 @@ ofw_pcib_pci_route_interrupt(device_t bridge, device_t dev, int intpin)
ii = &sc->ops_iinfo;
if (ii->opi_imapsz > 0) {
pintr = intpin;
+
+ /* Fabricate imap information if 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);
+
if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), ii, &reg,
sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
&iparent, maskbuf)) {
diff --git a/sys/powerpc/ofw/ofw_pcibus.c b/sys/powerpc/ofw/ofw_pcibus.c
index 8005e00..a17e6d7 100644
--- a/sys/powerpc/ofw/ofw_pcibus.c
+++ b/sys/powerpc/ofw/ofw_pcibus.c
@@ -320,20 +320,9 @@ ofw_pcibus_assign_interrupt(device_t dev, device_t child)
if (node == -1) {
/* Non-firmware enumerated child, use standard routing */
- /*
- * XXX: Right now we don't have anything sensible to do here,
- * since the ofw_imap stuff relies on nodes having a reg
- * property. There exist ways around this, so the ePAPR
- * spec will need to be studied.
- */
-
- return (PCI_INVALID_IRQ);
-
-#ifdef NOTYET
intr = pci_get_intpin(child);
return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child,
intr));
-#endif
}
/*
diff --git a/sys/powerpc/powerpc/clock.c b/sys/powerpc/powerpc/clock.c
index 2b9477a..a218a70 100644
--- a/sys/powerpc/powerpc/clock.c
+++ b/sys/powerpc/powerpc/clock.c
@@ -167,8 +167,8 @@ decr_init(void)
char buf[32];
/*
- * Check the BSP's timebase frequency. Sometimes we can't find the BSP, so fall
- * back to the first CPU in this case.
+ * Check the BSP's timebase frequency. Sometimes we can't find the BSP,
+ * so fall back to the first CPU in this case.
*/
if (platform_smp_get_bsp(&cpu) != 0)
platform_smp_first_cpu(&cpu);
diff --git a/sys/powerpc/powerpc/nexus.c b/sys/powerpc/powerpc/nexus.c
index 109ec52..f3305db 100644
--- a/sys/powerpc/powerpc/nexus.c
+++ b/sys/powerpc/powerpc/nexus.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
@@ -88,19 +89,8 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_NEXUS, "nexus", "nexus device information");
-enum nexus_ivars {
- NEXUS_IVAR_NODE,
- NEXUS_IVAR_NAME,
- NEXUS_IVAR_DEVICE_TYPE,
- NEXUS_IVAR_COMPATIBLE,
-};
-
struct nexus_devinfo {
- phandle_t ndi_node;
- /* Some common properties. */
- const char *ndi_name;
- const char *ndi_device_type;
- const char *ndi_compatible;
+ struct ofw_bus_devinfo ndi_ofwinfo;
};
struct nexus_softc {
@@ -118,8 +108,6 @@ static int nexus_attach(device_t);
*/
static device_t nexus_add_child(device_t, u_int, const char *, int);
static void nexus_probe_nomatch(device_t, device_t);
-static int nexus_read_ivar(device_t, device_t, int, uintptr_t *);
-static int nexus_write_ivar(device_t, device_t, int, uintptr_t);
#ifdef SMP
static int nexus_bind_intr(device_t dev, device_t child,
struct resource *irq, int cpu);
@@ -138,14 +126,8 @@ static int nexus_deactivate_resource(device_t, device_t, int, int,
struct resource *);
static int nexus_release_resource(device_t, device_t, int, int,
struct resource *);
-
-/*
- * OFW bus interface.
- */
-static phandle_t nexus_ofw_get_node(device_t, device_t);
-static const char *nexus_ofw_get_name(device_t, device_t);
-static const char *nexus_ofw_get_type(device_t, device_t);
-static const char *nexus_ofw_get_compat(device_t, device_t);
+static const struct ofw_bus_devinfo *nexus_get_devinfo(device_t dev,
+ device_t child);
/*
* Local routines
@@ -165,8 +147,6 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(bus_add_child, nexus_add_child),
DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
DEVMETHOD(bus_probe_nomatch, nexus_probe_nomatch),
- DEVMETHOD(bus_read_ivar, nexus_read_ivar),
- DEVMETHOD(bus_write_ivar, nexus_write_ivar),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
#ifdef SMP
@@ -179,10 +159,12 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(bus_release_resource, nexus_release_resource),
/* OFW bus interface */
- DEVMETHOD(ofw_bus_get_node, nexus_ofw_get_node),
- DEVMETHOD(ofw_bus_get_name, nexus_ofw_get_name),
- DEVMETHOD(ofw_bus_get_type, nexus_ofw_get_type),
- DEVMETHOD(ofw_bus_get_compat, nexus_ofw_get_compat),
+ DEVMETHOD(ofw_bus_get_devinfo, nexus_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
DEVMETHOD_END
};
@@ -246,14 +228,13 @@ nexus_attach(device_t dev)
static void
nexus_probe_nomatch(device_t dev, device_t child)
{
- char *name, *type;
+ const char *name, *type;
- if (BUS_READ_IVAR(dev, child, NEXUS_IVAR_NAME,
- (uintptr_t *)&name) != 0 ||
- BUS_READ_IVAR(dev, child, NEXUS_IVAR_DEVICE_TYPE,
- (uintptr_t *)&type) != 0)
- return;
+ name = ofw_bus_get_name(child);
+ type = ofw_bus_get_type(child);
+ if (name == NULL)
+ name = "unknown";
if (type == NULL)
type = "(unknown)";
@@ -276,67 +257,17 @@ nexus_add_child(device_t dev, u_int order, const char *name, int unit)
if (dinfo == NULL)
return (NULL);
- dinfo->ndi_node = -1;
- dinfo->ndi_name = name;
+ dinfo->ndi_ofwinfo.obd_node = -1;
+ dinfo->ndi_ofwinfo.obd_name = NULL;
+ dinfo->ndi_ofwinfo.obd_compat = NULL;
+ dinfo->ndi_ofwinfo.obd_type = NULL;
+ dinfo->ndi_ofwinfo.obd_model = NULL;
+
device_set_ivars(child, dinfo);
return (child);
}
-
-static int
-nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(child)) == 0)
- return (ENOENT);
- switch (which) {
- case NEXUS_IVAR_NODE:
- *result = dinfo->ndi_node;
- break;
- case NEXUS_IVAR_NAME:
- *result = (uintptr_t)dinfo->ndi_name;
- break;
- case NEXUS_IVAR_DEVICE_TYPE:
- *result = (uintptr_t)dinfo->ndi_device_type;
- break;
- case NEXUS_IVAR_COMPATIBLE:
- *result = (uintptr_t)dinfo->ndi_compatible;
- break;
- default:
- return (ENOENT);
- }
- return 0;
-}
-
-static int
-nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(child)) == 0)
- return (ENOENT);
-
- switch (which) {
- case NEXUS_IVAR_NAME:
- return (EINVAL);
-
- /* Identified devices may want to set these */
- case NEXUS_IVAR_NODE:
- dinfo->ndi_node = (phandle_t)value;
- break;
-
- case NEXUS_IVAR_DEVICE_TYPE:
- dinfo->ndi_device_type = (char *)value;
- break;
-
- default:
- return (ENOENT);
- }
- return 0;
-}
-
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
driver_filter_t *filter, driver_intr_t *ihand, void *arg, void **cookiep)
@@ -462,66 +393,23 @@ nexus_device_from_node(device_t parent, phandle_t node)
{
device_t cdev;
struct nexus_devinfo *dinfo;
- char *name, *type, *compatible;
- OF_getprop_alloc(node, "name", 1, (void **)&name);
- OF_getprop_alloc(node, "device_type", 1, (void **)&type);
- OF_getprop_alloc(node, "compatible", 1, (void **)&compatible);
cdev = device_add_child(parent, NULL, -1);
if (cdev != NULL) {
dinfo = malloc(sizeof(*dinfo), M_NEXUS, M_WAITOK);
- dinfo->ndi_node = node;
- dinfo->ndi_name = name;
- dinfo->ndi_device_type = type;
- dinfo->ndi_compatible = compatible;
+ ofw_bus_gen_setup_devinfo(&dinfo->ndi_ofwinfo, node);
device_set_ivars(cdev, dinfo);
- } else
- free(name, M_OFWPROP);
+ }
return (cdev);
}
-static const char *
-nexus_ofw_get_name(device_t bus, device_t dev)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(dev)) == NULL)
- return (NULL);
-
- return (dinfo->ndi_name);
-}
-
-static phandle_t
-nexus_ofw_get_node(device_t bus, device_t dev)
+static const struct ofw_bus_devinfo *
+nexus_get_devinfo(device_t dev, device_t child)
{
struct nexus_devinfo *dinfo;
- if ((dinfo = device_get_ivars(dev)) == NULL)
- return (0);
-
- return (dinfo->ndi_node);
-}
-
-static const char *
-nexus_ofw_get_type(device_t bus, device_t dev)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(dev)) == NULL)
- return (NULL);
-
- return (dinfo->ndi_device_type);
-}
-
-static const char *
-nexus_ofw_get_compat(device_t bus, device_t dev)
-{
- struct nexus_devinfo *dinfo;
-
- if ((dinfo = device_get_ivars(dev)) == NULL)
- return (NULL);
-
- return (dinfo->ndi_compatible);
+ dinfo = device_get_ivars(child);
+ return (&dinfo->ndi_ofwinfo);
}
OpenPOWER on IntegriCloud