Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

375 lines
11 KiB
ArmAsm

# @(#)63 1.4 src/bos/kernel/ml/POWER/tlb_flih.s, sysml, bos41J, 9522A_all 5/30/95 18:12:49
#******************************************************************************
#******************************************************************************
#
# COMPONENT_NAME: (SYSML) machine language routines
#
# FUNCTIONS: tlb_flih
#
# ORIGINS: 27
#
# IBM CONFIDENTIAL -- (IBM Confidential Restricted when
# combined with the aggregated modules for this product)
# SOURCE MATERIALS
# (C) COPYRIGHT International Business Machines Corp. 1994
# All Rights Reserved
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
#******************************************************************************
ifdef(`_POWER_603',`
.file "tlb_flih.s"
.machine "any"
.set IDCMP_Hbit, 0x040
.set PTE_Rbit, 0x100
.set PTE_Cbit, 0x080
.set PTE_Gbit, 0x008
#******************************************************************************
#
# (1) These three flihs can only use GPR r0, r1, r2, and r3 while TGPR bit
# in msr is set.
#
# (2) It is necessary to set R bit in PTE for I-fetch tlb miss and
# D-read tlb miss, and set both R bit and C bit in PTE for D-write tlb miss
# and C = 0 exception to keep PTE in sync with TLB
#
# (3) Each of these flihs must fit in 256 bytes.
#
#******************************************************************************
#******************************************************************************
#
# NAME: tlb_flih_ifm
#
# FUNCTION: This is 603 specific interrupt handler for tlb miss on
# instruction fetch.
# This code is overlaid at 0x1000 during system initialization
#
# Execution Environment: interrupts disabled, I/D translation off
#
# On entry, the SPR registers setting is the same as that for ISI except that
# (a) CRF0 is saved in SRR1,
# (b) TGPR in msr is set,
# (c) IMISS register contains the effective address that causes the fault,
# HASH1 and HASH2 registers contain the physical addresses at which the
# primary and secondary PTEGs (respectively) reside, and
# ICMP register contains the first word in the PTE for which the table
# search is looking (H bit is 0)
#
# CRF0 needs to be restored and TGPR in msr needs to be reset before exiting
# from this routine.
#
# Note that PPC architecture forbits I-fetch from guarded storage.
# But 603 processor does not check G bit during I-fetch.
# It depends on this handler to check against I-fetching from guarded
# stoarge. The logic in this handler will also prevent the existence of
# G=1 I-tlb entries.
#******************************************************************************
DATA(tlb_flih_ifm):
mfspr r2,HASH1 # r2 = address of the first entry of primary PTEG
mfctr r0 # r0 = saved ctr
mfspr r3,ICMP # r3 = search target
ifm_grp:
lil r1,0x8
addi r2,r2,-8 # subtract by 8
mtctr r1 # set ctr to 8
ifm_next:
lwzu r1,8(r2) # read first word of the entry
cmp cr0,r1,r3
beq ifm_found
bdnz+ ifm_next
andi. r1,r3,IDCMP_Hbit # test H bit
mfspr r2,HASH2 # r2 = address of the first entry of 2nd PTEG
bne- cr0,ifm_not_found
# go for the secondary PTEG
ori r3,r3,IDCMP_Hbit # set H bit
b ifm_grp # search 2nd PTEG
ifm_found:
lwz r1,4(r2) # target found, read the second word of the entry
mtctr r0 # restore ctr
andi. r3,r1,PTE_Gbit
bne- ifm_Gbit
mfspr r3,SRR1
ori r1,r1,PTE_Rbit # set R bit
mfspr r0,IMISS
mtcrf 0x80,r3 # restore cr0
mtspr RPA,r1
tlbli r0 # load instruction tlb entry selected by r0 and
# srr1(w) with ICMP and RPA
stw r1,4(r2) # set R bit in PTE
# It is NOT necessary to clear bit 0 of SRR1 first.
# Bit 0 of msr in 603 is reserved and dont care.
DATA(tlb_nop1): # 603e 1.4 workaround sync patched at si
.globl DATA(tlb_nop1)
sync
rfi
ifm_not_found:
cau r1,0,SRR_IS_PFT>16 # set bit 1 to indicate PTE miss
mtctr r0 # restore ctr
ifm_goto_ISI:
# reconstruct MSR and SRR1 before branching to is_flih
# On entry, SRR0 contains the EA of the next instruction to be executed
mfspr r3,SRR1
andi. r2,r3,0xffff # r2 = old msr
mfmsr r0
or r2,r2,r1
andi. r0,r0,0xffff # clear TGPR bit (14)
mtspr SRR1,r2
mtcrf 0x80,r3 # restore cr0
mtmsr r0
isync # can not use r4-r31 until TGPR bit is clear
# is_prolog_ppc
mtspr SPRG1, r15 # save the value of r15
mfspr r15, SPRG0 # get ppda pointer
ba DATA(is_flih) # branch to flih
.extern DATA(is_flih)
ifm_Gbit:
# set bit 3 to indicate I fetch from Guarded page
cau r1,0,SRR_IS_GUARD>16
b ifm_goto_ISI
#******************************************************************************
#
# NAME: tlb_flih_drm
#
# FUNCTION: This is 603 specific interrupt handler for tlb miss on
# data read.
# This code is overlaid at 0x1100 during system initialization
#
# Execution Environment: interrupts disabled, I/D translation off
#
# On entry, the SPR registers setting is the same as that for DSI except that
# (a) CRF0 is saved in SRR1,
# (b) TGPR in msr is set,
# (c) DMISS register contains the effective address that causes the fault,
# DAR dees not contain the effective address that causes the fault,
# HASH1 and HASH2 registers contain the physical addresses at which the
# primary and secondary PTEGs (respectively) reside, and
# DCMP register contains the first word in the PTE for which the table
# search is looking (H bit is 0).
#
# CRF0 needs to be restored and TGPR in msr needs to be reset before exiting
# from this routine.
#******************************************************************************
DATA(tlb_flih_drm):
mfspr r2,HASH1 # r2 = address of the first entry of primary PTEG
mfctr r0 # r0 = saved ctr
mfspr r3,DCMP # r3 = search target
drm_grp:
lil r1,0x8
addi r2,r2,-8 # subtract by 8
mtctr r1 # set ctr to 8
drm_next:
lwzu r1,8(r2) # read first word of the entry
cmp cr0,r1,r3
beq drm_found
bdnz+ drm_next
andi. r1,r3,IDCMP_Hbit # test H bit
mfspr r2,HASH2 # r2 = address of the first entry of 2nd PTEG
bne- cr0,drm_goto_DSI
# go for the secondary PTEG
ori r3,r3,IDCMP_Hbit # set H bit
b drm_grp # search 2nd PTEG
drm_found:
lwz r1,4(r2) # target found, read the second word of the entry
mtctr r0 # restore ctr
mfspr r3,SRR1
ori r1,r1,PTE_Rbit # set R bit
mfspr r0,DMISS
mtcrf 0x80,r3 # restore cr0
mtspr RPA,r1
tlbld r0 # load data tlb entry selected by r0 and srr1(w)
# with DCMP and RPA
stw r1,4(r2) # set R bit in PTE
DATA(tlb_nop2): # 603e 1.4 workaround sync patched at si
.globl DATA(tlb_nop2) # time
sync
rfi
drm_goto_DSI:
# reconstruct SRR1, DSISR, DAR, and MSR
# On entry, SRR0 contains the EA of the instruction that causes the
# interrupt.
mtctr r0 # restore ctr
mfspr r3,SRR1
mfspr r0,DMISS
andi. r2,r3,0xffff # extract old msr
mtspr DAR,r0 # save DMISS in DAR
cau r1,0,DSISR_PFT>16
mfmsr r0
mtspr SRR1,r2 # and save it in SRR1
andi. r0,r0,0xffff
mtspr DSISR,r1 # set bit 1 of DSISR
mtcrf 0x80,r3 # restore cr0
mtmsr r0 # clear bit 0 - 15 of msr, esp TGPR bit (14)
isync
# ds_prolog_ppc
mtspr SPRG1, r15 # save the value of r15
mfspr r15, SPRG0 # get ppda pointer
ba DATA(ds_flih) # branch to flih
.extern DATA(ds_flih)
#******************************************************************************
#
# NAME: tlb_flih_dwm
#
# FUNCTION: This is 603 specific interrupt handler for tlb miss or C = 0
# exception on data write.
# This code is overlaid at 0x1200 during system initialization
#
# Execution Environment: interrupts disabled, I/D translation off
#
# On entry, the SPR registers setting is the same as that for DSI except that
# (a) CRF0 is saved in SRR1,
# (b) TGPR in msr is set,
# (c) DMISS register contains the effective address that causes the fault,
# DAR does not contain the effective address that causes the fault,
# HASH1 and HASH2 registers contain the physical addresses at which the
# primary and secondary PTEGs (respectively) reside, and
# DCMP register contains the first word in the PTE for which the table
# search is looking (H bit is 0).
#
# CRF0 needs to be restored and TGPR in msr needs to be reset before exiting
# from this routine.
#******************************************************************************
DATA(tlb_flih_dwm):
mfspr r2,HASH1 # r2 = address of the first entry of primary PTEG
mfctr r0 # r0 = saved ctr
mfspr r3,DCMP # r3 = search target
dwm_grp:
lil r1,0x8
addi r2,r2,-8 # subtract by 8
mtctr r1 # set ctr to 8
dwm_next:
lwzu r1,8(r2) # read first word of the entry
cmp cr0,r1,r3
beq dwm_found
bdnz+ dwm_next
andi. r1,r3,IDCMP_Hbit # test H bit
mfspr r2,HASH2 # r2 = address of the first entry of 2nd PTEG
bne- cr0,dwm_not_found
# go for the secondary PTEG
ori r3,r3,IDCMP_Hbit # set H bit
b dwm_grp # search 2nd PTEG
# The following logic will prevent the setting of C bit in PTE
# in case protection is violated.
dwm_found:
lwz r1,4(r2) # target found, read the second word of the entry
mtctr r0 # restore ctr
rlinm. r3,r1,0,PTE_Cbit # check C bit
mfspr r0,DMISS
beq- cr0,dwm_C0 # branch if C bit == 0
dwm_chkok:
mfspr r3,SRR1
ori r1,r1,(PTE_Rbit|PTE_Cbit) # set R bit and C bit
mtcrf 0x80,r3 # restore cr0
mtspr RPA,r1
# It is NOT necessary to execute "tlbie" to synchronize instruction tlb
# with data tlb (C bit may be different).
# C bit in instruction tlb is dont care.
tlbld r0 # load data tlb entry selected by r0 and srr1(w)
# with DCMP and RPA
stw r1,4(r2) # set R bit and C bit in PTE
DATA(tlb_nop3): # 603e 1.4 workaround sync patched at si
.globl DATA(tlb_nop3) # time
sync
rfi
dwm_C0:
# C bit == 0
rlinm. r3,r1,0,30,30 # check for PP == 1x
beq- cr0,dwm_chk0
# PP == 1x
rlinm. r3,r1,0,31,31 # check for PP == 10
beq+ cr0,dwm_chkok # branch if PP == 10
# PP == 11
cau r1,0,(DSISR_PROT|DSISR_ST)>16
b dwm_goto_DSI
dwm_chk0:
# PP == 00 or 01
mfspr r3,SRR1
andi. r3,r3,MSR_PR # test if user mode
mfsrin r3,r0 # r3 = SR of faulting eaddr
bne- dwm_user
rlinm. r3,r3,0,1,1 # check for Ks bit
beq+ dwm_chkok # branch if Ks bit == 0
cau r1,0,(DSISR_PROT|DSISR_ST)>16
b dwm_goto_DSI
dwm_user:
rlinm. r3,r3,0,2,2 # check for Kp bit
beq+ dwm_chkok # branch if Kp bit == 0
cau r1,0,(DSISR_PROT|DSISR_ST)>16
b dwm_goto_DSI
dwm_not_found:
mtctr r0 # restore ctr
cau r1,0,(DSISR_PFT|DSISR_ST)>16
mfspr r0,DMISS
dwm_goto_DSI:
# reconstruct SRR1, DSISR, DAR, and MSR
# On entry, SRR0 contains the EA of the instruction that causes the
# interrupt.
mtspr DAR,r0 # save DMISS in DAR
mfspr r3,SRR1
andi. r2,r3,0xffff # extract old msr
mfmsr r0
mtspr SRR1,r2 # and save it in SRR1
andi. r0,r0,0xffff
mtspr DSISR,r1
mtcrf 0x80,r3 # restore cr0
mtmsr r0 # clear bit 0 - 15 of msr, esp TGPR bit (14)
isync
# ds_prolog_ppc
mtspr SPRG1, r15 # save the value of r15
mfspr r15, SPRG0 # get ppda pointer
ba DATA(ds_flih) # branch to flih
.extern DATA(ds_flih)
.globl DATA(tlb_flih_ifm)
.globl DATA(tlb_flih_drm)
.globl DATA(tlb_flih_dwm)
include(scrs.m4)
include(machine.m4)
',)