summaryrefslogtreecommitdiffstats
path: root/bl2
diff options
context:
space:
mode:
Diffstat (limited to 'bl2')
-rw-r--r--bl2/aarch32/bl2_arch_setup.c16
-rw-r--r--bl2/aarch32/bl2_el3_entrypoint.S57
-rw-r--r--bl2/aarch32/bl2_el3_exceptions.S21
-rw-r--r--bl2/aarch32/bl2_entrypoint.S136
-rw-r--r--bl2/aarch32/bl2_run_next_image.S46
-rw-r--r--bl2/aarch64/bl2_arch_setup.c19
-rw-r--r--bl2/aarch64/bl2_el3_entrypoint.S72
-rw-r--r--bl2/aarch64/bl2_el3_exceptions.S131
-rw-r--r--bl2/aarch64/bl2_entrypoint.S141
-rw-r--r--bl2/aarch64/bl2_rme_entrypoint.S67
-rw-r--r--bl2/aarch64/bl2_run_next_image.S36
-rw-r--r--bl2/bl2.ld.S133
-rw-r--r--bl2/bl2.mk55
-rw-r--r--bl2/bl2_el3.ld.S221
-rw-r--r--bl2/bl2_image_load_v2.c110
-rw-r--r--bl2/bl2_main.c169
-rw-r--r--bl2/bl2_private.h24
17 files changed, 1454 insertions, 0 deletions
diff --git a/bl2/aarch32/bl2_arch_setup.c b/bl2/aarch32/bl2_arch_setup.c
new file mode 100644
index 0000000..4fd8d07
--- /dev/null
+++ b/bl2/aarch32/bl2_arch_setup.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "../bl2_private.h"
+
+/*******************************************************************************
+ * Place holder function to perform any Secure SVC specific architectural
+ * setup. At the moment there is nothing to do.
+ ******************************************************************************/
+void bl2_arch_setup(void)
+{
+
+}
diff --git a/bl2/aarch32/bl2_el3_entrypoint.S b/bl2/aarch32/bl2_el3_entrypoint.S
new file mode 100644
index 0000000..40154aa
--- /dev/null
+++ b/bl2/aarch32/bl2_el3_entrypoint.S
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <el3_common_macros.S>
+
+ .globl bl2_entrypoint
+
+
+func bl2_entrypoint
+ /* Save arguments x0-x3 from previous Boot loader */
+ mov r9, r0
+ mov r10, r1
+ mov r11, r2
+ mov r12, r3
+
+ el3_entrypoint_common \
+ _init_sctlr=1 \
+ _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
+ _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
+ _init_memory=1 \
+ _init_c_runtime=1 \
+ _exception_vectors=bl2_vector_table \
+ _pie_fixup_size=0
+
+ /*
+ * Restore parameters of boot rom
+ */
+ mov r0, r9
+ mov r1, r10
+ mov r2, r11
+ mov r3, r12
+
+ /* ---------------------------------------------
+ * Perform BL2 setup
+ * ---------------------------------------------
+ */
+ bl bl2_el3_setup
+
+ /* ---------------------------------------------
+ * Jump to main function.
+ * ---------------------------------------------
+ */
+ bl bl2_main
+
+ /* ---------------------------------------------
+ * Should never reach this point.
+ * ---------------------------------------------
+ */
+ no_ret plat_panic_handler
+
+endfunc bl2_entrypoint
diff --git a/bl2/aarch32/bl2_el3_exceptions.S b/bl2/aarch32/bl2_el3_exceptions.S
new file mode 100644
index 0000000..eaa2582
--- /dev/null
+++ b/bl2/aarch32/bl2_el3_exceptions.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+
+ .globl bl2_vector_table
+
+vector_base bl2_vector_table
+ b bl2_entrypoint
+ b report_exception /* Undef */
+ b report_exception /* SVC call */
+ b report_prefetch_abort /* Prefetch abort */
+ b report_data_abort /* Data abort */
+ b report_exception /* Reserved */
+ b report_exception /* IRQ */
+ b report_exception /* FIQ */
diff --git a/bl2/aarch32/bl2_entrypoint.S b/bl2/aarch32/bl2_entrypoint.S
new file mode 100644
index 0000000..678d9c2
--- /dev/null
+++ b/bl2/aarch32/bl2_entrypoint.S
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+
+ .globl bl2_vector_table
+ .globl bl2_entrypoint
+
+
+vector_base bl2_vector_table
+ b bl2_entrypoint
+ b report_exception /* Undef */
+ b report_exception /* SVC call */
+ b report_prefetch_abort /* Prefetch abort */
+ b report_data_abort /* Data abort */
+ b report_exception /* Reserved */
+ b report_exception /* IRQ */
+ b report_exception /* FIQ */
+
+
+func bl2_entrypoint
+ /*---------------------------------------------
+ * Save arguments x0 - x3 from BL1 for future
+ * use.
+ * ---------------------------------------------
+ */
+ mov r9, r0
+ mov r10, r1
+ mov r11, r2
+ mov r12, r3
+
+ /* ---------------------------------------------
+ * Set the exception vector to something sane.
+ * ---------------------------------------------
+ */
+ ldr r0, =bl2_vector_table
+ stcopr r0, VBAR
+ isb
+
+ /* --------------------------------------------------------
+ * Enable the instruction cache - disable speculative loads
+ * --------------------------------------------------------
+ */
+ ldcopr r0, SCTLR
+ orr r0, r0, #SCTLR_I_BIT
+ bic r0, r0, #SCTLR_DSSBS_BIT
+ stcopr r0, SCTLR
+ isb
+
+ /* ---------------------------------------------
+ * Since BL2 executes after BL1, it is assumed
+ * here that BL1 has already has done the
+ * necessary register initializations.
+ * ---------------------------------------------
+ */
+
+ /* ---------------------------------------------
+ * Invalidate the RW memory used by the BL2
+ * image. This includes the data and NOBITS
+ * sections. This is done to safeguard against
+ * possible corruption of this memory by dirty
+ * cache lines in a system cache as a result of
+ * use by an earlier boot loader stage.
+ * ---------------------------------------------
+ */
+ ldr r0, =__RW_START__
+ ldr r1, =__RW_END__
+ sub r1, r1, r0
+ bl inv_dcache_range
+
+ /* ---------------------------------------------
+ * Zero out NOBITS sections. There are 2 of them:
+ * - the .bss section;
+ * - the coherent memory section.
+ * ---------------------------------------------
+ */
+ ldr r0, =__BSS_START__
+ ldr r1, =__BSS_END__
+ sub r1, r1, r0
+ bl zeromem
+
+#if USE_COHERENT_MEM
+ ldr r0, =__COHERENT_RAM_START__
+ ldr r1, =__COHERENT_RAM_END_UNALIGNED__
+ sub r1, r1, r0
+ bl zeromem
+#endif
+
+ /* --------------------------------------------
+ * Allocate a stack whose memory will be marked
+ * as Normal-IS-WBWA when the MMU is enabled.
+ * There is no risk of reading stale stack
+ * memory after enabling the MMU as only the
+ * primary cpu is running at the moment.
+ * --------------------------------------------
+ */
+ bl plat_set_my_stack
+
+ /* ---------------------------------------------
+ * Initialize the stack protector canary before
+ * any C code is called.
+ * ---------------------------------------------
+ */
+#if STACK_PROTECTOR_ENABLED
+ bl update_stack_protector_canary
+#endif
+
+ /* ---------------------------------------------
+ * Perform BL2 setup
+ * ---------------------------------------------
+ */
+ mov r0, r9
+ mov r1, r10
+ mov r2, r11
+ mov r3, r12
+
+ bl bl2_setup
+
+ /* ---------------------------------------------
+ * Jump to main function.
+ * ---------------------------------------------
+ */
+ bl bl2_main
+
+ /* ---------------------------------------------
+ * Should never reach this point.
+ * ---------------------------------------------
+ */
+ no_ret plat_panic_handler
+
+endfunc bl2_entrypoint
diff --git a/bl2/aarch32/bl2_run_next_image.S b/bl2/aarch32/bl2_run_next_image.S
new file mode 100644
index 0000000..0b3554e
--- /dev/null
+++ b/bl2/aarch32/bl2_run_next_image.S
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+
+ .globl bl2_run_next_image
+
+
+func bl2_run_next_image
+ mov r8,r0
+
+ /*
+ * MMU needs to be disabled because both BL2 and BL32 execute
+ * in PL1, and therefore share the same address space.
+ * BL32 will initialize the address space according to its
+ * own requirement.
+ */
+ bl disable_mmu_icache_secure
+ stcopr r0, TLBIALL
+ dsb sy
+ isb
+ mov r0, r8
+ bl bl2_el3_plat_prepare_exit
+
+ /*
+ * Extract PC and SPSR based on struct `entry_point_info_t`
+ * and load it in LR and SPSR registers respectively.
+ */
+ ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET]
+ ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)]
+ msr spsr_xc, r1
+
+ /* Some BL32 stages expect lr_svc to provide the BL33 entry address */
+ cps #MODE32_svc
+ ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET]
+ cps #MODE32_mon
+
+ add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET
+ ldm r8, {r0, r1, r2, r3}
+ exception_return
+endfunc bl2_run_next_image
diff --git a/bl2/aarch64/bl2_arch_setup.c b/bl2/aarch64/bl2_arch_setup.c
new file mode 100644
index 0000000..54052f7
--- /dev/null
+++ b/bl2/aarch64/bl2_arch_setup.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include "../bl2_private.h"
+
+/*******************************************************************************
+ * Place holder function to perform any S-EL1 specific architectural setup. At
+ * the moment there is nothing to do.
+ ******************************************************************************/
+void bl2_arch_setup(void)
+{
+ /* Give access to FP/SIMD registers */
+ write_cpacr(CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
+}
diff --git a/bl2/aarch64/bl2_el3_entrypoint.S b/bl2/aarch64/bl2_el3_entrypoint.S
new file mode 100644
index 0000000..45bac7d
--- /dev/null
+++ b/bl2/aarch64/bl2_el3_entrypoint.S
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <el3_common_macros.S>
+
+ .globl bl2_entrypoint
+
+#if BL2_IN_XIP_MEM
+#define FIXUP_SIZE 0
+#else
+#define FIXUP_SIZE ((BL2_LIMIT) - (BL2_BASE))
+#endif
+
+func bl2_entrypoint
+ /* Save arguments x0-x3 from previous Boot loader */
+ mov x20, x0
+ mov x21, x1
+ mov x22, x2
+ mov x23, x3
+
+ el3_entrypoint_common \
+ _init_sctlr=1 \
+ _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
+ _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
+ _init_memory=1 \
+ _init_c_runtime=1 \
+ _exception_vectors=bl2_el3_exceptions \
+ _pie_fixup_size=FIXUP_SIZE
+
+ /* ---------------------------------------------
+ * Restore parameters of boot rom
+ * ---------------------------------------------
+ */
+ mov x0, x20
+ mov x1, x21
+ mov x2, x22
+ mov x3, x23
+
+ /* ---------------------------------------------
+ * Perform BL2 setup
+ * ---------------------------------------------
+ */
+ bl bl2_el3_setup
+
+#if ENABLE_PAUTH
+ /* ---------------------------------------------
+ * Program APIAKey_EL1 and enable pointer authentication.
+ * ---------------------------------------------
+ */
+ bl pauth_init_enable_el3
+#endif /* ENABLE_PAUTH */
+
+ /* ---------------------------------------------
+ * Jump to main function.
+ * ---------------------------------------------
+ */
+ bl bl2_main
+
+ /* ---------------------------------------------
+ * Should never reach this point.
+ * ---------------------------------------------
+ */
+ no_ret plat_panic_handler
+endfunc bl2_entrypoint
diff --git a/bl2/aarch64/bl2_el3_exceptions.S b/bl2/aarch64/bl2_el3_exceptions.S
new file mode 100644
index 0000000..3d58051
--- /dev/null
+++ b/bl2/aarch64/bl2_el3_exceptions.S
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl1/bl1.h>
+#include <common/bl_common.h>
+#include <context.h>
+
+/* -----------------------------------------------------------------------------
+ * Very simple stackless exception handlers used by BL2.
+ * -----------------------------------------------------------------------------
+ */
+ .globl bl2_el3_exceptions
+
+vector_base bl2_el3_exceptions
+
+ /* -----------------------------------------------------
+ * Current EL with SP0 : 0x0 - 0x200
+ * -----------------------------------------------------
+ */
+vector_entry SynchronousExceptionSP0
+ mov x0, #SYNC_EXCEPTION_SP_EL0
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SynchronousExceptionSP0
+
+vector_entry IrqSP0
+ mov x0, #IRQ_SP_EL0
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry IrqSP0
+
+vector_entry FiqSP0
+ mov x0, #FIQ_SP_EL0
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry FiqSP0
+
+vector_entry SErrorSP0
+ mov x0, #SERROR_SP_EL0
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SErrorSP0
+
+ /* -----------------------------------------------------
+ * Current EL with SPx: 0x200 - 0x400
+ * -----------------------------------------------------
+ */
+vector_entry SynchronousExceptionSPx
+ mov x0, #SYNC_EXCEPTION_SP_ELX
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SynchronousExceptionSPx
+
+vector_entry IrqSPx
+ mov x0, #IRQ_SP_ELX
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry IrqSPx
+
+vector_entry FiqSPx
+ mov x0, #FIQ_SP_ELX
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry FiqSPx
+
+vector_entry SErrorSPx
+ mov x0, #SERROR_SP_ELX
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SErrorSPx
+
+ /* -----------------------------------------------------
+ * Lower EL using AArch64 : 0x400 - 0x600
+ * -----------------------------------------------------
+ */
+vector_entry SynchronousExceptionA64
+ mov x0, #SYNC_EXCEPTION_AARCH64
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SynchronousExceptionA64
+
+vector_entry IrqA64
+ mov x0, #IRQ_AARCH64
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry IrqA64
+
+vector_entry FiqA64
+ mov x0, #FIQ_AARCH64
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry FiqA64
+
+vector_entry SErrorA64
+ mov x0, #SERROR_AARCH64
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SErrorA64
+
+ /* -----------------------------------------------------
+ * Lower EL using AArch32 : 0x600 - 0x800
+ * -----------------------------------------------------
+ */
+vector_entry SynchronousExceptionA32
+ mov x0, #SYNC_EXCEPTION_AARCH32
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SynchronousExceptionA32
+
+vector_entry IrqA32
+ mov x0, #IRQ_AARCH32
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry IrqA32
+
+vector_entry FiqA32
+ mov x0, #FIQ_AARCH32
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry FiqA32
+
+vector_entry SErrorA32
+ mov x0, #SERROR_AARCH32
+ bl plat_report_exception
+ no_ret plat_panic_handler
+end_vector_entry SErrorA32
diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S
new file mode 100644
index 0000000..a021e42
--- /dev/null
+++ b/bl2/aarch64/bl2_entrypoint.S
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+
+
+ .globl bl2_entrypoint
+
+
+
+func bl2_entrypoint
+ /*---------------------------------------------
+ * Save arguments x0 - x3 from BL1 for future
+ * use.
+ * ---------------------------------------------
+ */
+ mov x20, x0
+ mov x21, x1
+ mov x22, x2
+ mov x23, x3
+
+ /* ---------------------------------------------
+ * Set the exception vector to something sane.
+ * ---------------------------------------------
+ */
+ adr x0, early_exceptions
+ msr vbar_el1, x0
+ isb
+
+ /* ---------------------------------------------
+ * Enable the SError interrupt now that the
+ * exception vectors have been setup.
+ * ---------------------------------------------
+ */
+ msr daifclr, #DAIF_ABT_BIT
+
+ /* ---------------------------------------------
+ * Enable the instruction cache, stack pointer
+ * and data access alignment checks and disable
+ * speculative loads.
+ * ---------------------------------------------
+ */
+ mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+ mrs x0, sctlr_el1
+ orr x0, x0, x1
+ bic x0, x0, #SCTLR_DSSBS_BIT
+ msr sctlr_el1, x0
+ isb
+
+ /* ---------------------------------------------
+ * Invalidate the RW memory used by the BL2
+ * image. This includes the data and NOBITS
+ * sections. This is done to safeguard against
+ * possible corruption of this memory by dirty
+ * cache lines in a system cache as a result of
+ * use by an earlier boot loader stage.
+ * ---------------------------------------------
+ */
+ adr x0, __RW_START__
+ adr x1, __RW_END__
+ sub x1, x1, x0
+ bl inv_dcache_range
+
+ /* ---------------------------------------------
+ * Zero out NOBITS sections. There are 2 of them:
+ * - the .bss section;
+ * - the coherent memory section.
+ * ---------------------------------------------
+ */
+ adrp x0, __BSS_START__
+ add x0, x0, :lo12:__BSS_START__
+ adrp x1, __BSS_END__
+ add x1, x1, :lo12:__BSS_END__
+ sub x1, x1, x0
+ bl zeromem
+
+#if USE_COHERENT_MEM
+ adrp x0, __COHERENT_RAM_START__
+ add x0, x0, :lo12:__COHERENT_RAM_START__
+ adrp x1, __COHERENT_RAM_END_UNALIGNED__
+ add x1, x1, :lo12:__COHERENT_RAM_END_UNALIGNED__
+ sub x1, x1, x0
+ bl zeromem
+#endif
+
+ /* --------------------------------------------
+ * Allocate a stack whose memory will be marked
+ * as Normal-IS-WBWA when the MMU is enabled.
+ * There is no risk of reading stale stack
+ * memory after enabling the MMU as only the
+ * primary cpu is running at the moment.
+ * --------------------------------------------
+ */
+ bl plat_set_my_stack
+
+ /* ---------------------------------------------
+ * Initialize the stack protector canary before
+ * any C code is called.
+ * ---------------------------------------------
+ */
+#if STACK_PROTECTOR_ENABLED
+ bl update_stack_protector_canary
+#endif
+
+ /* ---------------------------------------------
+ * Perform BL2 setup
+ * ---------------------------------------------
+ */
+ mov x0, x20
+ mov x1, x21
+ mov x2, x22
+ mov x3, x23
+ bl bl2_setup
+
+#if ENABLE_PAUTH
+ /* ---------------------------------------------
+ * Program APIAKey_EL1
+ * and enable pointer authentication.
+ * ---------------------------------------------
+ */
+ bl pauth_init_enable_el1
+#endif /* ENABLE_PAUTH */
+
+ /* ---------------------------------------------
+ * Jump to main function.
+ * ---------------------------------------------
+ */
+ bl bl2_main
+
+ /* ---------------------------------------------
+ * Should never reach this point.
+ * ---------------------------------------------
+ */
+ no_ret plat_panic_handler
+
+endfunc bl2_entrypoint
diff --git a/bl2/aarch64/bl2_rme_entrypoint.S b/bl2/aarch64/bl2_rme_entrypoint.S
new file mode 100644
index 0000000..076e326
--- /dev/null
+++ b/bl2/aarch64/bl2_rme_entrypoint.S
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <el3_common_macros.S>
+
+ .globl bl2_entrypoint
+
+
+func bl2_entrypoint
+ /* Save arguments x0-x3 from previous Boot loader */
+ mov x20, x0
+ mov x21, x1
+ mov x22, x2
+ mov x23, x3
+
+ el3_entrypoint_common \
+ _init_sctlr=0 \
+ _warm_boot_mailbox=0 \
+ _secondary_cold_boot=0 \
+ _init_memory=0 \
+ _init_c_runtime=1 \
+ _exception_vectors=bl2_el3_exceptions \
+ _pie_fixup_size=0
+
+ /* ---------------------------------------------
+ * Restore parameters of boot rom
+ * ---------------------------------------------
+ */
+ mov x0, x20
+ mov x1, x21
+ mov x2, x22
+ mov x3, x23
+
+ /* ---------------------------------------------
+ * Perform BL2 setup
+ * ---------------------------------------------
+ */
+ bl bl2_setup
+
+#if ENABLE_PAUTH
+ /* ---------------------------------------------
+ * Program APIAKey_EL1 and enable pointer authentication.
+ * ---------------------------------------------
+ */
+ bl pauth_init_enable_el3
+#endif /* ENABLE_PAUTH */
+
+ /* ---------------------------------------------
+ * Jump to main function.
+ * ---------------------------------------------
+ */
+ bl bl2_main
+
+ /* ---------------------------------------------
+ * Should never reach this point.
+ * ---------------------------------------------
+ */
+ no_ret plat_panic_handler
+endfunc bl2_entrypoint
diff --git a/bl2/aarch64/bl2_run_next_image.S b/bl2/aarch64/bl2_run_next_image.S
new file mode 100644
index 0000000..1431a5f
--- /dev/null
+++ b/bl2/aarch64/bl2_run_next_image.S
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+
+ .globl bl2_run_next_image
+
+
+func bl2_run_next_image
+ mov x20,x0
+ /* ---------------------------------------------
+ * MMU needs to be disabled because both BL2 and BL31 execute
+ * in EL3, and therefore share the same address space.
+ * BL31 will initialize the address space according to its
+ * own requirement.
+ * ---------------------------------------------
+ */
+ bl disable_mmu_icache_el3
+ tlbi alle3
+ bl bl2_el3_plat_prepare_exit
+
+ ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
+ msr elr_el3, x0
+ msr spsr_el3, x1
+
+ ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
+ ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
+ ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
+ ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
+ exception_return
+endfunc bl2_run_next_image
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
new file mode 100644
index 0000000..db83a0c
--- /dev/null
+++ b/bl2/bl2.ld.S
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.ld.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(bl2_entrypoint)
+
+MEMORY {
+ RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+}
+
+SECTIONS {
+ RAM_REGION_START = ORIGIN(RAM);
+ RAM_REGION_LENGTH = LENGTH(RAM);
+ . = BL2_BASE;
+
+ ASSERT(. == ALIGN(PAGE_SIZE),
+ "BL2_BASE address is not aligned on a page boundary.")
+
+#if SEPARATE_CODE_AND_RODATA
+ .text . : {
+ __TEXT_START__ = .;
+
+#if ENABLE_RME
+ *bl2_rme_entrypoint.o(.text*)
+#else /* ENABLE_RME */
+ *bl2_entrypoint.o(.text*)
+#endif /* ENABLE_RME */
+
+ *(SORT_BY_ALIGNMENT(.text*))
+ *(.vectors)
+ __TEXT_END_UNALIGNED__ = .;
+
+ . = ALIGN(PAGE_SIZE);
+
+ __TEXT_END__ = .;
+ } >RAM
+
+ /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
+ .ARM.extab . : {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } >RAM
+
+ .ARM.exidx . : {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } >RAM
+
+ .rodata . : {
+ __RODATA_START__ = .;
+
+ *(SORT_BY_ALIGNMENT(.rodata*))
+
+ RODATA_COMMON
+
+ __RODATA_END_UNALIGNED__ = .;
+ . = ALIGN(PAGE_SIZE);
+
+ __RODATA_END__ = .;
+ } >RAM
+#else /* SEPARATE_CODE_AND_RODATA */
+ .ro . : {
+ __RO_START__ = .;
+
+ *bl2_entrypoint.o(.text*)
+ *(SORT_BY_ALIGNMENT(.text*))
+ *(SORT_BY_ALIGNMENT(.rodata*))
+
+ RODATA_COMMON
+
+ *(.vectors)
+
+ __RO_END_UNALIGNED__ = .;
+
+ /*
+ * Memory page(s) mapped to this section will be marked as read-only,
+ * executable. No RW data from the next section must creep in. Ensure
+ * that the rest of the current memory page is unused.
+ */
+ . = ALIGN(PAGE_SIZE);
+
+ __RO_END__ = .;
+ } >RAM
+#endif /* SEPARATE_CODE_AND_RODATA */
+
+ __RW_START__ = .;
+
+ DATA_SECTION >RAM
+ STACK_SECTION >RAM
+ BSS_SECTION >RAM
+ XLAT_TABLE_SECTION >RAM
+
+#if USE_COHERENT_MEM
+ /*
+ * The base address of the coherent memory section must be page-aligned to
+ * guarantee that the coherent data are stored on their own pages and are
+ * not mixed with normal data. This is required to set up the correct
+ * memory attributes for the coherent data page tables.
+ */
+ .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
+ __COHERENT_RAM_START__ = .;
+ *(.tzfw_coherent_mem)
+ __COHERENT_RAM_END_UNALIGNED__ = .;
+
+ /*
+ * Memory page(s) mapped to this section will be marked as device
+ * memory. No other unexpected data must creep in. Ensure the rest of
+ * the current memory page is unused.
+ */
+ . = ALIGN(PAGE_SIZE);
+
+ __COHERENT_RAM_END__ = .;
+ } >RAM
+#endif /* USE_COHERENT_MEM */
+
+ __RW_END__ = .;
+ __BL2_END__ = .;
+ RAM_REGION_END = .;
+
+ __BSS_SIZE__ = SIZEOF(.bss);
+
+#if USE_COHERENT_MEM
+ __COHERENT_RAM_UNALIGNED_SIZE__ =
+ __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
+#endif /* USE_COHERENT_MEM */
+
+ ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
+}
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
new file mode 100644
index 0000000..b70a3fb
--- /dev/null
+++ b/bl2/bl2.mk
@@ -0,0 +1,55 @@
+#
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL2_SOURCES += bl2/bl2_image_load_v2.c \
+ bl2/bl2_main.c \
+ bl2/${ARCH}/bl2_arch_setup.c \
+ lib/locks/exclusive/${ARCH}/spinlock.S \
+ plat/common/${ARCH}/platform_up_stack.S \
+ ${MBEDTLS_SOURCES}
+
+ifeq (${ARCH},aarch64)
+BL2_SOURCES += common/aarch64/early_exceptions.S
+endif
+
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+ BL2_LDFLAGS += -Wl,--sort-section=alignment
+else ifneq ($(findstring ld,$(notdir $(LD))),)
+ BL2_LDFLAGS += --sort-section=alignment
+endif
+
+ifeq (${ENABLE_RME},1)
+# Using RME, run BL2 at EL3
+include lib/gpt_rme/gpt_rme.mk
+
+BL2_SOURCES += bl2/${ARCH}/bl2_rme_entrypoint.S \
+ bl2/${ARCH}/bl2_el3_exceptions.S \
+ bl2/${ARCH}/bl2_run_next_image.S \
+ ${GPT_LIB_SRCS}
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2.ld.S
+
+else ifeq (${RESET_TO_BL2},0)
+# Normal operation, no RME, no BL2 at EL3
+BL2_SOURCES += bl2/${ARCH}/bl2_entrypoint.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2.ld.S
+
+else
+# BL2 at EL3, no RME
+BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \
+ bl2/${ARCH}/bl2_el3_exceptions.S \
+ bl2/${ARCH}/bl2_run_next_image.S \
+ lib/cpus/${ARCH}/cpu_helpers.S
+
+ifeq (${ARCH},aarch64)
+BL2_SOURCES += lib/cpus/aarch64/dsu_helpers.S
+endif
+
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2_el3.ld.S
+endif
+
+ifeq (${ENABLE_PMF},1)
+BL2_SOURCES += lib/pmf/pmf_main.c
+endif \ No newline at end of file
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
new file mode 100644
index 0000000..4aa5cb0
--- /dev/null
+++ b/bl2/bl2_el3.ld.S
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.ld.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(bl2_entrypoint)
+
+MEMORY {
+#if BL2_IN_XIP_MEM
+ ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
+ RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
+#else /* BL2_IN_XIP_MEM */
+ RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+#endif /* BL2_IN_XIP_MEM */
+
+#if SEPARATE_BL2_NOLOAD_REGION
+ RAM_NOLOAD (rw!a): ORIGIN = BL2_NOLOAD_START, LENGTH = BL2_NOLOAD_LIMIT - BL2_NOLOAD_START
+#else /* SEPARATE_BL2_NOLOAD_REGION */
+# define RAM_NOLOAD RAM
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
+}
+
+#if !BL2_IN_XIP_MEM
+# define ROM RAM
+#endif /* !BL2_IN_XIP_MEM */
+
+SECTIONS {
+ RAM_REGION_START = ORIGIN(RAM);
+ RAM_REGION_LENGTH = LENGTH(RAM);
+#if BL2_IN_XIP_MEM
+ ROM_REGION_START = ORIGIN(ROM);
+ ROM_REGION_LENGTH = LENGTH(ROM);
+
+ . = BL2_RO_BASE;
+
+ ASSERT(. == ALIGN(PAGE_SIZE),
+ "BL2_RO_BASE address is not aligned on a page boundary.")
+#else /* BL2_IN_XIP_MEM */
+ . = BL2_BASE;
+
+ ASSERT(. == ALIGN(PAGE_SIZE),
+ "BL2_BASE address is not aligned on a page boundary.")
+#endif /* BL2_IN_XIP_MEM */
+
+#if SEPARATE_BL2_NOLOAD_REGION
+ RAM_NOLOAD_REGION_START = ORIGIN(RAM_NOLOAD);
+ RAM_NOLOAD_REGION_LENGTH = LENGTH(RAM_NOLOAD);
+#endif
+
+#if SEPARATE_CODE_AND_RODATA
+ .text . : {
+ __TEXT_START__ = .;
+ __TEXT_RESIDENT_START__ = .;
+
+ *bl2_el3_entrypoint.o(.text*)
+ *(.text.asm.*)
+
+ __TEXT_RESIDENT_END__ = .;
+
+ *(SORT_BY_ALIGNMENT(.text*))
+ *(.vectors)
+ __TEXT_END_UNALIGNED__ = .;
+
+ . = ALIGN(PAGE_SIZE);
+
+ __TEXT_END__ = .;
+ } >ROM
+
+ .rodata . : {
+ __RODATA_START__ = .;
+
+ *(SORT_BY_ALIGNMENT(.rodata*))
+
+ RODATA_COMMON
+
+ __RODATA_END_UNALIGNED__ = .;
+ . = ALIGN(PAGE_SIZE);
+
+ __RODATA_END__ = .;
+ } >ROM
+
+ ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
+ "Resident part of BL2 has exceeded its limit.")
+#else /* SEPARATE_CODE_AND_RODATA */
+ .ro . : {
+ __RO_START__ = .;
+ __TEXT_RESIDENT_START__ = .;
+
+ *bl2_el3_entrypoint.o(.text*)
+ *(.text.asm.*)
+
+ __TEXT_RESIDENT_END__ = .;
+
+ *(SORT_BY_ALIGNMENT(.text*))
+ *(SORT_BY_ALIGNMENT(.rodata*))
+
+ RODATA_COMMON
+
+ *(.vectors)
+
+ __RO_END_UNALIGNED__ = .;
+
+ /*
+ * Memory page(s) mapped to this section will be marked as read-only,
+ * executable. No RW data from the next section must creep in. Ensure
+ * that the rest of the current memory page is unused.
+ */
+ . = ALIGN(PAGE_SIZE);
+
+ __RO_END__ = .;
+ } >ROM
+#endif /* SEPARATE_CODE_AND_RODATA */
+
+ ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
+ "cpu_ops not defined for this platform.")
+
+#if BL2_IN_XIP_MEM
+ ROM_REGION_END = .;
+ . = BL2_RW_BASE;
+
+ ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
+ "BL2_RW_BASE address is not aligned on a page boundary.")
+#endif /* BL2_IN_XIP_MEM */
+
+ __RW_START__ = .;
+
+ DATA_SECTION >RAM AT>ROM
+
+ __DATA_RAM_START__ = __DATA_START__;
+ __DATA_RAM_END__ = __DATA_END__;
+
+ RELA_SECTION >RAM
+
+#if SEPARATE_BL2_NOLOAD_REGION
+ SAVED_ADDR = .;
+
+ . = BL2_NOLOAD_START;
+
+ __BL2_NOLOAD_START__ = .;
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
+
+ STACK_SECTION >RAM_NOLOAD
+ BSS_SECTION >RAM_NOLOAD
+ XLAT_TABLE_SECTION >RAM_NOLOAD
+
+#if SEPARATE_BL2_NOLOAD_REGION
+ __BL2_NOLOAD_END__ = .;
+ RAM_NOLOAD_REGION_END = .;
+
+ . = SAVED_ADDR;
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
+
+#if USE_COHERENT_MEM
+ /*
+ * The base address of the coherent memory section must be page-aligned to
+ * guarantee that the coherent data are stored on their own pages and are
+ * not mixed with normal data. This is required to set up the correct
+ * memory attributes for the coherent data page tables.
+ */
+ .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
+ __COHERENT_RAM_START__ = .;
+
+ *(.tzfw_coherent_mem)
+
+ __COHERENT_RAM_END_UNALIGNED__ = .;
+
+ /*
+ * Memory page(s) mapped to this section will be marked as device
+ * memory. No other unexpected data must creep in. Ensure the rest of
+ * the current memory page is unused.
+ */
+ . = ALIGN(PAGE_SIZE);
+
+ __COHERENT_RAM_END__ = .;
+ } >RAM
+#endif /* USE_COHERENT_MEM */
+
+ __RW_END__ = .;
+ __BL2_END__ = .;
+
+ /DISCARD/ : {
+ *(.dynsym .dynstr .hash .gnu.hash)
+ }
+
+#if BL2_IN_XIP_MEM
+ __BL2_RAM_START__ = ADDR(.data);
+ __BL2_RAM_END__ = .;
+
+ __DATA_ROM_START__ = LOADADDR(.data);
+ __DATA_SIZE__ = SIZEOF(.data);
+
+ /*
+ * The .data section is the last PROGBITS section so its end marks the end
+ * of BL2's RO content in XIP memory.
+ */
+ __BL2_ROM_END__ = __DATA_ROM_START__ + __DATA_SIZE__;
+
+ ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
+ "BL2's RO content has exceeded its limit.")
+#endif /* BL2_IN_XIP_MEM */
+
+ __BSS_SIZE__ = SIZEOF(.bss);
+
+#if USE_COHERENT_MEM
+ __COHERENT_RAM_UNALIGNED_SIZE__ =
+ __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
+#endif /* USE_COHERENT_MEM */
+
+ RAM_REGION_END = .;
+#if BL2_IN_XIP_MEM
+ ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
+#else /* BL2_IN_XIP_MEM */
+ ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
+#endif /* BL2_IN_XIP_MEM */
+}
diff --git a/bl2/bl2_image_load_v2.c b/bl2/bl2_image_load_v2.c
new file mode 100644
index 0000000..dee3fc2
--- /dev/null
+++ b/bl2/bl2_image_load_v2.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include "bl2_private.h"
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/auth/auth_mod.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * This function loads SCP_BL2/BL3x images and returns the ep_info for
+ * the next executable image.
+ ******************************************************************************/
+struct entry_point_info *bl2_load_images(void)
+{
+ bl_params_t *bl2_to_next_bl_params;
+ bl_load_info_t *bl2_load_info;
+ const bl_load_info_node_t *bl2_node_info;
+ int plat_setup_done = 0;
+ int err;
+
+ /*
+ * Get information about the images to load.
+ */
+ bl2_load_info = plat_get_bl_image_load_info();
+ assert(bl2_load_info != NULL);
+ assert(bl2_load_info->head != NULL);
+ assert(bl2_load_info->h.type == PARAM_BL_LOAD_INFO);
+ assert(bl2_load_info->h.version >= VERSION_2);
+ bl2_node_info = bl2_load_info->head;
+
+ while (bl2_node_info != NULL) {
+ /*
+ * Perform platform setup before loading the image,
+ * if indicated in the image attributes AND if NOT
+ * already done before.
+ */
+ if ((bl2_node_info->image_info->h.attr &
+ IMAGE_ATTRIB_PLAT_SETUP) != 0U) {
+ if (plat_setup_done != 0) {
+ WARN("BL2: Platform setup already done!!\n");
+ } else {
+ INFO("BL2: Doing platform setup\n");
+ bl2_platform_setup();
+ plat_setup_done = 1;
+ }
+ }
+
+ err = bl2_plat_handle_pre_image_load(bl2_node_info->image_id);
+ if (err != 0) {
+ ERROR("BL2: Failure in pre image load handling (%i)\n", err);
+ plat_error_handler(err);
+ }
+
+ if ((bl2_node_info->image_info->h.attr &
+ IMAGE_ATTRIB_SKIP_LOADING) == 0U) {
+ INFO("BL2: Loading image id %u\n", bl2_node_info->image_id);
+ err = load_auth_image(bl2_node_info->image_id,
+ bl2_node_info->image_info);
+ if (err != 0) {
+ ERROR("BL2: Failed to load image id %u (%i)\n",
+ bl2_node_info->image_id, err);
+ plat_error_handler(err);
+ }
+ } else {
+ INFO("BL2: Skip loading image id %u\n", bl2_node_info->image_id);
+ }
+
+ /* Allow platform to handle image information. */
+ err = bl2_plat_handle_post_image_load(bl2_node_info->image_id);
+ if (err != 0) {
+ ERROR("BL2: Failure in post image load handling (%i)\n", err);
+ plat_error_handler(err);
+ }
+
+ /* Go to next image */
+ bl2_node_info = bl2_node_info->next_load_info;
+ }
+
+ /*
+ * Get information to pass to the next image.
+ */
+ bl2_to_next_bl_params = plat_get_next_bl_params();
+ assert(bl2_to_next_bl_params != NULL);
+ assert(bl2_to_next_bl_params->head != NULL);
+ assert(bl2_to_next_bl_params->h.type == PARAM_BL_PARAMS);
+ assert(bl2_to_next_bl_params->h.version >= VERSION_2);
+ assert(bl2_to_next_bl_params->head->ep_info != NULL);
+
+ /* Populate arg0 for the next BL image if not already provided */
+ if (bl2_to_next_bl_params->head->ep_info->args.arg0 == (u_register_t)0)
+ bl2_to_next_bl_params->head->ep_info->args.arg0 =
+ (u_register_t)bl2_to_next_bl_params;
+
+ /* Flush the parameters to be passed to next image */
+ plat_flush_next_bl_params();
+
+ return bl2_to_next_bl_params->head->ep_info;
+}
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
new file mode 100644
index 0000000..923a554
--- /dev/null
+++ b/bl2/bl2_main.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <arch_features.h>
+#include <bl1/bl1.h>
+#include <bl2/bl2.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/auth/auth_mod.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/console.h>
+#include <drivers/fwu/fwu.h>
+#include <lib/bootmarker_capture.h>
+#include <lib/extensions/pauth.h>
+#include <lib/pmf/pmf.h>
+#include <plat/common/platform.h>
+
+#include "bl2_private.h"
+
+#ifdef __aarch64__
+#define NEXT_IMAGE "BL31"
+#else
+#define NEXT_IMAGE "BL32"
+#endif
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+ PMF_REGISTER_SERVICE(bl_svc, PMF_RT_INSTR_SVC_ID,
+ BL_TOTAL_IDS, PMF_DUMP_ENABLE);
+#endif
+
+#if RESET_TO_BL2
+/*******************************************************************************
+ * Setup function for BL2 when RESET_TO_BL2=1
+ ******************************************************************************/
+void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
+ u_register_t arg3)
+{
+ /* Perform early platform-specific setup */
+ bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3);
+
+ /* Perform late platform-specific setup */
+ bl2_el3_plat_arch_setup();
+
+#if CTX_INCLUDE_PAUTH_REGS
+ /*
+ * Assert that the ARMv8.3-PAuth registers are present or an access
+ * fault will be triggered when they are being saved or restored.
+ */
+ assert(is_armv8_3_pauth_present());
+#endif /* CTX_INCLUDE_PAUTH_REGS */
+}
+#else /* RESET_TO_BL2 */
+
+/*******************************************************************************
+ * Setup function for BL2 when RESET_TO_BL2=0
+ ******************************************************************************/
+void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
+ u_register_t arg3)
+{
+ /* Perform early platform-specific setup */
+ bl2_early_platform_setup2(arg0, arg1, arg2, arg3);
+
+ /* Perform late platform-specific setup */
+ bl2_plat_arch_setup();
+
+#if CTX_INCLUDE_PAUTH_REGS
+ /*
+ * Assert that the ARMv8.3-PAuth registers are present or an access
+ * fault will be triggered when they are being saved or restored.
+ */
+ assert(is_armv8_3_pauth_present());
+#endif /* CTX_INCLUDE_PAUTH_REGS */
+}
+#endif /* RESET_TO_BL2 */
+
+/*******************************************************************************
+ * The only thing to do in BL2 is to load further images and pass control to
+ * next BL. The memory occupied by BL2 will be reclaimed by BL3x stages. BL2
+ * runs entirely in S-EL1.
+ ******************************************************************************/
+void bl2_main(void)
+{
+ entry_point_info_t *next_bl_ep_info;
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+ PMF_CAPTURE_TIMESTAMP(bl_svc, BL2_ENTRY, PMF_CACHE_MAINT);
+#endif
+
+ NOTICE("BL2: %s\n", version_string);
+ NOTICE("BL2: %s\n", build_message);
+
+ /* Perform remaining generic architectural setup in S-EL1 */
+ bl2_arch_setup();
+
+#if PSA_FWU_SUPPORT
+ fwu_init();
+#endif /* PSA_FWU_SUPPORT */
+
+ crypto_mod_init();
+
+ /* Initialize authentication module */
+ auth_mod_init();
+
+ /* Initialize the Measured Boot backend */
+ bl2_plat_mboot_init();
+
+ /* Initialize boot source */
+ bl2_plat_preload_setup();
+
+ /* Load the subsequent bootloader images. */
+ next_bl_ep_info = bl2_load_images();
+
+ /* Teardown the Measured Boot backend */
+ bl2_plat_mboot_finish();
+
+#if !BL2_RUNS_AT_EL3
+#ifndef __aarch64__
+ /*
+ * For AArch32 state BL1 and BL2 share the MMU setup.
+ * Given that BL2 does not map BL1 regions, MMU needs
+ * to be disabled in order to go back to BL1.
+ */
+ disable_mmu_icache_secure();
+#endif /* !__aarch64__ */
+
+#if ENABLE_PAUTH
+ /*
+ * Disable pointer authentication before running next boot image
+ */
+ pauth_disable_el1();
+#endif /* ENABLE_PAUTH */
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+ PMF_CAPTURE_TIMESTAMP(bl_svc, BL2_EXIT, PMF_CACHE_MAINT);
+#endif
+
+ console_flush();
+
+ /*
+ * Run next BL image via an SMC to BL1. Information on how to pass
+ * control to the BL32 (if present) and BL33 software images will
+ * be passed to next BL image as an argument.
+ */
+ smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0, 0, 0);
+#else /* if BL2_RUNS_AT_EL3 */
+
+ NOTICE("BL2: Booting " NEXT_IMAGE "\n");
+ print_entry_point_info(next_bl_ep_info);
+#if ENABLE_RUNTIME_INSTRUMENTATION
+ PMF_CAPTURE_TIMESTAMP(bl_svc, BL2_EXIT, PMF_CACHE_MAINT);
+#endif
+ console_flush();
+
+#if ENABLE_PAUTH
+ /*
+ * Disable pointer authentication before running next boot image
+ */
+ pauth_disable_el3();
+#endif /* ENABLE_PAUTH */
+
+ bl2_run_next_image(next_bl_ep_info);
+#endif /* BL2_RUNS_AT_EL3 */
+}
diff --git a/bl2/bl2_private.h b/bl2/bl2_private.h
new file mode 100644
index 0000000..b1704d2
--- /dev/null
+++ b/bl2/bl2_private.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BL2_PRIVATE_H
+#define BL2_PRIVATE_H
+
+#include <common/bl_common.h>
+
+/******************************************
+ * Forward declarations
+ *****************************************/
+struct entry_point_info;
+
+/******************************************
+ * Function prototypes
+ *****************************************/
+void bl2_arch_setup(void);
+struct entry_point_info *bl2_load_images(void);
+void bl2_run_next_image(const struct entry_point_info *bl_ep_info);
+
+#endif /* BL2_PRIVATE_H */