Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Mar 2009 17:16:16 +0000 (UTC)
From:      Sam Leffler <sam@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r189632 - head/sys/arm/xscale/ixp425
Message-ID:  <200903101716.n2AHGGJ2068418@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sam
Date: Tue Mar 10 17:16:16 2009
New Revision: 189632
URL: http://svn.freebsd.org/changeset/base/189632

Log:
  Small cleanup of memory resource allocation from Cambria branch:
  o encode need for A4 bus space tag hackery according to the memory
    address; checking for "uart" breaks down with the GPS chip support
    which is also a uart but does not require the same hackery
  o encode the correct memory window instead of carving up all of i/o
    space, potentially with a larger window than a device should have;
    this likely should be handled in the drivers by using a proper bus
    alloc call but since some drivers depend on the bus support to figure
    this out we cannot simply mod them
  o add optional GPS and RS485 support (conditionally as the support
    isn't ready yet)

Modified:
  head/sys/arm/xscale/ixp425/ixp425.c

Modified: head/sys/arm/xscale/ixp425/ixp425.c
==============================================================================
--- head/sys/arm/xscale/ixp425/ixp425.c	Tue Mar 10 17:00:28 2009	(r189631)
+++ head/sys/arm/xscale/ixp425/ixp425.c	Tue Mar 10 17:16:16 2009	(r189632)
@@ -315,43 +315,82 @@ ixp425_read_ivar(device_t bus, device_t 
 }
 
 /*
- * NB: This table handles P->V translations for regions mapped
- * through bus_alloc_resource.  Anything done with bus_space_map
- * is handled elsewhere and does not require an entry here.
+ * NB: This table handles P->V translations for regions setup with
+ * static mappings in initarm.  This is used solely for calls to
+ * bus_alloc_resource_any; anything done with bus_space_map is
+ * handled elsewhere and does not require an entry here.
  *
- * XXX getvbase is also used by uart_cpu_getdev (hence public)
+ * XXX this table is also used by uart_cpu_getdev via getvbase
+ *    (hence the public api)
  */
-static const struct {
+struct hwvtrans {
 	uint32_t	hwbase;
 	uint32_t	size;
 	uint32_t	vbase;
-} hwvtrans[] = {
-	{ IXP425_IO_HWBASE,	IXP425_IO_SIZE,		IXP425_IO_VBASE },
-	{ IXP425_PCI_HWBASE,	IXP425_PCI_SIZE,	IXP425_PCI_VBASE },
-	{ IXP425_PCI_MEM_HWBASE,IXP425_PCI_MEM_SIZE,	IXP425_PCI_MEM_VBASE },
-	{ IXP425_EXP_BUS_CS0_HWBASE, IXP425_EXP_BUS_CS0_SIZE,
-	  IXP425_EXP_BUS_CS0_VBASE },
-	/* NB: needed only for uart_cpu_getdev */
-	{ IXP425_UART0_HWBASE,	IXP425_REG_SIZE,	IXP425_UART0_VBASE },
-	{ IXP425_UART1_HWBASE,	IXP425_REG_SIZE,	IXP425_UART1_VBASE },
-	/* NB: need for ixp435 ehci controllers */
-	{ IXP435_USB1_HWBASE,	IXP435_USB1_SIZE,	IXP435_USB1_VBASE },
-	{ IXP435_USB2_HWBASE,	IXP435_USB2_SIZE,	IXP435_USB2_VBASE },
+	int		isa4x;	/* XXX needs special bus space tag */
 };
 
-int
-getvbase(uint32_t hwbase, uint32_t size, uint32_t *vbase)
+static const struct hwvtrans *
+gethwvtrans(uint32_t hwbase, uint32_t size)
 {
+	static const struct hwvtrans hwvtrans[] = {
+	    /* NB: needed only for uart_cpu_getdev */
+	    { .hwbase	= IXP425_UART0_HWBASE,
+	      .size 	= IXP425_REG_SIZE,
+	      .vbase	= IXP425_UART0_VBASE,
+	      .isa4x	= 1 },
+	    { .hwbase	= IXP425_UART1_HWBASE,
+	      .size 	= IXP425_REG_SIZE,
+	      .vbase	= IXP425_UART1_VBASE,
+	      .isa4x	= 1 },
+	    { .hwbase	= IXP425_PCI_HWBASE,
+	      .size 	= IXP425_PCI_SIZE,
+	      .vbase	= IXP425_PCI_VBASE },
+	    { .hwbase	= IXP425_PCI_MEM_HWBASE,
+	      .size 	= IXP425_PCI_MEM_SIZE,
+	      .vbase	= IXP425_PCI_MEM_VBASE },
+	    { .hwbase	= IXP425_EXP_BUS_CS0_HWBASE,
+	      .size 	= IXP425_EXP_BUS_CS0_SIZE,
+	      .vbase	= IXP425_EXP_BUS_CS0_VBASE },
+	    /* NB: needed for ixp435 ehci controllers */
+	    { .hwbase	= IXP435_USB1_HWBASE,
+	      .size 	= IXP435_USB1_SIZE,
+	      .vbase	= IXP435_USB1_VBASE },
+	    { .hwbase	= IXP435_USB2_HWBASE,
+	      .size 	= IXP435_USB2_SIZE,
+	      .vbase	= IXP435_USB2_VBASE },
+#ifdef CAMBRIA_GPS_VBASE
+	    { .hwbase	= CAMBRIA_GPS_HWBASE,
+	      .size 	= CAMBRIA_GPS_SIZE,
+	      .vbase	= CAMBRIA_GPS_VBASE },
+#endif
+#ifdef CAMBRIA_RS485_VBASE
+	    { .hwbase	= CAMBRIA_RS485_HWBASE,
+	      .size 	= CAMBRIA_RS485_SIZE,
+	      .vbase	= CAMBRIA_RS485_VBASE },
+#endif
+	};
 	int i;
 
 	for (i = 0; i < sizeof hwvtrans / sizeof *hwvtrans; i++) {
 		if (hwbase >= hwvtrans[i].hwbase &&
-		    hwbase + size <= hwvtrans[i].hwbase + hwvtrans[i].size) {
-			*vbase = hwbase - hwvtrans[i].hwbase + hwvtrans[i].vbase;
-			return (0);
-		}
+		    hwbase + size <= hwvtrans[i].hwbase + hwvtrans[i].size)
+			return &hwvtrans[i];
 	}
-	return (ENOENT);
+	return NULL;
+}
+
+/* XXX for uart_cpu_getdev */
+int
+getvbase(uint32_t hwbase, uint32_t size, uint32_t *vbase)
+{
+	const struct hwvtrans *hw;
+
+	hw = gethwvtrans(hwbase, size);
+	if (hw == NULL)
+		return (ENOENT);
+	*vbase = hwbase - hw->hwbase + hw->vbase;
+	return (0);
 }
 
 static struct resource *
@@ -359,9 +398,10 @@ ixp425_alloc_resource(device_t dev, devi
     u_long start, u_long end, u_long count, u_int flags)
 {
 	struct ixp425_softc *sc = device_get_softc(dev);
+	const struct hwvtrans *vtrans;
 	struct rman *rmanp;
 	struct resource *rv;
-	uint32_t vbase, addr;
+	uint32_t addr;
 	int needactivate = flags & RF_ACTIVE;
 	int irq;
 
@@ -383,16 +423,31 @@ ixp425_alloc_resource(device_t dev, devi
 		/* override per hints */
 		if (BUS_READ_IVAR(dev, child, IXP425_IVAR_ADDR, &addr) == 0) {
 			start = addr;
-			end = start + 0x1000;	/* XXX */
-			count = end - start;
-		}
-		if (getvbase(start, end - start, &vbase) != 0) {
+			/* XXX use nominal window to check for mapping */
+			vtrans = gethwvtrans(start, 0x1000);
+			if (vtrans != NULL) {
+				/*
+				 * Assign the entire mapped region; this may
+				 * not be correct but without more info from
+				 * the caller we cannot tell.
+				 */
+				end = start + vtrans->size -
+				    (start - vtrans->hwbase);
+				if (bootverbose)
+					device_printf(child,
+					    "%s: assign 0x%lx:0x%lx%s\n",
+					    __func__, start, end - start,
+					    vtrans->isa4x ? " A4X" : "");
+			}
+		} else
+			vtrans = gethwvtrans(start, end - start);
+		if (vtrans == NULL) {
 			/* likely means above table needs to be updated */
-			device_printf(dev, "%s: no mapping for 0x%lx:0x%lx\n",
+			device_printf(child, "%s: no mapping for 0x%lx:0x%lx\n",
 			    __func__, start, end-start);
 			return NULL;
 		}
-		rv = rman_reserve_resource(rmanp, start, end, count,
+		rv = rman_reserve_resource(rmanp, start, end, end - start,
 			flags, child);
 		if (rv != NULL)
 			rman_set_rid(rv, *rid);
@@ -415,18 +470,17 @@ ixp425_activate_resource(device_t dev, d
     struct resource *r)
 {
 	struct ixp425_softc *sc = device_get_softc(dev);
-	int error;
-	uint32_t vbase;
+	const struct hwvtrans *vtrans;
 
 	if (type == SYS_RES_MEMORY) {
-		error = getvbase(rman_get_start(r), rman_get_size(r), &vbase);
-		if (error)
-			return (error);
-		if (strcmp(device_get_name(child), "uart") == 0)
+		vtrans = gethwvtrans(rman_get_start(r), rman_get_size(r));
+		if (vtrans == NULL)		/* NB: should not happen */
+			return (ENOENT);
+		if (vtrans->isa4x)
 			rman_set_bustag(r, &ixp425_a4x_bs_tag);
 		else
 			rman_set_bustag(r, sc->sc_iot);
-		rman_set_bushandle(r, vbase);		
+		rman_set_bushandle(r, vtrans->vbase);
 	}
 	return (rman_activate_resource(r));
 }



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