diff --git a/sys/arm/s3c2xx0/s3c24x0.c b/sys/arm/s3c2xx0/s3c24x0.c index b0e338add76f..c896bcfea732 100644 --- a/sys/arm/s3c2xx0/s3c24x0.c +++ b/sys/arm/s3c2xx0/s3c24x0.c @@ -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, device_t child, int type, int *rid, 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, diff --git a/sys/arm/s3c2xx0/s3c24x0_machdep.c b/sys/arm/s3c2xx0/s3c24x0_machdep.c index 2c73842bcb64..899222f52be9 100644 --- a/sys/arm/s3c2xx0/s3c24x0_machdep.c +++ b/sys/arm/s3c2xx0/s3c24x0_machdep.c @@ -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), @@ -160,13 +163,6 @@ static const struct pmap_devmap s3c24x0_devmap[] = { VM_PROT_READ|VM_PROT_WRITE, 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), @@ -175,16 +171,9 @@ static const struct pmap_devmap s3c24x0_devmap[] = { 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, }, @@ -195,13 +184,6 @@ static const struct pmap_devmap s3c24x0_devmap[] = { VM_PROT_READ|VM_PROT_WRITE, 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), diff --git a/sys/arm/s3c2xx0/s3c24x0reg.h b/sys/arm/s3c2xx0/s3c24x0reg.h index 3b8dc6ecfa65..25bee39809c1 100644 --- a/sys/arm/s3c2xx0/s3c24x0reg.h +++ b/sys/arm/s3c2xx0/s3c24x0reg.h @@ -46,13 +46,21 @@ #include /* - * 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 diff --git a/sys/arm/s3c2xx0/s3c2xx0_space.c b/sys/arm/s3c2xx0/s3c2xx0_space.c index 23496729df4e..958e65882922 100644 --- a/sys/arm/s3c2xx0/s3c2xx0_space.c +++ b/sys/arm/s3c2xx0/s3c2xx0_space.c @@ -182,9 +182,7 @@ s3c2xx0_bs_map(void *t, bus_addr_t bpa, bus_size_t size, 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); diff --git a/sys/arm/s3c2xx0/s3c2xx0var.h b/sys/arm/s3c2xx0/s3c2xx0var.h index fea800efb492..fea0982e9b01 100644 --- a/sys/arm/s3c2xx0/s3c2xx0var.h +++ b/sys/arm/s3c2xx0/s3c2xx0var.h @@ -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;