diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/m68k/mm | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/m68k/mm')
-rw-r--r-- | arch/m68k/mm/Makefile | 8 | ||||
-rw-r--r-- | arch/m68k/mm/cache.c | 30 | ||||
-rw-r--r-- | arch/m68k/mm/fault.c | 44 | ||||
-rw-r--r-- | arch/m68k/mm/init.c | 224 | ||||
-rw-r--r-- | arch/m68k/mm/kmap.c | 4 | ||||
-rw-r--r-- | arch/m68k/mm/mcfmmu.c | 195 | ||||
-rw-r--r-- | arch/m68k/mm/memory.c | 9 | ||||
-rw-r--r-- | arch/m68k/mm/motorola.c | 15 | ||||
-rw-r--r-- | arch/m68k/mm/sun3mmu.c | 5 |
9 files changed, 45 insertions, 489 deletions
diff --git a/arch/m68k/mm/Makefile b/arch/m68k/mm/Makefile index cfbf3205724..09cadf1058d 100644 --- a/arch/m68k/mm/Makefile +++ b/arch/m68k/mm/Makefile | |||
@@ -4,8 +4,6 @@ | |||
4 | 4 | ||
5 | obj-y := init.o | 5 | obj-y := init.o |
6 | 6 | ||
7 | obj-$(CONFIG_MMU) += cache.o fault.o | 7 | obj-$(CONFIG_MMU) += cache.o fault.o hwtest.o |
8 | obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o hwtest.o | 8 | obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o |
9 | obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o hwtest.o | 9 | obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o |
10 | obj-$(CONFIG_MMU_COLDFIRE) += kmap.o memory.o mcfmmu.o | ||
11 | |||
diff --git a/arch/m68k/mm/cache.c b/arch/m68k/mm/cache.c index 3d84c1f2ffb..5437fff5fe0 100644 --- a/arch/m68k/mm/cache.c +++ b/arch/m68k/mm/cache.c | |||
@@ -52,9 +52,9 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr) | |||
52 | unsigned long *descaddr; | 52 | unsigned long *descaddr; |
53 | 53 | ||
54 | asm volatile ("ptestr %3,%2@,#7,%0\n\t" | 54 | asm volatile ("ptestr %3,%2@,#7,%0\n\t" |
55 | "pmove %%psr,%1" | 55 | "pmove %%psr,%1@" |
56 | : "=a&" (descaddr), "=m" (mmusr) | 56 | : "=a&" (descaddr) |
57 | : "a" (vaddr), "d" (get_fs().seg)); | 57 | : "a" (&mmusr), "a" (vaddr), "d" (get_fs().seg)); |
58 | if (mmusr & (MMU_I|MMU_B|MMU_L)) | 58 | if (mmusr & (MMU_I|MMU_B|MMU_L)) |
59 | return 0; | 59 | return 0; |
60 | descaddr = phys_to_virt((unsigned long)descaddr); | 60 | descaddr = phys_to_virt((unsigned long)descaddr); |
@@ -74,16 +74,8 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr) | |||
74 | /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ | 74 | /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ |
75 | void flush_icache_range(unsigned long address, unsigned long endaddr) | 75 | void flush_icache_range(unsigned long address, unsigned long endaddr) |
76 | { | 76 | { |
77 | if (CPU_IS_COLDFIRE) { | 77 | |
78 | unsigned long start, end; | 78 | if (CPU_IS_040_OR_060) { |
79 | start = address & ICACHE_SET_MASK; | ||
80 | end = endaddr & ICACHE_SET_MASK; | ||
81 | if (start > end) { | ||
82 | flush_cf_icache(0, end); | ||
83 | end = ICACHE_MAX_ADDR; | ||
84 | } | ||
85 | flush_cf_icache(start, end); | ||
86 | } else if (CPU_IS_040_OR_060) { | ||
87 | address &= PAGE_MASK; | 79 | address &= PAGE_MASK; |
88 | 80 | ||
89 | do { | 81 | do { |
@@ -108,17 +100,7 @@ EXPORT_SYMBOL(flush_icache_range); | |||
108 | void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, | 100 | void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, |
109 | unsigned long addr, int len) | 101 | unsigned long addr, int len) |
110 | { | 102 | { |
111 | if (CPU_IS_COLDFIRE) { | 103 | if (CPU_IS_040_OR_060) { |
112 | unsigned long start, end; | ||
113 | start = addr & ICACHE_SET_MASK; | ||
114 | end = (addr + len) & ICACHE_SET_MASK; | ||
115 | if (start > end) { | ||
116 | flush_cf_icache(0, end); | ||
117 | end = ICACHE_MAX_ADDR; | ||
118 | } | ||
119 | flush_cf_icache(start, end); | ||
120 | |||
121 | } else if (CPU_IS_040_OR_060) { | ||
122 | asm volatile ("nop\n\t" | 104 | asm volatile ("nop\n\t" |
123 | ".chip 68040\n\t" | 105 | ".chip 68040\n\t" |
124 | "cpushp %%bc,(%0)\n\t" | 106 | "cpushp %%bc,(%0)\n\t" |
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index a563727806b..2db6099784b 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <asm/setup.h> | 14 | #include <asm/setup.h> |
15 | #include <asm/traps.h> | 15 | #include <asm/traps.h> |
16 | #include <asm/system.h> | ||
16 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
17 | #include <asm/pgalloc.h> | 18 | #include <asm/pgalloc.h> |
18 | 19 | ||
@@ -72,8 +73,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, | |||
72 | { | 73 | { |
73 | struct mm_struct *mm = current->mm; | 74 | struct mm_struct *mm = current->mm; |
74 | struct vm_area_struct * vma; | 75 | struct vm_area_struct * vma; |
75 | int fault; | 76 | int write, fault; |
76 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | ||
77 | 77 | ||
78 | #ifdef DEBUG | 78 | #ifdef DEBUG |
79 | printk ("do page fault:\nregs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n", | 79 | printk ("do page fault:\nregs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n", |
@@ -88,7 +88,6 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, | |||
88 | if (in_atomic() || !mm) | 88 | if (in_atomic() || !mm) |
89 | goto no_context; | 89 | goto no_context; |
90 | 90 | ||
91 | retry: | ||
92 | down_read(&mm->mmap_sem); | 91 | down_read(&mm->mmap_sem); |
93 | 92 | ||
94 | vma = find_vma(mm, address); | 93 | vma = find_vma(mm, address); |
@@ -119,13 +118,14 @@ good_area: | |||
119 | #ifdef DEBUG | 118 | #ifdef DEBUG |
120 | printk("do_page_fault: good_area\n"); | 119 | printk("do_page_fault: good_area\n"); |
121 | #endif | 120 | #endif |
121 | write = 0; | ||
122 | switch (error_code & 3) { | 122 | switch (error_code & 3) { |
123 | default: /* 3: write, present */ | 123 | default: /* 3: write, present */ |
124 | /* fall through */ | 124 | /* fall through */ |
125 | case 2: /* write, not present */ | 125 | case 2: /* write, not present */ |
126 | if (!(vma->vm_flags & VM_WRITE)) | 126 | if (!(vma->vm_flags & VM_WRITE)) |
127 | goto acc_err; | 127 | goto acc_err; |
128 | flags |= FAULT_FLAG_WRITE; | 128 | write++; |
129 | break; | 129 | break; |
130 | case 1: /* read, present */ | 130 | case 1: /* read, present */ |
131 | goto acc_err; | 131 | goto acc_err; |
@@ -140,14 +140,10 @@ good_area: | |||
140 | * the fault. | 140 | * the fault. |
141 | */ | 141 | */ |
142 | 142 | ||
143 | fault = handle_mm_fault(mm, vma, address, flags); | 143 | fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); |
144 | #ifdef DEBUG | 144 | #ifdef DEBUG |
145 | printk("handle_mm_fault returns %d\n",fault); | 145 | printk("handle_mm_fault returns %d\n",fault); |
146 | #endif | 146 | #endif |
147 | |||
148 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
149 | return 0; | ||
150 | |||
151 | if (unlikely(fault & VM_FAULT_ERROR)) { | 147 | if (unlikely(fault & VM_FAULT_ERROR)) { |
152 | if (fault & VM_FAULT_OOM) | 148 | if (fault & VM_FAULT_OOM) |
153 | goto out_of_memory; | 149 | goto out_of_memory; |
@@ -155,32 +151,10 @@ good_area: | |||
155 | goto bus_err; | 151 | goto bus_err; |
156 | BUG(); | 152 | BUG(); |
157 | } | 153 | } |
158 | 154 | if (fault & VM_FAULT_MAJOR) | |
159 | /* | 155 | current->maj_flt++; |
160 | * Major/minor page fault accounting is only done on the | 156 | else |
161 | * initial attempt. If we go through a retry, it is extremely | 157 | current->min_flt++; |
162 | * likely that the page will be found in page cache at that point. | ||
163 | */ | ||
164 | if (flags & FAULT_FLAG_ALLOW_RETRY) { | ||
165 | if (fault & VM_FAULT_MAJOR) | ||
166 | current->maj_flt++; | ||
167 | else | ||
168 | current->min_flt++; | ||
169 | if (fault & VM_FAULT_RETRY) { | ||
170 | /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk | ||
171 | * of starvation. */ | ||
172 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | ||
173 | flags |= FAULT_FLAG_TRIED; | ||
174 | |||
175 | /* | ||
176 | * No need to up_read(&mm->mmap_sem) as we would | ||
177 | * have already released it in __lock_page_or_retry | ||
178 | * in mm/filemap.c. | ||
179 | */ | ||
180 | |||
181 | goto retry; | ||
182 | } | ||
183 | } | ||
184 | 158 | ||
185 | up_read(&mm->mmap_sem); | 159 | up_read(&mm->mmap_sem); |
186 | return 0; | 160 | return 0; |
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index f0e05bce92f..27b5ce089a3 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c | |||
@@ -1,225 +1,5 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/mm/init.c | ||
3 | * | ||
4 | * Copyright (C) 1995 Hamish Macdonald | ||
5 | * | ||
6 | * Contains common initialization routines, specific init code moved | ||
7 | * to motorola.c and sun3mmu.c | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/signal.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/mm.h> | ||
14 | #include <linux/swap.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/gfp.h> | ||
21 | |||
22 | #include <asm/setup.h> | ||
23 | #include <asm/uaccess.h> | ||
24 | #include <asm/page.h> | ||
25 | #include <asm/pgalloc.h> | ||
26 | #include <asm/traps.h> | ||
27 | #include <asm/machdep.h> | ||
28 | #include <asm/io.h> | ||
29 | #ifdef CONFIG_ATARI | ||
30 | #include <asm/atari_stram.h> | ||
31 | #endif | ||
32 | #include <asm/sections.h> | ||
33 | #include <asm/tlb.h> | ||
34 | |||
35 | /* | ||
36 | * ZERO_PAGE is a special page that is used for zero-initialized | ||
37 | * data and COW. | ||
38 | */ | ||
39 | void *empty_zero_page; | ||
40 | EXPORT_SYMBOL(empty_zero_page); | ||
41 | |||
42 | #ifdef CONFIG_MMU | 1 | #ifdef CONFIG_MMU |
43 | 2 | #include "init_mm.c" | |
44 | pg_data_t pg_data_map[MAX_NUMNODES]; | ||
45 | EXPORT_SYMBOL(pg_data_map); | ||
46 | |||
47 | int m68k_virt_to_node_shift; | ||
48 | |||
49 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
50 | pg_data_t *pg_data_table[65]; | ||
51 | EXPORT_SYMBOL(pg_data_table); | ||
52 | #endif | ||
53 | |||
54 | void __init m68k_setup_node(int node) | ||
55 | { | ||
56 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
57 | struct mem_info *info = m68k_memory + node; | ||
58 | int i, end; | ||
59 | |||
60 | i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift(); | ||
61 | end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift(); | ||
62 | for (; i <= end; i++) { | ||
63 | if (pg_data_table[i]) | ||
64 | printk("overlap at %u for chunk %u\n", i, node); | ||
65 | pg_data_table[i] = pg_data_map + node; | ||
66 | } | ||
67 | #endif | ||
68 | pg_data_map[node].bdata = bootmem_node_data + node; | ||
69 | node_set_online(node); | ||
70 | } | ||
71 | |||
72 | extern void init_pointer_table(unsigned long ptable); | ||
73 | extern pmd_t *zero_pgtable; | ||
74 | |||
75 | #else /* CONFIG_MMU */ | ||
76 | |||
77 | /* | ||
78 | * paging_init() continues the virtual memory environment setup which | ||
79 | * was begun by the code in arch/head.S. | ||
80 | * The parameters are pointers to where to stick the starting and ending | ||
81 | * addresses of available kernel virtual memory. | ||
82 | */ | ||
83 | void __init paging_init(void) | ||
84 | { | ||
85 | /* | ||
86 | * Make sure start_mem is page aligned, otherwise bootmem and | ||
87 | * page_alloc get different views of the world. | ||
88 | */ | ||
89 | unsigned long end_mem = memory_end & PAGE_MASK; | ||
90 | unsigned long zones_size[MAX_NR_ZONES] = { 0, }; | ||
91 | |||
92 | high_memory = (void *) end_mem; | ||
93 | |||
94 | empty_zero_page = alloc_bootmem_pages(PAGE_SIZE); | ||
95 | memset(empty_zero_page, 0, PAGE_SIZE); | ||
96 | |||
97 | /* | ||
98 | * Set up SFC/DFC registers (user data space). | ||
99 | */ | ||
100 | set_fs (USER_DS); | ||
101 | |||
102 | zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; | ||
103 | free_area_init(zones_size); | ||
104 | } | ||
105 | |||
106 | #endif /* CONFIG_MMU */ | ||
107 | |||
108 | void free_initmem(void) | ||
109 | { | ||
110 | #ifndef CONFIG_MMU_SUN3 | ||
111 | unsigned long addr; | ||
112 | |||
113 | addr = (unsigned long) __init_begin; | ||
114 | for (; addr < ((unsigned long) __init_end); addr += PAGE_SIZE) { | ||
115 | ClearPageReserved(virt_to_page(addr)); | ||
116 | init_page_count(virt_to_page(addr)); | ||
117 | free_page(addr); | ||
118 | totalram_pages++; | ||
119 | } | ||
120 | pr_notice("Freeing unused kernel memory: %luk freed (0x%x - 0x%x)\n", | ||
121 | (addr - (unsigned long) __init_begin) >> 10, | ||
122 | (unsigned int) __init_begin, (unsigned int) __init_end); | ||
123 | #endif /* CONFIG_MMU_SUN3 */ | ||
124 | } | ||
125 | |||
126 | #if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) | ||
127 | #define VECTORS &vectors[0] | ||
128 | #else | 3 | #else |
129 | #define VECTORS _ramvec | 4 | #include "init_no.c" |
130 | #endif | ||
131 | |||
132 | void __init print_memmap(void) | ||
133 | { | ||
134 | #define UL(x) ((unsigned long) (x)) | ||
135 | #define MLK(b, t) UL(b), UL(t), (UL(t) - UL(b)) >> 10 | ||
136 | #define MLM(b, t) UL(b), UL(t), (UL(t) - UL(b)) >> 20 | ||
137 | #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), 1024) | ||
138 | |||
139 | pr_notice("Virtual kernel memory layout:\n" | ||
140 | " vector : 0x%08lx - 0x%08lx (%4ld KiB)\n" | ||
141 | " kmap : 0x%08lx - 0x%08lx (%4ld MiB)\n" | ||
142 | " vmalloc : 0x%08lx - 0x%08lx (%4ld MiB)\n" | ||
143 | " lowmem : 0x%08lx - 0x%08lx (%4ld MiB)\n" | ||
144 | " .init : 0x%p" " - 0x%p" " (%4d KiB)\n" | ||
145 | " .text : 0x%p" " - 0x%p" " (%4d KiB)\n" | ||
146 | " .data : 0x%p" " - 0x%p" " (%4d KiB)\n" | ||
147 | " .bss : 0x%p" " - 0x%p" " (%4d KiB)\n", | ||
148 | MLK(VECTORS, VECTORS + 256), | ||
149 | MLM(KMAP_START, KMAP_END), | ||
150 | MLM(VMALLOC_START, VMALLOC_END), | ||
151 | MLM(PAGE_OFFSET, (unsigned long)high_memory), | ||
152 | MLK_ROUNDUP(__init_begin, __init_end), | ||
153 | MLK_ROUNDUP(_stext, _etext), | ||
154 | MLK_ROUNDUP(_sdata, _edata), | ||
155 | MLK_ROUNDUP(__bss_start, __bss_stop)); | ||
156 | } | ||
157 | |||
158 | void __init mem_init(void) | ||
159 | { | ||
160 | pg_data_t *pgdat; | ||
161 | int codepages = 0; | ||
162 | int datapages = 0; | ||
163 | int initpages = 0; | ||
164 | int i; | ||
165 | |||
166 | /* this will put all memory onto the freelists */ | ||
167 | totalram_pages = num_physpages = 0; | ||
168 | for_each_online_pgdat(pgdat) { | ||
169 | num_physpages += pgdat->node_present_pages; | ||
170 | |||
171 | totalram_pages += free_all_bootmem_node(pgdat); | ||
172 | for (i = 0; i < pgdat->node_spanned_pages; i++) { | ||
173 | struct page *page = pgdat->node_mem_map + i; | ||
174 | char *addr = page_to_virt(page); | ||
175 | |||
176 | if (!PageReserved(page)) | ||
177 | continue; | ||
178 | if (addr >= _text && | ||
179 | addr < _etext) | ||
180 | codepages++; | ||
181 | else if (addr >= __init_begin && | ||
182 | addr < __init_end) | ||
183 | initpages++; | ||
184 | else | ||
185 | datapages++; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | #if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) | ||
190 | /* insert pointer tables allocated so far into the tablelist */ | ||
191 | init_pointer_table((unsigned long)kernel_pg_dir); | ||
192 | for (i = 0; i < PTRS_PER_PGD; i++) { | ||
193 | if (pgd_present(kernel_pg_dir[i])) | ||
194 | init_pointer_table(__pgd_page(kernel_pg_dir[i])); | ||
195 | } | ||
196 | |||
197 | /* insert also pointer table that we used to unmap the zero page */ | ||
198 | if (zero_pgtable) | ||
199 | init_pointer_table((unsigned long)zero_pgtable); | ||
200 | #endif | ||
201 | |||
202 | pr_info("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n", | ||
203 | nr_free_pages() << (PAGE_SHIFT-10), | ||
204 | totalram_pages << (PAGE_SHIFT-10), | ||
205 | codepages << (PAGE_SHIFT-10), | ||
206 | datapages << (PAGE_SHIFT-10), | ||
207 | initpages << (PAGE_SHIFT-10)); | ||
208 | print_memmap(); | ||
209 | } | ||
210 | |||
211 | #ifdef CONFIG_BLK_DEV_INITRD | ||
212 | void free_initrd_mem(unsigned long start, unsigned long end) | ||
213 | { | ||
214 | int pages = 0; | ||
215 | for (; start < end; start += PAGE_SIZE) { | ||
216 | ClearPageReserved(virt_to_page(start)); | ||
217 | init_page_count(virt_to_page(start)); | ||
218 | free_page(start); | ||
219 | totalram_pages++; | ||
220 | pages++; | ||
221 | } | ||
222 | pr_notice("Freeing initrd memory: %dk freed\n", | ||
223 | pages << (PAGE_SHIFT - 10)); | ||
224 | } | ||
225 | #endif | 5 | #endif |
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c index 568cfad3ceb..69345849454 100644 --- a/arch/m68k/mm/kmap.c +++ b/arch/m68k/mm/kmap.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <asm/page.h> | 20 | #include <asm/page.h> |
21 | #include <asm/pgalloc.h> | 21 | #include <asm/pgalloc.h> |
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/system.h> | ||
23 | 24 | ||
24 | #undef DEBUG | 25 | #undef DEBUG |
25 | 26 | ||
@@ -170,8 +171,7 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla | |||
170 | break; | 171 | break; |
171 | } | 172 | } |
172 | } else { | 173 | } else { |
173 | physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | | 174 | physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); |
174 | _PAGE_DIRTY | _PAGE_READWRITE); | ||
175 | switch (cacheflag) { | 175 | switch (cacheflag) { |
176 | case IOMAP_NOCACHE_SER: | 176 | case IOMAP_NOCACHE_SER: |
177 | case IOMAP_NOCACHE_NONSER: | 177 | case IOMAP_NOCACHE_NONSER: |
diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c deleted file mode 100644 index f58fafe7e4c..00000000000 --- a/arch/m68k/mm/mcfmmu.c +++ /dev/null | |||
@@ -1,195 +0,0 @@ | |||
1 | /* | ||
2 | * Based upon linux/arch/m68k/mm/sun3mmu.c | ||
3 | * Based upon linux/arch/ppc/mm/mmu_context.c | ||
4 | * | ||
5 | * Implementations of mm routines specific to the Coldfire MMU. | ||
6 | * | ||
7 | * Copyright (c) 2008 Freescale Semiconductor, Inc. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <linux/bootmem.h> | ||
16 | |||
17 | #include <asm/setup.h> | ||
18 | #include <asm/page.h> | ||
19 | #include <asm/pgtable.h> | ||
20 | #include <asm/mmu_context.h> | ||
21 | #include <asm/mcf_pgalloc.h> | ||
22 | #include <asm/tlbflush.h> | ||
23 | |||
24 | #define KMAPAREA(x) ((x >= VMALLOC_START) && (x < KMAP_END)) | ||
25 | |||
26 | mm_context_t next_mmu_context; | ||
27 | unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1]; | ||
28 | atomic_t nr_free_contexts; | ||
29 | struct mm_struct *context_mm[LAST_CONTEXT+1]; | ||
30 | extern unsigned long num_pages; | ||
31 | |||
32 | /* | ||
33 | * ColdFire paging_init derived from sun3. | ||
34 | */ | ||
35 | void __init paging_init(void) | ||
36 | { | ||
37 | pgd_t *pg_dir; | ||
38 | pte_t *pg_table; | ||
39 | unsigned long address, size; | ||
40 | unsigned long next_pgtable, bootmem_end; | ||
41 | unsigned long zones_size[MAX_NR_ZONES]; | ||
42 | enum zone_type zone; | ||
43 | int i; | ||
44 | |||
45 | empty_zero_page = (void *) alloc_bootmem_pages(PAGE_SIZE); | ||
46 | memset((void *) empty_zero_page, 0, PAGE_SIZE); | ||
47 | |||
48 | pg_dir = swapper_pg_dir; | ||
49 | memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir)); | ||
50 | |||
51 | size = num_pages * sizeof(pte_t); | ||
52 | size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1); | ||
53 | next_pgtable = (unsigned long) alloc_bootmem_pages(size); | ||
54 | |||
55 | bootmem_end = (next_pgtable + size + PAGE_SIZE) & PAGE_MASK; | ||
56 | pg_dir += PAGE_OFFSET >> PGDIR_SHIFT; | ||
57 | |||
58 | address = PAGE_OFFSET; | ||
59 | while (address < (unsigned long)high_memory) { | ||
60 | pg_table = (pte_t *) next_pgtable; | ||
61 | next_pgtable += PTRS_PER_PTE * sizeof(pte_t); | ||
62 | pgd_val(*pg_dir) = (unsigned long) pg_table; | ||
63 | pg_dir++; | ||
64 | |||
65 | /* now change pg_table to kernel virtual addresses */ | ||
66 | for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) { | ||
67 | pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT); | ||
68 | if (address >= (unsigned long) high_memory) | ||
69 | pte_val(pte) = 0; | ||
70 | |||
71 | set_pte(pg_table, pte); | ||
72 | address += PAGE_SIZE; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | current->mm = NULL; | ||
77 | |||
78 | for (zone = 0; zone < MAX_NR_ZONES; zone++) | ||
79 | zones_size[zone] = 0x0; | ||
80 | zones_size[ZONE_DMA] = num_pages; | ||
81 | free_area_init(zones_size); | ||
82 | } | ||
83 | |||
84 | int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word) | ||
85 | { | ||
86 | unsigned long flags, mmuar, mmutr; | ||
87 | struct mm_struct *mm; | ||
88 | pgd_t *pgd; | ||
89 | pmd_t *pmd; | ||
90 | pte_t *pte; | ||
91 | int asid; | ||
92 | |||
93 | local_irq_save(flags); | ||
94 | |||
95 | mmuar = (dtlb) ? mmu_read(MMUAR) : | ||
96 | regs->pc + (extension_word * sizeof(long)); | ||
97 | |||
98 | mm = (!user_mode(regs) && KMAPAREA(mmuar)) ? &init_mm : current->mm; | ||
99 | if (!mm) { | ||
100 | local_irq_restore(flags); | ||
101 | return -1; | ||
102 | } | ||
103 | |||
104 | pgd = pgd_offset(mm, mmuar); | ||
105 | if (pgd_none(*pgd)) { | ||
106 | local_irq_restore(flags); | ||
107 | return -1; | ||
108 | } | ||
109 | |||
110 | pmd = pmd_offset(pgd, mmuar); | ||
111 | if (pmd_none(*pmd)) { | ||
112 | local_irq_restore(flags); | ||
113 | return -1; | ||
114 | } | ||
115 | |||
116 | pte = (KMAPAREA(mmuar)) ? pte_offset_kernel(pmd, mmuar) | ||
117 | : pte_offset_map(pmd, mmuar); | ||
118 | if (pte_none(*pte) || !pte_present(*pte)) { | ||
119 | local_irq_restore(flags); | ||
120 | return -1; | ||
121 | } | ||
122 | |||
123 | if (write) { | ||
124 | if (!pte_write(*pte)) { | ||
125 | local_irq_restore(flags); | ||
126 | return -1; | ||
127 | } | ||
128 | set_pte(pte, pte_mkdirty(*pte)); | ||
129 | } | ||
130 | |||
131 | set_pte(pte, pte_mkyoung(*pte)); | ||
132 | asid = mm->context & 0xff; | ||
133 | if (!pte_dirty(*pte) && !KMAPAREA(mmuar)) | ||
134 | set_pte(pte, pte_wrprotect(*pte)); | ||
135 | |||
136 | mmutr = (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) | MMUTR_V; | ||
137 | if ((mmuar < TASK_UNMAPPED_BASE) || (mmuar >= TASK_SIZE)) | ||
138 | mmutr |= (pte->pte & CF_PAGE_MMUTR_MASK) >> CF_PAGE_MMUTR_SHIFT; | ||
139 | mmu_write(MMUTR, mmutr); | ||
140 | |||
141 | mmu_write(MMUDR, (pte_val(*pte) & PAGE_MASK) | | ||
142 | ((pte->pte) & CF_PAGE_MMUDR_MASK) | MMUDR_SZ_8KB | MMUDR_X); | ||
143 | |||
144 | if (dtlb) | ||
145 | mmu_write(MMUOR, MMUOR_ACC | MMUOR_UAA); | ||
146 | else | ||
147 | mmu_write(MMUOR, MMUOR_ITLB | MMUOR_ACC | MMUOR_UAA); | ||
148 | |||
149 | local_irq_restore(flags); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Initialize the context management stuff. | ||
155 | * The following was taken from arch/ppc/mmu_context.c | ||
156 | */ | ||
157 | void __init mmu_context_init(void) | ||
158 | { | ||
159 | /* | ||
160 | * Some processors have too few contexts to reserve one for | ||
161 | * init_mm, and require using context 0 for a normal task. | ||
162 | * Other processors reserve the use of context zero for the kernel. | ||
163 | * This code assumes FIRST_CONTEXT < 32. | ||
164 | */ | ||
165 | context_map[0] = (1 << FIRST_CONTEXT) - 1; | ||
166 | next_mmu_context = FIRST_CONTEXT; | ||
167 | atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1); | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * Steal a context from a task that has one at the moment. | ||
172 | * This is only used on 8xx and 4xx and we presently assume that | ||
173 | * they don't do SMP. If they do then thicfpgalloc.hs will have to check | ||
174 | * whether the MM we steal is in use. | ||
175 | * We also assume that this is only used on systems that don't | ||
176 | * use an MMU hash table - this is true for 8xx and 4xx. | ||
177 | * This isn't an LRU system, it just frees up each context in | ||
178 | * turn (sort-of pseudo-random replacement :). This would be the | ||
179 | * place to implement an LRU scheme if anyone was motivated to do it. | ||
180 | * -- paulus | ||
181 | */ | ||
182 | void steal_context(void) | ||
183 | { | ||
184 | struct mm_struct *mm; | ||
185 | /* | ||
186 | * free up context `next_mmu_context' | ||
187 | * if we shouldn't free context 0, don't... | ||
188 | */ | ||
189 | if (next_mmu_context < FIRST_CONTEXT) | ||
190 | next_mmu_context = FIRST_CONTEXT; | ||
191 | mm = context_mm[next_mmu_context]; | ||
192 | flush_tlb_mm(mm); | ||
193 | destroy_context(mm); | ||
194 | } | ||
195 | |||
diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index 51bc9d258ed..34c77ce24fb 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <asm/segment.h> | 17 | #include <asm/segment.h> |
18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
19 | #include <asm/pgalloc.h> | 19 | #include <asm/pgalloc.h> |
20 | #include <asm/system.h> | ||
20 | #include <asm/traps.h> | 21 | #include <asm/traps.h> |
21 | #include <asm/machdep.h> | 22 | #include <asm/machdep.h> |
22 | 23 | ||
@@ -202,9 +203,7 @@ static inline void pushcl040(unsigned long paddr) | |||
202 | 203 | ||
203 | void cache_clear (unsigned long paddr, int len) | 204 | void cache_clear (unsigned long paddr, int len) |
204 | { | 205 | { |
205 | if (CPU_IS_COLDFIRE) { | 206 | if (CPU_IS_040_OR_060) { |
206 | clear_cf_bcache(0, DCACHE_MAX_ADDR); | ||
207 | } else if (CPU_IS_040_OR_060) { | ||
208 | int tmp; | 207 | int tmp; |
209 | 208 | ||
210 | /* | 209 | /* |
@@ -251,9 +250,7 @@ EXPORT_SYMBOL(cache_clear); | |||
251 | 250 | ||
252 | void cache_push (unsigned long paddr, int len) | 251 | void cache_push (unsigned long paddr, int len) |
253 | { | 252 | { |
254 | if (CPU_IS_COLDFIRE) { | 253 | if (CPU_IS_040_OR_060) { |
255 | flush_cf_bcache(0, DCACHE_MAX_ADDR); | ||
256 | } else if (CPU_IS_040_OR_060) { | ||
257 | int tmp = PAGE_SIZE; | 254 | int tmp = PAGE_SIZE; |
258 | 255 | ||
259 | /* | 256 | /* |
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index 251c5437787..8b3db1c587f 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | #include <asm/page.h> | 25 | #include <asm/page.h> |
26 | #include <asm/pgalloc.h> | 26 | #include <asm/pgalloc.h> |
27 | #include <asm/system.h> | ||
27 | #include <asm/machdep.h> | 28 | #include <asm/machdep.h> |
28 | #include <asm/io.h> | 29 | #include <asm/io.h> |
29 | #include <asm/dma.h> | 30 | #include <asm/dma.h> |
@@ -304,3 +305,17 @@ void __init paging_init(void) | |||
304 | } | 305 | } |
305 | } | 306 | } |
306 | 307 | ||
308 | void free_initmem(void) | ||
309 | { | ||
310 | unsigned long addr; | ||
311 | |||
312 | addr = (unsigned long)__init_begin; | ||
313 | for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { | ||
314 | virt_to_page(addr)->flags &= ~(1 << PG_reserved); | ||
315 | init_page_count(virt_to_page(addr)); | ||
316 | free_page(addr); | ||
317 | totalram_pages++; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | |||
diff --git a/arch/m68k/mm/sun3mmu.c b/arch/m68k/mm/sun3mmu.c index 269f81158a3..1b902dbd437 100644 --- a/arch/m68k/mm/sun3mmu.c +++ b/arch/m68k/mm/sun3mmu.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | #include <asm/page.h> | 22 | #include <asm/page.h> |
23 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
24 | #include <asm/system.h> | ||
24 | #include <asm/machdep.h> | 25 | #include <asm/machdep.h> |
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
26 | 27 | ||
@@ -30,6 +31,10 @@ const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n"; | |||
30 | 31 | ||
31 | extern unsigned long num_pages; | 32 | extern unsigned long num_pages; |
32 | 33 | ||
34 | void free_initmem(void) | ||
35 | { | ||
36 | } | ||
37 | |||
33 | /* For the sun3 we try to follow the i386 paging_init() more closely */ | 38 | /* For the sun3 we try to follow the i386 paging_init() more closely */ |
34 | /* start_mem and end_mem have PAGE_OFFSET added already */ | 39 | /* start_mem and end_mem have PAGE_OFFSET added already */ |
35 | /* now sets up tables using sun3 PTEs rather than i386 as before. --m */ | 40 | /* now sets up tables using sun3 PTEs rather than i386 as before. --m */ |