1/* 2 * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved. 3 * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved. 4 * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9#include <arch.h> 10#include <asm_macros.S> 11#include <drivers/arm/gicv3.h> 12 13#include <platform_def.h> 14 15 .globl plat_secondary_cold_boot_setup 16 .globl plat_is_my_cpu_primary 17 .globl platform_mem_init 18 .globl plat_my_core_pos 19 .globl plat_core_pos_by_mpidr 20 .extern plat_primary_cpu_core 21 22 /* ----------------------------------------------------- 23 * void plat_secondary_cold_boot_setup (void); 24 * 25 * This function performs any platform specific actions 26 * needed for a secondary cpu after a cold reset e.g 27 * mark the cpu's presence, mechanism to place it in a 28 * holding pen etc. 29 * TODO: Should we read the PSYS register to make sure 30 * that the request has gone through. 31 * ----------------------------------------------------- 32 */ 33func plat_secondary_cold_boot_setup 34 mrs x0, mpidr_el1 35 36 /* 37 * There is no sane reason to come out of this wfi. This 38 * cpu will be powered on and reset by the cpu_on pm api 39 */ 40 dsb sy 41 bl plat_panic_handler 42endfunc plat_secondary_cold_boot_setup 43 44func plat_is_my_cpu_primary 45 mov x9, x30 46 bl plat_my_core_pos 47 48 /* Load address of var into x2. */ 49 ldr x2, =plat_primary_cpu_core 50 /* Load var value into x3 */ 51 ldr w3, [x2] 52 mov w4, #PLAT_INVALID_CPU_CORE 53 cmp w3, w4 54 /* On first instance (as it equals) primary core pos is updated. */ 55 b.ne skip_var_update 56 57 str w0, [x2] 58 mov x3, x0 59 60skip_var_update: 61 cmp x0, x3 62 cset x0, eq 63 ret x9 64endfunc plat_is_my_cpu_primary 65 66 /* ----------------------------------------------------- 67 * unsigned int plat_my_core_pos(void) 68 * This function uses the plat_core_pos_by_mpidr() 69 * definition to get the index of the calling CPU. 70 * ----------------------------------------------------- 71 */ 72func plat_my_core_pos 73 mrs x0, mpidr_el1 74 b plat_core_pos_by_mpidr 75endfunc plat_my_core_pos 76 77 /*---------------------------------------------------------------------- 78 * unsigned int plat_core_pos_by_mpidr(u_register_t mpid) 79 * 80 * Function to calculate the core position 81 * 82 * clobbers: x0 - x3 83 * --------------------------------------------------------------------- 84 */ 85func plat_core_pos_by_mpidr 86 87 /* Extract individual affinity fields from MPIDR */ 88 ubfx x1, x0, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS 89 ubfx x2, x0, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS 90 91 /* check if cpu_id valid */ 92 cmp x2, #PLATFORM_CORE_COUNT_PER_CLUSTER 93 b.hi error_invalid_core 94 95 /* check if cluster valid */ 96 cmp x1, #PLATFORM_CLUSTER_COUNT 97 b.hi error_invalid_cluster 98 99 /* Compute linear position */ 100 mov x3, #PLATFORM_CORE_COUNT_PER_CLUSTER 101 madd x0, x1, x3, x2 102 ret 103error_invalid_cluster: 104 mov x0, #E_INVALID_CLUSTER_COUNT 105 ret 106error_invalid_core: 107 mov x0, #E_INVALID_CORE_COUNT 108 ret 109endfunc plat_core_pos_by_mpidr 110 111 /* --------------------------------------------------------------------- 112 * We don't need to carry out any memory initialization on platform 113 * The Secure RAM is accessible straight away. 114 * --------------------------------------------------------------------- 115 */ 116func platform_mem_init 117 ret 118endfunc platform_mem_init 119