diff --git a/acknowledgements.md b/acknowledgements.md deleted file mode 100644 index 028f321..0000000 --- a/acknowledgements.md +++ /dev/null @@ -1,15 +0,0 @@ -Contributor Acknowledgements -============================ - -Companies ---------- -Linaro Limited - -NVIDIA Corporation - -Socionext Inc. - -Xilinx, Inc. - -Individuals ------------ diff --git a/contributing.md b/contributing.md deleted file mode 100644 index d1be281..0000000 --- a/contributing.md +++ /dev/null @@ -1,122 +0,0 @@ -Contributing to ARM Trusted Firmware -==================================== - -Getting Started ---------------- - -* Make sure you have a [GitHub account]. -* Create an [issue] for your work if one does not already exist. This gives - everyone visibility of whether others are working on something similar. ARM - licensees may contact ARM directly via their partner managers instead if - they prefer. - * Note that the [issue] tracker for this project is in a separate - [issue tracking repository]. Please follow the guidelines in that - repository. - * If you intend to include Third Party IP in your contribution, please - raise a separate [issue] for this and ensure that the changes that - include Third Party IP are made on a separate topic branch. -* [Fork][] [arm-trusted-firmware][] on GitHub. -* Clone the fork to your own machine. -* Create a local topic branch based on the [arm-trusted-firmware][] `master` - branch. - - -Making Changes --------------- - -* Make commits of logical units. See these general [Git guidelines] for - contributing to a project. -* Follow the [Linux coding style]; this style is enforced for the ARM Trusted - Firmware project (style errors only, not warnings). - * Use the checkpatch.pl script provided with the Linux source tree. A - Makefile target is provided for convenience (see section 2 in the - [User Guide]). -* Keep the commits on topic. If you need to fix another bug or make another - enhancement, please create a separate [issue] and address it on a separate - topic branch. -* Avoid long commit series. If you do have a long series, consider whether - some commits should be squashed together or addressed in a separate topic. -* Make sure your commit messages are in the proper format. If a commit fixes - a GitHub [issue], include a reference (e.g. - "fixes arm-software/tf-issues#45"); this ensures the [issue] is - [automatically closed] when merged into the [arm-trusted-firmware] `master` - branch. -* Where appropriate, please update the documentation. - * Consider whether the [User Guide], [Porting Guide], [Firmware Design] or - other in-source documentation needs updating. - * Ensure that each changed file has the correct copyright and license - information. Files that entirely consist of contributions to this - project should have the copyright notice and BSD-3-Clause SPDX license - identifier as shown in [license.md](./license.md). Files that contain - changes to imported Third Party IP should contain a notice as follows, - with the original copyright and license text retained: - ``` - Portions copyright (c) [XXXX-]YYYY, ARM Limited and Contributors. All rights reserved. - ``` - where XXXX is the year of first contribution (if different to YYYY) and - YYYY is the year of most recent contribution. - * If not done previously, you may add your name or your company name to - the [Acknowledgements] file. - * If you are submitting new files that you intend to be the technical - sub-maintainer for (for example, a new platform port), then also update - the [Maintainers] file. - * For topics with multiple commits, you should make all documentation - changes (and nothing else) in the last commit of the series. Otherwise, - include the documentation changes within the single commit. -* Please test your changes. As a minimum, ensure UEFI boots to the shell on - the Foundation FVP. See [Running the software on FVP] for more information. - - -Submitting Changes ------------------- - -* Ensure that each commit in the series has at least one `Signed-off-by:` - line, using your real name and email address. The names in the - `Signed-off-by:` and `Author:` lines must match. If anyone else contributes - to the commit, they must also add their own `Signed-off-by:` line. - By adding this line the contributor certifies the contribution is made under - the terms of the [Developer Certificate of Origin (DCO)][DCO]. -* Push your local changes to your fork of the repository. -* Submit a [pull request] to the [arm-trusted-firmware] `integration` branch. - * The changes in the [pull request] will then undergo further review and - testing by the [Maintainers]. Any review comments will be made as - comments on the [pull request]. This may require you to do some rework. -* When the changes are accepted, the [Maintainers] will integrate them. - * Typically, the [Maintainers] will merge the [pull request] into the - `integration` branch within the GitHub UI, creating a merge commit. - * Please avoid creating merge commits in the [pull request] itself. - * If the [pull request] is not based on a recent commit, the [Maintainers] - may rebase it onto the `master` branch first, or ask you to do this. - * If the [pull request] cannot be automatically merged, the [Maintainers] - will ask you to rebase it onto the `master` branch. - * After final integration testing, the [Maintainers] will push your merge - commit to the `master` branch. If a problem is found during integration, - the merge commit will be removed from the `integration` branch and the - [Maintainers] will ask you to create a new pull request to resolve the - problem. - * Please do not delete your topic branch until it is safely merged into - the `master` branch. - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved._ - - -[User Guide]: ./docs/user-guide.md -[Running the software on FVP]: ./docs/user-guide.md#8--running-the-software-on-fvp -[Porting Guide]: ./docs/porting-guide.md -[Firmware Design]: ./docs/firmware-design.md -[Acknowledgements]: ./acknowledgements.md "Contributor acknowledgements" -[DCO]: ./dco.txt -[Maintainers]: ./maintainers.md - -[GitHub account]: https://github.com/signup/free -[Fork]: https://help.github.com/articles/fork-a-repo -[issue tracking repository]: https://github.com/ARM-software/tf-issues -[issue]: https://github.com/ARM-software/tf-issues/issues -[pull request]: https://help.github.com/articles/using-pull-requests -[automatically closed]: https://help.github.com/articles/closing-issues-via-commit-messages -[Git guidelines]: http://git-scm.com/book/ch5-2.html -[Linux coding style]: https://www.kernel.org/doc/Documentation/CodingStyle -[arm-trusted-firmware]: https://github.com/ARM-software/arm-trusted-firmware diff --git a/docs/arm-sip-service.md b/docs/arm-sip-service.md deleted file mode 100644 index 1d15b85..0000000 --- a/docs/arm-sip-service.md +++ /dev/null @@ -1,93 +0,0 @@ - -ARM SiP Service -=============== - -This document enumerates and describes the ARM SiP (Silicon Provider) services. - -SiP services are non-standard, platform-specific services offered by the silicon -implementer or platform provider. They are accessed via. `SMC` ("SMC calls") -instruction executed from Exception Levels below EL3. SMC calls for SiP -services: - -* Follow [SMC Calling Convention][SMCCC]; -* Use SMC function IDs that fall in the SiP range, which are `0xc2000000` - - `0xc200ffff` for 64-bit calls, and `0x82000000` - `0x8200ffff` for 32-bit - calls. - -The ARM SiP implementation offers the following services: - -* Performance Measurement Framework (PMF) -* Execution State Switching service - -Source definitions for ARM SiP service are located in the `arm_sip_svc.h` header -file. - -Performance Measurement Framework (PMF) ---------------------------------------- - -The [Performance Measurement Framework](./firmware-design.md#13--performance-measurement-framework) -allows callers to retrieve timestamps captured at various paths in ARM Trusted -Firmware execution. It's described in detail in [Firmware Design document][Firmware Design]. - -Execution State Switching service ---------------------------------- - -Execution State Switching service provides a mechanism for a non-secure lower -Exception Level (either EL2, or NS EL1 if EL2 isn't implemented) to request to -switch its execution state (a.k.a. Register Width), either from AArch64 to -AArch32, or from AArch32 to AArch64, for the calling CPU. This service is only -available when ARM Trusted Firmware is built for AArch64 (i.e. when build option -`ARCH` is set to `aarch64`). - -### `ARM_SIP_SVC_EXE_STATE_SWITCH` - - Arguments: - uint32_t Function ID - uint32_t PC hi - uint32_t PC lo - uint32_t Cookie hi - uint32_t Cookie lo - - Return: - uint32_t - -The function ID parameter must be `0x82000020`. It uniquely identifies the -Execution State Switching service being requested. - -The parameters _PC hi_ and _PC lo_ defines upper and lower words, respectively, -of the entry point (physical address) at which execution should start, after -Execution State has been switched. When calling from AArch64, _PC hi_ must be 0. - -When execution starts at the supplied entry point after Execution State has been -switched, the parameters _Cookie hi_ and _Cookie lo_ are passed in CPU registers -0 and 1, respectively. When calling from AArch64, _Cookie hi_ must be 0. - -This call can only be made on the primary CPU, before any secondaries were -brought up with `CPU_ON` PSCI call. Otherwise, the call will always fail. - -The effect of switching execution state is as if the Exception Level were -entered for the first time, following power on. This means CPU registers that -have a defined reset value by the Architecture will assume that value. Other -registers should not be expected to hold their values before the call was made. -CPU endianness, however, is preserved from the previous execution state. Note -that this switches the execution state of the calling CPU only. This is not a -substitute for PSCI `SYSTEM_RESET`. - -The service may return the following error codes: - - - `STATE_SW_E_PARAM`: If any of the parameters were deemed invalid for - a specific request. - - `STATE_SW_E_DENIED`: If the call is not successful, or when ARM Trusted - Firmware is built for AArch32. - -If the call is successful, the caller wouldn't observe the SMC returning. -Instead, execution starts at the supplied entry point, with the CPU registers 0 -and 1 populated with the supplied _Cookie hi_ and _Cookie lo_ values, -respectively. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2017, ARM Limited and Contributors. All rights reserved._ - -[Firmware Design]: ./firmware-design.md -[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" diff --git a/docs/auth-framework.md b/docs/auth-framework.md deleted file mode 100644 index b416acf..0000000 --- a/docs/auth-framework.md +++ /dev/null @@ -1,925 +0,0 @@ -Abstracting a Chain of Trust -============================ - -Contents : - -1. [Introduction](#1--introduction) -2. [Framework design](#2--framework-design) -3. [Specifying a Chain of Trust](#3--specifying-a-chain-of-trust) -4. [Implementation example](#4--implementation-example) - - -1. Introduction ----------------- - -The aim of this document is to describe the authentication framework implemented -in the Trusted Firmware. This framework fulfills the following requirements: - -1. It should be possible for a platform port to specify the Chain of Trust in - terms of certificate hierarchy and the mechanisms used to verify a - particular image/certificate. - -2. The framework should distinguish between: - - - The mechanism used to encode and transport information, e.g. DER encoded - X.509v3 certificates to ferry Subject Public Keys, hashes and non-volatile - counters. - - - The mechanism used to verify the transported information i.e. the - cryptographic libraries. - -The framework has been designed following a modular approach illustrated in the -next diagram: - -``` - +---------------+---------------+------------+ - | Trusted | Trusted | Trusted | - | Firmware | Firmware | Firmware | - | Generic | IO Framework | Platform | - | Code i.e. | (IO) | Port | - | BL1/BL2 (GEN) | | (PP) | - +---------------+---------------+------------+ - ^ ^ ^ - | | | - v v v - +-----------+ +-----------+ +-----------+ - | | | | | Image | - | Crypto | | Auth | | Parser | - | Module |<->| Module |<->| Module | - | (CM) | | (AM) | | (IPM) | - | | | | | | - +-----------+ +-----------+ +-----------+ - ^ ^ - | | - v v - +----------------+ +-----------------+ - | Cryptographic | | Image Parser | - | Libraries (CL) | | Libraries (IPL) | - +----------------+ +-----------------+ - | | - | | - | | - v v - +-----------------+ - | Misc. Libs e.g. | - | ASN.1 decoder | - | | - +-----------------+ - - DIAGRAM 1. -``` - -This document describes the inner details of the authentication framework and -the abstraction mechanisms available to specify a Chain of Trust. - - -2. Framework design --------------------- - -This section describes some aspects of the framework design and the rationale -behind them. These aspects are key to verify a Chain of Trust. - -### 2.1 Chain of Trust - -A CoT is basically a sequence of authentication images which usually starts with -a root of trust and culminates in a single data image. The following diagram -illustrates how this maps to a CoT for the BL31 image described in the -TBBR-Client specification. - -``` - +------------------+ +-------------------+ - | ROTPK/ROTPK Hash |------>| Trusted Key | - +------------------+ | Certificate | - | (Auth Image) | - /+-------------------+ - / | - / | - / | - / | - L v - +------------------+ +-------------------+ - | Trusted World |------>| BL31 Key | - | Public Key | | Certificate | - +------------------+ | (Auth Image) | - +-------------------+ - / | - / | - / | - / | - / v - +------------------+ L +-------------------+ - | BL31 Content |------>| BL31 Content | - | Certificate PK | | Certificate | - +------------------+ | (Auth Image) | - +-------------------+ - / | - / | - / | - / | - / v - +------------------+ L +-------------------+ - | BL31 Hash |------>| BL31 Image | - | | | (Data Image) | - +------------------+ | | - +-------------------+ - - DIAGRAM 2. -``` - -The root of trust is usually a public key (ROTPK) that has been burnt in the -platform and cannot be modified. - -### 2.2 Image types - -Images in a CoT are categorised as authentication and data images. An -authentication image contains information to authenticate a data image or -another authentication image. A data image is usually a boot loader binary, but -it could be any other data that requires authentication. - -### 2.3 Component responsibilities - -For every image in a Chain of Trust, the following high level operations are -performed to verify it: - -1. Allocate memory for the image either statically or at runtime. - -2. Identify the image and load it in the allocated memory. - -3. Check the integrity of the image as per its type. - -4. Authenticate the image as per the cryptographic algorithms used. - -5. If the image is an authentication image, extract the information that will - be used to authenticate the next image in the CoT. - -In Diagram 1, each component is responsible for one or more of these operations. -The responsibilities are briefly described below. - - -#### 2.2.1 TF Generic code and IO framework (GEN/IO) - -These components are responsible for initiating the authentication process for a -particular image in BL1 or BL2. For each BL image that requires authentication, -the Generic code asks recursively the Authentication module what is the parent -image until either an authenticated image or the ROT is reached. Then the -Generic code calls the IO framewotk to load the image and calls the -Authentication module to authenticate it, following the CoT from ROT to Image. - - -#### 2.2.2 TF Platform Port (PP) - -The platform is responsible for: - -1. Specifying the CoT for each image that needs to be authenticated. Details of - how a CoT can be specified by the platform are explained later. The platform - also specifies the authentication methods and the parsing method used for - each image. - -2. Statically allocating memory for each parameter in each image which is - used for verifying the CoT, e.g. memory for public keys, hashes etc. - -3. Providing the ROTPK or a hash of it. - -4. Providing additional information to the IPM to enable it to identify and - extract authentication parameters contained in an image, e.g. if the - parameters are stored as X509v3 extensions, the corresponding OID must be - provided. - -5. Fulfill any other memory requirements of the IPM and the CM (not currently - described in this document). - -6. Export functions to verify an image which uses an authentication method that - cannot be interpreted by the CM, e.g. if an image has to be verified using a - NV counter, then the value of the counter to compare with can only be - provided by the platform. - -7. Export a custom IPM if a proprietary image format is being used (described - later). - - -#### 2.2.3 Authentication Module (AM) - -It is responsible for: - -1. Providing the necessary abstraction mechanisms to describe a CoT. Amongst - other things, the authentication and image parsing methods must be specified - by the PP in the CoT. - -2. Verifying the CoT passed by GEN by utilising functionality exported by the - PP, IPM and CM. - -3. Tracking which images have been verified. In case an image is a part of - multiple CoTs then it should be verified only once e.g. the Trusted World - Key Certificate in the TBBR-Client spec. contains information to verify - SCP_BL2, BL31, BL32 each of which have a separate CoT. (This - responsibility has not been described in this document but should be - trivial to implement). - -4. Reusing memory meant for a data image to verify authentication images e.g. - in the CoT described in Diagram 2, each certificate can be loaded and - verified in the memory reserved by the platform for the BL31 image. By the - time BL31 (the data image) is loaded, all information to authenticate it - will have been extracted from the parent image i.e. BL31 content - certificate. It is assumed that the size of an authentication image will - never exceed the size of a data image. It should be possible to verify this - at build time using asserts. - - -#### 2.2.4 Cryptographic Module (CM) - -The CM is responsible for providing an API to: - -1. Verify a digital signature. -2. Verify a hash. - -The CM does not include any cryptography related code, but it relies on an -external library to perform the cryptographic operations. A Crypto-Library (CL) -linking the CM and the external library must be implemented. The following -functions must be provided by the CL: - -``` -void (*init)(void); -int (*verify_signature)(void *data_ptr, unsigned int data_len, - void *sig_ptr, unsigned int sig_len, - void *sig_alg, unsigned int sig_alg_len, - void *pk_ptr, unsigned int pk_len); -int (*verify_hash)(void *data_ptr, unsigned int data_len, - void *digest_info_ptr, unsigned int digest_info_len); -``` - -These functions are registered in the CM using the macro: -``` -REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash); -``` - -`_name` must be a string containing the name of the CL. This name is used for -debugging purposes. - -#### 2.2.5 Image Parser Module (IPM) - -The IPM is responsible for: - -1. Checking the integrity of each image loaded by the IO framework. -2. Extracting parameters used for authenticating an image based upon a - description provided by the platform in the CoT descriptor. - -Images may have different formats (for example, authentication images could be -x509v3 certificates, signed ELF files or any other platform specific format). -The IPM allows to register an Image Parser Library (IPL) for every image format -used in the CoT. This library must implement the specific methods to parse the -image. The IPM obtains the image format from the CoT and calls the right IPL to -check the image integrity and extract the authentication parameters. - -See Section "Describing the image parsing methods" for more details about the -mechanism the IPM provides to define and register IPLs. - - -### 2.3 Authentication methods - -The AM supports the following authentication methods: - -1. Hash -2. Digital signature - -The platform may specify these methods in the CoT in case it decides to define -a custom CoT instead of reusing a predefined one. - -If a data image uses multiple methods, then all the methods must be a part of -the same CoT. The number and type of parameters are method specific. These -parameters should be obtained from the parent image using the IPM. - -1. Hash - - Parameters: - - 1. A pointer to data to hash - 2. Length of the data - 4. A pointer to the hash - 5. Length of the hash - - The hash will be represented by the DER encoding of the following ASN.1 - type: - - ``` - DigestInfo ::= SEQUENCE { - digestAlgorithm DigestAlgorithmIdentifier, - digest Digest - } - ``` - - This ASN.1 structure makes it possible to remove any assumption about the - type of hash algorithm used as this information accompanies the hash. This - should allow the Cryptography Library (CL) to support multiple hash - algorithm implementations. - -2. Digital Signature - - Parameters: - - 1. A pointer to data to sign - 2. Length of the data - 3. Public Key Algorithm - 4. Public Key value - 5. Digital Signature Algorithm - 6. Digital Signature value - - The Public Key parameters will be represented by the DER encoding of the - following ASN.1 type: - - ``` - SubjectPublicKeyInfo ::= SEQUENCE { - algorithm AlgorithmIdentifier{PUBLIC-KEY,{PublicKeyAlgorithms}}, - subjectPublicKey BIT STRING } - ``` - - The Digital Signature Algorithm will be represented by the DER encoding of - the following ASN.1 types. - - ``` - AlgorithmIdentifier {ALGORITHM:IOSet } ::= SEQUENCE { - algorithm ALGORITHM.&id({IOSet}), - parameters ALGORITHM.&Type({IOSet}{@algorithm}) OPTIONAL - } - ``` - - The digital signature will be represented by: - ``` - signature ::= BIT STRING - ``` - -The authentication framework will use the image descriptor to extract all the -information related to authentication. - - -3. Specifying a Chain of Trust -------------------------------- - -A CoT can be described as a set of image descriptors linked together in a -particular order. The order dictates the sequence in which they must be -verified. Each image has a set of properties which allow the AM to verify it. -These properties are described below. - -The PP is responsible for defining a single or multiple CoTs for a data image. -Unless otherwise specified, the data structures described in the following -sections are populated by the PP statically. - - -### 3.1 Describing the image parsing methods - -The parsing method refers to the format of a particular image. For example, an -authentication image that represents a certificate could be in the X.509v3 -format. A data image that represents a boot loader stage could be in raw binary -or ELF format. The IPM supports three parsing methods. An image has to use one -of the three methods described below. An IPL is responsible for interpreting a -single parsing method. There has to be one IPL for every method used by the -platform. - -1. Raw format: This format is effectively a nop as an image using this method - is treated as being in raw binary format e.g. boot loader images used by ARM - TF. This method should only be used by data images. - -2. X509V3 method: This method uses industry standards like X.509 to represent - PKI certificates (authentication images). It is expected that open source - libraries will be available which can be used to parse an image represented - by this method. Such libraries can be used to write the corresponding IPL - e.g. the X.509 parsing library code in mbed TLS. - -3. Platform defined method: This method caters for platform specific - proprietary standards to represent authentication or data images. For - example, The signature of a data image could be appended to the data image - raw binary. A header could be prepended to the combined blob to specify the - extents of each component. The platform will have to implement the - corresponding IPL to interpret such a format. - -The following enum can be used to define these three methods. - -``` -typedef enum img_type_enum { - IMG_RAW, /* Binary image */ - IMG_PLAT, /* Platform specific format */ - IMG_CERT, /* X509v3 certificate */ - IMG_MAX_TYPES, -} img_type_t; -``` - -An IPL must provide functions with the following prototypes: - -``` -void init(void); -int check_integrity(void *img, unsigned int img_len); -int get_auth_param(const auth_param_type_desc_t *type_desc, - void *img, unsigned int img_len, - void **param, unsigned int *param_len); -``` - -An IPL for each type must be registered using the following macro: - -``` -REGISTER_IMG_PARSER_LIB(_type, _name, _init, _check_int, _get_param) -``` - -* `_type`: one of the types described above. -* `_name`: a string containing the IPL name for debugging purposes. -* `_init`: initialization function pointer. -* `_check_int`: check image integrity function pointer. -* `_get_param`: extract authentication parameter funcion pointer. - -The `init()` function will be used to initialize the IPL. - -The `check_integrity()` function is passed a pointer to the memory where the -image has been loaded by the IO framework and the image length. It should ensure -that the image is in the format corresponding to the parsing method and has not -been tampered with. For example, RFC-2459 describes a validation sequence for an -X.509 certificate. - -The `get_auth_param()` function is passed a parameter descriptor containing -information about the parameter (`type_desc` and `cookie`) to identify and -extract the data corresponding to that parameter from an image. This data will -be used to verify either the current or the next image in the CoT sequence. - -Each image in the CoT will specify the parsing method it uses. This information -will be used by the IPM to find the right parser descriptor for the image. - - -### 3.2 Describing the authentication method(s) - -As part of the CoT, each image has to specify one or more authentication methods -which will be used to verify it. As described in the Section "Authentication -methods", there are three methods supported by the AM. - -``` -typedef enum { - AUTH_METHOD_NONE, - AUTH_METHOD_HASH, - AUTH_METHOD_SIG, - AUTH_METHOD_NUM -} auth_method_type_t; -``` - -The AM defines the type of each parameter used by an authentication method. It -uses this information to: - -1. Specify to the `get_auth_param()` function exported by the IPM, which - parameter should be extracted from an image. - -2. Correctly marshall the parameters while calling the verification function - exported by the CM and PP. - -3. Extract authentication parameters from a parent image in order to verify a - child image e.g. to verify the certificate image, the public key has to be - obtained from the parent image. - -``` -typedef enum { - AUTH_PARAM_NONE, - AUTH_PARAM_RAW_DATA, /* Raw image data */ - AUTH_PARAM_SIG, /* The image signature */ - AUTH_PARAM_SIG_ALG, /* The image signature algorithm */ - AUTH_PARAM_HASH, /* A hash (including the algorithm) */ - AUTH_PARAM_PUB_KEY, /* A public key */ -} auth_param_type_t; -``` - -The AM defines the following structure to identify an authentication parameter -required to verify an image. - -``` -typedef struct auth_param_type_desc_s { - auth_param_type_t type; - void *cookie; -} auth_param_type_desc_t; -``` - -`cookie` is used by the platform to specify additional information to the IPM -which enables it to uniquely identify the parameter that should be extracted -from an image. For example, the hash of a BL3x image in its corresponding -content certificate is stored in an X509v3 custom extension field. An extension -field can only be identified using an OID. In this case, the `cookie` could -contain the pointer to the OID defined by the platform for the hash extension -field while the `type` field could be set to `AUTH_PARAM_HASH`. A value of 0 for -the `cookie` field means that it is not used. - -For each method, the AM defines a structure with the parameters required to -verify the image. - -``` -/* - * Parameters for authentication by hash matching - */ -typedef struct auth_method_param_hash_s { - auth_param_type_desc_t *data; /* Data to hash */ - auth_param_type_desc_t *hash; /* Hash to match with */ -} auth_method_param_hash_t; - -/* - * Parameters for authentication by signature - */ -typedef struct auth_method_param_sig_s { - auth_param_type_desc_t *pk; /* Public key */ - auth_param_type_desc_t *sig; /* Signature to check */ - auth_param_type_desc_t *alg; /* Signature algorithm */ - auth_param_type_desc_t *tbs; /* Data signed */ -} auth_method_param_sig_t; - -``` - -The AM defines the following structure to describe an authentication method for -verifying an image - -``` -/* - * Authentication method descriptor - */ -typedef struct auth_method_desc_s { - auth_method_type_t type; - union { - auth_method_param_hash_t hash; - auth_method_param_sig_t sig; - } param; -} auth_method_desc_t; -``` - -Using the method type specified in the `type` field, the AM finds out what field -needs to access within the `param` union. - -### 3.3 Storing Authentication parameters - -A parameter described by `auth_param_type_desc_t` to verify an image could be -obtained from either the image itself or its parent image. The memory allocated -for loading the parent image will be reused for loading the child image. Hence -parameters which are obtained from the parent for verifying a child image need -to have memory allocated for them separately where they can be stored. This -memory must be statically allocated by the platform port. - -The AM defines the following structure to store the data corresponding to an -authentication parameter. - -``` -typedef struct auth_param_data_desc_s { - void *auth_param_ptr; - unsigned int auth_param_len; -} auth_param_data_desc_t; -``` - -The `auth_param_ptr` field is initialized by the platform. The `auth_param_len` -field is used to specify the length of the data in the memory. - -For parameters that can be obtained from the child image itself, the IPM is -responsible for populating the `auth_param_ptr` and `auth_param_len` fields -while executing the `img_get_auth_param()` function. - -The AM defines the following structure to enable an image to describe the -parameters that should be extracted from it and used to verify the next image -(child) in a CoT. - -``` -typedef struct auth_param_desc_s { - auth_param_type_desc_t type_desc; - auth_param_data_desc_t data; -} auth_param_desc_t; -``` - -### 3.4 Describing an image in a CoT - -An image in a CoT is a consolidation of the following aspects of a CoT described -above. - -1. A unique identifier specified by the platform which allows the IO framework - to locate the image in a FIP and load it in the memory reserved for the data - image in the CoT. - -2. A parsing method which is used by the AM to find the appropriate IPM. - -3. Authentication methods and their parameters as described in the previous - section. These are used to verify the current image. - -4. Parameters which are used to verify the next image in the current CoT. These - parameters are specified only by authentication images and can be extracted - from the current image once it has been verified. - -The following data structure describes an image in a CoT. -``` -typedef struct auth_img_desc_s { - unsigned int img_id; - const struct auth_img_desc_s *parent; - img_type_t img_type; - auth_method_desc_t img_auth_methods[AUTH_METHOD_NUM]; - auth_param_desc_t authenticated_data[COT_MAX_VERIFIED_PARAMS]; -} auth_img_desc_t; -``` -A CoT is defined as an array of `auth_image_desc_t` structures linked together -by the `parent` field. Those nodes with no parent must be authenticated using -the ROTPK stored in the platform. - - -4. Implementation example --------------------------- - -This section is a detailed guide explaining a trusted boot implementation using -the authentication framework. This example corresponds to the Applicative -Functional Mode (AFM) as specified in the TBBR-Client document. It is -recommended to read this guide along with the source code. - -### 4.1 The TBBR CoT - -The CoT can be found in `drivers/auth/tbbr/tbbr_cot.c`. This CoT consists of an -array of image descriptors and it is registered in the framework using the macro -`REGISTER_COT(cot_desc)`, where 'cot_desc' must be the name of the array -(passing a pointer or any other type of indirection will cause the registration -process to fail). - -The number of images participating in the boot process depends on the CoT. There -is, however, a minimum set of images that are mandatory in the Trusted Firmware -and thus all CoTs must present: - -* `BL2` -* `SCP_BL2` (platform specific) -* `BL31` -* `BL32` (optional) -* `BL33` - -The TBBR specifies the additional certificates that must accompany these images -for a proper authentication. Details about the TBBR CoT may be found in the -[Trusted Board Boot] document. - -Following the [Platform Porting Guide], a platform must provide unique -identifiers for all the images and certificates that will be loaded during the -boot process. If a platform is using the TBBR as a reference for trusted boot, -these identifiers can be obtained from `include/common/tbbr/tbbr_img_def.h`. -ARM platforms include this file in `include/plat/arm/common/arm_def.h`. Other -platforms may also include this file or provide their own identifiers. - -**Important**: the authentication module uses these identifiers to index the -CoT array, so the descriptors location in the array must match the identifiers. - -Each image descriptor must specify: - -* `img_id`: the corresponding image unique identifier defined by the platform. -* `img_type`: the image parser module uses the image type to call the proper - parsing library to check the image integrity and extract the required - authentication parameters. Three types of images are currently supported: - * `IMG_RAW`: image is a raw binary. No parsing functions are available, - other than reading the whole image. - * `IMG_PLAT`: image format is platform specific. The platform may use this - type for custom images not directly supported by the authentication - framework. - * `IMG_CERT`: image is an x509v3 certificate. -* `parent`: pointer to the parent image descriptor. The parent will contain - the information required to authenticate the current image. If the parent - is NULL, the authentication parameters will be obtained from the platform - (i.e. the BL2 and Trusted Key certificates are signed with the ROT private - key, whose public part is stored in the platform). -* `img_auth_methods`: this array defines the authentication methods that must - be checked to consider an image authenticated. Each method consists of a - type and a list of parameter descriptors. A parameter descriptor consists of - a type and a cookie which will point to specific information required to - extract that parameter from the image (i.e. if the parameter is stored in an - x509v3 extension, the cookie will point to the extension OID). Depending on - the method type, a different number of parameters must be specified. - Supported methods are: - * `AUTH_METHOD_HASH`: the hash of the image must match the hash extracted - from the parent image. The following parameter descriptors must be - specified: - * `data`: data to be hashed (obtained from current image) - * `hash`: reference hash (obtained from parent image) - * `AUTH_METHOD_SIG`: the image (usually a certificate) must be signed with - the private key whose public part is extracted from the parent image (or - the platform if the parent is NULL). The following parameter descriptors - must be specified: - * `pk`: the public key (obtained from parent image) - * `sig`: the digital signature (obtained from current image) - * `alg`: the signature algorithm used (obtained from current image) - * `data`: the data to be signed (obtained from current image) -* `authenticated_data`: this array indicates what authentication parameters - must be extracted from an image once it has been authenticated. Each - parameter consists of a parameter descriptor and the buffer address/size - to store the parameter. The CoT is responsible for allocating the required - memory to store the parameters. - -In the `tbbr_cot.c` file, a set of buffers are allocated to store the parameters -extracted from the certificates. In the case of the TBBR CoT, these parameters -are hashes and public keys. In DER format, an RSA-2048 public key requires 294 -bytes, and a hash requires 51 bytes. Depending on the CoT and the authentication -process, some of the buffers may be reused at different stages during the boot. - -Next in that file, the parameter descriptors are defined. These descriptors will -be used to extract the parameter data from the corresponding image. - -#### 4.1.1 Example: the BL31 Chain of Trust - -Four image descriptors form the BL31 Chain of Trust: - -``` -[TRUSTED_KEY_CERT_ID] = { - .img_id = TRUSTED_KEY_CERT_ID, - .img_type = IMG_CERT, - .parent = NULL, - .img_auth_methods = { - [0] = { - .type = AUTH_METHOD_SIG, - .param.sig = { - .pk = &subject_pk, - .sig = &sig, - .alg = &sig_alg, - .data = &raw_data, - } - } - }, - .authenticated_data = { - [0] = { - .type_desc = &trusted_world_pk, - .data = { - .ptr = (void *)trusted_world_pk_buf, - .len = (unsigned int)PK_DER_LEN - } - }, - [1] = { - .type_desc = &non_trusted_world_pk, - .data = { - .ptr = (void *)non_trusted_world_pk_buf, - .len = (unsigned int)PK_DER_LEN - } - } - } -}, -[SOC_FW_KEY_CERT_ID] = { - .img_id = SOC_FW_KEY_CERT_ID, - .img_type = IMG_CERT, - .parent = &cot_desc[TRUSTED_KEY_CERT_ID], - .img_auth_methods = { - [0] = { - .type = AUTH_METHOD_SIG, - .param.sig = { - .pk = &trusted_world_pk, - .sig = &sig, - .alg = &sig_alg, - .data = &raw_data, - } - } - }, - .authenticated_data = { - [0] = { - .type_desc = &soc_fw_content_pk, - .data = { - .ptr = (void *)content_pk_buf, - .len = (unsigned int)PK_DER_LEN - } - } - } -}, -[SOC_FW_CONTENT_CERT_ID] = { - .img_id = SOC_FW_CONTENT_CERT_ID, - .img_type = IMG_CERT, - .parent = &cot_desc[SOC_FW_KEY_CERT_ID], - .img_auth_methods = { - [0] = { - .type = AUTH_METHOD_SIG, - .param.sig = { - .pk = &soc_fw_content_pk, - .sig = &sig, - .alg = &sig_alg, - .data = &raw_data, - } - } - }, - .authenticated_data = { - [0] = { - .type_desc = &soc_fw_hash, - .data = { - .ptr = (void *)soc_fw_hash_buf, - .len = (unsigned int)HASH_DER_LEN - } - } - } -}, -[BL31_IMAGE_ID] = { - .img_id = BL31_IMAGE_ID, - .img_type = IMG_RAW, - .parent = &cot_desc[SOC_FW_CONTENT_CERT_ID], - .img_auth_methods = { - [0] = { - .type = AUTH_METHOD_HASH, - .param.hash = { - .data = &raw_data, - .hash = &soc_fw_hash, - } - } - } -} -``` -The **Trusted Key certificate** is signed with the ROT private key and contains -the Trusted World public key and the Non-Trusted World public key as x509v3 -extensions. This must be specified in the image descriptor using the -`img_auth_methods` and `authenticated_data` arrays, respectively. - -The Trusted Key certificate is authenticated by checking its digital signature -using the ROTPK. Four parameters are required to check a signature: the public -key, the algorithm, the signature and the data that has been signed. Therefore, -four parameter descriptors must be specified with the authentication method: - -* `subject_pk`: parameter descriptor of type `AUTH_PARAM_PUB_KEY`. This type - is used to extract a public key from the parent image. If the cookie is an - OID, the key is extracted from the corresponding x509v3 extension. If the - cookie is NULL, the subject public key is retrieved. In this case, because - the parent image is NULL, the public key is obtained from the platform - (this key will be the ROTPK). -* `sig`: parameter descriptor of type `AUTH_PARAM_SIG`. It is used to extract - the signature from the certificate. -* `sig_alg`: parameter descriptor of type `AUTH_PARAM_SIG`. It is used to - extract the signature algorithm from the certificate. -* `raw_data`: parameter descriptor of type `AUTH_PARAM_RAW_DATA`. It is used - to extract the data to be signed from the certificate. - -Once the signature has been checked and the certificate authenticated, the -Trusted World public key needs to be extracted from the certificate. A new entry -is created in the `authenticated_data` array for that purpose. In that entry, -the corresponding parameter descriptor must be specified along with the buffer -address to store the parameter value. In this case, the `tz_world_pk` descriptor -is used to extract the public key from an x509v3 extension with OID -`TRUSTED_WORLD_PK_OID`. The BL31 key certificate will use this descriptor as -parameter in the signature authentication method. The key is stored in the -`plat_tz_world_pk_buf` buffer. - -The **BL31 Key certificate** is authenticated by checking its digital signature -using the Trusted World public key obtained previously from the Trusted Key -certificate. In the image descriptor, we specify a single authentication method -by signature whose public key is the `tz_world_pk`. Once this certificate has -been authenticated, we have to extract the BL31 public key, stored in the -extension specified by `bl31_content_pk`. This key will be copied to the -`plat_content_pk` buffer. - -The **BL31 certificate** is authenticated by checking its digital signature -using the BL31 public key obtained previously from the BL31 Key certificate. -We specify the authentication method using `bl31_content_pk` as public key. -After authentication, we need to extract the BL31 hash, stored in the extension -specified by `bl31_hash`. This hash will be copied to the `plat_bl31_hash_buf` -buffer. - -The **BL31 image** is authenticated by calculating its hash and matching it -with the hash obtained from the BL31 certificate. The image descriptor contains -a single authentication method by hash. The parameters to the hash method are -the reference hash, `bl31_hash`, and the data to be hashed. In this case, it is -the whole image, so we specify `raw_data`. - -### 4.2 The image parser library - -The image parser module relies on libraries to check the image integrity and -extract the authentication parameters. The number and type of parser libraries -depend on the images used in the CoT. Raw images do not need a library, so -only an x509v3 library is required for the TBBR CoT. - -ARM platforms will use an x509v3 library based on mbed TLS. This library may be -found in `drivers/auth/mbedtls/mbedtls_x509_parser.c`. It exports three -functions: - -``` -void init(void); -int check_integrity(void *img, unsigned int img_len); -int get_auth_param(const auth_param_type_desc_t *type_desc, - void *img, unsigned int img_len, - void **param, unsigned int *param_len); -``` - -The library is registered in the framework using the macro -`REGISTER_IMG_PARSER_LIB()`. Each time the image parser module needs to access -an image of type `IMG_CERT`, it will call the corresponding function exported -in this file. - -The build system must be updated to include the corresponding library and -mbed TLS sources. ARM platforms use the `arm_common.mk` file to pull the -sources. - -### 4.3 The cryptographic library - -The cryptographic module relies on a library to perform the required operations, -i.e. verify a hash or a digital signature. ARM platforms will use a library -based on mbed TLS, which can be found in -`drivers/auth/mbedtls/mbedtls_crypto.c`. This library is registered in the -authentication framework using the macro `REGISTER_CRYPTO_LIB()` and exports -three functions: - -``` -void init(void); -int verify_signature(void *data_ptr, unsigned int data_len, - void *sig_ptr, unsigned int sig_len, - void *sig_alg, unsigned int sig_alg_len, - void *pk_ptr, unsigned int pk_len); -int verify_hash(void *data_ptr, unsigned int data_len, - void *digest_info_ptr, unsigned int digest_info_len); -``` - -The key algorithm (rsa, ecdsa) must be specified in the build system using the -`TF_MBEDTLS_KEY_ALG` variable, so the Makefile can include the corresponding -sources in the build. - -Note: If code size is a concern, the build option `MBEDTLS_SHA256_SMALLER` can -be defined in the platform Makefile. It will make mbed TLS use an implementation -of SHA-256 with smaller memory footprint (~1.5 KB less) but slower (~30%). - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2015, ARM Limited and Contributors. All rights reserved._ - - -[Trusted Board Boot]: ./trusted-board-boot.md -[Platform Porting Guide]: ./porting-guide.md diff --git a/docs/change-log.md b/docs/change-log.md deleted file mode 100644 index 4eb1254..0000000 --- a/docs/change-log.md +++ /dev/null @@ -1,1103 +0,0 @@ - -ARM Trusted Firmware - version 1.3 -================================== - -New features ------------- - -* Added support for running Trusted Firmware in AArch32 execution state. - - The PSCI library has been refactored to allow integration with **EL3 Runtime - Software**. This is software that is executing at the highest secure - privilege which is EL3 in AArch64 or Secure SVC/Monitor mode in AArch32. See - [PSCI Integration Guide]. - - Included is a minimal AArch32 Secure Payload, **SP-MIN**, that illustrates - the usage and integration of the PSCI library with EL3 Runtime Software - running in AArch32 state. - - Booting to the BL1/BL2 images as well as booting straight to the Secure - Payload is supported. - -* Improvements to the initialization framework for the PSCI service and ARM - Standard Services in general. - - The PSCI service is now initialized as part of ARM Standard Service - initialization. This consolidates the initializations of any ARM Standard - Service that may be added in the future. - - A new function `get_arm_std_svc_args()` is introduced to get arguments - corresponding to each standard service and must be implemented by the EL3 - Runtime Software. - - For PSCI, a new versioned structure `psci_lib_args_t` is introduced to - initialize the PSCI Library. **Note** this is a compatibility break due to - the change in the prototype of `psci_setup()`. - -* To support AArch32 builds of BL1 and BL2, implemented a new, alternative - firmware image loading mechanism that adds flexibility. - - The current mechanism has a hard-coded set of images and execution order - (BL31, BL32, etc). The new mechanism is data-driven by a list of image - descriptors provided by the platform code. - - ARM platforms have been updated to support the new loading mechanism. - - The new mechanism is enabled by a build flag (`LOAD_IMAGE_V2`) which is - currently off by default for the AArch64 build. - - **Note** `TRUSTED_BOARD_BOOT` is currently not supported when - `LOAD_IMAGE_V2` is enabled. - -* Updated requirements for making contributions to ARM TF. - - Commits now must have a 'Signed-off-by:' field to certify that the - contribution has been made under the terms of the - [Developer Certificate of Origin]. - - A signed CLA is no longer required. - - The [Contribution Guide] has been updated to reflect this change. - -* Introduced Performance Measurement Framework (PMF) which provides support - for capturing, storing, dumping and retrieving time-stamps to measure the - execution time of critical paths in the firmware. This relies on defining - fixed sample points at key places in the code. - -* To support the QEMU platform port, imported libfdt v1.4.1 from - https://git.kernel.org/cgit/utils/dtc/dtc.git - -* Updated PSCI support: - - * Added support for PSCI NODE_HW_STATE API for ARM platforms. - - * New optional platform hook, `pwr_domain_pwr_down_wfi()`, in - `plat_psci_ops` to enable platforms to perform platform-specific actions - needed to enter powerdown, including the 'wfi' invocation. - - * PSCI STAT residency and count functions have been added on ARM platforms - by using PMF. - -* Enhancements to the translation table library: - - * Limited memory mapping support for region overlaps to only allow regions - to overlap that are identity mapped or have the same virtual to physical - address offset, and overlap completely but must not cover the same area. - - This limitation will enable future enhancements without having to - support complex edge cases that may not be necessary. - - * The initial translation lookup level is now inferred from the virtual - address space size. Previously, it was hard-coded. - - * Added support for mapping Normal, Inner Non-cacheable, Outer - Non-cacheable memory in the translation table library. - - This can be useful to map a non-cacheable memory region, such as a DMA - buffer. - - * Introduced the MT_EXECUTE/MT_EXECUTE_NEVER memory mapping attributes to - specify the access permissions for instruction execution of a memory - region. - -* Enabled support to isolate code and read-only data on separate memory pages, - allowing independent access control to be applied to each. - -* Enabled SCR_EL3.SIF (Secure Instruction Fetch) bit in BL1 and BL31 common - architectural setup code, preventing fetching instructions from non-secure - memory when in secure state. - -* Enhancements to FIP support: - - * Replaced `fip_create` with `fiptool` which provides a more consistent - and intuitive interface as well as additional support to remove an image - from a FIP file. - - * Enabled printing the SHA256 digest with info command, allowing quick - verification of an image within a FIP without having to extract the - image and running sha256sum on it. - - * Added support for unpacking the contents of an existing FIP file into - the working directory. - - * Aligned command line options for specifying images to use same naming - convention as specified by TBBR and already used in cert_create tool. - -* Refactored the TZC-400 driver to also support memory controllers that - integrate TZC functionality, for example ARM CoreLink DMC-500. Also added - DMC-500 specific support. - -* Implemented generic delay timer based on the system generic counter and - migrated all platforms to use it. - -* Enhanced support for ARM platforms: - - * Updated image loading support to make SCP images (SCP_BL2 and SCP_BL2U) - optional. - - * Enhanced topology description support to allow multi-cluster topology - definitions. - - * Added interconnect abstraction layer to help platform ports select the - right interconnect driver, CCI or CCN, for the platform. - - * Added support to allow loading BL31 in the TZC-secured DRAM instead of - the default secure SRAM. - - * Added support to use a System Security Control (SSC) Registers Unit - enabling ARM TF to be compiled to support multiple ARM platforms and - then select one at runtime. - - * Restricted mapping of Trusted ROM in BL1 to what is actually needed by - BL1 rather than entire Trusted ROM region. - - * Flash is now mapped as execute-never by default. This increases security - by restricting the executable region to what is strictly needed. - -* Applied following erratum workarounds for Cortex-A57: 833471, 826977, - 829520, 828024 and 826974. - -* Added support for Mediatek MT6795 platform. - -* Added support for QEMU virtualization ARMv8-A target. - -* Added support for Rockchip RK3368 and RK3399 platforms. - -* Added support for Xilinx Zynq UltraScale+ MPSoC platform. - -* Added support for ARM Cortex-A73 MPCore Processor. - -* Added support for ARM Cortex-A72 processor. - -* Added support for ARM Cortex-A35 processor. - -* Added support for ARM Cortex-A32 MPCore Processor. - -* Enabled preloaded BL33 alternative boot flow, in which BL2 does not load - BL33 from non-volatile storage and BL31 hands execution over to a preloaded - BL33. The User Guide has been updated with an example of how to use this - option with a bootwrapped kernel. - -* Added support to build ARM TF on a Windows-based host machine. - -* Updated Trusted Board Boot prototype implementation: - - * Enabled the ability for a production ROM with TBBR enabled to boot test - software before a real ROTPK is deployed (e.g. manufacturing mode). - Added support to use ROTPK in certificate without verifying against the - platform value when `ROTPK_NOT_DEPLOYED` bit is set. - - * Added support for non-volatile counter authentication to the - Authentication Module to protect against roll-back. - -* Updated GICv3 support: - - * Enabled processor power-down and automatic power-on using GICv3. - - * Enabled G1S or G0 interrupts to be configured independently. - - * Changed FVP default interrupt driver to be the GICv3-only driver. - **Note** the default build of Trusted Firmware will not be able to boot - Linux kernel with GICv2 FDT blob. - - * Enabled wake-up from CPU_SUSPEND to stand-by by temporarily re-routing - interrupts and then restoring after resume. - -Issues resolved since last release ----------------------------------- - -Known issues ------------- - -* The version of the AEMv8 Base FVP used in this release resets the model - instead of terminating its execution in response to a shutdown request using - the PSCI `SYSTEM_OFF` API. This issue will be fixed in a future version of - the model. - -* Building TF with compiler optimisations disabled (`-O0`) fails. - - -* ARM TF cannot be built with mbed TLS version v2.3.0 due to build warnings - that the ARM TF build system interprets as errors. - -* TBBR is not currently supported when running Trusted Firmware in AArch32 - state. - - -ARM Trusted Firmware - version 1.2 -================================== - -New features ------------- - -* The Trusted Board Boot implementation on ARM platforms now conforms to the - mandatory requirements of the TBBR specification. - - In particular, the boot process is now guarded by a Trusted Watchdog, which - will reset the system in case of an authentication or loading error. On ARM - platforms, a secure instance of ARM SP805 is used as the Trusted Watchdog. - - Also, a firmware update process has been implemented. It enables - authenticated firmware to update firmware images from external interfaces to - SoC Non-Volatile memories. This feature functions even when the current - firmware in the system is corrupt or missing; it therefore may be used as - a recovery mode. - -* Improvements have been made to the Certificate Generation Tool - (`cert_create`) as follows. - - * Added support for the Firmware Update process by extending the Chain - of Trust definition in the tool to include the Firmware Update - certificate and the required extensions. - - * Introduced a new API that allows one to specify command line options in - the Chain of Trust description. This makes the declaration of the tool's - arguments more flexible and easier to extend. - - * The tool has been reworked to follow a data driven approach, which - makes it easier to maintain and extend. - -* Extended the FIP tool (`fip_create`) to support the new set of images - involved in the Firmware Update process. - -* Various memory footprint improvements. In particular: - - * The bakery lock structure for coherent memory has been optimised. - - * The mbed TLS SHA1 functions are not needed, as SHA256 is used to - generate the certificate signature. Therefore, they have been compiled - out, reducing the memory footprint of BL1 and BL2 by approximately - 6 KB. - - * On ARM development platforms, each BL stage now individually defines - the number of regions that it needs to map in the MMU. - -* Added the following new design documents: - - * [Authentication framework] - * [Firmware Update] - * [TF Reset Design] - * [Power Domain Topology Design] - -* Applied the new image terminology to the code base and documentation, as - described on the [TF wiki on GitHub][TF Image Terminology]. - -* The build system has been reworked to improve readability and facilitate - adding future extensions. - -* On ARM standard platforms, BL31 uses the boot console during cold boot - but switches to the runtime console for any later logs at runtime. The TSP - uses the runtime console for all output. - -* Implemented a basic NOR flash driver for ARM platforms. It programs the - device using CFI (Common Flash Interface) standard commands. - -* Implemented support for booting EL3 payloads on ARM platforms, which - reduces the complexity of developing EL3 baremetal code by doing essential - baremetal initialization. - -* Provided separate drivers for GICv3 and GICv2. These expect the entire - software stack to use either GICv2 or GICv3; hybrid GIC software systems - are no longer supported and the legacy ARM GIC driver has been deprecated. - -* Added support for Juno r1 and r2. A single set of Juno TF binaries can run - on Juno r0, r1 and r2 boards. Note that this TF version depends on a Linaro - release that does *not* contain Juno r2 support. - -* Added support for MediaTek mt8173 platform. - -* Implemented a generic driver for ARM CCN IP. - -* Major rework of the PSCI implementation. - - * Added framework to handle composite power states. - - * Decoupled the notions of affinity instances (which describes the - hierarchical arrangement of cores) and of power domain topology, instead - of assuming a one-to-one mapping. - - * Better alignment with version 1.0 of the PSCI specification. - -* Added support for the SYSTEM_SUSPEND PSCI API on ARM platforms. When invoked - on the last running core on a supported platform, this puts the system - into a low power mode with memory retention. - -* Unified the reset handling code as much as possible across BL stages. - Also introduced some build options to enable optimization of the reset path - on platforms that support it. - -* Added a simple delay timer API, as well as an SP804 timer driver, which is - enabled on FVP. - -* Added support for NVidia Tegra T210 and T132 SoCs. - -* Reorganised ARM platforms ports to greatly improve code shareability and - facilitate the reuse of some of this code by other platforms. - -* Added support for ARM Cortex-A72 processor in the CPU specific framework. - -* Provided better error handling. Platform ports can now define their own - error handling, for example to perform platform specific bookkeeping or - post-error actions. - -* Implemented a unified driver for ARM Cache Coherent Interconnects used for - both CCI-400 & CCI-500 IPs. ARM platforms ports have been migrated to this - common driver. The standalone CCI-400 driver has been deprecated. - - -Issues resolved since last release ----------------------------------- - -* The Trusted Board Boot implementation has been redesigned to provide greater - modularity and scalability. See the [Authentication Framework] document. - All missing mandatory features are now implemented. - -* The FVP and Juno ports may now use the hash of the ROTPK stored in the - Trusted Key Storage registers to verify the ROTPK. Alternatively, a - development public key hash embedded in the BL1 and BL2 binaries might be - used instead. The location of the ROTPK is chosen at build-time using the - `ARM_ROTPK_LOCATION` build option. - -* GICv3 is now fully supported and stable. - - -Known issues ------------- - -* The version of the AEMv8 Base FVP used in this release resets the model - instead of terminating its execution in response to a shutdown request using - the PSCI `SYSTEM_OFF` API. This issue will be fixed in a future version of - the model. - -* While this version has low on-chip RAM requirements, there are further - RAM usage enhancements that could be made. - -* The upstream documentation could be improved for structural consistency, - clarity and completeness. In particular, the design documentation is - incomplete for PSCI, the TSP(D) and the Juno platform. - -* Building TF with compiler optimisations disabled (`-O0`) fails. - - -ARM Trusted Firmware - version 1.1 -================================== - -New features ------------- - -* A prototype implementation of Trusted Board Boot has been added. Boot - loader images are verified by BL1 and BL2 during the cold boot path. BL1 and - BL2 use the PolarSSL SSL library to verify certificates and images. The - OpenSSL library is used to create the X.509 certificates. Support has been - added to `fip_create` tool to package the certificates in a FIP. - -* Support for calling CPU and platform specific reset handlers upon entry into - BL3-1 during the cold and warm boot paths has been added. This happens after - another Boot ROM `reset_handler()` has already run. This enables a developer - to perform additional actions or undo actions already performed during the - first call of the reset handlers e.g. apply additional errata workarounds. - -* Support has been added to demonstrate routing of IRQs to EL3 instead of - S-EL1 when execution is in secure world. - -* The PSCI implementation now conforms to version 1.0 of the PSCI - specification. All the mandatory APIs and selected optional APIs are - supported. In particular, support for the `PSCI_FEATURES` API has been - added. A capability variable is constructed during initialization by - examining the `plat_pm_ops` and `spd_pm_ops` exported by the platform and - the Secure Payload Dispatcher. This is used by the PSCI FEATURES function - to determine which PSCI APIs are supported by the platform. - -* Improvements have been made to the PSCI code as follows. - - * The code has been refactored to remove redundant parameters from - internal functions. - - * Changes have been made to the code for PSCI `CPU_SUSPEND`, `CPU_ON` and - `CPU_OFF` calls to facilitate an early return to the caller in case a - failure condition is detected. For example, a PSCI `CPU_SUSPEND` call - returns `SUCCESS` to the caller if a pending interrupt is detected early - in the code path. - - * Optional platform APIs have been added to validate the `power_state` and - `entrypoint` parameters early in PSCI `CPU_ON` and `CPU_SUSPEND` code - paths. - - * PSCI migrate APIs have been reworked to invoke the SPD hook to determine - the type of Trusted OS and the CPU it is resident on (if - applicable). Also, during a PSCI `MIGRATE` call, the SPD hook to migrate - the Trusted OS is invoked. - -* It is now possible to build Trusted Firmware without marking at least an - extra page of memory as coherent. The build flag `USE_COHERENT_MEM` can be - used to choose between the two implementations. This has been made possible - through these changes. - - * An implementation of Bakery locks, where the locks are not allocated in - coherent memory has been added. - - * Memory which was previously marked as coherent is now kept coherent - through the use of software cache maintenance operations. - - Approximately, 4K worth of memory is saved for each boot loader stage when - `USE_COHERENT_MEM=0`. Enabling this option increases the latencies - associated with acquire and release of locks. It also requires changes to - the platform ports. - -* It is now possible to specify the name of the FIP at build time by defining - the `FIP_NAME` variable. - -* Issues with depedencies on the 'fiptool' makefile target have been - rectified. The `fip_create` tool is now rebuilt whenever its source files - change. - -* The BL3-1 runtime console is now also used as the crash console. The crash - console is changed to SoC UART0 (UART2) from the previous FPGA UART0 (UART0) - on Juno. In FVP, it is changed from UART0 to UART1. - -* CPU errata workarounds are applied only when the revision and part number - match. This behaviour has been made consistent across the debug and release - builds. The debug build additionally prints a warning if a mismatch is - detected. - -* It is now possible to issue cache maintenance operations by set/way for a - particular level of data cache. Levels 1-3 are currently supported. - -* The following improvements have been made to the FVP port. - - * The build option `FVP_SHARED_DATA_LOCATION` which allowed relocation of - shared data into the Trusted DRAM has been deprecated. Shared data is - now always located at the base of Trusted SRAM. - - * BL2 Translation tables have been updated to map only the region of - DRAM which is accessible to normal world. This is the region of the 2GB - DDR-DRAM memory at 0x80000000 excluding the top 16MB. The top 16MB is - accessible to only the secure world. - - * BL3-2 can now reside in the top 16MB of DRAM which is accessible only to - the secure world. This can be done by setting the build flag - `FVP_TSP_RAM_LOCATION` to the value `dram`. - -* Separate transation tables are created for each boot loader image. The - `IMAGE_BLx` build options are used to do this. This allows each stage to - create mappings only for areas in the memory map that it needs. - -* A Secure Payload Dispatcher (OPTEED) for the OP-TEE Trusted OS has been - added. Details of using it with ARM Trusted Firmware can be found in - [OP-TEE Dispatcher] - - - -Issues resolved since last release ----------------------------------- - -* The Juno port has been aligned with the FVP port as follows. - - * Support for reclaiming all BL1 RW memory and BL2 memory by overlaying - the BL3-1/BL3-2 NOBITS sections on top of them has been added to the - Juno port. - - * The top 16MB of the 2GB DDR-DRAM memory at 0x80000000 is configured - using the TZC-400 controller to be accessible only to the secure world. - - * The ARM GIC driver is used to configure the GIC-400 instead of using a - GIC driver private to the Juno port. - - * PSCI `CPU_SUSPEND` calls that target a standby state are now supported. - - * The TZC-400 driver is used to configure the controller instead of direct - accesses to the registers. - -* The Linux kernel version referred to in the user guide has DVFS and HMP - support enabled. - -* DS-5 v5.19 did not detect Version 5.8 of the Cortex-A57-A53 Base FVPs in - CADI server mode. This issue is not seen with DS-5 v5.20 and Version 6.2 of - the Cortex-A57-A53 Base FVPs. - - -Known issues ------------- - -* The Trusted Board Boot implementation is a prototype. There are issues with - the modularity and scalability of the design. Support for a Trusted - Watchdog, firmware update mechanism, recovery images and Trusted debug is - absent. These issues will be addressed in future releases. - -* The FVP and Juno ports do not use the hash of the ROTPK stored in the - Trusted Key Storage registers to verify the ROTPK in the - `plat_match_rotpk()` function. This prevents the correct establishment of - the Chain of Trust at the first step in the Trusted Board Boot process. - -* The version of the AEMv8 Base FVP used in this release resets the model - instead of terminating its execution in response to a shutdown request using - the PSCI `SYSTEM_OFF` API. This issue will be fixed in a future version of - the model. - -* GICv3 support is experimental. There are known issues with GICv3 - initialization in the ARM Trusted Firmware. - -* While this version greatly reduces the on-chip RAM requirements, there are - further RAM usage enhancements that could be made. - -* The firmware design documentation for the Test Secure-EL1 Payload (TSP) and - its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. - -* The Juno-specific firmware design documentation is incomplete. - - -ARM Trusted Firmware - version 1.0 -================================== - -New features ------------- - -* It is now possible to map higher physical addresses using non-flat virtual - to physical address mappings in the MMU setup. - -* Wider use is now made of the per-CPU data cache in BL3-1 to store: - - * Pointers to the non-secure and secure security state contexts. - - * A pointer to the CPU-specific operations. - - * A pointer to PSCI specific information (for example the current power - state). - - * A crash reporting buffer. - -* The following RAM usage improvements result in a BL3-1 RAM usage reduction - from 96KB to 56KB (for FVP with TSPD), and a total RAM usage reduction - across all images from 208KB to 88KB, compared to the previous release. - - * Removed the separate `early_exception` vectors from BL3-1 (2KB code size - saving). - - * Removed NSRAM from the FVP memory map, allowing the removal of one - (4KB) translation table. - - * Eliminated the internal `psci_suspend_context` array, saving 2KB. - - * Correctly dimensioned the PSCI `aff_map_node` array, saving 1.5KB in the - FVP port. - - * Removed calling CPU mpidr from the bakery lock API, saving 160 bytes. - - * Removed current CPU mpidr from PSCI common code, saving 160 bytes. - - * Inlined the mmio accessor functions, saving 360 bytes. - - * Fully reclaimed all BL1 RW memory and BL2 memory on the FVP port by - overlaying the BL3-1/BL3-2 NOBITS sections on top of these at runtime. - - * Made storing the FP register context optional, saving 0.5KB per context - (8KB on the FVP port, with TSPD enabled and running on 8 CPUs). - - * Implemented a leaner `tf_printf()` function, allowing the stack to be - greatly reduced. - - * Removed coherent stacks from the codebase. Stacks allocated in normal - memory are now used before and after the MMU is enabled. This saves 768 - bytes per CPU in BL3-1. - - * Reworked the crash reporting in BL3-1 to use less stack. - - * Optimized the EL3 register state stored in the `cpu_context` structure - so that registers that do not change during normal execution are - re-initialized each time during cold/warm boot, rather than restored - from memory. This saves about 1.2KB. - - * As a result of some of the above, reduced the runtime stack size in all - BL images. For BL3-1, this saves 1KB per CPU. - -* PSCI SMC handler improvements to correctly handle calls from secure states - and from AArch32. - -* CPU contexts are now initialized from the `entry_point_info`. BL3-1 fully - determines the exception level to use for the non-trusted firmware (BL3-3) - based on the SPSR value provided by the BL2 platform code (or otherwise - provided to BL3-1). This allows platform code to directly run non-trusted - firmware payloads at either EL2 or EL1 without requiring an EL2 stub or OS - loader. - -* Code refactoring improvements: - - * Refactored `fvp_config` into a common platform header. - - * Refactored the fvp gic code to be a generic driver that no longer has an - explicit dependency on platform code. - - * Refactored the CCI-400 driver to not have dependency on platform code. - - * Simplified the IO driver so it's no longer necessary to call `io_init()` - and moved all the IO storage framework code to one place. - - * Simplified the interface the the TZC-400 driver. - - * Clarified the platform porting interface to the TSP. - - * Reworked the TSPD setup code to support the alternate BL3-2 - intialization flow where BL3-1 generic code hands control to BL3-2, - rather than expecting the TSPD to hand control directly to BL3-2. - - * Considerable rework to PSCI generic code to support CPU specific - operations. - -* Improved console log output, by: - - * Adding the concept of debug log levels. - - * Rationalizing the existing debug messages and adding new ones. - - * Printing out the version of each BL stage at runtime. - - * Adding support for printing console output from assembler code, - including when a crash occurs before the C runtime is initialized. - -* Moved up to the latest versions of the FVPs, toolchain, EDK2, kernel, Linaro - file system and DS-5. - -* On the FVP port, made the use of the Trusted DRAM region optional at build - time (off by default). Normal platforms will not have such a "ready-to-use" - DRAM area so it is not a good example to use it. - -* Added support for PSCI `SYSTEM_OFF` and `SYSTEM_RESET` APIs. - -* Added support for CPU specific reset sequences, power down sequences and - register dumping during crash reporting. The CPU specific reset sequences - include support for errata workarounds. - -* Merged the Juno port into the master branch. Added support for CPU hotplug - and CPU idle. Updated the user guide to describe how to build and run on the - Juno platform. - - -Issues resolved since last release ----------------------------------- - -* Removed the concept of top/bottom image loading. The image loader now - automatically detects the position of the image inside the current memory - layout and updates the layout to minimize fragementation. This resolves the - image loader limitations of previously releases. There are currently no - plans to support dynamic image loading. - -* CPU idle now works on the publicized version of the Foundation FVP. - -* All known issues relating to the compiler version used have now been - resolved. This TF version uses Linaro toolchain 14.07 (based on GCC 4.9). - - -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. - -* While this version greatly reduces the on-chip RAM requirements, there are - further RAM usage enhancements that could be made. - -* The firmware design documentation for the Test Secure-EL1 Payload (TSP) and - its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. - -* The Juno-specific firmware design documentation is incomplete. - -* Some recent enhancements to the FVP port have not yet been translated into - the Juno port. These will be tracked via the tf-issues project. - -* The Linux kernel version referred to in the user guide has DVFS and HMP - support disabled due to some known instabilities at the time of this - release. A future kernel version will re-enable these features. - -* DS-5 v5.19 does not detect Version 5.8 of the Cortex-A57-A53 Base FVPs in - CADI server mode. This is because the `` reported by the FVP in - this version has changed. For example, for the Cortex-A57x4-A53x4 Base FVP, - the `` reported by the FVP is `FVP_Base_Cortex_A57x4_A53x4`, while - DS-5 expects it to be `FVP_Base_A57x4_A53x4`. - - The temporary fix to this problem is to change the name of the FVP in - `sw/debugger/configdb/Boards/ARM FVP/Base_A57x4_A53x4/cadi_config.xml`. - Change the following line: - - System Generator:FVP_Base_A57x4_A53x4 - to - System Generator:FVP_Base_Cortex-A57x4_A53x4 - - A similar change can be made to the other Cortex-A57-A53 Base FVP variants. - - -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-2016, ARM Limited and Contributors. All rights reserved._ - -[OP-TEE Dispatcher]: optee-dispatcher.md -[Power Domain Topology Design]: psci-pd-tree.md -[TF Image Terminology]: https://github.com/ARM-software/arm-trusted-firmware/wiki/ARM-Trusted-Firmware-Image-Terminology -[Authentication Framework]: auth-framework.md -[Firmware Update]: firmware-update.md -[TF Reset Design]: reset-design.md -[PSCI Integration Guide]: psci-lib-integration-guide.md -[Firmware Design]: firmware-design.md -[CPU Specific Build Macros]: cpu-specific-build-macros.md -[User Guide]: user-guide.md -[Porting Guide]: porting-guide.md -[Developer Certificate of Origin]: ../dco.txt -[Contribution Guide]: ../contributing.md diff --git a/docs/cpu-specific-build-macros.md b/docs/cpu-specific-build-macros.md deleted file mode 100644 index eb23bcd..0000000 --- a/docs/cpu-specific-build-macros.md +++ /dev/null @@ -1,132 +0,0 @@ -ARM CPU Specific Build Macros -============================= - -Contents --------- - -1. [Introduction](#1--introduction) -2. [CPU Errata Workarounds](#2--cpu-errata-workarounds) -3. [CPU Specific optimizations](#3--cpu-specific-optimizations) - - -1. Introduction ----------------- - -This document describes the various build options present in the CPU specific -operations framework to enable errata workarounds and to enable optimizations -for a specific CPU on a platform. - -2. CPU Errata Workarounds --------------------------- - -ARM Trusted Firmware exports a series of build flags which control the -errata workarounds that are applied to each CPU by the reset handler. The -errata details can be found in the CPU specific errata documents published -by ARM: - -* [Cortex-A53 MPCore Software Developers Errata Notice][A53 Errata Notice] -* [Cortex-A57 MPCore Software Developers Errata Notice][A57 Errata Notice] - -The errata workarounds are implemented for a particular revision or a set of -processor revisions. This is checked by the reset handler at runtime. Each -errata workaround is identified by its `ID` as specified in the processor's -errata notice document. The format of the define used to enable/disable the -errata workaround is `ERRATA__`, where the `Processor name` -is for example `A57` for the `Cortex_A57` CPU. - -Refer to the section _CPU errata status reporting_ in [Firmware Design -guide][Firmware Design] for information on to write errata workaround functions. - -All workarounds are disabled by default. The platform is responsible for -enabling these workarounds according to its requirement by defining the -errata workaround build flags in the platform specific makefile. In case -these workarounds are enabled for the wrong CPU revision then the errata -workaround is not applied. In the DEBUG build, this is indicated by -printing a warning to the crash console. - -In the current implementation, a platform which has more than 1 variant -with different revisions of a processor has no runtime mechanism available -for it to specify which errata workarounds should be enabled or not. - -The value of the build flags are 0 by default, that is, disabled. Any other -value will enable it. - -For Cortex-A53, following errata build flags are defined : - -* `ERRATA_A53_826319`: This applies errata 826319 workaround to Cortex-A53 - CPU. This needs to be enabled only for revision <= r0p2 of the CPU. - -* `ERRATA_A53_836870`: This applies errata 836870 workaround to Cortex-A53 - CPU. This needs to be enabled only for revision <= r0p3 of the CPU. From - r0p4 and onwards, this errata is enabled by default in hardware. - -* `ERRATA_A53_855873`: This applies errata 855873 workaround to Cortex-A53 - CPUs. Though the erratum is present in every revision of the CPU, - this workaround is only applied to CPUs from r0p3 onwards, which feature - a chicken bit in CPUACTLR_EL1 to enable a hardware workaround. - Earlier revisions of the CPU have other errata which require the same - workaround in software, so they should be covered anyway. - -For Cortex-A57, following errata build flags are defined : - -* `ERRATA_A57_806969`: This applies errata 806969 workaround to Cortex-A57 - CPU. This needs to be enabled only for revision r0p0 of the CPU. - -* `ERRATA_A57_813419`: This applies errata 813419 workaround to Cortex-A57 - CPU. This needs to be enabled only for revision r0p0 of the CPU. - -* `ERRATA_A57_813420`: This applies errata 813420 workaround to Cortex-A57 - CPU. This needs to be enabled only for revision r0p0 of the CPU. - -* `ERRATA_A57_826974`: This applies errata 826974 workaround to Cortex-A57 - CPU. This needs to be enabled only for revision <= r1p1 of the CPU. - -* `ERRATA_A57_826977`: This applies errata 826977 workaround to Cortex-A57 - CPU. This needs to be enabled only for revision <= r1p1 of the CPU. - -* `ERRATA_A57_828024`: This applies errata 828024 workaround to Cortex-A57 - CPU. This needs to be enabled only for revision <= r1p1 of the CPU. - -* `ERRATA_A57_829520`: This applies errata 829520 workaround to Cortex-A57 - CPU. This needs to be enabled only for revision <= r1p2 of the CPU. - -* `ERRATA_A57_833471`: This applies errata 833471 workaround to Cortex-A57 - CPU. This needs to be enabled only for revision <= r1p2 of the CPU. - -3. CPU Specific optimizations ------------------------------- - -This section describes some of the optimizations allowed by the CPU micro -architecture that can be enabled by the platform as desired. - -* `SKIP_A57_L1_FLUSH_PWR_DWN`: This flag enables an optimization in the - Cortex-A57 cluster power down sequence by not flushing the Level 1 data - cache. The L1 data cache and the L2 unified cache are inclusive. A flush - of the L2 by set/way flushes any dirty lines from the L1 as well. This - is a known safe deviation from the Cortex-A57 TRM defined power down - sequence. Each Cortex-A57 based platform must make its own decision on - whether to use the optimization. - -* `A53_DISABLE_NON_TEMPORAL_HINT`: This flag disables the cache non-temporal - hint. The LDNP/STNP instructions as implemented on Cortex-A53 do not behave - in a way most programmers expect, and will most probably result in a - significant speed degradation to any code that employs them. The ARMv8-A - architecture (see ARM DDI 0487A.h, section D3.4.3) allows cores to ignore - the non-temporal hint and treat LDNP/STNP as LDP/STP instead. Enabling this - flag enforces this behaviour. This needs to be enabled only for revisions - <= r0p3 of the CPU and is enabled by default. - -* `A57_DISABLE_NON_TEMPORAL_HINT`: This flag has the same behaviour as - `A53_DISABLE_NON_TEMPORAL_HINT` but for Cortex-A57. This needs to be - enabled only for revisions <= r1p2 of the CPU and is enabled by default, - as recommended in section "4.7 Non-Temporal Loads/Stores" of the - [Cortex-A57 Software Optimization Guide][A57 SW Optimization Guide]. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved._ - -[A57 SW Optimization Guide]: http://infocenter.arm.com/help/topic/com.arm.doc.uan0015b/Cortex_A57_Software_Optimization_Guide_external.pdf -[A53 Errata Notice]: http://infocenter.arm.com/help/topic/com.arm.doc.epm048406/index.html -[A57 Errata Notice]: http://infocenter.arm.com/help/topic/com.arm.doc.epm049219/cortex_a57_mpcore_software_developers_errata_notice.pdf -[Firmware Design]: firmware-design.md diff --git a/docs/firmware-design.md b/docs/firmware-design.md deleted file mode 100644 index 0d4578a..0000000 --- a/docs/firmware-design.md +++ /dev/null @@ -1,2325 +0,0 @@ -ARM Trusted Firmware Design -=========================== - -Contents : - -1. [Introduction](#1--introduction) -2. [Cold boot](#2--cold-boot) -3. [EL3 runtime services framework](#3--el3-runtime-services-framework) -4. [Power State Coordination Interface](#4--power-state-coordination-interface) -5. [Secure-EL1 Payloads and Dispatchers](#5--secure-el1-payloads-and-dispatchers) -6. [Crash Reporting in BL31](#6--crash-reporting-in-bl31) -7. [Guidelines for Reset Handlers](#7--guidelines-for-reset-handlers) -8. [CPU specific operations framework](#8--cpu-specific-operations-framework) -9. [Memory layout of BL images](#9-memory-layout-of-bl-images) -10. [Firmware Image Package (FIP)](#10--firmware-image-package-fip) -11. [Use of coherent memory in Trusted Firmware](#11--use-of-coherent-memory-in-trusted-firmware) -12. [Isolating code and read-only data on separate memory pages](#12--isolating-code-and-read-only-data-on-separate-memory-pages) -13. [Performance Measurement Framework](#13--performance-measurement-framework) -14. [ARMv8 Architecture Extensions](#14--armv8-architecture-extensions) -15. [Code Structure](#15--code-structure) -16. [References](#16--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 -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 [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 [4]. - -The ARM Trusted Firmware can be built to support either AArch64 or AArch32 -execution state. - -2. Cold boot -------------- - -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, -depends on the execution state. -For AArch64, it 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 (BL31) _EL3 Runtime Software_ -* Boot Loader stage 3-2 (BL32) _Secure-EL1 Payload_ (optional) -* Boot Loader stage 3-3 (BL33) _Non-trusted Firmware_ - -For AArch32, it is divided into four 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-2 (BL32) _EL3 Runtime Software_ -* Boot Loader stage 3-3 (BL33) _Non-trusted Firmware_ - -ARM development platforms (Fixed Virtual Platforms (FVPs) and Juno) implement a -combination of the following types of memory regions. Each bootloader stage uses -one or more of these memory regions. - -* Regions accessible from both non-secure and secure states. For example, - non-trusted SRAM, ROM and DRAM. -* Regions accessible from only the secure state. For example, trusted SRAM and - ROM. The FVPs also implement the trusted DRAM which is statically - configured. Additionally, the Base FVPs and Juno development platform - configure the TrustZone Controller (TZC) to create a region in the DRAM - which is accessible only from the secure state. - - -The sections below provide the following details: - -* initialization and execution of the first three stages during cold boot -* specification of the EL3 Runtime Software (BL31 for AArch64 and BL32 for - AArch32) entrypoint requirements for use by alternative Trusted Boot - Firmware in place of the provided BL1 and BL2 - - -### BL1 - -This stage begins execution from the platform's reset vector at EL3. The reset -address is platform dependent but it is usually located in a Trusted ROM area. -The BL1 data section is copied to trusted SRAM at runtime. - -On the ARM development platforms, BL1 code starts execution from the reset -vector defined by the constant `BL1_RO_BASE`. The BL1 data section is copied -to the top of trusted SRAM as defined by the constant `BL1_RW_BASE`. - -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 platform-specific mechanisms (see the -`plat_get_my_entrypoint()` function in the [Porting Guide]). In the case of a -warm boot, a CPU is expected to continue execution from a separate -entrypoint. In the case of a cold boot, the secondary CPUs are placed in a safe -platform-specific state (see the `plat_secondary_cold_boot_setup()` function in -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. - -* Exception vectors - - BL1 sets up simple exception vectors for both synchronous and asynchronous - exceptions. The default behavior upon receiving an exception is to populate - a status code in the general purpose register `X0/R0` and call the - `plat_report_exception()` function (see the [Porting Guide]). The status - code is one of: - - For AArch64: - - 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 - - For AArch32: - - 0x10 : User mode - 0x11 : FIQ mode - 0x12 : IRQ mode - 0x13 : SVC mode - 0x16 : Monitor mode - 0x17 : Abort mode - 0x1a : Hypervisor mode - 0x1b : Undefined mode - 0x1f : System mode - - The `plat_report_exception()` implementation on the ARM FVP port programs - the Versatile Express System LED register in the following format to - indicate the occurence of an unexpected exception: - - SYS_LED[0] - Security state (Secure=0/Non-Secure=1) - SYS_LED[2:1] - Exception Level (EL3=0x3, EL2=0x2, EL1=0x1, EL0=0x0) - For AArch32 it is always 0x0 - SYS_LED[7:3] - Exception Class (Sync/Async & origin). This is the value - of the status code - - A write to the LED register reflects in the System LEDs (S6LED0..7) in the - CLCD window of the FVP. - - BL1 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 a - limited set of SMC types (determined by their function IDs in the general - purpose register `X0/R0`): - - `BL1_SMC_RUN_IMAGE`: This SMC is raised by BL2 to make BL1 pass control - to EL3 Runtime Software. - - All SMCs listed in section "BL1 SMC Interface" in the [Firmware Update] - Design Guide are supported for AArch64 only. These SMCs are currently - not supported when BL1 is built for AArch32. - - Any other SMC leads to an assertion failure. - -* CPU initialization - - BL1 calls the `reset_handler()` function which in turn calls the CPU - specific reset handler function (see the section: "CPU specific operations - framework"). - -* Control register setup (for AArch64) - - `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. - - - `SCR_EL3`. The register width of the next lower exception level is set - to AArch64 by setting the `SCR.RW` bit. The `SCR.EA` bit is set to trap - both External Aborts and SError Interrupts in EL3. The `SCR.SIF` bit is - also set to disable instruction fetches from Non-secure memory when in - secure state. - - - `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. - - - `DAIF`. The SError interrupt is enabled by clearing the SError interrupt - mask bit. - - - `MDCR_EL3`. The trap controls, `MDCR_EL3.TDOSA`, `MDCR_EL3.TDA` and - `MDCR_EL3.TPM`, are set so that accesses to the registers they control - do not trap to EL3. AArch64 Secure self-hosted debug is disabled by - setting the `MDCR_EL3.SDD` bit. Also `MDCR_EL3.SPD32` is set to - disable AArch32 Secure self-hosted privileged debug from S-EL1. - -* Control register setup (for AArch32) - - `SCTLR`. Instruction cache is enabled by setting the `SCTLR.I` bit. - Alignment checking is enabled by setting the `SCTLR.A` bit. - Exception endianness is set to little-endian by clearing the - `SCTLR.EE` bit. - - - `SCR`. The `SCR.SIF` bit is set to disable instruction fetches from - Non-secure memory when in secure state. - - - `CPACR`. Allow execution of Advanced SIMD instructions at PL0 and PL1, - by clearing the `CPACR.ASEDIS` bit. Access to the trace functionality - is configured not to trap to undefined mode by clearing the - `CPACR.TRCDIS` bit. - - - `NSACR`. Enable non-secure access to Advanced SIMD functionality and - system register access to implemented trace registers. - - - `FPEXC`. Enable access to the Advanced SIMD and floating-point - functionality from all Exception levels. - - - `CPSR.A`. The Asynchronous data abort interrupt is enabled by clearing - the Asynchronous data abort interrupt mask bit. - - - `SDCR`. The `SDCR.SPD` field is set to disable AArch32 Secure - self-hosted privileged debug. - -#### Platform initialization - -On ARM platforms, BL1 performs the following platform initializations: - -* Enable the Trusted Watchdog. -* Initialize the console. -* Configure the Interconnect to enable hardware coherency. -* Enable the MMU and map the memory it needs to access. -* Configure any required platform storage to load the next bootloader image - (BL2). - -#### Firmware Update detection and execution - -After performing platform setup, BL1 common code calls -`bl1_plat_get_next_image_id()` to determine if [Firmware Update] is required or -to proceed with the normal boot process. If the platform code returns -`BL2_IMAGE_ID` then the normal boot sequence is executed as described in the -next section, else BL1 assumes that [Firmware Update] is required and execution -passes to the first image in the [Firmware Update] process. In either case, BL1 -retrieves a descriptor of the next image by calling `bl1_plat_get_image_desc()`. -The image descriptor contains an `entry_point_info_t` structure, which BL1 -uses to initialize the execution state of the next image. - -#### BL2 image load and execution - -In the normal boot flow, BL1 execution continues as follows: - -1. BL1 prints the following string from the primary CPU to indicate successful - execution of the BL1 stage: - - "Booting Trusted Firmware" - -2. 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 BL2 firmware." - - BL1 calculates the amount of Trusted SRAM that can be 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. - -3. BL1 passes control to the BL2 image at Secure EL1 (for AArch64) or at - Secure SVC mode (for AArch32), 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 (for AArch64) or at Secure -SVC mode (for AArch32) . 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 - -For AArch64, BL2 performs the minimal architectural initialization required -for subsequent stages of the ARM Trusted Firmware and normal world software. -EL1 and EL0 are given access to Floating Point and Advanced SIMD registers -by clearing the `CPACR.FPEN` bits. - -For AArch32, the minimal architectural initialization required for subsequent -stages of the ARM Trusted Firmware and normal world software is taken care of -in BL1 as both BL1 and BL2 execute at PL1. - -#### Platform initialization - -On ARM platforms, BL2 performs the following platform initializations: - -* Initialize the console. -* Configure any required platform storage to allow loading further bootloader - images. -* Enable the MMU and map the memory it needs to access. -* Perform platform security setup to allow access to controlled components. -* Reserve some memory for passing information to the next bootloader image - EL3 Runtime Software and populate it. -* Define the extents of memory available for loading each subsequent - bootloader image. - -#### Image loading in BL2 - -Image loading scheme in BL2 depends on `LOAD_IMAGE_V2` build option. If the -flag is disabled, the BLxx images are loaded, by calling the respective -load_blxx() function from BL2 generic code. If the flag is enabled, the BL2 -generic code loads the images based on the list of loadable images provided -by the platform. BL2 passes the list of executable images provided by the -platform to the next handover BL image. By default, this flag is disabled for -AArch64 and the AArch32 build is supported only if this flag is enabled. - -#### SCP_BL2 (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 SCP_BL2 image from platform -storage into a platform-specific region of secure memory. The subsequent -handling of SCP_BL2 is platform specific. For example, on the Juno ARM -development platform port the image is transferred into SCP's internal memory -using the Boot Over MHU (BOM) protocol after being loaded in the trusted SRAM -memory. The SCP executes SCP_BL2 and signals to the Application Processor (AP) -for BL2 execution to continue. - -#### EL3 Runtime Software image load - -BL2 loads the EL3 Runtime Software 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 `LOAD_IMAGE_V2` -is disabled and if image loads successfully, BL2 updates the amount of trusted -SRAM used and available for use by EL3 Runtime Software. This information is -populated at a platform-specific memory address. - -#### AArch64 BL32 (Secure-EL1 Payload) image load - -BL2 loads the optional BL32 image from platform storage into a platform- -specific region of secure memory. The image executes in the secure world. BL2 -relies on BL31 to pass control to the BL32 image, if present. Hence, BL2 -populates a platform-specific area of memory with the entrypoint/load-address -of the BL32 image. The value of the Saved Processor Status Register (`SPSR`) -for entry into BL32 is not determined by BL2, it is initialized by the -Secure-EL1 Payload Dispatcher (see later) within BL31, which is responsible for -managing interaction with BL32. This information is passed to BL31. - -#### BL33 (Non-trusted Firmware) image load - -BL2 loads the BL33 image (e.g. UEFI or other test or boot software) from -platform storage into non-secure memory as defined by the platform. - -BL2 relies on EL3 Runtime Software to pass control to BL33 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 BL33 -image. The `SPSR` is determined as specified in Section 5.13 of the -[PSCI PDD][PSCI]. This information is passed to the EL3 Runtime Software. - -#### AArch64 BL31 (EL3 Runtime Software) execution - -BL2 execution continues as follows: - -1. BL2 passes control back to BL1 by raising an SMC, providing BL1 with the - BL31 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 BL31 at the specified entrypoint at EL3. - - -### AArch64 BL31 - -The image for this stage is loaded by BL2 and BL1 passes control to BL31 at -EL3. BL31 executes solely in trusted SRAM. BL31 is linked against and -loaded at a platform-specific base address (more information can be found later -in this document). The functionality implemented by BL31 is as follows. - -#### Architectural initialization - -Currently, BL31 performs a similar architectural initialization to BL1 as -far as system register settings are concerned. Since BL1 code resides in ROM, -architectural initialization in BL31 allows override of any previous -initialization done by BL1. - -BL31 initializes the per-CPU data framework, which provides a cache of -frequently accessed per-CPU data optimised for fast, concurrent manipulation -on different CPUs. This buffer includes pointers to per-CPU contexts, crash -buffer, CPU reset and power down operations, PSCI data, platform data and so on. - -It then replaces the exception vectors populated by BL1 with its own. BL31 -exception vectors implement more elaborate support for handling SMCs since this -is the only mechanism to access the runtime services implemented by BL31 (PSCI -for example). BL31 checks each SMC for validity as specified by the -[SMC calling convention PDD][SMCCC] before passing control to the required SMC -handler routine. - -BL31 programs the `CNTFRQ_EL0` register with the clock frequency of the system -counter, which is provided by the platform. - -#### Platform initialization - -BL31 performs detailed platform initialization, which enables normal world -software to function correctly. - -On ARM platforms, this consists of the following: - -* Initialize the console. -* Configure the Interconnect to enable hardware coherency. -* Enable the MMU and map the memory it needs to access. -* Initialize the generic interrupt controller. -* Initialize the power controller device. -* Detect the system topology. - -#### Runtime services initialization - -BL31 is responsible for initializing the runtime services. One of them is PSCI. - -As part of the PSCI initializations, BL31 detects the system topology. It also -initializes the data structures that implement the state machine used to track -the state of power domain nodes. The state can be one of `OFF`, `RUN` or -`RETENTION`. All secondary CPUs are initially in the `OFF` state. The cluster -that the primary CPU belongs to is `ON`; any other cluster is `OFF`. It also -initializes the locks that protect them. BL31 accesses the state of a CPU or -cluster immediately after reset and before the data cache is enabled in the -warm boot path. It is not currently possible to use 'exclusive' based spinlocks, -therefore BL31 uses locks based on Lamport's Bakery algorithm instead. - -The runtime service framework and its initialization is described in more -detail in the "EL3 runtime services framework" section below. - -Details about the status of the PSCI implementation are provided in the -"Power State Coordination Interface" section below. - -#### AArch64 BL32 (Secure-EL1 Payload) image initialization - -If a BL32 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 BL32 -once the runtime services are fully initialized. BL31 invokes such a -registered function to initialize BL32 before running BL33. This initialization -is not necessary for AArch32 SPs. - -Details on BL32 initialization and the SPD's role are described in the -"Secure-EL1 Payloads and Dispatchers" section below. - -#### BL33 (Non-trusted Firmware) execution - -EL3 Runtime Software 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. EL3 Runtime Software uses the entrypoint -information provided by BL2 to jump to the Non-trusted firmware image (BL33) -at the highest available Exception Level (EL2 if available, otherwise EL1). - -### Using alternative Trusted Boot Firmware in place of BL1 & BL2 (AArch64 only) - -Some platforms have existing implementations of Trusted Boot Firmware that -would like to use ARM Trusted Firmware BL31 for the EL3 Runtime Software. To -enable this firmware architecture it is important to provide a fully documented -and stable interface between the Trusted Boot Firmware and BL31. - -Future changes to the BL31 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. - -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 - SCTLR_EL3.EE = 0 - -X0 and X1 can be used to pass information from the Trusted Boot Firmware to the -platform code in BL31: - - X0 : Reserved for common Trusted Firmware information - X1 : Platform specific information - -BL31 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 BL31 code. - -The convention is that `X0` conveys information regarding the BL31, BL32 and -BL33 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. - -BL31 common and SPD initialization code depends on image and entrypoint -information about BL33 and BL32, which is provided via BL31 platform APIs. -This information is required until the start of execution of BL33. This -information can be provided in a platform defined manner, e.g. compiled into -the platform code in BL31, 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 -BL31 platform code before the caches are enabled. - -ARM Trusted Firmware's BL2 implementation passes a `bl31_params` structure in -`X0` and the ARM development platforms interpret this in the BL31 platform -code. - -##### MMU, Data caches & Coherency - -BL31 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 BL31 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 -BL31 that can interpret the BL3x image information from different versions of -BL2, a platform that uses an extended entry_point_info structure to convey -additional register information to BL31, 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 -BL31 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_PARAM_HEAD()` a macro is defined -to simplify this action. - -#### Required CPU state for BL31 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. - -### AArch32 EL3 Runtime Software entrypoint interface - -To enable this firmware architecture it is important to provide a fully -documented and stable interface between the Trusted Boot Firmware and the -AArch32 EL3 Runtime Software. - -Future changes to the entrypoint 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 entering during cold boot - -This function must only be called by the primary CPU. - -On entry to this function the calling primary CPU must be executing in AArch32 -EL3, little-endian data access, and all interrupt sources masked: - - PSTATE.AIF = 0x7 - SCTLR.EE = 0 - -R0 and R1 are used to pass information from the Trusted Boot Firmware to the -platform code in AArch32 EL3 Runtime Software: - - R0 : Reserved for common Trusted Firmware information - R1 : Platform specific information - -##### Use of the R0 and R1 parameters - -The parameters are platform specific and the convention is that `R0` conveys -information regarding the BL3x images from the Trusted Boot firmware and `R1` -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 `R0` to pass a `bl_params` -structure. - -The AArch32 EL3 Runtime Software is responsible for entry into BL33. This -information can be obtained in a platform defined manner, e.g. compiled into -the AArch32 EL3 Runtime Software, 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 AArch32 EL3 Runtime Software before the caches are enabled. - -When using AArch32 EL3 Runtime Software, the ARM development platforms pass a -`bl_params` structure in `R0` from BL2 to be interpreted by AArch32 EL3 Runtime -Software platform code. - -##### MMU, Data caches & Coherency - -AArch32 EL3 Runtime Software must not depend on the enabled state of the MMU, -data caches or interconnect coherency in its entrypoint. They must be explicitly -enabled if required. - -##### Data structures used in cold boot interface - -The AArch32 EL3 Runtime Software cold boot interface uses `bl_params` instead -of `bl31_params`. The `bl_params` structure is based on the convention -described in AArch64 BL31 cold boot interface section. - -#### Required CPU state for warm boot initialization - -When requesting a CPU power-on, or suspending a running CPU, AArch32 EL3 -Runtime Software must ensure execution of a warm boot initialization entrypoint. -If ARM Trusted Firmware BL1 is used and the PROGRAMMABLE_RESET_ADDRESS build -flag is false, then AArch32 EL3 Runtime Software must ensure that BL1 branches -to the warm boot entrypoint by arranging for the BL1 platform function, -plat_get_my_entrypoint(), to return a non-zero value. - -In this case, the warm boot entrypoint must be in AArch32 EL3, little-endian -data access and all interrupt sources masked: - - PSTATE.AIF = 0x7 - SCTLR.EE = 0 - -The warm boot entrypoint may be implemented by using the ARM Trusted Firmware -`psci_warmboot_entrypoint()` function. In that case, the platform must fulfil -the pre-requisites mentioned in the [PSCI Library integration guide] -[PSCI Lib guide]. - -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 -Software (BL31). - -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 Yielding 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). - -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 Software 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 BL31. - -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 BL31 -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 BL31 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/yielding 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 PSCI v1.0 specification categorizes APIs as optional and mandatory. All the -mandatory APIs in PSCI v1.0 and all the APIs in PSCI v0.2 draft specification -[Power State Coordination Interface PDD] [PSCI] are implemented. The table lists -the PSCI v1.0 APIs and their support in generic code. - -An API implementation might have a dependency on platform code e.g. CPU_SUSPEND -requires the platform to export a part of the implementation. Hence the level -of support of the mandatory APIs depends upon the support exported by the -platform port as well. The Juno and FVP (all variants) platforms export all the -required support. - -| PSCI v1.0 API |Supported| Comments | -|:----------------------|:--------|:------------------------------------------| -|`PSCI_VERSION` | Yes | The version returned is 1.0 | -|`CPU_SUSPEND` | Yes* | | -|`CPU_OFF` | Yes* | | -|`CPU_ON` | Yes* | | -|`AFFINITY_INFO` | Yes | | -|`MIGRATE` | Yes** | | -|`MIGRATE_INFO_TYPE` | Yes** | | -|`MIGRATE_INFO_CPU` | Yes** | | -|`SYSTEM_OFF` | Yes* | | -|`SYSTEM_RESET` | Yes* | | -|`PSCI_FEATURES` | Yes | | -|`CPU_FREEZE` | No | | -|`CPU_DEFAULT_SUSPEND` | No | | -|`NODE_HW_STATE` | Yes* | | -|`SYSTEM_SUSPEND` | Yes* | | -|`PSCI_SET_SUSPEND_MODE`| No | | -|`PSCI_STAT_RESIDENCY` | Yes* | | -|`PSCI_STAT_COUNT` | Yes* | | - -*Note : These PSCI APIs require platform power management hooks to be -registered with the generic PSCI code to be supported. - -**Note : These PSCI APIs require appropriate Secure Payload Dispatcher -hooks to be registered with the generic PSCI code to be supported. - -The PSCI implementation in ARM Trusted Firmware is a library which can be -integrated with AArch64 or AArch32 EL3 Runtime Software for ARMv8-A systems. -A guide to integrating PSCI library with AArch32 EL3 Runtime Software -can be found [here][PSCI Lib guide]. - - -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 BL31 -firmware. This service is responsible for the initialisation of the Trusted -OS and all communications with it. The Trusted OS is the BL32 stage of the -boot flow in ARM Trusted Firmware. The firmware will attempt to locate, load -and execute a BL32 image. - -ARM Trusted Firmware uses a more general term for the BL32 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 BL32 image and service are replaced by the Trusted OS -and its dispatcher service. The ARM Trusted Firmware build system expects that -the dispatcher will define the build flag `NEED_BL32` to enable it to include -the BL32 in the build either as a binary or to compile from source depending -on whether the `BL32` build option is specified or not. - -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 BL32 Image - -The Secure-EL1 Payload Dispatcher (SPD) service is responsible for initializing -the BL32 image. It needs access to the information passed by BL2 to BL31 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, BL32. - -In the absence of a BL32 image, BL31 passes control to the normal world -bootloader image (BL33). When the BL32 image is present, it is typical -that the SPD wants control to be passed to BL32 first and then later to BL33. - -To do this the SPD has to register a BL32 initialization function during -initialization of the SPD service. The BL32 initialization function has this -prototype: - - int32_t init(void); - -and is registered using the `bl31_register_bl32_init()` function. - -Trusted Firmware supports two approaches for the SPD to pass control to BL32 -before returning through EL3 and running the non-trusted firmware (BL33): - -1. In the BL32 setup function, use `bl31_set_next_image_type()` to - request that the exit from `bl31_main()` is to the BL32 entrypoint in - Secure-EL1. BL31 will exit to BL32 using the asynchronous method by - calling `bl31_prepare_next_image_entry()` and `el3_exit()`. - - When the BL32 has completed initialization at Secure-EL1, it returns to - BL31 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 BL33. On return from the handler the framework - will exit to EL2 and run BL33. - -2. The BL32 setup function registers an initialization function using - `bl31_register_bl32_init()` which provides a SPD-defined mechanism to - invoke a 'world-switch synchronous call' to Secure-EL1 to run the BL32 - entrypoint. - NOTE: The Test SPD service included with the Trusted Firmware provides one - implementation of such a mechanism. - - On completion BL32 returns control to BL31 via a SMC, and on receipt the - SPD service handler invokes the synchronous call return mechanism to return - to the BL32 initialization function. On return from this function, - `bl31_main()` will set up the return to the normal world firmware BL33 and - continue the boot process in the normal world. - - -6. Crash Reporting in BL31 ----------------------------- - -BL31 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 a dedicated UART (PL011 console). BL31 -reports the general purpose, EL3, Secure EL1 and some EL2 state registers. - -A dedicated per-CPU crash stack is maintained by BL31 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. Guidelines for Reset Handlers ---------------------------------- - -Trusted Firmware implements a framework that allows CPU and platform ports to -perform actions very early after a CPU is released from reset in both the cold -and warm boot paths. This is done by calling the `reset_handler()` function in -both the BL1 and BL31 images. It in turn calls the platform and CPU specific -reset handling functions. - -Details for implementing a CPU specific reset handler can be found in -Section 8. Details for implementing a platform specific reset handler can be -found in the [Porting Guide] (see the `plat_reset_handler()` function). - -When adding functionality to a reset handler, keep in mind that if a different -reset handling behavior is required between the first and the subsequent -invocations of the reset handling code, this should be detected at runtime. -In other words, the reset handler should be able to detect whether an action has -already been performed and act as appropriate. Possible courses of actions are, -e.g. skip the action the second time, or undo/redo it. - -8. CPU specific operations framework -------------------------------------- - -Certain aspects of the ARMv8 architecture are implementation defined, -that is, certain behaviours are not architecturally defined, but must be defined -and documented by individual processor implementations. The ARM Trusted -Firmware implements a framework which categorises the common implementation -defined behaviours and allows a processor to export its implementation of that -behaviour. The categories are: - -1. Processor specific reset sequence. - -2. Processor specific power down sequences. - -3. Processor specific register dumping as a part of crash reporting. - -4. Errata status reporting. - -Each of the above categories fulfils a different requirement. - -1. allows any processor specific initialization before the caches and MMU - are turned on, like implementation of errata workarounds, entry into - the intra-cluster coherency domain etc. - -2. allows each processor to implement the power down sequence mandated in - its Technical Reference Manual (TRM). - -3. allows a processor to provide additional information to the developer - in the event of a crash, for example Cortex-A53 has registers which - can expose the data cache contents. - -4. allows a processor to define a function that inspects and reports the status - of all errata workarounds on that processor. - -Please note that only 2. is mandated by the TRM. - -The CPU specific operations framework scales to accommodate a large number of -different CPUs during power down and reset handling. The platform can specify -any CPU optimization it wants to enable for each CPU. It can also specify -the CPU errata workarounds to be applied for each CPU type during reset -handling by defining CPU errata compile time macros. Details on these macros -can be found in the [cpu-specific-build-macros.md][CPUBM] file. - -The CPU specific operations framework depends on the `cpu_ops` structure which -needs to be exported for each type of CPU in the platform. It is defined in -`include/lib/cpus/aarch64/cpu_macros.S` and has the following fields : `midr`, -`reset_func()`, `cpu_pwr_down_ops` (array of power down functions) and -`cpu_reg_dump()`. - -The CPU specific files in `lib/cpus` export a `cpu_ops` data structure with -suitable handlers for that CPU. For example, `lib/cpus/aarch64/cortex_a53.S` -exports the `cpu_ops` for Cortex-A53 CPU. According to the platform -configuration, these CPU specific files must be included in the build by -the platform makefile. The generic CPU specific operations framework code exists -in `lib/cpus/aarch64/cpu_helpers.S`. - -### CPU specific Reset Handling - -After a reset, the state of the CPU when it calls generic reset handler is: -MMU turned off, both instruction and data caches turned off and not part -of any coherency domain. - -The BL entrypoint code first invokes the `plat_reset_handler()` to allow -the platform to perform any system initialization required and any system -errata workarounds that needs to be applied. The `get_cpu_ops_ptr()` reads -the current CPU midr, finds the matching `cpu_ops` entry in the `cpu_ops` -array and returns it. Note that only the part number and implementer fields -in midr are used to find the matching `cpu_ops` entry. The `reset_func()` in -the returned `cpu_ops` is then invoked which executes the required reset -handling for that CPU and also any errata workarounds enabled by the platform. -This function must preserve the values of general purpose registers x20 to x29. - -Refer to Section "Guidelines for Reset Handlers" for general guidelines -regarding placement of code in a reset handler. - -### CPU specific power down sequence - -During the BL31 initialization sequence, the pointer to the matching `cpu_ops` -entry is stored in per-CPU data by `init_cpu_ops()` so that it can be quickly -retrieved during power down sequences. - -Various CPU drivers register handlers to perform power down at certain power -levels for that specific CPU. The PSCI service, upon receiving a power down -request, determines the highest power level at which to execute power down -sequence for a particular CPU. It uses the `prepare_cpu_pwr_dwn()` function to -pick the right power down handler for the requested level. The function -retrieves `cpu_ops` pointer member of per-CPU data, and from that, further -retrieves `cpu_pwr_down_ops` array, and indexes into the required level. If the -requested power level is higher than what a CPU driver supports, the handler -registered for highest level is invoked. - -At runtime the platform hooks for power down are invoked by the PSCI service to -perform platform specific operations during a power down sequence, for example -turning off CCI coherency during a cluster power down. - -### CPU specific register reporting during crash - -If the crash reporting is enabled in BL31, when a crash occurs, the crash -reporting framework calls `do_cpu_reg_dump` which retrieves the matching -`cpu_ops` using `get_cpu_ops_ptr()` function. The `cpu_reg_dump()` in -`cpu_ops` is invoked, which then returns the CPU specific register values to -be reported and a pointer to the ASCII list of register names in a format -expected by the crash reporting framework. - -### CPU errata status reporting - -Errata workarounds for CPUs supported in ARM Trusted Firmware are applied during -both cold and warm boots, shortly after reset. Individual Errata workarounds are -enabled as build options. Some errata workarounds have potential run-time -implications; therefore some are enabled by default, others not. Platform ports -shall override build options to enable or disable errata as appropriate. The CPU -drivers take care of applying errata workarounds that are enabled and applicable -to a given CPU. Refer to the section titled _CPU Errata Workarounds_ in [CPUBM] -for more information. - -Functions in CPU drivers that apply errata workaround must follow the -conventions listed below. - -The errata workaround must be authored as two separate functions: - -* One that checks for errata. This function must determine whether that errata - applies to the current CPU. Typically this involves matching the current - CPUs revision and variant against a value that's known to be affected by the - errata. If the function determines that the errata applies to this CPU, it - must return `ERRATA_APPLIES`; otherwise, it must return - `ERRATA_NOT_APPLIES`. The utility functions `cpu_get_rev_var` and - `cpu_rev_var_ls` functions may come in handy for this purpose. - - For an errata identified as `E`, the check function must be named - `check_errata_E`. - - This function will be invoked at different times, both from assembly and from - C run time. Therefore it must follow AAPCS, and must not use stack. - -* Another one that applies the errata workaround. This function would call the - check function described above, and applies errata workaround if required. - -CPU drivers that apply errata workaround can optionally implement an assembly -function that report the status of errata workarounds pertaining to that CPU. -For a driver that registers the CPU, for example, `cpux` via. `declare_cpu_ops` -macro, the errata reporting function, if it exists, must be named -`cpux_errata_report`. This function will always be called with MMU enabled; it -must follow AAPCS and may use stack. - -In a debug build of ARM Trusted Firmware, on a CPU that comes out of reset, both -BL1 and the run time firmware (BL31 in AArch64, and BL32 in AArch32) will invoke -errata status reporting function, if one exists, for that type of CPU. - -To report the status of each errata workaround, the function shall use the -assembler macro `report_errata`, passing it: - -* The build option that enables the errata; - -* The name of the CPU: this must be the same identifier that CPU driver - registered itself with, using `declare_cpu_ops`; - -* And the errata identifier: the identifier must match what's used in the - errata's check function described above. - -The errata status reporting function will be called once per CPU type/errata -combination during the software's active life time. - -It's expected that whenever an errata workaround is submitted to ARM Trusted -Firmware, the errata reporting function is appropriately extended to report its -status as well. - -Reporting the status of errata workaround is for informational purpose only; it -has no functional significance. - -9. Memory layout of BL images ------------------------------ - -Each bootloader image can be divided in 2 parts: - - * the static contents of the image. These are data actually stored in the - binary on the disk. In the ELF terminology, they are called `PROGBITS` - sections; - - * the run-time contents of the image. These are data that don't occupy any - space in the binary on the disk. The ELF binary just contains some - metadata indicating where these data will be stored at run-time and the - corresponding sections need to be allocated and initialized at run-time. - In the ELF terminology, they are called `NOBITS` sections. - -All PROGBITS sections are grouped together at the beginning of the image, -followed by all NOBITS sections. This is true for all Trusted Firmware images -and it is governed by the linker scripts. This ensures that the raw binary -images are as small as possible. If a NOBITS section was inserted in between -PROGBITS sections then the resulting binary file would contain zero bytes in -place of this NOBITS section, making the image unnecessarily bigger. Smaller -images allow faster loading from the FIP to the main memory. - -### Linker scripts and symbols - -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. - -* `__
_START__` - - Start address of a given section named `
`. - -* `__
_END__` - - End address of a given section named `
`. If there is an alignment - constraint on the section's end address then `__
_END__` corresponds - to the end address of the section's actual contents, rounded up to the right - boundary. Refer to the value of `__
_UNALIGNED_END__` to know the - actual end address of the section's contents. - -* `__
_UNALIGNED_END__` - - End address of a given section named `
` without any padding or - rounding up due to some alignment constraint. - -* `__
_SIZE__` - - Size (in bytes) of a given section named `
`. If there is an - alignment constraint on the section's end address then `__
_SIZE__` - corresponds to the size of the section's actual contents, rounded up to the - right boundary. In other words, `__
_SIZE__ = __
_END__ - - _
_START__`. Refer to the value of `__
_UNALIGNED_SIZE__` - to know the actual size of the section's contents. - -* `__
_UNALIGNED_SIZE__` - - Size (in bytes) of a given section named `
` without any padding or - rounding up due to some alignment constraint. In other words, - `__
_UNALIGNED_SIZE__ = __
_UNALIGNED_END__ - - __
_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 - -All BL images share the following requirements: - -* The BSS section must be zero-initialised before executing any C code. -* The coherent memory section (if enabled) must be zero-initialised as well. -* The MMU setup code needs to know the extents of the coherent and read-only - memory regions to set the right memory attributes. When - `SEPARATE_CODE_AND_RODATA=1`, it needs to know more specifically how the - read-only memory region is divided between code and data. - -The following linker symbols are defined for this purpose: - -* `__BSS_START__` -* `__BSS_SIZE__` -* `__COHERENT_RAM_START__` Must be aligned on a page-size boundary. -* `__COHERENT_RAM_END__` Must be aligned on a page-size boundary. -* `__COHERENT_RAM_UNALIGNED_SIZE__` -* `__RO_START__` -* `__RO_END__` -* `__TEXT_START__` -* `__TEXT_END__` -* `__RODATA_START__` -* `__RODATA_END__` - -#### BL1's linker symbols - -BL1 being the ROM image, it has additional requirements. BL1 resides in ROM and -it is entirely executed in place but it needs some read-write memory for its -mutable data. Its `.data` section (i.e. its allocated read-write data) must be -relocated from ROM to RAM before executing any C code. - -The following additional linker symbols are defined for BL1: - -* `__BL1_ROM_END__` End address of BL1's ROM contents, covering its code - and `.data` section in ROM. -* `__DATA_ROM_START__` Start address of the `.data` section in ROM. Must be - aligned on a 16-byte boundary. -* `__DATA_RAM_START__` Address in RAM where the `.data` section should be - copied over. Must be aligned on a 16-byte boundary. -* `__DATA_SIZE__` Size of the `.data` section (in ROM or RAM). -* `__BL1_RAM_START__` Start address of BL1 read-write data. -* `__BL1_RAM_END__` End address of BL1 read-write data. - - -### 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///bl/bl.map`, with `` -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. - -Additionally, if the platform memory layout implies some image overlaying like -on FVP, BL31 and TSP need to know the limit address that their PROGBITS -sections must not overstep. The platform code must provide those. - -When LOAD_IMAGE_V2 is disabled, Trusted Firmware provides a mechanism to -verify at boot time that the memory to load a new image is free to prevent -overwriting a previously loaded image. For this mechanism to work, the platform -must specify the memory available in the system as regions, where each region -consists of base address, total size and the free area within it (as defined -in the `meminfo_t` structure). Trusted Firmware retrieves these memory regions -by calling the corresponding platform API: - -* `meminfo_t *bl1_plat_sec_mem_layout(void)` -* `meminfo_t *bl2_plat_sec_mem_layout(void)` -* `void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)` -* `void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)` -* `void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)` - -For example, in the case of BL1 loading BL2, `bl1_plat_sec_mem_layout()` will -return the region defined by the platform where BL1 intends to load BL2. The -`load_image()` function will check that the memory where BL2 will be loaded is -within the specified region and marked as free. - -The actual number of regions and their base addresses and sizes is platform -specific. The platform may return the same region or define a different one for -each API. However, the overlap verification mechanism applies only to a single -region. Hence, it is the platform responsibility to guarantee that different -regions do not overlap, or that if they do, the overlapping images are not -accessed at the same time. This could be used, for example, to load temporary -images (e.g. certificates) or firmware images prior to being transfered to its -corresponding processor (e.g. the SCP BL2 image). - -To reduce fragmentation and simplify the tracking of free memory, all the free -memory within a region is always located in one single buffer defined by its -base address and size. Trusted Firmware implements a top/bottom load approach: -after a new image is loaded, it checks how much memory remains free above and -below the image. The smallest area is marked as unavailable, while the larger -area becomes the new free memory buffer. Platforms should take this behaviour -into account when defining the base address for each of the images. For example, -if an image is loaded near the middle of the region, small changes in image size -could cause a flip between a top load and a bottom load, which may result in an -unexpected memory layout. - -The following diagram is an example of an image loaded in the bottom part of -the memory region. The region is initially free (nothing has been loaded yet): - - Memory region - +----------+ - | | - | | <<<<<<<<<<<<< Free - | | - |----------| +------------+ - | image | <<<<<<<<<<<<< | image | - |----------| +------------+ - | xxxxxxxx | <<<<<<<<<<<<< Marked as unavailable - +----------+ - -And the following diagram is an example of an image loaded in the top part: - - Memory region - +----------+ - | xxxxxxxx | <<<<<<<<<<<<< Marked as unavailable - |----------| +------------+ - | image | <<<<<<<<<<<<< | image | - |----------| +------------+ - | | - | | <<<<<<<<<<<<< Free - | | - +----------+ - - -When LOAD_IMAGE_V2 is enabled, Trusted Firmware does not provide any mechanism -to verify at boot time that the memory to load a new image is free to prevent -overwriting a previously loaded image. The platform must specify the memory -available in the system for all the relevant BL images to be loaded. - -For example, in the case of BL1 loading BL2, `bl1_plat_sec_mem_layout()` will -return the region defined by the platform where BL1 intends to load BL2. The -`load_image()` function performs bounds check for the image size based on the -base and maximum image size provided by the platforms. Platforms must take -this behaviour into account when defining the base/size for each of the images. - -#### Memory layout on ARM development platforms - -The following list describes the memory layout on the ARM development platforms: - -* A 4KB page of shared memory is used for communication between Trusted - Firmware and the platform's power controller. This is located at the base of - Trusted SRAM. The amount of Trusted SRAM available to load the bootloader - images is reduced by the size of the shared memory. - - The shared memory is used to store the CPUs' entrypoint mailbox. On Juno, - this is also used for the MHU payload when passing messages to and from the - SCP. - -* On FVP, BL1 is originally sitting in the Trusted ROM at address `0x0`. On - Juno, BL1 resides in flash memory at address `0x0BEC0000`. BL1 read-write - data are relocated to the top of Trusted SRAM at runtime. - -* EL3 Runtime Software, BL31 for AArch64 and BL32 for AArch32 (e.g. SP_MIN), - is loaded at the top of the Trusted SRAM, such that its NOBITS sections will - overwrite BL1 R/W data. This implies that BL1 global variables remain valid - only until execution reaches the EL3 Runtime Software entry point during a - cold boot. - -* BL2 is loaded below EL3 Runtime Software. - -* On Juno, SCP_BL2 is loaded temporarily into the EL3 Runtime Software memory - region and transfered to the SCP before being overwritten by EL3 Runtime - Software. - -* BL32 (for AArch64) can be loaded in one of the following locations: - - * Trusted SRAM - * Trusted DRAM (FVP only) - * Secure region of DRAM (top 16MB of DRAM configured by the TrustZone - controller) - - When BL32 (for AArch64) is loaded into Trusted SRAM, its NOBITS sections - are allowed to overlay BL2. This memory layout is designed to give the - BL32 image as much memory as possible when it is loaded into Trusted SRAM. - -When LOAD_IMAGE_V2 is disabled the memory regions for the overlap detection -mechanism at boot time are defined as follows (shown per API): - -* `meminfo_t *bl1_plat_sec_mem_layout(void)` - - This region corresponds to the whole Trusted SRAM except for the shared - memory at the base. This region is initially free. At boot time, BL1 will - mark the BL1(rw) section within this region as occupied. The BL1(rw) section - is placed at the top of Trusted SRAM. - -* `meminfo_t *bl2_plat_sec_mem_layout(void)` - - This region corresponds to the whole Trusted SRAM as defined by - `bl1_plat_sec_mem_layout()`, but with the BL1(rw) section marked as - occupied. This memory region is used to check that BL2 and BL31 do not - overlap with each other. BL2_BASE and BL1_RW_BASE are carefully chosen so - that the memory for BL31 is top loaded above BL2. - -* `void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)` - - This region is an exact copy of the region defined by - `bl2_plat_sec_mem_layout()`. Being a disconnected copy means that all the - changes made to this region by the Trusted Firmware will not be propagated. - This approach is valid because the SCP BL2 image is loaded temporarily - while it is being transferred to the SCP, so this memory is reused - afterwards. - -* `void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)` - - This region depends on the location of the BL32 image. Currently, ARM - platforms support three different locations (detailed below): Trusted SRAM, - Trusted DRAM and the TZC-Secured DRAM. - -* `void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)` - - This region corresponds to the Non-Secure DDR-DRAM, excluding the - TZC-Secured area. - -The location of the BL32 image will result in different memory maps. This is -illustrated for both FVP and Juno in the following diagrams, using the TSP as -an example. - -Note: Loading the BL32 image in TZC secured DRAM doesn't change the memory -layout of the other images in Trusted SRAM. - -**FVP with TSP in Trusted SRAM (default option):** -(These diagrams only cover the AArch64 case) - - Trusted SRAM - 0x04040000 +----------+ loaded by BL2 ------------------ - | BL1 (rw) | <<<<<<<<<<<<< | BL31 NOBITS | - |----------| <<<<<<<<<<<<< |----------------| - | | <<<<<<<<<<<<< | BL31 PROGBITS | - |----------| ------------------ - | BL2 | <<<<<<<<<<<<< | BL32 NOBITS | - |----------| <<<<<<<<<<<<< |----------------| - | | <<<<<<<<<<<<< | BL32 PROGBITS | - 0x04001000 +----------+ ------------------ - | Shared | - 0x04000000 +----------+ - - Trusted ROM - 0x04000000 +----------+ - | BL1 (ro) | - 0x00000000 +----------+ - - -**FVP with TSP in Trusted DRAM:** - - Trusted DRAM - 0x08000000 +----------+ - | BL32 | - 0x06000000 +----------+ - - Trusted SRAM - 0x04040000 +----------+ loaded by BL2 ------------------ - | BL1 (rw) | <<<<<<<<<<<<< | BL31 NOBITS | - |----------| <<<<<<<<<<<<< |----------------| - | | <<<<<<<<<<<<< | BL31 PROGBITS | - |----------| ------------------ - | BL2 | - |----------| - | | - 0x04001000 +----------+ - | Shared | - 0x04000000 +----------+ - - Trusted ROM - 0x04000000 +----------+ - | BL1 (ro) | - 0x00000000 +----------+ - -**FVP with TSP in TZC-Secured DRAM:** - - DRAM - 0xffffffff +----------+ - | BL32 | (secure) - 0xff000000 +----------+ - | | - : : (non-secure) - | | - 0x80000000 +----------+ - - Trusted SRAM - 0x04040000 +----------+ loaded by BL2 ------------------ - | BL1 (rw) | <<<<<<<<<<<<< | BL31 NOBITS | - |----------| <<<<<<<<<<<<< |----------------| - | | <<<<<<<<<<<<< | BL31 PROGBITS | - |----------| ------------------ - | BL2 | - |----------| - | | - 0x04001000 +----------+ - | Shared | - 0x04000000 +----------+ - - Trusted ROM - 0x04000000 +----------+ - | BL1 (ro) | - 0x00000000 +----------+ - - -**Juno with BL32 in Trusted SRAM (default option):** - - Flash0 - 0x0C000000 +----------+ - : : - 0x0BED0000 |----------| - | BL1 (ro) | - 0x0BEC0000 |----------| - : : - 0x08000000 +----------+ BL31 is loaded - after SCP_BL2 has - Trusted SRAM been sent to SCP - 0x04040000 +----------+ loaded by BL2 ------------------ - | BL1 (rw) | <<<<<<<<<<<<< | BL31 NOBITS | - |----------| <<<<<<<<<<<<< |----------------| - | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS | - |----------| ------------------ - | BL2 | <<<<<<<<<<<<< | BL32 NOBITS | - |----------| <<<<<<<<<<<<< |----------------| - | | <<<<<<<<<<<<< | BL32 PROGBITS | - 0x04001000 +----------+ ------------------ - | MHU | - 0x04000000 +----------+ - - -**Juno with BL32 in TZC-secured DRAM:** - - DRAM - 0xFFE00000 +----------+ - | BL32 | (secure) - 0xFF000000 |----------| - | | - : : (non-secure) - | | - 0x80000000 +----------+ - - Flash0 - 0x0C000000 +----------+ - : : - 0x0BED0000 |----------| - | BL1 (ro) | - 0x0BEC0000 |----------| - : : - 0x08000000 +----------+ BL31 is loaded - after SCP_BL2 has - Trusted SRAM been sent to SCP - 0x04040000 +----------+ loaded by BL2 ------------------ - | BL1 (rw) | <<<<<<<<<<<<< | BL31 NOBITS | - |----------| <<<<<<<<<<<<< |----------------| - | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS | - |----------| ------------------ - | BL2 | - |----------| - | | - 0x04001000 +----------+ - | MHU | - 0x04000000 +----------+ - - -10. 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/tools_share/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. - Bits 0-31: Reserved - Bits 32-47: Platform defined - Bits 48-63: Reserved - -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/tools_share/firmware_image_package.h`. 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/fiptool`. - -### 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 ARM development platforms, this is -currently NOR FLASH. - -Bootloader images are loaded according to the platform policy as specified by -the function `plat_get_image_source()`. For the ARM development platforms, this -means the platform will attempt to load images from a Firmware Image Package -located at the start of NOR FLASH0. - -The ARM development platforms' policy is to only allow loading of a known set of -images. The platform policy can be modified to allow additional images. - - -11. Use of coherent memory in Trusted Firmware ------------------------------------------------ - -There might be loss of coherency when physical memory with mismatched -shareability, cacheability and memory attributes is accessed by multiple CPUs -(refer to section B2.9 of [ARM ARM] for more details). This possibility occurs -in Trusted Firmware during power up/down sequences when coherency, MMU and -caches are turned on/off incrementally. - -Trusted Firmware defines coherent memory as a region of memory with Device -nGnRE attributes in the translation tables. The translation granule size in -Trusted Firmware is 4KB. This is the smallest possible size of the coherent -memory region. - -By default, all data structures which are susceptible to accesses with -mismatched attributes from various CPUs are allocated in a coherent memory -region (refer to section 2.1 of [Porting Guide]). The coherent memory region -accesses are Outer Shareable, non-cacheable and they can be accessed -with the Device nGnRE attributes when the MMU is turned on. Hence, at the -expense of at least an extra page of memory, Trusted Firmware is able to work -around coherency issues due to mismatched memory attributes. - -The alternative to the above approach is to allocate the susceptible data -structures in Normal WriteBack WriteAllocate Inner shareable memory. This -approach requires the data structures to be designed so that it is possible to -work around the issue of mismatched memory attributes by performing software -cache maintenance on them. - -### Disabling the use of coherent memory in Trusted Firmware - -It might be desirable to avoid the cost of allocating coherent memory on -platforms which are memory constrained. Trusted Firmware enables inclusion of -coherent memory in firmware images through the build flag `USE_COHERENT_MEM`. -This flag is enabled by default. It can be disabled to choose the second -approach described above. - -The below sections analyze the data structures allocated in the coherent memory -region and the changes required to allocate them in normal memory. - -### Coherent memory usage in PSCI implementation - -The `psci_non_cpu_pd_nodes` data structure stores the platform's power domain -tree information for state management of power domains. By default, this data -structure is allocated in the coherent memory region in the Trusted Firmware -because it can be accessed by multple CPUs, either with caches enabled or -disabled. - - typedef struct non_cpu_pwr_domain_node { - /* - * Index of the first CPU power domain node level 0 which has this node - * as its parent. - */ - unsigned int cpu_start_idx; - - /* - * Number of CPU power domains which are siblings of the domain indexed - * by 'cpu_start_idx' i.e. all the domains in the range 'cpu_start_idx - * -> cpu_start_idx + ncpus' have this node as their parent. - */ - unsigned int ncpus; - - /* - * Index of the parent power domain node. - * TODO: Figure out whether to whether using pointer is more efficient. - */ - unsigned int parent_node; - - plat_local_state_t local_state; - - unsigned char level; - - /* For indexing the psci_lock array*/ - unsigned char lock_index; - } non_cpu_pd_node_t; - -In order to move this data structure to normal memory, the use of each of its -fields must be analyzed. Fields like `cpu_start_idx`, `ncpus`, `parent_node` -`level` and `lock_index` are only written once during cold boot. Hence removing -them from coherent memory involves only doing a clean and invalidate of the -cache lines after these fields are written. - -The field `local_state` can be concurrently accessed by multiple CPUs in -different cache states. A Lamport's Bakery lock `psci_locks` is used to ensure -mutual exlusion to this field and a clean and invalidate is needed after it -is written. - -### Bakery lock data - -The bakery lock data structure `bakery_lock_t` is allocated in coherent memory -and is accessed by multiple CPUs with mismatched attributes. `bakery_lock_t` is -defined as follows: - - typedef struct bakery_lock { - /* - * The lock_data is a bit-field of 2 members: - * Bit[0] : choosing. This field is set when the CPU is - * choosing its bakery number. - * Bits[1 - 15] : number. This is the bakery number allocated. - */ - volatile uint16_t lock_data[BAKERY_LOCK_MAX_CPUS]; - } bakery_lock_t; - -It is a characteristic of Lamport's Bakery algorithm that the volatile per-CPU -fields can be read by all CPUs but only written to by the owning CPU. - -Depending upon the data cache line size, the per-CPU fields of the -`bakery_lock_t` structure for multiple CPUs may exist on a single cache line. -These per-CPU fields can be read and written during lock contention by multiple -CPUs with mismatched memory attributes. Since these fields are a part of the -lock implementation, they do not have access to any other locking primitive to -safeguard against the resulting coherency issues. As a result, simple software -cache maintenance is not enough to allocate them in coherent memory. Consider -the following example. - -CPU0 updates its per-CPU field with data cache enabled. This write updates a -local cache line which contains a copy of the fields for other CPUs as well. Now -CPU1 updates its per-CPU field of the `bakery_lock_t` structure with data cache -disabled. CPU1 then issues a DCIVAC operation to invalidate any stale copies of -its field in any other cache line in the system. This operation will invalidate -the update made by CPU0 as well. - -To use bakery locks when `USE_COHERENT_MEM` is disabled, the lock data structure -has been redesigned. The changes utilise the characteristic of Lamport's Bakery -algorithm mentioned earlier. The bakery_lock structure only allocates the memory -for a single CPU. The macro `DEFINE_BAKERY_LOCK` allocates all the bakery locks -needed for a CPU into a section `bakery_lock`. The linker allocates the memory -for other cores by using the total size allocated for the bakery_lock section -and multiplying it with (PLATFORM_CORE_COUNT - 1). This enables software to -perform software cache maintenance on the lock data structure without running -into coherency issues associated with mismatched attributes. - -The bakery lock data structure `bakery_info_t` is defined for use when -`USE_COHERENT_MEM` is disabled as follows: - - typedef struct bakery_info { - /* - * The lock_data is a bit-field of 2 members: - * Bit[0] : choosing. This field is set when the CPU is - * choosing its bakery number. - * Bits[1 - 15] : number. This is the bakery number allocated. - */ - volatile uint16_t lock_data; - } bakery_info_t; - -The `bakery_info_t` represents a single per-CPU field of one lock and -the combination of corresponding `bakery_info_t` structures for all CPUs in the -system represents the complete bakery lock. The view in memory for a system -with n bakery locks are: - - bakery_lock section start - |----------------| - | `bakery_info_t`| <-- Lock_0 per-CPU field - | Lock_0 | for CPU0 - |----------------| - | `bakery_info_t`| <-- Lock_1 per-CPU field - | Lock_1 | for CPU0 - |----------------| - | .... | - |----------------| - | `bakery_info_t`| <-- Lock_N per-CPU field - | Lock_N | for CPU0 - ------------------ - | XXXXX | - | Padding to | - | next Cache WB | <--- Calculate PERCPU_BAKERY_LOCK_SIZE, allocate - | Granule | continuous memory for remaining CPUs. - ------------------ - | `bakery_info_t`| <-- Lock_0 per-CPU field - | Lock_0 | for CPU1 - |----------------| - | `bakery_info_t`| <-- Lock_1 per-CPU field - | Lock_1 | for CPU1 - |----------------| - | .... | - |----------------| - | `bakery_info_t`| <-- Lock_N per-CPU field - | Lock_N | for CPU1 - ------------------ - | XXXXX | - | Padding to | - | next Cache WB | - | Granule | - ------------------ - -Consider a system of 2 CPUs with 'N' bakery locks as shown above. For an -operation on Lock_N, the corresponding `bakery_info_t` in both CPU0 and CPU1 -`bakery_lock` section need to be fetched and appropriate cache operations need -to be performed for each access. - -On ARM Platforms, bakery locks are used in psci (`psci_locks`) and power controller -driver (`arm_lock`). - - -### Non Functional Impact of removing coherent memory - -Removal of the coherent memory region leads to the additional software overhead -of performing cache maintenance for the affected data structures. However, since -the memory where the data structures are allocated is cacheable, the overhead is -mostly mitigated by an increase in performance. - -There is however a performance impact for bakery locks, due to: -* Additional cache maintenance operations, and -* Multiple cache line reads for each lock operation, since the bakery locks - for each CPU are distributed across different cache lines. - -The implementation has been optimized to minimize this additional overhead. -Measurements indicate that when bakery locks are allocated in Normal memory, the -minimum latency of acquiring a lock is on an average 3-4 micro seconds whereas -in Device memory the same is 2 micro seconds. The measurements were done on the -Juno ARM development platform. - -As mentioned earlier, almost a page of memory can be saved by disabling -`USE_COHERENT_MEM`. Each platform needs to consider these trade-offs to decide -whether coherent memory should be used. If a platform disables -`USE_COHERENT_MEM` and needs to use bakery locks in the porting layer, it can -optionally define macro `PLAT_PERCPU_BAKERY_LOCK_SIZE` (see the [Porting -Guide]). Refer to the reference platform code for examples. - - -12. Isolating code and read-only data on separate memory pages ---------------------------------------------------------------- - -In the ARMv8 VMSA, translation table entries include fields that define the -properties of the target memory region, such as its access permissions. The -smallest unit of memory that can be addressed by a translation table entry is -a memory page. Therefore, if software needs to set different permissions on two -memory regions then it needs to map them using different memory pages. - -The default memory layout for each BL image is as follows: - - | ... | - +-------------------+ - | Read-write data | - +-------------------+ Page boundary - | | - +-------------------+ - | Exception vectors | - +-------------------+ 2 KB boundary - | | - +-------------------+ - | Read-only data | - +-------------------+ - | Code | - +-------------------+ BLx_BASE - -Note: The 2KB alignment for the exception vectors is an architectural -requirement. - -The read-write data start on a new memory page so that they can be mapped with -read-write permissions, whereas the code and read-only data below are configured -as read-only. - -However, the read-only data are not aligned on a page boundary. They are -contiguous to the code. Therefore, the end of the code section and the beginning -of the read-only data one might share a memory page. This forces both to be -mapped with the same memory attributes. As the code needs to be executable, this -means that the read-only data stored on the same memory page as the code are -executable as well. This could potentially be exploited as part of a security -attack. - -TF provides the build flag `SEPARATE_CODE_AND_RODATA` to isolate the code and -read-only data on separate memory pages. This in turn allows independent control -of the access permissions for the code and read-only data. In this case, -platform code gets a finer-grained view of the image layout and can -appropriately map the code region as executable and the read-only data as -execute-never. - -This has an impact on memory footprint, as padding bytes need to be introduced -between the code and read-only data to ensure the segragation of the two. To -limit the memory cost, this flag also changes the memory layout such that the -code and exception vectors are now contiguous, like so: - - | ... | - +-------------------+ - | Read-write data | - +-------------------+ Page boundary - | | - +-------------------+ - | Read-only data | - +-------------------+ Page boundary - | | - +-------------------+ - | Exception vectors | - +-------------------+ 2 KB boundary - | | - +-------------------+ - | Code | - +-------------------+ BLx_BASE - -With this more condensed memory layout, the separation of read-only data will -add zero or one page to the memory footprint of each BL image. Each platform -should consider the trade-off between memory footprint and security. - -This build flag is disabled by default, minimising memory footprint. On ARM -platforms, it is enabled. - - -13. Performance Measurement Framework --------------------------------------- - -The Performance Measurement Framework (PMF) facilitates collection of -timestamps by registered services and provides interfaces to retrieve -them from within the ARM Trusted Firmware. A platform can choose to -expose appropriate SMCs to retrieve these collected timestamps. - -By default, the global physical counter is used for the timestamp -value and is read via `CNTPCT_EL0`. The framework allows to retrieve -timestamps captured by other CPUs. - -### Timestamp identifier format - -A PMF timestamp is uniquely identified across the system via the -timestamp ID or `tid`. The `tid` is composed as follows: - - Bits 0-7: The local timestamp identifier. - Bits 8-9: Reserved. - Bits 10-15: The service identifier. - Bits 16-31: Reserved. - -1. The service identifier. Each PMF service is identified by a - service name and a service identifier. Both the service name and - identifier are unique within the system as a whole. - -2. The local timestamp identifier. This identifier is unique within a given - service. - -### Registering a PMF service - -To register a PMF service, the `PMF_REGISTER_SERVICE()` macro from `pmf.h` -is used. The arguments required are the service name, the service ID, -the total number of local timestamps to be captured and a set of flags. - -The `flags` field can be specified as a bitwise-OR of the following values: - - PMF_STORE_ENABLE: The timestamp is stored in memory for later retrieval. - PMF_DUMP_ENABLE: The timestamp is dumped on the serial console. - -The `PMF_REGISTER_SERVICE()` reserves memory to store captured -timestamps in a PMF specific linker section at build time. -Additionally, it defines necessary functions to capture and -retrieve a particular timestamp for the given service at runtime. - -The macro `PMF_REGISTER_SERVICE()` only enables capturing PMF -timestamps from within ARM Trusted Firmware. In order to retrieve -timestamps from outside of ARM Trusted Firmware, the -`PMF_REGISTER_SERVICE_SMC()` macro must be used instead. This macro -accepts the same set of arguments as the `PMF_REGISTER_SERVICE()` -macro but additionally supports retrieving timestamps using SMCs. - -### Capturing a timestamp - -PMF timestamps are stored in a per-service timestamp region. On a -system with multiple CPUs, each timestamp is captured and stored -in a per-CPU cache line aligned memory region. - -Having registered the service, the `PMF_CAPTURE_TIMESTAMP()` macro can be -used to capture a timestamp at the location where it is used. The macro -takes the service name, a local timestamp identifier and a flag as arguments. - -The `flags` field argument can be zero, or `PMF_CACHE_MAINT` which -instructs PMF to do cache maintenance following the capture. Cache -maintenance is required if any of the service's timestamps are captured -with data cache disabled. - -To capture a timestamp in assembly code, the caller should use -`pmf_calc_timestamp_addr` macro (defined in `pmf_asm_macros.S`) to -calculate the address of where the timestamp would be stored. The -caller should then read `CNTPCT_EL0` register to obtain the timestamp -and store it at the determined address for later retrieval. - -### Retrieving a timestamp - -From within ARM Trusted Firmware, timestamps for individual CPUs can -be retrieved using either `PMF_GET_TIMESTAMP_BY_MPIDR()` or -`PMF_GET_TIMESTAMP_BY_INDEX()` macros. These macros accept the CPU's MPIDR -value, or its ordinal position, respectively. - -From outside ARM Trusted Firmware, timestamps for individual CPUs can be -retrieved by calling into `pmf_smc_handler()`. - - Interface : pmf_smc_handler() - Argument : unsigned int smc_fid, u_register_t x1, - u_register_t x2, u_register_t x3, - u_register_t x4, void *cookie, - void *handle, u_register_t flags - Return : uintptr_t - - smc_fid: Holds the SMC identifier which is either `PMF_SMC_GET_TIMESTAMP_32` - when the caller of the SMC is running in AArch32 mode - or `PMF_SMC_GET_TIMESTAMP_64` when the caller is running in AArch64 mode. - x1: Timestamp identifier. - x2: The `mpidr` of the CPU for which the timestamp has to be retrieved. - This can be the `mpidr` of a different core to the one initiating - the SMC. In that case, service specific cache maintenance may be - required to ensure the updated copy of the timestamp is returned. - x3: A flags value that is either 0 or `PMF_CACHE_MAINT`. If - `PMF_CACHE_MAINT` is passed, then the PMF code will perform a - cache invalidate before reading the timestamp. This ensures - an updated copy is returned. - -The remaining arguments, `x4`, `cookie`, `handle` and `flags` are unused -in this implementation. - -### PMF code structure - -1. `pmf_main.c` consists of core functions that implement service registration, - initialization, storing, dumping and retrieving timestamps. - -2. `pmf_smc.c` contains the SMC handling for registered PMF services. - -3. `pmf.h` contains the public interface to Performance Measurement Framework. - -4. `pmf_asm_macros.S` consists of macros to facilitate capturing timestamps in - assembly code. - -5. `pmf_helpers.h` is an internal header used by `pmf.h`. - - -14. ARMv8 Architecture Extensions ----------------------------------- - -ARM Trusted Firmware makes use of ARMv8 Architecture Extensions where -applicable. This section lists the usage of Architecture Extensions, and build -flags controlling them. - -In general, and unless individually mentioned, the build options -`ARM_ARCH_MAJOR` and `ARM_ARCH_MINOR` selects the Architecture Extension to -target when building ARM Trusted Firmware. Subsequent ARM Architecture -Extensions are backward compatible with previous versions. - -The build system only requires that `ARM_ARCH_MAJOR` and `ARM_ARCH_MINOR` have a -valid numeric value. These build options only control whether or not -Architecture Extension-specific code is included in the build. Otherwise, ARM -Trusted Firmware targets the base ARMv8.0 architecture; i.e. as if -`ARM_ARCH_MAJOR` == 8 and `ARM_ARCH_MINOR` == 0, which are also their respective -default values. - -See also the _Summary of build options_ in [User Guide]. - -For details on the Architecture Extension and available features, please refer -to the respective Architecture Extension Supplement. - -### ARMv8.1 - -This Architecture Extension is targeted when `ARM_ARCH_MAJOR` >= 8, or when -`ARM_ARCH_MAJOR` == 8 and `ARM_ARCH_MINOR` >= 1. - -* The Compare and Swap instruction is used to implement spinlocks. Otherwise, - the load-/store-exclusive instruction pair is used. - -15. 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): - -* **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. The PSCI implementation and other EL3 runtime frameworks reside - as Library components. -* **Stage specific.** Code specific to a boot stage. -* **Drivers.** -* **Services.** EL3 runtime services (eg: 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 BL31? - bl1 Yes No No - bl2 No Yes No - bl31 No No Yes - plat Yes Yes Yes - drivers Yes No Yes - common Yes Yes Yes - lib Yes Yes Yes - services No No Yes - -The build system provides a non configurable build option IMAGE_BLx for each -boot loader stage (where x = BL stage). e.g. for BL1 , IMAGE_BL1 will be -defined by the build system. This enables the Trusted Firmware to compile -certain code only for specific boot loader stages - -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. - - -16. 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][PSCI] - -3. [SMC Calling Convention PDD][SMCCC] - -4. [ARM Trusted Firmware Interrupt Management Design guide][INTRG]. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved._ - -[ARM ARM]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.e/index.html "ARMv8-A Reference Manual (ARM DDI0487A.E)" -[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf "Power State Coordination Interface PDD (ARM DEN 0022D)" -[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf "SMC Calling Convention PDD (ARM DEN 0028B)" -[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 -[Firmware Update]: ./firmware-update.md -[PSCI Lib guide]: ./psci-lib-integration-guide.md diff --git a/docs/firmware-update.md b/docs/firmware-update.md deleted file mode 100644 index b04586e..0000000 --- a/docs/firmware-update.md +++ /dev/null @@ -1,388 +0,0 @@ -ARM Trusted Firmware - Firmware Update Design Guide -=================================================== - -Contents : - -1. [Introduction](#1--introduction) -2. [FWU Overview](#2--fwu-overview) -3. [Image Identification](#3--image-identification) -4. [FWU State Machine](#4--fwu-state-machine) -5. [BL1 SMC Interface](#5--bl1-smc-interface) - -- - - - - - - - - - - - - - - - - - - -1. Introduction ----------------- - -This document describes the design of the Firmware Update (FWU) feature, which -enables authenticated firmware to update firmware images from external -interfaces such as USB, UART, SD-eMMC, NAND, NOR or Ethernet to SoC Non-Volatile -memories such as NAND Flash, LPPDR2-NVM or any memory determined by the -platform. This feature functions even when the current firmware in the system -is corrupt or missing; it therefore may be used as a recovery mode. It may also -be complemented by other, higher level firmware update software. - -FWU implements a specific part of the Trusted Board Boot Requirements (TBBR) -specification, ARM DEN0006C-1. It should be used in conjunction with the -[Trusted Board Boot] design document, which describes the image authentication -parts of the Trusted Firmware (TF) TBBR implementation. - -### Scope - -This document describes the secure world FWU design. It is beyond its scope to -describe how normal world FWU images should operate. To implement normal world -FWU images, please refer to the "Non-Trusted Firmware Updater" requirements in -the TBBR. - - -2. FWU Overview ----------------- - -The FWU boot flow is primarily mediated by BL1. Since BL1 executes in ROM, and -it is usually desirable to minimize the amount of ROM code, the design allows -some parts of FWU to be implemented in other secure and normal world images. -Platform code may choose which parts are implemented in which images but the -general expectation is: - -* BL1 handles: - * Detection and initiation of the FWU boot flow. - * Copying images from non-secure to secure memory - * FWU image authentication - * Context switching between the normal and secure world during the FWU - process. -* Other secure world FWU images handle platform initialization required by - the FWU process. -* Normal world FWU images handle loading of firmware images from external - interfaces to non-secure memory. - -The primary requirements of the FWU feature are: - -1. Export a BL1 SMC interface to interoperate with other FWU images executing - at other Exception Levels. -2. Export a platform interface to provide FWU common code with the information - it needs, and to enable platform specific FWU functionality. See the - [Porting Guide] for details of this interface. - -TF uses abbreviated image terminology for FWU images like for other TF images. -An overview of this terminology can be found [here][TF Image Terminology]. - -The following diagram shows the FWU boot flow for ARM development platforms. -ARM CSS platforms like Juno have a System Control Processor (SCP), and these -use all defined FWU images. Other platforms may use a subset of these. - -![Flow Diagram](diagrams/fwu_flow.png?raw=true) - - -3. Image Identification ------------------------- - -Each FWU image and certificate is identified by a unique ID, defined by the -platform, which BL1 uses to fetch an image descriptor (`image_desc_t`) via a -call to `bl1_plat_get_image_desc()`. The same ID is also used to prepare the -Chain of Trust (Refer to the [Authentication Framework Design][Auth Framework] -for more information). - -The image descriptor includes the following information: - -* Executable or non-executable image. This indicates whether the normal world - is permitted to request execution of a secure world FWU image (after - authentication). Secure world certificates and non-AP images are examples - of non-executable images. -* Secure or non-secure image. This indicates whether the image is - authenticated/executed in secure or non-secure memory. -* Image base address and size. -* Image entry point configuration (an `entry_point_info_t`). -* FWU image state. - -BL1 uses the FWU image descriptors to: - -* Validate the arguments of FWU SMCs -* Manage the state of the FWU process -* Initialize the execution state of the next FWU image. - - -4. FWU State Machine ---------------------- - -BL1 maintains state for each FWU image during FWU execution. FWU images at lower -Exception Levels raise SMCs to invoke FWU functionality in BL1, which causes -BL1 to update its FWU image state. The BL1 image states and valid state -transitions are shown in the diagram below. Note that secure images have a more -complex state machine than non-secure images. - -![FWU state machine](diagrams/fwu_states.png?raw=true) - -The following is a brief description of the supported states: - -* RESET: This is the initial state of every image at the start of FWU. - Authentication failure also leads to this state. A secure - image may yield to this state if it has completed execution. - It can also be reached by using `FWU_SMC_IMAGE_RESET`. - -* COPYING: This is the state of a secure image while BL1 is copying it - in blocks from non-secure to secure memory. - -* COPIED: This is the state of a secure image when BL1 has completed - copying it to secure memory. - -* AUTHENTICATED: This is the state of an image when BL1 has successfully - authenticated it. - -* EXECUTED: This is the state of a secure, executable image when BL1 has - passed execution control to it. - -* INTERRUPTED: This is the state of a secure, executable image after it has - requested BL1 to resume normal world execution. - - -5. BL1 SMC Interface ---------------------- - -### BL1_SMC_CALL_COUNT - - Arguments: - uint32_t function ID : 0x0 - - Return: - uint32_t - -This SMC returns the number of SMCs supported by BL1. - -### BL1_SMC_UID - - Arguments: - uint32_t function ID : 0x1 - - Return: - UUID : 32 bits in each of w0-w3 (or r0-r3 for AArch32 callers) - -This SMC returns the 128-bit [Universally Unique Identifier][UUID] for the -BL1 SMC service. - -### BL1_SMC_VERSION - - Argument: - uint32_t function ID : 0x3 - - Return: - uint32_t : Bits [31:16] Major Version - Bits [15:0] Minor Version - -This SMC returns the current version of the BL1 SMC service. - -### BL1_SMC_RUN_IMAGE - - Arguments: - uint32_t function ID : 0x4 - entry_point_info_t *ep_info - - Return: - void - - Pre-conditions: - if (normal world caller) synchronous exception - if (ep_info not EL3) synchronous exception - -This SMC passes execution control to an EL3 image described by the provided -`entry_point_info_t` structure. In the normal TF boot flow, BL2 invokes this SMC -for BL1 to pass execution control to BL31. - - -### FWU_SMC_IMAGE_COPY - - Arguments: - uint32_t function ID : 0x10 - unsigned int image_id - uintptr_t image_addr - unsigned int block_size - unsigned int image_size - - Return: - int : 0 (Success) - : -ENOMEM - : -EPERM - - Pre-conditions: - if (image_id is invalid) return -EPERM - if (image_id is non-secure image) return -EPERM - if (image_id state is not (RESET or COPYING)) return -EPERM - if (secure world caller) return -EPERM - if (image_addr + block_size overflows) return -ENOMEM - if (image destination address + image_size overflows) return -ENOMEM - if (source block is in secure memory) return -ENOMEM - if (source block is not mapped into BL1) return -ENOMEM - if (image_size > free secure memory) return -ENOMEM - if (image overlaps another image) return -EPERM - -This SMC copies the secure image indicated by `image_id` from non-secure memory -to secure memory for later authentication. The image may be copied in a single -block or multiple blocks. In either case, the total size of the image must be -provided in `image_size` when invoking this SMC for the first time for each -image; it is ignored in subsequent calls (if any) for the same image. - -The `image_addr` and `block_size` specify the source memory block to copy from. -The destination address is provided by the platform code. - -If `block_size` is greater than the amount of remaining bytes to copy for this -image then the former is truncated to the latter. The copy operation is then -considered as complete and the FWU state machine transitions to the "COPIED" -state. If there is still more to copy, the FWU state machine stays in or -transitions to the COPYING state (depending on the previous state). - -When using multiple blocks, the source blocks do not necessarily need to be in -contiguous memory. - -Once the SMC is handled, BL1 returns from exception to the normal world caller. - - -### FWU_SMC_IMAGE_AUTH - - Arguments: - uint32_t function ID : 0x11 - unsigned int image_id - uintptr_t image_addr - unsigned int image_size - - Return: - int : 0 (Success) - : -ENOMEM - : -EPERM - : -EAUTH - - Pre-conditions: - if (image_id is invalid) return -EPERM - if (secure world caller) - if (image_id state is not RESET) return -EPERM - if (image_addr/image_size is not mappped into BL1) return -ENOMEM - else // normal world caller - if (image_id is secure image) - if (image_id state is not COPIED) return -EPERM - else // image_id is non-secure image - if (image_id state is not RESET) return -EPERM - if (image_addr/image_size is in secure memory) return -ENOMEM - if (image_addr/image_size not mappped into BL1) return -ENOMEM - -This SMC authenticates the image specified by `image_id`. If the image is in the - RESET state, BL1 authenticates the image in place using the provided -`image_addr` and `image_size`. If the image is a secure image in the COPIED -state, BL1 authenticates the image from the secure memory that BL1 previously -copied the image into. - -BL1 returns from exception to the caller. If authentication succeeds then BL1 -sets the image state to AUTHENTICATED. If authentication fails then BL1 returns -the -EAUTH error and sets the image state back to RESET. - - -### FWU_SMC_IMAGE_EXECUTE - - Arguments: - uint32_t function ID : 0x12 - unsigned int image_id - - Return: - int : 0 (Success) - : -EPERM - - Pre-conditions: - if (image_id is invalid) return -EPERM - if (secure world caller) return -EPERM - if (image_id is non-secure image) return -EPERM - if (image_id is non-executable image) return -EPERM - if (image_id state is not AUTHENTICATED) return -EPERM - -This SMC initiates execution of a previously authenticated image specified by -`image_id`, in the other security world to the caller. The current -implementation only supports normal world callers initiating execution of a -secure world image. - -BL1 saves the normal world caller's context, sets the secure image state to -EXECUTED, and returns from exception to the secure image. - - -### FWU_SMC_IMAGE_RESUME - - Arguments: - uint32_t function ID : 0x13 - register_t image_param - - Return: - register_t : image_param (Success) - : -EPERM - - Pre-conditions: - if (normal world caller and no INTERRUPTED secure image) return -EPERM - -This SMC resumes execution in the other security world while there is a secure -image in the EXECUTED/INTERRUPTED state. - -For normal world callers, BL1 sets the previously interrupted secure image state -to EXECUTED. For secure world callers, BL1 sets the previously executing secure -image state to INTERRUPTED. In either case, BL1 saves the calling world's -context, restores the resuming world's context and returns from exception into -the resuming world. If the call is successful then the caller provided -`image_param` is returned to the resumed world, otherwise an error code is -returned to the caller. - - -### FWU_SMC_SEC_IMAGE_DONE - - Arguments: - uint32_t function ID : 0x14 - - Return: - int : 0 (Success) - : -EPERM - - Pre-conditions: - if (normal world caller) return -EPERM - -This SMC indicates completion of a previously executing secure image. - -BL1 sets the previously executing secure image state to the RESET state, -restores the normal world context and returns from exception into the normal -world. - - -### FWU_SMC_UPDATE_DONE - - Arguments: - uint32_t function ID : 0x15 - register_t client_cookie - - Return: - N/A - -This SMC completes the firmware update process. BL1 calls the platform specific -function `bl1_plat_fwu_done`, passing the optional argument `client_cookie` as -a `void *`. The SMC does not return. - - -### FWU_SMC_IMAGE_RESET - - Arguments: - uint32_t function ID : 0x16 - unsigned int image_id - - Return: - int : 0 (Success) - : -EPERM - - Pre-conditions: - if (secure world caller) return -EPERM - if (image in EXECUTED) return -EPERM - -This SMC sets the state of an image to RESET and zeroes the memory used by it. - -This is only allowed if the image is not being executed. - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved._ - - -[Porting Guide]: ./porting-guide.md -[Auth Framework]: ./auth-framework.md -[Trusted Board Boot]: ./trusted-board-boot.md -[TF Image Terminology]: https://github.com/ARM-software/arm-trusted-firmware/wiki/ARM-Trusted-Firmware-Image-Terminology -[UUID]: https://tools.ietf.org/rfc/rfc4122.txt "A Universally Unique IDentifier (UUID) URN Namespace" diff --git a/docs/interrupt-framework-design.md b/docs/interrupt-framework-design.md deleted file mode 100644 index 1deab02..0000000 --- a/docs/interrupt-framework-design.md +++ /dev/null @@ -1,997 +0,0 @@ -ARM Trusted Firmware Interrupt Management Design guide -====================================================== - -Contents : - -1. [Introduction](#1-introduction) - * [Concepts](#11-concepts) - - [Interrupt Types](#111-interrupt-types) - - [Routing Model](#112-routing-model) - - [Valid Routing Models](#113-valid-routing-models) - + [Secure-EL1 Interrupts](#1131-secure-el1-interrupts) - + [Non-secure Interrupts](#1132-non-secure-interrupts) - + [EL3 interrupts](#1133-el3-interrupts) - - [Mapping of Interrupt Type to Signal](#114-mapping-of-interrupt-type-to-signal) - + [Effect of mapping of several interrupt types to one signal](#1141-effect-of-mapping-of-several-interrupt-types-to-one-signal) - - [Assumptions in Interrupt Management Framework](#12-assumptions-in-interrupt-management-framework) - -2. [Interrupt Management](#2-interrupt-management) - * [Software Components](#21-software-components) - * [Interrupt Registration](#22-interrupt-registration) - - [EL3 Runtime Firmware](#221-el3-runtime-firmware) - - [Secure Payload Dispatcher](#222-secure-payload-dispatcher) - + [Test Secure Payload Dispatcher behavior](#2221-test-secure-payload-dispatcher-behavior) - - [Secure Payload](#223-secure-payload) - + [Secure Payload IHF design w.r.t Secure-EL1 interrupts](#2231-secure-payload-ihf-design-wrt-secure-el1-interrupts) - + [Secure Payload IHF design w.r.t Non-secure interrupts](#2232-secure-payload-ihf-design-wrt-non-secure-interrupts) - + [Test Secure Payload behavior](#2233-test-secure-payload-behavior) - * [Interrupt Handling](#23-interrupt-handling) - - [EL3 Runtime Firmware](#231-el3-runtime-firmware) - - [Secure Payload Dispatcher](#232-secure-payload-dispatcher) - + [Interrupt Entry](#2321-interrupt-entry) - + [Interrupt Exit](#2322-interrupt-exit) - + [Test secure payload dispatcher Secure-EL1 interrupt handling](#2323-test-secure-payload-dispatcher-secure-el1-interrupt-handling) - + [Test secure payload dispatcher non-secure interrupt handling](#2324-test-secure-payload-dispatcher-non-secure-interrupt-handling) - - [Secure Payload](#233-secure-payload) - + [Test Secure Payload behavior](#2331-test-secure-payload-behavior) - -3. [Other considerations](#3-other-considerations) - * [Implication of preempted SMC on Non-Secure Software](#31-implication-of-preempted-smc-on-non-secure-software) - - -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 Concepts - -#### 1.1.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. - -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.1.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.1.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. EL3 interrupts are currently supported only -for GIC version 3.0 (ARM GICv3) and only the Secure-EL1 and Non-secure interrupt -types are supported for GIC version 2.0 (ARM GICv2) (See 1.2). 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.1.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 - non-secure state. This is a valid routing model as secure software in EL3 - can handover the interrupt to Secure-EL1 for handling. - - -##### 1.1.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 book-keeping 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 preempted 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.1.3.3 EL3 interrupts - -1. __CSS=0, TEL3=0__. Interrupt is routed to the FEL when execution is in - Secure-EL1/Secure-EL0. This is a valid routing model as secure software - in Secure-EL1/Secure-EL0 is in control of how its execution is preempted - by EL3 interrupt and can handover the interrupt to EL3 for handling. - -2. __CSS=0, TEL3=1__. Interrupt is routed to EL3 when execution is in - Secure-EL1/Secure-EL0. This is a valid routing model as secure software - in EL3 can handle the interrupt. - -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 - non-secure state. This is a valid routing model as secure software in EL3 - can handle the interrupt. - - -#### 1.1.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 signaled through the FIQ signal -while Non-secure interrupts are signaled through the IRQ signal. This applies -when execution is in either security state. - - -##### 1.1.4.1 Effect of mapping of several interrupt types to one signal -It should be noted that if more than one interrupt type maps to a single -interrupt signal, and if any one of the interrupt type sets __TEL3=1__ for a -particular security state, then interrupt signal will be routed to EL3 when in -that security state. This means that all the other interrupt types using the -same interrupt signal will be forced to the same routing model. This should be -borne in mind when choosing the routing model for an interrupt type. - -For example, in ARM GICv3, when the execution context is Secure-EL1/ -Secure-EL0, both the EL3 and the non secure interrupt types map to the FIQ -signal. So if either one of the interrupt type sets the routing model so -that __TEL3=1__ when __CSS=0__, the FIQ bit in `SCR_EL3` will be programmed to -route the FIQ signal to EL3 when executing in Secure-EL1/Secure-EL0, thereby -effectively routing the other interrupt type also to EL3. - - -### 1.2 Assumptions in Interrupt Management Framework -The framework makes the following assumptions to simplify its implementation. - -1. Although the framework has support for 2 types of secure interrupts (EL3 - and Secure-EL1 interrupt), only interrupt controller architectures - like ARM GICv3 has architectural support for EL3 interrupts in the form of - Group 0 interrupts. In ARM GICv2, all secure interrupts are assumed to be - handled in Secure-EL1. They can be delivered to Secure-EL1 via EL3 but they - cannot be handled in EL3. - -2. Interrupt exceptions (`PSTATE.I` and `F` bits) are masked during execution - in EL3. - - -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 [Porting Guide] to enable -handling of interrupts. - -In the remainder of this document, for the sake of simplicity a ARM GICv2 system -is considered and 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. EL3 interrupts are not considered. - - -### 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 Secure-EL1/Secure-EL0 and is - responsible for switching execution between secure and non-secure states. - A switch is triggered by a Secure Monitor Call and 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 `id` is parameter is reserved and could be used in the future for passing -the interrupt id of the highest pending interrupt only if there is a foolproof -way of determining the id. Currently it 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 must return a pointer to -`cpu_context` structure of the current CPU for the target security state. On -AArch64, this return value is currently ignored by the caller as the -appropriate `cpu_context` to be used is expected to be set by the handler -via the context management library APIs. -A portable interrupt handler implementation must set the target context both in -the structure pointed to by the returned pointer and via the context management -library APIs. The handler 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`. 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`. - -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 - -* When the build flag `TSP_NS_INTR_ASYNC_PREEMPT` is zero, the default routing - model is used for non-secure interrupts. They are routed to the FEL in - either security state i.e __CSS=0, TEL3=0__ & __CSS=1, TEL3=0__ for - Non-secure interrupts. - -* When the build flag `TSP_NS_INTR_ASYNC_PREEMPT` is defined to 1, then the - non secure interrupts are routed to EL3 when execution is in secure state - i.e __CSS=0, TEL3=1__ for non-secure interrupts. This effectively preempts - Secure-EL1. The default routing model is used for non secure interrupts in - non-secure state. i.e __CSS=1, TEL3=0__. - -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 `sel1_intr_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_sel1_intr_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. This - function is registered 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); - if (rc) - panic(); - -3. When the build flag `TSP_NS_INTR_ASYNC_PREEMPT` is defined to 1, the TSPD - implements a handler function for non-secure interrupts. This function is - registered with the EL3 runtime firmware using the - `register_interrupt_type_handler()` API as follows - - /* Forward declaration */ - interrupt_type_handler tspd_ns_interrupt_handler; - int32_t rc, flags = 0; - set_interrupt_rm_flag(flags, SECURE); - rc = register_interrupt_type_handler(INTR_TYPE_NS, - tspd_ns_interrupt_handler, - flags); - if (rc) - panic(); - - -#### 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 mode__ 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, a ARM GICv2 system is considered and 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 - triggered 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 separate 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-EL1 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 - triggered 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 preempted 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_sel1_intr_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 signaled - at the FIQ vector. Non-secure interrupts will be signaled 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 `id` parameter is set to `INTR_ID_UNAVAILABLE` currently. 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 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. A non-secure interrupt should never be routed to EL3 from - from non-secure state. Also if a routing model is chosen where Secure-EL1 - interrupts are routed to S-EL1 when execution is in Secure state, then a - S-EL1 interrupt should never be routed to EL3 from secure state. The handler - could use the security state flag to check this. - -2. Determining whether a context switch is required. This depends upon the - routing model and interrupt type. For non secure and S-EL1 interrupt, - if the security state of the execution context where the interrupt was - generated is not the same as the security state required for handling - the interrupt, a context switch is required. The following 2 cases - 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. The SPD - service should be able to handle this preemption or manage secure interrupt - priorities before handing control to the SP. - -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 interrupt Secure-EL1 when in -secure state if it has been configured to do so. 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.3 Test secure payload dispatcher Secure-EL1 interrupt handling -The example TSPD service registers a handler for Secure-EL1 interrupts taken -from the non-secure state. During execution in S-EL1, the TSPD expects that the -Secure-EL1 interrupts are handled in S-EL1 by TSP. Its handler -`tspd_secure_el1_interrupt_handler()` expects only to be invoked for Secure-EL1 -originating from the non-secure state. It takes the following actions upon being -invoked. - -1. 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. - -2. It saves the system register context for the non-secure state by calling - `cm_el1_sysregs_context_save(NON_SECURE);`. - -3. It sets the `ELR_EL3` system register to `tsp_sel1_intr_entry` and sets the - `SPSR_EL3.DAIF` bits in the secure CPU context. It sets `x0` to - `TSP_HANDLE_SEL1_INTR_AND_RETURN`. If the TSP was preempted earlier by a non - secure interrupt during `yielding` SMC processing, save the registers that - will be trashed, which is the `ELR_EL3` and `SPSR_EL3`, in order to be able - to re-enter TSP for Secure-EL1 interrupt processing. It does not need to - save any other secure context since the TSP is expected to preserve it - (see Section 2.2.2.1). - -4. It restores the system register context for the secure state by calling - `cm_el1_sysregs_context_restore(SECURE);`. - -5. 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);`. - -6. 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_INTR` as the function identifier to -signal completion of interrupt handling. - -The TSPD service takes the following actions in `tspd_smc_handler()` function -upon receiving an SMC with `TSP_HANDLED_S_EL1_INTR` as the function identifier: - -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. It restores the saved `ELR_EL3` and `SPSR_EL3` system registers back to - the secure CPU context (see step 3 above) in case the TSP had been preempted - by a non secure interrupt earlier. - -3. It restores the system register context for the non-secure state by - calling `cm_el1_sysregs_context_restore(NON_SECURE)`. - -4. 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)`. - -5. `tspd_smc_handler()` returns a reference to the non-secure `cpu_context` - as the return value. - - -##### 2.3.2.4 Test secure payload dispatcher non-secure interrupt handling -The TSP in Secure-EL1 can be preempted by a non-secure interrupt during -`yielding` SMC processing or by a higher priority EL3 interrupt during -Secure-EL1 interrupt processing. Currently only non-secure interrupts can -cause preemption of TSP since there are no EL3 interrupts in the -system. - -It should be noted that while TSP is preempted, the TSPD only allows entry into -the TSP either for Secure-EL1 interrupt handling or for resuming the preempted -`yielding` SMC in response to the `TSP_FID_RESUME` SMC from the normal world. -(See Section 3). - -The non-secure interrupt triggered in Secure-EL1 during `yielding` SMC processing -can be routed to either EL3 or Secure-EL1 and is controlled by build option -`TSP_NS_INTR_ASYNC_PREEMPT` (see Section 2.2.2.1). If the build option is set, -the TSPD will set the routing model for the non-secure interrupt to be routed to -EL3 from secure state i.e. __TEL3=1, CSS=0__ and registers -`tspd_ns_interrupt_handler()` as the non-secure interrupt handler. The -`tspd_ns_interrupt_handler()` on being invoked ensures that the interrupt -originated from the secure state and disables routing of non-secure interrupts -from secure state to EL3. This is to prevent further preemption (by a non-secure -interrupt) when TSP is reentered for handling Secure-EL1 interrupts that -triggered while execution was in the normal world. The -`tspd_ns_interrupt_handler()` then invokes `tspd_handle_sp_preemption()` for -further handling. - -If the `TSP_NS_INTR_ASYNC_PREEMPT` build option is zero (default), the default -routing model for non-secure interrupt in secure state is in effect -i.e. __TEL3=0, CSS=0__. During `yielding` SMC processing, the IRQ -exceptions are unmasked i.e. `PSTATE.I=0`, and a non-secure interrupt will -trigger at Secure-EL1 IRQ exception vector. The TSP saves the general purpose -register context and issues an SMC with `TSP_PREEMPTED` as the function -identifier to signal preemption of TSP. The TSPD SMC handler, -`tspd_smc_handler()`, ensures that the SMC call originated from the -secure state otherwise execution returns to the non-secure state with -`SMC_UNK` in `x0`. It then invokes `tspd_handle_sp_preemption()` for -further handling. - -The `tspd_handle_sp_preemption()` takes the following actions upon being -invoked: - -1. It saves the system register context for the secure state by calling - `cm_el1_sysregs_context_save(SECURE)`. - -2. It restores the system register context for the non-secure state by - calling `cm_el1_sysregs_context_restore(NON_SECURE)`. - -3. 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)`. - -4. `SMC_PREEMPTED` is set in x0 and return to non secure state after - restoring non secure context. - -The Normal World is expected to resume the TSP after the `yielding` SMC preemption -by issuing an SMC with `TSP_FID_RESUME` as the function identifier (see section 3). -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 non-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 when the -`TSP_NS_INTR_ASYNC_PREEMPT` build flag is 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_sel1_intr_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_sel1_intr_stats()`. It then calls -`tsp_common_int_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. If it is not the secure physical timer interrupt, then - that means that a higher priority interrupt has preempted it. Invoke - `tsp_handle_preemption()` to handover control back to EL3 by issuing - an SMC with `TSP_PREEMPTED` as the function identifier. - -2. Handles the secure timer interrupt 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_INTR` as the function identifier. - -The TSP handles interrupts under the asynchronous model as follows. - -1. Secure-EL1 interrupts are handled by calling the `tsp_common_int_handler()` - function. The function has been described above. - -2. Non-secure interrupts are handled by by calling the `tsp_common_int_handler()` - function which ends up invoking `tsp_handle_preemption()` and 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.4). - - -3. Other considerations ------------------------ - -### 3.1 Implication of preempted SMC on Non-Secure Software -A `yielding` SMC call to Secure payload can be preempted by a non-secure -interrupt and the execution can return to the non-secure world for handling -the interrupt (For details on `yielding` SMC refer [SMC calling convention]). -In this case, the SMC call has not completed its execution and the execution -must return back to the secure payload to resume the preempted SMC call. -This can be achieved by issuing an SMC call which instructs to resume the -preempted SMC. - -A `fast` SMC cannot be preempted and hence this case will not happen for -a fast SMC call. - -In the Test Secure Payload implementation, `TSP_FID_RESUME` is designated -as the resume SMC FID. It is important to note that `TSP_FID_RESUME` is a -`yielding` SMC which means it too can be be preempted. The typical non -secure software sequence for issuing a `yielding` SMC would look like this, -assuming `P.STATE.I=0` in the non secure state : - - int rc; - rc = smc(TSP_YIELD_SMC_FID, ...); /* Issue a Yielding SMC call */ - /* The pending non-secure interrupt is handled by the interrupt handler - and returns back here. */ - while (rc == SMC_PREEMPTED) { /* Check if the SMC call is preempted */ - rc = smc(TSP_FID_RESUME); /* Issue resume SMC call */ - } - -The `TSP_YIELD_SMC_FID` is any `yielding` SMC function identifier and the smc() -function invokes a SMC call with the required arguments. The pending non-secure -interrupt causes an IRQ exception and the IRQ handler registered at the -exception vector handles the non-secure interrupt and returns. The return value -from the SMC call is tested for `SMC_PREEMPTED` to check whether it is -preempted. If it is, then the resume SMC call `TSP_FID_RESUME` is issued. The -return value of the SMC call is tested again to check if it is preempted. -This is done in a loop till the SMC call succeeds or fails. If a `yielding` -SMC is preempted, until it is resumed using `TSP_FID_RESUME` SMC and -completed, the current TSPD prevents any other SMC call from re-entering -TSP by returning `SMC_UNK` error. - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved._ - -[Porting Guide]: ./porting-guide.md -[SMC calling convention]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" diff --git a/docs/plat/hikey.md b/docs/plat/hikey.md deleted file mode 100644 index 5e62a5b..0000000 --- a/docs/plat/hikey.md +++ /dev/null @@ -1,147 +0,0 @@ - -Description -==================== -HiKey is one of 96boards. Hisilicon Kirin6220 processor is installed on HiKey. - -More information are listed in [link](https://github.com/96boards/documentation/blob/master/ConsumerEdition/HiKey/Quickstart/README.md). - - -How to build -==================== - -1. Code Locations ------------------ - - * ARM Trusted Firmware: - [link](https://github.com/ARM-software/arm-trusted-firmware) - - * edk2: - [link](https://github.com/96boards-hikey/edk2/tree/testing/hikey960_v2.5) - - * OpenPlatformPkg: - [link](https://github.com/96boards-hikey/OpenPlatformPkg/tree/testing/hikey960_v1.3.4) - - * l-loader: - [link](https://github.com/96boards-hikey/l-loader/tree/testing/hikey960_v1.2) - - * uefi-tools: - [link](https://github.com/96boards-hikey/uefi-tools/tree/testing/hikey960_v1) - - * atf-fastboot: - [link](https://github.com/96boards-hikey/atf-fastboot/tree/master) - - -2. Build Procedure ------------------- - - * Fetch all the above repositories into local host. - Make all the repositories in the same ${BUILD_PATH}. - - * Create the symbol link to OpenPlatformPkg in edk2. - ```shell - $cd ${BUILD_PATH}/edk2 - $ln -sf ../OpenPlatformPkg - ``` - - * Prepare AARCH64 && AARCH32 toolchain. Prepare python. - - * If your hikey hardware is built by CircuitCo, update _uefi-tools/platform.config_ first. _(optional)_ - __Uncomment the below sentence. Otherwise, UEFI can't output messages on serial - console on hikey.__ - ```shell - BUILDFLAGS=-DSERIAL_BASE=0xF8015000 - ``` - If your hikey hardware is built by LeMarker, nothing to do. - - * Build it as debug mode. Create your own build script file or you could refer to __build_uefi.sh__ in l-loader git repository. - ```shell - BUILD_OPTION=DEBUG - export AARCH64_TOOLCHAIN=GCC5 - export UEFI_TOOLS_DIR=${BUILD_PATH}/uefi-tools - export EDK2_DIR=${BUILD_PATH}/edk2 - EDK2_OUTPUT_DIR=${EDK2_DIR}/Build/HiKey/${BUILD_OPTION}_${AARCH64_TOOLCHAIN} - # Build fastboot for ARM Trust Firmware. It's used for recovery mode. - cd ${BUILD_PATH}/atf-fastboot - CROSS_COMPILE=aarch64-linux-gnu- make PLAT=hikey DEBUG=1 - # Convert DEBUG/RELEASE to debug/release - FASTBOOT_BUILD_OPTION=$(echo ${BUILD_OPTION} | tr '[A-Z]' '[a-z]') - cd ${EDK2_DIR} - # Build UEFI & ARM Trust Firmware - ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware hikey - # Generate l-loader.bin - cd ${BUILD_PATH}/l-loader - ln -sf ${EDK2_OUTPUT_DIR}/FV/bl1.bin - ln -sf ${EDK2_OUTPUT_DIR}/FV/fip.bin - ln -sf ${BUILD_PATH}/atf-fastboot/build/hikey/${FASTBOOT_BUILD_OPTION}/bl1.bin fastboot.bin - python gen_loader.py -o l-loader.bin --img_bl1=bl1.bin --img_ns_bl1u=BL33_AP_UEFI.fd - arm-linux-gnueabihf-gcc -c -o start.o start.S - arm-linux-gnueabihf-ld -Bstatic -Tl-loader.lds -Ttext 0xf9800800 start.o -o loader - arm-linux-gnueabihf-objcopy -O binary loader temp - python gen_loader_hikey.py -o l-loader.bin --img_loader=temp --img_bl1=bl1.bin --img_ns_bl1u=fastboot.bin - ``` - - * Generate partition table for aosp. The eMMC capacity is either 4GB or 8GB. Just change "aosp-4g" to "linux-4g" for debian. - ```shell - $PTABLE=aosp-4g SECTOR_SIZE=512 bash -x generate_ptable.sh - ``` - - -3. Setup Console ----------------- - - * Install ser2net. Use telnet as the console since UEFI fails to display Boot Manager GUI in minicom. __If you don't need Boot Manager GUI, just ignore this section.__ - ```shell - $sudo apt-get install ser2net - ``` - - * Configure ser2net. - ```shell - $sudo vi /etc/ser2net.conf - ``` - - Append one line for serial-over-USB in below. - _#ser2net.conf_ - ```shell - 2004:telnet:0:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT banner - ``` - - * Open the console. - ```shell - $telnet localhost 2004 - ``` - - And you could open the console remotely, too. - - -4. Flush images in recovery mode ------------------------------ - - * Make sure Pin3-Pin4 on J15 are connected for recovery mode. Then power on HiKey. - - * Remove the modemmanager package. This package may cause the idt tool failure. - ```shell - $sudo apt-get purge modemmanager - ``` - - * Run the command to download l-loader.bin into HiKey. - ```shell - $sudo python hisi-idt.py -d /dev/ttyUSB1 --img1 l-loader.bin - ``` - - * Update images. All aosp or debian images could be fetched from [link](https://builds.96boards.org/). - ```shell - $sudo fastboot flash ptable prm_ptable.img - $sudo fastboot flash fastboot fip.bin - $sudo fastboot flash boot boot.img - $sudo fastboot flash cache cache.img - $sudo fastboot flash system system.img - $sudo fastboot flash userdata userdata.img - ``` - - -5. Boot UEFI in normal mode ------------------------------ - - * Make sure Pin3-Pin4 on J15 are open for normal boot mode. Then power on HiKey. - - * Reference [link](https://github.com/96boards-hikey/tools-images-hikey960/blob/master/build-from-source/README-ATF-UEFI-build-from-source.md) diff --git a/docs/plat/hikey960.md b/docs/plat/hikey960.md deleted file mode 100644 index 8442a18..0000000 --- a/docs/plat/hikey960.md +++ /dev/null @@ -1,159 +0,0 @@ - -Description -==================== -HiKey960 is one of 96boards. Hisilicon Hi3660 processor is installed on HiKey960. - -More information are listed in [link](http://www.96boards.org/documentation/ConsumerEdition/HiKey960/README.md). - - -How to build -==================== - -1. Code Locations ------------------ - - * ARM Trusted Firmware: - [link](https://github.com/ARM-software/arm-trusted-firmware) - - * edk2: - [link](https://github.com/96boards-hikey/edk2/tree/testing/hikey960_v2.5) - - * OpenPlatformPkg: - [link](https://github.com/96boards-hikey/OpenPlatformPkg/tree/testing/hikey960_v1.3.4) - - * l-loader: - [link](https://github.com/96boards-hikey/l-loader/tree/testing/hikey960_v1.2) - - * uefi-tools: - [link](https://github.com/96boards-hikey/uefi-tools/tree/hikey960_v1) - - -2. Build Procedure ------------------- - - * Fetch all the above 5 repositories into local host. - Make all the repositories in the same ${BUILD_PATH}. - - * Create the symbol link to OpenPlatformPkg in edk2. - ```shell - $cd ${BUILD_PATH}/edk2 - $ln -sf ../OpenPlatformPkg - ``` - - * Prepare AARCH64 toolchain. - - * If your hikey960 hardware is v1, update _uefi-tools/platform.config_ first. _(optional)_ - __Uncomment the below sentence. Otherwise, UEFI can't output messages on serial - console on hikey960 v1.__ - ```shell - BUILDFLAGS=-DSERIAL_BASE=0xFDF05000 - ``` - If your hikey960 hardware is v2 or newer, nothing to do. - - * Build it as debug mode. Create script file for build. - ```shell - BUILD_OPTION=DEBUG - export AARCH64_TOOLCHAIN=GCC48 - export UEFI_TOOLS_DIR=${BUILD_PATH}/uefi-tools - export EDK2_DIR=${BUILD_PATH}/edk2 - EDK2_OUTPUT_DIR=${EDK2_DIR}/Build/HiKey960/${BUILD_OPTION}_${AARCH64_TOOLCHAIN} - cd ${EDK2_DIR} - # Build UEFI & ARM Trust Firmware - ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware hikey960 - # Generate l-loader.bin - cd ${BUILD_PATH}/l-loader - ln -sf ${EDK2_OUTPUT_DIR}/FV/bl1.bin - ln -sf ${EDK2_OUTPUT_DIR}/FV/fip.bin - ln -sf ${EDK2_OUTPUT_DIR}/FV/BL33_AP_UEFI.fd - python gen_loader.py -o l-loader.bin --img_bl1=bl1.bin --img_ns_bl1u=BL33_AP_UEFI.fd - ``` - - * Generate partition table. - _Make sure that you're using the sgdisk in the l-loader directory._ - ```shell - $PTABLE=aosp-32g SECTOR_SIZE=4096 SGDISK=./sgdisk bash -x generate_ptable.sh - ``` - - -3. Setup Console ----------------- - - * Install ser2net. Use telnet as the console since UEFI will output window - that fails to display in minicom. - ```shell - $sudo apt-get install ser2net - ``` - - * Configure ser2net. - ```shell - $sudo vi /etc/ser2net.conf - ``` - Append one line for serial-over-USB in _#ser2net.conf_ - ``` - 2004:telnet:0:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT banner - ``` - - * Open the console. - ```shell - $telnet localhost 2004 - ``` - And you could open the console remotely, too. - - -4. Boot UEFI in recovery mode ------------------------------ - - * Fetch that are used in recovery mode. The code location is in below. - [link](https://github.com/96boards-hikey/tools-images-hikey960) - - * Generate l-loader.bin. - ```shell - $cd tools-images-hikey960 - $ln -sf ${BUILD_PATH}/l-loader/l-loader.bin - ``` - - * Prepare config file. - ```shell - $vi config - # The content of config file - ./sec_user_xloader.img 0x00020000 - ./sec_uce_boot.img 0x6A908000 - ./l-loader.bin 0x1AC00000 - ``` - - * Remove the modemmanager package. This package may causes hikey_idt tool failure. - ```shell - $sudo apt-get purge modemmanager - ``` - - * Run the command to download l-loader.bin into HiKey960. - ```shell - $sudo ./hikey_idt -c config -p /dev/ttyUSB1 - ``` - - * UEFI running in recovery mode. - When prompt '.' is displayed on console, press hotkey 'f' in keyboard. Then Android fastboot app is running. - The timeout of prompt '.' is 10 seconds. - - * Update images. - ```shell - $sudo fastboot flash ptable prm_ptable.img - $sudo fastboot flash xloader sec_xloader.img - $sudo fastboot flash fastboot l-loader.bin - $sudo fastboot flash fip fip.bin - $sudo fastboot flash boot boot.img - $sudo fastboot flash cache cache.img - $sudo fastboot flash system system.img - $sudo fastboot flash userdata userdata.img - ``` - - * Notice: UEFI could also boot kernel in recovery mode, but BL31 isn't loaded in - recovery mode. - - -5. Boot UEFI in normal mode ------------------------------ - - * Make sure "Boot Mode" switch is OFF for normal boot mode. Then power on HiKey960. - - * Reference [link](https://github.com/96boards-hikey/tools-images-hikey960/blob/master/build-from-source/README-ATF-UEFI-build-from-source.md) diff --git a/docs/plat/nvidia-tegra.md b/docs/plat/nvidia-tegra.md deleted file mode 100644 index 3cb1682..0000000 --- a/docs/plat/nvidia-tegra.md +++ /dev/null @@ -1,95 +0,0 @@ -Tegra SoCs - Overview -====================== - -* T210 -------- - -T210 has Quad ARM® Cortex®-A57 cores in a switched configuration with a -companion set of quad ARM Cortex-A53 cores. The Cortex-A57 and A53 cores -support ARMv8, executing both 64-bit Aarch64 code, and 32-bit Aarch32 code -including legacy ARMv7 applications. The Cortex-A57 processors each have -48 KB Instruction and 32 KB Data Level 1 caches; and have a 2 MB shared -Level 2 unified cache. The Cortex-A53 processors each have 32 KB Instruction -and 32 KB Data Level 1 caches; and have a 512 KB shared Level 2 unified cache. - -* T132 -------- - -Denver is NVIDIA's own custom-designed, 64-bit, dual-core CPU which is -fully ARMv8 architecture compatible. Each of the two Denver cores -implements a 7-way superscalar microarchitecture (up to 7 concurrent -micro-ops can be executed per clock), and includes a 128KB 4-way L1 -instruction cache, a 64KB 4-way L1 data cache, and a 2MB 16-way L2 -cache, which services both cores. - -Denver implements an innovative process called Dynamic Code Optimization, -which optimizes frequently used software routines at runtime into dense, -highly tuned microcode-equivalent routines. These are stored in a -dedicated, 128MB main-memory-based optimization cache. After being read -into the instruction cache, the optimized micro-ops are executed, -re-fetched and executed from the instruction cache as long as needed and -capacity allows. - -Effectively, this reduces the need to re-optimize the software routines. -Instead of using hardware to extract the instruction-level parallelism -(ILP) inherent in the code, Denver extracts the ILP once via software -techniques, and then executes those routines repeatedly, thus amortizing -the cost of ILP extraction over the many execution instances. - -Denver also features new low latency power-state transitions, in addition -to extensive power-gating and dynamic voltage and clock scaling based on -workloads. - -Directory structure -==================== - -* plat/nvidia/tegra/common - Common code for all Tegra SoCs -* plat/nvidia/tegra/soc/txxx - Chip specific code - -Trusted OS dispatcher -===================== -Tegra supports multiple Trusted OS', Trusted Little Kernel (TLK) being one of -them. In order to include the 'tlkd' dispatcher in the image, pass 'SPD=tlkd' -on the command line while preparing a bl31 image. This allows other Trusted OS -vendors to use the upstream code and include their dispatchers in the image -without changing any makefiles. - -Preparing the BL31 image to run on Tegra SoCs -=================================================== -```shell -CROSS_COMPILE=/bin/aarch64-none-elf- make PLAT=tegra \ -TARGET_SOC= SPD= bl31 -``` - -Platforms wanting to use different TZDRAM_BASE, can add `TZDRAM_BASE=` -to the build command line. - -The Tegra platform code expects a pointer to the following platform specific -structure via 'x1' register from the BL2 layer which is used by the -bl31_early_platform_setup() handler to extract the TZDRAM carveout base and -size for loading the Trusted OS and the UART port ID to be used. The Tegra -memory controller driver programs this base/size in order to restrict NS -accesses. - -typedef struct plat_params_from_bl2 { - /* TZ memory size */ - uint64_t tzdram_size; - /* TZ memory base */ - uint64_t tzdram_base; - /* UART port ID */ - int uart_id; -} plat_params_from_bl2_t; - -Power Management -================ -The PSCI implementation expects each platform to expose the 'power state' -parameter to be used during the 'SYSTEM SUSPEND' call. The state-id field -is implementation defined on Tegra SoCs and is preferably defined by -tegra_def.h. - -Tegra configs -============= - -* 'tegra_enable_l2_ecc_parity_prot': This flag enables the L2 ECC and Parity - Protection bit, for ARM Cortex-A57 CPUs, during CPU boot. This flag will - be enabled by Tegrs SoCs during 'Cluster power up' or 'System Suspend' exit. diff --git a/docs/plat/qemu.md b/docs/plat/qemu.md deleted file mode 100644 index 5e6bcbc..0000000 --- a/docs/plat/qemu.md +++ /dev/null @@ -1,44 +0,0 @@ -ARM Trusted Firmware for QEMU virt ARMv8-A -========================================== - -ARM Trusted Firmware implements the EL3 firmware layer for QEMU virt -ARMv8-A. BL1 is used as the BootROM, supplied with the -bios argument. -When QEMU starts all CPUs are released simultaneously, BL1 selects a -primary CPU to handle the boot and the secondaries are placed in a polling -loop to be released by normal world via PSCI. - -BL2 edits the Flattened Device Tree, FDT, generated by QEMU at run-time to -add a node describing PSCI and also enable methods for the CPUs. - -An ARM64 defonfig v4.5 Linux kernel is known to boot, FTD doesn't need to be -provided as it's generated by QEMU. - -Current limitations: -* Only cold boot is supported -* No build instructions for QEMU_EFI.fd and rootfs-arm64.cpio.gz -* No instructions for how to load a BL32 (Secure Payload) - -`QEMU_EFI.fd` can be dowloaded from -http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-KERNEL-AARCH64/RELEASE_GCC49/QEMU_EFI.fd - -Boot binaries, except BL1, are primarily loaded via semi-hosting so all -binaries has to reside in the same directory as QEMU is started from. This -is conveniently achieved with symlinks the local names as: -* `bl2.bin` -> BL2 -* `bl31.bin` -> BL31 -* `bl33.bin` -> BL33 (`QEMU_EFI.fd`) -* `Image` -> linux/Image - -To build: -``` -make CROSS_COMPILE=aarch64-none-elf- PLAT=qemu -``` - -To start (QEMU v2.6.0): -``` -qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57 \ - -kernel Image \ - -append console=ttyAMA0,38400 keep_bootcon root=/dev/vda2 \ - -initrd rootfs-arm64.cpio.gz -smp 2 -m 1024 -bios bl1.bin \ - -d unimp -semihosting-config enable,target=native -``` diff --git a/docs/plat/socionext-uniphier.md b/docs/plat/socionext-uniphier.md deleted file mode 100644 index 91d72ec..0000000 --- a/docs/plat/socionext-uniphier.md +++ /dev/null @@ -1,130 +0,0 @@ -ARM Trusted Firmware for Socionext UniPhier SoCs -================================================ - -Socionext UniPhier ARMv8-A SoCs use ARM Trusted Firmware as the secure world -firmware, supporting BL1, BL2, and BL31. - -UniPhier SoC family implements its internal boot ROM, so BL1 is used as pseudo -ROM (i.e. runs in RAM). The internal boot ROM loads 64KB [1] image from a -non-volatile storage to the on-chip SRAM. Unfortunately, BL1 does not fit in -the 64KB limit if [Trusted Board Boot] (TBB) is enabled. To solve this problem, -Socionext provides a first stage loader called [UniPhier BL]. This loader runs -in the on-chip SRAM, initializes the DRAM, expands BL1 there, and hands the -control over to it. Therefore, all images of ARM Trusted Firmware run in DRAM. - -The UniPhier platform works with/without TBB. See below for the build process -of each case. The image authentication for the UniPhier platform fully -complies with the Trusted Board Boot Requirements (TBBR) specification. - -The UniPhier BL does not implement the authentication functionality, that is, -it can not verify the BL1 image by itself. Instead, the UniPhier BL assures -the BL1 validity in a different way; BL1 is GZIP-compressed and appended to -the UniPhier BL. The concatenation of the UniPhier BL and the compressed BL1 -fits in the 64KB limit. The concatenated image is loaded by the boot ROM -(and verified if the chip fuses are blown). - -[1]: Some SoCs can load 80KB, but the software implementation must be aligned - to the lowest common denominator. - -[Trusted Board Boot]: ../trusted-board-boot.md - -[UniPhier BL]: https://github.com/uniphier/uniphier-bl - - -Boot Flow ---------- - -1. The Boot ROM - - This is hard-wired ROM, so never corrupted. It loads the UniPhier BL (with - compressed-BL1 appended) into the on-chip SRAM. If the SoC fuses are blown, - the image is verified by the SoC's own method. - -2. UniPhier BL - - This runs in the on-chip SRAM. After the minimum SoC initialization and DRAM - setup, it decompresses the appended BL1 image into the DRAM, then jumps to - the BL1 entry. - -3. BL1 - - This runs in the DRAM. It extracts BL2 from FIP (Firmware Image Package). - If TBB is enabled, the BL2 is authenticated by the standard mechanism of ARM - Trusted Firmware. - -4. BL2, BL31, and more - - They all run in the DRAM, and are authenticated by the standard mechanism if - TBB is enabled. See [Firmware Design] for details. - -[Firmware Design]: ../firmware-design.md - - -Basic Build ------------ - -BL1 must be compressed for the reason above. The UniPhier's platform makefile -provides a build target `bl1_gzip` for this. - -For a non-secure boot loader (aka BL33), U-Boot is well supported for UniPhier -SoCs. The U-Boot image (`u-boot.bin`) must be built in advance. For the build -procedure of U-Boot, refer to the document in the [U-Boot] project. - -[U-Boot]: https://www.denx.de/wiki/U-Boot - -To build minimum functionality for UniPhier (without TBB): - -``` -make CROSS_COMPILE= PLAT=uniphier BL33= bl1_gzip fip -``` - -Output images: - -- `bl1.bin.gzip` -- `fip.bin` - - -Optional features ------------------ - -- Trusted Board Boot - -[mbed TLS] is needed as the cryptographic and image parser modules. -Refer to the [User Guide] for the appropriate version of mbed TLS. - -To enable TBB, add the following options to the build command: - -``` - TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 MBEDTLS_DIR= -``` - -[mbed TLS]: https://tls.mbed.org/ - -[User Guide]: ../user-guide.md - -- System Control Processor (SCP) - -If desired, FIP can include an SCP BL2 image. If BL2 finds an SCP BL2 image -in FIP, BL2 loads it into DRAM and kicks the SCP. Most of UniPhier boards -still work without SCP, but SCP provides better power management support. - -To include SCP_BL2, add the following option to the build command: - -``` - SCP_BL2= -``` - -- BL32 (Secure Payload) - -To enable BL32, add the following option to the build command: - -``` - SPD= BL32= -``` - -If you use TSP for BL32, `BL32=` is not required. Just add the -following: - -``` - SPD=tspd -``` diff --git a/docs/plat/xilinx-zynqmp.md b/docs/plat/xilinx-zynqmp.md deleted file mode 100644 index d2dc8b7..0000000 --- a/docs/plat/xilinx-zynqmp.md +++ /dev/null @@ -1,56 +0,0 @@ -ARM Trusted Firmware for Xilinx Zynq UltraScale+ MPSoC -================================ - -ARM Trusted Firmware implements the EL3 firmware layer for Xilinx Zynq -UltraScale + MPSoC. -The platform only uses the runtime part of ATF as ZynqMP already has a -BootROM (BL1) and FSBL (BL2). - -BL31 is ATF. -BL32 is an optional Secure Payload. -BL33 is the non-secure world software (U-Boot, Linux etc). - -To build: -```bash -make ERROR_DEPRECATED=1 CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp bl31 -``` - -To build bl32 TSP you have to rebuild bl31 too: -```bash -make ERROR_DEPRECATED=1 CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp SPD=tspd bl31 bl32 -``` - -# ZynqMP platform specific build options -* `ZYNQMP_ATF_MEM_BASE`: Specifies the base address of the bl31 binary. -* `ZYNQMP_ATF_MEM_SIZE`: Specifies the size of the memory region of the bl31 binary. -* `ZYNQMP_BL32_MEM_BASE`: Specifies the base address of the bl32 binary. -* `ZYNQMP_BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary. - -* `ZYNQMP_CONSOLE`: Select the console driver. Options: - - `cadence`, `cadence0`: Cadence UART 0 - - `cadence1` : Cadence UART 1 - -# FSBL->ATF Parameter Passing -The FSBL populates a data structure with image information for the ATF. The ATF -uses that data to hand off to the loaded images. The address of the handoff data -structure is passed in the ```PMU_GLOBAL.GLOBAL_GEN_STORAGE6``` register. The -register is free to be used by other software once the ATF is bringing up -further firmware images. - -# Power Domain Tree -The following power domain tree represents the power domain model used by the -ATF for ZynqMP: -``` - +-+ - |0| - +-+ - +-------+---+---+-------+ - | | | | - | | | | - v v v v - +-+ +-+ +-+ +-+ - |0| |1| |2| |3| - +-+ +-+ +-+ +-+ -``` -The 4 leaf power domains represent the individual A53 cores, while resources -common to the cluster are grouped in the power domain on the top. diff --git a/docs/platform-migration-guide.md b/docs/platform-migration-guide.md deleted file mode 100644 index 27cd067..0000000 --- a/docs/platform-migration-guide.md +++ /dev/null @@ -1,575 +0,0 @@ -Guide to migrate to new Platform porting interface -================================================== - -Contents --------- - -1. [Introduction](#1--introduction) -2. [Platform API modification due to PSCI framework changes](#2--platform-api-modification-due-to-psci-framework-changes) - * [Power domain topology framework platform API modifications](#21-power-domain-topology-framework-platform-api-modifications) - * [Composite power state framework platform API modifications](#22-composite-power-state-framework-platform-api-modifications) - * [Miscellaneous modifications](#23-miscellaneous-modifications) -3. [Compatibility layer](#3--compatibility-layer) -4. [Deprecated Platform API](#4--deprecated-platform-api) - -- - - - - - - - - - - - - - - - - - - - -1. Introduction ----------------- - -The PSCI implementation in Trusted Firmware has undergone a redesign because of -three requirements that the PSCI 1.0 specification introduced : - -* Removing the framework assumption about the structure of the MPIDR, and - its relation to the power topology enables support for deeper and more - complex hierarchies. - -* Reworking the power state coordination implementation in the framework - to support the more detailed PSCI 1.0 requirements and reduce platform - port complexity - -* Enable the use of the extended power_state parameter and the larger StateID - field - -The PSCI 1.0 implementation introduces new frameworks to fulfill the above -requirements. These framework changes mean that the platform porting API must -also be modified. This document is a guide to assist migration of the existing -platform ports to the new platform API. - -This document describes the new platform API and compares it with the -deprecated API. It also describes the compatibility layer that enables the -existing platform ports to work with the PSCI 1.0 implementation. The -deprecated platform API is documented for reference. - - -2. Platform API modification due to PSCI framework changes ------------------------------------------------------------ - -This section describes changes to the platform APIs. - - -2.1 Power domain topology framework platform API modifications --------------------------------------------------------------- - -This removes the assumption in the PSCI implementation that MPIDR -based affinity instances map directly to power domains. A power domain, as -described in section 4.2 of [PSCI], could contain a core or a logical group -of cores (a cluster) which share some state on which power management -operations can be performed. The existing affinity instance based APIs -`plat_get_aff_count()` and `plat_get_aff_state()` are deprecated. The new -platform interfaces that are introduced for this framework are: - -* `plat_core_pos_by_mpidr()` -* `plat_my_core_pos()` -* `plat_get_power_domain_tree_desc()` - -`plat_my_core_pos()` and `plat_core_pos_by_mpidr()` are mandatory -and are meant to replace the existing `platform_get_core_pos()` API. -The description of these APIs can be found in the [Porting Guide][my_core_pos]. -These are used by the power domain topology framework such that: - -1. The generic PSCI code does not generate MPIDRs or use them to query the - platform about the number of power domains at a particular power level. The - `plat_get_power_domain_tree_desc()` provides a description of the power - domain tree on the SoC through a pointer to the byte array containing the - power domain topology tree description data structure. - -2. The linear indices returned by `plat_core_pos_by_mpidr()` and - `plat_my_core_pos()` are used to retrieve core power domain nodes from - the power domain tree. These core indices are unique for a core and it is a - number between `0` and `PLATFORM_CORE_COUNT - 1`. The platform can choose - to implement a static mapping between `MPIDR` and core index or implement - a dynamic mapping, choosing to skip the unavailable/unused cores to compact - the core indices. - -In addition, the platforms must define the macros `PLAT_NUM_PWR_DOMAINS` and -`PLAT_MAX_PWR_LVL` which replace the macros `PLAT_NUM_AFFS` and -`PLATFORM_MAX_AFFLVL` respectively. On platforms where the affinity instances -correspond to power domains, the values of new macros remain the same as the -old ones. - -More details on the power domain topology description and its platform -interface can be found in [psci pd tree]. - - -2.2 Composite power state framework platform API modifications --------------------------------------------------------------- - -The state-ID field in the power-state parameter of a CPU_SUSPEND call can be -used to describe the composite power states specific to a platform. The existing -PSCI state coordination had the limitation that it operates on a run/off -granularity of power states and it did not interpret the state-ID field. This -was acceptable as the specification requirement in PSCI 0.2 and the framework's -approach to coordination only required maintaining a reference -count of the number of cores that have requested the cluster to remain powered. - -In the PSCI 1.0 specification, this approach is non optimal. If composite -power states are used, the PSCI implementation cannot make global -decisions about state coordination required because it does not understand the -platform specific states. - -The PSCI 1.0 implementation now defines a generic representation of the -power-state parameter : - - typedef struct psci_power_state { - plat_local_state_t pwr_domain_state[PLAT_MAX_PWR_LVL + 1]; - } psci_power_state_t; - - -`pwr_domain_state` is an array where each index corresponds to a power level. -Each entry in the array contains the local power state the power domain at -that power level could enter. The meaning of the local power state value is -platform defined, and can vary between levels in a single platform. The PSCI -implementation constraints the values only so that it can classify the state -as RUN, RETENTION or OFF as required by the specification: - -1. Zero means RUN - -2. All OFF state values at all levels must be higher than all - RETENTION state values at all levels - -The platform is required to define the macros `PLAT_MAX_RET_STATE` and -`PLAT_MAX_OFF_STATE` to the framework. The requirement for these macros can -be found in the [Porting Guide]. - -The PSCI 1.0 implementation adds support to involve the platform in state -coordination. This enables the platform to decide the final target state. -During a request to place a power domain in a low power state, the platform -is passed an array of requested `plat_local_state_t` for that power domain by -each core within it through the `plat_get_target_pwr_state()` API. This API -coordinates amongst these requested states to determine a target -`plat_local_state_t` for that power domain. A default weak implementation of -this API is provided in the platform layer which returns the minimum of the -requested local states back to the PSCI state coordination. More details -of `plat_get_target_pwr_state()` API can be found in the -[Porting Guide][get_target_pwr_state]. - -The PSCI Generic implementation expects platform ports to populate the handlers -for the `plat_psci_ops` structure which is declared as : - - typedef struct plat_psci_ops { - void (*cpu_standby)(plat_local_state_t cpu_state); - int (*pwr_domain_on)(u_register_t mpidr); - void (*pwr_domain_off)(const psci_power_state_t *target_state); - void (*pwr_domain_suspend)(const psci_power_state_t *target_state); - void (*pwr_domain_on_finish)(const psci_power_state_t *target_state); - void (*pwr_domain_suspend_finish)( - const psci_power_state_t *target_state); - void (*system_off)(void) __dead2; - void (*system_reset)(void) __dead2; - int (*validate_power_state)(unsigned int power_state, - psci_power_state_t *req_state); - int (*validate_ns_entrypoint)(unsigned long ns_entrypoint); - void (*get_sys_suspend_power_state)( - psci_power_state_t *req_state); - } plat_psci_ops_t; - -The description of these handlers can be found in the [Porting Guide][psci_ops]. -The previous `plat_pm_ops` structure is deprecated. Compared with the previous -handlers, the major differences are: - -* Difference in parameters - -The PSCI 1.0 implementation depends on the `validate_power_state` handler to -convert the power-state parameter (possibly encoding a composite power state) -passed in a PSCI `CPU_SUSPEND` to the `psci_power_state` format. This handler -is now mandatory for PSCI `CPU_SUSPEND` support. - -The `plat_psci_ops` handlers, `pwr_domain_off` and `pwr_domain_suspend`, are -passed the target local state for each affected power domain. The platform -must execute operations specific to these target states. Similarly, -`pwr_domain_on_finish` and `pwr_domain_suspend_finish` are passed the local -states of the affected power domains before wakeup. The platform -must execute actions to restore these power domains from these specific -local states. - -* Difference in invocation - -Whereas the power management handlers in `plat_pm_ops` used to be invoked -for each affinity level till the target affinity level, the new handlers -are only invoked once. The `target_state` encodes the target low power -state or the low power state woken up from for each affected power domain. - -* Difference in semantics - -Although the previous `suspend` handlers could be used for power down as well -as retention at different affinity levels, the new handlers make this support -explicit. The `pwr_domain_suspend` can be used to specify powerdown and -retention at various power domain levels subject to the conditions mentioned -in section 4.2.1 of [PSCI] - -Unlike the previous `standby` handler, the `cpu_standby()` handler is only used -as a fast path for placing a core power domain into a standby or retention -state. - -The below diagram shows the sequence of a PSCI SUSPEND call and the interaction -with the platform layer depicting the exchange of data between PSCI Generic -layer and the platform layer. - -![Image 1](diagrams/psci-suspend-sequence.png?raw=true) - -Refer [plat/arm/board/fvp/fvp_pm.c] for the implementation details of -these handlers for the FVP. The commit 38dce70f51fb83b27958ba3e2ad15f5635cb1061 -demonstrates the migration of ARM reference platforms to the new platform API. - - -2.3 Miscellaneous modifications -------------------------------- - -In addition to the framework changes, unification of warm reset entry points on -wakeup from low power modes has led to a change in the platform API. In the -earlier implementation, the warm reset entry used to be programmed into the -mailboxes by the 'ON' and 'SUSPEND' power management hooks. In the PSCI 1.0 -implementation, this information is not required, because it can figure that -out by querying affinity info state whether to execute the 'suspend_finisher` -or 'on_finisher'. - -As a result, the warm reset entry point must be programmed only once. The -`plat_setup_psci_ops()` API takes the secure entry point as an -additional parameter to enable the platforms to configure their mailbox. The -plat_psci_ops handlers `pwr_domain_on` and `pwr_domain_suspend` no longer take -the warm reset entry point as a parameter. - -Also, some platform APIs which took `MPIDR` as an argument were only ever -invoked to perform actions specific to the caller core which makes the argument -redundant. Therefore the platform APIs `plat_get_my_entrypoint()`, -`plat_is_my_cpu_primary()`, `plat_set_my_stack()` and -`plat_get_my_stack()` are defined which are meant to be invoked only for -operations on the current caller core instead of `platform_get_entrypoint()`, -`platform_is_primary_cpu()`, `platform_set_stack()` and `platform_get_stack()`. - - -3. Compatibility layer ----------------------- - -To ease the migration of the platform ports to the new porting interface, -a compatibility layer is introduced that essentially implements a glue layer -between the old platform API and the new API. The build flag -`ENABLE_PLAT_COMPAT` (enabled by default), specifies whether to enable this -layer or not. A platform port which has migrated to the new API can disable -this flag within the platform specific makefile. - -The compatibility layer works on the assumption that the onus of -state coordination, in case multiple low power states are supported, -is with the platform. The generic PSCI implementation only takes into -account whether the suspend request is power down or not. This corresponds -with the behavior of the PSCI implementation before the introduction of -new frameworks. Also, it assumes that the affinity levels of the platform -correspond directly to the power domain levels. - -The compatibility layer dynamically constructs the new topology -description array by querying the platform using `plat_get_aff_count()` -and `plat_get_aff_state()` APIs. The linear index returned by -`platform_get_core_pos()` is used as the core index for the cores. The -higher level (non-core) power domain nodes must know the cores contained -within its domain. It does so by storing the core index of first core -within it and number of core indexes following it. This means that core -indices returned by `platform_get_core_pos()` for cores within a particular -power domain must be consecutive. We expect that this is the case for most -platform ports including ARM reference platforms. - -The old PSCI helpers like `psci_get_suspend_powerstate()`, -`psci_get_suspend_stateid()`, `psci_get_suspend_stateid_by_mpidr()`, -`psci_get_max_phys_off_afflvl()` and `psci_get_suspend_afflvl()` are also -implemented for the compatibility layer. This allows the existing -platform ports to work with the new PSCI frameworks without significant -rework. - - -4. Deprecated Platform API ---------------------------- - -This section documents the deprecated platform porting API. - -## Common mandatory modifications - -The mandatory macros to be defined by the platform port in `platform_def.h` - -* **#define : PLATFORM_NUM_AFFS** - - Defines the total number of nodes in the affinity hierarchy at all affinity - levels used by the platform. - -* **#define : PLATFORM_MAX_AFFLVL** - - Defines the maximum affinity level that the power management operations - should apply to. ARMv8-A has support for four affinity levels. It is likely - that hardware will implement fewer affinity levels. This macro 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 cores. It reports the maximum - affinity level as 1, resulting in PSCI power control up to the cluster - level. - -The following functions must be implemented by the platform port to enable -the reset vector code to perform the required tasks. - -### Function : platform_get_entrypoint() [mandatory] - - Argument : unsigned long - Return : unsigned long - -This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The core -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 is a warm reset, it returns the entrypoint into the -BL31 image that the core must jump to. If it is a cold reset, this function -must return zero. - -This function is also responsible for implementing a platform-specific mechanism -to handle the condition where the core 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. - -### Function : platform_is_primary_cpu() [mandatory] - - Argument : unsigned long - Return : unsigned int - -This function identifies a core by its `MPIDR`, which is passed as the argument, -to determine whether this core is the primary core or a secondary core. A return -value of zero indicates that the core is not the primary core, while a non-zero -return value indicates that the core is the primary core. - -## Common optional modifications - -### Function : platform_get_core_pos() - - Argument : unsigned long - Return : int - -A platform may need to convert the `MPIDR` of a core to an absolute number, which -can be used as a core-specific linear index into blocks of memory (for example -while allocating per-core stacks). This routine contains a simple mechanism -to perform this conversion, using the assumption that each cluster contains a -maximum of four cores: - - 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_stack() - - Argument : unsigned long - Return : void - -This function sets the current stack pointer to the normal memory stack that -has been allocated for the core specified by MPIDR. For BL images that only -require a stack for the primary core the parameter is ignored. The size of -the stack allocated to each core 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 core specificed by MPIDR. For BL images that only -require a stack for the primary core the parameter is ignored. The size of -the stack allocated to each core 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] - - -## Modifications for Power State Coordination Interface (in BL31) - -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 core. - -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 two cores and the second cluster -implements four cores, 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 core. - -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 four cores and -another core implemented directly on the interconnect with the cluster. The -`MPIDR`s of the cluster would range from `0x0-0x3`. The `MPIDR` of the single -core is 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 core in the -topology tree. Therefore it is marked as `PSCI_AFF_ABSENT`. - - -### Function : platform_setup_pm() [mandatory] - - Argument : const 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 core. - -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 the private `plat_pm_ops` structure of -BL31. - -A description of each member of this structure is given below. A platform port -is expected to implement these handlers if the corresponding PSCI operation -is to be supported and these handlers are expected to succeed if the return -type is `void`. - -#### plat_pm_ops.affinst_standby() - -Perform the platform-specific setup to enter the standby state indicated by the -passed argument. The generic code expects the handler to succeed. - -#### 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` (third argument). The -`state` (fourth 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 core, the cluster that contains this core 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). The generic code expects the platform to return -E_SUCCESS on success or E_INTERN_FAIL for any failure. - -#### plat_pm_ops.affinst_off() - -Perform the platform specific setup to power off an affinity instance of the -calling core. It is called by the PSCI `CPU_OFF` API implementation. - -The `affinity level` (first argument) and `state` (second argument) have -a similar meaning as described in the `affinst_on()` operation. They -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 core is the last powered on core in the cluster, after powering down -affinity level 0 (the core), the platform port should power down affinity -level 1 (the cluster) as well. The generic code expects the handler to succeed. - -#### plat_pm_ops.affinst_suspend() - -Perform the platform specific setup to power off an affinity instance of the -calling core. It is called by the PSCI `CPU_SUSPEND` API and `SYSTEM_SUSPEND` -API implementation - -The `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 core is the -last powered on core in the cluster, after powering down affinity level 0 -(the core), the platform port should power down affinity level 1 (the cluster) -as well. - -The difference between turning an affinity instance off and suspending it -is that in the former case, the affinity instance is expected to re-initialize -its state when it is 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 it is powered on (see -`affinst_suspend_finish()`).The generic code expects the handler to succeed. - -#### plat_pm_ops.affinst_on_finish() - -This function is called by the PSCI implementation after the calling core 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 core to enter the Normal world and also provide secure runtime firmware -services. - -The `affinity level` (first argument) and `state` (second argument) have a -similar meaning as described in the previous operations. The generic code -expects the handler to succeed. - -#### plat_pm_ops.affinst_suspend_finish() - -This function is called by the PSCI implementation after the calling core is -powered on and released from reset in response to an asynchronous wakeup -event, for example a timer interrupt that was programmed by the core during the -`CPU_SUSPEND` call or `SYSTEM_SUSPEND` call. It performs the platform-specific -setup required to restore the saved state for this core to resume execution -in the Normal world and also provide secure runtime firmware services. - -The `affinity level` (first argument) and `state` (second argument) have a -similar meaning as described in the previous operations. The generic code -expects the platform to succeed. - -#### plat_pm_ops.validate_power_state() - -This function is called by the PSCI implementation during the `CPU_SUSPEND` -call to validate the `power_state` parameter of the PSCI API. If the -`power_state` is known to be invalid, the platform must return -PSCI_E_INVALID_PARAMS as an error, which is propagated back to the Normal -world PSCI client. - -#### plat_pm_ops.validate_ns_entrypoint() - -This function is called by the PSCI implementation during the `CPU_SUSPEND`, -`SYSTEM_SUSPEND` and `CPU_ON` calls to validate the Non-secure `entry_point` -parameter passed by the Normal world. If the `entry_point` is known to be -invalid, the platform must return PSCI_E_INVALID_PARAMS as an error, which is -propagated back to the Normal world PSCI client. - -#### plat_pm_ops.get_sys_suspend_power_state() - -This function is called by the PSCI implementation during the `SYSTEM_SUSPEND` -call to return the `power_state` parameter. This allows the platform to encode -the appropriate State-ID field within the `power_state` parameter which can be -utilized in `affinst_suspend()` to suspend to system affinity level. The -`power_state` parameter should be in the same format as specified by the -PSCI specification for the CPU_SUSPEND API. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2015, ARM Limited and Contributors. All rights reserved._ - - -[Porting Guide]: porting-guide.md -[Power Domain Topology Design]: psci-pd-tree.md -[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf -[psci pd tree]: psci-pd-tree.md -[my_core_pos]: porting-guide.md#function--plat_my_core_pos -[get_target_pwr_state]: porting-guide.md#function--plat_get_target_pwr_state-optional -[psci_ops]: porting-guide.md#function--plat_setup_psci_ops-mandatory -[plat/arm/board/fvp/fvp_pm.c]: ../plat/arm/board/fvp/fvp_pm.c -[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 diff --git a/docs/porting-guide.md b/docs/porting-guide.md deleted file mode 100644 index 047e225..0000000 --- a/docs/porting-guide.md +++ /dev/null @@ -1,2413 +0,0 @@ -ARM Trusted Firmware Porting Guide -================================== - -Contents --------- - -1. [Introduction](#1--introduction) -2. [Common Modifications](#2--common-modifications) - * [Common mandatory modifications](#21-common-mandatory-modifications) - * [Handling reset](#22-handling-reset) - * [Common mandatory function modifications](#23-common-mandatory-function-modifications) - * [Common optional modifications](#24-common-optional-modifications) -3. [Boot Loader stage specific modifications](#3--modifications-specific-to-a-boot-loader-stage) - * [Boot Loader stage 1 (BL1)](#31-boot-loader-stage-1-bl1) - * [Boot Loader stage 2 (BL2)](#32-boot-loader-stage-2-bl2) - * [FWU Boot Loader stage 2 (BL2U)](#33-fwu-boot-loader-stage-2-bl2u) - * [Boot Loader stage 3-1 (BL31)](#34-boot-loader-stage-3-1-bl31) - * [PSCI implementation (in BL31)](#35-power-state-coordination-interface-in-bl31) - * [Interrupt Management framework (in BL31)](#36--interrupt-management-framework-in-bl31) - * [Crash Reporting mechanism (in BL31)](#37--crash-reporting-mechanism-in-bl31) -4. [Build flags](#4--build-flags) -5. [C Library](#5--c-library) -6. [Storage abstraction layer](#6--storage-abstraction-layer) - -- - - - - - - - - - - - - - - - - - - -1. Introduction ----------------- - -Please note that this document has been updated for the new platform API -as required by the PSCI v1.0 implementation. Please refer to the -[Migration Guide] for the previous platform API. - -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 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. - -Platform ports that want to be aligned with standard ARM platforms (for example -FVP and Juno) may also use [include/plat/arm/common/plat_arm.h] and the -corresponding source files in `plat/arm/common/`. These provide standard -implementations for some of the required platform porting functions. However, -using these functions requires the platform port to implement additional -ARM standard platform porting functions. These additional functions are not -documented here. - -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) as well as the -instruction and data caches for each BL stage. Setting up the translation -tables is the responsibility of the platform port because memory maps differ -across platforms. A memory translation library (see `lib/xlat_tables/`) is -provided to help in this setup. Note that although this library supports -non-identity mappings, this is intended only for re-mapping peripheral physical -addresses and allows platforms with high I/O addresses to reduce their virtual -address space. All other addresses corresponding to code and data must currently -use an identity mapping. - -In ARM standard platforms, each BL stage configures the MMU in the -platform-specific architecture setup function, `blX_plat_arch_setup()`, and uses -an identity mapping for all addresses. - -If the build option `USE_COHERENT_MEM` is enabled, each platform can allocate a -block of identity mapped secure memory with Device-nGnRE attributes aligned to -page boundary (4K) for each BL stage. All sections which allocate coherent -memory are grouped under `coherent_ram`. For ex: Bakery locks are placed in a -section identified by name `bakery_lock` inside `coherent_ram` so that its -possible for the firmware to place variables in it using the following C code -directive: - - __section("bakery_lock") - -Or alternatively the following assembler code directive: - - .section bakery_lock - -The `coherent_ram` section is a sum of all sections like `bakery_lock` which are -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 development -platforms, this file is found in `plat/arm/board//include/`. - -Platform ports may optionally use the file [include/plat/common/common_def.h], -which provides typical values for some of the constants below. These values are -likely to be suitable for all platform ports. - -Platform ports that want to be aligned with standard ARM platforms (for example -FVP and Juno) may also use [include/plat/arm/common/arm_def.h], which provides -standard values for some of the constants below. However, this requires the -platform port to define additional platform porting constants in -`platform_def.h`. These additional constants are not documented here. - -* **#define : PLATFORM_LINKER_FORMAT** - - Defines the linker format used by the platform, for example - `elf64-littleaarch64`. - -* **#define : PLATFORM_LINKER_ARCH** - - Defines the processor architecture for the linker by the platform, for - example `aarch64`. - -* **#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 : CACHE_WRITEBACK_GRANULE** - - Defines the size in bits of the largest cache line across all the cache - levels in the platform. - -* **#define : FIRMWARE_WELCOME_STR** - - Defines the character string printed by BL1 upon entry into the `bl1_main()` - function. - -* **#define : PLATFORM_CORE_COUNT** - - Defines the total number of CPUs implemented by the platform across all - clusters in the system. - -* **#define : PLAT_NUM_PWR_DOMAINS** - - Defines the total number of nodes in the power domain topology - tree at all the power domain levels used by the platform. - This macro is used by the PSCI implementation to allocate - data structures to represent power domain topology. - -* **#define : PLAT_MAX_PWR_LVL** - - Defines the maximum power domain level that the power management operations - should apply to. More often, but not always, the power domain level - corresponds to affinity level. This macro allows the PSCI implementation - to know the highest power domain level that it should consider for power - management operations in the system that the platform implements. For - example, the Base AEM FVP implements two clusters with a configurable - number of CPUs and it reports the maximum power domain level as 1. - -* **#define : PLAT_MAX_OFF_STATE** - - Defines the local power state corresponding to the deepest power down - possible at every power domain level in the platform. The local power - states for each level may be sparsely allocated between 0 and this value - with 0 being reserved for the RUN state. The PSCI implementation uses this - value to initialize the local power states of the power domain nodes and - to specify the requested power state for a PSCI_CPU_OFF call. - -* **#define : PLAT_MAX_RET_STATE** - - Defines the local power state corresponding to the deepest retention state - possible at every power domain level in the platform. This macro should be - a value less than PLAT_MAX_OFF_STATE and greater than 0. It is used by the - PSCI implementation to distinguish between retention and power down local - power states within PSCI_CPU_SUSPEND call. - -* **#define : PLAT_MAX_PWR_LVL_STATES** - - Defines the maximum number of local power states per power domain level - that the platform supports. The default value of this macro is 2 since - most platforms just support a maximum of two local power states at each - power domain level (power-down and retention). If the platform needs to - account for more local power states, then it must redefine this macro. - - Currently, this macro is used by the Generic PSCI implementation to size - the array used for PSCI_STAT_COUNT/RESIDENCY accounting. - -* **#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 BL31 binary - image. Must be aligned on a page-size boundary. - -* **#define : BL31_LIMIT** - - Defines the maximum address in secure RAM that the BL31 image can occupy. - -For every image, the platform must define individual identifiers that will be -used by BL1 or BL2 to load the corresponding image into memory from non-volatile -storage. For the sake of performance, integer numbers will be used as -identifiers. The platform will use those identifiers to return the relevant -information about the image to be loaded (file handler, load address, -authentication information, etc.). The following image identifiers are -mandatory: - -* **#define : BL2_IMAGE_ID** - - BL2 image identifier, used by BL1 to load BL2. - -* **#define : BL31_IMAGE_ID** - - BL31 image identifier, used by BL2 to load BL31. - -* **#define : BL33_IMAGE_ID** - - BL33 image identifier, used by BL2 to load BL33. - -If Trusted Board Boot is enabled, the following certificate identifiers must -also be defined: - -* **#define : TRUSTED_BOOT_FW_CERT_ID** - - BL2 content certificate identifier, used by BL1 to load the BL2 content - certificate. - -* **#define : TRUSTED_KEY_CERT_ID** - - Trusted key certificate identifier, used by BL2 to load the trusted key - certificate. - -* **#define : SOC_FW_KEY_CERT_ID** - - BL31 key certificate identifier, used by BL2 to load the BL31 key - certificate. - -* **#define : SOC_FW_CONTENT_CERT_ID** - - BL31 content certificate identifier, used by BL2 to load the BL31 content - certificate. - -* **#define : NON_TRUSTED_FW_KEY_CERT_ID** - - BL33 key certificate identifier, used by BL2 to load the BL33 key - certificate. - -* **#define : NON_TRUSTED_FW_CONTENT_CERT_ID** - - BL33 content certificate identifier, used by BL2 to load the BL33 content - certificate. - -* **#define : FWU_CERT_ID** - - Firmware Update (FWU) certificate identifier, used by NS_BL1U to load the - FWU content certificate. - -* **#define : PLAT_CRYPTOCELL_BASE** - - This defines the base address of ARM® TrustZone® CryptoCell and must be - defined if CryptoCell crypto driver is used for Trusted Board Boot. For - capable ARM platforms, this driver is used if `ARM_CRYPTOCELL_INTEG` is - set. - -If the AP Firmware Updater Configuration image, BL2U is used, the following -must also be defined: - -* **#define : BL2U_BASE** - - Defines the base address in secure memory where BL1 copies the BL2U binary - image. Must be aligned on a page-size boundary. - -* **#define : BL2U_LIMIT** - - Defines the maximum address in secure memory that the BL2U image can occupy. - -* **#define : BL2U_IMAGE_ID** - - BL2U image identifier, used by BL1 to fetch an image descriptor - corresponding to BL2U. - -If the SCP Firmware Update Configuration Image, SCP_BL2U is used, the following -must also be defined: - -* **#define : SCP_BL2U_IMAGE_ID** - - SCP_BL2U image identifier, used by BL1 to fetch an image descriptor - corresponding to SCP_BL2U. - NOTE: TF does not provide source code for this image. - -If the Non-Secure Firmware Updater ROM, NS_BL1U is used, the following must -also be defined: - -* **#define : NS_BL1U_BASE** - - Defines the base address in non-secure ROM where NS_BL1U executes. - Must be aligned on a page-size boundary. - NOTE: TF does not provide source code for this image. - -* **#define : NS_BL1U_IMAGE_ID** - - NS_BL1U image identifier, used by BL1 to fetch an image descriptor - corresponding to NS_BL1U. - -If the Non-Secure Firmware Updater, NS_BL2U is used, the following must also -be defined: - -* **#define : NS_BL2U_BASE** - - Defines the base address in non-secure memory where NS_BL2U executes. - Must be aligned on a page-size boundary. - NOTE: TF does not provide source code for this image. - -* **#define : NS_BL2U_IMAGE_ID** - - NS_BL2U image identifier, used by BL1 to fetch an image descriptor - corresponding to NS_BL2U. - -For the the Firmware update capability of TRUSTED BOARD BOOT, the following -macros may also be defined: - -* **#define : PLAT_FWU_MAX_SIMULTANEOUS_IMAGES** - - Total number of images that can be loaded simultaneously. If the platform - doesn't specify any value, it defaults to 10. - -If a SCP_BL2 image is supported by the platform, the following constants must -also be defined: - -* **#define : SCP_BL2_IMAGE_ID** - - SCP_BL2 image identifier, used by BL2 to load SCP_BL2 into secure memory - from platform storage before being transfered to the SCP. - -* **#define : SCP_FW_KEY_CERT_ID** - - SCP_BL2 key certificate identifier, used by BL2 to load the SCP_BL2 key - certificate (mandatory when Trusted Board Boot is enabled). - -* **#define : SCP_FW_CONTENT_CERT_ID** - - SCP_BL2 content certificate identifier, used by BL2 to load the SCP_BL2 - content certificate (mandatory when Trusted Board Boot is enabled). - -If a BL32 image is supported by the platform, the following constants must -also be defined: - -* **#define : BL32_IMAGE_ID** - - BL32 image identifier, used by BL2 to load BL32. - -* **#define : TRUSTED_OS_FW_KEY_CERT_ID** - - BL32 key certificate identifier, used by BL2 to load the BL32 key - certificate (mandatory when Trusted Board Boot is enabled). - -* **#define : TRUSTED_OS_FW_CONTENT_CERT_ID** - - BL32 content certificate identifier, used by BL2 to load the BL32 content - certificate (mandatory when Trusted Board Boot is enabled). - -* **#define : BL32_BASE** - - Defines the base address in secure memory where BL2 loads the BL32 binary - image. Must be aligned on a page-size boundary. - -* **#define : BL32_LIMIT** - - Defines the maximum address that the BL32 image can occupy. - -If the Test Secure-EL1 Payload (TSP) instantiation of BL32 is supported by the -platform, the following constants must also be defined: - -* **#define : TSP_SEC_MEM_BASE** - - Defines the base address of the secure memory used by the TSP image on the - platform. This must be at the same address or below `BL32_BASE`. - -* **#define : TSP_SEC_MEM_SIZE** - - Defines the size of the secure memory used by the BL32 image on the - platform. `TSP_SEC_MEM_BASE` and `TSP_SEC_MEM_SIZE` must fully accomodate - the memory required by the BL32 image, defined by `BL32_BASE` and - `BL32_LIMIT`. - -* **#define : TSP_IRQ_SEC_PHY_TIMER** - - Defines the ID of the secure physical generic timer interrupt used by the - TSP's interrupt handling code. - -If the platform port uses the translation table library code, the following -constants must also be defined: - -* **#define : PLAT_XLAT_TABLES_DYNAMIC** - - Optional flag that can be set per-image to enable the dynamic allocation of - regions even when the MMU is enabled. If not defined, only static - functionality will be available, if defined and set to 1 it will also - include the dynamic functionality. - -* **#define : MAX_XLAT_TABLES** - - Defines the maximum number of translation tables that are allocated by the - translation table library code. To minimize the amount of runtime memory - used, choose the smallest value needed to map the required virtual addresses - for each BL stage. If `PLAT_XLAT_TABLES_DYNAMIC` flag is enabled for a BL - image, `MAX_XLAT_TABLES` must be defined to accommodate the dynamic regions - as well. - -* **#define : MAX_MMAP_REGIONS** - - Defines the maximum number of regions that are allocated by the translation - table library code. A region consists of physical base address, virtual base - address, size and attributes (Device/Memory, RO/RW, Secure/Non-Secure), as - defined in the `mmap_region_t` structure. The platform defines the regions - that should be mapped. Then, the translation table library will create the - corresponding tables and descriptors at runtime. To minimize the amount of - runtime memory used, choose the smallest value needed to register the - required regions for each BL stage. If `PLAT_XLAT_TABLES_DYNAMIC` flag is - enabled for a BL image, `MAX_MMAP_REGIONS` must be defined to accommodate - the dynamic regions as well. - -* **#define : ADDR_SPACE_SIZE** - - Defines the total size of the address space in bytes. For example, for a 32 - bit address space, this value should be `(1ull << 32)`. This definition is - now deprecated, platforms should use `PLAT_PHY_ADDR_SPACE_SIZE` and - `PLAT_VIRT_ADDR_SPACE_SIZE` instead. - -* **#define : PLAT_VIRT_ADDR_SPACE_SIZE** - - Defines the total size of the virtual address space in bytes. For example, - for a 32 bit virtual address space, this value should be `(1ull << 32)`. - -* **#define : PLAT_PHY_ADDR_SPACE_SIZE** - - Defines the total size of the physical address space in bytes. For example, - for a 32 bit physical address space, this value should be `(1ull << 32)`. - -If the platform port uses the IO storage framework, the following constants -must also be defined: - -* **#define : MAX_IO_DEVICES** - - Defines the maximum number of registered IO devices. Attempting to register - more devices than this value using `io_register_device()` will fail with - -ENOMEM. - -* **#define : MAX_IO_HANDLES** - - Defines the maximum number of open IO handles. Attempting to open more IO - entities than this value using `io_open()` will fail with -ENOMEM. - -* **#define : MAX_IO_BLOCK_DEVICES** - - Defines the maximum number of registered IO block devices. Attempting to - register more devices this value using `io_dev_open()` will fail - with -ENOMEM. MAX_IO_BLOCK_DEVICES should be less than MAX_IO_DEVICES. - With this macro, multiple block devices could be supported at the same - time. - -If the platform needs to allocate data within the per-cpu data framework in -BL31, it should define the following macro. Currently this is only required if -the platform decides not to use the coherent memory section by undefining the -`USE_COHERENT_MEM` build flag. In this case, the framework allocates the -required memory within the the per-cpu data to minimize wastage. - -* **#define : PLAT_PCPU_DATA_SIZE** - - Defines the memory (in bytes) to be reserved within the per-cpu data - structure for use by the platform layer. - -The following constants are optional. They should be defined when the platform -memory layout implies some image overlaying like in ARM standard platforms. - -* **#define : BL31_PROGBITS_LIMIT** - - Defines the maximum address in secure RAM that the BL31's progbits sections - can occupy. - -* **#define : TSP_PROGBITS_LIMIT** - - Defines the maximum address that the TSP's progbits sections can occupy. - -If the platform port uses the PL061 GPIO driver, the following constant may -optionally be defined: - -* **PLAT_PL061_MAX_GPIOS** - Maximum number of GPIOs required by the platform. This allows control how - much memory is allocated for PL061 GPIO controllers. The default value is - 32. - [For example, define the build flag in platform.mk]: - PLAT_PL061_MAX_GPIOS := 160 - $(eval $(call add_define,PLAT_PL061_MAX_GPIOS)) - -If the platform port uses the partition driver, the following constant may -optionally be defined: - -* **PLAT_PARTITION_MAX_ENTRIES** - Maximum number of partition entries required by the platform. This allows - control how much memory is allocated for partition entries. The default - value is 128. - [For example, define the build flag in platform.mk]: - PLAT_PARTITION_MAX_ENTRIES := 12 - $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES)) - -The following constant is optional. It should be defined to override the default -behaviour of the `assert()` function (for example, to save memory). - -* **PLAT_LOG_LEVEL_ASSERT** - If `PLAT_LOG_LEVEL_ASSERT` is higher or equal than `LOG_LEVEL_VERBOSE`, - `assert()` prints the name of the file, the line number and the asserted - expression. Else if it is higher than `LOG_LEVEL_INFO`, it prints the file - name and the line number. Else if it is lower than `LOG_LEVEL_INFO`, it - doesn't print anything to the console. If `PLAT_LOG_LEVEL_ASSERT` isn't - defined, it defaults to `LOG_LEVEL`. - - -### 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 development platforms, this file is -found in `plat/arm/board//include/plat_macros.S`. - -* **Macro : plat_crash_print_regs** - - This macro allows the crash reporting routine to print relevant platform - registers in case of an unhandled exception in BL31. This aids in debugging - and this macro can be defined to be empty in case register reporting is not - desired. - - For instance, GIC or interconnect registers may be helpful for - troubleshooting. - - -2.2 Handling Reset ------------------- - -BL1 by default implements the reset vector where execution starts from a cold -or warm boot. BL31 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 BL31 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 : plat_get_my_entrypoint() [mandatory when PROGRAMMABLE_RESET_ADDRESS == 0] - - Argument : void - Return : uintptr_t - -This function is called with the MMU and caches disabled -(`SCTLR_EL3.M` = 0 and `SCTLR_EL3.C` = 0). The function is responsible for -distinguishing between a warm and cold reset for the current CPU using -platform-specific means. If it's a warm reset, then it returns the warm -reset entrypoint point provided to `plat_setup_psci_ops()` during -BL31 initialization. If it's a cold reset then this function must return zero. - -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. - -Note that for platforms that support programming the reset address, it is -expected that a CPU will start executing code directly at the right address, -both on a cold and warm reset. In this case, there is no need to identify the -type of reset nor to query the warm reset entrypoint. Therefore, implementing -this function is not required on such platforms. - - -### Function : plat_secondary_cold_boot_setup() [mandatory when COLD_BOOT_SINGLE_CPU == 0] - - Argument : 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. This function must not return. - -In the ARM FVP port, when using the normal boot flow, each secondary CPU powers -itself off. The primary CPU is responsible for powering up the secondary CPUs -when normal world software requires them. When booting an EL3 payload instead, -they stay powered on and are put in a holding pen until their mailbox gets -populated. - -This function fulfills requirement 2 above. - -Note that for platforms that can't release secondary CPUs out of reset, only the -primary CPU will execute the cold boot code. Therefore, implementing this -function is not required on such platforms. - - -### Function : plat_is_my_cpu_primary() [mandatory when COLD_BOOT_SINGLE_CPU == 0] - - Argument : void - Return : unsigned int - -This function identifies whether the current 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. - -Note that for platforms that can't release secondary CPUs out of reset, only the -primary CPU will execute the cold boot code. Therefore, there is no need to -distinguish between primary and secondary CPUs and implementing this function is -not required. - - -### 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. - - -### Function: plat_get_rotpk_info() - - Argument : void *, void **, unsigned int *, unsigned int * - Return : int - -This function is mandatory when Trusted Board Boot is enabled. It returns a -pointer to the ROTPK stored in the platform (or a hash of it) and its length. -The ROTPK must be encoded in DER format according to the following ASN.1 -structure: - - AlgorithmIdentifier ::= SEQUENCE { - algorithm OBJECT IDENTIFIER, - parameters ANY DEFINED BY algorithm OPTIONAL - } - - SubjectPublicKeyInfo ::= SEQUENCE { - algorithm AlgorithmIdentifier, - subjectPublicKey BIT STRING - } - -In case the function returns a hash of the key: - - DigestInfo ::= SEQUENCE { - digestAlgorithm AlgorithmIdentifier, - digest OCTET STRING - } - -The function returns 0 on success. Any other value is treated as error by the -Trusted Board Boot. The function also reports extra information related -to the ROTPK in the flags parameter: - - ROTPK_IS_HASH : Indicates that the ROTPK returned by the platform is a - hash. - ROTPK_NOT_DEPLOYED : This allows the platform to skip certificate ROTPK - verification while the platform ROTPK is not deployed. - When this flag is set, the function does not need to - return a platform ROTPK, and the authentication - framework uses the ROTPK in the certificate without - verifying it against the platform value. This flag - must not be used in a deployed production environment. - -### Function: plat_get_nv_ctr() - - Argument : void *, unsigned int * - Return : int - -This function is mandatory when Trusted Board Boot is enabled. It returns the -non-volatile counter value stored in the platform in the second argument. The -cookie in the first argument may be used to select the counter in case the -platform provides more than one (for example, on platforms that use the default -TBBR CoT, the cookie will correspond to the OID values defined in -TRUSTED_FW_NVCOUNTER_OID or NON_TRUSTED_FW_NVCOUNTER_OID). - -The function returns 0 on success. Any other value means the counter value could -not be retrieved from the platform. - - -### Function: plat_set_nv_ctr() - - Argument : void *, unsigned int - Return : int - -This function is mandatory when Trusted Board Boot is enabled. It sets a new -counter value in the platform. The cookie in the first argument may be used to -select the counter (as explained in plat_get_nv_ctr()). The second argument is -the updated counter value to be written to the NV counter. - -The function returns 0 on success. Any other value means the counter value could -not be updated. - - -### Function: plat_set_nv_ctr2() - - Argument : void *, const auth_img_desc_t *, unsigned int - Return : int - -This function is optional when Trusted Board Boot is enabled. If this -interface is defined, then `plat_set_nv_ctr()` need not be defined. The -first argument passed is a cookie and is typically used to -differentiate between a Non Trusted NV Counter and a Trusted NV -Counter. The second argument is a pointer to an authentication image -descriptor and may be used to decide if the counter is allowed to be -updated or not. The third argument is the updated counter value to -be written to the NV counter. - -The function returns 0 on success. Any other value means the counter value -either could not be updated or the authentication image descriptor indicates -that it is not allowed to be updated. - - -2.3 Common mandatory function modifications ---------------------------------- - -The following functions are mandatory functions which need to be implemented -by the platform port. - -### Function : plat_my_core_pos() - - Argument : void - Return : unsigned int - -This funtion returns the index of the calling CPU which is used as a -CPU-specific linear index into blocks of memory (for example while allocating -per-CPU stacks). This function will be invoked very early in the -initialization sequence which mandates that this function should be -implemented in assembly and should not rely on the avalability of a C -runtime environment. This function can clobber x0 - x8 and must preserve -x9 - x29. - -This function plays a crucial role in the power domain topology framework in -PSCI and details of this can be found in [Power Domain Topology Design]. - -### Function : plat_core_pos_by_mpidr() - - Argument : u_register_t - Return : int - -This function validates the `MPIDR` of a CPU and converts it to an index, -which can be used as a CPU-specific linear index into blocks of memory. In -case the `MPIDR` is invalid, this function returns -1. This function will only -be invoked by BL31 after the power domain topology is initialized and can -utilize the C runtime environment. For further details about how ARM Trusted -Firmware represents the power domain topology and how this relates to the -linear CPU index, please refer [Power Domain Topology Design]. - - -2.4 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 : plat_set_my_stack() - - Argument : void - Return : void - -This function sets the current stack pointer to the normal memory stack that -has been allocated for the current CPU. For BL images that only require a -stack for the primary CPU, the UP version of the function is used. 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_get_my_stack() - - Argument : void - Return : uintptr_t - -This function returns the base address of the normal memory stack that -has been allocated for the current CPU. For BL images that only require a -stack for the primary CPU, the UP version of the function is used. 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. - -For AArch64, this function receives the exception type as its argument. -Possible values for exceptions types are listed in the -[include/common/bl_common.h] header file. Note that these constants are not -related to any architectural exception code; they are just an ARM Trusted -Firmware convention. - -For AArch32, this function receives the exception mode as its argument. -Possible values for exception modes are listed in the -[include/lib/aarch32/arch.h] header file. - -### Function : plat_reset_handler() - - Argument : void - Return : void - -A platform may need to do additional initialization after reset. This function -allows the platform to do the platform specific intializations. Platform -specific errata workarounds could also be implemented here. The api should -preserve the values of callee saved registers x19 to x29. - -The default implementation doesn't do anything. If a platform needs to override -the default implementation, refer to the [Firmware Design] for general -guidelines. - -### Function : plat_disable_acp() - - Argument : void - Return : void - -This api allows a platform to disable the Accelerator Coherency Port (if -present) during a cluster power down sequence. The default weak implementation -doesn't do anything. Since this api is called during the power down sequence, -it has restrictions for stack usage and it can use the registers x0 - x17 as -scratch registers. It should preserve the value in x18 register as it is used -by the caller to store the return address. - -### Function : plat_error_handler() - - Argument : int - Return : void - -This API is called when the generic code encounters an error situation from -which it cannot continue. It allows the platform to perform error reporting or -recovery actions (for example, reset the system). This function must not return. - -The parameter indicates the type of error using standard codes from `errno.h`. -Possible errors reported by the generic code are: - -* `-EAUTH`: a certificate or image could not be authenticated (when Trusted - Board Boot is enabled) -* `-ENOENT`: the requested image or certificate could not be found or an IO - error was detected -* `-ENOMEM`: resources exhausted. Trusted Firmware does not use dynamic - memory, so this error is usually an indication of an incorrect array size - -The default implementation simply spins. - -### Function : plat_panic_handler() - - Argument : void - Return : void - -This API is called when the generic code encounters an unexpected error -situation from which it cannot recover. This function must not return, -and must be implemented in assembly because it may be called before the C -environment is initialized. - -Note: The address from where it was called is stored in x30 (Link Register). -The default implementation simply spins. - - -### Function : plat_get_bl_image_load_info() - - Argument : void - Return : bl_load_info_t * - -This function returns pointer to the list of images that the platform has -populated to load. This function is currently invoked in BL2 to load the -BL3xx images, when LOAD_IMAGE_V2 is enabled. - -### Function : plat_get_next_bl_params() - - Argument : void - Return : bl_params_t * - -This function returns a pointer to the shared memory that the platform has -kept aside to pass trusted firmware related information that next BL image -needs. This function is currently invoked in BL2 to pass this information to -the next BL image, when LOAD_IMAGE_V2 is enabled. - -### Function : plat_get_stack_protector_canary() - Argument : void - Return : u_register_t - -This function returns a random value that is used to initialize the canary used -when the stack protector is enabled with ENABLE_STACK_PROTECTOR. A predictable -value will weaken the protection as the attacker could easily write the right -value as part of the attack most of the time. Therefore, it should return a -true random number. - -Note: For the protection to be effective, the global data need to be placed at -a lower address than the stack bases. Failure to do so would allow an attacker -to overwrite the canary as part of the stack buffer overflow attack. - -### Function : plat_flush_next_bl_params() - - Argument : void - Return : void - -This function flushes to main memory all the image params that are passed to -next image. This function is currently invoked in BL2 to flush this information -to the next BL image, when LOAD_IMAGE_V2 is enabled. - -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. Identifying and starting the Firmware Update process (if required). - -4. Loading the BL2 image from non-volatile storage into secure memory at the - address specified by the platform defined constant `BL2_BASE`. - -5. 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 `bl1_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_early_platform_setup() [mandatory] - - Argument : void - Return : void - -This function executes with the MMU and data caches disabled. It is only called -by the primary CPU. - -On ARM standard platforms, this function: - -* Enables a secure instance of SP805 to act as the Trusted Watchdog. - -* Initializes a UART (PL011 console), which enables access to the `printf` - family of functions in BL1. - -* Enables issuing of snoop and DVM (Distributed Virtual Memory) requests to - the CCI slave interface corresponding to the cluster that includes the - primary CPU. - -### 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 and the interconnect. - -In ARM standard platforms, this function 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. - -In ARM standard platforms, this function initializes the storage abstraction -layer used to load the next bootloader image. - -This function helps fulfill requirement 4 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 requirements 4 and 5 above. - - -### Function : bl1_init_bl2_mem_layout() [optional] - - Argument : meminfo *, meminfo * - 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 ARM standard platforms is given -in the **Memory layout on ARM development platforms** section in the -[Firmware Design]. - - -### Function : bl1_plat_prepare_exit() [optional] - - Argument : entry_point_info_t * - Return : void - -This function is called prior to exiting BL1 in response to the -`BL1_SMC_RUN_IMAGE` SMC request raised by BL2. It should be used to perform -platform specific clean up or bookkeeping operations before transferring -control to the next image. It receives the address of the `entry_point_info_t` -structure passed from BL2. This function runs with MMU disabled. - -### Function : bl1_plat_set_ep_info() [optional] - - Argument : unsigned int image_id, entry_point_info_t *ep_info - Return : void - -This function allows platforms to override `ep_info` for the given `image_id`. - -The default implementation just returns. - -### Function : bl1_plat_get_next_image_id() [optional] - - Argument : void - Return : unsigned int - -This and the following function must be overridden to enable the FWU feature. - -BL1 calls this function after platform setup to identify the next image to be -loaded and executed. If the platform returns `BL2_IMAGE_ID` then BL1 proceeds -with the normal boot sequence, which loads and executes BL2. If the platform -returns a different image id, BL1 assumes that Firmware Update is required. - -The default implementation always returns `BL2_IMAGE_ID`. The ARM development -platforms override this function to detect if firmware update is required, and -if so, return the first image in the firmware update process. - -### Function : bl1_plat_get_image_desc() [optional] - - Argument : unsigned int image_id - Return : image_desc_t * - -BL1 calls this function to get the image descriptor information `image_desc_t` -for the provided `image_id` from the platform. - -The default implementation always returns a common BL2 image descriptor. ARM -standard platforms return an image descriptor corresponding to BL2 or one of -the firmware update images defined in the Trusted Board Boot Requirements -specification. - -### Function : bl1_plat_fwu_done() [optional] - - Argument : unsigned int image_id, uintptr_t image_src, - unsigned int image_size - Return : void - -BL1 calls this function when the FWU process is complete. It must not return. -The platform may override this function to take platform specific action, for -example to initiate the normal boot flow. - -The default implementation spins forever. - -### Function : bl1_plat_mem_check() [mandatory] - - Argument : uintptr_t mem_base, unsigned int mem_size, - unsigned int flags - Return : int - -BL1 calls this function while handling FWU related SMCs, more specifically when -copying or authenticating an image. Its responsibility is to ensure that the -region of memory identified by `mem_base` and `mem_size` is mapped in BL1, and -that this memory corresponds to either a secure or non-secure memory region as -indicated by the security state of the `flags` argument. - -This function can safely assume that the value resulting from the addition of -`mem_base` and `mem_size` fits into a `uintptr_t` type variable and does not -overflow. - -This function must return 0 on success, a non-null error code otherwise. - -The default implementation of this function asserts therefore platforms must -override it when using the FWU feature. - - -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. (Optional) Loading the SCP_BL2 binary image (if present) from platform - provided non-volatile storage. To load the SCP_BL2 image, BL2 makes use of - the `meminfo` returned by the `bl2_plat_get_scp_bl2_meminfo()` function. - The platform also defines the address in memory where SCP_BL2 is loaded - through the optional constant `SCP_BL2_BASE`. BL2 uses this information - to determine if there is enough memory to load the SCP_BL2 image. - Subsequent handling of the SCP_BL2 image is platform-specific and is - implemented in the `bl2_plat_handle_scp_bl2()` function. - If `SCP_BL2_BASE` is not defined then this step is not performed. - -2. Loading the BL31 binary image into secure RAM from non-volatile storage. To - load the BL31 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 BL31 is loaded through the constant `BL31_BASE`. BL2 uses this - information to determine if there is enough memory to load the BL31 image. - -3. (Optional) Loading the BL32 binary image (if present) from platform - provided non-volatile storage. To load the BL32 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 BL32 is loaded - through the optional constant `BL32_BASE`. BL2 uses this information - to determine if there is enough memory to load the BL32 image. - If `BL32_BASE` is not defined then this and the next step is not performed. - -4. (Optional) Arranging to pass control to the BL32 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 - BL31 should pass control to the BL32 image. - -5. (Optional) Loading the normal world BL33 binary image (if not loaded by - other means) into non-secure DRAM from platform storage and arranging for - BL31 to pass control to this image. This address is determined using the - `plat_get_ns_image_entrypoint()` function described below. - -6. BL2 populates an `entry_point_info` structure in memory provided by the - platform with information about how BL31 should pass control to the - other BL images. - -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 may 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. - -On ARM standard platforms, this function also: - -* Initializes a UART (PL011 console), which enables access to the `printf` - family of functions in BL2. - -* Initializes the storage abstraction layer used to load further bootloader - images. It is necessary to do this early on platforms with a SCP_BL2 image, - since the later `bl2_platform_setup` must be done after SCP_BL2 is loaded. - - -### 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. - -On ARM standard platforms, this function enables the MMU. - -### 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. - -In ARM standard platforms, this function performs security setup, including -configuration of the TrustZone controller to allow non-secure masters access -to most of DRAM. Part of DRAM is reserved for secure world use. - - -### 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. - - -Following function is required only when LOAD_IMAGE_V2 is enabled. - -### Function : bl2_plat_handle_post_image_load() [mandatory] - - Argument : unsigned int - Return : int - -This function can be used by the platforms to update/use image information -for given `image_id`. This function is currently invoked in BL2 to handle -BL image specific information based on the `image_id` passed, when -LOAD_IMAGE_V2 is enabled. - -Following functions are required only when LOAD_IMAGE_V2 is disabled. - -### Function : bl2_plat_get_scp_bl2_meminfo() [mandatory] - - Argument : meminfo * - Return : void - -This function is used to get the memory limits where BL2 can load the -SCP_BL2 image. The meminfo provided by this is used by load_image() to -validate whether the SCP_BL2 image can be loaded within the given -memory from the given base. - - -### Function : bl2_plat_handle_scp_bl2() [mandatory] - - Argument : image_info * - Return : int - -This function is called after loading SCP_BL2 image and it is used to perform -any platform-specific actions required to handle the SCP firmware. Typically it -transfers the image into SCP memory using a platform-specific protocol and waits -until SCP executes it and signals to the Application Processor (AP) for BL2 -execution to continue. - -This function returns 0 on success, a negative error code otherwise. - - -### 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 BL31. The `bl31_params` structure carries -the following information. - - Header describing the version information for interpreting the bl31_param - structure - - Information about executing the BL33 image in the `bl33_ep_info` field - - Information about executing the BL32 image in the `bl32_ep_info` field - - Information about the type and extents of BL31 image in the - `bl31_image_info` field - - Information about the type and extents of BL32 image in the - `bl32_image_info` field - - Information about the type and extents of BL33 image in the - `bl33_image_info` field - -The memory pointed by this structure and its sub-structures should be -accessible from BL31 initialisation code. BL31 might choose to copy the -necessary content, or maintain the structures until BL33 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 BL31 entry point. The location pointed by it should be -accessible from BL1 while processing the synchronous exception to run to BL31. - -In ARM standard platforms this is allocated inside a bl2_to_bl31_params_mem -structure in BL2 memory. - - -### Function : bl2_plat_set_bl31_ep_info() [mandatory] - - Argument : image_info *, entry_point_info * - Return : void - -In the normal boot flow, this function is called after loading BL31 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 BL31. - -When booting an EL3 payload instead, this function is called after populating -its entry point address and can be used for the same purpose for the payload -image. It receives a null pointer as its first argument in this case. - -### Function : bl2_plat_set_bl32_ep_info() [mandatory] - - Argument : image_info *, entry_point_info * - Return : void - -This function is called after loading BL32 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 BL32. - - -### Function : bl2_plat_set_bl33_ep_info() [mandatory] - - Argument : image_info *, entry_point_info * - Return : void - -This function is called after loading BL33 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 BL33. - -In the preloaded BL33 alternative boot flow, this function is called after -populating its entry point address. It is passed a null pointer as its first -argument in this case. - - -### 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 -BL32 image. The meminfo provided by this is used by load_image() to -validate whether the BL32 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 -BL33 image. The meminfo provided by this is used by load_image() to -validate whether the BL33 image can be loaded with in the given -memory from the given base. - -This function isn't needed if either `PRELOADED_BL33_BASE` or `EL3_PAYLOAD_BASE` -build options are used. - -### 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 BL31 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 : uintptr_t - -As previously described, BL2 is responsible for arranging for control to be -passed to a normal world BL image through BL31. This function returns the -entrypoint of that image, which BL31 uses to jump to it. - -BL2 is responsible for loading the normal world BL33 image (e.g. UEFI). - -This function isn't needed if either `PRELOADED_BL33_BASE` or `EL3_PAYLOAD_BASE` -build options are used. - - -3.3 FWU Boot Loader Stage 2 (BL2U) ----------------------------------- - -The AP Firmware Updater Configuration, BL2U, is an optional part of the FWU -process and is executed only by the primary CPU. BL1 passes control to BL2U at -`BL2U_BASE`. BL2U executes in Secure-EL1 and is responsible for: - -1. (Optional) Transfering the optional SCP_BL2U binary image from AP secure - memory to SCP RAM. BL2U uses the SCP_BL2U `image_info` passed by BL1. - `SCP_BL2U_BASE` defines the address in AP secure memory where SCP_BL2U - should be copied from. Subsequent handling of the SCP_BL2U image is - implemented by the platform specific `bl2u_plat_handle_scp_bl2u()` function. - If `SCP_BL2U_BASE` is not defined then this step is not performed. - -2. Any platform specific setup required to perform the FWU process. For - example, ARM standard platforms initialize the TZC controller so that the - normal world can access DDR memory. - -The following functions must be implemented by the platform port to enable -BL2U to perform the tasks mentioned above. - -### Function : bl2u_early_platform_setup() [mandatory] - - Argument : meminfo *mem_info, void *plat_info - 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 and platform specific info provided by BL1. - -The platform may copy the contents of the `mem_info` and `plat_info` into -private storage as the original memory may be subsequently overwritten by BL2U. - -On ARM CSS platforms `plat_info` is interpreted as an `image_info_t` structure, -to extract SCP_BL2U image information, which is then copied into a private -variable. - -### Function : bl2u_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 : bl2u_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 `bl2u_plat_arch_setup()`. It is only -called by the primary CPU. - -The purpose of this function is to perform any platform initialization -specific to BL2U. - -In ARM standard platforms, this function performs security setup, including -configuration of the TrustZone controller to allow non-secure masters access -to most of DRAM. Part of DRAM is reserved for secure world use. - -### Function : bl2u_plat_handle_scp_bl2u() [optional] - - Argument : void - Return : int - -This function is used to perform any platform-specific actions required to -handle the SCP firmware. Typically it transfers the image into SCP memory using -a platform-specific protocol and waits until SCP executes it and signals to the -Application Processor (AP) for BL2U execution to continue. - -This function returns 0 on success, a negative error code otherwise. -This function is included if SCP_BL2U_BASE is defined. - - -3.4 Boot Loader Stage 3-1 (BL31) ---------------------------------- - -During cold boot, the BL31 stage is executed only by the primary CPU. This is -determined in BL1 using the `platform_is_primary_cpu()` function. BL1 passes -control to BL31 at `BL31_BASE`. During warm boot, BL31 is executed by all -CPUs. BL31 executes at EL3 and is responsible for: - -1. Re-initializing all architectural and platform state. Although BL1 performs - some of this initialization, BL31 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. BL31 uses the `entry_point_info` structure that BL2 - populated in memory to do this. - -3. Providing runtime firmware services. Currently, BL31 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 BL32 image, pre-loaded at a platform- - specific address by BL2. BL31 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. BL31 uses the `entry_point_info` - structure populated by BL2 to do this. - -If BL31 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 BL31 -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 BL31 and similarly the `void *` pointing -to the platform data also needs to be saved. - -In ARM standard platforms, BL2 passes a pointer to a `bl31_params` structure -in BL2 memory. BL31 copies the information in this pointer to internal data -structures. It also performs the following: - -* Initialize a UART (PL011 console), which enables access to the `printf` - family of functions in BL31. - -* Enable issuing of snoop and DVM (Distributed Virtual Memory) requests to the - CCI slave interface corresponding to the cluster that includes the primary - CPU. - - -### 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. - -On ARM standard platforms, this function enables the MMU. - - -### 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 -BL31 runtime services and normal world software can function correctly. - -On ARM standard platforms, this function does the following: - -* Initialize the generic interrupt controller. - - Depending on the GIC driver selected by the platform, the appropriate GICv2 - or GICv3 initialization will be done, which mainly consists of: - - - Enable secure interrupts in the GIC CPU interface. - - 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 and the other secure interrupts on the platform as secure. - - Target all secure SPIs to CPU0. - - Enable these secure interrupts in the GIC distributor. - - Configure all other interrupts as non-secure. - - Enable signaling of secure interrupts in the GIC distributor. - -* Enable system-level implementation of the generic timer counter through the - memory mapped interface. - -* Grant access to the system counter timer module - -* Initialize the power controller device. - - In particular, initialise the locks that prevent concurrent accesses to the - power controller device. - - -### Function : bl31_plat_runtime_setup() [optional] - - Argument : void - Return : void - -The purpose of this function is allow the platform to perform any BL31 runtime -setup just prior to BL31 exit during cold boot. The default weak -implementation of this function will invoke `console_uninit()` which will -suppress any BL31 runtime logs. - -In ARM Standard platforms, this function will initialize the BL31 runtime -console which will cause all further BL31 logs to be output to the -runtime console. - - -### 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. BL31 -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. - -### Function : plat_get_syscnt_freq2() [mandatory] - - Argument : void - Return : unsigned int - -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 ARM standard platforms, it returns the base frequency -of the system counter, which is retrieved from the first entry in the frequency -modes table. - - -### #define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional] - - When `USE_COHERENT_MEM = 0`, this constant defines the total memory (in - bytes) aligned to the cache line boundary that should be allocated per-cpu to - accommodate all the bakery locks. - - If this constant is not defined when `USE_COHERENT_MEM = 0`, the linker - calculates the size of the `bakery_lock` input section, aligns it to the - nearest `CACHE_WRITEBACK_GRANULE`, multiplies it with `PLATFORM_CORE_COUNT` - and stores the result in a linker symbol. This constant prevents a platform - from relying on the linker and provide a more efficient mechanism for - accessing per-cpu bakery lock information. - - If this constant is defined and its value is not equal to the value - calculated by the linker then a link time assertion is raised. A compile time - assertion is raised if the value of the constant is not aligned to the cache - line boundary. - -3.5 Power State Coordination Interface (in BL31) ------------------------------------------------- - -The ARM Trusted Firmware's implementation of the PSCI API is based around the -concept of a _power domain_. A _power domain_ is a CPU or a logical group of -CPUs which share some state on which power management operations can be -performed as specified by [PSCI]. Each CPU in the system is assigned a cpu -index which is a unique number between `0` and `PLATFORM_CORE_COUNT - 1`. -The _power domains_ are arranged in a hierarchical tree structure and -each _power domain_ can be identified in a system by the cpu index of any CPU -that is part of that domain and a _power domain level_. A processing element -(for example, a CPU) is at level 0. If the _power domain_ node above a CPU is -a logical grouping of CPUs that share some state, then level 1 is that group -of CPUs (for example, a cluster), and level 2 is a group of clusters -(for example, the system). More details on the power domain topology and its -organization can be found in [Power Domain Topology Design]. - -BL31'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_psci_ops` structure. The -PSCI implementation calls members of the `plat_psci_ops` structure for performing -power management operations on the power domains. For example, the target -CPU is specified by its `MPIDR` in a PSCI `CPU_ON` call. The `pwr_domain_on()` -handler (if present) is called for the CPU power domain. - -The `power-state` parameter of a PSCI `CPU_SUSPEND` call can be used to -describe composite power states specific to a platform. The PSCI implementation -defines a generic representation of the power-state parameter viz which is an -array of local power states where each index corresponds to a power domain -level. Each entry contains the local power state the power domain at that power -level could enter. It depends on the `validate_power_state()` handler to -convert the power-state parameter (possibly encoding a composite power state) -passed in a PSCI `CPU_SUSPEND` call to this representation. - -The following functions form part of platform port of PSCI functionality. - - -### Function : plat_psci_stat_accounting_start() [optional] - - Argument : const psci_power_state_t * - Return : void - -This is an optional hook that platforms can implement for residency statistics -accounting before entering a low power state. The `pwr_domain_state` field of -`state_info` (first argument) can be inspected if stat accounting is done -differently at CPU level versus higher levels. As an example, if the element at -index 0 (CPU power level) in the `pwr_domain_state` array indicates a power down -state, special hardware logic may be programmed in order to keep track of the -residency statistics. For higher levels (array indices > 0), the residency -statistics could be tracked in software using PMF. If `ENABLE_PMF` is set, the -default implementation will use PMF to capture timestamps. - -### Function : plat_psci_stat_accounting_stop() [optional] - - Argument : const psci_power_state_t * - Return : void - -This is an optional hook that platforms can implement for residency statistics -accounting after exiting from a low power state. The `pwr_domain_state` field -of `state_info` (first argument) can be inspected if stat accounting is done -differently at CPU level versus higher levels. As an example, if the element at -index 0 (CPU power level) in the `pwr_domain_state` array indicates a power down -state, special hardware logic may be programmed in order to keep track of the -residency statistics. For higher levels (array indices > 0), the residency -statistics could be tracked in software using PMF. If `ENABLE_PMF` is set, the -default implementation will use PMF to capture timestamps. - -### Function : plat_psci_stat_get_residency() [optional] - - Argument : unsigned int, const psci_power_state_t *, int - Return : u_register_t - -This is an optional interface that is is invoked after resuming from a low power -state and provides the time spent resident in that low power state by the power -domain at a particular power domain level. When a CPU wakes up from suspend, -all its parent power domain levels are also woken up. The generic PSCI code -invokes this function for each parent power domain that is resumed and it -identified by the `lvl` (first argument) parameter. The `state_info` (second -argument) describes the low power state that the power domain has resumed from. -The current CPU is the first CPU in the power domain to resume from the low -power state and the `last_cpu_idx` (third parameter) is the index of the last -CPU in the power domain to suspend and may be needed to calculate the residency -for that power domain. - -### Function : plat_get_target_pwr_state() [optional] - - Argument : unsigned int, const plat_local_state_t *, unsigned int - Return : plat_local_state_t - -The PSCI generic code uses this function to let the platform participate in -state coordination during a power management operation. The function is passed -a pointer to an array of platform specific local power state `states` (second -argument) which contains the requested power state for each CPU at a particular -power domain level `lvl` (first argument) within the power domain. The function -is expected to traverse this array of upto `ncpus` (third argument) and return -a coordinated target power state by the comparing all the requested power -states. The target power state should not be deeper than any of the requested -power states. - -A weak definition of this API is provided by default wherein it assumes -that the platform assigns a local state value in order of increasing depth -of the power state i.e. for two power states X & Y, if X < Y -then X represents a shallower power state than Y. As a result, the -coordinated target local power state for a power domain will be the minimum -of the requested local power state values. - - -### Function : plat_get_power_domain_tree_desc() [mandatory] - - Argument : void - Return : const unsigned char * - -This function returns a pointer to the byte array containing the power domain -topology tree description. The format and method to construct this array are -described in [Power Domain Topology Design]. The BL31 PSCI initilization code -requires this array to be described by the platform, either statically or -dynamically, to initialize the power domain topology tree. In case the array -is populated dynamically, then plat_core_pos_by_mpidr() and -plat_my_core_pos() should also be implemented suitably so that the topology -tree description matches the CPU indices returned by these APIs. These APIs -together form the platform interface for the PSCI topology framework. - - -## Function : plat_setup_psci_ops() [mandatory] - - Argument : uintptr_t, const plat_psci_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 let -the platform layer know about the warm boot entrypoint through the -`sec_entrypoint` (first argument) and to export handler routines for -platform-specific psci power management actions by populating the passed -pointer with a pointer to BL31's private `plat_psci_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/arm/board/fvp/fvp_pm.c] as an example. For each PSCI function that the -platform wants to support, the associated operation or operations in this -structure must be provided and implemented (Refer section 4 of -[Firmware Design] for the PSCI API supported in Trusted Firmware). To disable -a PSCI function in a platform port, the operation should be removed from this -structure instead of providing an empty implementation. - -#### plat_psci_ops.cpu_standby() - -Perform the platform-specific actions to enter the standby state for a cpu -indicated by the passed argument. This provides a fast path for CPU standby -wherein overheads of PSCI state management and lock acquistion is avoided. -For this handler to be invoked by the PSCI `CPU_SUSPEND` API implementation, -the suspend state type specified in the `power-state` parameter should be -STANDBY and the target power domain level specified should be the CPU. The -handler should put the CPU into a low power retention state (usually by -issuing a wfi instruction) and ensure that it can be woken up from that -state by a normal interrupt. The generic code expects the handler to succeed. - -#### plat_psci_ops.pwr_domain_on() - -Perform the platform specific actions to power on a CPU, specified -by the `MPIDR` (first argument). The generic code expects the platform to -return PSCI_E_SUCCESS on success or PSCI_E_INTERN_FAIL for any failure. - -#### plat_psci_ops.pwr_domain_off() - -Perform the platform specific actions to prepare to power off the calling CPU -and its higher parent power domain levels as indicated by the `target_state` -(first argument). It is called by the PSCI `CPU_OFF` API implementation. - -The `target_state` encodes the platform coordinated target local power states -for the CPU power domain and its parent power domain levels. The handler -needs to perform power management operation corresponding to the local state -at each power level. - -For this handler, the local power state for the CPU power domain will be a -power down state where as it could be either power down, retention or run state -for the higher power domain levels depending on the result of state -coordination. The generic code expects the handler to succeed. - -#### plat_psci_ops.pwr_domain_suspend() - -Perform the platform specific actions to prepare to suspend the calling -CPU and its higher parent power domain levels as indicated by the -`target_state` (first argument). It is called by the PSCI `CPU_SUSPEND` -API implementation. - -The `target_state` has a similar meaning as described in -the `pwr_domain_off()` operation. It encodes the platform coordinated -target local power states for the CPU power domain and its parent -power domain levels. The handler needs to perform power management operation -corresponding to the local state at each power level. The generic code -expects the handler to succeed. - -The difference between turning a power domain off versus suspending it -is that in the former case, the power domain is expected to re-initialize -its state when it is next powered on (see `pwr_domain_on_finish()`). In the -latter case, the power domain is expected to save enough state so that it can -resume execution by restoring this state when its powered on (see -`pwr_domain_suspend_finish()`). - -#### plat_psci_ops.pwr_domain_pwr_down_wfi() - -This is an optional function and, if implemented, is expected to perform -platform specific actions including the `wfi` invocation which allows the -CPU to powerdown. Since this function is invoked outside the PSCI locks, -the actions performed in this hook must be local to the CPU or the platform -must ensure that races between multiple CPUs cannot occur. - -The `target_state` has a similar meaning as described in the `pwr_domain_off()` -operation and it encodes the platform coordinated target local power states for -the CPU power domain and its parent power domain levels. This function must -not return back to the caller. - -If this function is not implemented by the platform, PSCI generic -implementation invokes `psci_power_down_wfi()` for power down. - -#### plat_psci_ops.pwr_domain_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 `target_state` (first argument) is the prior state of the power domains -immediately before the CPU was turned on. It indicates which power domains -above the CPU might require initialization due to having previously been in -low power states. The generic code expects the handler to succeed. - -#### plat_psci_ops.pwr_domain_suspend_finish() - -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 or `SYSTEM_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 `target_state` (first argument) has a similar meaning as described in -the `pwr_domain_on_finish()` operation. The generic code expects the platform -to succeed. - -#### plat_psci_ops.system_off() - -This function is called by PSCI implementation in response to a `SYSTEM_OFF` -call. It performs the platform-specific system poweroff sequence after -notifying the Secure Payload Dispatcher. - -#### plat_psci_ops.system_reset() - -This function is called by PSCI implementation in response to a `SYSTEM_RESET` -call. It performs the platform-specific system reset sequence after -notifying the Secure Payload Dispatcher. - -#### plat_psci_ops.validate_power_state() - -This function is called by the PSCI implementation during the `CPU_SUSPEND` -call to validate the `power_state` parameter of the PSCI API and if valid, -populate it in `req_state` (second argument) array as power domain level -specific local states. If the `power_state` is invalid, the platform must -return PSCI_E_INVALID_PARAMS as error, which is propagated back to the -normal world PSCI client. - -#### plat_psci_ops.validate_ns_entrypoint() - -This function is called by the PSCI implementation during the `CPU_SUSPEND`, -`SYSTEM_SUSPEND` and `CPU_ON` calls to validate the non-secure `entry_point` -parameter passed by the normal world. If the `entry_point` is invalid, -the platform must return PSCI_E_INVALID_ADDRESS as error, which is -propagated back to the normal world PSCI client. - -#### plat_psci_ops.get_sys_suspend_power_state() - -This function is called by the PSCI implementation during the `SYSTEM_SUSPEND` -call to get the `req_state` parameter from platform which encodes the power -domain level specific local states to suspend to system affinity level. The -`req_state` will be utilized to do the PSCI state coordination and -`pwr_domain_suspend()` will be invoked with the coordinated target state to -enter system suspend. - -#### plat_psci_ops.get_pwr_lvl_state_idx() - -This is an optional function and, if implemented, is invoked by the PSCI -implementation to convert the `local_state` (first argument) at a specified -`pwr_lvl` (second argument) to an index between 0 and -`PLAT_MAX_PWR_LVL_STATES` - 1. This function is only needed if the platform -supports more than two local power states at each power domain level, that is -`PLAT_MAX_PWR_LVL_STATES` is greater than 2, and needs to account for these -local power states. - -#### plat_psci_ops.translate_power_state_by_mpidr() - -This is an optional function and, if implemented, verifies the `power_state` -(second argument) parameter of the PSCI API corresponding to a target power -domain. The target power domain is identified by using both `MPIDR` (first -argument) and the power domain level encoded in `power_state`. The power domain -level specific local states are to be extracted from `power_state` and be -populated in the `output_state` (third argument) array. The functionality -is similar to the `validate_power_state` function described above and is -envisaged to be used in case the validity of `power_state` depend on the -targeted power domain. If the `power_state` is invalid for the targeted power -domain, the platform must return PSCI_E_INVALID_PARAMS as error. If this -function is not implemented, then the generic implementation relies on -`validate_power_state` function to translate the `power_state`. - -This function can also be used in case the platform wants to support local -power state encoding for `power_state` parameter of PSCI_STAT_COUNT/RESIDENCY -APIs as described in Section 5.18 of [PSCI]. - -#### plat_psci_ops.get_node_hw_state() - -This is an optional function. If implemented this function is intended to return -the power state of a node (identified by the first parameter, the `MPIDR`) in -the power domain topology (identified by the second parameter, `power_level`), -as retrieved from a power controller or equivalent component on the platform. -Upon successful completion, the implementation must map and return the final -status among `HW_ON`, `HW_OFF` or `HW_STANDBY`. Upon encountering failures, it -must return either `PSCI_E_INVALID_PARAMS` or `PSCI_E_NOT_SUPPORTED` as -appropriate. - -Implementations are not expected to handle `power_levels` greater than -`PLAT_MAX_PWR_LVL`. - -3.6 Interrupt Management framework (in BL31) ----------------------------------------------- -BL31 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 in ARM standard -platforms. The API implementation depends upon the type of interrupt controller -present in the platform. ARM standard platform layer supports both [ARM Generic -Interrupt Controller version 2.0 (GICv2)][ARM GIC Architecture Specification 2.0] -and [3.0 (GICv3)][ARM GIC Architecture Specification 3.0]. Juno builds the ARM -Standard layer to use GICv2 and the FVP can be configured to use either GICv2 or -GICv3 depending on the build flag `FVP_USE_GIC_DRIVER` (See FVP platform -specific build options in [User Guide] for more details). - -### 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. This API must be invoked at EL3. - -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. - -In the case of ARM standard platforms using GICv2, S-EL1 interrupts are -configured as FIQs and Non-secure interrupts as IRQs from either security -state. - -In the case of ARM standard platforms using GICv3, the interrupt line to be -configured depends on the security state of the execution context when the -interrupt is signalled and are as follows: -* The S-EL1 interrupts are signaled as IRQ in S-EL0/1 context and as FIQ in - NS-EL0/1/2 context. -* The Non secure interrupts are signaled as FIQ in S-EL0/1 context and as IRQ - in the NS-EL0/1/2 context. -* The EL3 interrupts are signaled as FIQ in both S-EL0/1 and NS-EL0/1/2 - context. - - -### 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`. This API must be invoked at EL3. - -In the case of ARM standard platforms using GICv2, the _Highest Priority -Pending Interrupt Register_ (`GICC_HPPIR`) is read 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. - -In the case of ARM standard platforms using GICv3, the system register -`ICC_HPPIR0_EL1`, _Highest Priority Pending group 0 Interrupt Register_, -is read to determine the id of the pending interrupt. The type of interrupt -depends upon the id value as follows. - -1. id = `PENDING_G1S_INTID` (1020) is reported as a S-EL1 interrupt -2. id = `PENDING_G1NS_INTID` (1021) is reported as a Non-secure interrupt. -3. id = `GIC_SPURIOUS_INTERRUPT` (1023) is reported as an invalid interrupt type. -4. All other interrupt id's are reported as EL3 interrupt. - - -### 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. `INTR_ID_UNAVAILABLE` is returned when there is no interrupt -pending. - -In the case of ARM standard platforms using GICv2, the _Highest Priority -Pending Interrupt Register_ (`GICC_HPPIR`) is read 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. - -In the case of ARM standard platforms using GICv3, if the API is invoked from -EL3, the system register `ICC_HPPIR0_EL1`, _Highest Priority Pending Interrupt -group 0 Register_, is read 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 < `PENDING_G1S_INTID` (1020). id is returned as is. -2. id = `PENDING_G1S_INTID` (1020) or `PENDING_G1NS_INTID` (1021). The system - register `ICC_HPPIR1_EL1`, _Highest Priority Pending Interrupt group 1 - Register_ is read to determine the id of the group 1 interrupt. This id - is returned by the API as long as it is a valid interrupt id -3. If the id is any of the special interrupt identifiers, - `INTR_ID_UNAVAILABLE` is returned. - -When the API invoked from S-EL1 for GICv3 systems, the id read from system -register `ICC_HPPIR1_EL1`, _Highest Priority Pending group 1 Interrupt -Register_, is returned if is not equal to GIC_SPURIOUS_INTERRUPT (1023) else -`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. - -This function in ARM standard platforms using GICv2, 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. - -In the case of ARM standard platforms using GICv3, if the API is invoked -from EL3, the function reads the system register `ICC_IAR0_EL1`, _Interrupt -Acknowledge Register group 0_. If the API is invoked from S-EL1, the function -reads the system register `ICC_IAR1_EL1`, _Interrupt Acknowledge Register -group 1_. The read changes the state of the highest pending interrupt from -pending to active in the interrupt controller. The value read is returned -and 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. - -ARM standard platforms write the id to the _End of Interrupt Register_ -(`GICC_EOIR`) in case of GICv2, and to `ICC_EOIR0_EL1` or `ICC_EOIR1_EL1` -system register in case of GICv3 depending on where the API is invoked from, -EL3 or S-EL1. 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. This API must be invoked at EL3. - -ARM standard platforms using GICv2 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. - -In the case of ARM standard platforms using GICv3, both the _Interrupt Group -Register_ (`GICD_IGROUPRn`) and _Interrupt Group Modifier Register_ -(`GICD_IGRPMODRn`) is read to figure out whether the interrupt is configured -as Group 0 secure interrupt, Group 1 secure interrupt or Group 1 NS interrupt. - - -3.7 Crash Reporting mechanism (in BL31) ----------------------------------------------- -BL31 implements a crash reporting mechanism which prints the various registers -of the CPU to enable quick crash analysis and debugging. It requires that a -console is designated as the crash console by the platform which will be used to -print the register dump. - -The following functions must be implemented by the platform if it wants crash -reporting mechanism in BL31. The functions are implemented in assembly so that -they can be invoked without a C Runtime stack. - -### Function : plat_crash_console_init - - Argument : void - Return : int - -This API is used by the crash reporting mechanism to initialize the crash -console. It must only use the general purpose registers x0 to x4 to do the -initialization and returns 1 on success. - -### Function : plat_crash_console_putc - - Argument : int - Return : int - -This API is used by the crash reporting mechanism to print a character on the -designated crash console. It must only use general purpose registers x1 and -x2 to do its work. The parameter and the return value are in general purpose -register x0. - -### Function : plat_crash_console_flush - - Argument : void - Return : int - -This API is used by the crash reporting mechanism to force write of all buffered -data on the designated crash console. It should only use general purpose -registers x0 and x1 to do its work. The return value is 0 on successful -completion; otherwise the return value is -1. - - -4. Build flags ---------------- - -* **ENABLE_PLAT_COMPAT** - All the platforms ports conforming to this API specification should define - the build flag `ENABLE_PLAT_COMPAT` to 0 as the compatibility layer should - be disabled. For more details on compatibility layer, refer - [Migration Guide]. - -There are some build flags which can be defined by the platform to control -inclusion or exclusion of certain BL stages from the FIP image. These flags -need to be defined in the platform makefile which will get included by the -build system. - -* **NEED_BL33** - By default, this flag is defined `yes` by the build system and `BL33` - build option should be supplied as a build option. The platform has the - option of excluding the BL33 image in the `fip` image by defining this flag - to `no`. If any of the options `EL3_PAYLOAD_BASE` or `PRELOADED_BL33_BASE` - are used, this flag will be set to `no` automatically. - -5. 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/lib/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/lib/stdlib` with more system and machine specific declarations in -`include/lib/stdlib/sys` and `include/lib/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/` 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 - - -6. 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 ARM -development platforms 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/drivers/io/io_storage.h`. The implementation of the common library -is in `drivers/io/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 identifiers, as defined in -[include/plat/common/platform_def.h] (or a separate header file included from -there). 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-2016, ARM Limited and Contributors. All rights reserved._ - - -[ARM GIC Architecture Specification 2.0]: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html -[ARM GIC Architecture Specification 3.0]: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0069b/index.html -[IMF Design Guide]: interrupt-framework-design.md -[User Guide]: user-guide.md -[FreeBSD]: http://www.freebsd.org -[Firmware Design]: firmware-design.md -[Power Domain Topology Design]: psci-pd-tree.md -[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf -[Migration Guide]: platform-migration-guide.md -[Firmware Update]: firmware-update.md - -[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/arm/board/fvp/fvp_pm.c]: ../plat/arm/board/fvp/fvp_pm.c -[include/common/bl_common.h]: ../include/common/bl_common.h -[include/lib/aarch32/arch.h]: ../include/lib/aarch32/arch.h -[include/plat/arm/common/arm_def.h]: ../include/plat/arm/common/arm_def.h -[include/plat/common/common_def.h]: ../include/plat/common/common_def.h -[include/plat/common/platform.h]: ../include/plat/common/platform.h -[include/plat/arm/common/plat_arm.h]: ../include/plat/arm/common/plat_arm.h] diff --git a/docs/psci-lib-integration-guide.md b/docs/psci-lib-integration-guide.md deleted file mode 100644 index ab0276b..0000000 --- a/docs/psci-lib-integration-guide.md +++ /dev/null @@ -1,536 +0,0 @@ -PSCI Library Integration guide for ARMv8-A AArch32 systems -========================================================== - -Contents - -1. [Introduction](#1-introduction) -2. [Generic call sequence for PSCI Library interface (AArch32)](#2-generic-call-sequence-for-psci-library-interface-aarch32) -3. [PSCI CPU context management](#3-psci-cpu-context-management) -4. [PSCI Library Interface](#4-psci-library-interface) -5. [EL3 Runtime Software dependencies](#5-el3-runtime-software-dependencies) - - -1. Introduction ---------------- - -This document describes the PSCI library interface with a focus on how to -integrate with a suitable Trusted OS for an ARMv8-A AArch32 system. The PSCI -Library implements the PSCI Standard as described in [PSCI spec] and is meant -to be integrated with EL3 Runtime Software which invokes the PSCI Library -interface appropriately. **EL3 Runtime Software** refers to software executing -at the highest secure privileged mode, which is EL3 in AArch64 or Secure SVC/ -Monitor mode in AArch32, and provides runtime services to the non-secure world. -The runtime service request is made via SMC (Secure Monitor Call) and the call -must adhere to [SMCCC]. In AArch32, EL3 Runtime Software may additionally -include Trusted OS functionality. A minimal AArch32 Secure Payload, SP-MIN, is -provided in ARM Trusted Firmware to illustrate the usage and integration of the -PSCI library. The description of PSCI library interface and its integration -with EL3 Runtime Software in this document is targeted towards AArch32 systems. - -2. Generic call sequence for PSCI Library interface (AArch32) -------------------------------------------------------------- - -The generic call sequence of PSCI Library interfaces (see -[section 4](#4-psci-library-interface)) during cold boot in AArch32 -system is described below: - -1. After cold reset, the EL3 Runtime Software performs its cold boot - initialization including the PSCI library pre-requisites mentioned in - [section 4](#4-psci-library-interface), and also the necessary platform - setup. - -2. Call `psci_setup()` in Monitor mode. - -3. Optionally call `psci_register_spd_pm_hook()` to register callbacks to - do bookkeeping for the EL3 Runtime Software during power management. - -4. Call `psci_prepare_next_non_secure_ctx()` to initialize the non-secure CPU - context. - -5. Get the non-secure `cpu_context_t` for the current CPU by calling - `cm_get_context()` , then programming the registers in the non-secure - context and exiting to non-secure world. If the EL3 Runtime Software needs - additional configuration to be set for non-secure context, like routing - FIQs to the secure world, the values of the registers can be modified prior - to programming. See [section 3](#3-psci-cpu-context-management) for more - details on CPU context management. - -The generic call sequence of PSCI library interfaces during warm boot in -AArch32 systems is described below: - -1. After warm reset, the EL3 Runtime Software performs the necessary warm - boot initialization including the PSCI library pre-requisites mentioned in - [section 4](#4-psci-library-interface) (Note that the Data cache - **must not** be enabled). - -2. Call `psci_warmboot_entrypoint()` in Monitor mode. This interface - initializes/restores the non-secure CPU context as well. - -3. Do step 5 of the cold boot call sequence described above. - -The generic call sequence of PSCI library interfaces on receipt of a PSCI SMC -on an AArch32 system is described below: - -1. On receipt of an SMC, save the register context as per [SMCCC]. - -2. If the SMC function identifier corresponds to a SMC32 PSCI API, construct - the appropriate arguments and call the `psci_smc_handler()` interface. - The invocation may or may not return back to the caller depending on - whether the PSCI API resulted in power down of the CPU. - -3. If `psci_smc_handler()` returns, populate the return value in R0 (AArch32)/ - X0 (AArch64) and restore other registers as per [SMCCC]. - - -3. PSCI CPU context management ------------------------------- - -PSCI library is in charge of initializing/restoring the non-secure CPU system -registers according to [PSCI specification][PSCI spec] during cold/warm boot. -This is referred to as `PSCI CPU Context Management`. Registers that need to -be preserved across CPU power down/power up cycles are maintained in -`cpu_context_t` data structure. The initialization of other non-secure CPU -system registers which do not require coordination with the EL3 Runtime -Software is done directly by the PSCI library (see `cm_prepare_el3_exit()`). - -The EL3 Runtime Software is responsible for managing register context -during switch between Normal and Secure worlds. The register context to be -saved and restored depends on the mechanism used to trigger the world switch. -For example, if the world switch was triggered by an SMC call, then the -registers need to be saved and restored according to [SMCCC]. In AArch64, -due to the tight integration with BL31, both BL31 and PSCI library -use the same `cpu_context_t` data structure for PSCI CPU context management -and register context management during world switch. This cannot be assumed -for AArch32 EL3 Runtime Software since most AArch32 Trusted OSes already implement -a mechanism for register context management during world switch. Hence, when -the PSCI library is integrated with a AArch32 EL3 Runtime Software, the -`cpu_context_t` is stripped down for just PSCI CPU context management. - -During cold/warm boot, after invoking appropriate PSCI library interfaces, it -is expected that the EL3 Runtime Software will query the `cpu_context_t` and -write appropriate values to the corresponding system registers. This mechanism -resolves 2 additional problems for AArch32 EL3 Runtime Software: - -1. Values for certain system registers like SCR and SCTLR cannot be - unilaterally determined by PSCI library and need inputs from the EL3 - Runtime Software. Using `cpu_context_t` as an intermediary data store - allows EL3 Runtime Software to modify the register values appropriately - before programming them. - -2. The PSCI library provides appropriate LR and SPSR values (entrypoint - information) for exit into non-secure world. Using `cpu_context_t` as an - intermediary data store allows the EL3 Runtime Software to store these - values safely until it is ready for exit to non-secure world. - -Currently the `cpu_context_t` data structure for AArch32 stores the following -registers: R0 - R3, LR (R14), SCR, SPSR, SCTLR. - -The EL3 Runtime Software must implement accessors to get/set pointers -to CPU context `cpu_context_t` data and these are described in -[section 5.2](#52-cpu-context-management-api). - - -4. PSCI Library Interface -------------------------- - -The PSCI library implements the [PSCI Specification][PSCI spec]. The interfaces -to this library are declared in `psci.h` and are as listed below: - -``` - u_register_t psci_smc_handler(uint32_t smc_fid, u_register_t x1, - u_register_t x2, u_register_t x3, - u_register_t x4, void *cookie, - void *handle, u_register_t flags); - int psci_setup(const psci_lib_args_t *lib_args); - void psci_warmboot_entrypoint(void); - void psci_register_spd_pm_hook(const spd_pm_ops_t *pm); - void psci_prepare_next_non_secure_ctx(entry_point_info_t *next_image_info); -``` - -The CPU context data 'cpu_context_t' is programmed to the registers differently -when PSCI is integrated with an AArch32 EL3 Runtime Software compared to -when the PSCI is integrated with an AArch64 EL3 Runtime Software (BL31). For -example, in the case of AArch64, there is no need to retrieve `cpu_context_t` -data and program the registers as it will done implicitly as part of -`el3_exit`. The description below of the PSCI interfaces is targeted at -integration with an AArch32 EL3 Runtime Software. - -The PSCI library is responsible for initializing/restoring the non-secure world -to an appropriate state after boot and may choose to directly program the -non-secure system registers. The PSCI generic code takes care not to directly -modify any of the system registers affecting the secure world and instead -returns the values to be programmed to these registers via `cpu_context_t`. -The EL3 Runtime Software is responsible for programming those registers and -can use the proposed values provided in the `cpu_context_t`, modifying the -values if required. - -PSCI library needs the flexibility to access both secure and non-secure -copies of banked registers. Hence it needs to be invoked in Monitor mode -for AArch32 and in EL3 for AArch64. The NS bit in SCR (in AArch32) or SCR_EL3 -(in AArch64) must be set to 0. Additional requirements for the PSCI library -interfaces are: - - * Instruction cache must be enabled - * Both IRQ and FIQ must be masked for the current CPU - * The page tables must be setup and the MMU enabled - * The C runtime environment must be setup and stack initialized - * The Data cache must be enabled prior to invoking any of the PSCI library - interfaces except for `psci_warmboot_entrypoint()`. For - `psci_warmboot_entrypoint()`, if the build option `HW_ASSISTED_COHERENCY` - is enabled however, data caches are expected to be enabled. - -Further requirements for each interface can be found in the interface -description. - -### 4.1 Interface : psci_setup() - - Argument : const psci_lib_args_t *lib_args - Return : void - -This function is to be called by the primary CPU during cold boot before -any other interface to the PSCI library. It takes `lib_args`, a const pointer -to `psci_lib_args_t`, as the argument. The `psci_lib_args_t` is a versioned -structure and is declared in `psci.h` header as follows: - -``` - typedef struct psci_lib_args { - /* The version information of PSCI Library Interface */ - param_header_t h; - /* The warm boot entrypoint function */ - mailbox_entrypoint_t mailbox_ep; - } psci_lib_args_t; -``` - -The first field `h`, of `param_header_t` type, provides the version -information. The second field `mailbox_ep` is the warm boot entrypoint address -and is used to configure the platform mailbox. Helper macros are provided in -psci.h to construct the `lib_args` argument statically or during runtime. Prior -to calling the `psci_setup()` interface, the platform setup for cold boot -must have completed. Major actions performed by this interface are: - - * Initializes architecture. - * Initializes PSCI power domain and state coordination data structures. - * Calls `plat_setup_psci_ops()` with warm boot entrypoint `mailbox_ep` as - argument. - * Calls `cm_set_context_by_index()` (see - [section 5.2](#52-cpu-context-management-api)) for all the CPUs in the - platform - -### 4.2 Interface : psci_prepare_next_non_secure_ctx() - - Argument : entry_point_info_t *next_image_info - Return : void - -After `psci_setup()` and prior to exit to the non-secure world, this function -must be called by the EL3 Runtime Software to initialize the non-secure world -context. The non-secure world entrypoint information `next_image_info` (first -argument) will be used to determine the non-secure context. After this function -returns, the EL3 Runtime Software must retrieve the `cpu_context_t` (using -cm_get_context()) for the current CPU and program the registers prior to exit -to the non-secure world. - -### 4.3 Interface : psci_register_spd_pm_hook() - - Argument : const spd_pm_ops_t * - Return : void - -As explained in [section 5.4](#54-secure-payload-power-management-callback), -the EL3 Runtime Software may want to perform some bookkeeping during power -management operations. This function is used to register the `spd_pm_ops_t` -(first argument) callbacks with the PSCI library which will be called -ppropriately during power management. Calling this function is optional and -need to be called by the primary CPU during the cold boot sequence after -`psci_setup()` has completed. - -### 4.4 Interface : psci_smc_handler() - - Argument : uint32_t smc_fid, u_register_t x1, - u_register_t x2, u_register_t x3, - u_register_t x4, void *cookie, - void *handle, u_register_t flags - Return : u_register_t - -This function is the top level handler for SMCs which fall within the -PSCI service range specified in [SMCCC]. The function ID `smc_fid` (first -argument) determines the PSCI API to be called. The `x1` to `x4` (2nd to 5th -arguments), are the values of the registers r1 - r4 (in AArch32) or x1 - x4 -(in AArch64) when the SMC is received. These are the arguments to PSCI API as -described in [PSCI spec]. The 'flags' (8th argument) is a bit field parameter -and is detailed in 'smcc.h' header. It includes whether the call is from the -secure or non-secure world. The `cookie` (6th argument) and the `handle` -(7th argument) are not used and are reserved for future use. - -The return value from this interface is the return value from the underlying -PSCI API corresponding to `smc_fid`. This function may not return back to the -caller if PSCI API causes power down of the CPU. In this case, when the CPU -wakes up, it will start execution from the warm reset address. - -### 4.5 Interface : psci_warmboot_entrypoint() - - Argument : void - Return : void - -This function performs the warm boot initialization/restoration as mandated by -[PSCI spec]. For AArch32, on wakeup from power down the CPU resets to secure SVC -mode and the EL3 Runtime Software must perform the prerequisite initializations -mentioned at top of this section. This function must be called with Data cache -disabled (unless build option `HW_ASSISTED_COHERENCY` is enabled) but with MMU -initialized and enabled. The major actions performed by this function are: - - * Invalidates the stack and enables the data cache. - * Initializes architecture and PSCI state coordination. - * Restores/Initializes the peripheral drivers to the required state via - appropriate `plat_psci_ops_t` hooks - * Restores the EL3 Runtime Software context via appropriate `spd_pm_ops_t` - callbacks. - * Restores/Initializes the non-secure context and populates the - `cpu_context_t` for the current CPU. - -Upon the return of this function, the EL3 Runtime Software must retrieve the -non-secure `cpu_context_t` using `cm_get_context()` and program the registers -prior to exit to the non-secure world. - - -5. EL3 Runtime Software dependencies ---------------------------------------- - -The PSCI Library includes supporting frameworks like context management, -cpu operations (cpu_ops) and per-cpu data framework. Other helper library -functions like bakery locks and spin locks are also included in the library. -The dependencies which must be fulfilled by the EL3 Runtime Software -for integration with PSCI library are described below. - -### 5.1 General dependencies - -The PSCI library being a Multiprocessor (MP) implementation, EL3 Runtime -Software must provide an SMC handling framework capable of MP adhering to -[SMCCC] specification. - -The EL3 Runtime Software must also export cache maintenance primitives -and some helper utilities for assert, print and memory operations as listed -below. The ARM Trusted Firmware source tree provides implementations for all -these functions but the EL3 Runtime Software may use its own implementation. - -**Functions : assert(), memcpy(), memset** - -These must be implemented as described in ISO C Standard. - -**Function : flush_dcache_range()** - - Argument : uintptr_t addr, size_t size - Return : void - -This function cleans and invalidates (flushes) the data cache for memory -at address `addr` (first argument) address and of size `size` (second argument). - -**Function : inv_dcache_range()** - - Argument : uintptr_t addr, size_t size - Return : void - -This function invalidates (flushes) the data cache for memory at address -`addr` (first argument) address and of size `size` (second argument). - -**Function : do_panic()** - - Argument : void - Return : void - -This function will be called by the PSCI library on encountering a critical -failure that cannot be recovered from. This function **must not** return. - -**Function : tf_printf()** - -This is printf-compatible function, but unlike printf, it does not return any -value. The ARM Trusted Firmware source tree provides an implementation which -is optimized for stack usage and supports only a subset of format specifiers. -The details of the format specifiers supported can be found in the -`tf_printf.c` file in ARM Trusted Firmware source tree. - -### 5.2 CPU Context management API - -The CPU context management data memory is statically allocated by PSCI library -in BSS section. The PSCI library requires the EL3 Runtime Software to implement -APIs to store and retrieve pointers to this CPU context data. SP-MIN -demonstrates how these APIs can be implemented but the EL3 Runtime Software can -choose a more optimal implementation (like dedicating the secure TPIDRPRW -system register (in AArch32) for storing these pointers). - -**Function : cm_set_context_by_index()** - - Argument : unsigned int cpu_idx, void *context, unsigned int security_state - Return : void - -This function is called during cold boot when the `psci_setup()` PSCI library -interface is called. - -This function must store the pointer to the CPU context data, `context` (2nd -argument), for the specified `security_state` (3rd argument) and CPU identified -by `cpu_idx` (first argument). The `security_state` will always be non-secure -when called by PSCI library and this argument is retained for compatibility -with BL31. The `cpu_idx` will correspond to the index returned by the -`plat_core_pos_by_mpidr()` for `mpidr` of the CPU. - -The actual method of storing the `context` pointers is implementation specific. -For example, SP-MIN stores the pointers in the array `sp_min_cpu_ctx_ptr` -declared in `sp_min_main.c`. - -**Function : cm_get_context()** - - Argument : uint32_t security_state - Return : void * - -This function must return the pointer to the `cpu_context_t` structure for -the specified `security_state` (first argument) for the current CPU. The caller -must ensure that `cm_set_context_by_index` is called first and the appropriate -context pointers are stored prior to invoking this API. The `security_state` -will always be non-secure when called by PSCI library and this argument -is retained for compatibility with BL31. - -**Function : cm_get_context_by_index()** - - Argument : unsigned int cpu_idx, unsigned int security_state - Return : void * - -This function must return the pointer to the `cpu_context_t` structure for -the specified `security_state` (second argument) for the CPU identified by -`cpu_idx` (first argument). The caller must ensure that -`cm_set_context_by_index` is called first and the appropriate context -pointers are stored prior to invoking this API. The `security_state` will -always be non-secure when called by PSCI library and this argument is -retained for compatibility with BL31. The `cpu_idx` will correspond to the -index returned by the `plat_core_pos_by_mpidr()` for `mpidr` of the CPU. - -### 5.3 Platform API - -The platform layer abstracts the platform-specific details from the generic -PSCI library. The following platform APIs/macros must be defined by the EL3 -Runtime Software for integration with the PSCI library. - -The mandatory platform APIs are: - - * plat_my_core_pos - * plat_core_pos_by_mpidr - * plat_get_syscnt_freq2 - * plat_get_power_domain_tree_desc - * plat_setup_psci_ops - * plat_reset_handler - * plat_panic_handler - * plat_get_my_stack - -The mandatory platform macros are: - - * PLATFORM_CORE_COUNT - * PLAT_MAX_PWR_LVL - * PLAT_NUM_PWR_DOMAINS - * CACHE_WRITEBACK_GRANULE - * PLAT_MAX_OFF_STATE - * PLAT_MAX_RET_STATE - * PLAT_MAX_PWR_LVL_STATES (optional) - * PLAT_PCPU_DATA_SIZE (optional) - -The details of these APIs/macros can be found in [Porting Guide]. - -All platform specific operations for power management are done via -`plat_psci_ops_t` callbacks registered by the platform when -`plat_setup_psci_ops()` API is called. The description of each of -the callbacks in `plat_psci_ops_t` can be found in PSCI section of the -[Porting Guide]. If any these callbacks are not registered, then the -PSCI API associated with that callback will not be supported by PSCI -library. - -### 5.4 Secure payload power management callback - -During PSCI power management operations, the EL3 Runtime Software may -need to perform some bookkeeping, and PSCI library provides -`spd_pm_ops_t` callbacks for this purpose. These hooks must be -populated and registered by using `psci_register_spd_pm_hook()` PSCI -library interface. - -Typical bookkeeping during PSCI power management calls include save/restore -of the EL3 Runtime Software context. Also if the EL3 Runtime Software makes -use of secure interrupts, then these interrupts must also be managed -appropriately during CPU power down/power up. Any secure interrupt targeted -to the current CPU must be disabled or re-targeted to other running CPU prior -to power down of the current CPU. During power up, these interrupt can be -enabled/re-targeted back to the current CPU. - -``` - typedef struct spd_pm_ops { - void (*svc_on)(u_register_t target_cpu); - int32_t (*svc_off)(u_register_t __unused); - void (*svc_suspend)(u_register_t max_off_pwrlvl); - void (*svc_on_finish)(u_register_t __unused); - void (*svc_suspend_finish)(u_register_t max_off_pwrlvl); - int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu); - int32_t (*svc_migrate_info)(u_register_t *resident_cpu); - void (*svc_system_off)(void); - void (*svc_system_reset)(void); - } spd_pm_ops_t; -``` -A brief description of each callback is given below: - -* svc_on, svc_off, svc_on_finish - - The `svc_on`, `svc_off` callbacks are called during PSCI_CPU_ON, - PSCI_CPU_OFF APIs respectively. The `svc_on_finish` is called when the - target CPU of PSCI_CPU_ON API powers up and executes the - `psci_warmboot_entrypoint()` PSCI library interface. - -* svc_suspend, svc_suspend_finish - - The `svc_suspend` callback is called during power down bu either - PSCI_SUSPEND or PSCI_SYSTEM_SUSPEND APIs. The `svc_suspend_finish` is - called when the CPU wakes up from suspend and executes the - `psci_warmboot_entrypoint()` PSCI library interface. The `max_off_pwrlvl` - (first parameter) denotes the highest power domain level being powered down - to or woken up from suspend. - -* svc_system_off, svc_system_reset - - These callbacks are called during PSCI_SYSTEM_OFF and PSCI_SYSTEM_RESET - PSCI APIs respectively. - -* svc_migrate_info - - This callback is called in response to PSCI_MIGRATE_INFO_TYPE or - PSCI_MIGRATE_INFO_UP_CPU APIs. The return value of this callback must - correspond to the return value of PSCI_MIGRATE_INFO_TYPE API as described - in [PSCI spec]. If the secure payload is a Uniprocessor (UP) - implementation, then it must update the mpidr of the CPU it is resident in - via `resident_cpu` (first argument). The updates to `resident_cpu` is - ignored if the secure payload is a multiprocessor (MP) implementation. - -* svc_migrate - - This callback is only relevant if the secure payload in EL3 Runtime - Software is a Uniprocessor (UP) implementation and supports migration from - the current CPU `from_cpu` (first argument) to another CPU `to_cpu` - (second argument). This callback is called in response to PSCI_MIGRATE - API. This callback is never called if the secure payload is a - Multiprocessor (MP) implementation. - -### 5.5 CPU operations - -The CPU operations (cpu_ops) framework implement power down sequence specific -to the CPU and the details of which can be found in the `CPU specific -operations framework` section of [Firmware Design]. The ARM Trusted Firmware -tree implements the `cpu_ops` for various supported CPUs and the EL3 Runtime -Software needs to include the required `cpu_ops` in its build. The start and -end of the `cpu_ops` descriptors must be exported by the EL3 Runtime Software -via the `__CPU_OPS_START__` and `__CPU_OPS_END__` linker symbols. - -The `cpu_ops` descriptors also include reset sequences and may include errata -workarounds for the CPU. The EL3 Runtime Software can choose to call this -during cold/warm reset if it does not implement its own reset sequence/errata -workarounds. - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2016, ARM Limited and Contributors. All rights reserved._ - -[PSCI spec]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)" -[SMCCC]: https://silver.arm.com/download/ARM_and_AMBA_Architecture/AR570-DA-80002-r0p0-00rel0/ARM_DEN0028A_SMC_Calling_Convention.pdf "SMC Calling Convention" -[Porting Guide]: porting-guide.md -[Firmware Design]: ./firmware-design.md diff --git a/docs/psci-pd-tree.md b/docs/psci-pd-tree.md deleted file mode 100644 index a847f06..0000000 --- a/docs/psci-pd-tree.md +++ /dev/null @@ -1,308 +0,0 @@ -PSCI Library Integration guide for ARMv8-A AArch32 systems -========================================================== - -Contents --------- - -1. [Requirements](#requirements) -2. [Design](#design) - ------------- -Requirements ------------- - -1. A platform must export the `plat_get_aff_count()` and - `plat_get_aff_state()` APIs to enable the generic PSCI code to - populate a tree that describes the hierarchy of power domains in the - system. This approach is inflexible because a change to the topology - requires a change in the code. - - It would be much simpler for the platform to describe its power domain tree - in a data structure. - -2. The generic PSCI code generates MPIDRs in order to populate the power domain - tree. It also uses an MPIDR to find a node in the tree. The assumption that - a platform will use exactly the same MPIDRs as generated by the generic PSCI - code is not scalable. The use of an MPIDR also restricts the number of - levels in the power domain tree to four. - - Therefore, there is a need to decouple allocation of MPIDRs from the - mechanism used to populate the power domain topology tree. - -3. The current arrangement of the power domain tree requires a binary search - over the sibling nodes at a particular level to find a specified power - domain node. During a power management operation, the tree is traversed from - a 'start' to an 'end' power level. The binary search is required to find the - node at each level. The natural way to perform this traversal is to - start from a leaf node and follow the parent node pointer to reach the end - level. - - Therefore, there is a need to define data structures that implement the tree in - a way which facilitates such a traversal. - -4. The attributes of a core power domain differ from the attributes of power - domains at higher levels. For example, only a core power domain can be identified - using an MPIDR. There is no requirement to perform state coordination while - performing a power management operation on the core power domain. - - Therefore, there is a need to implement the tree in a way which facilitates this - distinction between a leaf and non-leaf node and any associated - optimizations. - - ------- -Design ------- - -### Describing a power domain tree - -To fulfill requirement 1., the existing platform APIs -`plat_get_aff_count()` and `plat_get_aff_state()` have been -removed. A platform must define an array of unsigned chars such that: - -1. The first entry in the array specifies the number of power domains at the - highest power level implemented in the platform. This caters for platforms - where the power domain tree does not have a single root node, for example, - the FVP has two cluster power domains at the highest level (1). - -2. Each subsequent entry corresponds to a power domain and contains the number - of power domains that are its direct children. - -3. The size of the array minus the first entry will be equal to the number of - non-leaf power domains. - -4. The value in each entry in the array is used to find the number of entries - to consider at the next level. The sum of the values (number of children) of - all the entries at a level specifies the number of entries in the array for - the next level. - -The following example power domain topology tree will be used to describe the -above text further. The leaf and non-leaf nodes in this tree have been numbered -separately. - -``` - +-+ - |0| - +-+ - / \ - / \ - / \ - / \ - / \ - / \ - / \ - / \ - / \ - / \ - +-+ +-+ - |1| |2| - +-+ +-+ - / \ / \ - / \ / \ - / \ / \ - / \ / \ - +-+ +-+ +-+ +-+ - |3| |4| |5| |6| - +-+ +-+ +-+ +-+ - +---+-----+ +----+----| +----+----+ +----+-----+-----+ - | | | | | | | | | | | | | - | | | | | | | | | | | | | - v v v v v v v v v v v v v - +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +--+ +--+ +--+ - |0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |10| |11| |12| - +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +--+ +--+ +--+ -``` - - -This tree is defined by the platform as the array described above as follows: - -``` - #define PLAT_NUM_POWER_DOMAINS 20 - #define PLATFORM_CORE_COUNT 13 - #define PSCI_NUM_NON_CPU_PWR_DOMAINS \ - (PLAT_NUM_POWER_DOMAINS - PLATFORM_CORE_COUNT) - - unsigned char plat_power_domain_tree_desc[] = { 1, 2, 2, 2, 3, 3, 3, 4}; -``` - -### Removing assumptions about MPIDRs used in a platform - -To fulfill requirement 2., it is assumed that the platform assigns a -unique number (core index) between `0` and `PLAT_CORE_COUNT - 1` to each core -power domain. MPIDRs could be allocated in any manner and will not be used to -populate the tree. - -`plat_core_pos_by_mpidr(mpidr)` will return the core index for the core -corresponding to the MPIDR. It will return an error (-1) if an MPIDR is passed -which is not allocated or corresponds to an absent core. The semantics of this -platform API have changed since it is required to validate the passed MPIDR. It -has been made a mandatory API as a result. - -Another mandatory API, `plat_my_core_pos()` has been added to return the core -index for the calling core. This API provides a more lightweight mechanism to get -the index since there is no need to validate the MPIDR of the calling core. - -The platform should assign the core indices (as illustrated in the diagram above) -such that, if the core nodes are numbered from left to right, then the index -for a core domain will be the same as the index returned by - `plat_core_pos_by_mpidr()` or `plat_my_core_pos()` for that core. This -relationship allows the core nodes to be allocated in a separate array -(requirement 4.) during `psci_setup()` in such an order that the index of the -core in the array is the same as the return value from these APIs. - -#### Dealing with holes in MPIDR allocation - -For platforms where the number of allocated MPIDRs is equal to the number of -core power domains, for example, Juno and FVPs, the logic to convert an MPIDR to -a core index should remain unchanged. Both Juno and FVP use a simple collision -proof hash function to do this. - -It is possible that on some platforms, the allocation of MPIDRs is not -contiguous or certain cores have been disabled. This essentially means that the -MPIDRs have been sparsely allocated, that is, the size of the range of MPIDRs -used by the platform is not equal to the number of core power domains. - -The platform could adopt one of the following approaches to deal with this -scenario: - -1. Implement more complex logic to convert a valid MPIDR to a core index while - maintaining the relationship described earlier. This means that the power - domain tree descriptor will not describe any core power domains which are - disabled or absent. Entries will not be allocated in the tree for these - domains. - -2. Treat unallocated MPIDRs and disabled cores as absent but still describe them - in the power domain descriptor, that is, the number of core nodes described - is equal to the size of the range of MPIDRs allocated. This approach will - lead to memory wastage since entries will be allocated in the tree but will - allow use of a simpler logic to convert an MPIDR to a core index. - - -### Traversing through and distinguishing between core and non-core power domains - -To fulfill requirement 3 and 4, separate data structures have been defined -to represent leaf and non-leaf power domain nodes in the tree. - -``` -/******************************************************************************* - * The following two data structures implement the power domain tree. The tree - * is used to track the state of all the nodes i.e. power domain instances - * described by the platform. The tree consists of nodes that describe CPU power - * domains i.e. leaf nodes and all other power domains which are parents of a - * CPU power domain i.e. non-leaf nodes. - ******************************************************************************/ -typedef struct non_cpu_pwr_domain_node { - /* - * Index of the first CPU power domain node level 0 which has this node - * as its parent. - */ - unsigned int cpu_start_idx; - - /* - * Number of CPU power domains which are siblings of the domain indexed - * by 'cpu_start_idx' i.e. all the domains in the range 'cpu_start_idx - * -> cpu_start_idx + ncpus' have this node as their parent. - */ - unsigned int ncpus; - - /* Index of the parent power domain node */ - unsigned int parent_node; - - ----- -} non_cpu_pd_node_t; - -typedef struct cpu_pwr_domain_node { - u_register_t mpidr; - - /* Index of the parent power domain node */ - unsigned int parent_node; - - ----- -} cpu_pd_node_t; -``` - -The power domain tree is implemented as a combination of the following data -structures. - -``` -non_cpu_pd_node_t psci_non_cpu_pd_nodes[PSCI_NUM_NON_CPU_PWR_DOMAINS]; -cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT]; -``` - -### Populating the power domain tree - -The `populate_power_domain_tree()` function in `psci_setup.c` implements the -algorithm to parse the power domain descriptor exported by the platform to -populate the two arrays. It is essentially a breadth-first-search. The nodes for -each level starting from the root are laid out one after another in the -`psci_non_cpu_pd_nodes` and `psci_cpu_pd_nodes` arrays as follows: - -``` -psci_non_cpu_pd_nodes -> [[Level 3 nodes][Level 2 nodes][Level 1 nodes]] -psci_cpu_pd_nodes -> [Level 0 nodes] -``` - -For the example power domain tree illustrated above, the `psci_cpu_pd_nodes` -will be populated as follows. The value in each entry is the index of the parent -node. Other fields have been ignored for simplicity. - -``` - +-------------+ ^ - CPU0 | 3 | | - +-------------+ | - CPU1 | 3 | | - +-------------+ | - CPU2 | 3 | | - +-------------+ | - CPU3 | 4 | | - +-------------+ | - CPU4 | 4 | | - +-------------+ | - CPU5 | 4 | | PLATFORM_CORE_COUNT - +-------------+ | - CPU6 | 5 | | - +-------------+ | - CPU7 | 5 | | - +-------------+ | - CPU8 | 5 | | - +-------------+ | - CPU9 | 6 | | - +-------------+ | - CPU10 | 6 | | - +-------------+ | - CPU11 | 6 | | - +-------------+ | - CPU12 | 6 | v - +-------------+ -``` - -The `psci_non_cpu_pd_nodes` array will be populated as follows. The value in -each entry is the index of the parent node. - -``` - +-------------+ ^ - PD0 | -1 | | - +-------------+ | - PD1 | 0 | | - +-------------+ | - PD2 | 0 | | - +-------------+ | - PD3 | 1 | | PLAT_NUM_POWER_DOMAINS - - +-------------+ | PLATFORM_CORE_COUNT - PD4 | 1 | | - +-------------+ | - PD5 | 2 | | - +-------------+ | - PD6 | 2 | | - +-------------+ v -``` - -Each core can find its node in the `psci_cpu_pd_nodes` array using the -`plat_my_core_pos()` function. When a core is turned on, the normal world -provides an MPIDR. The `plat_core_pos_by_mpidr()` function is used to validate -the MPIDR before using it to find the corresponding core node. The non-core power -domain nodes do not need to be identified. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2017, ARM Limited and Contributors. All rights reserved._ diff --git a/docs/reset-design.md b/docs/reset-design.md deleted file mode 100644 index 3e45d41..0000000 --- a/docs/reset-design.md +++ /dev/null @@ -1,172 +0,0 @@ -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 diff --git a/docs/rt-svc-writers-guide.md b/docs/rt-svc-writers-guide.md deleted file mode 100644 index ea599ed..0000000 --- a/docs/rt-svc-writers-guide.md +++ /dev/null @@ -1,307 +0,0 @@ -EL3 Runtime Service Writers Guide for ARM Trusted Firmware -========================================================== - -Contents --------- - -1. [Introduction](#1--introduction) -2. [Owning Entities, Call Types and Function IDs](#2--owning-entities-call-types-and-function-ids) -3. [Getting started](#3--getting-started) -4. [Registering a runtime service](#4--registering-a-runtime-service) -5. [Initializing a runtime service](#5-initializing-a-runtime-service) -6. [Handling runtime service requests](#6--handling-runtime-service-requests) -7. [Services that contain multiple sub-services](#7--services-that-contain-multiple-sub-services) -8. [Secure-EL1 Payload Dispatcher service (SPD)](#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 (BL31). - -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 BL31 enables the -independent implementation of services for each group, which are then compiled -into the BL31 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 _Yielding_. Fast calls are -uninterruptible whereas Yielding calls can be pre-empted. The majority of -Owning Entities only have allocated ranges for Fast calls: Yielding 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 - - Yielding 0- 1 Reserved for existing ARMv7 calls - Yielding 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 [`lib/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 - [`smcc.h`] - -* `_type` must be one of `SMC_TYPE_FAST` or `SMC_TYPE_YIELD` - -* `_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 uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid, - u_register_t x1, u_register_t x2, - u_register_t x3, u_register_t x4, - void *cookie, - void *handle, - u_register_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_YIELD` -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 - -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 uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid, - u_register_t x1, u_register_t x2, - u_register_t x3, u_register_t x4, - void *cookie, - void *handle, - u_register_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 `cookie` parameter to the handler is reserved for future use and can be -ignored. The `handle` is returned by the SMC handler - 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 BL31 support for these services. Or a reference to the document that will -provide this information.... - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved._ - - -[Firmware Design]: ./firmware-design.md -[`services`]: ../services -[`lib/psci`]: ../lib/psci -[`std_svc_setup.c`]: ../services/std_svc/std_svc_setup.c -[`runtime_svc.h`]: ../include/common/runtime_svc.h -[`smcc.h`]: ../include/lib/smcc.h -[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)" -[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" diff --git a/docs/spd/optee-dispatcher.md b/docs/spd/optee-dispatcher.md deleted file mode 100644 index 1971d9a..0000000 --- a/docs/spd/optee-dispatcher.md +++ /dev/null @@ -1,13 +0,0 @@ -OP-TEE Dispatcher -================= - -[OP-TEE OS] is a Trusted OS running as Secure EL1. - -To build and execute OP-TEE follow the instructions at -[OP-TEE build.git][OP-TEE OS] - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved._ - -[OP-TEE OS]: https://github.com/OP-TEE/build diff --git a/docs/spd/tlk-dispatcher.md b/docs/spd/tlk-dispatcher.md deleted file mode 100644 index 40c8344..0000000 --- a/docs/spd/tlk-dispatcher.md +++ /dev/null @@ -1,70 +0,0 @@ -Trusted Little Kernel (TLK) Dispatcher -======================================= -TLK dispatcher adds support for NVIDIA's Trusted Little Kernel (TLK) to work -with the Trusted Firmware. TLK-D can be compiled by including it in the -platform's makefile. TLK is primarily meant to work with Tegra SoCs, so until -Trusted Firmware starts supporting Tegra, the dispatcher code can only be -compiled for other platforms. - -In order to compile TLK-D, we need a BL32 image to be present. Since, TLKD -just needs to compile, any BL32 image would do. To use TLK as the BL32, please -refer to the "Build TLK" section. - -Once a BL32 is ready, TLKD can be included in the image by adding "SPD=tlkd" -to the build command. - -Trusted Little Kernel (TLK) -=========================== -TLK is a Trusted OS running as Secure EL1. It is a Free Open Source Software -(FOSS) release of the NVIDIA® Trusted Little Kernel (TLK) technology, which -extends technology made available with the development of the Little Kernel (LK). -You can download the LK modular embedded preemptive kernel for use on ARM, -x86, and AVR32 systems from https://github.com/travisg/lk - -NVIDIA implemented its Trusted Little Kernel (TLK) technology, designed as a -free and open-source trusted execution environment (OTE). - -TLK features include: - -• Small, pre-emptive kernel -• Supports multi-threading, IPCs, and thread scheduling -• Added TrustZone features -• Added Secure Storage -• Under MIT/FreeBSD license - -NVIDIA extensions to Little Kernel (LK) include: - -• User mode -• Address-space separation for TAs -• TLK Client Application (CA) library -• TLK TA library -• Crypto library (encrypt/decrypt, key handling) via OpenSSL -• Linux kernel driver -• Cortex A9/A15 support -• Power Management -• TrustZone memory carve-out (reconfigurable) -• Page table management -• Debugging support over UART (USB planned) - -TLK is hosted by NVIDIA on http://nv-tegra.nvidia.com under the -3rdparty/ote_partner/tlk.git repository. Detailed information about -TLK and OTE can be found in the Tegra_BSP_for_Android_TLK_FOSS_Reference.pdf -manual located under the "documentation" directory_. - -Build TLK -========= -To build and execute TLK, follow the instructions from "Building a TLK Device" -section from Tegra_BSP_for_Android_TLK_FOSS_Reference.pdf manual. - -Input parameters to TLK -======================= -TLK expects the TZDRAM size and a structure containing the boot arguments. BL2 -passes this information to the EL3 software as members of the bl32_ep_info -struct, where bl32_ep_info is part of bl31_params_t (passed by BL2 in X0) - -Example: --------- - bl32_ep_info->args.arg0 = TZDRAM size available for BL32 - bl32_ep_info->args.arg1 = unused (used only on ARMv7) - bl32_ep_info->args.arg2 = pointer to boot args - diff --git a/docs/spd/trusty-dispatcher.md b/docs/spd/trusty-dispatcher.md deleted file mode 100644 index 0258959..0000000 --- a/docs/spd/trusty-dispatcher.md +++ /dev/null @@ -1,15 +0,0 @@ -Trusty Dispatcher -================= -Trusty is a a set of software components, supporting a Trusted Execution -Environment (TEE) on mobile devices, published and maintained by Google. - -Detailed information and build instructions can be found on the Android -Open Source Project (AOSP) webpage for Trusty hosted at -https://source.android.com/security/trusty - -Supported platforms -=================== -Out of all the platforms supported by the ARM Trusted Firmware, Trusty is -verified and supported by NVIDIA's Tegra SoCs. - - diff --git a/docs/trusted-board-boot.md b/docs/trusted-board-boot.md deleted file mode 100644 index 833b5db..0000000 --- a/docs/trusted-board-boot.md +++ /dev/null @@ -1,251 +0,0 @@ -Trusted Board Boot Design Guide -=============================== - -Contents : - -1. [Introduction](#1--introduction) -2. [Chain of Trust](#2--chain-of-trust) -3. [Trusted Board Boot Sequence](#3--trusted-board-boot-sequence) -4. [Authentication Framework](#4--authentication-framework) -5. [Certificate Generation Tool](#5--certificate-generation-tool) - - -1. Introduction ----------------- - -The Trusted Board Boot (TBB) feature prevents malicious firmware from running on -the platform by authenticating all firmware images up to and including the -normal world bootloader. It does this by establishing a Chain of Trust using -Public-Key-Cryptography Standards (PKCS). - -This document describes the design of ARM Trusted Firmware TBB, which is an -implementation of the Trusted Board Boot Requirements (TBBR) specification, -ARM DEN0006C-1. It should be used in conjunction with the [Firmware Update] -design document, which implements a specific aspect of the TBBR. - - -2. Chain of Trust ------------------- - -A Chain of Trust (CoT) starts with a set of implicitly trusted components. On -the ARM development platforms, these components are: - -* A SHA-256 hash of the Root of Trust Public Key (ROTPK). It is stored in the - trusted root-key storage registers. - -* The BL1 image, on the assumption that it resides in ROM so cannot be - tampered with. - -The remaining components in the CoT are either certificates or boot loader -images. The certificates follow the [X.509 v3] standard. This standard -enables adding custom extensions to the certificates, which are used to store -essential information to establish the CoT. - -In the TBB CoT all certificates are self-signed. There is no need for a -Certificate Authority (CA) because the CoT is not established by verifying the -validity of a certificate's issuer but by the content of the certificate -extensions. To sign the certificates, the PKCS#1 SHA-256 with RSA Encryption -signature scheme is used with a RSA key length of 2048 bits. Future version of -Trusted Firmware will support additional cryptographic algorithms. - -The certificates are categorised as "Key" and "Content" certificates. Key -certificates are used to verify public keys which have been used to sign content -certificates. Content certificates are used to store the hash of a boot loader -image. An image can be authenticated by calculating its hash and matching it -with the hash extracted from the content certificate. The SHA-256 function is -used to calculate all hashes. The public keys and hashes are included as -non-standard extension fields in the [X.509 v3] certificates. - -The keys used to establish the CoT are: - -* **Root of trust key** - - The private part of this key is used to sign the BL2 content certificate and - the trusted key certificate. The public part is the ROTPK. - -* **Trusted world key** - - The private part is used to sign the key certificates corresponding to the - secure world images (SCP_BL2, BL31 and BL32). The public part is stored in - one of the extension fields in the trusted world certificate. - -* **Non-trusted world key** - - The private part is used to sign the key certificate corresponding to the - non secure world image (BL33). The public part is stored in one of the - extension fields in the trusted world certificate. - -* **BL3-X keys** - - For each of SCP_BL2, BL31, BL32 and BL33, the private part is used to - sign the content certificate for the BL3-X image. The public part is stored - in one of the extension fields in the corresponding key certificate. - -The following images are included in the CoT: - -* BL1 -* BL2 -* SCP_BL2 (optional) -* BL31 -* BL33 -* BL32 (optional) - -The following certificates are used to authenticate the images. - -* **BL2 content certificate** - - It is self-signed with the private part of the ROT key. It contains a hash - of the BL2 image. - -* **Trusted key certificate** - - It is self-signed with the private part of the ROT key. It contains the - public part of the trusted world key and the public part of the non-trusted - world key. - -* **SCP_BL2 key certificate** - - It is self-signed with the trusted world key. It contains the public part of - the SCP_BL2 key. - -* **SCP_BL2 content certificate** - - It is self-signed with the SCP_BL2 key. It contains a hash of the SCP_BL2 - image. - -* **BL31 key certificate** - - It is self-signed with the trusted world key. It contains the public part of - the BL31 key. - -* **BL31 content certificate** - - It is self-signed with the BL31 key. It contains a hash of the BL31 image. - -* **BL32 key certificate** - - It is self-signed with the trusted world key. It contains the public part of - the BL32 key. - -* **BL32 content certificate** - - It is self-signed with the BL32 key. It contains a hash of the BL32 image. - -* **BL33 key certificate** - - It is self-signed with the non-trusted world key. It contains the public - part of the BL33 key. - -* **BL33 content certificate** - - It is self-signed with the BL33 key. It contains a hash of the BL33 image. - -The SCP_BL2 and BL32 certificates are optional, but they must be present if the -corresponding SCP_BL2 or BL32 images are present. - - -3. Trusted Board Boot Sequence -------------------------------- - -The CoT is verified through the following sequence of steps. The system panics -if any of the steps fail. - -* BL1 loads and verifies the BL2 content certificate. The issuer public key is - read from the verified certificate. A hash of that key is calculated and - compared with the hash of the ROTPK read from the trusted root-key storage - registers. If they match, the BL2 hash is read from the certificate. - - Note: the matching operation is platform specific and is currently - unimplemented on the ARM development platforms. - -* BL1 loads the BL2 image. Its hash is calculated and compared with the hash - read from the certificate. Control is transferred to the BL2 image if all - the comparisons succeed. - -* BL2 loads and verifies the trusted key certificate. The issuer public key is - read from the verified certificate. A hash of that key is calculated and - compared with the hash of the ROTPK read from the trusted root-key storage - registers. If the comparison succeeds, BL2 reads and saves the trusted and - non-trusted world public keys from the verified certificate. - -The next two steps are executed for each of the SCP_BL2, BL31 & BL32 images. -The steps for the optional SCP_BL2 and BL32 images are skipped if these images -are not present. - -* BL2 loads and verifies the BL3x key certificate. The certificate signature - is verified using the trusted world public key. If the signature - verification succeeds, BL2 reads and saves the BL3x public key from the - certificate. - -* BL2 loads and verifies the BL3x content certificate. The signature is - verified using the BL3x public key. If the signature verification succeeds, - BL2 reads and saves the BL3x image hash from the certificate. - -The next two steps are executed only for the BL33 image. - -* BL2 loads and verifies the BL33 key certificate. If the signature - verification succeeds, BL2 reads and saves the BL33 public key from the - certificate. - -* BL2 loads and verifies the BL33 content certificate. If the signature - verification succeeds, BL2 reads and saves the BL33 image hash from the - certificate. - -The next step is executed for all the boot loader images. - -* BL2 calculates the hash of each image. It compares it with the hash obtained - from the corresponding content certificate. The image authentication succeeds - if the hashes match. - -The Trusted Board Boot implementation spans both generic and platform-specific -BL1 and BL2 code, and in tool code on the host build machine. The feature is -enabled through use of specific build flags as described in the [User Guide]. - -On the host machine, a tool generates the certificates, which are included in -the FIP along with the boot loader images. These certificates are loaded in -Trusted SRAM using the IO storage framework. They are then verified by an -Authentication module included in the Trusted Firmware. - -The mechanism used for generating the FIP and the Authentication module are -described in the following sections. - - -4. Authentication Framework ----------------------------- - -The authentication framework included in the Trusted Firmware provides support -to implement the desired trusted boot sequence. ARM platforms use this framework -to implement the boot requirements specified in the TBBR-client document. - -More information about the authentication framework can be found in the -[Auth Framework] document. - - -5. Certificate Generation Tool -------------------------------- - -The `cert_create` tool is built and runs on the host machine as part of the -Trusted Firmware build process when `GENERATE_COT=1`. It takes the boot loader -images and keys as inputs (keys must be in PEM format) and generates the -certificates (in DER format) required to establish the CoT. New keys can be -generated by the tool in case they are not provided. The certificates are then -passed as inputs to the `fiptool` utility for creating the FIP. - -The certificates are also stored individually in the in the output build -directory. - -The tool resides in the `tools/cert_create` directory. It uses OpenSSL SSL -library version 1.0.1 or later to generate the X.509 certificates. Instructions -for building and using the tool can be found in the [User Guide]. - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2015, ARM Limited and Contributors. All rights reserved._ - - -[X.509 v3]: http://www.ietf.org/rfc/rfc5280.txt -[X.690]: http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf -[Auth Framework]: auth-framework.md -[User Guide]: user-guide.md -[Firmware Update]: firmware-update.md diff --git a/docs/user-guide.md b/docs/user-guide.md deleted file mode 100644 index 678bb42..0000000 --- a/docs/user-guide.md +++ /dev/null @@ -1,1600 +0,0 @@ -ARM Trusted Firmware User Guide -=============================== - -Contents : - -1. [Introduction](#1--introduction) -2. [Host machine requirements](#2--host-machine-requirements) -3. [Tools](#3--tools) -4. [Getting the Trusted Firmware source code](#4--getting-the-trusted-firmware-source-code) -5. [Building the Trusted Firmware](#5--building-the-trusted-firmware) -6. [Building a FIP for Juno and FVP](#6--building-a-fip-for-juno-and-fvp) -7. [EL3 payloads alternative boot flow](#7--el3-payloads-alternative-boot-flow) -8. [Preloaded BL33 alternative boot flow](#8--preloaded-bl33-alternative-boot-flow) -9. [Running the software on FVP](#9--running-the-software-on-fvp) -10. [Running the software on Juno](#10--running-the-software-on-juno) - - -1. Introduction ----------------- - -This document describes how to build ARM Trusted Firmware (TF) and run it with a -tested set of other software components using defined configurations on the Juno -ARM development platform and 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 assumes that the reader has previous experience running a fully -bootable Linux software stack on Juno or FVP using the prebuilt binaries and -filesystems provided by [Linaro][Linaro Release Notes]. Further information may -be found in the [Instructions for using the Linaro software deliverables] -[Linaro SW Instructions]. It also assumes that the user understands the role of -the different software components required to boot a Linux system: - -* Specific firmware images required by the platform (e.g. SCP firmware on Juno) -* Normal world bootloader (e.g. UEFI or U-Boot) -* Device tree -* Linux kernel image -* Root filesystem - -Note: the ARM TF v1.3 release was tested with Linaro Release 16.06, and the -latest version of ARM TF is tested with Linaro Release 17.01. - -This document also assumes that the user is familiar with the FVP models and -the different command line options available to launch the model. - -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 14.04 LTS (64-bit). Packages used for -building the software were installed from that distribution unless otherwise -specified. - -The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE, -Cygwin, and Msys (MinGW) shells, using version 4.9.1 of the GNU toolchain. - -3. Tools ---------- - -Install the required packages to build Trusted Firmware with the following -command: - - sudo apt-get install build-essential gcc make git libssl-dev - -Download and install the AArch32 or AArch64 little-endian GCC cross compiler. -The [Linaro Release Notes][Linaro Release Notes] documents which version of the -compiler to use for a given Linaro Release. Also, these -[Linaro instructions][Linaro SW Instructions] provide further guidance. - -Optionally, Trusted Firmware can be built using clang or ARM Compiler 6. -See instructions below on how to switch the default compiler. - -In addition, the following optional packages and tools may be needed: - -* `device-tree-compiler` package if you need to rebuild the Flattened Device - Tree (FDT) source files (`.dts` files) provided with this software. - -* For debugging, ARM [Development Studio 5 (DS-5)][DS-5]. - - -4. Getting the Trusted Firmware source code --------------------------------------------- - -Download the Trusted Firmware source code from Github: - - git clone https://github.com/ARM-software/arm-trusted-firmware.git - - -5. Building the Trusted Firmware ---------------------------------- - -* Before building Trusted Firmware, the environment variable `CROSS_COMPILE` - must point to the Linaro cross compiler. - - For AArch64: - - export CROSS_COMPILE=/bin/aarch64-linux-gnu- - - For AArch32: - - export CROSS_COMPILE=/bin/arm-linux-gnueabihf- - - It is possible to build Trusted Firmware using clang or ARM Compiler 6. - To do so `CC` needs to point to the clang or armclang binary. Only the - compiler is switched; the assembler and linker need to be provided by - the GNU toolchain, thus `CROSS_COMPILE` should be set as described above. - - ARM Compiler 6 will be selected when the base name of the path assigned - to `CC` matches the string 'armclang'. - - For AArch64 using ARM Compiler 6: - - export CROSS_COMPILE=/bin/aarch64-linux-gnu- - make CC=/bin/armclang PLAT= all - - Clang will be selected when the base name of the path assigned to `CC` - contains the string 'clang'. This is to allow both clang and clang-X.Y - to work. - - For AArch64 using clang: - - export CROSS_COMPILE=/bin/aarch64-linux-gnu- - make CC=/bin/clang PLAT= all - -* Change to the root directory of the Trusted Firmware source tree and build. - - For AArch64: - - make PLAT= all - - For AArch32: - - make PLAT= ARCH=aarch32 AARCH32_SP=sp_min all - - - Notes: - - * If `PLAT` is not specified, `fvp` is assumed by default. See the - [Summary of build options](#summary-of-build-options) for more information on available build - options. - - * (AArch32 only) Currently only `PLAT=fvp` is supported. - - * (AArch32 only) `AARCH32_SP` is the AArch32 EL3 Runtime Software and it - corresponds to the BL32 image. A minimal `AARCH32_SP`, sp_min, is - provided by ARM Trusted Firmware to demonstrate how PSCI Library can - be integrated with an AArch32 EL3 Runtime Software. Some AArch32 EL3 - Runtime Software may include other runtime services, for example - Trusted OS services. A guide to integrate PSCI library with AArch32 - EL3 Runtime Software can be found [here][PSCI Lib Integration]. - - * (AArch64 only) The TSP (Test Secure Payload), corresponding to the BL32 - image, is not compiled in by default. Refer to the [Building the Test - Secure Payload](#building-the-test-secure-payload) section below. - - * By default this produces a release version of the build. To produce a - debug version instead, refer to the "Debugging options" 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///bl1.bin` - * `build///bl2.bin` - * `build///bl31.bin` (AArch64 only) - * `build///bl32.bin` (mandatory for AArch32) - - where `` is the name of the chosen platform and `` - is either `debug` or `release`. The actual number of images might differ - depending on the platform. - -* Build products for a specific build variant can be removed using: - - make DEBUG= PLAT= clean - - ... where `` 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. - -#### Common build options - -* `AARCH32_SP` : Choose the AArch32 Secure Payload component to be built as - as the BL32 image when `ARCH=aarch32`. The value should be the path to the - directory containing the SP source, relative to the `bl32/`; the directory - is expected to contain a makefile called `.mk`. - -* `ARCH` : Choose the target build architecture for ARM Trusted Firmware. - It can take either `aarch64` or `aarch32` as values. By default, it is - defined to `aarch64`. - -* `ARM_CCI_PRODUCT_ID`: Choice of ARM CCI product used by the platform. This - is used to determine the number of valid slave interfaces available in the - ARM CCI driver. Default is 400 (that is, CCI-400). - -* `ARM_ARCH_MAJOR`: The major version of ARM Architecture to target when - compiling ARM Trusted Firmware. Its value must be numeric, and defaults to - 8 . See also, _ARMv8 Architecture Extensions_ in [Firmware Design]. - -* `ARM_ARCH_MINOR`: The minor version of ARM Architecture to target when - compiling ARM Trusted Firmware. Its value must be a numeric, and defaults - to 0. See also, _ARMv8 Architecture Extensions_ in [Firmware Design]. - -* `ARM_GIC_ARCH`: Choice of ARM GIC architecture version used by the ARM - Legacy GIC driver for implementing the platform GIC API. This API is used - by the interrupt management framework. Default is 2 (that is, version 2.0). - This build option is deprecated. - -* `ARM_PLAT_MT`: This flag determines whether the ARM platform layer has to - cater for the multi-threading `MT` bit when accessing MPIDR. When this - flag is set, the functions which deal with MPIDR assume that the `MT` bit - in MPIDR is set and access the bit-fields in MPIDR accordingly. Default - value of this flag is 0. - -* `BL2`: This is an optional build option which specifies the path to BL2 - image for the `fip` target. In this case, the BL2 in the ARM Trusted - Firmware will not be built. - -* `BL2U`: This is an optional build option which specifies the path to - BL2U image. In this case, the BL2U in the ARM Trusted Firmware will not - be built. - -* `BL31`: This is an optional build option which specifies the path to - BL31 image for the `fip` target. In this case, the BL31 in the ARM - Trusted Firmware will not be built. - -* `BL31_KEY`: This option is used when `GENERATE_COT=1`. It specifies the - file that contains the BL31 private key in PEM format. If `SAVE_KEYS=1`, - this file name will be used to save the key. - -* `BL32`: This is an optional build option which specifies the path to - BL32 image for the `fip` target. In this case, the BL32 in the ARM - Trusted Firmware will not be built. - -* `BL32_KEY`: This option is used when `GENERATE_COT=1`. It specifies the - file that contains the BL32 private key in PEM format. If `SAVE_KEYS=1`, - this file name will be used to save the key. - -* `BL33`: Path to BL33 image in the host file system. This is mandatory for - `fip` target in case the BL2 from ARM Trusted Firmware is used. - -* `BL33_KEY`: This option is used when `GENERATE_COT=1`. It specifies the - file that contains the BL33 private key in PEM format. If `SAVE_KEYS=1`, - this file name will be used to save the key. - -* `BUILD_MESSAGE_TIMESTAMP`: String used to identify the time and date of the - compilation of each build. It must be set to a C string (including quotes - where applicable). Defaults to a string that contains the time and date of - the compilation. - -* `BUILD_STRING`: Input string for VERSION_STRING, which allows the TF build - to be uniquely identified. Defaults to the current git commit id. - -* `CFLAGS`: Extra user options appended on the compiler's command line in - addition to the options set by the build system. - -* `COLD_BOOT_SINGLE_CPU`: This option indicates whether the platform may - release several CPUs out of reset. It can take either 0 (several CPUs may be - brought up) or 1 (only one CPU will ever be brought up during cold reset). - Default is 0. If the platform always brings up a single CPU, there is no - need to distinguish between primary and secondary CPUs and the boot path can - be optimised. The `plat_is_my_cpu_primary()` and - `plat_secondary_cold_boot_setup()` platform porting interfaces do not need - to be implemented in this case. - -* `CRASH_REPORTING`: A non-zero value enables a console dump of processor - register state when an unexpected exception occurs during execution of - BL31. This option defaults to the value of `DEBUG` - i.e. by default - this is only enabled for a debug build of the firmware. - -* `CREATE_KEYS`: This option is used when `GENERATE_COT=1`. It tells the - certificate generation tool to create new keys in case no valid keys are - present or specified. Allowed options are '0' or '1'. Default is '1'. - -* `CTX_INCLUDE_AARCH32_REGS` : Boolean option that, when set to 1, will cause - the AArch32 system registers to be included when saving and restoring the - CPU context. The option must be set to 0 for AArch64-only platforms (that - is on hardware that does not implement AArch32, or at least not at EL1 and - higher ELs). Default value is 1. - -* `CTX_INCLUDE_FPREGS`: Boolean option that, when set to 1, will cause the FP - registers to be included when saving and restoring the CPU context. Default - is 0. - -* `DEBUG`: Chooses between a debug and release build. It can take either 0 - (release) or 1 (debug) as values. 0 is the default. - -* `EL3_PAYLOAD_BASE`: This option enables booting an EL3 payload instead of - the normal boot flow. It must specify the entry point address of the EL3 - payload. Please refer to the "Booting an EL3 payload" section for more - details. - -* `ENABLE_ASSERTIONS`: This option controls whether or not calls to `assert()` - are compiled out. For debug builds, this option defaults to 1, and calls to - `assert()` are left in place. For release builds, this option defaults to 0 - and calls to `assert()` function are compiled out. This option can be set - independently of `DEBUG`. It can also be used to hide any auxiliary code - that is only required for the assertion and does not fit in the assertion - itself. - -* `ENABLE_PMF`: Boolean option to enable support for optional Performance - Measurement Framework(PMF). Default is 0. - -* `ENABLE_PSCI_STAT`: Boolean option to enable support for optional PSCI - functions `PSCI_STAT_RESIDENCY` and `PSCI_STAT_COUNT`. Default is 0. - In the absence of an alternate stat collection backend, `ENABLE_PMF` must - be enabled. If `ENABLE_PMF` is set, the residency statistics are tracked in - software. - -* `ENABLE_RUNTIME_INSTRUMENTATION`: Boolean option to enable runtime - instrumentation which injects timestamp collection points into - Trusted Firmware to allow runtime performance to be measured. - Currently, only PSCI is instrumented. Enabling this option enables - the `ENABLE_PMF` build option as well. Default is 0. - -* `ENABLE_STACK_PROTECTOR`: String option to enable the stack protection - checks in GCC. Allowed values are "all", "strong" and "0" (default). - "strong" is the recommended stack protection level if this feature is - desired. 0 disables the stack protection. For all values other than 0, the - `plat_get_stack_protector_canary()` platform hook needs to be implemented. - The value is passed as the last component of the option - `-fstack-protector-$ENABLE_STACK_PROTECTOR`. - -* `ERROR_DEPRECATED`: This option decides whether to treat the usage of - deprecated platform APIs, helper functions or drivers within Trusted - Firmware as error. It can take the value 1 (flag the use of deprecated - APIs as error) or 0. The default is 0. - -* `FIP_NAME`: This is an optional build option which specifies the FIP - filename for the `fip` target. Default is `fip.bin`. - -* `FWU_FIP_NAME`: This is an optional build option which specifies the FWU - FIP filename for the `fwu_fip` target. Default is `fwu_fip.bin`. - -* `GENERATE_COT`: Boolean flag used to build and execute the `cert_create` - tool to create certificates as per the Chain of Trust described in - [Trusted Board Boot]. The build system then calls `fiptool` to - include the certificates in the FIP and FWU_FIP. Default value is '0'. - - Specify both `TRUSTED_BOARD_BOOT=1` and `GENERATE_COT=1` to include support - for the Trusted Board Boot feature in the BL1 and BL2 images, to generate - the corresponding certificates, and to include those certificates in the - FIP and FWU_FIP. - - Note that if `TRUSTED_BOARD_BOOT=0` and `GENERATE_COT=1`, the BL1 and BL2 - images will not include support for Trusted Board Boot. The FIP will still - include the corresponding certificates. This FIP can be used to verify the - Chain of Trust on the host machine through other mechanisms. - - Note that if `TRUSTED_BOARD_BOOT=1` and `GENERATE_COT=0`, the BL1 and BL2 - images will include support for Trusted Board Boot, but the FIP and FWU_FIP - will not include the corresponding certificates, causing a boot failure. - -* `HANDLE_EA_EL3_FIRST`: When defined External Aborts and SError Interrupts - will be always trapped in EL3 i.e. in BL31 at runtime. - -* `HW_ASSISTED_COHERENCY`: On most ARM systems to-date, platform-specific - software operations are required for CPUs to enter and exit coherency. - However, there exists newer systems where CPUs' entry to and exit from - coherency is managed in hardware. Such systems require software to only - initiate the operations, and the rest is managed in hardware, minimizing - active software management. In such systems, this boolean option enables ARM - Trusted Firmware to carry out build and run-time optimizations during boot - and power management operations. This option defaults to 0 and if it is - enabled, then it implies `WARMBOOT_ENABLE_DCACHE_EARLY` is also enabled. - -* `JUNO_AARCH32_EL3_RUNTIME`: This build flag enables you to execute EL3 - runtime software in AArch32 mode, which is required to run AArch32 on Juno. - By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in - AArch64 and facilitates the loading of `SP_MIN` and BL33 as AArch32 executable - images. - -* `LDFLAGS`: Extra user options appended to the linkers' command line in - addition to the one set by the build system. - -* `LOAD_IMAGE_V2`: Boolean option to enable support for new version (v2) of - image loading, which provides more flexibility and scalability around what - images are loaded and executed during boot. Default is 0. - Note: `TRUSTED_BOARD_BOOT` is currently only supported for AArch64 when - `LOAD_IMAGE_V2` is enabled. - -* `LOG_LEVEL`: Chooses the log level, which controls the amount of console log - output compiled into the build. This should be one of the following: - - 0 (LOG_LEVEL_NONE) - 10 (LOG_LEVEL_NOTICE) - 20 (LOG_LEVEL_ERROR) - 30 (LOG_LEVEL_WARNING) - 40 (LOG_LEVEL_INFO) - 50 (LOG_LEVEL_VERBOSE) - - All log output up to and including the log level is compiled into the build. - The default value is 40 in debug builds and 20 in release builds. - -* `NON_TRUSTED_WORLD_KEY`: This option is used when `GENERATE_COT=1`. It - specifies the file that contains the Non-Trusted World private key in PEM - format. If `SAVE_KEYS=1`, this file name will be used to save the key. - -* `NS_BL2U`: Path to NS_BL2U image in the host file system. This image is - optional. It is only needed if the platform makefile specifies that it - is required in order to build the `fwu_fip` target. - -* `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 may set this to 1 if it - wants the timer registers to be saved and restored. - -* `PL011_GENERIC_UART`: Boolean option to indicate the PL011 driver that - the underlying hardware is not a full PL011 UART but a minimally compliant - generic UART, which is a subset of the PL011. The driver will not access - any register that is not part of the SBSA generic UART specification. - Default value is 0 (a full PL011 compliant UART is present). - -* `PLAT`: Choose a platform to build ARM Trusted Firmware for. The chosen - platform name must be subdirectory of any depth under `plat/`, and must - contain a platform makefile named `platform.mk`. - -* `PRELOADED_BL33_BASE`: This option enables booting a preloaded BL33 image - instead of the normal boot flow. When defined, it must specify the entry - point address for the preloaded BL33 image. This option is incompatible with - `EL3_PAYLOAD_BASE`. If both are defined, `EL3_PAYLOAD_BASE` has priority - over `PRELOADED_BL33_BASE`. - -* `PROGRAMMABLE_RESET_ADDRESS`: This option indicates whether the reset - vector address can be programmed or is fixed on the platform. It can take - either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a - programmable reset address, it is expected that a CPU will start executing - code directly at the right address, both on a cold and warm reset. In this - case, there is no need to identify the entrypoint on boot and the boot path - can be optimised. The `plat_get_my_entrypoint()` platform porting interface - does not need to be implemented in this case. - -* `PSCI_EXTENDED_STATE_ID`: As per PSCI1.0 Specification, there are 2 formats - possible for the PSCI power-state parameter viz original and extended - State-ID formats. This flag if set to 1, configures the generic PSCI layer - to use the extended format. The default value of this flag is 0, which - means by default the original power-state format is used by the PSCI - implementation. This flag should be specified by the platform makefile - and it governs the return value of PSCI_FEATURES API for CPU_SUSPEND - smc function id. When this option is enabled on ARM platforms, the - option `ARM_RECOM_STATE_ID_ENC` needs to be set to 1 as well. - -* `RESET_TO_BL31`: Enable BL31 entrypoint as the CPU reset vector instead - of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1 - entrypoint) or 1 (CPU reset to BL31 entrypoint). - The default value is 0. - -* `RESET_TO_SP_MIN`: SP_MIN is the minimal AArch32 Secure Payload provided in - ARM Trusted Firmware. This flag configures SP_MIN entrypoint as the CPU - reset vector instead of the BL1 entrypoint. It can take the value 0 (CPU - reset to BL1 entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default - value is 0. - -* `ROT_KEY`: This option is used when `GENERATE_COT=1`. It specifies the - file that contains the ROT private key in PEM format. If `SAVE_KEYS=1`, this - file name will be used to save the key. - -* `SAVE_KEYS`: This option is used when `GENERATE_COT=1`. It tells the - certificate generation tool to save the keys used to establish the Chain of - Trust. Allowed options are '0' or '1'. Default is '0' (do not save). - -* `SCP_BL2`: Path to SCP_BL2 image in the host file system. This image is optional. - If a SCP_BL2 image is present then this option must be passed for the `fip` - target. - -* `SCP_BL2_KEY`: This option is used when `GENERATE_COT=1`. It specifies the - file that contains the SCP_BL2 private key in PEM format. If `SAVE_KEYS=1`, - this file name will be used to save the key. - -* `SCP_BL2U`: Path to SCP_BL2U image in the host file system. This image is - optional. It is only needed if the platform makefile specifies that it - is required in order to build the `fwu_fip` target. - -* `SEPARATE_CODE_AND_RODATA`: Whether code and read-only data should be - isolated on separate memory pages. This is a trade-off between security and - memory usage. See "Isolating code and read-only data on separate memory - pages" section in [Firmware Design]. This flag is disabled by default and - affects all BL images. - -* `SPD`: Choose a Secure Payload Dispatcher component to be built into the - Trusted Firmware. This build option is only valid if `ARCH=aarch64`. The - value should be the path to the directory containing the SPD source, - relative to `services/spd/`; the directory is expected to - contain a makefile called `.mk`. - -* `SPIN_ON_BL1_EXIT`: This option introduces an infinite loop in BL1. It can - take either 0 (no loop) or 1 (add a loop). 0 is the default. This loop stops - execution in BL1 just before handing over to BL31. At this point, all - firmware images have been loaded in memory, and the MMU and caches are - turned off. Refer to the "Debugging options" section for more details. - -* `TRUSTED_BOARD_BOOT`: Boolean flag to include support for the Trusted Board - Boot feature. When set to '1', BL1 and BL2 images include support to load - and verify the certificates and images in a FIP, and BL1 includes support - for the Firmware Update. The default value is '0'. Generation and inclusion - of certificates in the FIP and FWU_FIP depends upon the value of the - `GENERATE_COT` option. - - Note: This option depends on `CREATE_KEYS` to be enabled. If the keys - already exist in disk, they will be overwritten without further notice. - -* `TRUSTED_WORLD_KEY`: This option is used when `GENERATE_COT=1`. It - specifies the file that contains the Trusted World private key in PEM - format. If `SAVE_KEYS=1`, this file name will be used to save the key. - -* `TSP_INIT_ASYNC`: Choose BL32 initialization method as asynchronous or - synchronous, (see "Initializing a BL32 Image" section in [Firmware - Design]). It can take the value 0 (BL32 is initialized using - synchronous method) or 1 (BL32 is initialized using asynchronous method). - Default is 0. - -* `TSP_NS_INTR_ASYNC_PREEMPT`: A non zero value enables the interrupt - routing model which routes non-secure interrupts asynchronously from TSP - to EL3 causing immediate preemption of TSP. The EL3 is responsible - for saving and restoring the TSP context in this routing model. The - default routing model (when the value is 0) is to route non-secure - interrupts to TSP allowing it to save its context and hand over - synchronously to EL3 via an SMC. - -* `USE_COHERENT_MEM`: This flag determines whether to include the coherent - memory region in the BL memory map or not (see "Use of Coherent memory in - Trusted Firmware" section in [Firmware Design]). It can take the value 1 - (Coherent memory region is included) or 0 (Coherent memory region is - excluded). Default is 1. - -* `V`: Verbose build. If assigned anything other than 0, the build commands - are printed. Default is 0. - -* `VERSION_STRING`: String used in the log output for each TF image. Defaults - to a string formed by concatenating the version number, build type and build - string. - -* `WARMBOOT_ENABLE_DCACHE_EARLY` : Boolean option to enable D-cache early on - the CPU after warm boot. This is applicable for platforms which do not - require interconnect programming to enable cache coherency (eg: single - cluster platforms). If this option is enabled, then warm boot path - enables D-caches immediately after enabling MMU. This option defaults to 0. - -* `ENABLE_SPE_FOR_LOWER_ELS` : Boolean option to enable Statistical Profiling - extensions. This is an optional architectural feature available only for - AArch64 8.2 onwards. This option defaults to 1 but is automatically - disabled when the target architecture is AArch32 or AArch64 8.0/8.1. - -#### ARM development platform specific build options - -* `ARM_BL31_IN_DRAM`: Boolean option to select loading of BL31 in TZC secured - DRAM. By default, BL31 is in the secure SRAM. Set this flag to 1 to load - BL31 in TZC secured DRAM. If TSP is present, then setting this option also - sets the TSP location to DRAM and ignores the `ARM_TSP_RAM_LOCATION` build - flag. - -* `ARM_BOARD_OPTIMISE_MEM`: Boolean option to enable or disable optimisation - of the memory reserved for each image. This affects the maximum size of each - BL image as well as the number of allocated memory regions and translation - tables. By default this flag is 0, which means it uses the default - unoptimised values for these macros. ARM development platforms that wish to - optimise memory usage need to set this flag to 1 and must override the - related macros. - -* `ARM_CONFIG_CNTACR`: boolean option to unlock access to the `CNTBase` - frame registers by setting the `CNTCTLBase.CNTACR` register bits. The - frame number `` is defined by `PLAT_ARM_NSTIMER_FRAME_ID`, which should - match the frame used by the Non-Secure image (normally the Linux kernel). - Default is true (access to the frame is allowed). - -* `ARM_DISABLE_TRUSTED_WDOG`: boolean option to disable the Trusted Watchdog. - By default, ARM platforms use a watchdog to trigger a system reset in case - an error is encountered during the boot process (for example, when an image - could not be loaded or authenticated). The watchdog is enabled in the early - platform setup hook at BL1 and disabled in the BL1 prepare exit hook. The - Trusted Watchdog may be disabled at build time for testing or development - purposes. - -* `ARM_RECOM_STATE_ID_ENC`: The PSCI1.0 specification recommends an encoding - for the construction of composite state-ID in the power-state parameter. - The existing PSCI clients currently do not support this encoding of - State-ID yet. Hence this flag is used to configure whether to use the - recommended State-ID encoding or not. The default value of this flag is 0, - in which case the platform is configured to expect NULL in the State-ID - field of power-state parameter. - -* `ARM_ROTPK_LOCATION`: used when `TRUSTED_BOARD_BOOT=1`. It specifies the - location of the ROTPK hash returned by the function `plat_get_rotpk_info()` - for ARM platforms. Depending on the selected option, the proper private key - must be specified using the `ROT_KEY` option when building the Trusted - Firmware. This private key will be used by the certificate generation tool - to sign the BL2 and Trusted Key certificates. Available options for - `ARM_ROTPK_LOCATION` are: - - - `regs` : return the ROTPK hash stored in the Trusted root-key storage - registers. The private key corresponding to this ROTPK hash is not - currently available. - - `devel_rsa` : return a development public key hash embedded in the BL1 - and BL2 binaries. This hash has been obtained from the RSA public key - `arm_rotpk_rsa.der`, located in `plat/arm/board/common/rotpk`. To use - this option, `arm_rotprivk_rsa.pem` must be specified as `ROT_KEY` when - creating the certificates. - -* `ARM_TSP_RAM_LOCATION`: location of the TSP binary. Options: - - `tsram` : Trusted SRAM (default option) - - `tdram` : Trusted DRAM (if available) - - `dram` : Secure region in DRAM (configured by the TrustZone controller) - -* `ARM_XLAT_TABLES_LIB_V1`: boolean option to compile the Trusted Firmware - with version 1 of the translation tables library instead of version 2. It is - set to 0 by default, which selects version 2. - -* `ARM_CRYPTOCELL_INTEG` : bool option to enable Trusted Firmware to invoke - ARM® TrustZone® CryptoCell functionality for Trusted Board Boot on capable - ARM platforms. If this option is specified, then the path to the CryptoCell - SBROM library must be specified via `CCSBROM_LIB_PATH` flag. - -For a better understanding of these options, the ARM development platform memory -map is explained in the [Firmware Design]. - -#### ARM CSS platform specific build options - -* `CSS_DETECT_PRE_1_7_0_SCP`: Boolean flag to detect SCP version - incompatibility. Version 1.7.0 of the SCP firmware made a non-backwards - compatible change to the MTL protocol, used for AP/SCP communication. - Trusted Firmware no longer supports earlier SCP versions. If this option is - set to 1 then Trusted Firmware will detect if an earlier version is in use. - Default is 1. - -* `CSS_LOAD_SCP_IMAGES`: Boolean flag, which when set, adds SCP_BL2 and - SCP_BL2U to the FIP and FWU_FIP respectively, and enables them to be loaded - during boot. Default is 1. - -* `CSS_USE_SCMI_DRIVER`: Boolean flag which selects SCMI driver instead of - SCPI driver for communicating with the SCP during power management operations. - If this option is set to 1, then SCMI driver will be used. Default is 0. - -#### ARM FVP platform specific build options - -* `FVP_CLUSTER_COUNT` : Configures the cluster count to be used to - build the topology tree within Trusted Firmware. By default the - Trusted Firmware is configured for dual cluster topology and this option - can be used to override the default value. - -* `FVP_INTERCONNECT_DRIVER`: Selects the interconnect driver to be built. The - default interconnect driver depends on the value of `FVP_CLUSTER_COUNT` as - explained in the options below: - - `FVP_CCI` : The CCI driver is selected. This is the default - if 0 < `FVP_CLUSTER_COUNT` <= 2. - - `FVP_CCN` : The CCN driver is selected. This is the default - if `FVP_CLUSTER_COUNT` > 2. - -* `FVP_USE_GIC_DRIVER` : Selects the GIC driver to be built. Options: - - `FVP_GIC600` : The GIC600 implementation of GICv3 is selected - - `FVP_GICV2` : The GICv2 only driver is selected - - `FVP_GICV3` : The GICv3 only driver is selected (default option) - - `FVP_GICV3_LEGACY`: The Legacy GICv3 driver is selected (deprecated) - Note: If Trusted Firmware is compiled with this option on FVPs with - GICv3 hardware, then it configures the hardware to run in GICv2 - emulation mode - -* `FVP_USE_SP804_TIMER` : Use the SP804 timer instead of the Generic Timer - for functions that wait for an arbitrary time length (udelay and mdelay). - The default value is 0. - -### Debugging options - -To compile a debug version and make the build more verbose use - - make PLAT= DEBUG=1 V=1 all - -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-` 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 **Memory layout on ARM development -platforms** section in the [Firmware Design]). - -Extra debug options can be passed to the build system by setting `CFLAGS` or -`LDFLAGS`: - - CFLAGS='-O0 -gdwarf-2' \ - make PLAT= DEBUG=1 V=1 all - -Note that using `-Wl,` style compilation driver options in `CFLAGS` will be -ignored as the linker is called directly. - -It is also possible to introduce an infinite loop to help in debugging the -post-BL2 phase of the Trusted Firmware. This can be done by rebuilding BL1 with -the `SPIN_ON_BL1_EXIT=1` build flag. Refer to the "Summary of build options" -section. In this case, the developer may take control of the target using a -debugger when indicated by the console output. When using DS-5, the following -commands can be used: - - # Stop target execution - interrupt - - # - # Prepare your debugging environment, e.g. set breakpoints - # - - # Jump over the debug loop - set var $AARCH64::$Core::$PC = $AARCH64::$Core::$PC + 4 - - # Resume execution - continue - - -### Building the Test Secure Payload - -The TSP is coupled with a companion runtime service in the BL31 firmware, -called the TSPD. Therefore, if you intend to use the TSP, the BL31 image -must be recompiled as well. For more information on SPs and SPDs, see the -[Secure-EL1 Payloads and Dispatchers](firmware-design.rst#secure-el1-payloads-and-dispatchers) section in the [Firmware Design]. - -First clean the Trusted Firmware build directory to get rid of any previous -BL31 binary. Then to build the TSP image use: - - make PLAT= SPD=tspd all - -An additional boot loader binary file is created in the `build` directory: - - build///bl32.bin - -### 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`. - - -### Building and using the FIP tool - -Firmware Image Package (FIP) is a packaging format used by the Trusted Firmware -project to package firmware images in a single binary. The number and type of -images that should be packed in a FIP is platform specific and may include TF -images and other firmware images required by the platform. For example, most -platforms require a BL33 image which corresponds to the normal world bootloader -(e.g. UEFI or U-Boot). - -The TF build system provides the make target `fip` to create a FIP file for the -specified platform using the FIP creation tool included in the TF project. -Examples below show how to build a FIP file for FVP, packaging TF images and a -BL33 image. - -For AArch64: - - make PLAT=fvp BL33= fip - -For AArch32: - - make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33= fip - -Note that AArch32 support for Normal world boot loader (BL33), like U-boot or -UEFI, on FVP is not available upstream. Hence custom solutions are required to -allow Linux boot on FVP. These instructions assume such a custom boot loader -(BL33) is available. - -The resulting FIP may be found in: - - build/fvp//fip.bin - -For advanced operations on FIP files, it is also possible to independently build -the tool and create or modify FIPs using this tool. To do this, follow these -steps: - -It is recommended to remove old artifacts before building the tool: - - make -C tools/fiptool clean - -Build the tool: - - make [DEBUG=1] [V=1] fiptool - -The tool binary can be located in: - - ./tools/fiptool/fiptool - -Invoking the tool with `--help` will print a help message with all available -options. - -Example 1: create a new Firmware package `fip.bin` that contains BL2 and BL31: - - ./tools/fiptool/fiptool create \ - --tb-fw build///bl2.bin \ - --soc-fw build///bl31.bin \ - fip.bin - -Example 2: view the contents of an existing Firmware package: - - ./tools/fiptool/fiptool info /fip.bin - -Example 3: update the entries of an existing Firmware package: - - # Change the BL2 from Debug to Release version - ./tools/fiptool/fiptool update \ - --tb-fw build//release/bl2.bin \ - build//debug/fip.bin - -Example 4: unpack all entries from an existing Firmware package: - - # Images will be unpacked to the working directory - ./tools/fiptool/fiptool unpack /fip.bin - -Example 5: remove an entry from an existing Firmware package: - - ./tools/fiptool/fiptool remove \ - --tb-fw build//debug/fip.bin - -Note that if the destination FIP file exists, the create, update and -remove operations will automatically overwrite it. - -The unpack operation will fail if the images already exist at the -destination. In that case, use -f or --force to continue. - -More information about FIP can be found in the [Firmware Design] document. - -#### Migrating from fip_create to fiptool - -The previous version of fiptool was called fip_create. A compatibility script -that emulates the basic functionality of the previous fip_create is provided. -However, users are strongly encouraged to migrate to fiptool. - -* To create a new FIP file, replace "fip_create" with "fiptool create". -* To update a FIP file, replace "fip_create" with "fiptool update". -* To dump the contents of a FIP file, replace "fip_create --dump" - with "fiptool info". - -### Building FIP images with support for Trusted Board Boot - -Trusted Board Boot primarily consists of the following two features: - -* Image Authentication, described in [Trusted Board Boot], and -* Firmware Update, described in [Firmware Update] - -The following steps should be followed to build FIP and (optionally) FWU_FIP -images with support for these features: - -1. Fulfill the dependencies of the `mbedtls` cryptographic and image parser - modules by checking out a recent version of the [mbed TLS Repository]. It - is important to use a version that is compatible with TF and fixes any - known security vulnerabilities. See [mbed TLS Security Center] for more - information. The latest version of TF is tested with tag `mbedtls-2.4.2`. - - The `drivers/auth/mbedtls/mbedtls_*.mk` files contain the list of mbed TLS - source files the modules depend upon. - `include/drivers/auth/mbedtls/mbedtls_config.h` contains the configuration - options required to build the mbed TLS sources. - - Note that the mbed TLS library is licensed under the Apache version 2.0 - license. Using mbed TLS source code will affect the licensing of - Trusted Firmware binaries that are built using this library. - -2. To build the FIP image, ensure the following command line variables are set - while invoking `make` to build Trusted Firmware: - - * `MBEDTLS_DIR=` - * `TRUSTED_BOARD_BOOT=1` - * `GENERATE_COT=1` - - In the case of ARM platforms, the location of the ROTPK hash must also be - specified at build time. Two locations are currently supported (see - `ARM_ROTPK_LOCATION` build option): - - * `ARM_ROTPK_LOCATION=regs`: the ROTPK hash is obtained from the Trusted - root-key storage registers present in the platform. On Juno, this - registers are read-only. On FVP Base and Cortex models, the registers - are read-only, but the value can be specified using the command line - option `bp.trusted_key_storage.public_key` when launching the model. - On both Juno and FVP models, the default value corresponds to an - ECDSA-SECP256R1 public key hash, whose private part is not currently - available. - - * `ARM_ROTPK_LOCATION=devel_rsa`: use the ROTPK hash that is hardcoded - in the ARM platform port. The private/public RSA key pair may be - found in `plat/arm/board/common/rotpk`. - - Example of command line using RSA development keys: - - MBEDTLS_DIR= \ - make PLAT= TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \ - ARM_ROTPK_LOCATION=devel_rsa \ - ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \ - BL33=/ \ - all fip - - The result of this build will be the bl1.bin and the fip.bin binaries. This - FIP will include the certificates corresponding to the Chain of Trust - described in the TBBR-client document. These certificates can also be found - in the output build directory. - -3. The optional FWU_FIP contains any additional images to be loaded from - Non-Volatile storage during the [Firmware Update] process. To build the - FWU_FIP, any FWU images required by the platform must be specified on the - command line. On ARM development platforms like Juno, these are: - - * NS_BL2U. The AP non-secure Firmware Updater image. - * SCP_BL2U. The SCP Firmware Update Configuration image. - - Example of Juno command line for generating both `fwu` and `fwu_fip` - targets using RSA development: - - MBEDTLS_DIR= \ - make PLAT=juno TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \ - ARM_ROTPK_LOCATION=devel_rsa \ - ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \ - BL33=/ \ - SCP_BL2=/ \ - SCP_BL2U=/ \ - NS_BL2U=/ \ - all fip fwu_fip - - Note: The BL2U image will be built by default and added to the FWU_FIP. - The user may override this by adding `BL2U=/` - to the command line above. - - Note: Building and installing the non-secure and SCP FWU images (NS_BL1U, - NS_BL2U and SCP_BL2U) is outside the scope of this document. - - The result of this build will be bl1.bin, fip.bin and fwu_fip.bin binaries. - Both the FIP and FWU_FIP will include the certificates corresponding to the - Chain of Trust described in the TBBR-client document. These certificates - can also be found in the output build directory. - - -### Building the Certificate Generation Tool - -The `cert_create` tool is built as part of the TF build process when the `fip` -make target is specified and TBB is enabled (as described in the previous -section), but it can also be built separately with the following command: - - make PLAT= [DEBUG=1] [V=1] certtool - -For platforms that do not require their own IDs in certificate files, -the generic 'cert_create' tool can be built with the following command: - - make USE_TBBR_DEFS=1 [DEBUG=1] [V=1] certtool - -`DEBUG=1` builds the tool in debug mode. `V=1` makes the build process more -verbose. The following command should be used to obtain help about the tool: - - ./tools/cert_create/cert_create -h - - -6. Building a FIP for Juno and FVP ------------------------------------ - -This section provides Juno and FVP specific instructions to build Trusted -Firmware, obtain the additional required firmware, and pack it all together in -a single FIP binary. It assumes that a [Linaro Release][Linaro Release Notes] -has been installed. - -Note: Linaro Release 16.06 only includes pre-built binaries for AArch64. For -AArch32, pre-built binaries are only available from Linaro Release 16.12. - -Note: follow the full instructions for one platform before switching to a -different one. Mixing instructions for different platforms may result in -corrupted binaries. - -1. Clean the working directory - - make realclean - -2. Obtain SCP_BL2 (Juno) and BL33 (all platforms) - - Use the fiptool to extract the SCP_BL2 and BL33 images from the FIP - package included in the Linaro release: - - # Build the fiptool - make [DEBUG=1] [V=1] fiptool - - # Unpack firmware images from Linaro FIP - ./tools/fiptool/fiptool unpack \ - /fip.bin - - The unpack operation will result in a set of binary images extracted to the - working directory. The SCP_BL2 image corresponds to `scp-fw.bin` and BL33 - corresponds to `nt-fw.bin`. - - Note: the fiptool will complain if the images to be unpacked already - exist in the current directory. If that is the case, either delete those - files or use the `--force` option to overwrite. - - Note for AArch32, the instructions below assume that nt-fw.bin is a custom - Normal world boot loader that supports AArch32. - -3. Build TF images and create a new FIP for FVP - - # AArch64 - make PLAT=fvp BL33=nt-fw.bin all fip - - # AArch32 - make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=nt-fw.bin all fip - -4. Build TF images and create a new FIP for Juno - - For AArch64: - - Building for AArch64 on Juno simply requires the addition of `SCP_BL2` - as a build parameter. - - make PLAT=juno all fip \ - BL33=/SOFTWARE/bl33-uboot.bin \ - SCP_BL2=/SOFTWARE/scp_bl2.bin - - For AArch32: - - Hardware restrictions on Juno prevent cold reset into AArch32 execution mode, - therefore BL1 and BL2 must be compiled for AArch64, and BL32 is compiled - separately for AArch32. - - * Before building BL32, the environment variable `CROSS_COMPILE` must point - to the AArch32 Linaro cross compiler. - - export CROSS_COMPILE=/bin/arm-linux-gnueabihf- - - * Build BL32 in AArch32. - - make ARCH=aarch32 PLAT=juno AARCH32_SP=sp_min \ - RESET_TO_SP_MIN=1 JUNO_AARCH32_EL3_RUNTIME=1 bl32 - - * Before building BL1 and BL2, the environment variable `CROSS_COMPILE` - must point to the AArch64 Linaro cross compiler. - - export CROSS_COMPILE=/bin/aarch64-linux-gnu- - - * The following parameters should be used to build BL1 and BL2 in AArch64 - and point to the BL32 file. - - make ARCH=aarch64 PLAT=juno LOAD_IMAGE_V2=1 JUNO_AARCH32_EL3_RUNTIME=1 \ - BL33=/SOFTWARE/bl33-uboot.bin \ - SCP_BL2=/SOFTWARE/scp_bl2.bin SPD=tspd \ - BL32=/bl32.bin all fip - -The resulting BL1 and FIP images may be found in: - - # Juno - ./build/juno/release/bl1.bin - ./build/juno/release/fip.bin - - # FVP - ./build/fvp/release/bl1.bin - ./build/fvp/release/fip.bin - - -7. EL3 payloads alternative boot flow --------------------------------------- - -On a pre-production system, the ability to execute arbitrary, bare-metal code at -the highest exception level is required. It allows full, direct access to the -hardware, for example to run silicon soak tests. - -Although it is possible to implement some baremetal secure firmware from -scratch, this is a complex task on some platforms, depending on the level of -configuration required to put the system in the expected state. - -Rather than booting a baremetal application, a possible compromise is to boot -`EL3 payloads` through the Trusted Firmware instead. This is implemented as an -alternative boot flow, where a modified BL2 boots an EL3 payload, instead of -loading the other BL images and passing control to BL31. It reduces the -complexity of developing EL3 baremetal code by: - -* putting the system into a known architectural state; -* taking care of platform secure world initialization; -* loading the SCP_BL2 image if required by the platform. - -When booting an EL3 payload on ARM standard platforms, the configuration of the -TrustZone controller is simplified such that only region 0 is enabled and is -configured to permit secure access only. This gives full access to the whole -DRAM to the EL3 payload. - -The system is left in the same state as when entering BL31 in the default boot -flow. In particular: - -* Running in EL3; -* Current state is AArch64; -* Little-endian data access; -* All exceptions disabled; -* MMU disabled; -* Caches disabled. - -### Booting an EL3 payload - -The EL3 payload image is a standalone image and is not part of the FIP. It is -not loaded by the Trusted Firmware. Therefore, there are 2 possible scenarios: - -* The EL3 payload may reside in non-volatile memory (NVM) and execute in - place. In this case, booting it is just a matter of specifying the right - address in NVM through `EL3_PAYLOAD_BASE` when building the TF. - -* The EL3 payload needs to be loaded in volatile memory (e.g. DRAM) at - run-time. - -To help in the latter scenario, the `SPIN_ON_BL1_EXIT=1` build option can be -used. The infinite loop that it introduces in BL1 stops execution at the right -moment for a debugger to take control of the target and load the payload (for -example, over JTAG). - -It is expected that this loading method will work in most cases, as a debugger -connection is usually available in a pre-production system. The user is free to -use any other platform-specific mechanism to load the EL3 payload, though. - -#### Booting an EL3 payload on FVP - -The EL3 payloads boot flow requires the CPU's mailbox to be cleared at reset for -the secondary CPUs holding pen to work properly. Unfortunately, its reset value -is undefined on the FVP platform and the FVP platform code doesn't clear it. -Therefore, one must modify the way the model is normally invoked in order to -clear the mailbox at start-up. - -One way to do that is to create an 8-byte file containing all zero bytes using -the following command: - - dd if=/dev/zero of=mailbox.dat bs=1 count=8 - -and pre-load it into the FVP memory at the mailbox address (i.e. `0x04000000`) -using the following model parameters: - - --data cluster0.cpu0=mailbox.dat@0x04000000 [Base FVPs] - --data=mailbox.dat@0x04000000 [Foundation FVP] - -To provide the model with the EL3 payload image, the following methods may be -used: - -1. If the EL3 payload is able to execute in place, it may be programmed into - flash memory. On Base Cortex and AEM FVPs, the following model parameter - loads it at the base address of the NOR FLASH1 (the NOR FLASH0 is already - used for the FIP): - - -C bp.flashloader1.fname="/path/to/el3-payload" - - On Foundation FVP, there is no flash loader component and the EL3 payload - may be programmed anywhere in flash using method 3 below. - -2. When using the `SPIN_ON_BL1_EXIT=1` loading method, the following DS-5 - command may be used to load the EL3 payload ELF image over JTAG: - - load /path/to/el3-payload.elf - -3. The EL3 payload may be pre-loaded in volatile memory using the following - model parameters: - - --data cluster0.cpu0="/path/to/el3-payload"@address [Base FVPs] - --data="/path/to/el3-payload"@address [Foundation FVP] - - The address provided to the FVP must match the `EL3_PAYLOAD_BASE` address - used when building the Trusted Firmware. - -#### Booting an EL3 payload on Juno - -If the EL3 payload is able to execute in place, it may be programmed in flash -memory by adding an entry in the `SITE1/HBI0262x/images.txt` configuration file -on the Juno SD card (where `x` depends on the revision of the Juno board). -Refer to the [Juno Getting Started Guide], section 2.3 "Flash memory -programming" for more information. - -Alternatively, the same DS-5 command mentioned in the FVP section above can -be used to load the EL3 payload's ELF file over JTAG on Juno. - - -8. Preloaded BL33 alternative boot flow ----------------------------------------- - -Some platforms have the ability to preload BL33 into memory instead of relying -on Trusted Firmware to load it. This may simplify packaging of the normal world -code and improve performance in a development environment. When secure world -cold boot is complete, Trusted Firmware simply jumps to a BL33 base address -provided at build time. - -For this option to be used, the `PRELOADED_BL33_BASE` build option has to be -used when compiling the Trusted Firmware. For example, the following command -will create a FIP without a BL33 and prepare to jump to a BL33 image loaded at -address 0x80000000: - - make PRELOADED_BL33_BASE=0x80000000 PLAT=fvp all fip - -#### Boot of a preloaded bootwrapped kernel image on Base FVP - -The following example uses the AArch64 boot wrapper. This simplifies normal -world booting while also making use of TF features. It can be obtained from its -repository with: - - git clone git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git - -After compiling it, an ELF file is generated. It can be loaded with the -following command: - - /FVP_Base_AEMv8A-AEMv8A \ - -C bp.secureflashloader.fname=bl1.bin \ - -C bp.flashloader0.fname=fip.bin \ - -a cluster0.cpu0= \ - --start cluster0.cpu0=0x0 - -The `-a cluster0.cpu0=` option loads the ELF file. It -also sets the PC register to the ELF entry point address, which is not the -desired behaviour, so the `--start cluster0.cpu0=0x0` option forces the PC back -to 0x0 (the BL1 entry point address) on CPU #0. The `PRELOADED_BL33_BASE` define -used when compiling the FIP must match the ELF entry point. - -#### Boot of a preloaded bootwrapped kernel image on Juno - -The procedure to obtain and compile the boot wrapper is very similar to the case -of the FVP. The execution must be stopped at the end of bl2_main(), and the -loading method explained above in the EL3 payload boot flow section may be used -to load the ELF file over JTAG on Juno. - - -9. Running the software on FVP -------------------------------- - -The latest version of the AArch64 build of ARM Trusted Firmware has been tested -on the following ARM FVPs (64-bit host machine only). - -* `Foundation_Platform` (Version 10.2, Build 10.2.20) -* `FVP_Base_AEMv8A-AEMv8A` (Version 8.4, Build 0.8.8402) -* `FVP_Base_Cortex-A57x4-A53x4` (Version 8.4, Build 0.8.8402) - -The latest version of the AArch32 build of ARM Trusted Firmware has been tested -on the following ARM FVPs (64-bit host machine only). - -* `FVP_Base_AEMv8A-AEMv8A` (Version 8.4, Build 0.8.8402) -* `FVP_Base_Cortex-A32x4` (Version 10.1, Build 10.1.32) - -NOTE: The build numbers quoted above are those reported by launching the FVP -with the `--version` parameter. - -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. - -NOTE: FVPs can be launched with `--cadi-server` option such that a -CADI-compliant debugger (for example, ARM DS-5) can connect to and control its -execution. - -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]. - -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. - -Note the instructions in the following sections assume that Linaro Release 16.06 -is being 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. - -Note: It is not recommended to use the FDTs built along the kernel because not -all FDTs are available from there. - -* `fvp-base-gicv2-psci.dtb` - - For use with both AEMv8 and Cortex-A57-A53 Base FVPs with - Base memory map configuration. - -* `fvp-base-gicv2-psci-aarch32.dtb` - - For use with AEMv8 and Cortex-A32 Base FVPs running Linux in AArch32 state - with Base memory map configuration. - -* `fvp-base-gicv3-psci.dtb` - - (Default) For use with both AEMv8 and Cortex-A57-A53 Base FVPs with Base - memory map configuration and Linux GICv3 support. - -* `fvp-base-gicv3-psci-aarch32.dtb` - - For use with AEMv8 and Cortex-A32 Base FVPs running Linux in AArch32 state - with Base memory map configuration and Linux GICv3 support. - -* `fvp-foundation-gicv2-psci.dtb` - - For use with Foundation FVP with Base memory map configuration. - -* `fvp-foundation-gicv3-psci.dtb` - - (Default) For use with Foundation FVP with Base memory map configuration - and Linux GICv3 support. - -### Running on the Foundation FVP with reset to BL1 entrypoint - -The following `Foundation_Platform` parameters should be used to boot Linux with -4 CPUs using the AArch64 build of ARM Trusted Firmware. - - /Foundation_Platform \ - --cores=4 \ - --secure-memory \ - --visualization \ - --gicv3 \ - --data="/"@0x0 \ - --data="/"@0x08000000 \ - --data="/"@0x83000000 \ - --data="/"@0x80080000 \ - --block-device="/" - -Notes: -* BL1 is loaded at the start of the Trusted ROM. -* The Firmware Image Package is loaded at the start of NOR FLASH0. -* The Linux kernel image and device tree are loaded in DRAM. -* The default use-case for the Foundation FVP is to use the `--gicv3` option - and enable the GICv3 device in the model. Note that without this option, - the Foundation FVP defaults to legacy (Versatile Express) memory map which - is not supported by ARM Trusted Firmware. - -### Running on the AEMv8 Base FVP with reset to BL1 entrypoint - -The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux -with 8 CPUs using the AArch64 build of ARM Trusted Firmware. - - /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.secureflashloader.fname="/" \ - -C bp.flashloader0.fname="/" \ - --data cluster0.cpu0="/"@0x83000000 \ - --data cluster0.cpu0="/"@0x80080000 \ - -C bp.virtioblockdevice.image_path="/" - -### Running on the AEMv8 Base FVP (AArch32) with reset to BL1 entrypoint - -The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux -with 8 CPUs using the AArch32 build of ARM Trusted Firmware. - - /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 cluster0.cpu0.CONFIG64=0 \ - -C cluster0.cpu1.CONFIG64=0 \ - -C cluster0.cpu2.CONFIG64=0 \ - -C cluster0.cpu3.CONFIG64=0 \ - -C cluster1.cpu0.CONFIG64=0 \ - -C cluster1.cpu1.CONFIG64=0 \ - -C cluster1.cpu2.CONFIG64=0 \ - -C cluster1.cpu3.CONFIG64=0 \ - -C bp.secureflashloader.fname="/" \ - -C bp.flashloader0.fname="/" \ - --data cluster0.cpu0="/"@0x83000000 \ - --data cluster0.cpu0="/"@0x80080000 \ - -C bp.virtioblockdevice.image_path="/" - -### Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint - -The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to -boot Linux with 8 CPUs using the AArch64 build of ARM Trusted Firmware. - - /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.secureflashloader.fname="/" \ - -C bp.flashloader0.fname="/" \ - --data cluster0.cpu0="/"@0x83000000 \ - --data cluster0.cpu0="/"@0x80080000 \ - -C bp.virtioblockdevice.image_path="/" - -### Running on the Cortex-A32 Base FVP (AArch32) with reset to BL1 entrypoint - -The following `FVP_Base_Cortex-A32x4` model parameters should be used to -boot Linux with 4 CPUs using the AArch32 build of ARM Trusted Firmware. - - /FVP_Base_Cortex-A32x4 \ - -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.secureflashloader.fname="/" \ - -C bp.flashloader0.fname="/" \ - --data cluster0.cpu0="/"@0x83000000 \ - --data cluster0.cpu0="/"@0x80080000 \ - -C bp.virtioblockdevice.image_path="/" - -### Running on the AEMv8 Base FVP with reset to BL31 entrypoint - -The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux -with 8 CPUs using the AArch64 build of ARM Trusted Firmware. - - /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 cluster0.cpu0.RVBAR=0x04023000 \ - -C cluster0.cpu1.RVBAR=0x04023000 \ - -C cluster0.cpu2.RVBAR=0x04023000 \ - -C cluster0.cpu3.RVBAR=0x04023000 \ - -C cluster1.cpu0.RVBAR=0x04023000 \ - -C cluster1.cpu1.RVBAR=0x04023000 \ - -C cluster1.cpu2.RVBAR=0x04023000 \ - -C cluster1.cpu3.RVBAR=0x04023000 \ - --data cluster0.cpu0="/"@0x04023000 \ - --data cluster0.cpu0="/"@0x04001000 \ - --data cluster0.cpu0="/"@0x88000000 \ - --data cluster0.cpu0="/"@0x83000000 \ - --data cluster0.cpu0="/"@0x80080000 \ - -C bp.virtioblockdevice.image_path="/" - -Notes: - -* Since a FIP is not loaded when using BL31 as reset entrypoint, the - `--data=""@` - parameter is needed to load the individual bootloader images in memory. - BL32 image is only needed if BL31 has been built to expect a Secure-EL1 - Payload. - -* The `-C cluster.cpu.RVBAR=@` parameter, where - X and Y are the cluster and CPU numbers respectively, is used to set the - reset vector for each core. - -* Changing the default value of `ARM_TSP_RAM_LOCATION` will also require - changing the value of - `--data=""@` to the new value of - `BL32_BASE`. - -### Running on the AEMv8 Base FVP (AArch32) with reset to SP_MIN entrypoint - -The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux -with 8 CPUs using the AArch32 build of ARM Trusted Firmware. - - /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 cluster0.cpu0.CONFIG64=0 \ - -C cluster0.cpu1.CONFIG64=0 \ - -C cluster0.cpu2.CONFIG64=0 \ - -C cluster0.cpu3.CONFIG64=0 \ - -C cluster1.cpu0.CONFIG64=0 \ - -C cluster1.cpu1.CONFIG64=0 \ - -C cluster1.cpu2.CONFIG64=0 \ - -C cluster1.cpu3.CONFIG64=0 \ - -C cluster0.cpu0.RVBAR=0x04001000 \ - -C cluster0.cpu1.RVBAR=0x04001000 \ - -C cluster0.cpu2.RVBAR=0x04001000 \ - -C cluster0.cpu3.RVBAR=0x04001000 \ - -C cluster1.cpu0.RVBAR=0x04001000 \ - -C cluster1.cpu1.RVBAR=0x04001000 \ - -C cluster1.cpu2.RVBAR=0x04001000 \ - -C cluster1.cpu3.RVBAR=0x04001000 \ - --data cluster0.cpu0="/"@0x04001000 \ - --data cluster0.cpu0="/"@0x88000000 \ - --data cluster0.cpu0="/"@0x83000000 \ - --data cluster0.cpu0="/"@0x80080000 \ - -C bp.virtioblockdevice.image_path="/" - -Note: The load address of `` depends on the value `BL32_BASE`. -It should match the address programmed into the RVBAR register as well. - -### Running on the Cortex-A57-A53 Base FVP with reset to BL31 entrypoint - -The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to -boot Linux with 8 CPUs using the AArch64 build of ARM Trusted Firmware. - - /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 cluster0.cpu0.RVBARADDR=0x04023000 \ - -C cluster0.cpu1.RVBARADDR=0x04023000 \ - -C cluster0.cpu2.RVBARADDR=0x04023000 \ - -C cluster0.cpu3.RVBARADDR=0x04023000 \ - -C cluster1.cpu0.RVBARADDR=0x04023000 \ - -C cluster1.cpu1.RVBARADDR=0x04023000 \ - -C cluster1.cpu2.RVBARADDR=0x04023000 \ - -C cluster1.cpu3.RVBARADDR=0x04023000 \ - --data cluster0.cpu0="/"@0x04023000 \ - --data cluster0.cpu0="/"@0x04001000 \ - --data cluster0.cpu0="/"@0x88000000 \ - --data cluster0.cpu0="/"@0x83000000 \ - --data cluster0.cpu0="/"@0x80080000 \ - -C bp.virtioblockdevice.image_path="/" - -### Running on the Cortex-A32 Base FVP (AArch32) with reset to SP_MIN entrypoint - -The following `FVP_Base_Cortex-A32x4` model parameters should be used to -boot Linux with 4 CPUs using the AArch32 build of ARM Trusted Firmware. - - /FVP_Base_Cortex-A32x4 \ - -C pctl.startup=0.0.0.0 \ - -C bp.secure_memory=1 \ - -C bp.tzc_400.diagnostics=1 \ - -C cache_state_modelled=1 \ - -C cluster0.cpu0.RVBARADDR=0x04001000 \ - -C cluster0.cpu1.RVBARADDR=0x04001000 \ - -C cluster0.cpu2.RVBARADDR=0x04001000 \ - -C cluster0.cpu3.RVBARADDR=0x04001000 \ - --data cluster0.cpu0="/"@0x04001000 \ - --data cluster0.cpu0="/"@0x88000000 \ - --data cluster0.cpu0="/"@0x83000000 \ - --data cluster0.cpu0="/"@0x80080000 \ - -C bp.virtioblockdevice.image_path="/" - -10. Running the software on Juno ---------------------------------- - -This version of the ARM Trusted Firmware has been tested on Juno r0 and Juno r1. - -To execute the software stack on Juno, the version of the Juno board recovery -image indicated in the [Linaro Release Notes] must be installed. If you have an -earlier version installed or are unsure which version is installed, please -re-install the recovery image by following the [Instructions for using Linaro's -deliverables on Juno][Juno Instructions]. - -### Preparing Trusted Firmware images - -After building Trusted Firmware, the files `bl1.bin` and `fip.bin` need copying -to the `SOFTWARE/` directory of the Juno SD card. - -### Other Juno software information - -Please visit the [ARM Platforms Portal] to get support and obtain any other Juno -software information. Please also refer to the [Juno Getting Started Guide] to -get more detailed information about the Juno ARM development platform and how to -configure it. - -### Testing SYSTEM SUSPEND on Juno - -The SYSTEM SUSPEND is a PSCI API which can be used to implement system suspend -to RAM. For more details refer to section 5.16 of [PSCI]. To test system suspend -on Juno, at the linux shell prompt, issue the following command: - - echo +10 > /sys/class/rtc/rtc0/wakealarm - echo -n mem > /sys/power/state - -The Juno board should suspend to RAM and then wakeup after 10 seconds due to -wakeup interrupt from RTC. - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved._ - - -[Firmware Design]: firmware-design.md -[ARM FVP website]: https://developer.arm.com/products/system-design/fixed-virtual-platforms -[Linaro Release Notes]: https://community.arm.com/tools/dev-platforms/b/documents/posts/linaro-release-notes-deprecated -[ARM Platforms Portal]: https://community.arm.com/groups/arm-development-platforms -[Linaro SW Instructions]: https://community.arm.com/dev-platforms/b/documents/posts/instructions-for-using-the-linaro-software-deliverables -[Juno Instructions]: https://community.arm.com/dev-platforms/b/documents/posts/using-linaros-deliverables-on-juno -[Juno Getting Started Guide]: http://infocenter.arm.com/help/topic/com.arm.doc.dui0928e/DUI0928E_juno_arm_development_platform_gsg.pdf -[DS-5]: http://www.arm.com/products/tools/software-tools/ds-5/index.php -[mbed TLS Repository]: https://github.com/ARMmbed/mbedtls.git -[mbed TLS Security Center]: https://tls.mbed.org/security -[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)" -[Trusted Board Boot]: trusted-board-boot.md -[Firmware Update]: ./firmware-update.md -[PSCI Lib Integration]: ./psci-lib-integration-guide.md diff --git a/license.md b/license.md deleted file mode 100644 index 185ecd1..0000000 --- a/license.md +++ /dev/null @@ -1,35 +0,0 @@ -Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -* Neither the name of ARM nor the names of its contributors may be used to - endorse or promote products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------- -Note: -Individual files contain the following tag instead of the full license text. - - SPDX-License-Identifier: BSD-3-Clause - -This enables machine processing of license information based on the SPDX -License Identifiers that are here available: http://spdx.org/licenses/ diff --git a/maintainers.md b/maintainers.md deleted file mode 100644 index c8fc19d..0000000 --- a/maintainers.md +++ /dev/null @@ -1,84 +0,0 @@ -ARM Trusted Firmware Maintainers -================================ - -ARM Trusted Firmware is an ARM maintained project. All contributions are -ultimately merged by the maintainers listed below. Technical ownership of some -parts of the codebase is delegated to the sub-maintainers listed below. An -acknowledgement from these sub-maintainers may be required before the -maintainers merge a contribution. - - -## Maintainers - -Dan Handley (dan.handley@arm.com, [danh-arm](https://github.com/danh-arm)) - -David Cunado (david.cunado@arm.com, [davidcunado-arm](https://github.com/davidcunado-arm)) - - -## OPTEE and QEMU platform sub-maintainer - -Jens Wiklander (jens.wiklander@linaro.org, [jenswi-linaro](https://github.com/jenswi-linaro)) - -Files: -* docs/spd/optee-dispatcher.md -* docs/plat/qemu.md -* services/spd/opteed/* -* plat/qemu/* - - -## TLK/Trusty SPDs and NVidia platforms sub-maintainer - -Varun Wadekar (vwadekar@nvidia.com, [vwadekar](https://github.com/vwadekar)) - -Files: -* docs/spd/tlk-dispatcher.md -* docs/spd/trusty-dispatcher.md -* include/bl32/payloads/tlk.h -* include/lib/cpus/aarch64/denver.h -* lib/cpus/aarch64/denver.S -* services/spd/tlkd/* -* services/spd/trusty/* -* plat/nvidia/* - - -## eMMC/UFS drivers and HiSilicon platform sub-maintainer - -Haojian Zhuang (haojian.zhuang@linaro.org, [hzhuang1](https://github.com/hzhuang1)) - -Files: -* docs/plat/hikey.md -* docs/plat/hikey960.md -* drivers/emmc/* -* drivers/partition/* -* drivers/synopsys/emmc/* -* drivers/synopsys/ufs/* -* drivers/ufs/* -* include/drivers/dw_ufs.h -* include/drivers/emmc.h -* include/drivers/ufs.h -* include/drivers/synopsys/dw_mmc.h -* plat/hisilicon/* - - -## MediaTek platform sub-maintainer - -Yidi Lin (林以廸 yidi.lin@mediatek.com, [mtk09422](https://github.com/mtk09422)) - -Files: -* plat/mediatek/* - - -## RockChip platform sub-maintainer -Tony Xie (tony.xie@rock-chips.com, [TonyXie06](https://github.com/TonyXie06) -or [rkchrome](https://github.com/rkchrome)) - -Files: -* plat/rockchip/* - - -## Xilinx platform sub-maintainer -Sören Brinkmann (soren.brinkmann@xilinx.com, [sorenb-xlnx](https://github.com/sorenb-xlnx)) - -Files: -* docs/plat/xilinx-zynqmp.md -* plat/xilinx/* diff --git a/readme.md b/readme.md deleted file mode 100644 index ef5f6ee..0000000 --- a/readme.md +++ /dev/null @@ -1,197 +0,0 @@ -ARM Trusted Firmware - version 1.3 -================================== - -ARM Trusted Firmware provides a reference implementation of secure world -software for [ARMv8-A], including a [Secure Monitor] [TEE-SMC] executing at -Exception Level 3 (EL3). It implements various ARM interface standards, such as -the Power State Coordination Interface ([PSCI]), Trusted Board Boot Requirements -(TBBR, ARM DEN0006C-1) and [SMC Calling Convention][SMCCC]. As far as possible -the code is designed for reuse or porting to other ARMv8-A model and hardware -platforms. - -ARM will continue development in collaboration with interested parties to -provide a full reference implementation of PSCI, TBBR and Secure Monitor code -to the benefit of all developers working with ARMv8-A TrustZone technology. - - -License -------- - -The software is provided under a BSD-3-Clause [license]. Contributions to this -project are accepted under the same license with developer sign-off as -described in the [Contributing Guidelines]. - -This project contains code from other projects as listed below. The original -license text is included in those source files. - -* The stdlib source code is derived from FreeBSD code. - -* The libfdt source code is dual licensed. It is used by this project under - the terms of the BSD-2-Clause license. - - -This Release ------------- - -This release provides a suitable starting point for productization of secure -world boot and runtime firmware, executing in either the AArch32 or AArch64 -execution state. - -Users are encouraged to do their own security validation, including penetration -testing, on any secure world code derived from ARM Trusted Firmware. - -### Functionality - -* Initialization of the secure world (for example, exception vectors, control - registers, interrupt controller and interrupts for the platform), before - transitioning into the normal world at the Exception Level and Register - Width specified by the platform. - -* Library support for CPU specific reset and power down sequences. This - includes support for errata workarounds. - -* Drivers for both versions 2.0 and 3.0 of the ARM Generic Interrupt - Controller specifications (GICv2 and GICv3). The latter also enables GICv3 - hardware systems that do not contain legacy GICv2 support. - -* Drivers to enable standard initialization of ARM System IP, for example - Cache Coherent Interconnect (CCI), Cache Coherent Network (CCN), Network - Interconnect (NIC) and TrustZone Controller (TZC). - -* SMC (Secure Monitor Call) handling, conforming to the [SMC Calling - Convention][SMCCC] using an EL3 runtime services framework. - -* [PSCI] library support for the Secondary CPU Boot, CPU Hotplug, CPU Idle - and System Shutdown/Reset/Suspend use-cases. - This library is pre-integrated with the provided AArch64 EL3 Runtime - Software, and is also suitable for integration into other EL3 Runtime - Software. - -* A minimal AArch32 Secure Payload to demonstrate [PSCI] library integration - on platforms with AArch32 EL3 Runtime Software. - -* Secure Monitor library code such as world switching, EL1 context management - and interrupt routing. - When using the provided AArch64 EL3 Runtime Software, this must be - integrated with a Secure-EL1 Payload Dispatcher (SPD) component to - customize the interaction with a Secure-EL1 Payload (SP), for example a - Secure OS. - -* A Test Secure-EL1 Payload and Dispatcher to demonstrate AArch64 Secure - Monitor functionality and Secure-EL1 interaction with PSCI. - -* AArch64 SPDs for the [OP-TEE Secure OS] and [NVidia Trusted Little Kernel] - [NVidia TLK]. - -* A Trusted Board Boot implementation, conforming to all mandatory TBBR - requirements. This includes image authentication using certificates, a - Firmware Update (or recovery mode) boot flow, and packaging of the various - firmware images into a Firmware Image Package (FIP) to be loaded from - non-volatile storage. - The TBBR implementation is currently only supported in the AArch64 build. - -* Support for alternative boot flows. Some platforms have their own boot - firmware and only require the AArch64 EL3 Runtime Software provided by this - project. Other platforms require minimal initialization before booting - into an arbitrary EL3 payload. - -For a full description of functionality and implementation details, please -see the [Firmware Design] and supporting documentation. The [Change Log] -provides details of changes made since the last release. - -### Platforms - -The AArch64 build of this release has been tested on variants r0, r1 and r2 -of the [Juno ARM Development Platform] [Juno] with [Linaro Release 16.06]. - -The AArch64 build of this release has been tested on the following ARM -[FVP]s (64-bit host machine only, with [Linaro Release 16.06]): - -* `Foundation_Platform` (Version 10.1, Build 10.1.32) -* `FVP_Base_AEMv8A-AEMv8A` (Version 7.7, Build 0.8.7701) -* `FVP_Base_Cortex-A57x4-A53x4` (Version 7.7, Build 0.8.7701) -* `FVP_Base_Cortex-A57x1-A53x1` (Version 7.7, Build 0.8.7701) -* `FVP_Base_Cortex-A57x2-A53x4` (Version 7.7, Build 0.8.7701) - -The AArch32 build of this release has been tested on the following ARM -[FVP]s (64-bit host machine only, with [Linaro Release 16.06]): - -* `FVP_Base_AEMv8A-AEMv8A` (Version 7.7, Build 0.8.7701) -* `FVP_Base_Cortex-A32x4` (Version 10.1, Build 10.1.32) - -The Foundation FVP can be downloaded free of charge. The Base FVPs can be -licensed from ARM: see [www.arm.com/fvp] [FVP]. - -This release also contains the following platform support: - -* MediaTek MT6795 and MT8173 SoCs -* NVidia T210 and T132 SoCs -* QEMU emulator -* RockChip RK3368 and RK3399 SoCs -* Xilinx Zynq UltraScale + MPSoC - -### Still to Come - -* AArch32 TBBR support and ongoing TBBR alignment. - -* More platform support. - -* Ongoing support for new architectural features, CPUs and System IP. - -* Ongoing [PSCI] alignment and feature support. - -* Ongoing security hardening, optimization and quality improvements. - -For a full list of detailed issues in the current code, please see the [Change -Log] and the [GitHub issue tracker]. - - -Getting Started ---------------- - -Get the Trusted Firmware source code from -[GitHub](https://www.github.com/ARM-software/arm-trusted-firmware). - -See the [User Guide] for instructions on how to install, build and use -the Trusted Firmware with the ARM [FVP]s. - -See the [Firmware Design] for information on how the ARM Trusted Firmware works. - -See the [Porting Guide] as well for information about how to use this -software on another ARMv8-A platform. - -See the [Contributing Guidelines] for information on how to contribute to this -project and the [Acknowledgments] file for a list of contributors to the -project. - -### Feedback and support - -ARM welcomes any feedback on the Trusted Firmware. Please send feedback using -the [GitHub issue tracker]. - -ARM licensees may contact ARM directly via their partner managers. - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved._ - - -[License]: ./license.md "BSD license for ARM Trusted Firmware" -[Contributing Guidelines]: ./contributing.md "Guidelines for contributors" -[Acknowledgments]: ./acknowledgements.md "Contributor acknowledgments" -[Change Log]: ./docs/change-log.md -[User Guide]: ./docs/user-guide.md -[Firmware Design]: ./docs/firmware-design.md -[Porting Guide]: ./docs/porting-guide.md - -[ARMv8-A]: http://www.arm.com/products/processors/armv8-architecture.php "ARMv8-A Architecture" -[FVP]: http://www.arm.com/fvp "ARM's Fixed Virtual Platforms" -[Juno]: http://www.arm.com/products/tools/development-boards/versatile-express/juno-arm-development-platform.php "Juno ARM Development Platform" -[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)" -[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" -[TEE-SMC]: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php "Secure Monitor and TEEs" -[GitHub issue tracker]: https://github.com/ARM-software/tf-issues/issues -[OP-TEE Secure OS]: https://github.com/OP-TEE/optee_os -[NVidia TLK]: http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary -[Linaro Release 16.06]: https://community.arm.com/docs/DOC-10952#jive_content_id_Linaro_Release_1606