;
; 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
;
;   Kernel startup routine for Samsung SMDKV210 board. Hardware is
;   initialized in boot loader - so there isn't much code at all.
;
;------------------------------------------------------------------------------

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

        IMPORT  InitClockCONforBL
        IMPORT	InitCache

        TEXTAREA
        INCLUDE	oemaddrtab_cfg.inc


        IMPORT  main

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

		b		ResetHandler
		b		.				; HandlerUndef
		b		.				; HandlerSWI
		b		.				; HandlerPabort
		b		.				; HandlerDabort
		b		.				; HandlerReserved
		b		.				; HandlerIRQ
		b		.				; HandlerFIQ

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

ResetHandler

;------------------------------------
;	Check boot mode
;------------------------------------
        mrc		p15, 0, r0, c1, c0, 0
        tst		r0, #1
        bne		VirtualStart				; If the MMU is already enabled, we don't need to initialize H/W. (normal boot : STEPLDR-BL2-EBOOT)
											; If the MMU is disabled, continue to intialize H/W. (EBOOT.nb0)


;------------------------------------
;	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
        
;------------------------------------
;    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]
        
;--------------------------------------------------
;    Set Clock Control 
;--------------------------------------------------
        ;bl      InitClockCONforBL



;------------------------------------
;   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]


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


;------------------------------------
;   Initialize GPIO for POWER_LOCK GPH00 HIGH
;------------------------------------

;    rGPH0CON = (rGPH0CON & ~(0xf<<0)) | (0x1<<0);   // GPH0[0] : Output
;    rGPH0PUD = rGPH0PUD & ~(0x3<<0);     
;   rGPH0DAT = (rGPH0DAT |(0x1<<0));


		ldr		r0, =0xE0200C00		; GPH0CON
		ldr		r1, [r0]
		ldr		r2, =0x0000000F
		bic		r1, r1, r2
		ldr		r2, =0x00000001
		orr		r1, r1, r2			;     GPH0[0] : Output
      	       str     r1, [r0]

		ldr		r0, =0xE0200C08		; GPH0PUD
		ldr		r1, [r0]
		ldr		r2, =0x00000003
		bic		r1, r1, r2
		ldr		r2, =0x00000000
		orr		r1, r1, r2			;    
              str     r1, [r0]

		ldr		r0, =0xE0200C04		; GPH0DAT
		ldr		r1, [r0]
		ldr		r2, =0x01
		bic		r1, r1, r2
		ldr		r2, =0x01
		orr		r1, r1, r2		
              str     r1, [r0]



;------------------------------------
;	Initialize MMU Table
; 	Compute physical address of the OEMAddressTable.
;------------------------------------
20
	add	r11, pc, #g_oalAddressTable -(. + 8)
	ldr	r10, =PT_1ST_BASE		; (r10) = 1st level page table

;----------------------------
; 	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.
;
; 	(r10) = 1st level page table
; 	(r11) = ptr to MemoryMap array

	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
25
	mov	r1, r11				; (r1) = ptr to MemoryMap array

30
	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	%F40

	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

35
	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	%B35				; Map next MB

	bic	r0, r0, #0xF0000000		; Clear Section Base Address Field
	bic	r0, r0, #0x0FF00000		; Clear Section Base Address Field
	b	%B30				; Get next element

40
	tst	r0, #8
	bic	r0, r0, #0x0C			; clear cachable & bufferable bits in PTE
	orr     r0, r0, #(1<<4)           	; set ARMV6_MMU_PTL1_XN.. for ARMV6
	add	r10, r10, #0x0800		; (r10) = ptr to 1st PTE for "unmapped uncached space"
	bne	%B25				; 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 == 0x40000000).

	; cached area
	ldr	r0, =PT_1ST_BASE	; PTE entry for VA = 0
	ldr	r1, =PT_1ST_ENTRY_CNB	; Cache/Unbuffer/RW
	str	r1, [r0]

	; uncached area.
	add	r0, r0, #0x0800		; PTE entry for VA = 0x02000000
	ldr	r1, =PT_1ST_ENTRY_NCNB	; Uncache/Unbuffer/RW
	str	r1, [r0]

	; Comment:
	; The following loop is to direct map RAM VA == PA. i.e.
	;   VA == 0x40XXXXXX => PA == 0x40XXXXXX for S5PV210
	; Fill in 8 entries to have a direct mapping for DRAM

	ldr	r10, =PT_1ST_BASE	; Restore address of 1st level page table
	ldr	r0,  =DRAM_BASE_PA_START

	add	r10, r10, #PTR_1ST_PTE	; (r10) = ptr to 1st PTE for 0x20000000

	add	r0, r0, #0x1E		; 1MB cachable bufferable
	orr	r0, r0, #0x400		; set kernel r/w permission
	mov	r1, #0
	; if you need to use 256MB DRAM, modify following value! (BSP_V0)
	mov		r3, #128				; 128MB DRAM
45
	mov	r2, r1			; (r2) = virtual address to map Bank at
	cmp	r2, #0x20000000:SHR:BANK_SHIFT
	add	r2, r10, r2, LSL #BANK_SHIFT-18
	strlo	r0, [r2]
	add	r0, r0, #0x00100000	; (r0) = PTE for next physical page
	subs	r3, r3, #1
	add	r1, r1, #1
	bgt	%B45

	ldr	r10, =PT_1ST_BASE		; (r10) = restore address of 1st level page table        
	mcr	p15, 0, r10, c2, c0, 0		
	
	; The page tables and exception vectors are setup.
	; Initialize the MMU and turn it on.
	mov	r1, #3              		; 1->3 : client -> manager.. by shin...1010
	mcr	p15, 0, r1, c3, c0, 0		; setup access to domain 0
	mcr	p15, 0, r0, c8, c7, 0		; flush I+D TLBs
	mrc	p15, 0, r1, c1, c0, 0
	orr	r1, r1, #0x0071			; Enable MMU
	orr	r1, r1, #0x0004			; Enable the Data Cache
;	bic     r1, r1, #1<<12      		; test, disable I-cache, na9da, 2008.11.09
;	bic     r1, r1, #1<<2       		; test, disable D-cache, na9da, 2008.11.09

	ldr	r0, =VirtualStart

	cmp	r0, #0				; make sure no stall on "mov pc,r0" below
	mcr	p15, 0, r1, c1, c0, 0
	mov	pc, r0				; & jump to new virtual address
	nop

;-----------------------------------------------
;	MMU Enabled and Virtual Address is Valid from here
;-----------------------------------------------
VirtualStart
      
;------------------------------------
;	Clear Bootloader RAM
;------------------------------------
        ldr     r0, =IMAGE_BL_RAM_CA_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_VIRTUAL
        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_VA		; IRQStack

	bic	r0, r0, #Mode_MASK | NOINT
	orr	r1, r0, #Mode_SVC
	msr	cpsr_cxsf, r1			; SVCMode
	ldr	sp, =SVCStack_VA		; SVCStack
	
                
;------------------------------------
;	Jump to Main() "C" Routine
;------------------------------------
	b	main
	b	.		; Should no be here...

	ENTRY_END


	END

