Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 May 2014 16:59:51 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r265954 - in stable/10/sys: dev/ofw powerpc/booke powerpc/ofw powerpc/powerpc
Message-ID:  <201405131659.s4DGxp4O081466@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Tue May 13 16:59:50 2014
New Revision: 265954
URL: http://svnweb.freebsd.org/changeset/base/265954

Log:
  MFC r256814, r256816, r256818, r256846, r256855, r256864 (by nwhitehorn):
  
   - Handle 2GB of ram
   - Allow the OFW interrupt mapping code to work with PCI devices not
     enumerated by Open Firmware, as in the case of FDT.
   - Provide an interface for PCI bus drivers that need some of ofw_pci's
     metadata during attach.
   - Use standard ofw_bus helpers instead of reinventing the wheel.
   - Make hard-wired TLB allocations be at minimum one page.

Modified:
  stable/10/sys/dev/ofw/ofw_bus_subr.c
  stable/10/sys/powerpc/booke/machdep.c
  stable/10/sys/powerpc/booke/pmap.c
  stable/10/sys/powerpc/ofw/ofw_pci.c
  stable/10/sys/powerpc/ofw/ofw_pci.h
  stable/10/sys/powerpc/ofw/ofw_pcib_pci.c
  stable/10/sys/powerpc/ofw/ofw_pcibus.c
  stable/10/sys/powerpc/powerpc/clock.c
  stable/10/sys/powerpc/powerpc/nexus.c

Modified: stable/10/sys/dev/ofw/ofw_bus_subr.c
==============================================================================
--- stable/10/sys/dev/ofw/ofw_bus_subr.c	Tue May 13 16:52:21 2014	(r265953)
+++ stable/10/sys/dev/ofw/ofw_bus_subr.c	Tue May 13 16:59:50 2014	(r265954)
@@ -223,7 +223,6 @@ ofw_bus_has_prop(device_t dev, const cha
 	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, stru
 	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 i
 	}
 	return (0);
 }
-#endif /* !FDT */
+

Modified: stable/10/sys/powerpc/booke/machdep.c
==============================================================================
--- stable/10/sys/powerpc/booke/machdep.c	Tue May 13 16:52:21 2014	(r265953)
+++ stable/10/sys/powerpc/booke/machdep.c	Tue May 13 16:59:50 2014	(r265954)
@@ -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. */

Modified: stable/10/sys/powerpc/booke/pmap.c
==============================================================================
--- stable/10/sys/powerpc/booke/pmap.c	Tue May 13 16:52:21 2014	(r265953)
+++ stable/10/sys/powerpc/booke/pmap.c	Tue May 13 16:59:50 2014	(r265954)
@@ -2613,6 +2613,8 @@ mmu_booke_mapdev(mmu_t mmu, vm_paddr_t p
 
 	va = (pa >= 0x80000000) ? pa : (0xe2000000 + pa);
 	res = (void *)va;
+	if (size < PAGE_SIZE)
+	    size = PAGE_SIZE;
 
 	do {
 		sz = 1 << (ilog2(size) & ~1);

Modified: stable/10/sys/powerpc/ofw/ofw_pci.c
==============================================================================
--- stable/10/sys/powerpc/ofw/ofw_pci.c	Tue May 13 16:52:21 2014	(r265953)
+++ stable/10/sys/powerpc/ofw/ofw_pci.c	Tue May 13 16:59:50 2014	(r265954)
@@ -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, de
 
 	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))

Modified: stable/10/sys/powerpc/ofw/ofw_pci.h
==============================================================================
--- stable/10/sys/powerpc/ofw/ofw_pci.h	Tue May 13 16:52:21 2014	(r265953)
+++ stable/10/sys/powerpc/ofw/ofw_pci.h	Tue May 13 16:59:50 2014	(r265954)
@@ -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

Modified: stable/10/sys/powerpc/ofw/ofw_pcib_pci.c
==============================================================================
--- stable/10/sys/powerpc/ofw/ofw_pcib_pci.c	Tue May 13 16:52:21 2014	(r265953)
+++ stable/10/sys/powerpc/ofw/ofw_pcib_pci.c	Tue May 13 16:59:50 2014	(r265954)
@@ -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 br
 	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)) {

Modified: stable/10/sys/powerpc/ofw/ofw_pcibus.c
==============================================================================
--- stable/10/sys/powerpc/ofw/ofw_pcibus.c	Tue May 13 16:52:21 2014	(r265953)
+++ stable/10/sys/powerpc/ofw/ofw_pcibus.c	Tue May 13 16:59:50 2014	(r265954)
@@ -320,20 +320,9 @@ ofw_pcibus_assign_interrupt(device_t dev
 	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
 	}
 	
 	/*

Modified: stable/10/sys/powerpc/powerpc/clock.c
==============================================================================
--- stable/10/sys/powerpc/powerpc/clock.c	Tue May 13 16:52:21 2014	(r265953)
+++ stable/10/sys/powerpc/powerpc/clock.c	Tue May 13 16:59:50 2014	(r265954)
@@ -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);

Modified: stable/10/sys/powerpc/powerpc/nexus.c
==============================================================================
--- stable/10/sys/powerpc/powerpc/nexus.c	Tue May 13 16:52:21 2014	(r265953)
+++ stable/10/sys/powerpc/powerpc/nexus.c	Tue May 13 16:59:50 2014	(r265954)
@@ -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(dev
 		    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 orde
 	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, 
 {
 	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)
-{
-	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)
+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 (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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405131659.s4DGxp4O081466>