acrn-kernel/arch/mn10300/mm/tlb-mn10300.S

208 lines
4.7 KiB
ArmAsm

###############################################################################
#
# 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)
and ~EPSW_NMID,epsw
#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
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)
bset _PAGE_ACCESSED,(0,a2)
and ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2
itlb_miss_set:
mov d2,(IPTEL) # 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)
and ~EPSW_NMID,epsw
#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
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)
bset _PAGE_ACCESSED,(0,a2)
and ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2
dtlb_miss_set:
mov d2,(DPTEL) # 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)
and ~EPSW_NMID,epsw
add -4,sp
SAVE_ALL
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),a2
mov a2,d0
and PAGE_MASK,d0
mov d0,(12,sp)
clr d0
mov d0,(IPTEL)
and ~EPSW_NMID,epsw
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)
and ~EPSW_NMID,epsw
add -4,sp
mov d1,(sp)
movhu (MMUFCR_DFC),d1 # is it the initial valid write
# to this page?
and MMUFCR_xFC_INITWR,d1
beq dtlb_pagefault # jump if not
mov (DPTEL),d1 # set the dirty bit
# (don't replace with BSET!)
or _PAGE_DIRTY,d1
mov d1,(DPTEL)
mov (sp),d1
add 4,sp
rti
ALIGN
dtlb_pagefault:
mov (sp),d1
SAVE_ALL
add -4,sp # need to pass three params
# 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,(DPTEL)
and ~EPSW_NMID,epsw
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