Merge "aarch32: Allow compiling with soft-float toolchain" into integration
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index c295176..1734d7e 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -420,7 +420,7 @@
 	mov	x0, #SMC_UNK
 	str	x0, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
 #if CTX_INCLUDE_PAUTH_REGS
-	bl	pauth_context_save
+	bl	pauth_context_restore
 #endif
 	b	restore_gp_registers_eret
 
diff --git a/docs/auth-framework.rst b/docs/auth-framework.rst
index 7e401b7..317ac18 100644
--- a/docs/auth-framework.rst
+++ b/docs/auth-framework.rst
@@ -606,13 +606,13 @@
         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];
+        const auth_method_desc_t *const img_auth_methods;
+        const auth_param_desc_t *const authenticated_data;
     } 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.
+A CoT is defined as an array of pointers to ``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.
 
 Implementation example
 ----------------------
@@ -625,15 +625,15 @@
 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 CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of
+an array of pointers to 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 TF-A and thus all
-CoTs must present:
+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 TF-A and thus
+all CoTs must present:
 
 -  ``BL2``
 -  ``SCP_BL2`` (platform specific)
@@ -674,13 +674,15 @@
    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.
+-  ``img_auth_methods``: this points to an array which 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. This pointer should not be
+   NULL.
    Supported methods are:
 
    -  ``AUTH_METHOD_HASH``: the hash of the image must match the hash extracted
@@ -700,11 +702,11 @@
       -  ``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.
+-  ``authenticated_data``: this array pointer 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. This pointer may be NULL.
 
 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
@@ -722,102 +724,130 @@
 
 .. code:: c
 
-    [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
-                }
+    static const auth_img_desc_t trusted_key_cert = {
+            .img_id = TRUSTED_KEY_CERT_ID,
+            .img_type = IMG_CERT,
+            .parent = NULL,
+            .img_auth_methods =  (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+                    [0] = {
+                            .type = AUTH_METHOD_SIG,
+                            .param.sig = {
+                                    .pk = &subject_pk,
+                                    .sig = &sig,
+                                    .alg = &sig_alg,
+                                    .data = &raw_data
+                            }
+                    },
+                    [1] = {
+                            .type = AUTH_METHOD_NV_CTR,
+                            .param.nv_ctr = {
+                                    .cert_nv_ctr = &trusted_nv_ctr,
+                                    .plat_nv_ctr = &trusted_nv_ctr
+                            }
+                    }
             },
-            [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 = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+                    [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
+                            }
+                    }
             }
-        },
-        .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,
-                }
+    };
+    static const auth_img_desc_t soc_fw_key_cert = {
+            .img_id = SOC_FW_KEY_CERT_ID,
+            .img_type = IMG_CERT,
+            .parent = &trusted_key_cert,
+            .img_auth_methods =  (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+                    [0] = {
+                            .type = AUTH_METHOD_SIG,
+                            .param.sig = {
+                                    .pk = &trusted_world_pk,
+                                    .sig = &sig,
+                                    .alg = &sig_alg,
+                                    .data = &raw_data
+                            }
+                    },
+                    [1] = {
+                            .type = AUTH_METHOD_NV_CTR,
+                            .param.nv_ctr = {
+                                    .cert_nv_ctr = &trusted_nv_ctr,
+                                    .plat_nv_ctr = &trusted_nv_ctr
+                            }
+                    }
+            },
+            .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+                    [0] = {
+                            .type_desc = &soc_fw_content_pk,
+                            .data = {
+                                    .ptr = (void *)content_pk_buf,
+                                    .len = (unsigned int)PK_DER_LEN
+                            }
+                    }
             }
-        },
-        .authenticated_data = {
-            [0] = {
-                .type_desc = &soc_fw_hash,
-                .data = {
-                    .ptr = (void *)soc_fw_hash_buf,
-                    .len = (unsigned int)HASH_DER_LEN
-                }
+    };
+    static const auth_img_desc_t soc_fw_content_cert = {
+            .img_id = SOC_FW_CONTENT_CERT_ID,
+            .img_type = IMG_CERT,
+            .parent = &soc_fw_key_cert,
+            .img_auth_methods =  (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+                    [0] = {
+                            .type = AUTH_METHOD_SIG,
+                            .param.sig = {
+                                    .pk = &soc_fw_content_pk,
+                                    .sig = &sig,
+                                    .alg = &sig_alg,
+                                    .data = &raw_data
+                            }
+                    },
+                    [1] = {
+                            .type = AUTH_METHOD_NV_CTR,
+                            .param.nv_ctr = {
+                                    .cert_nv_ctr = &trusted_nv_ctr,
+                                    .plat_nv_ctr = &trusted_nv_ctr
+                            }
+                    }
+            },
+            .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+                    [0] = {
+                            .type_desc = &soc_fw_hash,
+                            .data = {
+                                    .ptr = (void *)soc_fw_hash_buf,
+                                    .len = (unsigned int)HASH_DER_LEN
+                            }
+                    },
+                    [1] = {
+                            .type_desc = &soc_fw_config_hash,
+                            .data = {
+                                    .ptr = (void *)soc_fw_config_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,
-                }
+    };
+    static const auth_img_desc_t bl31_image = {
+            .img_id = BL31_IMAGE_ID,
+            .img_type = IMG_RAW,
+            .parent = &soc_fw_content_cert,
+            .img_auth_methods =  (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+                    [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
@@ -935,7 +965,7 @@
 
 --------------
 
-*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
 
 .. _Trusted Board Boot: ./trusted-board-boot.rst
 .. _Platform Porting Guide: ./porting-guide.rst
diff --git a/docs/change-log.rst b/docs/change-log.rst
index d652ff6..1aca22b 100644
--- a/docs/change-log.rst
+++ b/docs/change-log.rst
@@ -1,14 +1,16 @@
+Trusted Firmware-A Release Notes
+================================
 
-.. section-numbering::
-    :suffix: .
+This document contains a summary of the new features, changes, fixes and known
+issues in each release of Trusted Firmware-A.
 
 .. contents::
 
-Trusted Firmware-A - version 2.1
-================================
+Version 2.1
+-----------
 
 New Features
-------------
+^^^^^^^^^^^^
 
 - Architecture
    - Support for ARMv8.3 pointer authentication in the normal and secure worlds
@@ -198,7 +200,7 @@
 
 
 Changed
--------
+^^^^^^^
 
 - Build System
    - Warning levels are now selectable with ``W=<1,2,3>``
@@ -311,7 +313,7 @@
 
 
 Resolved Issues
----------------
+^^^^^^^^^^^^^^^
 
 - Architecture
    - Incorrect check for SSBS feature detection
@@ -401,7 +403,7 @@
 
 
 Deprecations
-------------
+^^^^^^^^^^^^
 
 - Common Code
    - ``plat_crash_console_init`` function
@@ -424,7 +426,7 @@
 
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 - Build System Issues
    - dtb: DTB creation not supported when building on a Windows host.
@@ -448,11 +450,11 @@
 
    - mediatek/mt6795: This platform does not build in this release
 
-Trusted Firmware-A - version 2.0
-================================
+Version 2.0
+-----------
 
 New Features
-------------
+^^^^^^^^^^^^
 
 -  Removal of a number of deprecated APIs
 
@@ -469,12 +471,12 @@
    -  This release is otherwise unchanged from 1.6 release
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  No issues known at 1.6 release resolved in 2.0 release
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 -  DTB creation not supported when building on a Windows host. This step in the
    build process is skipped when running on a Windows host. Known issue from
@@ -487,11 +489,11 @@
    confirmed to be working after the removal of the deprecated interfaces
    although they do build.
 
-Trusted Firmware-A - version 1.6
-================================
+Version 1.6
+-----------
 
 New Features
-------------
+^^^^^^^^^^^^
 
 -  Addressing Speculation Security Vulnerabilities
 
@@ -760,22 +762,22 @@
    -  STMicroelectronics STM32MP1 Platform
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  No issues known at 1.5 release resolved in 1.6 release
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 -  DTB creation not supported when building on a Windows host. This step in the
    build process is skipped when running on a Windows host. Known issue from
    1.5 version.
 
-Trusted Firmware-A - version 1.5
-================================
+Version 1.5
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Added new firmware support to enable RAS (Reliability, Availability, and
    Serviceability) functionality.
@@ -1044,7 +1046,7 @@
       facilitate transfer by DMA.
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  TF-A can be built with optimisations disabled (-O0).
 
@@ -1052,16 +1054,16 @@
    running TF-A in AArch32 execution mode (resolving `tf-issue#501`_).
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 -  DTB creation not supported when building on a Windows host. This step in the
    build process is skipped when running on a Windows host.
 
-Trusted Firmware-A - version 1.4
-================================
+Version 1.4
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Enabled support for platforms with hardware assisted coherency.
 
@@ -1318,7 +1320,7 @@
    pre-empted SMC during PSCI power management requests.
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  TF-A can be built with the latest mbed TLS version (v2.4.2). The earlier
    version 2.3.0 cannot be used due to build warnings that the TF-A build
@@ -1332,7 +1334,7 @@
    shutdown request using the PSCI SYSTEM_OFF API.
 
 Known Issues
-------------
+^^^^^^^^^^^^
 
 -  Building TF-A with compiler optimisations disabled (-O0) fails.
 
@@ -1346,12 +1348,12 @@
    platform, please use GCC compiler version of at least 5.0. See `PR#1002`_ for
    more details.
 
-Trusted Firmware-A - version 1.3
-================================
+Version 1.3
+-----------
 
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Added support for running TF-A in AArch32 execution state.
 
@@ -1552,10 +1554,10 @@
       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
@@ -1569,11 +1571,11 @@
 
 -  TBBR is not currently supported when running TF-A in AArch32 state.
 
-Trusted Firmware-A - version 1.2
-================================
+Version 1.2
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  The Trusted Board Boot implementation on Arm platforms now conforms to the
    mandatory requirements of the TBBR specification.
@@ -1690,7 +1692,7 @@
    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.
@@ -1705,7 +1707,7 @@
 -  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
@@ -1721,11 +1723,11 @@
 
 -  Building TF-A with compiler optimisations disabled (``-O0``) fails.
 
-Trusted Firmware-A - version 1.1
-================================
+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
@@ -1828,7 +1830,7 @@
    added. Details of using it with TF-A can be found in `OP-TEE Dispatcher`_
 
 Issues resolved since last release
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 -  The Juno port has been aligned with the FVP port as follows.
 
@@ -1855,7 +1857,7 @@
    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
@@ -1883,11 +1885,11 @@
 
 -  The Juno-specific firmware design documentation is incomplete.
 
-Trusted Firmware-A - version 1.0
-================================
+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.
@@ -2009,7 +2011,7 @@
    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
@@ -2023,7 +2025,7 @@
    resolved. This TF-A 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
@@ -2063,11 +2065,11 @@
 
    A similar change can be made to the other Cortex-A57-A53 Base FVP variants.
 
-Trusted Firmware-A - version 0.4
-================================
+Version 0.4
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Makefile improvements:
 
@@ -2145,7 +2147,7 @@
    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**).
@@ -2164,7 +2166,7 @@
    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
@@ -2193,11 +2195,11 @@
 -  The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
    its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
 
-Trusted Firmware-A - version 0.3
-================================
+Version 0.3
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  Support for Foundation FVP Version 2.0 added.
    The documented UEFI configuration disables some devices that are unavailable
@@ -2274,7 +2276,7 @@
    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.
@@ -2299,7 +2301,7 @@
    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 TF-A.
@@ -2347,11 +2349,11 @@
 -  The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
    its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
 
-Trusted Firmware-A - version 0.2
-================================
+Version 0.2
+-----------
 
 New features
-------------
+^^^^^^^^^^^^
 
 -  First source release.
 
@@ -2359,13 +2361,13 @@
    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 TF-A.
@@ -2427,5 +2429,3 @@
 .. _OP-TEE Dispatcher: optee-dispatcher.rst
 .. _tf-issue#501: https://github.com/ARM-software/tf-issues/issues/501
 .. _PR#1002: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193
-.. _mbed TLS releases: https://tls.mbed.org/tech-updates/releases
-.. _Firmware Design: firmware-design.rst
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 769ad45..fe8ce5f 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -1669,6 +1669,8 @@
 -  ``FVP_Base_Cortex-A73x4``
 -  ``FVP_Base_Cortex-A75x4``
 -  ``FVP_Base_Cortex-A76x4``
+-  ``FVP_Base_Cortex-A76AEx4`` (Tested with internal model)
+-  ``FVP_Base_Cortex-A76AEx8`` (Tested with internal model)
 -  ``FVP_Base_Neoverse-N1x4`` (Tested with internal model)
 -  ``FVP_Base_Deimos``
 -  ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 97e1220..01f8f29 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -30,6 +30,10 @@
 
 #pragma weak plat_set_nv_ctr2
 
+/* Pointer to CoT */
+extern const auth_img_desc_t **const cot_desc_ptr;
+extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
+
 static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
 		const auth_param_type_desc_t *b)
 {
@@ -49,6 +53,9 @@
 {
 	int i;
 
+	if (img_desc->authenticated_data == NULL)
+		return 1;
+
 	for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) {
 		if (0 == cmp_auth_param_type_desc(param_type_desc,
 				img_desc->authenticated_data[i].type_desc)) {
@@ -300,7 +307,7 @@
 	assert(parent_id != NULL);
 
 	/* Get the image descriptor */
-	img_desc = &cot_desc_ptr[img_id];
+	img_desc = cot_desc_ptr[img_id];
 
 	/* Check if the image has no parent (ROT) */
 	if (img_desc->parent == NULL) {
@@ -349,7 +356,7 @@
 	int rc, i;
 
 	/* Get the image descriptor from the chain of trust */
-	img_desc = &cot_desc_ptr[img_id];
+	img_desc = cot_desc_ptr[img_id];
 
 	/* Ask the parser to check the image integrity */
 	rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len);
@@ -357,6 +364,8 @@
 
 	/* Authenticate the image using the methods indicated in the image
 	 * descriptor. */
+	if (img_desc->img_auth_methods == NULL)
+		return 1;
 	for (i = 0 ; i < AUTH_METHOD_NUM ; i++) {
 		auth_method = &img_desc->img_auth_methods[i];
 		switch (auth_method->type) {
@@ -385,25 +394,27 @@
 
 	/* Extract the parameters indicated in the image descriptor to
 	 * authenticate the children images. */
-	for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) {
-		if (img_desc->authenticated_data[i].type_desc == NULL) {
-			continue;
-		}
+	if (img_desc->authenticated_data != NULL) {
+		for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) {
+			if (img_desc->authenticated_data[i].type_desc == NULL) {
+				continue;
+			}
 
-		/* Get the parameter from the image parser module */
-		rc = img_parser_get_auth_param(img_desc->img_type,
-				img_desc->authenticated_data[i].type_desc,
-				img_ptr, img_len, &param_ptr, &param_len);
-		return_if_error(rc);
+			/* Get the parameter from the image parser module */
+			rc = img_parser_get_auth_param(img_desc->img_type,
+					img_desc->authenticated_data[i].type_desc,
+					img_ptr, img_len, &param_ptr, &param_len);
+			return_if_error(rc);
 
-		/* Check parameter size */
-		if (param_len > img_desc->authenticated_data[i].data.len) {
-			return 1;
-		}
+			/* Check parameter size */
+			if (param_len > img_desc->authenticated_data[i].data.len) {
+				return 1;
+			}
 
-		/* Copy the parameter for later use */
-		memcpy((void *)img_desc->authenticated_data[i].data.ptr,
-				(void *)param_ptr, param_len);
+			/* Copy the parameter for later use */
+			memcpy((void *)img_desc->authenticated_data[i].data.ptr,
+					(void *)param_ptr, param_len);
+		}
 	}
 
 	/* Mark image as authenticated */
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c
index ec14a18..da3631b 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,29 +27,31 @@
  * extracted from the certificates. In this case, because of the way the CoT is
  * established, we can reuse some of the buffers on different stages
  */
+
 static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
 static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char hw_config_hash_buf[HASH_DER_LEN];
 static unsigned char scp_fw_hash_buf[HASH_DER_LEN];
+static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
+
+#ifdef IMAGE_BL2
 static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN];
-static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
 static unsigned char trusted_world_pk_buf[PK_DER_LEN];
 static unsigned char non_trusted_world_pk_buf[PK_DER_LEN];
 static unsigned char content_pk_buf[PK_DER_LEN];
 static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
+#endif
 
 /*
  * Parameter type descriptors
  */
 static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
-static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
 
 static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, 0);
@@ -60,11 +62,29 @@
 static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_RAW_DATA, 0);
 
+
+static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
+static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
+#ifdef IMAGE_BL1
+static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, FWU_HASH_OID);
+#endif /* IMAGE_BL1 */
+
+#ifdef IMAGE_BL2
+static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
 static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
 static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID);
-
 static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID);
 static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC(
@@ -73,13 +93,6 @@
 		AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID);
 static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID);
-
-static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
-static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
 static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, SCP_FW_HASH_OID);
 static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
@@ -98,678 +111,716 @@
 		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
 static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, FWU_HASH_OID);
 
-/*
- * TBBR Chain of trust definition
- */
-static const auth_img_desc_t cot_desc[] = {
+#endif /* IMAGE_BL2 */
+
+
 	/*
 	 * BL2
 	 */
-	[TRUSTED_BOOT_FW_CERT_ID] = {
-		.img_id = TRUSTED_BOOT_FW_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,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+static const auth_img_desc_t trusted_boot_fw_cert = {
+	.img_id = TRUSTED_BOOT_FW_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &tb_fw_hash,
-				.data = {
-					.ptr = (void *)tb_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &tb_fw_config_hash,
-				.data = {
-					.ptr = (void *)tb_fw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[2] = {
-				.type_desc = &hw_config_hash,
-				.data = {
-					.ptr = (void *)hw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[BL2_IMAGE_ID] = {
-		.img_id = BL2_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_BOOT_FW_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tb_fw_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tb_fw_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tb_fw_config_hash,
+			.data = {
+				.ptr = (void *)tb_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &hw_config_hash,
+			.data = {
+				.ptr = (void *)hw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	/* HW Config */
-	[HW_CONFIG_ID] = {
-		.img_id = HW_CONFIG_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_BOOT_FW_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &hw_config_hash,
-				}
+	}
+	};
+#ifdef IMAGE_BL1
+static const auth_img_desc_t bl2_image = {
+	.img_id = BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_hash
 			}
 		}
-	},
-	/* TB FW Config */
-	[TB_FW_CONFIG_ID] = {
-		.img_id = TB_FW_CONFIG_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_BOOT_FW_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tb_fw_config_hash,
-				}
+	}
+};
+#endif /* IMAGE_BL1 */
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
 			}
 		}
-	},
-	/*
-	 * Trusted key certificate
-	 */
-	[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,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	}
+};
+/* TB FW Config */
+#ifdef IMAGE_BL1
+static const auth_img_desc_t tb_fw_config = {
+	.img_id = TB_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_config_hash
+			}
+		}
+	}
+};
+#endif /* IMAGE_BL1 */
+#ifdef IMAGE_BL2
+/*
+ * Trusted key certificate
+ */
+static const auth_img_desc_t trusted_key_cert = {
+	.img_id = TRUSTED_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[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
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	/*
-	 * SCP Firmware
-	 */
-	[SCP_FW_KEY_CERT_ID] = {
-		.img_id = SCP_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,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &trusted_world_pk,
+			.data = {
+				.ptr = (void *)trusted_world_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &scp_fw_content_pk,
-				.data = {
-					.ptr = (void *)content_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
 			}
 		}
-	},
-	[SCP_FW_CONTENT_CERT_ID] = {
-		.img_id = SCP_FW_CONTENT_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[SCP_FW_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &scp_fw_content_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	}
+};
+/*
+ * SCP Firmware
+ */
+static const auth_img_desc_t scp_fw_key_cert = {
+	.img_id = SCP_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &scp_fw_hash,
-				.data = {
-					.ptr = (void *)scp_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[SCP_BL2_IMAGE_ID] = {
-		.img_id = SCP_BL2_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[SCP_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &scp_fw_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
 			}
 		}
-	},
-	/*
-	 * SoC Firmware
-	 */
-	[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,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	}
+};
+static const auth_img_desc_t scp_fw_content_cert = {
+	.img_id = SCP_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &scp_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &scp_fw_content_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
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[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,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_fw_hash,
+			.data = {
+				.ptr = (void *)scp_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t scp_bl2_image = {
+	.img_id = SCP_BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &scp_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &scp_fw_hash
+			}
+		}
+	}
+};
+/*
+ * SoC Firmware
+ */
+static const auth_img_desc_t soc_fw_key_cert = {
+	.img_id = SOC_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[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_hash,
-				.data = {
-					.ptr = (void *)soc_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &soc_fw_config_hash,
-				.data = {
-					.ptr = (void *)soc_fw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[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,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &soc_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
 			}
 		}
-	},
-	/* SOC FW Config */
-	[SOC_FW_CONFIG_ID] = {
-		.img_id = SOC_FW_CONFIG_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_config_hash,
-				}
+	}
+};
+static const auth_img_desc_t soc_fw_content_cert = {
+	.img_id = SOC_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &soc_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &soc_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	/*
-	 * Trusted OS Firmware
-	 */
-	[TRUSTED_OS_FW_KEY_CERT_ID] = {
-		.img_id = TRUSTED_OS_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,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &soc_fw_hash,
+			.data = {
+				.ptr = (void *)soc_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &tos_fw_content_pk,
-				.data = {
-					.ptr = (void *)content_pk_buf,
-					.len = (unsigned int)PK_DER_LEN
-				}
+		[1] = {
+			.type_desc = &soc_fw_config_hash,
+			.data = {
+				.ptr = (void *)soc_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
-		.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[TRUSTED_OS_FW_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &tos_fw_content_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &trusted_nv_ctr,
-					.plat_nv_ctr = &trusted_nv_ctr
-				}
+	}
+};
+static const auth_img_desc_t bl31_image = {
+	.img_id = BL31_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &soc_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &soc_fw_hash
+			}
+		}
+	}
+};
+/* SOC FW Config */
+static const auth_img_desc_t soc_fw_config = {
+	.img_id = SOC_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &soc_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &soc_fw_config_hash
+			}
+		}
+	}
+};
+/*
+ * Trusted OS Firmware
+ */
+static const auth_img_desc_t trusted_os_fw_key_cert = {
+	.img_id = TRUSTED_OS_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &tos_fw_hash,
-				.data = {
-					.ptr = (void *)tos_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &tos_fw_extra1_hash,
-				.data = {
-					.ptr = (void *)tos_fw_extra1_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[2] = {
-				.type_desc = &tos_fw_extra2_hash,
-				.data = {
-					.ptr = (void *)tos_fw_extra2_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[3] = {
-				.type_desc = &tos_fw_config_hash,
-				.data = {
-					.ptr = (void *)tos_fw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[BL32_IMAGE_ID] = {
-		.img_id = BL32_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_OS_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tos_fw_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tos_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
 			}
 		}
-	},
-	[BL32_EXTRA1_IMAGE_ID] = {
-		.img_id = BL32_EXTRA1_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_OS_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tos_fw_extra1_hash,
-				}
+	}
+};
+static const auth_img_desc_t trusted_os_fw_content_cert = {
+	.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_os_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &tos_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
 			}
 		}
 	},
-	[BL32_EXTRA2_IMAGE_ID] = {
-		.img_id = BL32_EXTRA2_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_OS_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tos_fw_extra2_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tos_fw_hash,
+			.data = {
+				.ptr = (void *)tos_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tos_fw_extra1_hash,
+			.data = {
+				.ptr = (void *)tos_fw_extra1_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &tos_fw_extra2_hash,
+			.data = {
+				.ptr = (void *)tos_fw_extra2_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[3] = {
+			.type_desc = &tos_fw_config_hash,
+			.data = {
+				.ptr = (void *)tos_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	/* TOS FW Config */
-	[TOS_FW_CONFIG_ID] = {
-		.img_id = TOS_FW_CONFIG_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[TRUSTED_OS_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &tos_fw_config_hash,
-				}
+	}
+};
+static const auth_img_desc_t bl32_image = {
+	.img_id = BL32_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_hash
 			}
 		}
-	},
-	/*
-	 * Non-Trusted Firmware
-	 */
-	[NON_TRUSTED_FW_KEY_CERT_ID] = {
-		.img_id = NON_TRUSTED_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 = &non_trusted_world_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &non_trusted_nv_ctr,
-					.plat_nv_ctr = &non_trusted_nv_ctr
-				}
+	}
+};
+static const auth_img_desc_t bl32_extra1_image = {
+	.img_id = BL32_EXTRA1_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_extra1_hash
+			}
+		}
+	}
+};
+static const auth_img_desc_t bl32_extra2_image = {
+	.img_id = BL32_EXTRA2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_extra2_hash
+			}
+		}
+	}
+};
+/* TOS FW Config */
+static const auth_img_desc_t tos_fw_config = {
+	.img_id = TOS_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_os_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tos_fw_config_hash
+			}
+		}
+	}
+};
+/*
+ * Non-Trusted Firmware
+ */
+static const auth_img_desc_t non_trusted_fw_key_cert = {
+	.img_id = NON_TRUSTED_FW_KEY_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &non_trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &nt_fw_content_pk,
-				.data = {
-					.ptr = (void *)content_pk_buf,
-					.len = (unsigned int)PK_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
 			}
 		}
 	},
-	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
-		.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
-		.img_type = IMG_CERT,
-		.parent = &cot_desc[NON_TRUSTED_FW_KEY_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_SIG,
-				.param.sig = {
-					.pk = &nt_fw_content_pk,
-					.sig = &sig,
-					.alg = &sig_alg,
-					.data = &raw_data,
-				}
-			},
-			[1] = {
-				.type = AUTH_METHOD_NV_CTR,
-				.param.nv_ctr = {
-					.cert_nv_ctr = &non_trusted_nv_ctr,
-					.plat_nv_ctr = &non_trusted_nv_ctr
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &nt_fw_content_pk,
+			.data = {
+				.ptr = (void *)content_pk_buf,
+				.len = (unsigned int)PK_DER_LEN
+			}
+		}
+	}
+};
+static const auth_img_desc_t non_trusted_fw_content_cert = {
+	.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &non_trusted_fw_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &nt_fw_content_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &nt_world_bl_hash,
-				.data = {
-					.ptr = (void *)nt_world_bl_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &nt_fw_config_hash,
-				.data = {
-					.ptr = (void *)nt_fw_config_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &non_trusted_nv_ctr,
+				.plat_nv_ctr = &non_trusted_nv_ctr
 			}
 		}
 	},
-	[BL33_IMAGE_ID] = {
-		.img_id = BL33_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[NON_TRUSTED_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &nt_world_bl_hash,
-				}
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &nt_world_bl_hash,
+			.data = {
+				.ptr = (void *)nt_world_bl_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &nt_fw_config_hash,
+			.data = {
+				.ptr = (void *)nt_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	/* NT FW Config */
-	[NT_FW_CONFIG_ID] = {
-		.img_id = NT_FW_CONFIG_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[NON_TRUSTED_FW_CONTENT_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &nt_fw_config_hash,
-				}
+	}
+};
+static const auth_img_desc_t bl33_image = {
+	.img_id = BL33_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &non_trusted_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &nt_world_bl_hash
 			}
 		}
+	}
+};
+/* NT FW Config */
+static const auth_img_desc_t nt_fw_config = {
+	.img_id = NT_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &non_trusted_fw_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &nt_fw_config_hash
+			}
+		}
+	}
+};
+#else  /* IMAGE_BL2 */
+/*
+ * FWU auth descriptor.
+ */
+static const auth_img_desc_t fwu_cert = {
+	.img_id = FWU_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		}
 	},
-	/*
-	 * FWU auth descriptor.
-	 */
-	[FWU_CERT_ID] = {
-		.img_id = FWU_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 = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_bl2u_hash,
+			.data = {
+				.ptr = (void *)scp_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		},
-		.authenticated_data = {
-			[0] = {
-				.type_desc = &scp_bl2u_hash,
-				.data = {
-					.ptr = (void *)scp_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[1] = {
-				.type_desc = &bl2u_hash,
-				.data = {
-					.ptr = (void *)tb_fw_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
-			},
-			[2] = {
-				.type_desc = &ns_bl2u_hash,
-				.data = {
-					.ptr = (void *)nt_world_bl_hash_buf,
-					.len = (unsigned int)HASH_DER_LEN
-				}
+		[1] = {
+			.type_desc = &bl2u_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &ns_bl2u_hash,
+			.data = {
+				.ptr = (void *)nt_world_bl_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
 			}
 		}
-	},
-	/*
-	 * SCP_BL2U
-	 */
-	[SCP_BL2U_IMAGE_ID] = {
-		.img_id = SCP_BL2U_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[FWU_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &scp_bl2u_hash,
-				}
+	}
+};
+/*
+ * SCP_BL2U
+ */
+static const auth_img_desc_t scp_bl2u_image = {
+	.img_id = SCP_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &scp_bl2u_hash
 			}
 		}
-	},
-	/*
-	 * BL2U
-	 */
-	[BL2U_IMAGE_ID] = {
-		.img_id = BL2U_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[FWU_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &bl2u_hash,
-				}
+	}
+};
+/*
+ * BL2U
+ */
+static const auth_img_desc_t bl2u_image = {
+	.img_id = BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &bl2u_hash
 			}
 		}
-	},
-	/*
-	 * NS_BL2U
-	 */
-	[NS_BL2U_IMAGE_ID] = {
-		.img_id = NS_BL2U_IMAGE_ID,
-		.img_type = IMG_RAW,
-		.parent = &cot_desc[FWU_CERT_ID],
-		.img_auth_methods = {
-			[0] = {
-				.type = AUTH_METHOD_HASH,
-				.param.hash = {
-					.data = &raw_data,
-					.hash = &ns_bl2u_hash,
+	}
+};
+/*
+ * NS_BL2U
+ */
+static const auth_img_desc_t ns_bl2u_image = {
+	.img_id = NS_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &ns_bl2u_hash
 				}
 			}
 		}
-	}
+	};
+#endif /* IMAGE_BL2 */
+/*
+ * TBBR Chain of trust definition
+ */
+
+#ifdef IMAGE_BL1
+static const auth_img_desc_t * const cot_desc[] = {
+	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
+	[BL2_IMAGE_ID]				=	&bl2_image,
+	[HW_CONFIG_ID]				=	&hw_config,
+	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
+	[FWU_CERT_ID]				=	&fwu_cert,
+	[SCP_BL2U_IMAGE_ID]			=	&scp_bl2u_image,
+	[BL2U_IMAGE_ID]				=	&bl2u_image,
+	[NS_BL2U_IMAGE_ID]			=	&ns_bl2u_image
+};
+#else /* IMAGE_BL2 */
+static const auth_img_desc_t * const cot_desc[] = {
+	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
+	[HW_CONFIG_ID]				=	&hw_config,
+	[TRUSTED_KEY_CERT_ID]			=	&trusted_key_cert,
+	[SCP_FW_KEY_CERT_ID]			=	&scp_fw_key_cert,
+	[SCP_FW_CONTENT_CERT_ID]		=	&scp_fw_content_cert,
+	[SCP_BL2_IMAGE_ID]			=	&scp_bl2_image,
+	[SOC_FW_KEY_CERT_ID]			=	&soc_fw_key_cert,
+	[SOC_FW_CONTENT_CERT_ID]		=	&soc_fw_content_cert,
+	[BL31_IMAGE_ID]				=	&bl31_image,
+	[SOC_FW_CONFIG_ID]			=	&soc_fw_config,
+	[TRUSTED_OS_FW_KEY_CERT_ID]		=	&trusted_os_fw_key_cert,
+	[TRUSTED_OS_FW_CONTENT_CERT_ID]		=	&trusted_os_fw_content_cert,
+	[BL32_IMAGE_ID]				=	&bl32_image,
+	[BL32_EXTRA1_IMAGE_ID]			=	&bl32_extra1_image,
+	[BL32_EXTRA2_IMAGE_ID]			=	&bl32_extra2_image,
+	[TOS_FW_CONFIG_ID]			=	&tos_fw_config,
+	[NON_TRUSTED_FW_KEY_CERT_ID]		=	&non_trusted_fw_key_cert,
+	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
+	[BL33_IMAGE_ID]				=	&bl33_image,
+	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
 };
+#endif
 
 /* Register the CoT in the authentication module */
 REGISTER_COT(cot_desc);
diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h
index 9089953..39f5372 100644
--- a/include/drivers/auth/auth_mod.h
+++ b/include/drivers/auth/auth_mod.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,8 +27,8 @@
 	unsigned int img_id;
 	img_type_t img_type;
 	const struct auth_img_desc_s *parent;
-	auth_method_desc_t img_auth_methods[AUTH_METHOD_NUM];
-	auth_param_desc_t authenticated_data[COT_MAX_VERIFIED_PARAMS];
+	const auth_method_desc_t *const img_auth_methods;
+	const auth_param_desc_t *const authenticated_data;
 } auth_img_desc_t;
 
 /* Public functions */
@@ -38,13 +38,13 @@
 			void *img_ptr,
 			unsigned int img_len);
 
-/* Macro to register a CoT defined as an array of auth_img_desc_t */
+/* Macro to register a CoT defined as an array of auth_img_desc_t pointers */
 #define REGISTER_COT(_cot) \
-	const auth_img_desc_t *const cot_desc_ptr = \
-			(const auth_img_desc_t *const)&_cot[0]; \
+	const auth_img_desc_t **const cot_desc_ptr = \
+			(const auth_img_desc_t **const)_cot; \
 	unsigned int auth_img_flags[MAX_NUMBER_IDS]
 
-extern const auth_img_desc_t *const cot_desc_ptr;
+extern const auth_img_desc_t **const cot_desc_ptr;
 extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
 
 #endif /* TRUSTED_BOARD_BOOT */
diff --git a/include/lib/cpus/aarch32/cortex_a12.h b/include/lib/cpus/aarch32/cortex_a12.h
index 8f6e7b8..abacdba 100644
--- a/include/lib/cpus/aarch32/cortex_a12.h
+++ b/include/lib/cpus/aarch32/cortex_a12.h
@@ -12,7 +12,7 @@
 /*******************************************************************************
  * Cortex-A12 midr with version/revision set to 0
  ******************************************************************************/
-#define CORTEX_A12_MIDR			U(0x410FC0C0)
+#define CORTEX_A12_MIDR			U(0x410FC0D0)
 
 /*******************************************************************************
  * CPU Auxiliary Control register specific definitions.
diff --git a/include/lib/cpus/aarch64/cortex_a76ae.h b/include/lib/cpus/aarch64/cortex_a76ae.h
new file mode 100644
index 0000000..9e34efb
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a76ae.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A76AE_H
+#define CORTEX_A76AE_H
+
+#include <lib/utils_def.h>
+
+/* Cortex-A76AE MIDR for revision 0 */
+#define CORTEX_A76AE_MIDR		U(0x410FD0E0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A76AE_CPUPWRCTLR_EL1	S3_0_C15_C2_7
+
+/* Definitions of register field mask in CORTEX_A76AE_CPUPWRCTLR_EL1 */
+#define CORTEX_A76AE_CORE_PWRDN_EN_MASK	U(0x1)
+
+#define CORTEX_A76AE_CPUECTLR_EL1	S3_0_C15_C1_4
+
+#endif /* CORTEX_A76AE_H */
diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S
new file mode 100644
index 0000000..1ba8e9a
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a76ae.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <cortex_a76ae.h>
+#include <cpu_macros.S>
+
+	/* ---------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ---------------------------------------------
+	 */
+func cortex_a76ae_core_pwr_dwn
+	/* ---------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------
+	 */
+	mrs	x0, CORTEX_A76AE_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_A76AE_CORE_PWRDN_EN_MASK
+	msr	CORTEX_A76AE_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_a76ae_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex-A76AE. Must follow AAPCS.
+ */
+func cortex_a76ae_errata_report
+	ret
+endfunc cortex_a76ae_errata_report
+#endif	/* REPORT_ERRATA */
+
+	/* ---------------------------------------------
+	 * This function provides cortex_a76ae specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a76ae_regs, "aS"
+cortex_a76ae_regs:  /* The ASCII list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a76ae_cpu_reg_dump
+	adr	x6, cortex_a76ae_regs
+	mrs	x8, CORTEX_A76AE_CPUECTLR_EL1
+	ret
+endfunc cortex_a76ae_cpu_reg_dump
+
+declare_cpu_ops cortex_a76ae, CORTEX_A76AE_MIDR, CPU_NO_RESET_FUNC, \
+	cortex_a76ae_core_pwr_dwn
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 61a3734..1a63e87 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -103,6 +103,7 @@
 				lib/cpus/aarch64/cortex_a73.S			\
 				lib/cpus/aarch64/cortex_a75.S			\
 				lib/cpus/aarch64/cortex_a76.S			\
+				lib/cpus/aarch64/cortex_a76ae.S			\
 				lib/cpus/aarch64/neoverse_n1.S			\
 				lib/cpus/aarch64/cortex_deimos.S		\
 				lib/cpus/aarch64/neoverse_zeus.S
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index d50af20..d87624e 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -28,7 +28,6 @@
 				lib/xlat_tables/aarch64/xlat_tables.c		\
 				lib/xlat_tables/xlat_tables_common.c		\
 				lib/cpus/aarch64/cortex_a53.S			\
-				drivers/console/aarch64/console.S		\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 7004c56..89c2da0 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -28,7 +28,6 @@
 				lib/xlat_tables/aarch64/xlat_tables.c		\
 				lib/xlat_tables/xlat_tables_common.c		\
 				lib/cpus/aarch64/cortex_a53.S			\
-				drivers/console/aarch64/console.S		\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
diff --git a/readme.rst b/readme.rst
index 849bbb3..d7260d7 100644
--- a/readme.rst
+++ b/readme.rst
@@ -185,6 +185,8 @@
 -  ``FVP_Base_Cortex-A73x4``
 -  ``FVP_Base_Cortex-A75x4``
 -  ``FVP_Base_Cortex-A76x4``
+-  ``FVP_Base_Cortex-A76AEx4`` (Tested with internal model)
+-  ``FVP_Base_Cortex-A76AEx8`` (Tested with internal model)
 -  ``FVP_Base_Neoverse-N1x4`` (Tested with internal model)
 -  ``FVP_Base_Deimos``
 -  ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index aa7bd04..3a63f1c 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -104,7 +104,7 @@
 		     rdsvc = rdsvc->next) {
 			uint32_t *rd_uuid = (uint32_t *)(rdsvc->uuid);
 
-			if (memcmp(rd_uuid, svc_uuid, sizeof(rd_uuid)) == 0) {
+			if (memcmp(rd_uuid, svc_uuid, sizeof(*svc_uuid)) == 0) {
 				return sp_ctx;
 			}
 		}