📄 armtrap.s
字号:
103
ldr r0, [r1, #4] ; (r0) = OEMAddressTable[i].paddr
mov r0, r0, LSR #BANK_SHIFT ; (r0) >>= 20
add r0, r12, r0, LSL #BANK_SHIFT ; (r0) = VA + (r0 << 20)
sub r0, r0, r3 ; (r0) -= OEMAddressTable[i].vaddr
mov pc, lr ; return
ENTRY_END
;-------------------------------------------------------------------------------
; VaFromPa: Figure out Virtual Address of a Physical Address
;
; (r0) = PA
; (r1) = ptr to OEMAddressTable
;
; On return
; (r0) = VA
;
; Register used:
; r0 - r3, r12
;
;-------------------------------------------------------------------------------
LEAF_ENTRY VaFromPa
mov r12, r0 ; (r12) = PA
mov r0, #0 ; (r0) = 0 (initialize return value to an invalid VA)
201
ldr r3, [r1, #8] ; (r3) = OEMAddressTable[i].size
ldr r2, [r1, #4] ; (r2) = OEMAddressTable[i].paddr
cmp r3, #0 ; EndOfTable?
moveq pc, lr ; PA not found if end of table
cmp r12, r2 ; Is (PA >= OEMAddressTable[i].paddr)?
blt %F202 ; go to next entry if not
add r2, r2, r3, LSL #BANK_SHIFT ; (r2) = OEMAddressTable[i].vaddr + region size
cmp r12, r2 ; Is (PA < OEMAddressTable[i].vaddr + region size)?
blt %F203 ; Found if it's true
202
add r1, r1, #12 ; i ++ (move to next entry)
b %B201 ; test next entry
203
; found the entry
; (r1) = &OEMAddressTable[i]
ldr r0, [r1] ; (r0) = OEMAddressTable[i].vaddr
ldr r3, [r1, #4] ; (r3) = OEMAddressTable[i].paddr
mov r0, r0, LSR #BANK_SHIFT ; (r0) >>= 20
add r0, r12, r0, LSL #BANK_SHIFT ; (r0) = PA + (r0 << 20)
sub r0, r0, r3 ; (r0) -= OEMAddressTable[i].paddr
mov pc, lr ; return
ENTRY_END
;-------------------------------------------------------------------------------
; 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)
; figure out the virtual address of OEMAddressTable
mov r1, r11 ; (r1) = &MemoryMap (2nd argument to VaFromPa)
bl VaFromPa
mov r6, r0 ; (r6) = VA of MemoryMap
; convert base of PTs to Physical address
ldr r4, =PTs ; (r4) = virtual address of FirstPT
mov r0, r4 ; (r0) = virtual address of FirstPT
mov r1, r11 ; (r1) = &MemoryMap (2nd argument to PaFromVa)
bl PaFromVa
mov r10, r0 ; (r10) = ptr to FirstPT (physical)
; 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
; 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]
add r8, r10, #ExceptionVectors-PTs ; (r8) = ptr to vector page
bl OEMARMCacheMode ; places C and B bit values in r0 as set by OEM
mov r2, r0
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 r7, #2 ; (r7) = pass counter
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
bic r0, r0, #0x0C ; clear cachable & bufferable bits in PTE
add r10, r10, #0x0800 ; (r10) = ptr to 1st PTE for "unmapped uncached space"
subs r7, r7, #1 ; decrement pass counter
bne %B20 ; go setup PTEs for uncached space if we're not done
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
; Set up page table entry for PSL calls to turn the pre-fetch abort into a permission fault rather
; than a translation fault. This speeds up the time to execute a PSL call, as this entry can be
; cached in the TLB
;
; (r10) = ptr to first level page table
add r0, r10, #0x3C00 ; Page table entry for 0xF0000000 -> 0xF0100000
mov r1, #PTL1_SECTION + PTL1_XN ; Level 1 Section, with Cachable/bufferable, access
; bits and phys address set to zero
;; Because the CP15 R1 R bit is set, there are no unreadable settings via the AP permission bits.
orr r1, r1, #0x1E0 ; Set Domain to 15 (to cause domain access fault)
; Domain access is set up below..
str r1, [r0] ; Store the level 1 PTE
; 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
; convert VectorTable to Physical Address
ldr r0, =VectorTable ; (r0) = VA of VectorTable
mov r1, r11 ; (r1) = &OEMAddressTable[0]
bl PaFromVa
mov r7, r0 ; (r7) = PA of VectorTable
add r8, r8, #0x3E0-(8*4) ; (r8) = target location of the vector table
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 and clear other
; domains including 15 for PSL calls (see above)
mtc15 r10, c2
mov r0, #0
mcr p15, 0, r0, c8, c7, 0 ; Flush the I&D TLBs
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
; Initialize stacks for each mode.
mov r1, #ABORT_MODE:OR:0xC0
msr cpsr_c, r1 ; switch to Abort Mode w/IRQs disabled
add sp, r4, #AbortStack-KData
mov r1, sp
mov r2, #IRQ_MODE:OR:0xC0
msr cpsr_c, r2 ; switch to IRQ Mode w/IRQs disabled
add sp, r4, #IntStack-KData
mov r2, sp
mov r3, #FIQ_MODE:OR:0xC0
msr cpsr_c, r3 ; switch to FIQ Mode w/IRQs disabled
add sp, r4, #FIQStack-KData
mov r3, #UNDEF_MODE:OR:0xC0
msr cpsr_c, r3 ; switch to Undefined Mode w/IRQs disabled
mov sp, r4 ; (sp_undef) = &KData
mov r3, sp
mov r0, #SVC_MODE:OR:0xC0
msr cpsr_c, r0 ; switch to Supervisor Mode w/IRQs disabled
mfc15 r0, c0 ; (r0) = processor ID
stmfd sp!, {r6} ; 5th argument: &OEMAddressTable
CALL ARMInit
ldmfd sp!, {r6}
mov r1, #SVC_MODE
msr cpsr_c, r1 ; 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
ldr pc, [pc, #0x3E0-8] ; 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
ldr pc, [pc, #0x3E0-8] ; unused vector location
ldr pc, [pc, #0x3E0-8] ; IRQ
ldr pc, [pc, #0x3E0-8] ; FIQ
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -