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)
This commit is contained in:
Andrew Turner 2010-07-22 23:12:19 +00:00
parent 6f450d8e09
commit 6eae6892da
5 changed files with 67 additions and 81 deletions

View File

@ -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,

View File

@ -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),

View File

@ -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

View File

@ -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);

View File

@ -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;