13f7b1490SHadi Asyrafi/* 26197dc98SJit Loon Lim * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved. 37ac7dadbSSieu Mun Tang * Copyright (c) 2019-2023, Intel Corporation. All rights reserved. 47ac7dadbSSieu Mun Tang * Copyright (c) 2024, Altera Corporation. All rights reserved. 53f7b1490SHadi Asyrafi * 63f7b1490SHadi Asyrafi * SPDX-License-Identifier: BSD-3-Clause 73f7b1490SHadi Asyrafi */ 83f7b1490SHadi Asyrafi 93f7b1490SHadi Asyrafi#include <arch.h> 103f7b1490SHadi Asyrafi#include <asm_macros.S> 113f7b1490SHadi Asyrafi#include <cpu_macros.S> 123f7b1490SHadi Asyrafi#include <platform_def.h> 132db1e766SHadi Asyrafi#include <el3_common_macros.S> 143f7b1490SHadi Asyrafi 153f7b1490SHadi Asyrafi .globl plat_secondary_cold_boot_setup 163f7b1490SHadi Asyrafi .globl platform_is_primary_cpu 173f7b1490SHadi Asyrafi .globl plat_is_my_cpu_primary 183f7b1490SHadi Asyrafi .globl plat_my_core_pos 193f7b1490SHadi Asyrafi .globl plat_crash_console_init 203f7b1490SHadi Asyrafi .globl plat_crash_console_putc 213f7b1490SHadi Asyrafi .globl plat_crash_console_flush 223f7b1490SHadi Asyrafi .globl platform_mem_init 232db1e766SHadi Asyrafi .globl plat_secondary_cpus_bl31_entry 243f7b1490SHadi Asyrafi 253f7b1490SHadi Asyrafi .globl plat_get_my_entrypoint 263f7b1490SHadi Asyrafi 273f7b1490SHadi Asyrafi /* ----------------------------------------------------- 283f7b1490SHadi Asyrafi * void plat_secondary_cold_boot_setup (void); 293f7b1490SHadi Asyrafi * 303f7b1490SHadi Asyrafi * This function performs any platform specific actions 313f7b1490SHadi Asyrafi * needed for a secondary cpu after a cold reset e.g 323f7b1490SHadi Asyrafi * mark the cpu's presence, mechanism to place it in a 333f7b1490SHadi Asyrafi * holding pen etc. 343f7b1490SHadi Asyrafi * ----------------------------------------------------- 353f7b1490SHadi Asyrafi */ 363f7b1490SHadi Asyrafifunc plat_secondary_cold_boot_setup 373f7b1490SHadi Asyrafi /* Wait until the it gets reset signal from rstmgr gets populated */ 383f7b1490SHadi Asyrafipoll_mailbox: 397931d332SJit Loon Lim#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 407931d332SJit Loon Lim mov_imm x0, PLAT_SEC_ENTRY 417931d332SJit Loon Lim cbz x0, poll_mailbox 427931d332SJit Loon Lim br x0 437931d332SJit Loon Lim#else 443f7b1490SHadi Asyrafi wfi 453f7b1490SHadi Asyrafi mov_imm x0, PLAT_SEC_ENTRY 463f7b1490SHadi Asyrafi ldr x1, [x0] 473f7b1490SHadi Asyrafi mov_imm x2, PLAT_CPUID_RELEASE 483f7b1490SHadi Asyrafi ldr x3, [x2] 493f7b1490SHadi Asyrafi mrs x4, mpidr_el1 503f7b1490SHadi Asyrafi and x4, x4, #0xff 513f7b1490SHadi Asyrafi cmp x3, x4 523f7b1490SHadi Asyrafi b.ne poll_mailbox 533f7b1490SHadi Asyrafi br x1 547931d332SJit Loon Lim#endif 553f7b1490SHadi Asyrafiendfunc plat_secondary_cold_boot_setup 563f7b1490SHadi Asyrafi 577931d332SJit Loon Lim#if ((PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10) || \ 587931d332SJit Loon Lim (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || \ 597931d332SJit Loon Lim (PLATFORM_MODEL == PLAT_SOCFPGA_N5X)) 607931d332SJit Loon Lim 613f7b1490SHadi Asyrafifunc platform_is_primary_cpu 623f7b1490SHadi Asyrafi and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 633f7b1490SHadi Asyrafi cmp x0, #PLAT_PRIMARY_CPU 643f7b1490SHadi Asyrafi cset x0, eq 653f7b1490SHadi Asyrafi ret 663f7b1490SHadi Asyrafiendfunc platform_is_primary_cpu 673f7b1490SHadi Asyrafi 687931d332SJit Loon Lim#else 697931d332SJit Loon Lim 707931d332SJit Loon Limfunc platform_is_primary_cpu 717931d332SJit Loon Lim and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 727931d332SJit Loon Lim cmp x0, #(PLAT_PRIMARY_CPU_A76) 737931d332SJit Loon Lim b.eq primary_cpu 747931d332SJit Loon Lim cmp x0, #(PLAT_PRIMARY_CPU_A55) 757931d332SJit Loon Lim b.eq primary_cpu 767931d332SJit Loon Limprimary_cpu: 777931d332SJit Loon Lim cset x0, eq 787931d332SJit Loon Lim ret 797931d332SJit Loon Limendfunc platform_is_primary_cpu 807931d332SJit Loon Lim 817931d332SJit Loon Lim#endif 827931d332SJit Loon Lim 833f7b1490SHadi Asyrafifunc plat_is_my_cpu_primary 843f7b1490SHadi Asyrafi mrs x0, mpidr_el1 853f7b1490SHadi Asyrafi b platform_is_primary_cpu 863f7b1490SHadi Asyrafiendfunc plat_is_my_cpu_primary 873f7b1490SHadi Asyrafi 883f7b1490SHadi Asyrafifunc plat_my_core_pos 893f7b1490SHadi Asyrafi mrs x0, mpidr_el1 903f7b1490SHadi Asyrafi and x1, x0, #MPIDR_CPU_MASK 913f7b1490SHadi Asyrafi and x0, x0, #MPIDR_CLUSTER_MASK 927931d332SJit Loon Lim#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 937931d332SJit Loon Lim add x0, x1, x0, LSR #8 947931d332SJit Loon Lim#else 953f7b1490SHadi Asyrafi add x0, x1, x0, LSR #6 967931d332SJit Loon Lim#endif 973f7b1490SHadi Asyrafi ret 983f7b1490SHadi Asyrafiendfunc plat_my_core_pos 993f7b1490SHadi Asyrafi 10032cf34acSHadi Asyrafifunc warm_reset_req 101*646a9a16SJit Loon Lim#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 102*646a9a16SJit Loon Lim /* Clear the markup before going for warm reset */ 103*646a9a16SJit Loon Lim bic x2, x2, #BS_REG_MAGIC_KEYS_MASK 104*646a9a16SJit Loon Lim /* Check if the address is 64 bit aligned or not */ 105*646a9a16SJit Loon Lim ldr x4, =L2_RESET_DONE_REG 106*646a9a16SJit Loon Lim tst x4, #ALIGN_CHECK_64BIT_MASK 107*646a9a16SJit Loon Lim b.ne unaligned_store 108*646a9a16SJit Loon Lim /* Device memory address is aligned, store the value directly */ 109*646a9a16SJit Loon Lim str x2, [x4] 110*646a9a16SJit Loon Lim b continue_warm_reset 111*646a9a16SJit Loon Lim 112*646a9a16SJit Loon Lim /* Unaligned store, use byte by byte method to store */ 113*646a9a16SJit Loon Limunaligned_store: 114*646a9a16SJit Loon Lim strb w2, [x4] 115*646a9a16SJit Loon Lim lsr x2, x2, #8 116*646a9a16SJit Loon Lim add x4, x4, #1 117*646a9a16SJit Loon Lim strb w2, [x4] 118*646a9a16SJit Loon Lim lsr x2, x2, #8 119*646a9a16SJit Loon Lim add x4, x4, #1 120*646a9a16SJit Loon Lim strb w2, [x4] 121*646a9a16SJit Loon Lim lsr x2, x2, #8 122*646a9a16SJit Loon Lim add x4, x4, #1 123*646a9a16SJit Loon Lim strb w2, [x4] 124*646a9a16SJit Loon Lim#else 125*646a9a16SJit Loon Lim /* Clear the markup before going for warm reset */ 126*646a9a16SJit Loon Lim bic x2, x2, #BS_REG_MAGIC_KEYS_MASK 127*646a9a16SJit Loon Lim str x2, [x4] 128*646a9a16SJit Loon Lim#endif 129*646a9a16SJit Loon Lim 130*646a9a16SJit Loon Limcontinue_warm_reset: 13132cf34acSHadi Asyrafi bl plat_is_my_cpu_primary 13232cf34acSHadi Asyrafi cbz x0, cpu_in_wfi 13332cf34acSHadi Asyrafi mov_imm x1, PLAT_SEC_ENTRY 13432cf34acSHadi Asyrafi str xzr, [x1] 13532cf34acSHadi Asyrafi mrs x1, rmr_el3 13632cf34acSHadi Asyrafi orr x1, x1, #0x02 13732cf34acSHadi Asyrafi msr rmr_el3, x1 13832cf34acSHadi Asyrafi isb 13932cf34acSHadi Asyrafi dsb sy 14032cf34acSHadi Asyraficpu_in_wfi: 14132cf34acSHadi Asyrafi wfi 14232cf34acSHadi Asyrafi b cpu_in_wfi 14332cf34acSHadi Asyrafiendfunc warm_reset_req 14432cf34acSHadi Asyrafi 1457931d332SJit Loon Lim#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 1467931d332SJit Loon Limfunc plat_get_my_entrypoint 1477931d332SJit Loon Lim ldr x4, =L2_RESET_DONE_REG 148*646a9a16SJit Loon Lim 149*646a9a16SJit Loon Lim /* Check if the address is 64 bit aligned or not */ 150*646a9a16SJit Loon Lim tst x4, #ALIGN_CHECK_64BIT_MASK 151*646a9a16SJit Loon Lim b.ne unaligned_load 152*646a9a16SJit Loon Lim 153*646a9a16SJit Loon Lim /* Device memory address is aligned, load the value directly */ 154*646a9a16SJit Loon Lim ldr x1, [x4] 155*646a9a16SJit Loon Lim b events_check 156*646a9a16SJit Loon Lim 157*646a9a16SJit Loon Lim /* 158*646a9a16SJit Loon Lim * It is unaligned device memory access. Read only LSB 32 bits 159*646a9a16SJit Loon Lim * byte by byte and combine them to get the 32 bit value. 160*646a9a16SJit Loon Lim */ 161*646a9a16SJit Loon Limunaligned_load: 162*646a9a16SJit Loon Lim ldrb w1, [x4] 163*646a9a16SJit Loon Lim ldrb w2, [x4, #1] 164*646a9a16SJit Loon Lim ldrb w3, [x4, #2] 165*646a9a16SJit Loon Lim ldrb w4, [x4, #3] 166*646a9a16SJit Loon Lim orr x1, x1, x2, lsl #8 167*646a9a16SJit Loon Lim orr x1, x1, x3, lsl #16 168*646a9a16SJit Loon Lim orr x1, x1, x4, lsl #24 169*646a9a16SJit Loon Lim 170*646a9a16SJit Loon Limevents_check: 171*646a9a16SJit Loon Lim /* Keep a backup of the boot scratch register contents */ 172*646a9a16SJit Loon Lim mov x2, x1 173*646a9a16SJit Loon Lim 174*646a9a16SJit Loon Lim /* Mask and get the required bits */ 175*646a9a16SJit Loon Lim and x1, x1, #BS_REG_MAGIC_KEYS_MASK 176c1253b24SSieu Mun Tang 177c1253b24SSieu Mun Tang /* Check for warm reset request */ 178*646a9a16SJit Loon Lim ldr x5, =L2_RESET_DONE_STATUS 1797931d332SJit Loon Lim cmp x1, x5 180c1253b24SSieu Mun Tang b.eq warm_reset_req 181c1253b24SSieu Mun Tang 182c1253b24SSieu Mun Tang /* Check for SMP secondary cores boot request */ 183*646a9a16SJit Loon Lim ldr x5, =SMP_SEC_CORE_BOOT_REQ 184c1253b24SSieu Mun Tang cmp x1, x5 185c1253b24SSieu Mun Tang b.eq smp_request 186c1253b24SSieu Mun Tang 187*646a9a16SJit Loon Lim /* Otherwise it is a cold reset request */ 188c1253b24SSieu Mun Tang mov x0, #0 189c1253b24SSieu Mun Tang ret 190*646a9a16SJit Loon Lim 191c1253b24SSieu Mun Tangsmp_request: 192c1253b24SSieu Mun Tang /* 193*646a9a16SJit Loon Lim * On the SMP boot request, return the address 'bl31_warm_entrypoint', 194*646a9a16SJit Loon Lim * which is passed to 'psci_setup' routine as part of BL31 195*646a9a16SJit Loon Lim * initialization. 196c1253b24SSieu Mun Tang */ 197*646a9a16SJit Loon Lim ldr x1, =PLAT_SEC_ENTRY 1987931d332SJit Loon Lim ldr x0, [x1] 1997931d332SJit Loon Lim ret 2007931d332SJit Loon Limendfunc plat_get_my_entrypoint 2017931d332SJit Loon Lim#else 2023f7b1490SHadi Asyrafifunc plat_get_my_entrypoint 20332cf34acSHadi Asyrafi ldr x4, =L2_RESET_DONE_REG 20432cf34acSHadi Asyrafi ldr x5, [x4] 205*646a9a16SJit Loon Lim 206*646a9a16SJit Loon Lim /* Keep a backup of the boot scratch register contents */ 207*646a9a16SJit Loon Lim mov x2, x5 208*646a9a16SJit Loon Lim 209*646a9a16SJit Loon Lim /* Mask and get only the required bits */ 210*646a9a16SJit Loon Lim and x5, x5, #BS_REG_MAGIC_KEYS_MASK 211*646a9a16SJit Loon Lim 212*646a9a16SJit Loon Lim /* Check for warm reset request */ 21332cf34acSHadi Asyrafi ldr x1, =L2_RESET_DONE_STATUS 21432cf34acSHadi Asyrafi cmp x1, x5 21532cf34acSHadi Asyrafi b.eq warm_reset_req 2163f7b1490SHadi Asyrafi mov_imm x1, PLAT_SEC_ENTRY 2173f7b1490SHadi Asyrafi ldr x0, [x1] 2183f7b1490SHadi Asyrafi ret 2193f7b1490SHadi Asyrafiendfunc plat_get_my_entrypoint 2207931d332SJit Loon Lim#endif 22132cf34acSHadi Asyrafi 2223f7b1490SHadi Asyrafi /* --------------------------------------------- 2233f7b1490SHadi Asyrafi * int plat_crash_console_init(void) 2243f7b1490SHadi Asyrafi * Function to initialize the crash console 2253f7b1490SHadi Asyrafi * without a C Runtime to print crash report. 2263f7b1490SHadi Asyrafi * Clobber list : x0, x1, x2 2273f7b1490SHadi Asyrafi * --------------------------------------------- 2283f7b1490SHadi Asyrafi */ 2293f7b1490SHadi Asyrafifunc plat_crash_console_init 230447e699fSBoon Khai Ng mov_imm x0, CRASH_CONSOLE_BASE 2313f7b1490SHadi Asyrafi mov_imm x1, PLAT_UART_CLOCK 2323f7b1490SHadi Asyrafi mov_imm x2, PLAT_BAUDRATE 2333f7b1490SHadi Asyrafi b console_16550_core_init 2343f7b1490SHadi Asyrafiendfunc plat_crash_console_init 2353f7b1490SHadi Asyrafi 2363f7b1490SHadi Asyrafi /* --------------------------------------------- 2373f7b1490SHadi Asyrafi * int plat_crash_console_putc(void) 2383f7b1490SHadi Asyrafi * Function to print a character on the crash 2393f7b1490SHadi Asyrafi * console without a C Runtime. 2403f7b1490SHadi Asyrafi * Clobber list : x1, x2 2413f7b1490SHadi Asyrafi * --------------------------------------------- 2423f7b1490SHadi Asyrafi */ 2433f7b1490SHadi Asyrafifunc plat_crash_console_putc 244447e699fSBoon Khai Ng mov_imm x1, CRASH_CONSOLE_BASE 2453f7b1490SHadi Asyrafi b console_16550_core_putc 2463f7b1490SHadi Asyrafiendfunc plat_crash_console_putc 2473f7b1490SHadi Asyrafi 2483f7b1490SHadi Asyrafifunc plat_crash_console_flush 2493f7b1490SHadi Asyrafi mov_imm x0, CRASH_CONSOLE_BASE 2503f7b1490SHadi Asyrafi b console_16550_core_flush 2513f7b1490SHadi Asyrafiendfunc plat_crash_console_flush 2523f7b1490SHadi Asyrafi 2533f7b1490SHadi Asyrafi 2543f7b1490SHadi Asyrafi /* -------------------------------------------------------- 2553f7b1490SHadi Asyrafi * void platform_mem_init (void); 2563f7b1490SHadi Asyrafi * 2573f7b1490SHadi Asyrafi * Any memory init, relocation to be done before the 2583f7b1490SHadi Asyrafi * platform boots. Called very early in the boot process. 2593f7b1490SHadi Asyrafi * -------------------------------------------------------- 2603f7b1490SHadi Asyrafi */ 2613f7b1490SHadi Asyrafifunc platform_mem_init 2623f7b1490SHadi Asyrafi mov x0, #0 2633f7b1490SHadi Asyrafi ret 2643f7b1490SHadi Asyrafiendfunc platform_mem_init 2652db1e766SHadi Asyrafi 2667931d332SJit Loon Lim /* -------------------------------------------------------- 2677931d332SJit Loon Lim * macro plat_secondary_cpus_bl31_entry; 2687931d332SJit Loon Lim * 2697931d332SJit Loon Lim * el3_entrypoint_common init param configuration. 2707931d332SJit Loon Lim * Called very early in the secondary cores boot process. 2717931d332SJit Loon Lim * -------------------------------------------------------- 2727931d332SJit Loon Lim */ 2732db1e766SHadi Asyrafifunc plat_secondary_cpus_bl31_entry 2742db1e766SHadi Asyrafi el3_entrypoint_common \ 2752db1e766SHadi Asyrafi _init_sctlr=0 \ 2762db1e766SHadi Asyrafi _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \ 2772db1e766SHadi Asyrafi _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ 2782db1e766SHadi Asyrafi _init_memory=1 \ 2792db1e766SHadi Asyrafi _init_c_runtime=1 \ 2802db1e766SHadi Asyrafi _exception_vectors=runtime_exceptions \ 2812db1e766SHadi Asyrafi _pie_fixup_size=BL31_LIMIT - BL31_BASE 2822db1e766SHadi Asyrafiendfunc plat_secondary_cpus_bl31_entry 283