Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/arch/m68k/mm/sun3mmu.c | |
3 | * | |
4 | * Implementations of mm routines specific to the sun3 MMU. | |
5 | * | |
6 | * Moved here 8/20/1999 Sam Creasey | |
7 | * | |
8 | */ | |
9 | ||
10 | #include <linux/signal.h> | |
11 | #include <linux/sched.h> | |
12 | #include <linux/mm.h> | |
13 | #include <linux/swap.h> | |
14 | #include <linux/kernel.h> | |
15 | #include <linux/string.h> | |
16 | #include <linux/types.h> | |
17 | #include <linux/init.h> | |
18 | #include <linux/bootmem.h> | |
19 | ||
20 | #include <asm/setup.h> | |
21 | #include <asm/uaccess.h> | |
22 | #include <asm/page.h> | |
23 | #include <asm/pgtable.h> | |
24 | #include <asm/system.h> | |
25 | #include <asm/machdep.h> | |
26 | #include <asm/io.h> | |
27 | ||
28 | extern void mmu_emu_init (unsigned long bootmem_end); | |
29 | ||
30 | const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n"; | |
31 | ||
32 | extern unsigned long num_pages; | |
33 | ||
34 | void free_initmem(void) | |
35 | { | |
36 | } | |
37 | ||
38 | /* For the sun3 we try to follow the i386 paging_init() more closely */ | |
39 | /* start_mem and end_mem have PAGE_OFFSET added already */ | |
40 | /* now sets up tables using sun3 PTEs rather than i386 as before. --m */ | |
41 | void __init paging_init(void) | |
42 | { | |
43 | pgd_t * pg_dir; | |
44 | pte_t * pg_table; | |
45 | int i; | |
46 | unsigned long address; | |
47 | unsigned long next_pgtable; | |
48 | unsigned long bootmem_end; | |
2dcf15b7 | 49 | unsigned long zones_size[MAX_NR_ZONES] = { 0, }; |
1da177e4 LT |
50 | unsigned long size; |
51 | ||
1da177e4 LT |
52 | #ifdef TEST_VERIFY_AREA |
53 | wp_works_ok = 0; | |
54 | #endif | |
55 | empty_zero_page = alloc_bootmem_pages(PAGE_SIZE); | |
56 | memset(empty_zero_page, 0, PAGE_SIZE); | |
57 | ||
58 | address = PAGE_OFFSET; | |
59 | pg_dir = swapper_pg_dir; | |
60 | memset (swapper_pg_dir, 0, sizeof (swapper_pg_dir)); | |
61 | memset (kernel_pg_dir, 0, sizeof (kernel_pg_dir)); | |
62 | ||
63 | size = num_pages * sizeof(pte_t); | |
64 | size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1); | |
65 | ||
66 | next_pgtable = (unsigned long)alloc_bootmem_pages(size); | |
67 | bootmem_end = (next_pgtable + size + PAGE_SIZE) & PAGE_MASK; | |
68 | ||
69 | /* Map whole memory from PAGE_OFFSET (0x0E000000) */ | |
70 | pg_dir += PAGE_OFFSET >> PGDIR_SHIFT; | |
71 | ||
72 | while (address < (unsigned long)high_memory) { | |
73 | pg_table = (pte_t *) __pa (next_pgtable); | |
74 | next_pgtable += PTRS_PER_PTE * sizeof (pte_t); | |
75 | pgd_val(*pg_dir) = (unsigned long) pg_table; | |
76 | pg_dir++; | |
77 | ||
78 | /* now change pg_table to kernel virtual addresses */ | |
79 | pg_table = (pte_t *) __va ((unsigned long) pg_table); | |
80 | for (i=0; i<PTRS_PER_PTE; ++i, ++pg_table) { | |
81 | pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT); | |
82 | if (address >= (unsigned long)high_memory) | |
83 | pte_val (pte) = 0; | |
84 | set_pte (pg_table, pte); | |
85 | address += PAGE_SIZE; | |
86 | } | |
87 | } | |
88 | ||
89 | mmu_emu_init(bootmem_end); | |
90 | ||
91 | current->mm = NULL; | |
92 | ||
93 | /* memory sizing is a hack stolen from motorola.c.. hope it works for us */ | |
2dcf15b7 | 94 | zones_size[ZONE_DMA] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT; |
1da177e4 | 95 | |
a3a79bd7 SC |
96 | /* I really wish I knew why the following change made things better... -- Sam */ |
97 | /* free_area_init(zones_size); */ | |
98 | free_area_init_node(0, NODE_DATA(0), zones_size, | |
99 | (__pa(PAGE_OFFSET) >> PAGE_SHIFT) + 1, NULL); | |
100 | ||
1da177e4 LT |
101 | |
102 | } | |
103 | ||
104 |