~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorFerass El Hafidi <vitali64pmemail@protonmail.com>2023-05-08 19:03:10 +0200
committerFerass El Hafidi <vitali64pmemail@protonmail.com>2023-05-08 19:03:10 +0200
commitf9ed707f171c8069e99e24e24c3da73d8b6f5716 (patch)
tree4da9838d387c8bc260e83f3f51f5dfa83e0b48ae /docs
downloadamlogic-bl2-master.tar.gz
Push old Amlogic BL2 sourcesHEADmaster
Diffstat (limited to 'docs')
-rw-r--r--docs/change-log.md361
-rw-r--r--docs/diagrams/non-sec-int-handling.pngbin0 -> 249672 bytes
-rw-r--r--docs/diagrams/rt-svc-descs-layout.pngbin0 -> 77894 bytes
-rw-r--r--docs/diagrams/sec-int-handling.pngbin0 -> 191026 bytes
-rw-r--r--docs/firmware-design.md1313
-rw-r--r--docs/interrupt-framework-design.md848
-rw-r--r--docs/porting-guide.md1372
-rw-r--r--docs/rt-svc-writers-guide.md309
-rw-r--r--docs/user-guide.md841
9 files changed, 5044 insertions, 0 deletions
diff --git a/docs/change-log.md b/docs/change-log.md
new file mode 100644
index 0000000..c7ad084
--- /dev/null
+++ b/docs/change-log.md
@@ -0,0 +1,361 @@
+ARM Trusted Firmware - version 0.4
+==================================
+
+New features
+------------
+
+* Makefile improvements:
+
+ * Improved dependency checking when building.
+
+ * Removed `dump` target (build now always produces dump files).
+
+ * Enabled platform ports to optionally make use of parts of the Trusted
+ Firmware (e.g. BL3-1 only), rather than being forced to use all parts.
+ Also made the `fip` target optional.
+
+ * Specified the full path to source files and removed use of the `vpath`
+ keyword.
+
+* Provided translation table library code for potential re-use by platforms
+ other than the FVPs.
+
+* Moved architectural timer setup to platform-specific code.
+
+* Added standby state support to PSCI cpu_suspend implementation.
+
+* SRAM usage improvements:
+
+ * Started using the `-ffunction-sections`, `-fdata-sections` and
+ `--gc-sections` compiler/linker options to remove unused code and data
+ from the images. Previously, all common functions were being built into
+ all binary images, whether or not they were actually used.
+
+ * Placed all assembler functions in their own section to allow more unused
+ functions to be removed from images.
+
+ * Updated BL1 and BL2 to use a single coherent stack each, rather than one
+ per CPU.
+
+ * Changed variables that were unnecessarily declared and initialized as
+ non-const (i.e. in the .data section) so they are either uninitialized
+ (zero init) or const.
+
+* Moved the Test Secure-EL1 Payload (BL3-2) to execute in Trusted SRAM by
+ default. The option for it to run in Trusted DRAM remains.
+
+* Implemented a TrustZone Address Space Controller (TZC-400) driver. A
+ default configuration is provided for the Base FVPs. This means the model
+ parameter `-C bp.secure_memory=1` is now supported.
+
+* Started saving the PSCI cpu_suspend 'power_state' parameter prior to
+ suspending a CPU. This allows platforms that implement multiple power-down
+ states at the same affinity level to identify a specific state.
+
+* Refactored the entire codebase to reduce the amount of nesting in header
+ files and to make the use of system/user includes more consistent. Also
+ split platform.h to separate out the platform porting declarations from the
+ required platform porting definitions and the definitions/declarations
+ specific to the platform port.
+
+* Optimized the data cache clean/invalidate operations.
+
+* Improved the BL3-1 unhandled exception handling and reporting. Unhandled
+ exceptions now result in a dump of registers to the console.
+
+* Major rework to the handover interface between BL stages, in particular the
+ interface to BL3-1. The interface now conforms to a specification and is
+ more future proof.
+
+* Added support for optionally making the BL3-1 entrypoint a reset handler
+ (instead of BL1). This allows platforms with an alternative image loading
+ architecture to re-use BL3-1 with fewer modifications to generic code.
+
+* Reserved some DDR DRAM for secure use on FVP platforms to avoid future
+ compatibility problems with non-secure software.
+
+* Added support for secure interrupts targeting the Secure-EL1 Payload (SP)
+ (using GICv2 routing only). Demonstrated this working by adding an interrupt
+ target and supporting test code to the TSP. Also demonstrated non-secure
+ interrupt handling during TSP processing.
+
+
+Issues resolved since last release
+----------------------------------
+
+* Now support use of the model parameter `-C bp.secure_memory=1` in the Base
+ FVPs (see **New features**).
+
+* Support for secure world interrupt handling now available (see **New
+ features**).
+
+* Made enough SRAM savings (see **New features**) to enable the Test Secure-EL1
+ Payload (BL3-2) to execute in Trusted SRAM by default.
+
+* The tested filesystem used for this release (Linaro AArch64 OpenEmbedded
+ 14.04) now correctly reports progress in the console.
+
+* Improved the Makefile structure to make it easier to separate out parts of
+ the Trusted Firmware for re-use in platform ports. Also, improved target
+ dependency checking.
+
+
+Known issues
+------------
+
+* GICv3 support is experimental. The Linux kernel patches to support this are
+ not widely available. There are known issues with GICv3 initialization in
+ the ARM Trusted Firmware.
+
+* Dynamic image loading is not available yet. The current image loader
+ implementation (used to load BL2 and all subsequent images) has some
+ limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead
+ to loading errors, even if the images should theoretically fit in memory.
+
+* The ARM Trusted Firmware still uses too much on-chip Trusted SRAM. A number
+ of RAM usage enhancements have been identified to rectify this situation.
+
+* CPU idle does not work on the advertised version of the Foundation FVP.
+ Some FVP fixes are required that are not available externally at the time
+ of writing. This can be worked around by disabling CPU idle in the Linux
+ kernel.
+
+* Various bugs in ARM Trusted Firmware, UEFI and the Linux kernel have been
+ observed when using Linaro toolchain versions later than 13.11. Although
+ most of these have been fixed, some remain at the time of writing. These
+ mainly seem to relate to a subtle change in the way the compiler converts
+ between 64-bit and 32-bit values (e.g. during casting operations), which
+ reveals previously hidden bugs in client code.
+
+* The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
+ its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
+
+
+ARM Trusted Firmware - version 0.3
+==================================
+
+New features
+------------
+
+* Support for Foundation FVP Version 2.0 added.
+ The documented UEFI configuration disables some devices that are unavailable
+ in the Foundation FVP, including MMC and CLCD. The resultant UEFI binary can
+ be used on the AEMv8 and Cortex-A57-A53 Base FVPs, as well as the Foundation
+ FVP.
+
+ NOTE: The software will not work on Version 1.0 of the Foundation FVP.
+
+* Enabled third party contributions. Added a new contributing.md containing
+ instructions for how to contribute and updated copyright text in all files
+ to acknowledge contributors.
+
+* The PSCI CPU_SUSPEND API has been stabilised to the extent where it can be
+ used for entry into power down states with the following restrictions:
+ - Entry into standby states is not supported.
+ - The API is only supported on the AEMv8 and Cortex-A57-A53 Base FVPs.
+
+* The PSCI AFFINITY_INFO api has undergone limited testing on the Base FVPs to
+ allow experimental use.
+
+* Required C library and runtime header files are now included locally in ARM
+ Trusted Firmware instead of depending on the toolchain standard include
+ paths. The local implementation has been cleaned up and reduced in scope.
+
+* Added I/O abstraction framework, primarily to allow generic code to load
+ images in a platform-independent way. The existing image loading code has
+ been reworked to use the new framework. Semi-hosting and NOR flash I/O
+ drivers are provided.
+
+* Introduced Firmware Image Package (FIP) handling code and tools. A FIP
+ combines multiple firmware images with a Table of Contents (ToC) into a
+ single binary image. The new FIP driver is another type of I/O driver. The
+ Makefile builds a FIP by default and the FVP platform code expect to load a
+ FIP from NOR flash, although some support for image loading using semi-
+ hosting is retained.
+
+ NOTE: Building a FIP by default is a non-backwards-compatible change.
+
+ NOTE: Generic BL2 code now loads a BL3-3 (non-trusted firmware) image into
+ DRAM instead of expecting this to be pre-loaded at known location. This is
+ also a non-backwards-compatible change.
+
+ NOTE: Some non-trusted firmware (e.g. UEFI) will need to be rebuilt so that
+ it knows the new location to execute from and no longer needs to copy
+ particular code modules to DRAM itself.
+
+* Reworked BL2 to BL3-1 handover interface. A new composite structure
+ (bl31_args) holds the superset of information that needs to be passed from
+ BL2 to BL3-1, including information on how handover execution control to
+ BL3-2 (if present) and BL3-3 (non-trusted firmware).
+
+* Added library support for CPU context management, allowing the saving and
+ restoring of
+ - Shared system registers between Secure-EL1 and EL1.
+ - VFP registers.
+ - Essential EL3 system registers.
+
+* Added a framework for implementing EL3 runtime services. Reworked the PSCI
+ implementation to be one such runtime service.
+
+* Reworked the exception handling logic, making use of both SP_EL0 and SP_EL3
+ stack pointers for determining the type of exception, managing general
+ purpose and system register context on exception entry/exit, and handling
+ SMCs. SMCs are directed to the correct EL3 runtime service.
+
+* Added support for a Test Secure-EL1 Payload (TSP) and a corresponding
+ Dispatcher (TSPD), which is loaded as an EL3 runtime service. The TSPD
+ implements Secure Monitor functionality such as world switching and
+ EL1 context management, and is responsible for communication with the TSP.
+ NOTE: The TSPD does not yet contain support for secure world interrupts.
+ NOTE: The TSP/TSPD is not built by default.
+
+
+Issues resolved since last release
+----------------------------------
+
+* Support has been added for switching context between secure and normal
+ worlds in EL3.
+
+* PSCI API calls `AFFINITY_INFO` & `PSCI_VERSION` have now been tested (to
+ a limited extent).
+
+* The ARM Trusted Firmware build artifacts are now placed in the `./build`
+ directory and sub-directories instead of being placed in the root of the
+ project.
+
+* The ARM Trusted Firmware is now free from build warnings. Build warnings
+ are now treated as errors.
+
+* The ARM Trusted Firmware now provides C library support locally within the
+ project to maintain compatibility between toolchains/systems.
+
+* The PSCI locking code has been reworked so it no longer takes locks in an
+ incorrect sequence.
+
+* The RAM-disk method of loading a Linux file-system has been confirmed to
+ work with the ARM Trusted Firmware and Linux kernel version (based on
+ version 3.13) used in this release, for both Foundation and Base FVPs.
+
+
+Known issues
+------------
+
+The following is a list of issues which are expected to be fixed in the future
+releases of the ARM Trusted Firmware.
+
+* The TrustZone Address Space Controller (TZC-400) is not being programmed
+ yet. Use of model parameter `-C bp.secure_memory=1` is not supported.
+
+* No support yet for secure world interrupt handling.
+
+* GICv3 support is experimental. The Linux kernel patches to support this are
+ not widely available. There are known issues with GICv3 initialization in
+ the ARM Trusted Firmware.
+
+* Dynamic image loading is not available yet. The current image loader
+ implementation (used to load BL2 and all subsequent images) has some
+ limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead
+ to loading errors, even if the images should theoretically fit in memory.
+
+* The ARM Trusted Firmware uses too much on-chip Trusted SRAM. Currently the
+ Test Secure-EL1 Payload (BL3-2) executes in Trusted DRAM since there is not
+ enough SRAM. A number of RAM usage enhancements have been identified to
+ rectify this situation.
+
+* CPU idle does not work on the advertised version of the Foundation FVP.
+ Some FVP fixes are required that are not available externally at the time
+ of writing.
+
+* Various bugs in ARM Trusted Firmware, UEFI and the Linux kernel have been
+ observed when using Linaro toolchain versions later than 13.11. Although
+ most of these have been fixed, some remain at the time of writing. These
+ mainly seem to relate to a subtle change in the way the compiler converts
+ between 64-bit and 32-bit values (e.g. during casting operations), which
+ reveals previously hidden bugs in client code.
+
+* The tested filesystem used for this release (Linaro AArch64 OpenEmbedded
+ 14.01) does not report progress correctly in the console. It only seems to
+ produce error output, not standard output. It otherwise appears to function
+ correctly. Other filesystem versions on the same software stack do not
+ exhibit the problem.
+
+* The Makefile structure doesn't make it easy to separate out parts of the
+ Trusted Firmware for re-use in platform ports, for example if only BL3-1 is
+ required in a platform port. Also, dependency checking in the Makefile is
+ flawed.
+
+* The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
+ its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
+
+
+ARM Trusted Firmware - version 0.2
+==================================
+
+New features
+------------
+
+* First source release.
+
+* Code for the PSCI suspend feature is supplied, although this is not enabled
+ by default since there are known issues (see below).
+
+
+Issues resolved since last release
+----------------------------------
+
+* The "psci" nodes in the FDTs provided in this release now fully comply
+ with the recommendations made in the PSCI specification.
+
+
+Known issues
+------------
+
+The following is a list of issues which are expected to be fixed in the future
+releases of the ARM Trusted Firmware.
+
+* The TrustZone Address Space Controller (TZC-400) is not being programmed
+ yet. Use of model parameter `-C bp.secure_memory=1` is not supported.
+
+* No support yet for secure world interrupt handling or for switching context
+ between secure and normal worlds in EL3.
+
+* GICv3 support is experimental. The Linux kernel patches to support this are
+ not widely available. There are known issues with GICv3 initialization in
+ the ARM Trusted Firmware.
+
+* Dynamic image loading is not available yet. The current image loader
+ implementation (used to load BL2 and all subsequent images) has some
+ limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead
+ to loading errors, even if the images should theoretically fit in memory.
+
+* Although support for PSCI `CPU_SUSPEND` is present, it is not yet stable
+ and ready for use.
+
+* PSCI API calls `AFFINITY_INFO` & `PSCI_VERSION` are implemented but have not
+ been tested.
+
+* The ARM Trusted Firmware make files result in all build artifacts being
+ placed in the root of the project. These should be placed in appropriate
+ sub-directories.
+
+* The compilation of ARM Trusted Firmware is not free from compilation
+ warnings. Some of these warnings have not been investigated yet so they
+ could mask real bugs.
+
+* The ARM Trusted Firmware currently uses toolchain/system include files like
+ stdio.h. It should provide versions of these within the project to maintain
+ compatibility between toolchains/systems.
+
+* The PSCI code takes some locks in an incorrect sequence. This may cause
+ problems with suspend and hotplug in certain conditions.
+
+* The Linux kernel used in this release is based on version 3.12-rc4. Using
+ this kernel with the ARM Trusted Firmware fails to start the file-system as
+ a RAM-disk. It fails to execute user-space `init` from the RAM-disk. As an
+ alternative, the VirtioBlock mechanism can be used to provide a file-system
+ to the kernel.
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._
diff --git a/docs/diagrams/non-sec-int-handling.png b/docs/diagrams/non-sec-int-handling.png
new file mode 100644
index 0000000..1a5f629
--- /dev/null
+++ b/docs/diagrams/non-sec-int-handling.png
Binary files differ
diff --git a/docs/diagrams/rt-svc-descs-layout.png b/docs/diagrams/rt-svc-descs-layout.png
new file mode 100644
index 0000000..1a9fa5b
--- /dev/null
+++ b/docs/diagrams/rt-svc-descs-layout.png
Binary files differ
diff --git a/docs/diagrams/sec-int-handling.png b/docs/diagrams/sec-int-handling.png
new file mode 100644
index 0000000..2ebbca4
--- /dev/null
+++ b/docs/diagrams/sec-int-handling.png
Binary files differ
diff --git a/docs/firmware-design.md b/docs/firmware-design.md
new file mode 100644
index 0000000..1700007
--- /dev/null
+++ b/docs/firmware-design.md
@@ -0,0 +1,1313 @@
+ARM Trusted Firmware Design
+===========================
+
+Contents :
+
+1. Introduction
+2. Cold boot
+3. EL3 runtime services framework
+4. Power State Coordination Interface
+5. Secure-EL1 Payloads and Dispatchers
+6. Crash Reporting in BL3-1
+7. Memory layout on FVP platforms
+8. Firmware Image Package (FIP)
+9. Code Structure
+10. References
+
+
+1. Introduction
+----------------
+
+The ARM Trusted Firmware implements a subset of the Trusted Board Boot
+Requirements (TBBR) Platform Design Document (PDD) [1] for ARM reference
+platforms. The TBB sequence starts when the platform is powered on and runs up
+to the stage where it hands-off control to firmware running in the normal
+world in DRAM. This is the cold boot path.
+
+The ARM Trusted Firmware also implements the Power State Coordination Interface
+([PSCI]) PDD [2] as a runtime service. PSCI is the interface from normal world
+software to firmware implementing power management use-cases (for example,
+secondary CPU boot, hotplug and idle). Normal world software can access ARM
+Trusted Firmware runtime services via the ARM SMC (Secure Monitor Call)
+instruction. The SMC instruction must be used as mandated by the [SMC Calling
+Convention PDD][SMCCC] [3].
+
+The ARM Trusted Firmware implements a framework for configuring and managing
+interrupts generated in either security state. The details of the interrupt
+management framework and its design can be found in [ARM Trusted
+Firmware Interrupt Management Design guide][INTRG] [4].
+
+2. Cold boot
+-------------
+
+The cold boot path starts when the platform is physically turned on. One of
+the CPUs released from reset is chosen as the primary CPU, and the remaining
+CPUs are considered secondary CPUs. The primary CPU is chosen through
+platform-specific means. The cold boot path is mainly executed by the primary
+CPU, other than essential CPU initialization executed by all CPUs. The
+secondary CPUs are kept in a safe platform-specific state until the primary
+CPU has performed enough initialization to boot them.
+
+The cold boot path in this implementation of the ARM Trusted Firmware is divided
+into five steps (in order of execution):
+
+* Boot Loader stage 1 (BL1) _AP Trusted ROM_
+* Boot Loader stage 2 (BL2) _Trusted Boot Firmware_
+* Boot Loader stage 3-1 (BL3-1) _EL3 Runtime Firmware_
+* Boot Loader stage 3-2 (BL3-2) _Secure-EL1 Payload_ (optional)
+* Boot Loader stage 3-3 (BL3-3) _Non-trusted Firmware_
+
+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
+
+This stage begins execution from the platform's reset vector in trusted ROM at
+EL3. BL1 code starts at `0x00000000` (trusted ROM) in the FVP memory map. The
+BL1 data section is placed at the start of trusted SRAM, `0x04000000`. The
+functionality implemented by this stage is as follows.
+
+#### Determination of boot path
+
+Whenever a CPU is released from reset, BL1 needs to distinguish between a warm
+boot and a cold boot. This is done using a platform-specific mechanism. The
+ARM FVPs implement a simple power controller at `0x1c100000`. The `PSYS`
+register (`0x10`) is used to distinguish between a cold and warm boot. This
+information is contained in the `PSYS.WK[25:24]` field. Additionally, a
+per-CPU mailbox is maintained in trusted DRAM (`0x00600000`), to which BL1
+writes an entrypoint. Each CPU jumps to this entrypoint upon warm boot. During
+cold boot, BL1 places the secondary CPUs in a safe platform-specific state while
+the primary CPU executes the remaining cold boot path as described in the
+following sections.
+
+#### Architectural initialization
+
+BL1 performs minimal architectural initialization as follows.
+
+* Exception vectors
+
+ BL1 sets up simple exception vectors for both synchronous and asynchronous
+ exceptions. The default behavior upon receiving an exception is to set a
+ status code. In the case of the FVP this code is written to the Versatile
+ Express System LED register in the following format:
+
+ SYS_LED[0] - Security state (Secure=0/Non-Secure=1)
+ SYS_LED[2:1] - Exception Level (EL3=0x3, EL2=0x2, EL1=0x1, EL0=0x0)
+ SYS_LED[7:3] - Exception Class (Sync/Async & origin). The values for
+ each exception class are:
+
+ 0x0 : Synchronous exception from Current EL with SP_EL0
+ 0x1 : IRQ exception from Current EL with SP_EL0
+ 0x2 : FIQ exception from Current EL with SP_EL0
+ 0x3 : System Error exception from Current EL with SP_EL0
+ 0x4 : Synchronous exception from Current EL with SP_ELx
+ 0x5 : IRQ exception from Current EL with SP_ELx
+ 0x6 : FIQ exception from Current EL with SP_ELx
+ 0x7 : System Error exception from Current EL with SP_ELx
+ 0x8 : Synchronous exception from Lower EL using aarch64
+ 0x9 : IRQ exception from Lower EL using aarch64
+ 0xa : FIQ exception from Lower EL using aarch64
+ 0xb : System Error exception from Lower EL using aarch64
+ 0xc : Synchronous exception from Lower EL using aarch32
+ 0xd : IRQ exception from Lower EL using aarch32
+ 0xe : FIQ exception from Lower EL using aarch32
+ 0xf : System Error exception from Lower EL using aarch32
+
+ A write to the LED register reflects in the System LEDs (S6LED0..7) in the
+ CLCD window of the FVP. This behavior is because this boot loader stage
+ does not expect to receive any exceptions other than the SMC exception.
+ For the latter, BL1 installs a simple stub. The stub expects to receive
+ only a single type of SMC (determined by its function ID in the general
+ purpose register `X0`). This SMC is raised by BL2 to make BL1 pass control
+ to BL3-1 (loaded by BL2) at EL3. Any other SMC leads to an assertion
+ failure.
+
+* MMU setup
+
+ BL1 sets up EL3 memory translation by creating page tables to cover the
+ first 4GB of physical address space. This covers all the memories and
+ peripherals needed by BL1.
+
+* Control register setup
+ - `SCTLR_EL3`. Instruction cache is enabled by setting the `SCTLR_EL3.I`
+ bit. Alignment and stack alignment checking is enabled by setting the
+ `SCTLR_EL3.A` and `SCTLR_EL3.SA` bits. Exception endianness is set to
+ little-endian by clearing the `SCTLR_EL3.EE` bit.
+
+ - `CPUECTLR`. When the FVP includes a model of a specific ARM processor
+ implementation (for example A57 or A53), then intra-cluster coherency is
+ enabled by setting the `CPUECTLR.SMPEN` bit. The AEMv8 Base FVP is
+ inherently coherent so does not implement `CPUECTLR`.
+
+ - `SCR`. Use of the HVC instruction from EL1 is enabled by setting the
+ `SCR.HCE` bit. FIQ exceptions are configured to be taken in EL3 by
+ setting the `SCR.FIQ` bit. The register width of the next lower
+ exception level is set to AArch64 by setting the `SCR.RW` bit.
+
+ - `CPTR_EL3`. Accesses to the `CPACR_EL1` register from EL1 or EL2, or the
+ `CPTR_EL2` register from EL2 are configured to not trap to EL3 by
+ clearing the `CPTR_EL3.TCPAC` bit. Access to the trace functionality is
+ configured not to trap to EL3 by clearing the `CPTR_EL3.TTA` bit.
+ Instructions that access the registers associated with Floating Point
+ and Advanced SIMD execution are configured to not trap to EL3 by
+ clearing the `CPTR_EL3.TFP` bit.
+
+#### Platform initialization
+
+BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests from
+the CCI-400 slave interface corresponding to the cluster that includes the
+primary CPU. BL1 also initializes UART0 (PL011 console), which enables access to
+the `printf` family of functions in BL1.
+
+#### BL2 image load and execution
+
+BL1 execution continues as follows:
+
+1. BL1 determines the amount of free trusted SRAM memory available by
+ calculating the extent of its own data section, which also resides in
+ trusted SRAM. BL1 loads a BL2 raw binary image from platform storage, at a
+ platform-specific base address. If the BL2 image file is not present or if
+ there is not enough free trusted SRAM the following error message is
+ printed:
+
+ "Failed to load boot loader stage 2 (BL2) firmware."
+
+ If the load is successful, BL1 updates the limits of the remaining free
+ trusted SRAM. It also populates information about the amount of trusted
+ SRAM used by the BL2 image. The exact load location of the image is
+ provided as a base address in the platform header. Further description of
+ the memory layout can be found later in this document.
+
+2. BL1 prints the following string from the primary CPU to indicate successful
+ execution of the BL1 stage:
+
+ "Booting trusted firmware boot loader stage 1"
+
+3. BL1 passes control to the BL2 image at Secure EL1, starting from its load
+ address.
+
+4. BL1 also passes information about the amount of trusted SRAM used and
+ available for use. This information is populated at a platform-specific
+ memory address.
+
+
+### BL2
+
+BL1 loads and passes control to BL2 at Secure-EL1. BL2 is linked against and
+loaded at a platform-specific base address (more information can be found later
+in this document). The functionality implemented by BL2 is as follows.
+
+#### Architectural initialization
+
+BL2 performs minimal architectural initialization required for subsequent
+stages of the ARM Trusted Firmware and normal world software. It sets up
+Secure EL1 memory translation by creating page tables to address the first 4GB
+of the physical address space in a similar way to BL1. EL1 and EL0 are given
+access to Floating Point & Advanced SIMD registers by clearing the `CPACR.FPEN`
+bits.
+
+#### Platform initialization
+
+BL2 copies the information regarding the trusted SRAM populated by BL1 using a
+platform-specific mechanism. It calculates the limits of DRAM (main memory)
+to determine whether there is enough space to load the BL3-3 image. A platform
+defined base address is used to specify the load address for the BL3-1 image.
+It also defines the extents of memory available for use by the BL3-2 image.
+BL2 also initializes UART0 (PL011 console), which enables access to the
+`printf` family of functions in BL2. Platform security is initialized to allow
+access to access controlled components. On the Base FVP a TrustZone controller
+(TZC-400) is configured to give full access to the platform DRAM. The storage
+abstraction layer is initialized which is used to load further bootloader
+images.
+
+#### BL3-0 (System Control Processor Firmware) image load
+
+Some systems have a separate System Control Processor (SCP) for power, clock,
+reset and system control. BL2 loads the optional BL3-0 image from platform
+storage into a platform-specific region of secure memory. The subsequent
+handling of BL3-0 is platform specific. Typically the image is transferred into
+SCP memory using a platform-specific protocol. The SCP executes BL3-0 and
+signals to the Application Processor (AP) for BL2 execution to continue.
+
+#### BL3-1 (EL3 Runtime Firmware) image load
+
+BL2 loads the BL3-1 image from platform storage into a platform-specific address
+in trusted SRAM. If there is not enough memory to load the image or image is
+missing it leads to an assertion failure. If the BL3-1 image loads successfully,
+BL2 updates the amount of trusted SRAM used and available for use by BL3-1.
+This information is populated at a platform-specific memory address.
+
+#### BL3-2 (Secure-EL1 Payload) image load
+
+BL2 loads the optional BL3-2 image from platform storage into a platform-
+specific region of secure memory. The image executes in the secure world. BL2
+relies on BL3-1 to pass control to the BL3-2 image, if present. Hence, BL2
+populates a platform-specific area of memory with the entrypoint/load-address
+of the BL3-2 image. The value of the Saved Processor Status Register (`SPSR`)
+for entry into BL3-2 is not determined by BL2, it is initialized by the
+Secure-EL1 Payload Dispatcher (see later) within BL3-1, which is responsible for
+managing interaction with BL3-2. This information is passed to BL3-1.
+
+#### BL3-3 (Non-trusted Firmware) image load
+
+BL2 loads the BL3-3 image (e.g. UEFI or other test or boot software) from
+platform storage into non-secure memory as defined by the platform
+(`0x88000000` for FVPs).
+
+BL2 relies on BL3-1 to pass control to BL3-3 once secure state initialization is
+complete. Hence, BL2 populates a platform-specific area of memory with the
+entrypoint and Saved Program Status Register (`SPSR`) of the normal world
+software image. The entrypoint is the load address of the BL3-3 image. The
+`SPSR` is determined as specified in Section 5.13 of the [PSCI PDD] [PSCI]. This
+information is passed to BL3-1.
+
+#### BL3-1 (EL3 Runtime Firmware) execution
+
+BL2 execution continues as follows:
+
+1. BL2 passes control back to BL1 by raising an SMC, providing BL1 with the
+ BL3-1 entrypoint. The exception is handled by the SMC exception handler
+ installed by BL1.
+
+2. BL1 turns off the MMU and flushes the caches. It clears the
+ `SCTLR_EL3.M/I/C` bits, flushes the data cache to the point of coherency
+ and invalidates the TLBs.
+
+3. BL1 passes control to BL3-1 at the specified entrypoint at EL3.
+
+
+### BL3-1
+
+The image for this stage is loaded by BL2 and BL1 passes control to BL3-1 at
+EL3. BL3-1 executes solely in trusted SRAM. BL3-1 is linked against and
+loaded at a platform-specific base address (more information can be found later
+in this document). The functionality implemented by BL3-1 is as follows.
+
+#### Architectural initialization
+
+Currently, BL3-1 performs a similar architectural initialization to BL1 as
+far as system register settings are concerned. Since BL1 code resides in ROM,
+architectural initialization in BL3-1 allows override of any previous
+initialization done by BL1. BL3-1 creates page tables to address the first
+4GB of physical address space and initializes the MMU accordingly. It initializes
+a buffer of frequently used pointers, called per-cpu pointer cache, in memory for
+faster access. Currently the per-cpu pointer cache contains only the pointer
+to crash stack. It then replaces the exception vectors populated by BL1 with its
+own. BL3-1 exception vectors implement more elaborate support for
+handling SMCs since this is the only mechanism to access the runtime services
+implemented by BL3-1 (PSCI for example). BL3-1 checks each SMC for validity as
+specified by the [SMC calling convention PDD][SMCCC] before passing control to
+the required SMC handler routine. BL3-1 programs the `CNTFRQ_EL0` register with
+the clock frequency of the system counter, which is provided by the platform.
+
+#### Platform initialization
+
+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 UART0 (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.
+
+* GICv2 initialization:
+
+ - Enable group0 interrupts in the GIC CPU interface.
+ - Configure group0 interrupts to be asserted as FIQs.
+ - Disable the legacy interrupt bypass mechanism.
+ - Configure the priority mask register to allow interrupts of all
+ priorities to be signaled to the CPU interface.
+ - Mark SGIs 8-15, the secure physical timer interrupt (#29) and the
+ trusted watchdog interrupt (#56) as group0 (secure).
+ - Target the trusted watchdog interrupt to CPU0.
+ - Enable these group0 interrupts in the GIC distributor.
+ - Configure all other interrupts as group1 (non-secure).
+ - Enable signaling of group0 interrupts in the GIC distributor.
+
+* GICv3 initialization:
+
+ If a GICv3 implementation is available in the platform, BL3-1 initializes
+ the GICv3 in GICv2 emulation mode with settings as described for GICv2
+ above.
+
+* Power management initialization:
+
+ BL3-1 implements a state machine to track CPU and cluster state. The state
+ can be one of `OFF`, `ON_PENDING`, `SUSPEND` or `ON`. All secondary CPUs are
+ initially in the `OFF` state. The cluster that the primary CPU belongs to is
+ `ON`; any other cluster is `OFF`. BL3-1 initializes the data structures that
+ implement the state machine, including the locks that protect them. BL3-1
+ accesses the state of a CPU or cluster immediately after reset and before
+ the MMU is enabled in the warm boot path. It is not currently possible to
+ use 'exclusive' based spinlocks, therefore BL3-1 uses locks based on
+ Lamport's Bakery algorithm instead. BL3-1 allocates these locks in device
+ memory. They are accessible irrespective of MMU state.
+
+* Runtime services initialization:
+
+ The runtime service framework and its initialization is described in the
+ "EL3 runtime services framework" section below.
+
+ Details about the PSCI service are provided in the "Power State Coordination
+ Interface" section below.
+
+* BL3-2 (Secure-EL1 Payload) image initialization
+
+ If a BL3-2 image is present then there must be a matching Secure-EL1 Payload
+ Dispatcher (SPD) service (see later for details). During initialization
+ that service must register a function to carry out initialization of BL3-2
+ once the runtime services are fully initialized. BL3-1 invokes such a
+ registered function to initialize BL3-2 before running BL3-3.
+
+ Details on BL3-2 initialization and the SPD's role are described in the
+ "Secure-EL1 Payloads and Dispatchers" section below.
+
+* BL3-3 (Non-trusted Firmware) execution
+
+ BL3-1 initializes the EL2 or EL1 processor context for normal-world cold
+ boot, ensuring that no secure state information finds its way into the
+ non-secure execution state. BL3-1 uses the entrypoint information provided
+ by BL2 to jump to the Non-trusted firmware image (BL3-3) at the highest
+ 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
+----------------------------------
+
+Software executing in the non-secure state and in the secure state at exception
+levels lower than EL3 will request runtime services using the Secure Monitor
+Call (SMC) instruction. These requests will follow the convention described in
+the SMC Calling Convention PDD ([SMCCC]). The [SMCCC] assigns function
+identifiers to each SMC request and describes how arguments are passed and
+returned.
+
+The EL3 runtime services framework enables the development of services by
+different providers that can be easily integrated into final product firmware.
+The following sections describe the framework which facilitates the
+registration, initialization and use of runtime services in EL3 Runtime
+Firmware (BL3-1).
+
+The design of the runtime services depends heavily on the concepts and
+definitions described in the [SMCCC], in particular SMC Function IDs, Owning
+Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and SMC64 calling
+conventions. Please refer to that document for more detailed explanation of
+these terms.
+
+The following runtime services are expected to be implemented first. They have
+not all been instantiated in the current implementation.
+
+1. Standard service calls
+
+ This service is for management of the entire system. The Power State
+ Coordination Interface ([PSCI]) is the first set of standard service calls
+ defined by ARM (see PSCI section later).
+
+ NOTE: Currently this service is called PSCI since there are no other
+ defined standard service calls.
+
+2. Secure-EL1 Payload Dispatcher service
+
+ If a system runs a Trusted OS or other Secure-EL1 Payload (SP) then
+ it also requires a _Secure Monitor_ at EL3 to switch the EL1 processor
+ context between the normal world (EL1/EL2) and trusted world (Secure-EL1).
+ The Secure Monitor will make these world switches in response to SMCs. The
+ [SMCCC] provides for such SMCs with the Trusted OS Call and Trusted
+ Application Call OEN ranges.
+
+ The interface between the EL3 Runtime Firmware and the Secure-EL1 Payload is
+ not defined by the [SMCCC] or any other standard. As a result, each
+ Secure-EL1 Payload requires a specific Secure Monitor that runs as a runtime
+ service - within ARM Trusted Firmware this service is referred to as the
+ Secure-EL1 Payload Dispatcher (SPD).
+
+ ARM Trusted Firmware provides a Test Secure-EL1 Payload (TSP) and its
+ associated Dispatcher (TSPD). Details of SPD design and TSP/TSPD operation
+ are described in the "Secure-EL1 Payloads and Dispatchers" section below.
+
+3. CPU implementation service
+
+ This service will provide an interface to CPU implementation specific
+ services for a given platform e.g. access to processor errata workarounds.
+ This service is currently unimplemented.
+
+Additional services for ARM Architecture, SiP and OEM calls can be implemented.
+Each implemented service handles a range of SMC function identifiers as
+described in the [SMCCC].
+
+
+### Registration
+
+A runtime service is registered using the `DECLARE_RT_SVC()` macro, specifying
+the name of the service, the range of OENs covered, the type of service and
+initialization and call handler functions. This macro instantiates a `const
+struct rt_svc_desc` for the service with these details (see `runtime_svc.h`).
+This structure is allocated in a special ELF section `rt_svc_descs`, enabling
+the framework to find all service descriptors included into BL3-1.
+
+The specific service for a SMC Function is selected based on the OEN and call
+type of the Function ID, and the framework uses that information in the service
+descriptor to identify the handler for the SMC Call.
+
+The service descriptors do not include information to identify the precise set
+of SMC function identifiers supported by this service implementation, the
+security state from which such calls are valid nor the capability to support
+64-bit and/or 32-bit callers (using SMC32 or SMC64). Responding appropriately
+to these aspects of a SMC call is the responsibility of the service
+implementation, the framework is focused on integration of services from
+different providers and minimizing the time taken by the framework before the
+service handler is invoked.
+
+Details of the parameters, requirements and behavior of the initialization and
+call handling functions are provided in the following sections.
+
+
+### Initialization
+
+`runtime_svc_init()` in `runtime_svc.c` initializes the runtime services
+framework running on the primary CPU during cold boot as part of the BL3-1
+initialization. This happens prior to initializing a Trusted OS and running
+Normal world boot firmware that might in turn use these services.
+Initialization involves validating each of the declared runtime service
+descriptors, calling the service initialization function and populating the
+index used for runtime lookup of the service.
+
+The BL3-1 linker script collects all of the declared service descriptors into a
+single array and defines symbols that allow the framework to locate and traverse
+the array, and determine its size.
+
+The framework does basic validation of each descriptor to halt firmware
+initialization if service declaration errors are detected. The framework does
+not check descriptors for the following error conditions, and may behave in an
+unpredictable manner under such scenarios:
+
+1. Overlapping OEN ranges
+2. Multiple descriptors for the same range of OENs and `call_type`
+3. Incorrect range of owning entity numbers for a given `call_type`
+
+Once validated, the service `init()` callback is invoked. This function carries
+out any essential EL3 initialization before servicing requests. The `init()`
+function is only invoked on the primary CPU during cold boot. If the service
+uses per-CPU data this must either be initialized for all CPUs during this call,
+or be done lazily when a CPU first issues an SMC call to that service. If
+`init()` returns anything other than `0`, this is treated as an initialization
+error and the service is ignored: this does not cause the firmware to halt.
+
+The OEN and call type fields present in the SMC Function ID cover a total of
+128 distinct services, but in practice a single descriptor can cover a range of
+OENs, e.g. SMCs to call a Trusted OS function. To optimize the lookup of a
+service handler, the framework uses an array of 128 indices that map every
+distinct OEN/call-type combination either to one of the declared services or to
+indicate the service is not handled. This `rt_svc_descs_indices[]` array is
+populated for all of the OENs covered by a service after the service `init()`
+function has reported success. So a service that fails to initialize will never
+have it's `handle()` function invoked.
+
+The following figure shows how the `rt_svc_descs_indices[]` index maps the SMC
+Function ID call type and OEN onto a specific service handler in the
+`rt_svc_descs[]` array.
+
+![Image 1](diagrams/rt-svc-descs-layout.png?raw=true)
+
+
+### Handling an SMC
+
+When the EL3 runtime services framework receives a Secure Monitor Call, the SMC
+Function ID is passed in W0 from the lower exception level (as per the
+[SMCCC]). If the calling register width is AArch32, it is invalid to invoke an
+SMC Function which indicates the SMC64 calling convention: such calls are
+ignored and return the Unknown SMC Function Identifier result code `0xFFFFFFFF`
+in R0/X0.
+
+Bit[31] (fast/standard call) and bits[29:24] (owning entity number) of the SMC
+Function ID are combined to index into the `rt_svc_descs_indices[]` array. The
+resulting value might indicate a service that has no handler, in this case the
+framework will also report an Unknown SMC Function ID. Otherwise, the value is
+used as a further index into the `rt_svc_descs[]` array to locate the required
+service and handler.
+
+The service's `handle()` callback is provided with five of the SMC parameters
+directly, the others are saved into memory for retrieval (if needed) by the
+handler. The handler is also provided with an opaque `handle` for use with the
+supporting library for parameter retrieval, setting return values and context
+manipulation; and with `flags` indicating the security state of the caller. The
+framework finally sets up the execution stack for the handler, and invokes the
+services `handle()` function.
+
+On return from the handler the result registers are populated in X0-X3 before
+restoring the stack and CPU state and returning from the original SMC.
+
+
+4. Power State Coordination Interface
+--------------------------------------
+
+TODO: Provide design walkthrough of PSCI implementation.
+
+The complete PSCI API is not yet implemented. The following functions are
+currently implemented:
+
+- `PSCI_VERSION`
+- `CPU_OFF`
+- `CPU_ON`
+- `CPU_SUSPEND`
+- `AFFINITY_INFO`
+
+The `CPU_ON`, `CPU_OFF` and `CPU_SUSPEND` functions implement the warm boot
+path in ARM Trusted Firmware. `CPU_ON` and `CPU_OFF` have undergone testing
+on all the supported FVPs. `CPU_SUSPEND` & `AFFINITY_INFO` have undergone
+testing only on the AEM v8 Base FVP. Support for `AFFINITY_INFO` is still
+experimental. Support for `CPU_SUSPEND` is stable for entry into power down
+states. Standby states are currently not supported. `PSCI_VERSION` is
+present but completely untested in this version of the software.
+
+Unsupported PSCI functions can be divided into ones that can return
+execution to the caller and ones that cannot. The following functions
+return with a error code as documented in the [Power State Coordination
+Interface PDD] [PSCI].
+
+- `MIGRATE` : -1 (NOT_SUPPORTED)
+- `MIGRATE_INFO_TYPE` : 2 (Trusted OS is either not present or does not
+ require migration)
+- `MIGRATE_INFO_UP_CPU` : 0 (Return value is UNDEFINED)
+
+The following unsupported functions do not return and signal an assertion
+failure if invoked.
+
+- `SYSTEM_OFF`
+- `SYSTEM_RESET`
+
+
+5. Secure-EL1 Payloads and Dispatchers
+---------------------------------------
+
+On a production system that includes a Trusted OS running in Secure-EL1/EL0,
+the Trusted OS is coupled with a companion runtime service in the BL3-1
+firmware. This service is responsible for the initialisation of the Trusted
+OS and all communications with it. The Trusted OS is the BL3-2 stage of the
+boot flow in ARM Trusted Firmware. The firmware will attempt to locate, load
+and execute a BL3-2 image.
+
+ARM Trusted Firmware uses a more general term for the BL3-2 software that runs
+at Secure-EL1 - the _Secure-EL1 Payload_ - as it is not always a Trusted OS.
+
+The ARM Trusted Firmware provides a Test Secure-EL1 Payload (TSP) and a Test
+Secure-EL1 Payload Dispatcher (TSPD) service as an example of how a Trusted OS
+is supported on a production system using the Runtime Services Framework. On
+such a system, the Test BL3-2 image and service are replaced by the Trusted OS
+and its dispatcher service.
+
+The TSP runs in Secure-EL1. It is designed to demonstrate synchronous
+communication with the normal-world software running in EL1/EL2. Communication
+is initiated by the normal-world software
+
+* either directly through a Fast SMC (as defined in the [SMCCC])
+
+* or indirectly through a [PSCI] SMC. The [PSCI] implementation in turn
+ informs the TSPD about the requested power management operation. This allows
+ the TSP to prepare for or respond to the power state change
+
+The TSPD service is responsible for.
+
+* Initializing the TSP
+
+* Routing requests and responses between the secure and the non-secure
+ states during the two types of communications just described
+
+### Initializing a BL3-2 Image
+
+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. This is provided by:
+
+ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t);
+
+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
+that the SPD wants control to be passed to BL3-2 first and then later to BL3-3.
+
+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();
+
+and is registered using the `bl31_register_bl32_init()` function.
+
+Trusted Firmware supports two approaches for the SPD to pass control to BL3-2
+before returning through EL3 and running the non-trusted firmware (BL3-3):
+
+1. In the BL3-2 initialization function, set up a secure context (see below
+ for more details of CPU context support) for this CPU and use
+ `bl31_set_next_image_type()` to request that the exit from `bl31_main()` is
+ to the BL3-2 entrypoint in Secure-EL1.
+
+ When the BL3-2 has completed initialization at Secure-EL1, it returns to
+ BL3-1 by issuing an SMC, using a Function ID allocated to the SPD. On
+ receipt of this SMC, the SPD service handler should switch the CPU context
+ from trusted to normal world and use the `bl31_set_next_image_type()` and
+ `bl31_prepare_next_image_entry()` functions to set up the initial return to
+ the normal world firmware BL3-3. On return from the handler the framework
+ will exit to EL2 and run BL3-3.
+
+2. In the BL3-2 initialization function, use an SPD-defined mechanism to
+ invoke a 'world-switch synchronous call' to Secure-EL1 to run the BL3-2
+ entrypoint.
+ NOTE: The Test SPD service included with the Trusted Firmware provides one
+ implementation of such a mechanism.
+
+ On completion BL3-2 returns control to BL3-1 via a SMC, and on receipt the
+ SPD service handler invokes the synchronous call return mechanism to return
+ to the BL3-2 initialization function. On return from this function,
+ `bl31_main()` will set up the return to the normal world firmware BL3-3 and
+ continue the boot process in the normal world.
+
+6. Crash Reporting in BL3-1
+----------------------------------
+
+The BL3-1 implements a scheme for reporting the processor state when an unhandled
+exception is encountered. The reporting mechanism attempts to preserve all the
+register contents and report it via the default serial output. The general purpose
+registers, EL3, Secure EL1 and some EL2 state registers are reported.
+
+A dedicated per-cpu crash stack is maintained by BL3-1 and this is retrieved via
+the per-cpu pointer cache. The implementation attempts to minimise the memory
+required for this feature. The file `crash_reporting.S` contains the
+implementation for crash reporting.
+
+The sample crash output is shown below.
+
+ x0 :0x000000004F00007C
+ x1 :0x0000000007FFFFFF
+ x2 :0x0000000004014D50
+ x3 :0x0000000000000000
+ x4 :0x0000000088007998
+ x5 :0x00000000001343AC
+ x6 :0x0000000000000016
+ x7 :0x00000000000B8A38
+ x8 :0x00000000001343AC
+ x9 :0x00000000000101A8
+ x10 :0x0000000000000002
+ x11 :0x000000000000011C
+ x12 :0x00000000FEFDC644
+ x13 :0x00000000FED93FFC
+ x14 :0x0000000000247950
+ x15 :0x00000000000007A2
+ x16 :0x00000000000007A4
+ x17 :0x0000000000247950
+ x18 :0x0000000000000000
+ x19 :0x00000000FFFFFFFF
+ x20 :0x0000000004014D50
+ x21 :0x000000000400A38C
+ x22 :0x0000000000247950
+ x23 :0x0000000000000010
+ x24 :0x0000000000000024
+ x25 :0x00000000FEFDC868
+ x26 :0x00000000FEFDC86A
+ x27 :0x00000000019EDEDC
+ x28 :0x000000000A7CFDAA
+ x29 :0x0000000004010780
+ x30 :0x000000000400F004
+ scr_el3 :0x0000000000000D3D
+ sctlr_el3 :0x0000000000C8181F
+ cptr_el3 :0x0000000000000000
+ tcr_el3 :0x0000000080803520
+ daif :0x00000000000003C0
+ mair_el3 :0x00000000000004FF
+ spsr_el3 :0x00000000800003CC
+ elr_el3 :0x000000000400C0CC
+ ttbr0_el3 :0x00000000040172A0
+ esr_el3 :0x0000000096000210
+ sp_el3 :0x0000000004014D50
+ far_el3 :0x000000004F00007C
+ spsr_el1 :0x0000000000000000
+ elr_el1 :0x0000000000000000
+ spsr_abt :0x0000000000000000
+ spsr_und :0x0000000000000000
+ spsr_irq :0x0000000000000000
+ spsr_fiq :0x0000000000000000
+ sctlr_el1 :0x0000000030C81807
+ actlr_el1 :0x0000000000000000
+ cpacr_el1 :0x0000000000300000
+ csselr_el1 :0x0000000000000002
+ sp_el1 :0x0000000004028800
+ esr_el1 :0x0000000000000000
+ ttbr0_el1 :0x000000000402C200
+ ttbr1_el1 :0x0000000000000000
+ mair_el1 :0x00000000000004FF
+ amair_el1 :0x0000000000000000
+ tcr_el1 :0x0000000000003520
+ tpidr_el1 :0x0000000000000000
+ tpidr_el0 :0x0000000000000000
+ tpidrro_el0 :0x0000000000000000
+ dacr32_el2 :0x0000000000000000
+ ifsr32_el2 :0x0000000000000000
+ par_el1 :0x0000000000000000
+ far_el1 :0x0000000000000000
+ afsr0_el1 :0x0000000000000000
+ afsr1_el1 :0x0000000000000000
+ contextidr_el1 :0x0000000000000000
+ vbar_el1 :0x0000000004027000
+ cntp_ctl_el0 :0x0000000000000000
+ cntp_cval_el0 :0x0000000000000000
+ cntv_ctl_el0 :0x0000000000000000
+ cntv_cval_el0 :0x0000000000000000
+ cntkctl_el1 :0x0000000000000000
+ fpexc32_el2 :0x0000000004000700
+ sp_el0 :0x0000000004010780
+
+
+7. Memory layout on FVP platforms
+----------------------------------
+
+On FVP platforms, we use the Trusted ROM and Trusted SRAM to store the trusted
+firmware binaries. BL1 is originally sitting in the Trusted ROM at address
+`0x0`. Its read-write data are relocated at the base of the Trusted SRAM at
+runtime. BL1 loads BL2 image near the top of the trusted SRAM. BL2 loads BL3-1
+image between BL1 and BL2. Optionally, BL2 then loads the TSP as the BL3-2
+image. By default it is loaded in Trusted SRAM, in this case it sits between
+BL3-1 and BL2. This memory layout is illustrated by the following diagram.
+
+ Trusted SRAM
+ +----------+ 0x04040000
+ | |
+ |----------|
+ | BL2 |
+ |----------|
+ | |
+ |----------|
+ | BL32 | (optional)
+ |----------|
+ | |
+ |----------|
+ | BL31 |
+ |----------|
+ | |
+ |----------|
+ | BL1 (rw) |
+ +----------+ 0x04000000
+
+ Trusted ROM
+ +----------+ 0x04000000
+ | BL1 (ro) |
+ +----------+ 0x00000000
+
+The TSP image may be loaded in Trusted DRAM instead. This doesn't change the
+memory layout of the other boot loader images in Trusted SRAM.
+
+Although the goal at long term is to give complete flexibility over the memory
+layout, all platforms should conform to this layout at the moment. This is
+because of some limitations in the implementation of the image loader in the
+Trusted Firmware. Refer to the "Limitations of the image loader" section below.
+
+Each bootloader stage image layout is described by its own linker script. The
+linker scripts export some symbols into the program symbol table. Their values
+correspond to particular addresses. The trusted firmware code can refer to these
+symbols to figure out the image memory layout.
+
+Linker symbols follow the following naming convention in the trusted firmware.
+
+* `__<SECTION>_START__`
+
+ Start address of a given section named `<SECTION>`.
+
+* `__<SECTION>_END__`
+
+ End address of a given section named `<SECTION>`. If there is an alignment
+ constraint on the section's end address then `__<SECTION>_END__` corresponds
+ to the end address of the section's actual contents, rounded up to the right
+ boundary. Refer to the value of `__<SECTION>_UNALIGNED_END__` to know the
+ actual end address of the section's contents.
+
+* `__<SECTION>_UNALIGNED_END__`
+
+ End address of a given section named `<SECTION>` without any padding or
+ rounding up due to some alignment constraint.
+
+* `__<SECTION>_SIZE__`
+
+ Size (in bytes) of a given section named `<SECTION>`. If there is an
+ alignment constraint on the section's end address then `__<SECTION>_SIZE__`
+ corresponds to the size of the section's actual contents, rounded up to the
+ right boundary. In other words, `__<SECTION>_SIZE__ = __<SECTION>_END__ -
+ _<SECTION>_START__`. Refer to the value of `__<SECTION>_UNALIGNED_SIZE__`
+ to know the actual size of the section's contents.
+
+* `__<SECTION>_UNALIGNED_SIZE__`
+
+ Size (in bytes) of a given section named `<SECTION>` without any padding or
+ rounding up due to some alignment constraint. In other words,
+ `__<SECTION>_UNALIGNED_SIZE__ = __<SECTION>_UNALIGNED_END__ -
+ __<SECTION>_START__`.
+
+Some of the linker symbols are mandatory as the trusted firmware code relies on
+them to be defined. They are listed in the following subsections. Some of them
+must be provided for each bootloader stage and some are specific to a given
+bootloader stage.
+
+The linker scripts define some extra, optional symbols. They are not actually
+used by any code but they help in understanding the bootloader images' memory
+layout as they are easy to spot in the link map files.
+
+### Common linker symbols
+
+Early setup code needs to know the extents of the BSS section to zero-initialise
+it before executing any C code. The following linker symbols are defined for
+this purpose:
+
+* `__BSS_START__` This address must be aligned on a 16-byte boundary.
+* `__BSS_SIZE__`
+
+Similarly, the coherent memory section must be zero-initialised. Also, the MMU
+setup code needs to know the extents of this section to set the right memory
+attributes for it. The following linker symbols are defined for this purpose:
+
+* `__COHERENT_RAM_START__` This address must be aligned on a page-size boundary.
+* `__COHERENT_RAM_END__` This address must be aligned on a page-size boundary.
+* `__COHERENT_RAM_UNALIGNED_SIZE__`
+
+### BL1's linker symbols
+
+BL1's early setup code needs to know the extents of the .data section to
+relocate it from ROM to RAM before executing any C code. The following linker
+symbols are defined for this purpose:
+
+* `__DATA_ROM_START__` This address must be aligned on a 16-byte boundary.
+* `__DATA_RAM_START__` This address must be aligned on a 16-byte boundary.
+* `__DATA_SIZE__`
+
+BL1's platform setup code needs to know the extents of its read-write data
+region to figure out its memory layout. The following linker symbols are defined
+for this purpose:
+
+* `__BL1_RAM_START__` This is the start address of BL1 RW data.
+* `__BL1_RAM_END__` This is the end address of BL1 RW data.
+
+### BL2's, BL3-1's and TSP's linker symbols
+
+BL2, BL3-1 and TSP need to know the extents of their read-only section to set
+the right memory attributes for this memory region in their MMU setup code. The
+following linker symbols are defined for this purpose:
+
+* `__RO_START__`
+* `__RO_END__`
+
+### How to choose the right base addresses for each bootloader stage image
+
+There is currently no support for dynamic image loading in the Trusted Firmware.
+This means that all bootloader images need to be linked against their ultimate
+runtime locations and the base addresses of each image must be chosen carefully
+such that images don't overlap each other in an undesired way. As the code
+grows, the base addresses might need adjustments to cope with the new memory
+layout.
+
+The memory layout is completely specific to the platform and so there is no
+general recipe for choosing the right base addresses for each bootloader image.
+However, there are tools to aid in understanding the memory layout. These are
+the link map files: `build/<platform>/<build-type>/bl<x>/bl<x>.map`, with `<x>`
+being the stage bootloader. They provide a detailed view of the memory usage of
+each image. Among other useful information, they provide the end address of
+each image.
+
+* `bl1.map` link map file provides `__BL1_RAM_END__` address.
+* `bl2.map` link map file provides `__BL2_END__` address.
+* `bl31.map` link map file provides `__BL31_END__` address.
+* `bl32.map` link map file provides `__BL32_END__` address.
+
+For each bootloader image, the platform code must provide its start address
+as well as a limit address that it must not overstep. The latter is used in the
+linker scripts to check that the image doesn't grow past that address. If that
+happens, the linker will issue a message similar to the following:
+
+ aarch64-none-elf-ld: BLx has exceeded its limit.
+
+On FVP platforms, the base addresses have been chosen such that all images can
+reside concurrently in Trusted RAM without overlapping each other. Note that
+this is not a requirement, as not all images live in memory at the same time.
+For example, when the BL3-1 image takes over execution, BL1 and BL2 images are
+not needed anymore.
+
+### Limitations of the image loader
+
+The current implementation of the image loader can result in wasted space
+because of the simplified data structure used to represent the extents of free
+memory. For example, to load BL2 at address `0x0402D000`, the resulting memory
+layout should be as follows:
+
+ ------------ 0x04040000
+ | | <- Free space (1)
+ |----------|
+ | BL2 |
+ |----------| BL2_BASE (0x0402D000)
+ | | <- Free space (2)
+ |----------|
+ | BL1 |
+ ------------ 0x04000000
+
+In the current implementation, we need to specify whether BL2 is loaded at the
+top or bottom of the free memory. BL2 is top-loaded so in the example above,
+the free space (1) above BL2 is hidden, resulting in the following view of
+memory:
+
+ ------------ 0x04040000
+ | |
+ | |
+ | BL2 |
+ |----------| BL2_BASE (0x0402D000)
+ | | <- Free space (2)
+ |----------|
+ | BL1 |
+ ------------ 0x04000000
+
+BL3-1 is bottom-loaded above BL1. For example, if BL3-1 is bottom-loaded at
+`0x0400E000`, the memory layout should look like this:
+
+ ------------ 0x04040000
+ | |
+ | |
+ | BL2 |
+ |----------| BL2_BASE (0x0402D000)
+ | | <- Free space (2)
+ | |
+ |----------|
+ | |
+ | BL31 |
+ |----------| BL31_BASE (0x0400E000)
+ | | <- Free space (3)
+ |----------|
+ | BL1 |
+ ------------ 0x04000000
+
+But the free space (3) between BL1 and BL3-1 is wasted, resulting in the
+following view:
+
+ ------------ 0x04040000
+ | |
+ | |
+ | BL2 |
+ |----------| BL2_BASE (0x0402D000)
+ | | <- Free space (2)
+ | |
+ |----------|
+ | |
+ | |
+ | BL31 | BL31_BASE (0x0400E000)
+ | |
+ |----------|
+ | BL1 |
+ ------------ 0x04000000
+
+
+8. Firmware Image Package (FIP)
+--------------------------------
+
+Using a Firmware Image Package (FIP) allows for packing bootloader images (and
+potentially other payloads) into a single archive that can be loaded by the ARM
+Trusted Firmware from non-volatile platform storage. A driver to load images
+from a FIP has been added to the storage layer and allows a package to be read
+from supported platform storage. A tool to create Firmware Image Packages is
+also provided and described below.
+
+### Firmware Image Package layout
+
+The FIP layout consists of a table of contents (ToC) followed by payload data.
+The ToC itself has a header followed by one or more table entries. The ToC is
+terminated by an end marker entry. All ToC entries describe some payload data
+that has been appended to the end of the binary package. With the information
+provided in the ToC entry the corresponding payload data can be retrieved.
+
+ ------------------
+ | ToC Header |
+ |----------------|
+ | ToC Entry 0 |
+ |----------------|
+ | ToC Entry 1 |
+ |----------------|
+ | ToC End Marker |
+ |----------------|
+ | |
+ | Data 0 |
+ | |
+ |----------------|
+ | |
+ | Data 1 |
+ | |
+ ------------------
+
+The ToC header and entry formats are described in the header file
+`include/firmware_image_package.h`. This file is used by both the tool and the
+ARM Trusted firmware.
+
+The ToC header has the following fields:
+ `name`: The name of the ToC. This is currently used to validate the header.
+ `serial_number`: A non-zero number provided by the creation tool
+ `flags`: Flags associated with this data. None are yet defined.
+
+A ToC entry has the following fields:
+ `uuid`: All files are referred to by a pre-defined Universally Unique
+ IDentifier [UUID] . The UUIDs are defined in
+ `include/firmware_image_package`. The platform translates the requested
+ image name into the corresponding UUID when accessing the package.
+ `offset_address`: The offset address at which the corresponding payload data
+ can be found. The offset is calculated from the ToC base address.
+ `size`: The size of the corresponding payload data in bytes.
+ `flags`: Flags associated with this entry. Non are yet defined.
+
+### Firmware Image Package creation tool
+
+The FIP creation tool can be used to pack specified images into a binary package
+that can be loaded by the ARM Trusted Firmware from platform storage. The tool
+currently only supports packing bootloader images. Additional image definitions
+can be added to the tool as required.
+
+The tool can be found in `tools/fip_create`.
+
+### Loading from a Firmware Image Package (FIP)
+
+The Firmware Image Package (FIP) driver can load images from a binary package on
+non-volatile platform storage. For the FVPs this is currently NOR FLASH.
+
+Bootloader images are loaded according to the platform policy as specified in
+`plat/<platform>/plat_io_storage.c`. For the FVPs this means the platform will
+attempt to load images from a Firmware Image Package located at the start of NOR
+FLASH0.
+
+Currently the FVP's policy only allows loading of a known set of images. The
+platform policy can be modified to allow additional images.
+
+
+9. Code Structure
+------------------
+
+Trusted Firmware code is logically divided between the three boot loader
+stages mentioned in the previous sections. The code is also divided into the
+following categories (present as directories in the source code):
+
+* **Architecture specific.** This could be AArch32 or AArch64.
+* **Platform specific.** Choice of architecture specific code depends upon
+ the platform.
+* **Common code.** This is platform and architecture agnostic code.
+* **Library code.** This code comprises of functionality commonly used by all
+ other code.
+* **Stage specific.** Code specific to a boot stage.
+* **Drivers.**
+* **Services.** EL3 runtime services, e.g. PSCI or SPD. Specific SPD services
+ reside in the `services/spd` directory (e.g. `services/spd/tspd`).
+
+Each boot loader stage uses code from one or more of the above mentioned
+categories. Based upon the above, the code layout looks like this:
+
+ Directory Used by BL1? Used by BL2? Used by BL3-1?
+ bl1 Yes No No
+ bl2 No Yes No
+ bl31 No No Yes
+ arch Yes Yes Yes
+ plat Yes Yes Yes
+ drivers Yes No Yes
+ common Yes Yes Yes
+ lib Yes Yes Yes
+ services No No Yes
+
+All assembler files have the `.S` extension. The linker source files for each
+boot stage have the extension `.ld.S`. These are processed by GCC to create the
+linker scripts which have the extension `.ld`.
+
+FDTs provide a description of the hardware platform and are used by the Linux
+kernel at boot time. These can be found in the `fdts` directory.
+
+
+10. References
+--------------
+
+1. Trusted Board Boot Requirements CLIENT PDD (ARM DEN 0006B-5). Available
+ under NDA through your ARM account representative.
+
+2. [Power State Coordination Interface PDD (ARM DEN 0022B.b)][PSCI].
+
+3. [SMC Calling Convention PDD (ARM DEN 0028A)][SMCCC].
+
+4. [ARM Trusted Firmware Interrupt Management Design guide][INTRG].
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_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
+[INTRG]: ./interrupt-framework-design.md
diff --git a/docs/interrupt-framework-design.md b/docs/interrupt-framework-design.md
new file mode 100644
index 0000000..f96f764
--- /dev/null
+++ b/docs/interrupt-framework-design.md
@@ -0,0 +1,848 @@
+ARM Trusted Firmware Interrupt Management Design guide
+======================================================
+
+Contents :
+
+1. Introduction
+ * Assumptions
+ * Concepts
+ - Interrupt Types
+ - Routing Model
+ - Valid Routing Models
+ + Secure-EL1 Interrupts
+ + Non-secure Interrupts
+ - Mapping of Interrupt Type to Signal
+
+2. Interrupt Management
+ * Software Components
+ * Interrupt Registration
+ - EL3 Runtime Firmware
+ - Secure Payload Dispatcher
+ + Test Secure Payload Dispatcher behavior
+ - Secure Payload
+ + Secure Payload IHF design w.r.t Secure-EL1 interrupts
+ + Secure Payload IHF design w.r.t Non-secure interrupts
+ + Test Secure Payload behavior
+ * Interrupt Handling
+ - EL3 Runtime Firmware
+ - Secure Payload Dispatcher
+ + Interrupt Entry
+ + Interrupt Exit
+ + Test Secure Payload Dispatcher behavior
+ - Secure Payload
+ + Test Secure Payload behavior
+
+
+1. Introduction
+----------------
+This document describes the design of the Interrupt management framework in ARM
+Trusted Firmware. This section briefly describes the requirements from this
+framework. It also briefly explains some concepts and assumptions. They will
+help in understanding the implementation of the framework explained in
+subsequent sections.
+
+This framework is responsible for managing interrupts routed to EL3. It also
+allows EL3 software to configure the interrupt routing behavior. Its main
+objective is to implement the following two requirements.
+
+1. It should be possible to route interrupts meant to be handled by secure
+ software (Secure interrupts) to EL3, when execution is in non-secure state
+ (normal world). The framework should then take care of handing control of
+ the interrupt to either software in EL3 or Secure-EL1 depending upon the
+ software configuration and the GIC implementation. This requirement ensures
+ that secure interrupts are under the control of the secure software with
+ respect to their delivery and handling without the possibility of
+ intervention from non-secure software.
+
+2. It should be possible to route interrupts meant to be handled by
+ non-secure software (Non-secure interrupts) to the last executed exception
+ level in the normal world when the execution is in secure world at
+ exception levels lower than EL3. This could be done with or without the
+ knowledge of software executing in Secure-EL1/Secure-EL0. The choice of
+ approach should be governed by the secure software. This requirement
+ ensures that non-secure software is able to execute in tandem with the
+ secure software without overriding it.
+
+### 1.1 Assumptions
+The framework makes the following assumptions to simplify its implementation.
+
+1. All secure interrupts are handled in Secure-EL1. They can be delivered to
+ Secure-EL1 via EL3 but they cannot be handled in EL3. It will be possible
+ to extend the framework to handle secure interrupts in EL3 in the future.
+
+2. Interrupt exceptions (`PSTATE.I` and `F` bits) are masked during execution
+ in EL3.
+
+### 1.2 Concepts
+
+#### 1.2.1 Interrupt types
+The framework categorises an interrupt to be one of the following depending upon
+the exception level(s) it is handled in.
+
+1. Secure EL1 interrupt. This type of interrupt can be routed to EL3 or
+ Secure-EL1 depending upon the security state of the current execution
+ context. It is always handled in Secure-EL1.
+
+2. Non-secure interrupt. This type of interrupt can be routed to EL3,
+ Secure-EL1, Non-secure EL1 or EL2 depending upon the security state of the
+ current execution context. It is always handled in either Non-secure EL1
+ or EL2.
+
+3. EL3 interrupt. This type of interrupt can be routed to EL3 or Secure-EL1
+ depending upon the security state of the current execution context. It is
+ always handled in EL3.
+
+In the current implementation of the framework, all secure interrupts are
+treated as Secure EL1 interrupts. It will be possible for EL3 software to
+configure a secure interrupt as an EL3 interrupt in future implementations. The
+following constants define the various interrupt types in the framework
+implementation.
+
+ #define INTR_TYPE_S_EL1 0
+ #define INTR_TYPE_EL3 1
+ #define INTR_TYPE_NS 2
+
+
+#### 1.2.2 Routing model
+A type of interrupt can be either generated as an FIQ or an IRQ. The target
+exception level of an interrupt type is configured through the FIQ and IRQ bits
+in the Secure Configuration Register at EL3 (`SCR_EL3.FIQ` and `SCR_EL3.IRQ`
+bits). When `SCR_EL3.FIQ`=1, FIQs are routed to EL3. Otherwise they are routed
+to the First Exception Level (FEL) capable of handling interrupts. When
+`SCR_EL3.IRQ`=1, IRQs are routed to EL3. Otherwise they are routed to the
+FEL. This register is configured independently by EL3 software for each security
+state prior to entry into a lower exception level in that security state.
+
+A routing model for a type of interrupt (generated as FIQ or IRQ) is defined as
+its target exception level for each security state. It is represented by a
+single bit for each security state. A value of `0` means that the interrupt
+should be routed to the FEL. A value of `1` means that the interrupt should be
+routed to EL3. A routing model is applicable only when execution is not in EL3.
+
+The default routing model for an interrupt type is to route it to the FEL in
+either security state.
+
+#### 1.2.3 Valid routing models
+The framework considers certain routing models for each type of interrupt to be
+incorrect as they conflict with the requirements mentioned in Section 1. The
+following sub-sections describe all the possible routing models and specify
+which ones are valid or invalid. Only the Secure-EL1 and Non-secure interrupt
+types are considered as EL3 interrupts are currently unsupported (See 1.1). The
+terminology used in the following sub-sections is explained below.
+
+1. __CSS__. Current Security State. `0` when secure and `1` when non-secure
+
+2. __TEL3__. Target Exception Level 3. `0` when targeted to the FEL. `1` when
+ targeted to EL3.
+
+
+##### 1.2.3.1 Secure-EL1 interrupts
+
+1. __CSS=0, TEL3=0__. Interrupt is routed to the FEL when execution is in
+ secure state. This is a valid routing model as secure software is in
+ control of handling secure interrupts.
+
+2. __CSS=0, TEL3=1__. Interrupt is routed to EL3 when execution is in secure
+ state. This is a valid routing model as secure software in EL3 can
+ handover the interrupt to Secure-EL1 for handling.
+
+3. __CSS=1, TEL3=0__. Interrupt is routed to the FEL when execution is in
+ non-secure state. This is an invalid routing model as a secure interrupt
+ is not visible to the secure software which violates the motivation behind
+ the ARM Security Extensions.
+
+4. __CSS=1, TEL3=1__. Interrupt is routed to EL3 when execution is in secure
+ state. This is a valid routing model as secure software in EL3 can
+ handover the interrupt to Secure-EL1 for handling.
+
+
+##### 1.2.3.2 Non-secure interrupts
+
+1. __CSS=0, TEL3=0__. Interrupt is routed to the FEL when execution is in
+ secure state. This allows the secure software to trap non-secure
+ interrupts, perform its bookeeping and hand the interrupt to the
+ non-secure software through EL3. This is a valid routing model as secure
+ software is in control of how its execution is pre-empted by non-secure
+ interrupts.
+
+2. __CSS=0, TEL3=1__. Interrupt is routed to EL3 when execution is in secure
+ state. This is a valid routing model as secure software in EL3 can save
+ the state of software in Secure-EL1/Secure-EL0 before handing the
+ interrupt to non-secure software. This model requires additional
+ coordination between Secure-EL1 and EL3 software to ensure that the
+ former's state is correctly saved by the latter.
+
+3. __CSS=1, TEL3=0__. Interrupt is routed to FEL when execution is in
+ non-secure state. This is an valid routing model as a non-secure interrupt
+ is handled by non-secure software.
+
+4. __CSS=1, TEL3=1__. Interrupt is routed to EL3 when execution is in
+ non-secure state. This is an invalid routing model as there is no valid
+ reason to route the interrupt to EL3 software and then hand it back to
+ non-secure software for handling.
+
+
+#### 1.2.4 Mapping of interrupt type to signal
+The framework is meant to work with any interrupt controller implemented by a
+platform. A interrupt controller could generate a type of interrupt as either an
+FIQ or IRQ signal to the CPU depending upon the current security state.The
+mapping between the type and signal is known only to the platform. The framework
+uses this information to determine whether the IRQ or the FIQ bit should be
+programmed in `SCR_EL3` while applying the routing model for a type of
+interrupt. The platform provides this information through the
+`plat_interrupt_type_to_line()` API (described in the [Porting
+Guide]). For example, on the FVP port when the platform uses an ARM GICv2
+interrupt controller, Secure-EL1 interrupts are signalled through the FIQ signal
+while Non-secure interrupts are signalled through the IRQ signal. This applies
+when execution is in either security state.
+
+
+2. Interrupt management
+-----------------------
+The following sections describe how interrupts are managed by the interrupt
+handling framework. This entails:
+
+1. Providing an interface to allow registration of a handler and specification
+ of the routing model for a type of interrupt.
+
+2. Implementing support to hand control of an interrupt type to its registered
+ handler when the interrupt is generated.
+
+Both aspects of interrupt management involve various components in the secure
+software stack spanning from EL3 to Secure-EL1. These components are described
+in the section 2.1. The framework stores information associated with each type
+of interrupt in the following data structure.
+
+```
+typedef struct intr_type_desc {
+ interrupt_type_handler_t handler;
+ uint32_t flags;
+ uint32_t scr_el3[2];
+} intr_type_desc_t;
+```
+
+The `flags` field stores the routing model for the interrupt type in
+bits[1:0]. Bit[0] stores the routing model when execution is in the secure
+state. Bit[1] stores the routing model when execution is in the non-secure
+state. As mentioned in Section 1.2.2, a value of `0` implies that the interrupt
+should be targeted to the FEL. A value of `1` implies that it should be targeted
+to EL3. The remaining bits are reserved and SBZ. The helper macro
+`set_interrupt_rm_flag()` should be used to set the bits in the `flags`
+parameter.
+
+The `scr_el3[2]` field also stores the routing model but as a mapping of the
+model in the `flags` field to the corresponding bit in the `SCR_EL3` for each
+security state.
+
+The framework also depends upon the platform port to configure the interrupt
+controller to distinguish between secure and non-secure interrupts. The platform
+is expected to be aware of the secure devices present in the system and their
+associated interrupt numbers. It should configure the interrupt controller to
+enable the secure interrupts, ensure that their priority is always higher than
+the non-secure interrupts and target them to the primary CPU. It should also
+export the interface described in the the [Porting Guide][PRTG] to enable
+handling of interrupts.
+
+In the remainder of this document, for the sake of simplicity it is assumed that
+the FIQ signal is used to generate Secure-EL1 interrupts and the IRQ signal is
+used to generate non-secure interrupts in either security state.
+
+### 2.1 Software components
+Roles and responsibilities for interrupt management are sub-divided between the
+following components of software running in EL3 and Secure-EL1. Each component is
+briefly described below.
+
+1. EL3 Runtime Firmware. This component is common to all ports of the ARM
+ Trusted Firmware.
+
+2. Secure Payload Dispatcher (SPD) service. This service interfaces with the
+ Secure Payload (SP) software which runs in exception levels lower than EL3
+ i.e. Secure-EL1/Secure-EL0. It is responsible for switching execution
+ between software running in secure and non-secure states at exception
+ levels lower than EL3. A switch is triggered by a Secure Monitor Call from
+ either state. It uses the APIs exported by the Context management library
+ to implement this functionality. Switching execution between the two
+ security states is a requirement for interrupt management as well. This
+ results in a significant dependency on the SPD service. ARM Trusted
+ firmware implements an example Test Secure Payload Dispatcher (TSPD)
+ service.
+
+ An SPD service plugs into the EL3 runtime firmware and could be common to
+ some ports of the ARM Trusted Firmware.
+
+3. Secure Payload (SP). On a production system, the Secure Payload corresponds
+ to a Secure OS which runs in Secure-EL1/Secure-EL0. It interfaces with the
+ SPD service to manage communication with non-secure software. ARM Trusted
+ Firmware implements an example secure payload called Test Secure Payload
+ (TSP) which runs only in Secure-EL1.
+
+ A Secure payload implementation could be common to some ports of the ARM
+ Trusted Firmware just like the SPD service.
+
+
+### 2.2 Interrupt registration
+This section describes in detail the role of each software component (see 2.1)
+during the registration of a handler for an interrupt type.
+
+
+#### 2.2.1 EL3 runtime firmware
+This component declares the following prototype for a handler of an interrupt type.
+
+ typedef uint64_t (*interrupt_type_handler_t)(uint32_t id,
+ uint32_t flags,
+ void *handle,
+ void *cookie);
+
+The value of the `id` parameter depends upon the definition of the
+`IMF_READ_INTERRUPT_ID` build time flag. When the flag is defined, `id` contains
+the number of the highest priority pending interrupt of the type that this
+handler was registered for. When the flag is not defined `id` contains
+`INTR_ID_UNAVAILABLE`.
+
+The `flags` parameter contains miscellaneous information as follows.
+
+1. Security state, bit[0]. This bit indicates the security state of the lower
+ exception level when the interrupt was generated. A value of `1` means
+ that it was in the non-secure state. A value of `0` indicates that it was
+ in the secure state. This bit can be used by the handler to ensure that
+ interrupt was generated and routed as per the routing model specified
+ during registration.
+
+2. Reserved, bits[31:1]. The remaining bits are reserved for future use.
+
+The `handle` parameter points to the `cpu_context` structure of the current CPU
+for the security state specified in the `flags` parameter.
+
+Once the handler routine completes, execution will return to either the secure
+or non-secure state. The handler routine should return a pointer to
+`cpu_context` structure of the current CPU for the the target security state. It
+should treat all error conditions as critical errors and take appropriate action
+within its implementation e.g. use assertion failures.
+
+The runtime firmware provides the following API for registering a handler for a
+particular type of interrupt. A Secure Payload Dispatcher service should use
+this API to register a handler for Secure-EL1 and optionally for non-secure
+interrupts. This API also requires the caller to specify the routing model for
+the type of interrupt.
+
+ int32_t register_interrupt_type_handler(uint32_t type,
+ interrupt_type_handler handler,
+ uint64_t flags);
+
+
+The `type` parameter can be one of the three interrupt types listed above i.e.
+`INTR_TYPE_S_EL1`, `INTR_TYPE_NS` & `INTR_TYPE_EL3` (currently unimplemented).
+The `flags` parameter is as described in Section 2.
+
+The function will return `0` upon a successful registration. It will return
+`-EALREADY` in case a handler for the interrupt type has already been
+registered. If the `type` is unrecognised or the `flags` or the `handler` are
+invalid it will return `-EINVAL`. It will return `-ENOTSUP` if the specified
+`type` is not supported by the framework i.e. `INTR_TYPE_EL3`.
+
+Interrupt routing is governed by the configuration of the `SCR_EL3.FIQ/IRQ` bits
+prior to entry into a lower exception level in either security state. The
+context management library maintains a copy of the `SCR_EL3` system register for
+each security state in the `cpu_context` structure of each CPU. It exports the
+following APIs to let EL3 Runtime Firmware program and retrieve the routing
+model for each security state for the current CPU. The value of `SCR_EL3` stored
+in the `cpu_context` is used by the `el3_exit()` function to program the
+`SCR_EL3` register prior to returning from the EL3 exception level.
+
+ uint32_t cm_get_scr_el3(uint32_t security_state);
+ void cm_write_scr_el3_bit(uint32_t security_state,
+ uint32_t bit_pos,
+ uint32_t value);
+
+`cm_get_scr_el3()` returns the value of the `SCR_EL3` register for the specified
+security state of the current CPU. `cm_write_scr_el3()` writes a `0` or `1` to
+the bit specified by `bit_pos`. `register_interrupt_type_handler()` invokes
+`set_routing_model()` API which programs the `SCR_EL3` according to the routing
+model using the `cm_get_scr_el3()` and `cm_write_scr_el3_bit()` APIs.
+
+It is worth noting that in the current implementation of the framework, the EL3
+runtime firmware is responsible for programming the routing model. The SPD is
+responsible for ensuring that the routing model has been adhered to upon
+receiving an interrupt.
+
+#### 2.2.2 Secure payload dispatcher
+A SPD service is responsible for determining and maintaining the interrupt
+routing model supported by itself and the Secure Payload. It is also responsible
+for ferrying interrupts between secure and non-secure software depending upon
+the routing model. It could determine the routing model at build time or at
+runtime. It must use this information to register a handler for each interrupt
+type using the `register_interrupt_type_handler()` API in EL3 runtime firmware.
+
+If the routing model is not known to the SPD service at build time, then it must
+be provided by the SP as the result of its initialisation. The SPD should
+program the routing model only after SP initialisation has completed e.g. in the
+SPD initialisation function pointed to by the `bl32_init` variable.
+
+The SPD should determine the mechanism to pass control to the Secure Payload
+after receiving an interrupt from the EL3 runtime firmware. This information
+could either be provided to the SPD service at build time or by the SP at
+runtime.
+
+#### 2.2.2.1 Test secure payload dispatcher behavior
+The TSPD only handles Secure-EL1 interrupts and is provided with the following
+routing model at build time.
+
+* Secure-EL1 interrupts are routed to EL3 when execution is in non-secure
+ state and are routed to the FEL when execution is in the secure state
+ i.e __CSS=0, TEL3=0__ & __CSS=1, TEL3=1__ for Secure-EL1 interrupts
+
+* The default routing model is used for non-secure interrupts i.e they are
+ routed to the FEL in either security state i.e __CSS=0, TEL3=0__ &
+ __CSS=1, TEL3=0__ for Non-secure interrupts
+
+It performs the following actions in the `tspd_init()` function to fulfill the
+requirements mentioned earlier.
+
+1. It passes control to the Test Secure Payload to perform its
+ initialisation. The TSP provides the address of the vector table
+ `tsp_vectors` in the SP which also includes the handler for Secure-EL1
+ interrupts in the `fiq_entry` field. The TSPD passes control to the TSP at
+ this address when it receives a Secure-EL1 interrupt.
+
+ The handover agreement between the TSP and the TSPD requires that the TSPD
+ masks all interrupts (`PSTATE.DAIF` bits) when it calls
+ `tsp_fiq_entry()`. The TSP has to preserve the callee saved general
+ purpose, SP_EL1/Secure-EL0, LR, VFP and system registers. It can use
+ `x0-x18` to enable its C runtime.
+
+2. The TSPD implements a handler function for Secure-EL1 interrupts. It
+ registers it with the EL3 runtime firmware using the
+ `register_interrupt_type_handler()` API as follows
+
+ /* Forward declaration */
+ interrupt_type_handler tspd_secure_el1_interrupt_handler;
+ int32_t rc, flags = 0;
+ set_interrupt_rm_flag(flags, NON_SECURE);
+ rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+ tspd_secure_el1_interrupt_handler,
+ flags);
+ assert(rc == 0);
+
+#### 2.2.3 Secure payload
+A Secure Payload must implement an interrupt handling framework at Secure-EL1
+(Secure-EL1 IHF) to support its chosen interrupt routing model. Secure payload
+execution will alternate between the below cases.
+
+1. In the code where IRQ, FIQ or both interrupts are enabled, if an interrupt
+ type is targeted to the FEL, then it will be routed to the Secure-EL1
+ exception vector table. This is defined as the asynchronous model of
+ handling interrupts. This mode applies to both Secure-EL1 and non-secure
+ interrupts.
+
+2. In the code where both interrupts are disabled, if an interrupt type is
+ targeted to the FEL, then execution will eventually migrate to the
+ non-secure state. Any non-secure interrupts will be handled as described
+ in the routing model where __CSS=1 and TEL3=0__. Secure-EL1 interrupts
+ will be routed to EL3 (as per the routing model where __CSS=1 and
+ TEL3=1__) where the SPD service will hand them to the SP. This is defined
+ as the synchronous mode of handling interrupts.
+
+The interrupt handling framework implemented by the SP should support one or
+both these interrupt handling models depending upon the chosen routing model.
+
+The following list briefly describes how the choice of a valid routing model
+(See 1.2.3) effects the implementation of the Secure-EL1 IHF. If the choice of
+the interrupt routing model is not known to the SPD service at compile time,
+then the SP should pass this information to the SPD service at runtime during
+its initialisation phase.
+
+As mentioned earlier, it is assumed that the FIQ signal is used to generate
+Secure-EL1 interrupts and the IRQ signal is used to generate non-secure
+interrupts in either security state.
+
+##### 2.2.3.1 Secure payload IHF design w.r.t secure-EL1 interrupts
+1. __CSS=0, TEL3=0__. If `PSTATE.F=0`, Secure-EL1 interrupts will be
+ trigerred at one of the Secure-EL1 FIQ exception vectors. The Secure-EL1
+ IHF should implement support for handling FIQ interrupts asynchronously.
+
+ If `PSTATE.F=1` then Secure-EL1 interrupts will be handled as per the
+ synchronous interrupt handling model. The SP could implement this scenario
+ by exporting a seperate entrypoint for Secure-EL1 interrupts to the SPD
+ service during the registration phase. The SPD service would also need to
+ know the state of the system, general purpose and the `PSTATE` registers
+ in which it should arrange to return execution to the SP. The SP should
+ provide this information in an implementation defined way during the
+ registration phase if it is not known to the SPD service at build time.
+
+2. __CSS=1, TEL3=1__. Interrupts are routed to EL3 when execution is in
+ non-secure state. They should be handled through the synchronous interrupt
+ handling model as described in 1. above.
+
+3. __CSS=0, TEL3=1__. Secure interrupts are routed to EL3 when execution is in
+ secure state. They will not be visible to the SP. The `PSTATE.F` bit in
+ Secure-EL1/Secure-EL0 will not mask FIQs. The EL3 runtime firmware will
+ call the handler registered by the SPD service for Secure-EL1
+ interrupts. Secure-EL1 IHF should then handle all Secure-EL1 interrupt
+ through the synchronous interrupt handling model described in 1. above.
+
+
+##### 2.2.3.2 Secure payload IHF design w.r.t non-secure interrupts
+1. __CSS=0, TEL3=0__. If `PSTATE.I=0`, non-secure interrupts will be
+ trigerred at one of the Secure-EL1 IRQ exception vectors . The Secure-EL1
+ IHF should co-ordinate with the SPD service to transfer execution to the
+ non-secure state where the interrupt should be handled e.g the SP could
+ allocate a function identifier to issue a SMC64 or SMC32 to the SPD
+ service which indicates that the SP execution has been pre-empted by a
+ non-secure interrupt. If this function identifier is not known to the SPD
+ service at compile time then the SP could provide it during the
+ registration phase.
+
+ If `PSTATE.I=1` then the non-secure interrupt will pend until execution
+ resumes in the non-secure state.
+
+2. __CSS=0, TEL3=1__. Non-secure interrupts are routed to EL3. They will not
+ be visible to the SP. The `PSTATE.I` bit in Secure-EL1/Secure-EL0 will
+ have not effect. The SPD service should register a non-secure interrupt
+ handler which should save the SP state correctly and resume execution in
+ the non-secure state where the interrupt will be handled. The Secure-EL1
+ IHF does not need to take any action.
+
+3. __CSS=1, TEL3=0__. Non-secure interrupts are handled in the FEL in
+ non-secure state (EL1/EL2) and are not visible to the SP. This routing
+ model does not affect the SP behavior.
+
+
+A Secure Payload must also ensure that all Secure-EL1 interrupts are correctly
+configured at the interrupt controller by the platform port of the EL3 runtime
+firmware. It should configure any additional Secure-EL1 interrupts which the EL3
+runtime firmware is not aware of through its platform port.
+
+#### 2.2.3.3 Test secure payload behavior
+The routing model for Secure-EL1 and non-secure interrupts chosen by the TSP is
+described in Section 2.2.2. It is known to the TSPD service at build time.
+
+The TSP implements an entrypoint (`tsp_fiq_entry()`) for handling Secure-EL1
+interrupts taken in non-secure state and routed through the TSPD service
+(synchronous handling model). It passes the reference to this entrypoint via
+`tsp_vectors` to the TSPD service.
+
+The TSP also replaces the default exception vector table referenced through the
+`early_exceptions` variable, with a vector table capable of handling FIQ and IRQ
+exceptions taken at the same (Secure-EL1) exception level. This table is
+referenced through the `tsp_exceptions` variable and programmed into the
+VBAR_EL1. It caters for the asynchronous handling model.
+
+The TSP also programs the Secure Physical Timer in the ARM Generic Timer block
+to raise a periodic interrupt (every half a second) for the purpose of testing
+interrupt management across all the software components listed in 2.1
+
+
+### 2.3 Interrupt handling
+This section describes in detail the role of each software component (see
+Section 2.1) in handling an interrupt of a particular type.
+
+#### 2.3.1 EL3 runtime firmware
+The EL3 runtime firmware populates the IRQ and FIQ exception vectors referenced
+by the `runtime_exceptions` variable as follows.
+
+1. IRQ and FIQ exceptions taken from the current exception level with
+ `SP_EL0` or `SP_EL3` are reported as irrecoverable error conditions. As
+ mentioned earlier, EL3 runtime firmware always executes with the
+ `PSTATE.I` and `PSTATE.F` bits set.
+
+2. The following text describes how the IRQ and FIQ exceptions taken from a
+ lower exception level using AArch64 or AArch32 are handled.
+
+When an interrupt is generated, the vector for each interrupt type is
+responsible for:
+
+1. Saving the entire general purpose register context (x0-x30) immediately
+ upon exception entry. The registers are saved in the per-cpu `cpu_context`
+ data structure referenced by the `SP_EL3`register.
+
+2. Saving the `ELR_EL3`, `SP_EL0` and `SPSR_EL3` system registers in the
+ per-cpu `cpu_context` data structure referenced by the `SP_EL3` register.
+
+3. Switching to the C runtime stack by restoring the `CTX_RUNTIME_SP` value
+ from the per-cpu `cpu_context` data structure in `SP_EL0` and
+ executing the `msr spsel, #0` instruction.
+
+4. Determining the type of interrupt. Secure-EL1 interrupts will be signalled
+ at the FIQ vector. Non-secure interrupts will be signalled at the IRQ
+ vector. The platform should implement the following API to determine the
+ type of the pending interrupt.
+
+ uint32_t plat_ic_get_interrupt_type(void);
+
+ It should return either `INTR_TYPE_S_EL1` or `INTR_TYPE_NS`.
+
+5. Determining the handler for the type of interrupt that has been generated.
+ The following API has been added for this purpose.
+
+ interrupt_type_handler get_interrupt_type_handler(uint32_t interrupt_type);
+
+ It returns the reference to the registered handler for this interrupt
+ type. The `handler` is retrieved from the `intr_type_desc_t` structure as
+ described in Section 2. `NULL` is returned if no handler has been
+ registered for this type of interrupt. This scenario is reported as an
+ irrecoverable error condition.
+
+6. Calling the registered handler function for the interrupt type generated.
+ The firmware also determines the interrupt id if the IMF_READ_INTERRUPT_ID
+ build time flag is set. The id is set to `INTR_ID_UNAVAILABLE` if the flag
+ is not set. The id along with the current security state and a reference to
+ the `cpu_context_t` structure for the current security state are passed to
+ the handler function as its arguments.
+
+ The handler function returns a reference to the per-cpu `cpu_context_t`
+ structure for the target security state.
+
+7. Calling `el3_exit()` to return from EL3 into a lower exception level in
+ the security state determined by the handler routine. The `el3_exit()`
+ function is responsible for restoring the register context from the
+ `cpu_context_t` data structure for the target security state.
+
+
+#### 2.3.2 Secure payload dispatcher
+
+##### 2.3.2.1 Interrupt entry
+The SPD service begins handling an interrupt when the EL3 runtime firmware calls
+the handler function for that type of interrupt. The SPD service is responsible
+for the following:
+
+1. Validating the interrupt. This involves ensuring that the interrupt was
+ generating according to the interrupt routing model specified by the SPD
+ service during registration. It should use the interrupt id and the
+ security state of the exception level (passed in the `flags` parameter of
+ the handler) where the interrupt was taken from to determine this. If the
+ interrupt is not recognised then the handler should treat it as an
+ irrecoverable error condition.
+
+ A SPD service can register a handler for Secure-EL1 and/or Non-secure
+ interrupts. The following text describes further error scenarios keeping
+ this in mind:
+
+ 1. __SPD service has registered a handler for Non-secure interrupts__:
+ When an interrupt is received by the handler, it could check its id
+ to ensure it has been configured as a non-secure interrupt at the
+ interrupt controller. A secure interrupt should never be handed to
+ the non-secure interrupt handler. A non-secure interrupt should
+ never be routed to EL3 when execution is in non-secure state. The
+ handler could check the security state flag to ensure this.
+
+ 2. __SPD service has registered a handler for Secure-EL1 interrupts__:
+ When an interrupt is received by the handler, it could check its id
+ to ensure it has been configured as a secure interrupt at the
+ interrupt controller. A non-secure interrupt should never be handed
+ to the secure interrupt handler. If the routing model chosen is such
+ that Secure-EL1 interrupts are not routed to EL3 when execution is
+ in non-secure state, then a Secure-EL1 interrupt generated in the
+ secure state would be invalid. The handler could use the security
+ state flag to check this.
+
+ The SPD service should use the platform API:
+ `plat_ic_get_interrupt_type()` to determine the type of interrupt for the
+ specified id.
+
+2. Determining whether the security state of the exception level for handling
+ the interrupt is the same as the security state of the exception level
+ where the interrupt was generated. This depends upon the routing model and
+ type of the interrupt. The SPD should use this information to determine if
+ a context switch is required. The following two cases would require a
+ context switch from secure to non-secure or vice-versa.
+
+ 1. A Secure-EL1 interrupt taken from the non-secure state should be
+ routed to the Secure Payload.
+
+ 2. A non-secure interrupt taken from the secure state should be routed
+ to the last known non-secure exception level.
+
+ The SPD service must save the system register context of the current
+ security state. It must then restore the system register context of the
+ target security state. It should use the `cm_set_next_eret_context()` API
+ to ensure that the next `cpu_context` to be restored is of the target
+ security state.
+
+ If the target state is secure then execution should be handed to the SP as
+ per the synchronous interrupt handling model it implements. A Secure-EL1
+ interrupt can be routed to EL3 while execution is in the SP. This implies
+ that SP execution can be preempted while handling an interrupt by a
+ another higher priority Secure-EL1 interrupt (or a EL3 interrupt in the
+ future). The SPD service should manage secure interrupt priorities before
+ handing control to the SP to prevent this type of preemption which can
+ leave the system in an inconsistent state.
+
+3. Setting the return value of the handler to the per-cpu `cpu_context` if
+ the interrupt has been successfully validated and ready to be handled at a
+ lower exception level.
+
+The routing model allows non-secure interrupts to be taken to Secure-EL1 when in
+secure state. The SPD service and the SP should implement a mechanism for
+routing these interrupts to the last known exception level in the non-secure
+state. The former should save the SP context, restore the non-secure context and
+arrange for entry into the non-secure state so that the interrupt can be
+handled.
+
+##### 2.3.2.2 Interrupt exit
+When the Secure Payload has finished handling a Secure-EL1 interrupt, it could
+return control back to the SPD service through a SMC32 or SMC64. The SPD service
+should handle this secure monitor call so that execution resumes in the
+exception level and the security state from where the Secure-EL1 interrupt was
+originally taken.
+
+##### 2.3.2.1 Test secure payload dispatcher behavior
+The example TSPD service registers a handler for Secure-EL1 interrupts taken
+from the non-secure state. Its handler `tspd_secure_el1_interrupt_handler()`
+takes the following actions upon being invoked.
+
+1. It uses the `id` parameter to query the interrupt controller to ensure
+ that the interrupt is a Secure-EL1 interrupt. It asserts if this is not
+ the case.
+
+2. It uses the security state provided in the `flags` parameter to ensure
+ that the secure interrupt originated from the non-secure state. It asserts
+ if this is not the case.
+
+3. It saves the system register context for the non-secure state by calling
+ `cm_el1_sysregs_context_save(NON_SECURE);`.
+
+4. It sets the `ELR_EL3` system register to `tsp_fiq_entry` and sets the
+ `SPSR_EL3.DAIF` bits in the secure CPU context. It sets `x0` to
+ `TSP_HANDLE_FIQ_AND_RETURN`. If the TSP was in the middle of handling a
+ standard SMC, then the `ELR_EL3` and `SPSR_EL3` registers in the secure CPU
+ context are saved first.
+
+5. It restores the system register context for the secure state by calling
+ `cm_el1_sysregs_context_restore(SECURE);`.
+
+6. It ensures that the secure CPU context is used to program the next
+ exception return from EL3 by calling `cm_set_next_eret_context(SECURE);`.
+
+7. It returns the per-cpu `cpu_context` to indicate that the interrupt can
+ now be handled by the SP. `x1` is written with the value of `elr_el3`
+ register for the non-secure state. This information is used by the SP for
+ debugging purposes.
+
+The figure below describes how the interrupt handling is implemented by the TSPD
+when a Secure-EL1 interrupt is generated when execution is in the non-secure
+state.
+
+![Image 1](diagrams/sec-int-handling.png?raw=true)
+
+The TSP issues an SMC with `TSP_HANDLED_S_EL1_FIQ` as the function identifier to
+signal completion of interrupt handling.
+
+The TSP issues an SMC with `TSP_PREEMPTED` as the function identifier to signal
+generation of a non-secure interrupt in Secure-EL1.
+
+The TSPD service takes the following actions in `tspd_smc_handler()` function
+upon receiving an SMC with `TSP_HANDLED_S_EL1_FIQ` and `TSP_PREEMPTED` as the
+function identifiers:
+
+1. It ensures that the call originated from the secure state otherwise
+ execution returns to the non-secure state with `SMC_UNK` in `x0`.
+
+2. If the function identifier is `TSP_HANDLED_S_EL1_FIQ`, it restores the
+ saved `ELR_EL3` and `SPSR_EL3` system registers back to the secure CPU
+ context (see step 4 above) in case the TSP had been preempted by a non
+ secure interrupt earlier. It does not save the secure context since the
+ TSP is expected to preserve it (see Section 2.2.2.1)
+
+3. If the function identifier is `TSP_PREEMPTED`, it saves the system
+ register context for the secure state by calling
+ `cm_el1_sysregs_context_save(SECURE)`.
+
+4. It restores the system register context for the non-secure state by
+ calling `cm_el1_sysregs_context_restore(NON_SECURE)`. It sets `x0` to
+ `SMC_PREEMPTED` if the incoming function identifier is
+ `TSP_PREEMPTED`. The Normal World is expected to resume the TSP after the
+ non-secure interrupt handling by issuing an SMC with `TSP_FID_RESUME` as
+ the function identifier.
+
+5. It ensures that the non-secure CPU context is used to program the next
+ exception return from EL3 by calling
+ `cm_set_next_eret_context(NON_SECURE)`.
+
+6. `tspd_smc_handler()` returns a reference to the non-secure `cpu_context`
+ as the return value.
+
+As mentioned in 4. above, if a non-secure interrupt preempts the TSP execution
+then the non-secure software issues an SMC with `TSP_FID_RESUME` as the function
+identifier to resume TSP execution. The TSPD service takes the following actions
+in `tspd_smc_handler()` function upon receiving this SMC:
+
+1. It ensures that the call originated from the non secure state. An
+ assertion is raised otherwise.
+
+2. Checks whether the TSP needs a resume i.e check if it was preempted. It
+ then saves the system register context for the secure state by calling
+ `cm_el1_sysregs_context_save(NON_SECURE)`.
+
+3. Restores the secure context by calling
+ `cm_el1_sysregs_context_restore(SECURE)`
+
+4. It ensures that the secure CPU context is used to program the next
+ exception return from EL3 by calling `cm_set_next_eret_context(SECURE)`.
+
+5. `tspd_smc_handler()` returns a reference to the secure `cpu_context` as the
+ return value.
+
+The figure below describes how the TSP/TSPD handle a non-secure interrupt when
+it is generated during execution in the TSP with `PSTATE.I` = 0.
+
+![Image 2](diagrams/non-sec-int-handling.png?raw=true)
+
+
+#### 2.3.3 Secure payload
+The SP should implement one or both of the synchronous and asynchronous
+interrupt handling models depending upon the interrupt routing model it has
+chosen (as described in 2.2.3).
+
+In the synchronous model, it should begin handling a Secure-EL1 interrupt after
+receiving control from the SPD service at an entrypoint agreed upon during build
+time or during the registration phase. Before handling the interrupt, the SP
+should save any Secure-EL1 system register context which is needed for resuming
+normal execution in the SP later e.g. `SPSR_EL1, `ELR_EL1`. After handling the
+interrupt, the SP could return control back to the exception level and security
+state where the interrupt was originally taken from. The SP should use an SMC32
+or SMC64 to ask the SPD service to do this.
+
+In the asynchronous model, the Secure Payload is responsible for handling
+non-secure and Secure-EL1 interrupts at the IRQ and FIQ vectors in its exception
+vector table when `PSTATE.I` and `PSTATE.F` bits are 0. As described earlier,
+when a non-secure interrupt is generated, the SP should coordinate with the SPD
+service to pass control back to the non-secure state in the last known exception
+level. This will allow the non-secure interrupt to be handled in the non-secure
+state.
+
+##### 2.3.3.1 Test secure payload behavior
+The TSPD hands control of a Secure-EL1 interrupt to the TSP at the
+`tsp_fiq_entry()`. The TSP handles the interrupt while ensuring that the
+handover agreement described in Section 2.2.2.1 is maintained. It updates some
+statistics by calling `tsp_update_sync_fiq_stats()`. It then calls
+`tsp_fiq_handler()` which.
+
+1. Checks whether the interrupt is the secure physical timer interrupt. It
+ uses the platform API `plat_ic_get_pending_interrupt_id()` to get the
+ interrupt number.
+
+2. Handles the interrupt by acknowledging it using the
+ `plat_ic_acknowledge_interrupt()` platform API, calling
+ `tsp_generic_timer_handler()` to reprogram the secure physical generic
+ timer and calling the `plat_ic_end_of_interrupt()` platform API to signal
+ end of interrupt processing.
+
+The TSP passes control back to the TSPD by issuing an SMC64 with
+`TSP_HANDLED_S_EL1_FIQ` as the function identifier.
+
+The TSP handles interrupts under the asynchronous model as follows.
+
+1. Secure-EL1 interrupts are handled by calling the `tsp_fiq_handler()`
+ function. The function has been described above.
+
+2. Non-secure interrupts are handled by issuing an SMC64 with `TSP_PREEMPTED`
+ as the function identifier. Execution resumes at the instruction that
+ follows this SMC instruction when the TSPD hands control to the TSP in
+ response to an SMC with `TSP_FID_RESUME` as the function identifier from
+ the non-secure state (see section 2.3.2.1).
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2014, ARM Limited and Contributors. All rights reserved._
+
+[Porting Guide]: ./porting-guide.md
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
new file mode 100644
index 0000000..d970190
--- /dev/null
+++ b/docs/porting-guide.md
@@ -0,0 +1,1372 @@
+ARM Trusted Firmware Porting Guide
+==================================
+
+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)
+ * Boot Loader stage 2 (BL2)
+ * Boot Loader stage 3-1 (BL3-1)
+ * PSCI implementation (in BL3-1)
+ * Interrupt Management framework (in BL3-1)
+4. C Library
+5. Storage abstraction layer
+
+- - - - - - - - - - - - - - - - - -
+
+1. Introduction
+----------------
+
+Porting the ARM Trusted Firmware to a new platform involves making some
+mandatory and optional modifications for both the cold and warm boot paths.
+Modifications consist of:
+
+* Implementing a platform-specific function or variable,
+* Setting up the execution context in a certain way, or
+* Defining certain constants (for example #defines).
+
+The platform-specific functions and variables are all declared in
+[include/plat/common/platform.h]. The firmware provides a default implementation
+of variables and functions to fulfill the optional requirements. These
+implementations are all weakly defined; they are provided to ease the porting
+effort. Each platform port can override them with its own implementation if the
+default implementation is inadequate.
+
+Some modifications are common to all Boot Loader (BL) stages. Section 2
+discusses these in detail. The subsequent sections discuss the remaining
+modifications for each BL stage in detail.
+
+This document should be read in conjunction with the ARM Trusted Firmware
+[User Guide].
+
+
+2. Common modifications
+------------------------
+
+This section covers the modifications that should be made by the platform for
+each BL stage to correctly port the firmware stack. They are categorized as
+either mandatory or optional.
+
+
+2.1 Common mandatory modifications
+----------------------------------
+A platform port must enable the Memory Management Unit (MMU) with identity
+mapped page tables, and enable both the instruction and data caches for each BL
+stage. In the ARM FVP port, each BL stage configures the MMU in its platform-
+specific architecture setup function, for example `blX_plat_arch_setup()`.
+
+Each platform must allocate a block of identity mapped secure memory with
+Device-nGnRE attributes aligned to page boundary (4K) for each BL stage. This
+memory is identified by the section name `tzfw_coherent_mem` so that its
+possible for the firmware to place variables in it using the following C code
+directive:
+
+ __attribute__ ((section("tzfw_coherent_mem")))
+
+Or alternatively the following assembler code directive:
+
+ .section tzfw_coherent_mem
+
+The `tzfw_coherent_mem` section is used to allocate any data structures that are
+accessed both when a CPU is executing with its MMU and caches enabled, and when
+it's running with its MMU and caches disabled. Examples are given below.
+
+The following variables, functions and constants must be defined by the platform
+for the firmware to work correctly.
+
+
+### File : platform_def.h [mandatory]
+
+Each platform must ensure that a header file of this name is in the system
+include path with the following constants defined. This may require updating the
+list of `PLAT_INCLUDES` in the `platform.mk` file. In the ARM FVP port, this
+file is found in [plat/fvp/include/platform_def.h].
+
+* **#define : PLATFORM_LINKER_FORMAT**
+
+ Defines the linker format used by the platform, for example
+ `elf64-littleaarch64` used by the FVP.
+
+* **#define : PLATFORM_LINKER_ARCH**
+
+ Defines the processor architecture for the linker by the platform, for
+ example `aarch64` used by the FVP.
+
+* **#define : PLATFORM_STACK_SIZE**
+
+ Defines the normal stack memory available to each CPU. This constant is used
+ by [plat/common/aarch64/platform_mp_stack.S] and
+ [plat/common/aarch64/platform_up_stack.S].
+
+* **#define : PCPU_DV_MEM_STACK_SIZE**
+
+ Defines the coherent stack memory available to each CPU. This constant is used
+ by [plat/common/aarch64/platform_mp_stack.S] and
+ [plat/common/aarch64/platform_up_stack.S].
+
+* **#define : FIRMWARE_WELCOME_STR**
+
+ Defines the character string printed by BL1 upon entry into the `bl1_main()`
+ function.
+
+* **#define : BL2_IMAGE_NAME**
+
+ Name of the BL2 binary image on the host file-system. This name is used by
+ BL1 to load BL2 into secure memory from non-volatile storage.
+
+* **#define : BL31_IMAGE_NAME**
+
+ Name of the BL3-1 binary image on the host file-system. This name is used by
+ BL2 to load BL3-1 into secure memory from platform storage.
+
+* **#define : BL33_IMAGE_NAME**
+
+ Name of the BL3-3 binary image on the host file-system. This name is used by
+ BL2 to load BL3-3 into non-secure memory from platform storage.
+
+* **#define : PLATFORM_CACHE_LINE_SIZE**
+
+ Defines the size (in bytes) of the largest cache line across all the cache
+ levels in the platform.
+
+* **#define : PLATFORM_CLUSTER_COUNT**
+
+ Defines the total number of clusters implemented by the platform in the
+ system.
+
+* **#define : PLATFORM_CORE_COUNT**
+
+ Defines the total number of CPUs implemented by the platform across all
+ clusters in the system.
+
+* **#define : PLATFORM_MAX_CPUS_PER_CLUSTER**
+
+ Defines the maximum number of CPUs that can be implemented within a cluster
+ on the platform.
+
+* **#define : PRIMARY_CPU**
+
+ Defines the `MPIDR` of the primary CPU on the platform. This value is used
+ after a cold boot to distinguish between primary and secondary CPUs.
+
+* **#define : TZROM_BASE**
+
+ Defines the base address of secure ROM on the platform, where the BL1 binary
+ is loaded. This constant is used by the linker scripts to ensure that the
+ BL1 image fits into the available memory.
+
+* **#define : TZROM_SIZE**
+
+ Defines the size of secure ROM on the platform. This constant is used by the
+ linker scripts to ensure that the BL1 image fits into the available memory.
+
+* **#define : TZRAM_BASE**
+
+ Defines the base address of the secure RAM on platform, where the data
+ section of the BL1 binary is loaded. The BL2 and BL3-1 images are also
+ loaded in this secure RAM region. This constant is used by the linker
+ scripts to ensure that the BL1 data section and BL2/BL3-1 binary images fit
+ into the available memory.
+
+* **#define : TZRAM_SIZE**
+
+ Defines the size of the secure RAM on the platform. This constant is used by
+ the linker scripts to ensure that the BL1 data section and BL2/BL3-1 binary
+ images fit into the available memory.
+
+* **#define : BL1_RO_BASE**
+
+ Defines the base address in secure ROM where BL1 originally lives. Must be
+ aligned on a page-size boundary.
+
+* **#define : BL1_RO_LIMIT**
+
+ Defines the maximum address in secure ROM that BL1's actual content (i.e.
+ excluding any data section allocated at runtime) can occupy.
+
+* **#define : BL1_RW_BASE**
+
+ Defines the base address in secure RAM where BL1's read-write data will live
+ at runtime. Must be aligned on a page-size boundary.
+
+* **#define : BL1_RW_LIMIT**
+
+ Defines the maximum address in secure RAM that BL1's read-write data can
+ occupy at runtime.
+
+* **#define : BL2_BASE**
+
+ Defines the base address in secure RAM where BL1 loads the BL2 binary image.
+ Must be aligned on a page-size boundary.
+
+* **#define : BL2_LIMIT**
+
+ Defines the maximum address in secure RAM that the BL2 image can occupy.
+
+* **#define : BL31_BASE**
+
+ Defines the base address in secure RAM where BL2 loads the BL3-1 binary
+ image. Must be aligned on a page-size boundary.
+
+* **#define : BL31_LIMIT**
+
+ Defines the maximum address in secure RAM that the BL3-1 image can occupy.
+
+* **#define : NS_IMAGE_OFFSET**
+
+ Defines the base address in non-secure DRAM where BL2 loads the BL3-3 binary
+ image. Must be aligned on a page-size boundary.
+
+If the BL3-2 image is supported by the platform, the following constants must
+be defined as well:
+
+* **#define : TSP_SEC_MEM_BASE**
+
+ Defines the base address of the secure memory used by the BL3-2 image on the
+ platform.
+
+* **#define : TSP_SEC_MEM_SIZE**
+
+ Defines the size of the secure memory used by the BL3-2 image on the
+ platform.
+
+* **#define : BL32_BASE**
+
+ Defines the base address in secure memory where BL2 loads the BL3-2 binary
+ image. Must be inside the secure memory identified by `TSP_SEC_MEM_BASE` and
+ `TSP_SEC_MEM_SIZE` constants. Must also be aligned on a page-size boundary.
+
+* **#define : BL32_LIMIT**
+
+ Defines the maximum address that the BL3-2 image can occupy. Must be inside
+ the secure memory identified by `TSP_SEC_MEM_BASE` and `TSP_SEC_MEM_SIZE`
+ constants.
+
+
+### File : plat_macros.S [mandatory]
+
+Each platform must ensure a file of this name is in the system include path with
+the following macro defined. In the ARM FVP port, this file is found in
+[plat/fvp/include/plat_macros.S].
+
+* **Macro : plat_print_gic_regs**
+
+ This macro allows the crash reporting routine to print GIC registers
+ in case of an unhandled IRQ or FIQ in BL3-1. This aids in debugging and
+ this macro can be defined to be empty in case GIC register reporting is
+ not desired.
+
+### Other mandatory modifications
+
+The following mandatory modifications may be implemented in any file
+the implementer chooses. In the ARM FVP port, they are implemented in
+[plat/fvp/aarch64/plat_common.c].
+
+* **Function : uint64_t plat_get_syscnt_freq(void)**
+
+ This function is used by the architecture setup code to retrieve the
+ counter frequency for the CPU's generic timer. This value will be
+ programmed into the `CNTFRQ_EL0` register.
+ In the ARM FVP port, it returns the base frequency of the system counter,
+ which is retrieved from the first entry in the frequency modes table.
+
+
+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
+common platform-specific tasks. A platform may choose to override these
+definitions.
+
+
+### Function : platform_get_core_pos()
+
+ Argument : unsigned long
+ Return : int
+
+A platform may need to convert the `MPIDR` of a CPU to an absolute number, which
+can be used as a CPU-specific linear index into blocks of memory (for example
+while allocating per-CPU stacks). This routine contains a simple mechanism
+to perform this conversion, using the assumption that each cluster contains a
+maximum of 4 CPUs:
+
+ linear index = cpu_id + (cluster_id * 4)
+
+ cpu_id = 8-bit value in MPIDR at affinity level 0
+ cluster_id = 8-bit value in MPIDR at affinity level 1
+
+
+### Function : platform_set_coherent_stack()
+
+ Argument : unsigned long
+ Return : void
+
+A platform may need stack memory that is coherent with main memory to perform
+certain operations like:
+
+* Turning the MMU on, or
+* Flushing caches prior to powering down a CPU or cluster.
+
+Each BL stage allocates this coherent stack memory for each CPU in the
+`tzfw_coherent_mem` section.
+
+This function sets the current stack pointer to the coherent stack that
+has been allocated for the CPU specified by MPIDR. For BL images that only
+require a stack for the primary CPU the parameter is ignored. The size of
+the stack allocated to each CPU is specified by the platform defined constant
+`PCPU_DV_MEM_STACK_SIZE`.
+
+Common implementations of this function for the UP and MP BL images are
+provided in [plat/common/aarch64/platform_up_stack.S] and
+[plat/common/aarch64/platform_mp_stack.S]
+
+
+### Function : platform_is_primary_cpu()
+
+ Argument : unsigned long
+ Return : unsigned int
+
+This function identifies a CPU by its `MPIDR`, which is passed as the argument,
+to determine whether this CPU is the primary CPU or a secondary CPU. A return
+value of zero indicates that the CPU is not the primary CPU, while a non-zero
+return value indicates that the CPU is the primary CPU.
+
+
+### Function : platform_set_stack()
+
+ Argument : unsigned long
+ Return : void
+
+This function sets the current stack pointer to the normal memory stack that
+has been allocated for the CPU specificed by MPIDR. For BL images that only
+require a stack for the primary CPU the parameter is ignored. The size of
+the stack allocated to each CPU is specified by the platform defined constant
+`PLATFORM_STACK_SIZE`.
+
+Common implementations of this function for the UP and MP BL images are
+provided in [plat/common/aarch64/platform_up_stack.S] and
+[plat/common/aarch64/platform_mp_stack.S]
+
+
+### Function : platform_get_stack()
+
+ Argument : unsigned long
+ Return : unsigned long
+
+This function returns the base address of the normal memory stack that
+has been allocated for the CPU specificed by MPIDR. For BL images that only
+require a stack for the primary CPU the parameter is ignored. The size of
+the stack allocated to each CPU is specified by the platform defined constant
+`PLATFORM_STACK_SIZE`.
+
+Common implementations of this function for the UP and MP BL images are
+provided in [plat/common/aarch64/platform_up_stack.S] and
+[plat/common/aarch64/platform_mp_stack.S]
+
+
+### Function : plat_report_exception()
+
+ Argument : unsigned int
+ Return : void
+
+A platform may need to report various information about its status when an
+exception is taken, for example the current exception level, the CPU security
+state (secure/non-secure), the exception type, and so on. This function is
+called in the following circumstances:
+
+* In BL1, whenever an exception is taken.
+* In BL2, whenever an exception is taken.
+
+The default implementation doesn't do anything, to avoid making assumptions
+about the way the platform displays its status information.
+
+This function receives the exception type as its argument. Possible values for
+exceptions types are listed in the [include/runtime_svc.h] header file. Note
+that these constants are not related to any architectural exception code; they
+are just an ARM Trusted Firmware convention.
+
+
+3. Modifications specific to a Boot Loader stage
+-------------------------------------------------
+
+3.1 Boot Loader Stage 1 (BL1)
+-----------------------------
+
+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. 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. Loading the BL2 image from non-volatile storage into secure memory at the
+ address specified by the platform defined constant `BL2_BASE`.
+
+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
+ meminfo.total_size = Size of secure RAM visible to BL2
+ meminfo.free_base = Base address of secure RAM available for
+ allocation to BL2
+ meminfo.free_size = Size of secure RAM available for allocation to BL2
+
+ BL1 places this `meminfo` structure at the beginning of the free memory
+ available for its use. Since BL1 cannot allocate memory dynamically at the
+ moment, its free memory will be available for BL2's use as-is. However, this
+ means that BL2 must read the `meminfo` structure before it starts using its
+ free memory (this is discussed in Section 3.2).
+
+ In future releases of the ARM Trusted Firmware it will be possible for
+ the platform to decide where it wants to place the `meminfo` structure for
+ BL2.
+
+ BL1 implements the `init_bl2_mem_layout()` function to populate the
+ BL2 `meminfo` structure. The platform may override this implementation, for
+ example if the platform wants to restrict the amount of memory visible to
+ BL2. Details of how to do this are given below.
+
+The following functions need to be implemented by the platform port to enable
+BL1 to perform the above tasks.
+
+
+### Function : bl1_plat_arch_setup() [mandatory]
+
+ Argument : void
+ Return : void
+
+This function performs any platform-specific and architectural setup that the
+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.
+
+This function helps fulfill requirement 2 above.
+
+
+### Function : bl1_platform_setup() [mandatory]
+
+ Argument : void
+ Return : void
+
+This function executes with the MMU and data caches enabled. It is responsible
+for performing any remaining platform-specific setup that can occur after the
+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 3 above.
+
+
+### Function : bl1_plat_sec_mem_layout() [mandatory]
+
+ Argument : void
+ Return : meminfo *
+
+This function should only be called on the cold boot path. It executes with the
+MMU and data caches enabled. The pointer returned by this function must point to
+a `meminfo` structure containing the extents and availability of secure RAM for
+the BL1 stage.
+
+ meminfo.total_base = Base address of secure RAM visible to BL1
+ meminfo.total_size = Size of secure RAM visible to BL1
+ meminfo.free_base = Base address of secure RAM available for allocation
+ to BL1
+ meminfo.free_size = Size of secure RAM available for allocation to BL1
+
+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 3 above.
+
+
+### Function : init_bl2_mem_layout() [optional]
+
+ Argument : meminfo *, meminfo *, unsigned int, unsigned long
+ Return : void
+
+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
+`BL2_BASE`), BL1 calculates the amount of free memory available for BL2 to use.
+BL1 also ensures that its data sections resident in secure RAM are not visible
+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)
+-----------------------------
+
+The BL2 stage is executed only by the primary CPU, which is determined in BL1
+using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at
+`BL2_BASE`. BL2 executes in Secure EL1 and is responsible for:
+
+1. Loading the BL3-1 binary image into secure RAM from non-volatile storage. To
+ load the BL3-1 image, BL2 makes use of the `meminfo` structure passed to it
+ by BL1. This structure allows BL2 to calculate how much secure RAM is
+ available for its use. The platform also defines the address in secure RAM
+ where BL3-1 is loaded through the constant `BL31_BASE`. BL2 uses this
+ information to determine if there is enough memory to load the BL3-1 image.
+
+2. Loading the normal world BL3-3 binary image into non-secure DRAM from
+ platform storage and arranging for BL3-1 to pass control to this image. This
+ address is determined using the `plat_get_ns_image_entrypoint()` function
+ described 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 `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 `entry_point_info`
+ structure in memory provided by the platform with information about how
+ 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.
+
+
+### Function : bl2_early_platform_setup() [mandatory]
+
+ 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 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
+copied structure is made available to all BL2 code through the
+`bl2_plat_sec_mem_layout()` function.
+
+
+### Function : bl2_plat_arch_setup() [mandatory]
+
+ Argument : void
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU.
+
+The purpose of this function is to perform any architectural initialization
+that varies across platforms, for example enabling the MMU (since the memory
+map differs across platforms).
+
+
+### Function : bl2_platform_setup() [mandatory]
+
+ Argument : void
+ Return : void
+
+This function may execute with the MMU and data caches enabled if the platform
+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. 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.
+
+
+### Function : bl2_plat_sec_mem_layout() [mandatory]
+
+ Argument : void
+ Return : meminfo *
+
+This function should only be called on the cold boot path. It may execute with
+the MMU and data caches enabled if the platform 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 return a pointer to a `meminfo` structure
+populated with the extents of secure RAM available for BL2 to use. See
+`bl2_early_platform_setup()` above.
+
+
+### Function : bl2_plat_get_bl31_params() [mandatory]
+
+ Argument : void
+ 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.
+
+
+### Funtion : bl2_plat_get_bl31_ep_info() [mandatory]
+
+ Argument : void
+ Return : entry_point_info *
+
+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.
+
+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
+
+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]
+
+ 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]
+
+ Argument : void
+ Return : unsigned long
+
+As previously described, BL2 is responsible for arranging for control to be
+passed to a normal world BL image through BL3-1. This function returns the
+entrypoint of that image, which BL3-1 uses to jump to it.
+
+BL2 is responsible for loading the normal world BL3-3 image (e.g. UEFI).
+
+
+3.2 Boot Loader Stage 3-1 (BL3-1)
+---------------------------------
+
+During cold boot, the BL3-1 stage is executed only by the primary CPU. This is
+determined in BL1 using the `platform_is_primary_cpu()` function. BL1 passes
+control to BL3-1 at `BL31_BASE`. During warm boot, BL3-1 is executed by all
+CPUs. BL3-1 executes at EL3 and is responsible for:
+
+1. Re-initializing all architectural and platform state. Although BL1 performs
+ some of this initialization, BL3-1 remains resident in EL3 and must ensure
+ that EL3 architectural and platform state is completely initialized. It
+ 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 `entry_point_info` structure that BL2
+ populated in memory to do this.
+
+3. Providing runtime firmware services. Currently, BL3-1 only implements a
+ subset of the Power State Coordination Interface (PSCI) API as a runtime
+ service. See Section 3.3 below for details of porting the PSCI
+ implementation.
+
+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 `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.
+
+
+### Function : bl31_early_platform_setup() [mandatory]
+
+ 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 `bl31_params` structure populated by BL2.
+* An opaque pointer that the platform may use as needed.
+
+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_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]
+
+ Argument : void
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU.
+
+The purpose of this function is to perform any architectural initialization
+that varies across platforms, for example enabling the MMU (since the memory
+map differs across platforms).
+
+
+### Function : bl31_platform_setup() [mandatory]
+
+ Argument : void
+ Return : void
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initialization in `bl31_plat_arch_setup()`. It is only
+called by the primary CPU.
+
+The purpose of this function is to complete platform initialization so that both
+BL3-1 runtime services and normal world software can function correctly.
+
+The ARM FVP port does the following:
+* Initializes the generic interrupt controller.
+* Configures the CLCD controller.
+* Enables system-level implementation of the generic timer counter.
+* Grants access to the system counter timer module
+* Initializes the FVP power controller device
+* Detects the system topology.
+
+
+### Function : bl31_get_next_image_info() [mandatory]
+
+ Argument : unsigned int
+ 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()`.
+
+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 `entry_point_info` structure
+(that was copied during `bl31_early_platform_setup()`) if the image exists. It
+should return NULL otherwise.
+
+
+3.3 Power State Coordination Interface (in BL3-1)
+------------------------------------------------
+
+The ARM Trusted Firmware's implementation of the PSCI API is based around the
+concept of an _affinity instance_. Each _affinity instance_ can be uniquely
+identified in a system by a CPU ID (the processor `MPIDR` is used in the PSCI
+interface) and an _affinity level_. A processing element (for example, a
+CPU) is at level 0. If the CPUs in the system are described in a tree where the
+node above a CPU is a logical grouping of CPUs that share some state, then
+affinity level 1 is that group of CPUs (for example, a cluster), and affinity
+level 2 is a group of clusters (for example, the system). The implementation
+assumes that the affinity level 1 ID can be computed from the affinity level 0
+ID (for example, a unique cluster ID can be computed from the CPU ID). The
+current implementation computes this on the basis of the recommended use of
+`MPIDR` affinity fields in the ARM Architecture Reference Manual.
+
+BL3-1's platform initialization code exports a pointer to the platform-specific
+power management operations required for the PSCI implementation to function
+correctly. This information is populated in the `plat_pm_ops` structure. The
+PSCI implementation calls members of the `plat_pm_ops` structure for performing
+power management operations for each affinity instance. For example, the target
+CPU is specified by its `MPIDR` in a PSCI `CPU_ON` call. The `affinst_on()`
+handler (if present) is called for each affinity instance as the PSCI
+implementation powers up each affinity level implemented in the `MPIDR` (for
+example, CPU, cluster and system).
+
+The following functions must be implemented to initialize PSCI functionality in
+the ARM Trusted Firmware.
+
+
+### Function : plat_get_aff_count() [mandatory]
+
+ Argument : unsigned int, unsigned long
+ Return : unsigned int
+
+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.
+
+This function is called by the PSCI initialization code to detect the system
+topology. Its purpose is to return the number of affinity instances implemented
+at a given `affinity level` (specified by the first argument) and a given
+`MPIDR` (specified by the second argument). For example, on a dual-cluster
+system where first cluster implements 2 CPUs and the second cluster implements 4
+CPUs, a call to this function with an `MPIDR` corresponding to the first cluster
+(`0x0`) and affinity level 0, would return 2. A call to this function with an
+`MPIDR` corresponding to the second cluster (`0x100`) and affinity level 0,
+would return 4.
+
+
+### Function : plat_get_aff_state() [mandatory]
+
+ Argument : unsigned int, unsigned long
+ Return : unsigned int
+
+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.
+
+This function is called by the PSCI initialization code. Its purpose is to
+return the state of an affinity instance. The affinity instance is determined by
+the affinity ID at a given `affinity level` (specified by the first argument)
+and an `MPIDR` (specified by the second argument). The state can be one of
+`PSCI_AFF_PRESENT` or `PSCI_AFF_ABSENT`. The latter state is used to cater for
+system topologies where certain affinity instances are unimplemented. For
+example, consider a platform that implements a single cluster with 4 CPUs and
+another CPU implemented directly on the interconnect with the cluster. The
+`MPIDR`s of the cluster would range from `0x0-0x3`. The `MPIDR` of the single
+CPU would be 0x100 to indicate that it does not belong to cluster 0. Cluster 1
+is missing but needs to be accounted for to reach this single CPU in the
+topology tree. Hence it is marked as `PSCI_AFF_ABSENT`.
+
+
+### Function : plat_get_max_afflvl() [mandatory]
+
+ Argument : void
+ Return : int
+
+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.
+
+This function is called by the PSCI implementation both during cold and warm
+boot, to determine the maximum affinity level that the power management
+operations should apply to. ARMv8-A has support for 4 affinity levels. It is
+likely that hardware will implement fewer affinity levels. This function allows
+the PSCI implementation to consider only those affinity levels in the system
+that the platform implements. For example, the Base AEM FVP implements two
+clusters with a configurable number of CPUs. It reports the maximum affinity
+level as 1, resulting in PSCI power control up to the cluster level.
+
+
+### Function : platform_setup_pm() [mandatory]
+
+ Argument : plat_pm_ops **
+ Return : int
+
+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.
+
+This function is called by PSCI initialization code. Its purpose is to export
+handler routines for platform-specific power management actions by populating
+the passed pointer with a pointer to BL3-1's private `plat_pm_ops` structure.
+
+A description of each member of this structure is given below. Please refer to
+the ARM FVP specific implementation of these handlers in [plat/fvp/plat_pm.c]
+as an example. A platform port may choose not implement some of the power
+management operations. For example, the ARM FVP port does not implement the
+`affinst_standby()` function.
+
+#### plat_pm_ops.affinst_standby()
+
+Perform the platform-specific setup to enter the standby state indicated by the
+passed argument.
+
+#### plat_pm_ops.affinst_on()
+
+Perform the platform specific setup to power on an affinity instance, specified
+by the `MPIDR` (first argument) and `affinity level` (fourth argument). The
+`state` (fifth argument) contains the current state of that affinity instance
+(ON or OFF). This is useful to determine whether any action must be taken. For
+example, while powering on a CPU, the cluster that contains this CPU might
+already be in the ON state. The platform decides what actions must be taken to
+transition from the current state to the target state (indicated by the power
+management operation).
+
+#### plat_pm_ops.affinst_off()
+
+Perform the platform specific setup to power off an affinity instance in the
+`MPIDR` of the calling CPU. It is called by the PSCI `CPU_OFF` API
+implementation.
+
+The `MPIDR` (first argument), `affinity level` (second argument) and `state`
+(third argument) have a similar meaning as described in the `affinst_on()`
+operation. They are used to identify the affinity instance on which the call
+is made and its current state. This gives the platform port an indication of the
+state transition it must make to perform the requested action. For example, if
+the calling CPU is the last powered on CPU in the cluster, after powering down
+affinity level 0 (CPU), the platform port should power down affinity level 1
+(the cluster) as well.
+
+This function is called with coherent stacks. This allows the PSCI
+implementation to flush caches at a given affinity level without running into
+stale stack state after turning off the caches. On ARMv8-A cache hits do not
+occur after the cache has been turned off.
+
+#### plat_pm_ops.affinst_suspend()
+
+Perform the platform specific setup to power off an affinity instance in the
+`MPIDR` of the calling CPU. It is called by the PSCI `CPU_SUSPEND` API
+implementation.
+
+The `MPIDR` (first argument), `affinity level` (third argument) and `state`
+(fifth argument) have a similar meaning as described in the `affinst_on()`
+operation. They are used to identify the affinity instance on which the call
+is made and its current state. This gives the platform port an indication of the
+state transition it must make to perform the requested action. For example, if
+the calling CPU is the last powered on CPU in the cluster, after powering down
+affinity level 0 (CPU), the platform port should power down affinity level 1
+(the cluster) as well.
+
+The difference between turning an affinity instance off versus suspending it
+is that in the former case, the affinity instance is expected to re-initialize
+its state when its next powered on (see `affinst_on_finish()`). In the latter
+case, the affinity instance is expected to save enough state so that it can
+resume execution by restoring this state when its powered on (see
+`affinst_suspend_finish()`).
+
+This function is called with coherent stacks. This allows the PSCI
+implementation to flush caches at a given affinity level without running into
+stale stack state after turning off the caches. On ARMv8-A cache hits do not
+occur after the cache has been turned off.
+
+#### plat_pm_ops.affinst_on_finish()
+
+This function is called by the PSCI implementation after the calling CPU is
+powered on and released from reset in response to an earlier PSCI `CPU_ON` call.
+It performs the platform-specific setup required to initialize enough state for
+this CPU to enter the normal world and also provide secure runtime firmware
+services.
+
+The `MPIDR` (first argument), `affinity level` (second argument) and `state`
+(third argument) have a similar meaning as described in the previous operations.
+
+This function is called with coherent stacks. This allows the PSCI
+implementation to flush caches at a given affinity level without running into
+stale stack state after turning off the caches. On ARMv8-A cache hits do not
+occur after the cache has been turned off.
+
+#### plat_pm_ops.affinst_on_suspend()
+
+This function is called by the PSCI implementation after the calling CPU is
+powered on and released from reset in response to an asynchronous wakeup
+event, for example a timer interrupt that was programmed by the CPU during the
+`CPU_SUSPEND` call. It performs the platform-specific setup required to
+restore the saved state for this CPU to resume execution in the normal world
+and also provide secure runtime firmware services.
+
+The `MPIDR` (first argument), `affinity level` (second argument) and `state`
+(third argument) have a similar meaning as described in the previous operations.
+
+This function is called with coherent stacks. This allows the PSCI
+implementation to flush caches at a given affinity level without running into
+stale stack state after turning off the caches. On ARMv8-A cache hits do not
+occur after the cache has been turned off.
+
+BL3-1 platform initialization code must also detect the system topology and
+the state of each affinity instance in the topology. This information is
+critical for the PSCI runtime service to function correctly. More details are
+provided in the description of the `plat_get_aff_count()` and
+`plat_get_aff_state()` functions above.
+
+3.4 Interrupt Management framework (in BL3-1)
+----------------------------------------------
+BL3-1 implements an Interrupt Management Framework (IMF) to manage interrupts
+generated in either security state and targeted to EL1 or EL2 in the non-secure
+state or EL3/S-EL1 in the secure state. The design of this framework is
+described in the [IMF Design Guide]
+
+A platform should export the following APIs to support the IMF. The following
+text briefly describes each api and its implementation on the FVP port. The API
+implementation depends upon the type of interrupt controller present in the
+platform. The FVP implements an ARM Generic Interrupt Controller (ARM GIC) as
+per the version 2.0 of the [ARM GIC Architecture Specification]
+
+### Function : plat_interrupt_type_to_line() [mandatory]
+
+ Argument : uint32_t, uint32_t
+ Return : uint32_t
+
+The ARM processor signals an interrupt exception either through the IRQ or FIQ
+interrupt line. The specific line that is signaled depends on how the interrupt
+controller (IC) reports different interrupt types from an execution context in
+either security state. The IMF uses this API to determine which interrupt line
+the platform IC uses to signal each type of interrupt supported by the framework
+from a given security state.
+
+The first parameter will be one of the `INTR_TYPE_*` values (see [IMF Design
+Guide]) indicating the target type of the interrupt, the second parameter is the
+security state of the originating execution context. The return result is the
+bit position in the `SCR_EL3` register of the respective interrupt trap: IRQ=1,
+FIQ=2.
+
+The FVP port configures the ARM GIC to signal S-EL1 interrupts as FIQs and
+Non-secure interrupts as IRQs from either security state.
+
+
+### Function : plat_ic_get_pending_interrupt_type() [mandatory]
+
+ Argument : void
+ Return : uint32_t
+
+This API returns the type of the highest priority pending interrupt at the
+platform IC. The IMF uses the interrupt type to retrieve the corresponding
+handler function. `INTR_TYPE_INVAL` is returned when there is no interrupt
+pending. The valid interrupt types that can be returned are `INTR_TYPE_EL3`,
+`INTR_TYPE_S_EL1` and `INTR_TYPE_NS`.
+
+The FVP port reads the _Highest Priority Pending Interrupt Register_
+(`GICC_HPPIR`) to determine the id of the pending interrupt. The type of interrupt
+depends upon the id value as follows.
+
+1. id < 1022 is reported as a S-EL1 interrupt
+2. id = 1022 is reported as a Non-secure interrupt.
+3. id = 1023 is reported as an invalid interrupt type.
+
+
+### Function : plat_ic_get_pending_interrupt_id() [mandatory]
+
+ Argument : void
+ Return : uint32_t
+
+This API returns the id of the highest priority pending interrupt at the
+platform IC. The IMF passes the id returned by this API to the registered
+handler for the pending interrupt if the `IMF_READ_INTERRUPT_ID` build time flag
+is set. INTR_ID_UNAVAILABLE is returned when there is no interrupt pending.
+
+The FVP port reads the _Highest Priority Pending Interrupt Register_
+(`GICC_HPPIR`) to determine the id of the pending interrupt. The id that is
+returned by API depends upon the value of the id read from the interrupt
+controller as follows.
+
+1. id < 1022. id is returned as is.
+2. id = 1022. The _Aliased Highest Priority Pending Interrupt Register_
+ (`GICC_AHPPIR`) is read to determine the id of the non-secure interrupt. This
+ id is returned by the API.
+3. id = 1023. `INTR_ID_UNAVAILABLE` is returned.
+
+
+### Function : plat_ic_acknowledge_interrupt() [mandatory]
+
+ Argument : void
+ Return : uint32_t
+
+This API is used by the CPU to indicate to the platform IC that processing of
+the highest pending interrupt has begun. It should return the id of the
+interrupt which is being processed.
+
+The FVP port reads the _Interrupt Acknowledge Register_ (`GICC_IAR`). This
+changes the state of the highest priority pending interrupt from pending to
+active in the interrupt controller. It returns the value read from the
+`GICC_IAR`. This value is the id of the interrupt whose state has been changed.
+
+The TSP uses this API to start processing of the secure physical timer
+interrupt.
+
+
+### Function : plat_ic_end_of_interrupt() [mandatory]
+
+ Argument : uint32_t
+ Return : void
+
+This API is used by the CPU to indicate to the platform IC that processing of
+the interrupt corresponding to the id (passed as the parameter) has
+finished. The id should be the same as the id returned by the
+`plat_ic_acknowledge_interrupt()` API.
+
+The FVP port writes the id to the _End of Interrupt Register_
+(`GICC_EOIR`). This deactivates the corresponding interrupt in the interrupt
+controller.
+
+The TSP uses this API to finish processing of the secure physical timer
+interrupt.
+
+
+### Function : plat_ic_get_interrupt_type() [mandatory]
+
+ Argument : uint32_t
+ Return : uint32_t
+
+This API returns the type of the interrupt id passed as the parameter.
+`INTR_TYPE_INVAL` is returned if the id is invalid. If the id is valid, a valid
+interrupt type (one of `INTR_TYPE_EL3`, `INTR_TYPE_S_EL1` and `INTR_TYPE_NS`) is
+returned depending upon how the interrupt has been configured by the platform
+IC.
+
+The FVP port configures S-EL1 interrupts as Group0 interrupts and Non-secure
+interrupts as Group1 interrupts. It reads the group value corresponding to the
+interrupt id from the relevant _Interrupt Group Register_ (`GICD_IGROUPRn`). It
+uses the group value to determine the type of interrupt.
+
+
+4. C Library
+-------------
+
+To avoid subtle toolchain behavioral dependencies, the header files provided
+by the compiler are not used. The software is built with the `-nostdinc` flag
+to ensure no headers are included from the toolchain inadvertently. Instead the
+required headers are included in the ARM Trusted Firmware source tree. The
+library only contains those C library definitions required by the local
+implementation. If more functionality is required, the needed library functions
+will need to be added to the local implementation.
+
+Versions of [FreeBSD] headers can be found in `include/stdlib`. Some of these
+headers have been cut down in order to simplify the implementation. In order to
+minimize changes to the header files, the [FreeBSD] layout has been maintained.
+The generic C library definitions can be found in `include/stdlib` with more
+system and machine specific declarations in `include/stdlib/sys` and
+`include/stdlib/machine`.
+
+The local C library implementations can be found in `lib/stdlib`. In order to
+extend the C library these files may need to be modified. It is recommended to
+use a release version of [FreeBSD] as a starting point.
+
+The C library header files in the [FreeBSD] source tree are located in the
+`include` and `sys/sys` directories. [FreeBSD] machine specific definitions
+can be found in the `sys/<machine-type>` directories. These files define things
+like 'the size of a pointer' and 'the range of an integer'. Since an AArch64
+port for [FreeBSD] does not yet exist, the machine specific definitions are
+based on existing machine types with similar properties (for example SPARC64).
+
+Where possible, C library function implementations were taken from [FreeBSD]
+as found in the `lib/libc` directory.
+
+A copy of the [FreeBSD] sources can be downloaded with `git`.
+
+ git clone git://github.com/freebsd/freebsd.git -b origin/release/9.2.0
+
+
+5. Storage abstraction layer
+-----------------------------
+
+In order to improve platform independence and portability an storage abstraction
+layer is used to load data from non-volatile platform storage.
+
+Each platform should register devices and their drivers via the Storage layer.
+These drivers then need to be initialized by bootloader phases as
+required in their respective `blx_platform_setup()` functions. Currently
+storage access is only required by BL1 and BL2 phases. The `load_image()`
+function uses the storage layer to access non-volatile platform storage.
+
+It is mandatory to implement at least one storage driver. For the FVP the
+Firmware Image Package(FIP) driver is provided as the default means to load data
+from storage (see the "Firmware Image Package" section in the [User Guide]).
+The storage layer is described in the header file `include/io_storage.h`. The
+implementation of the common library is in `lib/io_storage.c` and the driver
+files are located in `drivers/io/`.
+
+Each IO driver must provide `io_dev_*` structures, as described in
+`drivers/io/io_driver.h`. These are returned via a mandatory registration
+function that is called on platform initialization. The semi-hosting driver
+implementation in `io_semihosting.c` can be used as an example.
+
+The Storage layer provides mechanisms to initialize storage devices before
+IO operations are called. The basic operations supported by the layer
+include `open()`, `close()`, `read()`, `write()`, `size()` and `seek()`.
+Drivers do not have to implement all operations, but each platform must
+provide at least one driver for a device capable of supporting generic
+operations such as loading a bootloader image.
+
+The current implementation only allows for known images to be loaded by the
+firmware. These images are specified by using their names, as defined in
+[include/plat/common/platform.h]. The platform layer (`plat_get_image_source()`)
+then returns a reference to a device and a driver-specific `spec` which will be
+understood by the driver to allow access to the image data.
+
+The layer is designed in such a way that is it possible to chain drivers with
+other drivers. For example, file-system drivers may be implemented on top of
+physical block devices, both represented by IO devices with corresponding
+drivers. In such a case, the file-system "binding" with the block device may
+be deferred until the file-system device is initialised.
+
+The abstraction currently depends on structures being statically allocated
+by the drivers and callers, as the system does not yet provide a means of
+dynamically allocating memory. This may also have the affect of limiting the
+amount of open resources per driver.
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._
+
+
+[ARM GIC Architecture Specification]: http://arminfo.emea.arm.com/help/topic/com.arm.doc.ihi0048b/IHI0048B_gic_architecture_specification.pdf
+[IMF Design Guide]: interrupt-framework-design.md
+[User Guide]: user-guide.md
+[FreeBSD]: http://www.freebsd.org
+
+[plat/common/aarch64/platform_mp_stack.S]: ../plat/common/aarch64/platform_mp_stack.S
+[plat/common/aarch64/platform_up_stack.S]: ../plat/common/aarch64/platform_up_stack.S
+[plat/fvp/include/platform_def.h]: ../plat/fvp/include/platform_def.h
+[plat/fvp/include/plat_macros.S]: ../plat/fvp/include/plat_macros.S
+[plat/fvp/aarch64/plat_common.c]: ../plat/fvp/aarch64/plat_common.c
+[plat/fvp/plat_pm.c]: ../plat/fvp/plat_pm.c
+[include/runtime_svc.h]: ../include/runtime_svc.h
+[include/plat/common/platform.h]: ../include/plat/common/platform.h
diff --git a/docs/rt-svc-writers-guide.md b/docs/rt-svc-writers-guide.md
new file mode 100644
index 0000000..2d13f74
--- /dev/null
+++ b/docs/rt-svc-writers-guide.md
@@ -0,0 +1,309 @@
+EL3 Runtime Service Writers Guide for ARM Trusted Firmware
+==========================================================
+
+Contents
+--------
+
+1. Introduction
+2. Owning Entities, Call Types and Function IDs
+3. Getting started
+4. Registering a runtime service
+5. Initializing a runtime service
+6. Handling runtime service requests
+7. Services that contain multiple sub-services
+8. Secure-EL1 Payload Dispatcher service (SPD)
+
+- - - - - - - - - - - - - - - - - -
+
+1. Introduction
+----------------
+
+This document describes how to add a runtime service to the EL3 Runtime
+Firmware component of ARM Trusted Firmware (BL3-1).
+
+Software executing in the normal world and in the trusted world at exception
+levels lower than EL3 will request runtime services using the Secure Monitor
+Call (SMC) instruction. These requests will follow the convention described in
+the SMC Calling Convention PDD ([SMCCC]). The [SMCCC] assigns function
+identifiers to each SMC request and describes how arguments are passed and
+results are returned.
+
+SMC Functions are grouped together based on the implementor of the service, for
+example a subset of the Function IDs are designated as "OEM Calls" (see [SMCCC]
+for full details). The EL3 runtime services framework in BL3-1 enables the
+independent implementation of services for each group, which are then compiled
+into the BL3-1 image. This simplifies the integration of common software from
+ARM to support [PSCI], Secure Monitor for a Trusted OS and SoC specific
+software. The common runtime services framework ensures that SMC Functions are
+dispatched to their respective service implementation - the [Firmware Design]
+provides details of how this is achieved.
+
+The interface and operation of the runtime services depends heavily on the
+concepts and definitions described in the [SMCCC], in particular SMC Function
+IDs, Owning Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and
+SMC64 calling conventions. Please refer to that document for a full explanation
+of these terms.
+
+
+2. Owning Entities, Call Types and Function IDs
+------------------------------------------------
+
+The SMC Function Identifier includes a OEN field. These values and their
+meaning are described in [SMCCC] and summarized in table 1 below. Some entities
+are allocated a range of of OENs. The OEN must be interpreted in conjunction
+with the SMC call type, which is either _Fast_ or _Standard_. Fast calls are
+uninterruptible whereas Standard calls can be pre-empted. The majority of
+Owning Entities only have allocated ranges for Fast calls: Standard calls are
+reserved exclusively for Trusted OS providers or for interoperability with
+legacy 32-bit software that predates the [SMCCC].
+
+ Type OEN Service
+ Fast 0 ARM Architecture calls
+ Fast 1 CPU Service calls
+ Fast 2 SiP Service calls
+ Fast 3 OEM Service calls
+ Fast 4 Standard Service calls
+ Fast 5-47 Reserved for future use
+ Fast 48-49 Trusted Application calls
+ Fast 50-63 Trusted OS calls
+
+ Std 0- 1 Reserved for existing ARMv7 calls
+ Std 2-63 Trusted OS Standard Calls
+
+_Table 1: Service types and their corresponding Owning Entity Numbers_
+
+Each individual entity can allocate the valid identifiers within the entity
+range as they need - it is not necessary to coordinate with other entities of
+the same type. For example, two SoC providers can use the same Function ID
+within the SiP Service calls OEN range to mean different things - as these
+calls should be specific to the SoC. The Standard Runtime Calls OEN is used for
+services defined by ARM standards, such as [PSCI].
+
+The SMC Function ID also indicates whether the call has followed the SMC32
+calling convention, where all parameters are 32-bit, or the SMC64 calling
+convention, where the parameters are 64-bit. The framework identifies and
+rejects invalid calls that use the SMC64 calling convention but that originate
+from an AArch32 caller.
+
+The EL3 runtime services framework uses the call type and OEN to identify a
+specific handler for each SMC call, but it is expected that an individual
+handler will be responsible for all SMC Functions within a given service type.
+
+
+3. Getting started
+-------------------
+
+ARM Trusted Firmware has a [`services`] directory in the source tree under which
+each owning entity can place the implementation of its runtime service. The
+[PSCI] implementation is located here in the [`services/std_svc/psci`]
+directory.
+
+Runtime service sources will need to include the [`runtime_svc.h`] header file.
+
+
+4. Registering a runtime service
+---------------------------------
+
+A runtime service is registered using the `DECLARE_RT_SVC()` macro, specifying
+the name of the service, the range of OENs covered, the type of service and
+initialization and call handler functions.
+
+ #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch)
+
+* `_name` is used to identify the data structure declared by this macro, and
+ is also used for diagnostic purposes
+
+* `_start` and `_end` values must be based on the `OEN_*` values defined in
+ [`runtime_svc.h`]
+
+* `_type` must be one of `SMC_TYPE_FAST` or `SMC_TYPE_STD`
+
+* `_setup` is the initialization function with the `rt_svc_init` signature:
+
+ typedef int32_t (*rt_svc_init)(void);
+
+* `_smch` is the SMC handler function with the `rt_svc_handle` signature:
+
+ typedef uint64_t (*rt_svc_handle)(uint32_t smc_fid,
+ uint64_t x1, uint64_t x2,
+ uint64_t x3, uint64_t x4,
+ void *reserved,
+ void *handle,
+ uint64_t flags);
+
+Details of the requirements and behavior of the two callbacks is provided in
+the following sections.
+
+During initialization the services framework validates each declared service
+to ensure that the following conditions are met:
+
+1. The `_start` OEN is not greater than the `_end` OEN
+2. The `_end` OEN does not exceed the maximum OEN value (63)
+3. The `_type` is one of `SMC_TYPE_FAST` or `SMC_TYPE_STD`
+4. `_setup` and `_smch` routines have been specified
+
+[`std_svc_setup.c`] provides an example of registering a runtime service:
+
+ /* Register Standard Service Calls as runtime service */
+ DECLARE_RT_SVC(
+ std_svc,
+ OEN_STD_START,
+ OEN_STD_END,
+ SMC_TYPE_FAST,
+ std_svc_setup,
+ std_svc_smc_handler
+ );
+
+
+5. Initializing a runtime service
+---------------------------------
+
+Runtime services are initialized once, during cold boot, by the primary CPU
+after platform and architectural initialization is complete. The framework
+performs basic validation of the declared service before calling
+the service initialization function (`_setup` in the declaration). This
+function must carry out any essential EL3 initialization prior to receiving a
+SMC Function call via the handler function.
+
+On success, the initialization function must return `0`. Any other return value
+will cause the framework to issue a diagnostic:
+
+ Error initializing runtime service <name of the service>
+
+and then ignore the service - the system will continue to boot but SMC calls
+will not be passed to the service handler and instead return the _Unknown SMC
+Function ID_ result `0xFFFFFFFF`.
+
+If the system must not be allowed to proceed without the service, the
+initialization function must itself cause the firmware boot to be halted.
+
+If the service uses per-CPU data this must either be initialized for all CPUs
+during this call, or be done lazily when a CPU first issues an SMC call to that
+service.
+
+
+6. Handling runtime service requests
+-------------------------------------
+
+SMC calls for a service are forwarded by the framework to the service's SMC
+handler function (`_smch` in the service declaration). This function must have
+the following signature:
+
+ typedef uint64_t (*rt_svc_handle)(uint32_t smc_fid,
+ uint64_t x1, uint64_t x2,
+ uint64_t x3, uint64_t x4,
+ void *reserved,
+ void *handle,
+ uint64_t flags);
+
+The handler is responsible for:
+
+1. Determining that `smc_fid` is a valid and supported SMC Function ID,
+ otherwise completing the request with the _Unknown SMC Function ID_:
+
+ SMC_RET1(handle, SMC_UNK);
+
+2. Determining if the requested function is valid for the calling security
+ state. SMC Calls can be made from both the normal and trusted worlds and
+ the framework will forward all calls to the service handler.
+
+ The `flags` parameter to this function indicates the caller security state
+ in bit[0], where a value of `1` indicates a non-secure caller. The
+ `is_caller_secure(flags)` and `is_caller_non_secure(flags)` can be used to
+ test this condition.
+
+ If invalid, the request should be completed with:
+
+ SMC_RET1(handle, SMC_UNK);
+
+3. Truncating parameters for calls made using the SMC32 calling convention.
+ Such calls can be determined by checking the CC field in bit[30] of the
+ `smc_fid` parameter, for example by using:
+
+ if (GET_SMC_CC(smc_fid) == SMC_32) ...
+
+ For such calls, the upper bits of the parameters x1-x4 and the saved
+ parameters X5-X7 are UNDEFINED and must be explicitly ignored by the
+ handler. This can be done by truncating the values to a suitable 32-bit
+ integer type before use, for example by ensuring that functions defined
+ to handle individual SMC Functions use appropriate 32-bit parameters.
+
+4. Providing the service requested by the SMC Function, utilizing the
+ immediate parameters x1-x4 and/or the additional saved parameters X5-X7.
+ The latter can be retrieved using the `SMC_GET_GP(handle, ref)` function,
+ supplying the appropriate `CTX_GPREG_Xn` reference, e.g.
+
+ uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+
+5. Implementing the standard SMC32 Functions that provide information about
+ the implementation of the service. These are the Call Count, Implementor
+ UID and Revision Details for each service documented in section 6 of the
+ [SMCCC].
+
+ The ARM Trusted Firmware expects owning entities to follow this
+ recommendation.
+
+5. Returning the result to the caller. The [SMCCC] allows for up to 256 bits
+ of return value in SMC64 using X0-X3 and 128 bits in SMC32 using W0-W3. The
+ framework provides a family of macros to set the multi-register return
+ value and complete the handler:
+
+ SMC_RET1(handle, x0);
+ SMC_RET2(handle, x0, x1);
+ SMC_RET3(handle, x0, x1, x2);
+ SMC_RET4(handle, x0, x1, x2, x3);
+
+The `reserved` parameter to the handler is reserved for future use and can be
+ignored. The value returned by a SMC handler is also reserved for future use -
+completion of the handler function must always be via one of the `SMC_RETn()`
+macros.
+
+NOTE: The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow
+all of the above requirements yet.
+
+
+7. Services that contain multiple sub-services
+-----------------------------------------------
+
+It is possible that a single owning entity implements multiple sub-services. For
+example, the Standard calls service handles `0x84000000`-`0x8400FFFF` and
+`0xC4000000`-`0xC400FFFF` functions. Within that range, the [PSCI] service
+handles the `0x84000000`-`0x8400001F` and `0xC4000000`-`0xC400001F` functions.
+In that respect, [PSCI] is a 'sub-service' of the Standard calls service. In
+future, there could be additional such sub-services in the Standard calls
+service which perform independent functions.
+
+In this situation it may be valuable to introduce a second level framework to
+enable independent implementation of sub-services. Such a framework might look
+very similar to the current runtime services framework, but using a different
+part of the SMC Function ID to identify the sub-service. Trusted Firmware does
+not provide such a framework at present.
+
+
+8. Secure-EL1 Payload Dispatcher service (SPD)
+-----------------------------------------------
+
+Services that handle SMC Functions targeting a Trusted OS, Trusted Application,
+or other Secure-EL1 Payload are special. These services need to manage the
+Secure-EL1 context, provide the _Secure Monitor_ functionality of switching
+between the normal and secure worlds, deliver SMC Calls through to Secure-EL1
+and generally manage the Secure-EL1 Payload through CPU power-state transitions.
+
+TODO: Provide details of the additional work required to implement a SPD and
+the BL3-1 support for these services. Or a reference to the document that will
+provide this information....
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2014, ARM Limited and Contributors. All rights reserved._
+
+
+[Firmware Design]: ./firmware-design.md
+
+[`services`]: ../services
+[`services/std_svc/psci`]: ../services/std_svc/psci
+[`std_svc_setup.c`]: ../services/std_svc/std_svc_setup.c
+[`runtime_svc.h`]: ../include/runtime_svc.h
+[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)"
diff --git a/docs/user-guide.md b/docs/user-guide.md
new file mode 100644
index 0000000..40a7955
--- /dev/null
+++ b/docs/user-guide.md
@@ -0,0 +1,841 @@
+ARM Trusted Firmware User Guide
+===============================
+
+Contents :
+
+1. Introduction
+2. Host machine requirements
+3. Tools
+4. Building the Trusted Firmware
+5. Obtaining the normal world software
+6. Running the software
+
+
+1. Introduction
+----------------
+This document describes how to build ARM Trusted Firmware and run it with a
+tested set of other software components using defined configurations on ARM
+Fixed Virtual Platform (FVP) models. It is possible to use other software
+components, configurations and platforms but that is outside the scope of this
+document.
+
+This document should be used in conjunction with the [Firmware Design].
+
+
+2. Host machine requirements
+-----------------------------
+
+The minimum recommended machine specification for building the software and
+running the FVP models is a dual-core processor running at 2GHz with 12GB of
+RAM. For best performance, use a machine with a quad-core processor running at
+2.6GHz with 16GB of RAM.
+
+The software has been tested on Ubuntu 12.04.04 (64-bit). Packages used
+for building the software were installed from that distribution unless
+otherwise specified.
+
+
+3. Tools
+---------
+
+The following tools are required to use the ARM Trusted Firmware:
+
+* `git` package to obtain source code
+
+* `ia32-libs` package
+
+* `build-essential` and `uuid-dev` packages for building UEFI and the Firmware
+ Image Package(FIP) tool
+
+* `bc` and `ncurses-dev` packages for building Linux
+
+* Baremetal GNU GCC tools. Verified packages can be downloaded from [Linaro]
+ [Linaro Toolchain]. The rest of this document assumes that the
+ `gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz` tools are used.
+
+ wget http://releases.linaro.org/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ tar -xf gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+
+* The Device Tree Compiler (DTC) included with Linux kernel 3.15-rc6 is used
+ to build the Flattened Device Tree (FDT) source files (`.dts` files)
+ provided with this software.
+
+* (Optional) For debugging, ARM [Development Studio 5 (DS-5)][DS-5] v5.18.
+
+
+4. Building the Trusted Firmware
+---------------------------------
+
+To build the software for the FVPs, follow these steps:
+
+1. Clone the ARM Trusted Firmware repository from GitHub:
+
+ git clone https://github.com/ARM-software/arm-trusted-firmware.git
+
+2. Change to the trusted firmware directory:
+
+ cd arm-trusted-firmware
+
+3. Set the compiler path, specify a Non-trusted Firmware image (BL3-3) and
+ build:
+
+ CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+ BL33=<path-to>/<bl33_image> \
+ make PLAT=fvp all fip
+
+ See the "Summary of build options" for information on available build
+ options.
+
+ By default this produces a release version of the build. To produce a debug
+ version instead, refer to the "Debugging options" section below. UEFI can be
+ used as the BL3-3 image, refer to the "Obtaining the normal world software"
+ section below. By default this won't compile the TSP in, refer to the
+ "Building the Test Secure Payload" section below.
+
+ The build process creates products in a `build` directory tree, building
+ the objects and binaries for each boot loader stage in separate
+ sub-directories. The following boot loader binary files are created from
+ the corresponding ELF files:
+
+ * `build/<platform>/<build-type>/bl1.bin`
+ * `build/<platform>/<build-type>/bl2.bin`
+ * `build/<platform>/<build-type>/bl31.bin`
+
+ ... where `<platform>` currently defaults to `fvp` and `<build-type>` is
+ either `debug` or `release`. A Firmare Image Package(FIP) will be created as
+ part of the build. It contains all boot loader images except for `bl1.bin`.
+
+ * `build/<platform>/<build-type>/fip.bin`
+
+ For more information on FIPs, see the "Firmware Image Package" section in
+ the [Firmware Design].
+
+4. Copy the `bl1.bin` and `fip.bin` binary files to the directory from which
+ the FVP will be launched. Symbolic links of the same names may be created
+ instead.
+
+5. (Optional) Build products for a specific build variant can be removed using:
+
+ make DEBUG=<D> PLAT=fvp clean
+
+ ... where `<D>` is `0` or `1`, as specified when building.
+
+ The build tree can be removed completely using:
+
+ make realclean
+
+### Summary of build options
+
+ARM Trusted Firmware build system supports the following build options. Unless
+mentioned otherwise, these options are expected to be specified at the build
+command line and are not to be modified in any component makefiles. Note that
+the build system doesn't track dependency for build options. Therefore, if any
+of the build options are changed from a previous build, a clean build must be
+performed.
+
+* `BL33`: Path to BL33 image in the host file system. This is mandatory for
+ `fip` target
+
+* `BL30`: Path to BL3-0 image in the host file system. This image is optional.
+ If a BL3-0 image is present then this option must be passed for the `fip`
+ target
+
+* `CROSS_COMPILE`: Prefix to tool chain binaries. Please refer to examples in
+ this document for usage
+
+* `DEBUG`: Chooses between a debug and release build. It can take either 0
+ (release) or 1 (debug) as values. 0 is the default
+
+* `NS_TIMER_SWITCH`: Enable save and restore for non-secure timer register
+ contents upon world switch. It can take either 0 (don't save and restore) or
+ 1 (do save and restore). 0 is the default. An SPD could set this to 1 if it
+ wants the timer registers to be saved and restored
+
+* `PLAT`: Choose a platform to build ARM Trusted Firmware for. The chosen
+ platform name must be the name of one of the directories under the `plat/`
+ directory other than `common`
+
+* `SPD`: Choose a Secure Payload Dispatcher component to be built into the
+ Trusted Firmware. The value should be the path to the directory containing
+ SPD source; the directory is expected to contain `spd.mk` makefile
+
+* `V`: Verbose build. If assigned anything other than 0, the build commands
+ are printed. Default is 0
+
+* `FVP_GIC_ARCH`: Choice of ARM GIC architecture version used by the FVP port
+ for implementing the platform GIC API. This API is used by the interrupt
+ management framework. Default is 2 i.e. version 2.0
+
+* `IMF_READ_INTERRUPT_ID`: Boolean flag used by the interrupt management
+ framework to enable passing of the interrupt id to its handler. The id is
+ 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
+the previous section. It is also possible to independently build the FIP
+creation tool and FIPs if required. To do this, follow these steps:
+
+Build the tool:
+
+ make -C tools/fip_create
+
+It is recommended to remove the build artifacts before rebuilding:
+
+ make -C tools/fip_create clean
+
+Create a Firmware package that contains existing FVP BL2 and BL3-1 images:
+
+ # fip_create --help to print usage information
+ # fip_create <fip_name> <images to add> [--dump to show result]
+ ./tools/fip_create/fip_create fip.bin --dump \
+ --bl2 build/fvp/debug/bl2.bin --bl31 build/fvp/debug/bl31.bin
+
+ Firmware Image Package ToC:
+ ---------------------------
+ - Trusted Boot Firmware BL2: offset=0x88, size=0x81E8
+ file: 'build/fvp/debug/bl2.bin'
+ - EL3 Runtime Firmware BL3-1: offset=0x8270, size=0xC218
+ file: 'build/fvp/debug/bl31.bin'
+ ---------------------------
+ Creating "fip.bin"
+
+View the contents of an existing Firmware package:
+
+ ./tools/fip_create/fip_create fip.bin --dump
+
+ Firmware Image Package ToC:
+ ---------------------------
+ - Trusted Boot Firmware BL2: offset=0x88, size=0x81E8
+ - EL3 Runtime Firmware BL3-1: offset=0x8270, size=0xC218
+ ---------------------------
+
+Existing package entries can be individially updated:
+
+ # Change the BL2 from Debug to Release version
+ ./tools/fip_create/fip_create fip.bin --dump \
+ --bl2 build/fvp/release/bl2.bin
+
+ Firmware Image Package ToC:
+ ---------------------------
+ - Trusted Boot Firmware BL2: offset=0x88, size=0x7240
+ file: 'build/fvp/release/bl2.bin'
+ - EL3 Runtime Firmware BL3-1: offset=0x72C8, size=0xC218
+ ---------------------------
+ Updating "fip.bin"
+
+
+### Debugging options
+
+To compile a debug version and make the build more verbose use
+
+ CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+ BL33=<path-to>/<bl33_image> \
+ make PLAT=fvp DEBUG=1 V=1 all fip
+
+AArch64 GCC uses DWARF version 4 debugging symbols by default. Some tools (for
+example DS-5) might not support this and may need an older version of DWARF
+symbols to be emitted by GCC. This can be achieved by using the
+`-gdwarf-<version>` flag, with the version being set to 2 or 3. Setting the
+version to 2 is recommended for DS-5 versions older than 5.16.
+
+When debugging logic problems it might also be useful to disable all compiler
+optimizations by using `-O0`.
+
+NOTE: Using `-O0` could cause output images to be larger and base addresses
+might need to be recalculated (see the later memory layout section).
+
+Extra debug options can be passed to the build system by setting `CFLAGS`:
+
+ CFLAGS='-O0 -gdwarf-2' \
+ CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+ BL33=<path-to>/<bl33_image> \
+ make PLAT=fvp DEBUG=1 V=1 all fip
+
+
+NOTE: The Foundation FVP does not provide a debugger interface.
+
+
+### Building the Test Secure Payload
+
+The TSP is coupled with a companion runtime service in the BL3-1 firmware,
+called the TSPD. Therefore, if you intend to use the TSP, the BL3-1 image
+must be recompiled as well. For more information on SPs and SPDs, see the
+"Secure-EL1 Payloads and Dispatchers" section in the [Firmware Design].
+
+First clean the Trusted Firmware build directory to get rid of any previous
+BL3-1 binary. Then to build the TSP image and include it into the FIP use:
+
+ CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+ BL33=<path-to>/<bl33_image> \
+ make PLAT=fvp SPD=tspd all fip
+
+An additional boot loader binary file is created in the `build` directory:
+
+ * `build/<platform>/<build-type>/bl32.bin`
+
+The Firmware Package contains this new image:
+
+ Firmware Image Package ToC:
+ ---------------------------
+ - Trusted Boot Firmware BL2: offset=0xD8, size=0x6000
+ file: './build/fvp/release/bl2.bin'
+ - EL3 Runtime Firmware BL3-1: offset=0x60D8, size=0x9000
+ file: './build/fvp/release/bl31.bin'
+ - Secure Payload BL3-2 (Trusted OS): offset=0xF0D8, size=0x3000
+ file: './build/fvp/release/bl32.bin'
+ - Non-Trusted Firmware BL3-3: offset=0x120D8, size=0x280000
+ file: '../FVP_AARCH64_EFI.fd'
+ ---------------------------
+ Creating "build/fvp/release/fip.bin"
+
+On FVP, the TSP binary runs from Trusted SRAM by default. It is also possible
+to run it from Trusted DRAM. This is controlled by the build configuration
+`TSP_RAM_LOCATION`:
+
+ CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+ BL33=<path-to>/<bl33_image> \
+ make PLAT=fvp SPD=tspd TSP_RAM_LOCATION=tdram all fip
+
+
+### Checking source code style
+
+When making changes to the source for submission to the project, the source
+must be in compliance with the Linux style guide, and to assist with this check
+the project Makefile contains two targets, which both utilise the checkpatch.pl
+script that ships with the Linux source tree.
+
+To check the entire source tree, you must first download a copy of checkpatch.pl
+(or the full Linux source), set the CHECKPATCH environment variable to point to
+the script and build the target checkcodebase:
+
+ make CHECKPATCH=../linux/scripts/checkpatch.pl checkcodebase
+
+To just check the style on the files that differ between your local branch and
+the remote master, use:
+
+ make CHECKPATCH=../linux/scripts/checkpatch.pl checkpatch
+
+If you wish to check your patch against something other than the remote master,
+set the BASE_COMMIT variable to your desired branch. By default, BASE_COMMIT
+is set to 'origin/master'.
+
+
+5. Obtaining the normal world software
+---------------------------------------
+
+### Obtaining EDK2
+
+Potentially any kind of non-trusted firmware may be used with the ARM Trusted
+Firmware but the software has only been tested with the EFI Development Kit 2
+(EDK2) open source implementation of the UEFI specification.
+
+Clone the [EDK2 source code][EDK2] from GitHub. This version supports the Base
+and Foundation FVPs:
+
+ git clone -n https://github.com/tianocore/edk2.git
+ cd edk2
+ git checkout 129ff94661bd3a6c759b1e154c143d0136bedc7d
+
+
+To build the software to be compatible with Foundation and Base FVPs, follow
+these steps:
+
+1. Copy build config templates to local workspace
+
+ # in edk2/
+ . edksetup.sh
+
+2. Build the EDK2 host tools
+
+ make -C BaseTools clean
+ make -C BaseTools
+
+3. Build the EDK2 software
+
+ CROSS_COMPILE=<absolute-path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+ make -f ArmPlatformPkg/Scripts/Makefile EDK2_ARCH=AARCH64 \
+ EDK2_DSC=ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc \
+ EDK2_TOOLCHAIN=ARMGCC EDK2_MACROS="-n 6 -D ARM_FOUNDATION_FVP=1"
+
+ The EDK2 binary for use with the ARM Trusted Firmware can then be found
+ here:
+
+ Build/ArmVExpress-FVP-AArch64/DEBUG_ARMGCC/FV/FVP_AARCH64_EFI.fd
+
+ This will build EDK2 for the default settings as used by the FVPs. The EDK2
+ binary `FVP_AARCH64_EFI.fd` should be specified as `BL33` in in the `make`
+ command line when building the Trusted Firmware. See the "Building the
+ Trusted Firmware" section above.
+
+4. (Optional) To boot Linux using a VirtioBlock file-system, the command line
+ passed from EDK2 to the Linux kernel must be modified as described in the
+ "Obtaining a root file-system" section below.
+
+5. (Optional) If legacy GICv2 locations are used, the EDK2 platform description
+ must be updated. This is required as EDK2 does not support probing for the
+ GIC location. To do this, first clean the EDK2 build directory.
+
+ make -f ArmPlatformPkg/Scripts/Makefile EDK2_ARCH=AARCH64 \
+ EDK2_DSC=ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc \
+ EDK2_TOOLCHAIN=ARMGCC clean
+
+ Then rebuild EDK2 as described in step 3, using the following flag:
+
+ -D ARM_FVP_LEGACY_GICV2_LOCATION=1
+
+ Finally rebuild the Trusted Firmware to generate a new FIP using the
+ instructions in the "Building the Trusted Firmware" section.
+
+
+### Obtaining a Linux kernel
+
+The software has been verified using a Linux kernel based on version 3.15-rc6.
+Patches have been applied in order to enable the CPU idle feature.
+
+Preparing a Linux kernel for use on the FVPs with CPU idle support can
+be done as follows (GICv2 support only):
+
+1. Clone Linux:
+
+ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+
+ Not all CPU idle features are included in the mainline kernel yet. To
+ use these, add the patches from Sudeep Holla's kernel:
+
+ cd linux
+ git remote add -f --tags arm64_idle_v3.15-rc6 git://linux-arm.org/linux-skn.git
+ git checkout -b cpuidle arm64_idle_v3.15-rc6
+
+2. Build with the Linaro GCC tools.
+
+ # in linux/
+ make mrproper
+ make ARCH=arm64 defconfig
+
+ # Enable CPU idle
+ make ARCH=arm64 menuconfig
+ # CPU Power Management ---> CPU Idle ---> [*] CPU idle PM support
+ # CPU Power Management ---> CPU Idle ---> ARM64 CPU Idle Drivers ---> [*] Generic ARM64 CPU idle Driver
+
+ CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+ make -j6 ARCH=arm64
+
+3. Copy the Linux image `arch/arm64/boot/Image` to the working directory from
+ where the FVP is launched. Alternatively a symbolic link may be used.
+
+### Obtaining the Flattened Device Trees
+
+Depending on the FVP configuration and Linux configuration used, different
+FDT files are required. FDTs for the Foundation and Base FVPs can be found in
+the Trusted Firmware source directory under `fdts/`. The Foundation FVP has a
+subset of the Base FVP components. For example, the Foundation FVP lacks CLCD
+and MMC support, and has only one CPU cluster.
+
+* `fvp-base-gicv2-psci.dtb`
+
+ (Default) For use with both AEMv8 and Cortex-A57-A53 Base FVPs with
+ Base memory map configuration.
+
+* `fvp-base-gicv2legacy-psci.dtb`
+
+ For use with AEMv8 Base FVP with legacy VE GIC memory map configuration.
+
+* `fvp-base-gicv3-psci.dtb`
+
+ For use with both AEMv8 and Cortex-A57-A53 Base FVPs with Base memory map
+ configuration and Linux GICv3 support.
+
+* `fvp-foundation-gicv2-psci.dtb`
+
+ (Default) For use with Foundation FVP with Base memory map configuration.
+
+* `fvp-foundation-gicv2legacy-psci.dtb`
+
+ For use with Foundation FVP with legacy VE GIC memory map configuration.
+
+* `fvp-foundation-gicv3-psci.dtb`
+
+ For use with Foundation FVP with Base memory map configuration and Linux
+ GICv3 support.
+
+
+Copy the chosen FDT blob as `fdt.dtb` to the directory from which the FVP
+is launched. Alternatively a symbolic link may be used.
+
+### Obtaining a root file-system
+
+To prepare a Linaro LAMP based Open Embedded file-system, the following
+instructions can be used as a guide. The file-system can be provided to Linux
+via VirtioBlock or as a RAM-disk. Both methods are described below.
+
+#### Prepare VirtioBlock
+
+To prepare a VirtioBlock file-system, do the following:
+
+1. Download and unpack the disk image.
+
+ NOTE: The unpacked disk image grows to 3 GiB in size.
+
+ wget http://releases.linaro.org/14.04/openembedded/aarch64/vexpress64-openembedded_lamp-armv8-gcc-4.8_20140417-630.img.gz
+ gunzip vexpress64-openembedded_lamp-armv8-gcc-4.8_20140417-630.img.gz
+
+2. Make sure the Linux kernel has Virtio support enabled using
+ `make ARCH=arm64 menuconfig`.
+
+ Device Drivers ---> Virtio drivers ---> <*> Platform bus driver for memory mapped virtio devices
+ Device Drivers ---> [*] Block devices ---> <*> Virtio block driver
+ File systems ---> <*> The Extended 4 (ext4) filesystem
+
+ If some of these configurations are missing, enable them, save the kernel
+ configuration, then rebuild the kernel image using the instructions
+ provided in the section "Obtaining a Linux kernel".
+
+3. Change the Kernel command line to include `root=/dev/vda2`. This can either
+ be done in the EDK2 boot menu or in the platform file. Editing the platform
+ file and rebuilding EDK2 will make the change persist. To do this:
+
+ 1. In EDK2, edit the following file:
+
+ ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc
+
+ 2. Add `root=/dev/vda2` to:
+
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"<Other default options>"
+
+ 3. Remove the entry:
+
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|""
+
+ 4. Rebuild EDK2 (see "Obtaining UEFI" section above).
+
+4. The file-system image file should be provided to the model environment by
+ passing it the correct command line option. In the FVPs the following
+ option should be provided in addition to the ones described in the
+ "Running the software" section below.
+
+ NOTE: A symbolic link to this file cannot be used with the FVP; the path
+ to the real file must be provided.
+
+ On the Base FVPs:
+
+ -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
+
+ On the Foundation FVP:
+
+ --block-device="<path-to>/<file-system-image>"
+
+
+5. Ensure that the FVP doesn't output any error messages. If the following
+ error message is displayed:
+
+ ERROR: BlockDevice: Failed to open "<path-to>/<file-system-image>"!
+
+ then make sure the path to the file-system image in the model parameter is
+ correct and that read permission is correctly set on the file-system image
+ file.
+
+#### Prepare RAM-disk
+
+To prepare a RAM-disk root file-system, do the following:
+
+1. Download the file-system image:
+
+ wget http://releases.linaro.org/14.04/openembedded/aarch64/linaro-image-lamp-genericarmv8-20140417-667.rootfs.tar.gz
+
+2. Modify the Linaro image:
+
+ # Prepare for use as RAM-disk. Normally use MMC, NFS or VirtioBlock.
+ # Be careful, otherwise you could damage your host file-system.
+ mkdir tmp; cd tmp
+ sudo sh -c "zcat ../linaro-image-lamp-genericarmv8-20140417-667.rootfs.tar.gz | cpio -id"
+ sudo ln -s sbin/init .
+ sudo sh -c "echo 'devtmpfs /dev devtmpfs mode=0755,nosuid 0 0' >> etc/fstab"
+ sudo sh -c "find . | cpio --quiet -H newc -o | gzip -3 -n > ../filesystem.cpio.gz"
+ cd ..
+
+3. Copy the resultant `filesystem.cpio.gz` to the directory where the FVP is
+ launched from. Alternatively a symbolic link may be used.
+
+
+6. Running the software
+------------------------
+
+This version of the ARM Trusted Firmware has been tested on the following ARM
+FVPs (64-bit versions only).
+
+* `Foundation_v8` (Version 2.0, Build 0.8.5206)
+* `FVP_Base_AEMv8A-AEMv8A` (Version 5.6, Build 0.8.5602)
+* `FVP_Base_Cortex-A57x4-A53x4` (Version 5.6, Build 0.8.5602)
+* `FVP_Base_Cortex-A57x1-A53x1` (Version 5.6, Build 0.8.5602)
+* `FVP_Base_Cortex-A57x2-A53x4` (Version 5.6, Build 0.8.5602)
+
+NOTE: The software will not work on Version 1.0 of the Foundation FVP.
+The commands below would report an `unhandled argument` error in this case.
+
+Please refer to the FVP documentation for a detailed description of the model
+parameter options. A brief description of the important ones that affect the
+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 with reset to BL1 entrypoint
+
+The following `Foundation_v8` parameters should be used to boot Linux with
+4 CPUs using the ARM Trusted Firmware.
+
+NOTE: Using the `--block-device` parameter is not necessary if a Linux RAM-disk
+file-system is used (see the "Obtaining a File-system" section above).
+
+NOTE: The `--data="<path to FIP binary>"@0x8000000` parameter is used to load a
+Firmware Image Package at the start of NOR FLASH0 (see the "Building the
+Trusted Firmware" section above).
+
+ <path-to>/Foundation_v8 \
+ --cores=4 \
+ --no-secure-memory \
+ --visualization \
+ --gicv3 \
+ --data="<path-to>/<bl1-binary>"@0x0 \
+ --data="<path-to>/<FIP-binary>"@0x8000000 \
+ --block-device="<path-to>/<file-system-image>"
+
+The default use-case for the Foundation FVP is to enable the GICv3 device in
+the model but use the GICv2 FDT, in order for Linux to drive the GIC in GICv2
+emulation mode.
+
+The memory mapped addresses `0x0` and `0x8000000` correspond to the start of
+trusted ROM and NOR FLASH0 respectively.
+
+### Notes regarding Base FVP configuration options
+
+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).
+
+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.
+
+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).
+
+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.
+
+
+### 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 \
+ -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 bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
+ -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 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.
+
+ <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 bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
+ -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
+following addresses. The Foundation FVP also supports these addresses when
+configured for GICv3 in GICv2 emulation mode.
+
+ GICv2 Distributor Interface 0x2f000000
+ GICv2 CPU Interface 0x2c000000
+ GICv2 Virtual CPU Interface 0x2c010000
+ GICv2 Hypervisor Interface 0x2c02f000
+
+The AEMv8 Base FVP can be configured to support GICv2 at addresses
+corresponding to the legacy (Versatile Express) memory map as follows. These are
+the default addresses when using the Foundation FVP in GICv2 mode.
+
+ GICv2 Distributor Interface 0x2c001000
+ GICv2 CPU Interface 0x2c002000
+ GICv2 Virtual CPU Interface 0x2c004000
+ GICv2 Hypervisor Interface 0x2c006000
+
+The choice of memory map is reflected in the build variant field (bits[15:12])
+in the `SYS_ID` register (Offset `0x0`) in the Versatile Express System
+registers memory map (`0x1c010000`).
+
+* `SYS_ID.Build[15:12]`
+
+ `0x1` corresponds to the presence of the Base GIC memory map. This is the
+ default value on the Base FVPs.
+
+* `SYS_ID.Build[15:12]`
+
+ `0x0` corresponds to the presence of the Legacy VE GIC memory map. This is
+ the default value on the Foundation FVP.
+
+This register can be configured as described in the following sections.
+
+NOTE: If the legacy VE GIC memory map is used, then the corresponding FDT and
+BL3-3 images should be used.
+
+#### Configuring AEMv8 Foundation FVP GIC for legacy VE memory map
+
+The following parameters configure the Foundation FVP to use GICv2 with the
+legacy VE memory map:
+
+ <path-to>/Foundation_v8 \
+ --cores=4 \
+ --no-secure-memory \
+ --visualization \
+ --no-gicv3 \
+ --data="<path-to>/<bl1-binary>"@0x0 \
+ --data="<path-to>/<FIP-binary>"@0x8000000 \
+ --block-device="<path-to>/<file-system-image>"
+
+Explicit configuration of the `SYS_ID` register is not required.
+
+#### Configuring AEMv8 Base FVP GIC for legacy VE memory map
+
+The following parameters configure the AEMv8 Base FVP to use GICv2 with the
+legacy VE memory map. They must added to the parameters described in the
+"Running on the AEMv8 Base FVP" section above:
+
+ -C cluster0.gic.GICD-offset=0x1000 \
+ -C cluster0.gic.GICC-offset=0x2000 \
+ -C cluster0.gic.GICH-offset=0x4000 \
+ -C cluster0.gic.GICH-other-CPU-offset=0x5000 \
+ -C cluster0.gic.GICV-offset=0x6000 \
+ -C cluster0.gic.PERIPH-size=0x8000 \
+ -C cluster1.gic.GICD-offset=0x1000 \
+ -C cluster1.gic.GICC-offset=0x2000 \
+ -C cluster1.gic.GICH-offset=0x4000 \
+ -C cluster1.gic.GICH-other-CPU-offset=0x5000 \
+ -C cluster1.gic.GICV-offset=0x6000 \
+ -C cluster1.gic.PERIPH-size=0x8000 \
+ -C gic_distributor.GICD-alias=0x2c001000 \
+ -C bp.variant=0x0
+
+The `bp.variant` parameter corresponds to the build variant field of the
+`SYS_ID` register. Setting this to `0x0` allows the ARM Trusted Firmware to
+detect the legacy VE memory map while configuring the GIC.
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._
+
+
+[Firmware Design]: ./firmware-design.md
+
+[ARM FVP website]: http://www.arm.com/fvp
+[Linaro Toolchain]: http://releases.linaro.org/13.11/components/toolchain/binaries/
+[EDK2]: http://github.com/tianocore/edk2
+[DS-5]: http://www.arm.com/products/tools/software-tools/ds-5/index.php