aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/mm
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/m68k/mm
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/m68k/mm')
-rw-r--r--arch/m68k/mm/Makefile8
-rw-r--r--arch/m68k/mm/cache.c30
-rw-r--r--arch/m68k/mm/fault.c44
-rw-r--r--arch/m68k/mm/init.c224
-rw-r--r--arch/m68k/mm/kmap.c4
-rw-r--r--arch/m68k/mm/mcfmmu.c195
-rw-r--r--arch/m68k/mm/memory.c9
-rw-r--r--arch/m68k/mm/motorola.c15
-rw-r--r--arch/m68k/mm/sun3mmu.c5
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
5obj-y := init.o 5obj-y := init.o
6 6
7obj-$(CONFIG_MMU) += cache.o fault.o 7obj-$(CONFIG_MMU) += cache.o fault.o hwtest.o
8obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o hwtest.o 8obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o
9obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o hwtest.o 9obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
10obj-$(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 */
75void flush_icache_range(unsigned long address, unsigned long endaddr) 75void 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);
108void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, 100void 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
91retry:
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 */
39void *empty_zero_page;
40EXPORT_SYMBOL(empty_zero_page);
41
42#ifdef CONFIG_MMU 1#ifdef CONFIG_MMU
43 2#include "init_mm.c"
44pg_data_t pg_data_map[MAX_NUMNODES];
45EXPORT_SYMBOL(pg_data_map);
46
47int m68k_virt_to_node_shift;
48
49#ifndef CONFIG_SINGLE_MEMORY_CHUNK
50pg_data_t *pg_data_table[65];
51EXPORT_SYMBOL(pg_data_table);
52#endif
53
54void __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
72extern void init_pointer_table(unsigned long ptable);
73extern 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 */
83void __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
108void 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
132void __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
158void __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
212void 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
26mm_context_t next_mmu_context;
27unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
28atomic_t nr_free_contexts;
29struct mm_struct *context_mm[LAST_CONTEXT+1];
30extern unsigned long num_pages;
31
32/*
33 * ColdFire paging_init derived from sun3.
34 */
35void __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
84int 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 */
157void __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 */
182void 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
203void cache_clear (unsigned long paddr, int len) 204void 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
252void cache_push (unsigned long paddr, int len) 251void 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
308void 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
31extern unsigned long num_pages; 32extern unsigned long num_pages;
32 33
34void 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 */