1*91f16700Schasinglulu/* 2*91f16700Schasinglulu * Copyright (c) 2019, Arm Limited. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu#include <arch.h> 8*91f16700Schasinglulu#include <asm_macros.S> 9*91f16700Schasinglulu#include <platform_def.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu .globl plat_secondary_cold_boot_setup 12*91f16700Schasinglulu .globl plat_get_my_entrypoint 13*91f16700Schasinglulu .globl plat_is_my_cpu_primary 14*91f16700Schasinglulu 15*91f16700Schasinglulu /* ----------------------------------------------------- 16*91f16700Schasinglulu * void plat_secondary_cold_boot_setup (void); 17*91f16700Schasinglulu * 18*91f16700Schasinglulu * This function performs any platform specific actions 19*91f16700Schasinglulu * needed for a secondary cpu after a cold reset e.g 20*91f16700Schasinglulu * mark the cpu's presence, mechanism to place it in a 21*91f16700Schasinglulu * holding pen etc. 22*91f16700Schasinglulu * ----------------------------------------------------- 23*91f16700Schasinglulu */ 24*91f16700Schasinglulufunc plat_secondary_cold_boot_setup 25*91f16700Schasinglulu /* Calculate address of our hold entry */ 26*91f16700Schasinglulu bl plat_my_core_pos 27*91f16700Schasinglulu lsl r0, r0, #A5DS_HOLD_ENTRY_SHIFT 28*91f16700Schasinglulu mov_imm r2, A5DS_HOLD_BASE 29*91f16700Schasinglulu /* Clear the value stored in the hold address for the specific core */ 30*91f16700Schasinglulu mov_imm r3, A5DS_HOLD_STATE_WAIT 31*91f16700Schasinglulu str r3, [r2, r0] 32*91f16700Schasinglulu dmb ish 33*91f16700Schasinglulu 34*91f16700Schasinglulu /* Wait until we have a go */ 35*91f16700Schasinglulupoll_mailbox: 36*91f16700Schasinglulu ldr r1, [r2, r0] 37*91f16700Schasinglulu cmp r1, #A5DS_HOLD_STATE_WAIT 38*91f16700Schasinglulu beq 1f 39*91f16700Schasinglulu mov_imm r0, A5DS_TRUSTED_MAILBOX_BASE 40*91f16700Schasinglulu ldr r1, [r0] 41*91f16700Schasinglulu bx r1 42*91f16700Schasinglulu1: 43*91f16700Schasinglulu wfe 44*91f16700Schasinglulu b poll_mailbox 45*91f16700Schasingluluendfunc plat_secondary_cold_boot_setup 46*91f16700Schasinglulu 47*91f16700Schasinglulu /* --------------------------------------------------------------------- 48*91f16700Schasinglulu * unsigned long plat_get_my_entrypoint (void); 49*91f16700Schasinglulu * 50*91f16700Schasinglulu * Main job of this routine is to distinguish between a cold and warm 51*91f16700Schasinglulu * boot. 52*91f16700Schasinglulu * --------------------------------------------------------------------- 53*91f16700Schasinglulu */ 54*91f16700Schasinglulufunc plat_get_my_entrypoint 55*91f16700Schasinglulu /* TODO support warm boot */ 56*91f16700Schasinglulu /* Cold reset */ 57*91f16700Schasinglulu mov r0, #0 58*91f16700Schasinglulu bx lr 59*91f16700Schasinglulu 60*91f16700Schasingluluendfunc plat_get_my_entrypoint 61*91f16700Schasinglulu 62*91f16700Schasinglulu /* ----------------------------------------------------- 63*91f16700Schasinglulu * unsigned int plat_is_my_cpu_primary (void); 64*91f16700Schasinglulu * 65*91f16700Schasinglulu * Find out whether the current cpu is the primary 66*91f16700Schasinglulu * cpu. 67*91f16700Schasinglulu * ----------------------------------------------------- 68*91f16700Schasinglulu */ 69*91f16700Schasinglulufunc plat_is_my_cpu_primary 70*91f16700Schasinglulu ldcopr r0, MPIDR 71*91f16700Schasinglulu ldr r1, =MPIDR_AFFINITY_MASK 72*91f16700Schasinglulu and r0, r1 73*91f16700Schasinglulu cmp r0, #0 74*91f16700Schasinglulu moveq r0, #1 75*91f16700Schasinglulu movne r0, #0 76*91f16700Schasinglulu bx lr 77*91f16700Schasingluluendfunc plat_is_my_cpu_primary 78*91f16700Schasinglulu 79*91f16700Schasinglulu /* --------------------------------------------------------------------- 80*91f16700Schasinglulu * Loads MPIDR in r0 and calls plat_arm_calc_core_pos 81*91f16700Schasinglulu * --------------------------------------------------------------------- 82*91f16700Schasinglulu */ 83*91f16700Schasinglulufunc plat_my_core_pos 84*91f16700Schasinglulu ldcopr r0, MPIDR 85*91f16700Schasinglulu b plat_arm_calc_core_pos 86*91f16700Schasinglulu 87*91f16700Schasingluluendfunc plat_my_core_pos 88*91f16700Schasinglulu 89*91f16700Schasinglulu /* --------------------------------------------------------------------- 90*91f16700Schasinglulu * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) 91*91f16700Schasinglulu * 92*91f16700Schasinglulu * Function to calculate the core position on A5DS. 93*91f16700Schasinglulu * 94*91f16700Schasinglulu * (ClusterId * A5DS_MAX_CPUS_PER_CLUSTER * A5DS_MAX_PE_PER_CPU) + 95*91f16700Schasinglulu * (CPUId * A5DS_MAX_PE_PER_CPU) + 96*91f16700Schasinglulu * ThreadId 97*91f16700Schasinglulu * 98*91f16700Schasinglulu * which can be simplified as: 99*91f16700Schasinglulu * 100*91f16700Schasinglulu * ((ClusterId * A5DS_MAX_CPUS_PER_CLUSTER + CPUId) * A5DS_MAX_PE_PER_CPU) 101*91f16700Schasinglulu * + ThreadId 102*91f16700Schasinglulu * --------------------------------------------------------------------- 103*91f16700Schasinglulu */ 104*91f16700Schasinglulufunc plat_arm_calc_core_pos 105*91f16700Schasinglulu mov r3, r0 106*91f16700Schasinglulu 107*91f16700Schasinglulu /* 108*91f16700Schasinglulu * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it 109*91f16700Schasinglulu * look as if in a multi-threaded implementation 110*91f16700Schasinglulu */ 111*91f16700Schasinglulu tst r0, #MPIDR_MT_MASK 112*91f16700Schasinglulu lsleq r3, r0, #MPIDR_AFFINITY_BITS 113*91f16700Schasinglulu 114*91f16700Schasinglulu /* Extract individual affinity fields from MPIDR */ 115*91f16700Schasinglulu ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS 116*91f16700Schasinglulu ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS 117*91f16700Schasinglulu ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS 118*91f16700Schasinglulu 119*91f16700Schasinglulu /* Compute linear position */ 120*91f16700Schasinglulu mov r3, #A5DS_MAX_CPUS_PER_CLUSTER 121*91f16700Schasinglulu mla r1, r2, r3, r1 122*91f16700Schasinglulu mov r3, #A5DS_MAX_PE_PER_CPU 123*91f16700Schasinglulu mla r0, r1, r3, r0 124*91f16700Schasinglulu 125*91f16700Schasinglulu bx lr 126*91f16700Schasingluluendfunc plat_arm_calc_core_pos 127