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.c4
-rw-r--r--arch/ppc/mm/fault.c32
-rw-r--r--arch/ppc/mm/hashtable.S36
-rw-r--r--arch/ppc/mm/init.c19
-rw-r--r--arch/ppc/mm/mmu_context.c2
-rw-r--r--arch/ppc/mm/pgtable.c8
-rw-r--r--arch/ppc/mm/ppc_mmu.c28
7 files changed, 29 insertions, 100 deletions
diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c
index 3d79ce281b67..e0152a9b26e6 100644
--- a/arch/ppc/mm/44x_mmu.c
+++ b/arch/ppc/mm/44x_mmu.c
@@ -104,7 +104,7 @@ unsigned long __init mmu_mapin_ram(void)
104 104
105 /* Determine number of entries necessary to cover lowmem */ 105 /* Determine number of entries necessary to cover lowmem */
106 pinned_tlbs = (unsigned int) 106 pinned_tlbs = (unsigned int)
107 (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT); 107 (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT);
108 108
109 /* Write upper watermark to save location */ 109 /* Write upper watermark to save location */
110 tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs; 110 tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
@@ -112,7 +112,7 @@ unsigned long __init mmu_mapin_ram(void)
112 /* If necessary, set additional pinned TLBs */ 112 /* If necessary, set additional pinned TLBs */
113 if (pinned_tlbs > 1) 113 if (pinned_tlbs > 1)
114 for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { 114 for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) {
115 unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE; 115 unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE;
116 ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); 116 ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr);
117 } 117 }
118 118
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index ee5e9f25baf9..8e08ca32531a 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/mm/fault.c
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * 4 *
@@ -204,6 +202,7 @@ good_area:
204 /* an exec - 4xx/Book-E allows for per-page execute permission */ 202 /* an exec - 4xx/Book-E allows for per-page execute permission */
205 } else if (TRAP(regs) == 0x400) { 203 } else if (TRAP(regs) == 0x400) {
206 pte_t *ptep; 204 pte_t *ptep;
205 pmd_t *pmdp;
207 206
208#if 0 207#if 0
209 /* It would be nice to actually enforce the VM execute 208 /* It would be nice to actually enforce the VM execute
@@ -217,21 +216,24 @@ good_area:
217 /* Since 4xx/Book-E supports per-page execute permission, 216 /* Since 4xx/Book-E supports per-page execute permission,
218 * we lazily flush dcache to icache. */ 217 * we lazily flush dcache to icache. */
219 ptep = NULL; 218 ptep = NULL;
220 if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { 219 if (get_pteptr(mm, address, &ptep, &pmdp)) {
221 struct page *page = pte_page(*ptep); 220 spinlock_t *ptl = pte_lockptr(mm, pmdp);
222 221 spin_lock(ptl);
223 if (! test_bit(PG_arch_1, &page->flags)) { 222 if (pte_present(*ptep)) {
224 flush_dcache_icache_page(page); 223 struct page *page = pte_page(*ptep);
225 set_bit(PG_arch_1, &page->flags); 224
225 if (!test_bit(PG_arch_1, &page->flags)) {
226 flush_dcache_icache_page(page);
227 set_bit(PG_arch_1, &page->flags);
228 }
229 pte_update(ptep, 0, _PAGE_HWEXEC);
230 _tlbie(address);
231 pte_unmap_unlock(ptep, ptl);
232 up_read(&mm->mmap_sem);
233 return 0;
226 } 234 }
227 pte_update(ptep, 0, _PAGE_HWEXEC); 235 pte_unmap_unlock(ptep, ptl);
228 _tlbie(address);
229 pte_unmap(ptep);
230 up_read(&mm->mmap_sem);
231 return 0;
232 } 236 }
233 if (ptep != NULL)
234 pte_unmap(ptep);
235#endif 237#endif
236 /* a read */ 238 /* a read */
237 } else { 239 } else {
diff --git a/arch/ppc/mm/hashtable.S b/arch/ppc/mm/hashtable.S
index 3ec87c91343e..31d0a924317c 100644
--- a/arch/ppc/mm/hashtable.S
+++ b/arch/ppc/mm/hashtable.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/hashtable.S
3 *
4 * $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $ 2 * $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
5 * 3 *
6 * PowerPC version 4 * PowerPC version
@@ -76,12 +74,6 @@ _GLOBAL(hash_page_sync)
76 */ 74 */
77 .text 75 .text
78_GLOBAL(hash_page) 76_GLOBAL(hash_page)
79#ifdef CONFIG_PPC64BRIDGE
80 mfmsr r0
81 clrldi r0,r0,1 /* make sure it's in 32-bit mode */
82 MTMSRD(r0)
83 isync
84#endif
85 tophys(r7,0) /* gets -KERNELBASE into r7 */ 77 tophys(r7,0) /* gets -KERNELBASE into r7 */
86#ifdef CONFIG_SMP 78#ifdef CONFIG_SMP
87 addis r8,r7,mmu_hash_lock@h 79 addis r8,r7,mmu_hash_lock@h
@@ -305,7 +297,6 @@ Hash_base = 0xc0180000
305Hash_bits = 12 /* e.g. 256kB hash table */ 297Hash_bits = 12 /* e.g. 256kB hash table */
306Hash_msk = (((1 << Hash_bits) - 1) * 64) 298Hash_msk = (((1 << Hash_bits) - 1) * 64)
307 299
308#ifndef CONFIG_PPC64BRIDGE
309/* defines for the PTE format for 32-bit PPCs */ 300/* defines for the PTE format for 32-bit PPCs */
310#define PTE_SIZE 8 301#define PTE_SIZE 8
311#define PTEG_SIZE 64 302#define PTEG_SIZE 64
@@ -319,21 +310,6 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64)
319#define SET_V(r) oris r,r,PTE_V@h 310#define SET_V(r) oris r,r,PTE_V@h
320#define CLR_V(r,t) rlwinm r,r,0,1,31 311#define CLR_V(r,t) rlwinm r,r,0,1,31
321 312
322#else
323/* defines for the PTE format for 64-bit PPCs */
324#define PTE_SIZE 16
325#define PTEG_SIZE 128
326#define LG_PTEG_SIZE 7
327#define LDPTEu ldu
328#define STPTE std
329#define CMPPTE cmpd
330#define PTE_H 2
331#define PTE_V 1
332#define TST_V(r) andi. r,r,PTE_V
333#define SET_V(r) ori r,r,PTE_V
334#define CLR_V(r,t) li t,PTE_V; andc r,r,t
335#endif /* CONFIG_PPC64BRIDGE */
336
337#define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1) 313#define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1)
338#define HASH_RIGHT 31-LG_PTEG_SIZE 314#define HASH_RIGHT 31-LG_PTEG_SIZE
339 315
@@ -351,14 +327,8 @@ BEGIN_FTR_SECTION
351END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT) 327END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT)
352 328
353 /* Construct the high word of the PPC-style PTE (r5) */ 329 /* Construct the high word of the PPC-style PTE (r5) */
354#ifndef CONFIG_PPC64BRIDGE
355 rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ 330 rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */
356 rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */ 331 rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */
357#else /* CONFIG_PPC64BRIDGE */
358 clrlwi r3,r3,8 /* reduce vsid to 24 bits */
359 sldi r5,r3,12 /* shift vsid into position */
360 rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */
361#endif /* CONFIG_PPC64BRIDGE */
362 SET_V(r5) /* set V (valid) bit */ 332 SET_V(r5) /* set V (valid) bit */
363 333
364 /* Get the address of the primary PTE group in the hash table (r3) */ 334 /* Get the address of the primary PTE group in the hash table (r3) */
@@ -542,14 +512,8 @@ _GLOBAL(flush_hash_pages)
542 add r3,r3,r0 /* note code below trims to 24 bits */ 512 add r3,r3,r0 /* note code below trims to 24 bits */
543 513
544 /* Construct the high word of the PPC-style PTE (r11) */ 514 /* Construct the high word of the PPC-style PTE (r11) */
545#ifndef CONFIG_PPC64BRIDGE
546 rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ 515 rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */
547 rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */ 516 rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */
548#else /* CONFIG_PPC64BRIDGE */
549 clrlwi r3,r3,8 /* reduce vsid to 24 bits */
550 sldi r11,r3,12 /* shift vsid into position */
551 rlwimi r11,r4,16,20,24 /* put in API (abbrev page index) */
552#endif /* CONFIG_PPC64BRIDGE */
553 SET_V(r11) /* set V (valid) bit */ 517 SET_V(r11) /* set V (valid) bit */
554 518
555#ifdef CONFIG_SMP 519#ifdef CONFIG_SMP
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 134db5c04203..386e000bcb73 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -140,7 +140,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name)
140 140
141 while (start < end) { 141 while (start < end) {
142 ClearPageReserved(virt_to_page(start)); 142 ClearPageReserved(virt_to_page(start));
143 set_page_count(virt_to_page(start), 1); 143 init_page_count(virt_to_page(start));
144 free_page(start); 144 free_page(start);
145 cnt++; 145 cnt++;
146 start += PAGE_SIZE; 146 start += PAGE_SIZE;
@@ -172,7 +172,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
172 172
173 for (; start < end; start += PAGE_SIZE) { 173 for (; start < end; start += PAGE_SIZE) {
174 ClearPageReserved(virt_to_page(start)); 174 ClearPageReserved(virt_to_page(start));
175 set_page_count(virt_to_page(start), 1); 175 init_page_count(virt_to_page(start));
176 free_page(start); 176 free_page(start);
177 totalram_pages++; 177 totalram_pages++;
178 } 178 }
@@ -412,14 +412,6 @@ void __init mem_init(void)
412 } 412 }
413#endif /* CONFIG_BLK_DEV_INITRD */ 413#endif /* CONFIG_BLK_DEV_INITRD */
414 414
415#ifdef CONFIG_PPC_OF
416 /* mark the RTAS pages as reserved */
417 if ( rtas_data )
418 for (addr = (ulong)__va(rtas_data);
419 addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ;
420 addr += PAGE_SIZE)
421 SetPageReserved(virt_to_page(addr));
422#endif
423 for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; 415 for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory;
424 addr += PAGE_SIZE) { 416 addr += PAGE_SIZE) {
425 if (!PageReserved(virt_to_page(addr))) 417 if (!PageReserved(virt_to_page(addr)))
@@ -441,7 +433,7 @@ void __init mem_init(void)
441 struct page *page = mem_map + pfn; 433 struct page *page = mem_map + pfn;
442 434
443 ClearPageReserved(page); 435 ClearPageReserved(page);
444 set_page_count(page, 1); 436 init_page_count(page);
445 __free_page(page); 437 __free_page(page);
446 totalhigh_pages++; 438 totalhigh_pages++;
447 } 439 }
@@ -494,11 +486,6 @@ set_phys_avail(unsigned long total_memory)
494 initrd_end - initrd_start, 1); 486 initrd_end - initrd_start, 1);
495 } 487 }
496#endif /* CONFIG_BLK_DEV_INITRD */ 488#endif /* CONFIG_BLK_DEV_INITRD */
497#ifdef CONFIG_PPC_OF
498 /* remove the RTAS pages from the available memory */
499 if (rtas_data)
500 mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
501#endif
502} 489}
503 490
504/* Mark some memory as reserved by removing it from phys_avail. */ 491/* Mark some memory as reserved by removing it from phys_avail. */
diff --git a/arch/ppc/mm/mmu_context.c b/arch/ppc/mm/mmu_context.c
index a8816e0f6a86..b4a4b3f02a1c 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 POWER3 implementations but excludes the 8xx and 4xx. 5 * 8260, and 83xx 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/pgtable.c b/arch/ppc/mm/pgtable.c
index 6ea9185fd120..706bca8eb144 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -39,7 +39,7 @@ unsigned long ioremap_base;
39unsigned long ioremap_bot; 39unsigned long ioremap_bot;
40int io_bat_index; 40int io_bat_index;
41 41
42#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) 42#if defined(CONFIG_6xx)
43#define HAVE_BATS 1 43#define HAVE_BATS 1
44#endif 44#endif
45 45
@@ -368,7 +368,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
368 * the PTE pointer is unmodified if PTE is not found. 368 * the PTE pointer is unmodified if PTE is not found.
369 */ 369 */
370int 370int
371get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep) 371get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
372{ 372{
373 pgd_t *pgd; 373 pgd_t *pgd;
374 pmd_t *pmd; 374 pmd_t *pmd;
@@ -383,6 +383,8 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
383 if (pte) { 383 if (pte) {
384 retval = 1; 384 retval = 1;
385 *ptep = pte; 385 *ptep = pte;
386 if (pmdp)
387 *pmdp = pmd;
386 /* XXX caller needs to do pte_unmap, yuck */ 388 /* XXX caller needs to do pte_unmap, yuck */
387 } 389 }
388 } 390 }
@@ -420,7 +422,7 @@ unsigned long iopa(unsigned long addr)
420 mm = &init_mm; 422 mm = &init_mm;
421 423
422 pa = 0; 424 pa = 0;
423 if (get_pteptr(mm, addr, &pte)) { 425 if (get_pteptr(mm, addr, &pte, NULL)) {
424 pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); 426 pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
425 pte_unmap(pte); 427 pte_unmap(pte);
426 } 428 }
diff --git a/arch/ppc/mm/ppc_mmu.c b/arch/ppc/mm/ppc_mmu.c
index 9a381ed5eb21..25bb6f3347c1 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 POWER3 implementations but excludes the 8xx and 4xx. 5 * 8260, and 83xx 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:
@@ -42,11 +42,7 @@ unsigned long _SDR1;
42 42
43union ubat { /* BAT register values to be loaded */ 43union ubat { /* BAT register values to be loaded */
44 BAT bat; 44 BAT bat;
45#ifdef CONFIG_PPC64BRIDGE
46 u64 word[2];
47#else
48 u32 word[2]; 45 u32 word[2];
49#endif
50} BATS[4][2]; /* 4 pairs of IBAT, DBAT */ 46} BATS[4][2]; /* 4 pairs of IBAT, DBAT */
51 47
52struct batrange { /* stores address ranges mapped by BATs */ 48struct batrange { /* stores address ranges mapped by BATs */
@@ -83,9 +79,6 @@ unsigned long p_mapped_by_bats(unsigned long pa)
83 79
84unsigned long __init mmu_mapin_ram(void) 80unsigned long __init mmu_mapin_ram(void)
85{ 81{
86#ifdef CONFIG_POWER4
87 return 0;
88#else
89 unsigned long tot, bl, done; 82 unsigned long tot, bl, done;
90 unsigned long max_size = (256<<20); 83 unsigned long max_size = (256<<20);
91 unsigned long align; 84 unsigned long align;
@@ -122,7 +115,6 @@ unsigned long __init mmu_mapin_ram(void)
122 } 115 }
123 116
124 return done; 117 return done;
125#endif
126} 118}
127 119
128/* 120/*
@@ -205,27 +197,10 @@ void __init MMU_init_hw(void)
205 197
206 if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105); 198 if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
207 199
208#ifdef CONFIG_PPC64BRIDGE
209#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */
210#define SDR1_LOW_BITS (lg_n_hpteg - 11)
211#define MIN_N_HPTEG 2048 /* min 256kB hash table */
212#else
213#define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */ 200#define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */
214#define SDR1_LOW_BITS ((n_hpteg - 1) >> 10) 201#define SDR1_LOW_BITS ((n_hpteg - 1) >> 10)
215#define MIN_N_HPTEG 1024 /* min 64kB hash table */ 202#define MIN_N_HPTEG 1024 /* min 64kB hash table */
216#endif
217
218#ifdef CONFIG_POWER4
219 /* The hash table has already been allocated and initialized
220 in prom.c */
221 n_hpteg = Hash_size >> LG_HPTEG_SIZE;
222 lg_n_hpteg = __ilog2(n_hpteg);
223
224 /* Remove the hash table from the available memory */
225 if (Hash)
226 reserve_phys_mem(__pa(Hash), Hash_size);
227 203
228#else /* CONFIG_POWER4 */
229 /* 204 /*
230 * Allow 1 HPTE (1/8 HPTEG) for each page of memory. 205 * Allow 1 HPTE (1/8 HPTEG) for each page of memory.
231 * This is less than the recommended amount, but then 206 * This is less than the recommended amount, but then
@@ -248,7 +223,6 @@ void __init MMU_init_hw(void)
248 Hash = mem_pieces_find(Hash_size, Hash_size); 223 Hash = mem_pieces_find(Hash_size, Hash_size);
249 cacheable_memzero(Hash, Hash_size); 224 cacheable_memzero(Hash, Hash_size);
250 _SDR1 = __pa(Hash) | SDR1_LOW_BITS; 225 _SDR1 = __pa(Hash) | SDR1_LOW_BITS;
251#endif /* CONFIG_POWER4 */
252 226
253 Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); 227 Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
254 228