📄 armtrap.s
字号:
; Setup 2nd level page table to map the high memory area which contains the
; first level page table, 2nd level page tables, kernel data page, etc.
add r4, r10, #HighPT-PTs ; (r4) = ptr to high page table
orr r0, r10, #0x051 ; (r0) = PTE for 64K, kr/w kr/w r/o r/o page, uncached unbuffered
str r0, [r4, #0xD0*4] ; store the entry into 8 consecutive slots
str r0, [r4, #0xD1*4]
str r0, [r4, #0xD2*4]
str r0, [r4, #0xD3*4]
str r0, [r4, #0xD4*4]
str r0, [r4, #0xD5*4]
str r0, [r4, #0xD6*4]
str r0, [r4, #0xD7*4]
add r8, r10, #Vectors-PTs ; (r8) = ptr to vector page
bl OEMARMCacheMode ; places C and B bit values in r0 as set by OEM
mov r2, r0
and r2, r2, #0x0000000C ; zero out all bits except for the valid C and B positions.
orr r0, r8, #0x002 ; construct the PTE
orr r0, r0, r2
str r0, [r4, #0xF0*4] ; store entry for exception vectors
orr r0, r0, #0x500 ; (r0) = PTE for 4k r/o r/o kr/w kr/w C+B page
str r0, [r4, #0xF4*4] ; store entry for abort stack
str r0, [r4, #0xF6*4] ; store entry for FIQ stack (access permissions overlap for abort and FIQ stacks, same 1k)
orr r0, r8, #0x042
orr r0, r0, r2 ; (r0)= PTE for 4K r/o kr/w r/o r/o (C+B as set by OEM)
str r0, [r4, #0xF2*4] ; store entry for interrupt stack
add r9, r10, #KPage-PTs ; (r9) = ptr to kdata page
orr r0, r9, #0x002
orr r0, r0, r2 ; (r0)=PTE for 4K (C+B as set by OEM)
orr r0, r0, #0x250 ; (r0) = set perms kr/w kr/w kr/w+ur/o r/o
str r0, [r4, #0xFC*4] ; store entry for kernel data page
orr r0, r4, #0x001 ; (r0) = 1st level PTE for high memory section
add r1, r10, #0x4000
str r0, [r1, #-4] ; store PTE in last slot of 1st level table
IF {FALSE}
mov r0, r4
mov r1, #256 ; dump 256 words
CALL WriteHex
ENDIF
; Fill in first level page table entries to create "un-mapped" regions
; from the contents of the MemoryMap array.
;
; (r9) = ptr to KData page
; (r10) = ptr to 1st level page table
; (r11) = ptr to MemoryMap array
add r10, r10, #0x2000 ; (r10) = ptr to 1st PTE for "unmapped space"
mov r0, #0x02
orr r0, r0, r2 ; (r0)=PTE for 0: 1MB (C+B as set by OEM)
orr r0, r0, #0x400 ; set kernel r/w permission
20 mov r1, r11 ; (r1) = ptr to MemoryMap array
25 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?
beq %F29
ldr r5, =0x1FF00000
and r2, r2, r5 ; VA needs 512MB, 1MB aligned.
ldr r5, =0xFFF00000
and r3, r3, r5 ; PA needs 4GB, 1MB aligned.
add r2, r10, r2, LSR #18
add r0, r0, r3 ; (r0) = PTE for next physical page
28 str r0, [r2], #4
add r0, r0, #0x00100000 ; (r0) = PTE for next physical page
sub r4, r4, #1 ; Decrement number of MB left
cmp r4, #0
bne %B28 ; Map next MB
bic r0, r0, #0xF0000000 ; Clear Section Base Address Field
bic r0, r0, #0x0FF00000 ; Clear Section Base Address Field
b %B25 ; Get next element
29
tst r0, #8
bic r0, r0, #0x0C ; clear cachable & bufferable bits in PTE
add r10, r10, #0x0800 ; (r10) = ptr to 1st PTE for "unmapped uncached space"
bne %B20 ; go setup PTEs for uncached space
sub r10, r10, #0x3000 ; (r10) = restore address of 1st level page table
IF {FALSE}
mov r0, r10
mov r1, #4096 ; dump 4096 words
CALL WriteHex
ENDIF
; Setup the vector area.
;
; (r8) = ptr to exception vectors
add r7, pc, #VectorInstructions - (.+8)
ldmia r7!, {r0-r3} ; load 4 instructions
stmia r8!, {r0-r3} ; store the 4 vector instructions
ldmia r7!, {r0-r3} ; load 4 instructions
stmia r8!, {r0-r3} ; store the 4 vector instructions
IF {FALSE}
sub r0, r8, #8*4
mov r1, #8 ; dump 8 words
CALL WriteHex
ENDIF
add r8, r8, #0x3E0-(8*4)
ldmia r7!, {r0-r3}
stmia r8!, {r0-r3}
ldmia r7!, {r0-r3}
stmia r8!, {r0-r3}
IF {FALSE}
sub r0, r8, #8*4
mov r1, #8 ; dump 8 words
CALL WriteHex
ENDIF
; The page tables and exception vectors are setup. Initialize the MMU and turn it on.
mov r1, #1
mtc15 r1, c3 ; setup access to domain 0
mtc15 r10, c2
bl TLBClear
mfc15 r1, c1
orr r1, r1, #0x007F ; changed to read-mod-write for ARM920 Enable: MMU, Align, DCache, WriteBuffer
orr r1, r1, #0x3200 ; vector adjust, ICache, ROM protection
ldr r0, VirtualStart
cmp r0, #0 ; make sure no stall on "mov pc,r0" below
mtc15 r1, c1 ; enable the MMU & Caches
mov pc, r0 ; & jump to new virtual address
nop
; MMU & caches now enabled.
;
; (r10) = physcial address of 1st level page table
VStart ldr sp, =KStack
add r4, sp, #KData-KStack ; (r4) = ptr to KDataStruct
mov r0, #0x80000000
str r0, [r4, #hBase] ; set HandleBase
ldr r0, =DirectRet
str r0, [r4, #pAPIReturn] ; set DirectReturn address
add r1, r10, #0x4000 ; (r1) = physical addr of 2nd page table pool
orr r1, r1, #1 ; (r1) = page table descriptor for pool entries
str r1, [r4, #ptDesc] ; save for LoadPageTable()
; Initialize stacks for each mode.
msr cpsr_c, #ABORT_MODE:OR:0xC0 ; switch to Abort Mode w/IRQs disabled
add sp, r4, #AbortStack-KData
mov r1, sp
msr cpsr_c, #IRQ_MODE:OR:0xC0 ; switch to IRQ Mode w/IRQs disabled
add sp, r4, #IntStack-KData
mov r2, sp
msr cpsr_c, #FIQ_MODE:OR:0xC0 ; switch to FIQ Mode w/IRQs disabled
add sp, r4, #FIQStack-KData
msr cpsr_c, #UNDEF_MODE:OR:0xC0 ; switch to Undefined Mode w/IRQs disabled
mov sp, r4 ; (sp_undef) = &KData
mov r3, sp
msr cpsr_c, #SVC_MODE:OR:0xC0 ; switch to Supervisor Mode w/IRQs disabled
mfc15 r0, c0 ; (r0) = processor ID
CALL ARMInit
msr cpsr_c, #SVC_MODE ; switch to Supervisor Mode w/IRQs enabled
CALL KernelInit ; initialize scheduler, etc.
mov r0, #0 ; no current thread
mov r1, #ID_RESCHEDULE
b FirstSchedule
VirtualStart DCD VStart
VectorInstructions
BREAKPOINT ; reset
ldr pc, [pc, #0x3E0-8] ; undefined instruction
ldr pc, [pc, #0x3E0-8] ; SVC
ldr pc, [pc, #0x3E0-8] ; Prefetch abort
ldr pc, [pc, #0x3E0-8] ; data abort
BREAKPOINT ; unused vector location
ldr pc, [pc, #0x3E0-8] ; IRQ
ldr pc, [pc, #0x3E0-8] ; FIQ
VectorTable
DCD -1
DCD UndefException
DCD SWIHandler
DCD PrefetchAbort
IF ARM920_HACK = 1
DCD DataAbortHandler
ELSE
IF _TGTCPU = "ARM720"
DCD OEMDataAbortHandler
ELSE
DCD DataAbortHandler
ENDIF
ENDIF
DCD -1 ; unused vector
DCD IRQHandler
DCD FIQHandler
LTORG
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
NESTED_ENTRY UndefException
IF Interworking :LOR: Thumbing
stmdb sp, {r0-r3, lr}
mrs r0, spsr
tst r0, #THUMB_STATE ; Entered from Thumb Mode ?
subne lr, lr, #2 ; Update return address
subeq lr, lr, #4 ; accordingly
str lr, [sp, #-4] ; update lr on stack
ELSE
sub lr, lr, #4 ; (lr) = address of undefined instruction
stmdb sp, {r0-r3, lr}
ENDIF
PROLOG_END
IF {FALSE}
ldr r0, =LED_ALPHA
10 ldr r1, =0x0DEF
str r1, [r0]
mov r1, #SPIN_DELAY
15 subs r1, r1, #1
bgt %B15
str lr, [r0]
mov r1, #SPIN_DELAY
17 subs r1, r1, #1
bgt %B17
ENDIF
mov r1, #ID_UNDEF_INSTR
b CommonHandler
ENTRY_END UndefException
LEAF_ENTRY SWIHandler
IF {FALSE}
ldr r0, =LED_ALPHA
10 ldr r1, =0x99999999
str r1, [r0]
mov r1, #SPIN_DELAY
15 subs r1, r1, #1
bgt %B15
str lr, [r0]
mov r1, #SPIN_DELAY
17 subs r1, r1, #1
bgt %B17
b %B10
ENDIF
movs pc, lr
ENTRY_END SWIHandler
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
NESTED_ENTRY FIQHandler
sub lr, lr, #4 ; fix return address
stmfd sp!, {r0-r3, r12, lr}
PROLOG_END
CALL OEMInterruptHandlerFIQ
ldmfd sp!, {r0-r3, r12, pc}^ ; restore regs & return for NOP
ENTRY_END FIQHandler
LTORG
;-------------------------------------------------------------------------------
;++
; The following code is never executed. Its purpose is to support unwinding
; through the calls to API dispatch and return routines.
;--
;-------------------------------------------------------------------------------
NESTED_ENTRY PrefetchAbortEH
stmfd sp!, {r0-r3}
sub sp, sp, #8
PROLOG_END
ALTERNATE_ENTRY PrefetchAbort
sub lr, lr, #0xF0000004
cmp lr, #0x00010400
bhs ProcessPrefAbort
mrs r12, spsr
and r12, r12, #0x0ff
orr r12, r12, lr, LSL #8 ; (r12) = old mode + 24 lower bits of LR.
msr cpsr_c, #SYSTEM_MODE ; switch to System Mode
; Find the address of the API function to dispatch to by:
; ObjectCall(int *pMode, RETADDR ra, void *args, long iMethod)
;
; (r0-r3) = function parameters or return values
; (r12) = abort address - 0xF0000000 (bits 31-8) (encodes API set & method index)
; combined with the previous mode (bits 7-0)
stmfd sp!, {r0-r3} ; save function parameters onto the stack
and r0, r12, #0x1f ; (r0) = previous mode (User/Kernel)
stmfd sp!, {r0, r9} ; pass mode & static base to ObjectCall
mov r0, sp ; (r0) = ptr to mode & extra info
mov r3, #FIRST_METHOD - 0xF0000000
rsb r3, r3, r12, LSR #8
mov r3, r3, ASR #2 ; (r3) = iMethod
cmp r3, #-1
beq SysRet ; system call return
add r2, sp, #8 ; (r2) = ptr to function args
mov r1, lr ; (r1) = return address
CALL ObjectCall
mov r12, r0 ; (r12) = API function address
ldr r0, [sp] ; (r0) = target mode
add sp, sp, #8 ; restore stack (ignore extra field)
cmp r0, #USER_MODE
ldmfd sp!, {r0-r3} ; reload function paramters
addne lr, pc, #DirectRet-(.+8)
IF Interworking :LOR: Thumbing
bxne r12
ELSE
movne pc, r12 ; invoke function in "kernel mode"
ENDIF
ldr lr, =SYSCALL_RETURN ; special return address for API calls
msr cpsr_c, #SVC_MODE:OR:0xC0 ; switch to Supervisor Mode w/IRQs disabled
tst r12, #0x01 ; continuing in Thumb mode ??
msrne spsr_c, #USER_MODE | THUMB_STATE ; Set Thumb mode bit
msreq spsr_c, #USER_MODE ; else continuing in ARM mode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -