📄 armtrap.s
字号:
TTL ARM Interrupt and Exception Processing
;-------------------------------------------------------------------------------
;++
;
; Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved.
;
; 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
;;; 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
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
; Def(1) to allow ARM to test 920 kernel as 720. Undef(0) for real life.
ARM920_HACK EQU 0
; High memory layout:
; FFFD0000 - first level page table (uncached) (2nd half is r/o)
; FFFD4000 - second level page tables (uncached)
; 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
PageTables # 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
KDataArea
PTs % 0x4000 ; space for first-level page table
% 0x4000 ; space for 2nd-level page tables
Vectors % 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 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
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
ENDIF
AREA |.data|, DATA
TEXTAREA
IMPORT ObjectCall
IMPORT ServerCallReturn
IMPORT LoadPageTable
IMPORT HandleException
IMPORT NextThread
IMPORT ExceptionDispatch
IMPORT OEMInterruptHandler
IMPORT OEMInterruptHandlerFIQ
IMPORT ARMInit
IMPORT KernelInit
IMPORT idleconv
IMPORT TLBClear
IMPORT OEMARMCacheMode
IF CELOG
IMPORT CeLogInterrupt
IMPORT CELOG_ThreadMigrateARM
ENDIF
IF ARM920_HACK <> 1
IF _TGTCPU = "ARM720"
IMPORT OEMDataAbortHandler
ENDIF
ENDIF
IF {FALSE}
IMPORT WhereAmI
IMPORT WriteHex
IMPORT WriteByte
IMPORT PutHex
ENDIF
;-------------------------------------------------------------------------------
; KernelStart - kernel main entry point
;
; The OEM layer will setup any platform or CPU specific configuration that is
; required for the kernel to have access to ROM and DRAM and jump here to start up
; the system. Any processor specific cache or MMU initialization should be completed.
; The MMU and caches should not enabled.
;
; This routine will initialize the first-level page table based up the contents of
; the MemoryMap array and enable the MMU and caches.
;
; NOTE: Until the MMU is enabled, kernel symbolic addresses are not valid and must be
; translated via the MemoryMap array to find the correct physical address.
;
; Entry (r0) = pointer to MemoryMap array in physical memory
; Exit returns if MemoryMap is invalid
;-------------------------------------------------------------------------------
LEAF_ENTRY KernelStart
mov r11, r0 ; (r11) = &MemoryMap (save pointer)
ldr r9, =PTs ; (r9) = "virtual address" of 1st level table
ldr r7, =0x1FF00000 ; VA needs 512MB, 1MB aligned.
ldr r8, =0xFFF00000 ; PA needs 4GB, 1MB aligned.
and r6, r9, r7 ; (r6) = KDATA Virtual Address (1MB)
mov r1, r11 ; (r1) = ptr to MemoryMap array
5 ldr r2, [r1], #4 ; (r2) = virtual address to map Bank at
ldr r3, [r1], #4 ; (r3) = physical address to map from
ldr r4, [r1], #4 ; (r4) = num MB to map
cmp r4, #0 ; End of table?
moveq pc, lr ; RETURN!!!! INVALID MEMORY MAP. NO MAPPING FOR KDATA AREA!
and r2, r2, r7 ; VA needs 512MB, 1MB aligned.
and r3, r3, r8 ; PA needs 4GB, 1MB aligned.
;
; For each MB in this table entry, compare with KDATA Virtal Address...
;
8
cmp r2, r6 ; KDATA VA = Section VA?
beq %F9 ; Found it!!! (r3) is the PA
add r2, r2, #0x00100000 ; (r2) = VA + 1MB
add r3, r3, #0x00100000 ; (r3) = PA + 1MB
sub r4, r4, #1 ; Decrement number of MB left
cmp r4, #0
bne %B8 ; Map next MB
b %B5 ; Get next element
9
mov r4, r9
mov r1, r3
; Found MemoryMap entry for .KDATA section which contains the kernel data page,
; the first-level page table, exception vector page, etc.
;
; (r1) = base address of bank
; (r4) = virtual address of FirstPT
; (r11) = ptr to MemoryMap array
15 mov r10, #BANK_SIZE
sub r10, r10, #1 ; (r10) = mask for offset
and r10, r10, r4 ; (r10) = offset into bank for FirstPT
orr r10, r10, r1 ; (r10) = ptr to FirstPT
; Zero out page tables & kernel data page
mov r0, #0 ; (r0-r3) = 0's to store
mov r1, #0
mov r2, #0
mov r3, #0
mov r4, r10 ; (r4) = first address to clear
add r5, r10, #KDEnd-PTs ; (r5) = last address + 1
18 stmia r4!, {r0-r3}
stmia r4!, {r0-r3}
cmp r4, r5
blo %B18
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -