aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc/mm')
-rw-r--r--arch/ppc/mm/44x_mmu.c51
-rw-r--r--arch/ppc/mm/Makefile1
-rw-r--r--arch/ppc/mm/fsl_booke_mmu.c236
-rw-r--r--arch/ppc/mm/init.c6
-rw-r--r--arch/ppc/mm/mmu_context.c2
-rw-r--r--arch/ppc/mm/mmu_decl.h6
-rw-r--r--arch/ppc/mm/pgtable.c28
-rw-r--r--arch/ppc/mm/ppc_mmu.c2
8 files changed, 18 insertions, 314 deletions
diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c
index 6536a25cfcb8..fbb577a0d165 100644
--- a/arch/ppc/mm/44x_mmu.c
+++ b/arch/ppc/mm/44x_mmu.c
@@ -60,38 +60,28 @@ extern char etext[], _stext[];
60 * Just needed it declared someplace. 60 * Just needed it declared someplace.
61 */ 61 */
62unsigned int tlb_44x_index = 0; 62unsigned int tlb_44x_index = 0;
63unsigned int tlb_44x_hwater = 62; 63unsigned int tlb_44x_hwater = PPC4XX_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
64int icache_44x_need_flush; 64int icache_44x_need_flush;
65 65
66/* 66/*
67 * "Pins" a 256MB TLB entry in AS0 for kernel lowmem 67 * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
68 */ 68 */
69static void __init 69static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
70ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys)
71{ 70{
72 unsigned long attrib = 0; 71 __asm__ __volatile__(
73 72 "tlbwe %2,%3,%4\n"
74 __asm__ __volatile__("\ 73 "tlbwe %1,%3,%5\n"
75 clrrwi %2,%2,10\n\ 74 "tlbwe %0,%3,%6\n"
76 ori %2,%2,%4\n\
77 clrrwi %1,%1,10\n\
78 li %0,0\n\
79 ori %0,%0,%5\n\
80 tlbwe %2,%3,%6\n\
81 tlbwe %1,%3,%7\n\
82 tlbwe %0,%3,%8"
83 : 75 :
84 : "r" (attrib), "r" (phys), "r" (virt), "r" (slot), 76 : "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
85 "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M), 77 "r" (phys),
86 "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), 78 "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M),
79 "r" (tlb_44x_hwater--), /* slot for this TLB entry */
87 "i" (PPC44x_TLB_PAGEID), 80 "i" (PPC44x_TLB_PAGEID),
88 "i" (PPC44x_TLB_XLAT), 81 "i" (PPC44x_TLB_XLAT),
89 "i" (PPC44x_TLB_ATTRIB)); 82 "i" (PPC44x_TLB_ATTRIB));
90} 83}
91 84
92/*
93 * MMU_init_hw does the chip-specific initialization of the MMU hardware.
94 */
95void __init MMU_init_hw(void) 85void __init MMU_init_hw(void)
96{ 86{
97 flush_instruction_cache(); 87 flush_instruction_cache();
@@ -99,22 +89,13 @@ void __init MMU_init_hw(void)
99 89
100unsigned long __init mmu_mapin_ram(void) 90unsigned long __init mmu_mapin_ram(void)
101{ 91{
102 unsigned int pinned_tlbs = 1; 92 unsigned long addr;
103 int i;
104
105 /* Determine number of entries necessary to cover lowmem */
106 pinned_tlbs = (unsigned int)
107 (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT);
108
109 /* Write upper watermark to save location */
110 tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
111 93
112 /* If necessary, set additional pinned TLBs */ 94 /* Pin in enough TLBs to cover any lowmem not covered by the
113 if (pinned_tlbs > 1) 95 * initial 256M mapping established in head_44x.S */
114 for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { 96 for (addr = PPC_PIN_SIZE; addr < total_lowmem;
115 unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE; 97 addr += PPC_PIN_SIZE)
116 ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); 98 ppc44x_pin_tlb(addr + PAGE_OFFSET, addr);
117 }
118 99
119 return total_lowmem; 100 return total_lowmem;
120} 101}
diff --git a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile
index cd3eae147cf8..691ba2bae05d 100644
--- a/arch/ppc/mm/Makefile
+++ b/arch/ppc/mm/Makefile
@@ -8,4 +8,3 @@ obj-y := fault.o init.o mem_pieces.o \
8obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o 8obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o
9obj-$(CONFIG_40x) += 4xx_mmu.o 9obj-$(CONFIG_40x) += 4xx_mmu.o
10obj-$(CONFIG_44x) += 44x_mmu.o 10obj-$(CONFIG_44x) += 44x_mmu.o
11obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o
diff --git a/arch/ppc/mm/fsl_booke_mmu.c b/arch/ppc/mm/fsl_booke_mmu.c
deleted file mode 100644
index 123da03ab118..000000000000
--- a/arch/ppc/mm/fsl_booke_mmu.c
+++ /dev/null
@@ -1,236 +0,0 @@
1/*
2 * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
3 * E500 Book E processors.
4 *
5 * Copyright 2004 Freescale Semiconductor, Inc
6 *
7 * This file contains the routines for initializing the MMU
8 * on the 4xx series of chips.
9 * -- paulus
10 *
11 * Derived from arch/ppc/mm/init.c:
12 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
13 *
14 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
15 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
16 * Copyright (C) 1996 Paul Mackerras
17 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
18 *
19 * Derived from "arch/i386/mm/init.c"
20 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
21 *
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version
25 * 2 of the License, or (at your option) any later version.
26 *
27 */
28
29#include <linux/signal.h>
30#include <linux/sched.h>
31#include <linux/kernel.h>
32#include <linux/errno.h>
33#include <linux/string.h>
34#include <linux/types.h>
35#include <linux/ptrace.h>
36#include <linux/mman.h>
37#include <linux/mm.h>
38#include <linux/swap.h>
39#include <linux/stddef.h>
40#include <linux/vmalloc.h>
41#include <linux/init.h>
42#include <linux/delay.h>
43#include <linux/highmem.h>
44
45#include <asm/pgalloc.h>
46#include <asm/prom.h>
47#include <asm/io.h>
48#include <asm/mmu_context.h>
49#include <asm/pgtable.h>
50#include <asm/mmu.h>
51#include <asm/uaccess.h>
52#include <asm/smp.h>
53#include <asm/bootx.h>
54#include <asm/machdep.h>
55#include <asm/setup.h>
56
57extern void loadcam_entry(unsigned int index);
58unsigned int tlbcam_index;
59unsigned int num_tlbcam_entries;
60static unsigned long __cam0, __cam1, __cam2;
61extern unsigned long total_lowmem;
62extern unsigned long __max_low_memory;
63#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE
64
65#define NUM_TLBCAMS (16)
66
67struct tlbcam {
68 u32 MAS0;
69 u32 MAS1;
70 u32 MAS2;
71 u32 MAS3;
72 u32 MAS7;
73} TLBCAM[NUM_TLBCAMS];
74
75struct tlbcamrange {
76 unsigned long start;
77 unsigned long limit;
78 phys_addr_t phys;
79} tlbcam_addrs[NUM_TLBCAMS];
80
81extern unsigned int tlbcam_index;
82
83/*
84 * Return PA for this VA if it is mapped by a CAM, or 0
85 */
86unsigned long v_mapped_by_tlbcam(unsigned long va)
87{
88 int b;
89 for (b = 0; b < tlbcam_index; ++b)
90 if (va >= tlbcam_addrs[b].start && va < tlbcam_addrs[b].limit)
91 return tlbcam_addrs[b].phys + (va - tlbcam_addrs[b].start);
92 return 0;
93}
94
95/*
96 * Return VA for a given PA or 0 if not mapped
97 */
98unsigned long p_mapped_by_tlbcam(unsigned long pa)
99{
100 int b;
101 for (b = 0; b < tlbcam_index; ++b)
102 if (pa >= tlbcam_addrs[b].phys
103 && pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start)
104 +tlbcam_addrs[b].phys)
105 return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys);
106 return 0;
107}
108
109/*
110 * Set up one of the I/D BAT (block address translation) register pairs.
111 * The parameters are not checked; in particular size must be a power
112 * of 4 between 4k and 256M.
113 */
114void settlbcam(int index, unsigned long virt, phys_addr_t phys,
115 unsigned int size, int flags, unsigned int pid)
116{
117 unsigned int tsize, lz;
118
119 asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
120 tsize = (21 - lz) / 2;
121
122#ifdef CONFIG_SMP
123 if ((flags & _PAGE_NO_CACHE) == 0)
124 flags |= _PAGE_COHERENT;
125#endif
126
127 TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1);
128 TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
129 TLBCAM[index].MAS2 = virt & PAGE_MASK;
130
131 TLBCAM[index].MAS2 |= (flags & _PAGE_WRITETHRU) ? MAS2_W : 0;
132 TLBCAM[index].MAS2 |= (flags & _PAGE_NO_CACHE) ? MAS2_I : 0;
133 TLBCAM[index].MAS2 |= (flags & _PAGE_COHERENT) ? MAS2_M : 0;
134 TLBCAM[index].MAS2 |= (flags & _PAGE_GUARDED) ? MAS2_G : 0;
135 TLBCAM[index].MAS2 |= (flags & _PAGE_ENDIAN) ? MAS2_E : 0;
136
137 TLBCAM[index].MAS3 = (phys & PAGE_MASK) | MAS3_SX | MAS3_SR;
138 TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
139
140#ifndef CONFIG_KGDB /* want user access for breakpoints */
141 if (flags & _PAGE_USER) {
142 TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
143 TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
144 }
145#else
146 TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
147 TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
148#endif
149
150 tlbcam_addrs[index].start = virt;
151 tlbcam_addrs[index].limit = virt + size - 1;
152 tlbcam_addrs[index].phys = phys;
153
154 loadcam_entry(index);
155}
156
157void invalidate_tlbcam_entry(int index)
158{
159 TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index);
160 TLBCAM[index].MAS1 = ~MAS1_VALID;
161
162 loadcam_entry(index);
163}
164
165void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1,
166 unsigned long cam2)
167{
168 settlbcam(0, KERNELBASE, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0);
169 tlbcam_index++;
170 if (cam1) {
171 tlbcam_index++;
172 settlbcam(1, KERNELBASE+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0);
173 }
174 if (cam2) {
175 tlbcam_index++;
176 settlbcam(2, KERNELBASE+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0);
177 }
178}
179
180/*
181 * MMU_init_hw does the chip-specific initialization of the MMU hardware.
182 */
183void __init MMU_init_hw(void)
184{
185 flush_instruction_cache();
186}
187
188unsigned long __init mmu_mapin_ram(void)
189{
190 cam_mapin_ram(__cam0, __cam1, __cam2);
191
192 return __cam0 + __cam1 + __cam2;
193}
194
195
196void __init
197adjust_total_lowmem(void)
198{
199 unsigned long max_low_mem = MAX_LOW_MEM;
200 unsigned long cam_max = 0x10000000;
201 unsigned long ram;
202
203 /* adjust CAM size to max_low_mem */
204 if (max_low_mem < cam_max)
205 cam_max = max_low_mem;
206
207 /* adjust lowmem size to max_low_mem */
208 if (max_low_mem < total_lowmem)
209 ram = max_low_mem;
210 else
211 ram = total_lowmem;
212
213 /* Calculate CAM values */
214 __cam0 = 1UL << 2 * (__ilog2(ram) / 2);
215 if (__cam0 > cam_max)
216 __cam0 = cam_max;
217 ram -= __cam0;
218 if (ram) {
219 __cam1 = 1UL << 2 * (__ilog2(ram) / 2);
220 if (__cam1 > cam_max)
221 __cam1 = cam_max;
222 ram -= __cam1;
223 }
224 if (ram) {
225 __cam2 = 1UL << 2 * (__ilog2(ram) / 2);
226 if (__cam2 > cam_max)
227 __cam2 = cam_max;
228 ram -= __cam2;
229 }
230
231 printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb,"
232 " CAM2=%ldMb residual: %ldMb\n",
233 __cam0 >> 20, __cam1 >> 20, __cam2 >> 20,
234 (total_lowmem - __cam0 - __cam1 - __cam2) >> 20);
235 __max_low_memory = max_low_mem = __cam0 + __cam1 + __cam2;
236}
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index dd898d32480e..7444df3889c5 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -241,12 +241,6 @@ void __init MMU_init(void)
241 if (__max_memory && total_memory > __max_memory) 241 if (__max_memory && total_memory > __max_memory)
242 total_memory = __max_memory; 242 total_memory = __max_memory;
243 total_lowmem = total_memory; 243 total_lowmem = total_memory;
244#ifdef CONFIG_FSL_BOOKE
245 /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB
246 * entries, so we need to adjust lowmem to match the amount we can map
247 * in the fixed entries */
248 adjust_total_lowmem();
249#endif /* CONFIG_FSL_BOOKE */
250 if (total_lowmem > __max_low_memory) { 244 if (total_lowmem > __max_low_memory) {
251 total_lowmem = __max_low_memory; 245 total_lowmem = __max_low_memory;
252#ifndef CONFIG_HIGHMEM 246#ifndef CONFIG_HIGHMEM
diff --git a/arch/ppc/mm/mmu_context.c b/arch/ppc/mm/mmu_context.c
index 85afa7f8aa78..dacf45ced473 100644
--- a/arch/ppc/mm/mmu_context.c
+++ b/arch/ppc/mm/mmu_context.c
@@ -2,7 +2,7 @@
2 * This file contains the routines for handling the MMU on those 2 * This file contains the routines for handling the MMU on those
3 * PowerPC implementations where the MMU substantially follows the 3 * PowerPC implementations where the MMU substantially follows the
4 * architecture specification. This includes the 6xx, 7xx, 7xxx, 4 * architecture specification. This includes the 6xx, 7xx, 7xxx,
5 * 8260, and 83xx implementations but excludes the 8xx and 4xx. 5 * and 8260 implementations but excludes the 8xx and 4xx.
6 * -- paulus 6 * -- paulus
7 * 7 *
8 * Derived from arch/ppc/mm/init.c: 8 * Derived from arch/ppc/mm/init.c:
diff --git a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h
index b298b60c202f..5f813e386b87 100644
--- a/arch/ppc/mm/mmu_decl.h
+++ b/arch/ppc/mm/mmu_decl.h
@@ -58,12 +58,6 @@ extern unsigned int num_tlbcam_entries;
58extern void MMU_init_hw(void); 58extern void MMU_init_hw(void);
59extern unsigned long mmu_mapin_ram(void); 59extern unsigned long mmu_mapin_ram(void);
60 60
61#elif defined(CONFIG_FSL_BOOKE)
62#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
63extern void MMU_init_hw(void);
64extern unsigned long mmu_mapin_ram(void);
65extern void adjust_total_lowmem(void);
66
67#else 61#else
68/* anything except 4xx or 8xx */ 62/* anything except 4xx or 8xx */
69extern void MMU_init_hw(void); 63extern void MMU_init_hw(void);
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
index 1f51e6c94507..fadacfd18806 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -42,10 +42,6 @@ int io_bat_index;
42#define HAVE_BATS 1 42#define HAVE_BATS 1
43#endif 43#endif
44 44
45#if defined(CONFIG_FSL_BOOKE)
46#define HAVE_TLBCAM 1
47#endif
48
49extern char etext[], _stext[]; 45extern char etext[], _stext[];
50 46
51#ifdef CONFIG_SMP 47#ifdef CONFIG_SMP
@@ -63,15 +59,6 @@ void setbat(int index, unsigned long virt, unsigned long phys,
63#define p_mapped_by_bats(x) (0UL) 59#define p_mapped_by_bats(x) (0UL)
64#endif /* HAVE_BATS */ 60#endif /* HAVE_BATS */
65 61
66#ifdef HAVE_TLBCAM
67extern unsigned int tlbcam_index;
68extern unsigned long v_mapped_by_tlbcam(unsigned long va);
69extern unsigned long p_mapped_by_tlbcam(unsigned long pa);
70#else /* !HAVE_TLBCAM */
71#define v_mapped_by_tlbcam(x) (0UL)
72#define p_mapped_by_tlbcam(x) (0UL)
73#endif /* HAVE_TLBCAM */
74
75#ifdef CONFIG_PTE_64BIT 62#ifdef CONFIG_PTE_64BIT
76/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */ 63/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */
77#define PGDIR_ORDER 1 64#define PGDIR_ORDER 1
@@ -213,9 +200,6 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
213 if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ ) 200 if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
214 goto out; 201 goto out;
215 202
216 if ((v = p_mapped_by_tlbcam(p)))
217 goto out;
218
219 if (mem_init_done) { 203 if (mem_init_done) {
220 struct vm_struct *area; 204 struct vm_struct *area;
221 area = get_vm_area(size, VM_IOREMAP); 205 area = get_vm_area(size, VM_IOREMAP);
@@ -341,18 +325,6 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
341 } 325 }
342#endif /* HAVE_BATS */ 326#endif /* HAVE_BATS */
343 327
344#ifdef HAVE_TLBCAM
345 /*
346 * Use a CAM for this if possible...
347 */
348 if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size)
349 && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
350 settlbcam(tlbcam_index, virt, phys, size, flags, 0);
351 ++tlbcam_index;
352 return;
353 }
354#endif /* HAVE_TLBCAM */
355
356 /* No BATs available, put it in the page tables. */ 328 /* No BATs available, put it in the page tables. */
357 for (i = 0; i < size; i += PAGE_SIZE) 329 for (i = 0; i < size; i += PAGE_SIZE)
358 map_page(virt + i, phys + i, flags); 330 map_page(virt + i, phys + i, flags);
diff --git a/arch/ppc/mm/ppc_mmu.c b/arch/ppc/mm/ppc_mmu.c
index 973f1e6afa53..0c1dc155996a 100644
--- a/arch/ppc/mm/ppc_mmu.c
+++ b/arch/ppc/mm/ppc_mmu.c
@@ -2,7 +2,7 @@
2 * This file contains the routines for handling the MMU on those 2 * This file contains the routines for handling the MMU on those
3 * PowerPC implementations where the MMU substantially follows the 3 * PowerPC implementations where the MMU substantially follows the
4 * architecture specification. This includes the 6xx, 7xx, 7xxx, 4 * architecture specification. This includes the 6xx, 7xx, 7xxx,
5 * 8260, and 83xx implementations but excludes the 8xx and 4xx. 5 * and 8260 implementations but excludes the 8xx and 4xx.
6 * -- paulus 6 * -- paulus
7 * 7 *
8 * Derived from arch/ppc/mm/init.c: 8 * Derived from arch/ppc/mm/init.c: