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

📄 serlasm.s

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 S
📖 第 1 页 / 共 3 页
字号:
        TTL     Angel serialiser support                 > serlasm.s        ;        ; This file provides veneers used by the serialiser module, as        ; well as some globaly needed functions.        ;        ; $Revision: 1.4 $        ;   $Author: mwelsh $        ;     $Date: 1999/06/25 15:25:29 $        ;        ; 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        GET     taskmacs.s           ; task manipulation macros                ; See serlock.h for the interface to these functions.        IMPORT  Angel_StackBase        IMPORT  angel_WaitCore        IMPORT  Angel_GlobalRegBlock        IMPORT  angel_SerialiseTaskCore      IF DEBUG > 0        IMPORT  angel_DebugTaskArea        IMPORT  angel_DebugStartTaskCount        IMPORT  angel_DebugQueueTaskCount      ENDIF                IMPORT  __rt_asm_fatalerror  ; error reporting via suppasm.s                IMPORT  angel_TQ_Pool                ; ---------------------------------------------------------------------        ; CONTEXTTABLE        ; ------------        ;        ; CONTEXTTABLE        ;        ; 16 byte lookup table used by the exception restore code to        ; get the offset for the correct r13 for the mode being entered.        ;	IF :DEF: ADS_BUILD :LAND: ADS_BUILD = 1        	AREA    |Serlasm$$RO$$Data|,READONLY	ELSE	        AREA    |Serlasm$$RO$$Data|,PIC,READONLY	ENDIF        ALIGN         IF MINIMAL_ANGEL = 0        EXPORT  ContextLookuptableContextLookuptable        ; r13 offsets by mode        DCB     RegOffsR13usr        DCB     RegOffsR13fiq        DCB     RegOffsR13irq        DCB     RegOffsR13svc        DCB     0, 0, 0        DCB     RegOffsR13abt        DCB     0, 0, 0        DCB     RegOffsR13und        DCB     0, 0, 0        DCB     RegOffsR13usr   ; sys mode        ; r14 offsets by mode        DCB     RegOffsR14usr        DCB     RegOffsR14fiq        DCB     RegOffsR14irq        DCB     RegOffsR14svc        DCB     0, 0, 0        DCB     RegOffsR14abt        DCB     0, 0, 0        DCB     RegOffsR14und        DCB     0, 0, 0        DCB     RegOffsR14usr   ; sys mode        ; SPSR offsets by mode        DCB     RegOffsCPSR     ; no USR SPSR, access CPSR instead        DCB     RegOffsSPSRfiq        DCB     RegOffsSPSRirq        DCB     RegOffsSPSRsvc        DCB     0, 0, 0        DCB     RegOffsSPSRabt        DCB     0, 0, 0        DCB     RegOffsSPSRund        DCB     0, 0, 0        DCB     RegOffsCPSR     ; no SYS SPSR, access CPSR instead              ENDIF        EXPORT  R13ContextLookuptableR13ContextLookuptable        R13LookupTable          ; from taskmacs.s        ALIGN   	IF :DEF: ADS_BUILD :LAND: ADS_BUILD = 1	        AREA    |Serlasm$$RW$$Data|,READWRITE	ELSE        	AREA    |Serlasm$$RW$$Data|,PIC,READWRITE	ENDIF        ; This is used to store the entry mode for EnterSVC, which        ; is then used to restore the correct interrupt / mode when        ; ExitToUSR is called.angel_SVCEntryMode      % 4		IF :DEF: ADS_BUILD :LAND: ADS_BUILD = 1	        AREA    |Serlasm$$Code|,CODE,READONLY	ELSE        	AREA    |Serlasm$$Code|,CODE,PIC,READONLY	ENDIF        ; ****************************************************************        ;        ; (*fn)(void) Angel_EnterSVC(void)        ;        ; -------------------------------------------        ;        ; On Entry:        ;    <CPSR Mode is either USR or SVC>        ;        ; On Exit:        ;    <CPSR Mode is SVC, IRQ and FIQ flags set>        ;    r0 <= address of Angel_ExitToUSR()        ;    r1, r2 trashed (as allowed by APCS)        ;    lr preserved        ;    IF entry mode == USR        ;       sp_svc <= sp_usr        ;    ENDIF        ;    angel_SVCEntryFlag <= (CPSR_entry == SVC)        ;        ; -------------------------------------------        ;         ; This routine provides a wrapper for the SWI_EnterSVC         ; SWI call, allowing entry to Supervisor mode. Note that        ; unlike the SWI, this call only allows entry from USR        ; or SVC mode (note: not SYS).        ;         ; The wrapper must note the entry mode to allow routines        ; which nest this call and so call it in SVC mode to         ; return in SVC mode (even though they call ExitToUSR!)        ;         ; These functions need to be revised.        ;         ; The code below assumes that the SWI only trashes those        ; registers which are allowed by APCS:  r0-3, ip, lr.        ;         ; [Currently, the SWI will only trash r0, r1, lr]        ;         ; -------------------------------------------        EXPORT  Angel_EnterSVCInappropriateModeError        FatalError "Inappropriate Mode\n"Angel_EnterSVC        ; a1-a4 and ip may be corrupted under the APCS        STMFD   sp!, {lr}        MRS     a1, CPSR        LDR     a3, =angel_SVCEntryMode        STR     a1, [a3]        AND     a2, a1, #ModeMaskUFIS        CMP     a2, #SVCmode :AND: ModeMaskUFIS        CMPNE   a2, #FIQmode :AND: ModeMaskUFIS        CMPNE   a2, #IRQmode :AND: ModeMaskUFIS        BEQ     WasSVCMode        CMP     a2, #USRmode :AND: ModeMaskUFIS        BNE     InappropriateModeError        ; The SWI does everthing for us - except note that entry was from USRWasUSRMode        LDR     a1, =angel_SWIreason_EnterSVC        SWI     angel_SWI_ARM   ; Get into SVC with IRQ and FIQ disabled        ; the SWI returns with a1 == Angel_ExitToUSR, so we don't have to         ; load it again.        LDMFD   sp!, {lr}        MOV     pc, lr          ; Return to caller        WasSVCMode      ; Just disable IRQ and FIQ and note SVC entry from SVC        ORR     a1, a1, #InterruptMask        MSR     CPSR_cf, a1        LDR     a1, =Angel_ExitToUSR        LDMFD   sp!, {lr}       ; note that this is writing to lr_svc,                                ; not lr_usr, which was what was saved!        MOV     pc, lr        ; ****************************************************************        ;        ; void Angel_ExitToUSR(void)        ;        ; -------------------------------------------        ;        ; On Entry:        ;    <CPSR Mode MUST BE Privileged [unchecked]>        ;    <angel_SVCEntryMode MUST contain a CPSR as set up        ;        by Angel_EnterSVC>        ;        ; On Exit:        ;    IF angel_SVCEntryFlag == USR mode value (0)        ;       <CPSR Mode is USR, IRQ and FIQ flags unset>        ;       sp_usr = sp_svc        ;       sp_svc = Top of SVC Stack        ;    ELSE ; must be SVC mode (1)        ;       <CPSR Mode is SVC, IRQ and FIQ flags unset>        ;    ENDIF        ;    r0, r1, r2 trashed (as allowed by APCS)        ;        ; -------------------------------------------        ;         ; This routine nominally returns from SVC mode to USR mode, on        ; the assumption that the user has just called Angel_EnterSVC. If        ; however the previous call to Angel_EnterSVC was made in SVC mode,        ; then we return in SVC mode.        ;         ; In either case, interrupts are enabled on exit, whatever state        ; they were in on entry.        ;         ; If returning to USR mode, the SVC stack pointer, which was lost on        ; entry to SVC mode, is returned to the Angel SVC Top of stack value.        EXPORT  Angel_ExitToUSRAngel_ExitToUSR        STMFD   sp!, {lr}        LDR     a3, =angel_SVCEntryMode        LDR     a1, [a3]        AND     a2, a1, #ModeMaskUFIS        CMP     a2, #SVCmode :AND: ModeMaskUFIS        CMPNE   a2, #FIQmode :AND: ModeMaskUFIS        CMPNE   a2, #IRQmode :AND: ModeMaskUFIS        BEQ     ReturnFromExitToUSR        CMP     a2, #USRmode :AND: ModeMaskUFIS        BNE     InappropriateModeError        ; The standard return to USR case follows ...        MOV     a3, sp        STMFD   a3, {a3}        ; copy sp_svc via SVC stack area ...        SUB     a3, a3, #4        LDMFD   a3, {sp}^       ; to sp_usr                ; Reset SVC sp to the empty SVC stack        SetStack Angel_SVCStackOffset        ReturnFromExitToUSR        MSR     CPSR_cxsf, a1        ; return to starting mode...        LDMFD   sp!, {lr}       ; note that this is writing to lr_svc,        MOV     pc, lr          ; return to our caller (bank indep.)             ; ****************************************************************        ;        ; int Angel_DisableInterruptsFromSVC(void)        ;        ; -------------------------------------------        ;         ; Disable (prevent) interrupts. Assumes you are in a supervisor        ; mode (that is, that MRS and MSR are allowed instructions).        ;        ; Passed no parameters;        ; Returns the previous state of the CPSR        ;        ; FIQ SAFETYLEVEL is used to determine which interrupt        ; flags are set.        ;        ; -------------------------------------------        EXPORT  Angel_DisableInterruptsFromSVCAngel_DisableInterruptsFromSVC        MRS     a1, CPSR        DisableAngelInts a1, a2                MSR     CPSR_cf, a2        MOV     pc, lr        ; ****************************************************************        ;        ; int Angel_EnableInterruptsFromSVC(void)        ;        ; -------------------------------------------        ;         ; Enable (allow) interrupts. Assumes you are in a supervisor        ; mode (that is, that MRS and MSR are allowed instructions).        ;        ; Passed no parameters;        ; Returns the previous state of the CPSR        ;        ; FIQ SAFETYLEVEL and HANDLE_INTERRUPTS_ON_IRQ are used to        ; determine which interrupt flags are cleared.         ;        ; -------------------------------------------        EXPORT  Angel_EnableInterruptsFromSVCAngel_EnableInterruptsFromSVC        MRS     a1, CPSR        EnableAngelInts a1, a2                MSR     CPSR_cf, a2        ;; and return in a1 (r0) the original CPSR...        MOV     pc, lr        ; ****************************************************************        ;        ; void Angel_RestoreInterruptsFromSVC(int old)        ;        ; -------------------------------------------        ;         ; Restore the interrupt flags to the state indicated by 'old'.        ; Assumes you are in a supervisor mode (that is, that MRS and MSR        ; are allowed instructions).        ;        ; calculates: CPSR = (CPSR & ~IRQMASK) | (a1 & IRQMASK)        ;        ; Passed a copy of the CPSR in a1;        ; Returns nothing.        ;        ; FIQ SAFETYLEVEL is used to determine which interrupt        ; flags are changed.        ;        ; -------------------------------------------        EXPORT Angel_RestoreInterruptsFromSVCAngel_RestoreInterruptsFromSVC        ;        ; Get a copy of CPSR as it is now, and mask out the IRQ bits        ; and mask from the old CPSR the other (non-IRQ) bits.                MRS     a2, CPSR                AND     a1, a1, #AngelInterruptMask        BIC     a2, a2, #AngelInterruptMask        ; now OR the previous value with the new IRQ bits and        ; put the result back in CPSR.         ORR     a1, a2, a1        MSR     CPSR_cf, a1

⌨️ 快捷键说明

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