###############################################################################1#2# TLB loading functions3#4# Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.5# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.6# Modified by David Howells ([email protected])7#8# This program is free software; you can redistribute it and/or9# modify it under the terms of the GNU General Public Licence10# as published by the Free Software Foundation; either version11# 2 of the Licence, or (at your option) any later version.12#13###############################################################################14#include <linux/sys.h>15#include <linux/linkage.h>16#include <asm/smp.h>17#include <asm/intctl-regs.h>18#include <asm/frame.inc>19#include <asm/page.h>20#include <asm/pgtable.h>2122###############################################################################23#24# Instruction TLB Miss handler entry point25#26###############################################################################27.type itlb_miss,@function28ENTRY(itlb_miss)29#ifdef CONFIG_GDBSTUB30movm [d2,d3,a2],(sp)31#else32or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate33# register bank34nop35nop36nop37#endif3839#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)40mov (MMUCTR),d241mov d2,(MMUCTR)42#endif4344and ~EPSW_NMID,epsw45mov (IPTEU),d346mov (PTBR),a247mov d3,d248and 0xffc00000,d249lsr 20,d250mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22]51btst _PAGE_VALID,a252beq itlb_miss_fault # jump if doesn't point anywhere5354and ~(PAGE_SIZE-1),a255mov d3,d256and 0x003ff000,d257lsr 10,d258add d2,a259mov (a2),d2 # get pte from PTD[addr 21..12]60btst _PAGE_VALID,d261beq itlb_miss_fault # jump if doesn't point to a page62# (might be a swap id)63#if ((_PAGE_ACCESSED & 0xffffff00) == 0)64bset _PAGE_ACCESSED,(0,a2)65#elif ((_PAGE_ACCESSED & 0xffff00ff) == 0)66bset +(_PAGE_ACCESSED >> 8),(1,a2)67#else68#error "_PAGE_ACCESSED value is out of range"69#endif70and ~xPTEL2_UNUSED1,d271itlb_miss_set:72mov d2,(IPTEL2) # change the TLB73#ifdef CONFIG_GDBSTUB74movm (sp),[d2,d3,a2]75#endif76rti7778itlb_miss_fault:79mov _PAGE_VALID,d2 # force address error handler to be80# invoked81bra itlb_miss_set8283.size itlb_miss, . - itlb_miss8485###############################################################################86#87# Data TLB Miss handler entry point88#89###############################################################################90.type dtlb_miss,@function91ENTRY(dtlb_miss)92#ifdef CONFIG_GDBSTUB93movm [d2,d3,a2],(sp)94#else95or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate96# register bank97nop98nop99nop100#endif101102#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)103mov (MMUCTR),d2104mov d2,(MMUCTR)105#endif106107and ~EPSW_NMID,epsw108mov (DPTEU),d3109mov (PTBR),a2110mov d3,d2111and 0xffc00000,d2112lsr 20,d2113mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22]114btst _PAGE_VALID,a2115beq dtlb_miss_fault # jump if doesn't point anywhere116117and ~(PAGE_SIZE-1),a2118mov d3,d2119and 0x003ff000,d2120lsr 10,d2121add d2,a2122mov (a2),d2 # get pte from PTD[addr 21..12]123btst _PAGE_VALID,d2124beq dtlb_miss_fault # jump if doesn't point to a page125# (might be a swap id)126#if ((_PAGE_ACCESSED & 0xffffff00) == 0)127bset _PAGE_ACCESSED,(0,a2)128#elif ((_PAGE_ACCESSED & 0xffff00ff) == 0)129bset +(_PAGE_ACCESSED >> 8),(1,a2)130#else131#error "_PAGE_ACCESSED value is out of range"132#endif133and ~xPTEL2_UNUSED1,d2134dtlb_miss_set:135mov d2,(DPTEL2) # change the TLB136#ifdef CONFIG_GDBSTUB137movm (sp),[d2,d3,a2]138#endif139rti140141dtlb_miss_fault:142mov _PAGE_VALID,d2 # force address error handler to be143# invoked144bra dtlb_miss_set145.size dtlb_miss, . - dtlb_miss146147###############################################################################148#149# Instruction TLB Address Error handler entry point150#151###############################################################################152.type itlb_aerror,@function153ENTRY(itlb_aerror)154add -4,sp155SAVE_ALL156157#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)158mov (MMUCTR),d1159mov d1,(MMUCTR)160#endif161162and ~EPSW_NMID,epsw163add -4,sp # need to pass three params164165# calculate the fault code166movhu (MMUFCR_IFC),d1167or 0x00010000,d1 # it's an instruction fetch168169# determine the page address170mov (IPTEU),d0171and PAGE_MASK,d0172mov d0,(12,sp)173174clr d0175mov d0,(IPTEL2)176177or EPSW_IE,epsw178mov fp,d0179call do_page_fault[],0 # do_page_fault(regs,code,addr180181jmp ret_from_exception182.size itlb_aerror, . - itlb_aerror183184###############################################################################185#186# Data TLB Address Error handler entry point187#188###############################################################################189.type dtlb_aerror,@function190ENTRY(dtlb_aerror)191add -4,sp192SAVE_ALL193194#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)195mov (MMUCTR),d1196mov d1,(MMUCTR)197#endif198199add -4,sp # need to pass three params200and ~EPSW_NMID,epsw201202# calculate the fault code203movhu (MMUFCR_DFC),d1204205# determine the page address206mov (DPTEU),a2207mov a2,d0208and PAGE_MASK,d0209mov d0,(12,sp)210211clr d0212mov d0,(DPTEL2)213214or EPSW_IE,epsw215mov fp,d0216call do_page_fault[],0 # do_page_fault(regs,code,addr217218jmp ret_from_exception219.size dtlb_aerror, . - dtlb_aerror220221222