1*91f16700Schasinglulu/* 2*91f16700Schasinglulu * Copyright (c) 2013-2017, ARM Limited and Contributors. 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 <cpu_macros.S> 10*91f16700Schasinglulu#include <platform_def.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu .weak plat_secondary_cold_boot_setup 13*91f16700Schasinglulu .weak plat_get_my_entrypoint 14*91f16700Schasinglulu .globl css_calc_core_pos_swap_cluster 15*91f16700Schasinglulu .weak plat_is_my_cpu_primary 16*91f16700Schasinglulu 17*91f16700Schasinglulu /* --------------------------------------------------------------------- 18*91f16700Schasinglulu * void plat_secondary_cold_boot_setup(void); 19*91f16700Schasinglulu * 20*91f16700Schasinglulu * In the normal boot flow, cold-booting secondary CPUs is not yet 21*91f16700Schasinglulu * implemented and they panic. 22*91f16700Schasinglulu * 23*91f16700Schasinglulu * When booting an EL3 payload, secondary CPUs are placed in a holding 24*91f16700Schasinglulu * pen, waiting for their mailbox to be populated. Note that all CPUs 25*91f16700Schasinglulu * share the same mailbox ; therefore, populating it will release all 26*91f16700Schasinglulu * CPUs from their holding pen. If finer-grained control is needed then 27*91f16700Schasinglulu * this should be handled in the code that secondary CPUs jump to. 28*91f16700Schasinglulu * --------------------------------------------------------------------- 29*91f16700Schasinglulu */ 30*91f16700Schasinglulufunc plat_secondary_cold_boot_setup 31*91f16700Schasinglulu#ifndef EL3_PAYLOAD_BASE 32*91f16700Schasinglulu /* TODO: Implement secondary CPU cold boot setup on CSS platforms */ 33*91f16700Schasinglulucb_panic: 34*91f16700Schasinglulu b cb_panic 35*91f16700Schasinglulu#else 36*91f16700Schasinglulu mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE 37*91f16700Schasinglulu 38*91f16700Schasinglulu /* Wait until the mailbox gets populated */ 39*91f16700Schasinglulupoll_mailbox: 40*91f16700Schasinglulu ldr x1, [x0] 41*91f16700Schasinglulu cbz x1, 1f 42*91f16700Schasinglulu br x1 43*91f16700Schasinglulu1: 44*91f16700Schasinglulu wfe 45*91f16700Schasinglulu b poll_mailbox 46*91f16700Schasinglulu#endif /* EL3_PAYLOAD_BASE */ 47*91f16700Schasingluluendfunc plat_secondary_cold_boot_setup 48*91f16700Schasinglulu 49*91f16700Schasinglulu /* --------------------------------------------------------------------- 50*91f16700Schasinglulu * uintptr_t plat_get_my_entrypoint (void); 51*91f16700Schasinglulu * 52*91f16700Schasinglulu * Main job of this routine is to distinguish between a cold and a warm 53*91f16700Schasinglulu * boot. On CSS platforms, this distinction is based on the contents of 54*91f16700Schasinglulu * the Trusted Mailbox. It is initialised to zero by the SCP before the 55*91f16700Schasinglulu * AP cores are released from reset. Therefore, a zero mailbox means 56*91f16700Schasinglulu * it's a cold reset. 57*91f16700Schasinglulu * 58*91f16700Schasinglulu * This functions returns the contents of the mailbox, i.e.: 59*91f16700Schasinglulu * - 0 for a cold boot; 60*91f16700Schasinglulu * - the warm boot entrypoint for a warm boot. 61*91f16700Schasinglulu * --------------------------------------------------------------------- 62*91f16700Schasinglulu */ 63*91f16700Schasinglulufunc plat_get_my_entrypoint 64*91f16700Schasinglulu mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE 65*91f16700Schasinglulu ldr x0, [x0] 66*91f16700Schasinglulu ret 67*91f16700Schasingluluendfunc plat_get_my_entrypoint 68*91f16700Schasinglulu 69*91f16700Schasinglulu /* ----------------------------------------------------------- 70*91f16700Schasinglulu * unsigned int css_calc_core_pos_swap_cluster(u_register_t mpidr) 71*91f16700Schasinglulu * Utility function to calculate the core position by 72*91f16700Schasinglulu * swapping the cluster order. This is necessary in order to 73*91f16700Schasinglulu * match the format of the boot information passed by the SCP 74*91f16700Schasinglulu * and read in plat_is_my_cpu_primary below. 75*91f16700Schasinglulu * ----------------------------------------------------------- 76*91f16700Schasinglulu */ 77*91f16700Schasinglulufunc css_calc_core_pos_swap_cluster 78*91f16700Schasinglulu and x1, x0, #MPIDR_CPU_MASK 79*91f16700Schasinglulu and x0, x0, #MPIDR_CLUSTER_MASK 80*91f16700Schasinglulu eor x0, x0, #(1 << MPIDR_AFFINITY_BITS) // swap cluster order 81*91f16700Schasinglulu add x0, x1, x0, LSR #6 82*91f16700Schasinglulu ret 83*91f16700Schasingluluendfunc css_calc_core_pos_swap_cluster 84*91f16700Schasinglulu 85*91f16700Schasinglulu /* ----------------------------------------------------- 86*91f16700Schasinglulu * unsigned int plat_is_my_cpu_primary (void); 87*91f16700Schasinglulu * 88*91f16700Schasinglulu * Find out whether the current cpu is the primary 89*91f16700Schasinglulu * cpu (applicable ony after a cold boot) 90*91f16700Schasinglulu * ----------------------------------------------------- 91*91f16700Schasinglulu */ 92*91f16700Schasinglulu#if CSS_USE_SCMI_SDS_DRIVER 93*91f16700Schasinglulufunc plat_is_my_cpu_primary 94*91f16700Schasinglulu mov x9, x30 95*91f16700Schasinglulu bl plat_my_core_pos 96*91f16700Schasinglulu mov x4, x0 97*91f16700Schasinglulu bl sds_get_primary_cpu_id 98*91f16700Schasinglulu /* Check for error */ 99*91f16700Schasinglulu mov x1, #0xffffffff 100*91f16700Schasinglulu cmp x0, x1 101*91f16700Schasinglulu b.eq 1f 102*91f16700Schasinglulu cmp x0, x4 103*91f16700Schasinglulu cset w0, eq 104*91f16700Schasinglulu ret x9 105*91f16700Schasinglulu1: 106*91f16700Schasinglulu no_ret plat_panic_handler 107*91f16700Schasingluluendfunc plat_is_my_cpu_primary 108*91f16700Schasinglulu#else 109*91f16700Schasinglulufunc plat_is_my_cpu_primary 110*91f16700Schasinglulu mov x9, x30 111*91f16700Schasinglulu bl plat_my_core_pos 112*91f16700Schasinglulu mov_imm x1, SCP_BOOT_CFG_ADDR 113*91f16700Schasinglulu ldr x1, [x1] 114*91f16700Schasinglulu ubfx x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \ 115*91f16700Schasinglulu #PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 116*91f16700Schasinglulu cmp x0, x1 117*91f16700Schasinglulu cset w0, eq 118*91f16700Schasinglulu ret x9 119*91f16700Schasingluluendfunc plat_is_my_cpu_primary 120*91f16700Schasinglulu#endif 121