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