cstartup.s

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· S 代码 · 共 310 行

S
310
字号
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Part one of the system initialization code,
;; contains low-level
;; initialization.
;;
;; Copyright 2006 IAR Systems. All rights reserved.
;;
;; $Revision: 19649 $
;;

;
; Naming covention of labels in this file:
;
;  ?xxx   - External labels only accessed from assembler.
;  __xxx  - External labels accessed from or defined in C.
;  xxx    - Labels local to one module (note: this file contains
;           several modules).
;  main   - The starting point of the user program.
;

#include "AT91SAM9260_inc.h"

;---------------------------------------------------------------
; Macros and definitions for the whole file
;---------------------------------------------------------------

; Mode, correspords to bits 0-5 in CPSR
MODE_BITS DEFINE  0x1F    ; Bit mask for mode bits in CPSR
USR_MODE  DEFINE  0x10    ; User mode
FIQ_MODE  DEFINE  0x11    ; Fast Interrupt Request mode
IRQ_MODE  DEFINE  0x12    ; Interrupt Request mode
SVC_MODE  DEFINE  0x13    ; Supervisor mode
ABT_MODE  DEFINE  0x17    ; Abort mode
UND_MODE  DEFINE  0x1B    ; Undefined Instruction mode
SYS_MODE  DEFINE  0x1F    ; System mode

I_BIT     DEFINE  0x80
F_BIT     DEFINE  0x40

CP_DIS_MASK DEFINE ~5     ; MMU Disable Mask

;---------------------------------------------------------------
; ?cstartup
    MODULE  ?cstartup
        ;; Forward declaration of sections.
        SECTION FIQ_STACK:DATA:NOROOT(3)
        SECTION IRQ_STACK:DATA:NOROOT(3)
        SECTION SVC_STACK:DATA:NOROOT(3)
        SECTION ABT_STACK:DATA:NOROOT(3)
        SECTION UND_STACK:DATA:NOROOT(3)
        SECTION CSTACK:DATA:NOROOT(3)
        SECTION FIQ_STACK:DATA:NOROOT(3)
        SECTION .intvec_remap:CODE

;---------------------------------------------------------------
; Reset Vector.
; Normally, segment INTVEC is linked at address 0.
; For debugging purposes, INTVEC may be placed at other
; addresses.
; A debugger that honors the entry point will start the
; program in a normal way even if INTVEC is not at address 0.
;---------------------------------------------------------------


        SECTION .intvec:CODE:NOROOT(2)
        PUBLIC  __vector
        PUBLIC  __iar_program_start
        EXTERN  AT91F_LowLevelInit
        EXTERN fl_ram_end

        ARM
__vector:
        ldr  pc,[pc,#+24]             ;; Reset
__und_handler:
        ldr  pc,[pc,#+24]             ;; Undefined instructions
__swi_handler:
        ldr  pc,[pc,#+24]             ;; Software interrupt (SWI/SVC)
__prefetch_handler:
        ldr  pc,[pc,#+24]             ;; Prefetch abort
__data_handler:
        ldr  pc,[pc,#+24]             ;; Data abort
        DC32  0xFFFFFFFF              ;; RESERVED
__irq_handler:
        ldr  pc,[pc,#+24]             ;; IRQ
__fiq_handler:
        ldr  pc,[pc,#+24]             ;; FIQ

        DC32  __iar_program_start
        DC32  __und_handler
        DC32  __swi_handler
        DC32  __prefetch_handler
        DC32  __data_handler
        B .
        DC32  IRQ_Handler_Entry
        DC32  FIQ_Handler_Entry

        SECTION .text:CODE:NOROOT(2)
    EXTERN  ?main
    REQUIRE __vector

; Execution starts here.
; After a reset, the mode is ARM, Supervisor, interrupts disabled.

    ARM
__iar_program_start

; Add initialization nedded before setup of stackpointers here
; CP15 Disable:
                mrc       p15,0,R1,C1,C0,0
                ldr       R0,=CP_DIS_MASK       ; 0xFFFFEFFA
                and       R1,R1,R0
                mcr       p15,0,R1,C1,C0,0

                msr       CPSR_c, #SVC_MODE | I_BIT | F_BIT
                ldr       SP,=fl_ram_end  ; temporary stack in internal RAM
;--Call Low level init function in ABSOLUTE through the Interworking
                ldr	      r0,=AT91F_LowLevelInit
                mov       lr, pc
                bx	      r0

; copy the flash code to RAM code this product use a very littel RAM
; and no need to get the code size
#define  __StartAdd     SFB(.intvec)
#define  __StartAddEnd  SFE(.intvec)
#define  __intram       SFB(.intvec_remap)

                ldr     r0, = __intram
                ldr     r3, = __StartAddEnd
		            ldr	    r1, = __StartAdd
next:		
            		ldr     r2,[r1],#4
            		str     r2,[r0],#4
            		cmp	    r1,r3
            		bne     next

; Initialize the stack pointers.
; The pattern below can be used for any of the exception stacks:
; FIQ, IRQ, SVC, ABT, UND, SYS.
; The USR mode uses the same stack as SYS.
; The stack segments must be defined in the linker command file,
; and be declared above.

                mrs     r0,cpsr                             ; Original PSR value
                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#SVC_MODE                     ; Set SVC mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(SVC_STACK)                  ; End of SVC_STACK

                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#UND_MODE                     ; Set UND mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(UND_STACK)                  ; End of UND_STACK

                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#ABT_MODE                     ; Set ABT mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(ABT_STACK)                  ; End of ABT_STACK

                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#FIQ_MODE                     ; Set FIQ mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(FIQ_STACK)                  ; End of FIQ_STACK

                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#IRQ_MODE                     ; Set IRQ mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(IRQ_STACK)                  ; End of IRQ_STACK

                bic     r0,r0,#MODE_BITS                    ; Clear the mode bits
                orr     r0,r0,#SYS_MODE                     ; Set System mode bits
                msr     cpsr_c,r0                           ; Change the mode
                ldr     sp,=SFE(CSTACK)                     ; End of CSTACK

#ifdef __ARMVFP__
; Enable the VFP coprocessor.
                mov       r0, #0x40000000                 ; Set EN bit in VFP
                fmxr      fpexc, r0                       ; FPEXC, clear others.

; Disable underflow exceptions by setting flush to zero mode.
; For full IEEE 754 underflow compliance this code should be removed
; and the appropriate exception handler installed.
                mov       r0, #0x01000000                 ; Set FZ bit in VFP
                fmxr      fpscr, r0                       ; FPSCR, clear others.

#endif

; Add more initialization here

; Continue to ?main for more IAR specific system startup

                ldr     r0,=?main
                bx      r0

;------------------------------------------------------------------------------
;- Function             : FIQ_Handler_Entry
;- Treatments           : FIQ Controller Interrupt Handler.
;- Called Functions     : AIC_FVR[interrupt]
;------------------------------------------------------------------------------
        SECTION .text:CODE:NOROOT(2)
        PUBLIC FIQ_Handler_Entry
        ARM
FIQ_Handler_Entry:

;- Switch in SVC/User Mode to allow User Stack access for C code
; because the FIQ is not yet acknowledged

;- Save and r0 in FIQ_Register
            mov         r9,r0
	          ldr         r0 , [r8, #AIC_FVR]
            msr         CPSR_c,#I_BIT | F_BIT | SVC_MODE

;- Save scratch/used registers and LR in User Stack
            stmfd       sp!, { r1-r3, r12, lr}

;- Branch to the routine pointed by the AIC_FVR
            mov         r14, pc
            bx          r0

;- Restore scratch/used registers and LR from User Stack
            ldmia       sp!, { r1-r3, r12, lr}

;- Leave Interrupts disabled and switch back in FIQ mode
            msr         CPSR_c, #I_BIT | F_BIT | FIQ_MODE

;- Restore the R0 ARM_MODE_SVC register
            mov         r0,r9

;- Restore the Program Counter using the LR_fiq directly in the PC
            subs        pc,lr,#4
;------------------------------------------------------------------------------
;- Function             : IRQ_Handler_Entry
;- Treatments           : IRQ Controller Interrupt Handler.
;- Called Functions     : AIC_IVR[interrupt]
;------------------------------------------------------------------------------
        SECTION .text:CODE:NOROOT(2)
        PUBLIC IRQ_Handler_Entry
        ARM
IRQ_Handler_Entry:

;- Manage Exception Entry
;- Adjust and save LR_irq in IRQ stack
            sub         lr, lr, #4
            stmfd       sp!, {lr}
;- Save and r0 in IRQ stack
            stmfd       sp!, {r0}

;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
            ldr         r14, =AT91C_BASE_AIC
	    ldr         r0 , [r14, #AIC_IVR]
	    str         r14, [r14, #AIC_IVR]

;- Enable Interrupt and Switch in Supervisor Mode
           msr         CPSR_c, #SVC_MODE

;- Save scratch/used registers and LR in User Stack
            stmfd       sp!, { r1-r3, r12, r14}

;- Branch to the routine pointed by the AIC_IVR
            mov         r14, pc
            bx          r0

;- Restore scratch/used registers and LR from User Stack
            ldmia       sp!, { r1-r3, r12, r14}

;- Disable Interrupt and switch back in IRQ mode
            msr         CPSR_c, #I_BIT | IRQ_MODE

;- Mark the End of Interrupt on the AIC
            ldr         r14, =AT91C_BASE_AIC
            str         r14, [r14, #AIC_EOICR]

;- Restore SPSR_irq and r0 from IRQ stack
            ldmia       sp!, {r0}

;- Restore adjusted  LR_irq from IRQ stack directly in the PC
            ldmia       sp!, {pc}^

;------------------------------------------------------------------------------
;- Manage exception
;---------------
;- This module The exception must be ensure in ARM mode
;------------------------------------------------------------------------------
        SECTION .text:CODE:NOROOT(2)
        ARM	
;---------------------------------------------------------------
; ?EXEPTION_VECTOR
; This module is only linked if needed for closing files.
;---------------------------------------------------------------
		PUBLIC	AT91F_Default_FIQ_handler
		PUBLIC	AT91F_Default_IRQ_handler
		PUBLIC	AT91F_Spurious_handler
                PUBLIC  Jump
		CODE32	; Always ARM mode after exeption	
Jump
		mov pc, r0	

AT91F_Default_FIQ_handler
            b     AT91F_Default_FIQ_handler

AT91F_Default_IRQ_handler
            b     AT91F_Default_IRQ_handler

AT91F_Spurious_handler
            b     AT91F_Spurious_handler

                END

⌨️ 快捷键说明

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