|Age||Commit message (Collapse)||Author|
Consolidate all BL3-1 CPU context initialization for cold boot, PSCI
and SPDs into two functions:
* The first uses entry_point_info to initialize the relevant
cpu_context for first entry into a lower exception level on a CPU
* The second populates the EL1 and EL2 system registers as needed
from the cpu_context to ensure correct entry into the lower EL
This patch alters the way that BL3-1 determines which exception level
is used when first entering EL1 or EL2 during cold boot - this is now
fully determined by the SPSR value in the entry_point_info for BL3-3,
as set up by the platform code in BL2 (or otherwise provided to BL3-1).
In the situation that EL1 (or svc mode) is selected for a processor
that supports EL2, the context management code will now configure all
essential EL2 register state to ensure correct execution of EL1. This
allows the platform code to run non-secure EL1 payloads directly
without requiring a small EL2 stub or OS loader.
The crash reporting support and early initialisation of the
cpu_data allow the runtime_exception vectors to be used from
the start in BL3-1, removing the need for the additional
early_exception vectors and 2KB of code from BL3-1.
This patch prepares the per-cpu pointer cache for wider use by:
* renaming the structure to cpu_data and placing in new header
* providing accessors for this CPU, or other CPUs
* splitting the initialization of the TPIDR pointer from the
initialization of the cpu_data content
* moving the crash stack initialization to a crash stack function
* setting the TPIDR pointer very early during boot
Make the BL3-1 crash reporting optional
This patch makes the console crash dump of processor register
state optional based on the CRASH_REPORTING make variable.
This defaults to only being enabled for DEBUG builds. This can
be overridden by setting a different value in the platform
makefile or on the make command line.
'crash_reporting.S' needs to include 'platform_def.h' to get the
definition of PLATFORM_CORE_COUNT.
Note: On FVP it was compiling because 'platform_def.h' gets included
through 'plat/fvp/include/plat_macros.S' but we don't want to rely on
that for other platforms.
This patch fixes the compilation issue for trusted firmware when the
IMF_READ_INTERRUPT_ID is enabled.
The interrupt handling routine in BL3-1 expects a cookie as its last
parameter which was not being passed when invoking the interrupt
handler in BL3-1. This patch fixes that by passing a dummy cookie
parameter in the x3 register.
Rename the ic_* platform porting functions to plat_ic_* to be
consistent with the other functions in platform.h. Also rename
bl31_get_next_image_info() to bl31_plat_get_next_image_ep_info()
and remove the duplicate declaration in bl31.h.
Previously, platform.h contained many declarations and definitions
used for different purposes. This file has been split so that:
* Platform definitions used by common code that must be defined
by the platform are now in platform_def.h. The exact include
path is exported through $PLAT_INCLUDES in the platform makefile.
* Platform definitions specific to the FVP platform are now in
* Platform API declarations specific to the FVP platform are now
* The remaining platform API declarations that must be ported by
each platform are still in platform.h but this file has been
moved to /include/plat/common since this can be shared by all
This patch adds a common handler for FIQ and IRQ exceptions in the
BL3-1 runtime exception vector table. This function determines the
interrupt type and calls its handler. A crash is reported if an
inconsistency in the interrupt management framework is detected. In
the event of a spurious interrupt, execution resumes from the
instruction where the interrupt was generated.
This patch also removes 'cm_macros.S' as its contents have been moved
This change adds optional reset vector support to BL3-1
which means BL3-1 entry point can detect cold/warm boot,
initialise primary cpu, set up cci and mail box.
When using BL3-1 as a reset vector it is assumed that
the BL3-1 platform code can determine the location of
the BL3-2 images, or load them as there are no parameters
that can be passed to BL3-1 at reset.
It also fixes the incorrect initialisation of mailbox
registers on the FVP platform
This feature can be enabled by building the code with
make variable RESET_TO_BL31 set as 1
This patch is based on spec published at
It rearranges the bl31_args struct into
bl31_params and bl31_plat_params which provide the
information needed for Trusted firmware and platform
specific data via x0 and x1
On the FVP platform BL3-1 params and BL3-1 plat params
and its constituents are stored at the start of TZDRAM.
The information about memory availability and size for
BL3-1, BL3-2 and BL3-3 is moved into platform specific data.
This patch reworks the handover interface from: BL1 to BL2 and
BL2 to BL3-1. It removes the raise_el(), change_el(), drop_el()
and run_image() functions as they catered for code paths that were
BL1 calls bl1_run_bl2() to jump into BL2 instead of doing the same
by calling run_image(). Similarly, BL2 issues the SMC to transfer
execution to BL3-1 through BL1 directly. Only x0 and x1 are used
to pass arguments to BL31. These arguments and parameters for
running BL3-1 are passed through a reference to a
'el_change_info_t' structure. They were being passed value in
general purpose registers earlier.
At present, non-secure timer register contents are saved and restored as
part of world switch by BL3-1. This effectively means that the
non-secure timer stops, and non-secure timer interrupts are prevented
from asserting until BL3-1 switches back, introducing latency for
non-secure services. Often, secure world might depend on alternate
sources for secure interrupts (secure timer or platform timer) instead
of non-secure timers, in which case this save and restore is
This patch introduces a boolean build-time configuration NS_TIMER_SWITCH
to choose whether or not to save and restore non-secure timer registers
upon world switch. The default choice is made not to save and restore
This patch implements the register reporting when unhandled exceptions are
taken in BL3-1. Unhandled exceptions will result in a dump of registers
to the console, before halting execution by that CPU. The Crash Stack,
previously called the Exception Stack, is used for this activity.
This stack is used to preserve the CPU context and runtime stack
contents for debugging and analysis.
This also introduces the per_cpu_ptr_cache, referenced by tpidr_el3,
to provide easy access to some of BL3-1 per-cpu data structures.
Initially, this is used to provide a pointer to the Crash stack.
panic() now prints the the error file and line number in Debug mode
and prints the PC value in release mode.
The Exception Stack is renamed to Crash Stack with this patch.
The original intention of exception stack is no longer valid
since we intend to support several valid exceptions like IRQ
and FIQ in the trusted firmware context. This stack is now
utilized for dumping and reporting the system state when a
crash happens and hence the rename.
Fixes ARM-software/tf-issues#79 Improve reporting of unhandled exception
Preserve x19-x29 across world switch for exception handling
Set processor endianness immediately after RESET v2
Previously exception handlers in BL3-1, X19-X29 were not saved
and restored on every SMC/trap into EL3. Instead these registers
were 'saved as needed' as a side effect of the A64 ABI used by the C
That approach failed when world switching but was not visible
with the TSP/TSPD code because the TSP is 64-bit, did not
clobber these registers when running and did not support pre-emption
by normal world interrupts. These scenarios showed
that the values in these registers can be passed through a world
switch, which broke the normal and trusted world assumptions
about these registers being preserved.
The Ideal solution saves and restores these registers when a
world switch occurs - but that type of implementation is more complex.
So this patch always saves and restores these registers on entry and
exit of EL3.
Instead of using the system register helper functions to read
or write system registers, assembler coded functions should
use MRS/MSR instructions. This results in faster and more
This change replaces all usage of the helper functions with
direct register accesses.
The current code does not always use data and instruction
barriers as required by the architecture and frequently uses
barriers excessively due to their inclusion in all of the
write_*() helper functions.
Barriers should be used explicitly in assembler or C code
when modifying processor state that requires the barriers in
order to enable review of correctness of the code.
This patch removes the barriers from the helper functions and
introduces them as necessary elsewhere in the code.
PORTING NOTE: check any port of Trusted Firmware for use of
system register helper functions for reliance on the previous
barrier behaviour and add explicit barriers as necessary.
SCTLR_EL3.EE is being configured too late in bl1_arch_setup() and
bl31_arch_setup() after data accesses have already occured on
the cold and warm boot paths.
This control bit must be configured immediately on CPU reset to
match the endian state of the firmware (little endian).
Reduce the number of header files included from other header
files as much as possible without splitting the files. Use forward
declarations where possible. This allows removal of some unnecessary
"#ifndef __ASSEMBLY__" statements.
Also, review the .c and .S files for which header files really need
including and reorder the #include statements alphabetically.
Make codebase consistent in its use of #include "" syntax for
user includes and #include <> syntax for system includes.
The BL images share common stack management code which provides
one coherent and one cacheable stack for every CPU. BL1 and BL2
just execute on the primary CPU during boot and do not require
the additional CPU stacks. This patch provides separate stack
support code for UP and MP images, substantially reducing the
RAM usage for BL1 and BL2 for the FVP platform.
This patch also provides macros for declaring stacks and
calculating stack base addresses to improve consistency where
this has to be done in the firmware.
The stack allocation source files are now included via
platform.mk rather than the common BLx makefiles. This allows
each platform to select the appropriate MP/UP stack support
for each BL image.
Each platform makefile must be updated when including this
Using GCC --gc-sections to eliminate unused code and data
BL3-1 architecture setup code programs the system counter frequency
into the CNTFRQ_EL0 register. This frequency is defined by the
platform, though. This patch introduces a new platform hook that
the architecture setup code can call to retrieve this information.
In the ARM FVP port, this returns the first entry of the frequency
modes table from the memory mapped generic timer.
All system counter setup code has been removed from BL1 as some
platforms may not have initialized the system counters at this stage.
The platform specific settings done exclusively in BL1 have been moved
to BL3-1. In the ARM FVP port, this consists in enabling and
initializing the System level generic timer. Also, the frequency change
request in the counter control register has been set to 0 to make it
explicit it's using the base frequency. The CNTCR_FCREQ() macro has been
fixed in this context to give an entry number rather than a bitmask.
In future, when support for firmware update is implemented, there
is a case where BL1 platform specific code will need to program
the counter frequency. This should be implemented at that time.
This patch also updates the relevant documentation.
It properly fixes ARM-software/tf-issues#24
This reverts commit 1c297bf015226c182b66498d5a64b8b51c7624f5
because it introduced a bug: the CNTFRQ_EL0 register was no
longer programmed by all CPUs. bl31_platform_setup() function
is invoked only in the cold boot path and consequently only
on the primary cpu.
A subsequent commit will correctly implement the necessary changes
to the counter frequency setup code.
This extends the --gc-sections behaviour to the many assembler
support functions in the firmware images by placing each function
into its own code section. This is achieved by creating a 'func'
macro used to declare each function label.
Each ARM Trusted Firmware image should know in which EL it is running
and it should use the corresponding register directly instead of reading
currentEL and knowing which asm register to read/write
At present, bl1_arch_setup() and bl31_arch_setup() program the counter
frequency using a value from the memory mapped generic timer. The
generic timer however is not necessarily present on all ARM systems
(although it is architected to be present on all server systems).
This patch moves the timer setup to platform-specific code and updates
the relevant documentation. Also, CNTR.FCREQ is set as the specification
requires the bit corresponding to the counter's frequency to be set when
enabling. Since we intend to use the base frequency, set bit 8.
This patch adds the following support to the BL3-1 stage:
1. BL3-1 allows runtime services to specify and determine the security
state of the next image after BL3-1. This has been done by adding
the `bl31_set_next_image_type()` & `bl31_get_next_image_type()`
apis. The default security state is non-secure. The platform api
`bl31_get_next_image_info()` has been modified to let the platform
decide which is the next image in the desired security state.
2. BL3-1 exports the `bl31_prepare_next_image_entry()` function to
program entry into the target security state. It uses the apis
introduced in 1. to do so.
3. BL3-1 reads the information populated by BL2 about the BL3-2 image
into its internal data structures.
4. BL3-1 introduces a weakly defined reference `bl32_init()` to allow
initialisation of a BL3-2 image. A runtime service like the Secure
payload dispatcher will define this function if present.
This patch reworks BL2 to BL3-1 hand over interface by introducing a
composite structure (bl31_args) that holds the superset of information
that needs to be passed from BL2 to BL3-1.
- The extents of secure memory available to BL3-1
- The extents of memory available to BL3-2 (not yet implemented) and
- Information to execute BL3-2 (not yet implemented) and BL3-3 images
This patch also introduces a new platform API (bl2_get_bl31_args_ptr)
that needs to be implemented by the platform code to export reference to
bl31_args structure which has been allocated in platform-defined memory.
The platform will initialize the extents of memory available to BL3-3
during early platform setup in bl31_args structure. This obviates the
need for bl2_get_ns_mem_layout platform API.
BL2 calls the bl2_get_bl31_args_ptr function to get a reference to
bl31_args structure. It uses the 'bl33_meminfo' field of this structure
to load the BL3-3 image. It sets the entry point information for the
BL3-3 image in the 'bl33_image_info' field of this structure. The
reference to this structure is passed to the BL3-1 image.
Also fixes issue ARM-software/tf-issues#25
This patch adds guards so that an exception vector exceeding 32
instructions will generate a compile-time error. This keeps the
exception handlers in check from spilling over.
This patch uses the reworked exception handling support to handle
runtime service requests through SMCs following the SMC calling
convention. This is a giant commit since all the changes are
inter-related. It does the following:
1. Replace the old exception handling mechanism with the new one
2. Enforce that SP_EL0 is used C runtime stacks.
3. Ensures that the cold and warm boot paths use the 'cpu_context'
structure to program an ERET into the next lower EL.
4. Ensures that SP_EL3 always points to the next 'cpu_context'
structure prior to an ERET into the next lower EL
5. Introduces a PSCI SMC handler which completes the use of PSCI as a
Co-authored-by: Achin Gupta <firstname.lastname@example.org>
This patch introduces the reworked exception handling logic which lays
the foundation for accessing runtime services in later patches. The
type of an exception has a greater say in the way it is
handled. SP_EL3 is used as the stack pointer for:
1. Determining the type of exception and handling the unexpected ones
on the exception stack
2. Saving and restoring the essential general purpose and system
register state after exception entry and prior to exception exit.
SP_EL0 is used as the stack pointer for handling runtime service
requests e.g. SMCs. A new structure for preserving general purpose
register state has been added to the 'cpu_context' structure. All
assembler ensures that it does not use callee saved registers
(x19-x29). The C runtime preserves them across functions calls. Hence
EL3 code does not have to save and restore them explicitly.
Since the exception handling framework has undergone substantial change,
the changes have been kept in separate files to aid readability. These
files will replace the existing ones in subsequent patches.
This patch introduces functions for saving and restoring shared system
registers between secure and non-secure EL1 exception levels, VFP
registers and essential EL3 system register and other state. It also
defines the 'cpu_context' data structure which will used for saving and
restoring execution context for a given security state. These functions
will allow runtime services like PSCI and Secure payload dispatcher to
implement logic for switching between the secure and non-secure states.
The save and restore functions follow AArch64 PCS and only use
caller-saved temporary registers.
This patch ensures that VBAR_EL3 points to the simple stack-less
'early_exceptions' when the C runtime stack is not correctly setup to
use the more complex 'runtime_exceptions'. It is initialised to
'runtime_exceptions' once this is done.
This patch also moves all exception vectors into a '.vectors' section
and modifies linker scripts to place all such sections together. This
will minimize space wastage from alignment restrictions.
Ctags seem to have a problem with generating tags for assembler symbols
when a comment immediately follows an assembly label.
This patch inserts a single space character between the label
definition and the following comments to help ctags.
The patch is generated by the command:
git ls-files -- \*.S | xargs sed -i 's/^\([^:]\+\):;/\1: ;/1'
Traps when accessing architectural features are disabled by clearing bits
in CPTR_EL3 during early boot, including accesses to floating point
registers. The value of this register was previously undetermined, causing
unwanted traps to EL3. Future EL3 code (for example, context save/restore
code) may use floating point registers, although they are not used by current
Also, the '-mgeneral-regs-only' flag is enabled in the GCC settings to
prevent generation of code that uses floating point registers.
ns_entry_info used to be a per-cpu array. This is a waste of space
because it is only accessed by the primary CPU on the cold boot path.
This patch reduces ns_entry_info to a single-cpu area.
RUN_IMAGE constant is used by all bootloader stages.
The runtime exception handling assembler code used magic numbers for
saving and restoring the general purpose register context on stack
memory. The memory is interpreted as a 'gp_regs' structure and the
magic numbers are offsets to members of this structure. This patch
replaces the magic number offsets with constants. It also adds compile
time assertions to prevent an incorrect assembler view of this
- Add instructions for contributing to ARM Trusted Firmware.
- Update copyright text in all files to acknowledge contributors.
This patch makes sure the C runtime environment is properly
initialised before executing any C code.
- Zero-initialise NOBITS sections (e.g. the bss section).
- Relocate BL1 data from ROM to RAM.
- Check at link-time that bootloader images will fit in memory
at run time and that they won't overlap each other.
- Remove text and rodata orphan sections.
- Define new linker symbols to remove the need for platform setup
code to know the order of sections.
- Reduce the size of the raw binary images by cutting some sections
out of the disk image and allocating them at load time, whenever
- Rework alignment constraints on sections.
- Remove unused linker symbols.
- Homogenize linker symbols names across all BLs.
- Add some comments in the linker scripts.
Any asynchronous exception caused by the firmware should be handled
in the firmware itself. For this reason, unmask SError exceptions
(and Debug ones as well) on all boot paths. Also route external
abort and SError interrupts to EL3, otherwise they will target EL1.