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

📄 armtrap.s

📁 windows ce 3.00 嵌入式操作系统源代码
💻 S
📖 第 1 页 / 共 5 页
字号:

;       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 + -