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

📄 serlasm.s

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 S
📖 第 1 页 / 共 2 页
字号:
        TTL     Angel serialiser support                 > serlasm.s        ;        ; This file provides veneers used by the serialiser module, as        ; well as some globaly needed functions.        ;        ; $Revision: 1.13.4.1 $        ;   $Author: rivimey $        ;     $Date: 1997/12/10 18:50:16 $        ;        ; Copyright Advanced RISC Machines Limited, 1995.        ; All Rights Reserved        ;        KEEP        GET     listopts.s           ; standard listing control        GET     lolevel.s            ; automatically built manifest definitions        GET     macros.s             ; standard assembler support        GET     target.s             ; target specific manifests        EXPORT  Angel_EnterSVC        EXPORT  Angel_ExitToUSR        EXPORT  Angel_DisableInterruptsFromSVC        EXPORT  Angel_EnableInterruptsFromSVC        EXPORT  Angel_RestoreInterruptsFromSVC        EXPORT  angel_ReadBankedRegs        AREA    |serlasm|,CODE,PIC,READONLY        ; See serlock.h for the interface to these functions.        IMPORT  Angel_StackBase        IMPORT  angel_SVCEntryFlag                IMPORT  __rt_asm_fatalerror  ; error reporting via suppasm.s        Angel_EnterSVC        ; a1-a4 and ip may be corrupted under the APCS        MRS     a1, CPSR        AND     a2, a1, #ModeMask        CMP     a2, #USRmode        BEQ     WasUSRMode        CMP     a2, #SVCmodeInappropriateModeError        BEQ     WasSVCMode        ADR     a1, imdmsg        B       __rt_asm_fatalerrorimdmsg        DCB     "Inappropriate Mode\n"        ALIGN        WasSVCMode      ; Just disable IRQ and FIQ and note SVC entry from SVC        MOV     a2, #1        LDR     a3, =angel_SVCEntryFlag        STR     a2, [a3]        ORR     a1, a1, #IRQDisable + FIQDisable        MSR     CPSR_cxsf, a1        MOV     pc, lr                WasUSRMode        ; The SWI does everthing for us - except note that entry was from USR        MOV     a2, #0        LDR     a3, =angel_SVCEntryFlag        STR     a2, [a3]        LDR     a1, =angel_SWIreason_EnterSVC        DCD     angel_SWI_ARM   ; Get into SVC with IRQ and FIQ disabled        MOV     pc, lr          ; Return to caller                ; On entry we check to see whether angel_SVCEntryFlag is        ; 0 => Entry to SVC was from USR mode        ; 1 => Entry to SVC was from SVC mode        ; and return in that modeAngel_ExitToUSR        ; a1-a4 and ip may be corrupted under the APCS        LDR     a3, =angel_SVCEntryFlag        LDR     a2, [a3]        CMP     a2, #0        BNE     ReturnInSVCMode        ; The standard return to USR case follows ...        MOV     a2, lr        MOV     a3, sp        LDR     sp, =Angel_StackBase   ; Reset SVC sp to the empty SVC stack        LDR     sp, [sp]        ADD     sp, sp, #Angel_SVCStackOffset        STMFD   a3, {a3}        SUB     a3, a3, #4        LDMFD   a3, {sp}^        MRS     a1 ,CPSR          BIC     a1, a1, #ModeMask + IRQDisable + FIQDisable        ORR     a1, a1, #USRmode        MSR     CPSR_cxsf, a1        MOV     pc, a2ReturnInSVCMode        MRS     a1, CPSR        BIC     a1, a1, #IRQDisable + FIQDisable        MSR     CPSR_cxsf, a1        MOV     pc, lr                        ; On entry a1 = address of the regblock, a2 = the mode        ; We must be called in USR mode - by debugos.c most likely.angel_ReadBankedRegs        CMP     a2, #USRmode        BNE     PrivModeCase        STR     r13, [a1, #Angel_RegBlock_R0offset + (13*4)]        STR     r14, [a1, #Angel_RegBlock_R0offset + (14*4)]        MOV     pc, lrPrivModeCase    ; Write r8-r14 + spsr (in case it was FIQ mode        MOV     a4, a1        LDR     a1, =angel_SWIreason_EnterSVC        DCD     angel_SWI_ARM   ; Get into SVC with IRQ and FIQ disabled        MSR     CPSR_cxsf, a2        ADD     a3, a4, #Angel_RegBlock_R0offset + (8*4)        STMIA   a3, {r8-r14}        MRS     a3, SPSR        STR     a3,  [a4, #Angel_RegBlock_SPSRoffset]        MOV     a2, #USRmode        MSR     CPSR_cxsf, a2        NOP        MOV     pc, lr        Angel_DisableInterruptsFromSVC        MRS     a1, CPSR        IF (FIQ_SAFETYLEVEL >= FIQ_NeverUsesSerialiser_DoesNotReschedule)          ORR   a2, a1, #IRQDisable        ELSE          ORR   a2, a1, #IRQDisable + FIQDisable        ENDIF        MSR     CPSR_cxsf, a2        MOV     pc, lrAngel_EnableInterruptsFromSVC        MRS     a1, CPSR        BIC     a2, a1, #IRQDisable + FIQDisable        MSR     CPSR_cxsf, a2        MOV     pc, lrAngel_RestoreInterruptsFromSVC        MSR     CPSR_cxsf, a1        MOV     pc, lr                ; ****************************************************************        IF :DEF: MINIMAL_ANGEL :LAND: MINIMAL_ANGEL<>0          ; Don't need all the serialiser-specific stuff        ELSE                IMPORT  Angel_MutexSharedTempRegBlocks        IMPORT  angel_SerialiseTaskCore        EXPORT  Angel_SerialiseTask                ; For the interface details of this pseudo function refer to        ; serlock.h.  For the details of the actual function        ; angel_SerialiseTaskCore see serlock.cAngel_SerialiseTask        ; r0 (a1) = called_by_yield        ; r1 (a2) = fn        ; r2 (a3) = state        ; r3 (a4) = empty_stack                ; Flatten the stack of whatever mode we were called in        MOV  sp, r3        ; Get into SVC and disable IRQ and FIQ        IF :DEF: ASSERT_ENABLED :LAND: ASSERT_ENABLED <> 0          ; Check we are not in USR mode          MRS  r4, CPSR          AND  r4, r4, #ModeMask          CMP  r4, #USRmode          BNE  NotUsrMode                  ADR  a1, serlusrmsg          B    __rt_asm_fatalerrorserlusrmsg          DCB  "Serialise in USR mode\n"          ALIGNNotUsrMode        ENDIF        IF (FIQ_SAFETYLEVEL >= \            FIQ_NeverUsesSerialiser_DoesNotReschedule_HasNoBreakpoints)          MOV r4, #SVCmode + IRQDisable        ELSE          MOV r4, #SVCmode + IRQDisable + FIQDisable        ENDIF        MSR  cpsr_cxsf, r4        ; Set up desired_regblock (pc and r0 only at this point)        LDR  r4, =Angel_MutexSharedTempRegBlocks        ADD  r4, r4, #Angel_RegBlockSize        STR  r1, [r4, #Angel_RegBlock_R0offset + (15*4)]        STR  r2, [r4, #Angel_RegBlock_R0offset]        MOV  r1, r4  ; This is 2nd arg to angel_SerialiseTaskCore        ; Note that at this point the SVC stack may be in any of the        ; following states:        ;  * Empty Angel_SVCStack - if no task of WantsLock priority        ;    is running, and the application is not using the SVC stack        ;  * Non empty Angel_SVCStack - if a task with WantsLock priority        ;    is running (this will call of serialise task will be due        ;    to another packet arriving).        ;  * Application SVC stack        ;        ; However, using the Application SVC stack is not acceptable        ; since it may not be large enough, or indeed r13 may have been        ; corrupted.  Therefore we must spot sp outside the range        ; Angel_SVCStack - Angel_SVCStackLimit and if that is the case        ; the it must be the Application stack in use, so switch to        ; the Angel_SVCStack (which is empty in this case).                LDR  r4, =Angel_StackBase        LDR  r4, [r4]        ADD  sl, r4, #Angel_SVCStackLimitOffset        ADD  r4, r4, #Angel_SVCStackOffset        CMP  sp, sl        BCC  StackNotSetUp      ; sp < Angel_SVCStackLimit        CMP  sp, r4        BLS  StackIsSetUp       ; sp <= Angel_SVCStackStackNotSetUp        MOV  sp, r4     StackIsSetUp                ; Call angel_SerialiseTaskCore and set up lr to "return" to        ; angel_NextTask.        LDR  lr, =angel_NextTask        LDR  r4, =angel_SerialiseTaskCore        MOV  pc, r4        ; ****************************************************************        EXPORT angel_StartTask        EXPORT angel_StartTask_NonSVCEntry        ; For the interface details of this pseudo function refer to        ; serlock.c        ;        ; What makes this all tricky is that we must completely finish with        ; regblock before making any mode switch as the modes switch may        ; enable interrupts, which can potentially corrupt regblock!angel_StartTask        ; r0 (a1) = regblock        ; This code resumes, restoring all regs from the regblock        ; It works for all modes (!!!) (inc FIQ, and SVC, SYS and USR)

⌨️ 快捷键说明

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