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:
parent
6f450d8e09
commit
6eae6892da
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user