;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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
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,=0x70000000
orr r0,r0,#0x13
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]
;--------------------------------------------------
; 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]
mov r2, #0x40
orr r1, r1, r2
str r1, [r0, #OTHERS_OFFSET]
nop
nop
nop
nop
nop
ldr r2, =0x80
orr r1, r1, r2
str r1, [r0, #OTHERS_OFFSET]
check_syncack:
ldr r1, [r0, #OTHERS_OFFSET]
ldr r2, =0xf00
and r1, r1, r2
cmp r1, #0xf00
bne check_syncack
;--------------------------------------------------------------------------------------------
; 把时钟切换到12MHz输入
;--------------------------------------------------------------------------------------------
ldr r0, =ELFIN_CLOCK_POWER_BASE
ldr r1, [r0,#CLK_SRC_OFFSET]
bic r1, r1, #0x7
str r1, [r0,#CLK_SRC_OFFSET]
;--------------------------------------------------------------------------------------------
; Set System Clock Divider
;--------------------------------------------------------------------------------------------
ldr r1, [r0, #CLK_DIV0_OFFSET] /*Set Clock Divider设置时钟分频比*/
bic r1, r1, #0x30000
bic r1, r1, #0xff00
bic r1, r1, #0xff
ldr r2, =CLK_DIV0_VAL
orr r1, r1, r2
str r1, [r0, #CLK_DIV0_OFFSET]
;--------------------------------------------------------------------------------------------
; 准备修改PLL,PLL需要一个锁定期间,当输入频率为改变或频分(乘法)值
; 改变。 PLL_LOCK寄存器指定该锁定期,这是对PLL的时钟源为基础。在此期间,输出将被屏蔽为0。
;--------------------------------------------------------------------------------------------
mov r1, #0xff00
orr r1, r1, #0xff
str r1, [r0, #APLL_LOCK_OFFSET]
str r1, [r0, #MPLL_LOCK_OFFSET]
str r1, [r0, #EPLL_LOCK_OFFSET]
;--------------------------------------------------------------------------------------------
; CLKUART(=66.5Mhz) = CLKUART_input(532/2=266Mhz) / (UART_RATIO(3)+1) */
; CLKUART(=50Mhz) = CLKUART_input(400/2=200Mhz) / (UART_RATIO(3)+1) */
; Now, When you use UART CLK SRC by EXT_UCLK1, We support 532MHz & 400MHz value */
;--------------------------------------------------------------------------------------------
ldr r1, =APLL_VAL
str r1, [r0, #APLL_CON_OFFSET]
ldr r1, =MPLL_VAL
str r1, [r0, #MPLL_CON_OFFSET]
ldr r1, =EPLL_VAL
str r1, [r0, #EPLL_CON0_OFFSET]
ldr r1, =EPLL_KDIV
str r1, [r0, #EPLL_CON1_OFFSET]
ldr r1, [r0, #CLK_SRC_OFFSET] /* APLL, MPLL, EPLL select to Fout把时钟切换到3个PLL输出 */
orr r1, r1, #0x7
str r1, [r0, #CLK_SRC_OFFSET]
;----------------------------------------------------------
; 延时一段时间等待时钟稳定
;----------------------------------------------------------
mov r1, #0x10000
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]
bl uart_asm_init ;;初始化UART
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, = 0x08000000 ;128MB of RAM
DDRAM_CLEAR_LOOP:
stmia r0!, {r1-r8}
subs r9, r9, #32
bne DDRAM_CLEAR_LOOP
nop
nop
;-----------------------------------------------
bl movi_bl2_copy
ldr pc,=TEXT_BASE
after_copy:
; Continue to ?main for C-level initialization.
LDR r0, =?main
BX r0
led_test:
/*led test state*/
ldr r0,=ELFIN_GPIO_BASE
ldr r1,=0x11110000
str r1,[r0,#GPKCON0_OFFSET]
ldr r1,=0x0
str r1,[r0,#GPKPUD_OFFSET]
str r2,[r0,#GPKDAT_OFFSET]
mov pc, lr
/*
* uart_asm_init: Initialize UART in asm mode, 115200bps fixed.
* void uart_asm_init(void)
*/
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
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]
//ldr r1, =0x30303030
//str r1, [r0, #UTXH_OFFSET] ;;'O'
mov pc, lr
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 .