;-------------------------------------------------------------------------------
; Assembler helper function.
;-------------------------------------------------------------------------------


    export _fcMain
    import fcMain

#if defined(CONFIG_EXYNOS5410) || defined(CONFIG_EXYNOS5420) || defined(CONFIG_4X12) || defined(CONFIG_EXYNOS3472) || defined(CONFIG_EXYNOS4415)|| defined(CONFIG_EXYNOS3475)
CORES_MAX   equ  4          ; max cores code for setting up a core-specific stack
#elif defined(CONFIG_EXYNOS5260)
CORES_MAX   equ  6          ; max cores code for setting up a core-specific stack
#elif defined(CONFIG_EXYNOS3250)
CORES_MAX   equ  2          ; max cores code for setting up a core-specific stack
#else
CORES_MAX   equ  8          ; max cores code for setting up a core-specific stack
#endif
#if defined(CONFIG_EXYNOS3475)
STACK_SIZE  equ  512 * 4 * 2    ; 1024 words on boot-stack for exynos3475
#else
STACK_SIZE  equ  512 * 4    ; 512 words on boot-stack for every core
#endif
;###############################################################################
;##
;## Fastcall entry function
;##
;###############################################################################


    area stack, noinit, readwrite
    ; stack for fastcall
fcStackBottom
    space CORES_MAX * STACK_SIZE
fcStackTop

    area text, code, readonly
    preserve8
    arm
_fcMain
    push {r0, r6-r8, r12, lr}
    mov r12, sp

    ; get affinity level 0 core number in r1
#if defined(CONFIG_EXYNOS7885)
	mrc    p15, 0, r7, c0, c0, 5    ; get mpidr
	ubfx   r6, r7, #0, #4           ; cpu id(1-3)
	ubfx   r8, r7, #8, #4           ; cluster id(0-1)
	cmp    r8, #2                   ; cluster 2
	addeq  r6, r6, r8
	addne  r6, r6, r8, lsl #2
#elif defined(CONFIG_EXYNOS9810)
	mrc    p15, 0, r7, c0, c0, 5    ; get mpidr
	tst    r7, #(1 << 24)
	lsrne  r7, r7, #8
	ubfx   r6, r7, #0, #4           ; cpu id(1-3)
	ubfx   r8, r7, #8, #4           ; cluster id(0-1)
	add    r6, r6, r8, lsl #2
#else
    mrc    p15, 0, r7, c0, c0, 5    ; get mpidr
    ubfx   r6, r7, #0, #4           ; cpu id(1-3)
    ubfx   r7, r7, #8, #4           ; cluster id
    add    r6, r6, r7, lsl #2       ; r6 = cpu_id + 4*cluster_id (cluster 0 : 0, 1, 2, 3 - cluster 1 : 4, 5, 6, 7)
#endif

    ; set own core-specific stack
    ldr    r7, =fcStackTop
    mov    r8, #STACK_SIZE
    mul    r6, r6, r8                               ; calculate stack-start for this core
    sub    r7, r7, r6                               ; by sp = top - (core_num * size_core)
    mov    sp, r7                                   ; set as current stack

    ; save the old stack in the new stack
    push {r12}
    blx fcMain
    ; get the old stack back
    pop {r12}
    mov sp, r12
    ; restore the context from the old stack
    pop {r0, r6-r8, r12, lr}
    bx lr

;###############################################################################
;###############################################################################
    end
