1/* 2 * Modifications by Matt Porter (mporter@mvista.com) to support 3 * PPC44x Book E processors. 4 * 5 * This file contains the routines for initializing the MMU 6 * on the 4xx series of chips. 7 * -- paulus 8 * 9 * Derived from arch/ppc/mm/init.c: 10 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 11 * 12 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 13 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 14 * Copyright (C) 1996 Paul Mackerras 15 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). 16 * 17 * Derived from "arch/i386/mm/init.c" 18 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 19 * 20 * This program is free software; you can redistribute it and/or 21 * modify it under the terms of the GNU General Public License 22 * as published by the Free Software Foundation; either version 23 * 2 of the License, or (at your option) any later version. 24 * 25 */ 26 27#include <linux/signal.h> 28#include <linux/sched.h> 29#include <linux/kernel.h> 30#include <linux/errno.h> 31#include <linux/string.h> 32#include <linux/types.h> 33#include <linux/ptrace.h> 34#include <linux/mman.h> 35#include <linux/mm.h> 36#include <linux/swap.h> 37#include <linux/stddef.h> 38#include <linux/vmalloc.h> 39#include <linux/init.h> 40#include <linux/delay.h> 41#include <linux/highmem.h> 42 43#include <asm/pgalloc.h> 44#include <asm/prom.h> 45#include <asm/io.h> 46#include <asm/mmu_context.h> 47#include <asm/pgtable.h> 48#include <asm/mmu.h> 49#include <asm/uaccess.h> 50#include <asm/smp.h> 51#include <asm/bootx.h> 52#include <asm/machdep.h> 53#include <asm/setup.h> 54 55#include "mmu_decl.h" 56 57extern char etext[], _stext[]; 58 59/* Used by the 44x TLB replacement exception handler. 60 * Just needed it declared someplace. 61 */ 62unsigned int tlb_44x_index = 0; 63unsigned int tlb_44x_hwater = 62; 64 65/* 66 * "Pins" a 256MB TLB entry in AS0 for kernel lowmem 67 */ 68static void __init 69ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys) 70{ 71 unsigned long attrib = 0; 72 73 __asm__ __volatile__("\ 74 clrrwi %2,%2,10\n\ 75 ori %2,%2,%4\n\ 76 clrrwi %1,%1,10\n\ 77 li %0,0\n\ 78 ori %0,%0,%5\n\ 79 tlbwe %2,%3,%6\n\ 80 tlbwe %1,%3,%7\n\ 81 tlbwe %0,%3,%8" 82 : 83 : "r" (attrib), "r" (phys), "r" (virt), "r" (slot), 84 "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M), 85 "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), 86 "i" (PPC44x_TLB_PAGEID), 87 "i" (PPC44x_TLB_XLAT), 88 "i" (PPC44x_TLB_ATTRIB)); 89} 90 91/* 92 * MMU_init_hw does the chip-specific initialization of the MMU hardware. 93 */ 94void __init MMU_init_hw(void) 95{ 96 flush_instruction_cache(); 97} 98 99unsigned long __init mmu_mapin_ram(void) 100{ 101 unsigned int pinned_tlbs = 1; 102 int i; 103 104 /* Determine number of entries necessary to cover lowmem */ 105 pinned_tlbs = (unsigned int) 106 (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT); 107 108 /* Write upper watermark to save location */ 109 tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs; 110 111 /* If necessary, set additional pinned TLBs */ 112 if (pinned_tlbs > 1) 113 for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { 114 unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE; 115 ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); 116 } 117 118 return total_lowmem; 119} 120