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