Merge pull request #471 from sandrine-bailleux/sb/reset-doc-v2

Introduce the ARM TF reset design document (v2)
diff --git a/docs/diagrams/default_reset_code.png b/docs/diagrams/default_reset_code.png
new file mode 100644
index 0000000..e7e0d85
--- /dev/null
+++ b/docs/diagrams/default_reset_code.png
Binary files differ
diff --git a/docs/diagrams/generate_reset_images.sh b/docs/diagrams/generate_reset_images.sh
new file mode 100755
index 0000000..eef5648
--- /dev/null
+++ b/docs/diagrams/generate_reset_images.sh
@@ -0,0 +1,41 @@
+#! /bin/bash
+
+#
+# This script generates the image files used in the ARM Trusted Firmware Reset
+# Design document from the 'reset_code_flow.dia' file.
+#
+# The PNG files in the present directory have been generated using Dia version
+# 0.97.2, which can be obtained from https://wiki.gnome.org/Apps/Dia/Download
+#
+
+set -e
+
+# Usage: generate_image <layers> <image_filename>
+function generate_image
+{
+	dia				\
+		--show-layers=$1	\
+		--filter=png		\
+		--export=$2		\
+		reset_code_flow.dia
+
+}
+
+# The 'reset_code_flow.dia' file is organized in several layers.
+# Each image is generated by combining and exporting the appropriate set of
+# layers.
+generate_image								\
+	Frontground,Background,cpu_type_check,boot_type_check		\
+	default_reset_code.png
+
+generate_image								\
+	Frontground,Background,no_cpu_type_check,boot_type_check	\
+	reset_code_no_cpu_check.png
+
+generate_image								\
+	Frontground,Background,cpu_type_check,no_boot_type_check	\
+	reset_code_no_boot_type_check.png
+
+generate_image								\
+	Frontground,Background,no_cpu_type_check,no_boot_type_check	\
+	reset_code_no_checks.png
diff --git a/docs/diagrams/reset_code_flow.dia b/docs/diagrams/reset_code_flow.dia
new file mode 100644
index 0000000..5de00da
--- /dev/null
+++ b/docs/diagrams/reset_code_flow.dia
Binary files differ
diff --git a/docs/diagrams/reset_code_no_boot_type_check.png b/docs/diagrams/reset_code_no_boot_type_check.png
new file mode 100644
index 0000000..8ce7e97
--- /dev/null
+++ b/docs/diagrams/reset_code_no_boot_type_check.png
Binary files differ
diff --git a/docs/diagrams/reset_code_no_checks.png b/docs/diagrams/reset_code_no_checks.png
new file mode 100644
index 0000000..8a02f0f
--- /dev/null
+++ b/docs/diagrams/reset_code_no_checks.png
Binary files differ
diff --git a/docs/diagrams/reset_code_no_cpu_check.png b/docs/diagrams/reset_code_no_cpu_check.png
new file mode 100644
index 0000000..8b05ea4
--- /dev/null
+++ b/docs/diagrams/reset_code_no_cpu_check.png
Binary files differ
diff --git a/docs/firmware-design.md b/docs/firmware-design.md
index d066fc3..fb94f56 100644
--- a/docs/firmware-design.md
+++ b/docs/firmware-design.md
@@ -43,13 +43,16 @@
 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 starts when the platform is physically turned on. If
+`COLD_BOOT_SINGLE_CPU=0`, 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.
+
+Refer to the [Reset Design] for more information on the effect of the
+`COLD_BOOT_SINGLE_CPU` platform build option.
 
 The cold boot path in this implementation of the ARM Trusted Firmware is divided
 into five steps (in order of execution):
@@ -78,8 +81,6 @@
 *   initialization and execution of the first three stages during cold boot
 *   specification of the BL31 entrypoint requirements for use by alternative
     Trusted Boot Firmware in place of the provided BL1 and BL2
-*   changes in BL31 behavior when using the `RESET_TO_BL31` option which
-    allows BL31 to run without BL1 and BL2
 
 
 ### BL1
@@ -105,6 +106,10 @@
 the [Porting Guide]) while the primary CPU executes the remaining cold boot path
 as described in the following sections.
 
+This step only applies when `PROGRAMMABLE_RESET_ADDRESS=0`. Refer to the
+[Reset Design] for more information on the effect of the
+`PROGRAMMABLE_RESET_ADDRESS` platform build option.
+
 #### Architectural initialization
 
 BL1 performs minimal architectural initialization as follows.
@@ -509,53 +514,6 @@
 platform power management code is then invoked as required to initialize all
 necessary system, cluster and CPU resources.
 
-
-### Using BL31 as the CPU reset vector
-
-On some platforms the runtime firmware (BL3x 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 BL31 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 BL31 entrypoint to support this use case.
-
-In this configuration, the platform's Trusted Boot Firmware must ensure that
-BL31 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 BL3x images required and
-providing entry point information for them to BL31. Loading these images might
-be done by the Trusted Boot Firmware or by platform code in BL31.
-
-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 BL31
-functionality:
-
-#### Determination of boot path
-
-In this configuration, BL31 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 BL31 initialization, as described below.
-
-#### Platform initialization
-
-In this configuration, when the CPU resets to BL31 there are no parameters
-that can be passed in registers by previous boot stages. Instead, the platform
-code in BL31 needs to know, or be able to determine, the location of the BL32
-(if required) and BL33 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 BL31 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
 ----------------------------------
@@ -1767,5 +1725,6 @@
 [UUID]:             https://tools.ietf.org/rfc/rfc4122.txt "A Universally Unique IDentifier (UUID) URN Namespace"
 [User Guide]:       ./user-guide.md
 [Porting Guide]:    ./porting-guide.md
+[Reset Design]:     ./reset-design.md
 [INTRG]:            ./interrupt-framework-design.md
 [CPUBM]:            ./cpu-specific-build-macros.md.md
diff --git a/docs/reset-design.md b/docs/reset-design.md
new file mode 100644
index 0000000..3e45d41
--- /dev/null
+++ b/docs/reset-design.md
@@ -0,0 +1,172 @@
+ARM Trusted Firmware Reset Design
+=================================
+
+1.  [Introduction](#1--introduction)
+2.  [General reset code flow](#2--general-reset-code-flow)
+3.  [Programmable CPU reset address](#3--programmable-cpu-reset-address)
+4.  [Cold boot on a single CPU](#4--cold-boot-on-a-single-cpu)
+5.  [Programmable CPU reset address, Cold boot on a single CPU](#5--programmable-cpu-reset-address-cold-boot-on-a-single-cpu)
+6.  [Using BL31 entrypoint as the reset address](#6--using-bl31-entrypoint-as-the-reset-address)
+
+
+1.  Introduction
+----------------
+
+This document describes the high-level design of the framework to handle CPU
+resets in ARM Trusted Firmware. It also describes how the platform integrator
+can tailor this code to the system configuration to some extent, resulting in a
+simplified and more optimised boot flow.
+
+This document should be used in conjunction with the [Firmware Design], which
+provides greater implementation details around the reset code, specifically
+for the cold boot path.
+
+
+2.  General reset code flow
+---------------------------
+
+The ARM Trusted Firmware (TF) reset code is implemented in BL1 by default. The
+following high-level diagram illustrates this:
+
+![Default reset code flow](diagrams/default_reset_code.png?raw=true)
+
+This diagram shows the default, unoptimised reset flow. Depending on the system
+configuration, some of these steps might be unnecessary. The following sections
+guide the platform integrator by indicating which build options exclude which
+steps, depending on the capability of the platform.
+
+Note: If BL31 is used as the Trusted Firmware entry point instead of BL1, the
+diagram above is still relevant, as all these operations will occur in BL31 in
+this case. Please refer to section 6 "Using BL31 entrypoint as the reset
+address" for more information.
+
+
+3.  Programmable CPU reset address
+----------------------------------
+
+By default, the TF assumes that the CPU reset address is not programmable.
+Therefore, all CPUs start at the same address (typically address 0) whenever
+they reset. Further logic is then required to identify whether it is a cold or
+warm boot to direct CPUs to the right execution path.
+
+If the reset vector address (reflected in the reset vector base address register
+`RVBAR_EL3`) is programmable then it is possible to make each CPU start directly
+at the right address, both on a cold and warm reset. Therefore, the boot type
+detection can be skipped, resulting in the following boot flow:
+
+![Reset code flow with programmable reset address](
+diagrams/reset_code_no_boot_type_check.png?raw=true)
+
+To enable this boot flow, compile the TF with `PROGRAMMABLE_RESET_ADDRESS=1`.
+This option only affects the TF reset image, which is BL1 by default or BL31 if
+`RESET_TO_BL31=1`.
+
+On both the FVP and Juno platforms, the reset vector address is not programmable
+so both ports use `PROGRAMMABLE_RESET_ADDRESS=0`.
+
+
+4.  Cold boot on a single CPU
+-----------------------------
+
+By default, the TF assumes that several CPUs may be released out of reset.
+Therefore, the cold boot code has to arbitrate access to hardware resources
+shared amongst CPUs. This is done by nominating one of the CPUs as the primary,
+which is responsible for initialising shared hardware and coordinating the boot
+flow with the other CPUs.
+
+If the platform guarantees that only a single CPU will ever be brought up then
+no arbitration is required. The notion of primary/secondary CPU itself no longer
+applies. This results in the following boot flow:
+
+![Reset code flow with single CPU released out of reset](
+diagrams/reset_code_no_cpu_check.png?raw=true)
+
+To enable this boot flow, compile the TF with `COLD_BOOT_SINGLE_CPU=1`. This
+option only affects the TF reset image, which is BL1 by default or BL31 if
+`RESET_TO_BL31=1`.
+
+On both the FVP and Juno platforms, although only one core is powered up by
+default, there are platform-specific ways to release any number of cores out of
+reset. Therefore, both platform ports use `COLD_BOOT_SINGLE_CPU=0`.
+
+
+5.  Programmable CPU reset address, Cold boot on a single CPU
+-------------------------------------------------------------
+
+It is obviously possible to combine both optimisations on platforms that have
+a programmable CPU reset address and which release a single CPU out of reset.
+This results in the following boot flow:
+
+![Reset code flow with programmable reset address and single CPU released out of
+reset](diagrams/reset_code_no_checks.png?raw=true)
+
+To enable this boot flow, compile the TF with both `COLD_BOOT_SINGLE_CPU=1`
+and `PROGRAMMABLE_RESET_ADDRESS=1`. These options only affect the TF reset
+image, which is BL1 by default or BL31 if `RESET_TO_BL31=1`.
+
+
+6.  Using BL31 entrypoint as the reset address
+----------------------------------------------
+
+On some platforms the runtime firmware (BL3x images) for the application
+processors are loaded by some 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 BL31 which eliminates the need for BL1 and BL2.
+
+TF provides a build-time option `RESET_TO_BL31` that includes some additional
+logic in the BL31 entry point to support this use case.
+
+In this configuration, the platform's Trusted Boot Firmware must ensure that
+BL31 is loaded to its runtime address, which must match the CPU's `RVBAR_EL3`
+reset vector base address, before the application processor is powered on.
+Additionally, platform software is responsible for loading the other BL3x images
+required and providing entry point information for them to BL31. Loading these
+images might be done by the Trusted Boot Firmware or by platform code in BL31.
+
+Although the ARM FVP platform does not support programming the reset base
+address dynamically at run-time, it is possible to set the initial value of the
+`RVBAR_EL3` register at start-up. This feature is provided on the Base FVP only.
+It allows the ARM FVP port to support 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.
+
+Although technically it would be possible to program the reset base address with
+the right support in the SCP firmware, this is currently not implemented so the
+Juno port doesn't support the `RESET_TO_BL31` configuration.
+
+The `RESET_TO_BL31` configuration requires some additions and changes in the
+BL31 functionality:
+
+#### Determination of boot path
+
+In this configuration, BL31 uses the same reset framework and code as the one
+described for BL1 above. Therefore, it is affected by the
+`PROGRAMMABLE_RESET_ADDRESS` and `COLD_BOOT_SINGLE_CPU` build options in the
+same way.
+
+In the default, unoptimised BL31 reset flow, 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 BL31 initialization, as described below.
+
+#### Platform initialization
+
+In this configuration, when the CPU resets to BL31 there are no parameters that
+can be passed in registers by previous boot stages. Instead, the platform code
+in BL31 needs to know, or be able to determine, the location of the BL32 (if
+required) and BL33 images and provide this information in response to the
+`bl31_plat_get_next_image_ep_info()` function.
+
+Additionally, platform software is responsible for carrying out any security
+initialisation, for example programming a TrustZone address space controller.
+This might be done by the Trusted Boot Firmware or by platform code in BL31.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2015, ARM Limited and Contributors. All rights reserved._
+
+
+[User Guide]:       user-guide.md
+[Firmware Design]:  firmware-design.md