############################################################################### # # TLB loading functions # # Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. # Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. # Modified by David Howells (dhowells@redhat.com) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public Licence # as published by the Free Software Foundation; either version # 2 of the Licence, or (at your option) any later version. # ############################################################################### #include <linux/sys.h> #include <linux/linkage.h> #include <asm/smp.h> #include <asm/intctl-regs.h> #include <asm/frame.inc> #include <asm/page.h> #include <asm/pgtable.h> ############################################################################### # # Instruction TLB Miss handler entry point # ############################################################################### .type itlb_miss,@function ENTRY(itlb_miss) #ifdef CONFIG_GDBSTUB movm [d2,d3,a2],(sp) #else or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate # register bank nop nop nop #endif #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) mov (MMUCTR),d2 mov d2,(MMUCTR) #endif and ~EPSW_NMID,epsw mov (IPTEU),d3 mov (PTBR),a2 mov d3,d2 and 0xffc00000,d2 lsr 20,d2 mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22] btst _PAGE_VALID,a2 beq itlb_miss_fault # jump if doesn't point anywhere and ~(PAGE_SIZE-1),a2 mov d3,d2 and 0x003ff000,d2 lsr 10,d2 add d2,a2 mov (a2),d2 # get pte from PTD[addr 21..12] btst _PAGE_VALID,d2 beq itlb_miss_fault # jump if doesn't point to a page # (might be a swap id) #if ((_PAGE_ACCESSED & 0xffffff00) == 0) bset _PAGE_ACCESSED,(0,a2) #elif ((_PAGE_ACCESSED & 0xffff00ff) == 0) bset +(_PAGE_ACCESSED >> 8),(1,a2) #else #error "_PAGE_ACCESSED value is out of range" #endif and ~xPTEL2_UNUSED1,d2 itlb_miss_set: mov d2,(IPTEL2) # change the TLB #ifdef CONFIG_GDBSTUB movm (sp),[d2,d3,a2] #endif rti itlb_miss_fault: mov _PAGE_VALID,d2 # force address error handler to be # invoked bra itlb_miss_set .size itlb_miss, . - itlb_miss ############################################################################### # # Data TLB Miss handler entry point # ############################################################################### .type dtlb_miss,@function ENTRY(dtlb_miss) #ifdef CONFIG_GDBSTUB movm [d2,d3,a2],(sp) #else or EPSW_nAR,epsw # switch D0-D3 & A0-A3 to the alternate # register bank nop nop nop #endif #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) mov (MMUCTR),d2 mov d2,(MMUCTR) #endif and ~EPSW_NMID,epsw mov (DPTEU),d3 mov (PTBR),a2 mov d3,d2 and 0xffc00000,d2 lsr 20,d2 mov (a2,d2),a2 # PTD *ptd = PGD[addr 31..22] btst _PAGE_VALID,a2 beq dtlb_miss_fault # jump if doesn't point anywhere and ~(PAGE_SIZE-1),a2 mov d3,d2 and 0x003ff000,d2 lsr 10,d2 add d2,a2 mov (a2),d2 # get pte from PTD[addr 21..12] btst _PAGE_VALID,d2 beq dtlb_miss_fault # jump if doesn't point to a page # (might be a swap id) #if ((_PAGE_ACCESSED & 0xffffff00) == 0) bset _PAGE_ACCESSED,(0,a2) #elif ((_PAGE_ACCESSED & 0xffff00ff) == 0) bset +(_PAGE_ACCESSED >> 8),(1,a2) #else #error "_PAGE_ACCESSED value is out of range" #endif and ~xPTEL2_UNUSED1,d2 dtlb_miss_set: mov d2,(DPTEL2) # change the TLB #ifdef CONFIG_GDBSTUB movm (sp),[d2,d3,a2] #endif rti dtlb_miss_fault: mov _PAGE_VALID,d2 # force address error handler to be # invoked bra dtlb_miss_set .size dtlb_miss, . - dtlb_miss ############################################################################### # # Instruction TLB Address Error handler entry point # ############################################################################### .type itlb_aerror,@function ENTRY(itlb_aerror) add -4,sp SAVE_ALL #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) mov (MMUCTR),d1 mov d1,(MMUCTR) #endif and ~EPSW_NMID,epsw add -4,sp # need to pass three params # calculate the fault code movhu (MMUFCR_IFC),d1 or 0x00010000,d1 # it's an instruction fetch # determine the page address mov (IPTEU),d0 and PAGE_MASK,d0 mov d0,(12,sp) clr d0 mov d0,(IPTEL2) or EPSW_IE,epsw mov fp,d0 call do_page_fault[],0 # do_page_fault(regs,code,addr jmp ret_from_exception .size itlb_aerror, . - itlb_aerror ############################################################################### # # Data TLB Address Error handler entry point # ############################################################################### .type dtlb_aerror,@function ENTRY(dtlb_aerror) add -4,sp SAVE_ALL #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR) mov (MMUCTR),d1 mov d1,(MMUCTR) #endif add -4,sp # need to pass three params and ~EPSW_NMID,epsw # calculate the fault code movhu (MMUFCR_DFC),d1 # determine the page address mov (DPTEU),a2 mov a2,d0 and PAGE_MASK,d0 mov d0,(12,sp) clr d0 mov d0,(DPTEL2) or EPSW_IE,epsw mov fp,d0 call do_page_fault[],0 # do_page_fault(regs,code,addr jmp ret_from_exception .size dtlb_aerror, . - dtlb_aerror