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

📄 except.s

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 S
📖 第 1 页 / 共 3 页
字号:
NotAngelOSAbort              IF DEBUG <> 0  ; or PORTING        IMPORT  Angel_IsApplicationBlocked        IMPORT  |Image$$RO$$Base|   ; start of code area        IMPORT  |Image$$RO$$Limit|  ; end of code area        	;	If appl blocked, this can't be an appl abort...	STMIA 	sp!, {r0-r3,r12,lr}	BL	Angel_IsApplicationBlocked	CMP	r0, #0	LDMIA 	sp!, {r0-r3,r12,lr}	BNE	AbtInAngelCode        LDR     r1, =|Image$$RO$$Base|        CMP     lr, r1        BLO     AbtNotAngelCode                LDR     r1, =|Image$$RO$$Limit|        CMP     lr, r1        BHI     AbtNotAngelCodeAbtInAngelCode        ; A data or prefetch abort in Angel ... oops!        ; Note: the test code above misses out a check for the        ; relocating code in the ROM etc.                MOV     a2, lr          ; parameter for msg        FatalError "Abort encountered in Angel code at pc=%p.\n"        AbtNotAngelCode        ; For a data abort, we need to subtract 8 to get back to the address        ; at which the aborted instruction was loaded; we have already subtracted        ; 4 in EXCEPTENTRY_PART1; now do the other 4.        LDR     r2, =ADP_Stopped_DataAbort        CMP     r2, r6        SUBEQ   r14, r14, #4                ; r0 already has the regblock pointer -- load r2 with the        ; reason code from r6 and report back to the debugger.        MOV     r2, r6        B       CallSerialiseTask      ENDIF     ; not Minimal Angel      ENDIF                ; ****************************************************************        ;        ; void HandlerUndef()        ;        ; -------------------------------------------        ;         ; Vector handler function for the Undefined instruction vector.        ; When compiled into EmbeddedICE (ICEMAN) the exception simply means        ; that the code is broken; hence we just ignore it!        ;         ; Angel uses undefined instructions to implement breakpoints for the        ; debugger, as well as the possibility that the user has inserted their        ; own undefines which are to be trapped by the debugger. So the handler        ; must check which instruction code caused the exception. The only        ; difference here, however, is which of the ADP_Stopped reason codes        ; is used to report this event to the debugger.        ;         ; The code to check the breakpoint is complicated slightly by the        ; requirement to check for both Thumb and ARM breakpoints, although        ; the entry and exit actions are the same in both cases.        ;         ; The helper function CallSerialiseTask is used to call the serialiser        ; with appropriate args to report the exception.         ;         ; If the exception was caused by a breakpoint instruction, the debugger        ; should rewrite it with the correct instruction before returning here        ; to continue execution.        ;         ; Entry:        r14 = <address of undef>+4        ;               r13 = empty_undef_stack        ;               cpsr_mode = UNDmode        ;         ; Exit:         <via Serialiser, does not return directly>        ;         ; -------------------------------------------        HandlerUndef      IF MINIMAL_ANGEL<>0          ;; we're not supposed to be handling this, so don't        SUBS    pc, lr, #4              ELSE        EXCEPTENTRY UNDmode, Angel_GlobalRegBlock + (RB_UNDEF * Angel_RegBlockSize)                ; The value of r14 has been decremented by 4, i.e. referring to the        ; undefined instruction. r0 points at (the start of) the regblock        ; referred to in the entry macro.        ; We have to check that the undefined instruction we hit        ; was indeed the Angel Undefined instruction        ;        ; Clearly this uses different code for Thumb and ARM states        ; but make the Thumb support code removable        ;        ; Note that r14_und has been adjusted to point to the undef        ; (ARM and Thumb).              IF DEBUG <> 0        STMFD   sp!, {r0-r3,lr}        MOV     r1, #0        MOV     r2, #DL_UndefSave        BL      Angel_DebugLog        LDMFD   sp!, {r0-r3,lr}      ENDIF      IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0        MRS     r0, SPSR                ; read CPSR of mode we were in...        TST     r0, #Tbit        BEQ     CompareWithARMBreakPoint                 LDRH    r0, [r14]               ; load the Thumb instruction        MOV     r1, #angel_BreakPointInstruction_THUMB :AND: 0xff00        ORR     r1, r1, #angel_BreakPointInstruction_THUMB :AND: 0xff        CMP     r0, r1        BNE     UnrecognisedInstruction        B       BreakPointInstruction      ENDIFCompareWithARMBreakPoint        LDR     r0, [r14]        ; load the ARM instruction        LDR     r1, =angel_BreakPointInstruction_ARM        CMP     r0, r1        BNE     UnrecognisedInstruction                ; We now know it is Angel's Undefined instruction        ; r0 = r1 = The undefined instruction        ; lr = address of the undefined instruction        ; spsr = unchanged        ; sp  = FD UND stack (currently empty)BreakPointInstruction        ; This is executed for both an ARM and Thumb breakpoint        LDR     r0, =Angel_GlobalRegBlock + (RB_UNDEF * Angel_RegBlockSize)        LDR     r2, =ADP_Stopped_BreakPoint        B       CallSerialiseTaskUnrecognisedInstruction        LDR     r0, =Angel_GlobalRegBlock + (RB_UNDEF * Angel_RegBlockSize)        LDR     r2, =ADP_Stopped_UndefinedInstr                B       CallSerialiseTask      ENDIF ; End of MINIMAL ANGEL        ; *************************************************************        ;        ; void HandlerSWI()        ;        ; -------------------------------------------        ;         ;         ;         ; in: SVC mode; IRQs disabled; FIQs undefined        ;     r13 = FD stack        ;     r14 = address of SWI instruction + 4        ;     All other registers must be preserved        ;        ; -------------------------------------------                IMPORT  angelOS_SemiHostingEnabled                EXPORT  HandlerSWIHandlerSWI        STMFD   sp!, {r0, r1}                ; Disable interrupts. The FIQ handler 'knows' that SWI has problems        ; here and will return as soon as it realizes a FIQ has been taken        ; around here.        EnsureFIQDisabled cpsr, r0                ; We have to check that the SWI we hit was indeed the Angel SWI        ;        ; This initial code is designed to be interrupt-safe, although we        ; don't re-enable IRQ (which would be disabled on entry to the SWI        ; automatically).      IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0                MRS     r1, SPSR        TST     r1, #Tbit        BEQ     CompareWithARMSWI1        LDRH    r1, [r14, #-2]          ; load the Thumb instruction        BIC     r1, r1, #0xff00        CMP     r1, #angel_SWI_THUMB        BNE     ComplexSWI        B       CheckSimpleSWI              ENDIF                             ; THUMB_SUPPORTCompareWithARMSWI1        LDR     r1, [r14, #-4]          ; load the ARM instruction        LDR     r0, =angel_SWI_ARM      ; load SWI number (+ SWI instr. code)        BIC     r1, r1, #0xFF000000     ; condition & instr. code, which shouldn't be compared.        EORS    r0, r0, r1              ; If the values are the same, we'll end up with zero        BNE     ComplexSWI        ; ... fall through to 'simple' SWI case                ;;         ; is this Angel SWI a "Simple" one -- that is, it doesn't call the        ; scheduler and is fast.CheckSimpleSWI        LDR     r0, [sp]                ; load original value of r0 from stack        CMP     r0, #angel_SWIreason_EnterSVC        BNE     NotEnterSVC             ; check for other simple SWI's.DoSWIEnterSVC        ; Handle the EnterSVC SWI. See "ARM SDT Reference Manual" $8.3 for what        ; docs exist on this.        ; Basically:     enter with r0 == angel_SWIreason_EnterSVC        ;                           mode == USR mode        ;                           sp == Angel/Appl USR stack        ;        ;                exit with  r0   <= address of a routine to return to        ;                                   USR mode        ;                           mode <= SVC mode with IRQ, FIQ disabled        ;                           sp_svc <= sp_usr        ;         ; The SDT Reference Manual guarantees that r1 - r3 are preserved by        ; Angel when an Angel system call is made, so other regs can be used.        ;         ; -----        ; Angel additionally allows one level of nesting, so that if        ; entered in SVC mode, the return routine will return in SVC mode.        ;        ; As written this code will allow entry in any privileged mode, and        ; return in SVC mode as stated above.        ;        ; However, the return routine (Angel_ExitToUSR) will not return to        ; the previous mode, but to SVC mode instead, with the wrong stack.                MRS     r1, SPSR                ; mode we came from        ; Accessing other modes depends on the mode        AND     r1, r1, #ModeMaskUFIS        CMP     r1, #USRmode :AND: ModeMaskUFIS        CMPNE   r1, #SYSmode :AND: ModeMaskUFIS        BNE     EnterSVCfromPriv        ; Now either we came from USR or SYS mode.        ; Write USR or SYS sp on the entry stack over saved r0.        ; Original SVC SP IS LOST!        STMIA   sp, {sp}^              IF HANDLE_INTERRUPTS_ON_FIQ = 0        ; Not handling interrupts on FIQ, so we didn't disable FIQ        ; at the start of the handler. Do so now, so we return with        ; both interrupt sources disabled.        MRS     r0, cpsr        ORR     r0, r0, #FIQDisable        MSR     cpsr_cf, r0      ENDIF        ; jump to exit code to load r0 with it's correct value.        B       ReturnFromEnterSVC        EnterSVCfromPriv        ; we have called the EnterSVC SWI in a privileged mode.        ;   r0 is the angel_SWIreason_EnterSVC code number,        ;   r1 is the masked mode we came from        ; neither values are needed any more.                MRS     r1, cpsr        ; need a copy of SVC CPSR        MRS     r0, spsr        ; get CPSR we came from ...              IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0        ; If we came from thumb state, don't (try to) return there just        ; yet!        BIC     r0, r0, #Tbit      ENDIF                ; In any mode, don't return to 26 bit mode (0x10), and don't        ; enable interrupts just yet.        ORR     r0, r0, #InterruptMask + 0x10                MSR     cpsr_cf, r0        ; switch to the mode we came from                AND     r0, r0, #ModeMaskUFIS        ; NOTE: If the spsr was _already_ SVCmode, the value we save has        ; to be adjusted for data put on the stack by the SWI!        CMP     r0, #SVCmode :AND: ModeMaskUFIS        MOV     r0, sp          ; take a copy of this mode's SP        ADDEQ   r0, r0, #8              IF HANDLE_INTERRUPTS_ON_FIQ = 0        ; Not handling interrupts on FIQ, so we didn't disable FIQ        ; at the start of the handler. Do so now, so we return with        ; both interrupt sources disabled.        ORR     r1, r1, #FIQDisable      ENDIF                MSR     cpsr_cf, r1        ; switch back to SVC mode        STMIA   sp, {r0}        ; Store out the USR or SYS stack pointer                ; now in SVC mode with sp_svc <= sp_<other mode>        ; fall through to exit code to return to the caller in this state.ReturnFromEnterSVC        ; Set the stack back to that at the beginning of the SWI.        LDMFD   sp!, {r0, r1}        MOV     sp, r0          ; put other mode's SP in here.        MRS     r0, spsr        ; We need to find out if the system was in                                ; Thumb state in its original operation                ; We could be returning to a Thumb code segment so we must use the        ; correct return method for Thumb ie BX rn        [ :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0        TST     r0, #Tbit        BNE     SVCThumb        ]                        ; Set r0 to the address of Angel_ExitToUser        LDR     r0, =Angel_ExitToUSR        ; Resume in SVC mode with interrupts disabled.        MOV     pc, lr                [ :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0SVCThumb        ; Set r0 to the address of Angel_ExitToUser        LDR     r0, =Angel_ExitToUSR                ; Push r0 and the lr (for the return) on to the stack        STMFD   sp!, {r0, lr}        ; Set bit 0 to 1 for the change to Thumb State        ADR     r0, SVCRettoThumb+1        BX      r0        CODE16SVCRettoThumb                ; And do the return BX - now in SVC mode retaining the stack info        POP {r0, pc}        ALIGN        CODE32        ]        NotEnterSVC        CMP     r0, #angel_SWIreason_SysElapsed        CMPNE   r0, #angel_SWIreason_SysTickFreq        BNE     NotSimpleSWI        ; Reason code: SYS_TICKFREQ:        ;     Purpose: Returns the number of elapsed target 'ticks' since the        ;              support code started executing.  Ticks are defined by        ;              SYS_TICKFREQ.  (If the target cannot define the length of        ;              a tick, it may still supply SYS_ELAPSED.)        ; Reason code: SYS_TICKFREQ        ;     Purpose: Define a tick frequency.  (The natural implementation is        ;              to have a software model specify one core cycle as one tick,        ;              and for Angel to return Timer1 ticks)        ; Both these are recognised but not implemented by Angel. Return -1        ; to indicate failure.        LogInfo "except.s", 756, LOG_EXCEPT, "Sys Elapsed/Tickfreq\n"

⌨️ 快捷键说明

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