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