📄 armtrap.s
字号:
;
; Copyright (c) Microsoft Corporation. All rights reserved.
;
;
; This source code is licensed under Microsoft Shared Source License
; Version 1.0 for Windows CE.
; For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
;
TTL ARM Interrupt and Exception Processing
;-------------------------------------------------------------------------------
;++
;
;
; Module Name:
;
; armtrap.s
;
; Abstract:
;
; This module implements the code necessary to field and process ARM
; interrupt and exception conditions.
;
; WARNING: This module executes in KSEG0 and, in general, cannot
; tolerate a TLB Miss. Registers k0 and k1 are used during initial
; interrupt and exception processing, and therefore, extreme care must
; be exercised when modifying this module.
;
; Environment:
;
; Kernel mode only.
;
;--
;-------------------------------------------------------------------------------
OPT 2 ; disable listing
INCLUDE ksarm.h
OPT 1 ; reenable listing
PTL1_SECTION EQU 2 ; top-level entry maps a 1MB section directly
PTL1_XN EQU 0 ; No execution control on pre-V6
PERFORMCALLBACK EQU -113
RAISEEXCEPTION EQU -114
KERN_TRUST_FULL EQU 2
; must match the value in kernel.h
SECURESTK_RESERVE EQU 48 ; (SIZE_PRETLS + 16)
MAX_PSL_ARGS EQU 56 ;
CALLEE_SAVED_REGS EQU 32 ; (r4-r11)
; must match the value defined in pkfuncs.h
CACHE_SYNC_FLUSH_TLB EQU 0x18
;;; P2 h/w defines
IF {TRUE}
HKEEP_FPGA_REGS_BASE EQU 0xA4000000 ; housekeeping FPGA reg base
LED_ALPHA EQU HKEEP_FPGA_REGS_BASE+0x00060000
LED_DISCRETE EQU HKEEP_FPGA_REGS_BASE+0x00040000
SPIN_DELAY EQU 0x40000
ENDIF
BANK_SIZE EQU 0x00100000 ; 1MB per bank in MemoryMap table
BANK_SHIFT EQU 20
; must match the value in celog.h
CELOGSTATUS_ENABLED_GENERAL EQU 0x20000000
MACRO
BREAKPOINT
DCD 0xE6000010 ; special undefined instruction
MEND
; Resister save frame for Code Aborts, Data Aborts and IRQs.
FrameR0 EQU 0
FrameR1 EQU 4
FrameR2 EQU 8
FrameR3 EQU 12
FrameR12 EQU 16
FrameLR EQU 20
; High memory layout:
; FFFD0000 - first level page table (uncached)
; FFFD4000 - not used
; FFFE0000 - disabled for protection
; FFFF0000 - exception vectors
; FFFF03E0 - exception vector jump table
; FFFF0400 - not used (r/o)
; FFFF1000 - disabled for protection
; FFFF2000 - r/o (physical overlaps with vectors)
; FFFF2400 - Interrupt stack (1k)
; FFFF2800 - r/o (physical overlaps with Abort stack)
; FFFF3000 - disabled for protection
; FFFF4000 - r/o (physical memory overlaps with vectors & intr. stack & FIQ stack)
; FFFF4900 - Abort stack (2k - 256 bytes)
; FFFF5000 - disabled for protection
; FFFF6000 - r/o (physical memory overlaps with vectors & intr. stack)
; FFFF6800 - FIQ stack (256 bytes)
; FFFF6900 - r/o (physical memory overlaps with Abort stack)
; FFFF7000 - disabled
; FFFFC000 - kernel stack
; FFFFC800 - KDataStruct
; FFFFCC00 - r/o for protection (2nd level page table for 0xFFF00000)
^ 0xFFFD0000
FirstPT # 0x4000
# 0x4000
# 0x8000
# 0x10000 ; not mapped
ExVector # 0x1000
# 0x1400 ; not mapped
# 0x0400 ; 1K interrupt stack
IntStack # 0x2000 ; not mapped (ffff2800)
# 0x0100 ; not mapped (FIQ stack) (ffff4800)
# 0x0700 ; 2K-256 abort stack (ffff4900)
AbortStack # 0x1800 ; not mapped (ffff5000)
# 0x0100 ; not mapped (FIQ stack) (ffff6800)
FIQStack # 0xC000-0x6900 ; not mapped (ffff6900)
KDBase # 0x07E0 ; 2K-32 kernel stack
KStack # 0x0020 ; temporary register save area
KData # 0x400 ; kernel data area
;-----------------------------------------------------------------------
; .KDATA area is used to reserve physical memory for the above structures.
AREA |.KDATA|,DATA,NOINIT
EXPORT ExceptionVectors
KDataArea
PTs % 0x4000 ; space for first-level page table
ExceptionVectors
% 0x0400 ; space for exception vectors
% 0x0400 ; space for interrupt stack
% 0x0100 ; space for FIQ stack
% 0x0700 ; space for Abort stack
KPage % 0x0c00 ; space for kernel stack & KDataStruct
HighPT % 0x0400 ; space for 2nd level page table to map 0xFFF00000
KDEnd % 0
MACRO
mtc15 $cpureg, $cp15reg
mcr p15,0,$cpureg,$cp15reg,c0,0
MEND
MACRO
mfc15 $cpureg, $cp15reg
mrc p15,0,$cpureg,$cp15reg,c0,0
MEND
MACRO
WRITELED $val
IF {FALSE}
stmfd sp!, {r0-r1}
ldr r0, =LED_ALPHA
ldr r1, $val
str r1, [r0]
ldmfd sp!, {r0-r1}
ENDIF
MEND
MACRO
WRITELED_REG $reg
IF {FALSE}
stmfd sp!, {r0}
ldr r0, =LED_ALPHA
str $reg, [r0]
ldmfd sp!, {r0}
ENDIF
MEND
IF Interworking :LOR: Thumbing
MACRO
CALL $Fn
ldr r12, =$Fn
mov lr, pc
bx r12
MEND
MACRO
CALLEQ $Fn
ldreq r12, =$Fn
moveq lr, pc
bxeq r12
MEND
MACRO
RETURN
bx lr
MEND
MACRO
RETURN_EQ
bxeq lr
MEND
MACRO
RETURN_NE
bxne lr
MEND
MACRO
RETURN_LT
bxlt lr
MEND
ELSE
MACRO
CALL $Fn
bl $Fn
MEND
MACRO
CALLEQ $Fn
bleq $Fn
MEND
MACRO
RETURN
mov pc, lr
MEND
MACRO
RETURN_EQ
moveq pc, lr
MEND
MACRO
RETURN_NE
movne pc, lr
MEND
MACRO
RETURN_LT
movlt pc, lr
MEND
ENDIF
;-----------------------------------------------------------------------
; Globals
AREA |.data|, DATA
;-----------------------------------------------------------------------
; Code (Read-only TEXT section)
TEXTAREA
IMPORT ObjectCall
IMPORT ServerCallReturn
IMPORT PerformCallBackExt
IMPORT CallbackReturn
IMPORT NKSection
IMPORT LoadPageTable
IMPORT HandleException
IMPORT NextThread
IMPORT ExceptionDispatch
IMPORT OEMInterruptHandler
IMPORT OEMInterruptHandlerFIQ
IMPORT ARMInit
IMPORT KernelInit
IMPORT idleconv
IMPORT OEMCacheRangeFlush
IMPORT OEMARMCacheMode
IMPORT VectorTable
IMPORT pfnOEMIntrOccurs
EXPORT MD_CBRtn
IF NKPROF
IMPORT CeLogInterrupt
ENDIF
IMPORT CeLogThreadMigrate
IF {FALSE}
IMPORT WhereAmI
IMPORT WriteHex
IMPORT WriteByte
IMPORT PutHex
ENDIF
;-------------------------------------------------------------------------------
; PaFromVa: Figure out Physical Address of a Virtual Address
;
; (r0) = VA
; (r1) = ptr to OEMAddressTable
;
; On return
; (r0) = PA
;
; Register used:
; r0 - r3, r12
;
;-------------------------------------------------------------------------------
LEAF_ENTRY PaFromVa
mov r12, r0 ; (r12) = VA
mov r0, #-1 ; (r0) = -1 (initialize return value to an invalid PA)
101
ldr r3, [r1] ; (r3) = OEMAddressTable[i].vaddr
mov r2, r3, LSR #BANK_SHIFT ; make 1MB aligned
mov r3, r2, LSL #BANK_SHIFT
cmp r3, #0 ; EndOfTable?
moveq pc, lr ; INVALID OEMAddressTable, VA not found
cmp r12, r3 ; Is (VA >= OEMAddressTable[i].vaddr)?
blt %F102 ; go to next entry if not
ldr r2, [r1, #8] ; (r2) = size in MB
add r2, r3, r2, LSL #BANK_SHIFT ; (r2) = OEMAddressTable[i].vaddr + region size
cmp r12, r2 ; Is (VA < OEMAddressTable[i].vaddr + region size)?
blt %F103 ; Found if it's true
102
add r1, r1, #12 ; i ++ (move to next entry)
b %B101 ; test next entry
; found the entry
; (r1) = &OEMAddressTable[i]
; (r3) = OEMAddressTable[i].vaddr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -