1############################################################################### 2# 3# TLB loading functions 4# 5# Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. 6# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 7# Modified by David Howells (dhowells@redhat.com) 8# 9# This program is free software; you can redistribute it and/or 10# modify it under the terms of the GNU General Public Licence 11# as published by the Free Software Foundation; either version 12# 2 of the Licence, or (at your option) any later version. 13# 14############################################################################### 15#include <linux/sys.h> 16#include <linux/linkage.h> 17#include <asm/smp.h> 18#include <asm/intctl-regs.h> 19#include <asm/frame.inc> 20#include <asm/page.h> 21#include <asm/pgtable.h> 22 23############################################################################### 24# 25# Instruction TLB Miss handler entry point 26# 27############################################################################### 28 .type itlb_miss,@function 29ENTRY(itlb_miss) 30#ifdef CONFIG_GDBSTUB 31 movm [d2,d3,a2],(sp) 32#else 33 or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate 34 # register bank 35 nop 36 nop 37 nop 38#endif 39 40#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) 41 mov (MMUCTR),d2 42 mov d2,(MMUCTR) 43#endif 44 45 and ~EPSW_NMID,epsw 46 mov (IPTEU),d3 47 mov (PTBR),a2 48 mov d3,d2 49 and 0xffc00000,d2 50 lsr 20,d2 51 mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22] 52 btst _PAGE_VALID,a2 53 beq itlb_miss_fault # jump if doesn't point anywhere 54 55 and ~(PAGE_SIZE-1),a2 56 mov d3,d2 57 and 0x003ff000,d2 58 lsr 10,d2 59 add d2,a2 60 mov (a2),d2 # get pte from PTD[addr 21..12] 61 btst _PAGE_VALID,d2 62 beq itlb_miss_fault # jump if doesn't point to a page 63 # (might be a swap id) 64#if ((_PAGE_ACCESSED & 0xffffff00) == 0) 65 bset _PAGE_ACCESSED,(0,a2) 66#elif ((_PAGE_ACCESSED & 0xffff00ff) == 0) 67 bset +(_PAGE_ACCESSED >> 8),(1,a2) 68#else 69#error "_PAGE_ACCESSED value is out of range" 70#endif 71 and ~xPTEL2_UNUSED1,d2 72itlb_miss_set: 73 mov d2,(IPTEL2) # change the TLB 74#ifdef CONFIG_GDBSTUB 75 movm (sp),[d2,d3,a2] 76#endif 77 rti 78 79itlb_miss_fault: 80 mov _PAGE_VALID,d2 # force address error handler to be 81 # invoked 82 bra itlb_miss_set 83 84 .size itlb_miss, . - itlb_miss 85 86############################################################################### 87# 88# Data TLB Miss handler entry point 89# 90############################################################################### 91 .type dtlb_miss,@function 92ENTRY(dtlb_miss) 93#ifdef CONFIG_GDBSTUB 94 movm [d2,d3,a2],(sp) 95#else 96 or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate 97 # register bank 98 nop 99 nop 100 nop 101#endif 102 103#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) 104 mov (MMUCTR),d2 105 mov d2,(MMUCTR) 106#endif 107 108 and ~EPSW_NMID,epsw 109 mov (DPTEU),d3 110 mov (PTBR),a2 111 mov d3,d2 112 and 0xffc00000,d2 113 lsr 20,d2 114 mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22] 115 btst _PAGE_VALID,a2 116 beq dtlb_miss_fault # jump if doesn't point anywhere 117 118 and ~(PAGE_SIZE-1),a2 119 mov d3,d2 120 and 0x003ff000,d2 121 lsr 10,d2 122 add d2,a2 123 mov (a2),d2 # get pte from PTD[addr 21..12] 124 btst _PAGE_VALID,d2 125 beq dtlb_miss_fault # jump if doesn't point to a page 126 # (might be a swap id) 127#if ((_PAGE_ACCESSED & 0xffffff00) == 0) 128 bset _PAGE_ACCESSED,(0,a2) 129#elif ((_PAGE_ACCESSED & 0xffff00ff) == 0) 130 bset +(_PAGE_ACCESSED >> 8),(1,a2) 131#else 132#error "_PAGE_ACCESSED value is out of range" 133#endif 134 and ~xPTEL2_UNUSED1,d2 135dtlb_miss_set: 136 mov d2,(DPTEL2) # change the TLB 137#ifdef CONFIG_GDBSTUB 138 movm (sp),[d2,d3,a2] 139#endif 140 rti 141 142dtlb_miss_fault: 143 mov _PAGE_VALID,d2 # force address error handler to be 144 # invoked 145 bra dtlb_miss_set 146 .size dtlb_miss, . - dtlb_miss 147 148############################################################################### 149# 150# Instruction TLB Address Error handler entry point 151# 152############################################################################### 153 .type itlb_aerror,@function 154ENTRY(itlb_aerror) 155 add -4,sp 156 SAVE_ALL 157 158#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) 159 mov (MMUCTR),d1 160 mov d1,(MMUCTR) 161#endif 162 163 and ~EPSW_NMID,epsw 164 add -4,sp # need to pass three params 165 166 # calculate the fault code 167 movhu (MMUFCR_IFC),d1 168 or 0x00010000,d1 # it's an instruction fetch 169 170 # determine the page address 171 mov (IPTEU),d0 172 and PAGE_MASK,d0 173 mov d0,(12,sp) 174 175 clr d0 176 mov d0,(IPTEL2) 177 178 or EPSW_IE,epsw 179 mov fp,d0 180 call do_page_fault[],0 # do_page_fault(regs,code,addr 181 182 jmp ret_from_exception 183 .size itlb_aerror, . - itlb_aerror 184 185############################################################################### 186# 187# Data TLB Address Error handler entry point 188# 189############################################################################### 190 .type dtlb_aerror,@function 191ENTRY(dtlb_aerror) 192 add -4,sp 193 SAVE_ALL 194 195#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) 196 mov (MMUCTR),d1 197 mov d1,(MMUCTR) 198#endif 199 200 add -4,sp # need to pass three params 201 and ~EPSW_NMID,epsw 202 203 # calculate the fault code 204 movhu (MMUFCR_DFC),d1 205 206 # determine the page address 207 mov (DPTEU),a2 208 mov a2,d0 209 and PAGE_MASK,d0 210 mov d0,(12,sp) 211 212 clr d0 213 mov d0,(DPTEL2) 214 215 or EPSW_IE,epsw 216 mov fp,d0 217 call do_page_fault[],0 # do_page_fault(regs,code,addr 218 219 jmp ret_from_exception 220 .size dtlb_aerror, . - dtlb_aerror 221