启动代码如下
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Part one of the system initialization code,
;; contains low-level
;; initialization.
;;
;; Copyright 2007 IAR Systems. All rights reserved.
;;
;; $Revision: 29252 $
;;
#include "s3c6410.h"
#include "s3c6410_config.h"
#include "movi.h"
MODULE ?cstartup
;; Forward declaration of sections.
SECTION IRQ_STACK:DATA:NOROOT(3)
SECTION FIQ_STACK:DATA:NOROOT(3)
SECTION CSTACK:DATA:NOROOT(3)
SECTION SVC_STACK:DATA:NOROOT(3)
SECTION UND_STACK:DATA:NOROOT(3)
SECTION ABT_STACK:DATA:NOROOT(3)
;
; The module in this file are included in the libraries, and may be
; replaced by any user-defined modules that define the PUBLIC symbol
; __iar_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.
SECTION .intvec:CODE:NOROOT(2)
PUBLIC __vector
PUBLIC __iar_program_start
PUBLIC jmp_pc
PUBLIC uart_asm_init
EXTERN Undefined_Handler
EXTERN SWI_Handler
EXTERN Prefetch_Handler
EXTERN Abort_Handler
EXTERN IRQ_Handler
EXTERN FIQ_Handler
EXTERN movi_bl2_copy
ARM
__iar_init$$done: ; The vector table is not needed
; until after copy initialization is done
__vector:
; All default exception handlers (except reset) are
; defined as weak symbol definitions.
; If a handler is defined by the application it will take precedence.
b __iar_program_start ; Reset
LDR PC,Undefined_Addr ; Undefined instructions
LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
LDR PC,Prefetch_Addr ; Prefetch abort
LDR PC,Abort_Addr ; Data abort
DCD 0 ; RESERVED
LDR PC,IRQ_Addr ; IRQ
LDR PC,FIQ_Addr ; FIQ
DATA
Undefined_Addr: DCD Undefined_Handler
SWI_Addr: DCD SWI_Handler
Prefetch_Addr: DCD Prefetch_Handler
Abort_Addr: DCD Abort_Handler
IRQ_Addr: DCD IRQ_Handler
FIQ_Addr: DCD FIQ_Handler
; --------------------------------------------------
; ?cstartup -- low-level system initialization code.
;
; After a reset execution starts here, the mode is ARM, supervisor
; with interrupts disabled.
;
PUBLIC ?cstartup
EXTERN ?main
;; REQUIRE __vector
;; SECTION .program_start_section:CODE:NOROOT(2)
;; ARM
__iar_program_start:
?cstartup:
;
; Add initialization needed before setup of stackpointers here.
;
;
; 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.
;
; --------------------
; Mode, correspords to bits 0-5 in CPSR
MODE_MSK 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
cpu_init_crit:
;; 清除V4 数据和指令缓存
MOV r0, #0
MCR p15, 0, r0, c7, c7, 0 ; flush v3/v4 cache
MCR p15, 0, r0, c8, c7, 0 ; flush v4 TLB
;; 禁止mmu和caches
MRC p15, 0, r0, c1, c0, 0
BIC r0, r0, #0x00002300 ;clear bits 13, 9:8 (--V- --RS)
BIC r0, r0, #0x00000087 ;clear bits 7, 2:0 (B--- -CAM)
ORR r0, r0, #0x00000002 ;set bit 2
ORR r0, r0, #0x00001000 ;set bit 12使能I CACHE
MCR p15, 0, r0, c1, c0, 0
;;重映射外设地址
ldr r0,=0x70000013
mcr p15,0,r0,c15,c2,4 ;映射到0x70000000-0x7fffffff范围
;--------------------------------------------------
; Disable Watchdog
;--------------------------------------------------
ldr r0, =0x7e004000 ;0x7e004000
mov r1, #0
str r1, [r0]
;--------------------------------------------------
; Interrupt Disable
;--------------------------------------------------
ldr r0, = 0x71200014 ; vic0 clear
ldr r1, = 0xFFFFFFFF
str r1, [r0]
ldr r0, = 0x71300014 ; vic0 clear
ldr r1, = 0xFFFFFFFF
str r1, [r0]
mov r2, #0x0000000e
bl led_test
;--------------------------------------------------
; Set Clock Out Pad to clock out APLL CLK
;--------------------------------------------------
; ldr r0, = 0x7f0080a0
; ldr r1, [r0]
; ;;orr r1, r1, #0x30000000
; str r1, [r0]
; ldr r0, =0x7f0080a8
; ldr r1, [r0]
; bic r1, r1, #0x03000000
; str r1, [r0]
; ldr r0, =0x7e00f02c
; mov r1, #0x10000
; str r1, [r0]
;----------------------------------------------------------
; Set the mem1drvcon to raise drive strength
;----------------------------------------------------------
ldr r0, =0x7F0081D4
; ldr r1, =0xFFFFFFFF
ldr r1, =0x55555555
str r1, [r0]
;----------------------------------------------------------
; 设置到同步模式
;----------------------------------------------------------
system_clock_init:
ldr r0, =ELFIN_CLOCK_POWER_BASE ;;0x7e00f000
ldr r1, [r0, #OTHERS_OFFSET]
orr r1, r1, #0x40
str r1, [r0, #OTHERS_OFFSET]
nop
nop
nop
nop
nop
ldr r1, [r0, #OTHERS_OFFSET]
orr r1, r1, #0x80
str r1, [r0, #OTHERS_OFFSET]
check_syncack:
ldr r1, [r0, #OTHERS_OFFSET]
and r1, r1, #0xf00
cmp r1, #0xf00
bne check_syncack
;; Check PLL and CLKDIV
ldr r3, =0x83FF3F07 ; Mask for APLL_CON/MPLL_CON
ldr r4, =0x80FF3F07 ; Mask for EPLL_CON0
ldr r5, =0x0000FFFF ; Mask for EPLL_CON1
ldr r6, =0x0003FF17 ; Mask for CLKDIV0
ldr r0, =0x7e00f00c ;;apll_con
ldr r1, [r0]
and r1, r1, r3
ldr r2, =APLL_VAL ; APLL_CON value to configure
cmp r1, r2
bne PLL_NeedToConfigure
ldr r0, =0x7e00f010 ; Check MPLL
ldr r1, [r0]
and r1, r1, r3
ldr r2, =MPLL_VAL ; MPLL_CON value to configure
cmp r1, r2
bne PLL_NeedToConfigure
ldr r0, =0x7e00f014 ; Check EPLL_CON0
ldr r1, [r0]
and r1, r1, r4
ldr r2, =EPLL_VAL ; EPLL_CON0 value to configure
cmp r1, r2
bne PLL_NeedToConfigure
ldr r0, =0x7e00f018 ; Check EPLL_CON1
ldr r1, [r0]
and r1, r1, r5
ldr r2, =EPLL_KDIV ; EPLL_CON1 value to configure
cmp r1, r2
bne PLL_NeedToConfigure
ldr r0, =0x7e00f020 ; Check CLKDIV0
ldr r1, [r0]
and r1, r1, r6
; CLKDIV0 value to configure
ldr r2, = CLK_DIV0_VAL
cmp r1, r2
bne CLKDIV_NeedToConfigure
b PLL_CLKDIV_AlreadyConfigured ; APLL/MPLL/EPLL and CLKDIV0 is already configured
PLL_NeedToConfigure:
ldr r0, =0x7e00f01c
ldr r1, [r0]
bic r1, r1, #0x7 ; select FIN out,Disable PLL Clock Out
str r1, [r0]
ldr r0, =0x7e00f020
ldr r1, [r0]
bic r1, r1, #0xff00
bic r1, r1, #0xff
ldr r2, = CLK_DIV0_VAL
orr r1, r1, r2
str r1, [r0]
; change PLL value
ldr r1, =0x4B1 ; Lock Time : 0x4b1 (100us @Fin12MHz) for APLL/MPLL
ldr r2, =0xE13 ; Lock Time : 0xe13 (300us @Fin12MHz) for EPLL
ldr r0, =0x7e00f000
str r1, [r0] ; APLL Lock Time
str r1, [r0, #0x4] ; MPLL Lock Time
str r2, [r0, #0x8] ; EPLL Lock Time
ldr r0, =0x7e00f00c ;APLL SET
ldr r1, =APLL_VAL
str r1, [r0]
ldr r0, =0x7e00f010 ;MPLL SET
ldr r1, =MPLL_VAL
str r1, [r0]
ldr r0, =0x7e00f018 ;EPLL SET
ldr r1, =EPLL_KDIV
str r1, [r0]
ldr r0, =0x7e00f014 ;EPLL SET
ldr r1, =EPLL_VAL
str r1, [r0]
; Set System Clock Divider
CLKDIV_NeedToConfigure:
ldr r0, =0x7e00f020 ;clk_div0
ldr r1, [r0]
bic r1, r1, #0x30000
bic r1, r1, #0xff00
bic r1, r1, #0xff
ldr r2, =CLK_DIV0_VAL
orr r1, r1, r2
str r1, [r0]
; Enable PLL Clock Out
ldr r0, =0x7e00f01c ;clk_src
ldr r1, [r0]
orr r1, r1, #0x7 ; PLL Clockout
str r1, [r0] ; System will be waiting for PLL unlocked after this instruction
PLL_CLKDIV_AlreadyConfigured:
;----------------------------------------------------------
; 延时一段时间等待时钟稳定
;----------------------------------------------------------
mov r1, #0x1000
clk_loop:
subs r1, r1, #1
bne clk_loop
nop
nop
;------------------------------------
; Expand Memory Port 1 to x32
;------------------------------------
ldr r0, =0x7e00f120
ldr r1, [r0]
bic r1, r1, #0x80 ; ADDR_EXPAND to "0"
str r1, [r0]
;------------------------------------
; CKE_INIT Configuration
;------------------------------------
ldr r0, =0x7F008880 ; SPCONSLP
ldr r1, [r0]
orr r1, r1, #0x10 ; SPCONSLP[4] = 1
str r1, [r0]
nop
bl mem_ctrl_asm_init ;;初始化DDRAM
nop
nop
;----------------------------------------------------------
;;set the cpu to SVC32 mode
mrs r0, cpsr ; Original PSR value
BIC r0, r0, #MODE_MSK ; 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 sp,sp,#0x7 ; Make sure SP is 8 aligned
;; Set up the fast interrupt stack pointer.
BIC r0, r0, #MODE_MSK ; Clear the mode bits
ORR r0, r0, #FIQ_MODE ; Set FIR mode bits
MSR cpsr_c, r0 ; Change the mode
LDR sp, =SFE(FIQ_STACK) ; End of FIQ_STACK
BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
;; Set up the normal stack pointer.
BIC r0 ,r0, #MODE_MSK ; Clear the mode bits
ORR r0 ,r0, #UND_MODE ; Set System mode bits
MSR cpsr_c, r0 ; Change the mode
LDR sp, =SFE(UND_STACK) ; End of UND_STACK
BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
BIC r0 ,r0, #MODE_MSK ; Clear the mode bits
ORR r0 ,r0, #ABT_MODE ; Set System mode bits
MSR cpsr_c, r0 ; Change the mode
LDR sp, =SFE(ABT_STACK) ; End of CSTACK
BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
BIC r0 ,r0, #MODE_MSK ; 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
BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
mrs r0, cpsr
bic r0, r0, #0x3f
orr r0, r0, #0xd3
msr cpsr_c, r0
ldr sp, = SFE(SVC_STACK);
bic sp,sp,#0x7
;----------------------------------------
nop
nop
ldr r0,=0x0000FFFF
bic r1,pc,r0
ldr r2,=TEXT_BASE
bic r2, r2, r0
cmp r1, r2
beq after_copy
;---------------------------------------------
; Clear DRAM
;---------------------------------------------
nop
nop
mov r1, #0
mov r2, #0
mov r3, #0
mov r4, #0
mov r5, #0
mov r6, #0
mov r7, #0
mov r8, #0
ldr r0, = 0x50000000 ;Start address (Physical 0x5000.0000)
ldr r9, = 0x10000000 ;128MB of RAM
DDRAM_CLEAR_LOOP:
stmia r0!, {r1-r8}
subs r9, r9, #32
bne DDRAM_CLEAR_LOOP
nop
nop
mov r2, #0x0000000c
bl led_test
nop
nop
nop
nop
;-----------------------------------------------
bl movi_bl2_copy
nop
nop
mov r1, #0
MCR p15, 0, r1, c7, c7, 0 ; flush v3/v4 cache
MCR p15, 0, r1, c8, c7, 0 ; flush v4 TLB
nop
nop
mov r2, #0x00000008
bl led_test
nop
nop
ldr pc,=TEXT_BASE
nop
nop
nop
nop
after_copy:
; Continue to ?main for C-level initialization.
mov r2, #0x00000000
bl led_test
nop
nop
LDR r0, =?main
BX r0
led_test:
/*led test state*/
ldr r0,=ELFIN_GPIO_BASE
ldr r1,=0x00000055
str r1,[r0,#GPNCON_OFFSET]
ldr r1,=0x0
str r1,[r0,#GPNPUD_OFFSET]
str r2,[r0,#GPNDAT_OFFSET]
mov pc, lr
nop
nop
sd_clk_ref:
ldr r0,=ELFIN_HSMMC_0_BASE
ldr r1,[r0,#0x2c] ; CLKCON
bic r1,r1,#0x04
str r1,[r0,#0x2c] ;;停止时钟
nop
nop
orr r1,r1,#0x00000400
str r1,[r0,#0x2c] ;;改变分频比
nop
nop
sd_wait1:
ldr r1,[r0,#0x2c]
mov r2, #0x2
and r1, r1, r2
cmp r1, #0x2
bne sd_wait1
nop
nop
ldr r1,[r0,#0x2c] ; CLKCON
orr r1,r1,#0x04
str r1,[r0,#0x2c] ;;使能时钟
nop
nop
sd_wait2:
ldr r1,[r0,#0x2c]
mov r2, #0x8
and r1, r1, r2
cmp r1, #0x8
bne sd_wait2
nop
nop
mov pc, lr
nop
nop
/*
* uart_asm_init: Initialize UART in asm mode, 115200bps fixed.
* void uart_asm_init(void)
*/
uart_asm_init:
/* set GPIO to enable UART */
;; GPIO setting for UART
ldr r0, =ELFIN_GPIO_BASE
ldr r1, =0x220022
str r1, [r0, #GPACON_OFFSET]
ldr r0, =ELFIN_CLOCK_POWER_BASE ;;0x7e00f000
ldr r1, [r0,#CLK_SRC_OFFSET]
orr r1, r1, #0x2000
str r1, [r0,#CLK_SRC_OFFSET]
ldr r1, [r0,#CLK_DIV2_OFFSET]
bic r1, r1,#0xF0000
orr r1, r1,#0x30000
str r1, [r0,#CLK_DIV2_OFFSET]
ldr r0, =ELFIN_UART_CONSOLE_BASE ;;0x7F005000
mov r1, #0x0
str r1, [r0, #UFCON_OFFSET]
str r1, [r0, #UMCON_OFFSET]
mov r1, #0x3 ;;was 0.
str r1, [r0, #ULCON_OFFSET]
ldr r1, =0xe45 /* UARTCLK SRC = 11 => EXT_UCLK1*/
str r1, [r0, #UCON_OFFSET]
ldr r1, =0x11
str r1, [r0, #UBRDIV_OFFSET]
ldr r1, =0x0
str r1, [r0, #UDIVSLOT_OFFSET]
str r5, [r0, #UTXH_OFFSET] ;;'O'
mov pc, lr
uart_send
ldr r6,=ELFIN_UART_CONSOLE_BASE
str r5,[r6,#UTXH_OFFSET]
mov pc,lr
jmp_pc:
mov r1, #0
MCR p15, 0, r1, c7, c7, 0 ; flush v3/v4 cache
MCR p15, 0, r1, c8, c7, 0 ; flush v4 TLB
mov pc,r0
mem_ctrl_asm_init:
ldr r0, =ELFIN_DMC1_BASE ;;DMC1 base address 0x7e001000
ldr r1, =0x04
str r1, [r0, #INDEX_DMC_MEMC_CMD]
ldr r1, =DMC_DDR_REFRESH_PRD
str r1, [r0, #INDEX_DMC_REFRESH_PRD]
ldr r1, =DMC_DDR_CAS_LATENCY
str r1, [r0, #INDEX_DMC_CAS_LATENCY]
ldr r1, =DMC_DDR_t_DQSS
str r1, [r0, #INDEX_DMC_T_DQSS]
ldr r1, =DMC_DDR_t_MRD
str r1, [r0, #INDEX_DMC_T_MRD]
ldr r1, =DMC_DDR_t_RAS
str r1, [r0, #INDEX_DMC_T_RAS]
ldr r1, =DMC_DDR_t_RC
str r1, [r0, #INDEX_DMC_T_RC]
ldr r1, =DMC_DDR_t_RCD
ldr r2, =DMC_DDR_schedule_RCD
orr r1, r1, r2
str r1, [r0, #INDEX_DMC_T_RCD]
ldr r1, =DMC_DDR_t_RFC
ldr r2, =DMC_DDR_schedule_RFC
orr r1, r1, r2
str r1, [r0, #INDEX_DMC_T_RFC]
ldr r1, =DMC_DDR_t_RP
ldr r2, =DMC_DDR_schedule_RP
orr r1, r1, r2
str r1, [r0, #INDEX_DMC_T_RP]
ldr r1, =DMC_DDR_t_RRD
str r1, [r0, #INDEX_DMC_T_RRD]
ldr r1, =DMC_DDR_t_WR
str r1, [r0, #INDEX_DMC_T_WR]
ldr r1, =DMC_DDR_t_WTR
str r1, [r0, #INDEX_DMC_T_WTR]
ldr r1, =DMC_DDR_t_XP
str r1, [r0, #INDEX_DMC_T_XP]
ldr r1, =DMC_DDR_t_XSR
str r1, [r0, #INDEX_DMC_T_XSR]
ldr r1, =DMC_DDR_t_ESR
str r1, [r0, #INDEX_DMC_T_ESR]
ldr r1, =DMC1_MEM_CFG
str r1, [r0, #INDEX_DMC_MEMORY_CFG]
ldr r1, =DMC1_MEM_CFG2
str r1, [r0, #INDEX_DMC_MEMORY_CFG2]
ldr r1, =DMC1_CHIP0_CFG
str r1, [r0, #INDEX_DMC_CHIP_0_CFG]
ldr r1, =DMC_DDR_32_CFG
str r1, [r0, #INDEX_DMC_USER_CONFIG]
;;DMC0 DDR Chip 0 configuration direct command reg
ldr r1, =DMC_NOP0
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
;;Precharge All
ldr r1, =DMC_PA0
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
;;Auto Refresh 2 time
ldr r1, =DMC_AR0
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
;;MRS
ldr r1, =DMC_mDDR_EMR0
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
;;Mode Reg
ldr r1, =DMC_mDDR_MR0
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
#ifdef CONFIG_SMDK6410_X5A
ldr r1, =DMC1_CHIP1_CFG
str r1, [r0, #INDEX_DMC_CHIP_1_CFG]
;;DMC0 DDR Chip 0 configuration direct command reg
ldr r1, =DMC_NOP1
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
;;Precharge All
ldr r1, =DMC_PA1
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
;;Auto Refresh 2 time
ldr r1, =DMC_AR1
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
;;MRS
ldr r1, =DMC_mDDR_EMR1
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
;;Mode Reg
ldr r1, =DMC_mDDR_MR1
str r1, [r0, #INDEX_DMC_DIRECT_CMD]
#endif
;;Enable DMC1
mov r1, #0x0
str r1, [r0, #INDEX_DMC_MEMC_CMD]
check_dmc1_ready:
ldr r1, [r0, #INDEX_DMC_MEMC_STATUS]
mov r2, #0x3
and r1, r1, r2
cmp r1, #0x1
bne check_dmc1_ready
nop
nop
mov pc, lr
nop
b .
SECTION .text:CODE:NOROOT(2)
ARM
END