m68k/atari - stram: alloc ST-RAM pool even if kernel not in ST-RAM

With the kernel loaded to FastRAM (TT-RAM), none of the ST-RAM
address range is mapped by init_mem, and ST-RAM is not accessible
through the normal allocation pathways as a result.

Implement ST-RAM pool allocation to be based on physical addresses
always (it already was when the kernel was loaded in ST-RAM).
Return kernel virtual addresses as per normal.

The current test for the kernel residing in ST-RAM always returns
true. Use the bootinfo memory chunk order instead - with the kernel
in FastRAM, ST-RAM (phys. 0x0) is not the first chunk.

In case the kernel is running from FastRAM, delay mapping of ST-RAM
pool until after mem_init.

Provide helper functions for those users of ST-RAM that need
to be aware of the backing physical addresses.

Kudos to Geert for his hints on getting this started.

Signed-off-by: Michael Schmitz <schmitz@debian.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
This commit is contained in:
Michael Schmitz 2014-03-31 21:06:05 +13:00 committed by Geert Uytterhoeven
parent c7208164e6
commit fded332bf4
2 changed files with 58 additions and 19 deletions

View file

@ -47,6 +47,7 @@ static struct resource stram_pool = {
static unsigned long pool_size = 1024*1024; static unsigned long pool_size = 1024*1024;
static unsigned long stram_virt_offset;
static int __init atari_stram_setup(char *arg) static int __init atari_stram_setup(char *arg)
{ {
@ -67,14 +68,12 @@ early_param("stram_pool", atari_stram_setup);
void __init atari_stram_init(void) void __init atari_stram_init(void)
{ {
int i; int i;
void *stram_start;
/* /*
* determine whether kernel code resides in ST-RAM * determine whether kernel code resides in ST-RAM
* (then ST-RAM is the first memory block at virtual 0x0) * (then ST-RAM is the first memory block at virtual 0x0)
*/ */
stram_start = phys_to_virt(0); kernel_in_stram = (m68k_memory[0].addr == 0);
kernel_in_stram = (stram_start == 0);
for (i = 0; i < m68k_num_memory; ++i) { for (i = 0; i < m68k_num_memory; ++i) {
if (m68k_memory[i].addr == 0) { if (m68k_memory[i].addr == 0) {
@ -89,26 +88,64 @@ void __init atari_stram_init(void)
/* /*
* This function is called from setup_arch() to reserve the pages needed for * This function is called from setup_arch() to reserve the pages needed for
* ST-RAM management. * ST-RAM management, if the kernel resides in ST-RAM.
*/ */
void __init atari_stram_reserve_pages(void *start_mem) void __init atari_stram_reserve_pages(void *start_mem)
{ {
/* if (kernel_in_stram) {
* always reserve first page of ST-RAM, the first 2 KiB are pr_debug("atari_stram pool: kernel in ST-RAM, using alloc_bootmem!\n");
* supervisor-only! stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size);
*/ stram_pool.end = stram_pool.start + pool_size - 1;
if (!kernel_in_stram) request_resource(&iomem_resource, &stram_pool);
reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT); stram_virt_offset = 0;
pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size); pool_size, &stram_pool);
stram_pool.end = stram_pool.start + pool_size - 1; pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
request_resource(&iomem_resource, &stram_pool); stram_virt_offset);
}
pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
pool_size, &stram_pool);
} }
/*
* This function is called as arch initcall to reserve the pages needed for
* ST-RAM management, if the kernel does not reside in ST-RAM.
*/
int __init atari_stram_map_pages(void)
{
if (!kernel_in_stram) {
/*
* Skip page 0, as the fhe first 2 KiB are supervisor-only!
*/
pr_debug("atari_stram pool: kernel not in ST-RAM, using ioremap!\n");
stram_pool.start = PAGE_SIZE;
stram_pool.end = stram_pool.start + pool_size - 1;
request_resource(&iomem_resource, &stram_pool);
stram_virt_offset = (unsigned long) ioremap(stram_pool.start,
resource_size(&stram_pool)) - stram_pool.start;
pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
pool_size, &stram_pool);
pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
stram_virt_offset);
}
return 0;
}
arch_initcall(atari_stram_map_pages);
void *atari_stram_to_virt(unsigned long phys)
{
return (void *)(phys + stram_virt_offset);
}
EXPORT_SYMBOL(atari_stram_to_virt);
unsigned long atari_stram_to_phys(void *virt)
{
return (unsigned long)(virt - stram_virt_offset);
}
EXPORT_SYMBOL(atari_stram_to_phys);
void *atari_stram_alloc(unsigned long size, const char *owner) void *atari_stram_alloc(unsigned long size, const char *owner)
{ {
struct resource *res; struct resource *res;
@ -134,14 +171,14 @@ void *atari_stram_alloc(unsigned long size, const char *owner)
} }
pr_debug("atari_stram_alloc: returning %pR\n", res); pr_debug("atari_stram_alloc: returning %pR\n", res);
return (void *)res->start; return atari_stram_to_virt(res->start);
} }
EXPORT_SYMBOL(atari_stram_alloc); EXPORT_SYMBOL(atari_stram_alloc);
void atari_stram_free(void *addr) void atari_stram_free(void *addr)
{ {
unsigned long start = (unsigned long)addr; unsigned long start = atari_stram_to_phys(addr);
struct resource *res; struct resource *res;
unsigned long size; unsigned long size;

View file

@ -8,6 +8,8 @@
/* public interface */ /* public interface */
void *atari_stram_alloc(unsigned long size, const char *owner); void *atari_stram_alloc(unsigned long size, const char *owner);
void atari_stram_free(void *); void atari_stram_free(void *);
void *atari_stram_to_virt(unsigned long phys);
unsigned long atari_stram_to_phys(void *);
/* functions called internally by other parts of the kernel */ /* functions called internally by other parts of the kernel */
void atari_stram_init(void); void atari_stram_init(void);