Browse Source

Documentation for BL3-1 hardening and reset vector

Update documentation with BL3-1 hardening interface
changes and for using BL3-1 as a reset vector feature

Change-Id: Iafdd05e7a8e66503409f2acc934372efef5bc51b
pull/118/head
Vikram Kanigiri 11 years ago
parent
commit
e452cd8993
  1. 185
      docs/firmware-design.md
  2. 446
      docs/porting-guide.md
  3. 134
      docs/user-guide.md

185
docs/firmware-design.md

@ -56,6 +56,14 @@ The ARM Fixed Virtual Platforms (FVPs) provide trusted ROM, trusted SRAM and
trusted DRAM regions. Each boot loader stage uses one or more of these
memories for its code and data.
The sections below provide the following details:
* initialization and execution of the first three stages during cold boot
* specification of the BL3-1 entrypoint requirements for use by alternative
Trusted Boot Firmware in place of the provided BL1 and BL2
* changes in BL3-1 behavior when using the `RESET_TO_BL31` option which
allows BL3-1 to run without BL1 and BL2
### BL1
@ -368,6 +376,167 @@ level implementation of the generic timer through the memory mapped interface.
available Exception Level (EL2 if available, otherwise EL1).
### Using alternative Trusted Boot Firmware in place of BL1 and BL2
Some platforms have existing implementations of Trusted Boot Firmware that
would like to use ARM Trusted Firmware BL3-1 for the EL3 Runtime Firmware. To
enable this firmware architecture it is important to provide a fully documented
and stable interface between the Trusted Boot Firmware and BL3-1.
Future changes to the BL3-1 interface will be done in a backwards compatible
way, and this enables these firmware components to be independently enhanced/
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.
On entry to this function the calling primary CPU must be executing in AArch64
EL3, little-endian data access, and all interrupt sources masked:
PSTATE.EL = 3
PSTATE.RW = 1
PSTATE.DAIF = 0xf
CTLR_EL3.EE = 0
X0 and X1 can be used to pass information from the Trusted Boot Firmware to the
platform code in BL3-1:
X0 : Reserved for common Trusted Firmware information
X1 : Platform specific information
BL3-1 zero-init sections (e.g. `.bss`) should not contain valid data on entry,
these will be zero filled prior to invoking platform setup code.
##### Use of the X0 and X1 parameters
The parameters are platform specific and passed from `bl31_entrypoint()` to
`bl31_early_platform_setup()`. The value of these parameters is never directly
used by the common BL3-1 code.
The convention is that `X0` conveys information regarding the BL3-1, BL3-2 and
BL3-3 images from the Trusted Boot firmware and `X1` can be used for other
platform specific purpose. This convention allows platforms which use ARM
Trusted Firmware's BL1 and BL2 images to transfer additional platform specific
information from Secure Boot without conflicting with future evolution of the
Trusted Firmware using `X0` to pass a `bl31_params` structure.
BL3-1 common and SPD initialization code depends on image and entrypoint
information about BL3-3 and BL3-2, which is provided via BL3-1 platform APIs.
This information is required until the start of execution of BL3-3. This
information can be provided in a platform defined manner, e.g. compiled into
the platform code in BL3-1, or provided in a platform defined memory location
by the Trusted Boot firmware, or passed from the Trusted Boot Firmware via the
Cold boot Initialization parameters. This data may need to be cleaned out of
the CPU caches if it is provided by an earlier boot stage and then accessed by
BL3-1 platform code before the caches are enabled.
ARM Trusted Firmware's BL2 implementation passes a `bl31_params` structure in
`X0` and the FVP port interprets this in the BL3-1 platform code.
##### MMU, Data caches & Coherency
BL3-1 does not depend on the enabled state of the MMU, data caches or
interconnect coherency on entry to `bl31_entrypoint()`. If these are disabled
on entry, these should be enabled during `bl31_plat_arch_setup()`.
##### Data structures used in the BL3-1 cold boot interface
These structures are designed to support compatibility and independent
evolution of the structures and the firmware images. For example, a version of
BL3-1 that can interpret the BL3-x image information from different versions of
BL2, a platform that uses an extended entry_point_info structure to convey
additional register information to BL3-1, or a ELF image loader that can convey
more details about the firmware images.
To support these scenarios the structures are versioned and sized, which enables
BL3-1 to detect which information is present and respond appropriately. The
`param_header` is defined to capture this information:
typedef struct param_header {
uint8_t type; /* type of the structure */
uint8_t version; /* version of this structure */
uint16_t size; /* size of this structure in bytes */
uint32_t attr; /* attributes: unused bits SBZ */
} param_header_t;
The structures using this format are `entry_point_info`, `image_info` and
`bl31_params`. The code that allocates and populates these structures must set
the header fields appropriately, and the `SET_PARA_HEAD()` a macro is defined
to simplify this action.
#### Required CPU state for BL3-1 Warm boot initialization
When requesting a CPU power-on, or suspending a running CPU, ARM Trusted
Firmware provides the platform power management code with a Warm boot
initialization entry-point, to be invoked by the CPU immediately after the
reset handler. On entry to the Warm boot initialization function the calling
CPU must be in AArch64 EL3, little-endian data access and all interrupt sources
masked:
PSTATE.EL = 3
PSTATE.RW = 1
PSTATE.DAIF = 0xf
SCTLR_EL3.EE = 0
The PSCI implementation will initialize the processor state and ensure that the
platform power management code is then invoked as required to initialize all
necessary system, cluster and CPU resources.
### Using BL3-1 as the CPU reset vector
On some platforms the runtime firmware (BL3-x images) for the application
processors are loaded by trusted firmware running on a secure system processor
on the SoC, rather than by BL1 and BL2 running on the primary application
processor. For this type of SoC it is desirable for the application processor
to always reset to BL3-1 which eliminates the need for BL1 and BL2.
ARM Trusted Firmware provides a build-time option `RESET_TO_BL31` that includes
some additional logic in the BL3-1 entrypoint to support this use case.
In this configuration, the platform's Trusted Boot Firmware must ensure that
BL3-1 is loaded to its runtime address, which must match the CPU's RVBAR reset
vector address, before the application processor is powered on. Additionally,
platform software is responsible for loading the other BL3-x images required and
providing entry point information for them to BL3-1. Loading these images might
be done by the Trusted Boot Firmware or by platform code in BL3-1.
The ARM FVP port supports the `RESET_TO_BL31` configuration, in which case the
`bl31.bin` image must be loaded to its run address in Trusted SRAM and all CPU
reset vectors be changed from the default `0x0` to this run address. See the
[User Guide] for details of running the FVP models in this way.
This configuration requires some additions and changes in the BL3-1
functionality:
#### Determination of boot path
In this configuration, BL3-1 uses the same reset framework and code as the one
described for BL1 above. On a warm boot a CPU is directed to the PSCI
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
that can be passed in registers by previous boot stages. Instead, the platform
code in BL3-1 needs to know, or be able to determine, the location of the BL3-2
(if required) and BL3-3 images and provide this information in response to the
`bl31_plat_get_next_image_ep_info()` function.
As the first image to execute in this configuration BL3-1 must also ensure that
any security initialisation, for example programming a TrustZone address space
controller, is carried out during early platform initialisation.
3. EL3 runtime services framework
----------------------------------
@ -613,16 +782,13 @@ The TSPD service is responsible for.
The Secure-EL1 Payload Dispatcher (SPD) service is responsible for initializing
the BL3-2 image. It needs access to the information passed by BL2 to BL3-1 to do
so. Hence BL3-1 implements:
so. This is provided by:
1. `bl31_plat_get_bl32_mem_layout()` to return the extents of memory
available for BL3-2's use as communicated by BL2.
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t);
2. `bl31_get_next_image_info(uint32_t security_state)` to return a reference
to the `el_change_info` structure corresponding to the next image which will
be run in the specified security state. The SPD uses this api with the
secure security state as the parameter to get entry related information about
BL3-2.
which returns a reference to the `entry_point_info` structure corresponding to
the image which will be run in the specified security state. The SPD uses this
API to get entry point information for the SECURE image, BL3-2.
In the absence of a BL3-2 image, BL3-1 passes control to the normal world
bootloader image (BL3-3). When the BL3-2 image is present, it is typical
@ -632,7 +798,7 @@ To do this the SPD has to register a BL3-2 initialization function during
initialization of the SPD service. The BL3-2 initialization function has this
prototype:
int32_t init(meminfo *bl32_meminfo);
int32_t init();
and is registered using the `bl31_register_bl32_init()` function.
@ -1044,3 +1210,4 @@ _Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._
[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022b/index.html "Power State Coordination Interface PDD (ARM DEN 0022B.b)"
[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)"
[UUID]: https://tools.ietf.org/rfc/rfc4122.txt "A Universally Unique IDentifier (UUID) URN Namespace"
[User Guide]: user-guide.md

446
docs/porting-guide.md

@ -7,6 +7,7 @@ Contents
1. Introduction
2. Common Modifications
* Common mandatory modifications
* Handling reset
* Common optional modifications
3. Boot Loader stage specific modifications
* Boot Loader stage 1 (BL1)
@ -277,7 +278,84 @@ the implementer chooses. In the ARM FVP port, they are implemented in
which is retrieved from the first entry in the frequency modes table.
2.2 Common optional modifications
2.2 Handling Reset
------------------
BL1 by default implements the reset vector where execution starts from a cold
or warm boot. BL3-1 can be optionally set as a reset vector using the
RESET_TO_BL31 make variable.
For each CPU, the reset vector code is responsible for the following tasks:
1. Distinguishing between a cold boot and a warm boot.
2. In the case of a cold boot and the CPU being a secondary CPU, ensuring that
the CPU is placed in a platform-specific state until the primary CPU
performs the necessary steps to remove it from this state.
3. In the case of a warm boot, ensuring that the CPU jumps to a platform-
specific address in the BL3-1 image in the same processor mode as it was
when released from reset.
The following functions need to be implemented by the platform port to enable
reset vector code to perform the above tasks.
### Function : platform_get_entrypoint() [mandatory]
Argument : unsigned long
Return : unsigned int
This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The CPU
is identified by its `MPIDR`, which is passed as the argument. The function is
responsible for distinguishing between a warm and cold reset using platform-
specific means. If it's a warm reset then it returns the entrypoint into the
BL3-1 image that the CPU must jump to. If it's a cold reset then this function
must return zero.
This function is also responsible for implementing a platform-specific mechanism
to handle the condition where the CPU has been warm reset but there is no
entrypoint to jump to.
This function does not follow the Procedure Call Standard used by the
Application Binary Interface for the ARM 64-bit architecture. The caller should
not assume that callee saved registers are preserved across a call to this
function.
This function fulfills requirement 1 and 3 listed above.
### Function : plat_secondary_cold_boot_setup() [mandatory]
Argument : void
Return : void
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.
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
requires them.
This function fulfills requirement 2 above.
### Function : platform_mem_init() [mandatory]
Argument : void
Return : void
This function is called before any access to data is made by the firmware, in
order to carry out any essential memory initialization.
The ARM FVP port uses this function to initialize the mailbox memory used for
providing the warm-boot entry-point addresses.
2.3 Common optional modifications
---------------------------------
The following are helper functions implemented by the firmware that perform
@ -403,24 +481,16 @@ are just an ARM Trusted Firmware convention.
BL1 implements the reset vector where execution starts from after a cold or
warm boot. For each CPU, BL1 is responsible for the following tasks:
1. Distinguishing between a cold boot and a warm boot.
1. Handling the reset as described in section 2.2
2. In the case of a cold boot and the CPU being the primary CPU, ensuring that
only this CPU executes the remaining BL1 code, including loading and passing
control to the BL2 stage.
3. In the case of a cold boot and the CPU being a secondary CPU, ensuring that
the CPU is placed in a platform-specific state until the primary CPU
performs the necessary steps to remove it from this state.
4. In the case of a warm boot, ensuring that the CPU jumps to a platform-
specific address in the BL3-1 image in the same processor mode as it was
when released from reset.
5. Loading the BL2 image from non-volatile storage into secure memory at the
3. Loading the BL2 image from non-volatile storage into secure memory at the
address specified by the platform defined constant `BL2_BASE`.
6. Populating a `meminfo` structure with the following information in memory,
4. Populating a `meminfo` structure with the following information in memory,
accessible by BL2 immediately upon entry.
meminfo.total_base = Base address of secure RAM visible to BL2
@ -448,68 +518,18 @@ The following functions need to be implemented by the platform port to enable
BL1 to perform the above tasks.
### Function : platform_get_entrypoint() [mandatory]
Argument : unsigned long
Return : unsigned int
This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The CPU
is identified by its `MPIDR`, which is passed as the argument. The function is
responsible for distinguishing between a warm and cold reset using platform-
specific means. If it's a warm reset then it returns the entrypoint into the
BL3-1 image that the CPU must jump to. If it's a cold reset then this function
must return zero.
This function is also responsible for implementing a platform-specific mechanism
to handle the condition where the CPU has been warm reset but there is no
entrypoint to jump to.
This function does not follow the Procedure Call Standard used by the
Application Binary Interface for the ARM 64-bit architecture. The caller should
not assume that callee saved registers are preserved across a call to this
function.
This function fulfills requirement 1 listed above.
### Function : plat_secondary_cold_boot_setup() [mandatory]
### Function : bl1_plat_arch_setup() [mandatory]
Argument : void
Return : void
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.
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
requires them.
This function fulfills requirement 3 above.
### Function : platform_cold_boot_init() [mandatory]
Argument : unsigned long
Return : unsigned int
This function executes with the MMU and data caches disabled. It is only called
by the primary CPU. The argument to this function is the address of the
`bl1_main()` routine where the generic BL1-specific actions are performed.
This function performs any platform-specific and architectural setup that the
platform requires to make execution of `bl1_main()` possible.
The platform must enable the MMU with identity mapped page tables and enable
caches by setting the `SCTLR.I` and `SCTLR.C` bits.
Platform-specific setup might include configuration of memory controllers,
configuration of the interconnect to allow the cluster to service cache snoop
requests from another cluster, zeroing of the ZI section, and so on.
platform requires. Platform-specific setup might include configuration of
memory controllers, configuration of the interconnect to allow the cluster
to service cache snoop requests from another cluster, and so on.
In the ARM FVP port, this function enables CCI snoops into the cluster that the
primary CPU is part of. It also enables the MMU and initializes the ZI section
in the BL1 image through the use of linker defined symbols.
primary CPU is part of. It also enables the MMU.
This function helps fulfill requirement 2 above.
@ -526,7 +546,7 @@ MMU and data cache have been enabled.
This function is also responsible for initializing the storage abstraction layer
which is used to load further bootloader images.
This function helps fulfill requirement 5 above.
This function helps fulfill requirement 3 above.
### Function : bl1_plat_sec_mem_layout() [mandatory]
@ -549,7 +569,7 @@ This information is used by BL1 to load the BL2 image in secure RAM. BL1 also
populates a similar structure to tell BL2 the extents of memory available for
its own use.
This function helps fulfill requirement 5 above.
This function helps fulfill requirement 3 above.
### Function : init_bl2_mem_layout() [optional]
@ -557,10 +577,8 @@ This function helps fulfill requirement 5 above.
Argument : meminfo *, meminfo *, unsigned int, unsigned long
Return : void
Each BL stage needs to tell the next stage the amount of secure RAM available
for it to use. For example, as part of handing control to BL2, BL1 informs BL2
of the extents of secure RAM available for BL2 to use. BL2 must do the same when
passing control to BL3-1. This information is populated in a `meminfo`
BL1 needs to tell the next stage the amount of secure RAM available
for it to use. This information is populated in a `meminfo`
structure.
Depending upon where BL2 has been loaded in secure RAM (determined by
@ -570,6 +588,18 @@ to BL2. An illustration of how this is done in the ARM FVP port is given in the
[User Guide], in the Section "Memory layout on Base FVP".
### Function : bl1_plat_set_bl2_ep_info() [mandatory]
Argument : image_info *, entry_point_info *
Return : void
This function is called after loading BL2 image and it can be used to overwrite
the entry point set by loader and also set the security state and SPSR which
represents the entry point system state for BL2.
On FVP, we are setting the security state and the SPSR for the BL2 entrypoint
3.2 Boot Loader Stage 2 (BL2)
-----------------------------
@ -589,55 +619,22 @@ using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at
address is determined using the `plat_get_ns_image_entrypoint()` function
described below.
BL2 populates an `el_change_info` structure in memory provided by the
platform with information about how BL3-1 should pass control to the normal
world BL image.
3. Populating a `meminfo` structure with the following information in
memory that is accessible by BL3-1 immediately upon entry.
meminfo.total_base = Base address of secure RAM visible to BL3-1
meminfo.total_size = Size of secure RAM visible to BL3-1
meminfo.free_base = Base address of secure RAM available for allocation
to BL3-1
meminfo.free_size = Size of secure RAM available for allocation to
BL3-1
BL2 populates this information in the `bl31_meminfo` field of the pointer
returned by the `bl2_get_bl31_args_ptr() function. BL2 implements the
`init_bl31_mem_layout()` function to populate the BL3-1 meminfo structure
described above. The platform may override this implementation, for example
if the platform wants to restrict the amount of memory visible to BL3-1.
Details of this function are given below.
3. BL2 populates an `entry_point_info` structure in memory provided by the
platform with information about how BL3-1 should pass control to the
other BL images.
4. (Optional) Loading the BL3-2 binary image (if present) from platform
provided non-volatile storage. To load the BL3-2 image, BL2 makes use of
the `bl32_meminfo` field in the `bl31_args` structure to which a pointer is
returned by the `bl2_get_bl31_args_ptr()` function. The platform also
defines the address in memory where BL3-2 is loaded through the optional
constant `BL32_BASE`. BL2 uses this information to determine if there is
enough memory to load the BL3-2 image. If `BL32_BASE` is not defined then
this and the following two steps are not performed.
the `meminfo` returned by the `bl2_plat_get_bl32_meminfo()` function.
The platform also defines the address in memory where BL3-2 is loaded
through the optional constant `BL32_BASE`. BL2 uses this information
to determine if there is enough memory to load the BL3-2 image.
If `BL32_BASE` is not defined then this and the next step is not performed.
5. (Optional) Arranging to pass control to the BL3-2 image (if present) that
has been pre-loaded at `BL32_BASE`. BL2 populates an `el_change_info`
has been pre-loaded at `BL32_BASE`. BL2 populates an `entry_point_info`
structure in memory provided by the platform with information about how
BL3-1 should pass control to the BL3-2 image. This structure follows the
`el_change_info` structure populated for the normal world BL image in 2.
above.
6. (Optional) Populating a `meminfo` structure with the following information
in memory that is accessible by BL3-1 immediately upon entry.
meminfo.total_base = Base address of memory visible to BL3-2
meminfo.total_size = Size of memory visible to BL3-2
meminfo.free_base = Base address of memory available for allocation
to BL3-2
meminfo.free_size = Size of memory available for allocation to
BL3-2
BL2 populates this information in the `bl32_meminfo` field of the pointer
returned by the `bl2_get_bl31_args_ptr()` function.
BL3-1 should pass control to the BL3-2 image.
The following functions must be implemented by the platform port to enable BL2
to perform the above tasks.
@ -645,14 +642,12 @@ to perform the above tasks.
### Function : bl2_early_platform_setup() [mandatory]
Argument : meminfo *, void *
Argument : meminfo *
Return : void
This function executes with the MMU and data caches disabled. It is only called
by the primary CPU. The arguments to this function are:
* The address of the `meminfo` structure populated by BL1
* An opaque pointer that the platform may use as needed.
by the primary CPU. The arguments to this function is the address of the
`meminfo` structure populated by BL1.
The platform must copy the contents of the `meminfo` structure into a private
variable as the original memory may be subsequently overwritten by BL2. The
@ -683,26 +678,11 @@ port does the necessary initialization in `bl2_plat_arch_setup()`. It is only
called by the primary CPU.
The purpose of this function is to perform any platform initialization
specific to BL2. For example on the ARM FVP port this function initialises a
internal pointer (`bl2_to_bl31_args`) to a `bl31_args` which will be used by
BL2 to pass information to BL3_1. The pointer is initialized to the base
address of Secure DRAM (`0x06000000`).
The ARM FVP port also populates the `bl32_meminfo` field in the `bl31_args`
structure pointed to by `bl2_to_bl31_args` with the extents of memory available
for use by the BL3-2 image. The memory is allocated in the Secure DRAM from the
address defined by the constant `BL32_BASE`. The ARM FVP port currently loads
the BL3-2 image at the Secure DRAM address `0x6002000`.
The non-secure memory extents used for loading BL3-3 are also initialized in
this function. This information is accessible in the `bl33_meminfo` field in
the `bl31_args` structure pointed to by `bl2_to_bl31_args`.
Platform security components are configured if required. For the Base FVP the
TZC-400 TrustZone controller is configured to only grant non-secure access
to DRAM. This avoids aliasing between secure and non-secure accesses in the
TLB and cache - secure execution states can use the NS attributes in the
MMU translation tables to access the DRAM.
specific to BL2. Platform security components are configured if required.
For the Base FVP the TZC-400 TrustZone controller is configured to only
grant non-secure access to DRAM. This avoids aliasing between secure and
non-secure accesses in the TLB and cache - secure execution states can use
the NS attributes in the MMU translation tables to access the DRAM.
This function is also responsible for initializing the storage abstraction layer
which is used to load further bootloader images.
@ -722,40 +702,109 @@ populated with the extents of secure RAM available for BL2 to use. See
`bl2_early_platform_setup()` above.
### Function : bl2_get_bl31_args_ptr() [mandatory]
### Function : bl2_plat_get_bl31_params() [mandatory]
Argument : void
Return : bl31_args *
Return : bl31_params *
BL2 platform code needs to return a pointer to a `bl31_params` structure it
will use for passing information to BL3-1. The `bl31_params` structure carries
the following information.
- Header describing the version information for interpreting the bl31_param
structure
- Information about executing the BL3-3 image in the `bl33_ep_info` field
- Information about executing the BL3-2 image in the `bl32_ep_info` field
- Information about the type and extents of BL3-1 image in the
`bl31_image_info` field
- Information about the type and extents of BL3-2 image in the
`bl32_image_info` field
- Information about the type and extents of BL3-3 image in the
`bl33_image_info` field
The memory pointed by this structure and its sub-structures should be
accessible from BL3-1 initialisation code. BL3-1 might choose to copy the
necessary content, or maintain the structures until BL3-3 is initialised.
BL2 platform code needs to return a pointer to a `bl31_args` structure it will
use for passing information to BL3-1. The `bl31_args` structure carries the
following information. This information is used by the `bl2_main()` function to
load the BL3-2 (if present) and BL3-3 images.
- Extents of memory available to the BL3-1 image in the `bl31_meminfo` field
- Extents of memory available to the BL3-2 image in the `bl32_meminfo` field
- Extents of memory available to the BL3-3 image in the `bl33_meminfo` field
- Information about executing the BL3-3 image in the `bl33_image_info` field
- Information about executing the BL3-2 image in the `bl32_image_info` field
### Funtion : bl2_plat_get_bl31_ep_info() [mandatory]
Argument : void
Return : entry_point_info *
### Function : init_bl31_mem_layout() [optional]
BL2 platform code returns a pointer which is used to populate the entry point
information for BL3-1 entry point. The location pointed by it should be
accessible from BL1 while processing the synchronous exception to run to BL3-1.
Argument : meminfo *, meminfo *, unsigned int
On FVP this is allocated inside an bl2_to_bl31_params_mem structure which
is allocated at an address pointed by PARAMS_BASE.
### Function : bl2_plat_set_bl31_ep_info() [mandatory]
Argument : image_info *, entry_point_info *
Return : void
This function is called after loading BL3-1 image and it can be used to
overwrite the entry point set by loader and also set the security state
and SPSR which represents the entry point system state for BL3-1.
On FVP, we are setting the security state and the SPSR for the BL3-1
entrypoint.
### Function : bl2_plat_set_bl32_ep_info() [mandatory]
Argument : image_info *, entry_point_info *
Return : void
This function is called after loading BL3-2 image and it can be used to
overwrite the entry point set by loader and also set the security state
and SPSR which represents the entry point system state for BL3-2.
On FVP, we are setting the security state and the SPSR for the BL3-2
entrypoint
### Function : bl2_plat_set_bl33_ep_info() [mandatory]
Argument : image_info *, entry_point_info *
Return : void
This function is called after loading BL3-3 image and it can be used to
overwrite the entry point set by loader and also set the security state
and SPSR which represents the entry point system state for BL3-3.
On FVP, we are setting the security state and the SPSR for the BL3-3
entrypoint
### Function : bl2_plat_get_bl32_meminfo() [mandatory]
Argument : meminfo *
Return : void
This function is used to get the memory limits where BL2 can load the
BL3-2 image. The meminfo provided by this is used by load_image() to
validate whether the BL3-2 image can be loaded with in the given
memory from the given base.
### Function : bl2_plat_get_bl33_meminfo() [mandatory]
Argument : meminfo *
Return : void
Each BL stage needs to tell the next stage the amount of secure RAM that is
available for it to use. For example, as part of handing control to BL2, BL1
must inform BL2 about the extents of secure RAM that is available for BL2 to
use. BL2 must do the same when passing control to BL3-1. This information is
populated in a `meminfo` structure.
This function is used to get the memory limits where BL2 can load the
BL3-3 image. The meminfo provided by this is used by load_image() to
validate whether the BL3-3 image can be loaded with in the given
memory from the given base.
### Function : bl2_plat_flush_bl31_params() [mandatory]
Depending upon where BL3-1 has been loaded in secure RAM (determined by
`BL31_BASE`), BL2 calculates the amount of free memory available for BL3-1 to
use. BL2 also ensures that BL3-1 is able reclaim memory occupied by BL2. This
is done because BL2 never executes again after passing control to BL3-1.
An illustration of how this is done in the ARM FVP port is given in the
[User Guide], in the section "Memory layout on Base FVP".
Argument : void
Return : void
Once BL2 has populated all the structures that needs to be read by BL1
and BL3-1 including the bl31_params structures and its sub-structures,
the bl31_ep_info structure and any platform specific data. It flushes
all these data to the main memory so that it is available when we jump to
later Bootloader stages with MMU off
### Function : plat_get_ns_image_entrypoint() [mandatory]
@ -783,7 +832,7 @@ CPUs. BL3-1 executes at EL3 and is responsible for:
should make no assumptions about the system state when it receives control.
2. Passing control to a normal world BL image, pre-loaded at a platform-
specific address by BL2. BL3-1 uses the `el_change_info` structure that BL2
specific address by BL2. BL3-1 uses the `entry_point_info` structure that BL2
populated in memory to do this.
3. Providing runtime firmware services. Currently, BL3-1 only implements a
@ -794,8 +843,11 @@ CPUs. BL3-1 executes at EL3 and is responsible for:
4. Optionally passing control to the BL3-2 image, pre-loaded at a platform-
specific address by BL2. BL3-1 exports a set of apis that allow runtime
services to specify the security state in which the next image should be
executed and run the corresponding image. BL3-1 uses the `el_change_info`
and `meminfo` structure populated by BL2 to do this.
executed and run the corresponding image. BL3-1 uses the `entry_point_info`
structure populated by BL2 to do this.
If BL3-1 is a reset vector, It also needs to handle the reset as specified in
section 2.2 before the tasks described above.
The following functions must be implemented by the platform port to enable BL3-1
to perform the above tasks.
@ -803,26 +855,26 @@ to perform the above tasks.
### Function : bl31_early_platform_setup() [mandatory]
Argument : meminfo *, void *, unsigned long
Argument : bl31_params *, void *
Return : void
This function executes with the MMU and data caches disabled. It is only called
by the primary CPU. The arguments to this function are:
* The address of the `meminfo` structure populated by BL2.
* The address of the `bl31_params` structure populated by BL2.
* An opaque pointer that the platform may use as needed.
* The `MPIDR` of the primary CPU.
The platform can copy the contents of the `meminfo` structure into a private
variable if the original memory may be subsequently overwritten by BL3-1. The
reference to this structure is made available to all BL3-1 code through the
`bl31_plat_sec_mem_layout()` function.
The platform can copy the contents of the `bl31_params` structure and its
sub-structures into private variables if the original memory may be
subsequently overwritten by BL3-1 and similarly the `void *` pointing
to the platform data also needs to be saved.
On the ARM FVP port, BL2 passes a pointer to a `bl31_args` structure populated
in the secure DRAM at address `0x6000000` in the opaque pointer mentioned
earlier. BL3-1 does not copy this information to internal data structures as it
guarantees that the secure DRAM memory will not be overwritten. It maintains an
internal reference to this information in the `bl2_to_bl31_args` variable.
On the ARM FVP port, BL2 passes a pointer to a `bl31_params` structure populated
in the secure DRAM at address `0x6000000` in the bl31_params * argument and it
does not use opaque pointer mentioned earlier. BL3-1 does not copy this
information to internal data structures as it guarantees that the secure
DRAM memory will not be overwritten. It maintains an internal reference to this
information in the `bl2_to_bl31_params` variable.
### Function : bl31_plat_arch_setup() [mandatory]
@ -861,7 +913,7 @@ The ARM FVP port does the following:
### Function : bl31_get_next_image_info() [mandatory]
Argument : unsigned int
Return : el_change_info *
Return : entry_point_info *
This function may execute with the MMU and data caches enabled if the platform
port does the necessary initializations in `bl31_plat_arch_setup()`.
@ -869,41 +921,11 @@ port does the necessary initializations in `bl31_plat_arch_setup()`.
This function is called by `bl31_main()` to retrieve information provided by
BL2 for the next image in the security state specified by the argument. BL3-1
uses this information to pass control to that image in the specified security
state. This function must return a pointer to the `el_change_info` structure
state. This function must return a pointer to the `entry_point_info` structure
(that was copied during `bl31_early_platform_setup()`) if the image exists. It
should return NULL otherwise.
### Function : bl31_plat_sec_mem_layout() [mandatory]
Argument : void
Return : meminfo *
This function should only be called on the cold boot path. This function may
execute with the MMU and data caches enabled if the platform port does the
necessary initializations in `bl31_plat_arch_setup()`. It is only called by the
primary CPU.
The purpose of this function is to return a pointer to a `meminfo` structure
populated with the extents of secure RAM available for BL3-1 to use. See
`bl31_early_platform_setup()` above.
### Function : bl31_plat_get_bl32_mem_layout() [mandatory]
Argument : void
Return : meminfo *
This function should only be called on the cold boot path. This function may
execute with the MMU and data caches enabled if the platform port does the
necessary initializations in `bl31_plat_arch_setup()`. It is only called by the
primary CPU.
The purpose of this function is to return a pointer to a `meminfo` structure
populated with the extents of memory available for BL3-2 to use. See
`bl31_early_platform_setup()` above.
3.3 Power State Coordination Interface (in BL3-1)
------------------------------------------------

134
docs/user-guide.md

@ -167,6 +167,12 @@ performed.
read using a platform GIC API. `INTR_ID_UNAVAILABLE` is passed instead if
this option set to 0. Default is 0.
* `RESET_TO_BL31`: Enable BL3-1 entrypoint as the CPU reset vector in place
of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
entrypoint) or 1 (CPU reset to BL3-1 entrypoint).
The default value is 0.
### Creating a Firmware Image Package
FIPs are automatically created as part of the build instructions described in
@ -575,7 +581,8 @@ ARM Trusted Firmware and normal world software behavior is provided below.
The Foundation FVP is a cut down version of the AArch64 Base FVP. It can be
downloaded for free from [ARM's website][ARM FVP website].
### Running on the Foundation FVP
### Running on the Foundation FVP with reset to BL1 entrypoint
The following `Foundation_v8` parameters should be used to boot Linux with
4 CPUs using the ARM Trusted Firmware.
@ -603,27 +610,42 @@ emulation mode.
The memory mapped addresses `0x0` and `0x8000000` correspond to the start of
trusted ROM and NOR FLASH0 respectively.
### Running on the AEMv8 Base FVP
### Notes regarding Base FVP configuration options
The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
with 8 CPUs using the ARM Trusted Firmware.
1. The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image
Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware"
section above).
NOTE: Using `cache_state_modelled=1` makes booting very slow. The software will
2. Using `cache_state_modelled=1` makes booting very slow. The software will
still work (and run much faster) without this option but this will hide any
cache maintenance defects in the software.
NOTE: Using the `-C bp.virtioblockdevice.image_path` parameter is not necessary
3. Using the `-C bp.virtioblockdevice.image_path` parameter is not necessary
if a Linux RAM-disk file-system is used (see the "Obtaining a root file-system"
section above).
NOTE: The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image
Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware"
section above).
4. Setting the `-C bp.secure_memory` parameter to `1` is only supported on
Base FVP versions 5.4 and newer. Setting this parameter to `0` is also
supported. The `-C bp.tzc_400.diagnostics=1` parameter is optional. It
instructs the FVP to provide some helpful information if a secure memory
violation occurs.
5. The `--data="<path-to><bl31/bl32/bl33-binary>"@base address of binaries`
parameter is used to load bootloader images in the Base FVP memory (see the
"Building the Trusted Firmware" section above). The base address used to
load the binaries with --data should match the image base addresses in
platform_def.h used while linking the images.
BL3-2 image is only needed if BL3-1 has been built to expect a secure-EL1
payload.
NOTE: Setting the `-C bp.secure_memory` parameter to `1` is only supported on
FVP versions 5.4 and newer. Setting this parameter to `0` is also supported.
The `-C bp.tzc_400.diagnostics=1` parameter is optional. It instructs the FVP to
provide some helpful information if a secure memory violation occurs.
### Running on the AEMv8 Base FVP with reset to BL1 entrypoint
Please read "Notes regarding Base FVP configuration options" section above for
information about some of the options to run the software.
The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
with 8 CPUs using the ARM Trusted Firmware.
<path-to>/FVP_Base_AEMv8A-AEMv8A \
-C pctl.startup=0.0.0.0 \
@ -637,28 +659,14 @@ provide some helpful information if a secure memory violation occurs.
-C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
### Running on the Cortex-A57-A53 Base FVP
### Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
Please read "Notes regarding Base FVP configuration options" section above for
information about some of the options to run the software.
The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to
boot Linux with 8 CPUs using the ARM Trusted Firmware.
NOTE: Using `cache_state_modelled=1` makes booting very slow. The software will
still work (and run much faster) without this option but this will hide any
cache maintenance defects in the software.
NOTE: Using the `-C bp.virtioblockdevice.image_path` parameter is not necessary
if a Linux RAM-disk file-system is used (see the "Obtaining a root file-system"
section above).
NOTE: The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image
Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware"
section above).
NOTE: Setting the `-C bp.secure_memory` parameter to `1` is only supported on
FVP versions 5.4 and newer. Setting this parameter to `0` is also supported.
The `-C bp.tzc_400.diagnostics=1` parameter is optional. It instructs the FVP to
provide some helpful information if a secure memory violation occurs.
<path-to>/FVP_Base_Cortex-A57x4-A53x4 \
-C pctl.startup=0.0.0.0 \
-C bp.secure_memory=1 \
@ -669,6 +677,70 @@ provide some helpful information if a secure memory violation occurs.
-C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
### Running on the AEMv8 Base FVP with reset to BL3-1 entrypoint
Please read "Notes regarding Base FVP configuration options" section above for
information about some of the options to run the software.
The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
with 8 CPUs using the ARM Trusted Firmware.
NOTE: Uses the `-c clusterX.cpuX.RVBAR=@base address of BL3-1` where X is
the cluster number in clusterX and cpu number in cpuX is used to set the reset
vector for each core.
<path-to>/FVP_Base_AEMv8A-AEMv8A \
-C pctl.startup=0.0.0.0 \
-C bp.secure_memory=1 \
-C bp.tzc_400.diagnostics=1 \
-C cluster0.NUM_CORES=4 \
-C cluster1.NUM_CORES=4 \
-C cache_state_modelled=1 \
-C bp.pl011_uart0.untimed_fifos=1 \
-C cluster0.cpu0.RVBAR=0x04006000 \
-C cluster0.cpu1.RVBAR=0x04006000 \
-C cluster0.cpu2.RVBAR=0x04006000 \
-C cluster0.cpu3.RVBAR=0x04006000 \
-C cluster1.cpu0.RVBAR=0x04006000 \
-C cluster1.cpu1.RVBAR=0x04006000 \
-C cluster1.cpu2.RVBAR=0x04006000 \
-C cluster1.cpu3.RVBAR=0x04006000 \
--data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04006000 \
--data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04024000 \
--data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
### Running on the Cortex-A57-A53 Base FVP with reset to BL3-1 entrypoint
Please read "Notes regarding Base FVP configuration options" section above for
information about some of the options to run the software.
The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to
boot Linux with 8 CPUs using the ARM Trusted Firmware.
NOTE: Uses the `-c clusterX.cpuX.RVBARADDR=@base address of BL3-1` where X is
the cluster number in clusterX and cpu number in cpuX is used to set the reset
vector for each core.
<path-to>/FVP_Base_Cortex-A57x4-A53x4 \
-C pctl.startup=0.0.0.0 \
-C bp.secure_memory=1 \
-C bp.tzc_400.diagnostics=1 \
-C cache_state_modelled=1 \
-C bp.pl011_uart0.untimed_fifos=1 \
-C cluster0.cpu0.RVBARADDR=0x04006000 \
-C cluster0.cpu1.RVBARADDR=0x04006000 \
-C cluster0.cpu2.RVBARADDR=0x04006000 \
-C cluster0.cpu3.RVBARADDR=0x04006000 \
-C cluster1.cpu0.RVBARADDR=0x04006000 \
-C cluster1.cpu1.RVBARADDR=0x04006000 \
-C cluster1.cpu2.RVBARADDR=0x04006000 \
-C cluster1.cpu3.RVBARADDR=0x04006000 \
--data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04006000 \
--data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04024000 \
--data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
### Configuring the GICv2 memory map
The Base FVP models support GICv2 with the default model parameters at the

Loading…
Cancel
Save