1/* 2 * Copyright (C) 2020 Intel Corporation. All rights reserved 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7#include <asm-offsets.h> 8#include <config.h> 9#include <linux/linkage.h> 10#include <asm/macro.h> 11 12ENTRY(lowlevel_init) 13 mov x29, lr /* Save LR */ 14 15#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) 16#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF) 17wait_for_atf: 18 ldr x4, =CPU_RELEASE_ADDR 19 ldr x5, [x4] 20 cbz x5, slave_wait_atf 21 br x5 22slave_wait_atf: 23 branch_if_slave x0, wait_for_atf 24#else 25 branch_if_slave x0, 1f 26#endif 27 ldr x0, =GICD_BASE 28 bl gic_init_secure 291: 30#if defined(CONFIG_GICV3) 31 ldr x0, =GICR_BASE 32 bl gic_init_secure_percpu 33#elif defined(CONFIG_GICV2) 34 ldr x0, =GICD_BASE 35 ldr x1, =GICC_BASE 36 bl gic_init_secure_percpu 37#endif 38#endif 39 40#ifdef CONFIG_ARMV8_MULTIENTRY 41 branch_if_master x0, x1, 2f 42 43 /* 44 * Slave should wait for master clearing spin table. 45 * This sync prevent slaves observing incorrect 46 * value of spin table and jumping to wrong place. 47 */ 48#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) 49#ifdef CONFIG_GICV2 50 ldr x0, =GICC_BASE 51#endif 52 bl gic_wait_for_interrupt 53#endif 54 55 /* 56 * All slaves will enter EL2 and optionally EL1. 57 */ 58 adr x4, lowlevel_in_el2 59 ldr x5, =ES_TO_AARCH64 60 bl armv8_switch_to_el2 61 62lowlevel_in_el2: 63#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 64 adr x4, lowlevel_in_el1 65 ldr x5, =ES_TO_AARCH64 66 bl armv8_switch_to_el1 67 68lowlevel_in_el1: 69#endif 70 71#endif /* CONFIG_ARMV8_MULTIENTRY */ 72 732: 74 mov lr, x29 /* Restore LR */ 75 ret 76ENDPROC(lowlevel_init) 77