mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-20 11:34:20 +00:00
Merge pull request #310 from sandrine-bailleux/sb/tf-issue-304-phase1
Enhance BL3-1 entrypoint handling to support non-TF boot firmware - Phase 1
This commit is contained in:
commit
e347e843a9
13 changed files with 371 additions and 406 deletions
7
Makefile
7
Makefile
|
@ -76,6 +76,9 @@ CREATE_KEYS := 1
|
|||
# Flags to build TF with Trusted Boot support
|
||||
TRUSTED_BOARD_BOOT := 0
|
||||
AUTH_MOD := none
|
||||
# By default, consider that the platform's reset address is not programmable.
|
||||
# The platform Makefile is free to override this value.
|
||||
PROGRAMMABLE_RESET_ADDRESS := 0
|
||||
|
||||
# Checkpatch ignores
|
||||
CHECK_IGNORE = --ignore COMPLEX_MACRO \
|
||||
|
@ -272,6 +275,10 @@ $(eval $(call assert_boolean,CREATE_KEYS))
|
|||
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
|
||||
$(eval $(call add_define,TRUSTED_BOARD_BOOT))
|
||||
|
||||
# Process PROGRAMMABLE_RESET_ADDRESS flag
|
||||
$(eval $(call assert_boolean,PROGRAMMABLE_RESET_ADDRESS))
|
||||
$(eval $(call add_define,PROGRAMMABLE_RESET_ADDRESS))
|
||||
|
||||
ASFLAGS += -nostdinc -ffreestanding -Wa,--fatal-warnings \
|
||||
-Werror -Wmissing-include-dirs \
|
||||
-mgeneral-regs-only -D__ASSEMBLY__ \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2015, 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,7 +29,7 @@
|
|||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <el3_common_macros.S>
|
||||
|
||||
.globl bl1_entrypoint
|
||||
|
||||
|
@ -42,116 +42,19 @@
|
|||
*/
|
||||
|
||||
func bl1_entrypoint
|
||||
/* ---------------------------------------------
|
||||
* Set the CPU endianness before doing anything
|
||||
* that might involve memory reads or writes.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mrs x0, sctlr_el3
|
||||
bic x0, x0, #SCTLR_EE_BIT
|
||||
msr sctlr_el3, x0
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Perform any processor specific actions upon
|
||||
* reset e.g. cache, tlb invalidations etc.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
bl reset_handler
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Enable the instruction cache, stack pointer
|
||||
* and data access alignment checks
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
|
||||
mrs x0, sctlr_el3
|
||||
orr x0, x0, x1
|
||||
msr sctlr_el3, x0
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Set the exception vector to something sane.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
adr x0, bl1_exceptions
|
||||
msr vbar_el3, x0
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Enable the SError interrupt now that the
|
||||
* exception vectors have been setup.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
msr daifclr, #DAIF_ABT_BIT
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* The initial state of the Architectural feature trap register
|
||||
* (CPTR_EL3) is unknown and it must be set to a known state. All
|
||||
* feature traps are disabled. Some bits in this register are marked as
|
||||
* Reserved and should not be modified.
|
||||
*
|
||||
* CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
|
||||
* or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
|
||||
* CPTR_EL3.TTA: This causes access to the Trace functionality to trap
|
||||
* to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
|
||||
* access to trace functionality is not supported, this bit is RES0.
|
||||
* CPTR_EL3.TFP: This causes instructions that access the registers
|
||||
* associated with Floating Point and Advanced SIMD execution to trap
|
||||
* to EL3 when executed from any exception level, unless trapped to EL1
|
||||
* or EL2.
|
||||
* 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.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mrs x0, cptr_el3
|
||||
bic w0, w0, #TCPAC_BIT
|
||||
bic w0, w0, #TTA_BIT
|
||||
bic w0, w0, #TFP_BIT
|
||||
msr cptr_el3, x0
|
||||
|
||||
/* -------------------------------------------------------
|
||||
* Will not return from this macro if it is a warm boot.
|
||||
* -------------------------------------------------------
|
||||
*/
|
||||
wait_for_entrypoint
|
||||
|
||||
bl platform_mem_init
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Init C runtime environment.
|
||||
* - Zero-initialise the NOBITS sections.
|
||||
* There are 2 of them:
|
||||
* - the .bss section;
|
||||
* - the coherent memory section.
|
||||
* - Copy the data section from BL1 image
|
||||
* (stored in ROM) to the correct location
|
||||
* in RAM.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
ldr x0, =__BSS_START__
|
||||
ldr x1, =__BSS_SIZE__
|
||||
bl zeromem16
|
||||
|
||||
#if USE_COHERENT_MEM
|
||||
ldr x0, =__COHERENT_RAM_START__
|
||||
ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__
|
||||
bl zeromem16
|
||||
#endif
|
||||
|
||||
ldr x0, =__DATA_RAM_START__
|
||||
ldr x1, =__DATA_ROM_START__
|
||||
ldr x2, =__DATA_SIZE__
|
||||
bl memcpy16
|
||||
|
||||
/* --------------------------------------------
|
||||
* 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.
|
||||
* --------------------------------------------
|
||||
*/
|
||||
mrs x0, mpidr_el1
|
||||
bl platform_set_stack
|
||||
el3_entrypoint_common \
|
||||
_set_endian=1 \
|
||||
_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
|
||||
_secondary_cold_boot=1 \
|
||||
_init_memory=1 \
|
||||
_init_c_runtime=1 \
|
||||
_exception_vectors=bl1_exceptions
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Architectural init. can be generic e.g.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2015, 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,8 +29,8 @@
|
|||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <bl_common.h>
|
||||
#include <el3_common_macros.S>
|
||||
|
||||
.globl bl31_entrypoint
|
||||
|
||||
|
@ -42,154 +42,68 @@
|
|||
*/
|
||||
|
||||
func bl31_entrypoint
|
||||
#if !RESET_TO_BL31
|
||||
/* ---------------------------------------------------------------
|
||||
* Preceding bootloader has populated x0 with a pointer to a
|
||||
* 'bl31_params' structure & x1 with a pointer to platform
|
||||
* specific structure
|
||||
* ---------------------------------------------------------------
|
||||
*/
|
||||
#if !RESET_TO_BL31
|
||||
mov x20, x0
|
||||
mov x21, x1
|
||||
#else
|
||||
/* ---------------------------------------------
|
||||
* Set the CPU endianness before doing anything
|
||||
* that might involve memory reads or writes.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mrs x0, sctlr_el3
|
||||
bic x0, x0, #SCTLR_EE_BIT
|
||||
msr sctlr_el3, x0
|
||||
isb
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------
|
||||
* When RESET_TO_BL31 is true, perform any
|
||||
* processor specific actions upon reset e.g.
|
||||
* cache, tlb invalidations, errata workarounds
|
||||
* etc.
|
||||
* When RESET_TO_BL31 is false, perform any
|
||||
* processor specific actions which undo or are
|
||||
* in addition to the actions performed by the
|
||||
* reset handler in the Boot ROM (BL1).
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
bl reset_handler
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Enable the instruction cache, stack pointer
|
||||
* and data access alignment checks
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
|
||||
mrs x0, sctlr_el3
|
||||
orr x0, x0, x1
|
||||
msr sctlr_el3, x0
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Initialise cpu_data early to enable crash
|
||||
* reporting to have access to crash stack.
|
||||
* Since crash reporting depends on cpu_data to
|
||||
* report the unhandled exception, not
|
||||
* doing so can lead to recursive exceptions due
|
||||
* to a NULL TPIDR_EL3
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
bl init_cpu_data_ptr
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Set the exception vector.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
adr x1, runtime_exceptions
|
||||
msr vbar_el3, x1
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Enable the SError interrupt now that the
|
||||
* exception vectors have been setup.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
msr daifclr, #DAIF_ABT_BIT
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* The initial state of the Architectural feature trap register
|
||||
* (CPTR_EL3) is unknown and it must be set to a known state. All
|
||||
* feature traps are disabled. Some bits in this register are marked as
|
||||
* Reserved and should not be modified.
|
||||
* For !RESET_TO_BL31 systems, only the primary CPU ever reaches
|
||||
* bl31_entrypoint() during the cold boot flow, so the cold/warm boot
|
||||
* and primary/secondary CPU logic should not be executed in this case.
|
||||
*
|
||||
* CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
|
||||
* or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
|
||||
* CPTR_EL3.TTA: This causes access to the Trace functionality to trap
|
||||
* to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
|
||||
* access to trace functionality is not supported, this bit is RES0.
|
||||
* CPTR_EL3.TFP: This causes instructions that access the registers
|
||||
* associated with Floating Point and Advanced SIMD execution to trap
|
||||
* to EL3 when executed from any exception level, unless trapped to EL1
|
||||
* or EL2.
|
||||
* Also, assume that the previous bootloader has already set up the CPU
|
||||
* endianness and has initialised the memory.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mrs x1, cptr_el3
|
||||
bic w1, w1, #TCPAC_BIT
|
||||
bic w1, w1, #TTA_BIT
|
||||
bic w1, w1, #TFP_BIT
|
||||
msr cptr_el3, x1
|
||||
el3_entrypoint_common \
|
||||
_set_endian=0 \
|
||||
_warm_boot_mailbox=0 \
|
||||
_secondary_cold_boot=0 \
|
||||
_init_memory=0 \
|
||||
_init_c_runtime=1 \
|
||||
_exception_vectors=runtime_exceptions
|
||||
|
||||
#if RESET_TO_BL31
|
||||
/* -------------------------------------------------------
|
||||
* Will not return from this macro if it is a warm boot.
|
||||
* -------------------------------------------------------
|
||||
/* ---------------------------------------------------------------------
|
||||
* Relay the previous bootloader's arguments to the platform layer
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
wait_for_entrypoint
|
||||
bl platform_mem_init
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Zero out NOBITS sections. There are 2 of them:
|
||||
* - the .bss section;
|
||||
* - the coherent memory section.
|
||||
* ---------------------------------------------
|
||||
mov x0, x20
|
||||
mov x1, x21
|
||||
#else
|
||||
/* ---------------------------------------------------------------------
|
||||
* For RESET_TO_BL31 systems which have a programmable reset address,
|
||||
* bl31_entrypoint() is executed only on the cold boot path so we can
|
||||
* skip the warm boot mailbox mechanism.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
ldr x0, =__BSS_START__
|
||||
ldr x1, =__BSS_SIZE__
|
||||
bl zeromem16
|
||||
el3_entrypoint_common \
|
||||
_set_endian=1 \
|
||||
_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
|
||||
_secondary_cold_boot=1 \
|
||||
_init_memory=1 \
|
||||
_init_c_runtime=1 \
|
||||
_exception_vectors=runtime_exceptions
|
||||
|
||||
#if USE_COHERENT_MEM
|
||||
ldr x0, =__COHERENT_RAM_START__
|
||||
ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__
|
||||
bl zeromem16
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Use SP_EL0 for the C runtime stack.
|
||||
* ---------------------------------------------
|
||||
/* ---------------------------------------------------------------------
|
||||
* For RESET_TO_BL31 systems, BL3-1 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.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
msr spsel, #0
|
||||
|
||||
/* --------------------------------------------
|
||||
* 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.
|
||||
* --------------------------------------------
|
||||
*/
|
||||
mrs x0, mpidr_el1
|
||||
bl platform_set_stack
|
||||
mov x0, 0
|
||||
mov x1, 0
|
||||
#endif /* RESET_TO_BL31 */
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Perform platform specific early arch. setup
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
#if RESET_TO_BL31
|
||||
mov x0, 0
|
||||
mov x1, 0
|
||||
#else
|
||||
mov x0, x20
|
||||
mov x1, x21
|
||||
#endif
|
||||
|
||||
bl bl31_early_platform_setup
|
||||
bl bl31_plat_arch_setup
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ BL1 performs minimal architectural initialization as follows.
|
|||
|
||||
#### Platform initialization
|
||||
|
||||
BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests from
|
||||
BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests to
|
||||
the CCI slave interface corresponding to the cluster that includes the
|
||||
primary CPU. BL1 also initializes a UART (PL011 console), which enables access
|
||||
to the `printf` family of functions in BL1.
|
||||
|
@ -334,7 +334,9 @@ the clock frequency of the system counter, which is provided by the platform.
|
|||
BL3-1 performs detailed platform initialization, which enables normal world
|
||||
software to function correctly. It also retrieves entrypoint information for
|
||||
the BL3-3 image loaded by BL2 from the platform defined memory address populated
|
||||
by BL2. BL3-1 also initializes a UART (PL011 console), which enables
|
||||
by BL2. It enables issuing of snoop and DVM (Distributed Virtual Memory)
|
||||
requests to the CCI slave interface corresponding to the cluster that includes
|
||||
the primary CPU. BL3-1 also initializes a UART (PL011 console), which enables
|
||||
access to the `printf` family of functions in BL3-1. It enables the system
|
||||
level implementation of the generic timer through the memory mapped interface.
|
||||
|
||||
|
@ -412,8 +414,7 @@ updated to develop and exploit new functionality.
|
|||
|
||||
#### Required CPU state when calling `bl31_entrypoint()` during cold boot
|
||||
|
||||
This function must only be called by the primary CPU, if this is called by any
|
||||
other CPU the firmware will abort.
|
||||
This function must only be called by the primary CPU.
|
||||
|
||||
On entry to this function the calling primary CPU must be executing in AArch64
|
||||
EL3, little-endian data access, and all interrupt sources masked:
|
||||
|
@ -543,11 +544,6 @@ implementation via a platform defined mechanism. On a cold boot, the platform
|
|||
must place any secondary CPUs into a safe state while the primary CPU executes
|
||||
a modified BL3-1 initialization, as described below.
|
||||
|
||||
#### Architectural initialization
|
||||
|
||||
As the first image to execute in this configuration BL3-1 must ensure that
|
||||
interconnect coherency is enabled (if required) before enabling the MMU.
|
||||
|
||||
#### Platform initialization
|
||||
|
||||
In this configuration, when the CPU resets to BL3-1 there are no parameters
|
||||
|
@ -962,7 +958,7 @@ The sample crash output is shown below.
|
|||
---------------------------------
|
||||
|
||||
Trusted Firmware implements a framework that allows CPU and platform ports to
|
||||
perform actions immediately after a CPU is released from reset in both the cold
|
||||
perform actions very early after a CPU is released from reset in both the cold
|
||||
and warm boot paths. This is done by calling the `reset_handler()` function in
|
||||
both the BL1 and BL3-1 images. It in turn calls the platform and CPU specific
|
||||
reset handling functions.
|
||||
|
@ -971,33 +967,12 @@ Details for implementing a CPU specific reset handler can be found in
|
|||
Section 8. Details for implementing a platform specific reset handler can be
|
||||
found in the [Porting Guide](see the `plat_reset_handler()` function).
|
||||
|
||||
When adding functionality to a reset handler, the following points should be
|
||||
kept in mind.
|
||||
|
||||
1. The first reset handler in the system exists either in a ROM image
|
||||
(e.g. BL1), or BL3-1 if `RESET_TO_BL31` is true. This may be detected at
|
||||
compile time using the constant `FIRST_RESET_HANDLER_CALL`.
|
||||
|
||||
2. When considering ROM images, it's important to consider non TF-based ROMs
|
||||
and ROMs based on previous versions of the TF code.
|
||||
|
||||
3. If the functionality should be applied to a ROM and there is no possibility
|
||||
of a ROM being used that does not apply the functionality (or equivalent),
|
||||
then the functionality should be applied within a `#if
|
||||
FIRST_RESET_HANDLER_CALL` block.
|
||||
|
||||
4. If the functionality should execute in BL3-1 in order to override or
|
||||
supplement a ROM version of the functionality, then the functionality
|
||||
should be applied in the `#else` part of a `#if FIRST_RESET_HANDLER_CALL`
|
||||
block.
|
||||
|
||||
5. If the functionality should be applied to a ROM but there is a possibility
|
||||
of ROMs being used that do not apply the functionality, then the
|
||||
functionality should be applied outside of a `FIRST_RESET_HANDLER_CALL`
|
||||
block, so that BL3-1 has an opportunity to apply the functionality instead.
|
||||
In this case, additional code may be needed to cope with different ROMs
|
||||
that do or do not apply the functionality.
|
||||
|
||||
When adding functionality to a reset handler, keep in mind that if a different
|
||||
reset handling behavior is required between the first and the subsequent
|
||||
invocations of the reset handling code, this should be detected at runtime.
|
||||
In other words, the reset handler should be able to detect whether an action has
|
||||
already been performed and act as appropriate. Possible courses of actions are,
|
||||
e.g. skip the action the second time, or undo/redo it.
|
||||
|
||||
8. CPU specific operations framework
|
||||
-----------------------------
|
||||
|
|
|
@ -434,7 +434,7 @@ This function fulfills requirement 1 and 3 listed above.
|
|||
This function is called with the MMU and data caches disabled. It is responsible
|
||||
for placing the executing secondary CPU in a platform-specific state until the
|
||||
primary CPU performs the necessary actions to bring it out of that state and
|
||||
allow entry into the OS.
|
||||
allow entry into the OS. This function must not return.
|
||||
|
||||
In the ARM FVP port, each secondary CPU powers itself off. The primary CPU is
|
||||
responsible for powering up the secondary CPU when normal world software
|
||||
|
@ -569,7 +569,7 @@ preserve the values of callee saved registers x19 to x29.
|
|||
|
||||
The default implementation doesn't do anything. If a platform needs to override
|
||||
the default implementation, refer to the [Firmware Design] for general
|
||||
guidelines regarding placement of code in a reset handler.
|
||||
guidelines.
|
||||
|
||||
### Function : plat_disable_acp()
|
||||
|
||||
|
|
|
@ -320,6 +320,10 @@ performed.
|
|||
* `BL33_KEY`: This option is used when `GENERATE_COT=1`. It specifies the
|
||||
file that contains the BL3-3 private key in PEM format.
|
||||
|
||||
* `PROGRAMMABLE_RESET_ADDRESS`: This option indicates whether the reset
|
||||
vector address can be programmed or is fixed on the platform. It can take
|
||||
either 0 (fixed) or 1 (programmable). Default is 0.
|
||||
|
||||
#### ARM development platform specific build options
|
||||
|
||||
* `ARM_TSP_RAM_LOCATION`: location of the TSP binary. Options:
|
||||
|
|
|
@ -99,41 +99,6 @@
|
|||
.size \_name, . - \_name
|
||||
.endm
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Find the type of reset and jump to handler
|
||||
* if present. If the handler is null then it is
|
||||
* a cold boot. The primary cpu will set up the
|
||||
* platform while the secondaries wait for
|
||||
* their turn to be woken up
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
.macro wait_for_entrypoint
|
||||
wait_for_entrypoint:
|
||||
mrs x0, mpidr_el1
|
||||
bl platform_get_entrypoint
|
||||
cbnz x0, do_warm_boot
|
||||
mrs x0, mpidr_el1
|
||||
bl platform_is_primary_cpu
|
||||
cbnz x0, do_cold_boot
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Perform any platform specific secondary cpu
|
||||
* actions
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
bl plat_secondary_cold_boot_setup
|
||||
b wait_for_entrypoint
|
||||
|
||||
do_warm_boot:
|
||||
/* ---------------------------------------------
|
||||
* Jump to BL31 for all warm boot init.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
blr x0
|
||||
|
||||
do_cold_boot:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This macro declares an array of 1 or more stacks, properly
|
||||
* aligned and in the requested section
|
||||
|
|
|
@ -90,18 +90,6 @@
|
|||
(_p)->h.attr = (uint32_t)(_attr) ; \
|
||||
} while (0)
|
||||
|
||||
/*******************************************************************************
|
||||
* Constant that indicates if this is the first version of the reset handler
|
||||
* contained in an image. This will be the case when the image is BL1 or when
|
||||
* its BL3-1 and RESET_TO_BL31 is true. This constant enables a subsequent
|
||||
* version of the reset handler to perform actions that override the ones
|
||||
* performed in the first version of the code. This will be required when the
|
||||
* first version exists in an un-modifiable image e.g. a BootROM image.
|
||||
******************************************************************************/
|
||||
#if IMAGE_BL1 || (IMAGE_BL31 && RESET_TO_BL31)
|
||||
#define FIRST_RESET_HANDLER_CALL
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <cdefs.h> /* For __dead2 */
|
||||
#include <cassert.h>
|
||||
|
@ -195,9 +183,9 @@ typedef struct image_info {
|
|||
* 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
|
||||
* populated only if BL2 detects its presence. A pointer to a structure of this
|
||||
* type should be passed in X3 to BL31's cold boot entrypoint
|
||||
* type should be passed in X0 to BL3-1's cold boot entrypoint.
|
||||
*
|
||||
* Use of this structure and the X3 parameter is not mandatory: the BL3-1
|
||||
* Use of this structure and the X0 parameter is not mandatory: the BL3-1
|
||||
* platform code can use other mechanisms to provide the necessary information
|
||||
* about BL3-2 and BL3-3 to the common and SPD code.
|
||||
*
|
||||
|
|
256
include/common/el3_common_macros.S
Normal file
256
include/common/el3_common_macros.S
Normal file
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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>
|
||||
|
||||
/*
|
||||
* Helper macro to initialise EL3 registers we care about.
|
||||
*/
|
||||
.macro el3_arch_init_common _exception_vectors
|
||||
/* ---------------------------------------------------------------------
|
||||
* Enable the instruction cache, stack pointer and data access alignment
|
||||
* checks
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
|
||||
mrs x0, sctlr_el3
|
||||
orr x0, x0, x1
|
||||
msr sctlr_el3, x0
|
||||
isb
|
||||
|
||||
#if IMAGE_BL31
|
||||
/* ---------------------------------------------------------------------
|
||||
* Initialise the per-cpu cache pointer to the CPU.
|
||||
* This is done early to enable crash reporting to have access to crash
|
||||
* stack. Since crash reporting depends on cpu_data to report the
|
||||
* unhandled exception, not doing so can lead to recursive exceptions
|
||||
* due to a NULL TPIDR_EL3.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
bl init_cpu_data_ptr
|
||||
#endif /* IMAGE_BL31 */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Set the exception vectors.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
adr x0, \_exception_vectors
|
||||
msr vbar_el3, x0
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Enable the SError interrupt now that the exception vectors have been
|
||||
* setup.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
msr daifclr, #DAIF_ABT_BIT
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* The initial state of the Architectural feature trap register
|
||||
* (CPTR_EL3) is unknown and it must be set to a known state. All
|
||||
* feature traps are disabled. Some bits in this register are marked as
|
||||
* reserved and should not be modified.
|
||||
*
|
||||
* CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
|
||||
* or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
|
||||
*
|
||||
* CPTR_EL3.TTA: This causes access to the Trace functionality to trap
|
||||
* to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
|
||||
* access to trace functionality is not supported, this bit is RES0.
|
||||
*
|
||||
* CPTR_EL3.TFP: This causes instructions that access the registers
|
||||
* associated with Floating Point and Advanced SIMD execution to trap
|
||||
* to EL3 when executed from any exception level, unless trapped to EL1
|
||||
* or EL2.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mrs x0, cptr_el3
|
||||
bic w0, w0, #TCPAC_BIT
|
||||
bic w0, w0, #TTA_BIT
|
||||
bic w0, w0, #TFP_BIT
|
||||
msr cptr_el3, x0
|
||||
.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 BL3-1.
|
||||
*
|
||||
* 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
|
||||
|
||||
.if \_set_endian
|
||||
/* -------------------------------------------------------------
|
||||
* Set the CPU endianness before doing anything that might
|
||||
* involve memory reads or writes.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
mrs x0, sctlr_el3
|
||||
bic x0, x0, #SCTLR_EE_BIT
|
||||
msr sctlr_el3, x0
|
||||
isb
|
||||
.endif /* _set_endian */
|
||||
|
||||
.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.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
mrs x0, mpidr_el1
|
||||
bl platform_get_entrypoint
|
||||
cbz x0, do_cold_boot
|
||||
br x0
|
||||
|
||||
do_cold_boot:
|
||||
.endif /* _warm_boot_mailbox */
|
||||
|
||||
.if \_secondary_cold_boot
|
||||
/* -------------------------------------------------------------
|
||||
* It is a 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.
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
mrs x0, mpidr_el1
|
||||
bl platform_is_primary_cpu
|
||||
cbnz x0, 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 */
|
||||
secondary_panic:
|
||||
b secondary_panic
|
||||
|
||||
do_primary_cold_boot:
|
||||
.endif /* _secondary_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 \_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
|
||||
ldr x0, =__BSS_START__
|
||||
ldr x1, =__BSS_SIZE__
|
||||
bl zeromem16
|
||||
|
||||
#if USE_COHERENT_MEM
|
||||
ldr x0, =__COHERENT_RAM_START__
|
||||
ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__
|
||||
bl zeromem16
|
||||
#endif
|
||||
|
||||
#ifdef __DATA_ROM_START__
|
||||
ldr x0, =__DATA_RAM_START__
|
||||
ldr x1, =__DATA_ROM_START__
|
||||
ldr x2, =__DATA_SIZE__
|
||||
bl memcpy16
|
||||
#endif
|
||||
.endif /* _init_c_runtime */
|
||||
|
||||
#if IMAGE_BL31
|
||||
/* ---------------------------------------------------------------------
|
||||
* Use SP_EL0 for the C runtime stack.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
msr spsel, #0
|
||||
#endif /* IMAGE_BL31 */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* 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.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
mrs x0, mpidr_el1
|
||||
bl platform_set_stack
|
||||
.endm
|
||||
|
||||
#endif /* __EL3_COMMON_MACROS_S__ */
|
|
@ -45,13 +45,13 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
|
|||
* No need for locks as no other CPU is active.
|
||||
*/
|
||||
fvp_cci_init();
|
||||
#if RESET_TO_BL31
|
||||
|
||||
/*
|
||||
* Enable CCI coherency for the primary CPU's cluster
|
||||
* (if earlier BL has not already done so).
|
||||
* Enable CCI coherency for the primary CPU's cluster.
|
||||
* Earlier bootloader stages might already do this (e.g. Trusted
|
||||
* Firmware's BL1 does it) but we can't assume so. There is no harm in
|
||||
* executing this code twice anyway.
|
||||
* FVP PSCI code will enable coherency for other clusters.
|
||||
*/
|
||||
fvp_cci_enable();
|
||||
|
||||
#endif /* RESET_TO_BL31 */
|
||||
}
|
||||
|
|
|
@ -42,10 +42,6 @@
|
|||
/* --------------------------------------------------------------------
|
||||
* void plat_reset_handler(void);
|
||||
*
|
||||
* Before adding code in this function, refer to the guidelines in
|
||||
* docs/firmware-design.md to determine whether the code should reside
|
||||
* within the FIRST_RESET_HANDLER_CALL block or not.
|
||||
*
|
||||
* For Juno r0:
|
||||
* - Implement workaround for defect id 831273 by enabling an event
|
||||
* stream every 65536 cycles.
|
||||
|
@ -58,13 +54,9 @@
|
|||
* - The default value for the L2 Tag RAM latency for Cortex-A57 is
|
||||
* suitable.
|
||||
* - Defect #831273 doesn't affect Juno r1.
|
||||
*
|
||||
* This code is included only when FIRST_RESET_HANDLER_CALL is defined
|
||||
* since it should be executed only during BL1.
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_reset_handler
|
||||
#ifdef FIRST_RESET_HANDLER_CALL
|
||||
/* --------------------------------------------------------------------
|
||||
* Determine whether this code is running on Juno r0 or Juno r1.
|
||||
* Keep this information in x2.
|
||||
|
@ -123,6 +115,5 @@ apply_831273:
|
|||
msr CNTKCTL_EL1, x0
|
||||
ret:
|
||||
isb
|
||||
#endif /* FIRST_RESET_HANDLER_CALL */
|
||||
ret
|
||||
endfunc plat_reset_handler
|
||||
|
|
|
@ -179,16 +179,16 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
|
|||
* No need for locks as no other CPU is active.
|
||||
*/
|
||||
arm_cci_init();
|
||||
#if RESET_TO_BL31
|
||||
|
||||
/*
|
||||
* Enable CCI coherency for the primary CPU's cluster
|
||||
* (if earlier BL has not already done so).
|
||||
* Enable CCI coherency for the primary CPU's cluster.
|
||||
* Earlier bootloader stages might already do this (e.g. Trusted
|
||||
* Firmware's BL1 does it) but we can't assume so. There is no harm in
|
||||
* executing this code twice anyway.
|
||||
* Platform specific PSCI code will enable coherency for other
|
||||
* clusters.
|
||||
*/
|
||||
cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
|
||||
|
||||
#endif /* RESET_TO_BL31 */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2015, 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:
|
||||
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <el3_common_macros.S>
|
||||
#include <psci.h>
|
||||
#include <xlat_tables.h>
|
||||
|
||||
|
@ -52,69 +53,30 @@ psci_aff_suspend_finish_entry:
|
|||
adr x23, psci_afflvl_suspend_finishers
|
||||
|
||||
psci_aff_common_finish_entry:
|
||||
#if !RESET_TO_BL31
|
||||
/* ---------------------------------------------
|
||||
* Perform any processor specific actions which
|
||||
* undo or are in addition to the actions
|
||||
* performed by the reset handler in the BootROM
|
||||
* (BL1) e.g. cache, tlb invalidations, errata
|
||||
* workarounds etc.
|
||||
* ---------------------------------------------
|
||||
/*
|
||||
* 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/BL3-1 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.
|
||||
*/
|
||||
bl reset_handler
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Enable the instruction cache, stack pointer
|
||||
* and data access alignment checks.
|
||||
* It can be assumed that BL3-1 entrypoint code
|
||||
* will do this when RESET_TO_BL31 is set. The
|
||||
* same assumption cannot be made when another
|
||||
* boot loader executes before BL3-1 in the warm
|
||||
* boot path e.g. BL1.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
|
||||
mrs x0, sctlr_el3
|
||||
orr x0, x0, x1
|
||||
msr sctlr_el3, x0
|
||||
isb
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Initialise the pcpu cache pointer for the CPU
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
bl init_cpu_data_ptr
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Set the exception vectors
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
adr x0, runtime_exceptions
|
||||
msr vbar_el3, x0
|
||||
isb
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Enable the SError interrupt now that the
|
||||
* exception vectors have been setup.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
msr daifclr, #DAIF_ABT_BIT
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Use SP_EL0 for the C runtime stack.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
msr spsel, #0
|
||||
|
||||
/* --------------------------------------------
|
||||
* Give ourselves a stack whose memory will be
|
||||
* marked as Normal-IS-WBWA when the MMU is
|
||||
* enabled.
|
||||
* --------------------------------------------
|
||||
*/
|
||||
mrs x0, mpidr_el1
|
||||
bl platform_set_stack
|
||||
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=runtime_exceptions
|
||||
|
||||
/* --------------------------------------------
|
||||
* Enable the MMU with the DCache disabled. It
|
||||
|
|
Loading…
Add table
Reference in a new issue