blob: 612ea8a0371fd5acde0171f96af10d2d66df0f4c [file] [log] [blame]
Chee Hong Angbb272ed2020-12-24 18:20:58 +08001/*
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)