File: /usr/src/linux/arch/parisc/mm/init.c
1 /*
2 * linux/arch/parisc/mm/init.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Copyright 1999 SuSE GmbH
6 * changed by Philipp Rumpf
7 * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
8 *
9 */
10
11 #include <linux/config.h>
12
13 #include <linux/mm.h>
14 #include <linux/bootmem.h>
15 #include <linux/delay.h>
16 #include <linux/init.h>
17 #include <linux/pci.h> /* for hppa_dma_ops and pcxl_dma_ops */
18 #include <linux/swap.h>
19 #include <linux/unistd.h>
20
21 #include <asm/pgalloc.h>
22
23 static unsigned long totalram_pages;
24 extern unsigned long max_pfn, mem_max;
25
26 void free_initmem(void) {
27 }
28
29 /*
30 * Just an arbitrary offset to serve as a "hole" between mapping areas
31 * (between top of physical memory and a potential pcxl dma mapping
32 * area, and below the vmalloc mapping area).
33 *
34 * The current 32K value just means that there will be a 32K "hole"
35 * between mapping areas. That means that any out-of-bounds memory
36 * accesses will hopefully be caught. The vmalloc() routines leaves
37 * a hole of 4kB between each vmalloced area for the same reason.
38 */
39
40 #define VM_MAP_OFFSET (32*1024)
41 #define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \
42 & ~(VM_MAP_OFFSET-1)))
43
44 void *vmalloc_start;
45 unsigned long pcxl_dma_start;
46
47 void __init mem_init(void)
48 {
49 max_mapnr = num_physpages = max_low_pfn;
50 high_memory = __va(max_low_pfn * PAGE_SIZE);
51
52 totalram_pages += free_all_bootmem();
53 printk("Memory: %luk available\n", totalram_pages << (PAGE_SHIFT-10));
54
55 if (hppa_dma_ops == &pcxl_dma_ops) {
56 pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(high_memory);
57 vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start + PCXL_DMA_MAP_SIZE);
58 }
59 else {
60 pcxl_dma_start = 0;
61 vmalloc_start = SET_MAP_OFFSET(high_memory);
62 }
63 }
64
65 void __bad_pgd(pgd_t *pgd)
66 {
67 printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd));
68 pgd_val(*pgd) = _PAGE_TABLE + __pa(BAD_PAGETABLE);
69 }
70
71 void __bad_pmd(pmd_t *pmd)
72 {
73 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
74 pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE);
75 }
76
77 pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
78 {
79 pte_t *pte;
80
81 pte = (pte_t *) __get_free_page(GFP_KERNEL);
82
83 if (pmd_none(*pmd)) {
84 if (pte) {
85 clear_page(pte);
86 pmd_val(*pmd) = _PAGE_TABLE + __pa((unsigned long)pte);
87 return pte + offset;
88 }
89 pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE);
90 return NULL;
91 }
92
93 free_page((unsigned long)pte);
94
95 if (pmd_bad(*pmd)) {
96 __bad_pmd(pmd);
97 return NULL;
98 }
99
100 return (pte_t *) pmd_page(*pmd) + offset;
101 }
102
103 int do_check_pgt_cache(int low, int high)
104 {
105 return 0;
106 }
107
108 /*
109 * BAD_PAGE is the page that is used for page faults when linux
110 * is out-of-memory. Older versions of linux just did a
111 * do_exit(), but using this instead means there is less risk
112 * for a process dying in kernel mode, possibly leaving an inode
113 * unused etc..
114 *
115 * BAD_PAGETABLE is the accompanying page-table: it is initialized
116 * to point to BAD_PAGE entries.
117 *
118 * ZERO_PAGE is a special page that is used for zero-initialized
119 * data and COW.
120 */
121 pte_t * __bad_pagetable(void)
122 {
123 return (pte_t *) NULL;
124 }
125
126 unsigned long *empty_zero_page;
127 unsigned long *empty_bad_page;
128
129 pte_t __bad_page(void)
130 {
131 return *(pte_t *)NULL;
132 }
133
134 void show_mem(void)
135 {
136 int i,free = 0,total = 0,reserved = 0;
137 int shared = 0, cached = 0;
138
139 printk("Mem-info:\n");
140 show_free_areas();
141 printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
142 i = max_mapnr;
143 while (i-- > 0) {
144 total++;
145 if (PageReserved(mem_map+i))
146 reserved++;
147 else if (PageSwapCache(mem_map+i))
148 cached++;
149 else if (!atomic_read(&mem_map[i].count))
150 free++;
151 else
152 shared += atomic_read(&mem_map[i].count) - 1;
153 }
154 printk("%d pages of RAM\n",total);
155 printk("%d reserved pages\n",reserved);
156 printk("%d pages shared\n",shared);
157 printk("%d pages swap cached\n",cached);
158 show_buffers();
159 }
160
161 void set_pte_phys (unsigned long vaddr, unsigned long phys)
162 {
163 }
164
165
166 /*
167 * pagetable_init() sets up the page tables
168 *
169 * Note that gateway_init() places the Linux gateway page at page 0.
170 * Since gateway pages cannot be dereferenced this has the desirable
171 * side effect of trapping those pesky NULL-reference errors in the
172 * kernel.
173 */
174 static void __init pagetable_init(void)
175 {
176 pgd_t *pg_dir;
177 pmd_t *pmd;
178 pte_t *pg_table;
179 unsigned long tmp1;
180 unsigned long tmp2;
181 unsigned long address;
182 unsigned long ro_start;
183 unsigned long ro_end;
184 unsigned long fv_addr;
185 extern const int stext;
186 extern int data_start;
187 extern const unsigned long fault_vector_20;
188
189 ro_start = __pa((unsigned long)&stext);
190 ro_end = __pa((unsigned long)&data_start);
191 fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
192
193 printk("pagetable_init\n");
194
195 /* Map whole memory from PAGE_OFFSET */
196 pg_dir = (pgd_t *)swapper_pg_dir + USER_PGD_PTRS;
197
198 address = 0;
199 while (address < mem_max) {
200 /* XXX: BTLB should be done here */
201
202 #if PTRS_PER_PMD == 1
203 pmd = (pmd_t *)__pa(pg_dir);
204 #else
205 pmd = (pmd_t *) (PAGE_MASK & pgd_val(*pg_dir));
206
207 /*
208 * pmd is physical at this point
209 */
210
211 if (!pmd) {
212 pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
213 pmd = (pmd_t *) __pa(pmd);
214 }
215
216 pgd_val(*pg_dir) = _PAGE_TABLE | (unsigned long) pmd;
217 #endif
218 pg_dir++;
219
220 /* now change pmd to kernel virtual addresses */
221
222 pmd = (pmd_t *) __va(pmd);
223 for (tmp1 = 0 ; tmp1 < PTRS_PER_PMD ; tmp1++,pmd++) {
224
225 /*
226 * pg_table is physical at this point
227 */
228
229 pg_table = (pte_t *) (PAGE_MASK & pmd_val(*pmd));
230 if (!pg_table) {
231 pg_table = (pte_t *)
232 alloc_bootmem_low_pages(PAGE_SIZE);
233 pg_table = (pte_t *) __pa(pg_table);
234 }
235
236 pmd_val(*pmd) = _PAGE_TABLE |
237 (unsigned long) pg_table;
238
239 /* now change pg_table to kernel virtual addresses */
240
241 pg_table = (pte_t *) __va(pg_table);
242 for (tmp2=0; tmp2 < PTRS_PER_PTE; tmp2++,pg_table++) {
243 pte_t pte;
244
245 #if !defined(CONFIG_KWDB) && !defined(CONFIG_STI_CONSOLE)
246 #warning STI console should explicitly allocate executable pages but does not
247 /* KWDB needs to write kernel text when setting break points.
248 **
249 ** The right thing to do seems like KWDB modify only the pte which
250 ** has a break point on it...otherwise we might mask worse bugs.
251 */
252 if (address >= ro_start && address < ro_end
253 && address != fv_addr)
254 pte = __mk_pte(address, PAGE_KERNEL_RO);
255 else
256 #endif
257 pte = __mk_pte(address, PAGE_KERNEL);
258
259 if (address >= mem_max)
260 pte_val(pte) = 0;
261
262 set_pte(pg_table, pte);
263
264 address += PAGE_SIZE;
265 }
266
267 if (address >= mem_max)
268 break;
269 }
270 }
271
272 empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
273 memset(empty_zero_page, 0, PAGE_SIZE);
274 }
275
276 unsigned long gateway_pgd_offset;
277 unsigned long gateway_pgd_entry;
278
279 static void __init gateway_init(void)
280 {
281 unsigned long hpux_gateway_page_addr;
282 unsigned long linux_gateway_page_addr;
283 pgd_t *pg_dir;
284 pmd_t *pmd_base;
285 pmd_t *pmd;
286 pte_t *pg_table_base;
287 pte_t *pg_table;
288 /* FIXME: These are 'const' in order to trick the compiler
289 into not treating them as DP-relative data. */
290 extern void * const hpux_gateway_page;
291 extern void * const linux_gateway_page;
292 pte_t pte;
293
294 hpux_gateway_page_addr = HPUX_GATEWAY_ADDR & PAGE_MASK;
295 linux_gateway_page_addr = LINUX_GATEWAY_ADDR & PAGE_MASK;
296
297 gateway_pgd_offset = hpux_gateway_page_addr >> PGDIR_SHIFT;
298
299 /*
300 * Setup Linux Gateway page.
301 *
302 * The Linux gateway page will reside in kernel space (on virtual
303 * page 0), so it doesn't need to be aliased into user space.
304 */
305
306 pg_dir = (pgd_t *)swapper_pg_dir;
307
308 #if PTRS_PER_PMD == 1
309 pmd_base = (pmd_t *)pg_dir;
310 pmd = pmd_base +
311 ((linux_gateway_page_addr) >> PGDIR_SHIFT);
312
313 #else
314 pmd_base = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE);
315 pgd_val(*(pg_dir + (linux_gateway_page_addr >> PGDIR_SHIFT))) =
316 _PAGE_TABLE | __pa(pmd_base);
317
318 pmd = pmd_base +
319 ((linux_gateway_page_addr & (PMD_MASK) & (PGDIR_SIZE - 1)) >>
320 PMD_SHIFT);
321 #endif
322
323 pg_table_base = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
324
325 pmd_val(*pmd) = _PAGE_TABLE | __pa(pg_table_base);
326
327 pte = __mk_pte(__pa(&linux_gateway_page), PAGE_GATEWAY);
328
329 pg_table = pg_table_base +
330 ((linux_gateway_page_addr & (PAGE_MASK) & (PMD_SIZE - 1)) >>
331 PAGE_SHIFT);
332
333 set_pte(pg_table,pte);
334
335 /*
336 * Setup HP-UX gateway page.
337 * This page will be aliased into each user address space.
338 */
339
340 pg_table_base = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
341
342 pte = __mk_pte(__pa(&hpux_gateway_page), PAGE_GATEWAY);
343 pg_table = pg_table_base +
344 ((hpux_gateway_page_addr & (PAGE_MASK) & (PMD_SIZE - 1)) >>
345 PAGE_SHIFT);
346
347 set_pte(pg_table,pte);
348
349
350 #if PTRS_PER_PMD == 1
351 pmd_base = (pmd_t *)pg_table_base;
352 #else
353 pmd_base = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE);
354 pmd = pmd_base +
355 ((hpux_gateway_page_addr & (PMD_MASK) & (PGDIR_SIZE - 1)) >>
356 PMD_SHIFT);
357 pmd_val(*pmd) = _PAGE_TABLE | __pa(pg_table_base);
358 #endif
359
360 gateway_pgd_entry = _PAGE_TABLE | __pa(pmd_base);
361
362 /*
363 * We will be aliasing the HP-UX gateway page into all HP-UX
364 * user spaces at the same address (not counting the space register
365 * value) that will be equivalently mapped as long as space register
366 * hashing is disabled. It will be a problem if anyone touches
367 * the gateway pages at its "kernel" address, since that is
368 * NOT equivalently mapped. We'll flush the caches at this
369 * point, just in case some code has touched those addresses
370 * previous to this, but all bets are off if they get touched
371 * after this point.
372 */
373
374 flush_all_caches();
375
376 return;
377 }
378
379 void __init paging_init(void)
380 {
381 pagetable_init();
382 gateway_init();
383
384 {
385 unsigned long zones_size[MAX_NR_ZONES] = { max_pfn/2, max_pfn/2, };
386
387 free_area_init(zones_size);
388 }
389 }
390
391 #define NR_SPACE_IDS 8192
392
393 static unsigned long space_id[NR_SPACE_IDS / (8 * sizeof(long))];
394 static unsigned long space_id_index;
395 static unsigned long free_space_ids = NR_SPACE_IDS;
396
397 /*
398 * XXX: We should probably unfold the set_bit / test_bit / clear_bit
399 * locking out of these two functions and have a single spinlock on the
400 * space_id data structures.
401 *
402 * Don't bother. This is all going to be significantly changed in the
403 * very near future.
404 */
405
406 #define SPACEID_SHIFT (PAGE_SHIFT + (PT_NLEVELS)*(PAGE_SHIFT - PT_NLEVELS) - 32)
407
408 unsigned long alloc_sid(void)
409 {
410 unsigned long index;
411
412 if (free_space_ids == 0)
413 BUG();
414
415 free_space_ids--;
416
417 do {
418 index = find_next_zero_bit(space_id, NR_SPACE_IDS, space_id_index);
419 } while(test_and_set_bit(index, space_id));
420
421 space_id_index = index;
422
423 return index << SPACEID_SHIFT;
424 }
425
426 void free_sid(unsigned long spaceid)
427 {
428 unsigned long index = spaceid >> SPACEID_SHIFT;
429 if (index < 0)
430 BUG();
431
432 clear_bit(index, space_id);
433
434 if (space_id_index > index) {
435 space_id_index = index;
436 }
437 free_space_ids++;
438 }
439
440 #ifdef CONFIG_BLK_DEV_INITRD
441 void free_initrd_mem(unsigned long start, unsigned long end)
442 {
443 #if 0
444 for (; start < end; start += PAGE_SIZE) {
445 ClearPageReserved(mem_map + MAP_NR(start));
446 set_page_count(mem_map+MAP_NR(start), 1);
447 free_page(start);
448 totalram_pages++;
449 }
450 printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
451 #endif
452 }
453 #endif
454
455 void si_meminfo(struct sysinfo *val)
456 {
457 int i;
458
459 i = max_mapnr;
460 val->totalram = totalram_pages;
461 val->sharedram = 0;
462 val->freeram = nr_free_pages();
463 val->bufferram = atomic_read(&buffermem_pages);
464 #if 0
465 while (i-- > 0) {
466 if (PageReserved(mem_map+i))
467 continue;
468 val->totalram++;
469 if (!atomic_read(&mem_map[i].count))
470 continue;
471 val->sharedram += atomic_read(&mem_map[i].count) - 1;
472 }
473 val->totalram <<= PAGE_SHIFT;
474 val->sharedram <<= PAGE_SHIFT;
475 #endif
476 val->totalhigh = 0;
477 val->freehigh = 0;
478 return;
479 }
480