diff options
-rw-r--r-- | arch/m68k/Kconfig.mmu | 6 | ||||
-rw-r--r-- | arch/m68k/atari/stram.c | 354 | ||||
-rw-r--r-- | arch/m68k/include/asm/atari_stram.h | 3 | ||||
-rw-r--r-- | arch/m68k/mm/init_mm.c | 5 |
4 files changed, 70 insertions, 298 deletions
diff --git a/arch/m68k/Kconfig.mmu b/arch/m68k/Kconfig.mmu index 16539b1d5d3a..13e20bbc4079 100644 --- a/arch/m68k/Kconfig.mmu +++ b/arch/m68k/Kconfig.mmu | |||
@@ -372,12 +372,6 @@ config AMIGA_PCMCIA | |||
372 | Include support in the kernel for pcmcia on Amiga 1200 and Amiga | 372 | Include support in the kernel for pcmcia on Amiga 1200 and Amiga |
373 | 600. If you intend to use pcmcia cards say Y; otherwise say N. | 373 | 600. If you intend to use pcmcia cards say Y; otherwise say N. |
374 | 374 | ||
375 | config STRAM_PROC | ||
376 | bool "ST-RAM statistics in /proc" | ||
377 | depends on ATARI | ||
378 | help | ||
379 | Say Y here to report ST-RAM usage statistics in /proc/stram. | ||
380 | |||
381 | config HEARTBEAT | 375 | config HEARTBEAT |
382 | bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40 | 376 | bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40 |
383 | default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300 | 377 | default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300 |
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c index 6ec3b7f33779..0810c8d56e59 100644 --- a/arch/m68k/atari/stram.c +++ b/arch/m68k/atari/stram.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/m68k/atari/stram.c: Functions for ST-RAM allocations | 2 | * Functions for ST-RAM allocations |
3 | * | 3 | * |
4 | * Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> | 4 | * Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> |
5 | * | 5 | * |
@@ -30,91 +30,35 @@ | |||
30 | #include <asm/atari_stram.h> | 30 | #include <asm/atari_stram.h> |
31 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | 32 | ||
33 | #undef DEBUG | ||
34 | |||
35 | #ifdef DEBUG | ||
36 | #define DPRINTK(fmt,args...) printk( fmt, ##args ) | ||
37 | #else | ||
38 | #define DPRINTK(fmt,args...) | ||
39 | #endif | ||
40 | |||
41 | #if defined(CONFIG_PROC_FS) && defined(CONFIG_STRAM_PROC) | ||
42 | /* abbrev for the && above... */ | ||
43 | #define DO_PROC | ||
44 | #include <linux/proc_fs.h> | ||
45 | #include <linux/seq_file.h> | ||
46 | #endif | ||
47 | 33 | ||
48 | /* | 34 | /* |
49 | * ++roman: | 35 | * The ST-RAM allocator allocates memory from a pool of reserved ST-RAM of |
50 | * | 36 | * configurable size, set aside on ST-RAM init. |
51 | * New version of ST-Ram buffer allocation. Instead of using the | 37 | * As long as this pool is not exhausted, allocation of real ST-RAM can be |
52 | * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000 | 38 | * guaranteed. |
53 | * (1 MB granularity!), such buffers are reserved like this: | ||
54 | * | ||
55 | * - If the kernel resides in ST-Ram anyway, we can take the buffer | ||
56 | * from behind the current kernel data space the normal way | ||
57 | * (incrementing start_mem). | ||
58 | * | ||
59 | * - If the kernel is in TT-Ram, stram_init() initializes start and | ||
60 | * end of the available region. Buffers are allocated from there | ||
61 | * and mem_init() later marks the such used pages as reserved. | ||
62 | * Since each TT-Ram chunk is at least 4 MB in size, I hope there | ||
63 | * won't be an overrun of the ST-Ram region by normal kernel data | ||
64 | * space. | ||
65 | * | ||
66 | * For that, ST-Ram may only be allocated while kernel initialization | ||
67 | * is going on, or exactly: before mem_init() is called. There is also | ||
68 | * no provision now for freeing ST-Ram buffers. It seems that isn't | ||
69 | * really needed. | ||
70 | * | ||
71 | */ | 39 | */ |
72 | 40 | ||
73 | /* Start and end (virtual) of ST-RAM */ | ||
74 | static void *stram_start, *stram_end; | ||
75 | |||
76 | /* set after memory_init() executed and allocations via start_mem aren't | ||
77 | * possible anymore */ | ||
78 | static int mem_init_done; | ||
79 | |||
80 | /* set if kernel is in ST-RAM */ | 41 | /* set if kernel is in ST-RAM */ |
81 | static int kernel_in_stram; | 42 | static int kernel_in_stram; |
82 | 43 | ||
83 | typedef struct stram_block { | 44 | static struct resource stram_pool = { |
84 | struct stram_block *next; | 45 | .name = "ST-RAM Pool" |
85 | void *start; | 46 | }; |
86 | unsigned long size; | ||
87 | unsigned flags; | ||
88 | const char *owner; | ||
89 | } BLOCK; | ||
90 | |||
91 | /* values for flags field */ | ||
92 | #define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */ | ||
93 | #define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */ | ||
94 | #define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */ | ||
95 | 47 | ||
96 | /* list of allocated blocks */ | 48 | static unsigned long pool_size = 1024*1024; |
97 | static BLOCK *alloc_list; | ||
98 | 49 | ||
99 | /* We can't always use kmalloc() to allocate BLOCK structures, since | ||
100 | * stram_alloc() can be called rather early. So we need some pool of | ||
101 | * statically allocated structures. 20 of them is more than enough, so in most | ||
102 | * cases we never should need to call kmalloc(). */ | ||
103 | #define N_STATIC_BLOCKS 20 | ||
104 | static BLOCK static_blocks[N_STATIC_BLOCKS]; | ||
105 | 50 | ||
106 | /***************************** Prototypes *****************************/ | 51 | static int __init atari_stram_setup(char *arg) |
52 | { | ||
53 | if (!MACH_IS_ATARI) | ||
54 | return 0; | ||
107 | 55 | ||
108 | static BLOCK *add_region( void *addr, unsigned long size ); | 56 | pool_size = memparse(arg, NULL); |
109 | static BLOCK *find_region( void *addr ); | 57 | return 0; |
110 | static int remove_region( BLOCK *block ); | 58 | } |
111 | 59 | ||
112 | /************************* End of Prototypes **************************/ | 60 | early_param("stram_pool", atari_stram_setup); |
113 | 61 | ||
114 | |||
115 | /* ------------------------------------------------------------------------ */ | ||
116 | /* Public Interface */ | ||
117 | /* ------------------------------------------------------------------------ */ | ||
118 | 62 | ||
119 | /* | 63 | /* |
120 | * This init function is called very early by atari/config.c | 64 | * This init function is called very early by atari/config.c |
@@ -123,25 +67,23 @@ static int remove_region( BLOCK *block ); | |||
123 | void __init atari_stram_init(void) | 67 | void __init atari_stram_init(void) |
124 | { | 68 | { |
125 | int i; | 69 | int i; |
70 | void *stram_start; | ||
126 | 71 | ||
127 | /* initialize static blocks */ | 72 | /* |
128 | for( i = 0; i < N_STATIC_BLOCKS; ++i ) | 73 | * determine whether kernel code resides in ST-RAM |
129 | static_blocks[i].flags = BLOCK_FREE; | 74 | * (then ST-RAM is the first memory block at virtual 0x0) |
130 | 75 | */ | |
131 | /* determine whether kernel code resides in ST-RAM (then ST-RAM is the | ||
132 | * first memory block at virtual 0x0) */ | ||
133 | stram_start = phys_to_virt(0); | 76 | stram_start = phys_to_virt(0); |
134 | kernel_in_stram = (stram_start == 0); | 77 | kernel_in_stram = (stram_start == 0); |
135 | 78 | ||
136 | for( i = 0; i < m68k_num_memory; ++i ) { | 79 | for (i = 0; i < m68k_num_memory; ++i) { |
137 | if (m68k_memory[i].addr == 0) { | 80 | if (m68k_memory[i].addr == 0) { |
138 | /* skip first 2kB or page (supervisor-only!) */ | ||
139 | stram_end = stram_start + m68k_memory[i].size; | ||
140 | return; | 81 | return; |
141 | } | 82 | } |
142 | } | 83 | } |
84 | |||
143 | /* Should never come here! (There is always ST-Ram!) */ | 85 | /* Should never come here! (There is always ST-Ram!) */ |
144 | panic( "atari_stram_init: no ST-RAM found!" ); | 86 | panic("atari_stram_init: no ST-RAM found!"); |
145 | } | 87 | } |
146 | 88 | ||
147 | 89 | ||
@@ -151,226 +93,68 @@ void __init atari_stram_init(void) | |||
151 | */ | 93 | */ |
152 | void __init atari_stram_reserve_pages(void *start_mem) | 94 | void __init atari_stram_reserve_pages(void *start_mem) |
153 | { | 95 | { |
154 | /* always reserve first page of ST-RAM, the first 2 kB are | 96 | /* |
155 | * supervisor-only! */ | 97 | * always reserve first page of ST-RAM, the first 2 KiB are |
98 | * supervisor-only! | ||
99 | */ | ||
156 | if (!kernel_in_stram) | 100 | if (!kernel_in_stram) |
157 | reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT); | 101 | reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT); |
158 | 102 | ||
159 | } | 103 | stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size); |
104 | stram_pool.end = stram_pool.start + pool_size - 1; | ||
105 | request_resource(&iomem_resource, &stram_pool); | ||
160 | 106 | ||
161 | void atari_stram_mem_init_hook (void) | 107 | pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n", |
162 | { | 108 | pool_size, &stram_pool); |
163 | mem_init_done = 1; | ||
164 | } | 109 | } |
165 | 110 | ||
166 | 111 | ||
167 | /* | 112 | void *atari_stram_alloc(unsigned long size, const char *owner) |
168 | * This is main public interface: somehow allocate a ST-RAM block | ||
169 | * | ||
170 | * - If we're before mem_init(), we have to make a static allocation. The | ||
171 | * region is taken in the kernel data area (if the kernel is in ST-RAM) or | ||
172 | * from the start of ST-RAM (if the kernel is in TT-RAM) and added to the | ||
173 | * rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel | ||
174 | * address space in the latter case. | ||
175 | * | ||
176 | * - If mem_init() already has been called, try with __get_dma_pages(). | ||
177 | * This has the disadvantage that it's very hard to get more than 1 page, | ||
178 | * and it is likely to fail :-( | ||
179 | * | ||
180 | */ | ||
181 | void *atari_stram_alloc(long size, const char *owner) | ||
182 | { | 113 | { |
183 | void *addr = NULL; | 114 | struct resource *res; |
184 | BLOCK *block; | 115 | int error; |
185 | int flags; | 116 | |
186 | 117 | pr_debug("atari_stram_alloc: allocate %lu bytes\n", size); | |
187 | DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner); | 118 | |
188 | 119 | /* round up */ | |
189 | if (!mem_init_done) | 120 | size = PAGE_ALIGN(size); |
190 | return alloc_bootmem_low(size); | 121 | |
191 | else { | 122 | res = kzalloc(sizeof(struct resource), GFP_KERNEL); |
192 | /* After mem_init(): can only resort to __get_dma_pages() */ | 123 | if (!res) |
193 | addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size)); | 124 | return NULL; |
194 | flags = BLOCK_GFP; | 125 | |
195 | DPRINTK( "atari_stram_alloc: after mem_init, " | 126 | res->name = owner; |
196 | "get_pages=%p\n", addr ); | 127 | error = allocate_resource(&stram_pool, res, size, 0, UINT_MAX, |
128 | PAGE_SIZE, NULL, NULL); | ||
129 | if (error < 0) { | ||
130 | pr_err("atari_stram_alloc: allocate_resource() failed %d!\n", | ||
131 | error); | ||
132 | kfree(res); | ||
133 | return NULL; | ||
197 | } | 134 | } |
198 | 135 | ||
199 | if (addr) { | 136 | pr_debug("atari_stram_alloc: returning %pR\n", res); |
200 | if (!(block = add_region( addr, size ))) { | 137 | return (void *)res->start; |
201 | /* out of memory for BLOCK structure :-( */ | ||
202 | DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- " | ||
203 | "freeing again\n" ); | ||
204 | free_pages((unsigned long)addr, get_order(size)); | ||
205 | return( NULL ); | ||
206 | } | ||
207 | block->owner = owner; | ||
208 | block->flags |= flags; | ||
209 | } | ||
210 | return( addr ); | ||
211 | } | 138 | } |
212 | EXPORT_SYMBOL(atari_stram_alloc); | 139 | EXPORT_SYMBOL(atari_stram_alloc); |
213 | 140 | ||
214 | void atari_stram_free( void *addr ) | ||
215 | 141 | ||
142 | void atari_stram_free(void *addr) | ||
216 | { | 143 | { |
217 | BLOCK *block; | 144 | unsigned long start = (unsigned long)addr; |
218 | 145 | struct resource *res; | |
219 | DPRINTK( "atari_stram_free(addr=%p)\n", addr ); | 146 | unsigned long size; |
220 | 147 | ||
221 | if (!(block = find_region( addr ))) { | 148 | res = lookup_resource(&stram_pool, start); |
222 | printk( KERN_ERR "Attempt to free non-allocated ST-RAM block at %p " | 149 | if (!res) { |
223 | "from %p\n", addr, __builtin_return_address(0) ); | 150 | pr_err("atari_stram_free: trying to free nonexistent region " |
151 | "at %p\n", addr); | ||
224 | return; | 152 | return; |
225 | } | 153 | } |
226 | DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, " | ||
227 | "flags=%02x\n", block, block->size, block->owner, block->flags ); | ||
228 | |||
229 | if (!(block->flags & BLOCK_GFP)) | ||
230 | goto fail; | ||
231 | 154 | ||
232 | DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n", | 155 | size = resource_size(res); |
233 | get_order(block->size)); | 156 | pr_debug("atari_stram_free: free %lu bytes at %p\n", size, addr); |
234 | free_pages((unsigned long)addr, get_order(block->size)); | 157 | release_resource(res); |
235 | remove_region( block ); | 158 | kfree(res); |
236 | return; | ||
237 | |||
238 | fail: | ||
239 | printk( KERN_ERR "atari_stram_free: cannot free block at %p " | ||
240 | "(called from %p)\n", addr, __builtin_return_address(0) ); | ||
241 | } | 159 | } |
242 | EXPORT_SYMBOL(atari_stram_free); | 160 | EXPORT_SYMBOL(atari_stram_free); |
243 | |||
244 | |||
245 | /* ------------------------------------------------------------------------ */ | ||
246 | /* Region Management */ | ||
247 | /* ------------------------------------------------------------------------ */ | ||
248 | |||
249 | |||
250 | /* insert a region into the alloced list (sorted) */ | ||
251 | static BLOCK *add_region( void *addr, unsigned long size ) | ||
252 | { | ||
253 | BLOCK **p, *n = NULL; | ||
254 | int i; | ||
255 | |||
256 | for( i = 0; i < N_STATIC_BLOCKS; ++i ) { | ||
257 | if (static_blocks[i].flags & BLOCK_FREE) { | ||
258 | n = &static_blocks[i]; | ||
259 | n->flags = 0; | ||
260 | break; | ||
261 | } | ||
262 | } | ||
263 | if (!n && mem_init_done) { | ||
264 | /* if statics block pool exhausted and we can call kmalloc() already | ||
265 | * (after mem_init()), try that */ | ||
266 | n = kmalloc( sizeof(BLOCK), GFP_KERNEL ); | ||
267 | if (n) | ||
268 | n->flags = BLOCK_KMALLOCED; | ||
269 | } | ||
270 | if (!n) { | ||
271 | printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" ); | ||
272 | return( NULL ); | ||
273 | } | ||
274 | n->start = addr; | ||
275 | n->size = size; | ||
276 | |||
277 | for( p = &alloc_list; *p; p = &((*p)->next) ) | ||
278 | if ((*p)->start > addr) break; | ||
279 | n->next = *p; | ||
280 | *p = n; | ||
281 | |||
282 | return( n ); | ||
283 | } | ||
284 | |||
285 | |||
286 | /* find a region (by start addr) in the alloced list */ | ||
287 | static BLOCK *find_region( void *addr ) | ||
288 | { | ||
289 | BLOCK *p; | ||
290 | |||
291 | for( p = alloc_list; p; p = p->next ) { | ||
292 | if (p->start == addr) | ||
293 | return( p ); | ||
294 | if (p->start > addr) | ||
295 | break; | ||
296 | } | ||
297 | return( NULL ); | ||
298 | } | ||
299 | |||
300 | |||
301 | /* remove a block from the alloced list */ | ||
302 | static int remove_region( BLOCK *block ) | ||
303 | { | ||
304 | BLOCK **p; | ||
305 | |||
306 | for( p = &alloc_list; *p; p = &((*p)->next) ) | ||
307 | if (*p == block) break; | ||
308 | if (!*p) | ||
309 | return( 0 ); | ||
310 | |||
311 | *p = block->next; | ||
312 | if (block->flags & BLOCK_KMALLOCED) | ||
313 | kfree( block ); | ||
314 | else | ||
315 | block->flags |= BLOCK_FREE; | ||
316 | return( 1 ); | ||
317 | } | ||
318 | |||
319 | |||
320 | |||
321 | /* ------------------------------------------------------------------------ */ | ||
322 | /* /proc statistics file stuff */ | ||
323 | /* ------------------------------------------------------------------------ */ | ||
324 | |||
325 | #ifdef DO_PROC | ||
326 | |||
327 | #define PRINT_PROC(fmt,args...) seq_printf( m, fmt, ##args ) | ||
328 | |||
329 | static int stram_proc_show(struct seq_file *m, void *v) | ||
330 | { | ||
331 | BLOCK *p; | ||
332 | |||
333 | PRINT_PROC("Total ST-RAM: %8u kB\n", | ||
334 | (stram_end - stram_start) >> 10); | ||
335 | PRINT_PROC( "Allocated regions:\n" ); | ||
336 | for( p = alloc_list; p; p = p->next ) { | ||
337 | PRINT_PROC("0x%08lx-0x%08lx: %s (", | ||
338 | virt_to_phys(p->start), | ||
339 | virt_to_phys(p->start+p->size-1), | ||
340 | p->owner); | ||
341 | if (p->flags & BLOCK_GFP) | ||
342 | PRINT_PROC( "page-alloced)\n" ); | ||
343 | else | ||
344 | PRINT_PROC( "??)\n" ); | ||
345 | } | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int stram_proc_open(struct inode *inode, struct file *file) | ||
351 | { | ||
352 | return single_open(file, stram_proc_show, NULL); | ||
353 | } | ||
354 | |||
355 | static const struct file_operations stram_proc_fops = { | ||
356 | .open = stram_proc_open, | ||
357 | .read = seq_read, | ||
358 | .llseek = seq_lseek, | ||
359 | .release = single_release, | ||
360 | }; | ||
361 | |||
362 | static int __init proc_stram_init(void) | ||
363 | { | ||
364 | proc_create("stram", 0, NULL, &stram_proc_fops); | ||
365 | return 0; | ||
366 | } | ||
367 | module_init(proc_stram_init); | ||
368 | #endif | ||
369 | |||
370 | |||
371 | /* | ||
372 | * Local variables: | ||
373 | * c-indent-level: 4 | ||
374 | * tab-width: 4 | ||
375 | * End: | ||
376 | */ | ||
diff --git a/arch/m68k/include/asm/atari_stram.h b/arch/m68k/include/asm/atari_stram.h index 7546d13963be..62e27598af91 100644 --- a/arch/m68k/include/asm/atari_stram.h +++ b/arch/m68k/include/asm/atari_stram.h | |||
@@ -6,12 +6,11 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | /* public interface */ | 8 | /* public interface */ |
9 | void *atari_stram_alloc(long size, const char *owner); | 9 | void *atari_stram_alloc(unsigned long size, const char *owner); |
10 | void atari_stram_free(void *); | 10 | void atari_stram_free(void *); |
11 | 11 | ||
12 | /* functions called internally by other parts of the kernel */ | 12 | /* functions called internally by other parts of the kernel */ |
13 | void atari_stram_init(void); | 13 | void atari_stram_init(void); |
14 | void atari_stram_reserve_pages(void *start_mem); | 14 | void atari_stram_reserve_pages(void *start_mem); |
15 | void atari_stram_mem_init_hook (void); | ||
16 | 15 | ||
17 | #endif /*_M68K_ATARI_STRAM_H */ | 16 | #endif /*_M68K_ATARI_STRAM_H */ |
diff --git a/arch/m68k/mm/init_mm.c b/arch/m68k/mm/init_mm.c index 9113c2f17607..bbe525434ccb 100644 --- a/arch/m68k/mm/init_mm.c +++ b/arch/m68k/mm/init_mm.c | |||
@@ -83,11 +83,6 @@ void __init mem_init(void) | |||
83 | int initpages = 0; | 83 | int initpages = 0; |
84 | int i; | 84 | int i; |
85 | 85 | ||
86 | #ifdef CONFIG_ATARI | ||
87 | if (MACH_IS_ATARI) | ||
88 | atari_stram_mem_init_hook(); | ||
89 | #endif | ||
90 | |||
91 | /* this will put all memory onto the freelists */ | 86 | /* this will put all memory onto the freelists */ |
92 | totalram_pages = num_physpages = 0; | 87 | totalram_pages = num_physpages = 0; |
93 | for_each_online_pgdat(pgdat) { | 88 | for_each_online_pgdat(pgdat) { |