Merge pull request #713 from yatharth-arm/yk/AArch32_porting

Add basic AArch32 support for BL1 & BL2
This commit is contained in:
danh-arm 2016-09-22 17:05:32 +01:00 committed by GitHub
commit 44abeaa632
60 changed files with 3175 additions and 519 deletions

View File

@ -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

View File

@ -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)
{
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)
{
}

View File

@ -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

View File

@ -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

285
bl2/bl2_image_load.c Normal file
View File

@ -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;
}

117
bl2/bl2_image_load_v2.c Normal file
View File

@ -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;
}

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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

View File

@ -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__ = .;
/*

View File

@ -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))

View File

@ -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

View File

@ -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.
******************************************************************************/

220
common/desc_image_load.c Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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

View File

@ -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__ */

View File

@ -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__*/

View File

@ -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__ */

View File

@ -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)

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
*

View File

@ -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);

View File

@ -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 \

View File

@ -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();

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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 */

View File

@ -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);

View File

@ -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

View File

@ -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();
}

View File

@ -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,

View File

@ -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;

View File

@ -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.

View File

@ -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