📄 at91_cstartup.s79
字号:
;-----------------------------------------------------------------------------
; This file contains the startup code used by the ICCARM C compiler.
;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbol _program_start or
; a user defined start symbol.
; To override the cstartup defined in the library, simply add your modified
; version to the workbench project.
;
; All code in the modules (except ?RESET) will be placed in the ICODE segment.
;
; $Revision: 1.1.2.1 $
;
;-----------------------------------------------------------------------------
;
; 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 "AT91SAM9261_inc.h"
#include "board.h"
#define SDRAM_BASE 0x20000000
;---------------------------------------------------------------
; 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
MATRIX_MCFG_ADDR DEFINE 0xFFFFEE00
MATRIX_MCFG_DATA DEFINE 0x3
;---------------------------------------------------------------
; ?RESET
; 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.
;---------------------------------------------------------------
MODULE ?RESET
RSEG PROGRAM_END
COMMON INTVEC:CODE:NOROOT(2)
PUBLIC __program_start
EXTERN ?cstartup
PUBLIC VectorsTable
CODE32 ; Always ARM mode after reset
org 0x00
__program_start
ldr pc,?reset_vec
org 0x04
ldr pc,?undefined_vec
org 0x08
ldr pc,?software_vec
org 0x0c
ldr pc,?preflech_abr_vec
org 0x10
ldr pc,?data_abr_vec
org 0x14
DCD SFB(PROGRAM_END)
org 0x18
ldr pc,AT91C_AIC_IVR
org 0x1c
ldr pc,AT91C_AIC_IVR
org 0x20
VectorsTable
?reset_vec
DCD ?cstartup
?undefined_vec
DCD 0x04
?software_vec
DCD 0x08
?preflech_abr_vec
DCD 0x0C
?data_abr_vec
DCD 0x10
LTORG
ENDMOD
;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
MODULE ?CSTARTUP
RSEG IRQ_STACK:DATA(2)
RSEG FIQ_STACK:DATA(2)
RSEG ABT_STACK:DATA(2)
RSEG UND_STACK:DATA(2)
RSEG SVC_STACK:DATA:NOROOT(2)
RSEG CSTACK:DATA(2)
RSEG ICODE:CODE:NOROOT(2)
PUBLIC ?cstartup
EXTERN ?main
; Execution starts here.
; After a reset, the mode is ARM, Supervisor, interrupts disabled.
CODE32
?cstartup
; Add initialization nedded before setup of stackpointers here
;-------------------------------------
; Read/modify/write CP15 control register
;-------------------------------------
mrc p15, 0, r0, c1, c0,0 ; read cp15 control registre (cp15 r1) in r0
ldr r3, =0xC0001084 ; Reset bit :Cache disable, Little Endian end fast bus mode
ldr r4, =0x40004000 ; Set bit :Round Robin replacement
bic r0, r0, r3
orr r0, r0, r4
mcr p15, 0, r0, c1, c0,0 ; write r0 in cp15 control registre (cp15 r1)
// Disable watchdog
ldr r0,=AT91C_WDTC_WDMR
ldr r1,=AT91C_WDTC_WDDIS
str r1,[r0]
// Setting PLLA and Divider
ldr r0,=AT91C_BASE_CKGR
ldr r4,=AT91C_BASE_PMC
#if PLLA_FREQ >= 190000000
ldr r1,=( AT91C_CKGR_SRCA |\
AT91C_CKGR_OUTA_2 |\
(AT91C_CKGR_DIVA & ( DIV_PLLA << 0)) |\
(AT91C_CKGR_MULA & ((MUL_PLLA-1) << 16)) |\
(AT91C_CKGR_PLLACOUNT & (6 << 8)))
#else
ldr r1,=( AT91C_CKGR_SRCA |\
(AT91C_CKGR_DIVA & ( DIV_PLLA << 0)) |\
(AT91C_CKGR_MULA & ((MUL_PLLA-1) << 16)) |\
(AT91C_CKGR_PLLACOUNT & (6 << 8)))
#endif
str r1,[r0,#+CKGR_PLLAR]
// Wait for PLL stabilization LOCK bit in PMC_SR
ldr r3,=AT91C_PMC_LOCKA
?plls_lock_loop
ldr r1,[r4,#+PMC_SR]
ands r1,r1,r3
beq ?plls_lock_loop
// Selection of Master Clock MCLK = PCLK/2
ldr r1,=AT91C_PMC_CSS_PLLA_CLK|AT91C_PMC_MDIV_2
str r1,[r4,#+PMC_MCKR]
// Wait until the master clock is established
ldr r3,=AT91C_PMC_MCKRDY
?mclk_loop
ldr r1,[r4,#+PMC_SR]
ands r1,r1,r3
beq ?mclk_loop
// Selection of SDRAM
#ifndef SDRAM
ldr r0,=AT91C_BASE_MATRIX
ldr r1,=0x1003A
str r1,[r0,#+MATRIX_EBICSA]
ldr r0,=AT91C_BASE_PIOC
ldr r1,=(AT91C_PC20_D20 |\
AT91C_PC21_D21 |\
AT91C_PC30_D30 |\
AT91C_PC22_D22 |\
AT91C_PC31_D31 |\
AT91C_PC23_D23 |\
AT91C_PC16_D16 |\
AT91C_PC24_D24 |\
AT91C_PC17_D17 |\
AT91C_PC25_D25 |\
AT91C_PC18_D18 |\
AT91C_PC26_D26 |\
AT91C_PC19_D19 |\
AT91C_PC27_D27 |\
AT91C_PC28_D28 |\
AT91C_PC29_D29)
str r1,[r0,#+PIO_ASR]
str r1,[r0,#+PIO_PDR]
ldr r0,=AT91C_BASE_SDRAMC
ldr r3,=SDRAM_BASE
ldr r1,=AT91C_SDRAMC_NC_9 |\
AT91C_SDRAMC_NR_13 |\
AT91C_SDRAMC_CAS_2 |\
AT91C_SDRAMC_NB_4_BANKS |\
AT91C_SDRAMC_DBW_32_BITS |\
AT91C_SDRAMC_TWR_2 |\
AT91C_SDRAMC_TRC_7 |\
AT91C_SDRAMC_TRP_2 |\
AT91C_SDRAMC_TRCD_2 |\
AT91C_SDRAMC_TRAS_5 |\
AT91C_SDRAMC_TXSR_8
str r1,[r0,#+SDRAMC_CR]
ldr r2,=10000
?sdly_loop1
adds r2,r2,#-1
bne ?sdly_loop1
mov r1,#AT91C_SDRAMC_MODE_PRCGALL_CMD
str r1,[r0,#+SDRAMC_MR]
ldr r1,[r3]
ldr r2,=10000
?sdly_loop2
adds r2,r2,#-1
bne ?sdly_loop2
mov r2,#8
ldr r1,=AT91C_SDRAMC_MODE_RFSH_CMD
str r1,[r0,#+SDRAMC_MR]
?sdram_auto_ref_loop
ldr r1,[r3]
adds r2,r2,#-1
bne ?sdram_auto_ref_loop
ldr r1,=AT91C_SDRAMC_MODE_LMR_CMD
str r1,[r0,#+SDRAMC_MR]
ldr r1,=0xcafedede
str r1,[r3,#+20]
ldr r1,=(Fmclk * 7)/1000000
str r1,[r0,#+SDRAMC_TR]
ldr r1,=AT91C_SDRAMC_MODE_NORMAL_CMD
str r1,[r0,#+SDRAMC_MR]
#endif // SDRAM
; 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,#UND_MODE ; Set UND mode bits
msr cpsr_c,r0 ; Change the mode
ldr sp,=SFE(UND_STACK) & 0xFFFFFFF8 ; 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) & 0xFFFFFFF8 ; End of ABT_STACK
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) & 0xFFFFFFF8 ; End of SVC_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) & 0xFFFFFFF8 ; 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) & 0xFFFFFFF8 ; 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) & 0xFFFFFFF8 ; 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
LTORG
ENDMOD
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -