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

📄 armtrap.s

📁 WinCE5.0部分核心源码
💻 S
📖 第 1 页 / 共 5 页
字号:
        ;

        ; update TLS
        ldr     r0, =KData                      ; (r0) = ptr to KData page
        ldr     r2, [r0, #pCurThd]              ; (r2) = pCurThread
        ldr     r0, [r2, #ThTlsNonSecure]       ; (r0) = pCurThread->tlsNonSecure
        str     r0, [r2, #ThTlsPtr]             ; pCurThread->tlsPtr = pCurThread->tlsNonSecure
        ldr     r2, =KData                      ; (r0) = ptr to KData page
        str     r0, [r2, #lpvTls]               ; lpvTls = pCurThread->tlsNonSecure

        ;
        ; update SP
        mov     r0, sp                          ; (r0) = old sp (original r0 - r3 saved on stack)
        sub     sp, r1, #MAX_PSL_ARGS           ; room for arguments on the new stack

        ; copy arguments
        ldr     r1, [r0]
        ldr     r2, [r0, #4]
        str     r1, [sp]
        str     r2, [sp, #4]
        ldr     r1, [r0, #8]
        ldr     r2, [r0, #12]
        str     r1, [sp, #8]
        str     r2, [sp, #12]
        ldr     r1, [r0, #16]
        ldr     r2, [r0, #20]
        str     r1, [sp, #16]
        str     r2, [sp, #20]
        ldr     r1, [r0, #24]
        ldr     r2, [r0, #28]
        str     r1, [sp, #24]
        str     r2, [sp, #28]

        ; save callee saved registers
        ; NOTE: we're relying on the fact that we only save 8 registers
        ;       and will never trigger a DemmandCommit on the secure stack
        ;       since the apiArgs and {r0-r3} were saved on the secure stack
        ;       before and the area we need would have been committed.
        sub     r0, r0, #(CALLEE_SAVED_REGS - 16)   ; already have room for {r0 - r3}
        stmia   r0, {r4-r11}                    ; save the caller registers

CBCommon
        ; common code for perform callback
        ;       (r12) = function to call
        ;       (r3) = mode to call into

        ldr     lr, =SYSCALL_RETURN             ; return via a trap
        cmp     r3, #USER_MODE                  ; callback to user mode proc?
        ldmfd   sp!, {r0-r3}                    ;       reload function arguments
        beq     RtnToUMode                      ; return to user mode if so

        ; calling callback in kmode
        add     lr, pc, #MD_CBRtn-(.+8)
  IF Interworking :LOR: Thumbing
        bx      r12                             ; invoke function in "kernel mode"
  ELSE
        mov     pc, r12                         ; invoke function in "kernel mode"
  ENDIF

CBRtn
        ; return from CALLBACK
        ;       r0 - r3 saved on stack
        ldmfd   sp!, {r0-r3}                    ; restore r0-r3

        ; fall thru to general callback return processing
MD_CBRtn
        ; (r0) = return value
        ldr     r3, =KData                      ; (r3) = ptr to KData page
        ldr     r2, [r3, #pCurThd]              ; (r2) = pCurThread
        ldr     r1, [r2, #ThPcstkTop]           ; (r1) = pCurThread->pcstkTop
        ldr     r1, [r1, #CstkPrevSP]           ; (r1) = pCurThread->pcstkTop->dwPrevSP

        tst     r1, r1                          ; need to switch stack?
        beq     CBRtnCommon                     ; go to common code if not
        ;
        ; stack switch is needed.
        ;

        ; restore callee saved registers
        ldmia   r1, {r4-r11}
        
        ; update TLS
        ldr     r12, [r2, #ThTlsSecure]         ; (r12) = pCurThread->tlsSecure
        str     r12, [r2, #ThTlsPtr]            ; pCurThread->tlsPtr = pCurThread->tlsSecure
        str     r12, [r3, #lpvTls]              ; update global TLS

        ; update SP
        add     sp, r1, #CALLEE_SAVED_REGS

CBRtnCommon
        ;
        ; common code for callback return
        ;
        sub     sp, sp, #size_api_args          ; make room for CallbackReturn arguments
        str     r0, [sp, #apiRa]                ; save return value
        add     r0, sp, #svrrtnstr              ; r0 = ptr to SVRRTNSTRUCT
        CALL    CallbackReturn                  ; call CallbackReturn

        ; (r0) = return address 
        mov     r12, r0                         ; (r12) = return address 
        ldr     r0, [sp, #apiRa]                ; (r0) = return value
        add     sp, sp, #size_api_args          ; pop the temp stuffs

        ; continue at return address in kmode
  IF Interworking :LOR: Thumbing
        bx      r12                             ; return in "kernel mode"
  ELSE
        mov     pc, r12                         ; return in "kernel mode"
  ENDIF

        ENTRY_END PrefetchAbortEH

; Process a prefetch abort.

ProcessPrefAbort
        add     lr, lr, #0xF0000000             ; repair continuation address
        stmfd   sp!, {r0-r3, r12, lr}
  IF {FALSE}
        ldr     r0, =LED_ALPHA
10      ldr     r1, =0xC0DEAB00
        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     r0, lr                          ; (r0) = faulting address
        mfc15   r2, c13                         ; (r2) = process base address
        tst     r0, #0xFE000000                 ; slot 0 reference?
        orreq   r0, r0, r2                      ; (r0) = process slot based address
        CALL    LoadPageTable                   ; (r0) = !0 if entry loaded
        tst     r0, r0
        ldmnefd sp!, {r0-r3, r12, pc}^          ; restore regs & continue
        ldmfd   sp!, {r0-r3, r12}
        ldr     lr, =KData-4
        stmdb   lr, {r0-r3}
        ldmfd   sp!, {r0}
        str     r0, [lr]                        ; save resume address
        mov     r1, #ID_PREFETCH_ABORT          ; (r1) = exception ID
        b       CommonHandler


        LTORG

;-------------------------------------------------------------------------------
; Common fault handler code.
;
;       The fault handlers all jump to this block of code to process an exception
; which cannot be handled in the fault handler or to reschedule.
;
;       (r1) = exception ID
;       original r0-r3 & lr saved at KData-0x14.
;-------------------------------------------------------------------------------
        ALTERNATE_ENTRY CommonHandler
        mrs     r2, spsr
        msr     cpsr_c, #SVC_MODE:OR:0x80       ; switch to Supervisor mode w/IRQs disabled
        ldr     r3, =KData                      ; (r3) = ptr to KData page


; Save the processor state into a thread structure. If the previous state was
; User or System and the kernel isn't busy, then save the state into the current
; thread. Otherwise, create a temporary thread structure on the kernel stack.
;
;       (r1) = exception ID
;       (r2) = SPSR
;       (r3) = ptr to KData page
;       Interrupted r0-r3, and Pc saved at (r3-0x14)
;       In Supervisor Mode.
        ALTERNATE_ENTRY SaveAndReschedule
  IF {FALSE}
        ldrb    r0, [r3,#cNest]                 ; (r0) = kernel nest level
        subs    r0, r0, #1                      ; in a bit deeper (0 if first entry)
        strb    r0, [r3,#cNest]                 ; save new nest level
  ENDIF
        and     r0, r2, #0x1f                   ; (r0) = previous mode
        cmp     r0, #USER_MODE                  ; 'Z' set if from user mode
        cmpne   r0, #SYSTEM_MODE                ; 'Z' set if from System mode
        bne     %F50                            ; reentering kernel, save state on stack

        ldr     r0, [r3,#pCurThd]               ; (r0) = ptr to current thread
        add     r0, r0, #TcxR4                  ; (r0) = ptr to r4 save
        stmia   r0, {r4-r14}^                   ; save User bank registers
10      ldmdb   r3, {r3-r7}                     ; load saved r0-r3 & Pc
        stmdb   r0!, {r2-r6}                    ; save Psr, r0-r3
        sub     r0, r0, #THREAD_CONTEXT_OFFSET  ; (r0) = ptr to Thread struct
        str     r7, [r0,#TcxPc]                 ; save Pc
        mfc15   r2, c6                          ; (r2) = fault address
        mfc15   r3, c5                          ; (r3) = fault status

; Process an exception or reschedule request.

FirstSchedule
20      msr     cpsr_c, #SVC_MODE               ; enable interrupts
        CALL    HandleException
        ldr     r2, [r0, #TcxPsr]               ; (r2) = target status
        and     r1, r2, #0x1f                   ; (r1) = target mode
        cmp     r1, #USER_MODE
        cmpne   r1, #SYSTEM_MODE
        bne     %F30                            ; not going back to user or system mode
        add     r0, r0, #TcxR3
        ldmia   r0, {r3-r14}^                   ; reload user/system mode registers
        ldr     r1, =KData
        msr     cpsr_c, #SVC_MODE:OR:0x80       ; disable all interrupts
        ldrb    r1, [r1, #bResched]             ; (r1) = nest level + reschedule flag
        cmp     r1, #1
        mov     r1, #ID_RESCHEDULE
        beq     %B20                            ; interrupted, reschedule again
        msr     spsr, r2
        ldr     lr, [r0, #TcxPc-TcxR3]
        ldmdb   r0, {r0-r2}
        movs    pc, lr                          ; return to user or system mode

; Return to a non-preemptible privileged mode.
;
;       (r0) = ptr to THREAD structure
;       (r2) = target mode

30
  IF Interworking :LOR: Thumbing

        tst     r2, #THUMB_STATE                ; returning to Thumb code ?
        addne   r1, r0, #THREAD_CONTEXT_OFFSET  ; create pointer to context
        bne     ThumbDispatch                   ; and branch to thumb dispatch code

  ENDIF

        msr     cpsr, r2                        ; switch to target mode
        add     r0, r0, #TcxR0
        ldmia   r0, {r0-r15}                    ; reload all registers & return

; Save registers for fault from a non-preemptible state.

50      sub     sp, sp, #TcxSizeof              ; allocate space for temp. thread structure
        cmp     r0, #SVC_MODE
        bne     %F55                            ; must mode switch to save state
        add     r0, sp, #TcxR4                  ; (r0) = ptr to r4 save area
        stmia   r0, {r4-r14}                    ; save SVC state registers
        add     r4, sp, #TcxSizeof              ; (r4) = old SVC stack pointer
        str     r4, [r0, #TcxSp-TcxR4]          ; update stack pointer value
        b       %B10

55
  IF Interworking :LOR: Thumbing
        bic     r0, r2, #THUMB_STATE            ; Ensure Thumb bit is clear
        msr     cpsr, r0                        ; and switch to mode exception came from
  ELSE
        msr     cpsr, r2                        ; switch to mode exception came from
  ENDIF

        add     r0, sp, #TcxR4                  ; (r0) = ptr to r4 save area
        stmia   r0, {r4-r14}                    ; save mode's register state
        msr     cpsr_c, #SVC_MODE:OR:0x80       ; back to supervisor mode
        b       %B10                            ; go save remaining state

        LTORG


;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
        NESTED_ENTRY    DataAbortHandler
        sub     lr, lr, #8                      ; repair continuation address
        stmfd   sp!, {r0-r3, r12, lr}
        PROLOG_END

        sub     r0, lr, #INTERLOCKED_START
        cmp     r0, #INTERLOCKED_END-INTERLOCKED_START
        bllo    CheckInterlockedRestart
        mfc15   r0, c6                          ; (r0) = FAR
        mfc15   r1, c5                          ; (r1) = FSR

  IF {FALSE}
        ldr     r2, =LED_DISCRETE
        str     r1, [r2]
        ldr     r2, =LED_ALPHA
10      ldr     r3, =0xDA2AAB00
        str     r3, [r2]
        mov     r3, #SPIN_DELAY
15      subs    r3, r3, #1
        bgt     %B15
        str     lr, [r2]
        mov     r3, #SPIN_DELAY
17      subs    r3, r3, #1
        bgt     %B17
        str     r0, [r2]
        mov     r3, #SPIN_DELAY
19      subs    r3, r3, #1
        bgt     %B19
;;;     b       %B10
  ENDIF

        mfc15   r2, c13                         ; (r2) = process base address
        tst     r0, #0xFE000000                 ; slot 0 reference?
        orreq   r0, r0, r2                      ; (r0) = process slot based address
;; V6 architectures introduce a new bit, and a new reason code.
;; This code will also work with all previous architectures, so should be
;; used for all builds (so an otherwise pre-V6 image will run properly on
;; a V6 system).
;; Two comments:
;; - bit 10 of the FSR is part of the reason code in V6, so the code would ideally
;;   check that it is zero. BUT the value of bit 10 in older architectures is defined
;;   as UNPREDICTABLE, so it is possible that some implementations will set this. We will
;;   call LoadPageTable for 3 possible new reason codes: none of these are defined in the
;;   V6 architecture specification (but could conceivably be used in implementation-specific
;;   extensions). It is preferable to call LoadPageTable and then generate an abort on extra
;;   (and very unlikely) reason codes, rather than not call LoadPageTable on old implementations
;;   that spuriously set bit 10.
;; - Because the memory is paged in with 1st-level page table entries, any page translation aborts
;;   will never cause memory to be mapped in, so only two reason codes actually need to be checked
;;   below.

        and     r3, r1, #0xF                    ; type of data abort
        cmp     r3, #0x4                        ; Instruction cache maintenance fault?
        cmpne   r3, #0x5                        ; Section translation error?
        cmpne   r3, #0x7                        ; Page translation error?

;; Reach here with EQ set if we should try to page in the FAR address
;; Reach here with NE set if we should just signal a fault.

        movne   r0, #0
        CALLEQ  LoadPageTable                   ; (r0) = !0 if entry loaded
        tst     r0, r0
        ldmnefd sp!, {r0-r3, r12, pc}^          ; restore regs & continue
        ldr     lr, =KData-4
        ldmfd   sp!, {r0-r3, r12}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -