;------------------------------------------------------------------------------
;
;  Copyright (c) Microsoft Corporation.  All rights reserved.
;
;
;  Use of this source code is subject to the terms of the Microsoft end-user
;  license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
;  If you did not accept the terms of the EULA, you are not authorized to use
;  this source code. For a copy of the EULA, please see the LICENSE.RTF on your
;  install media.
;
;------------------------------------------------------------------------------
;
;   File:  startup.s
;
;   Hardware startup routine for Samsung SMDKV210 board.
;
;------------------------------------------------------------------------------

    INCLUDE     kxarm.h
    INCLUDE     register_map.inc
    INCLUDE     image_cfg.inc

    IMPORT      main                    ; C entrypoint for Steppingstone loader.
    IMPORT      InitDMC
    IMPORT      InitClockCONforBL
    IMPORT      InitCache


;	IMPORT		InitIO
	
;------------------------------------------------------------------------------
;
;    Macro for Jumping to Kernel
;
;------------------------------------------------------------------------------

	MACRO
	JUMP_TO_KERNEL
	
	        ldr     r0, =DRAM_BASE_PA_START             ; DRAM Base Physical Address
	        add     r0, r0, #IMAGE_NK_OFFSET            ; NK Offset in DRAM
	        mov     pc, r0                              ; Jump to StartUp address
	        b       .
        
	MEND


    STARTUPTEXT

;------------------------------------------------------------------------------
;
;    StartUp Entry
;
;    Main entry point for CPU initialization.
;
;------------------------------------------------------------------------------

    LEAF_ENTRY    StartUp

    IF !:DEF: S5PV210_EVT0
;------------------------------------------------------------------------------
;    Header of V210 Steploader.
;    :  V210 IROM needs 4words header. 
;------------------------------------------------------------------------------
                DCD     0x4000	; Size of NBL1
                DCD     0x0
                DCD     0x0		; Checksum - will be calculated on downloading the STEPLDR
                DCD     0x0
    ENDIF
    
;------------------------------------------------------------------------------
;   Real Startup Code
;------------------------------------------------------------------------------
        b        ResetHandler
        b        .                ; HandlerUndef    (0x00000004)
        b        .                ; HandlerSWI        (0x00000008)
        b        .                ; HandlerPabort    (0x0000000C)
        b        .                ; HandlerDabort    (0x00000010)
        b        .                ; HandlerReserved    (0x00000014)
        b        .                ; HandlerIRQ        (0x00000018)
        b        .                ; HandlerFIQ        (0x0000001C)

;------------------------------------------------------------------------------
;    End of StartUp
;------------------------------------------------------------------------------


;------------------------------------------------------------------------------
;
;    ResetHandler Function
;
;    Reset Exception Handler
;
;------------------------------------------------------------------------------

ResetHandler

;------------------------------------
;    Check Deep IDLE Wakeup
;------------------------------------
        ldr     r0, =RST_STAT
        ldr     r1, [r0]
        and     r1, r1, #BP_DIDLE_WAKEUP
        cmp     r1, #BP_DIDLE_WAKEUP
        bne     NotDeepIdleWakeUp    		; is not DeepIdle WakeUp
lockloop
	ldr     r0, =APLL_CON			; wait when pll is locked
	ldr	r1, [r0]
	and	r1, r1, #BP_APLL_LOCKED
	cmp     r1, #BP_APLL_LOCKED
	bne	lockloop

;------------------------------------
;    Set Exception Vector Area to '0'
;------------------------------------
        mov     r0, #0
        mcr     p15,0,r0,c12,c0,0		

;------------------------------------
;    Enable Coprocessors
;------------------------------------
        ldr     r0, =0xffffffff
        mcr     p15,0,r0,c1,c0,2		

;------------------------------------
;    Initialize Cache
;------------------------------------     
        bl	    InitCache

        JUMP_TO_KERNEL				; DeepIdle Wakeup jump to Kernel
Loop1
	b Loop1

NotDeepIdleWakeUp

;------------------------------------
;    Interrupt Disable
;------------------------------------
        ldr     r1, =0xFFFFFFFF

        ldr     r0, =VIC0INTENCLEAR
        str     r1, [r0]

        ldr     r0, =VIC1INTENCLEAR
        str     r1, [r0]

        ldr     r0, =VIC2INTENCLEAR
        str     r1, [r0]
   
        ldr     r0, =VIC3INTENCLEAR
        str     r1, [r0]

;------------------------------------
;    Set Exception Vector Area to '0'
;------------------------------------
        mov     r0, #0
        mcr     p15,0,r0,c12,c0,0		

;------------------------------------
;    Enable Coprocessors
;------------------------------------
        ldr     r0, =0xffffffff
        mcr     p15,0,r0,c1,c0,2		
   
;------------------------------------
;    Initialize Cache
;------------------------------------     
        bl	    InitCache

;---------------------------------------------------------------
;    Initialization TZPC (Must be non-secure in case of using DMA
;---------------------------------------------------------------
        ldr     r0, =TZPC0_R0SIZE
        mov     r1, #0x00
        str     r1, [r0]
        ldr     r0, =TZPC0_DECPROT0Set
        mov     r1, #0xff
        str     r1, [r0]
        ldr     r0, =TZPC0_DECPROT1Set
        str     r1, [r0]

        ldr     r0, =TZPC1_DECPROT0Set
        str     r1, [r0]
        ldr     r0, =TZPC1_DECPROT1Set
        str     r1, [r0]
        ldr     r0, =TZPC1_DECPROT2Set
        str     r1, [r0]

        ldr     r0, =TZPC2_DECPROT0Set
        str     r1, [r0]
        ldr     r0, =TZPC2_DECPROT1Set
        str     r1, [r0]
        ldr     r0, =TZPC2_DECPROT2Set
        str     r1, [r0]
        ldr     r0, =TZPC2_DECPROT3Set
        str     r1, [r0]
        ldr     r0, =TZPC3_DECPROT0Set
        str     r1, [r0]

;------------------------------------------------
;    Configuration ASYNC BRIDGE for Performance
;------------------------------------------------
        [{true}
        ldr     r0, =HALFSYNC0
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]
        ldr     r0, =ASYNC_INDEX0
        mov     r1, #INDEX_1_1  ;MFC:VSYS0=200:200
        str     r1, [r0]
        ldr     r0, =DMASTER0
        mov     r1, #NON_DEFAULT_MASTER  
        str     r1, [r0]

        ldr     r0, =HALFSYNC1
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]
        ldr     r0, =ASYNC_INDEX1
        mov     r1, #INDEX_1_1  ;MFC:VSYS1=200:200
        str     r1, [r0]
        ldr     r0, =DMASTER1
        mov     r1, #NON_DEFAULT_MASTER  
        str     r1, [r0]

        ldr     r0, =HALFSYNC2
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]
        ldr     r0, =ASYNC_INDEX2
        mov     r1, #INDEX_6_5  ;DSYS:MSYS0=166:200
        str     r1, [r0]
        ldr     r0, =DMASTER2
        mov     r1, #NON_DEFAULT_MASTER  
        str     r1, [r0]

        ldr     r0, =HALFSYNC3
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]
        ldr     r0, =ASYNC_INDEX3
        mov     r1, #INDEX_6_5  ;DSYS:MSYS1=166:200
        str     r1, [r0]
        ldr     r0, =DMASTER3
        mov     r1, #NON_DEFAULT_MASTER  
        str     r1, [r0]

        ldr     r0, =HALFSYNC4       ;MSFR:DSFR
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]

        ldr     r0, =HALFSYNC5       ;MSFR:PSFR
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]

        ldr     r0, =HALFSYNC6
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]

        ldr     r0, =HALFSYNC7       ;MSFR:MPERI
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]

        ldr     r0, =HALFSYNC8
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]
        ldr     r0, =ASYNC_INDEX8
        mov     r1, #INDEX_5_4  ;PSYS:DSYS=133:166
        str     r1, [r0]
        ldr     r0, =DMASTER8
        mov     r1, #NON_DEFAULT_MASTER  
        str     r1, [r0]

        ldr     r0, =HALFSYNC9
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]
        ldr     r0, =ASYNC_INDEX9
        mov     r1, #INDEX_2_1  ;AUDIO:PSYS=24:133
        str     r1, [r0]
        ldr     r0, =DMASTER9
        mov     r1, #NON_DEFAULT_MASTER  
        str     r1, [r0]

        ldr     r0, =HALFSYNC10       ;PSFR:AUDIO
        mov     r1, #CYCLE_HALF_SYNC  ; using 1/2cycle synchronizer
        str     r1, [r0]
        
        ]
      
; We doesn't initialize the stack size and location because iROM code already did it.
; NBL1 can use it before DRAM initialization. 
; The stack address is 0xD0037F80 on iRAM and the size is 2KB 
;(IRQ stack is 512B and SVC is 1.5KB)

;--------------------------------------------------
;    Set Clock Control 
;--------------------------------------------------
; Here we initialize the clock and PLL control registers.
; The initialization values are defined at 'InitSystem.h'

        bl      InitClockCONforBL

;--------------------------------------------------
;    Initialize DRAM Controller
;--------------------------------------------------

        bl      InitDMC


;--------------------------------------------------
;    Power Management Routine
;    (WakeUp Processing)
;--------------------------------------------------

SleepWakeup_Check
        ldr     r0, =RST_STAT
        ldr     r1, [r0]  
        and     r1, r1, #BP_SLEEP_WAKEUP
        cmp     r1, #BP_SLEEP_WAKEUP
        bne     SoftReset_Check	    ; Not Wake Up

        JUMP_TO_KERNEL				; Sleep Wakeup jump to Kernel
        b	.
        

SoftReset_Check
;		bl		InitIO

;------------------------------------
;   Initialize GPIO for NFCON
;------------------------------------
		ldr		r0, =0xE02002E0		; MP0_1CON
		ldr		r1, [r0]
		ldr		r2, =0x00000F00
		bic		r1, r1, r2
		ldr		r2, =0x00000300
		orr		r1, r1, r2			; NFCSn[0]

		;lqm added.
		ldr		r0, =0xE0200C44		;GPH2DAT
		ldr 	r1, [r0]
		bic 	r1, r1,#0x10
		str		r1, [r0]


		ldr		r0, =0xe0200320		; MP0_3CON
		ldr		r2, =0x22222222		
		str		r2, [r0]			; NF_CLE, NF_ALE, NF_FWEn, NF_FREn, NF_RnB[3:0]




        ldr     r0, =RST_STAT
        ldr     r1, [r0]  
        and     r1, r1, #BP_SWRESET
        cmp     r1, #BP_SWRESET
        bne     Normal_Boot_Sequence            ; Normal Booting (Not SW Reset)

        JUMP_TO_KERNEL				; SW Reset jump to Kernel
        b	.


Normal_Boot_Sequence

        ldr     r0, =IMAGE_BL_RAM_PA_START   	
        ldr     r10,=IMAGE_BL_RAM_SIZE      	; 7MB of Bootloader RAM.
loop
        mov     r1,#0
        mov     r2,#0
        mov     r3,#0
        mov     r4,#0
        mov     r5,#0
        mov     r6,#0
        mov     r7,#0
        mov     r8,#0

        stmia   r0!, {r1-r8}
        subs    r10, r10, #32
        bne     loop

;--------------------------------------------------
;    Clear Bootloader Stack Area
;--------------------------------------------------

        ldr     r0, =TOP_OF_STACKS_PHYSICAL
        ldr     r10,=StackTotalSize      	    ; 64KB Bootloader Stack
loop2
        mov     r1,#0
        mov     r2,#0
        mov     r3,#0
        mov     r4,#0
        mov     r5,#0
        mov     r6,#0
        mov     r7,#0
        mov     r8,#0

        stmia   r0!, {r1-r8}
        subs    r10, r10, #32
        bne     loop2
        
        
;--------------------------------------------------
;    Initialize Stack
;    Stack size and location information is in "image_cfg.inc"
;--------------------------------------------------

        mrs     r0, cpsr

        bic     r0, r0, #Mode_MASK
        orr     r1, r0, #Mode_IRQ | NOINT
        msr     cpsr_cxsf, r1		; IRQMode
        ldr     sp, =IRQStack_PA		; IRQStack

        bic     r0, r0, #Mode_MASK | NOINT
        orr     r1, r0, #Mode_SVC
        msr     cpsr_cxsf, r1		; SVCMode
        ldr     sp, =SVCStack_PA		; SVCStack



;------------------------------------
;    Jump to Main() "C" Routine
;------------------------------------

        bl        main
        b         .            ; Should not be here...

        ENTRY_END


;------------------------------------------------------------------------------
;	End of StartUp
;------------------------------------------------------------------------------

        END

