Merge pull request #713 from yatharth-arm/yk/AArch32_porting
Add basic AArch32 support for BL1 & BL2
This commit is contained in:
commit
44abeaa632
28
Makefile
28
Makefile
|
@ -115,7 +115,8 @@ ENABLE_PSCI_STAT := 0
|
|||
# Whether code and read-only data should be put on separate memory pages.
|
||||
# The platform Makefile is free to override this value.
|
||||
SEPARATE_CODE_AND_RODATA := 0
|
||||
|
||||
# Flag to enable new version of image loading
|
||||
LOAD_IMAGE_V2 := 0
|
||||
|
||||
################################################################################
|
||||
# Checkpatch script options
|
||||
|
@ -187,6 +188,10 @@ ifneq (${GENERATE_COT},0)
|
|||
FWU_FIP_DEPS += fwu_certificates
|
||||
endif
|
||||
|
||||
# For AArch32, enable new version of image loading.
|
||||
ifeq (${ARCH},aarch32)
|
||||
LOAD_IMAGE_V2 := 1
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Toolchain
|
||||
|
@ -355,6 +360,21 @@ ifeq (${NEED_BL33},yes)
|
|||
endif
|
||||
endif
|
||||
|
||||
# TRUSTED_BOARD_BOOT is currently not supported when LOAD_IMAGE_V2 is enabled.
|
||||
ifeq (${LOAD_IMAGE_V2},1)
|
||||
ifeq (${TRUSTED_BOARD_BOOT},1)
|
||||
$(error "TRUSTED_BOARD_BOOT is currently not supported \
|
||||
for LOAD_IMAGE_V2=1")
|
||||
endif
|
||||
endif
|
||||
|
||||
# For AArch32, LOAD_IMAGE_V2 must be enabled.
|
||||
ifeq (${ARCH},aarch32)
|
||||
ifeq (${LOAD_IMAGE_V2}, 0)
|
||||
$(error "For AArch32, LOAD_IMAGE_V2 must be enabled.")
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
################################################################################
|
||||
# Process platform overrideable behaviour
|
||||
|
@ -445,6 +465,7 @@ $(eval $(call assert_boolean,PL011_GENERIC_UART))
|
|||
$(eval $(call assert_boolean,ENABLE_PMF))
|
||||
$(eval $(call assert_boolean,ENABLE_PSCI_STAT))
|
||||
$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
|
||||
$(eval $(call assert_boolean,LOAD_IMAGE_V2))
|
||||
|
||||
|
||||
################################################################################
|
||||
|
@ -475,6 +496,7 @@ $(eval $(call add_define,PL011_GENERIC_UART))
|
|||
$(eval $(call add_define,ENABLE_PMF))
|
||||
$(eval $(call add_define,ENABLE_PSCI_STAT))
|
||||
$(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
|
||||
$(eval $(call add_define,LOAD_IMAGE_V2))
|
||||
# Define the EL3_PAYLOAD_BASE flag only if it is provided.
|
||||
ifdef EL3_PAYLOAD_BASE
|
||||
$(eval $(call add_define,EL3_PAYLOAD_BASE))
|
||||
|
@ -495,8 +517,6 @@ endif
|
|||
################################################################################
|
||||
# Include BL specific makefiles
|
||||
################################################################################
|
||||
# BL31 is not needed and BL1, BL2 & BL2U are not currently supported in AArch32
|
||||
ifneq (${ARCH},aarch32)
|
||||
ifdef BL1_SOURCES
|
||||
NEED_BL1 := yes
|
||||
include bl1/bl1.mk
|
||||
|
@ -507,6 +527,8 @@ NEED_BL2 := yes
|
|||
include bl2/bl2.mk
|
||||
endif
|
||||
|
||||
# For AArch32, BL31 is not applicable, and BL2U is not supported at present.
|
||||
ifneq (${ARCH},aarch32)
|
||||
ifdef BL2U_SOURCES
|
||||
NEED_BL2U := yes
|
||||
include bl2u/bl2u.mk
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* TODO: Function that does the first bit of architectural setup.
|
||||
******************************************************************************/
|
||||
void bl1_arch_setup(void)
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <context.h>
|
||||
#include <context_mgmt.h>
|
||||
#include <debug.h>
|
||||
#include <platform.h>
|
||||
#include <smcc_helpers.h>
|
||||
|
||||
/*
|
||||
* Following arrays will be used for context management.
|
||||
* There are 2 instances, for the Secure and Non-Secure contexts.
|
||||
*/
|
||||
static cpu_context_t bl1_cpu_context[2];
|
||||
static smc_ctx_t bl1_smc_context[2];
|
||||
|
||||
/* Following contains the next cpu context pointer. */
|
||||
static void *bl1_next_cpu_context_ptr;
|
||||
|
||||
/* Following contains the next smc context pointer. */
|
||||
static void *bl1_next_smc_context_ptr;
|
||||
|
||||
/* Following functions are used for SMC context handling */
|
||||
void *smc_get_ctx(int security_state)
|
||||
{
|
||||
assert(sec_state_is_valid(security_state));
|
||||
return &bl1_smc_context[security_state];
|
||||
}
|
||||
|
||||
void smc_set_next_ctx(int security_state)
|
||||
{
|
||||
assert(sec_state_is_valid(security_state));
|
||||
bl1_next_smc_context_ptr = &bl1_smc_context[security_state];
|
||||
}
|
||||
|
||||
void *smc_get_next_ctx(void)
|
||||
{
|
||||
return bl1_next_smc_context_ptr;
|
||||
}
|
||||
|
||||
/* Following functions are used for CPU context handling */
|
||||
void *cm_get_context(uint32_t security_state)
|
||||
{
|
||||
assert(sec_state_is_valid(security_state));
|
||||
return &bl1_cpu_context[security_state];
|
||||
}
|
||||
|
||||
void cm_set_next_context(void *cpu_context)
|
||||
{
|
||||
assert(cpu_context);
|
||||
bl1_next_cpu_context_ptr = cpu_context;
|
||||
}
|
||||
|
||||
void *cm_get_next_context(void)
|
||||
{
|
||||
return bl1_next_cpu_context_ptr;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Following function copies GP regs r0-r4, lr and spsr,
|
||||
* from the CPU context to the SMC context structures.
|
||||
******************************************************************************/
|
||||
static void copy_cpu_ctx_to_smc_ctx(const regs_t *cpu_reg_ctx,
|
||||
smc_ctx_t *next_smc_ctx)
|
||||
{
|
||||
next_smc_ctx->r0 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R0);
|
||||
next_smc_ctx->r1 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R1);
|
||||
next_smc_ctx->r2 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R2);
|
||||
next_smc_ctx->r3 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R3);
|
||||
next_smc_ctx->lr_mon = read_ctx_reg(cpu_reg_ctx, CTX_LR);
|
||||
next_smc_ctx->spsr_mon = read_ctx_reg(cpu_reg_ctx, CTX_SPSR);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Following function flushes the SMC & CPU context pointer and its data.
|
||||
******************************************************************************/
|
||||
static void flush_smc_and_cpu_ctx(void)
|
||||
{
|
||||
flush_dcache_range((uintptr_t)&bl1_next_smc_context_ptr,
|
||||
sizeof(bl1_next_smc_context_ptr));
|
||||
flush_dcache_range((uintptr_t)bl1_next_smc_context_ptr,
|
||||
sizeof(smc_ctx_t));
|
||||
|
||||
flush_dcache_range((uintptr_t)&bl1_next_cpu_context_ptr,
|
||||
sizeof(bl1_next_cpu_context_ptr));
|
||||
flush_dcache_range((uintptr_t)bl1_next_cpu_context_ptr,
|
||||
sizeof(cpu_context_t));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function prepares the context for Secure/Normal world images.
|
||||
* Normal world images are transitioned to HYP(if supported) else SVC.
|
||||
******************************************************************************/
|
||||
void bl1_prepare_next_image(unsigned int image_id)
|
||||
{
|
||||
unsigned int security_state;
|
||||
image_desc_t *image_desc;
|
||||
entry_point_info_t *next_bl_ep;
|
||||
|
||||
/* Get the image descriptor. */
|
||||
image_desc = bl1_plat_get_image_desc(image_id);
|
||||
assert(image_desc);
|
||||
|
||||
/* Get the entry point info. */
|
||||
next_bl_ep = &image_desc->ep_info;
|
||||
|
||||
/* Get the image security state. */
|
||||
security_state = GET_SECURITY_STATE(next_bl_ep->h.attr);
|
||||
|
||||
/* Prepare the SPSR for the next BL image. */
|
||||
if (security_state == SECURE) {
|
||||
next_bl_ep->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
|
||||
SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
|
||||
} else {
|
||||
/* Use HYP mode if supported else use SVC. */
|
||||
if (GET_VIRT_EXT(read_id_pfr1()) == MODE32_hyp) {
|
||||
next_bl_ep->spsr = SPSR_MODE32(MODE32_hyp, SPSR_T_ARM,
|
||||
SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
|
||||
} else {
|
||||
next_bl_ep->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
|
||||
SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allow platform to make change */
|
||||
bl1_plat_set_ep_info(image_id, next_bl_ep);
|
||||
|
||||
/* Prepare the cpu context for the next BL image. */
|
||||
cm_init_my_context(next_bl_ep);
|
||||
cm_prepare_el3_exit(security_state);
|
||||
cm_set_next_context(cm_get_context(security_state));
|
||||
|
||||
/* Prepare the smc context for the next BL image. */
|
||||
smc_set_next_ctx(security_state);
|
||||
copy_cpu_ctx_to_smc_ctx(get_regs_ctx(cm_get_next_context()),
|
||||
smc_get_next_ctx());
|
||||
|
||||
/*
|
||||
* Flush the SMC & CPU context and the (next)pointers,
|
||||
* to access them after caches are disabled.
|
||||
*/
|
||||
flush_smc_and_cpu_ctx();
|
||||
|
||||
/* Indicate that image is in execution state. */
|
||||
image_desc->state = IMAGE_STATE_EXECUTED;
|
||||
|
||||
print_entry_point_info(next_bl_ep);
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <bl_common.h>
|
||||
#include <context.h>
|
||||
#include <el3_common_macros.S>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smcc_macros.S>
|
||||
|
||||
.globl bl1_vector_table
|
||||
.globl bl1_entrypoint
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Setup the vector table to support SVC & MON mode.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
vector_base bl1_vector_table
|
||||
b bl1_entrypoint
|
||||
b report_exception /* Undef */
|
||||
b bl1_aarch32_smc_handler /* SMC call */
|
||||
b report_exception /* Prefetch abort */
|
||||
b report_exception /* Data abort */
|
||||
b report_exception /* Reserved */
|
||||
b report_exception /* IRQ */
|
||||
b report_exception /* FIQ */
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* bl1_entrypoint() is the entry point into the trusted
|
||||
* firmware code when a cpu is released from warm or
|
||||
* cold reset.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
|
||||
func bl1_entrypoint
|
||||
/* ---------------------------------------------------------------------
|
||||
* If the reset address is programmable then bl1_entrypoint() is
|
||||
* executed only on the cold boot path. Therefore, we can skip the warm
|
||||
* boot mailbox mechanism.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
el3_entrypoint_common \
|
||||
_set_endian=1 \
|
||||
_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
|
||||
_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
|
||||
_init_memory=1 \
|
||||
_init_c_runtime=1 \
|
||||
_exception_vectors=bl1_vector_table
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Perform early platform setup & platform
|
||||
* specific early arch. setup e.g. mmu setup
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
bl bl1_early_platform_setup
|
||||
bl bl1_plat_arch_setup
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Jump to main function.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
bl bl1_main
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Jump to next image.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* MMU needs to be disabled because both BL1 and BL2 execute
|
||||
* in PL1, and therefore share the same address space.
|
||||
* BL2 will initialize the address space according to its
|
||||
* own requirement.
|
||||
*/
|
||||
bl disable_mmu_icache_secure
|
||||
stcopr r0, TLBIALL
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
/* Get the cpu_context for next BL image */
|
||||
bl cm_get_next_context
|
||||
|
||||
/* Restore the SCR */
|
||||
ldr r2, [r0, #CTX_REGS_OFFSET + CTX_SCR]
|
||||
stcopr r2, SCR
|
||||
isb
|
||||
|
||||
/*
|
||||
* Get the smc_context for next BL image,
|
||||
* program the gp/system registers and exit
|
||||
* secure monitor mode
|
||||
*/
|
||||
bl smc_get_next_ctx
|
||||
smcc_restore_gp_mode_regs
|
||||
eret
|
||||
endfunc bl1_entrypoint
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <bl1.h>
|
||||
#include <bl_common.h>
|
||||
|
||||
.globl bl1_aarch32_smc_handler
|
||||
|
||||
|
||||
func bl1_aarch32_smc_handler
|
||||
/* ------------------------------------------------
|
||||
* SMC in BL1 is handled assuming that the MMU is
|
||||
* turned off by BL2.
|
||||
* ------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------
|
||||
* Only RUN_IMAGE SMC is supported.
|
||||
* ----------------------------------------------
|
||||
*/
|
||||
mov r8, #BL1_SMC_RUN_IMAGE
|
||||
cmp r8, r0
|
||||
blne report_exception
|
||||
|
||||
/* ------------------------------------------------
|
||||
* Make sure only Secure world reaches here.
|
||||
* ------------------------------------------------
|
||||
*/
|
||||
ldcopr r8, SCR
|
||||
tst r8, #SCR_NS_BIT
|
||||
blne report_exception
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Pass control to next secure image.
|
||||
* Here it expects r1 to contain the address of a entry_point_info_t
|
||||
* structure describing the BL entrypoint.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov r8, r1
|
||||
mov r0, r1
|
||||
bl bl1_print_next_bl_ep_info
|
||||
|
||||
#if SPIN_ON_BL1_EXIT
|
||||
bl print_debug_loop_message
|
||||
debug_loop:
|
||||
b debug_loop
|
||||
#endif
|
||||
|
||||
mov r0, r8
|
||||
bl bl1_plat_prepare_exit
|
||||
|
||||
stcopr r0, TLBIALL
|
||||
dsb sy
|
||||
isb
|
||||
|
||||
/*
|
||||
* 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, r1
|
||||
|
||||
add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET
|
||||
ldm r8, {r0, r1, r2, r3}
|
||||
eret
|
||||
endfunc bl1_aarch32_smc_handler
|
|
@ -192,15 +192,15 @@ func smc_handler64
|
|||
mov sp, x30
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Pass EL3 control to BL31.
|
||||
* Pass EL3 control to next BL image.
|
||||
* Here it expects X1 with the address of a entry_point_info_t
|
||||
* structure describing the BL31 entrypoint.
|
||||
* structure describing the next BL image entrypoint.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov x20, x1
|
||||
|
||||
mov x0, x20
|
||||
bl bl1_print_bl31_ep_info
|
||||
bl bl1_print_next_bl_ep_info
|
||||
|
||||
ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
|
||||
msr elr_el3, x0
|
||||
|
|
18
bl1/bl1.mk
18
bl1/bl1.mk
|
@ -29,15 +29,19 @@
|
|||
#
|
||||
|
||||
BL1_SOURCES += bl1/bl1_main.c \
|
||||
bl1/aarch64/bl1_arch_setup.c \
|
||||
bl1/aarch64/bl1_entrypoint.S \
|
||||
bl1/aarch64/bl1_exceptions.S \
|
||||
bl1/bl1_context_mgmt.c \
|
||||
lib/cpus/aarch64/cpu_helpers.S \
|
||||
lib/el3_runtime/aarch64/context.S \
|
||||
lib/el3_runtime/aarch64/context_mgmt.c \
|
||||
bl1/${ARCH}/bl1_arch_setup.c \
|
||||
bl1/${ARCH}/bl1_context_mgmt.c \
|
||||
bl1/${ARCH}/bl1_entrypoint.S \
|
||||
bl1/${ARCH}/bl1_exceptions.S \
|
||||
lib/cpus/${ARCH}/cpu_helpers.S \
|
||||
lib/el3_runtime/${ARCH}/context_mgmt.c \
|
||||
plat/common/plat_bl1_common.c
|
||||
|
||||
|
||||
ifeq (${ARCH},aarch64)
|
||||
BL1_SOURCES += lib/el3_runtime/aarch64/context.S
|
||||
endif
|
||||
|
||||
ifeq (${TRUSTED_BOARD_BOOT},1)
|
||||
BL1_SOURCES += bl1/bl1_fwu.c
|
||||
endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -64,11 +64,19 @@ static void bl1_load_bl2(void);
|
|||
void bl1_init_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
|
||||
meminfo_t *bl2_mem_layout)
|
||||
{
|
||||
const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
|
||||
|
||||
assert(bl1_mem_layout != NULL);
|
||||
assert(bl2_mem_layout != NULL);
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
/*
|
||||
* Remove BL1 RW data from the scope of memory visible to BL2.
|
||||
* This is assuming BL1 RW data is at the top of bl1_mem_layout.
|
||||
*/
|
||||
assert(BL1_RW_BASE > bl1_mem_layout->total_base);
|
||||
bl2_mem_layout->total_base = bl1_mem_layout->total_base;
|
||||
bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base;
|
||||
#else
|
||||
/* Check that BL1's memory is lying outside of the free memory */
|
||||
assert((BL1_RAM_LIMIT <= bl1_mem_layout->free_base) ||
|
||||
(BL1_RAM_BASE >= bl1_mem_layout->free_base +
|
||||
|
@ -79,7 +87,8 @@ void bl1_init_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
|
|||
reserve_mem(&bl2_mem_layout->total_base,
|
||||
&bl2_mem_layout->total_size,
|
||||
BL1_RAM_BASE,
|
||||
bl1_size);
|
||||
BL1_RAM_LIMIT - BL1_RAM_BASE);
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
flush_dcache_range((unsigned long)bl2_mem_layout, sizeof(meminfo_t));
|
||||
}
|
||||
|
@ -98,15 +107,20 @@ void bl1_main(void)
|
|||
NOTICE("BL1: %s\n", version_string);
|
||||
NOTICE("BL1: %s\n", build_message);
|
||||
|
||||
INFO("BL1: RAM 0x%lx - 0x%lx\n", BL1_RAM_BASE, BL1_RAM_LIMIT);
|
||||
INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE,
|
||||
(void *)BL1_RAM_LIMIT);
|
||||
|
||||
|
||||
#if DEBUG
|
||||
unsigned long val;
|
||||
u_register_t val;
|
||||
/*
|
||||
* Ensure that MMU/Caches and coherency are turned on
|
||||
*/
|
||||
#ifdef AARCH32
|
||||
val = read_sctlr();
|
||||
#else
|
||||
val = read_sctlr_el3();
|
||||
#endif
|
||||
assert(val & SCTLR_M_BIT);
|
||||
assert(val & SCTLR_C_BIT);
|
||||
assert(val & SCTLR_I_BIT);
|
||||
|
@ -182,6 +196,9 @@ void bl1_load_bl2(void)
|
|||
|
||||
INFO("BL1: Loading BL2\n");
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
err = load_auth_image(BL2_IMAGE_ID, image_info);
|
||||
#else
|
||||
/* Load the BL2 image */
|
||||
err = load_auth_image(bl1_tzram_layout,
|
||||
BL2_IMAGE_ID,
|
||||
|
@ -189,6 +206,8 @@ void bl1_load_bl2(void)
|
|||
image_info,
|
||||
ep_info);
|
||||
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
if (err) {
|
||||
ERROR("Failed to load BL2 firmware.\n");
|
||||
plat_error_handler(err);
|
||||
|
@ -201,24 +220,33 @@ void bl1_load_bl2(void)
|
|||
* to BL2. BL2 will read the memory layout before using its
|
||||
* memory for other purposes.
|
||||
*/
|
||||
#if LOAD_IMAGE_V2
|
||||
bl2_tzram_layout = (meminfo_t *) bl1_tzram_layout->total_base;
|
||||
#else
|
||||
bl2_tzram_layout = (meminfo_t *) bl1_tzram_layout->free_base;
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
bl1_init_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout);
|
||||
|
||||
ep_info->args.arg1 = (unsigned long)bl2_tzram_layout;
|
||||
ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout;
|
||||
NOTICE("BL1: Booting BL2\n");
|
||||
VERBOSE("BL1: BL2 memory layout address = 0x%llx\n",
|
||||
(unsigned long long) bl2_tzram_layout);
|
||||
VERBOSE("BL1: BL2 memory layout address = %p\n",
|
||||
(void *) bl2_tzram_layout);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function called just before handing over to BL31 to inform the user about
|
||||
* the boot progress. In debug mode, also print details about the BL31 image's
|
||||
* execution context.
|
||||
* Function called just before handing over to the next BL to inform the user
|
||||
* about the boot progress. In debug mode, also print details about the BL
|
||||
* image's execution context.
|
||||
******************************************************************************/
|
||||
void bl1_print_bl31_ep_info(const entry_point_info_t *bl31_ep_info)
|
||||
void bl1_print_next_bl_ep_info(const entry_point_info_t *bl_ep_info)
|
||||
{
|
||||
#ifdef AARCH32
|
||||
NOTICE("BL1: Booting BL32\n");
|
||||
#else
|
||||
NOTICE("BL1: Booting BL31\n");
|
||||
print_entry_point_info(bl31_ep_info);
|
||||
#endif /* AARCH32 */
|
||||
print_entry_point_info(bl_ep_info);
|
||||
}
|
||||
|
||||
#if SPIN_ON_BL1_EXIT
|
||||
|
|
|
@ -37,13 +37,13 @@
|
|||
* Declarations of linker defined symbols which will tell us where BL1 lives
|
||||
* in Trusted ROM and RAM
|
||||
******************************************************************************/
|
||||
extern uint64_t __BL1_ROM_END__;
|
||||
#define BL1_ROM_END (uint64_t)(&__BL1_ROM_END__)
|
||||
extern uintptr_t __BL1_ROM_END__;
|
||||
#define BL1_ROM_END (uintptr_t)(&__BL1_ROM_END__)
|
||||
|
||||
extern uint64_t __BL1_RAM_START__;
|
||||
extern uint64_t __BL1_RAM_END__;
|
||||
#define BL1_RAM_BASE (uint64_t)(&__BL1_RAM_START__)
|
||||
#define BL1_RAM_LIMIT (uint64_t)(&__BL1_RAM_END__)
|
||||
extern uintptr_t __BL1_RAM_START__;
|
||||
extern uintptr_t __BL1_RAM_END__;
|
||||
#define BL1_RAM_BASE (uintptr_t)(&__BL1_RAM_START__)
|
||||
#define BL1_RAM_LIMIT (uintptr_t)(&__BL1_RAM_END__)
|
||||
|
||||
/******************************************
|
||||
* Function prototypes
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Place holder function to perform any Secure SVC specific architectural
|
||||
* setup. At the moment there is nothing to do.
|
||||
******************************************************************************/
|
||||
void bl2_arch_setup(void)
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <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_exception /* Prefetch abort */
|
||||
b report_exception /* Data abort */
|
||||
b report_exception /* Reserved */
|
||||
b report_exception /* IRQ */
|
||||
b report_exception /* FIQ */
|
||||
|
||||
|
||||
func bl2_entrypoint
|
||||
/*---------------------------------------------
|
||||
* Save from r1 the extents of the trusted ram
|
||||
* available to BL2 for future use.
|
||||
* r0 is not currently used.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mov r11, r1
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Set the exception vector to something sane.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
ldr r0, =bl2_vector_table
|
||||
stcopr r0, VBAR
|
||||
isb
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Enable the instruction cache
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
ldcopr r0, SCTLR
|
||||
orr r0, r0, #SCTLR_I_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_SIZE__
|
||||
bl zeromem
|
||||
|
||||
#if USE_COHERENT_MEM
|
||||
ldr r0, =__COHERENT_RAM_START__
|
||||
ldr r1, =__COHERENT_RAM_UNALIGNED_SIZE__
|
||||
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
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Perform early platform setup & platform
|
||||
* specific early arch. setup e.g. mmu setup
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mov r0, r11
|
||||
bl bl2_early_platform_setup
|
||||
bl bl2_plat_arch_setup
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Jump to main function.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
bl bl2_main
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Should never reach this point.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
bl plat_panic_handler
|
||||
|
||||
endfunc bl2_entrypoint
|
19
bl2/bl2.mk
19
bl2/bl2.mk
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||
# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
|
@ -29,9 +29,18 @@
|
|||
#
|
||||
|
||||
BL2_SOURCES += bl2/bl2_main.c \
|
||||
bl2/aarch64/bl2_entrypoint.S \
|
||||
bl2/aarch64/bl2_arch_setup.c \
|
||||
common/aarch64/early_exceptions.S \
|
||||
lib/locks/exclusive/aarch64/spinlock.S
|
||||
bl2/${ARCH}/bl2_entrypoint.S \
|
||||
bl2/${ARCH}/bl2_arch_setup.c \
|
||||
lib/locks/exclusive/${ARCH}/spinlock.S
|
||||
|
||||
ifeq (${ARCH},aarch64)
|
||||
BL2_SOURCES += common/aarch64/early_exceptions.S
|
||||
endif
|
||||
|
||||
ifeq (${LOAD_IMAGE_V2},1)
|
||||
BL2_SOURCES += bl2/bl2_image_load_v2.c
|
||||
else
|
||||
BL2_SOURCES += bl2/bl2_image_load.c
|
||||
endif
|
||||
|
||||
BL2_LINKERFILE := bl2/bl2.ld.S
|
||||
|
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <auth_mod.h>
|
||||
#include <bl_common.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Check for platforms that use obsolete image terminology
|
||||
*/
|
||||
#ifdef BL30_BASE
|
||||
# error "BL30_BASE platform define no longer used - please use SCP_BL2_BASE"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Load the SCP_BL2 image if there's one.
|
||||
* If a platform does not want to attempt to load SCP_BL2 image it must leave
|
||||
* SCP_BL2_BASE undefined.
|
||||
* Return 0 on success or if there's no SCP_BL2 image to load, a negative error
|
||||
* code otherwise.
|
||||
******************************************************************************/
|
||||
static int load_scp_bl2(void)
|
||||
{
|
||||
int e = 0;
|
||||
#ifdef SCP_BL2_BASE
|
||||
meminfo_t scp_bl2_mem_info;
|
||||
image_info_t scp_bl2_image_info;
|
||||
|
||||
/*
|
||||
* It is up to the platform to specify where SCP_BL2 should be loaded if
|
||||
* it exists. It could create space in the secure sram or point to a
|
||||
* completely different memory.
|
||||
*
|
||||
* The entry point information is not relevant in this case as the AP
|
||||
* won't execute the SCP_BL2 image.
|
||||
*/
|
||||
INFO("BL2: Loading SCP_BL2\n");
|
||||
bl2_plat_get_scp_bl2_meminfo(&scp_bl2_mem_info);
|
||||
scp_bl2_image_info.h.version = VERSION_1;
|
||||
e = load_auth_image(&scp_bl2_mem_info,
|
||||
SCP_BL2_IMAGE_ID,
|
||||
SCP_BL2_BASE,
|
||||
&scp_bl2_image_info,
|
||||
NULL);
|
||||
|
||||
if (e == 0) {
|
||||
/* The subsequent handling of SCP_BL2 is platform specific */
|
||||
e = bl2_plat_handle_scp_bl2(&scp_bl2_image_info);
|
||||
if (e) {
|
||||
ERROR("Failure in platform-specific handling of SCP_BL2 image.\n");
|
||||
}
|
||||
}
|
||||
#endif /* SCP_BL2_BASE */
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
#ifndef EL3_PAYLOAD_BASE
|
||||
/*******************************************************************************
|
||||
* Load the BL31 image.
|
||||
* The bl2_to_bl31_params and bl31_ep_info params will be updated with the
|
||||
* relevant BL31 information.
|
||||
* Return 0 on success, a negative error code otherwise.
|
||||
******************************************************************************/
|
||||
static int load_bl31(bl31_params_t *bl2_to_bl31_params,
|
||||
entry_point_info_t *bl31_ep_info)
|
||||
{
|
||||
meminfo_t *bl2_tzram_layout;
|
||||
int e;
|
||||
|
||||
INFO("BL2: Loading BL31\n");
|
||||
assert(bl2_to_bl31_params != NULL);
|
||||
assert(bl31_ep_info != NULL);
|
||||
|
||||
/* Find out how much free trusted ram remains after BL2 load */
|
||||
bl2_tzram_layout = bl2_plat_sec_mem_layout();
|
||||
|
||||
/* Set the X0 parameter to BL31 */
|
||||
bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params;
|
||||
|
||||
/* Load the BL31 image */
|
||||
e = load_auth_image(bl2_tzram_layout,
|
||||
BL31_IMAGE_ID,
|
||||
BL31_BASE,
|
||||
bl2_to_bl31_params->bl31_image_info,
|
||||
bl31_ep_info);
|
||||
|
||||
if (e == 0) {
|
||||
bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info,
|
||||
bl31_ep_info);
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Load the BL32 image if there's one.
|
||||
* The bl2_to_bl31_params param will be updated with the relevant BL32
|
||||
* information.
|
||||
* If a platform does not want to attempt to load BL32 image it must leave
|
||||
* BL32_BASE undefined.
|
||||
* Return 0 on success or if there's no BL32 image to load, a negative error
|
||||
* code otherwise.
|
||||
******************************************************************************/
|
||||
static int load_bl32(bl31_params_t *bl2_to_bl31_params)
|
||||
{
|
||||
int e = 0;
|
||||
#ifdef BL32_BASE
|
||||
meminfo_t bl32_mem_info;
|
||||
|
||||
INFO("BL2: Loading BL32\n");
|
||||
assert(bl2_to_bl31_params != NULL);
|
||||
|
||||
/*
|
||||
* It is up to the platform to specify where BL32 should be loaded if
|
||||
* it exists. It could create space in the secure sram or point to a
|
||||
* completely different memory.
|
||||
*/
|
||||
bl2_plat_get_bl32_meminfo(&bl32_mem_info);
|
||||
e = load_auth_image(&bl32_mem_info,
|
||||
BL32_IMAGE_ID,
|
||||
BL32_BASE,
|
||||
bl2_to_bl31_params->bl32_image_info,
|
||||
bl2_to_bl31_params->bl32_ep_info);
|
||||
|
||||
if (e == 0) {
|
||||
bl2_plat_set_bl32_ep_info(
|
||||
bl2_to_bl31_params->bl32_image_info,
|
||||
bl2_to_bl31_params->bl32_ep_info);
|
||||
}
|
||||
#endif /* BL32_BASE */
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
#ifndef PRELOADED_BL33_BASE
|
||||
/*******************************************************************************
|
||||
* Load the BL33 image.
|
||||
* The bl2_to_bl31_params param will be updated with the relevant BL33
|
||||
* information.
|
||||
* Return 0 on success, a negative error code otherwise.
|
||||
******************************************************************************/
|
||||
static int load_bl33(bl31_params_t *bl2_to_bl31_params)
|
||||
{
|
||||
meminfo_t bl33_mem_info;
|
||||
int e;
|
||||
|
||||
INFO("BL2: Loading BL33\n");
|
||||
assert(bl2_to_bl31_params != NULL);
|
||||
|
||||
bl2_plat_get_bl33_meminfo(&bl33_mem_info);
|
||||
|
||||
/* Load the BL33 image in non-secure memory provided by the platform */
|
||||
e = load_auth_image(&bl33_mem_info,
|
||||
BL33_IMAGE_ID,
|
||||
plat_get_ns_image_entrypoint(),
|
||||
bl2_to_bl31_params->bl33_image_info,
|
||||
bl2_to_bl31_params->bl33_ep_info);
|
||||
|
||||
if (e == 0) {
|
||||
bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info,
|
||||
bl2_to_bl31_params->bl33_ep_info);
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
#endif /* PRELOADED_BL33_BASE */
|
||||
|
||||
#endif /* EL3_PAYLOAD_BASE */
|
||||
|
||||
/*******************************************************************************
|
||||
* This function loads SCP_BL2/BL3x images and returns the ep_info for
|
||||
* the next executable image.
|
||||
******************************************************************************/
|
||||
entry_point_info_t *bl2_load_images(void)
|
||||
{
|
||||
bl31_params_t *bl2_to_bl31_params;
|
||||
entry_point_info_t *bl31_ep_info;
|
||||
int e;
|
||||
|
||||
e = load_scp_bl2();
|
||||
if (e) {
|
||||
ERROR("Failed to load SCP_BL2 (%i)\n", e);
|
||||
plat_error_handler(e);
|
||||
}
|
||||
|
||||
/* Perform platform setup in BL2 after loading SCP_BL2 */
|
||||
bl2_platform_setup();
|
||||
|
||||
/*
|
||||
* Get a pointer to the memory the platform has set aside to pass
|
||||
* information to BL31.
|
||||
*/
|
||||
bl2_to_bl31_params = bl2_plat_get_bl31_params();
|
||||
bl31_ep_info = bl2_plat_get_bl31_ep_info();
|
||||
|
||||
#ifdef EL3_PAYLOAD_BASE
|
||||
/*
|
||||
* In the case of an EL3 payload, we don't need to load any further
|
||||
* images. Just update the BL31 entrypoint info structure to make BL1
|
||||
* jump to the EL3 payload.
|
||||
* The pointer to the memory the platform has set aside to pass
|
||||
* information to BL31 in the normal boot flow is reused here, even
|
||||
* though only a fraction of the information contained in the
|
||||
* bl31_params_t structure makes sense in the context of EL3 payloads.
|
||||
* This will be refined in the future.
|
||||
*/
|
||||
INFO("BL2: Populating the entrypoint info for the EL3 payload\n");
|
||||
bl31_ep_info->pc = EL3_PAYLOAD_BASE;
|
||||
bl31_ep_info->args.arg0 = (unsigned long) bl2_to_bl31_params;
|
||||
bl2_plat_set_bl31_ep_info(NULL, bl31_ep_info);
|
||||
#else
|
||||
e = load_bl31(bl2_to_bl31_params, bl31_ep_info);
|
||||
if (e) {
|
||||
ERROR("Failed to load BL31 (%i)\n", e);
|
||||
plat_error_handler(e);
|
||||
}
|
||||
|
||||
e = load_bl32(bl2_to_bl31_params);
|
||||
if (e) {
|
||||
if (e == -EAUTH) {
|
||||
ERROR("Failed to authenticate BL32\n");
|
||||
plat_error_handler(e);
|
||||
} else {
|
||||
WARN("Failed to load BL32 (%i)\n", e);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PRELOADED_BL33_BASE
|
||||
/*
|
||||
* In this case, don't load the BL33 image as it's already loaded in
|
||||
* memory. Update BL33 entrypoint information.
|
||||
*/
|
||||
INFO("BL2: Populating the entrypoint info for the preloaded BL33\n");
|
||||
bl2_to_bl31_params->bl33_ep_info->pc = PRELOADED_BL33_BASE;
|
||||
bl2_plat_set_bl33_ep_info(NULL, bl2_to_bl31_params->bl33_ep_info);
|
||||
#else
|
||||
e = load_bl33(bl2_to_bl31_params);
|
||||
if (e) {
|
||||
ERROR("Failed to load BL33 (%i)\n", e);
|
||||
plat_error_handler(e);
|
||||
}
|
||||
#endif /* PRELOADED_BL33_BASE */
|
||||
|
||||
#endif /* EL3_PAYLOAD_BASE */
|
||||
|
||||
/* Flush the params to be passed to memory */
|
||||
bl2_plat_flush_bl31_params();
|
||||
|
||||
return bl31_ep_info;
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <auth_mod.h>
|
||||
#include <bl_common.h>
|
||||
#include <debug.h>
|
||||
#include <desc_image_load.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* This function loads SCP_BL2/BL3x images and returns the ep_info for
|
||||
* the next executable image.
|
||||
******************************************************************************/
|
||||
entry_point_info_t *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);
|
||||
assert(bl2_load_info->head);
|
||||
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) {
|
||||
/*
|
||||
* 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) {
|
||||
if (plat_setup_done) {
|
||||
WARN("BL2: Platform setup already done!!\n");
|
||||
} else {
|
||||
INFO("BL2: Doing platform setup\n");
|
||||
bl2_platform_setup();
|
||||
plat_setup_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(bl2_node_info->image_info->h.attr & IMAGE_ATTRIB_SKIP_LOADING)) {
|
||||
INFO("BL2: Loading image id %d\n", bl2_node_info->image_id);
|
||||
err = load_auth_image(bl2_node_info->image_id,
|
||||
bl2_node_info->image_info);
|
||||
if (err) {
|
||||
ERROR("BL2: Failed to load image (%i)\n", err);
|
||||
plat_error_handler(err);
|
||||
}
|
||||
} else {
|
||||
INFO("BL2: Skip loading image id %d\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) {
|
||||
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);
|
||||
assert(bl2_to_next_bl_params->head);
|
||||
assert(bl2_to_next_bl_params->h.type == PARAM_BL_PARAMS);
|
||||
assert(bl2_to_next_bl_params->h.version >= VERSION_2);
|
||||
|
||||
/* Flush the parameters to be passed to next image */
|
||||
plat_flush_next_bl_params();
|
||||
|
||||
return bl2_to_next_bl_params->head->ep_info;
|
||||
}
|
265
bl2/bl2_main.c
265
bl2/bl2_main.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -28,192 +28,23 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <auth_mod.h>
|
||||
#include <bl1.h>
|
||||
#include <bl_common.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <stdint.h>
|
||||
#include "bl2_private.h"
|
||||
|
||||
/*
|
||||
* Check for platforms that use obsolete image terminology
|
||||
*/
|
||||
#ifdef BL30_BASE
|
||||
# error "BL30_BASE platform define no longer used - please use SCP_BL2_BASE"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Load the SCP_BL2 image if there's one.
|
||||
* If a platform does not want to attempt to load SCP_BL2 image it must leave
|
||||
* SCP_BL2_BASE undefined.
|
||||
* Return 0 on success or if there's no SCP_BL2 image to load, a negative error
|
||||
* code otherwise.
|
||||
******************************************************************************/
|
||||
static int load_scp_bl2(void)
|
||||
{
|
||||
int e = 0;
|
||||
#ifdef SCP_BL2_BASE
|
||||
meminfo_t scp_bl2_mem_info;
|
||||
image_info_t scp_bl2_image_info;
|
||||
|
||||
/*
|
||||
* It is up to the platform to specify where SCP_BL2 should be loaded if
|
||||
* it exists. It could create space in the secure sram or point to a
|
||||
* completely different memory.
|
||||
*
|
||||
* The entry point information is not relevant in this case as the AP
|
||||
* won't execute the SCP_BL2 image.
|
||||
*/
|
||||
INFO("BL2: Loading SCP_BL2\n");
|
||||
bl2_plat_get_scp_bl2_meminfo(&scp_bl2_mem_info);
|
||||
scp_bl2_image_info.h.version = VERSION_1;
|
||||
e = load_auth_image(&scp_bl2_mem_info,
|
||||
SCP_BL2_IMAGE_ID,
|
||||
SCP_BL2_BASE,
|
||||
&scp_bl2_image_info,
|
||||
NULL);
|
||||
|
||||
if (e == 0) {
|
||||
/* The subsequent handling of SCP_BL2 is platform specific */
|
||||
e = bl2_plat_handle_scp_bl2(&scp_bl2_image_info);
|
||||
if (e) {
|
||||
ERROR("Failure in platform-specific handling of SCP_BL2 image.\n");
|
||||
}
|
||||
}
|
||||
#endif /* SCP_BL2_BASE */
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
#ifndef EL3_PAYLOAD_BASE
|
||||
/*******************************************************************************
|
||||
* Load the BL31 image.
|
||||
* The bl2_to_bl31_params and bl31_ep_info params will be updated with the
|
||||
* relevant BL31 information.
|
||||
* Return 0 on success, a negative error code otherwise.
|
||||
******************************************************************************/
|
||||
static int load_bl31(bl31_params_t *bl2_to_bl31_params,
|
||||
entry_point_info_t *bl31_ep_info)
|
||||
{
|
||||
meminfo_t *bl2_tzram_layout;
|
||||
int e;
|
||||
|
||||
INFO("BL2: Loading BL31\n");
|
||||
assert(bl2_to_bl31_params != NULL);
|
||||
assert(bl31_ep_info != NULL);
|
||||
|
||||
/* Find out how much free trusted ram remains after BL2 load */
|
||||
bl2_tzram_layout = bl2_plat_sec_mem_layout();
|
||||
|
||||
/* Set the X0 parameter to BL31 */
|
||||
bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params;
|
||||
|
||||
/* Load the BL31 image */
|
||||
e = load_auth_image(bl2_tzram_layout,
|
||||
BL31_IMAGE_ID,
|
||||
BL31_BASE,
|
||||
bl2_to_bl31_params->bl31_image_info,
|
||||
bl31_ep_info);
|
||||
|
||||
if (e == 0) {
|
||||
bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info,
|
||||
bl31_ep_info);
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Load the BL32 image if there's one.
|
||||
* The bl2_to_bl31_params param will be updated with the relevant BL32
|
||||
* information.
|
||||
* If a platform does not want to attempt to load BL32 image it must leave
|
||||
* BL32_BASE undefined.
|
||||
* Return 0 on success or if there's no BL32 image to load, a negative error
|
||||
* code otherwise.
|
||||
******************************************************************************/
|
||||
static int load_bl32(bl31_params_t *bl2_to_bl31_params)
|
||||
{
|
||||
int e = 0;
|
||||
#ifdef BL32_BASE
|
||||
meminfo_t bl32_mem_info;
|
||||
|
||||
INFO("BL2: Loading BL32\n");
|
||||
assert(bl2_to_bl31_params != NULL);
|
||||
|
||||
/*
|
||||
* It is up to the platform to specify where BL32 should be loaded if
|
||||
* it exists. It could create space in the secure sram or point to a
|
||||
* completely different memory.
|
||||
*/
|
||||
bl2_plat_get_bl32_meminfo(&bl32_mem_info);
|
||||
e = load_auth_image(&bl32_mem_info,
|
||||
BL32_IMAGE_ID,
|
||||
BL32_BASE,
|
||||
bl2_to_bl31_params->bl32_image_info,
|
||||
bl2_to_bl31_params->bl32_ep_info);
|
||||
|
||||
if (e == 0) {
|
||||
bl2_plat_set_bl32_ep_info(
|
||||
bl2_to_bl31_params->bl32_image_info,
|
||||
bl2_to_bl31_params->bl32_ep_info);
|
||||
}
|
||||
#endif /* BL32_BASE */
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
#ifndef PRELOADED_BL33_BASE
|
||||
/*******************************************************************************
|
||||
* Load the BL33 image.
|
||||
* The bl2_to_bl31_params param will be updated with the relevant BL33
|
||||
* information.
|
||||
* Return 0 on success, a negative error code otherwise.
|
||||
******************************************************************************/
|
||||
static int load_bl33(bl31_params_t *bl2_to_bl31_params)
|
||||
{
|
||||
meminfo_t bl33_mem_info;
|
||||
int e;
|
||||
|
||||
INFO("BL2: Loading BL33\n");
|
||||
assert(bl2_to_bl31_params != NULL);
|
||||
|
||||
bl2_plat_get_bl33_meminfo(&bl33_mem_info);
|
||||
|
||||
/* Load the BL33 image in non-secure memory provided by the platform */
|
||||
e = load_auth_image(&bl33_mem_info,
|
||||
BL33_IMAGE_ID,
|
||||
plat_get_ns_image_entrypoint(),
|
||||
bl2_to_bl31_params->bl33_image_info,
|
||||
bl2_to_bl31_params->bl33_ep_info);
|
||||
|
||||
if (e == 0) {
|
||||
bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info,
|
||||
bl2_to_bl31_params->bl33_ep_info);
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
#endif /* PRELOADED_BL33_BASE */
|
||||
|
||||
#endif /* EL3_PAYLOAD_BASE */
|
||||
|
||||
/*******************************************************************************
|
||||
* The only thing to do in BL2 is to load further images and pass control to
|
||||
* BL31. The memory occupied by BL2 will be reclaimed by BL3x stages. BL2 runs
|
||||
* entirely in S-EL1.
|
||||
* next BL. The memory occupied by BL2 will be reclaimed by BL3x stages. BL2
|
||||
* runs entirely in S-EL1.
|
||||
******************************************************************************/
|
||||
void bl2_main(void)
|
||||
{
|
||||
bl31_params_t *bl2_to_bl31_params;
|
||||
entry_point_info_t *bl31_ep_info;
|
||||
int e;
|
||||
entry_point_info_t *next_bl_ep_info;
|
||||
|
||||
NOTICE("BL2: %s\n", version_string);
|
||||
NOTICE("BL2: %s\n", build_message);
|
||||
|
@ -226,82 +57,22 @@ void bl2_main(void)
|
|||
auth_mod_init();
|
||||
#endif /* TRUSTED_BOARD_BOOT */
|
||||
|
||||
/*
|
||||
* Load the subsequent bootloader images
|
||||
*/
|
||||
e = load_scp_bl2();
|
||||
if (e) {
|
||||
ERROR("Failed to load SCP_BL2 (%i)\n", e);
|
||||
plat_error_handler(e);
|
||||
}
|
||||
/* Load the subsequent bootloader images. */
|
||||
next_bl_ep_info = bl2_load_images();
|
||||
|
||||
/* Perform platform setup in BL2 after loading SCP_BL2 */
|
||||
bl2_platform_setup();
|
||||
#ifdef AARCH32
|
||||
/*
|
||||
* 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 /* AARCH32 */
|
||||
|
||||
/*
|
||||
* Get a pointer to the memory the platform has set aside to pass
|
||||
* information to BL31.
|
||||
* 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.
|
||||
*/
|
||||
bl2_to_bl31_params = bl2_plat_get_bl31_params();
|
||||
bl31_ep_info = bl2_plat_get_bl31_ep_info();
|
||||
|
||||
#ifdef EL3_PAYLOAD_BASE
|
||||
/*
|
||||
* In the case of an EL3 payload, we don't need to load any further
|
||||
* images. Just update the BL31 entrypoint info structure to make BL1
|
||||
* jump to the EL3 payload.
|
||||
* The pointer to the memory the platform has set aside to pass
|
||||
* information to BL31 in the normal boot flow is reused here, even
|
||||
* though only a fraction of the information contained in the
|
||||
* bl31_params_t structure makes sense in the context of EL3 payloads.
|
||||
* This will be refined in the future.
|
||||
*/
|
||||
INFO("BL2: Populating the entrypoint info for the EL3 payload\n");
|
||||
bl31_ep_info->pc = EL3_PAYLOAD_BASE;
|
||||
bl31_ep_info->args.arg0 = (unsigned long) bl2_to_bl31_params;
|
||||
bl2_plat_set_bl31_ep_info(NULL, bl31_ep_info);
|
||||
#else
|
||||
e = load_bl31(bl2_to_bl31_params, bl31_ep_info);
|
||||
if (e) {
|
||||
ERROR("Failed to load BL31 (%i)\n", e);
|
||||
plat_error_handler(e);
|
||||
}
|
||||
|
||||
e = load_bl32(bl2_to_bl31_params);
|
||||
if (e) {
|
||||
if (e == -EAUTH) {
|
||||
ERROR("Failed to authenticate BL32\n");
|
||||
plat_error_handler(e);
|
||||
} else {
|
||||
WARN("Failed to load BL32 (%i)\n", e);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PRELOADED_BL33_BASE
|
||||
/*
|
||||
* In this case, don't load the BL33 image as it's already loaded in
|
||||
* memory. Update BL33 entrypoint information.
|
||||
*/
|
||||
INFO("BL2: Populating the entrypoint info for the preloaded BL33\n");
|
||||
bl2_to_bl31_params->bl33_ep_info->pc = PRELOADED_BL33_BASE;
|
||||
bl2_plat_set_bl33_ep_info(NULL, bl2_to_bl31_params->bl33_ep_info);
|
||||
#else
|
||||
e = load_bl33(bl2_to_bl31_params);
|
||||
if (e) {
|
||||
ERROR("Failed to load BL33 (%i)\n", e);
|
||||
plat_error_handler(e);
|
||||
}
|
||||
#endif /* PRELOADED_BL33_BASE */
|
||||
|
||||
#endif /* EL3_PAYLOAD_BASE */
|
||||
|
||||
/* Flush the params to be passed to memory */
|
||||
bl2_plat_flush_bl31_params();
|
||||
|
||||
/*
|
||||
* Run BL31 via an SMC to BL1. Information on how to pass control to
|
||||
* the BL32 (if present) and BL33 software images will be passed to
|
||||
* BL31 as an argument.
|
||||
*/
|
||||
smc(BL1_SMC_RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0);
|
||||
smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -31,9 +31,15 @@
|
|||
#ifndef __BL2_PRIVATE_H__
|
||||
#define __BL2_PRIVATE_H__
|
||||
|
||||
/******************************************
|
||||
* Forward declarations
|
||||
*****************************************/
|
||||
struct entry_point_info;
|
||||
|
||||
/******************************************
|
||||
* Function prototypes
|
||||
*****************************************/
|
||||
void bl2_arch_setup(void);
|
||||
struct entry_point_info *bl2_load_images(void);
|
||||
|
||||
#endif /* __BL2_PRIVATE_H__ */
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <asm_macros.S>
|
||||
#include <bl_common.h>
|
||||
#include <context.h>
|
||||
#include <el3_common_macros.S>
|
||||
#include <runtime_svc.h>
|
||||
#include <smcc_helpers.h>
|
||||
#include <smcc_macros.S>
|
||||
|
@ -41,7 +42,8 @@
|
|||
.globl sp_min_entrypoint
|
||||
.globl sp_min_warm_entrypoint
|
||||
|
||||
func sp_min_vector_table
|
||||
|
||||
vector_base sp_min_vector_table
|
||||
b sp_min_entrypoint
|
||||
b plat_panic_handler /* Undef */
|
||||
b handle_smc /* Syscall */
|
||||
|
@ -50,185 +52,70 @@ func sp_min_vector_table
|
|||
b plat_panic_handler /* Reserved */
|
||||
b plat_panic_handler /* IRQ */
|
||||
b plat_panic_handler /* FIQ */
|
||||
endfunc sp_min_vector_table
|
||||
|
||||
func handle_smc
|
||||
smcc_save_gp_mode_regs
|
||||
|
||||
/* r0 points to smc_context */
|
||||
mov r2, r0 /* handle */
|
||||
ldcopr r0, SCR
|
||||
|
||||
/* Save SCR in stack */
|
||||
push {r0}
|
||||
and r3, r0, #SCR_NS_BIT /* flags */
|
||||
|
||||
/* Switch to Secure Mode*/
|
||||
bic r0, #SCR_NS_BIT
|
||||
stcopr r0, SCR
|
||||
isb
|
||||
ldr r0, [r2, #SMC_CTX_GPREG_R0] /* smc_fid */
|
||||
/* Check whether an SMC64 is issued */
|
||||
tst r0, #(FUNCID_CC_MASK << FUNCID_CC_SHIFT)
|
||||
beq 1f /* SMC32 is detected */
|
||||
mov r0, #SMC_UNK
|
||||
str r0, [r2, #SMC_CTX_GPREG_R0]
|
||||
mov r0, r2
|
||||
b 2f /* Skip handling the SMC */
|
||||
1:
|
||||
mov r1, #0 /* cookie */
|
||||
bl handle_runtime_svc
|
||||
2:
|
||||
/* r0 points to smc context */
|
||||
|
||||
/* Restore SCR from stack */
|
||||
pop {r1}
|
||||
stcopr r1, SCR
|
||||
isb
|
||||
|
||||
b sp_min_exit
|
||||
endfunc handle_smc
|
||||
|
||||
/*
|
||||
* The Cold boot/Reset entrypoint for SP_MIN
|
||||
*/
|
||||
func sp_min_entrypoint
|
||||
|
||||
/*
|
||||
* The caches and TLBs are disabled at reset. If any implementation
|
||||
* allows the caches/TLB to be hit while they are disabled, ensure
|
||||
* that they are invalidated here
|
||||
#if !RESET_TO_SP_MIN
|
||||
/* ---------------------------------------------------------------
|
||||
* Preceding bootloader has populated r0 with a pointer to a
|
||||
* 'bl_params_t' structure & r1 with a pointer to platform
|
||||
* specific structure
|
||||
* ---------------------------------------------------------------
|
||||
*/
|
||||
mov r11, r0
|
||||
mov r12, r1
|
||||
|
||||
/* Make sure we are in Secure Mode*/
|
||||
ldcopr r0, SCR
|
||||
bic r0, #SCR_NS_BIT
|
||||
stcopr r0, SCR
|
||||
isb
|
||||
|
||||
/* Switch to monitor mode */
|
||||
cps #MODE32_mon
|
||||
isb
|
||||
|
||||
/*
|
||||
* Set sane values for NS SCTLR as well.
|
||||
* Switch to non secure mode for this.
|
||||
/* ---------------------------------------------------------------------
|
||||
* For !RESET_TO_SP_MIN systems, only the primary CPU ever reaches
|
||||
* sp_min_entrypoint() during the cold boot flow, so the cold/warm boot
|
||||
* and primary/secondary CPU logic should not be executed in this case.
|
||||
*
|
||||
* Also, assume that the previous bootloader has already set up the CPU
|
||||
* endianness and has initialised the memory.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr r0, =(SCTLR_RES1)
|
||||
ldcopr r1, SCR
|
||||
orr r2, r1, #SCR_NS_BIT
|
||||
stcopr r2, SCR
|
||||
isb
|
||||
el3_entrypoint_common \
|
||||
_set_endian=0 \
|
||||
_warm_boot_mailbox=0 \
|
||||
_secondary_cold_boot=0 \
|
||||
_init_memory=0 \
|
||||
_init_c_runtime=1 \
|
||||
_exception_vectors=sp_min_vector_table
|
||||
|
||||
ldcopr r2, SCTLR
|
||||
orr r0, r0, r2
|
||||
stcopr r0, SCTLR
|
||||
isb
|
||||
|
||||
stcopr r1, SCR
|
||||
isb
|
||||
|
||||
/*
|
||||
* Set the CPU endianness before doing anything that might involve
|
||||
* memory reads or writes.
|
||||
/* ---------------------------------------------------------------------
|
||||
* Relay the previous bootloader's arguments to the platform layer
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldcopr r0, SCTLR
|
||||
bic r0, r0, #SCTLR_EE_BIT
|
||||
stcopr r0, SCTLR
|
||||
isb
|
||||
|
||||
/* Run the CPU Specific Reset handler */
|
||||
bl reset_handler
|
||||
|
||||
/*
|
||||
* Enable the instruction cache and data access
|
||||
* alignment checks
|
||||
mov r0, r11
|
||||
mov r1, r12
|
||||
#else
|
||||
/* ---------------------------------------------------------------------
|
||||
* For RESET_TO_SP_MIN systems which have a programmable reset address,
|
||||
* sp_min_entrypoint() is executed only on the cold boot path so we can
|
||||
* skip the warm boot mailbox mechanism.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldcopr r0, SCTLR
|
||||
ldr r1, =(SCTLR_RES1 | SCTLR_A_BIT | SCTLR_I_BIT)
|
||||
orr r0, r0, r1
|
||||
stcopr r0, SCTLR
|
||||
isb
|
||||
el3_entrypoint_common \
|
||||
_set_endian=1 \
|
||||
_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
|
||||
_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
|
||||
_init_memory=1 \
|
||||
_init_c_runtime=1 \
|
||||
_exception_vectors=sp_min_vector_table
|
||||
|
||||
/* Set the vector tables */
|
||||
ldr r0, =sp_min_vector_table
|
||||
stcopr r0, VBAR
|
||||
stcopr r0, MVBAR
|
||||
isb
|
||||
|
||||
/*
|
||||
* Enable the SIF bit to disable instruction fetches
|
||||
* from Non-secure memory.
|
||||
/* ---------------------------------------------------------------------
|
||||
* For RESET_TO_SP_MIN systems, BL32 (SP_MIN) is the first bootloader
|
||||
* to run so there's no argument to relay from a previous bootloader.
|
||||
* Zero the arguments passed to the platform layer to reflect that.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldcopr r0, SCR
|
||||
orr r0, r0, #SCR_SIF_BIT
|
||||
stcopr r0, SCR
|
||||
mov r0, #0
|
||||
mov r1, #0
|
||||
#endif /* RESET_TO_SP_MIN */
|
||||
|
||||
/*
|
||||
* Enable the SError interrupt now that the exception vectors have been
|
||||
* setup.
|
||||
*/
|
||||
cpsie a
|
||||
isb
|
||||
|
||||
/* Enable access to Advanced SIMD registers */
|
||||
ldcopr r0, NSACR
|
||||
bic r0, r0, #NSASEDIS_BIT
|
||||
orr r0, r0, #(NASCR_CP10_BIT | NASCR_CP11_BIT)
|
||||
stcopr r0, NSACR
|
||||
isb
|
||||
|
||||
/*
|
||||
* Enable access to Advanced SIMD, Floating point and to the Trace
|
||||
* functionality as well.
|
||||
*/
|
||||
ldcopr r0, CPACR
|
||||
bic r0, r0, #ASEDIS_BIT
|
||||
bic r0, r0, #TRCDIS_BIT
|
||||
orr r0, r0, #CPACR_ENABLE_FP_ACCESS
|
||||
stcopr r0, CPACR
|
||||
isb
|
||||
|
||||
vmrs r0, FPEXC
|
||||
orr r0, r0, #FPEXC_EN_BIT
|
||||
vmsr FPEXC, r0
|
||||
|
||||
/* Detect whether Warm or Cold boot */
|
||||
bl plat_get_my_entrypoint
|
||||
cmp r0, #0
|
||||
/* If warm boot detected, jump to warm boot entry */
|
||||
bxne r0
|
||||
|
||||
/* Setup C runtime stack */
|
||||
bl plat_set_my_stack
|
||||
|
||||
/* Perform platform specific memory initialization */
|
||||
bl platform_mem_init
|
||||
|
||||
/* Initialize the C Runtime Environment */
|
||||
|
||||
/*
|
||||
* Invalidate the RW memory used by SP_MIN 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
|
||||
|
||||
ldr r0, =__BSS_START__
|
||||
ldr r1, =__BSS_SIZE__
|
||||
bl zeromem
|
||||
|
||||
#if USE_COHERENT_MEM
|
||||
ldr r0, =__COHERENT_RAM_START__
|
||||
ldr r1, =__COHERENT_RAM_UNALIGNED_SIZE__
|
||||
bl zeromem
|
||||
#endif
|
||||
|
||||
/* Perform platform specific early arch. setup */
|
||||
bl sp_min_early_platform_setup
|
||||
bl sp_min_plat_arch_setup
|
||||
|
||||
|
@ -270,13 +157,76 @@ func sp_min_entrypoint
|
|||
b sp_min_exit
|
||||
endfunc sp_min_entrypoint
|
||||
|
||||
|
||||
/*
|
||||
* SMC handling function for SP_MIN.
|
||||
*/
|
||||
func handle_smc
|
||||
smcc_save_gp_mode_regs
|
||||
|
||||
/* r0 points to smc_context */
|
||||
mov r2, r0 /* handle */
|
||||
ldcopr r0, SCR
|
||||
|
||||
/* Save SCR in stack */
|
||||
push {r0}
|
||||
and r3, r0, #SCR_NS_BIT /* flags */
|
||||
|
||||
/* Switch to Secure Mode*/
|
||||
bic r0, #SCR_NS_BIT
|
||||
stcopr r0, SCR
|
||||
isb
|
||||
ldr r0, [r2, #SMC_CTX_GPREG_R0] /* smc_fid */
|
||||
/* Check whether an SMC64 is issued */
|
||||
tst r0, #(FUNCID_CC_MASK << FUNCID_CC_SHIFT)
|
||||
beq 1f /* SMC32 is detected */
|
||||
mov r0, #SMC_UNK
|
||||
str r0, [r2, #SMC_CTX_GPREG_R0]
|
||||
mov r0, r2
|
||||
b 2f /* Skip handling the SMC */
|
||||
1:
|
||||
mov r1, #0 /* cookie */
|
||||
bl handle_runtime_svc
|
||||
2:
|
||||
/* r0 points to smc context */
|
||||
|
||||
/* Restore SCR from stack */
|
||||
pop {r1}
|
||||
stcopr r1, SCR
|
||||
isb
|
||||
|
||||
b sp_min_exit
|
||||
endfunc handle_smc
|
||||
|
||||
|
||||
/*
|
||||
* The Warm boot entrypoint for SP_MIN.
|
||||
*/
|
||||
func sp_min_warm_entrypoint
|
||||
|
||||
/* Setup C runtime stack */
|
||||
bl plat_set_my_stack
|
||||
/*
|
||||
* On the warm boot path, most of the EL3 initialisations performed by
|
||||
* 'el3_entrypoint_common' must be skipped:
|
||||
*
|
||||
* - Only when the platform bypasses the BL1/BL32 (SP_MIN) entrypoint by
|
||||
* programming the reset address do we need to set the CPU endianness.
|
||||
* In other cases, we assume this has been taken care by the
|
||||
* entrypoint code.
|
||||
*
|
||||
* - No need to determine the type of boot, we know it is a warm boot.
|
||||
*
|
||||
* - Do not try to distinguish between primary and secondary CPUs, this
|
||||
* notion only exists for a cold boot.
|
||||
*
|
||||
* - No need to initialise the memory or the C runtime environment,
|
||||
* it has been done once and for all on the cold boot path.
|
||||
*/
|
||||
el3_entrypoint_common \
|
||||
_set_endian=PROGRAMMABLE_RESET_ADDRESS \
|
||||
_warm_boot_mailbox=0 \
|
||||
_secondary_cold_boot=0 \
|
||||
_init_memory=0 \
|
||||
_init_c_runtime=0 \
|
||||
_exception_vectors=sp_min_vector_table
|
||||
|
||||
/* --------------------------------------------
|
||||
* Enable the MMU with the DCache disabled. It
|
||||
|
|
|
@ -50,6 +50,7 @@ SECTIONS
|
|||
__TEXT_START__ = .;
|
||||
*entrypoint.o(.text*)
|
||||
*(.text*)
|
||||
*(.vectors)
|
||||
. = NEXT(4096);
|
||||
__TEXT_END__ = .;
|
||||
} >RAM
|
||||
|
@ -98,6 +99,7 @@ SECTIONS
|
|||
KEEP(*(cpu_ops))
|
||||
__CPU_OPS_END__ = .;
|
||||
|
||||
*(.vectors)
|
||||
__RO_END_UNALIGNED__ = .;
|
||||
|
||||
/*
|
||||
|
|
|
@ -58,6 +58,6 @@ else
|
|||
include ${SP_MIN_PLAT_MAKEFILE}
|
||||
endif
|
||||
|
||||
RESET_TO_SP_MIN := 1
|
||||
RESET_TO_SP_MIN := 0
|
||||
$(eval $(call add_define,RESET_TO_SP_MIN))
|
||||
$(eval $(call assert_boolean,RESET_TO_SP_MIN))
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <asm_macros.S>
|
||||
|
||||
.globl do_panic
|
||||
.globl report_exception
|
||||
|
||||
/***********************************************************
|
||||
* The common implementation of do_panic for all BL stages
|
||||
|
@ -40,3 +41,14 @@ func do_panic
|
|||
b plat_panic_handler
|
||||
endfunc do_panic
|
||||
|
||||
/***********************************************************
|
||||
* This function is called from the vector table for
|
||||
* unhandled exceptions. It reads the current mode and
|
||||
* passes it to platform.
|
||||
***********************************************************/
|
||||
func report_exception
|
||||
mrs r0, cpsr
|
||||
and r0, #MODE32_MASK
|
||||
bl plat_report_exception
|
||||
bl plat_panic_handler
|
||||
endfunc report_exception
|
||||
|
|
|
@ -53,10 +53,7 @@ uintptr_t page_align(uintptr_t value, unsigned dir)
|
|||
return value;
|
||||
}
|
||||
|
||||
static inline unsigned int is_page_aligned (uintptr_t addr) {
|
||||
return (addr & (PAGE_SIZE - 1)) == 0;
|
||||
}
|
||||
|
||||
#if !LOAD_IMAGE_V2
|
||||
/******************************************************************************
|
||||
* Determine whether the memory region delimited by 'addr' and 'size' is free,
|
||||
* given the extents of free memory.
|
||||
|
@ -179,6 +176,7 @@ static void dump_load_info(uintptr_t image_load_addr,
|
|||
INFO(" free region = [base = %p, size = 0x%zx]\n",
|
||||
(void *) mem_layout->free_base, mem_layout->free_size);
|
||||
}
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
/* Generic function to return the size of an image */
|
||||
size_t image_size(unsigned int image_id)
|
||||
|
@ -223,6 +221,156 @@ size_t image_size(unsigned int image_id)
|
|||
return image_size;
|
||||
}
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
|
||||
/*******************************************************************************
|
||||
* Generic function to load an image at a specific address given
|
||||
* an image ID and extents of free memory.
|
||||
*
|
||||
* If the load is successful then the image information is updated.
|
||||
*
|
||||
* Returns 0 on success, a negative error code otherwise.
|
||||
******************************************************************************/
|
||||
int load_image(unsigned int image_id, image_info_t *image_data)
|
||||
{
|
||||
uintptr_t dev_handle;
|
||||
uintptr_t image_handle;
|
||||
uintptr_t image_spec;
|
||||
uintptr_t image_base;
|
||||
size_t image_size;
|
||||
size_t bytes_read;
|
||||
int io_result;
|
||||
|
||||
assert(image_data != NULL);
|
||||
assert(image_data->h.version >= VERSION_2);
|
||||
|
||||
image_base = image_data->image_base;
|
||||
|
||||
/* Obtain a reference to the image by querying the platform layer */
|
||||
io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
|
||||
if (io_result != 0) {
|
||||
WARN("Failed to obtain reference to image id=%u (%i)\n",
|
||||
image_id, io_result);
|
||||
return io_result;
|
||||
}
|
||||
|
||||
/* Attempt to access the image */
|
||||
io_result = io_open(dev_handle, image_spec, &image_handle);
|
||||
if (io_result != 0) {
|
||||
WARN("Failed to access image id=%u (%i)\n",
|
||||
image_id, io_result);
|
||||
return io_result;
|
||||
}
|
||||
|
||||
INFO("Loading image id=%u at address %p\n", image_id,
|
||||
(void *) image_base);
|
||||
|
||||
/* Find the size of the image */
|
||||
io_result = io_size(image_handle, &image_size);
|
||||
if ((io_result != 0) || (image_size == 0)) {
|
||||
WARN("Failed to determine the size of the image id=%u (%i)\n",
|
||||
image_id, io_result);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Check that the image size to load is within limit */
|
||||
if (image_size > image_data->image_max_size) {
|
||||
WARN("Image id=%u size out of bounds\n", image_id);
|
||||
io_result = -EFBIG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
image_data->image_size = image_size;
|
||||
|
||||
/* We have enough space so load the image now */
|
||||
/* TODO: Consider whether to try to recover/retry a partially successful read */
|
||||
io_result = io_read(image_handle, image_base, image_size, &bytes_read);
|
||||
if ((io_result != 0) || (bytes_read < image_size)) {
|
||||
WARN("Failed to load image id=%u (%i)\n", image_id, io_result);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if !TRUSTED_BOARD_BOOT
|
||||
/*
|
||||
* File has been successfully loaded.
|
||||
* Flush the image to main memory so that it can be executed later by
|
||||
* any CPU, regardless of cache and MMU state.
|
||||
* When TBB is enabled the image is flushed later, after image
|
||||
* authentication.
|
||||
*/
|
||||
flush_dcache_range(image_base, image_size);
|
||||
#endif /* TRUSTED_BOARD_BOOT */
|
||||
|
||||
INFO("Image id=%u loaded: %p - %p\n", image_id, (void *) image_base,
|
||||
(void *) (image_base + image_size));
|
||||
|
||||
exit:
|
||||
io_close(image_handle);
|
||||
/* Ignore improbable/unrecoverable error in 'close' */
|
||||
|
||||
/* TODO: Consider maintaining open device connection from this bootloader stage */
|
||||
io_dev_close(dev_handle);
|
||||
/* Ignore improbable/unrecoverable error in 'dev_close' */
|
||||
|
||||
return io_result;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Generic function to load and authenticate an image. The image is actually
|
||||
* loaded by calling the 'load_image()' function. Therefore, it returns the
|
||||
* same error codes if the loading operation failed, or -EAUTH if the
|
||||
* authentication failed. In addition, this function uses recursion to
|
||||
* authenticate the parent images up to the root of trust.
|
||||
******************************************************************************/
|
||||
int load_auth_image(unsigned int image_id, image_info_t *image_data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
#if TRUSTED_BOARD_BOOT
|
||||
unsigned int parent_id;
|
||||
|
||||
/* Use recursion to authenticate parent images */
|
||||
rc = auth_mod_get_parent_id(image_id, &parent_id);
|
||||
if (rc == 0) {
|
||||
rc = load_auth_image(parent_id, image_data);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
#endif /* TRUSTED_BOARD_BOOT */
|
||||
|
||||
/* Load the image */
|
||||
rc = load_image(image_id, image_data);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if TRUSTED_BOARD_BOOT
|
||||
/* Authenticate it */
|
||||
rc = auth_mod_verify_img(image_id,
|
||||
(void *)image_data->image_base,
|
||||
image_data->image_size);
|
||||
if (rc != 0) {
|
||||
memset((void *)image_data->image_base, 0x00,
|
||||
image_data->image_size);
|
||||
flush_dcache_range(image_data->image_base,
|
||||
image_data->image_size);
|
||||
return -EAUTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* File has been successfully loaded and authenticated.
|
||||
* Flush the image to main memory so that it can be executed later by
|
||||
* any CPU, regardless of cache and MMU state.
|
||||
*/
|
||||
flush_dcache_range(image_data->image_base, image_data->image_size);
|
||||
#endif /* TRUSTED_BOARD_BOOT */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*******************************************************************************
|
||||
* Generic function to load an image at a specific address given an image ID and
|
||||
* extents of free memory.
|
||||
|
@ -255,7 +403,7 @@ int load_image(meminfo_t *mem_layout,
|
|||
|
||||
assert(mem_layout != NULL);
|
||||
assert(image_data != NULL);
|
||||
assert(image_data->h.version >= VERSION_1);
|
||||
assert(image_data->h.version == VERSION_1);
|
||||
|
||||
/* Obtain a reference to the image by querying the platform layer */
|
||||
io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
|
||||
|
@ -348,8 +496,10 @@ exit:
|
|||
|
||||
/*******************************************************************************
|
||||
* Generic function to load and authenticate an image. The image is actually
|
||||
* loaded by calling the 'load_image()' function. In addition, this function
|
||||
* uses recursion to authenticate the parent images up to the root of trust.
|
||||
* loaded by calling the 'load_image()' function. Therefore, it returns the
|
||||
* same error codes if the loading operation failed, or -EAUTH if the
|
||||
* authentication failed. In addition, this function uses recursion to
|
||||
* authenticate the parent images up to the root of trust.
|
||||
******************************************************************************/
|
||||
int load_auth_image(meminfo_t *mem_layout,
|
||||
unsigned int image_id,
|
||||
|
@ -403,6 +553,8 @@ int load_auth_image(meminfo_t *mem_layout,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*******************************************************************************
|
||||
* Print the content of an entry_point_info_t structure.
|
||||
******************************************************************************/
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <desc_image_load.h>
|
||||
|
||||
|
||||
extern bl_mem_params_node_t *bl_mem_params_desc_ptr;
|
||||
extern unsigned int bl_mem_params_desc_num;
|
||||
|
||||
static bl_load_info_t bl_load_info;
|
||||
static bl_params_t next_bl_params;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* This function flushes the data structures so that they are visible
|
||||
* in memory for the next BL image.
|
||||
******************************************************************************/
|
||||
void flush_bl_params_desc(void)
|
||||
{
|
||||
flush_dcache_range((unsigned long)bl_mem_params_desc_ptr,
|
||||
sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns the index for given image_id, within the
|
||||
* image descriptor array provided by bl_image_info_descs_ptr, if the
|
||||
* image is found else it returns -1.
|
||||
******************************************************************************/
|
||||
int get_bl_params_node_index(unsigned int image_id)
|
||||
{
|
||||
int index;
|
||||
assert(image_id != INVALID_IMAGE_ID);
|
||||
|
||||
for (index = 0; index < bl_mem_params_desc_num; index++) {
|
||||
if (bl_mem_params_desc_ptr[index].image_id == image_id)
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns the pointer to `bl_mem_params_node_t` object for
|
||||
* given image_id, within the image descriptor array provided by
|
||||
* bl_mem_params_desc_ptr, if the image is found else it returns NULL.
|
||||
******************************************************************************/
|
||||
bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id)
|
||||
{
|
||||
int index;
|
||||
assert(image_id != INVALID_IMAGE_ID);
|
||||
|
||||
index = get_bl_params_node_index(image_id);
|
||||
if (index >= 0)
|
||||
return &bl_mem_params_desc_ptr[index];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function creates the list of loadable images, by populating and
|
||||
* linking each `bl_load_info_node_t` type node, using the internal array
|
||||
* of image descriptor provided by bl_mem_params_desc_ptr. It also populates
|
||||
* and returns `bl_load_info_t` type structure that contains head of the list
|
||||
* of loadable images.
|
||||
******************************************************************************/
|
||||
bl_load_info_t *get_bl_load_info_from_mem_params_desc(void)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* If there is no image to start with, return NULL */
|
||||
if (!bl_mem_params_desc_num)
|
||||
return NULL;
|
||||
|
||||
/* Assign initial data structures */
|
||||
bl_load_info_node_t *bl_node_info =
|
||||
&bl_mem_params_desc_ptr[index].load_node_mem;
|
||||
bl_load_info.head = bl_node_info;
|
||||
SET_PARAM_HEAD(&bl_load_info, PARAM_BL_LOAD_INFO, VERSION_2, 0);
|
||||
|
||||
/* Go through the image descriptor array and create the list */
|
||||
for (; index < bl_mem_params_desc_num; index++) {
|
||||
|
||||
/* Populate the image information */
|
||||
bl_node_info->image_id = bl_mem_params_desc_ptr[index].image_id;
|
||||
bl_node_info->image_info = &bl_mem_params_desc_ptr[index].image_info;
|
||||
|
||||
/* Link next image if present */
|
||||
if ((index + 1) < bl_mem_params_desc_num) {
|
||||
/* Get the memory and link the next node */
|
||||
bl_node_info->next_load_info =
|
||||
&bl_mem_params_desc_ptr[index + 1].load_node_mem;
|
||||
bl_node_info = bl_node_info->next_load_info;
|
||||
}
|
||||
}
|
||||
|
||||
return &bl_load_info;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function creates the list of executable images, by populating and
|
||||
* linking each `bl_params_node_t` type node, using the internal array of
|
||||
* image descriptor provided by bl_mem_params_desc_ptr. It also populates
|
||||
* and returns `bl_params_t` type structure that contains head of the list
|
||||
* of executable images.
|
||||
******************************************************************************/
|
||||
bl_params_t *get_next_bl_params_from_mem_params_desc(void)
|
||||
{
|
||||
int count;
|
||||
unsigned int img_id = 0;
|
||||
int link_index = 0;
|
||||
bl_params_node_t *bl_current_exec_node = NULL;
|
||||
bl_params_node_t *bl_last_exec_node = NULL;
|
||||
bl_mem_params_node_t *desc_ptr;
|
||||
|
||||
/* If there is no image to start with, return NULL */
|
||||
if (!bl_mem_params_desc_num)
|
||||
return NULL;
|
||||
|
||||
/* Get the list HEAD */
|
||||
for (count = 0; count < bl_mem_params_desc_num; count++) {
|
||||
|
||||
desc_ptr = &bl_mem_params_desc_ptr[count];
|
||||
|
||||
if ((EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE) &&
|
||||
(EP_GET_FIRST_EXE(desc_ptr->ep_info.h.attr) == EP_FIRST_EXE)) {
|
||||
next_bl_params.head = &desc_ptr->params_node_mem;
|
||||
link_index = count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we have a HEAD node */
|
||||
assert(next_bl_params.head != NULL);
|
||||
|
||||
/* Populate the HEAD information */
|
||||
SET_PARAM_HEAD(&next_bl_params, PARAM_BL_PARAMS, VERSION_2, 0);
|
||||
|
||||
/*
|
||||
* Go through the image descriptor array and create the list.
|
||||
* This bounded loop is to make sure that we are not looping forever.
|
||||
*/
|
||||
for (count = 0 ; count < bl_mem_params_desc_num; count++) {
|
||||
|
||||
desc_ptr = &bl_mem_params_desc_ptr[link_index];
|
||||
|
||||
/* Make sure the image is executable */
|
||||
assert(EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE);
|
||||
|
||||
/* Get the memory for current node */
|
||||
bl_current_exec_node = &desc_ptr->params_node_mem;
|
||||
|
||||
/* Populate the image information */
|
||||
bl_current_exec_node->image_id = desc_ptr->image_id;
|
||||
bl_current_exec_node->image_info = &desc_ptr->image_info;
|
||||
bl_current_exec_node->ep_info = &desc_ptr->ep_info;
|
||||
|
||||
if (bl_last_exec_node) {
|
||||
/* Assert if loop detected */
|
||||
assert(bl_last_exec_node->next_params_info == NULL);
|
||||
|
||||
/* Link the previous node to the current one */
|
||||
bl_last_exec_node->next_params_info = bl_current_exec_node;
|
||||
}
|
||||
|
||||
/* Update the last node */
|
||||
bl_last_exec_node = bl_current_exec_node;
|
||||
|
||||
/* If no next hand-off image then break out */
|
||||
img_id = desc_ptr->next_handoff_image_id;
|
||||
if (img_id == INVALID_IMAGE_ID)
|
||||
break;
|
||||
|
||||
/* Get the index for the next hand-off image */
|
||||
link_index = get_bl_params_node_index(img_id);
|
||||
assert((link_index > 0) &&
|
||||
(link_index < bl_mem_params_desc_num));
|
||||
}
|
||||
|
||||
/* Invalid image is expected to terminate the loop */
|
||||
assert(img_id == INVALID_IMAGE_ID);
|
||||
|
||||
/* Populate arg0 for the next BL image */
|
||||
next_bl_params.head->ep_info->args.arg0 = (unsigned long)&next_bl_params;
|
||||
|
||||
/* Flush the parameters to be passed to the next BL image */
|
||||
flush_dcache_range((unsigned long)&next_bl_params,
|
||||
sizeof(next_bl_params));
|
||||
|
||||
return &next_bl_params;
|
||||
}
|
|
@ -721,7 +721,6 @@ Firmware represents the power domain topology and how this relates to the
|
|||
linear CPU index, please refer [Power Domain Topology Design].
|
||||
|
||||
|
||||
|
||||
2.4 Common optional modifications
|
||||
---------------------------------
|
||||
|
||||
|
@ -777,11 +776,15 @@ called in the following circumstances:
|
|||
The default implementation doesn't do anything, to avoid making assumptions
|
||||
about the way the platform displays its status information.
|
||||
|
||||
This function receives the exception type as its argument. Possible values for
|
||||
exceptions types are listed in the [include/common/bl_common.h] header file.
|
||||
Note that these constants are not related to any architectural exception code;
|
||||
they are just an ARM Trusted Firmware convention.
|
||||
For AArch64, this function receives the exception type as its argument.
|
||||
Possible values for exceptions types are listed in the
|
||||
[include/common/bl_common.h] header file. Note that these constants are not
|
||||
related to any architectural exception code; they are just an ARM Trusted
|
||||
Firmware convention.
|
||||
|
||||
For AArch32, this function receives the exception mode as its argument.
|
||||
Possible values for exception modes are listed in the
|
||||
[include/lib/aarch32/arch.h] header file.
|
||||
|
||||
### Function : plat_reset_handler()
|
||||
|
||||
|
@ -841,10 +844,37 @@ and must be implemented in assembly because it may be called before the C
|
|||
environment is initialized.
|
||||
|
||||
Note: The address from where it was called is stored in x30 (Link Register).
|
||||
|
||||
The default implementation simply spins.
|
||||
|
||||
|
||||
### Function : plat_get_bl_image_load_info()
|
||||
|
||||
Argument : void
|
||||
Return : bl_load_info_t *
|
||||
|
||||
This function returns pointer to the list of images that the platform has
|
||||
populated to load. This function is currently invoked in BL2 to load the
|
||||
BL3xx images, when LOAD_IMAGE_V2 is enabled.
|
||||
|
||||
### Function : plat_get_next_bl_params()
|
||||
|
||||
Argument : void
|
||||
Return : bl_params_t *
|
||||
|
||||
This function returns a pointer to the shared memory that the platform has
|
||||
kept aside to pass trusted firmware related information that next BL image
|
||||
needs. This function is currently invoked in BL2 to pass this information to
|
||||
the next BL image, when LOAD_IMAGE_V2 is enabled.
|
||||
|
||||
### Function : plat_flush_next_bl_params()
|
||||
|
||||
Argument : void
|
||||
Return : void
|
||||
|
||||
This function flushes to main memory all the image params that are passed to
|
||||
next image. This function is currently invoked in BL2 to flush this information
|
||||
to the next BL image, when LOAD_IMAGE_V2 is enabled.
|
||||
|
||||
3. Modifications specific to a Boot Loader stage
|
||||
-------------------------------------------------
|
||||
|
||||
|
@ -1175,6 +1205,20 @@ populated with the extents of secure RAM available for BL2 to use. See
|
|||
`bl2_early_platform_setup()` above.
|
||||
|
||||
|
||||
Following function is required only when LOAD_IMAGE_V2 is enabled.
|
||||
|
||||
### Function : bl2_plat_handle_post_image_load() [mandatory]
|
||||
|
||||
Argument : unsigned int
|
||||
Return : int
|
||||
|
||||
This function can be used by the platforms to update/use image information
|
||||
for given `image_id`. This function is currently invoked in BL2 to handle
|
||||
BL image specific information based on the `image_id` passed, when
|
||||
LOAD_IMAGE_V2 is enabled.
|
||||
|
||||
Following functions are required only when LOAD_IMAGE_V2 is disabled.
|
||||
|
||||
### Function : bl2_plat_get_scp_bl2_meminfo() [mandatory]
|
||||
|
||||
Argument : meminfo *
|
||||
|
@ -2194,6 +2238,7 @@ _Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved._
|
|||
[plat/common/aarch64/platform_up_stack.S]: ../plat/common/aarch64/platform_up_stack.S
|
||||
[plat/arm/board/fvp/fvp_pm.c]: ../plat/arm/board/fvp/fvp_pm.c
|
||||
[include/common/bl_common.h]: ../include/common/bl_common.h
|
||||
[include/lib/aarch32/arch.h]: ../include/lib/aarch32/arch.h
|
||||
[include/plat/arm/common/arm_def.h]: ../include/plat/arm/common/arm_def.h
|
||||
[include/plat/common/common_def.h]: ../include/plat/common/common_def.h
|
||||
[include/plat/common/platform.h]: ../include/plat/common/platform.h
|
||||
|
|
|
@ -430,6 +430,12 @@ performed.
|
|||
pages" section in [Firmware Design]. This flag is disabled by default and
|
||||
affects all BL images.
|
||||
|
||||
* `LOAD_IMAGE_V2`: Boolean option to enable support for new version (v2) of
|
||||
image loading, which provides more flexibility and scalability around what
|
||||
images are loaded and executed during boot. Default is 0.
|
||||
Note: `TRUSTED_BOARD_BOOT` is currently not supported when `LOAD_IMAGE_V2`
|
||||
is enabled.
|
||||
|
||||
#### ARM development platform specific build options
|
||||
|
||||
* `ARM_TSP_RAM_LOCATION`: location of the TSP binary. Options:
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
/*******************************************************************************
|
||||
* Mandatory SP_MIN functions
|
||||
******************************************************************************/
|
||||
void sp_min_early_platform_setup(void);
|
||||
void sp_min_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2);
|
||||
void sp_min_plat_arch_setup(void);
|
||||
void sp_min_platform_setup(void);
|
||||
entry_point_info_t *sp_min_plat_get_bl33_ep_info(void);
|
||||
|
|
|
@ -69,6 +69,16 @@
|
|||
lsl \reg, \reg, \tmp
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Declare the exception vector table, enforcing it is aligned on a
|
||||
* 32 byte boundary.
|
||||
*/
|
||||
.macro vector_base label
|
||||
.section .vectors, "ax"
|
||||
.align 5
|
||||
\label:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This macro calculates the base address of the current CPU's multi
|
||||
* processor(MP) stack using the plat_my_core_pos() index, the name of
|
||||
|
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __EL3_COMMON_MACROS_S__
|
||||
#define __EL3_COMMON_MACROS_S__
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <assert_macros.S>
|
||||
|
||||
/*
|
||||
* Helper macro to initialise EL3 registers we care about.
|
||||
*/
|
||||
.macro el3_arch_init_common _exception_vectors
|
||||
/* ---------------------------------------------------------------------
|
||||
* Enable the instruction cache and alignment checks
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr r1, =(SCTLR_RES1 | SCTLR_I_BIT | SCTLR_A_BIT)
|
||||
ldcopr r0, SCTLR
|
||||
orr r0, r0, r1
|
||||
stcopr r0, SCTLR
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Set the exception vectors (VBAR/MVBAR).
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr r0, =\_exception_vectors
|
||||
stcopr r0, VBAR
|
||||
stcopr r0, MVBAR
|
||||
isb
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Enable the SIF bit to disable instruction fetches
|
||||
* from Non-secure memory.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
ldcopr r0, SCR
|
||||
orr r0, r0, #SCR_SIF_BIT
|
||||
stcopr r0, SCR
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Enable the Asynchronous data abort now that the
|
||||
* exception vectors have been setup.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
cpsie a
|
||||
isb
|
||||
|
||||
/* Enable access to Advanced SIMD registers */
|
||||
ldcopr r0, NSACR
|
||||
bic r0, r0, #NSASEDIS_BIT
|
||||
bic r0, r0, #NSTRCDIS_BIT
|
||||
orr r0, r0, #(NASCR_CP10_BIT | NASCR_CP11_BIT)
|
||||
stcopr r0, NSACR
|
||||
isb
|
||||
|
||||
/*
|
||||
* Enable access to Advanced SIMD, Floating point and to the Trace
|
||||
* functionality as well.
|
||||
*/
|
||||
ldcopr r0, CPACR
|
||||
bic r0, r0, #ASEDIS_BIT
|
||||
bic r0, r0, #TRCDIS_BIT
|
||||
orr r0, r0, #CPACR_ENABLE_FP_ACCESS
|
||||
stcopr r0, CPACR
|
||||
isb
|
||||
|
||||
vmrs r0, FPEXC
|
||||
orr r0, r0, #FPEXC_EN_BIT
|
||||
vmsr FPEXC, r0
|
||||
isb
|
||||
.endm
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* This is the super set of actions that need to be performed during a cold boot
|
||||
* or a warm boot in EL3. This code is shared by BL1 and BL32 (SP_MIN).
|
||||
*
|
||||
* This macro will always perform reset handling, architectural initialisations
|
||||
* and stack setup. The rest of the actions are optional because they might not
|
||||
* be needed, depending on the context in which this macro is called. This is
|
||||
* why this macro is parameterised ; each parameter allows to enable/disable
|
||||
* some actions.
|
||||
*
|
||||
* _set_endian:
|
||||
* Whether the macro needs to configure the endianness of data accesses.
|
||||
*
|
||||
* _warm_boot_mailbox:
|
||||
* Whether the macro needs to detect the type of boot (cold/warm). The
|
||||
* detection is based on the platform entrypoint address : if it is zero
|
||||
* then it is a cold boot, otherwise it is a warm boot. In the latter case,
|
||||
* this macro jumps on the platform entrypoint address.
|
||||
*
|
||||
* _secondary_cold_boot:
|
||||
* Whether the macro needs to identify the CPU that is calling it: primary
|
||||
* CPU or secondary CPU. The primary CPU will be allowed to carry on with
|
||||
* the platform initialisations, while the secondaries will be put in a
|
||||
* platform-specific state in the meantime.
|
||||
*
|
||||
* If the caller knows this macro will only be called by the primary CPU
|
||||
* then this parameter can be defined to 0 to skip this step.
|
||||
*
|
||||
* _init_memory:
|
||||
* Whether the macro needs to initialise the memory.
|
||||
*
|
||||
* _init_c_runtime:
|
||||
* Whether the macro needs to initialise the C runtime environment.
|
||||
*
|
||||
* _exception_vectors:
|
||||
* Address of the exception vectors to program in the VBAR_EL3 register.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
.macro el3_entrypoint_common \
|
||||
_set_endian, _warm_boot_mailbox, _secondary_cold_boot, \
|
||||
_init_memory, _init_c_runtime, _exception_vectors
|
||||
|
||||
/* Make sure we are in Secure Mode */
|
||||
#if ASM_ASSERTION
|
||||
ldcopr r0, SCR
|
||||
tst r0, #SCR_NS_BIT
|
||||
ASM_ASSERT(eq)
|
||||
#endif
|
||||
|
||||
.if \_set_endian
|
||||
/* -------------------------------------------------------------
|
||||
* Set the CPU endianness before doing anything that might
|
||||
* involve memory reads or writes.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
ldcopr r0, SCTLR
|
||||
bic r0, r0, #SCTLR_EE_BIT
|
||||
stcopr r0, SCTLR
|
||||
isb
|
||||
.endif /* _set_endian */
|
||||
|
||||
/* Switch to monitor mode */
|
||||
cps #MODE32_mon
|
||||
isb
|
||||
|
||||
.if \_warm_boot_mailbox
|
||||
/* -------------------------------------------------------------
|
||||
* This code will be executed for both warm and cold resets.
|
||||
* Now is the time to distinguish between the two.
|
||||
* Query the platform entrypoint address and if it is not zero
|
||||
* then it means it is a warm boot so jump to this address.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
bl plat_get_my_entrypoint
|
||||
cmp r0, #0
|
||||
bxne r0
|
||||
.endif /* _warm_boot_mailbox */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* It is a cold boot.
|
||||
* Perform any processor specific actions upon reset e.g. cache, TLB
|
||||
* invalidations etc.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
bl reset_handler
|
||||
|
||||
el3_arch_init_common \_exception_vectors
|
||||
|
||||
.if \_secondary_cold_boot
|
||||
/* -------------------------------------------------------------
|
||||
* Check if this is a primary or secondary CPU cold boot.
|
||||
* The primary CPU will set up the platform while the
|
||||
* secondaries are placed in a platform-specific state until the
|
||||
* primary CPU performs the necessary actions to bring them out
|
||||
* of that state and allows entry into the OS.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
bl plat_is_my_cpu_primary
|
||||
cmp r0, #0
|
||||
bne do_primary_cold_boot
|
||||
|
||||
/* This is a cold boot on a secondary CPU */
|
||||
bl plat_secondary_cold_boot_setup
|
||||
/* plat_secondary_cold_boot_setup() is not supposed to return */
|
||||
bl plat_panic_handler
|
||||
|
||||
do_primary_cold_boot:
|
||||
.endif /* _secondary_cold_boot */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialize memory now. Secondary CPU initialization won't get to this
|
||||
* point.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.if \_init_memory
|
||||
bl platform_mem_init
|
||||
.endif /* _init_memory */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Init C runtime environment:
|
||||
* - Zero-initialise the NOBITS sections. There are 2 of them:
|
||||
* - the .bss section;
|
||||
* - the coherent memory section (if any).
|
||||
* - Relocate the data section from ROM to RAM, if required.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
.if \_init_c_runtime
|
||||
#if IMAGE_BL32
|
||||
/* -----------------------------------------------------------------
|
||||
* Invalidate the RW memory used by the BL32 (SP_MIN) 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
|
||||
#endif /* IMAGE_BL32 */
|
||||
|
||||
ldr r0, =__BSS_START__
|
||||
ldr r1, =__BSS_SIZE__
|
||||
bl zeromem
|
||||
|
||||
#if USE_COHERENT_MEM
|
||||
ldr r0, =__COHERENT_RAM_START__
|
||||
ldr r1, =__COHERENT_RAM_UNALIGNED_SIZE__
|
||||
bl zeromem
|
||||
#endif
|
||||
|
||||
#if IMAGE_BL1
|
||||
/* -----------------------------------------------------
|
||||
* Copy data from ROM to RAM.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
ldr r0, =__DATA_RAM_START__
|
||||
ldr r1, =__DATA_ROM_START__
|
||||
ldr r2, =__DATA_SIZE__
|
||||
bl memcpy
|
||||
#endif
|
||||
.endif /* _init_c_runtime */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* 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
|
||||
.endm
|
||||
|
||||
#endif /* __EL3_COMMON_MACROS_S__ */
|
|
@ -93,11 +93,22 @@
|
|||
#define EP_GET_EXE(x) (x & EP_EXE_MASK)
|
||||
#define EP_SET_EXE(x, ee) ((x) = ((x) & ~EP_EXE_MASK) | (ee))
|
||||
|
||||
#define EP_FIRST_EXE_MASK 0x10
|
||||
#define EP_FIRST_EXE 0x10
|
||||
#define EP_GET_FIRST_EXE(x) ((x) & EP_FIRST_EXE_MASK)
|
||||
#define EP_SET_FIRST_EXE(x, ee) ((x) = ((x) & ~EP_FIRST_EXE_MASK) | (ee))
|
||||
|
||||
#define PARAM_EP 0x01
|
||||
#define PARAM_IMAGE_BINARY 0x02
|
||||
#define PARAM_BL31 0x03
|
||||
#define PARAM_BL_LOAD_INFO 0x04
|
||||
#define PARAM_BL_PARAMS 0x05
|
||||
|
||||
#define IMAGE_ATTRIB_SKIP_LOADING 0x02
|
||||
#define IMAGE_ATTRIB_PLAT_SETUP 0x04
|
||||
|
||||
#define VERSION_1 0x01
|
||||
#define VERSION_2 0x02
|
||||
|
||||
#define INVALID_IMAGE_ID (0xFFFFFFFF)
|
||||
|
||||
|
@ -181,8 +192,10 @@ extern uintptr_t __COHERENT_RAM_END__;
|
|||
typedef struct meminfo {
|
||||
uintptr_t total_base;
|
||||
size_t total_size;
|
||||
#if !LOAD_IMAGE_V2
|
||||
uintptr_t free_base;
|
||||
size_t free_size;
|
||||
#endif
|
||||
} meminfo_t;
|
||||
|
||||
typedef struct aapcs64_params {
|
||||
|
@ -245,6 +258,9 @@ typedef struct image_info {
|
|||
param_header_t h;
|
||||
uintptr_t image_base; /* physical address of base of image */
|
||||
uint32_t image_size; /* bytes read from image file */
|
||||
#if LOAD_IMAGE_V2
|
||||
uint32_t image_max_size;
|
||||
#endif
|
||||
} image_info_t;
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -263,6 +279,39 @@ typedef struct image_desc {
|
|||
entry_point_info_t ep_info;
|
||||
} image_desc_t;
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
/* BL image node in the BL image loading sequence */
|
||||
typedef struct bl_load_info_node {
|
||||
unsigned int image_id;
|
||||
image_info_t *image_info;
|
||||
struct bl_load_info_node *next_load_info;
|
||||
} bl_load_info_node_t;
|
||||
|
||||
/* BL image head node in the BL image loading sequence */
|
||||
typedef struct bl_load_info {
|
||||
param_header_t h;
|
||||
bl_load_info_node_t *head;
|
||||
} bl_load_info_t;
|
||||
|
||||
/* BL image node in the BL image execution sequence */
|
||||
typedef struct bl_params_node {
|
||||
unsigned int image_id;
|
||||
image_info_t *image_info;
|
||||
entry_point_info_t *ep_info;
|
||||
struct bl_params_node *next_params_info;
|
||||
} bl_params_node_t;
|
||||
|
||||
/*
|
||||
* BL image head node in the BL image execution sequence
|
||||
* It is also used to pass information to next BL image.
|
||||
*/
|
||||
typedef struct bl_params {
|
||||
param_header_t h;
|
||||
bl_params_node_t *head;
|
||||
} bl_params_t;
|
||||
|
||||
#else /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*******************************************************************************
|
||||
* This structure represents the superset of information that can be passed to
|
||||
* BL31 e.g. while passing control to it from BL2. The BL32 parameters will be
|
||||
|
@ -286,6 +335,7 @@ typedef struct bl31_params {
|
|||
image_info_t *bl33_image_info;
|
||||
} bl31_params_t;
|
||||
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*
|
||||
* Compile time assertions related to the 'entry_point_info' structure to
|
||||
|
@ -308,24 +358,34 @@ CASSERT(sizeof(uintptr_t) ==
|
|||
/*******************************************************************************
|
||||
* Function & variable prototypes
|
||||
******************************************************************************/
|
||||
uintptr_t page_align(uintptr_t, unsigned);
|
||||
size_t image_size(unsigned int image_id);
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
|
||||
int load_image(unsigned int image_id, image_info_t *image_data);
|
||||
int load_auth_image(unsigned int image_id, image_info_t *image_data);
|
||||
|
||||
#else
|
||||
|
||||
uintptr_t page_align(uintptr_t, unsigned);
|
||||
int load_image(meminfo_t *mem_layout,
|
||||
unsigned int image_id,
|
||||
uintptr_t image_base,
|
||||
image_info_t *image_data,
|
||||
entry_point_info_t *entry_point_info);
|
||||
int load_auth_image(meminfo_t *mem_layout,
|
||||
unsigned int image_name,
|
||||
unsigned int image_id,
|
||||
uintptr_t image_base,
|
||||
image_info_t *image_data,
|
||||
entry_point_info_t *entry_point_info);
|
||||
extern const char build_message[];
|
||||
extern const char version_string[];
|
||||
|
||||
void reserve_mem(uintptr_t *free_base, size_t *free_size,
|
||||
uintptr_t addr, size_t size);
|
||||
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
extern const char build_message[];
|
||||
extern const char version_string[];
|
||||
|
||||
void print_entry_point_info(const entry_point_info_t *ep_info);
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __DESC_IMAGE_LOAD_H__
|
||||
#define __DESC_IMAGE_LOAD_H__
|
||||
|
||||
#include <bl_common.h>
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
/* Following structure is used to store BL ep/image info. */
|
||||
typedef struct bl_mem_params_node {
|
||||
unsigned int image_id;
|
||||
image_info_t image_info;
|
||||
entry_point_info_t ep_info;
|
||||
unsigned int next_handoff_image_id;
|
||||
bl_load_info_node_t load_node_mem;
|
||||
bl_params_node_t params_node_mem;
|
||||
} bl_mem_params_node_t;
|
||||
|
||||
/*
|
||||
* Macro to register list of BL image descriptors,
|
||||
* defined as an array of bl_mem_params_node_t.
|
||||
*/
|
||||
#define REGISTER_BL_IMAGE_DESCS(_img_desc) \
|
||||
bl_mem_params_node_t *bl_mem_params_desc_ptr = &_img_desc[0]; \
|
||||
unsigned int bl_mem_params_desc_num = ARRAY_SIZE(_img_desc);
|
||||
|
||||
/* BL image loading utility functions */
|
||||
void flush_bl_params_desc(void);
|
||||
int get_bl_params_node_index(unsigned int image_id);
|
||||
bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id);
|
||||
bl_load_info_t *get_bl_load_info_from_mem_params_desc(void);
|
||||
bl_params_t *get_next_bl_params_from_mem_params_desc(void);
|
||||
|
||||
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
#endif /* __DESC_IMAGE_LOAD_H__ */
|
|
@ -191,6 +191,7 @@
|
|||
|
||||
/* NASCR definitions */
|
||||
#define NSASEDIS_BIT (1 << 15)
|
||||
#define NSTRCDIS_BIT (1 << 20)
|
||||
#define NASCR_CP11_BIT (1 << 11)
|
||||
#define NASCR_CP10_BIT (1 << 10)
|
||||
|
||||
|
|
|
@ -187,6 +187,9 @@ void flush_dcache_range(uintptr_t addr, size_t size);
|
|||
void clean_dcache_range(uintptr_t addr, size_t size);
|
||||
void inv_dcache_range(uintptr_t addr, size_t size);
|
||||
|
||||
void disable_mmu_secure(void);
|
||||
void disable_mmu_icache_secure(void);
|
||||
|
||||
DEFINE_SYSOP_FUNC(wfi)
|
||||
DEFINE_SYSOP_FUNC(wfe)
|
||||
DEFINE_SYSOP_FUNC(sev)
|
||||
|
@ -196,6 +199,9 @@ DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
|
|||
DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
|
||||
DEFINE_SYSOP_FUNC(isb)
|
||||
|
||||
void __dead2 smc(uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3,
|
||||
uint32_t r4, uint32_t r5, uint32_t r6, uint32_t r7);
|
||||
|
||||
DEFINE_SYSREG_RW_FUNCS(spsr)
|
||||
DEFINE_SYSREG_RW_FUNCS(cpsr)
|
||||
|
||||
|
@ -289,4 +295,6 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC)
|
|||
|
||||
#define read_cntpct_el0() read64_cntpct()
|
||||
|
||||
#define read_ctr_el0() read_ctr()
|
||||
|
||||
#endif /* __ARCH_HELPERS_H__ */
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __CORTEX_A32_H__
|
||||
#define __CORTEX_A32_H__
|
||||
|
||||
/* Cortex-A32 Main ID register for revision 0 */
|
||||
#define CORTEX_A32_MIDR 0x410FD010
|
||||
|
||||
/*******************************************************************************
|
||||
* CPU Extended Control register specific definitions.
|
||||
* CPUECTLR_EL1 is an implementation-specific register.
|
||||
******************************************************************************/
|
||||
#define CORTEX_A32_CPUECTLR_EL1 p15, 1, c15
|
||||
#define CORTEX_A32_CPUECTLR_SMPEN_BIT (1 << 6)
|
||||
|
||||
#endif /* __CORTEX_A32_H__ */
|
|
@ -42,12 +42,16 @@
|
|||
CPU_MIDR: /* cpu_ops midr */
|
||||
.space 4
|
||||
/* Reset fn is needed during reset */
|
||||
#if IMAGE_BL1 || IMAGE_BL32
|
||||
CPU_RESET_FUNC: /* cpu_ops reset_func */
|
||||
.space 4
|
||||
#endif
|
||||
#if IMAGE_BL32 /* The power down core and cluster is needed only in BL32 */
|
||||
CPU_PWR_DWN_CORE: /* cpu_ops core_pwr_dwn */
|
||||
.space 4
|
||||
CPU_PWR_DWN_CLUSTER: /* cpu_ops cluster_pwr_dwn */
|
||||
.space 4
|
||||
#endif
|
||||
CPU_OPS_SIZE = .
|
||||
|
||||
/*
|
||||
|
@ -60,13 +64,17 @@ CPU_OPS_SIZE = .
|
|||
.align 2
|
||||
.type cpu_ops_\_name, %object
|
||||
.word \_midr
|
||||
#if IMAGE_BL1 || IMAGE_BL32
|
||||
.if \_noresetfunc
|
||||
.word 0
|
||||
.else
|
||||
.word \_name\()_reset_func
|
||||
.endif
|
||||
#endif
|
||||
#if IMAGE_BL32
|
||||
.word \_name\()_core_pwr_dwn
|
||||
.word \_name\()_cluster_pwr_dwn
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* __CPU_MACROS_S__ */
|
||||
|
|
|
@ -103,5 +103,9 @@ static inline void cm_set_next_context(void *context)
|
|||
"msr spsel, #0\n"
|
||||
: : "r" (context));
|
||||
}
|
||||
|
||||
#else
|
||||
void *cm_get_next_context(void);
|
||||
#endif /* AARCH32 */
|
||||
|
||||
#endif /* __CM_H__ */
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
******************************************************************************/
|
||||
struct bl31_params;
|
||||
struct meminfo;
|
||||
struct image_info;
|
||||
|
||||
#define ARM_CASSERT_MMAP \
|
||||
CASSERT((ARRAY_SIZE(plat_arm_mmap) + ARM_BL_REGIONS) \
|
||||
|
@ -164,8 +165,13 @@ void arm_bl2u_platform_setup(void);
|
|||
void arm_bl2u_plat_arch_setup(void);
|
||||
|
||||
/* BL31 utility functions */
|
||||
#if LOAD_IMAGE_V2
|
||||
void arm_bl31_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2);
|
||||
#else
|
||||
void arm_bl31_early_platform_setup(struct bl31_params *from_bl2,
|
||||
void *plat_params_from_bl2);
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
void arm_bl31_platform_setup(void);
|
||||
void arm_bl31_plat_runtime_setup(void);
|
||||
void arm_bl31_plat_arch_setup(void);
|
||||
|
@ -174,7 +180,8 @@ void arm_bl31_plat_arch_setup(void);
|
|||
void arm_tsp_early_platform_setup(void);
|
||||
|
||||
/* SP_MIN utility functions */
|
||||
void arm_sp_min_early_platform_setup(void);
|
||||
void arm_sp_min_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2);
|
||||
|
||||
/* FIP TOC validity check */
|
||||
int arm_io_is_toc_valid(void);
|
||||
|
@ -194,6 +201,14 @@ void plat_arm_interconnect_init(void);
|
|||
void plat_arm_interconnect_enter_coherency(void);
|
||||
void plat_arm_interconnect_exit_coherency(void);
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
/*
|
||||
* This function is called after loading SCP_BL2 image and it is used to perform
|
||||
* any platform-specific actions required to handle the SCP firmware.
|
||||
*/
|
||||
int plat_arm_bl2_handle_scp_bl2(struct image_info *scp_bl2_image_info);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Optional functions required in ARM standard platforms
|
||||
*/
|
||||
|
|
|
@ -41,9 +41,13 @@
|
|||
/*
|
||||
* Platform binary types for linking
|
||||
*/
|
||||
#ifdef AARCH32
|
||||
#define PLATFORM_LINKER_FORMAT "elf32-littlearm"
|
||||
#define PLATFORM_LINKER_ARCH arm
|
||||
#else
|
||||
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
|
||||
#define PLATFORM_LINKER_ARCH aarch64
|
||||
|
||||
#endif /* AARCH32 */
|
||||
|
||||
/*
|
||||
* Generic platform constants
|
||||
|
@ -70,6 +74,18 @@
|
|||
#define MAKE_ULL(x) x
|
||||
#endif
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
#define BL2_IMAGE_DESC { \
|
||||
.image_id = BL2_IMAGE_ID, \
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, \
|
||||
VERSION_2, image_info_t, 0), \
|
||||
.image_info.image_base = BL2_BASE, \
|
||||
.image_info.image_max_size = BL2_LIMIT - BL2_BASE,\
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, \
|
||||
VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),\
|
||||
.ep_info.pc = BL2_BASE, \
|
||||
}
|
||||
#else /* LOAD_IMAGE_V2 */
|
||||
#define BL2_IMAGE_DESC { \
|
||||
.image_id = BL2_IMAGE_ID, \
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, \
|
||||
|
@ -79,6 +95,7 @@
|
|||
VERSION_1, entry_point_info_t, SECURE | EXECUTABLE),\
|
||||
.ep_info.pc = BL2_BASE, \
|
||||
}
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*
|
||||
* The following constants identify the extents of the code & read-only data
|
||||
|
|
|
@ -44,6 +44,8 @@ struct image_info;
|
|||
struct entry_point_info;
|
||||
struct bl31_params;
|
||||
struct image_desc;
|
||||
struct bl_load_info;
|
||||
struct bl_params;
|
||||
|
||||
/*******************************************************************************
|
||||
* plat_get_rotpk_info() flags
|
||||
|
@ -84,7 +86,7 @@ uint32_t plat_interrupt_type_to_line(uint32_t type,
|
|||
* Optional common functions (may be overridden)
|
||||
******************************************************************************/
|
||||
uintptr_t plat_get_my_stack(void);
|
||||
void plat_report_exception(unsigned long);
|
||||
void plat_report_exception(unsigned int exception_type);
|
||||
int plat_crash_console_init(void);
|
||||
int plat_crash_console_putc(int c);
|
||||
void plat_error_handler(int err) __dead2;
|
||||
|
@ -138,6 +140,15 @@ void bl2_plat_arch_setup(void);
|
|||
void bl2_platform_setup(void);
|
||||
struct meminfo *bl2_plat_sec_mem_layout(void);
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
/*
|
||||
* This function can be used by the platforms to update/use image
|
||||
* information for given `image_id`.
|
||||
*/
|
||||
int bl2_plat_handle_post_image_load(unsigned int image_id);
|
||||
|
||||
#else /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*
|
||||
* This function returns a pointer to the shared memory that the platform has
|
||||
* kept aside to pass trusted firmware related information that BL31
|
||||
|
@ -194,6 +205,8 @@ void bl2_plat_set_bl32_ep_info(struct image_info *image,
|
|||
/* Gets the memory layout for BL32 */
|
||||
void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info);
|
||||
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*******************************************************************************
|
||||
* Optional BL2 functions (may be overridden)
|
||||
******************************************************************************/
|
||||
|
@ -218,8 +231,13 @@ int bl2u_plat_handle_scp_bl2u(void);
|
|||
/*******************************************************************************
|
||||
* Mandatory BL31 functions
|
||||
******************************************************************************/
|
||||
#if LOAD_IMAGE_V2
|
||||
void bl31_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2);
|
||||
#else
|
||||
void bl31_early_platform_setup(struct bl31_params *from_bl2,
|
||||
void *plat_params_from_bl2);
|
||||
#endif
|
||||
void bl31_plat_arch_setup(void);
|
||||
void bl31_platform_setup(void);
|
||||
void bl31_plat_runtime_setup(void);
|
||||
|
@ -257,6 +275,31 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
|
|||
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr);
|
||||
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
/*******************************************************************************
|
||||
* Mandatory BL image load functions(may be overridden).
|
||||
******************************************************************************/
|
||||
/*
|
||||
* This function returns pointer to the list of images that the
|
||||
* platform has populated to load.
|
||||
*/
|
||||
struct bl_load_info *plat_get_bl_image_load_info(void);
|
||||
|
||||
/*
|
||||
* This function returns a pointer to the shared memory that the
|
||||
* platform has kept aside to pass trusted firmware related
|
||||
* information that next BL image could need.
|
||||
*/
|
||||
struct bl_params *plat_get_next_bl_params(void);
|
||||
|
||||
/*
|
||||
* This function flushes to main memory all the params that are
|
||||
* passed to next image.
|
||||
*/
|
||||
void plat_flush_next_bl_params(void);
|
||||
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
#if ENABLE_PLAT_COMPAT
|
||||
/*
|
||||
* The below declarations are to enable compatibility for the platform ports
|
||||
|
|
|
@ -32,7 +32,21 @@
|
|||
#include <asm_macros.S>
|
||||
#include <assert_macros.S>
|
||||
|
||||
.globl smc
|
||||
.globl zeromem
|
||||
.globl disable_mmu_icache_secure
|
||||
.globl disable_mmu_secure
|
||||
|
||||
func smc
|
||||
/*
|
||||
* For AArch32 only r0-r3 will be in the registers;
|
||||
* rest r4-r6 will be pushed on to the stack. So here, we'll
|
||||
* have to load them from the stack to registers r4-r6 explicitly.
|
||||
* Clobbers: r4-r6
|
||||
*/
|
||||
ldm sp, {r4, r5, r6}
|
||||
smc #0
|
||||
endfunc smc
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* void zeromem(void *mem, unsigned int length);
|
||||
|
@ -58,3 +72,25 @@ z_loop:
|
|||
z_end:
|
||||
bx lr
|
||||
endfunc zeromem
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Disable the MMU in Secure State
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
func disable_mmu_secure
|
||||
mov r1, #(SCTLR_M_BIT | SCTLR_C_BIT)
|
||||
do_disable_mmu:
|
||||
ldcopr r0, SCTLR
|
||||
bic r0, r0, r1
|
||||
stcopr r0, SCTLR
|
||||
isb // ensure MMU is off
|
||||
dsb sy
|
||||
bx lr
|
||||
endfunc disable_mmu_secure
|
||||
|
||||
|
||||
func disable_mmu_icache_secure
|
||||
ldr r1, =(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT)
|
||||
b do_disable_mmu
|
||||
endfunc disable_mmu_icache_secure
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <assert_macros.S>
|
||||
#include <cortex_a32.h>
|
||||
#include <cpu_macros.S>
|
||||
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Disable intra-cluster coherency
|
||||
* Clobbers: r0-r1
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
func cortex_a32_disable_smp
|
||||
ldcopr16 r0, r1, CORTEX_A32_CPUECTLR_EL1
|
||||
bic r0, r0, #CORTEX_A32_CPUECTLR_SMPEN_BIT
|
||||
stcopr16 r0, r1, CORTEX_A32_CPUECTLR_EL1
|
||||
isb
|
||||
dsb sy
|
||||
bx lr
|
||||
endfunc cortex_a32_disable_smp
|
||||
|
||||
/* -------------------------------------------------
|
||||
* The CPU Ops reset function for Cortex-A32.
|
||||
* Clobbers: r0-r1
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func cortex_a32_reset_func
|
||||
/* ---------------------------------------------
|
||||
* Enable the SMP bit.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
ldcopr16 r0, r1, CORTEX_A32_CPUECTLR_EL1
|
||||
orr r0, r0, #CORTEX_A32_CPUECTLR_SMPEN_BIT
|
||||
stcopr16 r0, r1, CORTEX_A32_CPUECTLR_EL1
|
||||
isb
|
||||
bx lr
|
||||
endfunc cortex_a32_reset_func
|
||||
|
||||
/* ----------------------------------------------------
|
||||
* The CPU Ops core power down function for Cortex-A32.
|
||||
* Clobbers: r0-r3
|
||||
* ----------------------------------------------------
|
||||
*/
|
||||
func cortex_a32_core_pwr_dwn
|
||||
push {lr}
|
||||
|
||||
/* Assert if cache is enabled */
|
||||
#if ASM_ASSERTION
|
||||
ldcopr r0, SCTLR
|
||||
tst r0, #SCTLR_C_BIT
|
||||
ASM_ASSERT(eq)
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Flush L1 caches.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mov r0, #DC_OP_CISW
|
||||
bl dcsw_op_level1
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Come out of intra cluster coherency
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
pop {lr}
|
||||
b cortex_a32_disable_smp
|
||||
endfunc cortex_a32_core_pwr_dwn
|
||||
|
||||
/* -------------------------------------------------------
|
||||
* The CPU Ops cluster power down function for Cortex-A32.
|
||||
* Clobbers: r0-r3
|
||||
* -------------------------------------------------------
|
||||
*/
|
||||
func cortex_a32_cluster_pwr_dwn
|
||||
push {lr}
|
||||
|
||||
/* Assert if cache is enabled */
|
||||
#if ASM_ASSERTION
|
||||
ldcopr r0, SCTLR
|
||||
tst r0, #SCTLR_C_BIT
|
||||
ASM_ASSERT(eq)
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Flush L1 cache.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mov r0, #DC_OP_CISW
|
||||
bl dcsw_op_level1
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Disable the optional ACP.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
bl plat_disable_acp
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Flush L2 cache.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mov r0, #DC_OP_CISW
|
||||
bl dcsw_op_level2
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Come out of intra cluster coherency
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
pop {lr}
|
||||
b cortex_a32_disable_smp
|
||||
endfunc cortex_a32_cluster_pwr_dwn
|
||||
|
||||
declare_cpu_ops cortex_a32, CORTEX_A32_MIDR
|
|
@ -34,6 +34,7 @@
|
|||
#include <cpu_data.h>
|
||||
#include <cpu_macros.S>
|
||||
|
||||
#if IMAGE_BL1 || IMAGE_BL32
|
||||
/*
|
||||
* The reset handler common to all platforms. After a matching
|
||||
* cpu_ops structure entry is found, the correponding reset_handler
|
||||
|
@ -65,6 +66,9 @@ func reset_handler
|
|||
bx lr
|
||||
endfunc reset_handler
|
||||
|
||||
#endif /* IMAGE_BL1 || IMAGE_BL32 */
|
||||
|
||||
#if IMAGE_BL32 /* The power down core and cluster is needed only in BL32 */
|
||||
/*
|
||||
* The prepare core power down function for all platforms. After
|
||||
* the cpu_ops pointer is retrieved from cpu_data, the corresponding
|
||||
|
@ -132,6 +136,8 @@ func init_cpu_ops
|
|||
pop {r4 - r6, pc}
|
||||
endfunc init_cpu_ops
|
||||
|
||||
#endif /* IMAGE_BL32 */
|
||||
|
||||
/*
|
||||
* The below function returns the cpu_ops structure matching the
|
||||
* midr of the core. It reads the MIDR and finds the matching
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <asm_macros.S>
|
||||
|
||||
.globl semihosting_call
|
||||
|
||||
func semihosting_call
|
||||
svc #0x123456
|
||||
bx lr
|
||||
endfunc semihosting_call
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <asm_macros.S>
|
||||
#include <bl_common.h>
|
||||
#include <v2m_def.h>
|
||||
|
||||
.globl plat_report_exception
|
||||
|
||||
|
||||
/* -------------------------------------------------------
|
||||
* void plat_report_exception(unsigned int type)
|
||||
* Function to report an unhandled exception
|
||||
* with platform-specific means.
|
||||
* On FVP platform, it updates the LEDs
|
||||
* to indicate where we are.
|
||||
* SYS_LED[0] - 0x0
|
||||
* SYS_LED[2:1] - 0x0
|
||||
* SYS_LED[7:3] - Exception Mode.
|
||||
* Clobbers: r0-r1
|
||||
* -------------------------------------------------------
|
||||
*/
|
||||
func plat_report_exception
|
||||
lsl r0, r0, #V2M_SYS_LED_EC_SHIFT
|
||||
ldr r1, =V2M_SYSREGS_BASE
|
||||
add r1, r1, #V2M_SYS_LED
|
||||
str r0, [r1]
|
||||
bx lr
|
||||
endfunc plat_report_exception
|
|
@ -31,10 +31,8 @@
|
|||
PLAT_INCLUDES += -Iinclude/plat/arm/board/common/ \
|
||||
-Iinclude/plat/arm/board/common/drivers
|
||||
|
||||
PLAT_BL_COMMON_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S
|
||||
ifeq (${ARCH}, aarch64)
|
||||
PLAT_BL_COMMON_SOURCES += plat/arm/board/common/aarch64/board_arm_helpers.S
|
||||
endif
|
||||
PLAT_BL_COMMON_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \
|
||||
plat/arm/board/common/${ARCH}/board_arm_helpers.S
|
||||
|
||||
BL1_SOURCES += plat/arm/board/common/drivers/norflash/norflash.c
|
||||
|
||||
|
|
|
@ -34,9 +34,22 @@
|
|||
#include "../drivers/pwrc/fvp_pwrc.h"
|
||||
#include "../fvp_def.h"
|
||||
|
||||
.globl plat_secondary_cold_boot_setup
|
||||
.globl plat_get_my_entrypoint
|
||||
.globl plat_is_my_cpu_primary
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* void plat_secondary_cold_boot_setup (void);
|
||||
*
|
||||
* For AArch32, cold-booting secondary CPUs is not yet
|
||||
* implemented and they panic.
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_secondary_cold_boot_setup
|
||||
cb_panic:
|
||||
b cb_panic
|
||||
endfunc plat_secondary_cold_boot_setup
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* unsigned long plat_get_my_entrypoint (void);
|
||||
*
|
||||
|
|
|
@ -31,9 +31,13 @@
|
|||
#include <plat_arm.h>
|
||||
#include "fvp_private.h"
|
||||
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
void bl31_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
#else
|
||||
void bl31_early_platform_setup(bl31_params_t *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
#endif
|
||||
{
|
||||
arm_bl31_early_platform_setup(from_bl2, plat_params_from_bl2);
|
||||
|
||||
|
|
|
@ -109,12 +109,14 @@ FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a35.S \
|
|||
lib/cpus/aarch64/cortex_a57.S \
|
||||
lib/cpus/aarch64/cortex_a72.S \
|
||||
lib/cpus/aarch64/cortex_a73.S
|
||||
else
|
||||
FVP_CPU_LIBS += lib/cpus/aarch32/cortex_a32.S
|
||||
endif
|
||||
|
||||
BL1_SOURCES += drivers/io/io_semihosting.c \
|
||||
lib/semihosting/semihosting.c \
|
||||
lib/semihosting/aarch64/semihosting_call.S \
|
||||
plat/arm/board/fvp/aarch64/fvp_helpers.S \
|
||||
lib/semihosting/${ARCH}/semihosting_call.S \
|
||||
plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
|
||||
plat/arm/board/fvp/fvp_bl1_setup.c \
|
||||
plat/arm/board/fvp/fvp_err.c \
|
||||
plat/arm/board/fvp/fvp_io_storage.c \
|
||||
|
@ -126,7 +128,7 @@ BL1_SOURCES += drivers/io/io_semihosting.c \
|
|||
BL2_SOURCES += drivers/io/io_semihosting.c \
|
||||
drivers/delay_timer/delay_timer.c \
|
||||
lib/semihosting/semihosting.c \
|
||||
lib/semihosting/aarch64/semihosting_call.S \
|
||||
lib/semihosting/${ARCH}/semihosting_call.S \
|
||||
plat/arm/board/fvp/fvp_bl2_setup.c \
|
||||
plat/arm/board/fvp/fvp_err.c \
|
||||
plat/arm/board/fvp/fvp_io_storage.c \
|
||||
|
|
|
@ -31,9 +31,10 @@
|
|||
#include <plat_arm.h>
|
||||
#include "../fvp_private.h"
|
||||
|
||||
void sp_min_early_platform_setup(void)
|
||||
void sp_min_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
{
|
||||
arm_sp_min_early_platform_setup();
|
||||
arm_sp_min_early_platform_setup(from_bl2, plat_params_from_bl2);
|
||||
|
||||
/* Initialize the platform config for future decision making */
|
||||
fvp_config_setup();
|
||||
|
|
|
@ -184,6 +184,12 @@
|
|||
#define PLAT_CSS_PRIMARY_CPU_SHIFT 8
|
||||
#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 4
|
||||
|
||||
/*
|
||||
* PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
|
||||
* SCP_BL2 size plus a little space for growth.
|
||||
*/
|
||||
#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x1D000
|
||||
|
||||
/*
|
||||
* Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
|
||||
* terminology. On a GICv2 system or mode, the lists will be merged and treated
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <bl_common.h>
|
||||
#include <desc_image_load.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Following descriptor provides BL image/ep information that gets used
|
||||
* by BL2 to load the images and also subset of this information is
|
||||
* passed to next BL image. The image loading sequence is managed by
|
||||
* populating the images in required loading order. The image execution
|
||||
* sequence is managed by populating the `next_handoff_image_id` with
|
||||
* the next executable image id.
|
||||
******************************************************************************/
|
||||
static bl_mem_params_node_t bl2_mem_params_descs[] = {
|
||||
#ifdef SCP_BL2_BASE
|
||||
/* Fill SCP_BL2 related information if it exists */
|
||||
{
|
||||
.image_id = SCP_BL2_IMAGE_ID,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
|
||||
VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
|
||||
VERSION_2, image_info_t, 0),
|
||||
.image_info.image_base = SCP_BL2_BASE,
|
||||
.image_info.image_max_size = PLAT_CSS_MAX_SCP_BL2_SIZE,
|
||||
|
||||
.next_handoff_image_id = INVALID_IMAGE_ID,
|
||||
},
|
||||
#endif /* SCP_BL2_BASE */
|
||||
|
||||
/* Fill BL32 related information */
|
||||
{
|
||||
.image_id = BL32_IMAGE_ID,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
|
||||
VERSION_2, entry_point_info_t,
|
||||
SECURE | EXECUTABLE | EP_FIRST_EXE),
|
||||
.ep_info.pc = BL32_BASE,
|
||||
.ep_info.spsr = SPSR_MODE32(MODE32_mon, SPSR_T_ARM,
|
||||
SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS),
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
|
||||
VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
|
||||
.image_info.image_base = BL32_BASE,
|
||||
.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
|
||||
|
||||
.next_handoff_image_id = BL33_IMAGE_ID,
|
||||
},
|
||||
|
||||
/* Fill BL33 related information */
|
||||
{
|
||||
.image_id = BL33_IMAGE_ID,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
|
||||
VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
|
||||
#ifdef PRELOADED_BL33_BASE
|
||||
.ep_info.pc = PRELOADED_BL33_BASE,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
|
||||
VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
|
||||
#else
|
||||
.ep_info.pc = PLAT_ARM_NS_IMAGE_OFFSET,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
|
||||
VERSION_2, image_info_t, 0),
|
||||
.image_info.image_base = PLAT_ARM_NS_IMAGE_OFFSET,
|
||||
.image_info.image_max_size = ARM_DRAM1_SIZE,
|
||||
#endif /* PRELOADED_BL33_BASE */
|
||||
|
||||
.next_handoff_image_id = INVALID_IMAGE_ID,
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <bl_common.h>
|
||||
#include <desc_image_load.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Following descriptor provides BL image/ep information that gets used
|
||||
* by BL2 to load the images and also subset of this information is
|
||||
* passed to next BL image. The image loading sequence is managed by
|
||||
* populating the images in required loading order. The image execution
|
||||
* sequence is managed by populating the `next_handoff_image_id` with
|
||||
* the next executable image id.
|
||||
******************************************************************************/
|
||||
static bl_mem_params_node_t bl2_mem_params_descs[] = {
|
||||
#ifdef SCP_BL2_BASE
|
||||
/* Fill SCP_BL2 related information if it exists */
|
||||
{
|
||||
.image_id = SCP_BL2_IMAGE_ID,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
|
||||
VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
|
||||
VERSION_2, image_info_t, 0),
|
||||
.image_info.image_base = SCP_BL2_BASE,
|
||||
.image_info.image_max_size = PLAT_CSS_MAX_SCP_BL2_SIZE,
|
||||
|
||||
.next_handoff_image_id = INVALID_IMAGE_ID,
|
||||
},
|
||||
#endif /* SCP_BL2_BASE */
|
||||
|
||||
#ifdef EL3_PAYLOAD_BASE
|
||||
/* Fill EL3 payload related information (BL31 is EL3 payload)*/
|
||||
{
|
||||
.image_id = BL31_IMAGE_ID,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
|
||||
VERSION_2, entry_point_info_t,
|
||||
SECURE | EXECUTABLE | EP_FIRST_EXE),
|
||||
.ep_info.pc = EL3_PAYLOAD_BASE,
|
||||
.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS),
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
|
||||
VERSION_2, image_info_t,
|
||||
IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
|
||||
|
||||
.next_handoff_image_id = INVALID_IMAGE_ID,
|
||||
},
|
||||
|
||||
#else /* EL3_PAYLOAD_BASE */
|
||||
|
||||
/* Fill BL31 related information */
|
||||
{
|
||||
.image_id = BL31_IMAGE_ID,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
|
||||
VERSION_2, entry_point_info_t,
|
||||
SECURE | EXECUTABLE | EP_FIRST_EXE),
|
||||
.ep_info.pc = BL31_BASE,
|
||||
.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS),
|
||||
#if DEBUG
|
||||
.ep_info.args.arg1 = ARM_BL31_PLAT_PARAM_VAL,
|
||||
#endif
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
|
||||
VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
|
||||
.image_info.image_base = BL31_BASE,
|
||||
.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
|
||||
|
||||
# ifdef BL32_BASE
|
||||
.next_handoff_image_id = BL32_IMAGE_ID,
|
||||
# else
|
||||
.next_handoff_image_id = BL33_IMAGE_ID,
|
||||
# endif
|
||||
},
|
||||
|
||||
# ifdef BL32_BASE
|
||||
/* Fill BL32 related information */
|
||||
{
|
||||
.image_id = BL32_IMAGE_ID,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
|
||||
VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
|
||||
.ep_info.pc = BL32_BASE,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
|
||||
VERSION_2, image_info_t, 0),
|
||||
.image_info.image_base = BL32_BASE,
|
||||
.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
|
||||
|
||||
.next_handoff_image_id = BL33_IMAGE_ID,
|
||||
},
|
||||
# endif /* BL32_BASE */
|
||||
|
||||
/* Fill BL33 related information */
|
||||
{
|
||||
.image_id = BL33_IMAGE_ID,
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
|
||||
VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
|
||||
# ifdef PRELOADED_BL33_BASE
|
||||
.ep_info.pc = PRELOADED_BL33_BASE,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
|
||||
VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
|
||||
# else
|
||||
.ep_info.pc = PLAT_ARM_NS_IMAGE_OFFSET,
|
||||
|
||||
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
|
||||
VERSION_2, image_info_t, 0),
|
||||
.image_info.image_base = PLAT_ARM_NS_IMAGE_OFFSET,
|
||||
.image_info.image_max_size = ARM_DRAM1_SIZE,
|
||||
# endif /* PRELOADED_BL33_BASE */
|
||||
|
||||
.next_handoff_image_id = INVALID_IMAGE_ID,
|
||||
}
|
||||
#endif /* EL3_PAYLOAD_BASE */
|
||||
};
|
||||
|
||||
REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
|
|
@ -73,7 +73,6 @@ meminfo_t *bl1_plat_sec_mem_layout(void)
|
|||
******************************************************************************/
|
||||
void arm_bl1_early_platform_setup(void)
|
||||
{
|
||||
const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
|
||||
|
||||
#if !ARM_DISABLE_TRUSTED_WDOG
|
||||
/* Enable watchdog */
|
||||
|
@ -88,13 +87,15 @@ void arm_bl1_early_platform_setup(void)
|
|||
bl1_tzram_layout.total_base = ARM_BL_RAM_BASE;
|
||||
bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE;
|
||||
|
||||
#if !LOAD_IMAGE_V2
|
||||
/* Calculate how much RAM BL1 is using and how much remains free */
|
||||
bl1_tzram_layout.free_base = ARM_BL_RAM_BASE;
|
||||
bl1_tzram_layout.free_size = ARM_BL_RAM_SIZE;
|
||||
reserve_mem(&bl1_tzram_layout.free_base,
|
||||
&bl1_tzram_layout.free_size,
|
||||
BL1_RAM_BASE,
|
||||
bl1_size);
|
||||
BL1_RAM_LIMIT - BL1_RAM_BASE);
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
}
|
||||
|
||||
void bl1_early_platform_setup(void)
|
||||
|
@ -131,7 +132,11 @@ void arm_bl1_plat_arch_setup(void)
|
|||
BL1_COHERENT_RAM_LIMIT
|
||||
#endif
|
||||
);
|
||||
#ifdef AARCH32
|
||||
enable_mmu_secure(0);
|
||||
#else
|
||||
enable_mmu_el3(0);
|
||||
#endif /* AARCH32 */
|
||||
}
|
||||
|
||||
void bl1_plat_arch_setup(void)
|
||||
|
|
|
@ -30,10 +30,13 @@
|
|||
|
||||
#include <arch_helpers.h>
|
||||
#include <arm_def.h>
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <console.h>
|
||||
#include <platform_def.h>
|
||||
#include <debug.h>
|
||||
#include <desc_image_load.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform_def.h>
|
||||
#include <string.h>
|
||||
|
||||
#if USE_COHERENT_MEM
|
||||
|
@ -51,6 +54,17 @@
|
|||
/* Data structure which holds the extents of the trusted SRAM for BL2 */
|
||||
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
|
||||
|
||||
/* Weak definitions may be overridden in specific ARM standard platform */
|
||||
#pragma weak bl2_early_platform_setup
|
||||
#pragma weak bl2_platform_setup
|
||||
#pragma weak bl2_plat_arch_setup
|
||||
#pragma weak bl2_plat_sec_mem_layout
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
|
||||
#pragma weak bl2_plat_handle_post_image_load
|
||||
|
||||
#else /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*******************************************************************************
|
||||
* This structure represents the superset of information that is passed to
|
||||
|
@ -72,10 +86,6 @@ static bl2_to_bl31_params_mem_t bl31_params_mem;
|
|||
|
||||
|
||||
/* Weak definitions may be overridden in specific ARM standard platform */
|
||||
#pragma weak bl2_early_platform_setup
|
||||
#pragma weak bl2_platform_setup
|
||||
#pragma weak bl2_plat_arch_setup
|
||||
#pragma weak bl2_plat_sec_mem_layout
|
||||
#pragma weak bl2_plat_get_bl31_params
|
||||
#pragma weak bl2_plat_get_bl31_ep_info
|
||||
#pragma weak bl2_plat_flush_bl31_params
|
||||
|
@ -106,7 +116,7 @@ meminfo_t *bl2_plat_sec_mem_layout(void)
|
|||
{
|
||||
return &bl2_tzram_layout;
|
||||
}
|
||||
#endif
|
||||
#endif /* ARM_BL31_IN_DRAM */
|
||||
|
||||
/*******************************************************************************
|
||||
* This function assigns a pointer to the memory that the platform has kept
|
||||
|
@ -180,6 +190,7 @@ struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
|
|||
|
||||
return &bl31_params_mem.bl31_ep_info;
|
||||
}
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*******************************************************************************
|
||||
* BL1 has passed the extents of the trusted SRAM that should be visible to BL2
|
||||
|
@ -235,7 +246,12 @@ void arm_bl2_plat_arch_setup(void)
|
|||
BL2_COHERENT_RAM_LIMIT
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef AARCH32
|
||||
enable_mmu_secure(0);
|
||||
#else
|
||||
enable_mmu_el1(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bl2_plat_arch_setup(void)
|
||||
|
@ -243,6 +259,46 @@ void bl2_plat_arch_setup(void)
|
|||
arm_bl2_plat_arch_setup();
|
||||
}
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
/*******************************************************************************
|
||||
* This function can be used by the platforms to update/use image
|
||||
* information for given `image_id`.
|
||||
******************************************************************************/
|
||||
int bl2_plat_handle_post_image_load(unsigned int image_id)
|
||||
{
|
||||
int err = 0;
|
||||
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
|
||||
assert(bl_mem_params);
|
||||
|
||||
switch (image_id) {
|
||||
#ifdef AARCH64
|
||||
case BL32_IMAGE_ID:
|
||||
bl_mem_params->ep_info.spsr = arm_get_spsr_for_bl32_entry();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case BL33_IMAGE_ID:
|
||||
/* BL33 expects to receive the primary CPU MPID (through r0) */
|
||||
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
|
||||
bl_mem_params->ep_info.spsr = arm_get_spsr_for_bl33_entry();
|
||||
break;
|
||||
|
||||
#ifdef SCP_BL2_BASE
|
||||
case SCP_BL2_IMAGE_ID:
|
||||
/* The subsequent handling of SCP_BL2 is platform specific */
|
||||
err = plat_arm_bl2_handle_scp_bl2(&bl_mem_params->image_info);
|
||||
if (err) {
|
||||
WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#else /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*******************************************************************************
|
||||
* Populate the extents of memory available for loading SCP_BL2 (if used),
|
||||
* i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2.
|
||||
|
@ -321,3 +377,5 @@ void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
|
|||
bl33_meminfo->free_base = ARM_NS_DRAM1_BASE;
|
||||
bl33_meminfo->free_size = ARM_NS_DRAM1_SIZE;
|
||||
}
|
||||
|
||||
#endif /* LOAD_IMAGE_V2 */
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <console.h>
|
||||
#include <debug.h>
|
||||
#include <mmio.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform.h>
|
||||
|
@ -98,8 +99,13 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
|
|||
* while creating page tables. BL2 has flushed this information to memory, so
|
||||
* we are guaranteed to pick up good data.
|
||||
******************************************************************************/
|
||||
#if LOAD_IMAGE_V2
|
||||
void arm_bl31_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
#else
|
||||
void arm_bl31_early_platform_setup(bl31_params_t *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
#endif
|
||||
{
|
||||
/* Initialize the console to provide early debug support */
|
||||
console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
|
||||
|
@ -135,13 +141,8 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2,
|
|||
bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
|
||||
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
|
||||
|
||||
#else
|
||||
/*
|
||||
* Check params passed from BL2 should not be NULL,
|
||||
*/
|
||||
assert(from_bl2 != NULL);
|
||||
assert(from_bl2->h.type == PARAM_BL31);
|
||||
assert(from_bl2->h.version >= VERSION_1);
|
||||
#else /* RESET_TO_BL31 */
|
||||
|
||||
/*
|
||||
* In debug builds, we pass a special value in 'plat_params_from_bl2'
|
||||
* to verify platform parameters from BL2 to BL31.
|
||||
|
@ -150,6 +151,43 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2,
|
|||
assert(((unsigned long long)plat_params_from_bl2) ==
|
||||
ARM_BL31_PLAT_PARAM_VAL);
|
||||
|
||||
# if LOAD_IMAGE_V2
|
||||
/*
|
||||
* Check params passed from BL2 should not be NULL,
|
||||
*/
|
||||
bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
|
||||
assert(params_from_bl2 != NULL);
|
||||
assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
|
||||
assert(params_from_bl2->h.version >= VERSION_2);
|
||||
|
||||
bl_params_node_t *bl_params = params_from_bl2->head;
|
||||
|
||||
/*
|
||||
* Copy BL33 and BL32 (if present), entry point information.
|
||||
* They are stored in Secure RAM, in BL2's address space.
|
||||
*/
|
||||
while (bl_params) {
|
||||
if (bl_params->image_id == BL32_IMAGE_ID)
|
||||
bl32_image_ep_info = *bl_params->ep_info;
|
||||
|
||||
if (bl_params->image_id == BL33_IMAGE_ID)
|
||||
bl33_image_ep_info = *bl_params->ep_info;
|
||||
|
||||
bl_params = bl_params->next_params_info;
|
||||
}
|
||||
|
||||
if (bl33_image_ep_info.pc == 0)
|
||||
panic();
|
||||
|
||||
# else /* LOAD_IMAGE_V2 */
|
||||
|
||||
/*
|
||||
* Check params passed from BL2 should not be NULL,
|
||||
*/
|
||||
assert(from_bl2 != NULL);
|
||||
assert(from_bl2->h.type == PARAM_BL31);
|
||||
assert(from_bl2->h.version >= VERSION_1);
|
||||
|
||||
/*
|
||||
* Copy BL32 (if populated by BL2) and BL33 entry point information.
|
||||
* They are stored in Secure RAM, in BL2's address space.
|
||||
|
@ -157,11 +195,18 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2,
|
|||
if (from_bl2->bl32_ep_info)
|
||||
bl32_image_ep_info = *from_bl2->bl32_ep_info;
|
||||
bl33_image_ep_info = *from_bl2->bl33_ep_info;
|
||||
#endif
|
||||
|
||||
# endif /* LOAD_IMAGE_V2 */
|
||||
#endif /* RESET_TO_BL31 */
|
||||
}
|
||||
|
||||
#if LOAD_IMAGE_V2
|
||||
void bl31_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
#else
|
||||
void bl31_early_platform_setup(bl31_params_t *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
#endif
|
||||
{
|
||||
arm_bl31_early_platform_setup(from_bl2, plat_params_from_bl2);
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ BL1_SOURCES += drivers/arm/sp805/sp805.c \
|
|||
drivers/io/io_storage.c \
|
||||
plat/arm/common/arm_bl1_setup.c \
|
||||
plat/arm/common/arm_io_storage.c \
|
||||
plat/common/aarch64/platform_up_stack.S
|
||||
plat/common/${ARCH}/platform_up_stack.S
|
||||
ifdef EL3_PAYLOAD_BASE
|
||||
# Need the arm_program_trusted_mailbox() function to release secondary CPUs from
|
||||
# their holding pen
|
||||
|
@ -128,7 +128,12 @@ BL2_SOURCES += drivers/io/io_fip.c \
|
|||
drivers/io/io_storage.c \
|
||||
plat/arm/common/arm_bl2_setup.c \
|
||||
plat/arm/common/arm_io_storage.c \
|
||||
plat/common/aarch64/platform_up_stack.S
|
||||
plat/common/${ARCH}/platform_up_stack.S
|
||||
ifeq (${LOAD_IMAGE_V2},1)
|
||||
BL2_SOURCES += plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c\
|
||||
plat/arm/common/arm_image_load.c \
|
||||
common/desc_image_load.c
|
||||
endif
|
||||
|
||||
BL2U_SOURCES += plat/arm/common/arm_bl2u_setup.c \
|
||||
plat/common/aarch64/platform_up_stack.S
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arm_def.h>
|
||||
#include <bl_common.h>
|
||||
#include <desc_image_load.h>
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
#pragma weak plat_flush_next_bl_params
|
||||
#pragma weak plat_get_bl_image_load_info
|
||||
#pragma weak plat_get_next_bl_params
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* This function flushes the data structures so that they are visible
|
||||
* in memory for the next BL image.
|
||||
******************************************************************************/
|
||||
void plat_flush_next_bl_params(void)
|
||||
{
|
||||
flush_bl_params_desc();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns the list of loadable images.
|
||||
******************************************************************************/
|
||||
bl_load_info_t *plat_get_bl_image_load_info(void)
|
||||
{
|
||||
return get_bl_load_info_from_mem_params_desc();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns the list of executable images.
|
||||
******************************************************************************/
|
||||
bl_params_t *plat_get_next_bl_params(void)
|
||||
{
|
||||
return get_next_bl_params_from_mem_params_desc();
|
||||
}
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <console.h>
|
||||
#include <debug.h>
|
||||
#include <mmio.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform.h>
|
||||
|
@ -58,10 +59,6 @@ static entry_point_info_t bl33_image_ep_info;
|
|||
#pragma weak sp_min_platform_setup
|
||||
#pragma weak sp_min_plat_arch_setup
|
||||
|
||||
#ifndef RESET_TO_SP_MIN
|
||||
#error (" RESET_TO_SP_MIN flag is expected to be set.")
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Return a pointer to the 'entry_point_info' structure of the next image for the
|
||||
|
@ -86,15 +83,20 @@ entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
|
|||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Perform early platform setup. We expect SP_MIN is the first boot loader
|
||||
* image and RESET_TO_SP_MIN build option to be set.
|
||||
* Perform early platform setup.
|
||||
******************************************************************************/
|
||||
void arm_sp_min_early_platform_setup(void)
|
||||
void arm_sp_min_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
{
|
||||
/* Initialize the console to provide early debug support */
|
||||
console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
|
||||
ARM_CONSOLE_BAUDRATE);
|
||||
|
||||
#if RESET_TO_SP_MIN
|
||||
/* There are no parameters from BL2 if SP_MIN is a reset vector */
|
||||
assert(from_bl2 == NULL);
|
||||
assert(plat_params_from_bl2 == NULL);
|
||||
|
||||
/* Populate entry point information for BL33 */
|
||||
SET_PARAM_HEAD(&bl33_image_ep_info,
|
||||
PARAM_EP,
|
||||
|
@ -104,18 +106,46 @@ void arm_sp_min_early_platform_setup(void)
|
|||
* Tell SP_MIN where the non-trusted software image
|
||||
* is located and the entry state information
|
||||
*/
|
||||
#ifdef PRELOADED_BL33_BASE
|
||||
bl33_image_ep_info.pc = PRELOADED_BL33_BASE;
|
||||
#else
|
||||
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
|
||||
#endif
|
||||
bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
|
||||
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
|
||||
|
||||
#else /* RESET_TO_SP_MIN */
|
||||
|
||||
/*
|
||||
* Check params passed from BL2 should not be NULL,
|
||||
*/
|
||||
bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
|
||||
assert(params_from_bl2 != NULL);
|
||||
assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
|
||||
assert(params_from_bl2->h.version >= VERSION_2);
|
||||
|
||||
bl_params_node_t *bl_params = params_from_bl2->head;
|
||||
|
||||
/*
|
||||
* Copy BL33 entry point information.
|
||||
* They are stored in Secure RAM, in BL2's address space.
|
||||
*/
|
||||
while (bl_params) {
|
||||
if (bl_params->image_id == BL33_IMAGE_ID) {
|
||||
bl33_image_ep_info = *bl_params->ep_info;
|
||||
break;
|
||||
}
|
||||
|
||||
bl_params = bl_params->next_params_info;
|
||||
}
|
||||
|
||||
if (bl33_image_ep_info.pc == 0)
|
||||
panic();
|
||||
|
||||
#endif /* RESET_TO_SP_MIN */
|
||||
|
||||
}
|
||||
|
||||
void sp_min_early_platform_setup(void)
|
||||
void sp_min_early_platform_setup(void *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
{
|
||||
arm_sp_min_early_platform_setup();
|
||||
arm_sp_min_early_platform_setup(from_bl2, plat_params_from_bl2);
|
||||
|
||||
/*
|
||||
* Initialize Interconnect for this cluster during cold boot.
|
||||
|
@ -146,10 +176,10 @@ void sp_min_platform_setup(void)
|
|||
/*
|
||||
* Do initial security configuration to allow DRAM/device access
|
||||
* (if earlier BL has not already done so).
|
||||
* TODO: If RESET_TO_SP_MIN is not set, the security setup needs
|
||||
* to be skipped.
|
||||
*/
|
||||
#if RESET_TO_SP_MIN
|
||||
plat_arm_security_setup();
|
||||
#endif
|
||||
|
||||
/* Enable and initialize the System level generic timer */
|
||||
mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
|
||||
|
|
|
@ -37,13 +37,21 @@
|
|||
#include "css_scp_bootloader.h"
|
||||
|
||||
/* Weak definition may be overridden in specific CSS based platform */
|
||||
#if LOAD_IMAGE_V2
|
||||
#pragma weak plat_arm_bl2_handle_scp_bl2
|
||||
#else
|
||||
#pragma weak bl2_plat_handle_scp_bl2
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
|
||||
* Return 0 on success, -1 otherwise.
|
||||
******************************************************************************/
|
||||
#if LOAD_IMAGE_V2
|
||||
int plat_arm_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
|
||||
#else
|
||||
int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
.weak plat_my_core_pos
|
||||
.weak plat_reset_handler
|
||||
.weak plat_disable_acp
|
||||
.weak platform_mem_init
|
||||
.weak plat_panic_handler
|
||||
|
||||
|
@ -59,6 +60,15 @@ func plat_reset_handler
|
|||
bx lr
|
||||
endfunc plat_reset_handler
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Placeholder function which should be redefined by
|
||||
* each platform.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func plat_disable_acp
|
||||
bx lr
|
||||
endfunc plat_disable_acp
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Placeholder function which should be redefined by
|
||||
* each platform.
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <platform_def.h>
|
||||
|
||||
.globl plat_get_my_stack
|
||||
.globl plat_set_my_stack
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* unsigned long plat_get_my_stack ()
|
||||
*
|
||||
* For cold-boot BL images, only the primary CPU needs
|
||||
* a stack. This function returns the stack pointer for
|
||||
* a stack allocated in normal memory.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func plat_get_my_stack
|
||||
get_up_stack platform_normal_stacks, PLATFORM_STACK_SIZE
|
||||
bx lr
|
||||
endfunc plat_get_my_stack
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* void plat_set_my_stack ()
|
||||
*
|
||||
* For cold-boot BL images, only the primary CPU needs
|
||||
* a stack. This function sets the stack pointer to a
|
||||
* stack allocated in normal memory.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func plat_set_my_stack
|
||||
get_up_stack platform_normal_stacks, PLATFORM_STACK_SIZE
|
||||
mov sp, r0
|
||||
bx lr
|
||||
endfunc plat_set_my_stack
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* Per-cpu stacks in normal memory. Each cpu gets a
|
||||
* stack of PLATFORM_STACK_SIZE bytes.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
declare_stack platform_normal_stacks, tzfw_normal_stacks, \
|
||||
PLATFORM_STACK_SIZE, 1, CACHE_WRITEBACK_GRANULE
|
Loading…
Reference in New Issue