📄 startup.s
字号:
;******************************************************************************
;*
;* System On Chip(SOC)
;*
;* Copyright (c) 2003 Mobile Solution Project Team, Samsung Electronics, Inc.
;* All rights reserved.
;*
;* This software is the confidential and proprietary information of Samsung
;* Electronics, Inc("Confidential Information"). You Shall not disclose such
;* Confidential Information and shall use it only in accordance with the terms
;* of the license agreement you entered into Samsung.
;*
;*-----------------------------------------------------------------------------
;*
;* S3C24A0 BSP (WinCE.NET)
;*
;* startup.s : BSP Startup Code(Entry Point)
;*
;* @author :
;*
;* @date : 2004/07/07
;*
;* Log:
;* 2004/07/07 Start
;*
;******************************************************************************
; OPT 2
INCLUDE kxarm.h
INCLUDE reg24A0.a
INCLUDE memcfg.a
;INCLUDE oemaddrtab_cfg.inc
MemoryMap EQU 0x2a4
BANK_SHIFT EQU (20)
TEXTAREA
; OPT 1
; OPT 128
;-------------------------------------------
;
; Macro to feed the LED Reg (The GPIO) with the value desired for debugging.
; Uses physical address
;
MACRO
LED_ON $data
LDR r10, = GPCON_L
LDR r11, = 0x9551a ;25552a
STR r11, [r10]
LDR r10, = GPDAT
LDR r11, =$data
MOV r11, r11, lsl #4
STR r11, [r10]
MEND
; LED_ON using virtual address
;
MACRO
VLED_ON $data
LDR r10, = vGPCON_L
LDR r11, = 0x9551a ;15552a
STR r11, [r10]
LDR r10, = vGPDAT
LDR r11, =$data
MOV r11, r11, lsl #4
STR r11, [r10]
MEND
MACRO
MTC15 $cpureg, $cp15reg
mcr p15, 0, $cpureg, $cp15reg, c0, 0
MEND
;
;-------------------------------------------
;ARM required functions to clear TLB, ICache and DCache
;
; IMPORT ARMClearUTLB
; IMPORT ARMFlushICache
; IMPORT ARMFlushDCache
;EbootMain function
;
IMPORT main
;
;The FCLK and the corresponding PLL values - see CLK and power mgt for these values
;Currently using 203 MHz.
;
FCLK EQU (203)
PLLVAL EQU (((195 << 12) + (10 << 4) + 0))
;FCLK EQU (204)
;PLLVAL EQU (((60 << 12) + (2 << 4) + 0))
;
;UPLL Output Setting Value
;
U_MDIV EQU 56 ;Fin=12.0MHz UPLL_clk=96.0MHz
U_PDIV EQU 2
U_SDIV EQU 1
R1_iA EQU (1 << 31)
R1_nF EQU (1 << 30)
;
; Data Cache Characteristics.
;
DCACHE_LINES_PER_SET_BITS EQU 6
DCACHE_LINES_PER_SET EQU 64
DCACHE_NUM_SETS EQU 8
DCACHE_SET_INDEX_BIT EQU (32 - DCACHE_LINES_PER_SET_BITS)
DCACHE_LINE_SIZE EQU 32
;
;The values used for storing data when going to sleep
;
SLEEPDATA_BASE_VIRTUAL EQU 0xA0032000 ; keep in sync w/ config.bib
SLEEPDATA_BASE_PHYSICAL EQU 0x10032000
PHYBASE EQU 0x10000000 ; physical start
PTs EQU 0x130B0000 ; save room for interrupt vectors.
WORD_SIZE EQU (4)
SleepState_Data_Start EQU (0)
SleepState_WakeAddr EQU (SleepState_Data_Start )
SleepState_MMUCTL EQU (SleepState_WakeAddr + WORD_SIZE )
SleepState_MMUTTB EQU (SleepState_MMUCTL + WORD_SIZE )
SleepState_MMUDOMAIN EQU (SleepState_MMUTTB + WORD_SIZE )
SleepState_SVC_SP EQU (SleepState_MMUDOMAIN + WORD_SIZE )
SleepState_SVC_SPSR EQU (SleepState_SVC_SP + WORD_SIZE )
SleepState_FIQ_SPSR EQU (SleepState_SVC_SPSR + WORD_SIZE )
SleepState_FIQ_R8 EQU (SleepState_FIQ_SPSR + WORD_SIZE )
SleepState_FIQ_R9 EQU (SleepState_FIQ_R8 + WORD_SIZE )
SleepState_FIQ_R10 EQU (SleepState_FIQ_R9 + WORD_SIZE )
SleepState_FIQ_R11 EQU (SleepState_FIQ_R10 + WORD_SIZE )
SleepState_FIQ_R12 EQU (SleepState_FIQ_R11 + WORD_SIZE )
SleepState_FIQ_SP EQU (SleepState_FIQ_R12 + WORD_SIZE )
SleepState_FIQ_LR EQU (SleepState_FIQ_SP + WORD_SIZE )
SleepState_ABT_SPSR EQU (SleepState_FIQ_LR + WORD_SIZE )
SleepState_ABT_SP EQU (SleepState_ABT_SPSR + WORD_SIZE )
SleepState_ABT_LR EQU (SleepState_ABT_SP + WORD_SIZE )
SleepState_IRQ_SPSR EQU (SleepState_ABT_LR + WORD_SIZE )
SleepState_IRQ_SP EQU (SleepState_IRQ_SPSR + WORD_SIZE )
SleepState_IRQ_LR EQU (SleepState_IRQ_SP + WORD_SIZE )
SleepState_UND_SPSR EQU (SleepState_IRQ_LR + WORD_SIZE )
SleepState_UND_SP EQU (SleepState_UND_SPSR + WORD_SIZE )
SleepState_UND_LR EQU (SleepState_UND_SP + WORD_SIZE )
SleepState_SYS_SP EQU (SleepState_UND_LR + WORD_SIZE )
SleepState_SYS_LR EQU (SleepState_SYS_SP + WORD_SIZE )
SleepState_Data_End EQU (SleepState_SYS_LR + WORD_SIZE )
SLEEPDATA_SIZE EQU (SleepState_Data_End - SleepState_Data_Start) / 4
MMU_CTL_MASK EQU 0x3FFF0000
MMU_TTB_MASK EQU 0x00003FFF
MMU_ID_MASK EQU 0xFFFFFFF0
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
I_Bit EQU 0x80
F_Bit EQU 0x40
BIT_SELFREFRESH EQU (1<<22)
HandleFIQ EQU 0x13ffff1c
;
; * StartUp - Image EntryPoint
; *
; * @return .
; * @param .
; *
STARTUPTEXT
LEAF_ENTRY StartUp
b ResetHandler
;
; The ResetHandler is the entry point for the firmware
;
ResetHandler
LED_ON 0xE
; bl ARMClearUTLB
; bl ARMFlushICache
ldr r0, = (DCACHE_LINES_PER_SET - 1)
ldr r1, = (DCACHE_NUM_SETS - 1)
ldr r2, = DCACHE_SET_INDEX_BIT
ldr r3, = DCACHE_LINE_SIZE
; bl ARMFlushDCache
nop
nop
nop
LED_ON 0x3
ldr r0, = GPCON_L ; Init the GPIO [10:0] as interrupts
ldr r1, = 0x9551a ; as they r used for wakeup signal in ;old value 0x2a55aa
str r1, [r0] ; power down mode - see GPIO desc
ldr r0, = WTCON ; watch dog disable
ldr r1, = 0x0
str r1, [r0]
ldr r0, = INTMSK
ldr r1, = 0xffffffff ; all interrupt disable
str r1, [r0]
ldr r0, = INTSUBMSK
ldr r1, = 0xffffffff ;all sub interrupt disable
str r1, [r0]
ldr r0, = INTMOD
ldr r1, = 0x0 ; set all interrupt as IRQ
str r1, [r0]
;
; To reduce PLL lock time, adjust the LOCKTIME register.
;
ldr r0, = LOCKTIME
ldr r1, = 0xfff0fff ; reset value
str r1, [r0]
ldr r0, = CLKDIVN
ldr r1, = ((HCLKdiv<<1)|(PCLKdiv<<0))
str r1, [r0]
1
ldr r0, = LOCKTIME ; To reduce PLL lock time, adjust the LOCKTIME register.
ldr r1, = 0xffffff
str r1, [r0]
ldr r0, = MPLLCON ; Configure MPLL
ldr r1, = PLLVAL ; Fin=12MHz, Fout=50MHz
str r1, [r0]
ldr r0, = UPLLCON ; Fin=12.0MHz UPLL_clk=96.0MHz
ldr r1, = ((U_MDIV << 12) + (U_PDIV << 4) + U_SDIV)
str r1, [r0]
; change of CLK so give a gap of 300us
;
mov r0, #0x2000
1
subs r0, r0, #1
bne %B1 ;ok till here
;-----------------------------------------------------------------------------
;
;wake up code, decide the boot mode here
;
; ldr r1, =ALIVECON ; Determine Booting Mode
ldr r1, =GPRAM10 ; Determine Booting Mode
ldr r10, [r1]
tst r10, #0x8
bne %F4 ;Branch to 4 as reset from power off mode
;Skip MISCCR setting
b BringUpWinCE
;************************ watchdog code can go here *************************
;not currently used
;**********************************************************************************
;
;Wake up from power off code here
;
4
;Clear EINTPND
;
ldr r0, =GPIOBASE
ldr r1, [r0, #oEINTPEND]
ldr r2, =0xA03
orr r1, r1,r2
str r1, [r0, #oEINTPEND]
;Clear SleepKeys
;
ldr r1, [r0, #oALIVECON]
ldr r2, =0x9
and r1, r1,r2
str r1, [r0, #oALIVECON]
ldr r1,=0x0
str r1, [r0, #oGPRAM10]
; b .
;************************ Checksum Calculation saved Data *************************
;
ldr r5, =SLEEPDATA_BASE_PHYSICAL ; pointer to physical address of reserved Sleep mode info data structure
mov r3, r5 ; pointer for checksum calculation
mov r2, #0
ldr r0, =SLEEPDATA_SIZE ; get size of data structure to do checksum on
40
ldr r1, [r3], #4 ; pointer to SLEEPDATA
and r1, r1, #0x1
mov r1, r1, LSL #31
orr r1, r1, r1, LSR #1
add r2, r2, r1
subs r0, r0, #1 ; dec the count
bne %b40 ; loop till done
ldr r0,=GPRAM9
ldr r3, [r0] ; get the Sleep data checksum from the Power Manager Scratch pad register
teq r2, r3 ; compare to what we saved before going to sleep
bne BringUpWinCE ; bad news - do a cold boot - If emergency power off case, normal booting.
;Set ROM/SAM control registers
ldr r0, = SMRDATA
ldmia r0, {r1-r4}
ldr r0, = SROM_BW
stmia r0, {r1-r4}
;
;**********************************************************************************
;Recover Process : Starting Point
;
mov r1, #0x0
mcr p15, 0, r1, c7, c7,0 ;invalidate I,D caches
mcr p15, 0, r1, c7, c10, 4 ;drain write buffer
mcr p15, 0, r1, c8, c7,0 ;invalidate I,D TLBs
ldr r5, =SLEEPDATA_BASE_PHYSICAL ; pointer to physical address of reserved Sleep mode info data structure
; 2. MMU Enable
;
ldr r10, [r5, #SleepState_MMUDOMAIN] ; load the MMU domain access info
ldr r9, [r5, #SleepState_MMUTTB] ; load the MMU TTB info
ldr r8, [r5, #SleepState_MMUCTL] ; load the MMU control info
ldr r7, [r5, #SleepState_WakeAddr ] ; load the LR address
nop
nop
nop
nop
nop
mcr p15, 0, r10, c3, c0, 0 ; setup access to domain 0
mcr p15, 0, r9, c2, c0, 0 ; PT address
mcr p15, 0, r0, c8, c7, 0 ; flush I+D TLBs
mcr p15, 0, r8, c1, c0, 0 ; restore MMU control
; 3. Jump to Kernel Image's fw.s(Awake_address)
mov pc, r7 ; & jump to new virtual address (back up Power management stack)
nop
;-----------------------------------------------------------------------------
BringUpWinCE ;power on reset code starts here
;Set ROM/RAM control registers
;
ldr r0, = SMRDATA
ldmia r0, {r1-r4}
ldr r0, = SROM_BW
stmia r0, {r1-r4}
;Set SDRAM control registers
;
ldr r1, =SDRAM_BANKCFG
ldr r3, =SDRAM_BANKCON
ldr r5, =SDRAM_REFRESH
;SDRAM init sequence pg 3-3
;1st : issue precharge all command
;
mov r0, #0x1
str r0, [r3]
;2st : make refresh cycle 32lk
; mov r0, #0xf
mov r0, #0x20
str r0, [r5]
;3rd : wait 128 clk
;very essential
mov r0, #0x100
1
subs r0, r0, #1
bne %B1
;4th : set nomal operation(133MHz) refresh cycle
ldr r0, =REFCYC
str r0, [r5]
;5th : set cfg/ctrl/timeout registers
ldr r0, =SDRAM_CFG
str r0, [r1]
mov r0, #0x0
str r0, [r3] ;memcon. WB off, normal
;6th : MRS command
mov r0, #0x2
str r0, [r3]
;7th : Normal Operation
mov r0, #0x0
str r0, [r3] ;memcon. WB off, normal
;8th : issue EMRS command(only mobile)
mov r0, #0x3
str r0, [r3]
;9th : (only mobile)
mov r0, #0x0
str r0, [r3] ;memcon. WB off, normal
ands r9, pc, #0xFF000000 ; see if we are in flash or in ram
bne %f15 ; go ahead if we are already in ram
; This is the loop that perform copying.
ldr r0, = 0x38000 ; offset into the RAM
add r0, r0, #PHYBASE ; add physical base
mov r1, r0 ; (r1) copy destination
ldr r2, =0x0 ; (r2) flash started at physical address 0
ldr r3, =0x10000 ; counter (0x40000/4)
10
ldr r4, [r2], #4
str r4, [r1], #4
subs r3, r3, #1
bne %b10
; Restart from the RAM position after copying.
mov pc, r0
nop
nop
nop
; Shouldn't get here.
b .
;;;;;;;;;;;;;;;;;;
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Setup 1st level page table (using section descriptor)
; Fill in first level page table entries to create "un-mapped" regions
; from the contents of the MemoryMap array.
;
INCLUDE oemaddrtab_cfg.inc
;ptr to MemoryMap array
15
add r11, pc, #g_oalAddressTable - (. + 8)
ldr r10, =PTs ;(r10) = 1st level page table
add r10, r10, #0x2000 ;(r10) = ptr to 1st PTE for "unmapped space"
mov r0, #0x0E ;(r0) = PTE for 0: 1MB cachable bufferable
orr r0, r0, #0x400 ;set kernel r/w permission
20
mov r1, r11 ;(r1) = ptr to MemoryMap array
25
ldr r2, [r1], #4 ;(r2) = virtual address to map Bank at
ldr r3, [r1], #4 ;(r3) = physical address to map from
ldr r4, [r1], #4 ;(r4) = num MB to map
cmp r4, #0 ;End of table?
beq %F29
ldr r5, =0x1FF00000
and r2, r2, r5 ;VA needs 512MB, 1MB aligned.
ldr r5, =0xFFF00000
and r3, r3, r5 ;PA needs 4GB, 1MB aligned.
add r2, r10, r2, LSR #18
add r0, r0, r3 ;(r0) = PTE for next physical page
28
str r0, [r2], #4
add r0, r0, #0x00100000 ;(r0) = PTE for next physical page
sub r4, r4, #1 ;Decrement number of MB left
cmp r4, #0
bne %B28 ;Map next MB
bic r0, r0, #0xF0000000 ;Clear Section Base Address Field
bic r0, r0, #0x0FF00000 ;Clear Section Base Address Field
b %B25 ;Get next element
29
tst r0, #8
bic r0, r0, #0x0C ;clear cachable & bufferable bits in PTE
add r10, r10, #0x0800 ;(r10) = ptr to 1st PTE for "unmapped uncached space"
bne %B20 ;go setup PTEs for uncached space
sub r10, r10, #0x3000 ;(r10) = restore address of 1st level page table
; setup mmu to map (VA == 0) to (PA == 0x30000000)
ldr r0, =PTs ;PTE entry for VA = 0
ldr r1, =0x1000040E ;uncache/unbuffer/rw, PA base == 0x30000000
str r1, [r0]
; uncached area
add r0, r0, #0x0800 ;PTE entry for VA = 0x0200.0000 , uncached
ldr r1, =0x10000402 ;uncache/unbuffer/rw, base == 0x10000000
str r1, [r0]
;
;The following loop is to direct map RAM VA == PA. i.e.
;VA == 0x30XXXXXX => PA == 0x30XXXXXX for S3C2400
;Fill in 8 entries to have a direct mapping for DRAM
;
ldr r10, =PTs ;restore address of 1st level page table
ldr r0, =PHYBASE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -