1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * arch/arm/cpu/armv8/rcar_gen3/lowlevel_init.S 4 * This file is lowlevel initialize routine. 5 * 6 * (C) Copyright 2015 Renesas Electronics Corporation 7 * 8 * This file is based on the arch/arm/cpu/armv8/start.S 9 * 10 * (C) Copyright 2013 11 * David Feng <fenghua (at) phytium.com.cn> 12 */ 13 14 #include <asm-offsets.h> 15 #include <config.h> 16 #include <linux/linkage.h> 17 #include <asm/macro.h> 18 19 ENTRY(lowlevel_init) 20 mov x29, lr /* Save LR */ 21 22 #ifndef CONFIG_ARMV8_MULTIENTRY 23 /* 24 * For single-entry systems the lowlevel init is very simple. 25 */ 26 ldr x0, =GICD_BASE 27 bl gic_init_secure 28 29 #else /* CONFIG_ARMV8_MULTIENTRY is set */ 30 31 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) 32 branch_if_slave x0, 1f 33 ldr x0, =GICD_BASE 34 bl gic_init_secure 35 1: 36 #if defined(CONFIG_GICV3) 37 ldr x0, =GICR_BASE 38 bl gic_init_secure_percpu 39 #elif defined(CONFIG_GICV2) 40 ldr x0, =GICD_BASE 41 ldr x1, =GICC_BASE 42 bl gic_init_secure_percpu 43 #endif 44 #endif 45 46 branch_if_master x0, x1, 2f 47 48 /* 49 * Slave should wait for master clearing spin table. 50 * This sync prevent salves observing incorrect 51 * value of spin table and jumping to wrong place. 52 */ 53 #if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) 54 #ifdef CONFIG_GICV2 55 ldr x0, =GICC_BASE 56 #endif 57 bl gic_wait_for_interrupt 58 #endif 59 60 /* 61 * All slaves will enter EL2 and optionally EL1. 62 */ 63 adr x4, lowlevel_in_el2 64 ldr x5, =ES_TO_AARCH64 65 bl armv8_switch_to_el2 66 67 lowlevel_in_el2: 68 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 69 adr x4, lowlevel_in_el1 70 ldr x5, =ES_TO_AARCH64 71 bl armv8_switch_to_el1 72 73 lowlevel_in_el1: 74 #endif 75 #endif /* CONFIG_ARMV8_MULTIENTRY */ 76 77 bl s_init 78 79 2: 80 mov lr, x29 /* Restore LR */ 81 ret 82 ENDPROC(lowlevel_init) 83