1/* 2 * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved. 3 * Copyright (c) 2019-2023, Intel Corporation. All rights reserved. 4 * Copyright (c) 2024, Altera Corporation. All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9#include <arch.h> 10#include <asm_macros.S> 11#include <cpu_macros.S> 12#include <platform_def.h> 13#include <el3_common_macros.S> 14 15 .globl plat_secondary_cold_boot_setup 16 .globl platform_is_primary_cpu 17 .globl plat_is_my_cpu_primary 18 .globl plat_my_core_pos 19 .globl plat_crash_console_init 20 .globl plat_crash_console_putc 21 .globl plat_crash_console_flush 22 .globl platform_mem_init 23 .globl plat_secondary_cpus_bl31_entry 24 25 .globl plat_get_my_entrypoint 26 27 /* ----------------------------------------------------- 28 * void plat_secondary_cold_boot_setup (void); 29 * 30 * This function performs any platform specific actions 31 * needed for a secondary cpu after a cold reset e.g 32 * mark the cpu's presence, mechanism to place it in a 33 * holding pen etc. 34 * ----------------------------------------------------- 35 */ 36func plat_secondary_cold_boot_setup 37 /* Wait until the it gets reset signal from rstmgr gets populated */ 38poll_mailbox: 39#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 40 mov_imm x0, PLAT_SEC_ENTRY 41 cbz x0, poll_mailbox 42 br x0 43#else 44 wfi 45 mov_imm x0, PLAT_SEC_ENTRY 46 ldr x1, [x0] 47 mov_imm x2, PLAT_CPUID_RELEASE 48 ldr x3, [x2] 49 mrs x4, mpidr_el1 50 and x4, x4, #0xff 51 cmp x3, x4 52 b.ne poll_mailbox 53 br x1 54#endif 55endfunc plat_secondary_cold_boot_setup 56 57#if ((PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10) || \ 58 (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || \ 59 (PLATFORM_MODEL == PLAT_SOCFPGA_N5X)) 60 61func platform_is_primary_cpu 62 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 63 cmp x0, #PLAT_PRIMARY_CPU 64 cset x0, eq 65 ret 66endfunc platform_is_primary_cpu 67 68#else 69 70func platform_is_primary_cpu 71 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 72 cmp x0, #(PLAT_PRIMARY_CPU_A76) 73 b.eq primary_cpu 74 cmp x0, #(PLAT_PRIMARY_CPU_A55) 75 b.eq primary_cpu 76primary_cpu: 77 cset x0, eq 78 ret 79endfunc platform_is_primary_cpu 80 81#endif 82 83func plat_is_my_cpu_primary 84 mrs x0, mpidr_el1 85 b platform_is_primary_cpu 86endfunc plat_is_my_cpu_primary 87 88func plat_my_core_pos 89 mrs x0, mpidr_el1 90 and x1, x0, #MPIDR_CPU_MASK 91 and x0, x0, #MPIDR_CLUSTER_MASK 92#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 93 add x0, x1, x0, LSR #8 94#else 95 add x0, x1, x0, LSR #6 96#endif 97 ret 98endfunc plat_my_core_pos 99 100func warm_reset_req 101 str xzr, [x4] 102 bl plat_is_my_cpu_primary 103 cbz x0, cpu_in_wfi 104 mov_imm x1, PLAT_SEC_ENTRY 105 str xzr, [x1] 106 mrs x1, rmr_el3 107 orr x1, x1, #0x02 108 msr rmr_el3, x1 109 isb 110 dsb sy 111cpu_in_wfi: 112 wfi 113 b cpu_in_wfi 114endfunc warm_reset_req 115 116#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 117func plat_get_my_entrypoint 118 ldr x4, =L2_RESET_DONE_REG 119 ldr x5, [x4] 120 121 /* Check for warm reset request */ 122 ldr x1, =L2_RESET_DONE_STATUS 123 cmp x1, x5 124 b.eq warm_reset_req 125 126 /* Check for SMP secondary cores boot request */ 127 ldr x1, =SMP_SEC_CORE_BOOT_REQ 128 cmp x1, x5 129 b.eq smp_request 130 131 /* Otherwise it is cold reset */ 132 mov x0, #0 133 ret 134smp_request: 135 /* 136 * Return the address 'bl31_warm_entrypoint', which is passed to 137 * 'psci_setup' routine as part of BL31 initialization. 138 */ 139 mov_imm x1, PLAT_SEC_ENTRY 140 ldr x0, [x1] 141 /* Clear the mark up before return */ 142 str xzr, [x4] 143 ret 144endfunc plat_get_my_entrypoint 145#else 146func plat_get_my_entrypoint 147 ldr x4, =L2_RESET_DONE_REG 148 ldr x5, [x4] 149 ldr x1, =L2_RESET_DONE_STATUS 150 cmp x1, x5 151 b.eq warm_reset_req 152 mov_imm x1, PLAT_SEC_ENTRY 153 ldr x0, [x1] 154 ret 155endfunc plat_get_my_entrypoint 156#endif 157 158 /* --------------------------------------------- 159 * int plat_crash_console_init(void) 160 * Function to initialize the crash console 161 * without a C Runtime to print crash report. 162 * Clobber list : x0, x1, x2 163 * --------------------------------------------- 164 */ 165func plat_crash_console_init 166 mov_imm x0, CRASH_CONSOLE_BASE 167 mov_imm x1, PLAT_UART_CLOCK 168 mov_imm x2, PLAT_BAUDRATE 169 b console_16550_core_init 170endfunc plat_crash_console_init 171 172 /* --------------------------------------------- 173 * int plat_crash_console_putc(void) 174 * Function to print a character on the crash 175 * console without a C Runtime. 176 * Clobber list : x1, x2 177 * --------------------------------------------- 178 */ 179func plat_crash_console_putc 180 mov_imm x1, CRASH_CONSOLE_BASE 181 b console_16550_core_putc 182endfunc plat_crash_console_putc 183 184func plat_crash_console_flush 185 mov_imm x0, CRASH_CONSOLE_BASE 186 b console_16550_core_flush 187endfunc plat_crash_console_flush 188 189 190 /* -------------------------------------------------------- 191 * void platform_mem_init (void); 192 * 193 * Any memory init, relocation to be done before the 194 * platform boots. Called very early in the boot process. 195 * -------------------------------------------------------- 196 */ 197func platform_mem_init 198 mov x0, #0 199 ret 200endfunc platform_mem_init 201 202 /* -------------------------------------------------------- 203 * macro plat_secondary_cpus_bl31_entry; 204 * 205 * el3_entrypoint_common init param configuration. 206 * Called very early in the secondary cores boot process. 207 * -------------------------------------------------------- 208 */ 209func plat_secondary_cpus_bl31_entry 210 el3_entrypoint_common \ 211 _init_sctlr=0 \ 212 _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \ 213 _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ 214 _init_memory=1 \ 215 _init_c_runtime=1 \ 216 _exception_vectors=runtime_exceptions \ 217 _pie_fixup_size=BL31_LIMIT - BL31_BASE 218endfunc plat_secondary_cpus_bl31_entry 219