Add EL3 runtime services and SPD documentation
authorDan Handley <dan.handley@arm.com>
Tue, 25 Feb 2014 19:09:48 +0000 (19:09 +0000)
committerDan Handley <dan.handley@arm.com>
Fri, 28 Feb 2014 17:51:07 +0000 (17:51 +0000)
1. Add design information on EL3 runtime services and
Secure-EL1 Payload Dispatchers (SPD) to
firmware-design.md.

2. Create new EL3 runtime service writer's guide
(rt-svc-writers-guide.md) to ease creation of new
runtime services.

Change-Id: I670aeb5fc246e25c6e599a15139aac886a0074fd

docs/diagrams/rt-svc-descs-layout.png [new file with mode: 0644]
docs/firmware-design.md
docs/rt-svc-writers-guide.md [new file with mode: 0644]

diff --git a/docs/diagrams/rt-svc-descs-layout.png b/docs/diagrams/rt-svc-descs-layout.png
new file mode 100644 (file)
index 0000000..1a9fa5b
Binary files /dev/null and b/docs/diagrams/rt-svc-descs-layout.png differ
index 89dd45f0a3e722095d57eae652802a9add6c65cc..4e7890e8897070975199cfabf388cdbdc0e4aeef 100644 (file)
@@ -4,11 +4,14 @@ ARM Trusted Firmware Design
 Contents :
 
 1.  Introduction
-2.  Cold Boot
-3.  Memory layout on FVP platforms
-4.  Firmware Image Package (FIP)
-5.  Code Structure
-6.  References
+2.  Cold boot
+3.  EL3 runtime services framework
+4.  Power State Coordination Interface
+5.  Secure-EL1 Payloads and Dispatchers
+6.  Memory layout on FVP platforms
+7.  Firmware Image Package (FIP)
+8.  Code Structure
+9.  References
 
 
 1.  Introduction
@@ -29,7 +32,7 @@ instruction. The SMC instruction must be used as mandated by the [SMC Calling
 Convention PDD][SMCCC] [3].
 
 
-2.  Cold Boot
+2.  Cold boot
 -------------
 
 The cold boot path starts when the platform is physically turned on. One of
@@ -334,59 +337,330 @@ memory address populated by BL2.
 
 *   Runtime services initialization:
 
-    The only runtime service implemented by BL3-1 is PSCI. The complete PSCI API
-    is not yet implemented. The following functions are currently implemented:
+    The runtime service framework and its initialization is described in the
+    "EL3 runtime services framework" section below.
 
-    -   `PSCI_VERSION`
-    -   `CPU_OFF`
-    -   `CPU_ON`
-    -   `CPU_SUSPEND`
-    -   `AFFINITY_INFO`
+    Details about the PSCI service are provided in the "Power State Coordination
+    Interface" section below.
 
-    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.
+*   BL3-2 (Secure-EL1 Payload) image initialization
 
-    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].
+    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.
 
-    -   `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)
+    Details on BL3-2 initialization and the SPD's role are described in the
+    "Secure-EL1 Payloads and Dispatchers" section below.
 
-    The following unsupported functions do not return and signal an assertion
-    failure if invoked.
+*   BL3-3 (Non-trusted Firmware) execution
 
-    -   `SYSTEM_OFF`
-    -   `SYSTEM_RESET`
+    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).
 
-    BL3-1 returns the error code `-1` if an SMC is raised for any other runtime
-    service. This behavior is mandated by the [SMC calling convention PDD]
-    [SMCCC].
 
+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. Hence BL3-1 implements:
+
+1.  `bl31_plat_get_bl32_mem_layout()` to return the extents of memory
+    available for BL3-2's use as communicated by BL2.
+
+2.  `bl31_get_next_image_info(uint32_t security_state)` to return a reference
+    to the `el_change_info` structure corresponding to the next image which will
+    be run in the specified security state. The SPD uses this api with the
+    secure security state as the parameter to get entry related information about
+    BL3-2.
+
+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(meminfo *bl32_meminfo);
+
+and is registered using the `bl31_register_bl32_init()` function.
 
-### BL3-2 (Secure Payload) image initialization
+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):
 
-BL2 is responsible for loading a BL3-2 image in memory specified by the platform.
-BL3-1 provides an api that uses the entrypoint and memory layout information for
-the BL3-2 image provided by BL2 to initialise BL3-2 in S-EL1.
+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.
 
-### Normal world software execution
+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.
 
-BL3-1 uses the entrypoint information provided by BL2 to jump to the normal
-world software image (BL3-3) at the highest available Exception Level (EL2 if
-available, otherwise EL1).
+    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.
 
 
-3.  Memory layout on FVP platforms
+6.  Memory layout on FVP platforms
 ----------------------------------
 
 On FVP platforms, we use the Trusted ROM and Trusted SRAM to store the trusted
@@ -659,7 +933,7 @@ following view:
     ------------ 0x04000000
 
 
-4.  Firmware Image Package (FIP)
+7.  Firmware Image Package (FIP)
 --------------------------------
 
 Using a Firmware Image Package (FIP) allows for packing bootloader images (and
@@ -739,7 +1013,7 @@ Currently the FVPs policy only allows for loading of known images. The platform
 policy can be modified to add additional images.
 
 
-5.  Code Structure
+8.  Code Structure
 ------------------
 
 Trusted Firmware code is logically divided between the three boot loader
@@ -754,11 +1028,13 @@ following categories (present as directories in the source code):
     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?
+    Directory    Used by BL1?    Used by BL2?    Used by BL3-1?
     bl1          Yes             No              No
     bl2          No              Yes             No
     bl31         No              No              Yes
@@ -767,6 +1043,7 @@ categories. Based upon the above, the code layout looks like this:
     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
@@ -776,7 +1053,7 @@ 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.
 
 
-6.  References
+9.  References
 --------------
 
 1.  Trusted Board Boot Requirements CLIENT PDD (ARM DEN 0006B-5). Available
diff --git a/docs/rt-svc-writers-guide.md b/docs/rt-svc-writers-guide.md
new file mode 100644 (file)
index 0000000..07394b0
--- /dev/null
@@ -0,0 +1,308 @@
+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/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
+
+[`psci_steup.c`] provides an example of registering a runtime service:
+
+    /* Register PSCI as a run time service */
+    DECLARE_RT_SVC(
+            psci,
+            OEN_STD_START,
+            OEN_STD_END,
+            SMC_TYPE_FAST,
+            psci_setup,
+            psci_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/psci`]:  ../services/psci
+[`psci_steup.c`]:   ../services/psci/psci_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)"