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;
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to