;/*************************************************************************************
;
;	Project Name : S5PC1XX
;
;	Copyright 2009 by Samsung Electronics, Inc.
;	All rights reserved.
;
;	Project Description :
;		This software is only for validating functions of the S5PC1XX.
;
;--------------------------------------------------------------------------------------
;
;	File Name : InitCache.s
;
;	File Description : This file implements the startup procedure.
;
;	Dept. : AP Development Team
;	Created Date : 2009/07/21
;	Version : 0.1
;
;	History
;	- Created(09/07/21)
;
;*************************************************************************************/

    INCLUDE kxarm.h
    INCLUDE register_map.inc

;------------------------------------------------------------------------------
;
;    Macro for Invalidate Cache
;
;------------------------------------------------------------------------------

CORTEXA8_CACHE_L1		EQU	(0<<0)
CORTEXA8_CACHE_L2		EQU	(1<<1)

CORTEXA8_CACHE_DATA		EQU	(0)
CORTEXA8_CACHE_UNIFIED	EQU	(0)
CORTEXA8_CACHE_INSTRUCTION	EQU	(1)

L1_D_CACHE			EQU	(CORTEXA8_CACHE_L1+CORTEXA8_CACHE_DATA)
L2_CACHE			EQU	(CORTEXA8_CACHE_L2+CORTEXA8_CACHE_UNIFIED)
L2RSTDISABLE      		EQU     (1<<31)
	
	
	TEXTAREA

	LEAF_ENTRY InitCache

	mov	r12, lr
	
;------------------------------------
;    Invalidate L1 I-cache
;------------------------------------      
	mov    r0, #0
	mcr    p15, 0, r0, c7, c5, 0	; invalidate instruction cache

;------------------------------------
;    Invalidate L1 D-cache
;------------------------------------
	[{FALSE}
	mov	r0, #L1_D_CACHE		; at cache level 0 (L1 cache) and data cache
	bl	InvalidateCache
	]
	
;------------------------------------
;    Disable L1 Instruction Cache
;------------------------------------
       	mrc     p15, 0, r0, c1, c0, 0
	bic	r0, r0, #R1_I
	mcr	p15, 0, r0, c1, c0, 0

;------------------------------------        
;    Disable L2 cache
;------------------------------------ 
        mov     r0, #0x00
        mrc     p15, 0, r0, c1, c0, 1 	; read Auxiliary Control Register
        bic     r1, r0, #0x02         	; disable L2 cache
        mcr     p15, 0, r1, c1, c0, 1 	;

;------------------------------------        
;    Check L2 hardware reset disable
;------------------------------------ 	
	; r0, Auxiliary Control Reigster 
	; L2 hardware reset disable bit - L2RSTDISABLE
	; 0 = the L2 valid RAM contents are reset by hardware
	; 1 = the L2 valid RAM contents are not reset by hardware
        and     r1, r0, #L2RSTDISABLE
        cmp     r1, #L2RSTDISABLE
        bne     set_L2			; If it is disable invalidate L2 cache.


	ldr	r0, =IDLE_CFG
	ldr	r1, [r0]
        and     r1, r1, #BP_ARM_L2CACHE
        cmp     r1, #ARM_L2CACHE_RET
	beq	set_L2
;------------------------------------        
;    Invalidate L2 cache
;------------------------------------ 
	mov	r0, #L2_CACHE		; at cache level 1 (L2 cache)
	bl	InvalidateCache
	
;------------------------------------        
;    Set parameter of L2 cache.
;------------------------------------ 
set_L2				
        mov     r1, #0x00
        mrc     p15, 1, r1, c9, c0, 2 	; read L2 Cache Auxiliary Control Register
        bic     r1, r1, #0x0F         	; clear value of Data RAM latency
        mcr     p15, 1, r1, c9, c0, 2 	;

        ldr     r2, =0x20000001       	; L2 data RAM read multiplexer select : one cycle
                                      	; Data RAM latency : two cycle
        orr     r1, r1, r2           
        mcr     p15, 1, r1, c9, c0, 2

;------------------------------------        
;    Enable L2 cache
;------------------------------------
        mov     r0, #0x00
        mrc     p15, 0, r0, c1, c0, 1 	; read Auxiliary Control Register
        orr     r0, r0, #0x02         	; enable L2 cache
        mcr     p15, 0, r0, c1, c0, 1

;------------------------------------
;    Enable L1 Instruction Cache
;------------------------------------
       	mrc     p15, 0, r0, c1, c0, 0 	; Enable L1 I-Cache
        orr	r0, r0, #R1_I
        mcr	p15, 0, r0, c1, c0, 0

	mov     pc, r12
	b	.

InvalidateCache
	; r0, Cache Level Selection value
	mcr     p15, 2, r0, c0, c0, 0   ; write the Cache Size selection register

	mov	r1, #0
	;mcr     p15, 0, r1, c7, c5, 4   ; prefetch flush to sync the change to the cachesize id reg
	DCD     0xf57ff06f              ; ISB (Instruction Synchronization Barrier)
	mrc     p15, 1, r1, c0, c0, 0   ; read the new csidr (Cache Size Identification Register)
	; [27:13] NumSets = num of sets - 1 (=0x3FF)
	; [12:3]  Associativity = num of way - 1 (=0x7)
	; [2:0]   LineSize = (log2(num of words in cache line(16 WORD))) - 2 (=0x2)

	and	r2, r1, #7		; extract the length of the cache lines
	add	r2, r2, #4		; add 4 (line length offset) (=0x6(64 bytes))

	ldr	r4, =0x3ff
	ands	r4, r4, r1, lsr #3	; r4 is maximum number on the way size
	clz	r5, r4			; r5 find bit position of way size increment (=0x1D, 29)

	ldr	r7, =0x7fff
	ands	r7, r7, r1, lsr #13	; r7 extract max number of the index size
				
SetLoop	mov	r9, r4			; r9 is working copy of max way size
WayLoop	orr	r11, r0, r9, lsl r5	; factor way and cache number into r11
	orr	r11, r11, r7, lsl r2	; factor index number into r11
	; r11 = (num of way << r5(29)) | (num of set << r2(6)) | (Cache size)

	mcr	p15, 0, r11, c7, c6, 2	; invalidate by set/ way
	
	subs	r9, r9, #1		; decrement the way
	bge	WayLoop

	subs	r7, r7, #1		; decrement the index
	bge 	SetLoop

	mov	r10, #L1_D_CACHE	; at cache level0
	mcr	p15, 2, r10, c0, c0, 0	; select current cache level in cssr

	mov 	pc, lr
	
	END

