⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 armtrap.s

📁 WinCE5.0部分核心源码
💻 S
📖 第 1 页 / 共 5 页
字号:
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 + -