svn commit: r210396 - head/sys/arm/s3c2xx0

Andrew Turner andrew at FreeBSD.org
Thu Jul 22 23:12:19 UTC 2010


Author: andrew
Date: Thu Jul 22 23:12:19 2010
New Revision: 210396
URL: http://svn.freebsd.org/changeset/base/210396

Log:
  Rework how device memory is allocated on the s3c24x0 CPU's.
  
  The device virtual addresses are now able to be allocated at runtime rather
  than from the static pmap_devmap at boot. The only exception is memory
  required before we have had a chance to dynamically allocate it.
  
  While here reduce the space between the statically allocated devices by
  reducing the distance between the virtual addresses.
  
  Approved by:	imp (mentor)

Modified:
  head/sys/arm/s3c2xx0/s3c24x0.c
  head/sys/arm/s3c2xx0/s3c24x0_machdep.c
  head/sys/arm/s3c2xx0/s3c24x0reg.h
  head/sys/arm/s3c2xx0/s3c2xx0_space.c
  head/sys/arm/s3c2xx0/s3c2xx0var.h

Modified: head/sys/arm/s3c2xx0/s3c24x0.c
==============================================================================
--- head/sys/arm/s3c2xx0/s3c24x0.c	Thu Jul 22 22:42:53 2010	(r210395)
+++ head/sys/arm/s3c2xx0/s3c24x0.c	Thu Jul 22 23:12:19 2010	(r210396)
@@ -83,22 +83,22 @@ static struct {
 	{ "timer", 0, -1, { { 0 }, } },
 	{ "uart", 1, 0, {
 		{ SYS_RES_IRQ, S3C24X0_INT_UART0, 1 },
-		{ SYS_RES_IOPORT, S3C24X0_UART_BASE(0),
+		{ SYS_RES_IOPORT, S3C24X0_UART_PA_BASE(0),
 		  S3C24X0_UART_BASE(1) - S3C24X0_UART_BASE(0) },
 	} },
 	{ "uart", 1, 1, {
 		{ SYS_RES_IRQ, S3C24X0_INT_UART1, 1 },
-		{ SYS_RES_IOPORT, S3C24X0_UART_BASE(1),
+		{ SYS_RES_IOPORT, S3C24X0_UART_PA_BASE(1),
 		  S3C24X0_UART_BASE(2) - S3C24X0_UART_BASE(1) },
 	} },
 	{ "uart", 1, 2, {
 		{ SYS_RES_IRQ, S3C24X0_INT_UART2, 1 },
-		{ SYS_RES_IOPORT, S3C24X0_UART_BASE(2),
+		{ SYS_RES_IOPORT, S3C24X0_UART_PA_BASE(2),
 		  S3C24X0_UART_BASE(3) - S3C24X0_UART_BASE(2) },
 	} },
 	{ "ohci", 0, -1, {
 		{ SYS_RES_IRQ, S3C24X0_INT_USBH, 0 },
-		{ SYS_RES_IOPORT, S3C24X0_USBHC_BASE, S3C24X0_USBHC_SIZE },
+		{ SYS_RES_IOPORT, S3C24X0_USBHC_PA_BASE, S3C24X0_USBHC_SIZE },
 	} },
 	{ NULL },
 };
@@ -257,8 +257,18 @@ s3c24x0_alloc_resource(device_t bus, dev
 		res = rman_reserve_resource(
 		    &s3c2xx0_softc->s3c2xx0_mem_rman,
 		    start, end, count, flags, child);
+		if (res == NULL)
+			panic("Unable to map address space %#lX-%#lX", start,
+			    end);
+
 		rman_set_bustag(res, &s3c2xx0_bs_tag);
 		rman_set_bushandle(res, start);
+		if (flags & RF_ACTIVE) {
+			if (bus_activate_resource(child, type, *rid, res)) {
+				rman_release_resource(res);
+				return (NULL);
+			}
+		} 
 		break;
 	}
 
@@ -279,6 +289,16 @@ static int
 s3c24x0_activate_resource(device_t bus, device_t child, int type, int rid,
         struct resource *r)
 {
+	bus_space_handle_t p;
+	int error;
+
+	if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+		error = bus_space_map(rman_get_bustag(r),
+		    rman_get_bushandle(r), rman_get_size(r), 0, &p);
+		if (error)
+			return (error);
+		rman_set_bushandle(r, p);
+	}
 	return (rman_activate_resource(r));
 }
 
@@ -335,32 +355,29 @@ s3c24x0_attach(device_t dev)
 
 	s3c2xx0_softc = &(sc->sc_sx);
 	sc->sc_sx.sc_iot = iot = &s3c2xx0_bs_tag;
+	s3c2xx0_softc->s3c2xx0_irq_rman.rm_type = RMAN_ARRAY;
+	s3c2xx0_softc->s3c2xx0_irq_rman.rm_descr = "S3C24X0 IRQs";
+	s3c2xx0_softc->s3c2xx0_mem_rman.rm_type = RMAN_ARRAY;
+	s3c2xx0_softc->s3c2xx0_mem_rman.rm_descr = "S3C24X0 Device Registers";
+	if (rman_init(&s3c2xx0_softc->s3c2xx0_irq_rman) != 0 ||
+	    rman_manage_region(&s3c2xx0_softc->s3c2xx0_irq_rman, 0,
+	    S3C2410_SUBIRQ_MAX) != 0) /* XXX Change S3C2440_SUBIRQ_MAX depending on micro */
+		panic("s3c24x0_attach: failed to set up IRQ rman");
+	/* Manage the registor memory space */
+	if ((rman_init(&s3c2xx0_softc->s3c2xx0_mem_rman) != 0) ||
+	    (rman_manage_region(&s3c2xx0_softc->s3c2xx0_mem_rman,
+	      S3C24X0_DEV_VA_OFFSET,
+	      S3C24X0_DEV_VA_OFFSET + S3C24X0_DEV_VA_SIZE) != 0) ||
+	    (rman_manage_region(&s3c2xx0_softc->s3c2xx0_mem_rman,
+	      S3C24X0_DEV_START, S3C24X0_DEV_STOP) != 0))
+		panic("s3c24x0_attach: failed to set up register rman");
 
-	if (bus_space_map(iot,
-		S3C24X0_INTCTL_PA_BASE, S3C24X0_INTCTL_SIZE,
-		BUS_SPACE_MAP_LINEAR, &sc->sc_sx.sc_intctl_ioh))
-		panic("Cannot map the interrupt controller");
-
-	/* Map the GPIO registers */
-	if (bus_space_map(iot, S3C24X0_GPIO_PA_BASE, S3C2410_GPIO_SIZE,
-		0, &sc->sc_sx.sc_gpio_ioh))
-		panic("Cannot map the GPIO");
-	/* Clock manager */
-	if (bus_space_map(iot, S3C24X0_CLKMAN_PA_BASE,
-		S3C24X0_CLKMAN_SIZE, 0, &sc->sc_sx.sc_clkman_ioh))
-		panic("cannot map the clock");
-
-	if (bus_space_map(iot, S3C24X0_TIMER_PA_BASE,
-		S3C24X0_TIMER_SIZE, 0, &sc->sc_timer_ioh))
-		panic("cannot map the TIMER");
-
-	if (bus_space_map(iot, S3C24X0_USBHC_PA_BASE,
-		S3C24X0_USBHC_SIZE, 0, &sc->sc_sx.sc_ohci_ioh))
-		panic("cannot map the USB Host");
-
-	if (bus_space_map(iot, S3C24X0_WDT_PA_BASE,
-		S3C24X0_WDT_SIZE, 0, &sc->sc_sx.sc_wdt_ioh))
-		panic("cannot map the watchdog timer");
+	/* These are needed for things without a proper device to attach to */
+	sc->sc_sx.sc_intctl_ioh = S3C24X0_INTCTL_BASE;
+	sc->sc_sx.sc_gpio_ioh = S3C24X0_GPIO_BASE;
+	sc->sc_sx.sc_clkman_ioh = S3C24X0_CLKMAN_BASE;
+	sc->sc_sx.sc_wdt_ioh = S3C24X0_WDT_BASE;
+	sc->sc_timer_ioh = S3C24X0_TIMER_BASE;
 
 	/*
 	 * Identify the CPU
@@ -376,20 +393,6 @@ s3c24x0_attach(device_t dev)
 	/*
 	 * Attach children devices
 	 */
-	s3c2xx0_softc->s3c2xx0_irq_rman.rm_type = RMAN_ARRAY;
-	s3c2xx0_softc->s3c2xx0_irq_rman.rm_descr = "S3C24X0 IRQs";
-	s3c2xx0_softc->s3c2xx0_mem_rman.rm_type = RMAN_ARRAY;
-	s3c2xx0_softc->s3c2xx0_mem_rman.rm_descr = "S3C24X0 Memory";
-	if (rman_init(&s3c2xx0_softc->s3c2xx0_irq_rman) != 0 ||
-	    rman_manage_region(&s3c2xx0_softc->s3c2xx0_irq_rman, 0,
-	    S3C2410_SUBIRQ_MAX) != 0)
-		panic("s3c24x0_attach: failed to set up IRQ rman");
-	/* Manage the registor memory space */
-	if ((rman_init(&s3c2xx0_softc->s3c2xx0_mem_rman) != 0) ||
-	    (rman_manage_region(&s3c2xx0_softc->s3c2xx0_mem_rman,
-	      S3C24X0_DEV_VA_OFFSET,
-	      S3C24X0_DEV_VA_OFFSET + S3C24X0_DEV_VA_SIZE) != 0))
-		panic("s3c24x0_attach: failed to set up register rman");
 
 	for (i = 0; s3c24x0_children[i].name != NULL; i++) {
 		child = s3c24x0_add_child(dev, s3c24x0_children[i].prio,

Modified: head/sys/arm/s3c2xx0/s3c24x0_machdep.c
==============================================================================
--- head/sys/arm/s3c2xx0/s3c24x0_machdep.c	Thu Jul 22 22:42:53 2010	(r210395)
+++ head/sys/arm/s3c2xx0/s3c24x0_machdep.c	Thu Jul 22 23:12:19 2010	(r210396)
@@ -146,6 +146,9 @@ static struct trapframe proc0_tf;
 
 /* Static device mappings. */
 static const struct pmap_devmap s3c24x0_devmap[] = {
+	/*
+	 * Map the devices we need early on.
+	 */
 	{
 		_A(S3C24X0_CLKMAN_BASE),
 		_A(S3C24X0_CLKMAN_PA_BASE),
@@ -161,13 +164,6 @@ static const struct pmap_devmap s3c24x0_
 		PTE_NOCACHE,
 	},
 	{
-		_A(S3C24X0_IIC_BASE),
-		_A(S3C24X0_IIC_PA_BASE),
-		_S(S3C24X0_IIC_SIZE),
-		VM_PROT_READ|VM_PROT_WRITE,                             
-		PTE_NOCACHE,
-	},
-	{
 		_A(S3C24X0_INTCTL_BASE),
 		_A(S3C24X0_INTCTL_PA_BASE),
 		_S(S3C24X0_INTCTL_SIZE),
@@ -175,16 +171,9 @@ static const struct pmap_devmap s3c24x0_
 		PTE_NOCACHE,
 	},
 	{
-		_A(S3C24X0_LCDC_BASE),
-		_A(S3C24X0_LCDC_PA_BASE),
-		_S(S3C24X0_LCDC_SIZE),
-		VM_PROT_READ|VM_PROT_WRITE,                             
-		PTE_NOCACHE,
-	},
-	{
-		_A(S3C24X0_SDI_BASE),
-		_A(S3C24X0_SDI_PA_BASE),
-		_S(S3C2410_SDI_SIZE),
+		_A(S3C24X0_TIMER_BASE),
+		_A(S3C24X0_TIMER_PA_BASE),
+		_S(S3C24X0_TIMER_SIZE),
 		VM_PROT_READ|VM_PROT_WRITE,                             
 		PTE_NOCACHE,
 	},
@@ -196,13 +185,6 @@ static const struct pmap_devmap s3c24x0_
 		PTE_NOCACHE,
 	},
 	{
-		_A(S3C24X0_USBHC_BASE),
-		_A(S3C24X0_USBHC_PA_BASE),
-		_S(S3C24X0_USBHC_SIZE),
-		VM_PROT_READ|VM_PROT_WRITE,                             
-		PTE_NOCACHE,
-	},
-	{
 		_A(S3C24X0_WDT_BASE),
 		_A(S3C24X0_WDT_PA_BASE),
 		_S(S3C24X0_WDT_SIZE),

Modified: head/sys/arm/s3c2xx0/s3c24x0reg.h
==============================================================================
--- head/sys/arm/s3c2xx0/s3c24x0reg.h	Thu Jul 22 22:42:53 2010	(r210395)
+++ head/sys/arm/s3c2xx0/s3c24x0reg.h	Thu Jul 22 23:12:19 2010	(r210396)
@@ -46,13 +46,21 @@
 #include <arm/s3c2xx0/s3c2xx0reg.h>
 
 /*
- * Map the device registers into kernel space
+ * Map the device registers into kernel space.
+ *
+ * As most devices use less than 1 page of memory reduce
+ * the distance between allocations by right shifting
+ * S3C24X0_DEV_SHIFT bits. Because the UART takes 3*0x4000
+ * bytes the upper limit on S3C24X0_DEV_SHIFT is 4.
+ * TODO: Fix the UART code so we can increase this value.
  */
 #define	S3C24X0_DEV_START	0x48000000
 #define	S3C24X0_DEV_STOP	0x60000000
-#define	S3C24X0_DEV_VA_OFFSET	0xD0000000
-#define	S3C24X0_DEV_VA_SIZE	(S3C24X0_DEV_STOP - S3C24X0_DEV_START)
-#define	S3C24X0_DEV_PA_TO_VA(x)	(x - S3C24X0_DEV_START + S3C24X0_DEV_VA_OFFSET)
+#define	S3C24X0_DEV_VA_OFFSET	0xD8000000
+#define	S3C24X0_DEV_SHIFT	4
+#define	S3C24X0_DEV_PA_SIZE	(S3C24X0_DEV_STOP - S3C24X0_DEV_START)
+#define	S3C24X0_DEV_VA_SIZE	(S3C24X0_DEV_PA_SIZE >> S3C24X0_DEV_SHIFT)
+#define	S3C24X0_DEV_PA_TO_VA(x)	((x >> S3C24X0_DEV_SHIFT) - S3C24X0_DEV_START + S3C24X0_DEV_VA_OFFSET)
 
 /*
  * Physical address of integrated peripherals
@@ -77,7 +85,7 @@
 #define	S3C24X0_UART0_PA_BASE	0x50000000
 #define	S3C24X0_UART0_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_UART0_PA_BASE)
 #define	S3C24X0_UART_PA_BASE(n)	(S3C24X0_UART0_PA_BASE+0x4000*(n))
-#define	S3C24X0_UART_BASE(n)	S3C24X0_DEV_PA_TO_VA(S3C24X0_UART_PA_BASE(n))
+#define	S3C24X0_UART_BASE(n)	(S3C24X0_UART0_BASE+0x4000*(n))
 #define	S3C24X0_TIMER_PA_BASE 	0x51000000
 #define	S3C24X0_TIMER_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_TIMER_PA_BASE)
 #define	S3C24X0_USBDC_PA_BASE 	0x5200140

Modified: head/sys/arm/s3c2xx0/s3c2xx0_space.c
==============================================================================
--- head/sys/arm/s3c2xx0/s3c2xx0_space.c	Thu Jul 22 22:42:53 2010	(r210395)
+++ head/sys/arm/s3c2xx0/s3c2xx0_space.c	Thu Jul 22 23:12:19 2010	(r210396)
@@ -182,9 +182,7 @@ s3c2xx0_bs_map(void *t, bus_addr_t bpa, 
 	startpa = trunc_page(bpa);
 	endpa = round_page(bpa + size);
 
-	/* XXX use extent manager to check duplicate mapping */
-
-	va = kmem_alloc(kernel_map, endpa - startpa);
+	va = kmem_alloc_nofault(kernel_map, endpa - startpa);
 	if (!va)
 		return (ENOMEM);
 

Modified: head/sys/arm/s3c2xx0/s3c2xx0var.h
==============================================================================
--- head/sys/arm/s3c2xx0/s3c2xx0var.h	Thu Jul 22 22:42:53 2010	(r210395)
+++ head/sys/arm/s3c2xx0/s3c2xx0var.h	Thu Jul 22 23:12:19 2010	(r210396)
@@ -53,13 +53,8 @@ struct s3c2xx0_softc {
 	bus_space_tag_t  	sc_iot;
 
 	bus_space_handle_t	sc_intctl_ioh;
-	bus_space_handle_t	sc_clkman_ioh; 	/* Clock manager */
 	bus_space_handle_t	sc_gpio_ioh;  	/* GPIO */
-	bus_space_handle_t	sc_lcd_ioh; 	/* LCD */
-	bus_space_handle_t	sc_rtc_ioh; 	/* real time clock */
-	bus_space_handle_t	sc_mci_ioh; 	/* MMC/SD */
-	bus_space_handle_t	sc_iic_ioh; 	/* IIC */
-	bus_space_handle_t	sc_ohci_ioh; 	/* USB/OHCI */
+	bus_space_handle_t	sc_clkman_ioh; 	/* Clock manager */
 	bus_space_handle_t	sc_wdt_ioh; 	/* Watchdog Timer */
 
 	bus_dma_tag_t  		sc_dmat;


More information about the svn-src-head mailing list