Merge pull request #601 from sandrine-bailleux-arm/sb/a57-errata-workarounds

Cortex-A57 errata workarounds
diff --git a/docs/user-guide.md b/docs/user-guide.md
index e5e28a3..03310c3 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -8,27 +8,40 @@
 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 the rest of the software stack](#6--building-the-rest-of-the-software-stack)
+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.  [Preparing the images to run on FVP](#9--preparing-the-images-to-run-on-fvp)
-10. [Running the software on FVP](#10--running-the-software-on-fvp)
-11. [Running the software on Juno](#11--running-the-software-on-juno)
-12. [Changes required for booting Linux on FVP in GICv3 mode](#12--changes-required-for-booting-linux-on-fvp-in-gicv3-mode)
+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 and run it with a
+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 should be used in conjunction with the [Firmware Design] and the
-[Instructions for using the Linaro software deliverables][Linaro SW Instructions].
+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
+
+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
 -----------------------------
@@ -48,53 +61,28 @@
 3.  Tools
 ---------
 
-In addition to the mandatory prerequisite tools listed in the [instructions for
-using the Linaro software deliverables][Linaro SW Instructions], the following
-optional 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.
+Install the required packages to build Trusted Firmware with the following
+command:
 
-*   For debugging, ARM [Development Studio 5 (DS-5)][DS-5] v5.22.
+    sudo apt-get install build-essential gcc make git
 
+Download and install the AArch64 little-endian GCC cross compiler as indicated
+in the [Linaro instructions][Linaro SW Instructions].
 
-4.  Getting the Trusted Firmware source code
---------------------------------------------
+In addition, the following optional packages and tools may be needed:
 
-The Trusted Firmware (TF) source code can be obtained as part of the standard
-Linaro releases, which provide a full software stack, including TF, normal
-world firmware, Linux kernel and device tree, file system as well as any
-additional micro-controller firmware required by the platform. This TF version
-is tested with the [Linaro 15.10 Release][Linaro Release Notes].
-
-Note 1: Both the LSK kernel or the latest tracking kernel can be used with TF;
-choose the one that best suits your needs.
-
-Note 2: Currently to run the latest tracking kernel on FVP with GICv3 driver,
-some modifications are required to UEFI. Refer
-[here](#11--changes-required-for-booting-linux-on-fvp-in-gicv3-mode)
-for more details.
-
-The TF source code will then be in `arm-tf/`. This is the upstream git
-repository cloned from GitHub. The revision checked out by the `repo` tool is
-indicated by the manifest file. Depending on the manifest file you're using,
-this might not be the latest upstream version. To synchronize your copy of the
-repository and get the latest updates, use the following commands:
+*   `device-tree-compiler` package if you need to rebuild the Flattened Device
+    Tree (FDT) source files (`.dts` files) provided with this software.
 
-    # Change to the Trusted Firmware directory.
-    cd arm-tf
+*   `libssl-dev` package if Trusted Board Boot is enabled in the build.
 
-    # Download the latest code from GitHub.
-    git fetch github
+*   For debugging, ARM [Development Studio 5 (DS-5)][DS-5].
 
-    # Update your working copy to the latest master.
-    # This command will create a local branch master that tracks the remote
-    # branch master from GitHub.
-    git checkout --track github/master
 
+4.  Getting the Trusted Firmware source code
+--------------------------------------------
 
-Alternatively, the TF source code can be separately cloned from the upstream
-GitHub repository:
+Download the Trusted Firmware source code from Github:
 
     git clone https://github.com/ARM-software/arm-trusted-firmware.git
 
@@ -102,60 +90,42 @@
 5.  Building the Trusted Firmware
 ---------------------------------
 
-To build the Trusted Firmware images, change to the root directory of the
-Trusted Firmware source tree and follow these steps:
+*   Before building Trusted Firmware, the environment variable `CROSS_COMPILE`
+    must point to the Linaro cross compiler:
 
-1.  Set the compiler path, specify a Non-trusted Firmware image (BL33) and
-    a valid platform, and then build:
+        export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
 
-        CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu- \
-        BL33=<path-to>/<bl33_image>                                \
-        make PLAT=<platform> all fip
+*   Change to the root directory of the Trusted Firmware source tree and build:
 
-    If `PLAT` is not specified, `fvp` is assumed by default. See the "Summary of
-    build options" for more information on available build options.
+        make PLAT=<platform> all
 
-    The BL33 image corresponds to the software that is executed after switching
-    to the non-secure world. UEFI can be used as the BL33 image. Refer to the
-    "Building the rest of the software stack" section below.
+    Notes:
 
-    The TSP (Test Secure Payload), corresponding to the BL32 image, is not
-    compiled in by default. Refer to the "Building the Test Secure Payload"
-    section below.
+    *   If `PLAT` is not specified, `fvp` is assumed by default. See the
+        "Summary of build options" for more information on available build
+        options.
 
-    By default this produces a release version of the build. To produce a debug
-    version instead, refer to the "Debugging options" section below.
+    *   The TSP (Test Secure Payload), corresponding to the BL32 image, is not
+        compiled in by default. Refer to the "Building the Test Secure Payload"
+        section below.
 
-    The build process creates products in a `build` directory tree, building
-    the objects and binaries for each boot loader stage in separate
-    sub-directories.  The following boot loader binary files are created from
-    the corresponding ELF files:
+    *   By default this produces a release version of the build. To produce a
+        debug version instead, refer to the "Debugging options" section below.
 
-    *   `build/<platform>/<build-type>/bl1.bin`
-    *   `build/<platform>/<build-type>/bl2.bin`
-    *   `build/<platform>/<build-type>/bl31.bin`
+    *   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:
 
-    where `<platform>` is the name of the chosen platform and `<build-type>` is
-    either `debug` or `release`. A Firmware Image Package (FIP) will be created
-    as part of the build. It contains all boot loader images except for
-    `bl1.bin`.
+        *   `build/<platform>/<build-type>/bl1.bin`
+        *   `build/<platform>/<build-type>/bl2.bin`
+        *   `build/<platform>/<build-type>/bl31.bin`
 
-    *   `build/<platform>/<build-type>/fip.bin`
+        where `<platform>` is the name of the chosen platform and `<build-type>`
+        is either `debug` or `release`. The actual number of images might differ
+        depending on the platform.
 
-    For more information on FIPs, see the "Firmware Image Package" section in
-    the [Firmware Design].
-
-2.  (Optional) Some platforms may require a SCP_BL2 image to boot. This image can
-    be included in the FIP when building the Trusted Firmware by specifying the
-    `SCP_BL2` build option:
-
-        SCP_BL2=<path-to>/<scp_bl2_image>
-
-3.  Output binary files `bl1.bin` and `fip.bin` are both required to boot the
-    system. How these files are used is platform specific. Refer to the
-    platform documentation on how to use the firmware images.
-
-4.  (Optional) Build products for a specific build variant can be removed using:
+*   Build products for a specific build variant can be removed using:
 
         make DEBUG=<D> PLAT=<platform> clean
 
@@ -165,16 +135,6 @@
 
         make realclean
 
-5.  (Optional) Path to binary for certain BL stages (BL2, BL31 and BL32) can be
-    provided by specifying the BLx=<path-to>/<blx_image> where BLx is the BL stage.
-    This will bypass the build of the BL component from source, but will include
-    the specified binary in the final FIP image. Please note that BL32 will be
-    included in the build, only if the `SPD` build option is specified.
-
-    For example, specifying `BL2=<path-to>/<bl2_image>` in the build option,
-    will skip compilation of BL2 source in trusted firmware, but include the BL2
-    binary specified in the final FIP image.
-
 ### Summary of build options
 
 ARM Trusted Firmware build system supports the following build options. Unless
@@ -223,9 +183,6 @@
     optional. It is only needed if the platform makefile specifies that it
     is required in order to build the `fwu_fip` target.
 
-*   `CROSS_COMPILE`: Prefix to toolchain binaries. Please refer to examples in
-    this document for usage.
-
 *   `DEBUG`: Chooses between a debug and release build. It can take either 0
     (release) or 1 (debug) as values. 0 is the default.
 
@@ -536,68 +493,12 @@
      Trusted Firmware is configured for dual cluster topology and this option
      can be used to override the default value.
 
-### Creating a Firmware Image Package
-
-FIPs are automatically created as part of the build instructions described in
-the previous section. It is also possible to independently build the FIP
-creation tool and FIPs if required. To do this, follow these steps:
-
-Build the tool:
-
-    make -C tools/fip_create
-
-It is recommended to remove the build artifacts before rebuilding:
-
-    make -C tools/fip_create clean
-
-Create a Firmware package that contains existing BL2 and BL31 images:
-
-    # fip_create --help to print usage information
-    # fip_create <fip_name> <images to add> [--dump to show result]
-    ./tools/fip_create/fip_create fip.bin --dump \
-       --tb-fw build/<platform>/debug/bl2.bin --soc-fw build/<platform>/debug/bl31.bin
-
-     Firmware Image Package ToC:
-    ---------------------------
-    - Trusted Boot Firmware BL2: offset=0x88, size=0x81E8
-      file: 'build/<platform>/debug/bl2.bin'
-    - EL3 Runtime Firmware BL31: offset=0x8270, size=0xC218
-      file: 'build/<platform>/debug/bl31.bin'
-    ---------------------------
-    Creating "fip.bin"
-
-View the contents of an existing Firmware package:
-
-    ./tools/fip_create/fip_create fip.bin --dump
-
-     Firmware Image Package ToC:
-    ---------------------------
-    - Trusted Boot Firmware BL2: offset=0x88, size=0x81E8
-    - EL3 Runtime Firmware BL31: offset=0x8270, size=0xC218
-    ---------------------------
-
-Existing package entries can be individually updated:
-
-    # Change the BL2 from Debug to Release version
-    ./tools/fip_create/fip_create fip.bin --dump \
-      --tb-fw build/<platform>/release/bl2.bin
-
-    Firmware Image Package ToC:
-    ---------------------------
-    - Trusted Boot Firmware BL2: offset=0x88, size=0x7240
-      file: 'build/<platform>/release/bl2.bin'
-    - EL3 Runtime Firmware BL31: offset=0x72C8, size=0xC218
-    ---------------------------
-    Updating "fip.bin"
-
 
 ### Debugging options
 
 To compile a debug version and make the build more verbose use
 
-    CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu- \
-    BL33=<path-to>/<bl33_image>                                \
-    make PLAT=<platform> DEBUG=1 V=1 all fip
+    make PLAT=<platform> 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
@@ -615,9 +516,7 @@
 Extra debug options can be passed to the build system by setting `CFLAGS`:
 
     CFLAGS='-O0 -gdwarf-2'                                     \
-    CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu- \
-    BL33=<path-to>/<bl33_image>                                \
-    make PLAT=<platform> DEBUG=1 V=1 all fip
+    make PLAT=<platform> DEBUG=1 V=1 all
 
 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
@@ -639,6 +538,7 @@
     # Resume execution
     continue
 
+
 ### Building the Test Secure Payload
 
 The TSP is coupled with a companion runtime service in the BL31 firmware,
@@ -647,49 +547,102 @@
 "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 and include it into the FIP use:
+BL31 binary. Then to build the TSP image use:
 
-    CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu- \
-    BL33=<path-to>/<bl33_image>                                \
-    make PLAT=<platform> SPD=tspd all fip
+    make PLAT=<platform> SPD=tspd all
 
 An additional boot loader binary file is created in the `build` directory:
 
-*   `build/<platform>/<build-type>/bl32.bin`
+    `build/<platform>/<build-type>/bl32.bin`
 
-The FIP will now contain the additional BL32 image. Here is an example
-output from an FVP build in release mode including BL32 and using
-`FVP_AARCH64_EFI.fd` as BL33 image:
 
-    Firmware Image Package ToC:
-    ---------------------------
-    - Trusted Boot Firmware BL2: offset=0xD8, size=0x6000
-      file: './build/fvp/release/bl2.bin'
-    - EL3 Runtime Firmware BL31: offset=0x60D8, size=0x9000
-      file: './build/fvp/release/bl31.bin'
-    - Secure Payload BL32 (Trusted OS): offset=0xF0D8, size=0x3000
-      file: './build/fvp/release/bl32.bin'
-    - Non-Trusted Firmware BL33: offset=0x120D8, size=0x280000
-      file: '../FVP_AARCH64_EFI.fd'
-    ---------------------------
-    Creating "build/fvp/release/fip.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:
 
-### Building the Certificate Generation Tool
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
 
-The `cert_create` tool can be built separately through the following commands:
+To just check the style on the files that differ between your local branch and
+the remote master, use:
 
-    $ cd tools/cert_create
-    $ make PLAT=<platform> [DEBUG=1] [V=1]
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
 
-`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:
+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`.
 
-    $ ./cert_create -h
 
-The `cert_create` tool is automatically built with the `fip` target when
-`GENERATE_COT=1`.
+### 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. For
+example, to build a FIP file for FVP, packaging TF images and a BL33 image:
+
+    make PLAT=fvp BL33=<path/to/bl33.bin> fip
+
+The resulting FIP may be found in:
+
+    `build/fvp/<build-type>/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/fip_create clean
+
+Build the tool:
+
+    make [DEBUG=1] [V=1] fiptool
+
+The tool binary can be located in:
+
+    ./tools/fip_create/fip_create
+
+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/fip_create/fip_create \
+        --tb-fw build/<platform>/<build-type>/bl2.bin \
+        --soc-fw build/<platform>/<build-type>/bl31.bin \
+        fip.bin
+
+Example 2: view the contents of an existing Firmware package:
+
+    ./tools/fip_create/fip_create --dump <path-to>/fip.bin
+
+Example 3: update the entries of an existing Firmware package:
+
+    # Change the BL2 from Debug to Release version
+    ./tools/fip_create/fip_create \
+        --tb-fw build/<platform>/release/bl2.bin \
+        build/<platform>/debug/fip.bin
+
+Example 4: unpack all entries from an existing Firmware package:
+
+    # Images will be unpacked to the working directory
+    ./tools/fip_create/fip_create --unpack <path-to>/fip.bin
+
+More information about FIP can be found in the [Firmware Design document]
+[Firmware Design].
+
 
 ### Building FIP images with support for Trusted Board Boot
 
@@ -742,18 +695,17 @@
 
     Example of command line using RSA development keys:
 
-        CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-      \
-        BL33=<path-to>/<bl33_image>                                     \
         MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
         make PLAT=<platform> TRUSTED_BOARD_BOOT=1 GENERATE_COT=1        \
         ARM_ROTPK_LOCATION=devel_rsa                                    \
         ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem        \
+        BL33=<path-to>/<bl33_image>                                     \
         all fip
 
-    The result of this build will be the bl1.bin and the fip.bin binaries, with
-    the difference that the 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.
+    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
@@ -766,15 +718,14 @@
     Example of Juno command line for generating both `fwu` and `fwu_fip`
     targets using RSA development:
 
-        CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-       \
-        BL33=<path-to>/<bl33_image>                                     \
-        SCP_BL2=<path-to>/<scp_bl2_image>                               \
-        SCP_BL2U=<path-to>/<scp_bl2u_image>                             \
-        NS_BL2U=<path-to>/<ns_bl2u_image>                               \
         MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
         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=<path-to>/<bl33_image>                                     \
+        SCP_BL2=<path-to>/<scp_bl2_image>                               \
+        SCP_BL2U=<path-to>/<scp_bl2u_image>                             \
+        NS_BL2U=<path-to>/<ns_bl2u_image>                               \
         all fip fwu_fip
 
     Note:   The BL2U image will be built by default and added to the FWU_FIP.
@@ -790,91 +741,74 @@
     can also be found in the output build directory.
 
 
-### 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=<path-to-linux>/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=<path-to-linux>/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`.
-
-
-6.  Building the rest of the software stack
--------------------------------------------
+### Building the Certificate Generation Tool
 
-The Linaro release provides a set of scripts that automate the process of
-building all components of the software stack. However, the scripts only support
-a limited number of Trusted Firmware build options. Therefore, it is recommended
-to modify these scripts to build all components except Trusted Firmware, and
-build Trusted Firmware separately as described in the section "Building the
-Trusted Firmware" above.
+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:
 
-The instructions below are targeted at an OpenEmbedded filesystem.
+    make PLAT=<platform> [DEBUG=1] [V=1] certtool
 
-1.  To exclude Trusted Firmware from the automated build process, edit the
-    variant file `build-scripts/variants/<platform>-oe`, where `<platform>`
-    is either `fvp` or `juno`. Add the following lines at the end of the file:
+Specifying the platform is mandatory since the tool is platform specific.
+`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:
 
-        # Disable ARM Trusted Firmware build
-        ARM_TF_BUILD_ENABLED=0
+    ./tools/cert_create/cert_create -h
 
-2.  Launch the build script:
 
-        CROSS_COMPILE=aarch64-linux-gnu- \
-        build-scripts/build-all.sh <platform>-oe
+6.  Building a FIP for Juno and FVP
+-----------------------------------
 
-### Preparing the Firmware Image Package
+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.
 
-The EDK2 binary should be specified as `BL33` in the `make` command line when
-building the Trusted Firmware. See the "Building the Trusted Firmware" section
-above. The EDK2 binary for use with the ARM Trusted Firmware can be found here:
+Note: follow the full instructions for one platform before switching to a
+different one. Mixing instructions for different platforms may result in
+corrupted binaries.
 
-    uefi/edk2/Build/ArmVExpress-FVP-AArch64-Minimal/DEBUG_GCC49/FV/FVP_AARCH64_EFI.fd   [for FVP]
-    uefi/edk2/Build/ArmJuno/DEBUG_GCC49/FV/BL33_AP_UEFI.fd                              [for Juno]
+1.  Clean the working directory
 
-### Building an alternative EDK2
+        make realclean
 
-*   By default, EDK2 is built in debug mode. To build a release version instead,
-    change the following line in the variant file:
+2.  Obtain SCP_BL2 (Juno) and BL33 (all platforms)
 
-        UEFI_BUILD_MODE=DEBUG
+    Use the fip_create tool to extract the SCP_BL2 and BL33 images from the FIP
+    package included in the Linaro release:
 
-    into:
+        # Build the fip_create tool
+        make [DEBUG=1] [V=1] fiptool
 
-        UEFI_BUILD_MODE=RELEASE
+        # Unpack firmware images from Linaro FIP
+        ./tools/fip_create/fip_create --unpack \
+             <path/to/linaro/release>/fip.bin
 
-*   On FVP, if legacy GICv2 locations are used, the EDK2 platform makefile must
-    be updated. This is required as EDK2 does not support probing for the GIC
-    location. To do this, first clean the EDK2 build directory:
+    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`.
 
-        build-scripts/build-uefi.sh fvp-oe clean
+    Note: the fip_create tool 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.
 
-    Then edit the following file:
+3.  Build TF images and create a new FIP
 
-        uefi/edk2/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.mak
+        # Juno
+        make PLAT=juno SCP_BL2=scp-fw.bin BL33=nt-fw.bin all fip
 
-    and add the following build flag into the `EDK2_MACROS` variable:
+        # FVP
+        make PLAT=fvp BL33=nt-fw.bin all fip
 
-        -D ARM_FVP_LEGACY_GICV2_LOCATION=1
+The resulting BL1 and FIP images may be found in:
 
-    Then rebuild everything as described above in step 2.
+    # Juno
+    ./build/juno/release/bl1.bin
+    ./build/juno/release/fip.bin
 
-    Finally rebuild the Trusted Firmware to generate a new FIP using the
-    instructions in the "Building the Trusted Firmware" section.
+    # FVP
+    ./build/fvp/release/bl1.bin
+    ./build/fvp/release/fip.bin
 
 
 7.  EL3 payloads alternative boot flow
@@ -1006,7 +940,6 @@
 will create a FIP without a BL33 and prepare to jump to a BL33 image loaded at
 address 0x80000000:
 
-    CROSS_COMPILE=<path-to>/bin/aarch64-linux-gnu- \
     make PRELOADED_BL33_BASE=0x80000000 PLAT=fvp all fip
 
 #### Boot of a preloaded bootwrapped kernel image on Base FVP
@@ -1040,11 +973,33 @@
 JTAG on Juno.
 
 
-9.  Preparing the images to run on FVP
---------------------------------------
+9.  Running the software on FVP
+-------------------------------
+
+This version of the ARM Trusted Firmware has been tested on the following ARM
+FVPs (64-bit versions only).
+
+*   `Foundation_Platform` (Version 9.5, Build 9.5.40)
+*   `FVP_Base_AEMv8A-AEMv8A` (Version 7.2, Build 0.8.7202)
+*   `FVP_Base_Cortex-A57x4-A53x4` (Version 7.2, Build 0.8.7202)
+*   `FVP_Base_Cortex-A57x1-A53x1` (Version 7.2, Build 0.8.7202)
+*   `FVP_Base_Cortex-A57x2-A53x4` (Version 7.2, Build 0.8.7202)
+
+NOTE: The build numbers quoted above are those reported by launching the FVP
+with the `--version` parameter. `Foundation_Platform` tarball for `--version`
+9.5.40 is labeled as version 9.5.41.
+
+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: This section can be ignored when booting an EL3 payload, as no Flattened
-Device Tree or kernel image is needed in this case.
+NOTE: The Foundation FVP does not provide a debugger interface.
+
+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.
 
 ### Obtaining the Flattened Device Trees
 
@@ -1084,48 +1039,6 @@
     For use with Foundation FVP with Base memory map configuration and Linux
     GICv3 support.
 
-Copy the chosen FDT blob as `fdt.dtb` to the directory from which the FVP
-is launched. Alternatively a symbolic link may be used.
-
-### Preparing the kernel image
-
-Copy the kernel image file `linux/arch/arm64/boot/Image` to the directory from
-which the FVP is launched. Alternatively a symbolic link may be used.
-
-
-10.  Running the software on FVP
---------------------------------
-
-This version of the ARM Trusted Firmware has been tested on the following ARM
-FVPs (64-bit versions only).
-
-*   `Foundation_Platform` (Version 9.5, Build 9.5.40)
-*   `FVP_Base_AEMv8A-AEMv8A` (Version 7.2, Build 0.8.7202)
-*   `FVP_Base_Cortex-A57x4-A53x4` (Version 7.2, Build 0.8.7202)
-*   `FVP_Base_Cortex-A57x1-A53x1` (Version 7.2, Build 0.8.7202)
-*   `FVP_Base_Cortex-A57x2-A53x4` (Version 7.2, Build 0.8.7202)
-
-NOTE: The build numbers quoted above are those reported by launching the FVP
-with the `--version` parameter. `Foundation_Platform` tarball for `--version`
-9.5.40 is labeled as version 9.5.41.
-
-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: The Foundation FVP does not provide a debugger interface.
-
-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].
-
-The Linaro release provides a script to run the software on FVP. However, it
-only supports a limited number of model parameter options. Therefore, it is
-recommended to launch the FVP manually for all use cases described below.
-
-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.
-
-
 ### Running on the Foundation FVP with reset to BL1 entrypoint
 
 The following `Foundation_Platform` parameters should be used to boot Linux with
@@ -1142,81 +1055,14 @@
     --data="<path-to>/<kernel-binary>"@0x80080000   \
     --block-device="<path-to>/<file-system-image>"
 
-1.  The `--data="<path-to-some-binary>"@0x...` parameters are used to load
-    binaries into memory.
-
-    *   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.
-
-2.  The `--block-device` parameter is used to specify the path to the file
-    system image provided to Linux via VirtioBlock. Note that it must point to
-    the real file and that a symbolic link to this file cannot be used with the
-    FVP.
-
-The default use-case for the Foundation FVP is to enable the GICv3 device in
-the model but use the GICv2 FDT, in order for Linux to drive the GIC in GICv2
-emulation mode.
-
-### Notes regarding Base FVP configuration options
-
-Please refer to these notes in the subsequent "Running on the Base FVP"
-sections.
-
-1.  The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image
-    Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware"
-    section above).
-
-2.  Using `cache_state_modelled=1` makes booting very slow. The software will
-    still work (and run much faster) without this option but this will hide any
-    cache maintenance defects in the software.
-
-3.  The `-C bp.virtioblockdevice.image_path` parameter is used to specify the
-    path to the file system image provided to Linux via VirtioBlock. Note that
-    it must point to the real file and that a symbolic link to this file cannot
-    be used with the FVP. Ensure that the FVP doesn't output any error messages.
-    If the following error message is displayed:
-
-        ERROR: BlockDevice: Failed to open "<path-to>/<file-system-image>"!
-
-    then make sure the path to the file-system image in the model parameter is
-    correct and that read permission is correctly set on the file-system image
-    file.
-
-4.  Setting the `-C bp.secure_memory` parameter to `1` is only supported on
-    Base FVP versions 5.4 and newer. Setting this parameter to `0` is also
-    supported. The `-C bp.tzc_400.diagnostics=1` parameter is optional. It
-    instructs the FVP to provide some helpful information if a secure memory
-    violation occurs.
-
-5.  The `--data="<path-to-some-binary>"@<base-address-of-binary>` parameter is
-    used to load images into Base FVP memory. The base addresses used should
-    match the image base addresses used while linking the images. This parameter
-    is used to load the Linux kernel image and device tree into DRAM.
-
-6.  This and the following notes only apply when the firmware is built with
-    the `RESET_TO_BL31` option.
-
-    The `--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>`
-    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.
+Notes:
 
-7.  The `-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>` parameter, where
-    X and Y are the cluster and CPU numbers respectively, is used to set the
-    reset vector for each core.
-
-8.  Changing the default value of `ARM_TSP_RAM_LOCATION` will also require
-    changing the value of
-    `--data="<path-to><bl32-binary>"@<base-address-of-bl32>` to the new value of
-    `BL32_BASE`.
-
+*   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.
 
 ### Running on the AEMv8 Base FVP with reset to BL1 entrypoint
 
-Please read "Notes regarding Base FVP configuration options" section above for
-information about some of the options to run the software.
-
 The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
 with 8 CPUs using the ARM Trusted Firmware.
 
@@ -1235,9 +1081,6 @@
 
 ### Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
 
-Please read "Notes regarding Base FVP configuration options" section above for
-information about some of the options to run the software.
-
 The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to
 boot Linux with 8 CPUs using the ARM Trusted Firmware.
 
@@ -1254,9 +1097,6 @@
 
 ### Running on the AEMv8 Base FVP with reset to BL31 entrypoint
 
-Please read "Notes regarding Base FVP configuration options" section above for
-information about some of the options to run the software.
-
 The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
 with 8 CPUs using the ARM Trusted Firmware.
 
@@ -1282,10 +1122,24 @@
     --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
     -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
 
-### Running on the Cortex-A57-A53 Base FVP with reset to BL31 entrypoint
+Notes:
 
-Please read "Notes regarding Base FVP configuration options" section above for
-information about some of the options to run the software.
+*   Since a FIP is not loaded when using BL31 as reset entrypoint, the
+    `--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>`
+    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<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>` 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="<path-to><bl32-binary>"@<base-address-of-bl32>` to the new value of
+    `BL32_BASE`.
+
+### 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 ARM Trusted Firmware.
@@ -1393,7 +1247,7 @@
 detect the legacy VE memory map while configuring the GIC.
 
 
-11.  Running the software on Juno
+10.  Running the software on Juno
 ---------------------------------
 
 This version of the ARM Trusted Firmware has been tested on Juno r0 and Juno r1.
@@ -1406,17 +1260,6 @@
 
 ### Preparing Trusted Firmware images
 
-The Juno platform requires a SCP_BL1 and a SCP_BL2 image to boot up. The
-SCP_BL1 image contains the ROM firmware that runs on the SCP (System Control
-Processor), whereas the SCP_BL2 image contains the SCP Runtime firmware. Both
-images are embedded within the Juno board recovery image, these are the files
-`bl0.bin` and `bl30.bin`, respectively. Please note that these filenames still
-use the old terminology.
-
-The SCP_BL2 file must be part of the FIP image. Therefore, its path must be
-supplied using the `SCP_BL2` variable on the command line when building the
-FIP. Please refer to the section "Building the Trusted Firmware".
-
 After building Trusted Firmware, the files `bl1.bin` and `fip.bin` need copying
 to the `SOFTWARE/` directory of the Juno SD card.
 
@@ -1430,66 +1273,15 @@
 ### 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]. The [Linaro Release
-Notes] point to the required SCP and motherboard firmware binaries supporting
-this feature on Juno. The mainline linux kernel does not yet have support for
-this feature on Juno but it is queued to be merged in v4.4. Till that becomes
-available, the feature can be tested by using a custom kernel built from the
-following repository:
-
-    git clone git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git
-    cd linux
-    git checkout firmware/psci-1.0
+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:
 
-Configure the linux kernel:
-
-    export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
-    make ARCH=arm64 defconfig
-
-The feature is tested conveniently by using the RTC. Enable the RTC driver in
-menuconfig
-
-    make ARCH=arm64 menuconfig
-
-The PL031 RTC driver can be enabled at the following location in menuconfig
-
-    ARM AMBA PL031 RTC
-      |   Location:
-      |     -> Device Drivers
-      |       -> Real Time Clock
-
-Build the kernel
-
-    make ARCH=arm64 Image -j8
-
-Replace the kernel image in the `SOFTWARE/` directory of the Juno SD card with
-the `Image` from `arch/arm64/boot/` of the linux directory.
-
-Reset the board and wait for it to boot. At the shell prompt issue the
-following command:
-
-    echo +10 > /sys/class/rtc/rtc1/wakealarm
+    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.
 
-
-12.  Changes required for booting Linux on FVP in GICv3 mode
-------------------------------------------------------------
-
-In case the TF FVP port is built with the build option
-`FVP_USE_GIC_DRIVER=FVP_GICV3`, then the GICv3 hardware cannot be used in
-GICv2 legacy mode. The default build of UEFI for FVP in
-[latest tracking kernel][Linaro Release Notes] configures GICv3 in GICv2 legacy
-mode. This can be changed by setting the build flag
-`gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy` to FALSE in
-`uefi/edk2/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc`.
-
-Recompile UEFI as mentioned [here][FVP Instructions].
-
-The GICv3 DTBs found in ARM Trusted Firmware source directory can be
-used to test the GICv3 kernel on the respective FVP models.
 
 - - - - - - - - - - - - - - - - - - - - - - - - - -
 
@@ -1498,7 +1290,7 @@
 
 [Firmware Design]:             firmware-design.md
 [ARM FVP website]:             http://www.arm.com/fvp
-[Linaro Release Notes]:        https://community.arm.com/docs/DOC-10952#jive_content_id_Linaro_Release_1510
+[Linaro Release Notes]:        https://community.arm.com/docs/DOC-10952#jive_content_id_Linaro_Release_1602
 [ARM Platforms Portal]:        https://community.arm.com/groups/arm-development-platforms
 [Linaro SW Instructions]:      https://community.arm.com/docs/DOC-10803
 [Juno Instructions]:           https://community.arm.com/docs/DOC-10804
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index d686c8d..54c528c 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -88,8 +88,8 @@
 {
 	mmap_region_t *mm = mmap;
 	mmap_region_t *mm_last = mm + ARRAY_SIZE(mmap) - 1;
-	unsigned long long pa_end = base_pa + size - 1;
-	uintptr_t va_end = base_va + size - 1;
+	unsigned long long end_pa = base_pa + size - 1;
+	uintptr_t end_va = base_va + size - 1;
 
 	assert(IS_PAGE_ALIGNED(base_pa));
 	assert(IS_PAGE_ALIGNED(base_va));
@@ -98,10 +98,74 @@
 	if (!size)
 		return;
 
+	assert(base_pa < end_pa); /* Check for overflows */
+	assert(base_va < end_va);
+
+#if DEBUG
+
+	/* Check for PAs and VAs overlaps with all other regions */
+	for (mm = mmap; mm->size; ++mm) {
+
+		uintptr_t mm_end_va = mm->base_va + mm->size - 1;
+
+		/*
+		 * Check if one of the regions is completely inside the other
+		 * one.
+		 */
+		int fully_overlapped_va =
+			((base_va >= mm->base_va) && (end_va <= mm_end_va)) ||
+			((mm->base_va >= base_va) && (mm_end_va <= end_va));
+
+		/*
+		 * Full VA overlaps are only allowed if both regions are
+		 * identity mapped (zero offset) or have the same VA to PA
+		 * offset. Also, make sure that it's not the exact same area.
+		 */
+		if (fully_overlapped_va) {
+			assert((mm->base_va - mm->base_pa) ==
+			       (base_va - base_pa));
+			assert((base_va != mm->base_va) || (size != mm->size));
+		} else {
+			/*
+			 * If the regions do not have fully overlapping VAs,
+			 * then they must have fully separated VAs and PAs.
+			 * Partial overlaps are not allowed
+			 */
+
+			unsigned long long mm_end_pa =
+						     mm->base_pa + mm->size - 1;
+
+			int separated_pa =
+				(end_pa < mm->base_pa) || (base_pa > mm_end_pa);
+			int separated_va =
+				(end_va < mm->base_va) || (base_va > mm_end_va);
+
+			assert(separated_va && separated_pa);
+		}
+	}
+
+	mm = mmap; /* Restore pointer to the start of the array */
+
+#endif /* DEBUG */
+
 	/* Find correct place in mmap to insert new region */
 	while (mm->base_va < base_va && mm->size)
 		++mm;
 
+	/*
+	 * If a section is contained inside another one with the same base
+	 * address, it must be placed after the one it is contained in:
+	 *
+	 * 1st |-----------------------|
+	 * 2nd |------------|
+	 * 3rd |------|
+	 *
+	 * This is required for mmap_region_attr() to get the attributes of the
+	 * small region correctly.
+	 */
+	while ((mm->base_va == base_va) && (mm->size > size))
+		++mm;
+
 	/* Make room for new region by moving other regions up by one place */
 	memmove(mm + 1, mm, (uintptr_t)mm_last - (uintptr_t)mm);
 
@@ -113,10 +177,10 @@
 	mm->size = size;
 	mm->attr = attr;
 
-	if (pa_end > xlat_max_pa)
-		xlat_max_pa = pa_end;
-	if (va_end > xlat_max_va)
-		xlat_max_va = va_end;
+	if (end_pa > xlat_max_pa)
+		xlat_max_pa = end_pa;
+	if (end_va > xlat_max_va)
+		xlat_max_va = end_va;
 }
 
 void mmap_add(const mmap_region_t *mm)
@@ -164,14 +228,33 @@
 	return desc;
 }
 
+/*
+ * Returns attributes of area at `base_va` with size `size`. It returns the
+ * attributes of the innermost region that contains it. If there are partial
+ * overlaps, it returns -1, as a smaller size is needed.
+ */
 static int mmap_region_attr(mmap_region_t *mm, uintptr_t base_va,
 					size_t size)
 {
-	int attr = mm->attr;
-	int old_mem_type, new_mem_type;
+	/* Don't assume that the area is contained in the first region */
+	int attr = -1;
 
-	for (;;) {
-		++mm;
+	/*
+	 * Get attributes from last (innermost) region that contains the
+	 * requested area. Don't stop as soon as one region doesn't contain it
+	 * because there may be other internal regions that contain this area:
+	 *
+	 * |-----------------------------1-----------------------------|
+	 * |----2----|     |-------3-------|    |----5----|
+	 *                   |--4--|
+	 *
+	 *                   |---| <- Area we want the attributes of.
+	 *
+	 * In this example, the area is contained in regions 1, 3 and 4 but not
+	 * in region 2. The loop shouldn't stop at region 2 as inner regions
+	 * have priority over outer regions, it should stop at region 5.
+	 */
+	for (;; ++mm) {
 
 		if (!mm->size)
 			return attr; /* Reached end of list */
@@ -182,27 +265,14 @@
 		if (mm->base_va + mm->size <= base_va)
 			continue; /* Next region has already been overtaken */
 
-		if ((mm->attr & attr) == attr)
+		if (mm->attr == attr)
 			continue; /* Region doesn't override attribs so skip */
 
-		/*
-		 * Update memory mapping attributes in 2 steps:
-		 * 1) Update access permissions and security state flags
-		 * 2) Update memory type.
-		 *
-		 * See xlat_tables.h for details about the attributes priority
-		 * system and the rules dictating whether attributes should be
-		 * updated.
-		 */
-		old_mem_type = MT_TYPE(attr);
-		new_mem_type = MT_TYPE(mm->attr);
-		attr &= mm->attr;
-		if (new_mem_type < old_mem_type)
-			attr = (attr & ~MT_TYPE_MASK) | new_mem_type;
-
 		if (mm->base_va > base_va ||
 			mm->base_va + mm->size < base_va + size)
 			return -1; /* Region doesn't fully cover our area */
+
+		attr = mm->attr;
 	}
 }
 
@@ -228,7 +298,7 @@
 			/* Done mapping regions; finish zeroing the table */
 			desc = INVALID_DESC;
 		} else if (mm->base_va + mm->size <= base_va) {
-			/* Area now after the region so skip it */
+			/* This area is after the region so get next region */
 			++mm;
 			continue;
 		}
@@ -237,24 +307,27 @@
 				(void *)base_va, level_size);
 
 		if (mm->base_va >= base_va + level_size) {
-			/* Next region is after area so nothing to map yet */
+			/* Next region is after this area. Nothing to map yet */
 			desc = INVALID_DESC;
-		} else if (mm->base_va <= base_va && mm->base_va + mm->size >=
-				base_va + level_size) {
-			/* Next region covers all of area */
+		} else {
+			/*
+			 * Try to get attributes of this area. It will fail if
+			 * there are partially overlapping regions. On success,
+			 * it will return the innermost region's attributes.
+			 */
 			int attr = mmap_region_attr(mm, base_va, level_size);
-			if (attr >= 0)
+			if (attr >= 0) {
 				desc = mmap_desc(attr,
 					base_va - mm->base_va + mm->base_pa,
 					level);
+			}
 		}
-		/* else Next region only partially covers area, so need */
 
 		if (desc == UNSET_DESC) {
 			/* Area not covered by a region so need finer table */
 			uint64_t *new_table = xlat_tables[next_xlat++];
 			assert(next_xlat <= MAX_XLAT_TABLES);
-			desc = TABLE_DESC | (unsigned long)new_table;
+			desc = TABLE_DESC | (uint64_t)new_table;
 
 			/* Recurse to fill in new table */
 			mm = init_xlation_table_inner(mm, base_va,