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#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 102 bl plat_is_my_cpu_primary 103 cbnz x0, warm_reset 104warm_reset: 105 mov_imm x1, PLAT_SEC_ENTRY 106 str xzr, [x1] 107 mrs x1, rmr_el3 108 orr x1, x1, #0x02 109 msr rmr_el3, x1 110 isb 111 dsb sy 112#else 113 str xzr, [x4] 114 bl plat_is_my_cpu_primary 115 cbz x0, cpu_in_wfi 116 mov_imm x1, PLAT_SEC_ENTRY 117 str xzr, [x1] 118 mrs x1, rmr_el3 119 orr x1, x1, #0x02 120 msr rmr_el3, x1 121 isb 122 dsb sy 123cpu_in_wfi: 124 wfi 125 b cpu_in_wfi 126#endif 127endfunc warm_reset_req 128 129/* TODO: Zephyr warm reset test */ 130#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 131func plat_get_my_entrypoint 132 ldr x4, =L2_RESET_DONE_REG 133 ldr x5, [x4] 134 ldr x1, =PLAT_L2_RESET_REQ 135 cmp x1, x5 136 b.eq zephyr_reset_req 137 mov_imm x1, PLAT_SEC_ENTRY 138 ldr x0, [x1] 139 ret 140zephyr_reset_req: 141 ldr x0, =0x00 142 ret 143endfunc plat_get_my_entrypoint 144#else 145func plat_get_my_entrypoint 146 ldr x4, =L2_RESET_DONE_REG 147 ldr x5, [x4] 148 ldr x1, =L2_RESET_DONE_STATUS 149 cmp x1, x5 150 b.eq warm_reset_req 151 mov_imm x1, PLAT_SEC_ENTRY 152 ldr x0, [x1] 153 ret 154endfunc plat_get_my_entrypoint 155#endif 156 157 /* --------------------------------------------- 158 * int plat_crash_console_init(void) 159 * Function to initialize the crash console 160 * without a C Runtime to print crash report. 161 * Clobber list : x0, x1, x2 162 * --------------------------------------------- 163 */ 164func plat_crash_console_init 165 mov_imm x0, CRASH_CONSOLE_BASE 166 mov_imm x1, PLAT_UART_CLOCK 167 mov_imm x2, PLAT_BAUDRATE 168 b console_16550_core_init 169endfunc plat_crash_console_init 170 171 /* --------------------------------------------- 172 * int plat_crash_console_putc(void) 173 * Function to print a character on the crash 174 * console without a C Runtime. 175 * Clobber list : x1, x2 176 * --------------------------------------------- 177 */ 178func plat_crash_console_putc 179 mov_imm x1, CRASH_CONSOLE_BASE 180 b console_16550_core_putc 181endfunc plat_crash_console_putc 182 183func plat_crash_console_flush 184 mov_imm x0, CRASH_CONSOLE_BASE 185 b console_16550_core_flush 186endfunc plat_crash_console_flush 187 188 189 /* -------------------------------------------------------- 190 * void platform_mem_init (void); 191 * 192 * Any memory init, relocation to be done before the 193 * platform boots. Called very early in the boot process. 194 * -------------------------------------------------------- 195 */ 196func platform_mem_init 197 mov x0, #0 198 ret 199endfunc platform_mem_init 200 201 /* -------------------------------------------------------- 202 * macro plat_secondary_cpus_bl31_entry; 203 * 204 * el3_entrypoint_common init param configuration. 205 * Called very early in the secondary cores boot process. 206 * -------------------------------------------------------- 207 */ 208func plat_secondary_cpus_bl31_entry 209 el3_entrypoint_common \ 210 _init_sctlr=0 \ 211 _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \ 212 _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ 213 _init_memory=1 \ 214 _init_c_runtime=1 \ 215 _exception_vectors=runtime_exceptions \ 216 _pie_fixup_size=BL31_LIMIT - BL31_BASE 217endfunc plat_secondary_cpus_bl31_entry 218