Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Michael Schmitz and committed by
Geert Uytterhoeven
fded332b c7208164

+58 -19
+56 -19
arch/m68k/atari/stram.c
··· 47 47 48 48 static unsigned long pool_size = 1024*1024; 49 49 50 + static unsigned long stram_virt_offset; 50 51 51 52 static int __init atari_stram_setup(char *arg) 52 53 { ··· 68 67 void __init atari_stram_init(void) 69 68 { 70 69 int i; 71 - void *stram_start; 72 70 73 71 /* 74 72 * determine whether kernel code resides in ST-RAM 75 73 * (then ST-RAM is the first memory block at virtual 0x0) 76 74 */ 77 - stram_start = phys_to_virt(0); 78 - kernel_in_stram = (stram_start == 0); 75 + kernel_in_stram = (m68k_memory[0].addr == 0); 79 76 80 77 for (i = 0; i < m68k_num_memory; ++i) { 81 78 if (m68k_memory[i].addr == 0) { ··· 88 89 89 90 /* 90 91 * This function is called from setup_arch() to reserve the pages needed for 91 - * ST-RAM management. 92 + * ST-RAM management, if the kernel resides in ST-RAM. 92 93 */ 93 94 void __init atari_stram_reserve_pages(void *start_mem) 94 95 { 95 - /* 96 - * always reserve first page of ST-RAM, the first 2 KiB are 97 - * supervisor-only! 98 - */ 99 - if (!kernel_in_stram) 100 - reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT); 101 - 102 - stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size); 103 - stram_pool.end = stram_pool.start + pool_size - 1; 104 - request_resource(&iomem_resource, &stram_pool); 105 - 106 - pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n", 107 - pool_size, &stram_pool); 96 + if (kernel_in_stram) { 97 + pr_debug("atari_stram pool: kernel in ST-RAM, using alloc_bootmem!\n"); 98 + stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size); 99 + stram_pool.end = stram_pool.start + pool_size - 1; 100 + request_resource(&iomem_resource, &stram_pool); 101 + stram_virt_offset = 0; 102 + pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n", 103 + pool_size, &stram_pool); 104 + pr_debug("atari_stram pool: stram_virt_offset = %lx\n", 105 + stram_virt_offset); 106 + } 108 107 } 108 + 109 + 110 + /* 111 + * This function is called as arch initcall to reserve the pages needed for 112 + * ST-RAM management, if the kernel does not reside in ST-RAM. 113 + */ 114 + int __init atari_stram_map_pages(void) 115 + { 116 + if (!kernel_in_stram) { 117 + /* 118 + * Skip page 0, as the fhe first 2 KiB are supervisor-only! 119 + */ 120 + pr_debug("atari_stram pool: kernel not in ST-RAM, using ioremap!\n"); 121 + stram_pool.start = PAGE_SIZE; 122 + stram_pool.end = stram_pool.start + pool_size - 1; 123 + request_resource(&iomem_resource, &stram_pool); 124 + stram_virt_offset = (unsigned long) ioremap(stram_pool.start, 125 + resource_size(&stram_pool)) - stram_pool.start; 126 + pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n", 127 + pool_size, &stram_pool); 128 + pr_debug("atari_stram pool: stram_virt_offset = %lx\n", 129 + stram_virt_offset); 130 + } 131 + return 0; 132 + } 133 + arch_initcall(atari_stram_map_pages); 134 + 135 + 136 + void *atari_stram_to_virt(unsigned long phys) 137 + { 138 + return (void *)(phys + stram_virt_offset); 139 + } 140 + EXPORT_SYMBOL(atari_stram_to_virt); 141 + 142 + 143 + unsigned long atari_stram_to_phys(void *virt) 144 + { 145 + return (unsigned long)(virt - stram_virt_offset); 146 + } 147 + EXPORT_SYMBOL(atari_stram_to_phys); 109 148 110 149 111 150 void *atari_stram_alloc(unsigned long size, const char *owner) ··· 171 134 } 172 135 173 136 pr_debug("atari_stram_alloc: returning %pR\n", res); 174 - return (void *)res->start; 137 + return atari_stram_to_virt(res->start); 175 138 } 176 139 EXPORT_SYMBOL(atari_stram_alloc); 177 140 178 141 179 142 void atari_stram_free(void *addr) 180 143 { 181 - unsigned long start = (unsigned long)addr; 144 + unsigned long start = atari_stram_to_phys(addr); 182 145 struct resource *res; 183 146 unsigned long size; 184 147
+2
arch/m68k/include/asm/atari_stram.h
··· 8 8 /* public interface */ 9 9 void *atari_stram_alloc(unsigned long size, const char *owner); 10 10 void atari_stram_free(void *); 11 + void *atari_stram_to_virt(unsigned long phys); 12 + unsigned long atari_stram_to_phys(void *); 11 13 12 14 /* functions called internally by other parts of the kernel */ 13 15 void atari_stram_init(void);