2 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
32 #include <asm_macros.S>
33 #include <bl_common.h>
35 #include <el3_common_macros.S>
36 #include <runtime_svc.h>
37 #include <smcc_helpers.h>
38 #include <smcc_macros.S>
39 #include <xlat_tables_defs.h>
41 .globl sp_min_vector_table
42 .globl sp_min_entrypoint
43 .globl sp_min_warm_entrypoint
46 vector_base sp_min_vector_table
48 b plat_panic_handler /* Undef */
49 b handle_smc /* Syscall */
50 b plat_panic_handler /* Prefetch abort */
51 b plat_panic_handler /* Data abort */
52 b plat_panic_handler /* Reserved */
53 b plat_panic_handler /* IRQ */
54 b plat_panic_handler /* FIQ */
58 * The Cold boot/Reset entrypoint for SP_MIN
60 func sp_min_entrypoint
62 /* ---------------------------------------------------------------
63 * Preceding bootloader has populated r0 with a pointer to a
64 * 'bl_params_t' structure & r1 with a pointer to platform
66 * ---------------------------------------------------------------
71 /* ---------------------------------------------------------------------
72 * For !RESET_TO_SP_MIN systems, only the primary CPU ever reaches
73 * sp_min_entrypoint() during the cold boot flow, so the cold/warm boot
74 * and primary/secondary CPU logic should not be executed in this case.
76 * Also, assume that the previous bootloader has already set up the CPU
77 * endianness and has initialised the memory.
78 * ---------------------------------------------------------------------
80 el3_entrypoint_common \
82 _warm_boot_mailbox=0 \
83 _secondary_cold_boot=0 \
86 _exception_vectors=sp_min_vector_table
88 /* ---------------------------------------------------------------------
89 * Relay the previous bootloader's arguments to the platform layer
90 * ---------------------------------------------------------------------
95 /* ---------------------------------------------------------------------
96 * For RESET_TO_SP_MIN systems which have a programmable reset address,
97 * sp_min_entrypoint() is executed only on the cold boot path so we can
98 * skip the warm boot mailbox mechanism.
99 * ---------------------------------------------------------------------
101 el3_entrypoint_common \
103 _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
104 _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
107 _exception_vectors=sp_min_vector_table
109 /* ---------------------------------------------------------------------
110 * For RESET_TO_SP_MIN systems, BL32 (SP_MIN) is the first bootloader
111 * to run so there's no argument to relay from a previous bootloader.
112 * Zero the arguments passed to the platform layer to reflect that.
113 * ---------------------------------------------------------------------
117 #endif /* RESET_TO_SP_MIN */
119 bl sp_min_early_platform_setup
120 bl sp_min_plat_arch_setup
122 /* Jump to the main function */
125 /* -------------------------------------------------------------
126 * Clean the .data & .bss sections to main memory. This ensures
127 * that any global data which was initialised by the primary CPU
128 * is visible to secondary CPUs before they enable their data
129 * caches and participate in coherency.
130 * -------------------------------------------------------------
132 ldr r0, =__DATA_START__
133 ldr r1, =__DATA_END__
135 bl clean_dcache_range
137 ldr r0, =__BSS_START__
140 bl clean_dcache_range
142 /* Program the registers in cpu_context and exit monitor mode */
146 /* Restore the SCR */
147 ldr r2, [r0, #CTX_REGS_OFFSET + CTX_SCR]
151 /* Restore the SCTLR */
152 ldr r2, [r0, #CTX_REGS_OFFSET + CTX_NS_SCTLR]
156 /* The other cpu_context registers have been copied to smc context */
158 endfunc sp_min_entrypoint
162 * SMC handling function for SP_MIN.
165 smcc_save_gp_mode_regs
167 /* r0 points to smc_context */
168 mov r2, r0 /* handle */
172 * Save SCR in stack. r1 is pushed to meet the 8 byte
173 * stack alignment requirement.
176 and r3, r0, #SCR_NS_BIT /* flags */
178 /* Switch to Secure Mode*/
182 ldr r0, [r2, #SMC_CTX_GPREG_R0] /* smc_fid */
183 /* Check whether an SMC64 is issued */
184 tst r0, #(FUNCID_CC_MASK << FUNCID_CC_SHIFT)
185 beq 1f /* SMC32 is detected */
187 str r0, [r2, #SMC_CTX_GPREG_R0]
189 b 2f /* Skip handling the SMC */
191 mov r1, #0 /* cookie */
192 bl handle_runtime_svc
194 /* r0 points to smc context */
196 /* Restore SCR from stack */
206 * The Warm boot entrypoint for SP_MIN.
208 func sp_min_warm_entrypoint
210 * On the warm boot path, most of the EL3 initialisations performed by
211 * 'el3_entrypoint_common' must be skipped:
213 * - Only when the platform bypasses the BL1/BL32 (SP_MIN) entrypoint by
214 * programming the reset address do we need to set the CPU endianness.
215 * In other cases, we assume this has been taken care by the
218 * - No need to determine the type of boot, we know it is a warm boot.
220 * - Do not try to distinguish between primary and secondary CPUs, this
221 * notion only exists for a cold boot.
223 * - No need to initialise the memory or the C runtime environment,
224 * it has been done once and for all on the cold boot path.
226 el3_entrypoint_common \
227 _set_endian=PROGRAMMABLE_RESET_ADDRESS \
228 _warm_boot_mailbox=0 \
229 _secondary_cold_boot=0 \
232 _exception_vectors=sp_min_vector_table
234 /* --------------------------------------------
235 * Enable the MMU with the DCache disabled. It
236 * is safe to use stacks allocated in normal
237 * memory as a result. All memory accesses are
238 * marked nGnRnE when the MMU is disabled. So
239 * all the stack writes will make it to memory.
240 * All memory accesses are marked Non-cacheable
241 * when the MMU is enabled but D$ is disabled.
242 * So used stack memory is guaranteed to be
243 * visible immediately after the MMU is enabled
244 * Enabling the DCache at the same time as the
245 * MMU can lead to speculatively fetched and
246 * possibly stale stack memory being read from
247 * other caches. This can lead to coherency
249 * --------------------------------------------
251 mov r0, #DISABLE_DCACHE
252 bl bl32_plat_enable_mmu
256 /* Program the registers in cpu_context and exit monitor mode */
260 /* Restore the SCR */
261 ldr r2, [r0, #CTX_REGS_OFFSET + CTX_SCR]
265 /* Restore the SCTLR */
266 ldr r2, [r0, #CTX_REGS_OFFSET + CTX_NS_SCTLR]
271 /* The other cpu_context registers have been copied to smc context */
273 endfunc sp_min_warm_entrypoint
276 * The function to restore the registers from SMC context and return
277 * to the mode restored to SPSR.
279 * Arguments : r0 must point to the SMC context to restore from.
282 smcc_restore_gp_mode_regs