@ -7,6 +7,8 @@
# include < arch.h >
# include < asm_macros.S >
# include < common / bl_common.h >
# include " .. / fpga_private.h "
# include < platform_def.h >
.globl plat_get_my_entrypoint
@ -14,10 +16,10 @@
.globl plat_is_my_cpu_primary
.globl platform_mem_init
.globl plat_my_core_pos
.globl plat_fpga_calc_core_pos
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl plat_crash_console_flush
.globl plat_fpga_calc_core_pos
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Indicate a cold boot for every CPU - warm boot is unsupported for the
@ -34,23 +36,59 @@ endfunc plat_get_my_entrypoint
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* /
func plat_secondary_cold_boot_setup
/ *
* Wait for the primary processor to initialise the .BSS segment
* to avoid a race condition that would erase fpga_valid_mpids
* if it is populated before the C runtime is ready.
*
* We cannot use the current spin-lock implementation until the
* runtime is up and we should not rely on sevl / wfe instructions as
* it is optional whether they are implemented or not , so we use
* a global variable as lock and wait for the primary processor to
* finish the C runtime bring-up.
* /
ldr w0 , = C_RUNTIME_READY_KEY
adrp x1 , secondary_core_spinlock
add x1 , x1 , : lo12 : secondary_core_spinlock
1 :
wfe
ldr w2 , [ x1 ]
cmp w2 , w0
b.ne 1 b
/ * Prevent reordering of the store into fpga_valid_mpids below * /
dmb ish
mov x10 , x30
bl plat_my_core_pos
mov x30 , x10
adrp x4 , fpga_valid_mpids
add x4 , x4 , : lo12 : fpga_valid_mpids
mov x5 , # VALID_MPID
strb w5 , [ x4 , x0 ]
/ *
* Poll the CPU ' s hold entry until it indicates to jump
* to the entrypoint address.
* /
bl plat_my_core_pos
lsl x0 , x0 , # PLAT_FPGA_HOLD_ENTRY_SHIFT
ldr x1 , = hold_base
ldr x2 , = fpga_sec_entrypoint
adrp x1 , hold_base
add x1 , x1 , : lo12 : hold_base
poll_hold_entry:
ldr x3 , [ x1 , x0 ]
ldr x3 , [ x1 , x0 , LSL # PLAT_FPGA_HOLD_ENTRY_SHIFT ]
cmp x3 , # PLAT_FPGA_HOLD_STATE_GO
b.ne 1 f
adrp x2 , fpga_sec_entrypoint
add x2 , x2 , : lo12 : fpga_sec_entrypoint
ldr x3 , [ x2 ]
br x3
1 :
wfe
b poll_hold_entry
endfunc plat_secondary_cold_boot_setup
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -73,12 +111,16 @@ func platform_mem_init
endfunc platform_mem_init
func plat_my_core_pos
ldr x1 , = ( MPID_MASK & ~ ( MPIDR_AFFLVL_MASK < < MPIDR_AFF3_SHIFT ))
mrs x0 , mpidr_el1
and x0 , x0 , x1
b plat_fpga_calc_core_pos
endfunc plat_my_core_pos
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* unsigned int plat_fpga_calc_core_pos ( u_register_t mpidr )
* unsigned int plat_fpga_calc_core_pos ( uint32_t mpid )
* Clobber registers : x0 to x5
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* /
func plat_fpga_calc_core_pos
@ -88,6 +130,7 @@ func plat_fpga_calc_core_pos
*
* If not set , shift MPIDR to left to make it look as if in a
* multi-threaded implementation.
*
* /
tst x0 , # MPIDR_MT_MASK
lsl x3 , x0 , # MPIDR_AFFINITY_BITS
@ -98,11 +141,13 @@ func plat_fpga_calc_core_pos
ubfx x1 , x3 , # MPIDR_AFF1_SHIFT , # MPIDR_AFFINITY_BITS
ubfx x2 , x3 , # MPIDR_AFF2_SHIFT , # MPIDR_AFFINITY_BITS
/ * Compute linear position * /
mov x4 , # FPGA_MAX_CPUS_PER_CLUSTER
madd x1 , x2 , x4 , x1
mov x5 , # FPGA_MAX_PE_PER_CPU
/ * Compute linear position * /
madd x1 , x2 , x4 , x1
madd x0 , x1 , x5 , x0
ret
endfunc plat_fpga_calc_core_pos