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