1/* 2 * BK Id: %F% %I% %G% %U% %#% 3 */ 4/* 5 * This file contains the routines for handling the MMU on those 6 * PowerPC implementations where the MMU substantially follows the 7 * architecture specification. This includes the 6xx, 7xx, 7xxx, 8 * 8260, and POWER3 implementations but excludes the 8xx and 4xx. 9 * Although the iSeries hardware does comply with the architecture 10 * specification, the need to work through the hypervisor makes 11 * things sufficiently different that it is handled elsewhere. 12 * -- paulus 13 * 14 * Derived from arch/ppc/mm/init.c: 15 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 16 * 17 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 18 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 19 * Copyright (C) 1996 Paul Mackerras 20 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). 21 * 22 * Derived from "arch/i386/mm/init.c" 23 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 24 * 25 * This program is free software; you can redistribute it and/or 26 * modify it under the terms of the GNU General Public License 27 * as published by the Free Software Foundation; either version 28 * 2 of the License, or (at your option) any later version. 29 * 30 */ 31 32#include <linux/config.h> 33#include <linux/kernel.h> 34#include <linux/mm.h> 35#include <linux/init.h> 36 37#include <asm/prom.h> 38#include <asm/mmu.h> 39#include <asm/machdep.h> 40 41#include "mmu_decl.h" 42#include "mem_pieces.h" 43 44PTE *Hash, *Hash_end; 45unsigned long Hash_size, Hash_mask; 46unsigned long _SDR1; 47 48union ubat { /* BAT register values to be loaded */ 49 BAT bat; 50#ifdef CONFIG_PPC64BRIDGE 51 u64 word[2]; 52#else 53 u32 word[2]; 54#endif 55} BATS[4][2]; /* 4 pairs of IBAT, DBAT */ 56 57struct batrange { /* stores address ranges mapped by BATs */ 58 unsigned long start; 59 unsigned long limit; 60 unsigned long phys; 61} bat_addrs[4]; 62 63/* 64 * Return PA for this VA if it is mapped by a BAT, or 0 65 */ 66unsigned long v_mapped_by_bats(unsigned long va) 67{ 68 int b; 69 for (b = 0; b < 4; ++b) 70 if (va >= bat_addrs[b].start && va < bat_addrs[b].limit) 71 return bat_addrs[b].phys + (va - bat_addrs[b].start); 72 return 0; 73} 74 75/* 76 * Return VA for a given PA or 0 if not mapped 77 */ 78unsigned long p_mapped_by_bats(unsigned long pa) 79{ 80 int b; 81 for (b = 0; b < 4; ++b) 82 if (pa >= bat_addrs[b].phys 83 && pa < (bat_addrs[b].limit-bat_addrs[b].start) 84 +bat_addrs[b].phys) 85 return bat_addrs[b].start+(pa-bat_addrs[b].phys); 86 return 0; 87} 88 89void __init bat_mapin_ram(unsigned long bat2, unsigned long bat3) 90{ 91 unsigned long tot, done; 92 93 tot = total_lowmem; 94 setbat(2, KERNELBASE, ram_phys_base, bat2, _PAGE_KERNEL); 95 done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1; 96 if ((done < tot) && !bat_addrs[3].limit && bat3) { 97 tot -= done; 98 setbat(3, KERNELBASE+done, ram_phys_base+done, bat3, 99 _PAGE_KERNEL); 100 } 101} 102 103/* 104 * Set up one of the I/D BAT (block address translation) register pairs. 105 * The parameters are not checked; in particular size must be a power 106 * of 2 between 128k and 256M. 107 */ 108void __init setbat(int index, unsigned long virt, unsigned long phys, 109 unsigned int size, int flags) 110{ 111 unsigned int bl; 112 int wimgxpp; 113 union ubat *bat = BATS[index]; 114 115#ifdef CONFIG_SMP 116 if ((flags & _PAGE_NO_CACHE) == 0) 117 flags |= _PAGE_COHERENT; 118#endif 119 bl = (size >> 17) - 1; 120 if (PVR_VER(mfspr(PVR)) != 1) { 121 /* 603, 604, etc. */ 122 /* Do DBAT first */ 123 wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE 124 | _PAGE_COHERENT | _PAGE_GUARDED); 125 wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX; 126 bat[1].word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */ 127 bat[1].word[1] = phys | wimgxpp; 128#ifndef CONFIG_KGDB /* want user access for breakpoints */ 129 if (flags & _PAGE_USER) 130#endif 131 bat[1].bat.batu.vp = 1; 132 if (flags & _PAGE_GUARDED) { 133 /* G bit must be zero in IBATs */ 134 bat[0].word[0] = bat[0].word[1] = 0; 135 } else { 136 /* make IBAT same as DBAT */ 137 bat[0] = bat[1]; 138 } 139 } else { 140 /* 601 cpu */ 141 if (bl > BL_8M) 142 bl = BL_8M; 143 wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE 144 | _PAGE_COHERENT); 145 wimgxpp |= (flags & _PAGE_RW)? 146 ((flags & _PAGE_USER)? PP_RWRW: PP_RWXX): PP_RXRX; 147 bat->word[0] = virt | wimgxpp | 4; /* Ks=0, Ku=1 */ 148 bat->word[1] = phys | bl | 0x40; /* V=1 */ 149 } 150 151 bat_addrs[index].start = virt; 152 bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1; 153 bat_addrs[index].phys = phys; 154} 155 156/* 157 * Initialize the hash table and patch the instructions in hashtable.S. 158 */ 159void __init MMU_init_hw(void) 160{ 161 unsigned int hmask, mb, mb2; 162 unsigned int n_hpteg, lg_n_hpteg; 163 164 extern unsigned int hash_page_patch_A[]; 165 extern unsigned int hash_page_patch_B[], hash_page_patch_C[]; 166 extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[]; 167 168 if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE) == 0) { 169 Hash_size = 0; 170 Hash_end = 0; 171 Hash = 0; 172 return; 173 } 174 175 if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105); 176 177#ifdef CONFIG_PPC64BRIDGE 178#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */ 179#define SDR1_LOW_BITS (lg_n_hpteg - 11) 180#define MIN_N_HPTEG 2048 /* min 256kB hash table */ 181#else 182#define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */ 183#define SDR1_LOW_BITS ((n_hpteg - 1) >> 10) 184#define MIN_N_HPTEG 1024 /* min 64kB hash table */ 185#endif 186 187 /* 188 * Allow 1 HPTE (1/8 HPTEG) for each page of memory. 189 * This is less than the recommended amount, but then 190 * Linux ain't AIX. 191 */ 192 n_hpteg = total_memory / (PAGE_SIZE * 8); 193 if (n_hpteg < MIN_N_HPTEG) 194 n_hpteg = MIN_N_HPTEG; 195 lg_n_hpteg = __ilog2(n_hpteg); 196 if (n_hpteg & (n_hpteg - 1)) { 197 ++lg_n_hpteg; /* round up if not power of 2 */ 198 n_hpteg = 1 << lg_n_hpteg; 199 } 200 Hash_size = n_hpteg << LG_HPTEG_SIZE; 201 202 /* 203 * Find some memory for the hash table. 204 */ 205 if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322); 206 Hash = mem_pieces_find(Hash_size, Hash_size); 207 cacheable_memzero(Hash, Hash_size); 208 _SDR1 = __pa(Hash) | SDR1_LOW_BITS; 209 Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); 210 211 printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n", 212 total_memory >> 20, Hash_size >> 10, Hash); 213 214 /* 215 * Patch up the instructions in hashtable.S:create_hpte 216 */ 217 if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); 218 Hash_mask = n_hpteg - 1; 219 hmask = Hash_mask >> (16 - LG_HPTEG_SIZE); 220 mb2 = mb = 32 - LG_HPTEG_SIZE - lg_n_hpteg; 221 if (lg_n_hpteg > 16) 222 mb2 = 16 - LG_HPTEG_SIZE; 223 hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff) 224 | ((unsigned int)(Hash) >> 16); 225 hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0) | (mb << 6); 226 hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0) | (mb2 << 6); 227 hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff) | hmask; 228 hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff) | hmask; 229 230 /* 231 * Ensure that the locations we've patched have been written 232 * out from the data cache and invalidated in the instruction 233 * cache, on those machines with split caches. 234 */ 235 flush_icache_range((unsigned long) &hash_page_patch_A[0], 236 (unsigned long) &hash_page_patch_C[1]); 237 238 /* 239 * Patch up the instructions in hashtable.S:flush_hash_page 240 */ 241 flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff) 242 | ((unsigned int)(Hash) >> 16); 243 flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0) | (mb << 6); 244 flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0) | (mb2 << 6); 245 flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff) | hmask; 246 flush_icache_range((unsigned long) &flush_hash_patch_A[0], 247 (unsigned long) &flush_hash_patch_B[1]); 248 249 if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205); 250} 251 252/* 253 * This is called at the end of handling a user page fault, when the 254 * fault has been handled by updating a PTE in the linux page tables. 255 * We use it to preload an HPTE into the hash table corresponding to 256 * the updated linux PTE. 257 */ 258void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, 259 pte_t pte) 260{ 261 struct mm_struct *mm; 262 pmd_t *pmd; 263 pte_t *ptep; 264 static int nopreload; 265 266 if (Hash == 0 || nopreload) 267 return; 268 /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */ 269 if (!pte_young(pte)) 270 return; 271 mm = (address < TASK_SIZE)? vma->vm_mm: &init_mm; 272 pmd = pmd_offset(pgd_offset(mm, address), address); 273 if (!pmd_none(*pmd)) { 274 ptep = pte_offset(pmd, address); 275 add_hash_page(mm->context, address, ptep); 276 } 277} 278