hikey: Add UEFI sources for reference

UEFI needs to be built outside Android build system.
Please follow the instructions in README.

The sources correspond to:
https://github.com/96boards/edk2/commit/14eae0c12e71fd33c4c0fc51e4475e8db02566cf
https://github.com/96boards/arm-trusted-firmware/commit/e9b4909dcd75fc4ae7041cfb83d28ab9adb7afdf
https://github.com/96boards/l-loader/commit/6b784ad5c4ab00e2b1c6f53cd5f74054e5d00a78
https://git.linaro.org/uefi/uefi-tools.git/commit/abe618f8ab72034fff1ce46c9c006a2c6bd40a7e

Change-Id: Ieeefdb63e673e0c8e64e0a1f02c7bddc63b2c7fb
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
diff --git a/uefi/README b/uefi/README
new file mode 100644
index 0000000..edd8679
--- /dev/null
+++ b/uefi/README
@@ -0,0 +1,30 @@
+---------------------------------------------------------------------------------------------------------------
+Prerequisites:
+---------------------------------------------------------------------------------------------------------------
+ - GCC  cross-toolchain for Aarch64 and gnueabihf should be available in your PATH. The same can be got from here:
+   - http://releases.linaro.org/15.02/components/toolchain/binaries/aarch64-linux-gnu/gcc-linaro-4.9-2015.02-3-x86_64_aarch64-linux-gnu.tar.xz
+   - http://releases.linaro.org/15.02/components/toolchain/binaries/arm-linux-gnueabihf/gcc-linaro-4.9-2015.02-3-x86_64_arm-linux-gnueabihf.tar.xz
+ - GPT fdisk (gdisk package from your favorite distribution).
+
+
+---------------------------------------------------------------------------------------------------------------
+Building UEFI for Hikey:
+---------------------------------------------------------------------------------------------------------------
+export AARCH64_TOOLCHAIN=GCC49
+export EDK2_DIR=${PWD}/linaro-edk2
+export UEFI_TOOLS_DIR=${PWD}/uefi-tools
+cd ${EDK2_DIR}
+${UEFI_TOOLS_DIR}/uefi-build.sh -b RELEASE -a ../arm-trusted-firmware hikey
+cd ../l-loader
+ln -s ${EDK2_DIR}/Build/HiKey/RELEASE_GCC49/FV/bl1.bin
+ln -s ${EDK2_DIR}/Build/HiKey/RELEASE_GCC49/FV/fip.bin
+arm-linux-gnueabihf-gcc -c -o start.o start.S
+arm-linux-gnueabihf-gcc -c -o debug.o debug.S
+arm-linux-gnueabihf-ld -Bstatic -Tl-loader.lds -Ttext 0xf9800800 start.o debug.o -o loader
+arm-linux-gnueabihf-objcopy -O binary loader temp
+python gen_loader.py -o l-loader.bin --img_loader=temp --img_bl1=bl1.bin
+# XXX sgdisk usage requires sudo
+sudo PTABLE=aosp-4g bash -x generate_ptable.sh
+python gen_loader.py -o ptable-aosp.img --img_prm_ptable=prm_ptable.img
+
+The files fip.bin, l-loader.bin and ptable-aosp.img are now built. All the image files are in $BUILD/l-loader directory. The Fastboot App is at $EDK2_DIR/Build/HiKey/RELEASE_GCC49/AARCH64/AndroidFastbootApp.efi
diff --git a/uefi/arm-trusted-firmware/.gitignore b/uefi/arm-trusted-firmware/.gitignore
new file mode 100644
index 0000000..d3567bc
--- /dev/null
+++ b/uefi/arm-trusted-firmware/.gitignore
@@ -0,0 +1,15 @@
+# Ignore miscellaneous files
+cscope.*
+*.swp
+*.patch
+.project
+.cproject
+
+# Ignore build directory
+build/
+
+# Ignore build products from tools
+tools/**/*.o
+tools/fip_create/fip_create
+tools/cert_create/src/*.o
+tools/cert_create/cert_create
diff --git a/uefi/arm-trusted-firmware/Makefile b/uefi/arm-trusted-firmware/Makefile
new file mode 100644
index 0000000..085fb6e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/Makefile
@@ -0,0 +1,649 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Trusted Firmware Version
+#
+VERSION_MAJOR		:= 1
+VERSION_MINOR		:= 1
+
+#
+# Default values for build configurations
+#
+
+# Build verbosity
+V			:= 0
+# Debug build
+DEBUG			:= 0
+# Build architecture
+ARCH 			:= aarch64
+# Build platform
+DEFAULT_PLAT		:= fvp
+PLAT			:= ${DEFAULT_PLAT}
+# SPD choice
+SPD			:= none
+# Base commit to perform code check on
+BASE_COMMIT		:= origin/master
+# NS timer register save and restore
+NS_TIMER_SWITCH		:= 0
+# By default, Bl1 acts as the reset handler, not BL31
+RESET_TO_BL31		:= 0
+# Include FP registers in cpu context
+CTX_INCLUDE_FPREGS		:= 0
+# Determine the version of ARM GIC architecture to use for interrupt management
+# in EL3. The platform port can change this value if needed.
+ARM_GIC_ARCH		:=	2
+# Flag used to indicate if ASM_ASSERTION should be enabled for the build.
+# This defaults to being present in DEBUG builds only.
+ASM_ASSERTION		:=	${DEBUG}
+# Build option to choose whether Trusted firmware uses Coherent memory or not.
+USE_COHERENT_MEM	:=	1
+# Default FIP file name
+FIP_NAME		:= fip.bin
+# By default, use the -pedantic option in the gcc command line
+DISABLE_PEDANTIC	:= 0
+# Flags to generate the Chain of Trust
+GENERATE_COT		:= 0
+CREATE_KEYS		:= 1
+# Flags to build TF with Trusted Boot support
+TRUSTED_BOARD_BOOT	:= 0
+AUTH_MOD		:= none
+
+# Checkpatch ignores
+CHECK_IGNORE		=	--ignore COMPLEX_MACRO
+
+CHECKPATCH_ARGS		=	--no-tree --no-signoff ${CHECK_IGNORE}
+CHECKCODE_ARGS		=	--no-patch --no-tree --no-signoff ${CHECK_IGNORE}
+
+ifeq (${V},0)
+	Q=@
+	CHECKCODE_ARGS	+=	--no-summary --terse
+else
+	Q=
+endif
+export Q
+
+ifneq (${DEBUG}, 0)
+	BUILD_TYPE	:=	debug
+	# Use LOG_LEVEL_INFO by default for debug builds
+	LOG_LEVEL	:=	40
+else
+	BUILD_TYPE	:=	release
+	# Use LOG_LEVEL_NOTICE by default for release builds
+	LOG_LEVEL	:=	20
+endif
+
+# Default build string (git branch and commit)
+ifeq (${BUILD_STRING},)
+	BUILD_STRING	:=	$(shell git log -n 1 --pretty=format:"%h")
+endif
+
+VERSION_STRING		:=	v${VERSION_MAJOR}.${VERSION_MINOR}(${BUILD_TYPE}):${BUILD_STRING}
+
+BL_COMMON_SOURCES	:=	common/bl_common.c			\
+				common/tf_printf.c			\
+				common/aarch64/debug.S			\
+				lib/aarch64/cache_helpers.S		\
+				lib/aarch64/misc_helpers.S		\
+				lib/aarch64/xlat_helpers.c		\
+				lib/stdlib/std.c			\
+				plat/common/aarch64/platform_helpers.S
+
+BUILD_BASE		:=	./build
+BUILD_PLAT		:=	${BUILD_BASE}/${PLAT}/${BUILD_TYPE}
+
+PLATFORMS		:=	$(shell ls -I common plat/)
+SPDS			:=	$(shell ls -I none services/spd)
+HELP_PLATFORMS		:=	$(shell echo ${PLATFORMS} | sed 's/ /|/g')
+
+# Convenience function for adding build definitions
+# $(eval $(call add_define,FOO)) will have:
+# -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise
+define add_define
+DEFINES			+=	-D$(1)$(if $(value $(1)),=$(value $(1)),)
+endef
+
+# Convenience function for verifying option has a boolean value
+# $(eval $(call assert_boolean,FOO)) will assert FOO is 0 or 1
+define assert_boolean
+$(and $(patsubst 0,,$(value $(1))),$(patsubst 1,,$(value $(1))),$(error $(1) must be boolean))
+endef
+
+ifeq (${PLAT},)
+  $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform.")
+endif
+ifeq ($(findstring ${PLAT},${PLATFORMS}),)
+  $(error "Error: Invalid platform. The following platforms are available: ${PLATFORMS}")
+endif
+
+all: msg_start
+
+msg_start:
+	@echo "Building ${PLAT}"
+
+include plat/${PLAT}/platform.mk
+
+# Include the CPU specific operations makefile. By default all CPU errata
+# workarounds and CPU specifc optimisations are disabled. This can be
+# overridden by the platform.
+include lib/cpus/cpu-ops.mk
+
+ifdef BL1_SOURCES
+NEED_BL1 := yes
+include bl1/bl1.mk
+endif
+
+ifdef BL2_SOURCES
+NEED_BL2 := yes
+include bl2/bl2.mk
+# Using the ARM Trusted Firmware BL2 implies that a BL3-3 image also need to be supplied for the FIP.
+# This flag can be overridden by the platform.
+NEED_BL33 ?= yes
+endif
+
+ifdef BL31_SOURCES
+NEED_BL31 := yes
+include bl31/bl31.mk
+endif
+
+# Include SPD Makefile if one has been specified
+ifneq (${SPD},none)
+  # We expect to locate an spd.mk under the specified SPD directory
+  SPD_MAKE		:=	$(shell m="services/spd/${SPD}/${SPD}.mk"; [ -f "$$m" ] && echo "$$m")
+
+  ifeq (${SPD_MAKE},)
+    $(error Error: No services/spd/${SPD}/${SPD}.mk located)
+  endif
+  $(info Including ${SPD_MAKE})
+  include ${SPD_MAKE}
+
+  # If there's BL3-2 companion for the chosen SPD, and the SPD wants to build the
+  # BL3-2 from source, we expect that the SPD's Makefile would set NEED_BL32
+  # variable to "yes". In case the BL3-2 is a binary which needs to be included in
+  # fip, then the NEED_BL32 needs to be set and BL3-2 would need to point to the bin.
+endif
+
+.PHONY:			all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool fip certtool
+.SUFFIXES:
+
+INCLUDES		+=	-Iinclude/bl31			\
+				-Iinclude/bl31/services		\
+				-Iinclude/common		\
+				-Iinclude/drivers		\
+				-Iinclude/drivers/arm		\
+				-Iinclude/drivers/io		\
+				-Iinclude/lib			\
+				-Iinclude/lib/aarch64		\
+				-Iinclude/lib/cpus/aarch64	\
+				-Iinclude/plat/common		\
+				-Iinclude/stdlib		\
+				-Iinclude/stdlib/sys		\
+				${PLAT_INCLUDES}		\
+				${SPD_INCLUDES}
+
+# Process DEBUG flag
+$(eval $(call assert_boolean,DEBUG))
+$(eval $(call add_define,DEBUG))
+ifeq (${DEBUG},0)
+  $(eval $(call add_define,NDEBUG))
+else
+CFLAGS			+= 	-g
+ASFLAGS			+= 	-g -Wa,--gdwarf-2
+endif
+
+# Process NS_TIMER_SWITCH flag
+$(eval $(call assert_boolean,NS_TIMER_SWITCH))
+$(eval $(call add_define,NS_TIMER_SWITCH))
+
+# Process RESET_TO_BL31 flag
+$(eval $(call assert_boolean,RESET_TO_BL31))
+$(eval $(call add_define,RESET_TO_BL31))
+
+# Process CTX_INCLUDE_FPREGS flag
+$(eval $(call assert_boolean,CTX_INCLUDE_FPREGS))
+$(eval $(call add_define,CTX_INCLUDE_FPREGS))
+
+# Process ARM_GIC_ARCH flag
+$(eval $(call add_define,ARM_GIC_ARCH))
+
+# Process ASM_ASSERTION flag
+$(eval $(call assert_boolean,ASM_ASSERTION))
+$(eval $(call add_define,ASM_ASSERTION))
+
+# Process LOG_LEVEL flag
+$(eval $(call add_define,LOG_LEVEL))
+
+# Process USE_COHERENT_MEM flag
+$(eval $(call assert_boolean,USE_COHERENT_MEM))
+$(eval $(call add_define,USE_COHERENT_MEM))
+
+# Process Generate CoT flags
+$(eval $(call assert_boolean,GENERATE_COT))
+$(eval $(call assert_boolean,CREATE_KEYS))
+
+# Process TRUSTED_BOARD_BOOT flag
+$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
+$(eval $(call add_define,TRUSTED_BOARD_BOOT))
+
+ASFLAGS			+= 	-nostdinc -ffreestanding -Wa,--fatal-warnings	\
+				-Werror -Wmissing-include-dirs			\
+				-mgeneral-regs-only -D__ASSEMBLY__		\
+				${DEFINES} ${INCLUDES}
+CFLAGS			+= 	-nostdinc -ffreestanding -Wall			\
+				-Werror -Wmissing-include-dirs			\
+				-mgeneral-regs-only -mstrict-align		\
+				-std=c99 -c -Os	${DEFINES} ${INCLUDES}
+CFLAGS			+=	-ffunction-sections -fdata-sections		\
+				-fno-delete-null-pointer-checks
+
+LDFLAGS			+=	--fatal-warnings -O1
+LDFLAGS			+=	--gc-sections
+
+
+CC			:=	${CROSS_COMPILE}gcc
+CPP			:=	${CROSS_COMPILE}cpp
+AS			:=	${CROSS_COMPILE}gcc
+AR			:=	${CROSS_COMPILE}ar
+LD			:=	${CROSS_COMPILE}ld
+OC			:=	${CROSS_COMPILE}objcopy
+OD			:=	${CROSS_COMPILE}objdump
+NM			:=	${CROSS_COMPILE}nm
+PP			:=	${CROSS_COMPILE}gcc -E ${CFLAGS}
+
+# Variables for use with Firmware Image Package
+FIPTOOLPATH		?=	tools/fip_create
+FIPTOOL			?=	${FIPTOOLPATH}/fip_create
+fiptool:		${FIPTOOL}
+fip:			${BUILD_PLAT}/${FIP_NAME}
+
+# Variables for use with Certificate Generation Tool
+CRTTOOLPATH		?=	tools/cert_create
+CRTTOOL			?=	${CRTTOOLPATH}/cert_create
+certtool:		${CRTTOOL}
+
+# CoT generation tool default parameters
+TRUSTED_KEY_CERT	:=	${BUILD_PLAT}/trusted_key.crt
+
+# Pass the private keys to the CoT generation tool in the command line
+# If CREATE_KEYS is set, the '-n' option will be added, indicating the tool to create new keys
+ifneq (${GENERATE_COT},0)
+    $(eval CERTS := yes)
+
+    $(eval FIP_DEPS += certificates)
+    $(eval FIP_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT})
+
+    ifneq (${CREATE_KEYS},0)
+        $(eval CRT_ARGS += -n)
+    endif
+    $(eval CRT_ARGS += $(if ${ROT_KEY}, --rot-key ${ROT_KEY}))
+    $(eval CRT_ARGS += $(if ${TRUSTED_WORLD_KEY}, --trusted-world-key ${TRUSTED_WORLD_KEY}))
+    $(eval CRT_ARGS += $(if ${NON_TRUSTED_WORLD_KEY}, --non-trusted-world-key ${NON_TRUSTED_WORLD_KEY}))
+    $(eval CRT_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT})
+endif
+
+# Check Trusted Board Boot options
+ifneq (${TRUSTED_BOARD_BOOT},0)
+    ifeq (${AUTH_MOD},none)
+        $(error Error: When TRUSTED_BOARD_BOOT=1, AUTH_MOD has to be the name of a valid authentication module)
+    else
+        # We expect to locate an *.mk file under the specified AUTH_MOD directory
+        AUTH_MAKE := $(shell m="common/auth/${AUTH_MOD}/${AUTH_MOD}.mk"; [ -f "$$m" ] && echo "$$m")
+        ifeq (${AUTH_MAKE},)
+            $(error Error: No common/auth/${AUTH_MOD}/${AUTH_MOD}.mk located)
+        endif
+        $(info Including ${AUTH_MAKE})
+        include ${AUTH_MAKE}
+    endif
+
+    BL_COMMON_SOURCES	+=	common/auth.c
+endif
+
+# Check if -pedantic option should be used
+ifeq (${DISABLE_PEDANTIC},0)
+    CFLAGS		+= 	-pedantic
+endif
+
+locate-checkpatch:
+ifndef CHECKPATCH
+	$(error "Please set CHECKPATCH to point to the Linux checkpatch.pl file, eg: CHECKPATCH=../linux/script/checkpatch.pl")
+else
+ifeq (,$(wildcard ${CHECKPATCH}))
+	$(error "The file CHECKPATCH points to cannot be found, use eg: CHECKPATCH=../linux/script/checkpatch.pl")
+endif
+endif
+
+clean:
+			@echo "  CLEAN"
+			${Q}rm -rf ${BUILD_PLAT}
+			${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+			${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+
+realclean distclean:
+			@echo "  REALCLEAN"
+			${Q}rm -rf ${BUILD_BASE}
+			${Q}rm -f ${CURDIR}/cscope.*
+			${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+			${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+
+checkcodebase:		locate-checkpatch
+			@echo "  CHECKING STYLE"
+			@if test -d .git ; then	\
+				git ls-files | grep -v stdlib | while read GIT_FILE ; do ${CHECKPATCH} ${CHECKCODE_ARGS} -f $$GIT_FILE ; done ;	\
+			 else			\
+				 find . -type f -not -iwholename "*.git*" -not -iwholename "*build*" -not -iwholename "*stdlib*" -exec ${CHECKPATCH} ${CHECKCODE_ARGS} -f {} \; ;	\
+			 fi
+
+checkpatch:		locate-checkpatch
+			@echo "  CHECKING STYLE"
+			@git format-patch --stdout ${BASE_COMMIT} | ${CHECKPATCH} ${CHECKPATCH_ARGS} - || true
+
+.PHONY: ${CRTTOOL}
+${CRTTOOL}:
+			${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH}
+			@echo
+			@echo "Built $@ successfully"
+			@echo
+
+.PHONY: ${FIPTOOL}
+${FIPTOOL}:
+			${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH}
+
+define match_goals
+$(strip $(foreach goal,$(1),$(filter $(goal),$(MAKECMDGOALS))))
+endef
+
+# List of rules that involve building things
+BUILD_TARGETS := all bl1 bl2 bl31 bl32 fip
+
+# Does the list of goals specified on the command line include a build target?
+ifneq ($(call match_goals,${BUILD_TARGETS}),)
+IS_ANYTHING_TO_BUILD := 1
+endif
+
+define MAKE_C
+
+$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
+$(eval PREREQUISITES := $(patsubst %.o,%.d,$(OBJ)))
+
+$(OBJ) : $(2)
+	@echo "  CC      $$<"
+	$$(Q)$$(CC) $$(CFLAGS) -DIMAGE_BL$(3) -c $$< -o $$@
+
+
+$(PREREQUISITES) : $(2)
+	@echo "  DEPS    $$@"
+	@mkdir -p $(1)
+	$$(Q)$$(CC) $$(CFLAGS) -M -MT $(OBJ) -MF $$@ $$<
+
+ifdef IS_ANYTHING_TO_BUILD
+-include $(PREREQUISITES)
+endif
+
+endef
+
+
+define MAKE_S
+
+$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
+$(eval PREREQUISITES := $(patsubst %.o,%.d,$(OBJ)))
+
+$(OBJ) : $(2)
+	@echo "  AS      $$<"
+	$$(Q)$$(AS) $$(ASFLAGS) -DIMAGE_BL$(3) -c $$< -o $$@
+
+$(PREREQUISITES) : $(2)
+	@echo "  DEPS    $$@"
+	@mkdir -p $(1)
+	$$(Q)$$(AS) $$(ASFLAGS) -M -MT $(OBJ) -MF $$@ $$<
+
+ifdef IS_ANYTHING_TO_BUILD
+-include $(PREREQUISITES)
+endif
+
+endef
+
+
+define MAKE_LD
+
+$(eval PREREQUISITES := $(1).d)
+
+$(1) : $(2)
+	@echo "  PP      $$<"
+	$$(Q)$$(AS) $$(ASFLAGS) -P -E -D__LINKER__ -o $$@ $$<
+
+$(PREREQUISITES) : $(2)
+	@echo "  DEPS    $$@"
+	@mkdir -p $$(dir $$@)
+	$$(Q)$$(AS) $$(ASFLAGS) -M -MT $(1) -MF $$@ $$<
+
+ifdef IS_ANYTHING_TO_BUILD
+-include $(PREREQUISITES)
+endif
+
+endef
+
+
+define MAKE_OBJS
+	$(eval C_OBJS := $(filter %.c,$(2)))
+	$(eval REMAIN := $(filter-out %.c,$(2)))
+	$(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3))))
+
+	$(eval S_OBJS := $(filter %.S,$(REMAIN)))
+	$(eval REMAIN := $(filter-out %.S,$(REMAIN)))
+	$(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3))))
+
+	$(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
+endef
+
+
+# NOTE: The line continuation '\' is required in the next define otherwise we
+# end up with a line-feed characer at the end of the last c filename.
+# Also bare this issue in mind if extending the list of supported filetypes.
+define SOURCES_TO_OBJS
+	$(notdir $(patsubst %.c,%.o,$(filter %.c,$(1)))) \
+	$(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
+endef
+
+
+# MAKE_TOOL_ARGS macro defines the command line arguments for the FIP and CRT
+# tools at each BL stage. Arguments:
+#   $(1) = BL stage (2, 30, 31, 32, 33)
+#   $(2) = Binary file
+#   $(3) = In FIP (false if empty)
+#   $(4) = Create certificates (false if empty)
+#   $(5) = Create key certificate (false if empty)
+#   $(6) = Private key (optional)
+define MAKE_TOOL_ARGS
+
+$(eval FIP_DEPS += $(if $3,$(2),))
+$(eval FIP_ARGS += $(if $3,--bl$(1) $(2),))
+$(eval FIP_ARGS += $(if $4,--bl$(1)-cert $(BUILD_PLAT)/bl$(1).crt))
+$(eval FIP_ARGS += $(if $4,$(if $5,--bl$(1)-key-cert $(BUILD_PLAT)/bl$(1)_key.crt)))
+
+$(eval CRT_DEPS += $(if $4,$(2),))
+$(eval CRT_DEPS += $(if $4,$(if $6,$(6),)))
+$(eval CRT_ARGS += $(if $4,--bl$(1) $(2)))
+$(eval CRT_ARGS += $(if $4,$(if $6,--bl$(1)-key $(6))))
+$(eval CRT_ARGS += $(if $4,--bl$(1)-cert $(BUILD_PLAT)/bl$(1).crt))
+$(eval CRT_ARGS += $(if $4,$(if $5,--bl$(1)-key-cert $(BUILD_PLAT)/bl$(1)_key.crt)))
+
+endef
+
+
+# MAKE_BL macro defines the targets and options to build each BL image.
+# Arguments:
+#   $(1) = BL stage (2, 30, 31, 32, 33)
+#   $(2) = In FIP (false if empty)
+#   $(3) = Create certificates (false if empty)
+#   $(4) = Create key certificate (false if empty)
+#   $(5) = Private key (optional)
+define MAKE_BL
+	$(eval BUILD_DIR  := ${BUILD_PLAT}/bl$(1))
+	$(eval SOURCES    := $(BL$(1)_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES))
+	$(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
+	$(eval LINKERFILE := $(BUILD_DIR)/bl$(1).ld)
+	$(eval MAPFILE    := $(BUILD_DIR)/bl$(1).map)
+	$(eval ELF        := $(BUILD_DIR)/bl$(1).elf)
+	$(eval DUMP       := $(BUILD_DIR)/bl$(1).dump)
+	$(eval BIN        := $(BUILD_PLAT)/bl$(1).bin)
+
+	$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+	$(eval $(call MAKE_LD,$(LINKERFILE),$(BL$(1)_LINKERFILE)))
+
+$(BUILD_DIR) :
+	$$(Q)mkdir -p "$$@"
+
+$(ELF) : $(OBJS) $(LINKERFILE)
+	@echo "  LD      $$@"
+	@echo 'const char build_message[] = "Built : "__TIME__", "__DATE__; \
+	       const char version_string[] = "${VERSION_STRING}";' | \
+		$$(CC) $$(CFLAGS) -xc - -o $(BUILD_DIR)/build_message.o
+	$$(Q)$$(LD) -o $$@ $$(LDFLAGS) -Map=$(MAPFILE) --script $(LINKERFILE) \
+					$(BUILD_DIR)/build_message.o $(OBJS)
+
+$(DUMP) : $(ELF)
+	@echo "  OD      $$@"
+	$${Q}$${OD} -dx $$< > $$@
+
+$(BIN) : $(ELF)
+	@echo "  BIN     $$@"
+	$$(Q)$$(OC) -O binary $$< $$@
+	@echo
+	@echo "Built $$@ successfully"
+	@echo
+
+.PHONY : bl$(1)
+bl$(1) : $(BUILD_DIR) $(BIN) $(DUMP)
+
+all : bl$(1)
+
+$(eval $(call MAKE_TOOL_ARGS,$(1),$(BIN),$(2),$(3),$(4),$(5)))
+
+endef
+
+
+ifeq (${NEED_BL1},yes)
+$(eval $(call MAKE_BL,1))
+endif
+
+ifeq (${NEED_BL2},yes)
+$(if ${BL2}, $(eval $(call MAKE_TOOL_ARGS,2,${BL2},in_fip,${CERTS})),\
+	$(eval $(call MAKE_BL,2,in_fip,${CERTS})))
+endif
+
+ifeq (${NEED_BL31},yes)
+BL31_SOURCES += ${SPD_SOURCES}
+$(if ${BL31}, $(eval $(call MAKE_TOOL_ARGS,31,${BL31},in_fip,${CERTS},${CERTS},${BL31_KEY})),\
+	$(eval $(call MAKE_BL,31,in_fip,${CERTS},${CERTS},${BL31_KEY})))
+endif
+
+ifeq (${NEED_BL32},yes)
+$(if ${BL32}, $(eval $(call MAKE_TOOL_ARGS,32,${BL32},in_fip,${CERTS},${CERTS},${BL32_KEY})),\
+	$(eval $(call MAKE_BL,32,in_fip,${CERTS},${CERTS},${BL32_KEY})))
+endif
+
+ifeq (${NEED_BL30},yes)
+$(if ${BL30}, $(eval $(call MAKE_TOOL_ARGS,30,${BL30},in_fip,${CERTS},${CERTS},${BL30_KEY})))
+
+# If BL3-0 is needed by the platform then 'BL30' variable must be defined.
+check_bl30:
+	$(if ${BL30},,$(error "To build a FIP for platform ${PLAT}, please set BL30 to point to the SCP firmware"))
+else
+
+# If BL3-0 is not needed by the platform but the user still specified the path
+# to a BL3-0 image then warn him that it will be ignored.
+check_bl30:
+	$(if ${BL30},$(warning "BL3-0 is not supported on platform ${PLAT}, it will just be ignored"),)
+endif
+
+ifeq (${NEED_BL33},yes)
+$(if ${BL33}, $(eval $(call MAKE_TOOL_ARGS,33,${BL33},in_fip,${CERTS},${CERTS},${BL33_KEY})))
+
+# If BL3-3 is needed by the platform then 'BL33' variable must be defined.
+check_bl33:
+	$(if ${BL33},,$(error "To build a FIP, please set BL33 to point to the Normal World binary, eg: BL33=../uefi/FVP_AARCH64_EFI.fd"))
+else
+
+# If BL3-3 is not needed by the platform but the user still specified the path
+# to a BL3-3 image then warn him that it will be ignored.
+check_bl33:
+	$(if ${BL33},$(warning "BL3-3 is not supported on platform ${PLAT}, it will just be ignored"),)
+endif
+
+# Add the dependency on the certificates
+ifneq (${GENERATE_COT},0)
+    all: certificates
+endif
+
+certificates: ${CRT_DEPS} ${CRTTOOL} check_bl30 check_bl33
+			${Q}${CRTTOOL} ${CRT_ARGS}
+			@echo
+			@echo "Built $@ successfully"
+			@echo "Certificates can be found in ${BUILD_PLAT}"
+			@echo
+
+${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL} check_bl30 check_bl33
+			${Q}${FIPTOOL} --dump \
+				${FIP_ARGS} \
+				$@
+			@echo
+			@echo "Built $@ successfully"
+			@echo
+
+
+cscope:
+	@echo "  CSCOPE"
+	${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
+	${Q}cscope -b -q -k
+
+help:
+	@echo "usage: ${MAKE} PLAT=<${HELP_PLATFORMS}> <all|bl1|bl2|bl31|distclean|clean|checkcodebase|checkpatch>"
+	@echo ""
+	@echo "PLAT is used to specify which platform you wish to build."
+	@echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
+	@echo ""
+	@echo "Supported Targets:"
+	@echo "  all            Build the BL1, BL2 and BL31 binaries"
+	@echo "  bl1            Build the BL1 binary"
+	@echo "  bl2            Build the BL2 binary"
+	@echo "  bl31           Build the BL31 binary"
+	@echo "  checkcodebase  Check the coding style of the entire source tree"
+	@echo "  checkpatch     Check the coding style on changes in the current"
+	@echo "                 branch against BASE_COMMIT (default origin/master)"
+	@echo "  clean          Clean the build for the selected platform"
+	@echo "  cscope         Generate cscope index"
+	@echo "  distclean      Remove all build artifacts for all platforms"
+	@echo "  certtool       Build the Certificate generation tool"
+	@echo "  fiptool        Build the Firmware Image Package(FIP) creation tool"
+	@echo ""
+	@echo "note: most build targets require PLAT to be set to a specific platform."
+	@echo ""
+	@echo "example: build all targets for the FVP platform:"
+	@echo "  CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all"
diff --git a/uefi/arm-trusted-firmware/acknowledgements.md b/uefi/arm-trusted-firmware/acknowledgements.md
new file mode 100644
index 0000000..a428f2f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/acknowledgements.md
@@ -0,0 +1,9 @@
+Contributor Acknowledgements
+============================
+
+Companies
+---------
+Linaro Limited
+
+Individuals
+-----------
diff --git a/uefi/arm-trusted-firmware/bl1/aarch64/bl1_arch_setup.c b/uefi/arm-trusted-firmware/bl1/aarch64/bl1_arch_setup.c
new file mode 100644
index 0000000..6a3f062
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl1/aarch64/bl1_arch_setup.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+
+/*******************************************************************************
+ * Function that does the first bit of architectural setup that affects
+ * execution in the non-secure address space.
+ ******************************************************************************/
+void bl1_arch_setup(void)
+{
+	/* Set the next EL to be AArch64 */
+	write_scr_el3(SCR_RES1_BITS | SCR_RW_BIT);
+}
+
+/*******************************************************************************
+ * Set the Secure EL1 required architectural state
+ ******************************************************************************/
+void bl1_arch_next_el_setup(void)
+{
+	unsigned long next_sctlr;
+
+	/* Use the same endianness than the current BL */
+	next_sctlr = (read_sctlr_el3() & SCTLR_EE_BIT);
+
+	/* Set SCTLR Secure EL1 */
+	next_sctlr |= SCTLR_EL1_RES1;
+
+	write_sctlr_el1(next_sctlr);
+}
diff --git a/uefi/arm-trusted-firmware/bl1/aarch64/bl1_entrypoint.S b/uefi/arm-trusted-firmware/bl1/aarch64/bl1_entrypoint.S
new file mode 100644
index 0000000..cfc6292
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl1/aarch64/bl1_entrypoint.S
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+	.globl	bl1_entrypoint
+
+
+	/* -----------------------------------------------------
+	 * bl1_entrypoint() is the entry point into the trusted
+	 * firmware code when a cpu is released from warm or
+	 * cold reset.
+	 * -----------------------------------------------------
+	 */
+
+func bl1_entrypoint
+	/* ---------------------------------------------
+	 * Set the CPU endianness before doing anything
+	 * that might involve memory reads or writes.
+	 * ---------------------------------------------
+	 */
+	mrs	x0, sctlr_el3
+	bic	x0, x0, #SCTLR_EE_BIT
+	msr	sctlr_el3, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Perform any processor specific actions upon
+	 * reset e.g. cache, tlb invalidations etc.
+	 * ---------------------------------------------
+	 */
+	bl	reset_handler
+
+	/* ---------------------------------------------
+	 * Enable the instruction cache, stack pointer
+	 * and data access alignment checks
+	 * ---------------------------------------------
+	 */
+	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	mrs	x0, sctlr_el3
+	orr	x0, x0, x1
+	msr	sctlr_el3, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Set the exception vector to something sane.
+	 * ---------------------------------------------
+	 */
+	adr	x0, bl1_exceptions
+	msr	vbar_el3, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Enable the SError interrupt now that the
+	 * exception vectors have been setup.
+	 * ---------------------------------------------
+	 */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	/* ---------------------------------------------------------------------
+	 * The initial state of the Architectural feature trap register
+	 * (CPTR_EL3) is unknown and it must be set to a known state. All
+	 * feature traps are disabled. Some bits in this register are marked as
+	 * Reserved and should not be modified.
+	 *
+	 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
+	 *  or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
+	 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
+	 *  to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
+	 *  access to trace functionality is not supported, this bit is RES0.
+	 * CPTR_EL3.TFP: This causes instructions that access the registers
+	 *  associated with Floating Point and Advanced SIMD execution to trap
+	 *  to EL3 when executed from any exception level, unless trapped to EL1
+	 *  or EL2.
+	 * ---------------------------------------------------------------------
+	 */
+	mrs	x0, cptr_el3
+	bic	w0, w0, #TCPAC_BIT
+	bic	w0, w0, #TTA_BIT
+	bic	w0, w0, #TFP_BIT
+	msr	cptr_el3, x0
+
+	/* -------------------------------------------------------
+	 * Will not return from this macro if it is a warm boot.
+	 * -------------------------------------------------------
+	 */
+	wait_for_entrypoint
+
+	bl	platform_mem_init
+
+	/* ---------------------------------------------
+	 * Init C runtime environment.
+	 *   - Zero-initialise the NOBITS sections.
+	 *     There are 2 of them:
+	 *       - the .bss section;
+	 *       - the coherent memory section.
+	 *   - Copy the data section from BL1 image
+	 *     (stored in ROM) to the correct location
+	 *     in RAM.
+	 * ---------------------------------------------
+	 */
+	ldr	x0, =__BSS_START__
+	ldr	x1, =__BSS_SIZE__
+	bl	zeromem16
+
+#if USE_COHERENT_MEM
+	ldr	x0, =__COHERENT_RAM_START__
+	ldr	x1, =__COHERENT_RAM_UNALIGNED_SIZE__
+	bl	zeromem16
+#endif
+
+	ldr	x0, =__DATA_RAM_START__
+	ldr	x1, =__DATA_ROM_START__
+	ldr	x2, =__DATA_SIZE__
+	bl	memcpy16
+
+	/* --------------------------------------------
+	 * Allocate a stack whose memory will be marked
+	 * as Normal-IS-WBWA when the MMU is enabled.
+	 * There is no risk of reading stale stack
+	 * memory after enabling the MMU as only the
+	 * primary cpu is running at the moment.
+	 * --------------------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	bl	platform_set_stack
+
+	/* ---------------------------------------------
+	 * Architectural init. can be generic e.g.
+	 * enabling stack alignment and platform spec-
+	 * ific e.g. MMU & page table setup as per the
+	 * platform memory map. Perform the latter here
+	 * and the former in bl1_main.
+	 * ---------------------------------------------
+	 */
+	bl	bl1_early_platform_setup
+	bl	bl1_plat_arch_setup
+
+	/* --------------------------------------------------
+	 * Initialize platform and jump to our c-entry point
+	 * for this type of reset. Panic if it returns
+	 * --------------------------------------------------
+	 */
+	bl	bl1_main
+panic:
+	b	panic
diff --git a/uefi/arm-trusted-firmware/bl1/aarch64/bl1_exceptions.S b/uefi/arm-trusted-firmware/bl1/aarch64/bl1_exceptions.S
new file mode 100644
index 0000000..1ca3a6c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl1/aarch64/bl1_exceptions.S
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+#include <runtime_svc.h>
+
+	.globl	bl1_exceptions
+
+	.section	.vectors, "ax"; .align 11
+
+	/* -----------------------------------------------------
+	 * Very simple stackless exception handlers used by BL1.
+	 * -----------------------------------------------------
+	 */
+	.align	7
+bl1_exceptions:
+	/* -----------------------------------------------------
+	 * Current EL with SP0 : 0x0 - 0x200
+	 * -----------------------------------------------------
+	 */
+SynchronousExceptionSP0:
+	mov	x0, #SYNC_EXCEPTION_SP_EL0
+	bl	plat_report_exception
+	b	SynchronousExceptionSP0
+	check_vector_size SynchronousExceptionSP0
+
+	.align	7
+IrqSP0:
+	mov	x0, #IRQ_SP_EL0
+	bl	plat_report_exception
+	b	IrqSP0
+	check_vector_size IrqSP0
+
+	.align	7
+FiqSP0:
+	mov	x0, #FIQ_SP_EL0
+	bl	plat_report_exception
+	b	FiqSP0
+	check_vector_size FiqSP0
+
+	.align	7
+SErrorSP0:
+	mov	x0, #SERROR_SP_EL0
+	bl	plat_report_exception
+	b	SErrorSP0
+	check_vector_size SErrorSP0
+
+	/* -----------------------------------------------------
+	 * Current EL with SPx: 0x200 - 0x400
+	 * -----------------------------------------------------
+	 */
+	.align	7
+SynchronousExceptionSPx:
+	mov	x0, #SYNC_EXCEPTION_SP_ELX
+	bl	plat_report_exception
+	b	SynchronousExceptionSPx
+	check_vector_size SynchronousExceptionSPx
+
+	.align	7
+IrqSPx:
+	mov	x0, #IRQ_SP_ELX
+	bl	plat_report_exception
+	b	IrqSPx
+	check_vector_size IrqSPx
+
+	.align	7
+FiqSPx:
+	mov	x0, #FIQ_SP_ELX
+	bl	plat_report_exception
+	b	FiqSPx
+	check_vector_size FiqSPx
+
+	.align	7
+SErrorSPx:
+	mov	x0, #SERROR_SP_ELX
+	bl	plat_report_exception
+	b	SErrorSPx
+	check_vector_size SErrorSPx
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch64 : 0x400 - 0x600
+	 * -----------------------------------------------------
+	 */
+	.align	7
+SynchronousExceptionA64:
+	/* Enable the SError interrupt */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	/* ------------------------------------------------
+	 * Only a single SMC exception from BL2 to ask
+	 * BL1 to pass EL3 control to BL31 is expected
+	 * here.
+	 * It expects X0 with RUN_IMAGE SMC function id
+	 * X1 with address of a entry_point_info_t structure
+	 * describing the BL3-1 entrypoint
+	 * ------------------------------------------------
+	 */
+	mov	x19, x0
+	mov	x20, x1
+
+	mrs	x0, esr_el3
+	ubfx	x1, x0, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+	cmp	x1, #EC_AARCH64_SMC
+	b.ne	panic
+
+	mov	x0, #RUN_IMAGE
+	cmp	x19, x0
+	b.ne	panic
+
+	mov	x0, x20
+	bl	display_boot_progress
+
+	ldp	x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
+	msr	elr_el3, x0
+	msr	spsr_el3, x1
+	ubfx	x0, x1, #MODE_EL_SHIFT, #2
+	cmp	x0, #MODE_EL3
+	b.ne	panic
+
+	bl	disable_mmu_icache_el3
+	tlbi	alle3
+
+	ldp	x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
+	ldp	x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
+	ldp	x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
+	ldp	x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
+	eret
+panic:
+	mov	x0, #SYNC_EXCEPTION_AARCH64
+	bl	plat_report_exception
+
+	wfi
+	b	panic
+	check_vector_size SynchronousExceptionA64
+
+	.align	7
+IrqA64:
+	mov	x0, #IRQ_AARCH64
+	bl	plat_report_exception
+	b	IrqA64
+	check_vector_size IrqA64
+
+	.align	7
+FiqA64:
+	mov	x0, #FIQ_AARCH64
+	bl	plat_report_exception
+	b	FiqA64
+	check_vector_size FiqA64
+
+	.align	7
+SErrorA64:
+	mov	x0, #SERROR_AARCH64
+	bl	plat_report_exception
+	b   	SErrorA64
+	check_vector_size SErrorA64
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch32 : 0x600 - 0x800
+	 * -----------------------------------------------------
+	 */
+	.align	7
+SynchronousExceptionA32:
+	mov	x0, #SYNC_EXCEPTION_AARCH32
+	bl	plat_report_exception
+	b	SynchronousExceptionA32
+	check_vector_size SynchronousExceptionA32
+
+	.align	7
+IrqA32:
+	mov	x0, #IRQ_AARCH32
+	bl	plat_report_exception
+	b	IrqA32
+	check_vector_size IrqA32
+
+	.align	7
+FiqA32:
+	mov	x0, #FIQ_AARCH32
+	bl	plat_report_exception
+	b	FiqA32
+	check_vector_size FiqA32
+
+	.align	7
+SErrorA32:
+	mov	x0, #SERROR_AARCH32
+	bl	plat_report_exception
+	b	SErrorA32
+	check_vector_size SErrorA32
diff --git a/uefi/arm-trusted-firmware/bl1/bl1.ld.S b/uefi/arm-trusted-firmware/bl1/bl1.ld.S
new file mode 100644
index 0000000..d682384
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl1/bl1.ld.S
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <platform_def.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(bl1_entrypoint)
+
+MEMORY {
+    ROM (rx): ORIGIN = BL1_RO_BASE, LENGTH = BL1_RO_LIMIT - BL1_RO_BASE
+    RAM (rwx): ORIGIN = BL1_RW_BASE, LENGTH = BL1_RW_LIMIT - BL1_RW_BASE
+}
+
+SECTIONS
+{
+    . = BL1_RO_BASE;
+    ASSERT(. == ALIGN(4096),
+           "BL1_RO_BASE address is not aligned on a page boundary.")
+
+    ro . : {
+        __RO_START__ = .;
+        *bl1_entrypoint.o(.text*)
+        *(.text*)
+        *(.rodata*)
+
+        /*
+         * Ensure 8-byte alignment for cpu_ops so that its fields are also
+         * aligned. Also ensure cpu_ops inclusion.
+         */
+        . = ALIGN(8);
+        __CPU_OPS_START__ = .;
+        KEEP(*(cpu_ops))
+        __CPU_OPS_END__ = .;
+
+        *(.vectors)
+        __RO_END__ = .;
+    } >ROM
+
+    ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
+           "cpu_ops not defined for this platform.")
+
+    /*
+     * The .data section gets copied from ROM to RAM at runtime.
+     * Its LMA must be 16-byte aligned.
+     * Its VMA must be page-aligned as it marks the first read/write page.
+     */
+    . = BL1_RW_BASE;
+    ASSERT(. == ALIGN(4096),
+           "BL1_RW_BASE address is not aligned on a page boundary.")
+    .data . : ALIGN(16) {
+        __DATA_RAM_START__ = .;
+        *(.data*)
+        __DATA_RAM_END__ = .;
+    } >RAM AT>ROM
+
+    stacks . (NOLOAD) : {
+        __STACKS_START__ = .;
+        *(tzfw_normal_stacks)
+        __STACKS_END__ = .;
+    } >RAM
+
+    /*
+     * The .bss section gets initialised to 0 at runtime.
+     * Its base address must be 16-byte aligned.
+     */
+    .bss : ALIGN(16) {
+        __BSS_START__ = .;
+        *(.bss*)
+        *(COMMON)
+        __BSS_END__ = .;
+    } >RAM
+
+    /*
+     * The xlat_table section is for full, aligned page tables (4K).
+     * Removing them from .bss avoids forcing 4K alignment on
+     * the .bss section and eliminates the unecessary zero init
+     */
+    xlat_table (NOLOAD) : {
+        *(xlat_table)
+    } >RAM
+
+#if USE_COHERENT_MEM
+    /*
+     * The base address of the coherent memory section must be page-aligned (4K)
+     * to guarantee that the coherent data are stored on their own pages and
+     * are not mixed with normal data.  This is required to set up the correct
+     * memory attributes for the coherent data page tables.
+     */
+    coherent_ram (NOLOAD) : ALIGN(4096) {
+        __COHERENT_RAM_START__ = .;
+        *(tzfw_coherent_mem)
+        __COHERENT_RAM_END_UNALIGNED__ = .;
+        /*
+         * Memory page(s) mapped to this section will be marked
+         * as device memory.  No other unexpected data must creep in.
+         * Ensure the rest of the current memory page is unused.
+         */
+        . = NEXT(4096);
+        __COHERENT_RAM_END__ = .;
+    } >RAM
+#endif
+
+    __BL1_RAM_START__ = ADDR(.data);
+    __BL1_RAM_END__ = .;
+
+    __DATA_ROM_START__ = LOADADDR(.data);
+    __DATA_SIZE__ = SIZEOF(.data);
+    /*
+     * The .data section is the last PROGBITS section so its end marks the end
+     * of the read-only part of BL1's binary.
+     */
+    ASSERT(__DATA_ROM_START__ + __DATA_SIZE__ <= BL1_RO_LIMIT,
+           "BL1's RO section has exceeded its limit.")
+
+    __BSS_SIZE__ = SIZEOF(.bss);
+
+#if USE_COHERENT_MEM
+    __COHERENT_RAM_UNALIGNED_SIZE__ =
+        __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
+#endif
+
+    ASSERT(. <= BL1_RW_LIMIT, "BL1's RW section has exceeded its limit.")
+}
diff --git a/uefi/arm-trusted-firmware/bl1/bl1.mk b/uefi/arm-trusted-firmware/bl1/bl1.mk
new file mode 100644
index 0000000..8e73bef
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl1/bl1.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BL1_SOURCES		+=	bl1/bl1_main.c				\
+				bl1/aarch64/bl1_arch_setup.c		\
+				bl1/aarch64/bl1_entrypoint.S		\
+				bl1/aarch64/bl1_exceptions.S		\
+				lib/cpus/aarch64/cpu_helpers.S
+
+BL1_LINKERFILE		:=	bl1/bl1.ld.S
diff --git a/uefi/arm-trusted-firmware/bl1/bl1_main.c b/uefi/arm-trusted-firmware/bl1/bl1_main.c
new file mode 100644
index 0000000..491fd5c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl1/bl1_main.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <auth.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <platform.h>
+#include <platform_def.h>
+#include "bl1_private.h"
+
+/*******************************************************************************
+ * Runs BL2 from the given entry point. It results in dropping the
+ * exception level
+ ******************************************************************************/
+static void __dead2 bl1_run_bl2(entry_point_info_t *bl2_ep)
+{
+	bl1_arch_next_el_setup();
+
+	/* Tell next EL what we want done */
+	bl2_ep->args.arg0 = RUN_IMAGE;
+
+	if (GET_SECURITY_STATE(bl2_ep->h.attr) == NON_SECURE)
+		change_security_state(GET_SECURITY_STATE(bl2_ep->h.attr));
+
+	write_spsr_el3(bl2_ep->spsr);
+	write_elr_el3(bl2_ep->pc);
+
+	eret(bl2_ep->args.arg0,
+		bl2_ep->args.arg1,
+		bl2_ep->args.arg2,
+		bl2_ep->args.arg3,
+		bl2_ep->args.arg4,
+		bl2_ep->args.arg5,
+		bl2_ep->args.arg6,
+		bl2_ep->args.arg7);
+}
+
+/*******************************************************************************
+ * The next function has a weak definition. Platform specific code can override
+ * it if it wishes to.
+ ******************************************************************************/
+#pragma weak bl1_init_bl2_mem_layout
+
+/*******************************************************************************
+ * Function that takes a memory layout into which BL2 has been loaded and
+ * populates a new memory layout for BL2 that ensures that BL1's data sections
+ * resident in secure RAM are not visible to BL2.
+ ******************************************************************************/
+void bl1_init_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
+			     meminfo_t *bl2_mem_layout)
+{
+	const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
+
+	assert(bl1_mem_layout != NULL);
+	assert(bl2_mem_layout != NULL);
+
+	/* Check that BL1's memory is lying outside of the free memory */
+	assert((BL1_RAM_LIMIT <= bl1_mem_layout->free_base) ||
+	       (BL1_RAM_BASE >= bl1_mem_layout->free_base + bl1_mem_layout->free_size));
+
+	/* Remove BL1 RW data from the scope of memory visible to BL2 */
+	*bl2_mem_layout = *bl1_mem_layout;
+	reserve_mem(&bl2_mem_layout->total_base,
+		    &bl2_mem_layout->total_size,
+		    BL1_RAM_BASE,
+		    bl1_size);
+
+	flush_dcache_range((unsigned long)bl2_mem_layout, sizeof(meminfo_t));
+}
+
+/*******************************************************************************
+ * Function to perform late architectural and platform specific initialization.
+ * It also locates and loads the BL2 raw binary image in the trusted DRAM. Only
+ * called by the primary cpu after a cold boot.
+ * TODO: Add support for alternative image load mechanism e.g using virtio/elf
+ * loader etc.
+  ******************************************************************************/
+void bl1_main(void)
+{
+	/* Announce our arrival */
+	NOTICE(FIRMWARE_WELCOME_STR);
+	NOTICE("BL1: %s\n", version_string);
+	NOTICE("BL1: %s\n", build_message);
+
+	INFO("BL1: RAM 0x%lx - 0x%lx\n", BL1_RAM_BASE, BL1_RAM_LIMIT);
+
+#if DEBUG
+	unsigned long sctlr_el3 = read_sctlr_el3();
+#endif
+	image_info_t bl2_image_info = { {0} };
+	entry_point_info_t bl2_ep = { {0} };
+	meminfo_t *bl1_tzram_layout;
+	meminfo_t *bl2_tzram_layout = 0x0;
+	int err;
+
+	/*
+	 * Ensure that MMU/Caches and coherency are turned on
+	 */
+	assert(sctlr_el3 | SCTLR_M_BIT);
+	assert(sctlr_el3 | SCTLR_C_BIT);
+	assert(sctlr_el3 | SCTLR_I_BIT);
+
+	/* Perform remaining generic architectural setup from EL3 */
+	bl1_arch_setup();
+
+	/* Perform platform setup in BL1. */
+	bl1_platform_setup();
+
+	SET_PARAM_HEAD(&bl2_image_info, PARAM_IMAGE_BINARY, VERSION_1, 0);
+	SET_PARAM_HEAD(&bl2_ep, PARAM_EP, VERSION_1, 0);
+
+	/* Find out how much free trusted ram remains after BL1 load */
+	bl1_tzram_layout = bl1_plat_sec_mem_layout();
+
+#if TRUSTED_BOARD_BOOT
+	/* Initialize authentication module */
+	auth_init();
+
+	/*
+	 * Load the BL2 certificate into the BL2 region. This region will be
+	 * overwritten by the image, so the authentication module is responsible
+	 * for storing the relevant data from the certificate (keys, hashes,
+	 * etc.) so it can be used later.
+	 */
+	err = load_image(bl1_tzram_layout,
+			 BL2_CERT_NAME,
+			 BL2_BASE,
+			 &bl2_image_info,
+			 NULL);
+	if (err) {
+		ERROR("Failed to load BL2 certificate.\n");
+		panic();
+	}
+
+	err = auth_verify_obj(AUTH_BL2_IMG_CERT, bl2_image_info.image_base,
+			bl2_image_info.image_size);
+	if (err) {
+		ERROR("Failed to validate BL2 certificate.\n");
+		panic();
+	}
+#endif /* TRUSTED_BOARD_BOOT */
+
+	/* Load the BL2 image */
+	err = load_image(bl1_tzram_layout,
+			 BL2_IMAGE_NAME,
+			 BL2_BASE,
+			 &bl2_image_info,
+			 &bl2_ep);
+	if (err) {
+		/*
+		 * TODO: print failure to load BL2 but also add a tzwdog timer
+		 * which will reset the system eventually.
+		 */
+		ERROR("Failed to load BL2 firmware.\n");
+		panic();
+	}
+
+#if TRUSTED_BOARD_BOOT
+	err = auth_verify_obj(AUTH_BL2_IMG, bl2_image_info.image_base,
+				bl2_image_info.image_size);
+	if (err) {
+		ERROR("Failed to validate BL2 image.\n");
+		panic();
+	}
+
+	/* After working with data, invalidate the data cache */
+	inv_dcache_range(bl2_image_info.image_base,
+			(size_t)bl2_image_info.image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
+	/*
+	 * Create a new layout of memory for BL2 as seen by BL1 i.e.
+	 * tell it the amount of total and free memory available.
+	 * This layout is created at the first free address visible
+	 * to BL2. BL2 will read the memory layout before using its
+	 * memory for other purposes.
+	 */
+	bl2_tzram_layout = (meminfo_t *) bl1_tzram_layout->free_base;
+	bl1_init_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout);
+
+	bl1_plat_set_bl2_ep_info(&bl2_image_info, &bl2_ep);
+	bl2_ep.args.arg1 = (unsigned long)bl2_tzram_layout;
+	NOTICE("BL1: Booting BL2\n");
+	INFO("BL1: BL2 address = 0x%llx\n",
+		(unsigned long long) bl2_ep.pc);
+	INFO("BL1: BL2 spsr = 0x%x\n", bl2_ep.spsr);
+	VERBOSE("BL1: BL2 memory layout address = 0x%llx\n",
+		(unsigned long long) bl2_tzram_layout);
+
+	bl1_run_bl2(&bl2_ep);
+
+	return;
+}
+
+/*******************************************************************************
+ * Temporary function to print the fact that BL2 has done its job and BL31 is
+ * about to be loaded. This is needed as long as printfs cannot be used
+ ******************************************************************************/
+void display_boot_progress(entry_point_info_t *bl31_ep_info)
+{
+	NOTICE("BL1: Booting BL3-1\n");
+	INFO("BL1: BL3-1 address = 0x%llx\n",
+		(unsigned long long)bl31_ep_info->pc);
+	INFO("BL1: BL3-1 spsr = 0x%llx\n",
+		(unsigned long long)bl31_ep_info->spsr);
+	INFO("BL1: BL3-1 params address = 0x%llx\n",
+		(unsigned long long)bl31_ep_info->args.arg0);
+	INFO("BL1: BL3-1 plat params address = 0x%llx\n",
+		(unsigned long long)bl31_ep_info->args.arg1);
+}
diff --git a/uefi/arm-trusted-firmware/bl1/bl1_private.h b/uefi/arm-trusted-firmware/bl1/bl1_private.h
new file mode 100644
index 0000000..0a8fc45
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl1/bl1_private.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BL1_PRIVATE_H__
+#define __BL1_PRIVATE_H__
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will tell us where BL1 lives
+ * in Trusted RAM
+ ******************************************************************************/
+extern uint64_t __BL1_RAM_START__;
+extern uint64_t __BL1_RAM_END__;
+#define BL1_RAM_BASE (uint64_t)(&__BL1_RAM_START__)
+#define BL1_RAM_LIMIT (uint64_t)(&__BL1_RAM_END__)
+
+/******************************************
+ * Function prototypes
+ *****************************************/
+void bl1_arch_setup(void);
+void bl1_arch_next_el_setup(void);
+
+#endif /* __BL1_PRIVATE_H__ */
diff --git a/uefi/arm-trusted-firmware/bl2/aarch64/bl2_arch_setup.c b/uefi/arm-trusted-firmware/bl2/aarch64/bl2_arch_setup.c
new file mode 100644
index 0000000..0eafd15
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl2/aarch64/bl2_arch_setup.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+
+/*******************************************************************************
+ * Place holder function to perform any S-EL1 specific architectural setup. At
+ * the moment there is nothing to do.
+ ******************************************************************************/
+void bl2_arch_setup(void)
+{
+	/* Give access to FP/SIMD registers */
+	write_cpacr(CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
+}
diff --git a/uefi/arm-trusted-firmware/bl2/aarch64/bl2_entrypoint.S b/uefi/arm-trusted-firmware/bl2/aarch64/bl2_entrypoint.S
new file mode 100644
index 0000000..499dc37
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl2/aarch64/bl2_entrypoint.S
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+
+
+	.globl	bl2_entrypoint
+
+
+
+func bl2_entrypoint
+	/*---------------------------------------------
+	 * Store the extents of the tzram available to
+	 * BL2 for future use. Use the opcode param to
+	 * allow implement other functions if needed.
+	 * ---------------------------------------------
+	 */
+	mov	x20, x0
+	mov	x21, x1
+
+	/* ---------------------------------------------
+	 * Set the exception vector to something sane.
+	 * ---------------------------------------------
+	 */
+	adr	x0, early_exceptions
+	msr	vbar_el1, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Enable the SError interrupt now that the
+	 * exception vectors have been setup.
+	 * ---------------------------------------------
+	 */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	/* ---------------------------------------------
+	 * Enable the instruction cache, stack pointer
+	 * and data access alignment checks
+	 * ---------------------------------------------
+	 */
+	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	mrs	x0, sctlr_el1
+	orr	x0, x0, x1
+	msr	sctlr_el1, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Check the opcodes out of paranoia.
+	 * ---------------------------------------------
+	 */
+	mov	x0, #RUN_IMAGE
+	cmp	x0, x20
+	b.ne	_panic
+
+	/* ---------------------------------------------
+	 * Zero out NOBITS sections. There are 2 of them:
+	 *   - the .bss section;
+	 *   - the coherent memory section.
+	 * ---------------------------------------------
+	 */
+	ldr	x0, =__BSS_START__
+	ldr	x1, =__BSS_SIZE__
+	bl	zeromem16
+
+#if USE_COHERENT_MEM
+	ldr	x0, =__COHERENT_RAM_START__
+	ldr	x1, =__COHERENT_RAM_UNALIGNED_SIZE__
+	bl	zeromem16
+#endif
+
+	/* --------------------------------------------
+	 * Allocate a stack whose memory will be marked
+	 * as Normal-IS-WBWA when the MMU is enabled.
+	 * There is no risk of reading stale stack
+	 * memory after enabling the MMU as only the
+	 * primary cpu is running at the moment.
+	 * --------------------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	bl	platform_set_stack
+
+	/* ---------------------------------------------
+	 * Perform early platform setup & platform
+	 * specific early arch. setup e.g. mmu setup
+	 * ---------------------------------------------
+	 */
+	mov	x0, x21
+	bl	bl2_early_platform_setup
+	bl	bl2_plat_arch_setup
+
+	/* ---------------------------------------------
+	 * Jump to main function.
+	 * ---------------------------------------------
+	 */
+	bl	bl2_main
+_panic:
+	b	_panic
diff --git a/uefi/arm-trusted-firmware/bl2/bl2.ld.S b/uefi/arm-trusted-firmware/bl2/bl2.ld.S
new file mode 100644
index 0000000..9933339
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl2/bl2.ld.S
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <platform_def.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(bl2_entrypoint)
+
+MEMORY {
+    RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+}
+
+
+SECTIONS
+{
+    . = BL2_BASE;
+    ASSERT(. == ALIGN(4096),
+           "BL2_BASE address is not aligned on a page boundary.")
+
+    ro . : {
+        __RO_START__ = .;
+        *bl2_entrypoint.o(.text*)
+        *(.text*)
+        *(.rodata*)
+        *(.vectors)
+        __RO_END_UNALIGNED__ = .;
+        /*
+         * Memory page(s) mapped to this section will be marked as
+         * read-only, executable.  No RW data from the next section must
+         * creep in.  Ensure the rest of the current memory page is unused.
+         */
+        . = NEXT(4096);
+        __RO_END__ = .;
+    } >RAM
+
+    .data . : {
+        __DATA_START__ = .;
+        *(.data*)
+        __DATA_END__ = .;
+    } >RAM
+
+    stacks (NOLOAD) : {
+        __STACKS_START__ = .;
+        *(tzfw_normal_stacks)
+        __STACKS_END__ = .;
+    } >RAM
+
+    /*
+     * The .bss section gets initialised to 0 at runtime.
+     * Its base address must be 16-byte aligned.
+     */
+    .bss : ALIGN(16) {
+        __BSS_START__ = .;
+        *(SORT_BY_ALIGNMENT(.bss*))
+        *(COMMON)
+        __BSS_END__ = .;
+    } >RAM
+
+    /*
+     * The xlat_table section is for full, aligned page tables (4K).
+     * Removing them from .bss avoids forcing 4K alignment on
+     * the .bss section and eliminates the unecessary zero init
+     */
+    xlat_table (NOLOAD) : {
+        *(xlat_table)
+    } >RAM
+
+#if USE_COHERENT_MEM
+    /*
+     * The base address of the coherent memory section must be page-aligned (4K)
+     * to guarantee that the coherent data are stored on their own pages and
+     * are not mixed with normal data.  This is required to set up the correct
+     * memory attributes for the coherent data page tables.
+     */
+    coherent_ram (NOLOAD) : ALIGN(4096) {
+        __COHERENT_RAM_START__ = .;
+        *(tzfw_coherent_mem)
+        __COHERENT_RAM_END_UNALIGNED__ = .;
+        /*
+         * Memory page(s) mapped to this section will be marked
+         * as device memory.  No other unexpected data must creep in.
+         * Ensure the rest of the current memory page is unused.
+         */
+        . = NEXT(4096);
+        __COHERENT_RAM_END__ = .;
+    } >RAM
+#endif
+
+    __BL2_END__ = .;
+
+    __BSS_SIZE__ = SIZEOF(.bss);
+
+#if USE_COHERENT_MEM
+    __COHERENT_RAM_UNALIGNED_SIZE__ =
+        __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
+#endif
+
+    ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
+}
diff --git a/uefi/arm-trusted-firmware/bl2/bl2.mk b/uefi/arm-trusted-firmware/bl2/bl2.mk
new file mode 100644
index 0000000..1e82078
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl2/bl2.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BL2_SOURCES		+=	bl2/bl2_main.c				\
+				bl2/aarch64/bl2_entrypoint.S		\
+				bl2/aarch64/bl2_arch_setup.c		\
+				common/aarch64/early_exceptions.S	\
+				lib/locks/exclusive/spinlock.S
+
+BL2_LINKERFILE		:=	bl2/bl2.ld.S
diff --git a/uefi/arm-trusted-firmware/bl2/bl2_main.c b/uefi/arm-trusted-firmware/bl2/bl2_main.c
new file mode 100644
index 0000000..5b1e69c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl2/bl2_main.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <auth.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <platform.h>
+#include <platform_def.h>
+#include "bl2_private.h"
+
+#if TRUSTED_BOARD_BOOT
+
+#ifdef BL32_BASE
+static int bl32_cert_error;
+#endif
+
+/*
+ * Load and authenticate the key and content certificates for a BL3-x image
+ *
+ * Parameters:
+ *   key_cert_blob: key certificate blob id (see auth.h)
+ *   key_cert_name: key certificate filename
+ *   cont_cert_blob: content certificate blob id (see auth.h)
+ *   cont_cert_name: content certificate filename
+ *   mem_layout: Trusted SRAM memory layout
+ *   load_addr: load the certificates at this address
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+static int load_cert_bl3x(int key_cert_blob, const char *key_cert_name,
+			  int cont_cert_blob, const char *cont_cert_name,
+			  meminfo_t *mem_layout, uint64_t load_addr)
+{
+	image_info_t image_info;
+	int err;
+
+	/* Load Key certificate */
+	image_info.h.version = VERSION_1;
+	err = load_image(mem_layout, key_cert_name, load_addr, &image_info, NULL);
+	if (err) {
+		ERROR("Cannot load %s.\n", key_cert_name);
+		return err;
+	}
+
+	err = auth_verify_obj(key_cert_blob, image_info.image_base,
+			image_info.image_size);
+	if (err) {
+		ERROR("Invalid key certificate %s.\n", key_cert_name);
+		return err;
+	}
+
+	/* Load Content certificate */
+	image_info.h.version = VERSION_1;
+	err = load_image(mem_layout, cont_cert_name, load_addr, &image_info, NULL);
+	if (err) {
+		ERROR("Cannot load %s.\n", cont_cert_name);
+		return err;
+	}
+
+	err = auth_verify_obj(cont_cert_blob, image_info.image_base,
+			image_info.image_size);
+	if (err) {
+		ERROR("Invalid content certificate %s.\n", cont_cert_name);
+		return err;
+	}
+
+	return 0;
+}
+
+/*
+ * Load and authenticate the Trusted Key certificate the key and content
+ * certificates for each of the BL3-x images.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+static int load_certs(void)
+{
+	const uint64_t load_addr = BL31_BASE;
+	image_info_t image_info;
+	meminfo_t *mem_layout;
+	int err;
+
+	/* Find out how much free trusted ram remains after BL2 load */
+	mem_layout = bl2_plat_sec_mem_layout();
+
+	/* Load the Trusted Key certificate in the BL31 region */
+	image_info.h.version = VERSION_1;
+	err = load_image(mem_layout, TRUSTED_KEY_CERT_NAME, load_addr,
+			 &image_info, NULL);
+	if (err) {
+		ERROR("Failed to load Trusted Key certificate.\n");
+		return err;
+	}
+
+	/* Validate the certificate */
+	err = auth_verify_obj(AUTH_TRUSTED_KEY_CERT, image_info.image_base,
+			image_info.image_size);
+	if (err) {
+		ERROR("Invalid Trusted Key certificate.\n");
+		return err;
+	}
+
+	/* Load and validate Key and Content certificates for BL3-x images */
+#ifdef BL30_BASE
+	err = load_cert_bl3x(AUTH_BL30_KEY_CERT, BL30_KEY_CERT_NAME,
+			     AUTH_BL30_IMG_CERT, BL30_CERT_NAME,
+			     mem_layout, load_addr);
+	if (err) {
+		ERROR("Failed to verify BL3-0 authenticity\n");
+		return err;
+	}
+#endif /* BL30_BASE */
+
+	err = load_cert_bl3x(AUTH_BL31_KEY_CERT, BL31_KEY_CERT_NAME,
+			     AUTH_BL31_IMG_CERT, BL31_CERT_NAME,
+			     mem_layout, load_addr);
+	if (err) {
+		ERROR("Failed to verify BL3-1 authenticity\n");
+		return err;
+	}
+
+#ifdef BL32_BASE
+	/* BL3-2 image is optional, but keep the return value in case the
+	 * image is present but the certificate is missing */
+	err = load_cert_bl3x(AUTH_BL32_KEY_CERT, BL32_KEY_CERT_NAME,
+			     AUTH_BL32_IMG_CERT, BL32_CERT_NAME,
+			     mem_layout, load_addr);
+	if (err) {
+		WARN("Failed to verify BL3-2 authenticity\n");
+	}
+	bl32_cert_error = err;
+#endif /* BL32_BASE */
+
+	err = load_cert_bl3x(AUTH_BL33_KEY_CERT, BL33_KEY_CERT_NAME,
+			     AUTH_BL33_IMG_CERT, BL33_CERT_NAME,
+			     mem_layout, load_addr);
+	if (err) {
+		ERROR("Failed to verify BL3-3 authenticity\n");
+		return err;
+	}
+
+	return 0;
+}
+
+#endif /* TRUSTED_BOARD_BOOT */
+
+/*******************************************************************************
+ * Load the BL3-0 image if there's one.
+ * If a platform does not want to attempt to load BL3-0 image it must leave
+ * BL30_BASE undefined.
+ * Return 0 on success or if there's no BL3-0 image to load, a negative error
+ * code otherwise.
+ ******************************************************************************/
+static int load_bl30(void)
+{
+	int e = 0;
+#ifdef BL30_BASE
+	meminfo_t bl30_mem_info;
+	image_info_t bl30_image_info;
+
+	/*
+	 * It is up to the platform to specify where BL3-0 should be loaded if
+	 * it exists. It could create space in the secure sram or point to a
+	 * completely different memory.
+	 *
+	 * The entry point information is not relevant in this case as the AP
+	 * won't execute the BL3-0 image.
+	 */
+	INFO("BL2: Loading BL3-0\n");
+	bl2_plat_get_bl30_meminfo(&bl30_mem_info);
+	bl30_image_info.h.version = VERSION_1;
+	e = load_image(&bl30_mem_info,
+		       BL30_IMAGE_NAME,
+		       BL30_BASE,
+		       &bl30_image_info,
+		       NULL);
+
+	if (e == 0) {
+#if TRUSTED_BOARD_BOOT
+		e = auth_verify_obj(AUTH_BL30_IMG,
+				bl30_image_info.image_base,
+				bl30_image_info.image_size);
+		if (e) {
+			ERROR("Failed to authenticate BL3-0 image.\n");
+			panic();
+		}
+
+		/* After working with data, invalidate the data cache */
+		inv_dcache_range(bl30_image_info.image_base,
+				 (size_t)bl30_image_info.image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
+		/* The subsequent handling of BL3-0 is platform specific */
+		bl2_plat_handle_bl30(&bl30_image_info);
+	}
+#endif /* BL30_BASE */
+
+	return e;
+}
+
+/*******************************************************************************
+ * Load the BL3-1 image.
+ * The bl2_to_bl31_params and bl31_ep_info params will be updated with the
+ * relevant BL3-1 information.
+ * Return 0 on success, a negative error code otherwise.
+ ******************************************************************************/
+static int load_bl31(bl31_params_t *bl2_to_bl31_params,
+		     entry_point_info_t *bl31_ep_info)
+{
+	meminfo_t *bl2_tzram_layout;
+	int e;
+
+	INFO("BL2: Loading BL3-1\n");
+	assert(bl2_to_bl31_params != NULL);
+	assert(bl31_ep_info != NULL);
+
+	/* Find out how much free trusted ram remains after BL2 load */
+	bl2_tzram_layout = bl2_plat_sec_mem_layout();
+
+	/* Set the X0 parameter to BL3-1 */
+	bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params;
+
+	/* Load the BL3-1 image */
+	e = load_image(bl2_tzram_layout,
+		       BL31_IMAGE_NAME,
+		       BL31_BASE,
+		       bl2_to_bl31_params->bl31_image_info,
+		       bl31_ep_info);
+
+	if (e == 0) {
+#if TRUSTED_BOARD_BOOT
+		e = auth_verify_obj(AUTH_BL31_IMG,
+			bl2_to_bl31_params->bl31_image_info->image_base,
+			bl2_to_bl31_params->bl31_image_info->image_size);
+		if (e) {
+			ERROR("Failed to authenticate BL3-1 image.\n");
+			panic();
+		}
+
+		/* After working with data, invalidate the data cache */
+		inv_dcache_range(bl2_to_bl31_params->bl31_image_info->image_base,
+			(size_t)bl2_to_bl31_params->bl31_image_info->image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
+		bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info,
+					  bl31_ep_info);
+	}
+
+	return e;
+}
+
+/*******************************************************************************
+ * Load the BL3-2 image if there's one.
+ * The bl2_to_bl31_params param will be updated with the relevant BL3-2
+ * information.
+ * If a platform does not want to attempt to load BL3-2 image it must leave
+ * BL32_BASE undefined.
+ * Return 0 on success or if there's no BL3-2 image to load, a negative error
+ * code otherwise.
+ ******************************************************************************/
+static int load_bl32(bl31_params_t *bl2_to_bl31_params)
+{
+	int e = 0;
+#ifdef BL32_BASE
+	meminfo_t bl32_mem_info;
+
+	INFO("BL2: Loading BL3-2\n");
+	assert(bl2_to_bl31_params != NULL);
+
+	/*
+	 * It is up to the platform to specify where BL3-2 should be loaded if
+	 * it exists. It could create space in the secure sram or point to a
+	 * completely different memory.
+	 */
+	bl2_plat_get_bl32_meminfo(&bl32_mem_info);
+	e = load_image(&bl32_mem_info,
+		       BL32_IMAGE_NAME,
+		       BL32_BASE,
+		       bl2_to_bl31_params->bl32_image_info,
+		       bl2_to_bl31_params->bl32_ep_info);
+
+	if (e == 0) {
+#if TRUSTED_BOARD_BOOT
+		/* Image is present. Check if there is a valid certificate */
+		if (bl32_cert_error) {
+			ERROR("Failed to authenticate BL3-2 certificates.\n");
+			panic();
+		}
+
+		e = auth_verify_obj(AUTH_BL32_IMG,
+			bl2_to_bl31_params->bl32_image_info->image_base,
+			bl2_to_bl31_params->bl32_image_info->image_size);
+		if (e) {
+			ERROR("Failed to authenticate BL3-2 image.\n");
+			panic();
+		}
+		/* After working with data, invalidate the data cache */
+		inv_dcache_range(bl2_to_bl31_params->bl32_image_info->image_base,
+			(size_t)bl2_to_bl31_params->bl32_image_info->image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
+		bl2_plat_set_bl32_ep_info(
+			bl2_to_bl31_params->bl32_image_info,
+			bl2_to_bl31_params->bl32_ep_info);
+	}
+#endif /* BL32_BASE */
+
+	return e;
+}
+
+/*******************************************************************************
+ * Load the BL3-3 image.
+ * The bl2_to_bl31_params param will be updated with the relevant BL3-3
+ * information.
+ * Return 0 on success, a negative error code otherwise.
+ ******************************************************************************/
+static int load_bl33(bl31_params_t *bl2_to_bl31_params)
+{
+	meminfo_t bl33_mem_info;
+	int e;
+
+	INFO("BL2: Loading BL3-3\n");
+	assert(bl2_to_bl31_params != NULL);
+
+	bl2_plat_get_bl33_meminfo(&bl33_mem_info);
+
+	/* Load the BL3-3 image in non-secure memory provided by the platform */
+	e = load_image(&bl33_mem_info,
+		       BL33_IMAGE_NAME,
+		       plat_get_ns_image_entrypoint(),
+		       bl2_to_bl31_params->bl33_image_info,
+		       bl2_to_bl31_params->bl33_ep_info);
+
+	if (e == 0) {
+#if TRUSTED_BOARD_BOOT
+		e = auth_verify_obj(AUTH_BL33_IMG,
+				bl2_to_bl31_params->bl33_image_info->image_base,
+				bl2_to_bl31_params->bl33_image_info->image_size);
+		if (e) {
+			ERROR("Failed to authenticate BL3-3 image.\n");
+			panic();
+		}
+		/* After working with data, invalidate the data cache */
+		inv_dcache_range(bl2_to_bl31_params->bl33_image_info->image_base,
+			(size_t)bl2_to_bl31_params->bl33_image_info->image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
+		bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info,
+					  bl2_to_bl31_params->bl33_ep_info);
+	}
+
+	return e;
+}
+
+/*******************************************************************************
+ * The only thing to do in BL2 is to load further images and pass control to
+ * BL3-1. The memory occupied by BL2 will be reclaimed by BL3-x stages. BL2 runs
+ * entirely in S-EL1.
+ ******************************************************************************/
+void bl2_main(void)
+{
+	bl31_params_t *bl2_to_bl31_params;
+	entry_point_info_t *bl31_ep_info;
+	int e;
+
+	NOTICE("BL2: %s\n", version_string);
+	NOTICE("BL2: %s\n", build_message);
+
+	/* Perform remaining generic architectural setup in S-EL1 */
+	bl2_arch_setup();
+
+#if TRUSTED_BOARD_BOOT
+	/* Initialize authentication module */
+	auth_init();
+
+	/* Validate the certificates involved in the Chain of Trust */
+	e = load_certs();
+	if (e) {
+		ERROR("Chain of Trust invalid. Aborting...\n");
+		panic();
+	}
+#endif /* TRUSTED_BOARD_BOOT */
+
+	/*
+	 * Load the subsequent bootloader images
+	 */
+	e = load_bl30();
+	if (e) {
+		ERROR("Failed to load BL3-0 (%i)\n", e);
+		ERROR("Please burn mcu image:\n");
+		ERROR("  sudo fastboot flash mcuimage mcuimage.bin\n");
+	}
+
+	/* Perform platform setup in BL2 after loading BL3-0 */
+	bl2_platform_setup();
+
+	/*
+	 * Get a pointer to the memory the platform has set aside to pass
+	 * information to BL3-1.
+	 */
+	bl2_to_bl31_params = bl2_plat_get_bl31_params();
+	bl31_ep_info = bl2_plat_get_bl31_ep_info();
+
+	e = load_bl31(bl2_to_bl31_params, bl31_ep_info);
+	if (e) {
+		ERROR("Failed to load BL3-1 (%i)\n", e);
+		panic();
+	}
+
+	e = load_bl32(bl2_to_bl31_params);
+	if (e)
+		WARN("Failed to load BL3-2 (%i)\n", e);
+
+	e = load_bl33(bl2_to_bl31_params);
+	if (e) {
+		ERROR("Failed to load BL3-3 (%i)\n", e);
+		panic();
+	}
+
+	/* Flush the params to be passed to memory */
+	bl2_plat_flush_bl31_params();
+
+	/*
+	 * Run BL3-1 via an SMC to BL1. Information on how to pass control to
+	 * the BL3-2 (if present) and BL3-3 software images will be passed to
+	 * BL3-1 as an argument.
+	 */
+	smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0);
+}
diff --git a/uefi/arm-trusted-firmware/bl2/bl2_private.h b/uefi/arm-trusted-firmware/bl2/bl2_private.h
new file mode 100644
index 0000000..022d1e9
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl2/bl2_private.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BL2_PRIVATE_H__
+#define __BL2_PRIVATE_H__
+
+/******************************************
+ * Function prototypes
+ *****************************************/
+void bl2_arch_setup(void);
+
+#endif /* __BL2_PRIVATE_H__ */
diff --git a/uefi/arm-trusted-firmware/bl31/aarch64/bl31_arch_setup.c b/uefi/arm-trusted-firmware/bl31/aarch64/bl31_arch_setup.c
new file mode 100644
index 0000000..a88b029
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/aarch64/bl31_arch_setup.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <bl31.h>
+#include <platform.h>
+
+/*******************************************************************************
+ * This duplicates what the primary cpu did after a cold boot in BL1. The same
+ * needs to be done when a cpu is hotplugged in. This function could also over-
+ * ride any EL3 setup done by BL1 as this code resides in rw memory.
+ ******************************************************************************/
+void bl31_arch_setup(void)
+{
+	/* Set the RES1 bits in the SCR_EL3 */
+	write_scr_el3(SCR_RES1_BITS);
+
+	/* Program the counter frequency */
+	write_cntfrq_el0(plat_get_syscnt_freq());
+}
diff --git a/uefi/arm-trusted-firmware/bl31/aarch64/bl31_entrypoint.S b/uefi/arm-trusted-firmware/bl31/aarch64/bl31_entrypoint.S
new file mode 100644
index 0000000..01d7a7f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/aarch64/bl31_entrypoint.S
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+
+	.globl	bl31_entrypoint
+
+
+	/* -----------------------------------------------------
+	 * bl31_entrypoint() is the cold boot entrypoint,
+	 * executed only by the primary cpu.
+	 * -----------------------------------------------------
+	 */
+
+func bl31_entrypoint
+	/* ---------------------------------------------------------------
+	 * Preceding bootloader has populated x0 with a pointer to a
+	 * 'bl31_params' structure & x1 with a pointer to platform
+	 * specific structure
+	 * ---------------------------------------------------------------
+	 */
+#if !RESET_TO_BL31
+	mov	x20, x0
+	mov	x21, x1
+#else
+	/* ---------------------------------------------
+	 * Set the CPU endianness before doing anything
+	 * that might involve memory reads or writes.
+	 * ---------------------------------------------
+	 */
+	mrs	x0, sctlr_el3
+	bic	x0, x0, #SCTLR_EE_BIT
+	msr	sctlr_el3, x0
+	isb
+#endif
+
+	/* ---------------------------------------------
+	 * When RESET_TO_BL31 is true, perform any
+	 * processor specific actions upon reset e.g.
+	 * cache, tlb invalidations, errata workarounds
+	 * etc.
+	 * When RESET_TO_BL31 is false, perform any
+	 * processor specific actions which undo or are
+	 * in addition to the actions performed by the
+	 * reset handler in the Boot ROM (BL1).
+	 * ---------------------------------------------
+	 */
+	bl	reset_handler
+
+	/* ---------------------------------------------
+	 * Enable the instruction cache, stack pointer
+	 * and data access alignment checks
+	 * ---------------------------------------------
+	 */
+	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	mrs	x0, sctlr_el3
+	orr	x0, x0, x1
+	msr	sctlr_el3, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Initialise cpu_data early to enable crash
+	 * reporting to have access to crash stack.
+	 * Since crash reporting depends on cpu_data to
+	 * report the unhandled exception, not
+	 * doing so can lead to recursive exceptions due
+	 * to a NULL TPIDR_EL3
+	 * ---------------------------------------------
+	 */
+	bl	init_cpu_data_ptr
+
+	/* ---------------------------------------------
+	 * Set the exception vector.
+	 * ---------------------------------------------
+	 */
+	adr	x1, runtime_exceptions
+	msr	vbar_el3, x1
+	isb
+
+	/* ---------------------------------------------
+	 * Enable the SError interrupt now that the
+	 * exception vectors have been setup.
+	 * ---------------------------------------------
+	 */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	/* ---------------------------------------------------------------------
+	 * The initial state of the Architectural feature trap register
+	 * (CPTR_EL3) is unknown and it must be set to a known state. All
+	 * feature traps are disabled. Some bits in this register are marked as
+	 * Reserved and should not be modified.
+	 *
+	 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
+	 *  or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
+	 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
+	 *  to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
+	 *  access to trace functionality is not supported, this bit is RES0.
+	 * CPTR_EL3.TFP: This causes instructions that access the registers
+	 *  associated with Floating Point and Advanced SIMD execution to trap
+	 *  to EL3 when executed from any exception level, unless trapped to EL1
+	 *  or EL2.
+	 * ---------------------------------------------------------------------
+	 */
+	mrs	x1, cptr_el3
+	bic	w1, w1, #TCPAC_BIT
+	bic	w1, w1, #TTA_BIT
+	bic	w1, w1, #TFP_BIT
+	msr	cptr_el3, x1
+
+#if RESET_TO_BL31
+	/* -------------------------------------------------------
+	 * Will not return from this macro if it is a warm boot.
+	 * -------------------------------------------------------
+	 */
+	wait_for_entrypoint
+	bl	platform_mem_init
+#endif
+
+	/* ---------------------------------------------
+	 * Zero out NOBITS sections. There are 2 of them:
+	 *   - the .bss section;
+	 *   - the coherent memory section.
+	 * ---------------------------------------------
+	 */
+	ldr	x0, =__BSS_START__
+	ldr	x1, =__BSS_SIZE__
+	bl	zeromem16
+
+#if USE_COHERENT_MEM
+	ldr	x0, =__COHERENT_RAM_START__
+	ldr	x1, =__COHERENT_RAM_UNALIGNED_SIZE__
+	bl	zeromem16
+#endif
+
+	/* ---------------------------------------------
+	 * Initialize the cpu_ops pointer.
+	 * ---------------------------------------------
+	 */
+	bl	init_cpu_ops
+
+	/* ---------------------------------------------
+	 * Use SP_EL0 for the C runtime stack.
+	 * ---------------------------------------------
+	 */
+	msr	spsel, #0
+
+	/* --------------------------------------------
+	 * Allocate a stack whose memory will be marked
+	 * as Normal-IS-WBWA when the MMU is enabled.
+	 * There is no risk of reading stale stack
+	 * memory after enabling the MMU as only the
+	 * primary cpu is running at the moment.
+	 * --------------------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	bl	platform_set_stack
+
+	/* ---------------------------------------------
+	 * Perform platform specific early arch. setup
+	 * ---------------------------------------------
+	 */
+#if RESET_TO_BL31
+	mov	x0, 0
+	mov	x1, 0
+#else
+	mov	x0, x20
+	mov	x1, x21
+#endif
+
+	bl	bl31_early_platform_setup
+	bl	bl31_plat_arch_setup
+
+	/* ---------------------------------------------
+	 * Jump to main function.
+	 * ---------------------------------------------
+	 */
+	bl	bl31_main
+
+	b	el3_exit
diff --git a/uefi/arm-trusted-firmware/bl31/aarch64/context.S b/uefi/arm-trusted-firmware/bl31/aarch64/context.S
new file mode 100644
index 0000000..b127480
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/aarch64/context.S
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <context.h>
+
+/* -----------------------------------------------------
+ * The following function strictly follows the AArch64
+ * PCS to use x9-x17 (temporary caller-saved registers)
+ * to save EL1 system register context. It assumes that
+ * 'x0' is pointing to a 'el1_sys_regs' structure where
+ * the register context will be saved.
+ * -----------------------------------------------------
+ */
+	.global el1_sysregs_context_save
+func el1_sysregs_context_save
+
+	mrs	x9, spsr_el1
+	mrs	x10, elr_el1
+	stp	x9, x10, [x0, #CTX_SPSR_EL1]
+
+	mrs	x11, spsr_abt
+	mrs	x12, spsr_und
+	stp	x11, x12, [x0, #CTX_SPSR_ABT]
+
+	mrs	x13, spsr_irq
+	mrs	x14, spsr_fiq
+	stp	x13, x14, [x0, #CTX_SPSR_IRQ]
+
+	mrs	x15, sctlr_el1
+	mrs	x16, actlr_el1
+	stp	x15, x16, [x0, #CTX_SCTLR_EL1]
+
+	mrs	x17, cpacr_el1
+	mrs	x9, csselr_el1
+	stp	x17, x9, [x0, #CTX_CPACR_EL1]
+
+	mrs	x10, sp_el1
+	mrs	x11, esr_el1
+	stp	x10, x11, [x0, #CTX_SP_EL1]
+
+	mrs	x12, ttbr0_el1
+	mrs	x13, ttbr1_el1
+	stp	x12, x13, [x0, #CTX_TTBR0_EL1]
+
+	mrs	x14, mair_el1
+	mrs	x15, amair_el1
+	stp	x14, x15, [x0, #CTX_MAIR_EL1]
+
+	mrs	x16, tcr_el1
+	mrs	x17, tpidr_el1
+	stp	x16, x17, [x0, #CTX_TCR_EL1]
+
+	mrs	x9, tpidr_el0
+	mrs	x10, tpidrro_el0
+	stp	x9, x10, [x0, #CTX_TPIDR_EL0]
+
+	mrs	x11, dacr32_el2
+	mrs	x12, ifsr32_el2
+	stp	x11, x12, [x0, #CTX_DACR32_EL2]
+
+	mrs	x13, par_el1
+	mrs	x14, far_el1
+	stp	x13, x14, [x0, #CTX_PAR_EL1]
+
+	mrs	x15, afsr0_el1
+	mrs	x16, afsr1_el1
+	stp	x15, x16, [x0, #CTX_AFSR0_EL1]
+
+	mrs	x17, contextidr_el1
+	mrs	x9, vbar_el1
+	stp	x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
+
+	/* Save NS timer registers if the build has instructed so */
+#if NS_TIMER_SWITCH
+	mrs	x10, cntp_ctl_el0
+	mrs	x11, cntp_cval_el0
+	stp	x10, x11, [x0, #CTX_CNTP_CTL_EL0]
+
+	mrs	x12, cntv_ctl_el0
+	mrs	x13, cntv_cval_el0
+	stp	x12, x13, [x0, #CTX_CNTV_CTL_EL0]
+
+	mrs	x14, cntkctl_el1
+	str	x14, [x0, #CTX_CNTKCTL_EL1]
+#endif
+
+	mrs	x15, fpexc32_el2
+	str	x15, [x0, #CTX_FP_FPEXC32_EL2]
+
+	ret
+
+/* -----------------------------------------------------
+ * The following function strictly follows the AArch64
+ * PCS to use x9-x17 (temporary caller-saved registers)
+ * to restore EL1 system register context.  It assumes
+ * that 'x0' is pointing to a 'el1_sys_regs' structure
+ * from where the register context will be restored
+ * -----------------------------------------------------
+ */
+	.global el1_sysregs_context_restore
+func el1_sysregs_context_restore
+
+	ldp	x9, x10, [x0, #CTX_SPSR_EL1]
+	msr	spsr_el1, x9
+	msr	elr_el1, x10
+
+	ldp	x11, x12, [x0, #CTX_SPSR_ABT]
+	msr	spsr_abt, x11
+	msr	spsr_und, x12
+
+	ldp	x13, x14, [x0, #CTX_SPSR_IRQ]
+	msr	spsr_irq, x13
+	msr	spsr_fiq, x14
+
+	ldp	x15, x16, [x0, #CTX_SCTLR_EL1]
+	msr	sctlr_el1, x15
+	msr	actlr_el1, x16
+
+	ldp	x17, x9, [x0, #CTX_CPACR_EL1]
+	msr	cpacr_el1, x17
+	msr	csselr_el1, x9
+
+	ldp	x10, x11, [x0, #CTX_SP_EL1]
+	msr	sp_el1, x10
+	msr	esr_el1, x11
+
+	ldp	x12, x13, [x0, #CTX_TTBR0_EL1]
+	msr	ttbr0_el1, x12
+	msr	ttbr1_el1, x13
+
+	ldp	x14, x15, [x0, #CTX_MAIR_EL1]
+	msr	mair_el1, x14
+	msr	amair_el1, x15
+
+	ldp	x16, x17, [x0, #CTX_TCR_EL1]
+	msr	tcr_el1, x16
+	msr	tpidr_el1, x17
+
+	ldp	x9, x10, [x0, #CTX_TPIDR_EL0]
+	msr	tpidr_el0, x9
+	msr	tpidrro_el0, x10
+
+	ldp	x11, x12, [x0, #CTX_DACR32_EL2]
+	msr	dacr32_el2, x11
+	msr	ifsr32_el2, x12
+
+	ldp	x13, x14, [x0, #CTX_PAR_EL1]
+	msr	par_el1, x13
+	msr	far_el1, x14
+
+	ldp	x15, x16, [x0, #CTX_AFSR0_EL1]
+	msr	afsr0_el1, x15
+	msr	afsr1_el1, x16
+
+	ldp	x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
+	msr	contextidr_el1, x17
+	msr	vbar_el1, x9
+
+	/* Restore NS timer registers if the build has instructed so */
+#if NS_TIMER_SWITCH
+	ldp	x10, x11, [x0, #CTX_CNTP_CTL_EL0]
+	msr	cntp_ctl_el0, x10
+	msr	cntp_cval_el0, x11
+
+	ldp	x12, x13, [x0, #CTX_CNTV_CTL_EL0]
+	msr	cntv_ctl_el0, x12
+	msr	cntv_cval_el0, x13
+
+	ldr	x14, [x0, #CTX_CNTKCTL_EL1]
+	msr	cntkctl_el1, x14
+#endif
+
+	ldr	x15, [x0, #CTX_FP_FPEXC32_EL2]
+	msr	fpexc32_el2, x15
+
+	/* No explict ISB required here as ERET covers it */
+
+	ret
+
+/* -----------------------------------------------------
+ * The following function follows the aapcs_64 strictly
+ * to use x9-x17 (temporary caller-saved registers
+ * according to AArch64 PCS) to save floating point
+ * register context. It assumes that 'x0' is pointing to
+ * a 'fp_regs' structure where the register context will
+ * be saved.
+ *
+ * Access to VFP registers will trap if CPTR_EL3.TFP is
+ * set.  However currently we don't use VFP registers
+ * nor set traps in Trusted Firmware, and assume it's
+ * cleared
+ *
+ * TODO: Revisit when VFP is used in secure world
+ * -----------------------------------------------------
+ */
+#if CTX_INCLUDE_FPREGS
+	.global fpregs_context_save
+func fpregs_context_save
+	stp	q0, q1, [x0, #CTX_FP_Q0]
+	stp	q2, q3, [x0, #CTX_FP_Q2]
+	stp	q4, q5, [x0, #CTX_FP_Q4]
+	stp	q6, q7, [x0, #CTX_FP_Q6]
+	stp	q8, q9, [x0, #CTX_FP_Q8]
+	stp	q10, q11, [x0, #CTX_FP_Q10]
+	stp	q12, q13, [x0, #CTX_FP_Q12]
+	stp	q14, q15, [x0, #CTX_FP_Q14]
+	stp	q16, q17, [x0, #CTX_FP_Q16]
+	stp	q18, q19, [x0, #CTX_FP_Q18]
+	stp	q20, q21, [x0, #CTX_FP_Q20]
+	stp	q22, q23, [x0, #CTX_FP_Q22]
+	stp	q24, q25, [x0, #CTX_FP_Q24]
+	stp	q26, q27, [x0, #CTX_FP_Q26]
+	stp	q28, q29, [x0, #CTX_FP_Q28]
+	stp	q30, q31, [x0, #CTX_FP_Q30]
+
+	mrs	x9, fpsr
+	str	x9, [x0, #CTX_FP_FPSR]
+
+	mrs	x10, fpcr
+	str	x10, [x0, #CTX_FP_FPCR]
+
+	ret
+
+/* -----------------------------------------------------
+ * The following function follows the aapcs_64 strictly
+ * to use x9-x17 (temporary caller-saved registers
+ * according to AArch64 PCS) to restore floating point
+ * register context. It assumes that 'x0' is pointing to
+ * a 'fp_regs' structure from where the register context
+ * will be restored.
+ *
+ * Access to VFP registers will trap if CPTR_EL3.TFP is
+ * set.  However currently we don't use VFP registers
+ * nor set traps in Trusted Firmware, and assume it's
+ * cleared
+ *
+ * TODO: Revisit when VFP is used in secure world
+ * -----------------------------------------------------
+ */
+	.global fpregs_context_restore
+func fpregs_context_restore
+	ldp	q0, q1, [x0, #CTX_FP_Q0]
+	ldp	q2, q3, [x0, #CTX_FP_Q2]
+	ldp	q4, q5, [x0, #CTX_FP_Q4]
+	ldp	q6, q7, [x0, #CTX_FP_Q6]
+	ldp	q8, q9, [x0, #CTX_FP_Q8]
+	ldp	q10, q11, [x0, #CTX_FP_Q10]
+	ldp	q12, q13, [x0, #CTX_FP_Q12]
+	ldp	q14, q15, [x0, #CTX_FP_Q14]
+	ldp	q16, q17, [x0, #CTX_FP_Q16]
+	ldp	q18, q19, [x0, #CTX_FP_Q18]
+	ldp	q20, q21, [x0, #CTX_FP_Q20]
+	ldp	q22, q23, [x0, #CTX_FP_Q22]
+	ldp	q24, q25, [x0, #CTX_FP_Q24]
+	ldp	q26, q27, [x0, #CTX_FP_Q26]
+	ldp	q28, q29, [x0, #CTX_FP_Q28]
+	ldp	q30, q31, [x0, #CTX_FP_Q30]
+
+	ldr	x9, [x0, #CTX_FP_FPSR]
+	msr	fpsr, x9
+
+	str	x10, [x0, #CTX_FP_FPCR]
+	msr	fpcr, x10
+
+	/*
+	 * No explict ISB required here as ERET to
+	 * swtich to secure EL1 or non-secure world
+	 * covers it
+	 */
+
+	ret
+#endif /* CTX_INCLUDE_FPREGS */
diff --git a/uefi/arm-trusted-firmware/bl31/aarch64/cpu_data.S b/uefi/arm-trusted-firmware/bl31/aarch64/cpu_data.S
new file mode 100644
index 0000000..feb51d6
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/aarch64/cpu_data.S
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <asm_macros.S>
+#include <cpu_data.h>
+
+.globl	init_cpu_data_ptr
+.globl	_cpu_data_by_mpidr
+.globl	_cpu_data_by_index
+
+/* -----------------------------------------------------------------
+ * void init_cpu_data_ptr(void)
+ *
+ * Initialise the TPIDR_EL3 register to refer to the cpu_data_t
+ * for the calling CPU. This must be called before cm_get_cpu_data()
+ *
+ * This can be called without a valid stack.
+ * clobbers: x0, x1, x9, x10
+ * -----------------------------------------------------------------
+ */
+func init_cpu_data_ptr
+	mov	x10, x30
+	mrs	x0, mpidr_el1
+	bl	_cpu_data_by_mpidr
+	msr	tpidr_el3, x0
+	ret	x10
+
+
+/* -----------------------------------------------------------------
+ * cpu_data_t *_cpu_data_by_mpidr(uint64_t mpidr)
+ *
+ * Return the cpu_data structure for the CPU with given MPIDR
+ *
+ * This can be called without a valid stack. It assumes that
+ * platform_get_core_pos() does not clobber register x9.
+ * clobbers: x0, x1, x9
+ * -----------------------------------------------------------------
+ */
+func _cpu_data_by_mpidr
+	mov	x9, x30
+	bl	platform_get_core_pos
+	mov	x30, x9
+	b	_cpu_data_by_index
+
+
+/* -----------------------------------------------------------------
+ * cpu_data_t *_cpu_data_by_index(uint32_t cpu_index)
+ *
+ * Return the cpu_data structure for the CPU with given linear index
+ *
+ * This can be called without a valid stack.
+ * clobbers: x0, x1
+ * -----------------------------------------------------------------
+ */
+func _cpu_data_by_index
+	adr	x1, percpu_data
+	add	x0, x1, x0, LSL #CPU_DATA_LOG2SIZE
+	ret
diff --git a/uefi/arm-trusted-firmware/bl31/aarch64/crash_reporting.S b/uefi/arm-trusted-firmware/bl31/aarch64/crash_reporting.S
new file mode 100644
index 0000000..68fe256
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/aarch64/crash_reporting.S
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <arch.h>
+#include <asm_macros.S>
+#include <context.h>
+#include <cpu_data.h>
+#include <plat_macros.S>
+#include <platform_def.h>
+
+	.globl	report_unhandled_exception
+	.globl	report_unhandled_interrupt
+	.globl	el3_panic
+
+#if CRASH_REPORTING
+#define REG_SIZE	0x8
+
+	/* ------------------------------------------------------
+	 * The below section deals with dumping the system state
+	 * when an unhandled exception is taken in EL3.
+	 * The layout and the names of the registers which will
+	 * be dumped during a unhandled exception is given below.
+	 * ------------------------------------------------------
+	 */
+.section .rodata.crash_prints, "aS"
+print_spacer:
+	.asciz	" =\t\t0x"
+
+gp_regs:
+	.asciz	"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",\
+		"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",\
+		"x16", "x17", "x18", "x19", "x20", "x21", "x22",\
+		"x23", "x24", "x25", "x26", "x27", "x28", "x29", ""
+el3_sys_regs:
+	.asciz	"scr_el3", "sctlr_el3", "cptr_el3", "tcr_el3",\
+		"daif", "mair_el3", "spsr_el3", "elr_el3", "ttbr0_el3",\
+		"esr_el3", "far_el3", ""
+
+non_el3_sys_regs:
+	.asciz	"spsr_el1", "elr_el1", "spsr_abt", "spsr_und",\
+		"spsr_irq", "spsr_fiq", "sctlr_el1", "actlr_el1", "cpacr_el1",\
+		"csselr_el1", "sp_el1", "esr_el1", "ttbr0_el1", "ttbr1_el1",\
+		"mair_el1", "amair_el1", "tcr_el1", "tpidr_el1", "tpidr_el0",\
+		"tpidrro_el0", "dacr32_el2", "ifsr32_el2", "par_el1",\
+		"mpidr_el1", "afsr0_el1", "afsr1_el1", "contextidr_el1",\
+		"vbar_el1", "cntp_ctl_el0", "cntp_cval_el0", "cntv_ctl_el0",\
+		"cntv_cval_el0", "cntkctl_el1", "fpexc32_el2", "sp_el0", ""
+
+panic_msg:
+	.asciz "PANIC in EL3 at x30 = 0x"
+excpt_msg:
+	.asciz "Unhandled Exception in EL3.\nx30 =\t\t0x"
+intr_excpt_msg:
+	.asciz "Unhandled Interrupt Exception in EL3.\nx30 =\t\t0x"
+
+	/*
+	 * Helper function to print newline to console.
+	 */
+func print_newline
+	mov	x0, '\n'
+	b	plat_crash_console_putc
+
+	/*
+	 * Helper function to print from crash buf.
+	 * The print loop is controlled by the buf size and
+	 * ascii reg name list which is passed in x6. The
+	 * function returns the crash buf address in x0.
+	 * Clobbers : x0 - x7, sp
+	 */
+func size_controlled_print
+	/* Save the lr */
+	mov	sp, x30
+	/* load the crash buf address */
+	mrs	x7, tpidr_el3
+test_size_list:
+	/* Calculate x5 always as it will be clobbered by asm_print_hex */
+	mrs	x5, tpidr_el3
+	add	x5, x5, #CPU_DATA_CRASH_BUF_SIZE
+	/* Test whether we have reached end of crash buf */
+	cmp	x7, x5
+	b.eq	exit_size_print
+	ldrb	w4, [x6]
+	/* Test whether we are at end of list */
+	cbz	w4, exit_size_print
+	mov	x4, x6
+	/* asm_print_str updates x4 to point to next entry in list */
+	bl	asm_print_str
+	/* update x6 with the updated list pointer */
+	mov	x6, x4
+	adr	x4, print_spacer
+	bl	asm_print_str
+	ldr	x4, [x7], #REG_SIZE
+	bl	asm_print_hex
+	bl	print_newline
+	b	test_size_list
+exit_size_print:
+	mov	x30, sp
+	ret
+
+	/*
+	 * Helper function to store x8 - x15 registers to
+	 * the crash buf. The system registers values are
+	 * copied to x8 to x15 by the caller which are then
+	 * copied to the crash buf by this function.
+	 * x0 points to the crash buf. It then calls
+	 * size_controlled_print to print to console.
+	 * Clobbers : x0 - x7, sp
+	 */
+func str_in_crash_buf_print
+	/* restore the crash buf address in x0 */
+	mrs	x0, tpidr_el3
+	stp	x8, x9, [x0]
+	stp	x10, x11, [x0, #REG_SIZE * 2]
+	stp	x12, x13, [x0, #REG_SIZE * 4]
+	stp	x14, x15, [x0, #REG_SIZE * 6]
+	b	size_controlled_print
+
+	/* ------------------------------------------------------
+	 * This macro calculates the offset to crash buf from
+	 * cpu_data and stores it in tpidr_el3. It also saves x0
+	 * and x1 in the crash buf by using sp as a temporary
+	 * register.
+	 * ------------------------------------------------------
+	 */
+	.macro prepare_crash_buf_save_x0_x1
+	/* we can corrupt this reg to free up x0 */
+	mov	sp, x0
+	/* tpidr_el3 contains the address to cpu_data structure */
+	mrs	x0, tpidr_el3
+	/* Calculate the Crash buffer offset in cpu_data */
+	add	x0, x0, #CPU_DATA_CRASH_BUF_OFFSET
+	/* Store crash buffer address in tpidr_el3 */
+	msr	tpidr_el3, x0
+	str	x1, [x0, #REG_SIZE]
+	mov	x1, sp
+	str	x1, [x0]
+	.endm
+
+	/* -----------------------------------------------------
+	 * This function allows to report a crash (if crash
+	 * reporting is enabled) when an unhandled exception
+	 * occurs. It prints the CPU state via the crash console
+	 * making use of the crash buf. This function will
+	 * not return.
+	 * -----------------------------------------------------
+	 */
+func report_unhandled_exception
+	prepare_crash_buf_save_x0_x1
+	adr	x0, excpt_msg
+	mov	sp, x0
+	/* This call will not return */
+	b	do_crash_reporting
+
+
+	/* -----------------------------------------------------
+	 * This function allows to report a crash (if crash
+	 * reporting is enabled) when an unhandled interrupt
+	 * occurs. It prints the CPU state via the crash console
+	 * making use of the crash buf. This function will
+	 * not return.
+	 * -----------------------------------------------------
+	 */
+func report_unhandled_interrupt
+	prepare_crash_buf_save_x0_x1
+	adr	x0, intr_excpt_msg
+	mov	sp, x0
+	/* This call will not return */
+	b	do_crash_reporting
+
+	/* -----------------------------------------------------
+	 * This function allows to report a crash (if crash
+	 * reporting is enabled) when panic() is invoked from
+	 * C Runtime. It prints the CPU state via the crash
+	 * console making use of the crash buf. This function
+	 * will not return.
+	 * -----------------------------------------------------
+	 */
+func el3_panic
+	msr	spsel, #1
+	prepare_crash_buf_save_x0_x1
+	adr	x0, panic_msg
+	mov	sp, x0
+	/* This call will not return */
+	b	do_crash_reporting
+
+	/* ------------------------------------------------------------
+	 * The common crash reporting functionality. It requires x0
+	 * and x1 has already been stored in crash buf, sp points to
+	 * crash message and tpidr_el3 contains the crash buf address.
+	 * The function does the following:
+	 *   - Retrieve the crash buffer from tpidr_el3
+	 *   - Store x2 to x6 in the crash buffer
+	 *   - Initialise the crash console.
+	 *   - Print the crash message by using the address in sp.
+	 *   - Print x30 value to the crash console.
+	 *   - Print x0 - x7 from the crash buf to the crash console.
+	 *   - Print x8 - x29 (in groups of 8 registers) using the
+	 *     crash buf to the crash console.
+	 *   - Print el3 sys regs (in groups of 8 registers) using the
+	 *     crash buf to the crash console.
+	 *   - Print non el3 sys regs (in groups of 8 registers) using
+	 *     the crash buf to the crash console.
+	 * ------------------------------------------------------------
+	 */
+func do_crash_reporting
+	/* Retrieve the crash buf from tpidr_el3 */
+	mrs	x0, tpidr_el3
+	/* Store x2 - x6, x30 in the crash buffer */
+	stp	x2, x3, [x0, #REG_SIZE * 2]
+	stp	x4, x5, [x0, #REG_SIZE * 4]
+	stp	x6, x30, [x0, #REG_SIZE * 6]
+	/* Initialize the crash console */
+	bl	plat_crash_console_init
+	/* Verify the console is initialized */
+	cbz	x0, crash_panic
+	/* Print the crash message. sp points to the crash message */
+	mov	x4, sp
+	bl	asm_print_str
+	/* load the crash buf address */
+	mrs	x0, tpidr_el3
+	/* report x30 first from the crash buf */
+	ldr	x4, [x0, #REG_SIZE * 7]
+	bl	asm_print_hex
+	bl	print_newline
+	/* Load the crash buf address */
+	mrs	x0, tpidr_el3
+	/* Now mov x7 into crash buf */
+	str	x7, [x0, #REG_SIZE * 7]
+
+	/* Report x0 - x29 values stored in crash buf*/
+	/* Store the ascii list pointer in x6 */
+	adr	x6, gp_regs
+	/* Print x0 to x7 from the crash buf */
+	bl	size_controlled_print
+	/* Store x8 - x15 in crash buf and print */
+	bl	str_in_crash_buf_print
+	/* Load the crash buf address */
+	mrs	x0, tpidr_el3
+	/* Store the rest of gp regs and print */
+	stp	x16, x17, [x0]
+	stp	x18, x19, [x0, #REG_SIZE * 2]
+	stp	x20, x21, [x0, #REG_SIZE * 4]
+	stp	x22, x23, [x0, #REG_SIZE * 6]
+	bl	size_controlled_print
+	/* Load the crash buf address */
+	mrs	x0, tpidr_el3
+	stp	x24, x25, [x0]
+	stp	x26, x27, [x0, #REG_SIZE * 2]
+	stp	x28, x29, [x0, #REG_SIZE * 4]
+	bl	size_controlled_print
+
+	/* Print the el3 sys registers */
+	adr	x6, el3_sys_regs
+	mrs	x8, scr_el3
+	mrs	x9, sctlr_el3
+	mrs	x10, cptr_el3
+	mrs	x11, tcr_el3
+	mrs	x12, daif
+	mrs	x13, mair_el3
+	mrs	x14, spsr_el3
+	mrs	x15, elr_el3
+	bl	str_in_crash_buf_print
+	mrs	x8, ttbr0_el3
+	mrs	x9, esr_el3
+	mrs	x10, far_el3
+	bl	str_in_crash_buf_print
+
+	/* Print the non el3 sys registers */
+	adr	x6, non_el3_sys_regs
+	mrs	x8, spsr_el1
+	mrs	x9, elr_el1
+	mrs	x10, spsr_abt
+	mrs	x11, spsr_und
+	mrs	x12, spsr_irq
+	mrs	x13, spsr_fiq
+	mrs	x14, sctlr_el1
+	mrs	x15, actlr_el1
+	bl	str_in_crash_buf_print
+	mrs	x8, cpacr_el1
+	mrs	x9, csselr_el1
+	mrs	x10, sp_el1
+	mrs	x11, esr_el1
+	mrs	x12, ttbr0_el1
+	mrs	x13, ttbr1_el1
+	mrs	x14, mair_el1
+	mrs	x15, amair_el1
+	bl	str_in_crash_buf_print
+	mrs	x8, tcr_el1
+	mrs	x9, tpidr_el1
+	mrs	x10, tpidr_el0
+	mrs	x11, tpidrro_el0
+	mrs	x12, dacr32_el2
+	mrs	x13, ifsr32_el2
+	mrs	x14, par_el1
+	mrs	x15, mpidr_el1
+	bl	str_in_crash_buf_print
+	mrs	x8, afsr0_el1
+	mrs	x9, afsr1_el1
+	mrs	x10, contextidr_el1
+	mrs	x11, vbar_el1
+	mrs	x12, cntp_ctl_el0
+	mrs	x13, cntp_cval_el0
+	mrs	x14, cntv_ctl_el0
+	mrs	x15, cntv_cval_el0
+	bl	str_in_crash_buf_print
+	mrs	x8, cntkctl_el1
+	mrs	x9, fpexc32_el2
+	mrs	x10, sp_el0
+	bl	str_in_crash_buf_print
+
+	/* Get the cpu specific registers to report */
+	bl	do_cpu_reg_dump
+	bl	str_in_crash_buf_print
+
+	/* Print the gic registers */
+	plat_print_gic_regs
+
+	/* Print the interconnect registers */
+	plat_print_interconnect_regs
+
+	/* Done reporting */
+	b	crash_panic
+
+#else	/* CRASH_REPORTING */
+func report_unhandled_exception
+report_unhandled_interrupt:
+	b	crash_panic
+#endif	/* CRASH_REPORING */
+
+
+func crash_panic
+	b	crash_panic
diff --git a/uefi/arm-trusted-firmware/bl31/aarch64/runtime_exceptions.S b/uefi/arm-trusted-firmware/bl31/aarch64/runtime_exceptions.S
new file mode 100644
index 0000000..3265862
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/aarch64/runtime_exceptions.S
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <context.h>
+#include <interrupt_mgmt.h>
+#include <platform_def.h>
+#include <runtime_svc.h>
+
+	.globl	runtime_exceptions
+	.globl	el3_exit
+
+	/* -----------------------------------------------------
+	 * Handle SMC exceptions separately from other sync.
+	 * exceptions.
+	 * -----------------------------------------------------
+	 */
+	.macro	handle_sync_exception
+	/* Enable the SError interrupt */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	mrs	x30, esr_el3
+	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+
+	cmp	x30, #EC_AARCH32_SMC
+	b.eq	smc_handler32
+
+	cmp	x30, #EC_AARCH64_SMC
+	b.eq	smc_handler64
+
+	/* -----------------------------------------------------
+	 * The following code handles any synchronous exception
+	 * that is not an SMC.
+	 * -----------------------------------------------------
+	 */
+
+	bl	report_unhandled_exception
+	.endm
+
+
+	/* -----------------------------------------------------
+	 * This macro handles FIQ or IRQ interrupts i.e. EL3,
+	 * S-EL1 and NS interrupts.
+	 * -----------------------------------------------------
+	 */
+	.macro	handle_interrupt_exception label
+	/* Enable the SError interrupt */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	bl	save_gp_registers
+
+	/* Switch to the runtime stack i.e. SP_EL0 */
+	ldr	x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+	mov	x20, sp
+	msr	spsel, #0
+	mov	sp, x2
+
+	/*
+	 * Find out whether this is a valid interrupt type. If the
+	 * interrupt controller reports a spurious interrupt then
+	 * return to where we came from.
+	 */
+	bl	plat_ic_get_pending_interrupt_type
+	cmp	x0, #INTR_TYPE_INVAL
+	b.eq	interrupt_exit_\label
+
+	/*
+	 * Get the registered handler for this interrupt type. A
+	 * NULL return value implies that an interrupt was generated
+	 * for which there is no handler registered or the interrupt
+	 * was routed incorrectly. This is a problem of the framework
+	 * so report it as an error.
+	 */
+	bl	get_interrupt_type_handler
+	cbz	x0, interrupt_error_\label
+	mov	x21, x0
+
+	mov	x0, #INTR_ID_UNAVAILABLE
+#if IMF_READ_INTERRUPT_ID
+	/*
+	 * Read the id of the highest priority pending interrupt. If
+	 * no interrupt is asserted then return to where we came from.
+	 */
+	mov	x19,  #INTR_ID_UNAVAILABLE
+	bl	plat_ic_get_pending_interrupt_id
+	cmp	x19, x0
+	b.eq	interrupt_exit_\label
+#endif
+
+	/*
+	 * Save the EL3 system registers needed to return from
+	 * this exception.
+	 */
+	mrs	x3, spsr_el3
+	mrs	x4, elr_el3
+	stp	x3, x4, [x20, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+
+	/* Set the current security state in the 'flags' parameter */
+	mrs	x2, scr_el3
+	ubfx	x1, x2, #0, #1
+
+	/* Restore the reference to the 'handle' i.e. SP_EL3 */
+	mov	x2, x20
+
+	/*  x3 will point to a cookie (not used now) */
+	mov	x3, xzr
+
+	/* Call the interrupt type handler */
+	blr	x21
+
+interrupt_exit_\label:
+	/* Return from exception, possibly in a different security state */
+	b	el3_exit
+
+	/*
+	 * This label signifies a problem with the interrupt management
+	 * framework where it is not safe to go back to the instruction
+	 * where the interrupt was generated.
+	 */
+interrupt_error_\label:
+	bl	report_unhandled_interrupt
+	.endm
+
+
+	.macro save_x18_to_x29_sp_el0
+	stp	x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]
+	stp	x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]
+	stp	x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]
+	stp	x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]
+	stp	x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]
+	stp	x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
+	mrs	x18, sp_el0
+	str	x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0]
+	.endm
+
+	.section	.vectors, "ax"; .align 11
+	.align	7
+runtime_exceptions:
+	/* -----------------------------------------------------
+	 * Current EL with _sp_el0 : 0x0 - 0x200
+	 * -----------------------------------------------------
+	 */
+sync_exception_sp_el0:
+	/* -----------------------------------------------------
+	 * We don't expect any synchronous exceptions from EL3
+	 * -----------------------------------------------------
+	 */
+	bl	report_unhandled_exception
+	check_vector_size sync_exception_sp_el0
+
+	.align	7
+	/* -----------------------------------------------------
+	 * EL3 code is non-reentrant. Any asynchronous exception
+	 * is a serious error. Loop infinitely.
+	 * -----------------------------------------------------
+	 */
+irq_sp_el0:
+	bl	report_unhandled_interrupt
+	check_vector_size irq_sp_el0
+
+	.align	7
+fiq_sp_el0:
+	bl	report_unhandled_interrupt
+	check_vector_size fiq_sp_el0
+
+	.align	7
+serror_sp_el0:
+	bl	report_unhandled_exception
+	check_vector_size serror_sp_el0
+
+	/* -----------------------------------------------------
+	 * Current EL with SPx: 0x200 - 0x400
+	 * -----------------------------------------------------
+	 */
+	.align	7
+sync_exception_sp_elx:
+	/* -----------------------------------------------------
+	 * This exception will trigger if anything went wrong
+	 * during a previous exception entry or exit or while
+	 * handling an earlier unexpected synchronous exception.
+	 * There is a high probability that SP_EL3 is corrupted.
+	 * -----------------------------------------------------
+	 */
+	bl	report_unhandled_exception
+	check_vector_size sync_exception_sp_elx
+
+	.align	7
+irq_sp_elx:
+	bl	report_unhandled_interrupt
+	check_vector_size irq_sp_elx
+
+	.align	7
+fiq_sp_elx:
+	bl	report_unhandled_interrupt
+	check_vector_size fiq_sp_elx
+
+	.align	7
+serror_sp_elx:
+	bl	report_unhandled_exception
+	check_vector_size serror_sp_elx
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch64 : 0x400 - 0x600
+	 * -----------------------------------------------------
+	 */
+	.align	7
+sync_exception_aarch64:
+	/* -----------------------------------------------------
+	 * This exception vector will be the entry point for
+	 * SMCs and traps that are unhandled at lower ELs most
+	 * commonly. SP_EL3 should point to a valid cpu context
+	 * where the general purpose and system register state
+	 * can be saved.
+	 * -----------------------------------------------------
+	 */
+	handle_sync_exception
+	check_vector_size sync_exception_aarch64
+
+	.align	7
+	/* -----------------------------------------------------
+	 * Asynchronous exceptions from lower ELs are not
+	 * currently supported. Report their occurrence.
+	 * -----------------------------------------------------
+	 */
+irq_aarch64:
+	handle_interrupt_exception irq_aarch64
+	check_vector_size irq_aarch64
+
+	.align	7
+fiq_aarch64:
+	handle_interrupt_exception fiq_aarch64
+	check_vector_size fiq_aarch64
+
+	.align	7
+serror_aarch64:
+	bl	report_unhandled_exception
+	check_vector_size serror_aarch64
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch32 : 0x600 - 0x800
+	 * -----------------------------------------------------
+	 */
+	.align	7
+sync_exception_aarch32:
+	/* -----------------------------------------------------
+	 * This exception vector will be the entry point for
+	 * SMCs and traps that are unhandled at lower ELs most
+	 * commonly. SP_EL3 should point to a valid cpu context
+	 * where the general purpose and system register state
+	 * can be saved.
+	 * -----------------------------------------------------
+	 */
+	handle_sync_exception
+	check_vector_size sync_exception_aarch32
+
+	.align	7
+	/* -----------------------------------------------------
+	 * Asynchronous exceptions from lower ELs are not
+	 * currently supported. Report their occurrence.
+	 * -----------------------------------------------------
+	 */
+irq_aarch32:
+	handle_interrupt_exception irq_aarch32
+	check_vector_size irq_aarch32
+
+	.align	7
+fiq_aarch32:
+	handle_interrupt_exception fiq_aarch32
+	check_vector_size fiq_aarch32
+
+	.align	7
+serror_aarch32:
+	bl	report_unhandled_exception
+	check_vector_size serror_aarch32
+
+	.align	7
+
+	/* -----------------------------------------------------
+	 * The following code handles secure monitor calls.
+	 * Depending upon the execution state from where the SMC
+	 * has been invoked, it frees some general purpose
+	 * registers to perform the remaining tasks. They
+	 * involve finding the runtime service handler that is
+	 * the target of the SMC & switching to runtime stacks
+	 * (SP_EL0) before calling the handler.
+	 *
+	 * Note that x30 has been explicitly saved and can be
+	 * used here
+	 * -----------------------------------------------------
+	 */
+func smc_handler
+smc_handler32:
+	/* Check whether aarch32 issued an SMC64 */
+	tbnz	x0, #FUNCID_CC_SHIFT, smc_prohibited
+
+	/* -----------------------------------------------------
+	 * Since we're are coming from aarch32, x8-x18 need to
+	 * be saved as per SMC32 calling convention. If a lower
+	 * EL in aarch64 is making an SMC32 call then it must
+	 * have saved x8-x17 already therein.
+	 * -----------------------------------------------------
+	 */
+	stp	x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
+	stp	x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
+	stp	x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
+	stp	x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
+	stp	x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
+
+	/* x4-x7, x18, sp_el0 are saved below */
+
+smc_handler64:
+	/* -----------------------------------------------------
+	 * Populate the parameters for the SMC handler. We
+	 * already have x0-x4 in place. x5 will point to a
+	 * cookie (not used now). x6 will point to the context
+	 * structure (SP_EL3) and x7 will contain flags we need
+	 * to pass to the handler Hence save x5-x7. Note that x4
+	 * only needs to be preserved for AArch32 callers but we
+	 * do it for AArch64 callers as well for convenience
+	 * -----------------------------------------------------
+	 */
+	stp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
+	stp	x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
+
+	/* Save rest of the gpregs and sp_el0*/
+	save_x18_to_x29_sp_el0
+
+	mov	x5, xzr
+	mov	x6, sp
+
+	/* Get the unique owning entity number */
+	ubfx	x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH
+	ubfx	x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH
+	orr	x16, x16, x15, lsl #FUNCID_OEN_WIDTH
+
+	adr	x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
+
+	/* Load descriptor index from array of indices */
+	adr	x14, rt_svc_descs_indices
+	ldrb	w15, [x14, x16]
+
+	/* -----------------------------------------------------
+	 * Restore the saved C runtime stack value which will
+	 * become the new SP_EL0 i.e. EL3 runtime stack. It was
+	 * saved in the 'cpu_context' structure prior to the last
+	 * ERET from EL3.
+	 * -----------------------------------------------------
+	 */
+	ldr	x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+
+	/*
+	 * Any index greater than 127 is invalid. Check bit 7 for
+	 * a valid index
+	 */
+	tbnz	w15, 7, smc_unknown
+
+	/* Switch to SP_EL0 */
+	msr	spsel, #0
+
+	/* -----------------------------------------------------
+	 * Get the descriptor using the index
+	 * x11 = (base + off), x15 = index
+	 *
+	 * handler = (base + off) + (index << log2(size))
+	 * -----------------------------------------------------
+	 */
+	lsl	w10, w15, #RT_SVC_SIZE_LOG2
+	ldr	x15, [x11, w10, uxtw]
+
+	/* -----------------------------------------------------
+	 * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there
+	 * is a world switch during SMC handling.
+	 * TODO: Revisit if all system registers can be saved
+	 * later.
+	 * -----------------------------------------------------
+	 */
+	mrs	x16, spsr_el3
+	mrs	x17, elr_el3
+	mrs	x18, scr_el3
+	stp	x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+	str	x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+
+	/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
+	bfi	x7, x18, #0, #1
+
+	mov	sp, x12
+
+	/* -----------------------------------------------------
+	 * Call the Secure Monitor Call handler and then drop
+	 * directly into el3_exit() which will program any
+	 * remaining architectural state prior to issuing the
+	 * ERET to the desired lower EL.
+	 * -----------------------------------------------------
+	 */
+#if DEBUG
+	cbz	x15, rt_svc_fw_critical_error
+#endif
+	blr	x15
+
+	/* -----------------------------------------------------
+	 * This routine assumes that the SP_EL3 is pointing to
+	 * a valid context structure from where the gp regs and
+	 * other special registers can be retrieved.
+	 *
+	 * Keep it in the same section as smc_handler as this
+	 * function uses a fall-through to el3_exit
+	 * -----------------------------------------------------
+	 */
+el3_exit: ; .type el3_exit, %function
+	/* -----------------------------------------------------
+	 * Save the current SP_EL0 i.e. the EL3 runtime stack
+	 * which will be used for handling the next SMC. Then
+	 * switch to SP_EL3
+	 * -----------------------------------------------------
+	 */
+	mov	x17, sp
+	msr	spsel, #1
+	str	x17, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+
+	/* -----------------------------------------------------
+	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
+	 * -----------------------------------------------------
+	 */
+	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+	ldp	x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+	msr	scr_el3, x18
+	msr	spsr_el3, x16
+	msr	elr_el3, x17
+
+	/* Restore saved general purpose registers and return */
+	b	restore_gp_registers_eret
+
+smc_unknown:
+	/*
+	 * Here we restore x4-x18 regardless of where we came from. AArch32
+	 * callers will find the registers contents unchanged, but AArch64
+	 * callers will find the registers modified (with stale earlier NS
+	 * content). Either way, we aren't leaking any secure information
+	 * through them
+	 */
+	mov	w0, #SMC_UNK
+	b	restore_gp_registers_callee_eret
+
+smc_prohibited:
+	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	mov	w0, #SMC_UNK
+	eret
+
+rt_svc_fw_critical_error:
+	msr	spsel, #1 /* Switch to SP_ELx */
+	bl	report_unhandled_exception
+
+	/* -----------------------------------------------------
+	 * The following functions are used to saved and restore
+	 * all the general pupose registers. Ideally we would
+	 * only save and restore the callee saved registers when
+	 * a world switch occurs but that type of implementation
+	 * is more complex. So currently we will always save and
+	 * restore these registers on entry and exit of EL3.
+	 * These are not macros to ensure their invocation fits
+	 * within the 32 instructions per exception vector.
+	 * -----------------------------------------------------
+	 */
+func save_gp_registers
+	stp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+	stp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
+	stp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
+	stp	x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
+	stp	x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
+	stp	x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
+	stp	x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
+	stp	x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
+	stp	x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
+	save_x18_to_x29_sp_el0
+	ret
+
+func restore_gp_registers_eret
+	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
+
+restore_gp_registers_callee_eret:
+	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
+	ldp	x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
+	ldp	x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
+	ldp	x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
+	ldp	x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
+	ldp	x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
+	ldp	x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]
+	ldp	x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]
+	ldp	x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]
+	ldp	x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]
+	ldp	x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]
+	ldp	x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
+	ldp	x30, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	msr	sp_el0, x17
+	ldp	x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
+	eret
diff --git a/uefi/arm-trusted-firmware/bl31/bl31.ld.S b/uefi/arm-trusted-firmware/bl31/bl31.ld.S
new file mode 100644
index 0000000..3327f31
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/bl31.ld.S
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <platform_def.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(bl31_entrypoint)
+
+
+MEMORY {
+    RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE
+}
+
+
+SECTIONS
+{
+    . = BL31_BASE;
+    ASSERT(. == ALIGN(4096),
+           "BL31_BASE address is not aligned on a page boundary.")
+
+    ro . : {
+        __RO_START__ = .;
+        *bl31_entrypoint.o(.text*)
+        *(.text*)
+        *(.rodata*)
+
+        /* Ensure 8-byte alignment for descriptors and ensure inclusion */
+        . = ALIGN(8);
+        __RT_SVC_DESCS_START__ = .;
+        KEEP(*(rt_svc_descs))
+        __RT_SVC_DESCS_END__ = .;
+
+        /*
+         * Ensure 8-byte alignment for cpu_ops so that its fields are also
+         * aligned. Also ensure cpu_ops inclusion.
+         */
+        . = ALIGN(8);
+        __CPU_OPS_START__ = .;
+        KEEP(*(cpu_ops))
+        __CPU_OPS_END__ = .;
+
+        *(.vectors)
+        __RO_END_UNALIGNED__ = .;
+        /*
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable.  No RW data from the next section must creep in.
+         * Ensure the rest of the current memory page is unused.
+         */
+        . = NEXT(4096);
+        __RO_END__ = .;
+    } >RAM
+
+    ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
+           "cpu_ops not defined for this platform.")
+
+    .data . : {
+        __DATA_START__ = .;
+        *(.data*)
+        __DATA_END__ = .;
+    } >RAM
+
+#ifdef BL31_PROGBITS_LIMIT
+    ASSERT(. <= BL31_PROGBITS_LIMIT, "BL3-1 progbits has exceeded its limit.")
+#endif
+
+    stacks (NOLOAD) : {
+        __STACKS_START__ = .;
+        *(tzfw_normal_stacks)
+        __STACKS_END__ = .;
+    } >RAM
+
+    /*
+     * The .bss section gets initialised to 0 at runtime.
+     * Its base address must be 16-byte aligned.
+     */
+    .bss : ALIGN(16) {
+        __BSS_START__ = .;
+        *(.bss*)
+        *(COMMON)
+        __BSS_END__ = .;
+    } >RAM
+
+    /*
+     * The xlat_table section is for full, aligned page tables (4K).
+     * Removing them from .bss avoids forcing 4K alignment on
+     * the .bss section and eliminates the unecessary zero init
+     */
+    xlat_table (NOLOAD) : {
+        *(xlat_table)
+    } >RAM
+
+#if USE_COHERENT_MEM
+    /*
+     * The base address of the coherent memory section must be page-aligned (4K)
+     * to guarantee that the coherent data are stored on their own pages and
+     * are not mixed with normal data.  This is required to set up the correct
+     * memory attributes for the coherent data page tables.
+     */
+    coherent_ram (NOLOAD) : ALIGN(4096) {
+        __COHERENT_RAM_START__ = .;
+        *(tzfw_coherent_mem)
+        __COHERENT_RAM_END_UNALIGNED__ = .;
+        /*
+         * Memory page(s) mapped to this section will be marked
+         * as device memory.  No other unexpected data must creep in.
+         * Ensure the rest of the current memory page is unused.
+         */
+        . = NEXT(4096);
+        __COHERENT_RAM_END__ = .;
+    } >RAM
+#endif
+
+    __BL31_END__ = .;
+
+    __BSS_SIZE__ = SIZEOF(.bss);
+#if USE_COHERENT_MEM
+    __COHERENT_RAM_UNALIGNED_SIZE__ =
+        __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
+#endif
+
+    ASSERT(. <= BL31_LIMIT, "BL3-1 image has exceeded its limit.")
+}
diff --git a/uefi/arm-trusted-firmware/bl31/bl31.mk b/uefi/arm-trusted-firmware/bl31/bl31.mk
new file mode 100644
index 0000000..4c25a60
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/bl31.mk
@@ -0,0 +1,77 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BL31_SOURCES		+=	bl31/bl31_main.c				\
+				bl31/context_mgmt.c				\
+				bl31/cpu_data_array.c				\
+				bl31/runtime_svc.c				\
+				bl31/interrupt_mgmt.c				\
+				bl31/aarch64/bl31_arch_setup.c			\
+				bl31/aarch64/bl31_entrypoint.S			\
+				bl31/aarch64/context.S				\
+				bl31/aarch64/cpu_data.S				\
+				bl31/aarch64/runtime_exceptions.S		\
+				bl31/aarch64/crash_reporting.S			\
+				lib/cpus/aarch64/cpu_helpers.S			\
+				lib/locks/exclusive/spinlock.S			\
+				services/std_svc/std_svc_setup.c		\
+				services/std_svc/psci/psci_afflvl_off.c		\
+				services/std_svc/psci/psci_afflvl_on.c		\
+				services/std_svc/psci/psci_afflvl_suspend.c	\
+				services/std_svc/psci/psci_common.c		\
+				services/std_svc/psci/psci_entry.S		\
+				services/std_svc/psci/psci_helpers.S		\
+				services/std_svc/psci/psci_main.c		\
+				services/std_svc/psci/psci_setup.c		\
+				services/std_svc/psci/psci_system_off.c
+
+ifeq (${USE_COHERENT_MEM}, 1)
+BL31_SOURCES		+=	lib/locks/bakery/bakery_lock_coherent.c
+else
+BL31_SOURCES		+=	lib/locks/bakery/bakery_lock_normal.c
+endif
+
+BL31_LINKERFILE		:=	bl31/bl31.ld.S
+
+# Flag used by the generic interrupt management framework to  determine if
+# upon the assertion of an interrupt, it should pass the interrupt id or not
+IMF_READ_INTERRUPT_ID	:=	0
+
+$(eval $(call assert_boolean,IMF_READ_INTERRUPT_ID))
+$(eval $(call add_define,IMF_READ_INTERRUPT_ID))
+
+# Flag used to inidicate if Crash reporting via console should be included
+# in BL3-1. This defaults to being present in DEBUG builds only
+ifndef CRASH_REPORTING
+CRASH_REPORTING		:=	$(DEBUG)
+endif
+
+$(eval $(call assert_boolean,CRASH_REPORTING))
+$(eval $(call add_define,CRASH_REPORTING))
diff --git a/uefi/arm-trusted-firmware/bl31/bl31_main.c b/uefi/arm-trusted-firmware/bl31/bl31_main.c
new file mode 100644
index 0000000..19f3774
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/bl31_main.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <bl31.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <platform.h>
+#include <runtime_svc.h>
+#include <string.h>
+
+/*******************************************************************************
+ * This function pointer is used to initialise the BL32 image. It's initialized
+ * by SPD calling bl31_register_bl32_init after setting up all things necessary
+ * for SP execution. In cases where both SPD and SP are absent, or when SPD
+ * finds it impossible to execute SP, this pointer is left as NULL
+ ******************************************************************************/
+static int32_t (*bl32_init)(void);
+
+/*******************************************************************************
+ * Variable to indicate whether next image to execute after BL31 is BL33
+ * (non-secure & default) or BL32 (secure).
+ ******************************************************************************/
+static uint32_t next_image_type = NON_SECURE;
+
+/*******************************************************************************
+ * Simple function to initialise all BL31 helper libraries.
+ ******************************************************************************/
+void bl31_lib_init(void)
+{
+	cm_init();
+}
+
+/*******************************************************************************
+ * BL31 is responsible for setting up the runtime services for the primary cpu
+ * before passing control to the bootloader or an Operating System. This
+ * function calls runtime_svc_init() which initializes all registered runtime
+ * services. The run time services would setup enough context for the core to
+ * swtich to the next exception level. When this function returns, the core will
+ * switch to the programmed exception level via. an ERET.
+ ******************************************************************************/
+void bl31_main(void)
+{
+	NOTICE("BL3-1: %s\n", version_string);
+	NOTICE("BL3-1: %s\n", build_message);
+
+	/* Perform remaining generic architectural setup from EL3 */
+	bl31_arch_setup();
+
+	/* Perform platform setup in BL1 */
+	bl31_platform_setup();
+
+	/* Initialise helper libraries */
+	bl31_lib_init();
+
+	/* Initialize the runtime services e.g. psci */
+	INFO("BL3-1: Initializing runtime services\n");
+	runtime_svc_init();
+
+	/* Clean caches before re-entering normal world */
+	dcsw_op_all(DCCSW);
+
+	/*
+	 * All the cold boot actions on the primary cpu are done. We now need to
+	 * decide which is the next image (BL32 or BL33) and how to execute it.
+	 * If the SPD runtime service is present, it would want to pass control
+	 * to BL32 first in S-EL1. In that case, SPD would have registered a
+	 * function to intialize bl32 where it takes responsibility of entering
+	 * S-EL1 and returning control back to bl31_main. Once this is done we
+	 * can prepare entry into BL33 as normal.
+	 */
+
+	/*
+	 * If SPD had registerd an init hook, invoke it.
+	 */
+	if (bl32_init) {
+		INFO("BL3-1: Initializing BL3-2\n");
+		(*bl32_init)();
+	}
+	/*
+	 * We are ready to enter the next EL. Prepare entry into the image
+	 * corresponding to the desired security state after the next ERET.
+	 */
+	bl31_prepare_next_image_entry();
+}
+
+/*******************************************************************************
+ * Accessor functions to help runtime services decide which image should be
+ * executed after BL31. This is BL33 or the non-secure bootloader image by
+ * default but the Secure payload dispatcher could override this by requesting
+ * an entry into BL32 (Secure payload) first. If it does so then it should use
+ * the same API to program an entry into BL33 once BL32 initialisation is
+ * complete.
+ ******************************************************************************/
+void bl31_set_next_image_type(uint32_t security_state)
+{
+	assert(sec_state_is_valid(security_state));
+	next_image_type = security_state;
+}
+
+uint32_t bl31_get_next_image_type(void)
+{
+	return next_image_type;
+}
+
+/*******************************************************************************
+ * This function programs EL3 registers and performs other setup to enable entry
+ * into the next image after BL31 at the next ERET.
+ ******************************************************************************/
+void bl31_prepare_next_image_entry(void)
+{
+	entry_point_info_t *next_image_info;
+	uint32_t image_type;
+
+	/* Determine which image to execute next */
+	image_type = bl31_get_next_image_type();
+
+	/* Program EL3 registers to enable entry into the next EL */
+	next_image_info = bl31_plat_get_next_image_ep_info(image_type);
+	assert(next_image_info);
+	assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));
+
+	INFO("BL3-1: Preparing for EL3 exit to %s world\n",
+		(image_type == SECURE) ? "secure" : "normal");
+	INFO("BL3-1: Next image address = 0x%llx\n",
+		(unsigned long long) next_image_info->pc);
+	INFO("BL3-1: Next image spsr = 0x%x\n", next_image_info->spsr);
+	cm_init_context(read_mpidr_el1(), next_image_info);
+	cm_prepare_el3_exit(image_type);
+}
+
+/*******************************************************************************
+ * This function initializes the pointer to BL32 init function. This is expected
+ * to be called by the SPD after it finishes all its initialization
+ ******************************************************************************/
+void bl31_register_bl32_init(int32_t (*func)(void))
+{
+	bl32_init = func;
+}
diff --git a/uefi/arm-trusted-firmware/bl31/context_mgmt.c b/uefi/arm-trusted-firmware/bl31/context_mgmt.c
new file mode 100644
index 0000000..6f27176
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/context_mgmt.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <bl31.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <cpu_data.h>
+#include <interrupt_mgmt.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <runtime_svc.h>
+#include <string.h>
+
+
+/*******************************************************************************
+ * Context management library initialisation routine. This library is used by
+ * runtime services to share pointers to 'cpu_context' structures for the secure
+ * and non-secure states. Management of the structures and their associated
+ * memory is not done by the context management library e.g. the PSCI service
+ * manages the cpu context used for entry from and exit to the non-secure state.
+ * The Secure payload dispatcher service manages the context(s) corresponding to
+ * the secure state. It also uses this library to get access to the non-secure
+ * state cpu context pointers.
+ * Lastly, this library provides the api to make SP_EL3 point to the cpu context
+ * which will used for programming an entry into a lower EL. The same context
+ * will used to save state upon exception entry from that EL.
+ ******************************************************************************/
+void cm_init(void)
+{
+	/*
+	 * The context management library has only global data to intialize, but
+	 * that will be done when the BSS is zeroed out
+	 */
+}
+
+/*******************************************************************************
+ * This function returns a pointer to the most recent 'cpu_context' structure
+ * for the CPU identified by MPIDR that was set as the context for the specified
+ * security state. NULL is returned if no such structure has been specified.
+ ******************************************************************************/
+void *cm_get_context_by_mpidr(uint64_t mpidr, uint32_t security_state)
+{
+	assert(sec_state_is_valid(security_state));
+
+	return get_cpu_data_by_mpidr(mpidr, cpu_context[security_state]);
+}
+
+/*******************************************************************************
+ * This function sets the pointer to the current 'cpu_context' structure for the
+ * specified security state for the CPU identified by MPIDR
+ ******************************************************************************/
+void cm_set_context_by_mpidr(uint64_t mpidr, void *context, uint32_t security_state)
+{
+	assert(sec_state_is_valid(security_state));
+
+	set_cpu_data_by_mpidr(mpidr, cpu_context[security_state], context);
+}
+
+/*******************************************************************************
+ * This function is used to program the context that's used for exception
+ * return. This initializes the SP_EL3 to a pointer to a 'cpu_context' set for
+ * the required security state
+ ******************************************************************************/
+static inline void cm_set_next_context(void *context)
+{
+#if DEBUG
+	uint64_t sp_mode;
+
+	/*
+	 * Check that this function is called with SP_EL0 as the stack
+	 * pointer
+	 */
+	__asm__ volatile("mrs	%0, SPSel\n"
+			 : "=r" (sp_mode));
+
+	assert(sp_mode == MODE_SP_EL0);
+#endif
+
+	__asm__ volatile("msr	spsel, #1\n"
+			 "mov	sp, %0\n"
+			 "msr	spsel, #0\n"
+			 : : "r" (context));
+}
+
+/*******************************************************************************
+ * The following function initializes a cpu_context for the current CPU for
+ * first use, and sets the initial entrypoint state as specified by the
+ * entry_point_info structure.
+ *
+ * The security state to initialize is determined by the SECURE attribute
+ * of the entry_point_info. The function returns a pointer to the initialized
+ * context and sets this as the next context to return to.
+ *
+ * The EE and ST attributes are used to configure the endianess and secure
+ * timer availability for the new excution context.
+ *
+ * To prepare the register state for entry call cm_prepare_el3_exit() and
+ * el3_exit(). For Secure-EL1 cm_prepare_el3_exit() is equivalent to
+ * cm_e1_sysreg_context_restore().
+ ******************************************************************************/
+void cm_init_context(uint64_t mpidr, const entry_point_info_t *ep)
+{
+	uint32_t security_state;
+	cpu_context_t *ctx;
+	uint32_t scr_el3;
+	el3_state_t *state;
+	gp_regs_t *gp_regs;
+	unsigned long sctlr_elx;
+
+	security_state = GET_SECURITY_STATE(ep->h.attr);
+	ctx = cm_get_context_by_mpidr(mpidr, security_state);
+	assert(ctx);
+
+	/* Clear any residual register values from the context */
+	memset(ctx, 0, sizeof(*ctx));
+
+	/*
+	 * Base the context SCR on the current value, adjust for entry point
+	 * specific requirements and set trap bits from the IMF
+	 * TODO: provide the base/global SCR bits using another mechanism?
+	 */
+	scr_el3 = read_scr();
+	scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
+			SCR_ST_BIT | SCR_HCE_BIT);
+
+	if (security_state != SECURE)
+		scr_el3 |= SCR_NS_BIT;
+
+	if (GET_RW(ep->spsr) == MODE_RW_64)
+		scr_el3 |= SCR_RW_BIT;
+
+	if (EP_GET_ST(ep->h.attr))
+		scr_el3 |= SCR_ST_BIT;
+
+	scr_el3 |= get_scr_el3_from_routing_model(security_state);
+
+	/*
+	 * Set up SCTLR_ELx for the target exception level:
+	 * EE bit is taken from the entrpoint attributes
+	 * M, C and I bits must be zero (as required by PSCI specification)
+	 *
+	 * The target exception level is based on the spsr mode requested.
+	 * If execution is requested to EL2 or hyp mode, HVC is enabled
+	 * via SCR_EL3.HCE.
+	 *
+	 * Always compute the SCTLR_EL1 value and save in the cpu_context
+	 * - the EL2 registers are set up by cm_preapre_ns_entry() as they
+	 * are not part of the stored cpu_context
+	 *
+	 * TODO: In debug builds the spsr should be validated and checked
+	 * against the CPU support, security state, endianess and pc
+	 */
+	sctlr_elx = EP_GET_EE(ep->h.attr) ? SCTLR_EE_BIT : 0;
+	if (GET_RW(ep->spsr) == MODE_RW_64)
+		sctlr_elx |= SCTLR_EL1_RES1;
+	else
+		sctlr_elx |= SCTLR_AARCH32_EL1_RES1;
+	write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
+
+	if ((GET_RW(ep->spsr) == MODE_RW_64
+	     && GET_EL(ep->spsr) == MODE_EL2)
+	    || (GET_RW(ep->spsr) != MODE_RW_64
+		&& GET_M32(ep->spsr) == MODE32_hyp)) {
+		scr_el3 |= SCR_HCE_BIT;
+	}
+
+	/* Populate EL3 state so that we've the right context before doing ERET */
+	state = get_el3state_ctx(ctx);
+	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
+	write_ctx_reg(state, CTX_ELR_EL3, ep->pc);
+	write_ctx_reg(state, CTX_SPSR_EL3, ep->spsr);
+
+	/*
+	 * Store the X0-X7 value from the entrypoint into the context
+	 * Use memcpy as we are in control of the layout of the structures
+	 */
+	gp_regs = get_gpregs_ctx(ctx);
+	memcpy(gp_regs, (void *)&ep->args, sizeof(aapcs64_params_t));
+}
+
+/*******************************************************************************
+ * Prepare the CPU system registers for first entry into secure or normal world
+ *
+ * If execution is requested to EL2 or hyp mode, SCTLR_EL2 is initialized
+ * If execution is requested to non-secure EL1 or svc mode, and the CPU supports
+ * EL2 then EL2 is disabled by configuring all necessary EL2 registers.
+ * For all entries, the EL1 registers are initialized from the cpu_context
+ ******************************************************************************/
+void cm_prepare_el3_exit(uint32_t security_state)
+{
+	uint32_t sctlr_elx, scr_el3, cptr_el2;
+	cpu_context_t *ctx = cm_get_context(security_state);
+
+	assert(ctx);
+
+	if (security_state == NON_SECURE) {
+		scr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_SCR_EL3);
+		if (scr_el3 & SCR_HCE_BIT) {
+			/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
+			sctlr_elx = read_ctx_reg(get_sysregs_ctx(ctx),
+						 CTX_SCTLR_EL1);
+			sctlr_elx &= ~SCTLR_EE_BIT;
+			sctlr_elx |= SCTLR_EL2_RES1;
+			write_sctlr_el2(sctlr_elx);
+		} else if (read_id_aa64pfr0_el1() &
+			   (ID_AA64PFR0_ELX_MASK << ID_AA64PFR0_EL2_SHIFT)) {
+			/* EL2 present but unused, need to disable safely */
+
+			/* HCR_EL2 = 0, except RW bit set to match SCR_EL3 */
+			write_hcr_el2((scr_el3 & SCR_RW_BIT) ? HCR_RW_BIT : 0);
+
+			/* SCTLR_EL2 : can be ignored when bypassing */
+
+			/* CPTR_EL2 : disable all traps TCPAC, TTA, TFP */
+			cptr_el2 = read_cptr_el2();
+			cptr_el2 &= ~(TCPAC_BIT | TTA_BIT | TFP_BIT);
+			write_cptr_el2(cptr_el2);
+
+			/* Enable EL1 access to timer */
+			write_cnthctl_el2(EL1PCEN_BIT | EL1PCTEN_BIT);
+
+			/* Reset CNTVOFF_EL2 */
+			write_cntvoff_el2(0);
+
+			/* Set VPIDR, VMPIDR to match MIDR, MPIDR */
+			write_vpidr_el2(read_midr_el1());
+			write_vmpidr_el2(read_mpidr_el1());
+		}
+	}
+
+	el1_sysregs_context_restore(get_sysregs_ctx(ctx));
+
+	cm_set_next_context(ctx);
+}
+
+/*******************************************************************************
+ * The next four functions are used by runtime services to save and restore
+ * EL1 context on the 'cpu_context' structure for the specified security
+ * state.
+ ******************************************************************************/
+void cm_el1_sysregs_context_save(uint32_t security_state)
+{
+	cpu_context_t *ctx;
+
+	ctx = cm_get_context(security_state);
+	assert(ctx);
+
+	el1_sysregs_context_save(get_sysregs_ctx(ctx));
+}
+
+void cm_el1_sysregs_context_restore(uint32_t security_state)
+{
+	cpu_context_t *ctx;
+
+	ctx = cm_get_context(security_state);
+	assert(ctx);
+
+	el1_sysregs_context_restore(get_sysregs_ctx(ctx));
+}
+
+/*******************************************************************************
+ * This function populates ELR_EL3 member of 'cpu_context' pertaining to the
+ * given security state with the given entrypoint
+ ******************************************************************************/
+void cm_set_elr_el3(uint32_t security_state, uint64_t entrypoint)
+{
+	cpu_context_t *ctx;
+	el3_state_t *state;
+
+	ctx = cm_get_context(security_state);
+	assert(ctx);
+
+	/* Populate EL3 state so that ERET jumps to the correct entry */
+	state = get_el3state_ctx(ctx);
+	write_ctx_reg(state, CTX_ELR_EL3, entrypoint);
+}
+
+/*******************************************************************************
+ * This function populates ELR_EL3 and SPSR_EL3 members of 'cpu_context'
+ * pertaining to the given security state
+ ******************************************************************************/
+void cm_set_elr_spsr_el3(uint32_t security_state,
+			 uint64_t entrypoint, uint32_t spsr)
+{
+	cpu_context_t *ctx;
+	el3_state_t *state;
+
+	ctx = cm_get_context(security_state);
+	assert(ctx);
+
+	/* Populate EL3 state so that ERET jumps to the correct entry */
+	state = get_el3state_ctx(ctx);
+	write_ctx_reg(state, CTX_ELR_EL3, entrypoint);
+	write_ctx_reg(state, CTX_SPSR_EL3, spsr);
+}
+
+/*******************************************************************************
+ * This function updates a single bit in the SCR_EL3 member of the 'cpu_context'
+ * pertaining to the given security state using the value and bit position
+ * specified in the parameters. It preserves all other bits.
+ ******************************************************************************/
+void cm_write_scr_el3_bit(uint32_t security_state,
+			  uint32_t bit_pos,
+			  uint32_t value)
+{
+	cpu_context_t *ctx;
+	el3_state_t *state;
+	uint32_t scr_el3;
+
+	ctx = cm_get_context(security_state);
+	assert(ctx);
+
+	/* Ensure that the bit position is a valid one */
+	assert((1 << bit_pos) & SCR_VALID_BIT_MASK);
+
+	/* Ensure that the 'value' is only a bit wide */
+	assert(value <= 1);
+
+	/*
+	 * Get the SCR_EL3 value from the cpu context, clear the desired bit
+	 * and set it to its new value.
+	 */
+	state = get_el3state_ctx(ctx);
+	scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
+	scr_el3 &= ~(1 << bit_pos);
+	scr_el3 |= value << bit_pos;
+	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
+}
+
+/*******************************************************************************
+ * This function retrieves SCR_EL3 member of 'cpu_context' pertaining to the
+ * given security state.
+ ******************************************************************************/
+uint32_t cm_get_scr_el3(uint32_t security_state)
+{
+	cpu_context_t *ctx;
+	el3_state_t *state;
+
+	ctx = cm_get_context(security_state);
+	assert(ctx);
+
+	/* Populate EL3 state so that ERET jumps to the correct entry */
+	state = get_el3state_ctx(ctx);
+	return read_ctx_reg(state, CTX_SCR_EL3);
+}
+
+/*******************************************************************************
+ * This function is used to program the context that's used for exception
+ * return. This initializes the SP_EL3 to a pointer to a 'cpu_context' set for
+ * the required security state
+ ******************************************************************************/
+void cm_set_next_eret_context(uint32_t security_state)
+{
+	cpu_context_t *ctx;
+
+	ctx = cm_get_context(security_state);
+	assert(ctx);
+
+	cm_set_next_context(ctx);
+}
diff --git a/uefi/arm-trusted-firmware/bl31/cpu_data_array.c b/uefi/arm-trusted-firmware/bl31/cpu_data_array.c
new file mode 100644
index 0000000..4cba118
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/cpu_data_array.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cassert.h>
+#include <cpu_data.h>
+#include <platform_def.h>
+
+/* The per_cpu_ptr_cache_t space allocation */
+cpu_data_t percpu_data[PLATFORM_CORE_COUNT];
diff --git a/uefi/arm-trusted-firmware/bl31/interrupt_mgmt.c b/uefi/arm-trusted-firmware/bl31/interrupt_mgmt.c
new file mode 100644
index 0000000..5478902
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/interrupt_mgmt.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <context_mgmt.h>
+#include <errno.h>
+#include <interrupt_mgmt.h>
+#include <platform.h>
+#include <stdio.h>
+
+/*******************************************************************************
+ * Local structure and corresponding array to keep track of the state of the
+ * registered interrupt handlers for each interrupt type.
+ * The field descriptions are:
+ *
+ * 'flags' : Bit[0], Routing model for this interrupt type when execution is
+ *                   not in EL3 in the secure state. '1' implies that this
+ *                   interrupt will be routed to EL3. '0' implies that this
+ *                   interrupt will be routed to the current exception level.
+ *
+ *           Bit[1], Routing model for this interrupt type when execution is
+ *                   not in EL3 in the non-secure state. '1' implies that this
+ *                   interrupt will be routed to EL3. '0' implies that this
+ *                   interrupt will be routed to the current exception level.
+ *
+ *           All other bits are reserved and SBZ.
+ *
+ * 'scr_el3[2]'  : Mapping of the routing model in the 'flags' field to the
+ *                 value of the SCR_EL3.IRQ or FIQ bit for each security state.
+ *                 There are two instances of this field corresponding to the
+ *                 two security states.
+ ******************************************************************************/
+typedef struct intr_type_desc {
+	interrupt_type_handler_t handler;
+	uint32_t flags;
+	uint32_t scr_el3[2];
+} intr_type_desc_t;
+
+static intr_type_desc_t intr_type_descs[MAX_INTR_TYPES];
+
+/*******************************************************************************
+ * This function validates the interrupt type. EL3 interrupts are currently not
+ * supported.
+ ******************************************************************************/
+static int32_t validate_interrupt_type(uint32_t type)
+{
+	if (type == INTR_TYPE_EL3)
+		return -ENOTSUP;
+
+	if (type != INTR_TYPE_S_EL1 && type != INTR_TYPE_NS)
+		return -EINVAL;
+
+	return 0;
+}
+
+/*******************************************************************************
+* This function validates the routing model for this type of interrupt
+ ******************************************************************************/
+static int32_t validate_routing_model(uint32_t type, uint32_t flags)
+{
+	flags >>= INTR_RM_FLAGS_SHIFT;
+	flags &= INTR_RM_FLAGS_MASK;
+
+	if (type == INTR_TYPE_S_EL1)
+		return validate_sel1_interrupt_rm(flags);
+
+	if (type == INTR_TYPE_NS)
+		return validate_ns_interrupt_rm(flags);
+
+	return -EINVAL;
+}
+
+/*******************************************************************************
+ * This function returns the cached copy of the SCR_EL3 which contains the
+ * routing model (expressed through the IRQ and FIQ bits) for a security state
+ * which was stored through a call to 'set_routing_model()' earlier.
+ ******************************************************************************/
+uint32_t get_scr_el3_from_routing_model(uint32_t security_state)
+{
+	uint32_t scr_el3;
+
+	assert(sec_state_is_valid(security_state));
+	scr_el3 = intr_type_descs[INTR_TYPE_NS].scr_el3[security_state];
+	scr_el3 |= intr_type_descs[INTR_TYPE_S_EL1].scr_el3[security_state];
+	scr_el3 |= intr_type_descs[INTR_TYPE_EL3].scr_el3[security_state];
+	return scr_el3;
+}
+
+/*******************************************************************************
+ * This function uses the 'interrupt_type_flags' parameter to obtain the value
+ * of the trap bit (IRQ/FIQ) in the SCR_EL3 for a security state for this
+ * interrupt type. It uses it to update the SCR_EL3 in the cpu context and the
+ * 'intr_type_desc' for that security state.
+ ******************************************************************************/
+static void set_scr_el3_from_rm(uint32_t type,
+				uint32_t interrupt_type_flags,
+				uint32_t security_state)
+{
+	uint32_t flag, bit_pos;
+
+	flag = get_interrupt_rm_flag(interrupt_type_flags, security_state);
+	bit_pos = plat_interrupt_type_to_line(type, security_state);
+	intr_type_descs[type].scr_el3[security_state] = flag << bit_pos;
+	cm_write_scr_el3_bit(security_state, bit_pos, flag);
+}
+
+/*******************************************************************************
+ * This function validates the routing model specified in the 'flags' and
+ * updates internal data structures to reflect the new routing model. It also
+ * updates the copy of SCR_EL3 for each security state with the new routing
+ * model in the 'cpu_context' structure for this cpu.
+ ******************************************************************************/
+int32_t set_routing_model(uint32_t type, uint32_t flags)
+{
+	int32_t rc;
+
+	rc = validate_interrupt_type(type);
+	if (rc)
+		return rc;
+
+	rc = validate_routing_model(type, flags);
+	if (rc)
+		return rc;
+
+	/* Update the routing model in internal data structures */
+	intr_type_descs[type].flags = flags;
+	set_scr_el3_from_rm(type, flags, SECURE);
+	set_scr_el3_from_rm(type, flags, NON_SECURE);
+
+	return 0;
+}
+
+/******************************************************************************
+ * This function disables the routing model of interrupt 'type' from the
+ * specified 'security_state' on the local core. The disable is in effect
+ * till the core powers down or till the next enable for that interrupt
+ * type.
+ *****************************************************************************/
+int disable_intr_rm_local(uint32_t type, uint32_t security_state)
+{
+	uint32_t bit_pos, flag;
+
+	assert(intr_type_descs[type].handler);
+
+	flag = get_interrupt_rm_flag(INTR_DEFAULT_RM, security_state);
+
+	bit_pos = plat_interrupt_type_to_line(type, security_state);
+	cm_write_scr_el3_bit(security_state, bit_pos, flag);
+
+	return 0;
+}
+
+/******************************************************************************
+ * This function enables the routing model of interrupt 'type' from the
+ * specified 'security_state' on the local core.
+ *****************************************************************************/
+int enable_intr_rm_local(uint32_t type, uint32_t security_state)
+{
+	uint32_t bit_pos, flag;
+
+	assert(intr_type_descs[type].handler);
+
+	flag = get_interrupt_rm_flag(intr_type_descs[type].flags,
+				security_state);
+
+	bit_pos = plat_interrupt_type_to_line(type, security_state);
+	cm_write_scr_el3_bit(security_state, bit_pos, flag);
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function registers a handler for the 'type' of interrupt specified. It
+ * also validates the routing model specified in the 'flags' for this type of
+ * interrupt.
+ ******************************************************************************/
+int32_t register_interrupt_type_handler(uint32_t type,
+					interrupt_type_handler_t handler,
+					uint32_t flags)
+{
+	int32_t rc;
+
+	/* Validate the 'handler' parameter */
+	if (!handler)
+		return -EINVAL;
+
+	/* Validate the 'flags' parameter */
+	if (flags & INTR_TYPE_FLAGS_MASK)
+		return -EINVAL;
+
+	/* Check if a handler has already been registered */
+	if (intr_type_descs[type].handler)
+		return -EALREADY;
+
+	rc = set_routing_model(type, flags);
+	if (rc)
+		return rc;
+
+	/* Save the handler */
+	intr_type_descs[type].handler = handler;
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function is called when an interrupt is generated and returns the
+ * handler for the interrupt type (if registered). It returns NULL if the
+ * interrupt type is not supported or its handler has not been registered.
+ ******************************************************************************/
+interrupt_type_handler_t get_interrupt_type_handler(uint32_t type)
+{
+	if (validate_interrupt_type(type))
+		return NULL;
+
+	return intr_type_descs[type].handler;
+}
+
diff --git a/uefi/arm-trusted-firmware/bl31/runtime_svc.c b/uefi/arm-trusted-firmware/bl31/runtime_svc.c
new file mode 100644
index 0000000..c33748f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl31/runtime_svc.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <errno.h>
+#include <runtime_svc.h>
+#include <string.h>
+
+/*******************************************************************************
+ * The 'rt_svc_descs' array holds the runtime service descriptors exported by
+ * services by placing them in the 'rt_svc_descs' linker section.
+ * The 'rt_svc_descs_indices' array holds the index of a descriptor in the
+ * 'rt_svc_descs' array. When an SMC arrives, the OEN[29:24] bits and the call
+ * type[31] bit in the function id are combined to get an index into the
+ * 'rt_svc_descs_indices' array. This gives the index of the descriptor in the
+ * 'rt_svc_descs' array which contains the SMC handler.
+ ******************************************************************************/
+#define RT_SVC_DESCS_START	((uint64_t) (&__RT_SVC_DESCS_START__))
+#define RT_SVC_DESCS_END	((uint64_t) (&__RT_SVC_DESCS_END__))
+uint8_t rt_svc_descs_indices[MAX_RT_SVCS];
+static rt_svc_desc_t *rt_svc_descs;
+
+/*******************************************************************************
+ * Simple routine to sanity check a runtime service descriptor before using it
+ ******************************************************************************/
+static int32_t validate_rt_svc_desc(rt_svc_desc_t *desc)
+{
+	if (desc == NULL)
+		return -EINVAL;
+
+	if (desc->start_oen > desc->end_oen)
+		return -EINVAL;
+
+	if (desc->end_oen >= OEN_LIMIT)
+		return -EINVAL;
+
+	if (desc->call_type != SMC_TYPE_FAST && desc->call_type != SMC_TYPE_STD)
+		return -EINVAL;
+
+	/* A runtime service having no init or handle function doesn't make sense */
+	if (desc->init == NULL && desc->handle == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function calls the initialisation routine in the descriptor exported by
+ * a runtime service. Once a descriptor has been validated, its start & end
+ * owning entity numbers and the call type are combined to form a unique oen.
+ * The unique oen is used as an index into the 'rt_svc_descs_indices' array.
+ * The index of the runtime service descriptor is stored at this index.
+ ******************************************************************************/
+void runtime_svc_init(void)
+{
+	int32_t rc = 0;
+	uint32_t index, start_idx, end_idx;
+	uint64_t rt_svc_descs_num;
+
+	/* If no runtime services are implemented then simply bail out */
+	rt_svc_descs_num = RT_SVC_DESCS_END - RT_SVC_DESCS_START;
+	rt_svc_descs_num /= sizeof(rt_svc_desc_t);
+	if (rt_svc_descs_num == 0)
+		return;
+
+	/* Initialise internal variables to invalid state */
+	memset(rt_svc_descs_indices, -1, sizeof(rt_svc_descs_indices));
+
+	rt_svc_descs = (rt_svc_desc_t *) RT_SVC_DESCS_START;
+	for (index = 0; index < rt_svc_descs_num; index++) {
+
+		/*
+		 * An invalid descriptor is an error condition since it is
+		 * difficult to predict the system behaviour in the absence
+		 * of this service.
+		 */
+		rc = validate_rt_svc_desc(&rt_svc_descs[index]);
+		if (rc) {
+			ERROR("Invalid runtime service descriptor 0x%x (%s)\n",
+					&rt_svc_descs[index],
+					rt_svc_descs[index].name);
+			goto error;
+		}
+
+		/*
+		 * The runtime service may have seperate rt_svc_desc_t
+		 * for its fast smc and standard smc. Since the service itself
+		 * need to be initialized only once, only one of them will have
+		 * an initialisation routine defined. Call the initialisation
+		 * routine for this runtime service, if it is defined.
+		 */
+		if (rt_svc_descs[index].init) {
+			rc = rt_svc_descs[index].init();
+			if (rc) {
+				ERROR("Error initializing runtime service %s\n",
+						rt_svc_descs[index].name);
+				continue;
+			}
+		}
+
+		/*
+		 * Fill the indices corresponding to the start and end
+		 * owning entity numbers with the index of the
+		 * descriptor which will handle the SMCs for this owning
+		 * entity range.
+		 */
+		start_idx = get_unique_oen(rt_svc_descs[index].start_oen,
+				rt_svc_descs[index].call_type);
+		end_idx = get_unique_oen(rt_svc_descs[index].end_oen,
+				rt_svc_descs[index].call_type);
+
+		for (; start_idx <= end_idx; start_idx++)
+			rt_svc_descs_indices[start_idx] = index;
+	}
+
+	return;
+error:
+	panic();
+}
diff --git a/uefi/arm-trusted-firmware/bl32/tsp/aarch64/tsp_entrypoint.S b/uefi/arm-trusted-firmware/bl32/tsp/aarch64/tsp_entrypoint.S
new file mode 100644
index 0000000..2714282
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <tsp.h>
+#include <xlat_tables.h>
+#include "../tsp_private.h"
+
+
+	.globl	tsp_entrypoint
+	.globl  tsp_vector_table
+
+
+
+	/* ---------------------------------------------
+	 * Populate the params in x0-x7 from the pointer
+	 * to the smc args structure in x0.
+	 * ---------------------------------------------
+	 */
+	.macro restore_args_call_smc
+	ldp	x6, x7, [x0, #TSP_ARG6]
+	ldp	x4, x5, [x0, #TSP_ARG4]
+	ldp	x2, x3, [x0, #TSP_ARG2]
+	ldp	x0, x1, [x0, #TSP_ARG0]
+	smc	#0
+	.endm
+
+	.macro	save_eret_context reg1 reg2
+	mrs	\reg1, elr_el1
+	mrs	\reg2, spsr_el1
+	stp	\reg1, \reg2, [sp, #-0x10]!
+	stp	x30, x18, [sp, #-0x10]!
+	.endm
+
+	.macro restore_eret_context reg1 reg2
+	ldp	x30, x18, [sp], #0x10
+	ldp	\reg1, \reg2, [sp], #0x10
+	msr	elr_el1, \reg1
+	msr	spsr_el1, \reg2
+	.endm
+
+	.section	.text, "ax"
+	.align 3
+
+func tsp_entrypoint
+
+	/* ---------------------------------------------
+	 * Set the exception vector to something sane.
+	 * ---------------------------------------------
+	 */
+	adr	x0, tsp_exceptions
+	msr	vbar_el1, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Enable the SError interrupt now that the
+	 * exception vectors have been setup.
+	 * ---------------------------------------------
+	 */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	/* ---------------------------------------------
+	 * Enable the instruction cache, stack pointer
+	 * and data access alignment checks
+	 * ---------------------------------------------
+	 */
+	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	mrs	x0, sctlr_el1
+	orr	x0, x0, x1
+	msr	sctlr_el1, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Zero out NOBITS sections. There are 2 of them:
+	 *   - the .bss section;
+	 *   - the coherent memory section.
+	 * ---------------------------------------------
+	 */
+	ldr	x0, =__BSS_START__
+	ldr	x1, =__BSS_SIZE__
+	bl	zeromem16
+
+#if USE_COHERENT_MEM
+	ldr	x0, =__COHERENT_RAM_START__
+	ldr	x1, =__COHERENT_RAM_UNALIGNED_SIZE__
+	bl	zeromem16
+#endif
+
+	/* --------------------------------------------
+	 * Allocate a stack whose memory will be marked
+	 * as Normal-IS-WBWA when the MMU is enabled.
+	 * There is no risk of reading stale stack
+	 * memory after enabling the MMU as only the
+	 * primary cpu is running at the moment.
+	 * --------------------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	bl	platform_set_stack
+
+	/* ---------------------------------------------
+	 * Perform early platform setup & platform
+	 * specific early arch. setup e.g. mmu setup
+	 * ---------------------------------------------
+	 */
+	bl	tsp_early_platform_setup
+	bl	tsp_plat_arch_setup
+
+	/* ---------------------------------------------
+	 * Jump to main function.
+	 * ---------------------------------------------
+	 */
+	bl	tsp_main
+
+	/* ---------------------------------------------
+	 * Tell TSPD that we are done initialising
+	 * ---------------------------------------------
+	 */
+	mov	x1, x0
+	mov	x0, #TSP_ENTRY_DONE
+	smc	#0
+
+tsp_entrypoint_panic:
+	b	tsp_entrypoint_panic
+
+
+	/* -------------------------------------------
+	 * Table of entrypoint vectors provided to the
+	 * TSPD for the various entrypoints
+	 * -------------------------------------------
+	 */
+func tsp_vector_table
+	b	tsp_std_smc_entry
+	b	tsp_fast_smc_entry
+	b	tsp_cpu_on_entry
+	b	tsp_cpu_off_entry
+	b	tsp_cpu_resume_entry
+	b	tsp_cpu_suspend_entry
+	b	tsp_fiq_entry
+	b	tsp_system_off_entry
+	b	tsp_system_reset_entry
+
+	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD when this
+	 * cpu is to be turned off through a CPU_OFF
+	 * psci call to ask the TSP to perform any
+	 * bookeeping necessary. In the current
+	 * implementation, the TSPD expects the TSP to
+	 * re-initialise its state so nothing is done
+	 * here except for acknowledging the request.
+	 * ---------------------------------------------
+	 */
+func tsp_cpu_off_entry
+	bl	tsp_cpu_off_main
+	restore_args_call_smc
+
+	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD when the
+	 * system is about to be switched off (through
+	 * a SYSTEM_OFF psci call) to ask the TSP to
+	 * perform any necessary bookkeeping.
+	 * ---------------------------------------------
+	 */
+func tsp_system_off_entry
+	bl	tsp_system_off_main
+	restore_args_call_smc
+
+	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD when the
+	 * system is about to be reset (through a
+	 * SYSTEM_RESET psci call) to ask the TSP to
+	 * perform any necessary bookkeeping.
+	 * ---------------------------------------------
+	 */
+func tsp_system_reset_entry
+	bl	tsp_system_reset_main
+	restore_args_call_smc
+
+	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD when this
+	 * cpu is turned on using a CPU_ON psci call to
+	 * ask the TSP to initialise itself i.e. setup
+	 * the mmu, stacks etc. Minimal architectural
+	 * state will be initialised by the TSPD when
+	 * this function is entered i.e. Caches and MMU
+	 * will be turned off, the execution state
+	 * will be aarch64 and exceptions masked.
+	 * ---------------------------------------------
+	 */
+func tsp_cpu_on_entry
+	/* ---------------------------------------------
+	 * Set the exception vector to something sane.
+	 * ---------------------------------------------
+	 */
+	adr	x0, tsp_exceptions
+	msr	vbar_el1, x0
+	isb
+
+	/* Enable the SError interrupt */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	/* ---------------------------------------------
+	 * Enable the instruction cache, stack pointer
+	 * and data access alignment checks
+	 * ---------------------------------------------
+	 */
+	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	mrs	x0, sctlr_el1
+	orr	x0, x0, x1
+	msr	sctlr_el1, x0
+	isb
+
+	/* --------------------------------------------
+	 * Give ourselves a stack whose memory will be
+	 * marked as Normal-IS-WBWA when the MMU is
+	 * enabled.
+	 * --------------------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	bl	platform_set_stack
+
+	/* --------------------------------------------
+	 * Enable the MMU with the DCache disabled. It
+	 * is safe to use stacks allocated in normal
+	 * memory as a result. All memory accesses are
+	 * marked nGnRnE when the MMU is disabled. So
+	 * all the stack writes will make it to memory.
+	 * All memory accesses are marked Non-cacheable
+	 * when the MMU is enabled but D$ is disabled.
+	 * So used stack memory is guaranteed to be
+	 * visible immediately after the MMU is enabled
+	 * Enabling the DCache at the same time as the
+	 * MMU can lead to speculatively fetched and
+	 * possibly stale stack memory being read from
+	 * other caches. This can lead to coherency
+	 * issues.
+	 * --------------------------------------------
+	 */
+	mov	x0, #DISABLE_DCACHE
+	bl	bl32_plat_enable_mmu
+
+	/* ---------------------------------------------
+	 * Enable the Data cache now that the MMU has
+	 * been enabled. The stack has been unwound. It
+	 * will be written first before being read. This
+	 * will invalidate any stale cache lines resi-
+	 * -dent in other caches. We assume that
+	 * interconnect coherency has been enabled for
+	 * this cluster by EL3 firmware.
+	 * ---------------------------------------------
+	 */
+	mrs	x0, sctlr_el1
+	orr	x0, x0, #SCTLR_C_BIT
+	msr	sctlr_el1, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Enter C runtime to perform any remaining
+	 * book keeping
+	 * ---------------------------------------------
+	 */
+	bl	tsp_cpu_on_main
+	restore_args_call_smc
+
+	/* Should never reach here */
+tsp_cpu_on_entry_panic:
+	b	tsp_cpu_on_entry_panic
+
+	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD when this
+	 * cpu is to be suspended through a CPU_SUSPEND
+	 * psci call to ask the TSP to perform any
+	 * bookeeping necessary. In the current
+	 * implementation, the TSPD saves and restores
+	 * the EL1 state.
+	 * ---------------------------------------------
+	 */
+func tsp_cpu_suspend_entry
+	bl	tsp_cpu_suspend_main
+	restore_args_call_smc
+
+	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD to pass
+	 * control for handling a pending S-EL1 FIQ.
+	 * 'x0' contains a magic number which indicates
+	 * this. TSPD expects control to be handed back
+	 * at the end of FIQ processing. This is done
+	 * through an SMC. The handover agreement is:
+	 *
+	 * 1. PSTATE.DAIF are set upon entry. 'x1' has
+	 *    the ELR_EL3 from the non-secure state.
+	 * 2. TSP has to preserve the callee saved
+	 *    general purpose registers, SP_EL1/EL0 and
+	 *    LR.
+	 * 3. TSP has to preserve the system and vfp
+	 *    registers (if applicable).
+	 * 4. TSP can use 'x0-x18' to enable its C
+	 *    runtime.
+	 * 5. TSP returns to TSPD using an SMC with
+	 *    'x0' = TSP_HANDLED_S_EL1_FIQ
+	 * ---------------------------------------------
+	 */
+func	tsp_fiq_entry
+#if DEBUG
+	mov	x2, #(TSP_HANDLE_FIQ_AND_RETURN & ~0xffff)
+	movk	x2, #(TSP_HANDLE_FIQ_AND_RETURN &  0xffff)
+	cmp	x0, x2
+	b.ne	tsp_fiq_entry_panic
+#endif
+	/*---------------------------------------------
+	 * Save any previous context needed to perform
+	 * an exception return from S-EL1 e.g. context
+	 * from a previous IRQ. Update statistics and
+	 * handle the FIQ before returning to the TSPD.
+	 * IRQ/FIQs are not enabled since that will
+	 * complicate the implementation. Execution
+	 * will be transferred back to the normal world
+	 * in any case. A non-zero return value from the
+	 * fiq handler is an error.
+	 * ---------------------------------------------
+	 */
+	save_eret_context x2 x3
+	bl	tsp_update_sync_fiq_stats
+	bl	tsp_fiq_handler
+	cbnz	x0, tsp_fiq_entry_panic
+	restore_eret_context x2 x3
+	mov	x0, #(TSP_HANDLED_S_EL1_FIQ & ~0xffff)
+	movk	x0, #(TSP_HANDLED_S_EL1_FIQ &  0xffff)
+	smc	#0
+
+tsp_fiq_entry_panic:
+	b	tsp_fiq_entry_panic
+
+	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD when this
+	 * cpu resumes execution after an earlier
+	 * CPU_SUSPEND psci call to ask the TSP to
+	 * restore its saved context. In the current
+	 * implementation, the TSPD saves and restores
+	 * EL1 state so nothing is done here apart from
+	 * acknowledging the request.
+	 * ---------------------------------------------
+	 */
+func tsp_cpu_resume_entry
+	bl	tsp_cpu_resume_main
+	restore_args_call_smc
+tsp_cpu_resume_panic:
+	b	tsp_cpu_resume_panic
+
+	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD to ask
+	 * the TSP to service a fast smc request.
+	 * ---------------------------------------------
+	 */
+func tsp_fast_smc_entry
+	bl	tsp_smc_handler
+	restore_args_call_smc
+tsp_fast_smc_entry_panic:
+	b	tsp_fast_smc_entry_panic
+
+	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD to ask
+	 * the TSP to service a std smc request.
+	 * We will enable preemption during execution
+	 * of tsp_smc_handler.
+	 * ---------------------------------------------
+	 */
+func tsp_std_smc_entry
+	msr	daifclr, #DAIF_FIQ_BIT | DAIF_IRQ_BIT
+	bl	tsp_smc_handler
+	msr	daifset, #DAIF_FIQ_BIT | DAIF_IRQ_BIT
+	restore_args_call_smc
+tsp_std_smc_entry_panic:
+	b	tsp_std_smc_entry_panic
diff --git a/uefi/arm-trusted-firmware/bl32/tsp/aarch64/tsp_exceptions.S b/uefi/arm-trusted-firmware/bl32/tsp/aarch64/tsp_exceptions.S
new file mode 100644
index 0000000..4c0d436
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl32/tsp/aarch64/tsp_exceptions.S
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <bl_common.h>
+#include <arch.h>
+#include <tsp.h>
+#include <asm_macros.S>
+
+
+	/* ----------------------------------------------------
+	 * The caller-saved registers x0-x18 and LR are saved
+	 * here.
+	 * ----------------------------------------------------
+	 */
+
+#define SCRATCH_REG_SIZE #(20 * 8)
+
+	.macro save_caller_regs_and_lr
+	sub	sp, sp, SCRATCH_REG_SIZE
+	stp	x0, x1, [sp]
+	stp	x2, x3, [sp, #0x10]
+	stp	x4, x5, [sp, #0x20]
+	stp	x6, x7, [sp, #0x30]
+	stp	x8, x9, [sp, #0x40]
+	stp	x10, x11, [sp, #0x50]
+	stp	x12, x13, [sp, #0x60]
+	stp	x14, x15, [sp, #0x70]
+	stp	x16, x17, [sp, #0x80]
+	stp	x18, x30, [sp, #0x90]
+	.endm
+
+	.macro restore_caller_regs_and_lr
+	ldp	x0, x1, [sp]
+	ldp	x2, x3, [sp, #0x10]
+	ldp	x4, x5, [sp, #0x20]
+	ldp	x6, x7, [sp, #0x30]
+	ldp	x8, x9, [sp, #0x40]
+	ldp	x10, x11, [sp, #0x50]
+	ldp	x12, x13, [sp, #0x60]
+	ldp	x14, x15, [sp, #0x70]
+	ldp	x16, x17, [sp, #0x80]
+	ldp	x18, x30, [sp, #0x90]
+	add	sp, sp, SCRATCH_REG_SIZE
+	.endm
+
+	.globl	tsp_exceptions
+
+	/* -----------------------------------------------------
+	 * TSP exception handlers.
+	 * -----------------------------------------------------
+	 */
+	.section	.vectors, "ax"; .align 11
+
+	.align	7
+tsp_exceptions:
+	/* -----------------------------------------------------
+	 * Current EL with _sp_el0 : 0x0 - 0x180. No exceptions
+	 * are expected and treated as irrecoverable errors.
+	 * -----------------------------------------------------
+	 */
+sync_exception_sp_el0:
+	wfi
+	b	sync_exception_sp_el0
+	check_vector_size sync_exception_sp_el0
+
+	.align	7
+
+irq_sp_el0:
+	b	irq_sp_el0
+	check_vector_size irq_sp_el0
+
+	.align	7
+fiq_sp_el0:
+	b	fiq_sp_el0
+	check_vector_size fiq_sp_el0
+
+	.align	7
+serror_sp_el0:
+	b	serror_sp_el0
+	check_vector_size serror_sp_el0
+
+
+	/* -----------------------------------------------------
+	 * Current EL with SPx: 0x200 - 0x380. Only IRQs/FIQs
+	 * are expected and handled
+	 * -----------------------------------------------------
+	 */
+	.align	7
+sync_exception_sp_elx:
+	wfi
+	b	sync_exception_sp_elx
+	check_vector_size sync_exception_sp_elx
+
+	.align	7
+irq_sp_elx:
+	/* Enable the SError interrupt */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	save_caller_regs_and_lr
+	/* We just update some statistics in the handler */
+	bl	tsp_irq_received
+	/* Hand over control to the normal world to handle the IRQ */
+	smc	#0
+	/* The resume std smc starts from here */
+	restore_caller_regs_and_lr
+	eret
+	check_vector_size irq_sp_elx
+
+	.align	7
+fiq_sp_elx:
+	/* Enable the SError interrupt */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	save_caller_regs_and_lr
+	bl	tsp_fiq_handler
+	cbz	x0, fiq_sp_elx_done
+
+	/*
+	 * This FIQ was not targetted to S-EL1 so send it to
+	 * the monitor and wait for execution to resume.
+	 */
+	smc	#0
+fiq_sp_elx_done:
+	restore_caller_regs_and_lr
+	eret
+	check_vector_size fiq_sp_elx
+
+	.align	7
+serror_sp_elx:
+	b	serror_sp_elx
+	check_vector_size serror_sp_elx
+
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch64 : 0x400 - 0x580. No exceptions
+	 * are handled since TSP does not implement a lower EL
+	 * -----------------------------------------------------
+	 */
+	.align	7
+sync_exception_aarch64:
+	wfi
+	b	sync_exception_aarch64
+	check_vector_size sync_exception_aarch64
+
+	.align	7
+irq_aarch64:
+	b	irq_aarch64
+	check_vector_size irq_aarch64
+
+	.align	7
+fiq_aarch64:
+	b	fiq_aarch64
+	check_vector_size fiq_aarch64
+
+	.align	7
+serror_aarch64:
+	b	serror_aarch64
+	check_vector_size serror_aarch64
+
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch32 : 0x600 - 0x780. No exceptions
+	 * handled since the TSP does not implement a lower EL.
+	 * -----------------------------------------------------
+	 */
+	.align	7
+sync_exception_aarch32:
+	wfi
+	b	sync_exception_aarch32
+	check_vector_size sync_exception_aarch32
+
+	.align	7
+irq_aarch32:
+	b	irq_aarch32
+	check_vector_size irq_aarch32
+
+	.align	7
+fiq_aarch32:
+	b	fiq_aarch32
+	check_vector_size fiq_aarch32
+
+	.align	7
+serror_aarch32:
+	b	serror_aarch32
+	check_vector_size serror_aarch32
+	.align	7
diff --git a/uefi/arm-trusted-firmware/bl32/tsp/aarch64/tsp_request.S b/uefi/arm-trusted-firmware/bl32/tsp/aarch64/tsp_request.S
new file mode 100644
index 0000000..6aa0873
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl32/tsp/aarch64/tsp_request.S
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <asm_macros.S>
+#include <tsp.h>
+
+	.globl tsp_get_magic
+
+
+/*
+ * This function raises an SMC to retrieve arguments from secure
+ * monitor/dispatcher, saves the returned arguments the array received in x0,
+ * and then returns to the caller
+ */
+func tsp_get_magic
+	/* Save address to stack */
+	stp	x0, xzr, [sp, #-16]!
+
+	/* Load arguments */
+	ldr	w0, _tsp_fid_get_magic
+
+	/* Raise SMC */
+	smc	#0
+
+	/* Restore address from stack */
+	ldp	x4, xzr, [sp], #16
+
+	/* Store returned arguments to the array */
+	stp	x0, x1, [x4, #0]
+
+	ret
+
+	.align 2
+_tsp_fid_get_magic:
+	.word	TSP_GET_ARGS
diff --git a/uefi/arm-trusted-firmware/bl32/tsp/tsp.ld.S b/uefi/arm-trusted-firmware/bl32/tsp/tsp.ld.S
new file mode 100644
index 0000000..d411ad0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl32/tsp/tsp.ld.S
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <platform_def.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(tsp_entrypoint)
+
+
+MEMORY {
+    RAM (rwx): ORIGIN = TSP_SEC_MEM_BASE, LENGTH = TSP_SEC_MEM_SIZE
+}
+
+
+SECTIONS
+{
+    . = BL32_BASE;
+    ASSERT(. == ALIGN(4096),
+           "BL32_BASE address is not aligned on a page boundary.")
+
+    ro . : {
+        __RO_START__ = .;
+        *tsp_entrypoint.o(.text*)
+        *(.text*)
+        *(.rodata*)
+        *(.vectors)
+        __RO_END_UNALIGNED__ = .;
+        /*
+         * Memory page(s) mapped to this section will be marked as
+         * read-only, executable.  No RW data from the next section must
+         * creep in.  Ensure the rest of the current memory page is unused.
+         */
+        . = NEXT(4096);
+        __RO_END__ = .;
+    } >RAM
+
+    .data . : {
+        __DATA_START__ = .;
+        *(.data*)
+        __DATA_END__ = .;
+    } >RAM
+
+#ifdef TSP_PROGBITS_LIMIT
+    ASSERT(. <= TSP_PROGBITS_LIMIT, "TSP progbits has exceeded its limit.")
+#endif
+
+    stacks (NOLOAD) : {
+        __STACKS_START__ = .;
+        *(tzfw_normal_stacks)
+        __STACKS_END__ = .;
+    } >RAM
+
+    /*
+     * The .bss section gets initialised to 0 at runtime.
+     * Its base address must be 16-byte aligned.
+     */
+    .bss : ALIGN(16) {
+        __BSS_START__ = .;
+        *(SORT_BY_ALIGNMENT(.bss*))
+        *(COMMON)
+        __BSS_END__ = .;
+    } >RAM
+
+    /*
+     * The xlat_table section is for full, aligned page tables (4K).
+     * Removing them from .bss avoids forcing 4K alignment on
+     * the .bss section and eliminates the unecessary zero init
+     */
+    xlat_table (NOLOAD) : {
+        *(xlat_table)
+    } >RAM
+
+#if USE_COHERENT_MEM
+    /*
+     * The base address of the coherent memory section must be page-aligned (4K)
+     * to guarantee that the coherent data are stored on their own pages and
+     * are not mixed with normal data.  This is required to set up the correct
+     * memory attributes for the coherent data page tables.
+     */
+    coherent_ram (NOLOAD) : ALIGN(4096) {
+        __COHERENT_RAM_START__ = .;
+        *(tzfw_coherent_mem)
+        __COHERENT_RAM_END_UNALIGNED__ = .;
+        /*
+         * Memory page(s) mapped to this section will be marked
+         * as device memory.  No other unexpected data must creep in.
+         * Ensure the rest of the current memory page is unused.
+         */
+        . = NEXT(4096);
+        __COHERENT_RAM_END__ = .;
+    } >RAM
+#endif
+
+    __BL32_END__ = .;
+
+    __BSS_SIZE__ = SIZEOF(.bss);
+#if USE_COHERENT_MEM
+    __COHERENT_RAM_UNALIGNED_SIZE__ =
+        __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
+#endif
+
+    ASSERT(. <= BL32_LIMIT, "BL3-2 image has exceeded its limit.")
+}
diff --git a/uefi/arm-trusted-firmware/bl32/tsp/tsp.mk b/uefi/arm-trusted-firmware/bl32/tsp/tsp.mk
new file mode 100644
index 0000000..f17ef1e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl32/tsp/tsp.mk
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+INCLUDES		+=	-Iinclude/bl32/tsp
+
+BL32_SOURCES		+=	bl32/tsp/tsp_main.c			\
+				bl32/tsp/aarch64/tsp_entrypoint.S	\
+				bl32/tsp/aarch64/tsp_exceptions.S	\
+				bl32/tsp/aarch64/tsp_request.S		\
+				bl32/tsp/tsp_interrupt.c		\
+				bl32/tsp/tsp_timer.c			\
+				common/aarch64/early_exceptions.S	\
+				lib/locks/exclusive/spinlock.S
+
+BL32_LINKERFILE		:=	bl32/tsp/tsp.ld.S
+
+# This flag determines if the TSPD initializes BL3-2 in tspd_init() (synchronous
+# method) or configures BL3-1 to pass control to BL3-2 instead of BL3-3
+# (asynchronous method).
+TSP_INIT_ASYNC         :=      0
+
+$(eval $(call assert_boolean,TSP_INIT_ASYNC))
+$(eval $(call add_define,TSP_INIT_ASYNC))
+
+# Include the platform-specific TSP Makefile
+# If no platform-specific TSP Makefile exists, it means TSP is not supported
+# on this platform.
+TSP_PLAT_MAKEFILE := plat/${PLAT}/tsp/tsp-${PLAT}.mk
+ifeq (,$(wildcard ${TSP_PLAT_MAKEFILE}))
+  $(error TSP is not supported on platform ${PLAT})
+else
+  include ${TSP_PLAT_MAKEFILE}
+endif
diff --git a/uefi/arm-trusted-firmware/bl32/tsp/tsp_interrupt.c b/uefi/arm-trusted-firmware/bl32/tsp/tsp_interrupt.c
new file mode 100644
index 0000000..7163bad
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl32/tsp/tsp_interrupt.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <gic_v2.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <tsp.h>
+#include "tsp_private.h"
+
+/*******************************************************************************
+ * This function updates the TSP statistics for FIQs handled synchronously i.e
+ * the ones that have been handed over by the TSPD. It also keeps count of the
+ * number of times control was passed back to the TSPD after handling an FIQ.
+ * In the future it will be possible that the TSPD hands over an FIQ to the TSP
+ * but does not expect it to return execution. This statistic will be useful to
+ * distinguish between these two models of synchronous FIQ handling.
+ * The 'elr_el3' parameter contains the address of the instruction in normal
+ * world where this FIQ was generated.
+ ******************************************************************************/
+void tsp_update_sync_fiq_stats(uint32_t type, uint64_t elr_el3)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	tsp_stats[linear_id].sync_fiq_count++;
+	if (type == TSP_HANDLE_FIQ_AND_RETURN)
+		tsp_stats[linear_id].sync_fiq_ret_count++;
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+	spin_lock(&console_lock);
+	VERBOSE("TSP: cpu 0x%x sync fiq request from 0x%llx\n",
+		mpidr, elr_el3);
+	VERBOSE("TSP: cpu 0x%x: %d sync fiq requests, %d sync fiq returns\n",
+		mpidr,
+		tsp_stats[linear_id].sync_fiq_count,
+		tsp_stats[linear_id].sync_fiq_ret_count);
+	spin_unlock(&console_lock);
+#endif
+}
+
+/*******************************************************************************
+ * TSP FIQ handler called as a part of both synchronous and asynchronous
+ * handling of FIQ interrupts. It returns 0 upon successfully handling a S-EL1
+ * FIQ and treats all other FIQs as EL3 interrupts. It assumes that the GIC
+ * architecture version in v2.0 and the secure physical timer interrupt is the
+ * only S-EL1 interrupt that it needs to handle.
+ ******************************************************************************/
+int32_t tsp_fiq_handler(void)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr), id;
+
+	/*
+	 * Get the highest priority pending interrupt id and see if it is the
+	 * secure physical generic timer interrupt in which case, handle it.
+	 * Otherwise throw this interrupt at the EL3 firmware.
+	 */
+	id = plat_ic_get_pending_interrupt_id();
+
+	/* TSP can only handle the secure physical timer interrupt */
+	if (id != TSP_IRQ_SEC_PHY_TIMER)
+		return TSP_EL3_FIQ;
+
+	/*
+	 * Handle the interrupt. Also sanity check if it has been preempted by
+	 * another secure interrupt through an assertion.
+	 */
+	id = plat_ic_acknowledge_interrupt();
+	assert(id == TSP_IRQ_SEC_PHY_TIMER);
+	tsp_generic_timer_handler();
+	plat_ic_end_of_interrupt(id);
+
+	/* Update the statistics and print some messages */
+	tsp_stats[linear_id].fiq_count++;
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+	spin_lock(&console_lock);
+	VERBOSE("TSP: cpu 0x%x handled fiq %d\n",
+	       mpidr, id);
+	VERBOSE("TSP: cpu 0x%x: %d fiq requests\n",
+	     mpidr, tsp_stats[linear_id].fiq_count);
+	spin_unlock(&console_lock);
+#endif
+	return 0;
+}
+
+int32_t tsp_irq_received(void)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	tsp_stats[linear_id].irq_count++;
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+	spin_lock(&console_lock);
+	VERBOSE("TSP: cpu 0x%x received irq\n", mpidr);
+	VERBOSE("TSP: cpu 0x%x: %d irq requests\n",
+		mpidr, tsp_stats[linear_id].irq_count);
+	spin_unlock(&console_lock);
+#endif
+	return TSP_PREEMPTED;
+}
diff --git a/uefi/arm-trusted-firmware/bl32/tsp/tsp_main.c b/uefi/arm-trusted-firmware/bl32/tsp/tsp_main.c
new file mode 100644
index 0000000..c6000e1
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl32/tsp/tsp_main.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <platform_tsp.h>
+#include <spinlock.h>
+#include <tsp.h>
+#include "tsp_private.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted SRAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __BL32_END__;
+
+/*******************************************************************************
+ * Lock to control access to the console
+ ******************************************************************************/
+spinlock_t console_lock;
+
+/*******************************************************************************
+ * Per cpu data structure to populate parameters for an SMC in C code and use
+ * a pointer to this structure in assembler code to populate x0-x7
+ ******************************************************************************/
+static tsp_args_t tsp_smc_args[PLATFORM_CORE_COUNT];
+
+/*******************************************************************************
+ * Per cpu data structure to keep track of TSP activity
+ ******************************************************************************/
+work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
+
+/*******************************************************************************
+ * The BL32 memory footprint starts with an RO sections and ends
+ * with the linker symbol __BL32_END__. Use it to find the memory size
+ ******************************************************************************/
+#define BL32_TOTAL_BASE (unsigned long)(&__RO_START__)
+
+#define BL32_TOTAL_LIMIT (unsigned long)(&__BL32_END__)
+
+static tsp_args_t *set_smc_args(uint64_t arg0,
+			     uint64_t arg1,
+			     uint64_t arg2,
+			     uint64_t arg3,
+			     uint64_t arg4,
+			     uint64_t arg5,
+			     uint64_t arg6,
+			     uint64_t arg7)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id;
+	tsp_args_t *pcpu_smc_args;
+
+	/*
+	 * Return to Secure Monitor by raising an SMC. The results of the
+	 * service are passed as an arguments to the SMC
+	 */
+	linear_id = platform_get_core_pos(mpidr);
+	pcpu_smc_args = &tsp_smc_args[linear_id];
+	write_sp_arg(pcpu_smc_args, TSP_ARG0, arg0);
+	write_sp_arg(pcpu_smc_args, TSP_ARG1, arg1);
+	write_sp_arg(pcpu_smc_args, TSP_ARG2, arg2);
+	write_sp_arg(pcpu_smc_args, TSP_ARG3, arg3);
+	write_sp_arg(pcpu_smc_args, TSP_ARG4, arg4);
+	write_sp_arg(pcpu_smc_args, TSP_ARG5, arg5);
+	write_sp_arg(pcpu_smc_args, TSP_ARG6, arg6);
+	write_sp_arg(pcpu_smc_args, TSP_ARG7, arg7);
+
+	return pcpu_smc_args;
+}
+
+/*******************************************************************************
+ * TSP main entry point where it gets the opportunity to initialize its secure
+ * state/applications. Once the state is initialized, it must return to the
+ * SPD with a pointer to the 'tsp_vector_table' jump table.
+ ******************************************************************************/
+uint64_t tsp_main(void)
+{
+	NOTICE("TSP: %s\n", version_string);
+	NOTICE("TSP: %s\n", build_message);
+	INFO("TSP: Total memory base : 0x%x\n", (unsigned long)BL32_TOTAL_BASE);
+	INFO("TSP: Total memory size : 0x%x bytes\n",
+			 (unsigned long)(BL32_TOTAL_LIMIT - BL32_TOTAL_BASE));
+
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	/* Initialize the platform */
+	tsp_platform_setup();
+
+	/* Initialize secure/applications state here */
+	tsp_generic_timer_start();
+
+	/* Update this cpu's statistics */
+	tsp_stats[linear_id].smc_count++;
+	tsp_stats[linear_id].eret_count++;
+	tsp_stats[linear_id].cpu_on_count++;
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+	spin_lock(&console_lock);
+	INFO("TSP: cpu 0x%x: %d smcs, %d erets %d cpu on requests\n", mpidr,
+	     tsp_stats[linear_id].smc_count,
+	     tsp_stats[linear_id].eret_count,
+	     tsp_stats[linear_id].cpu_on_count);
+	spin_unlock(&console_lock);
+#endif
+	return (uint64_t) &tsp_vector_table;
+}
+
+/*******************************************************************************
+ * This function performs any remaining book keeping in the test secure payload
+ * after this cpu's architectural state has been setup in response to an earlier
+ * psci cpu_on request.
+ ******************************************************************************/
+tsp_args_t *tsp_cpu_on_main(void)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	/* Initialize secure/applications state here */
+	tsp_generic_timer_start();
+
+	/* Update this cpu's statistics */
+	tsp_stats[linear_id].smc_count++;
+	tsp_stats[linear_id].eret_count++;
+	tsp_stats[linear_id].cpu_on_count++;
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+	spin_lock(&console_lock);
+	INFO("TSP: cpu 0x%x turned on\n", mpidr);
+	INFO("TSP: cpu 0x%x: %d smcs, %d erets %d cpu on requests\n", mpidr,
+		tsp_stats[linear_id].smc_count,
+		tsp_stats[linear_id].eret_count,
+		tsp_stats[linear_id].cpu_on_count);
+	spin_unlock(&console_lock);
+#endif
+	/* Indicate to the SPD that we have completed turned ourselves on */
+	return set_smc_args(TSP_ON_DONE, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * This function performs any remaining book keeping in the test secure payload
+ * before this cpu is turned off in response to a psci cpu_off request.
+ ******************************************************************************/
+tsp_args_t *tsp_cpu_off_main(uint64_t arg0,
+			   uint64_t arg1,
+			   uint64_t arg2,
+			   uint64_t arg3,
+			   uint64_t arg4,
+			   uint64_t arg5,
+			   uint64_t arg6,
+			   uint64_t arg7)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	/*
+	 * This cpu is being turned off, so disable the timer to prevent the
+	 * secure timer interrupt from interfering with power down. A pending
+	 * interrupt will be lost but we do not care as we are turning off.
+	 */
+	tsp_generic_timer_stop();
+
+	/* Update this cpu's statistics */
+	tsp_stats[linear_id].smc_count++;
+	tsp_stats[linear_id].eret_count++;
+	tsp_stats[linear_id].cpu_off_count++;
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+	spin_lock(&console_lock);
+	INFO("TSP: cpu 0x%x off request\n", mpidr);
+	INFO("TSP: cpu 0x%x: %d smcs, %d erets %d cpu off requests\n", mpidr,
+		tsp_stats[linear_id].smc_count,
+		tsp_stats[linear_id].eret_count,
+		tsp_stats[linear_id].cpu_off_count);
+	spin_unlock(&console_lock);
+#endif
+
+	/* Indicate to the SPD that we have completed this request */
+	return set_smc_args(TSP_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * This function performs any book keeping in the test secure payload before
+ * this cpu's architectural state is saved in response to an earlier psci
+ * cpu_suspend request.
+ ******************************************************************************/
+tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0,
+			       uint64_t arg1,
+			       uint64_t arg2,
+			       uint64_t arg3,
+			       uint64_t arg4,
+			       uint64_t arg5,
+			       uint64_t arg6,
+			       uint64_t arg7)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	/*
+	 * Save the time context and disable it to prevent the secure timer
+	 * interrupt from interfering with wakeup from the suspend state.
+	 */
+	tsp_generic_timer_save();
+	tsp_generic_timer_stop();
+
+	/* Update this cpu's statistics */
+	tsp_stats[linear_id].smc_count++;
+	tsp_stats[linear_id].eret_count++;
+	tsp_stats[linear_id].cpu_suspend_count++;
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+	spin_lock(&console_lock);
+	INFO("TSP: cpu 0x%x: %d smcs, %d erets %d cpu suspend requests\n",
+		mpidr,
+		tsp_stats[linear_id].smc_count,
+		tsp_stats[linear_id].eret_count,
+		tsp_stats[linear_id].cpu_suspend_count);
+	spin_unlock(&console_lock);
+#endif
+
+	/* Indicate to the SPD that we have completed this request */
+	return set_smc_args(TSP_SUSPEND_DONE, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * This function performs any book keeping in the test secure payload after this
+ * cpu's architectural state has been restored after wakeup from an earlier psci
+ * cpu_suspend request.
+ ******************************************************************************/
+tsp_args_t *tsp_cpu_resume_main(uint64_t suspend_level,
+			      uint64_t arg1,
+			      uint64_t arg2,
+			      uint64_t arg3,
+			      uint64_t arg4,
+			      uint64_t arg5,
+			      uint64_t arg6,
+			      uint64_t arg7)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	/* Restore the generic timer context */
+	tsp_generic_timer_restore();
+
+	/* Update this cpu's statistics */
+	tsp_stats[linear_id].smc_count++;
+	tsp_stats[linear_id].eret_count++;
+	tsp_stats[linear_id].cpu_resume_count++;
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+	spin_lock(&console_lock);
+	INFO("TSP: cpu 0x%x resumed. suspend level %d\n",
+		mpidr, suspend_level);
+	INFO("TSP: cpu 0x%x: %d smcs, %d erets %d cpu suspend requests\n",
+		mpidr,
+		tsp_stats[linear_id].smc_count,
+		tsp_stats[linear_id].eret_count,
+		tsp_stats[linear_id].cpu_suspend_count);
+	spin_unlock(&console_lock);
+#endif
+	/* Indicate to the SPD that we have completed this request */
+	return set_smc_args(TSP_RESUME_DONE, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * This function performs any remaining bookkeeping in the test secure payload
+ * before the system is switched off (in response to a psci SYSTEM_OFF request)
+ ******************************************************************************/
+tsp_args_t *tsp_system_off_main(uint64_t arg0,
+				uint64_t arg1,
+				uint64_t arg2,
+				uint64_t arg3,
+				uint64_t arg4,
+				uint64_t arg5,
+				uint64_t arg6,
+				uint64_t arg7)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	/* Update this cpu's statistics */
+	tsp_stats[linear_id].smc_count++;
+	tsp_stats[linear_id].eret_count++;
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+	spin_lock(&console_lock);
+	INFO("TSP: cpu 0x%x SYSTEM_OFF request\n", mpidr);
+	INFO("TSP: cpu 0x%x: %d smcs, %d erets requests\n", mpidr,
+	     tsp_stats[linear_id].smc_count,
+	     tsp_stats[linear_id].eret_count);
+	spin_unlock(&console_lock);
+#endif
+
+	/* Indicate to the SPD that we have completed this request */
+	return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * This function performs any remaining bookkeeping in the test secure payload
+ * before the system is reset (in response to a psci SYSTEM_RESET request)
+ ******************************************************************************/
+tsp_args_t *tsp_system_reset_main(uint64_t arg0,
+				uint64_t arg1,
+				uint64_t arg2,
+				uint64_t arg3,
+				uint64_t arg4,
+				uint64_t arg5,
+				uint64_t arg6,
+				uint64_t arg7)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	/* Update this cpu's statistics */
+	tsp_stats[linear_id].smc_count++;
+	tsp_stats[linear_id].eret_count++;
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+	spin_lock(&console_lock);
+	INFO("TSP: cpu 0x%x SYSTEM_RESET request\n", mpidr);
+	INFO("TSP: cpu 0x%x: %d smcs, %d erets requests\n", mpidr,
+	     tsp_stats[linear_id].smc_count,
+	     tsp_stats[linear_id].eret_count);
+	spin_unlock(&console_lock);
+#endif
+
+	/* Indicate to the SPD that we have completed this request */
+	return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * TSP fast smc handler. The secure monitor jumps to this function by
+ * doing the ERET after populating X0-X7 registers. The arguments are received
+ * in the function arguments in order. Once the service is rendered, this
+ * function returns to Secure Monitor by raising SMC.
+ ******************************************************************************/
+tsp_args_t *tsp_smc_handler(uint64_t func,
+			       uint64_t arg1,
+			       uint64_t arg2,
+			       uint64_t arg3,
+			       uint64_t arg4,
+			       uint64_t arg5,
+			       uint64_t arg6,
+			       uint64_t arg7)
+{
+	uint64_t results[2];
+	uint64_t service_args[2];
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+
+	/* Update this cpu's statistics */
+	tsp_stats[linear_id].smc_count++;
+	tsp_stats[linear_id].eret_count++;
+
+	INFO("TSP: cpu 0x%x received %s smc 0x%x\n", read_mpidr(),
+		((func >> 31) & 1) == 1 ? "fast" : "standard",
+		func);
+	INFO("TSP: cpu 0x%x: %d smcs, %d erets\n", mpidr,
+		tsp_stats[linear_id].smc_count,
+		tsp_stats[linear_id].eret_count);
+
+	/* Render secure services and obtain results here */
+	results[0] = arg1;
+	results[1] = arg2;
+
+	/*
+	 * Request a service back from dispatcher/secure monitor. This call
+	 * return and thereafter resume exectuion
+	 */
+	tsp_get_magic(service_args);
+
+	/* Determine the function to perform based on the function ID */
+	switch (TSP_BARE_FID(func)) {
+	case TSP_ADD:
+		results[0] += service_args[0];
+		results[1] += service_args[1];
+		break;
+	case TSP_SUB:
+		results[0] -= service_args[0];
+		results[1] -= service_args[1];
+		break;
+	case TSP_MUL:
+		results[0] *= service_args[0];
+		results[1] *= service_args[1];
+		break;
+	case TSP_DIV:
+		results[0] /= service_args[0] ? service_args[0] : 1;
+		results[1] /= service_args[1] ? service_args[1] : 1;
+		break;
+	default:
+		break;
+	}
+
+	return set_smc_args(func, 0,
+			    results[0],
+			    results[1],
+			    0, 0, 0, 0);
+}
+
diff --git a/uefi/arm-trusted-firmware/bl32/tsp/tsp_private.h b/uefi/arm-trusted-firmware/bl32/tsp/tsp_private.h
new file mode 100644
index 0000000..39fb5f6
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl32/tsp/tsp_private.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __TSP_PRIVATE_H__
+#define __TSP_PRIVATE_H__
+
+/* Definitions to help the assembler access the SMC/ERET args structure */
+#define TSP_ARGS_SIZE		0x40
+#define TSP_ARG0		0x0
+#define TSP_ARG1		0x8
+#define TSP_ARG2		0x10
+#define TSP_ARG3		0x18
+#define TSP_ARG4		0x20
+#define TSP_ARG5		0x28
+#define TSP_ARG6		0x30
+#define TSP_ARG7		0x38
+#define TSP_ARGS_END		0x40
+
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <platform_def.h> /* For CACHE_WRITEBACK_GRANULE */
+#include <spinlock.h>
+#include <stdint.h>
+#include <tsp.h>
+
+
+typedef struct work_statistics {
+	uint32_t fiq_count;		/* Number of FIQs on this cpu */
+	uint32_t irq_count;		/* Number of IRQs on this cpu */
+	uint32_t sync_fiq_count;	/* Number of sync. fiqs on this cpu */
+	uint32_t sync_fiq_ret_count;	/* Number of fiq returns on this cpu */
+	uint32_t smc_count;		/* Number of returns on this cpu */
+	uint32_t eret_count;		/* Number of entries on this cpu */
+	uint32_t cpu_on_count;		/* Number of cpu on requests */
+	uint32_t cpu_off_count;		/* Number of cpu off requests */
+	uint32_t cpu_suspend_count;	/* Number of cpu suspend requests */
+	uint32_t cpu_resume_count;	/* Number of cpu resume requests */
+} __aligned(CACHE_WRITEBACK_GRANULE) work_statistics_t;
+
+typedef struct tsp_args {
+	uint64_t _regs[TSP_ARGS_END >> 3];
+} __aligned(CACHE_WRITEBACK_GRANULE) tsp_args_t;
+
+/* Macros to access members of the above structure using their offsets */
+#define read_sp_arg(args, offset)	((args)->_regs[offset >> 3])
+#define write_sp_arg(args, offset, val) (((args)->_regs[offset >> 3])	\
+					 = val)
+/*
+ * Ensure that the assembler's view of the size of the tsp_args is the
+ * same as the compilers
+ */
+CASSERT(TSP_ARGS_SIZE == sizeof(tsp_args_t), assert_sp_args_size_mismatch);
+
+void tsp_get_magic(uint64_t args[4]);
+
+tsp_args_t *tsp_cpu_resume_main(uint64_t arg0,
+				uint64_t arg1,
+				uint64_t arg2,
+				uint64_t arg3,
+				uint64_t arg4,
+				uint64_t arg5,
+				uint64_t arg6,
+				uint64_t arg7);
+tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0,
+				 uint64_t arg1,
+				 uint64_t arg2,
+				 uint64_t arg3,
+				 uint64_t arg4,
+				 uint64_t arg5,
+				 uint64_t arg6,
+				 uint64_t arg7);
+tsp_args_t *tsp_cpu_on_main(void);
+tsp_args_t *tsp_cpu_off_main(uint64_t arg0,
+			     uint64_t arg1,
+			     uint64_t arg2,
+			     uint64_t arg3,
+			     uint64_t arg4,
+			     uint64_t arg5,
+			     uint64_t arg6,
+			     uint64_t arg7);
+
+/* Generic Timer functions */
+void tsp_generic_timer_start(void);
+void tsp_generic_timer_handler(void);
+void tsp_generic_timer_stop(void);
+void tsp_generic_timer_save(void);
+void tsp_generic_timer_restore(void);
+
+/* FIQ management functions */
+void tsp_update_sync_fiq_stats(uint32_t type, uint64_t elr_el3);
+
+
+/* Data structure to keep track of TSP statistics */
+extern spinlock_t console_lock;
+extern work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
+
+/* Vector table of jumps */
+extern tsp_vectors_t tsp_vector_table;
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __TSP_PRIVATE_H__ */
+
diff --git a/uefi/arm-trusted-firmware/bl32/tsp/tsp_timer.c b/uefi/arm-trusted-firmware/bl32/tsp/tsp_timer.c
new file mode 100644
index 0000000..f196021
--- /dev/null
+++ b/uefi/arm-trusted-firmware/bl32/tsp/tsp_timer.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <arch_helpers.h>
+#include <assert.h>
+#include <platform.h>
+#include "tsp_private.h"
+
+/*******************************************************************************
+ * Data structure to keep track of per-cpu secure generic timer context across
+ * power management operations.
+ ******************************************************************************/
+typedef struct timer_context {
+	uint64_t cval;
+	uint32_t ctl;
+} timer_context_t;
+
+static timer_context_t pcpu_timer_context[PLATFORM_CORE_COUNT];
+
+/*******************************************************************************
+ * This function initializes the generic timer to fire every 0.5 second
+ ******************************************************************************/
+void tsp_generic_timer_start(void)
+{
+	uint64_t cval;
+	uint32_t ctl = 0;
+
+	/* The timer will fire every 0.5 second */
+	cval = read_cntpct_el0() + (read_cntfrq_el0() >> 1);
+	write_cntps_cval_el1(cval);
+
+	/* Enable the secure physical timer */
+	set_cntp_ctl_enable(ctl);
+	write_cntps_ctl_el1(ctl);
+}
+
+/*******************************************************************************
+ * This function deasserts the timer interrupt and sets it up again
+ ******************************************************************************/
+void tsp_generic_timer_handler(void)
+{
+	/* Ensure that the timer did assert the interrupt */
+	assert(get_cntp_ctl_istatus(read_cntps_ctl_el1()));
+
+	/*
+	 * Disable the timer and reprogram it. The barriers ensure that there is
+	 * no reordering of instructions around the reprogramming code.
+	 */
+	isb();
+	write_cntps_ctl_el1(0);
+	tsp_generic_timer_start();
+	isb();
+}
+
+/*******************************************************************************
+ * This function deasserts the timer interrupt prior to cpu power down
+ ******************************************************************************/
+void tsp_generic_timer_stop(void)
+{
+	/* Disable the timer */
+	write_cntps_ctl_el1(0);
+}
+
+/*******************************************************************************
+ * This function saves the timer context prior to cpu suspension
+ ******************************************************************************/
+void tsp_generic_timer_save(void)
+{
+	uint32_t linear_id = platform_get_core_pos(read_mpidr());
+
+	pcpu_timer_context[linear_id].cval = read_cntps_cval_el1();
+	pcpu_timer_context[linear_id].ctl = read_cntps_ctl_el1();
+	flush_dcache_range((uint64_t) &pcpu_timer_context[linear_id],
+			   sizeof(pcpu_timer_context[linear_id]));
+}
+
+/*******************************************************************************
+ * This function restores the timer context post cpu resummption
+ ******************************************************************************/
+void tsp_generic_timer_restore(void)
+{
+	uint32_t linear_id = platform_get_core_pos(read_mpidr());
+
+	write_cntps_cval_el1(pcpu_timer_context[linear_id].cval);
+	write_cntps_ctl_el1(pcpu_timer_context[linear_id].ctl);
+}
diff --git a/uefi/arm-trusted-firmware/common/aarch64/debug.S b/uefi/arm-trusted-firmware/common/aarch64/debug.S
new file mode 100644
index 0000000..fcf5f26
--- /dev/null
+++ b/uefi/arm-trusted-firmware/common/aarch64/debug.S
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+	.globl	asm_print_str
+	.globl	asm_print_hex
+	.globl	asm_assert
+	.globl	do_panic
+
+/* Since the max decimal input number is 65536 */
+#define MAX_DEC_DIVISOR		10000
+/* The offset to add to get ascii for numerals '0 - 9' */
+#define ASCII_OFFSET_NUM	0x30
+
+#if ASM_ASSERTION
+.section .rodata.assert_str, "aS"
+assert_msg1:
+	.asciz "ASSERT: File "
+assert_msg2:
+	.asciz " Line "
+
+	/*
+	 * This macro is intended to be used to print the
+	 * line number in decimal. Used by asm_assert macro.
+	 * The max number expected is 65536.
+	 * In: x4 = the decimal to print.
+	 * Clobber: x30, x0, x1, x2, x5, x6
+	 */
+	.macro asm_print_line_dec
+	mov	x6, #10		/* Divide by 10 after every loop iteration */
+	mov	x5, #MAX_DEC_DIVISOR
+dec_print_loop:
+	udiv	x0, x4, x5		/* Get the quotient */
+	msub	x4, x0, x5, x4		/* Find the remainder */
+	add	x0, x0, #ASCII_OFFSET_NUM		/* Convert to ascii */
+	bl	plat_crash_console_putc
+	udiv	x5, x5, x6		/* Reduce divisor */
+	cbnz	x5, dec_print_loop
+	.endm
+
+
+/* ---------------------------------------------------------------------------
+ * Assertion support in assembly.
+ * The below function helps to support assertions in assembly where we do not
+ * have a C runtime stack. Arguments to the function are :
+ * x0 - File name
+ * x1 - Line no
+ * Clobber list : x30, x0, x1, x2, x3, x4, x5, x6.
+ * ---------------------------------------------------------------------------
+ */
+func asm_assert
+	mov	x5, x0
+	mov	x6, x1
+	/* Ensure the console is initialized */
+	bl	plat_crash_console_init
+	/* Check if the console is initialized */
+	cbz	x0, _assert_loop
+	/* The console is initialized */
+	adr	x4, assert_msg1
+	bl	asm_print_str
+	mov	x4, x5
+	bl	asm_print_str
+	adr	x4, assert_msg2
+	bl	asm_print_str
+	/* Check if line number higher than max permitted */
+	tst	x6, #~0xffff
+	b.ne	_assert_loop
+	mov	x4, x6
+	asm_print_line_dec
+_assert_loop:
+	b	_assert_loop
+#endif
+
+/*
+ * This function prints a string from address in x4.
+ * In: x4 = pointer to string.
+ * Clobber: x30, x0, x1, x2, x3
+ */
+func asm_print_str
+	mov	x3, x30
+1:
+	ldrb	w0, [x4], #0x1
+	cbz	x0, 2f
+	bl	plat_crash_console_putc
+	b	1b
+2:
+	ret	x3
+
+/*
+ * This function prints a hexadecimal number in x4.
+ * In: x4 = the hexadecimal to print.
+ * Clobber: x30, x0, x5, x1, x2, x3
+ */
+func asm_print_hex
+	mov	x3, x30
+	mov	x5, #64  /* No of bits to convert to ascii */
+1:
+	sub	x5, x5, #4
+	lsrv	x0, x4, x5
+	and	x0, x0, #0xf
+	cmp	x0, #0xA
+	b.lo	2f
+	/* Add by 0x27 in addition to ASCII_OFFSET_NUM
+	 * to get ascii for characters 'a - f'.
+	 */
+	add	x0, x0, #0x27
+2:
+	add	x0, x0, #ASCII_OFFSET_NUM
+	bl	plat_crash_console_putc
+	cbnz	x5, 1b
+	ret	x3
+
+	/***********************************************************
+	 * The common implementation of do_panic for all BL stages
+	 ***********************************************************/
+
+.section .rodata.panic_str, "aS"
+	panic_msg: .asciz "PANIC at PC : 0x"
+
+/* ---------------------------------------------------------------------------
+ * do_panic assumes that it is invoked from a C Runtime Environment ie a
+ * valid stack exists. This call will not return.
+ * Clobber list : if CRASH_REPORTING is not enabled then x30, x0 - x6
+ * ---------------------------------------------------------------------------
+ */
+
+/* This is for the non el3 BL stages to compile through */
+	.weak el3_panic
+
+func do_panic
+#if CRASH_REPORTING
+	str	x0, [sp, #-0x10]!
+	mrs	x0, currentel
+	ubfx	x0, x0, #2, #2
+	cmp	x0, #0x3
+	ldr	x0, [sp], #0x10
+	b.eq	el3_panic
+#endif
+
+panic_common:
+/*
+ * el3_panic will be redefined by the BL31
+ * crash reporting mechanism (if enabled)
+ */
+el3_panic:
+	mov	x6, x30
+	bl	plat_crash_console_init
+	/* Check if the console is initialized */
+	cbz	x0, _panic_loop
+	/* The console is initialized */
+	adr	x4, panic_msg
+	bl	asm_print_str
+	mov	x4, x6
+	/* The panic location is lr -4 */
+	sub	x4, x4, #4
+	bl	asm_print_hex
+_panic_loop:
+	b	_panic_loop
+
diff --git a/uefi/arm-trusted-firmware/common/aarch64/early_exceptions.S b/uefi/arm-trusted-firmware/common/aarch64/early_exceptions.S
new file mode 100644
index 0000000..90f5421
--- /dev/null
+++ b/uefi/arm-trusted-firmware/common/aarch64/early_exceptions.S
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <asm_macros.S>
+#include <runtime_svc.h>
+
+	.globl	early_exceptions
+
+	.section	.vectors, "ax"; .align 11
+
+	/* -----------------------------------------------------
+	 * Very simple stackless exception handlers used by BL2
+	 * and BL3-1 bootloader stages. BL3-1 uses them before
+	 * stacks are setup. BL2 uses them throughout.
+	 * -----------------------------------------------------
+	 */
+	.align	7
+early_exceptions:
+	/* -----------------------------------------------------
+	 * Current EL with SP0 : 0x0 - 0x180
+	 * -----------------------------------------------------
+	 */
+SynchronousExceptionSP0:
+	mov	x0, #SYNC_EXCEPTION_SP_EL0
+	bl	plat_report_exception
+	b	SynchronousExceptionSP0
+	check_vector_size SynchronousExceptionSP0
+
+	.align	7
+IrqSP0:
+	mov	x0, #IRQ_SP_EL0
+	bl	plat_report_exception
+	b	IrqSP0
+	check_vector_size IrqSP0
+
+	.align	7
+FiqSP0:
+	mov	x0, #FIQ_SP_EL0
+	bl	plat_report_exception
+	b	FiqSP0
+	check_vector_size FiqSP0
+
+	.align	7
+SErrorSP0:
+	mov	x0, #SERROR_SP_EL0
+	bl	plat_report_exception
+	b	SErrorSP0
+	check_vector_size SErrorSP0
+
+	/* -----------------------------------------------------
+	 * Current EL with SPx: 0x200 - 0x380
+	 * -----------------------------------------------------
+	 */
+	.align	7
+SynchronousExceptionSPx:
+	mov	x0, #SYNC_EXCEPTION_SP_ELX
+	bl	plat_report_exception
+	b	SynchronousExceptionSPx
+	check_vector_size SynchronousExceptionSPx
+
+	.align	7
+IrqSPx:
+	mov	x0, #IRQ_SP_ELX
+	bl	plat_report_exception
+	b	IrqSPx
+	check_vector_size IrqSPx
+
+	.align	7
+FiqSPx:
+	mov	x0, #FIQ_SP_ELX
+	bl	plat_report_exception
+	b	FiqSPx
+	check_vector_size FiqSPx
+
+	.align	7
+SErrorSPx:
+	mov	x0, #SERROR_SP_ELX
+	bl	plat_report_exception
+	b	SErrorSPx
+	check_vector_size SErrorSPx
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch64 : 0x400 - 0x580
+	 * -----------------------------------------------------
+	 */
+	.align	7
+SynchronousExceptionA64:
+	mov	x0, #SYNC_EXCEPTION_AARCH64
+	bl	plat_report_exception
+	b	SynchronousExceptionA64
+	check_vector_size SynchronousExceptionA64
+
+	.align	7
+IrqA64:
+	mov	x0, #IRQ_AARCH64
+	bl	plat_report_exception
+	b	IrqA64
+	check_vector_size IrqA64
+
+	.align	7
+FiqA64:
+	mov	x0, #FIQ_AARCH64
+	bl	plat_report_exception
+	b	FiqA64
+	check_vector_size FiqA64
+
+	.align	7
+SErrorA64:
+	mov	x0, #SERROR_AARCH64
+	bl	plat_report_exception
+	b   	SErrorA64
+	check_vector_size SErrorA64
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch32 : 0x0 - 0x180
+	 * -----------------------------------------------------
+	 */
+	.align	7
+SynchronousExceptionA32:
+	mov	x0, #SYNC_EXCEPTION_AARCH32
+	bl	plat_report_exception
+	b	SynchronousExceptionA32
+	check_vector_size SynchronousExceptionA32
+
+	.align	7
+IrqA32:
+	mov	x0, #IRQ_AARCH32
+	bl	plat_report_exception
+	b	IrqA32
+	check_vector_size IrqA32
+
+	.align	7
+FiqA32:
+	mov	x0, #FIQ_AARCH32
+	bl	plat_report_exception
+	b	FiqA32
+	check_vector_size FiqA32
+
+	.align	7
+SErrorA32:
+	mov	x0, #SERROR_AARCH32
+	bl	plat_report_exception
+	b	SErrorA32
+	check_vector_size SErrorA32
diff --git a/uefi/arm-trusted-firmware/common/auth.c b/uefi/arm-trusted-firmware/common/auth.c
new file mode 100644
index 0000000..37234b8
--- /dev/null
+++ b/uefi/arm-trusted-firmware/common/auth.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <auth.h>
+#include <debug.h>
+
+/*
+ * Initialize the authentication module
+ */
+void auth_init(void)
+{
+	assert(auth_mod.name);
+	assert(auth_mod.init);
+	assert(auth_mod.verify);
+
+	INFO("Using authentication module '%s'\n", auth_mod.name);
+	if (auth_mod.init() != 0)
+		assert(0);
+}
+
+/*
+ * Authenticate a certificate/image
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int auth_verify_obj(unsigned int obj_id, uintptr_t obj_buf, size_t len)
+{
+	assert(obj_id < AUTH_NUM_OBJ);
+	assert(obj_buf != 0);
+	assert(auth_mod.verify);
+
+	return auth_mod.verify(obj_id, obj_buf, len);
+}
diff --git a/uefi/arm-trusted-firmware/common/auth/polarssl/polarssl.c b/uefi/arm-trusted-firmware/common/auth/polarssl/polarssl.c
new file mode 100644
index 0000000..e099f50
--- /dev/null
+++ b/uefi/arm-trusted-firmware/common/auth/polarssl/polarssl.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Authentication module based on PolarSSL */
+
+#include <stddef.h>
+
+#include <assert.h>
+#include <auth.h>
+#include <debug.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <platform_oid.h>
+
+#include <polarssl/memory_buffer_alloc.h>
+#include <polarssl/oid.h>
+#include <polarssl/platform.h>
+#include <polarssl/sha256.h>
+#include <polarssl/x509_crt.h>
+
+/*
+ * At each authentication stage, the module is responsible for extracting and
+ * storing those elements (keys, hashes, etc.) that will be needed later on
+ * during the Trusted Boot process.
+ */
+
+/* SHA256 algorithm */
+#define SHA_BYTES			32
+
+/*
+ * An 8 KB stack has been proven to be enough for the current Trusted Boot
+ * process
+ */
+#define POLARSSL_HEAP_SIZE		(8*1024)
+static unsigned char heap[POLARSSL_HEAP_SIZE];
+
+/*
+ * RSA public keys:
+ *  SubjectPublicKeyInfo  ::=  SEQUENCE  {          1 + 3
+ *       algorithm            AlgorithmIdentifier,  1 + 1 (sequence)
+ *                                                + 1 + 1 + 9 (rsa oid)
+ *                                                + 1 + 1 (params null)
+ *       subjectPublicKey     BIT STRING }          1 + 3 + (1 + below)
+ *  RSAPublicKey ::= SEQUENCE {                     1 + 3
+ *      modulus           INTEGER,  -- n            1 + 3 + MPI_MAX + 1
+ *      publicExponent    INTEGER   -- e            1 + 3 + MPI_MAX + 1
+ *  }
+ *
+ * POLARSSL_MPI_MAX_SIZE is set to 256 bytes (RSA-2048 bit keys) in the
+ * configuration file
+ */
+#define RSA_PUB_DER_MAX_BYTES   38 + 2 * POLARSSL_MPI_MAX_SIZE
+
+/*
+ * Buffer for storing public keys extracted from certificates while they are
+ * verified
+ */
+static unsigned char pk_buf[RSA_PUB_DER_MAX_BYTES];
+
+/* We use this variable to parse and authenticate the certificates */
+static x509_crt cert;
+
+/* BL specific variables */
+#if IMAGE_BL1
+static unsigned char sha_bl2[SHA_BYTES];
+#elif IMAGE_BL2
+/* Buffers to store the hash of BL3-x images */
+static unsigned char sha_bl30[SHA_BYTES];
+static unsigned char sha_bl31[SHA_BYTES];
+static unsigned char sha_bl32[SHA_BYTES];
+static unsigned char sha_bl33[SHA_BYTES];
+/* Buffers to store the Trusted and Non-Trusted world public keys */
+static unsigned char tz_world_pk[RSA_PUB_DER_MAX_BYTES];
+static unsigned char ntz_world_pk[RSA_PUB_DER_MAX_BYTES];
+static size_t tz_world_pk_len, ntz_world_pk_len;
+/* Buffer to store the BL3-x public keys */
+static unsigned char content_pk[RSA_PUB_DER_MAX_BYTES];
+static size_t content_pk_len;
+#endif
+
+
+static int x509_get_crt_ext_data(const unsigned char **ext_data,
+				 size_t *ext_len,
+				 x509_crt *crt,
+				 const char *oid)
+{
+	int ret;
+	size_t len;
+	unsigned char *end_ext_data, *end_ext_octet;
+	unsigned char *p;
+	const unsigned char *end;
+	char oid_str[64];
+
+	p = crt->v3_ext.p;
+	end = crt->v3_ext.p + crt->v3_ext.len;
+
+	ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
+	if (ret != 0)
+		return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
+
+	if (end != p + len)
+		return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
+				POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
+
+	while (p < end) {
+		/*
+		 * Extension  ::=  SEQUENCE  {
+		 *      extnID      OBJECT IDENTIFIER,
+		 *      critical    BOOLEAN DEFAULT FALSE,
+		 *      extnValue   OCTET STRING  }
+		 */
+		x509_buf extn_oid = {0, 0, NULL};
+		int is_critical = 0; /* DEFAULT FALSE */
+
+		ret = asn1_get_tag(&p, end, &len,
+				ASN1_CONSTRUCTED | ASN1_SEQUENCE);
+		if (ret != 0)
+			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
+
+		end_ext_data = p + len;
+
+		/* Get extension ID */
+		extn_oid.tag = *p;
+
+		ret = asn1_get_tag(&p, end, &extn_oid.len, ASN1_OID);
+		if (ret != 0)
+			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
+
+		extn_oid.p = p;
+		p += extn_oid.len;
+
+		if ((end - p) < 1)
+			return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
+					POLARSSL_ERR_ASN1_OUT_OF_DATA;
+
+		/* Get optional critical */
+		ret = asn1_get_bool(&p, end_ext_data, &is_critical);
+		if (ret != 0 && (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG))
+			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
+
+		/* Data should be octet string type */
+		ret = asn1_get_tag(&p, end_ext_data, &len, ASN1_OCTET_STRING);
+		if (ret != 0)
+			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
+
+		end_ext_octet = p + len;
+
+		if (end_ext_octet != end_ext_data)
+			return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
+					POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
+
+		/* Detect requested extension */
+		oid_get_numeric_string(oid_str, 64, &extn_oid);
+		if (memcmp(oid, oid_str, sizeof(oid)) == 0) {
+			*ext_data = p;
+			*ext_len = len;
+			return 0;
+		}
+
+		/* Next */
+		p = end_ext_octet;
+	}
+
+	if (p != end)
+		return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
+				POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
+
+	return POLARSSL_ERR_X509_UNKNOWN_OID;
+}
+
+#if IMAGE_BL1
+/*
+ * Parse and verify the BL2 certificate
+ *
+ * This function verifies the integrity of the BL2 certificate, checks that it
+ * has been signed with the ROT key and extracts the BL2 hash stored in the
+ * certificate so it can be matched later against the calculated hash.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+static int check_bl2_cert(unsigned char *buf, size_t len)
+{
+	const unsigned char *p;
+	size_t sz;
+	int err, flags;
+
+	x509_crt_init(&cert);
+
+	/* Parse the BL2 certificate */
+	err = x509_crt_parse(&cert, buf, len);
+	if (err) {
+		ERROR("BL2 certificate parse error %d.\n", err);
+		goto error;
+	}
+
+	/* Check that it has been signed with the ROT key */
+	err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
+	if (err < 0) {
+		ERROR("Error loading ROT key in DER format %d.\n", err);
+		goto error;
+	}
+
+	sz = (size_t)err;
+	p = pk_buf + sizeof(pk_buf) - sz;
+
+	err = plat_match_rotpk(p, sz);
+	if (err) {
+		ERROR("ROT and BL2 certificate key mismatch\n");
+		goto error;
+	}
+
+	/* Verify certificate */
+	err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
+	if (err) {
+		ERROR("BL2 certificate verification error %d. Flags: 0x%x.\n",
+				err, flags);
+		goto error;
+	}
+
+	/* Extract BL2 image hash from certificate */
+	err = x509_get_crt_ext_data(&p, &sz, &cert, BL2_HASH_OID);
+	if (err) {
+		ERROR("Cannot read BL2 hash from certificate\n");
+		goto error;
+	}
+
+	assert(sz == SHA_BYTES + 2);
+
+	/* Skip the tag and length bytes and copy the hash */
+	p += 2;
+	memcpy(sha_bl2, p, SHA_BYTES);
+
+error:
+	x509_crt_free(&cert);
+
+	return err;
+}
+#endif /* IMAGE_BL1 */
+
+#if IMAGE_BL2
+static int check_trusted_key_cert(unsigned char *buf, size_t len)
+{
+	const unsigned char *p;
+	size_t sz;
+	int err, flags;
+
+	x509_crt_init(&cert);
+
+	/* Parse the Trusted Key certificate */
+	err = x509_crt_parse(&cert, buf, len);
+	if (err) {
+		ERROR("Trusted Key certificate parse error %d.\n", err);
+		goto error;
+	}
+
+	/* Verify Trusted Key certificate */
+	err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
+	if (err) {
+		ERROR("Trusted Key certificate verification error %d. Flags: "
+				"0x%x.\n", err, flags);
+		goto error;
+	}
+
+	/* Check that it has been signed with the ROT key */
+	err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
+	if (err < 0) {
+		ERROR("Error loading ROT key in DER format %d.\n", err);
+		goto error;
+	}
+
+	sz = (size_t)err;
+	p = pk_buf + sizeof(pk_buf) - sz;
+
+	if (plat_match_rotpk(p, sz)) {
+		ERROR("ROT and Trusted Key certificate key mismatch\n");
+		goto error;
+	}
+
+	/* Extract Trusted World key from extensions */
+	err = x509_get_crt_ext_data(&p, &tz_world_pk_len,
+			&cert, TZ_WORLD_PK_OID);
+	if (err) {
+		ERROR("Cannot read Trusted World key\n");
+		goto error;
+	}
+
+	assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES);
+	memcpy(tz_world_pk, p, tz_world_pk_len);
+
+	/* Extract Non-Trusted World key from extensions */
+	err = x509_get_crt_ext_data(&p, &ntz_world_pk_len,
+			&cert, NTZ_WORLD_PK_OID);
+	if (err) {
+		ERROR("Cannot read Non-Trusted World key\n");
+		goto error;
+	}
+
+	assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES);
+	memcpy(ntz_world_pk, p, ntz_world_pk_len);
+
+error:
+	x509_crt_free(&cert);
+
+	return err;
+}
+
+static int check_bl3x_key_cert(const unsigned char *buf, size_t len,
+			       const unsigned char *i_key, size_t i_key_len,
+			       unsigned char *s_key, size_t *s_key_len,
+			       const char *key_oid)
+{
+	const unsigned char *p;
+	size_t sz;
+	int err, flags;
+
+	x509_crt_init(&cert);
+
+	/* Parse key certificate */
+	err = x509_crt_parse(&cert, buf, len);
+	if (err) {
+		ERROR("Key certificate parse error %d.\n", err);
+		goto error;
+	}
+
+	/* Verify certificate */
+	err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
+	if (err) {
+		ERROR("Key certificate verification error %d. Flags: "
+				"0x%x.\n", err, flags);
+		goto error;
+	}
+
+	/* Check that the certificate has been signed by the issuer */
+	err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
+	if (err < 0) {
+		ERROR("Error loading key in DER format %d.\n", err);
+		goto error;
+	}
+
+	sz = (size_t)err;
+	p = pk_buf + sizeof(pk_buf) - sz;
+	if ((sz != i_key_len) || memcmp(p, i_key, sz)) {
+		ERROR("Key certificate not signed with issuer key\n");
+		err = 1;
+		goto error;
+	}
+
+	/* Get the content certificate key */
+	err = x509_get_crt_ext_data(&p, &sz, &cert, key_oid);
+	if (err) {
+		ERROR("Extension %s not found in Key certificate\n", key_oid);
+		goto error;
+	}
+
+	assert(sz <= RSA_PUB_DER_MAX_BYTES);
+	memcpy(s_key, p, sz);
+	*s_key_len = sz;
+
+error:
+	x509_crt_free(&cert);
+
+	return err;
+}
+
+static int check_bl3x_cert(unsigned char *buf, size_t len,
+		       const unsigned char *i_key, size_t i_key_len,
+		       const char *hash_oid, unsigned char *sha)
+{
+	const unsigned char *p;
+	size_t sz;
+	int err, flags;
+
+	x509_crt_init(&cert);
+
+	/* Parse BL31 content certificate */
+	err = x509_crt_parse(&cert, buf, len);
+	if (err) {
+		ERROR("Content certificate parse error %d.\n", err);
+		goto error;
+	}
+
+	/* Verify certificate */
+	err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
+	if (err) {
+		ERROR("Content certificate verification error %d. Flags: "
+				"0x%x.\n", err, flags);
+		goto error;
+	}
+
+	/* Check that content certificate has been signed with the content
+	 * certificate key corresponding to this image */
+	sz = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
+	p = pk_buf + sizeof(pk_buf) - sz;
+
+	if ((sz != i_key_len) || memcmp(p, i_key, sz)) {
+		ERROR("Content certificate not signed with content "
+				"certificate key\n");
+		err = 1;
+		goto error;
+	}
+
+	/* Extract image hash from certificate */
+	err = x509_get_crt_ext_data(&p, &sz, &cert, hash_oid);
+	if (err) {
+		ERROR("Cannot read hash from certificate\n");
+		goto error;
+	}
+
+	assert(sz == SHA_BYTES + 2);
+
+	/* Skip the tag and length bytes and copy the hash */
+	p += 2;
+	memcpy(sha, p, SHA_BYTES);
+
+error:
+	x509_crt_free(&cert);
+
+	return err;
+}
+#endif /* IMAGE_BL2 */
+
+/*
+ * Calculate the hash of the image and check it against the hash extracted
+ * previously from the certificate
+ *
+ * Parameters:
+ *   buf: buffer where image is loaded
+ *   len: size of the image
+ *   sha: matching hash (extracted from the image certificate)
+ *
+ * Return: 0 = match, Otherwise = mismatch
+ */
+static int check_bl_img(unsigned char *buf, size_t len,
+			const unsigned char *sha)
+{
+	unsigned char img_sha[SHA_BYTES];
+
+	/* Calculate the hash of the image */
+	sha256(buf, len, img_sha, 0);
+
+	/* Match the hash with the one extracted from the certificate */
+	if (memcmp(img_sha, sha, SHA_BYTES)) {
+		ERROR("Image hash mismatch\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Object verification function
+ *
+ * The id parameter will indicate the expected format of the object
+ * (certificate, image, etc).
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+static int polarssl_mod_verify(unsigned int id, uintptr_t obj, size_t len)
+{
+	int ret;
+
+	switch (id) {
+#if IMAGE_BL1
+	case AUTH_BL2_IMG_CERT:
+		ret = check_bl2_cert((unsigned char *)obj, len);
+		break;
+	case AUTH_BL2_IMG:
+		ret = check_bl_img((unsigned char *)obj, len, sha_bl2);
+		break;
+#endif /* IMAGE_BL1 */
+
+#if IMAGE_BL2
+	case AUTH_TRUSTED_KEY_CERT:
+		ret = check_trusted_key_cert((unsigned char *)obj, len);
+		break;
+	case AUTH_BL30_KEY_CERT:
+		ret = check_bl3x_key_cert((unsigned char *)obj, len,
+				tz_world_pk, tz_world_pk_len,
+				content_pk, &content_pk_len,
+				BL30_CONTENT_CERT_PK_OID);
+		break;
+	case AUTH_BL31_KEY_CERT:
+		ret = check_bl3x_key_cert((unsigned char *)obj, len,
+				tz_world_pk, tz_world_pk_len,
+				content_pk, &content_pk_len,
+				BL31_CONTENT_CERT_PK_OID);
+		break;
+	case AUTH_BL32_KEY_CERT:
+		ret = check_bl3x_key_cert((unsigned char *)obj, len,
+				tz_world_pk, tz_world_pk_len,
+				content_pk, &content_pk_len,
+				BL32_CONTENT_CERT_PK_OID);
+		break;
+	case AUTH_BL33_KEY_CERT:
+		ret = check_bl3x_key_cert((unsigned char *)obj, len,
+				ntz_world_pk, ntz_world_pk_len,
+				content_pk, &content_pk_len,
+				BL33_CONTENT_CERT_PK_OID);
+		break;
+	case AUTH_BL30_IMG_CERT:
+		ret = check_bl3x_cert((unsigned char *)obj, len,
+				content_pk, content_pk_len,
+				BL30_HASH_OID, sha_bl30);
+		break;
+	case AUTH_BL31_IMG_CERT:
+		ret = check_bl3x_cert((unsigned char *)obj, len,
+				content_pk, content_pk_len,
+				BL31_HASH_OID, sha_bl31);
+		break;
+	case AUTH_BL32_IMG_CERT:
+		ret = check_bl3x_cert((unsigned char *)obj, len,
+				content_pk, content_pk_len,
+				BL32_HASH_OID, sha_bl32);
+		break;
+	case AUTH_BL33_IMG_CERT:
+		ret = check_bl3x_cert((unsigned char *)obj, len,
+				content_pk, content_pk_len,
+				BL33_HASH_OID, sha_bl33);
+		break;
+	case AUTH_BL30_IMG:
+		ret = check_bl_img((unsigned char *)obj, len, sha_bl30);
+		break;
+	case AUTH_BL31_IMG:
+		ret = check_bl_img((unsigned char *)obj, len, sha_bl31);
+		break;
+	case AUTH_BL32_IMG:
+		ret = check_bl_img((unsigned char *)obj, len, sha_bl32);
+		break;
+	case AUTH_BL33_IMG:
+		ret = check_bl_img((unsigned char *)obj, len, sha_bl33);
+		break;
+#endif /* IMAGE_BL2 */
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * Module initialization function
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+static int polarssl_mod_init(void)
+{
+	/* Initialize the PolarSSL heap */
+	return memory_buffer_alloc_init(heap, POLARSSL_HEAP_SIZE);
+}
+
+const auth_mod_t auth_mod = {
+	.name = "PolarSSL",
+	.init = polarssl_mod_init,
+	.verify = polarssl_mod_verify
+};
diff --git a/uefi/arm-trusted-firmware/common/auth/polarssl/polarssl.mk b/uefi/arm-trusted-firmware/common/auth/polarssl/polarssl.mk
new file mode 100644
index 0000000..f7d92ea
--- /dev/null
+++ b/uefi/arm-trusted-firmware/common/auth/polarssl/polarssl.mk
@@ -0,0 +1,69 @@
+#
+# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# POLARSSL_DIR must be set to the PolarSSL main directory (it must contain
+# the 'include' and 'library' subdirectories).
+ifeq (${POLARSSL_DIR},)
+  $(error Error: POLARSSL_DIR not set)
+endif
+
+INCLUDES		+=	-I${POLARSSL_DIR}/include		\
+				-Icommon/auth/polarssl
+
+POLARSSL_CONFIG_FILE	:=	"<polarssl_config.h>"
+$(eval $(call add_define,POLARSSL_CONFIG_FILE))
+
+POLARSSL_SOURCES	:=	$(addprefix ${POLARSSL_DIR}/library/,	\
+				asn1parse.c 				\
+				asn1write.c 				\
+				bignum.c				\
+				md.c					\
+				md_wrap.c				\
+				memory_buffer_alloc.c			\
+				oid.c 					\
+				pk.c 					\
+				pk_wrap.c 				\
+				pkparse.c 				\
+				pkwrite.c 				\
+				platform.c 				\
+				rsa.c 					\
+				sha1.c					\
+				sha256.c				\
+				x509.c 					\
+				x509_crt.c 				\
+				)
+
+BL1_SOURCES		+=	${POLARSSL_SOURCES} 			\
+				common/auth/polarssl/polarssl.c
+
+BL2_SOURCES		+=	${POLARSSL_SOURCES} 			\
+				common/auth/polarssl/polarssl.c
+
+DISABLE_PEDANTIC	:=	1
diff --git a/uefi/arm-trusted-firmware/common/auth/polarssl/polarssl_config.h b/uefi/arm-trusted-firmware/common/auth/polarssl/polarssl_config.h
new file mode 100644
index 0000000..531e084
--- /dev/null
+++ b/uefi/arm-trusted-firmware/common/auth/polarssl/polarssl_config.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __POLARSSL_CONFIG_H__
+#define __POLARSSL_CONFIG_H__
+
+
+/*
+ * Configuration file to build PolarSSL with the required features for
+ * Trusted Boot
+ */
+
+#define POLARSSL_PLATFORM_MEMORY
+#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS
+
+#define POLARSSL_PKCS1_V15
+#define POLARSSL_PKCS1_V21
+
+#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+#define POLARSSL_X509_CHECK_KEY_USAGE
+#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE
+
+#define POLARSSL_ASN1_PARSE_C
+#define POLARSSL_ASN1_WRITE_C
+
+#define POLARSSL_BASE64_C
+#define POLARSSL_BIGNUM_C
+
+#define POLARSSL_ERROR_C
+#define POLARSSL_MD_C
+
+#define POLARSSL_MEMORY_BUFFER_ALLOC_C
+#define POLARSSL_OID_C
+
+#define POLARSSL_PK_C
+#define POLARSSL_PK_PARSE_C
+#define POLARSSL_PK_WRITE_C
+
+#define POLARSSL_PLATFORM_C
+
+#define POLARSSL_RSA_C
+#define POLARSSL_SHA1_C
+#define POLARSSL_SHA256_C
+
+#define POLARSSL_VERSION_C
+
+#define POLARSSL_X509_USE_C
+#define POLARSSL_X509_CRT_PARSE_C
+
+/* MPI / BIGNUM options */
+#define POLARSSL_MPI_WINDOW_SIZE              2
+#define POLARSSL_MPI_MAX_SIZE               256
+
+/* Memory buffer allocator options */
+#define POLARSSL_MEMORY_ALIGN_MULTIPLE        8
+
+#include "polarssl/check_config.h"
+
+#endif /* __POLARSSL_CONFIG_H__ */
diff --git a/uefi/arm-trusted-firmware/common/bl_common.c b/uefi/arm-trusted-firmware/common/bl_common.c
new file mode 100644
index 0000000..8c241ec
--- /dev/null
+++ b/uefi/arm-trusted-firmware/common/bl_common.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <errno.h>
+#include <io_storage.h>
+#include <platform.h>
+
+unsigned long page_align(unsigned long value, unsigned dir)
+{
+	unsigned long page_size = 1 << FOUR_KB_SHIFT;
+
+	/* Round up the limit to the next page boundary */
+	if (value & (page_size - 1)) {
+		value &= ~(page_size - 1);
+		if (dir == UP)
+			value += page_size;
+	}
+
+	return value;
+}
+
+static inline unsigned int is_page_aligned (unsigned long addr) {
+	const unsigned long page_size = 1 << FOUR_KB_SHIFT;
+
+	return (addr & (page_size - 1)) == 0;
+}
+
+void change_security_state(unsigned int target_security_state)
+{
+	unsigned long scr = read_scr();
+
+	assert(sec_state_is_valid(target_security_state));
+	if (target_security_state == SECURE)
+		scr &= ~SCR_NS_BIT;
+	else
+		scr |= SCR_NS_BIT;
+
+	write_scr(scr);
+}
+
+/******************************************************************************
+ * Determine whether the memory region delimited by 'addr' and 'size' is free,
+ * given the extents of free memory.
+ * Return 1 if it is free, 0 otherwise.
+ *****************************************************************************/
+static int is_mem_free(uint64_t free_base, size_t free_size,
+		       uint64_t addr, size_t size)
+{
+	return (addr >= free_base) && (addr + size <= free_base + free_size);
+}
+
+/******************************************************************************
+ * Inside a given memory region, determine whether a sub-region of memory is
+ * closer from the top or the bottom of the encompassing region. Return the
+ * size of the smallest chunk of free memory surrounding the sub-region in
+ * 'small_chunk_size'.
+ *****************************************************************************/
+static unsigned int choose_mem_pos(uint64_t mem_start, uint64_t mem_end,
+				   uint64_t submem_start, uint64_t submem_end,
+				   size_t *small_chunk_size)
+{
+	size_t top_chunk_size, bottom_chunk_size;
+
+	assert(mem_start <= submem_start);
+	assert(submem_start <= submem_end);
+	assert(submem_end <= mem_end);
+	assert(small_chunk_size != NULL);
+
+	top_chunk_size = mem_end - submem_end;
+	bottom_chunk_size = submem_start - mem_start;
+
+	if (top_chunk_size < bottom_chunk_size) {
+		*small_chunk_size = top_chunk_size;
+		return TOP;
+	} else {
+		*small_chunk_size = bottom_chunk_size;
+		return BOTTOM;
+	}
+}
+
+/******************************************************************************
+ * Reserve the memory region delimited by 'addr' and 'size'. The extents of free
+ * memory are passed in 'free_base' and 'free_size' and they will be updated to
+ * reflect the memory usage.
+ * The caller must ensure the memory to reserve is free.
+ *****************************************************************************/
+void reserve_mem(uint64_t *free_base, size_t *free_size,
+		 uint64_t addr, size_t size)
+{
+	size_t discard_size;
+	size_t reserved_size;
+	unsigned int pos;
+
+	assert(free_base != NULL);
+	assert(free_size != NULL);
+	assert(is_mem_free(*free_base, *free_size, addr, size));
+
+	pos = choose_mem_pos(*free_base, *free_base + *free_size,
+			     addr, addr + size,
+			     &discard_size);
+
+	reserved_size = size + discard_size;
+	*free_size -= reserved_size;
+
+	if (pos == BOTTOM)
+		*free_base = addr + size;
+
+	VERBOSE("Reserved %u bytes (discarded %u bytes %s)\n",
+	     reserved_size, discard_size,
+	     pos == TOP ? "above" : "below");
+}
+
+static void dump_load_info(unsigned long image_load_addr,
+			   unsigned long image_size,
+			   const meminfo_t *mem_layout)
+{
+	INFO("Trying to load image at address 0x%lx, size = 0x%lx\n",
+		image_load_addr, image_size);
+	INFO("Current memory layout:\n");
+	INFO("  total region = [0x%lx, 0x%lx]\n", mem_layout->total_base,
+			mem_layout->total_base + mem_layout->total_size);
+	INFO("  free region = [0x%lx, 0x%lx]\n", mem_layout->free_base,
+			mem_layout->free_base + mem_layout->free_size);
+}
+
+/* Generic function to return the size of an image */
+unsigned long image_size(const char *image_name)
+{
+	uintptr_t dev_handle;
+	uintptr_t image_handle;
+	uintptr_t image_spec;
+	size_t image_size = 0;
+	int io_result = IO_FAIL;
+
+	assert(image_name != NULL);
+
+	/* Obtain a reference to the image by querying the platform layer */
+	io_result = plat_get_image_source(image_name, &dev_handle, &image_spec);
+	if (io_result != IO_SUCCESS) {
+		WARN("Failed to obtain reference to image '%s' (%i)\n",
+			image_name, io_result);
+		return 0;
+	}
+
+	/* Attempt to access the image */
+	io_result = io_open(dev_handle, image_spec, &image_handle);
+	if (io_result != IO_SUCCESS) {
+		WARN("Failed to access image '%s' (%i)\n",
+			image_name, io_result);
+		return 0;
+	}
+
+	/* Find the size of the image */
+	io_result = io_size(image_handle, &image_size);
+	if ((io_result != IO_SUCCESS) || (image_size == 0)) {
+		WARN("Failed to determine the size of the image '%s' file (%i)\n",
+			image_name, io_result);
+	}
+	io_result = io_close(image_handle);
+	/* Ignore improbable/unrecoverable error in 'close' */
+
+	/* TODO: Consider maintaining open device connection from this
+	 * bootloader stage
+	 */
+	io_result = io_dev_close(dev_handle);
+	/* Ignore improbable/unrecoverable error in 'dev_close' */
+
+	return image_size;
+}
+
+/*******************************************************************************
+ * Generic function to load an image at a specific address given a name and
+ * extents of free memory. It updates the memory layout if the load is
+ * successful, as well as the image information and the entry point information.
+ * The caller might pass a NULL pointer for the entry point if it is not
+ * interested in this information, e.g. because the image just needs to be
+ * loaded in memory but won't ever be executed.
+ * Returns 0 on success, a negative error code otherwise.
+ ******************************************************************************/
+int load_image(meminfo_t *mem_layout,
+	       const char *image_name,
+	       uint64_t image_base,
+	       image_info_t *image_data,
+	       entry_point_info_t *entry_point_info)
+{
+	uintptr_t dev_handle;
+	uintptr_t image_handle;
+	uintptr_t image_spec;
+	size_t image_size;
+	size_t bytes_read;
+	int io_result = IO_FAIL;
+
+	assert(mem_layout != NULL);
+	assert(image_name != NULL);
+	assert(image_data != NULL);
+	assert(image_data->h.version >= VERSION_1);
+
+	/* Obtain a reference to the image by querying the platform layer */
+	io_result = plat_get_image_source(image_name, &dev_handle, &image_spec);
+	if (io_result != IO_SUCCESS) {
+		WARN("Failed to obtain reference to image '%s' (%i)\n",
+			image_name, io_result);
+		return io_result;
+	}
+
+	/* Attempt to access the image */
+	io_result = io_open(dev_handle, image_spec, &image_handle);
+	if (io_result != IO_SUCCESS) {
+		WARN("Failed to access image '%s' (%i)\n",
+			image_name, io_result);
+		return io_result;
+	}
+
+	INFO("Loading file '%s' at address 0x%lx\n", image_name, image_base);
+
+	/* Find the size of the image */
+	io_result = io_size(image_handle, &image_size);
+	if ((io_result != IO_SUCCESS) || (image_size == 0)) {
+		WARN("Failed to determine the size of the image '%s' file (%i)\n",
+			image_name, io_result);
+		goto exit;
+	}
+
+	/* Check that the memory where the image will be loaded is free */
+	if (!is_mem_free(mem_layout->free_base, mem_layout->free_size,
+			 image_base, image_size)) {
+		WARN("Failed to reserve memory: 0x%lx - 0x%lx\n",
+			image_base, image_base + image_size);
+		dump_load_info(image_base, image_size, mem_layout);
+		io_result = -ENOMEM;
+		goto exit;
+	}
+
+	/* We have enough space so load the image now */
+	/* TODO: Consider whether to try to recover/retry a partially successful read */
+	io_result = io_read(image_handle, image_base, image_size, &bytes_read);
+	if ((io_result != IO_SUCCESS) || (bytes_read < image_size)) {
+		WARN("Failed to load '%s' file (%i)\n", image_name, io_result);
+		goto exit;
+	}
+
+	/*
+	 * Update the memory usage info.
+	 * This is done after the actual loading so that it is not updated when
+	 * the load is unsuccessful.
+	 * If the caller does not provide an entry point, bypass the memory
+	 * reservation.
+	 */
+	if (entry_point_info != NULL) {
+		reserve_mem(&mem_layout->free_base, &mem_layout->free_size,
+				image_base, image_size);
+	} else {
+		INFO("Skip reserving memory: 0x%lx - 0x%lx\n",
+				image_base, image_base + image_size);
+	}
+
+	image_data->image_base = image_base;
+	image_data->image_size = image_size;
+
+	if (entry_point_info != NULL)
+		entry_point_info->pc = image_base;
+
+	/*
+	 * File has been successfully loaded.
+	 * Flush the image in TZRAM so that the next EL can see it.
+	 */
+	flush_dcache_range(image_base, image_size);
+
+	INFO("File '%s' loaded: 0x%lx - 0x%lx\n", image_name, image_base,
+	     image_base + image_size);
+
+exit:
+	io_close(image_handle);
+	/* Ignore improbable/unrecoverable error in 'close' */
+
+	/* TODO: Consider maintaining open device connection from this bootloader stage */
+	io_dev_close(dev_handle);
+	/* Ignore improbable/unrecoverable error in 'dev_close' */
+
+	return io_result;
+}
diff --git a/uefi/arm-trusted-firmware/common/tf_printf.c b/uefi/arm-trusted-firmware/common/tf_printf.c
new file mode 100644
index 0000000..02461c0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/common/tf_printf.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <debug.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+/***********************************************************
+ * The tf_printf implementation for all BL stages
+ ***********************************************************/
+static void unsigned_num_print(unsigned long int unum, unsigned int radix)
+{
+	/* Just need enough space to store 64 bit decimal integer */
+	unsigned char num_buf[20];
+	int i = 0 , rem;
+
+	do {
+		rem = unum % radix;
+		if (rem < 0xa)
+			num_buf[i++] = '0' + rem;
+		else
+			num_buf[i++] = 'a' + (rem - 0xa);
+	} while (unum /= radix);
+
+	while (--i >= 0)
+		putchar(num_buf[i]);
+}
+
+static void string_print(const char *str)
+{
+	while (*str)
+		putchar(*str++);
+}
+
+/*******************************************************************
+ * Reduced format print for Trusted firmware.
+ * The following formats are supported by this print
+ * %x - 32 bit hexadecimal format
+ * %llx and %lx -64 bit hexadecimal format
+ * %s - string format
+ * %d or %i - signed 32 bit decimal format
+ * %u - unsigned 32 bit decimal format
+ * %ld and %lld - signed 64 bit decimal format
+ * %lu and %llu - unsigned 64 bit decimal format
+ * Exits on all other formats.
+ *******************************************************************/
+
+void tf_printf(const char *fmt, ...)
+{
+	va_list args;
+	int bit64;
+	int64_t num;
+	uint64_t unum;
+	char *str;
+
+	va_start(args, fmt);
+	while (*fmt) {
+		bit64 = 0;
+
+		if (*fmt == '%') {
+			fmt++;
+			/* Check the format specifier */
+loop:
+			switch (*fmt) {
+			case 'i': /* Fall through to next one */
+			case 'd':
+				if (bit64)
+					num = va_arg(args, int64_t);
+				else
+					num = va_arg(args, int32_t);
+
+				if (num < 0) {
+					putchar('-');
+					unum = (unsigned long int)-num;
+				} else
+					unum = (unsigned long int)num;
+
+				unsigned_num_print(unum, 10);
+				break;
+			case 's':
+				str = va_arg(args, char *);
+				string_print(str);
+				break;
+			case 'x':
+				if (bit64)
+					unum = va_arg(args, uint64_t);
+				else
+					unum = va_arg(args, uint32_t);
+
+				unsigned_num_print(unum, 16);
+				break;
+			case 'l':
+				bit64 = 1;
+				fmt++;
+				goto loop;
+			case 'u':
+				if (bit64)
+					unum = va_arg(args, uint64_t);
+				else
+					unum = va_arg(args, uint32_t);
+
+				unsigned_num_print(unum, 10);
+				break;
+			default:
+				/* Exit on any other format specifier */
+				goto exit;
+			}
+			fmt++;
+			continue;
+		}
+		putchar(*fmt++);
+	}
+exit:
+	va_end(args);
+}
diff --git a/uefi/arm-trusted-firmware/contributing.md b/uefi/arm-trusted-firmware/contributing.md
new file mode 100644
index 0000000..6b24fb5
--- /dev/null
+++ b/uefi/arm-trusted-firmware/contributing.md
@@ -0,0 +1,121 @@
+Contributing to ARM Trusted Firmware
+====================================
+
+Before you start contributing to this project you must sign the ARM
+Contributor License Agreement (CLA).
+
+Individuals who want to contribute their own work must sign and return an
+Individual CLA. Companies that want to contribute must sign and return a
+Corporate CLA if their employees' intellectual property has been assigned to
+the employer. Copies of the CLAs are available from the [contributing page] of
+the ARM website.
+
+For this project, ARM also requires the GitHub account name(s) associated with
+each individual contributor or the designated employees of corporate
+contributors. Only contributions originating from these accounts will be
+considered covered by the CLA. To avoid delay, you should provide the Github
+account name(s) at the same time as the signed CLA.
+
+ARM reserves the right to not accept a contribution. This may be for technical,
+commercial or legal reasons.
+
+
+Getting Started
+---------------
+
+*   Make sure you have a [GitHub account].
+*   Create an [issue] for your work if one does not already exist. This gives
+    everyone visibility of whether others are working on something similar. ARM
+    licensees may contact ARM directly via their partner managers instead if
+    they prefer.
+    *   Note that the [issue] tracker for this project is in a separate
+        [issue tracking repository]. Please follow the guidelines in that
+        repository.
+    *   If you intend to include Third Party IP in your contribution, please
+        raise a separate [issue] for this and ensure that the changes that
+        include Third Party IP are made on a separate topic branch.
+*   [Fork][] [arm-trusted-firmware][] on GitHub.
+*   Clone the fork to your own machine.
+*   Create a local topic branch based on the [arm-trusted-firmware][] `master`
+    branch.
+
+
+Making Changes
+--------------
+
+*   Make commits of logical units. See these general [Git guidelines] for
+    contributing to a project.
+*   Follow the [Linux coding style]; this style is enforced for the ARM Trusted
+    Firmware project (style errors only, not warnings).
+    *   Use the checkpatch.pl script provided with the Linux source tree. A
+        Makefile target is provided for convenience (see section 2 in the
+        [User Guide]).
+*   Keep the commits on topic. If you need to fix another bug or make another
+    enhancement, please create a separate [issue] and address it on a separate
+    topic branch.
+*   Avoid long commit series. If you do have a long series, consider whether
+    some commits should be squashed together or addressed in a separate topic.
+*   Make sure your commit messages are in the proper format. If a commit fixes
+    a GitHub [issue], include a reference (e.g.
+    "fixes arm-software/tf-issues#45"); this ensures the [issue] is
+    [automatically closed] when merged into the [arm-trusted-firmware] `master`
+    branch.
+*   Where appropriate, please update the documentation.
+    *   Consider whether the [User Guide], [Porting Guide], [Firmware Design] or
+        other in-source documentation needs updating.
+    *   If this is your first contribution, you may add your name or your
+        company name to the [Acknowledgements] file.
+    *   For topics with multiple commits, you should make all documentation
+        changes (and nothing else) in the last commit of the series. Otherwise,
+        include the documentation changes within the single commit.
+*   Please test your changes. As a minimum, ensure UEFI boots to the shell on
+    the Foundation FVP. See the "[Running the software]" section of the
+    [User Guide] for more information.
+
+
+Submitting Changes
+------------------
+
+*   Ensure we have your signed CLA.
+*   Push your local changes to your fork of the repository.
+*   Submit a [pull request] to the [arm-trusted-firmware] `integration` branch.
+    *   The changes in the [pull request] will then undergo further review and
+        testing. Any review comments will be made as comments on the [pull
+        request]. This may require you to do some rework.
+*   When the changes are accepted, ARM will integrate them.
+    *   Typically, ARM will merge the [pull request] into the `integration`
+        branch within the GitHub UI, creating a merge commit.
+    *   Please avoid creating merge commits in the [pull request] itself.
+    *   If the [pull request] is not based on a recent commit, ARM may rebase
+        it onto the `master` branch first, or ask you to do this.
+    *   If the [pull request] cannot be automatically merged, ARM will ask you
+        to rebase it onto the `master` branch.
+    *   After final integration testing, ARM will push your merge commit to the
+        `master` branch. If a problem is found at this stage, the merge commit
+        will be removed from the `integration` branch and ARM will ask you to
+        create a new pull request to resolve the problem.
+    *   Please do not delete your topic branch until it is safely merged into
+        the `master` branch.
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._
+
+
+[User Guide]:                           ./docs/user-guide.md
+[Running the software]:                 ./docs/user-guide.md#6--running-the-software
+[Porting Guide]:                        ./docs/porting-guide.md
+[Firmware Design]:                      ./docs/firmware-design.md
+[Acknowledgements]:                     ./acknowledgements.md "Contributor acknowledgements"
+
+[contributing page]:            http://www.arm.com/community/open-source-contributing.php
+[GitHub account]:               https://github.com/signup/free
+[Fork]:                         https://help.github.com/articles/fork-a-repo
+[issue tracking repository]:    https://github.com/ARM-software/tf-issues
+[issue]:                        https://github.com/ARM-software/tf-issues/issues
+[pull request]:                 https://help.github.com/articles/using-pull-requests
+[automatically closed]:         https://help.github.com/articles/closing-issues-via-commit-messages
+[Git guidelines]:               http://git-scm.com/book/ch5-2.html
+[Linux coding style]:           https://www.kernel.org/doc/Documentation/CodingStyle
+[arm-trusted-firmware]:         https://github.com/ARM-software/arm-trusted-firmware
diff --git a/uefi/arm-trusted-firmware/docs/change-log.md b/uefi/arm-trusted-firmware/docs/change-log.md
new file mode 100644
index 0000000..c7b5508
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/change-log.md
@@ -0,0 +1,710 @@
+ARM Trusted Firmware - version 1.1
+==================================
+
+New features
+------------
+
+*   A prototype implementation of Trusted Board Boot has been added. Boot
+    loader images are verified by BL1 and BL2 during the cold boot path. BL1 and
+    BL2 use the PolarSSL SSL library to verify certificates and images. The
+    OpenSSL library is used to create the X.509 certificates. Support has been
+    added to `fip_create` tool to package the certificates in a FIP.
+
+*   Support for calling CPU and platform specific reset handlers upon entry into
+    BL3-1 during the cold and warm boot paths has been added. This happens after
+    another Boot ROM `reset_handler()` has already run. This enables a developer
+    to perform additional actions or undo actions already performed during the
+    first call of the reset handlers e.g. apply additional errata workarounds.
+
+*   Support has been added to demonstrate routing of IRQs to EL3 instead of
+    S-EL1 when execution is in secure world.
+
+*   The PSCI implementation now conforms to version 1.0 of the PSCI
+    specification. All the mandatory APIs and selected optional APIs are
+    supported. In particular, support for the `PSCI_FEATURES` API has been
+    added. A capability variable is constructed during initialization by
+    examining the `plat_pm_ops` and `spd_pm_ops` exported by the platform and
+    the Secure Payload Dispatcher.  This is used by the PSCI FEATURES function
+    to determine which PSCI APIs are supported by the platform.
+
+*   Improvements have been made to the PSCI code as follows.
+
+    *   The code has been refactored to remove redundant parameters from
+        internal functions.
+
+    *   Changes have been made to the code for PSCI `CPU_SUSPEND`, `CPU_ON` and
+        `CPU_OFF` calls to facilitate an early return to the caller in case a
+        failure condition is detected. For example, a PSCI `CPU_SUSPEND` call
+        returns `SUCCESS` to the caller if a pending interrupt is detected early
+        in the code path.
+
+    *   Optional platform APIs have been added to validate the `power_state` and
+        `entrypoint` parameters early in PSCI `CPU_ON` and `CPU_SUSPEND` code
+        paths.
+
+    *   PSCI migrate APIs have been reworked to invoke the SPD hook to determine
+        the type of Trusted OS and the CPU it is resident on (if
+        applicable). Also, during a PSCI `MIGRATE` call, the SPD hook to migrate
+        the Trusted OS is invoked.
+
+*   It is now possible to build Trusted Firmware without marking at least an
+    extra page of memory as coherent. The build flag `USE_COHERENT_MEM` can be
+    used to choose between the two implementations. This has been made possible
+    through these changes.
+
+    *   An implementation of Bakery locks, where the locks are not allocated in
+        coherent memory has been added.
+
+    *   Memory which was previously marked as coherent is now kept coherent
+        through the use of software cache maintenance operations.
+
+    Approximately, 4K worth of memory is saved for each boot loader stage when
+    `USE_COHERENT_MEM=0`. Enabling this option increases the latencies
+    associated with acquire and release of locks. It also requires changes to
+    the platform ports.
+
+*   It is now possible to specify the name of the FIP at build time by defining
+    the `FIP_NAME` variable.
+
+*   Issues with depedencies on the 'fiptool' makefile target have been
+    rectified. The `fip_create` tool is now rebuilt whenever its source files
+    change.
+
+*   The BL3-1 runtime console is now also used as the crash console. The crash
+    console is changed to SoC UART0 (UART2) from the previous FPGA UART0 (UART0)
+    on Juno. In FVP, it is changed from UART0 to UART1.
+
+*   CPU errata workarounds are applied only when the revision and part number
+    match. This behaviour has been made consistent across the debug and release
+    builds. The debug build additionally prints a warning if a mismatch is
+    detected.
+
+*   It is now possible to issue cache maintenance operations by set/way for a
+    particular level of data cache. Levels 1-3 are currently supported.
+
+*   The following improvements have been made to the FVP port.
+
+    *   The build option `FVP_SHARED_DATA_LOCATION` which allowed relocation of
+        shared data into the Trusted DRAM has been deprecated. Shared data is
+        now always located at the base of Trusted SRAM.
+
+    *   BL2 Translation tables have been updated to map only the region of
+        DRAM which is accessible to normal world. This is the region of the 2GB
+        DDR-DRAM memory at 0x80000000 excluding the top 16MB. The top 16MB is
+        accessible to only the secure world.
+
+    *   BL3-2 can now reside in the top 16MB of DRAM which is accessible only to
+        the secure world. This can be done by setting the build flag
+        `FVP_TSP_RAM_LOCATION` to the value `dram`.
+
+*   Separate transation tables are created for each boot loader image. The
+    `IMAGE_BLx` build options are used to do this.  This allows each stage to
+    create mappings only for areas in the memory map that it needs.
+
+*   A Secure Payload Dispatcher (OPTEED) for the OP-TEE Trusted OS has been
+    added.  Details of using it with ARM Trusted Firmware can be found in
+    [OP-TEE Dispatcher]
+
+
+
+Issues resolved since last release
+----------------------------------
+
+*   The Juno port has been aligned with the FVP port as follows.
+
+    *   Support for reclaiming all BL1 RW memory and BL2 memory by overlaying
+        the BL3-1/BL3-2 NOBITS sections on top of them has been added to the
+        Juno port.
+
+    *   The top 16MB of the 2GB DDR-DRAM memory at 0x80000000 is configured
+        using the TZC-400 controller to be accessible only to the secure world.
+
+    *   The ARM GIC driver is used to configure the GIC-400 instead of using a
+        GIC driver private to the Juno port.
+
+    *   PSCI `CPU_SUSPEND` calls that target a standby state are now supported.
+
+    *   The TZC-400 driver is used to configure the controller instead of direct
+        accesses to the registers.
+
+*   The Linux kernel version referred to in the user guide has DVFS and HMP
+    support enabled.
+
+*   DS-5 v5.19 did not detect Version 5.8 of the Cortex-A57-A53 Base FVPs in
+    CADI server mode. This issue is not seen with DS-5 v5.20 and Version 6.2 of
+    the Cortex-A57-A53 Base FVPs.
+
+
+Known issues
+------------
+
+*   The Trusted Board Boot implementation is a prototype. There are issues with
+    the modularity and scalability of the design. Support for a Trusted
+    Watchdog, firmware update mechanism, recovery images and Trusted debug is
+    absent. These issues will be addressed in future releases.
+
+*   The FVP and Juno ports do not use the hash of the ROTPK stored in the
+    Trusted Key Storage registers to verify the ROTPK in the
+    `plat_match_rotpk()` function. This prevents the correct establishment of
+    the Chain of Trust at the first step in the Trusted Board Boot process.
+
+*   The version of the AEMv8 Base FVP used in this release resets the model
+    instead of terminating its execution in response to a shutdown request using
+    the PSCI `SYSTEM_OFF` API. This issue will be fixed in a future version of
+    the model.
+
+*   GICv3 support is experimental. There are known issues with GICv3
+    initialization in the ARM Trusted Firmware.
+
+*   While this version greatly reduces the on-chip RAM requirements, there are
+    further RAM usage enhancements that could be made.
+
+*   The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
+    its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
+
+*   The Juno-specific firmware design documentation is incomplete.
+
+
+ARM Trusted Firmware - version 1.0
+==================================
+
+New features
+------------
+
+*   It is now possible to map higher physical addresses using non-flat virtual
+    to physical address mappings in the MMU setup.
+
+*   Wider use is now made of the per-CPU data cache in BL3-1 to store:
+
+    *   Pointers to the non-secure and secure security state contexts.
+
+    *   A pointer to the CPU-specific operations.
+
+    *   A pointer to PSCI specific information (for example the current power
+        state).
+
+    *   A crash reporting buffer.
+
+*   The following RAM usage improvements result in a BL3-1 RAM usage reduction
+    from 96KB to 56KB (for FVP with TSPD), and a total RAM usage reduction
+    across all images from 208KB to 88KB, compared to the previous release.
+
+    *   Removed the separate `early_exception` vectors from BL3-1 (2KB code size
+        saving).
+
+    *   Removed NSRAM from the FVP memory map, allowing the removal of one
+        (4KB) translation table.
+
+    *   Eliminated the internal `psci_suspend_context` array, saving 2KB.
+
+    *   Correctly dimensioned the PSCI `aff_map_node` array, saving 1.5KB in the
+        FVP port.
+
+    *   Removed calling CPU mpidr from the bakery lock API, saving 160 bytes.
+
+    *   Removed current CPU mpidr from PSCI common code, saving 160 bytes.
+
+    *   Inlined the mmio accessor functions, saving 360 bytes.
+
+    *   Fully reclaimed all BL1 RW memory and BL2 memory on the FVP port by
+        overlaying the BL3-1/BL3-2 NOBITS sections on top of these at runtime.
+
+    *   Made storing the FP register context optional, saving 0.5KB per context
+        (8KB on the FVP port, with TSPD enabled and running on 8 CPUs).
+
+    *   Implemented a leaner `tf_printf()` function, allowing the stack to be
+        greatly reduced.
+
+    *   Removed coherent stacks from the codebase. Stacks allocated in normal
+        memory are now used before and after the MMU is enabled. This saves 768
+        bytes per CPU in BL3-1.
+
+    *   Reworked the crash reporting in BL3-1 to use less stack.
+
+    *   Optimized the EL3 register state stored in the `cpu_context` structure
+        so that registers that do not change during normal execution are
+        re-initialized each time during cold/warm boot, rather than restored
+        from memory. This saves about 1.2KB.
+
+    *   As a result of some of the above, reduced the runtime stack size in all
+        BL images. For BL3-1, this saves 1KB per CPU.
+
+*   PSCI SMC handler improvements to correctly handle calls from secure states
+    and from AArch32.
+
+*   CPU contexts are now initialized from the `entry_point_info`. BL3-1 fully
+    determines the exception level to use for the non-trusted firmware (BL3-3)
+    based on the SPSR value provided by the BL2 platform code (or otherwise
+    provided to BL3-1). This allows platform code to directly run non-trusted
+    firmware payloads at either EL2 or EL1 without requiring an EL2 stub or OS
+    loader.
+
+*   Code refactoring improvements:
+
+    *   Refactored `fvp_config` into a common platform header.
+
+    *   Refactored the fvp gic code to be a generic driver that no longer has an
+        explicit dependency on platform code.
+
+    *   Refactored the CCI-400 driver to not have dependency on platform code.
+
+    *   Simplified the IO driver so it's no longer necessary to call `io_init()`
+        and moved all the IO storage framework code to one place.
+
+    *   Simplified the interface the the TZC-400 driver.
+
+    *   Clarified the platform porting interface to the TSP.
+
+    *   Reworked the TSPD setup code to support the alternate BL3-2
+        intialization flow where BL3-1 generic code hands control to BL3-2,
+        rather than expecting the TSPD to hand control directly to BL3-2.
+
+    *   Considerable rework to PSCI generic code to support CPU specific
+        operations.
+
+*   Improved console log output, by:
+
+    *   Adding the concept of debug log levels.
+
+    *   Rationalizing the existing debug messages and adding new ones.
+
+    *   Printing out the version of each BL stage at runtime.
+
+    *   Adding support for printing console output from assembler code,
+        including when a crash occurs before the C runtime is initialized.
+
+*   Moved up to the latest versions of the FVPs, toolchain, EDK2, kernel, Linaro
+    file system and DS-5.
+
+*   On the FVP port, made the use of the Trusted DRAM region optional at build
+    time (off by default). Normal platforms will not have such a "ready-to-use"
+    DRAM area so it is not a good example to use it.
+
+*   Added support for PSCI `SYSTEM_OFF` and `SYSTEM_RESET` APIs.
+
+*   Added support for CPU specific reset sequences, power down sequences and
+    register dumping during crash reporting. The CPU specific reset sequences
+    include support for errata workarounds.
+
+*   Merged the Juno port into the master branch. Added support for CPU hotplug
+    and CPU idle. Updated the user guide to describe how to build and run on the
+    Juno platform.
+
+
+Issues resolved since last release
+----------------------------------
+
+*   Removed the concept of top/bottom image loading. The image loader now
+    automatically detects the position of the image inside the current memory
+    layout and updates the layout to minimize fragementation. This resolves the
+    image loader limitations of previously releases. There are currently no
+    plans to support dynamic image loading.
+
+*   CPU idle now works on the publicized version of the Foundation FVP.
+
+*   All known issues relating to the compiler version used have now been
+    resolved. This TF version uses Linaro toolchain 14.07 (based on GCC 4.9).
+
+
+Known issues
+------------
+
+*   GICv3 support is experimental. The Linux kernel patches to support this are
+    not widely available. There are known issues with GICv3 initialization in
+    the ARM Trusted Firmware.
+
+*   While this version greatly reduces the on-chip RAM requirements, there are
+    further RAM usage enhancements that could be made.
+
+*   The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
+    its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
+
+*   The Juno-specific firmware design documentation is incomplete.
+
+*   Some recent enhancements to the FVP port have not yet been translated into
+    the Juno port. These will be tracked via the tf-issues project.
+
+*   The Linux kernel version referred to in the user guide has DVFS and HMP
+    support disabled due to some known instabilities at the time of this
+    release. A future kernel version will re-enable these features.
+
+*   DS-5 v5.19 does not detect Version 5.8 of the Cortex-A57-A53 Base FVPs in
+    CADI server mode. This is because the `<SimName>` reported by the FVP in
+    this version has changed. For example, for the Cortex-A57x4-A53x4 Base FVP,
+    the `<SimName>` reported by the FVP is `FVP_Base_Cortex_A57x4_A53x4`, while
+    DS-5 expects it to be `FVP_Base_A57x4_A53x4`.
+
+    The temporary fix to this problem is to change the name of the FVP in
+    `sw/debugger/configdb/Boards/ARM FVP/Base_A57x4_A53x4/cadi_config.xml`.
+    Change the following line:
+
+        <SimName>System Generator:FVP_Base_A57x4_A53x4</SimName>
+    to
+        <SimName>System Generator:FVP_Base_Cortex-A57x4_A53x4</SimName>
+
+    A similar change can be made to the other Cortex-A57-A53 Base FVP variants.
+
+
+ARM Trusted Firmware - version 0.4
+==================================
+
+New features
+------------
+
+*   Makefile improvements:
+
+    *   Improved dependency checking when building.
+
+    *   Removed `dump` target (build now always produces dump files).
+
+    *   Enabled platform ports to optionally make use of parts of the Trusted
+        Firmware (e.g. BL3-1 only), rather than being forced to use all parts.
+        Also made the `fip` target optional.
+
+    *   Specified the full path to source files and removed use of the `vpath`
+        keyword.
+
+*   Provided translation table library code for potential re-use by platforms
+    other than the FVPs.
+
+*   Moved architectural timer setup to platform-specific code.
+
+*   Added standby state support to PSCI cpu_suspend implementation.
+
+*   SRAM usage improvements:
+
+    *   Started using the `-ffunction-sections`, `-fdata-sections` and
+        `--gc-sections` compiler/linker options to remove unused code and data
+        from the images. Previously, all common functions were being built into
+        all binary images, whether or not they were actually used.
+
+    *   Placed all assembler functions in their own section to allow more unused
+        functions to be removed from images.
+
+    *   Updated BL1 and BL2 to use a single coherent stack each, rather than one
+        per CPU.
+
+    *   Changed variables that were unnecessarily declared and initialized as
+        non-const (i.e. in the .data section) so they are either uninitialized
+        (zero init) or const.
+
+*   Moved the Test Secure-EL1 Payload (BL3-2) to execute in Trusted SRAM by
+    default. The option for it to run in Trusted DRAM remains.
+
+*   Implemented a TrustZone Address Space Controller (TZC-400) driver. A
+    default configuration is provided for the Base FVPs. This means the model
+    parameter `-C bp.secure_memory=1` is now supported.
+
+*   Started saving the PSCI cpu_suspend 'power_state' parameter prior to
+    suspending a CPU. This allows platforms that implement multiple power-down
+    states at the same affinity level to identify a specific state.
+
+*   Refactored the entire codebase to reduce the amount of nesting in header
+    files and to make the use of system/user includes more consistent. Also
+    split platform.h to separate out the platform porting declarations from the
+    required platform porting definitions and the definitions/declarations
+    specific to the platform port.
+
+*   Optimized the data cache clean/invalidate operations.
+
+*   Improved the BL3-1 unhandled exception handling and reporting. Unhandled
+    exceptions now result in a dump of registers to the console.
+
+*   Major rework to the handover interface between BL stages, in particular the
+    interface to BL3-1. The interface now conforms to a specification and is
+    more future proof.
+
+*   Added support for optionally making the BL3-1 entrypoint a reset handler
+    (instead of BL1). This allows platforms with an alternative image loading
+    architecture to re-use BL3-1 with fewer modifications to generic code.
+
+*   Reserved some DDR DRAM for secure use on FVP platforms to avoid future
+    compatibility problems with non-secure software.
+
+*   Added support for secure interrupts targeting the Secure-EL1 Payload (SP)
+    (using GICv2 routing only). Demonstrated this working by adding an interrupt
+    target and supporting test code to the TSP. Also demonstrated non-secure
+    interrupt handling during TSP processing.
+
+
+Issues resolved since last release
+----------------------------------
+
+*   Now support use of the model parameter `-C bp.secure_memory=1` in the Base
+    FVPs (see **New features**).
+
+*   Support for secure world interrupt handling now available (see **New
+    features**).
+
+*   Made enough SRAM savings (see **New features**) to enable the Test Secure-EL1
+    Payload (BL3-2) to execute in Trusted SRAM by default.
+
+*   The tested filesystem used for this release (Linaro AArch64 OpenEmbedded
+    14.04) now correctly reports progress in the console.
+
+*   Improved the Makefile structure to make it easier to separate out parts of
+    the Trusted Firmware for re-use in platform ports. Also, improved target
+    dependency checking.
+
+
+Known issues
+------------
+
+*   GICv3 support is experimental. The Linux kernel patches to support this are
+    not widely available. There are known issues with GICv3 initialization in
+    the ARM Trusted Firmware.
+
+*   Dynamic image loading is not available yet. The current image loader
+    implementation (used to load BL2 and all subsequent images) has some
+    limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead
+    to loading errors, even if the images should theoretically fit in memory.
+
+*   The ARM Trusted Firmware still uses too much on-chip Trusted SRAM. A number
+    of RAM usage enhancements have been identified to rectify this situation.
+
+*   CPU idle does not work on the advertised version of the Foundation FVP.
+    Some FVP fixes are required that are not available externally at the time
+    of writing. This can be worked around by disabling CPU idle in the Linux
+    kernel.
+
+*   Various bugs in ARM Trusted Firmware, UEFI and the Linux kernel have been
+    observed when using Linaro toolchain versions later than 13.11. Although
+    most of these have been fixed, some remain at the time of writing. These
+    mainly seem to relate to a subtle change in the way the compiler converts
+    between 64-bit and 32-bit values (e.g. during casting operations), which
+    reveals previously hidden bugs in client code.
+
+*   The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
+    its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
+
+
+ARM Trusted Firmware - version 0.3
+==================================
+
+New features
+------------
+
+*   Support for Foundation FVP Version 2.0 added.
+    The documented UEFI configuration disables some devices that are unavailable
+    in the Foundation FVP, including MMC and CLCD. The resultant UEFI binary can
+    be used on the AEMv8 and Cortex-A57-A53 Base FVPs, as well as the Foundation
+    FVP.
+
+    NOTE: The software will not work on Version 1.0 of the Foundation FVP.
+
+*   Enabled third party contributions. Added a new contributing.md containing
+    instructions for how to contribute and updated copyright text in all files
+    to acknowledge contributors.
+
+*   The PSCI CPU_SUSPEND API has been stabilised to the extent where it can be
+    used for entry into power down states with the following restrictions:
+    -   Entry into standby states is not supported.
+    -   The API is only supported on the AEMv8 and Cortex-A57-A53 Base FVPs.
+
+*   The PSCI AFFINITY_INFO api has undergone limited testing on the Base FVPs to
+    allow experimental use.
+
+*   Required C library and runtime header files are now included locally in ARM
+    Trusted Firmware instead of depending on the toolchain standard include
+    paths. The local implementation has been cleaned up and reduced in scope.
+
+*   Added I/O abstraction framework, primarily to allow generic code to load
+    images in a platform-independent way. The existing image loading code has
+    been reworked to use the new framework. Semi-hosting and NOR flash I/O
+    drivers are provided.
+
+*   Introduced Firmware Image Package (FIP) handling code and tools. A FIP
+    combines multiple firmware images with a Table of Contents (ToC) into a
+    single binary image. The new FIP driver is another type of I/O driver. The
+    Makefile builds a FIP by default and the FVP platform code expect to load a
+    FIP from NOR flash, although some support for image loading using semi-
+    hosting is retained.
+
+    NOTE: Building a FIP by default is a non-backwards-compatible change.
+
+    NOTE: Generic BL2 code now loads a BL3-3 (non-trusted firmware) image into
+    DRAM instead of expecting this to be pre-loaded at known location. This is
+    also a non-backwards-compatible change.
+
+    NOTE: Some non-trusted firmware (e.g. UEFI) will need to be rebuilt so that
+    it knows the new location to execute from and no longer needs to copy
+    particular code modules to DRAM itself.
+
+*   Reworked BL2 to BL3-1 handover interface. A new composite structure
+    (bl31_args) holds the superset of information that needs to be passed from
+    BL2 to BL3-1, including information on how handover execution control to
+    BL3-2 (if present) and BL3-3 (non-trusted firmware).
+
+*   Added library support for CPU context management, allowing the saving and
+    restoring of
+    -   Shared system registers between Secure-EL1 and EL1.
+    -   VFP registers.
+    -   Essential EL3 system registers.
+
+*   Added a framework for implementing EL3 runtime services. Reworked the PSCI
+    implementation to be one such runtime service.
+
+*   Reworked the exception handling logic, making use of both SP_EL0 and SP_EL3
+    stack pointers for determining the type of exception, managing general
+    purpose and system register context on exception entry/exit, and handling
+    SMCs. SMCs are directed to the correct EL3 runtime service.
+
+*   Added support for a Test Secure-EL1 Payload (TSP) and a corresponding
+    Dispatcher (TSPD), which is loaded as an EL3 runtime service. The TSPD
+    implements Secure Monitor functionality such as world switching and
+    EL1 context management, and is responsible for communication with the TSP.
+    NOTE: The TSPD does not yet contain support for secure world interrupts.
+    NOTE: The TSP/TSPD is not built by default.
+
+
+Issues resolved since last release
+----------------------------------
+
+*   Support has been added for switching context between secure and normal
+    worlds in EL3.
+
+*   PSCI API calls `AFFINITY_INFO` & `PSCI_VERSION` have now been tested (to
+    a limited extent).
+
+*   The ARM Trusted Firmware build artifacts are now placed in the `./build`
+    directory and sub-directories instead of being placed in the root of the
+    project.
+
+*   The ARM Trusted Firmware is now free from build warnings. Build warnings
+    are now treated as errors.
+
+*   The ARM Trusted Firmware now provides C library support locally within the
+    project to maintain compatibility between toolchains/systems.
+
+*   The PSCI locking code has been reworked so it no longer takes locks in an
+    incorrect sequence.
+
+*   The RAM-disk method of loading a Linux file-system has been confirmed to
+    work with the ARM Trusted Firmware and Linux kernel version (based on
+    version 3.13) used in this release, for both Foundation and Base FVPs.
+
+
+Known issues
+------------
+
+The following is a list of issues which are expected to be fixed in the future
+releases of the ARM Trusted Firmware.
+
+*   The TrustZone Address Space Controller (TZC-400) is not being programmed
+    yet. Use of model parameter `-C bp.secure_memory=1` is not supported.
+
+*   No support yet for secure world interrupt handling.
+
+*   GICv3 support is experimental. The Linux kernel patches to support this are
+    not widely available. There are known issues with GICv3 initialization in
+    the ARM Trusted Firmware.
+
+*   Dynamic image loading is not available yet. The current image loader
+    implementation (used to load BL2 and all subsequent images) has some
+    limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead
+    to loading errors, even if the images should theoretically fit in memory.
+
+*   The ARM Trusted Firmware uses too much on-chip Trusted SRAM. Currently the
+    Test Secure-EL1 Payload (BL3-2) executes in Trusted DRAM since there is not
+    enough SRAM. A number of RAM usage enhancements have been identified to
+    rectify this situation.
+
+*   CPU idle does not work on the advertised version of the Foundation FVP.
+    Some FVP fixes are required that are not available externally at the time
+    of writing.
+
+*   Various bugs in ARM Trusted Firmware, UEFI and the Linux kernel have been
+    observed when using Linaro toolchain versions later than 13.11. Although
+    most of these have been fixed, some remain at the time of writing. These
+    mainly seem to relate to a subtle change in the way the compiler converts
+    between 64-bit and 32-bit values (e.g. during casting operations), which
+    reveals previously hidden bugs in client code.
+
+*   The tested filesystem used for this release (Linaro AArch64 OpenEmbedded
+    14.01) does not report progress correctly in the console. It only seems to
+    produce error output, not standard output. It otherwise appears to function
+    correctly. Other filesystem versions on the same software stack do not
+    exhibit the problem.
+
+*   The Makefile structure doesn't make it easy to separate out parts of the
+    Trusted Firmware for re-use in platform ports, for example if only BL3-1 is
+    required in a platform port. Also, dependency checking in the Makefile is
+    flawed.
+
+*   The firmware design documentation for the Test Secure-EL1 Payload (TSP) and
+    its dispatcher (TSPD) is incomplete. Similarly for the PSCI section.
+
+
+ARM Trusted Firmware - version 0.2
+==================================
+
+New features
+------------
+
+*   First source release.
+
+*   Code for the PSCI suspend feature is supplied, although this is not enabled
+    by default since there are known issues (see below).
+
+
+Issues resolved since last release
+----------------------------------
+
+*   The "psci" nodes in the FDTs provided in this release now fully comply
+    with the recommendations made in the PSCI specification.
+
+
+Known issues
+------------
+
+The following is a list of issues which are expected to be fixed in the future
+releases of the ARM Trusted Firmware.
+
+*   The TrustZone Address Space Controller (TZC-400) is not being programmed
+    yet. Use of model parameter `-C bp.secure_memory=1` is not supported.
+
+*   No support yet for secure world interrupt handling or for switching context
+    between secure and normal worlds in EL3.
+
+*   GICv3 support is experimental. The Linux kernel patches to support this are
+    not widely available. There are known issues with GICv3 initialization in
+    the ARM Trusted Firmware.
+
+*   Dynamic image loading is not available yet. The current image loader
+    implementation (used to load BL2 and all subsequent images) has some
+    limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead
+    to loading errors, even if the images should theoretically fit in memory.
+
+*   Although support for PSCI `CPU_SUSPEND` is present, it is not yet stable
+    and ready for use.
+
+*   PSCI API calls `AFFINITY_INFO` & `PSCI_VERSION` are implemented but have not
+    been tested.
+
+*   The ARM Trusted Firmware make files result in all build artifacts being
+    placed in the root of the project. These should be placed in appropriate
+    sub-directories.
+
+*   The compilation of ARM Trusted Firmware is not free from compilation
+    warnings. Some of these warnings have not been investigated yet so they
+    could mask real bugs.
+
+*   The ARM Trusted Firmware currently uses toolchain/system include files like
+    stdio.h. It should provide versions of these within the project to maintain
+    compatibility between toolchains/systems.
+
+*   The PSCI code takes some locks in an incorrect sequence. This may cause
+    problems with suspend and hotplug in certain conditions.
+
+*   The Linux kernel used in this release is based on version 3.12-rc4. Using
+    this kernel with the ARM Trusted Firmware fails to start the file-system as
+    a RAM-disk. It fails to execute user-space `init` from the RAM-disk. As an
+    alternative, the VirtioBlock mechanism can be used to provide a file-system
+    to the kernel.
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved._
+
+[OP-TEE Dispatcher]:       ./optee-dispatcher.md
diff --git a/uefi/arm-trusted-firmware/docs/cpu-specific-build-macros.md b/uefi/arm-trusted-firmware/docs/cpu-specific-build-macros.md
new file mode 100644
index 0000000..2368fd2
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/cpu-specific-build-macros.md
@@ -0,0 +1,70 @@
+ARM CPU Specific Build Macros
+=============================
+
+Contents
+--------
+
+1.  [Introduction](#1--introduction)
+2.  [CPU Errata Workarounds](#2--cpu-errata-workarounds)
+3.  [CPU Specific optimizations](#3--cpu-specific-optimizations)
+
+
+1.  Introduction
+----------------
+
+This document describes the various build options present in the CPU specific
+operations framework to enable errata workarounds and to enable optimizations
+for a specific CPU on a platform.
+
+2.  CPU Errata Workarounds
+--------------------------
+
+ARM Trusted Firmware exports a series of build flags which control the
+errata workarounds that are applied to each CPU by the reset handler. The
+errata details can be found in the CPU specific errata documents published
+by ARM. The errata workarounds are implemented for a particular revision
+or a set of processor revisions. This is checked by reset handler at runtime.
+Each errata workaround is identified by its `ID` as specified in the processor's
+errata notice document. The format of the define used to enable/disable the
+errata is `ERRATA_<Processor name>_<ID>` where the `Processor name`
+is either `A57` for the `Cortex_A57` CPU or `A53` for `Cortex_A53` CPU.
+
+All workarounds are disabled by default. The platform is reponsible for
+enabling these workarounds according to its requirement by defining the
+errata workaround build flags in the platform specific makefile. In case
+these workarounds are enabled for the wrong CPU revision then the errata
+workaround is not applied. In the DEBUG build, this is indicated by
+printing a warning to the crash console.
+
+In the current implementation, a platform which has more than 1 variant
+with different revisions of a processor has no runtime mechanism available
+for it to specify which errata workarounds should be enabled or not.
+
+The value of the build flags are 0 by default, that is, disabled. Any other
+value will enable it.
+
+For Cortex-A57, following errata build flags are defined :
+
+*   `ERRATA_A57_806969`: This applies errata 806969 workaround to Cortex-A57
+     CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+*   `ERRATA_A57_813420`: This applies errata 813420 workaround to Cortex-A57
+     CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+3.  CPU Specific optimizations
+------------------------------
+
+This section describes some of the optimizations allowed by the CPU micro
+architecture that can be enabled by the platform as desired.
+
+*    `SKIP_A57_L1_FLUSH_PWR_DWN`: This flag enables an optimization in the
+     Cortex-A57 cluster power down sequence by not flushing the Level 1 data
+     cache. The L1 data cache and the L2 unified cache are inclusive. A flush
+     of the L2 by set/way flushes any dirty lines from the L1 as well. This
+     is a known safe deviation from the Cortex-A57 TRM defined power down
+     sequence. Each Cortex-A57 based platform must make its own decision on
+     whether to use the optimization.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2014, ARM Limited and Contributors. All rights reserved._
diff --git a/uefi/arm-trusted-firmware/docs/diagrams/non-sec-int-handling.png b/uefi/arm-trusted-firmware/docs/diagrams/non-sec-int-handling.png
new file mode 100644
index 0000000..1a5f629
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/diagrams/non-sec-int-handling.png
Binary files differ
diff --git a/uefi/arm-trusted-firmware/docs/diagrams/rt-svc-descs-layout.png b/uefi/arm-trusted-firmware/docs/diagrams/rt-svc-descs-layout.png
new file mode 100644
index 0000000..1a9fa5b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/diagrams/rt-svc-descs-layout.png
Binary files differ
diff --git a/uefi/arm-trusted-firmware/docs/diagrams/sec-int-handling.png b/uefi/arm-trusted-firmware/docs/diagrams/sec-int-handling.png
new file mode 100644
index 0000000..2ebbca4
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/diagrams/sec-int-handling.png
Binary files differ
diff --git a/uefi/arm-trusted-firmware/docs/firmware-design.md b/uefi/arm-trusted-firmware/docs/firmware-design.md
new file mode 100644
index 0000000..72525bd
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/firmware-design.md
@@ -0,0 +1,1807 @@
+ARM Trusted Firmware Design
+===========================
+
+Contents :
+
+1.  [Introduction](#1--introduction)
+2.  [Cold boot](#2--cold-boot)
+3.  [EL3 runtime services framework](#3--el3-runtime-services-framework)
+4.  [Power State Coordination Interface](#4--power-state-coordination-interface)
+5.  [Secure-EL1 Payloads and Dispatchers](#5--secure-el1-payloads-and-dispatchers)
+6.  [Crash Reporting in BL3-1](#6--crash-reporting-in-bl3-1)
+7.  [Guidelines for Reset Handlers](#7--guidelines-for-reset-handlers)
+8.  [CPU specific operations framework](#8--cpu-specific-operations-framework)
+9.  [Memory layout of BL images](#9-memory-layout-of-bl-images)
+10. [Firmware Image Package (FIP)](#10--firmware-image-package-fip)
+11. [Use of coherent memory in Trusted Firmware](#11--use-of-coherent-memory-in-trusted-firmware)
+12. [Code Structure](#12--code-structure)
+13. [References](#13--references)
+
+
+1.  Introduction
+----------------
+
+The ARM Trusted Firmware implements a subset of the Trusted Board Boot
+Requirements (TBBR) Platform Design Document (PDD) [1] for ARM reference
+platforms. The TBB sequence starts when the platform is powered on and runs up
+to the stage where it hands-off control to firmware running in the normal
+world in DRAM. This is the cold boot path.
+
+The ARM Trusted Firmware also implements the Power State Coordination Interface
+([PSCI]) PDD [2] as a runtime service. PSCI is the interface from normal world
+software to firmware implementing power management use-cases (for example,
+secondary CPU boot, hotplug and idle). Normal world software can access ARM
+Trusted Firmware runtime services via the ARM SMC (Secure Monitor Call)
+instruction. The SMC instruction must be used as mandated by the [SMC Calling
+Convention PDD][SMCCC] [3].
+
+The ARM Trusted Firmware implements a framework for configuring and managing
+interrupts generated in either security state. The details of the interrupt
+management framework and its design can be found in [ARM Trusted
+Firmware Interrupt Management Design guide][INTRG] [4].
+
+2.  Cold boot
+-------------
+
+The cold boot path starts when the platform is physically turned on. One of
+the CPUs released from reset is chosen as the primary CPU, and the remaining
+CPUs are considered secondary CPUs. The primary CPU is chosen through
+platform-specific means. The cold boot path is mainly executed by the primary
+CPU, other than essential CPU initialization executed by all CPUs. The
+secondary CPUs are kept in a safe platform-specific state until the primary
+CPU has performed enough initialization to boot them.
+
+The cold boot path in this implementation of the ARM Trusted Firmware is divided
+into five steps (in order of execution):
+
+*   Boot Loader stage 1 (BL1) _AP Trusted ROM_
+*   Boot Loader stage 2 (BL2) _Trusted Boot Firmware_
+*   Boot Loader stage 3-1 (BL3-1) _EL3 Runtime Firmware_
+*   Boot Loader stage 3-2 (BL3-2) _Secure-EL1 Payload_ (optional)
+*   Boot Loader stage 3-3 (BL3-3) _Non-trusted Firmware_
+
+ARM development platforms (Fixed Virtual Platforms (FVPs) and Juno) implement a
+combination of the following types of memory regions. Each bootloader stage uses
+one or more of these memory regions.
+
+*   Regions accessible from both non-secure and secure states. For example,
+    non-trusted SRAM, ROM and DRAM.
+*   Regions accessible from only the secure state. For example, trusted SRAM and
+    ROM. The FVPs also implement the trusted DRAM which is statically
+    configured. Additionally, the Base FVPs and Juno development platform
+    configure the TrustZone Controller (TZC) to create a region in the DRAM
+    which is accessible only from the secure state.
+
+
+The sections below provide the following details:
+
+*   initialization and execution of the first three stages during cold boot
+*   specification of the BL3-1 entrypoint requirements for use by alternative
+    Trusted Boot Firmware in place of the provided BL1 and BL2
+*   changes in BL3-1 behavior when using the `RESET_TO_BL31` option which
+    allows BL3-1 to run without BL1 and BL2
+
+
+### BL1
+
+This stage begins execution from the platform's reset vector at EL3. The reset
+address is platform dependent but it is usually located in a Trusted ROM area.
+The BL1 data section is copied to trusted SRAM at runtime.
+
+On the ARM FVP port, BL1 code starts execution from the reset vector at address
+`0x00000000` (trusted ROM). The BL1 data section is copied to the start of
+trusted SRAM at address `0x04000000`.
+
+On the Juno ARM development platform port, BL1 code starts execution at
+`0x0BEC0000` (FLASH). The BL1 data section is copied to trusted SRAM at address
+`0x04001000.
+
+The functionality implemented by this stage is as follows.
+
+#### Determination of boot path
+
+Whenever a CPU is released from reset, BL1 needs to distinguish between a warm
+boot and a cold boot. This is done using platform-specific mechanisms (see the
+`platform_get_entrypoint()` function in the [Porting Guide]). In the case of a
+warm boot, a CPU is expected to continue execution from a seperate
+entrypoint. In the case of a cold boot, the secondary CPUs are placed in a safe
+platform-specific state (see the `plat_secondary_cold_boot_setup()` function in
+the [Porting Guide]) while the primary CPU executes the remaining cold boot path
+as described in the following sections.
+
+#### Architectural initialization
+
+BL1 performs minimal architectural initialization as follows.
+
+*   Exception vectors
+
+    BL1 sets up simple exception vectors for both synchronous and asynchronous
+    exceptions. The default behavior upon receiving an exception is to populate
+    a status code in the general purpose register `X0` and call the
+    `plat_report_exception()` function (see the [Porting Guide]). The status
+    code is one of:
+
+        0x0 : Synchronous exception from Current EL with SP_EL0
+        0x1 : IRQ exception from Current EL with SP_EL0
+        0x2 : FIQ exception from Current EL with SP_EL0
+        0x3 : System Error exception from Current EL with SP_EL0
+        0x4 : Synchronous exception from Current EL with SP_ELx
+        0x5 : IRQ exception from Current EL with SP_ELx
+        0x6 : FIQ exception from Current EL with SP_ELx
+        0x7 : System Error exception from Current EL with SP_ELx
+        0x8 : Synchronous exception from Lower EL using aarch64
+        0x9 : IRQ exception from Lower EL using aarch64
+        0xa : FIQ exception from Lower EL using aarch64
+        0xb : System Error exception from Lower EL using aarch64
+        0xc : Synchronous exception from Lower EL using aarch32
+        0xd : IRQ exception from Lower EL using aarch32
+        0xe : FIQ exception from Lower EL using aarch32
+        0xf : System Error exception from Lower EL using aarch32
+
+    The `plat_report_exception()` implementation on the ARM FVP port programs
+    the Versatile Express System LED register in the following format to
+    indicate the occurence of an unexpected exception:
+
+        SYS_LED[0]   - Security state (Secure=0/Non-Secure=1)
+        SYS_LED[2:1] - Exception Level (EL3=0x3, EL2=0x2, EL1=0x1, EL0=0x0)
+        SYS_LED[7:3] - Exception Class (Sync/Async & origin). This is the value
+                       of the status code
+
+    A write to the LED register reflects in the System LEDs (S6LED0..7) in the
+    CLCD window of the FVP.
+
+    BL1 does not expect to receive any exceptions other than the SMC exception.
+    For the latter, BL1 installs a simple stub. The stub expects to receive
+    only a single type of SMC (determined by its function ID in the general
+    purpose register `X0`). This SMC is raised by BL2 to make BL1 pass control
+    to BL3-1 (loaded by BL2) at EL3. Any other SMC leads to an assertion
+    failure.
+
+*   CPU initialization
+
+    BL1 calls the `reset_handler()` function which in turn calls the CPU
+    specific reset handler function (see the section: "CPU specific operations
+    framework").
+
+*   MMU setup
+
+    BL1 sets up EL3 memory translation by creating page tables to cover the
+    first 4GB of physical address space. This covers all the memories and
+    peripherals needed by BL1.
+
+*   Control register setup
+    -   `SCTLR_EL3`. Instruction cache is enabled by setting the `SCTLR_EL3.I`
+        bit. Alignment and stack alignment checking is enabled by setting the
+        `SCTLR_EL3.A` and `SCTLR_EL3.SA` bits. Exception endianness is set to
+        little-endian by clearing the `SCTLR_EL3.EE` bit.
+
+    -  `SCR_EL3`. The register width of the next lower exception level is set to
+        AArch64 by setting the `SCR.RW` bit.
+
+    -   `CPTR_EL3`. Accesses to the `CPACR_EL1` register from EL1 or EL2, or the
+        `CPTR_EL2` register from EL2 are configured to not trap to EL3 by
+        clearing the `CPTR_EL3.TCPAC` bit. Access to the trace functionality is
+        configured not to trap to EL3 by clearing the `CPTR_EL3.TTA` bit.
+        Instructions that access the registers associated with Floating Point
+        and Advanced SIMD execution are configured to not trap to EL3 by
+        clearing the `CPTR_EL3.TFP` bit.
+
+#### Platform initialization
+
+BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests from
+the CCI-400 slave interface corresponding to the cluster that includes the
+primary CPU. BL1 also initializes UART0 (PL011 console), which enables access to
+the `printf` family of functions in BL1.
+
+#### BL2 image load and execution
+
+BL1 execution continues as follows:
+
+1.  BL1 determines the amount of free trusted SRAM memory available by
+    calculating the extent of its own data section, which also resides in
+    trusted SRAM. BL1 loads a BL2 raw binary image from platform storage, at a
+    platform-specific base address. If the BL2 image file is not present or if
+    there is not enough free trusted SRAM the following error message is
+    printed:
+
+        "Failed to load boot loader stage 2 (BL2) firmware."
+
+    If the load is successful, BL1 updates the limits of the remaining free
+    trusted SRAM. It also populates information about the amount of trusted
+    SRAM used by the BL2 image. The exact load location of the image is
+    provided as a base address in the platform header. Further description of
+    the memory layout can be found later in this document.
+
+2.  BL1 prints the following string from the primary CPU to indicate successful
+    execution of the BL1 stage:
+
+        "Booting trusted firmware boot loader stage 1"
+
+3.  BL1 passes control to the BL2 image at Secure EL1, starting from its load
+    address.
+
+4.  BL1 also passes information about the amount of trusted SRAM used and
+    available for use. This information is populated at a platform-specific
+    memory address.
+
+
+### BL2
+
+BL1 loads and passes control to BL2 at Secure-EL1. BL2 is linked against and
+loaded at a platform-specific base address (more information can be found later
+in this document). The functionality implemented by BL2 is as follows.
+
+#### Architectural initialization
+
+BL2 performs minimal architectural initialization required for subsequent
+stages of the ARM Trusted Firmware and normal world software. It sets up
+Secure EL1 memory translation by creating page tables to address the first 4GB
+of the physical address space in a similar way to BL1. EL1 and EL0 are given
+access to Floating Point & Advanced SIMD registers by clearing the `CPACR.FPEN`
+bits.
+
+#### Platform initialization
+
+BL2 copies the information regarding the trusted SRAM populated by BL1 using a
+platform-specific mechanism. It calculates the limits of DRAM (main memory)
+to determine whether there is enough space to load the BL3-3 image. A platform
+defined base address is used to specify the load address for the BL3-1 image.
+It also defines the extents of memory available for use by the BL3-2 image.
+BL2 also initializes UART0 (PL011 console), which enables  access to the
+`printf` family of functions in BL2. Platform security is initialized to allow
+access to controlled components. The storage abstraction layer is initialized
+which is used to load further bootloader images.
+
+#### BL3-0 (System Control Processor Firmware) image load
+
+Some systems have a separate System Control Processor (SCP) for power, clock,
+reset and system control. BL2 loads the optional BL3-0 image from platform
+storage into a platform-specific region of secure memory. The subsequent
+handling of BL3-0 is platform specific. For example, on the Juno ARM development
+platform port the image is transferred into SCP memory using the SCPI protocol
+after being loaded in the trusted SRAM memory at address `0x04009000`. The SCP
+executes BL3-0 and signals to the Application Processor (AP) for BL2 execution
+to continue.
+
+#### BL3-1 (EL3 Runtime Firmware) image load
+
+BL2 loads the BL3-1 image from platform storage into a platform-specific address
+in trusted SRAM. If there is not enough memory to load the image or image is
+missing it leads to an assertion failure. If the BL3-1 image loads successfully,
+BL2 updates the amount of trusted SRAM used and available for use by BL3-1.
+This information is populated at a platform-specific memory address.
+
+#### BL3-2 (Secure-EL1 Payload) image load
+
+BL2 loads the optional BL3-2 image from platform storage into a platform-
+specific region of secure memory. The image executes in the secure world. BL2
+relies on BL3-1 to pass control to the BL3-2 image, if present. Hence, BL2
+populates a platform-specific area of memory with the entrypoint/load-address
+of the BL3-2 image. The value of the Saved Processor Status Register (`SPSR`)
+for entry into BL3-2 is not determined by BL2, it is initialized by the
+Secure-EL1 Payload Dispatcher (see later) within BL3-1, which is responsible for
+managing interaction with BL3-2. This information is passed to BL3-1.
+
+#### BL3-3 (Non-trusted Firmware) image load
+
+BL2 loads the BL3-3 image (e.g. UEFI or other test or boot software) from
+platform storage into non-secure memory as defined by the platform.
+
+BL2 relies on BL3-1 to pass control to BL3-3 once secure state initialization is
+complete. Hence, BL2 populates a platform-specific area of memory with the
+entrypoint and Saved Program Status Register (`SPSR`) of the normal world
+software image. The entrypoint is the load address of the BL3-3 image. The
+`SPSR` is determined as specified in Section 5.13 of the [PSCI PDD] [PSCI]. This
+information is passed to BL3-1.
+
+#### BL3-1 (EL3 Runtime Firmware) execution
+
+BL2 execution continues as follows:
+
+1.  BL2 passes control back to BL1 by raising an SMC, providing BL1 with the
+    BL3-1 entrypoint. The exception is handled by the SMC exception handler
+    installed by BL1.
+
+2.  BL1 turns off the MMU and flushes the caches. It clears the
+    `SCTLR_EL3.M/I/C` bits, flushes the data cache to the point of coherency
+    and invalidates the TLBs.
+
+3.  BL1 passes control to BL3-1 at the specified entrypoint at EL3.
+
+
+### BL3-1
+
+The image for this stage is loaded by BL2 and BL1 passes control to BL3-1 at
+EL3. BL3-1 executes solely in trusted SRAM. BL3-1 is linked against and
+loaded at a platform-specific base address (more information can be found later
+in this document). The functionality implemented by BL3-1 is as follows.
+
+#### Architectural initialization
+
+Currently, BL3-1 performs a similar architectural initialization to BL1 as
+far as system register settings are concerned. Since BL1 code resides in ROM,
+architectural initialization in BL3-1 allows override of any previous
+initialization done by BL1. BL3-1 creates page tables to address the first
+4GB of physical address space and initializes the MMU accordingly. It initializes
+a buffer of frequently used pointers, called per-CPU pointer cache, in memory for
+faster access. Currently the per-CPU pointer cache contains only the pointer
+to crash stack. It then replaces the exception vectors populated by BL1 with its
+own. BL3-1 exception vectors implement more elaborate support for
+handling SMCs since this is the only mechanism to access the runtime services
+implemented by BL3-1 (PSCI for example). BL3-1 checks each SMC for validity as
+specified by the [SMC calling convention PDD][SMCCC] before passing control to
+the required SMC handler routine. BL3-1 programs the `CNTFRQ_EL0` register with
+the clock frequency of the system counter, which is provided by the platform.
+
+#### Platform initialization
+
+BL3-1 performs detailed platform initialization, which enables normal world
+software to function correctly. It also retrieves entrypoint information for
+the BL3-3 image loaded by BL2 from the platform defined memory address populated
+by BL2. BL3-1 also initializes UART0 (PL011 console), which enables
+access to the `printf` family of functions in BL3-1.  It enables the system
+level implementation of the generic timer through the memory mapped interface.
+
+* GICv2 initialization:
+
+    -   Enable group0 interrupts in the GIC CPU interface.
+    -   Configure group0 interrupts to be asserted as FIQs.
+    -   Disable the legacy interrupt bypass mechanism.
+    -   Configure the priority mask register to allow interrupts of all
+        priorities to be signaled to the CPU interface.
+    -   Mark SGIs 8-15, the secure physical timer interrupt (#29) and the
+        trusted watchdog interrupt (#56) as group0 (secure).
+    -   Target the trusted watchdog interrupt to CPU0.
+    -   Enable these group0 interrupts in the GIC distributor.
+    -   Configure all other interrupts as group1 (non-secure).
+    -   Enable signaling of group0 interrupts in the GIC distributor.
+
+*   GICv3 initialization:
+
+    If a GICv3 implementation is available in the platform, BL3-1 initializes
+    the GICv3 in GICv2 emulation mode with settings as described for GICv2
+    above.
+
+*   Power management initialization:
+
+    BL3-1 implements a state machine to track CPU and cluster state. The state
+    can be one of `OFF`, `ON_PENDING`, `SUSPEND` or `ON`. All secondary CPUs are
+    initially in the `OFF` state. The cluster that the primary CPU belongs to is
+    `ON`; any other cluster is `OFF`. BL3-1 initializes the data structures that
+    implement the state machine, including the locks that protect them. BL3-1
+    accesses the state of a CPU or cluster immediately after reset and before
+    the data cache is enabled in the warm boot path. It is not currently
+    possible to use 'exclusive' based spinlocks, therefore BL3-1 uses locks
+    based on Lamport's Bakery algorithm instead. BL3-1 allocates these locks in
+    device memory by default.
+
+*   Runtime services initialization:
+
+    The runtime service framework and its initialization is described in the
+    "EL3 runtime services framework" section below.
+
+    Details about the PSCI service are provided in the "Power State Coordination
+    Interface" section below.
+
+*   BL3-2 (Secure-EL1 Payload) image initialization
+
+    If a BL3-2 image is present then there must be a matching Secure-EL1 Payload
+    Dispatcher (SPD) service (see later for details). During initialization
+    that service  must register a function to carry out initialization of BL3-2
+    once the runtime services are fully initialized. BL3-1 invokes such a
+    registered function to initialize BL3-2 before running BL3-3.
+
+    Details on BL3-2 initialization and the SPD's role are described in the
+    "Secure-EL1 Payloads and Dispatchers" section below.
+
+*   BL3-3 (Non-trusted Firmware) execution
+
+    BL3-1 initializes the EL2 or EL1 processor context for normal-world cold
+    boot, ensuring that no secure state information finds its way into the
+    non-secure execution state. BL3-1 uses the entrypoint information provided
+    by BL2 to jump to the Non-trusted firmware image (BL3-3) at the highest
+    available Exception Level (EL2 if available, otherwise EL1).
+
+
+### Using alternative Trusted Boot Firmware in place of BL1 and BL2
+
+Some platforms have existing implementations of Trusted Boot Firmware that
+would like to use ARM Trusted Firmware BL3-1 for the EL3 Runtime Firmware. To
+enable this firmware architecture it is important to provide a fully documented
+and stable interface between the Trusted Boot Firmware and BL3-1.
+
+Future changes to the BL3-1 interface will be done in a backwards compatible
+way, and this enables these firmware components to be independently enhanced/
+updated to develop and exploit new functionality.
+
+#### Required CPU state when calling `bl31_entrypoint()` during cold boot
+
+This function must only be called by the primary CPU, if this is called by any
+other CPU the firmware will abort.
+
+On entry to this function the calling primary CPU must be executing in AArch64
+EL3, little-endian data access, and all interrupt sources masked:
+
+    PSTATE.EL = 3
+    PSTATE.RW = 1
+    PSTATE.DAIF = 0xf
+    SCTLR_EL3.EE = 0
+
+X0 and X1 can be used to pass information from the Trusted Boot Firmware to the
+platform code in BL3-1:
+
+    X0 : Reserved for common Trusted Firmware information
+    X1 : Platform specific information
+
+BL3-1 zero-init sections (e.g. `.bss`) should not contain valid data on entry,
+these will be zero filled prior to invoking platform setup code.
+
+##### Use of the X0 and X1 parameters
+
+The parameters are platform specific and passed from `bl31_entrypoint()` to
+`bl31_early_platform_setup()`. The value of these parameters is never directly
+used by the common BL3-1 code.
+
+The convention is that `X0` conveys information regarding the BL3-1, BL3-2 and
+BL3-3 images from the Trusted Boot firmware and `X1` can be used for other
+platform specific purpose. This convention allows platforms which use ARM
+Trusted Firmware's BL1 and BL2 images to transfer additional platform specific
+information from Secure Boot without conflicting with future evolution of the
+Trusted Firmware using `X0` to pass a `bl31_params` structure.
+
+BL3-1 common and SPD initialization code depends on image and entrypoint
+information about BL3-3 and BL3-2, which is provided via BL3-1 platform APIs.
+This information is required until the start of execution of BL3-3. This
+information can be provided in a platform defined manner, e.g. compiled into
+the platform code in BL3-1, or provided in a platform defined memory location
+by the Trusted Boot firmware, or passed from the Trusted Boot Firmware via the
+Cold boot Initialization parameters. This data may need to be cleaned out of
+the CPU caches if it is provided by an earlier boot stage and then accessed by
+BL3-1 platform code before the caches are enabled.
+
+ARM Trusted Firmware's BL2 implementation passes a `bl31_params` structure in
+`X0` and the FVP port interprets this in the BL3-1 platform code.
+
+##### MMU, Data caches & Coherency
+
+BL3-1 does not depend on the enabled state of the MMU, data caches or
+interconnect coherency on entry to `bl31_entrypoint()`. If these are disabled
+on entry, these should be enabled during `bl31_plat_arch_setup()`.
+
+##### Data structures used in the BL3-1 cold boot interface
+
+These structures are designed to support compatibility and independent
+evolution of the structures and the firmware images. For example, a version of
+BL3-1 that can interpret the BL3-x image information from different versions of
+BL2, a platform that uses an extended entry_point_info structure to convey
+additional register information to BL3-1, or a ELF image loader that can convey
+more details about the firmware images.
+
+To support these scenarios the structures are versioned and sized, which enables
+BL3-1 to detect which information is present and respond appropriately. The
+`param_header` is defined to capture this information:
+
+    typedef struct param_header {
+        uint8_t type;       /* type of the structure */
+        uint8_t version;    /* version of this structure */
+        uint16_t size;      /* size of this structure in bytes */
+        uint32_t attr;      /* attributes: unused bits SBZ */
+    } param_header_t;
+
+The structures using this format are `entry_point_info`, `image_info` and
+`bl31_params`. The code that allocates and populates these structures must set
+the header fields appropriately, and the `SET_PARA_HEAD()` a macro is defined
+to simplify this action.
+
+#### Required CPU state for BL3-1 Warm boot initialization
+
+When requesting a CPU power-on, or suspending a running CPU, ARM Trusted
+Firmware provides the platform power management code with a Warm boot
+initialization entry-point, to be invoked by the CPU immediately after the
+reset handler. On entry to the Warm boot initialization function the calling
+CPU must be in AArch64 EL3, little-endian data access and all interrupt sources
+masked:
+
+    PSTATE.EL = 3
+    PSTATE.RW = 1
+    PSTATE.DAIF = 0xf
+    SCTLR_EL3.EE = 0
+
+The PSCI implementation will initialize the processor state and ensure that the
+platform power management code is then invoked as required to initialize all
+necessary system, cluster and CPU resources.
+
+
+### Using BL3-1 as the CPU reset vector
+
+On some platforms the runtime firmware (BL3-x images) for the application
+processors are loaded by trusted firmware running on a secure system processor
+on the SoC, rather than by BL1 and BL2 running on the primary application
+processor. For this type of SoC it is desirable for the application processor
+to always reset to BL3-1 which eliminates the need for BL1 and BL2.
+
+ARM Trusted Firmware provides a build-time option `RESET_TO_BL31` that includes
+some additional logic in the BL3-1 entrypoint to support this use case.
+
+In this configuration, the platform's Trusted Boot Firmware must ensure that
+BL3-1 is loaded to its runtime address, which must match the CPU's RVBAR reset
+vector address, before the application processor is powered on. Additionally,
+platform software is responsible for loading the other BL3-x images required and
+providing entry point information for them to BL3-1. Loading these images might
+be done by the Trusted Boot Firmware or by platform code in BL3-1.
+
+The ARM FVP port supports the `RESET_TO_BL31` configuration, in which case the
+`bl31.bin` image must be loaded to its run address in Trusted SRAM and all CPU
+reset vectors be changed from the default `0x0` to this run address. See the
+[User Guide] for details of running the FVP models in this way.
+
+This configuration requires some additions and changes in the BL3-1
+functionality:
+
+#### Determination of boot path
+
+In this configuration, BL3-1 uses the same reset framework and code as the one
+described for BL1 above. On a warm boot a CPU is directed to the PSCI
+implementation via a platform defined mechanism. On a cold boot, the platform
+must place any secondary CPUs into a safe state while the primary CPU executes
+a modified BL3-1 initialization, as described below.
+
+#### Architectural initialization
+
+As the first image to execute in this configuration BL3-1 must ensure that
+interconnect coherency is enabled (if required) before enabling the MMU.
+
+#### Platform initialization
+
+In this configuration, when the CPU resets to BL3-1 there are no parameters
+that can be passed in registers by previous boot stages. Instead, the platform
+code in BL3-1 needs to know, or be able to determine, the location of the BL3-2
+(if required) and BL3-3 images and provide this information in response to the
+`bl31_plat_get_next_image_ep_info()` function.
+
+As the first image to execute in this configuration BL3-1 must also ensure that
+any security initialisation, for example programming a TrustZone address space
+controller, is carried out during early platform initialisation.
+
+
+3.  EL3 runtime services framework
+----------------------------------
+
+Software executing in the non-secure state and in the secure state at exception
+levels lower than EL3 will request runtime services using the Secure Monitor
+Call (SMC) instruction. These requests will follow the convention described in
+the SMC Calling Convention PDD ([SMCCC]). The [SMCCC] assigns function
+identifiers to each SMC request and describes how arguments are passed and
+returned.
+
+The EL3 runtime services framework enables the development of services by
+different providers that can be easily integrated into final product firmware.
+The following sections describe the framework which facilitates the
+registration, initialization and use of runtime services in EL3 Runtime
+Firmware (BL3-1).
+
+The design of the runtime services depends heavily on the concepts and
+definitions described in the [SMCCC], in particular SMC Function IDs, Owning
+Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and SMC64 calling
+conventions. Please refer to that document for more detailed explanation of
+these terms.
+
+The following runtime services are expected to be implemented first. They have
+not all been instantiated in the current implementation.
+
+1.  Standard service calls
+
+    This service is for management of the entire system. The Power State
+    Coordination Interface ([PSCI]) is the first set of standard service calls
+    defined by ARM (see PSCI section later).
+
+    NOTE: Currently this service is called PSCI since there are no other
+    defined standard service calls.
+
+2.  Secure-EL1 Payload Dispatcher service
+
+    If a system runs a Trusted OS or other Secure-EL1 Payload (SP) then
+    it also requires a _Secure Monitor_ at EL3 to switch the EL1 processor
+    context between the normal world (EL1/EL2) and trusted world (Secure-EL1).
+    The Secure Monitor will make these world switches in response to SMCs. The
+    [SMCCC] provides for such SMCs with the Trusted OS Call and Trusted
+    Application Call OEN ranges.
+
+    The interface between the EL3 Runtime Firmware and the Secure-EL1 Payload is
+    not defined by the [SMCCC] or any other standard. As a result, each
+    Secure-EL1 Payload requires a specific Secure Monitor that runs as a runtime
+    service - within ARM Trusted Firmware this service is referred to as the
+    Secure-EL1 Payload Dispatcher (SPD).
+
+    ARM Trusted Firmware provides a Test Secure-EL1 Payload (TSP) and its
+    associated Dispatcher (TSPD). Details of SPD design and TSP/TSPD operation
+    are described in the "Secure-EL1 Payloads and Dispatchers" section below.
+
+3.  CPU implementation service
+
+    This service will provide an interface to CPU implementation specific
+    services for a given platform e.g. access to processor errata workarounds.
+    This service is currently unimplemented.
+
+Additional services for ARM Architecture, SiP and OEM calls can be implemented.
+Each implemented service handles a range of SMC function identifiers as
+described in the [SMCCC].
+
+
+### Registration
+
+A runtime service is registered using the `DECLARE_RT_SVC()` macro, specifying
+the name of the service, the range of OENs covered, the type of service and
+initialization and call handler functions. This macro instantiates a `const
+struct rt_svc_desc` for the service with these details (see `runtime_svc.h`).
+This structure is allocated in a special ELF section `rt_svc_descs`, enabling
+the framework to find all service descriptors included into BL3-1.
+
+The specific service for a SMC Function is selected based on the OEN and call
+type of the Function ID, and the framework uses that information in the service
+descriptor to identify the handler for the SMC Call.
+
+The service descriptors do not include information to identify the precise set
+of SMC function identifiers supported by this service implementation, the
+security state from which such calls are valid nor the capability to support
+64-bit and/or 32-bit callers (using SMC32 or SMC64). Responding appropriately
+to these aspects of a SMC call is the responsibility of the service
+implementation, the framework is focused on integration of services from
+different providers and minimizing the time taken by the framework before the
+service handler is invoked.
+
+Details of the parameters, requirements and behavior of the initialization and
+call handling functions are provided in the following sections.
+
+
+### Initialization
+
+`runtime_svc_init()` in `runtime_svc.c` initializes the runtime services
+framework running on the primary CPU during cold boot as part of the BL3-1
+initialization. This happens prior to initializing a Trusted OS and running
+Normal world boot firmware that might in turn use these services.
+Initialization involves validating each of the declared runtime service
+descriptors, calling the service initialization function and populating the
+index used for runtime lookup of the service.
+
+The BL3-1 linker script collects all of the declared service descriptors into a
+single array and defines symbols that allow the framework to locate and traverse
+the array, and determine its size.
+
+The framework does basic validation of each descriptor to halt firmware
+initialization if service declaration errors are detected. The framework does
+not check descriptors for the following error conditions, and may behave in an
+unpredictable manner under such scenarios:
+
+1.  Overlapping OEN ranges
+2.  Multiple descriptors for the same range of OENs and `call_type`
+3.  Incorrect range of owning entity numbers for a given `call_type`
+
+Once validated, the service `init()` callback is invoked. This function carries
+out any essential EL3 initialization before servicing requests. The `init()`
+function is only invoked on the primary CPU during cold boot. If the service
+uses per-CPU data this must either be initialized for all CPUs during this call,
+or be done lazily when a CPU first issues an SMC call to that service. If
+`init()` returns anything other than `0`, this is treated as an initialization
+error and the service is ignored: this does not cause the firmware to halt.
+
+The OEN and call type fields present in the SMC Function ID cover a total of
+128 distinct services, but in practice a single descriptor can cover a range of
+OENs, e.g. SMCs to call a Trusted OS function. To optimize the lookup of a
+service handler, the framework uses an array of 128 indices that map every
+distinct OEN/call-type combination either to one of the declared services or to
+indicate the service is not handled. This `rt_svc_descs_indices[]` array is
+populated for all of the OENs covered by a service after the service `init()`
+function has reported success. So a service that fails to initialize will never
+have it's `handle()` function invoked.
+
+The following figure shows how the `rt_svc_descs_indices[]` index maps the SMC
+Function ID call type and OEN onto a specific service handler in the
+`rt_svc_descs[]` array.
+
+![Image 1](diagrams/rt-svc-descs-layout.png?raw=true)
+
+
+### Handling an SMC
+
+When the EL3 runtime services framework receives a Secure Monitor Call, the SMC
+Function ID is passed in W0 from the lower exception level (as per the
+[SMCCC]). If the calling register width is AArch32, it is invalid to invoke an
+SMC Function which indicates the SMC64 calling convention: such calls are
+ignored and return the Unknown SMC Function Identifier result code `0xFFFFFFFF`
+in R0/X0.
+
+Bit[31] (fast/standard call) and bits[29:24] (owning entity number) of the SMC
+Function ID are combined to index into the `rt_svc_descs_indices[]` array. The
+resulting value might indicate a service that has no handler, in this case the
+framework will also report an Unknown SMC Function ID. Otherwise, the value is
+used as a further index into the `rt_svc_descs[]` array to locate the required
+service and handler.
+
+The service's `handle()` callback is provided with five of the SMC parameters
+directly, the others are saved into memory for retrieval (if needed) by the
+handler. The handler is also provided with an opaque `handle` for use with the
+supporting library for parameter retrieval, setting return values and context
+manipulation; and with `flags` indicating the security state of the caller. The
+framework finally sets up the execution stack for the handler, and invokes the
+services `handle()` function.
+
+On return from the handler the result registers are populated in X0-X3 before
+restoring the stack and CPU state and returning from the original SMC.
+
+
+4.  Power State Coordination Interface
+--------------------------------------
+
+TODO: Provide design walkthrough of PSCI implementation.
+
+The PSCI v1.0 specification categorizes APIs as optional and mandatory. All the
+mandatory APIs in PSCI v1.0 and all the APIs in PSCI v0.2 draft specification
+[Power State Coordination Interface PDD] [PSCI] are implemented. The table lists
+the PSCI v1.0 APIs and their support in generic code.
+
+An API implementation might have a dependency on platform code e.g. CPU_SUSPEND
+requires the platform to export a part of the implementation. Hence the level
+of support of the mandatory APIs depends upon the support exported by the
+platform port as well. The Juno and FVP (all variants) platforms export all the
+required support.
+
+| PSCI v1.0 API         |Supported| Comments                                  |
+|:----------------------|:--------|:------------------------------------------|
+|`PSCI_VERSION`         | Yes     | The version returned is 1.0               |
+|`CPU_SUSPEND`          | Yes*    | The original `power_state` format is used |
+|`CPU_OFF`              | Yes*    |                                           |
+|`CPU_ON`               | Yes*    |                                           |
+|`AFFINITY_INFO`        | Yes     |                                           |
+|`MIGRATE`              | Yes**   |                                           |
+|`MIGRATE_INFO_TYPE`    | Yes**   |                                           |
+|`MIGRATE_INFO_CPU`     | Yes**   |                                           |
+|`SYSTEM_OFF`           | Yes*    |                                           |
+|`SYSTEM_RESET`         | Yes*    |                                           |
+|`PSCI_FEATURES`        | Yes     |                                           |
+|`CPU_FREEZE`           | No      |                                           |
+|`CPU_DEFAULT_SUSPEND`  | No      |                                           |
+|`CPU_HW_STATE`         | No      |                                           |
+|`SYSTEM_SUSPEND`       | Yes*    |                                           |
+|`PSCI_SET_SUSPEND_MODE`| No      |                                           |
+|`PSCI_STAT_RESIDENCY`  | No      |                                           |
+|`PSCI_STAT_COUNT`      | No      |                                           |
+
+*Note : These PSCI APIs require platform power management hooks to be
+registered with the generic PSCI code to be supported.
+
+**Note : These PSCI APIs require appropriate Secure Payload Dispatcher
+hooks to be registered with the generic PSCI code to be supported.
+
+
+5.  Secure-EL1 Payloads and Dispatchers
+---------------------------------------
+
+On a production system that includes a Trusted OS running in Secure-EL1/EL0,
+the Trusted OS is coupled with a companion runtime service in the BL3-1
+firmware. This service is responsible for the initialisation of the Trusted
+OS and all communications with it. The Trusted OS is the BL3-2 stage of the
+boot flow in ARM Trusted Firmware. The firmware will attempt to locate, load
+and execute a BL3-2 image.
+
+ARM Trusted Firmware uses a more general term for the BL3-2 software that runs
+at Secure-EL1 - the _Secure-EL1 Payload_ - as it is not always a Trusted OS.
+
+The ARM Trusted Firmware provides a Test Secure-EL1 Payload (TSP) and a Test
+Secure-EL1 Payload Dispatcher (TSPD) service as an example of how a Trusted OS
+is supported on a production system using the Runtime Services Framework. On
+such a system, the Test BL3-2 image and service are replaced by the Trusted OS
+and its dispatcher service. The ARM Trusted Firmware build system expects that
+the dispatcher will define the build flag `NEED_BL32` to enable it to include
+the BL3-2 in the build either as a binary or to compile from source depending
+on whether the `BL32` build option is specified or not.
+
+The TSP runs in Secure-EL1. It is designed to demonstrate synchronous
+communication with the normal-world software running in EL1/EL2. Communication
+is initiated by the normal-world software
+
+*   either directly through a Fast SMC (as defined in the [SMCCC])
+
+*   or indirectly through a [PSCI] SMC. The [PSCI] implementation in turn
+    informs the TSPD about the requested power management operation. This allows
+    the TSP to prepare for or respond to the power state change
+
+The TSPD service is responsible for.
+
+*   Initializing the TSP
+
+*   Routing requests and responses between the secure and the non-secure
+    states during the two types of communications just described
+
+### Initializing a BL3-2 Image
+
+The Secure-EL1 Payload Dispatcher (SPD) service is responsible for initializing
+the BL3-2 image. It needs access to the information passed by BL2 to BL3-1 to do
+so. This is provided by:
+
+    entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t);
+
+which returns a reference to the `entry_point_info` structure corresponding to
+the image which will be run in the specified security state. The SPD uses this
+API to get entry point information for the SECURE image, BL3-2.
+
+In the absence of a BL3-2 image, BL3-1 passes control to the normal world
+bootloader image (BL3-3). When the BL3-2 image is present, it is typical
+that the SPD wants control to be passed to BL3-2 first and then later to BL3-3.
+
+To do this the SPD has to register a BL3-2 initialization function during
+initialization of the SPD service. The BL3-2 initialization function has this
+prototype:
+
+    int32_t init();
+
+and is registered using the `bl31_register_bl32_init()` function.
+
+Trusted Firmware supports two approaches for the SPD to pass control to BL3-2
+before returning through EL3 and running the non-trusted firmware (BL3-3):
+
+1.  In the BL3-2 setup function, use `bl31_set_next_image_type()` to
+    request that the exit from `bl31_main()` is to the BL3-2 entrypoint in
+    Secure-EL1. BL3-1 will exit to BL3-2 using the asynchronous method by
+    calling bl31_prepare_next_image_entry() and el3_exit().
+
+    When the BL3-2 has completed initialization at Secure-EL1, it returns to
+    BL3-1 by issuing an SMC, using a Function ID allocated to the SPD. On
+    receipt of this SMC, the SPD service handler should switch the CPU context
+    from trusted to normal world and use the `bl31_set_next_image_type()` and
+    `bl31_prepare_next_image_entry()` functions to set up the initial return to
+    the normal world firmware BL3-3. On return from the handler the framework
+    will exit to EL2 and run BL3-3.
+
+2.  The BL3-2 setup function registers a initialization function using
+    `bl31_register_bl32_init()` which provides a SPD-defined mechanism to
+    invoke a 'world-switch synchronous call' to Secure-EL1 to run the BL3-2
+    entrypoint.
+    NOTE: The Test SPD service included with the Trusted Firmware provides one
+    implementation of such a mechanism.
+
+    On completion BL3-2 returns control to BL3-1 via a SMC, and on receipt the
+    SPD service handler invokes the synchronous call return mechanism to return
+    to the BL3-2 initialization function. On return from this function,
+    `bl31_main()` will set up the return to the normal world firmware BL3-3 and
+    continue the boot process in the normal world.
+
+
+6.  Crash Reporting in BL3-1
+----------------------------
+
+The BL3-1 implements a scheme for reporting the processor state when an unhandled
+exception is encountered. The reporting mechanism attempts to preserve all the
+register contents and report it via the default serial output. The general purpose
+registers, EL3, Secure EL1 and some EL2 state registers are reported.
+
+A dedicated per-CPU crash stack is maintained by BL3-1 and this is retrieved via
+the per-CPU pointer cache. The implementation attempts to minimise the memory
+required for this feature. The file `crash_reporting.S` contains the
+implementation for crash reporting.
+
+The sample crash output is shown below.
+
+    x0	:0x000000004F00007C
+    x1	:0x0000000007FFFFFF
+    x2	:0x0000000004014D50
+    x3	:0x0000000000000000
+    x4	:0x0000000088007998
+    x5	:0x00000000001343AC
+    x6	:0x0000000000000016
+    x7	:0x00000000000B8A38
+    x8	:0x00000000001343AC
+    x9	:0x00000000000101A8
+    x10	:0x0000000000000002
+    x11	:0x000000000000011C
+    x12	:0x00000000FEFDC644
+    x13	:0x00000000FED93FFC
+    x14	:0x0000000000247950
+    x15	:0x00000000000007A2
+    x16	:0x00000000000007A4
+    x17	:0x0000000000247950
+    x18	:0x0000000000000000
+    x19	:0x00000000FFFFFFFF
+    x20	:0x0000000004014D50
+    x21	:0x000000000400A38C
+    x22	:0x0000000000247950
+    x23	:0x0000000000000010
+    x24	:0x0000000000000024
+    x25	:0x00000000FEFDC868
+    x26	:0x00000000FEFDC86A
+    x27	:0x00000000019EDEDC
+    x28	:0x000000000A7CFDAA
+    x29	:0x0000000004010780
+    x30	:0x000000000400F004
+    scr_el3	:0x0000000000000D3D
+    sctlr_el3	:0x0000000000C8181F
+    cptr_el3	:0x0000000000000000
+    tcr_el3	:0x0000000080803520
+    daif	:0x00000000000003C0
+    mair_el3	:0x00000000000004FF
+    spsr_el3	:0x00000000800003CC
+    elr_el3	:0x000000000400C0CC
+    ttbr0_el3	:0x00000000040172A0
+    esr_el3	:0x0000000096000210
+    sp_el3	:0x0000000004014D50
+    far_el3	:0x000000004F00007C
+    spsr_el1	:0x0000000000000000
+    elr_el1	:0x0000000000000000
+    spsr_abt	:0x0000000000000000
+    spsr_und	:0x0000000000000000
+    spsr_irq	:0x0000000000000000
+    spsr_fiq	:0x0000000000000000
+    sctlr_el1	:0x0000000030C81807
+    actlr_el1	:0x0000000000000000
+    cpacr_el1	:0x0000000000300000
+    csselr_el1	:0x0000000000000002
+    sp_el1	:0x0000000004028800
+    esr_el1	:0x0000000000000000
+    ttbr0_el1	:0x000000000402C200
+    ttbr1_el1	:0x0000000000000000
+    mair_el1	:0x00000000000004FF
+    amair_el1	:0x0000000000000000
+    tcr_el1	:0x0000000000003520
+    tpidr_el1	:0x0000000000000000
+    tpidr_el0	:0x0000000000000000
+    tpidrro_el0	:0x0000000000000000
+    dacr32_el2	:0x0000000000000000
+    ifsr32_el2	:0x0000000000000000
+    par_el1	:0x0000000000000000
+    far_el1	:0x0000000000000000
+    afsr0_el1	:0x0000000000000000
+    afsr1_el1	:0x0000000000000000
+    contextidr_el1	:0x0000000000000000
+    vbar_el1	:0x0000000004027000
+    cntp_ctl_el0	:0x0000000000000000
+    cntp_cval_el0	:0x0000000000000000
+    cntv_ctl_el0	:0x0000000000000000
+    cntv_cval_el0	:0x0000000000000000
+    cntkctl_el1	:0x0000000000000000
+    fpexc32_el2	:0x0000000004000700
+    sp_el0	:0x0000000004010780
+
+7.  Guidelines for Reset Handlers
+---------------------------------
+
+Trusted Firmware implements a framework that allows CPU and platform ports to
+perform actions immediately after a CPU is released from reset in both the cold
+and warm boot paths. This is done by calling the `reset_handler()` function in
+both the BL1 and BL3-1 images. It in turn calls the platform and CPU specific
+reset handling functions.
+
+Details for implementing a CPU specific reset handler can be found in
+Section 8. Details for implementing a platform specific reset handler can be
+found in the [Porting Guide](see the `plat_reset_handler()` function).
+
+When adding functionality to a reset handler, the following points should be
+kept in mind.
+
+1.   The first reset handler in the system exists either in a ROM image
+     (e.g. BL1), or BL3-1 if `RESET_TO_BL31` is true. This may be detected at
+     compile time using the constant `FIRST_RESET_HANDLER_CALL`.
+
+2.   When considering ROM images, it's important to consider non TF-based ROMs
+     and ROMs based on previous versions of the TF code.
+
+3.   If the functionality should be applied to a ROM and there is no possibility
+     of a ROM being used that does not apply the functionality (or equivalent),
+     then the functionality should be applied within a `#if
+     FIRST_RESET_HANDLER_CALL` block.
+
+4.   If the functionality should execute in BL3-1 in order to override or
+     supplement a ROM version of the functionality, then the functionality
+     should be applied in the `#else` part of a `#if FIRST_RESET_HANDLER_CALL`
+     block.
+
+5.   If the functionality should be applied to a ROM but there is a possibility
+     of ROMs being used that do not apply the functionality, then the
+     functionality should be applied outside of a `FIRST_RESET_HANDLER_CALL`
+     block, so that BL3-1 has an opportunity to apply the functionality instead.
+     In this case, additional code may be needed to cope with different ROMs
+     that do or do not apply the functionality.
+
+
+8.  CPU specific operations framework
+-----------------------------
+
+Certain aspects of the ARMv8 architecture are implementation defined,
+that is, certain behaviours are not architecturally defined, but must be defined
+and documented by individual processor implementations. The ARM Trusted
+Firmware implements a framework which categorises the common implementation
+defined behaviours and allows a processor to export its implementation of that
+behaviour. The categories are:
+
+1.  Processor specific reset sequence.
+
+2.  Processor specific power down sequences.
+
+3.  Processor specific register dumping as a part of crash reporting.
+
+Each of the above categories fulfils a different requirement.
+
+1.  allows any processor specific initialization before the caches and MMU
+    are turned on, like implementation of errata workarounds, entry into
+    the intra-cluster coherency domain etc.
+
+2.  allows each processor to implement the power down sequence mandated in
+    its Technical Reference Manual (TRM).
+
+3.  allows a processor to provide additional information to the developer
+    in the event of a crash, for example Cortex-A53 has registers which
+    can expose the data cache contents.
+
+Please note that only 2. is mandated by the TRM.
+
+The CPU specific operations framework scales to accommodate a large number of
+different CPUs during power down and reset handling. The platform can specify
+any CPU optimization it wants to enable for each CPU. It can also specify
+the CPU errata workarounds to be applied for each CPU type during reset
+handling by defining CPU errata compile time macros. Details on these macros
+can be found in the [cpu-specific-build-macros.md][CPUBM] file.
+
+The CPU specific operations framework depends on the `cpu_ops` structure which
+needs to be exported for each type of CPU in the platform. It is defined in
+`include/lib/cpus/aarch64/cpu_macros.S` and has the following fields : `midr`,
+`reset_func()`, `core_pwr_dwn()`, `cluster_pwr_dwn()` and `cpu_reg_dump()`.
+
+The CPU specific files in `lib/cpus` export a `cpu_ops` data structure with
+suitable handlers for that CPU.  For example, `lib/cpus/cortex_a53.S` exports
+the `cpu_ops` for Cortex-A53 CPU. According to the platform configuration,
+these CPU specific files must must be included in the build by the platform
+makefile. The generic CPU specific operations framework code exists in
+`lib/cpus/aarch64/cpu_helpers.S`.
+
+### CPU specific Reset Handling
+
+After a reset, the state of the CPU when it calls generic reset handler is:
+MMU turned off, both instruction and data caches turned off and not part
+of any coherency domain.
+
+The BL entrypoint code first invokes the `plat_reset_handler()` to allow
+the platform to perform any system initialization required and any system
+errata workarounds that needs to be applied. The `get_cpu_ops_ptr()` reads
+the current CPU midr, finds the matching `cpu_ops` entry in the `cpu_ops`
+array and returns it. Note that only the part number and implementer fields
+in midr are used to find the matching `cpu_ops` entry. The `reset_func()` in
+the returned `cpu_ops` is then invoked which executes the required reset
+handling for that CPU and also any errata workarounds enabled by the platform.
+This function must preserve the values of general purpose registers x20 to x29.
+
+Refer to Section "Guidelines for Reset Handlers" for general guidelines
+regarding placement of code in a reset handler.
+
+### CPU specific power down sequence
+
+During the BL3-1 initialization sequence, the pointer to the matching `cpu_ops`
+entry is stored in per-CPU data by `init_cpu_ops()` so that it can be quickly
+retrieved during power down sequences.
+
+The PSCI service, upon receiving a power down request, determines the highest
+affinity level at which to execute power down sequence for a particular CPU and
+invokes the corresponding 'prepare' power down handler in the CPU specific
+operations framework. For example, when a CPU executes a power down for affinity
+level 0, the `prepare_core_pwr_dwn()` retrieves the `cpu_ops` pointer from the
+per-CPU data and the corresponding `core_pwr_dwn()` is invoked. Similarly when
+a CPU executes power down at affinity level 1, the `prepare_cluster_pwr_dwn()`
+retrieves the `cpu_ops` pointer and the corresponding `cluster_pwr_dwn()` is
+invoked.
+
+At runtime the platform hooks for power down are invoked by the PSCI service to
+perform platform specific operations during a power down sequence, for example
+turning off CCI coherency during a cluster power down.
+
+### CPU specific register reporting during crash
+
+If the crash reporting is enabled in BL3-1, when a crash occurs, the crash
+reporting framework calls `do_cpu_reg_dump` which retrieves the matching
+`cpu_ops` using `get_cpu_ops_ptr()` function. The `cpu_reg_dump()` in
+`cpu_ops` is invoked, which then returns the CPU specific register values to
+be reported and a pointer to the ASCII list of register names in a format
+expected by the crash reporting framework.
+
+
+9. Memory layout of BL images
+-----------------------------
+
+Each bootloader image can be divided in 2 parts:
+
+ *    the static contents of the image. These are data actually stored in the
+      binary on the disk. In the ELF terminology, they are called `PROGBITS`
+      sections;
+
+ *    the run-time contents of the image. These are data that don't occupy any
+      space in the binary on the disk. The ELF binary just contains some
+      metadata indicating where these data will be stored at run-time and the
+      corresponding sections need to be allocated and initialized at run-time.
+      In the ELF terminology, they are called `NOBITS` sections.
+
+All PROGBITS sections are grouped together at the beginning of the image,
+followed by all NOBITS sections. This is true for all Trusted Firmware images
+and it is governed by the linker scripts. This ensures that the raw binary
+images are as small as possible. If a NOBITS section would sneak in between
+PROGBITS sections then the resulting binary file would contain a bunch of zero
+bytes at the location of this NOBITS section, making the image unnecessarily
+bigger. Smaller images allow faster loading from the FIP to the main memory.
+
+### Linker scripts and symbols
+
+Each bootloader stage image layout is described by its own linker script. The
+linker scripts export some symbols into the program symbol table. Their values
+correspond to particular addresses. The trusted firmware code can refer to these
+symbols to figure out the image memory layout.
+
+Linker symbols follow the following naming convention in the trusted firmware.
+
+*   `__<SECTION>_START__`
+
+    Start address of a given section named `<SECTION>`.
+
+*   `__<SECTION>_END__`
+
+    End address of a given section named `<SECTION>`. If there is an alignment
+    constraint on the section's end address then `__<SECTION>_END__` corresponds
+    to the end address of the section's actual contents, rounded up to the right
+    boundary. Refer to the value of `__<SECTION>_UNALIGNED_END__`  to know the
+    actual end address of the section's contents.
+
+*   `__<SECTION>_UNALIGNED_END__`
+
+    End address of a given section named `<SECTION>` without any padding or
+    rounding up due to some alignment constraint.
+
+*   `__<SECTION>_SIZE__`
+
+    Size (in bytes) of a given section named `<SECTION>`. If there is an
+    alignment constraint on the section's end address then `__<SECTION>_SIZE__`
+    corresponds to the size of the section's actual contents, rounded up to the
+    right boundary. In other words, `__<SECTION>_SIZE__ = __<SECTION>_END__ -
+    _<SECTION>_START__`. Refer to the value of `__<SECTION>_UNALIGNED_SIZE__`
+    to know the actual size of the section's contents.
+
+*   `__<SECTION>_UNALIGNED_SIZE__`
+
+    Size (in bytes) of a given section named `<SECTION>` without any padding or
+    rounding up due to some alignment constraint. In other words,
+    `__<SECTION>_UNALIGNED_SIZE__ = __<SECTION>_UNALIGNED_END__ -
+    __<SECTION>_START__`.
+
+Some of the linker symbols are mandatory as the trusted firmware code relies on
+them to be defined. They are listed in the following subsections. Some of them
+must be provided for each bootloader stage and some are specific to a given
+bootloader stage.
+
+The linker scripts define some extra, optional symbols. They are not actually
+used by any code but they help in understanding the bootloader images' memory
+layout as they are easy to spot in the link map files.
+
+#### Common linker symbols
+
+Early setup code needs to know the extents of the BSS section to zero-initialise
+it before executing any C code. The following linker symbols are defined for
+this purpose:
+
+* `__BSS_START__` This address must be aligned on a 16-byte boundary.
+* `__BSS_SIZE__`
+
+Similarly, the coherent memory section (if enabled) must be zero-initialised.
+Also, the MMU setup code needs to know the extents of this section to set the
+right memory attributes for it. The following linker symbols are defined for
+this purpose:
+
+* `__COHERENT_RAM_START__` This address must be aligned on a page-size boundary.
+* `__COHERENT_RAM_END__` This address must be aligned on a page-size boundary.
+* `__COHERENT_RAM_UNALIGNED_SIZE__`
+
+#### BL1's linker symbols
+
+BL1's early setup code needs to know the extents of the .data section to
+relocate it from ROM to RAM before executing any C code. The following linker
+symbols are defined for this purpose:
+
+* `__DATA_ROM_START__` This address must be aligned on a 16-byte boundary.
+* `__DATA_RAM_START__` This address must be aligned on a 16-byte boundary.
+* `__DATA_SIZE__`
+
+BL1's platform setup code needs to know the extents of its read-write data
+region to figure out its memory layout. The following linker symbols are defined
+for this purpose:
+
+* `__BL1_RAM_START__` This is the start address of BL1 RW data.
+* `__BL1_RAM_END__` This is the end address of BL1 RW data.
+
+#### BL2's, BL3-1's and TSP's linker symbols
+
+BL2, BL3-1 and TSP need to know the extents of their read-only section to set
+the right memory attributes for this memory region in their MMU setup code. The
+following linker symbols are defined for this purpose:
+
+* `__RO_START__`
+* `__RO_END__`
+
+### How to choose the right base addresses for each bootloader stage image
+
+There is currently no support for dynamic image loading in the Trusted Firmware.
+This means that all bootloader images need to be linked against their ultimate
+runtime locations and the base addresses of each image must be chosen carefully
+such that images don't overlap each other in an undesired way. As the code
+grows, the base addresses might need adjustments to cope with the new memory
+layout.
+
+The memory layout is completely specific to the platform and so there is no
+general recipe for choosing the right base addresses for each bootloader image.
+However, there are tools to aid in understanding the memory layout. These are
+the link map files: `build/<platform>/<build-type>/bl<x>/bl<x>.map`, with `<x>`
+being the stage bootloader. They provide a detailed view of the memory usage of
+each image. Among other useful information, they provide the end address of
+each image.
+
+* `bl1.map` link map file provides `__BL1_RAM_END__` address.
+* `bl2.map` link map file provides `__BL2_END__` address.
+* `bl31.map` link map file provides `__BL31_END__` address.
+* `bl32.map` link map file provides `__BL32_END__` address.
+
+For each bootloader image, the platform code must provide its start address
+as well as a limit address that it must not overstep. The latter is used in the
+linker scripts to check that the image doesn't grow past that address. If that
+happens, the linker will issue a message similar to the following:
+
+    aarch64-none-elf-ld: BLx has exceeded its limit.
+
+Additionally, if the platform memory layout implies some image overlaying like
+on FVP, BL3-1 and TSP need to know the limit address that their PROGBITS
+sections must not overstep. The platform code must provide those.
+
+
+####  Memory layout on ARM FVPs
+
+The following list describes the memory layout on the FVP:
+
+*   A 4KB page of shared memory is used to store the entrypoint mailboxes
+    and the parameters passed between bootloaders. The shared memory is located
+    at the base of the Trusted SRAM. The amount of Trusted SRAM available to
+    load the bootloader images will be reduced by the size of the shared memory.
+
+*   BL1 is originally sitting in the Trusted ROM at address `0x0`. Its
+    read-write data are relocated at the top of the Trusted SRAM at runtime.
+
+*   BL3-1 is loaded at the top of the Trusted SRAM, such that its NOBITS
+    sections will overwrite BL1 R/W data.
+
+*   BL2 is loaded below BL3-1.
+
+*   BL3-2 can be loaded in one of the following locations:
+
+    *   Trusted SRAM
+    *   Trusted DRAM
+    *   Secure region of DRAM (top 16MB of DRAM configured by the TrustZone
+        controller)
+
+When BL3-2 is loaded into Trusted SRAM, its NOBITS sections are allowed to
+overlay BL2. This memory layout is designed to give the BL3-2 image as much
+memory as possible when it is loaded into Trusted SRAM.
+
+The location of the BL3-2 image will result in different memory maps. This is
+illustrated in the following diagrams using the TSP as an example.
+
+**TSP in Trusted SRAM (default option):**
+
+               Trusted SRAM
+    0x04040000 +----------+  loaded by BL2  ------------------
+               | BL1 (rw) |  <<<<<<<<<<<<<  |  BL3-1 NOBITS  |
+               |----------|  <<<<<<<<<<<<<  |----------------|
+               |          |  <<<<<<<<<<<<<  | BL3-1 PROGBITS |
+               |----------|                 ------------------
+               |   BL2    |  <<<<<<<<<<<<<  |  BL3-2 NOBITS  |
+               |----------|  <<<<<<<<<<<<<  |----------------|
+               |          |  <<<<<<<<<<<<<  | BL3-2 PROGBITS |
+    0x04001000 +----------+                 ------------------
+               |  Shared  |
+    0x04000000 +----------+
+
+               Trusted ROM
+    0x04000000 +----------+
+               | BL1 (ro) |
+    0x00000000 +----------+
+
+
+**TSP in Trusted DRAM:**
+
+               Trusted DRAM
+    0x08000000 +----------+
+               |  BL3-2   |
+    0x06000000 +----------+
+
+               Trusted SRAM
+    0x04040000 +----------+  loaded by BL2  ------------------
+               | BL1 (rw) |  <<<<<<<<<<<<<  |  BL3-1 NOBITS  |
+               |----------|  <<<<<<<<<<<<<  |----------------|
+               |          |  <<<<<<<<<<<<<  | BL3-1 PROGBITS |
+               |----------|                 ------------------
+               |   BL2    |
+               |----------|
+               |          |
+    0x04001000 +----------+
+               |  Shared  |
+    0x04000000 +----------+
+
+               Trusted ROM
+    0x04000000 +----------+
+               | BL1 (ro) |
+    0x00000000 +----------+
+
+**TSP in the TZC-Secured DRAM:**
+
+                   DRAM
+    0xffffffff +----------+
+               |  BL3-2   |  (secure)
+    0xff000000 +----------+
+               |          |
+               :          :  (non-secure)
+               |          |
+    0x80000000 +----------+
+
+               Trusted SRAM
+    0x04040000 +----------+  loaded by BL2  ------------------
+               | BL1 (rw) |  <<<<<<<<<<<<<  |  BL3-1 NOBITS  |
+               |----------|  <<<<<<<<<<<<<  |----------------|
+               |          |  <<<<<<<<<<<<<  | BL3-1 PROGBITS |
+               |----------|                 ------------------
+               |   BL2    |
+               |----------|
+               |          |
+    0x04001000 +----------+
+               |  Shared  |
+    0x04000000 +----------+
+
+               Trusted ROM
+    0x04000000 +----------+
+               | BL1 (ro) |
+    0x00000000 +----------+
+
+Moving the TSP image out of the Trusted SRAM doesn't change the memory layout
+of the other boot loader images in Trusted SRAM.
+
+
+####  Memory layout on Juno ARM development platform
+
+The following list describes the memory layout on Juno:
+
+*   Trusted SRAM at 0x04000000 contains the MHU page, BL1 r/w section, BL2
+    image, BL3-1 image and, optionally, the BL3-2 image.
+
+*   The MHU 4 KB page is used as communication channel between SCP and AP. It
+    also contains the entrypoint mailboxes for the AP. Mailboxes are stored in
+    the first 128 bytes of the MHU page.
+
+*   BL1 resides in flash memory at address `0x0BEC0000`. Its read-write data
+    section is relocated to the top of the Trusted SRAM at runtime.
+
+*   BL3-1 is loaded at the top of the Trusted SRAM, such that its NOBITS
+    sections will overwrite BL1 R/W data. This implies that BL1 global variables
+    will remain valid only until execution reaches the BL3-1 entry point during
+    a cold boot.
+
+*   BL2 is loaded below BL3-1.
+
+*   BL3-0 is loaded temporarily into the BL3-1 memory region and transfered to
+    the SCP before being overwritten by BL3-1.
+
+*   The BL3-2 image is optional and can be loaded into one of these two
+    locations: Trusted SRAM (right after the MHU page) or DRAM (14 MB starting
+    at 0xFF000000 and secured by the TrustZone controller). When loaded into
+    Trusted SRAM, its NOBITS sections are allowed to overlap BL2.
+
+Depending on the location of the BL3-2 image, it will result in different memory
+maps, illustrated by the following diagrams.
+
+**BL3-2 in Trusted SRAM (default option):**
+
+                  Flash0
+    0x0C000000 +----------+
+               :          :
+    0x0BED0000 |----------|
+               | BL1 (ro) |
+    0x0BEC0000 |----------|
+               :          :
+    0x08000000 +----------+                  BL3-1 is loaded
+                                             after BL3-0 has
+               Trusted SRAM                  been sent to SCP
+    0x04040000 +----------+  loaded by BL2  ------------------
+               | BL1 (rw) |  <<<<<<<<<<<<<  |  BL3-1 NOBITS  |
+               |----------|  <<<<<<<<<<<<<  |----------------|
+               |  BL3-0   |  <<<<<<<<<<<<<  | BL3-1 PROGBITS |
+               |----------|                 ------------------
+               |   BL2    |  <<<<<<<<<<<<<  |  BL3-2 NOBITS  |
+               |----------|  <<<<<<<<<<<<<  |----------------|
+               |          |  <<<<<<<<<<<<<  | BL3-2 PROGBITS |
+    0x04001000 +----------+                 ------------------
+               |   MHU    |
+    0x04000000 +----------+
+
+
+**BL3-2 in the secure region of DRAM:**
+
+                   DRAM
+    0xFFE00000 +----------+
+               |  BL3-2   |  (secure)
+    0xFF000000 |----------|
+               |          |
+               :          :  (non-secure)
+               |          |
+    0x80000000 +----------+
+
+                  Flash0
+    0x0C000000 +----------+
+               :          :
+    0x0BED0000 |----------|
+               | BL1 (ro) |
+    0x0BEC0000 |----------|
+               :          :
+    0x08000000 +----------+                  BL3-1 is loaded
+                                             after BL3-0 has
+               Trusted SRAM                  been sent to SCP
+    0x04040000 +----------+  loaded by BL2  ------------------
+               | BL1 (rw) |  <<<<<<<<<<<<<  |  BL3-1 NOBITS  |
+               |----------|  <<<<<<<<<<<<<  |----------------|
+               |  BL3-0   |  <<<<<<<<<<<<<  | BL3-1 PROGBITS |
+               |----------|                 ------------------
+               |   BL2    |
+               |----------|
+               |          |
+    0x04001000 +----------+
+               |   MHU    |
+    0x04000000 +----------+
+
+Loading the BL3-2 image in DRAM doesn't change the memory layout of the other
+images in Trusted SRAM.
+
+
+10.  Firmware Image Package (FIP)
+---------------------------------
+
+Using a Firmware Image Package (FIP) allows for packing bootloader images (and
+potentially other payloads) into a single archive that can be loaded by the ARM
+Trusted Firmware from non-volatile platform storage. A driver to load images
+from a FIP has been added to the storage layer and allows a package to be read
+from supported platform storage. A tool to create Firmware Image Packages is
+also provided and described below.
+
+### Firmware Image Package layout
+
+The FIP layout consists of a table of contents (ToC) followed by payload data.
+The ToC itself has a header followed by one or more table entries. The ToC is
+terminated by an end marker entry. All ToC entries describe some payload data
+that has been appended to the end of the binary package. With the information
+provided in the ToC entry the corresponding payload data can be retrieved.
+
+    ------------------
+    | ToC Header     |
+    |----------------|
+    | ToC Entry 0    |
+    |----------------|
+    | ToC Entry 1    |
+    |----------------|
+    | ToC End Marker |
+    |----------------|
+    |                |
+    |     Data 0     |
+    |                |
+    |----------------|
+    |                |
+    |     Data 1     |
+    |                |
+    ------------------
+
+The ToC header and entry formats are described in the header file
+`include/firmware_image_package.h`. This file is used by both the tool and the
+ARM Trusted firmware.
+
+The ToC header has the following fields:
+    `name`: The name of the ToC. This is currently used to validate the header.
+    `serial_number`: A non-zero number provided by the creation tool
+    `flags`: Flags associated with this data. None are yet defined.
+
+A ToC entry has the following fields:
+    `uuid`: All files are referred to by a pre-defined Universally Unique
+        IDentifier [UUID] . The UUIDs are defined in
+        `include/firmware_image_package`. The platform translates the requested
+        image name into the corresponding UUID when accessing the package.
+    `offset_address`: The offset address at which the corresponding payload data
+        can be found. The offset is calculated from the ToC base address.
+    `size`: The size of the corresponding payload data in bytes.
+    `flags`: Flags associated with this entry. Non are yet defined.
+
+### Firmware Image Package creation tool
+
+The FIP creation tool can be used to pack specified images into a binary package
+that can be loaded by the ARM Trusted Firmware from platform storage. The tool
+currently only supports packing bootloader images. Additional image definitions
+can be added to the tool as required.
+
+The tool can be found in `tools/fip_create`.
+
+### Loading from a Firmware Image Package (FIP)
+
+The Firmware Image Package (FIP) driver can load images from a binary package on
+non-volatile platform storage. For the FVPs this is currently NOR FLASH.
+
+Bootloader images are loaded according to the platform policy as specified in
+`plat/<platform>/plat_io_storage.c`. For the FVPs this means the platform will
+attempt to load images from a Firmware Image Package located at the start of NOR
+FLASH0.
+
+Currently the FVP's policy only allows loading of a known set of images. The
+platform policy can be modified to allow additional images.
+
+
+11. Use of coherent memory in Trusted Firmware
+----------------------------------------------
+
+There might be loss of coherency when physical memory with mismatched
+shareability, cacheability and memory attributes is accessed by multiple CPUs
+(refer to section B2.9 of [ARM ARM] for more details). This possibility occurs
+in Trusted Firmware during power up/down sequences when coherency, MMU and
+caches are turned on/off incrementally.
+
+Trusted Firmware defines coherent memory as a region of memory with Device
+nGnRE attributes in the translation tables. The translation granule size in
+Trusted Firmware is 4KB. This is the smallest possible size of the coherent
+memory region.
+
+By default, all data structures which are susceptible to accesses with
+mismatched attributes from various CPUs are allocated in a coherent memory
+region (refer to section 2.1 of [Porting Guide]). The coherent memory region
+accesses are Outer Shareable, non-cacheable and they can be accessed
+with the Device nGnRE attributes when the MMU is turned on. Hence, at the
+expense of at least an extra page of memory, Trusted Firmware is able to work
+around coherency issues due to mismatched memory attributes.
+
+The alternative to the above approach is to allocate the susceptible data
+structures in Normal WriteBack WriteAllocate Inner shareable memory. This
+approach requires the data structures to be designed so that it is possible to
+work around the issue of mismatched memory attributes by performing software
+cache maintenance on them.
+
+### Disabling the use of coherent memory in Trusted Firmware
+
+It might be desirable to avoid the cost of allocating coherent memory on
+platforms which are memory constrained. Trusted Firmware enables inclusion of
+coherent memory in firmware images through the build flag `USE_COHERENT_MEM`.
+This flag is enabled by default. It can be disabled to choose the second
+approach described above.
+
+The below sections analyze the data structures allocated in the coherent memory
+region and the changes required to allocate them in normal memory.
+
+### PSCI Affinity map nodes
+
+The `psci_aff_map` data structure stores the hierarchial node information for
+each affinity level in the system including the PSCI states associated with them.
+By default, this data structure is allocated in the coherent memory region in
+the Trusted Firmware because it can be accessed by multiple CPUs, either with
+their caches enabled or disabled.
+
+	typedef struct aff_map_node {
+		unsigned long mpidr;
+		unsigned char ref_count;
+		unsigned char state;
+		unsigned char level;
+	#if USE_COHERENT_MEM
+		bakery_lock_t lock;
+	#else
+		unsigned char aff_map_index;
+	#endif
+	} aff_map_node_t;
+
+In order to move this data structure to normal memory, the use of each of its
+fields must be analyzed. Fields like `mpidr` and `level` are only written once
+during cold boot. Hence removing them from coherent memory involves only doing
+a clean and invalidate of the cache lines after these fields are written.
+
+The fields `state` and `ref_count` can be concurrently accessed by multiple
+CPUs in different cache states. A Lamport's Bakery lock is used to ensure mutual
+exlusion to these fields. As a result, it is possible to move these fields out
+of coherent memory by performing software cache maintenance on them. The field
+`lock` is the bakery lock data structure when `USE_COHERENT_MEM` is enabled.
+The `aff_map_index` is used to identify the bakery lock when `USE_COHERENT_MEM`
+is disabled.
+
+### Bakery lock data
+
+The bakery lock data structure `bakery_lock_t` is allocated in coherent memory
+and is accessed by multiple CPUs with mismatched attributes. `bakery_lock_t` is
+defined as follows:
+
+    typedef struct bakery_lock {
+        int owner;
+        volatile char entering[BAKERY_LOCK_MAX_CPUS];
+        volatile unsigned number[BAKERY_LOCK_MAX_CPUS];
+    } bakery_lock_t;
+
+It is a characteristic of Lamport's Bakery algorithm that the volatile per-CPU
+fields can be read by all CPUs but only written to by the owning CPU.
+
+Depending upon the data cache line size, the per-CPU fields of the
+`bakery_lock_t` structure for multiple CPUs may exist on a single cache line.
+These per-CPU fields can be read and written during lock contention by multiple
+CPUs with mismatched memory attributes. Since these fields are a part of the
+lock implementation, they do not have access to any other locking primitive to
+safeguard against the resulting coherency issues. As a result, simple software
+cache maintenance is not enough to allocate them in coherent memory. Consider
+the following example.
+
+CPU0 updates its per-CPU field with data cache enabled. This write updates a
+local cache line which contains a copy of the fields for other CPUs as well. Now
+CPU1 updates its per-CPU field of the `bakery_lock_t` structure with data cache
+disabled. CPU1 then issues a DCIVAC operation to invalidate any stale copies of
+its field in any other cache line in the system. This operation will invalidate
+the update made by CPU0 as well.
+
+To use bakery locks when `USE_COHERENT_MEM` is disabled, the lock data structure
+has been redesigned. The changes utilise the characteristic of Lamport's Bakery
+algorithm mentioned earlier. The per-CPU fields of the new lock structure are
+aligned such that they are allocated on separate cache lines. The per-CPU data
+framework in Trusted Firmware is used to achieve this. This enables software to
+perform software cache maintenance on the lock data structure without running
+into coherency issues associated with mismatched attributes.
+
+The per-CPU data framework enables consolidation of data structures on the
+fewest cache lines possible. This saves memory as compared to the scenario where
+each data structure is separately aligned to the cache line boundary to achieve
+the same effect.
+
+The bakery lock data structure `bakery_info_t` is defined for use when
+`USE_COHERENT_MEM` is disabled as follows:
+
+    typedef struct bakery_info {
+        /*
+         * The lock_data is a bit-field of 2 members:
+         * Bit[0]       : choosing. This field is set when the CPU is
+         *                choosing its bakery number.
+         * Bits[1 - 15] : number. This is the bakery number allocated.
+         */
+         volatile uint16_t lock_data;
+    } bakery_info_t;
+
+The `bakery_info_t` represents a single per-CPU field of one lock and
+the combination of corresponding `bakery_info_t` structures for all CPUs in the
+system represents the complete bakery lock. It is embedded in the per-CPU
+data framework `cpu_data` as shown below:
+
+      CPU0 cpu_data
+    ------------------
+    | ....           |
+    |----------------|
+    | `bakery_info_t`| <-- Lock_0 per-CPU field
+    |    Lock_0      |     for CPU0
+    |----------------|
+    | `bakery_info_t`| <-- Lock_1 per-CPU field
+    |    Lock_1      |     for CPU0
+    |----------------|
+    | ....           |
+    |----------------|
+    | `bakery_info_t`| <-- Lock_N per-CPU field
+    |    Lock_N      |     for CPU0
+    ------------------
+
+
+      CPU1 cpu_data
+    ------------------
+    | ....           |
+    |----------------|
+    | `bakery_info_t`| <-- Lock_0 per-CPU field
+    |    Lock_0      |     for CPU1
+    |----------------|
+    | `bakery_info_t`| <-- Lock_1 per-CPU field
+    |    Lock_1      |     for CPU1
+    |----------------|
+    | ....           |
+    |----------------|
+    | `bakery_info_t`| <-- Lock_N per-CPU field
+    |    Lock_N      |     for CPU1
+    ------------------
+
+Consider a system of 2 CPUs with 'N' bakery locks as shown above.  For an
+operation on Lock_N, the corresponding `bakery_info_t` in both CPU0 and CPU1
+`cpu_data` need to be fetched and appropriate cache operations need to be
+performed for each access.
+
+For multiple bakery locks, an array of `bakery_info_t` is declared in `cpu_data`
+and each lock is given an `id` to identify it in the array.
+
+### Non Functional Impact of removing coherent memory
+
+Removal of the coherent memory region leads to the additional software overhead
+of performing cache maintenance for the affected data structures. However, since
+the memory where the data structures are allocated is cacheable, the overhead is
+mostly mitigated by an increase in performance.
+
+There is however a performance impact for bakery locks, due to:
+*   Additional cache maintenance operations, and
+*   Multiple cache line reads for each lock operation, since the bakery locks
+    for each CPU are distributed across different cache lines.
+
+The implementation has been optimized to mimimize this additional overhead.
+Measurements indicate that when bakery locks are allocated in Normal memory, the
+minimum latency of acquiring a lock is on an average 3-4 micro seconds whereas
+in Device memory the same is 2 micro seconds. The measurements were done on the
+Juno ARM development platform.
+
+As mentioned earlier, almost a page of memory can be saved by disabling
+`USE_COHERENT_MEM`. Each platform needs to consider these trade-offs to decide
+whether coherent memory should be used. If a platform disables
+`USE_COHERENT_MEM` and needs to use bakery locks in the porting layer, it should
+reserve memory in `cpu_data` by defining the macro `PLAT_PCPU_DATA_SIZE` (see
+the [Porting Guide]). Refer to the reference platform code for examples.
+
+
+12.  Code Structure
+-------------------
+
+Trusted Firmware code is logically divided between the three boot loader
+stages mentioned in the previous sections. The code is also divided into the
+following categories (present as directories in the source code):
+
+*   **Architecture specific.** This could be AArch32 or AArch64.
+*   **Platform specific.** Choice of architecture specific code depends upon
+    the platform.
+*   **Common code.** This is platform and architecture agnostic code.
+*   **Library code.** This code comprises of functionality commonly used by all
+    other code.
+*   **Stage specific.** Code specific to a boot stage.
+*   **Drivers.**
+*   **Services.** EL3 runtime services, e.g. PSCI or SPD. Specific SPD services
+    reside in the `services/spd` directory (e.g. `services/spd/tspd`).
+
+Each boot loader stage uses code from one or more of the above mentioned
+categories. Based upon the above, the code layout looks like this:
+
+    Directory    Used by BL1?    Used by BL2?    Used by BL3-1?
+    bl1          Yes             No              No
+    bl2          No              Yes             No
+    bl31         No              No              Yes
+    arch         Yes             Yes             Yes
+    plat         Yes             Yes             Yes
+    drivers      Yes             No              Yes
+    common       Yes             Yes             Yes
+    lib          Yes             Yes             Yes
+    services     No              No              Yes
+
+The build system provides a non configurable build option IMAGE_BLx for each
+boot loader stage (where x = BL stage). e.g. for BL1 , IMAGE_BL1 will be
+defined by the build system. This enables the Trusted Firmware to compile
+certain code only for specific boot loader stages
+
+All assembler files have the `.S` extension. The linker source files for each
+boot stage have the extension `.ld.S`. These are processed by GCC to create the
+linker scripts which have the extension `.ld`.
+
+FDTs provide a description of the hardware platform and are used by the Linux
+kernel at boot time. These can be found in the `fdts` directory.
+
+
+13.  References
+---------------
+
+1.  Trusted Board Boot Requirements CLIENT PDD (ARM DEN 0006B-5). Available
+    under NDA through your ARM account representative.
+
+2.  [Power State Coordination Interface PDD (ARM DEN 0022B.b)][PSCI].
+
+3.  [SMC Calling Convention PDD (ARM DEN 0028A)][SMCCC].
+
+4.  [ARM Trusted Firmware Interrupt Management Design guide][INTRG].
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._
+
+[ARM ARM]:          http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.e/index.html "ARMv8-A Reference Manual (ARM DDI0487A.E)"
+[PSCI]:             http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)"
+[SMCCC]:            http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)"
+[UUID]:             https://tools.ietf.org/rfc/rfc4122.txt "A Universally Unique IDentifier (UUID) URN Namespace"
+[User Guide]:       ./user-guide.md
+[Porting Guide]:    ./porting-guide.md
+[INTRG]:            ./interrupt-framework-design.md
+[CPUBM]:            ./cpu-specific-build-macros.md.md
diff --git a/uefi/arm-trusted-firmware/docs/interrupt-framework-design.md b/uefi/arm-trusted-firmware/docs/interrupt-framework-design.md
new file mode 100644
index 0000000..ff001b1
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/interrupt-framework-design.md
@@ -0,0 +1,848 @@
+ARM Trusted Firmware Interrupt Management Design guide
+======================================================
+
+Contents :
+
+1.  [Introduction](#1-introduction)
+    *   [Assumptions](#11-assumptions)
+    *   [Concepts](#12-concepts)
+        -   [Interrupt Types](#121-interrupt-types)
+        -   [Routing Model](#122-routing-model)
+        -   [Valid Routing Models](#123-valid-routing-models)
+            +   [Secure-EL1 Interrupts](#1231-secure-el1-interrupts)
+            +   [Non-secure Interrupts](#1232-non-secure-interrupts)
+        -   [Mapping of Interrupt Type to Signal](#124-mapping-of-interrupt-type-to-signal)
+
+2.  [Interrupt Management](#2-interrupt-management)
+    *   [Software Components](#21-software-components)
+    *   [Interrupt Registration](#22-interrupt-registration)
+        -   [EL3 Runtime Firmware](#221-el3-runtime-firmware)
+        -   [Secure Payload Dispatcher](#222-secure-payload-dispatcher)
+            +   [Test Secure Payload Dispatcher behavior](#2221-test-secure-payload-dispatcher-behavior)
+        -   [Secure Payload](#223-secure-payload)
+            +   [Secure Payload IHF design w.r.t Secure-EL1 interrupts](#2231-secure-payload-ihf-design-wrt-secure-el1-interrupts)
+            +   [Secure Payload IHF design w.r.t Non-secure interrupts](#2232-secure-payload-ihf-design-wrt-non-secure-interrupts)
+            +   [Test Secure Payload behavior](#2233-test-secure-payload-behavior)
+    *   [Interrupt Handling](#23-interrupt-handling)
+        -   [EL3 Runtime Firmware](#231-el3-runtime-firmware)
+        -   [Secure Payload Dispatcher](#232-secure-payload-dispatcher)
+            +   [Interrupt Entry](#2321-interrupt-entry)
+            +   [Interrupt Exit](#2322-interrupt-exit)
+            +   [Test Secure Payload Dispatcher behavior](#2323-test-secure-payload-dispatcher-behavior)
+        -   [Secure Payload](#233-secure-payload)
+            +   [Test Secure Payload behavior](#2331-test-secure-payload-behavior)
+
+
+1. Introduction
+----------------
+This document describes the design of the Interrupt management framework in ARM
+Trusted Firmware. This section briefly describes the requirements from this
+framework. It also briefly explains some concepts and assumptions. They will
+help in understanding the implementation of the framework explained in
+subsequent sections.
+
+This framework is responsible for managing interrupts routed to EL3. It also
+allows EL3 software to configure the interrupt routing behavior. Its main
+objective is to implement the following two requirements.
+
+1.  It should be possible to route interrupts meant to be handled by secure
+    software (Secure interrupts) to EL3, when execution is in non-secure state
+    (normal world). The framework should then take care of handing control of
+    the interrupt to either software in EL3 or Secure-EL1 depending upon the
+    software configuration and the GIC implementation. This requirement ensures
+    that secure interrupts are under the control of the secure software with
+    respect to their delivery and handling without the possibility of
+    intervention from non-secure software.
+
+2.  It should be possible to route interrupts meant to be handled by
+    non-secure software (Non-secure interrupts) to the last executed exception
+    level in the normal world when the execution is in secure world at
+    exception levels lower than EL3. This could be done with or without the
+    knowledge of software executing in Secure-EL1/Secure-EL0. The choice of
+    approach should be governed by the secure software. This requirement
+    ensures that non-secure software is able to execute in tandem with the
+    secure software without overriding it.
+
+### 1.1 Assumptions
+The framework makes the following assumptions to simplify its implementation.
+
+1.  All secure interrupts are handled in Secure-EL1. They can be delivered to
+    Secure-EL1 via EL3 but they cannot be handled in EL3. It will be possible
+    to extend the framework to handle secure interrupts in EL3 in the future.
+
+2.  Interrupt exceptions (`PSTATE.I` and `F` bits) are masked during execution
+    in EL3.
+
+### 1.2 Concepts
+
+#### 1.2.1 Interrupt types
+The framework categorises an interrupt to be one of the following depending upon
+the exception level(s) it is handled in.
+
+1.  Secure EL1 interrupt. This type of interrupt can be routed to EL3 or
+    Secure-EL1 depending upon the security state of the current execution
+    context. It is always handled in Secure-EL1.
+
+2.  Non-secure interrupt. This type of interrupt can be routed to EL3,
+    Secure-EL1, Non-secure EL1 or EL2 depending upon the security state of the
+    current execution context. It is always handled in either Non-secure EL1
+    or EL2.
+
+3.  EL3 interrupt. This type of interrupt can be routed to EL3 or Secure-EL1
+    depending upon the security state of the current execution context. It is
+    always handled in EL3.
+
+In the current implementation of the framework, all secure interrupts are
+treated as Secure EL1 interrupts. It will be possible for EL3 software to
+configure a secure interrupt as an EL3 interrupt in future implementations.  The
+following constants define the various interrupt types in the framework
+implementation.
+
+    #define INTR_TYPE_S_EL1      0
+    #define INTR_TYPE_EL3        1
+    #define INTR_TYPE_NS         2
+
+
+#### 1.2.2 Routing model
+A type of interrupt can be either generated as an FIQ or an IRQ. The target
+exception level of an interrupt type is configured through the FIQ and IRQ bits
+in the Secure Configuration Register at EL3 (`SCR_EL3.FIQ` and `SCR_EL3.IRQ`
+bits). When `SCR_EL3.FIQ`=1, FIQs are routed to EL3. Otherwise they are routed
+to the First Exception Level (FEL) capable of handling interrupts. When
+`SCR_EL3.IRQ`=1, IRQs are routed to EL3. Otherwise they are routed to the
+FEL. This register is configured independently by EL3 software for each security
+state prior to entry into a lower exception level in that security state.
+
+A routing model for a type of interrupt (generated as FIQ or IRQ) is defined as
+its target exception level for each security state. It is represented by a
+single bit for each security state. A value of `0` means that the interrupt
+should be routed to the FEL. A value of `1` means that the interrupt should be
+routed to EL3. A routing model is applicable only when execution is not in EL3.
+
+The default routing model for an interrupt type is to route it to the FEL in
+either security state.
+
+#### 1.2.3 Valid routing models
+The framework considers certain routing models for each type of interrupt to be
+incorrect as they conflict with the requirements mentioned in Section 1. The
+following sub-sections describe all the possible routing models and specify
+which ones are valid or invalid. Only the Secure-EL1 and Non-secure interrupt
+types are considered as EL3 interrupts are currently unsupported (See 1.1). The
+terminology used in the following sub-sections is explained below.
+
+1.  __CSS__. Current Security State. `0` when secure and `1` when non-secure
+
+2.  __TEL3__. Target Exception Level 3. `0` when targeted to the FEL. `1` when
+    targeted to EL3.
+
+
+##### 1.2.3.1 Secure-EL1 interrupts
+
+1.  __CSS=0, TEL3=0__. Interrupt is routed to the FEL when execution is in
+    secure state. This is a valid routing model as secure software is in
+    control of handling secure interrupts.
+
+2.  __CSS=0, TEL3=1__. Interrupt is routed to EL3 when execution is in secure
+    state. This is a valid routing model as secure software in EL3 can
+    handover the interrupt to Secure-EL1 for handling.
+
+3.  __CSS=1, TEL3=0__. Interrupt is routed to the FEL when execution is in
+    non-secure state. This is an invalid routing model as a secure interrupt
+    is not visible to the secure software which violates the motivation behind
+    the ARM Security Extensions.
+
+4.  __CSS=1, TEL3=1__. Interrupt is routed to EL3 when execution is in
+    non-secure state. This is a valid routing model as secure software in EL3
+    can handover the interrupt to Secure-EL1 for handling.
+
+
+##### 1.2.3.2 Non-secure interrupts
+
+1.  __CSS=0, TEL3=0__. Interrupt is routed to the FEL when execution is in
+    secure state. This allows the secure software to trap non-secure
+    interrupts, perform its bookeeping and hand the interrupt to the
+    non-secure software through EL3. This is a valid routing model as secure
+    software is in control of how its execution is pre-empted by non-secure
+    interrupts.
+
+2.  __CSS=0, TEL3=1__. Interrupt is routed to EL3 when execution is in secure
+    state. This is a valid routing model as secure software in EL3 can save
+    the state of software in Secure-EL1/Secure-EL0 before handing the
+    interrupt to non-secure software. This model requires additional
+    coordination between Secure-EL1 and EL3 software to ensure that the
+    former's state is correctly saved by the latter.
+
+3.  __CSS=1, TEL3=0__. Interrupt is routed to FEL when execution is in
+    non-secure state. This is an valid routing model as a non-secure interrupt
+    is handled by non-secure software.
+
+4.   __CSS=1, TEL3=1__. Interrupt is routed to EL3 when execution is in
+    non-secure state. This is an invalid routing model as there is no valid
+    reason to route the interrupt to EL3 software and then hand it back to
+    non-secure software for handling.
+
+
+#### 1.2.4 Mapping of interrupt type to signal
+The framework is meant to work with any interrupt controller implemented by a
+platform. A interrupt controller could generate a type of interrupt as either an
+FIQ or IRQ signal to the CPU depending upon the current security state.The
+mapping between the type and signal is known only to the platform. The framework
+uses this information to determine whether the IRQ or the FIQ bit should be
+programmed in `SCR_EL3` while applying the routing model for a type of
+interrupt. The platform provides this information through the
+`plat_interrupt_type_to_line()` API (described in the [Porting
+Guide]). For example, on the FVP port when the platform uses an ARM GICv2
+interrupt controller, Secure-EL1 interrupts are signalled through the FIQ signal
+while Non-secure interrupts are signalled through the IRQ signal. This applies
+when execution is in either security state.
+
+
+2. Interrupt management
+-----------------------
+The following sections describe how interrupts are managed by the interrupt
+handling framework. This entails:
+
+1.  Providing an interface to allow registration of a handler and specification
+    of the routing model for a type of interrupt.
+
+2.  Implementing support to hand control of an interrupt type to its registered
+    handler when the interrupt is generated.
+
+Both aspects of interrupt management involve various components in the secure
+software stack spanning from EL3 to Secure-EL1. These components are described
+in the section 2.1. The framework stores information associated with each type
+of interrupt in the following data structure.
+
+```
+typedef struct intr_type_desc {
+        interrupt_type_handler_t handler;
+        uint32_t flags;
+        uint32_t scr_el3[2];
+} intr_type_desc_t;
+```
+
+The `flags` field stores the routing model for the interrupt type in
+bits[1:0]. Bit[0] stores the routing model when execution is in the secure
+state. Bit[1] stores the routing model when execution is in the non-secure
+state. As mentioned in Section 1.2.2, a value of `0` implies that the interrupt
+should be targeted to the FEL. A value of `1` implies that it should be targeted
+to EL3. The remaining bits are reserved and SBZ. The helper macro
+`set_interrupt_rm_flag()` should be used to set the bits in the `flags`
+parameter.
+
+The `scr_el3[2]` field also stores the routing model but as a mapping of the
+model in the `flags` field to the corresponding bit in the `SCR_EL3` for each
+security state.
+
+The framework also depends upon the platform port to configure the interrupt
+controller to distinguish between secure and non-secure interrupts. The platform
+is expected to be aware of the secure devices present in the system and their
+associated interrupt numbers. It should configure the interrupt controller to
+enable the secure interrupts, ensure that their priority is always higher than
+the non-secure interrupts and target them to the primary CPU. It should also
+export the interface described in the [Porting Guide] to enable
+handling of interrupts.
+
+In the remainder of this document, for the sake of simplicity it is assumed that
+the FIQ signal is used to generate Secure-EL1 interrupts and the IRQ signal is
+used to generate non-secure interrupts in either security state.
+
+### 2.1 Software components
+Roles and responsibilities for interrupt management are sub-divided between the
+following components of software running in EL3 and Secure-EL1. Each component is
+briefly described below.
+
+1.  EL3 Runtime Firmware. This component is common to all ports of the ARM
+    Trusted Firmware.
+
+2.  Secure Payload Dispatcher (SPD) service. This service interfaces with the
+    Secure Payload (SP) software which runs in exception levels lower than EL3
+    i.e. Secure-EL1/Secure-EL0. It is responsible for switching execution
+    between software running in secure and non-secure states at exception
+    levels lower than EL3. A switch is triggered by a Secure Monitor Call from
+    either state. It uses the APIs exported by the Context management library
+    to implement this functionality. Switching execution between the two
+    security states is a requirement for interrupt management as well. This
+    results in a significant dependency on the SPD service. ARM Trusted
+    firmware implements an example Test Secure Payload Dispatcher (TSPD)
+    service.
+
+    An SPD service plugs into the EL3 runtime firmware and could be common to
+    some ports of the ARM Trusted Firmware.
+
+3.  Secure Payload (SP). On a production system, the Secure Payload corresponds
+    to a Secure OS which runs in Secure-EL1/Secure-EL0. It interfaces with the
+    SPD service to manage communication with non-secure software. ARM Trusted
+    Firmware implements an example secure payload called Test Secure Payload
+    (TSP) which runs only in Secure-EL1.
+
+    A Secure payload implementation could be common to some ports of the ARM
+    Trusted Firmware just like the SPD service.
+
+
+### 2.2 Interrupt registration
+This section describes in detail the role of each software component (see 2.1)
+during the registration of a handler for an interrupt type.
+
+
+#### 2.2.1 EL3 runtime firmware
+This component declares the following prototype for a handler of an interrupt type.
+
+        typedef uint64_t (*interrupt_type_handler_t)(uint32_t id,
+					     uint32_t flags,
+					     void *handle,
+					     void *cookie);
+
+The value of the `id` parameter depends upon the definition of the
+`IMF_READ_INTERRUPT_ID` build time flag. When the flag is defined, `id` contains
+the number of the highest priority pending interrupt of the type that this
+handler was registered for. When the flag is not defined `id` contains
+`INTR_ID_UNAVAILABLE`.
+
+The `flags` parameter contains miscellaneous information as follows.
+
+1.  Security state, bit[0]. This bit indicates the security state of the lower
+    exception level when the interrupt was generated. A value of `1` means
+    that it was in the non-secure state. A value of `0` indicates that it was
+    in the secure state. This bit can be used by the handler to ensure that
+    interrupt was generated and routed as per the routing model specified
+    during registration.
+
+2.  Reserved, bits[31:1]. The remaining bits are reserved for future use.
+
+The `handle` parameter points to the `cpu_context` structure of the current CPU
+for the security state specified in the `flags` parameter.
+
+Once the handler routine completes, execution will return to either the secure
+or non-secure state. The handler routine should return a pointer to
+`cpu_context` structure of the current CPU for the the target security state. It
+should treat all error conditions as critical errors and take appropriate action
+within its implementation e.g. use assertion failures.
+
+The runtime firmware provides the following API for registering a handler for a
+particular type of interrupt. A Secure Payload Dispatcher service should use
+this API to register a handler for Secure-EL1 and optionally for non-secure
+interrupts. This API also requires the caller to specify the routing model for
+the type of interrupt.
+
+    int32_t register_interrupt_type_handler(uint32_t type,
+					interrupt_type_handler handler,
+					uint64_t flags);
+
+
+The `type` parameter can be one of the three interrupt types listed above i.e.
+`INTR_TYPE_S_EL1`, `INTR_TYPE_NS` & `INTR_TYPE_EL3` (currently unimplemented).
+The `flags` parameter is as described in Section 2.
+
+The function will return `0` upon a successful registration. It will return
+`-EALREADY` in case a handler for the interrupt type has already been
+registered.  If the `type` is unrecognised or the `flags` or the `handler` are
+invalid it will return `-EINVAL`. It will return `-ENOTSUP` if the specified
+`type` is not supported by the framework i.e. `INTR_TYPE_EL3`.
+
+Interrupt routing is governed by the configuration of the `SCR_EL3.FIQ/IRQ` bits
+prior to entry into a lower exception level in either security state. The
+context management library maintains a copy of the `SCR_EL3` system register for
+each security state in the `cpu_context` structure of each CPU. It exports the
+following APIs to let EL3 Runtime Firmware program and retrieve the routing
+model for each security state for the current CPU. The value of `SCR_EL3` stored
+in the `cpu_context` is used by the `el3_exit()` function to program the
+`SCR_EL3` register prior to returning from the EL3 exception level.
+
+        uint32_t cm_get_scr_el3(uint32_t security_state);
+        void cm_write_scr_el3_bit(uint32_t security_state,
+                                  uint32_t bit_pos,
+                                  uint32_t value);
+
+`cm_get_scr_el3()` returns the value of the `SCR_EL3` register for the specified
+security state of the current CPU. `cm_write_scr_el3()` writes a `0` or `1` to
+the bit specified by `bit_pos`. `register_interrupt_type_handler()` invokes
+`set_routing_model()` API which programs the `SCR_EL3` according to the routing
+model using the `cm_get_scr_el3()` and `cm_write_scr_el3_bit()` APIs.
+
+It is worth noting that in the current implementation of the framework, the EL3
+runtime firmware is responsible for programming the routing model. The SPD is
+responsible for ensuring that the routing model has been adhered to upon
+receiving an interrupt.
+
+#### 2.2.2 Secure payload dispatcher
+A SPD service is responsible for determining and maintaining the interrupt
+routing model supported by itself and the Secure Payload. It is also responsible
+for ferrying interrupts between secure and non-secure software depending upon
+the routing model. It could determine the routing model at build time or at
+runtime. It must use this information to register a handler for each interrupt
+type using the `register_interrupt_type_handler()` API in EL3 runtime firmware.
+
+If the routing model is not known to the SPD service at build time, then it must
+be provided by the SP as the result of its initialisation. The SPD should
+program the routing model only after SP initialisation has completed e.g. in the
+SPD initialisation function pointed to by the `bl32_init` variable.
+
+The SPD should determine the mechanism to pass control to the Secure Payload
+after receiving an interrupt from the EL3 runtime firmware. This information
+could either be provided to the SPD service at build time or by the SP at
+runtime.
+
+#### 2.2.2.1 Test secure payload dispatcher behavior
+The TSPD only handles Secure-EL1 interrupts and is provided with the following
+routing model at build time.
+
+*   Secure-EL1 interrupts are routed to EL3 when execution is in non-secure
+    state and are routed to the FEL when execution is in the secure state
+    i.e __CSS=0, TEL3=0__ & __CSS=1, TEL3=1__ for Secure-EL1 interrupts
+
+*   The default routing model is used for non-secure interrupts i.e they are
+    routed to the FEL in either security state i.e __CSS=0, TEL3=0__ &
+    __CSS=1, TEL3=0__ for Non-secure interrupts
+
+It performs the following actions in the `tspd_init()` function to fulfill the
+requirements mentioned earlier.
+
+1.  It passes control to the Test Secure Payload to perform its
+    initialisation. The TSP provides the address of the vector table
+    `tsp_vectors` in the SP which also includes the handler for Secure-EL1
+    interrupts in the `fiq_entry` field. The TSPD passes control to the TSP at
+    this address when it receives a Secure-EL1 interrupt.
+
+    The handover agreement between the TSP and the TSPD requires that the TSPD
+    masks all interrupts (`PSTATE.DAIF` bits) when it calls
+    `tsp_fiq_entry()`. The TSP has to preserve the callee saved general
+    purpose, SP_EL1/Secure-EL0, LR, VFP and system registers. It can use
+    `x0-x18` to enable its C runtime.
+
+2.  The TSPD implements a handler function for Secure-EL1 interrupts. It
+    registers it with the EL3 runtime firmware using the
+    `register_interrupt_type_handler()` API as follows
+
+        /* Forward declaration */
+        interrupt_type_handler tspd_secure_el1_interrupt_handler;
+        int32_t rc, flags = 0;
+        set_interrupt_rm_flag(flags, NON_SECURE);
+        rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+                                         tspd_secure_el1_interrupt_handler,
+                                         flags);
+        assert(rc == 0);
+
+#### 2.2.3 Secure payload
+A Secure Payload must implement an interrupt handling framework at Secure-EL1
+(Secure-EL1 IHF) to support its chosen interrupt routing model. Secure payload
+execution will alternate between the below cases.
+
+1.  In the code where IRQ, FIQ or both interrupts are enabled, if an interrupt
+    type is targeted to the FEL, then it will be routed to the Secure-EL1
+    exception vector table. This is defined as the asynchronous model of
+    handling interrupts. This mode applies to both Secure-EL1 and non-secure
+    interrupts.
+
+2.  In the code where both interrupts are disabled, if an interrupt type is
+    targeted to the FEL, then execution will eventually migrate to the
+    non-secure state. Any non-secure interrupts will be handled as described
+    in the routing model where __CSS=1 and TEL3=0__. Secure-EL1 interrupts
+    will be routed to EL3 (as per the routing model where __CSS=1 and
+    TEL3=1__) where the SPD service will hand them to the SP. This is defined
+    as the synchronous mode of handling interrupts.
+
+The interrupt handling framework implemented by the SP should support one or
+both these interrupt handling models depending upon the chosen routing model.
+
+The following list briefly describes how the choice of a valid routing model
+(See 1.2.3) effects the implementation of the Secure-EL1 IHF. If the choice of
+the interrupt routing model is not known to the SPD service at compile time,
+then the SP should pass this information to the SPD service at runtime during
+its initialisation phase.
+
+As mentioned earlier, it is assumed that the FIQ signal is used to generate
+Secure-EL1 interrupts and the IRQ signal is used to generate non-secure
+interrupts in either security state.
+
+##### 2.2.3.1 Secure payload IHF design w.r.t secure-EL1 interrupts
+1.  __CSS=0, TEL3=0__. If `PSTATE.F=0`, Secure-EL1 interrupts will be
+    trigerred at one of the Secure-EL1 FIQ exception vectors. The Secure-EL1
+    IHF should implement support for handling FIQ interrupts asynchronously.
+
+    If `PSTATE.F=1` then Secure-EL1 interrupts will be handled as per the
+    synchronous interrupt handling model. The SP could implement this scenario
+    by exporting a seperate entrypoint for Secure-EL1 interrupts to the SPD
+    service during the registration phase. The SPD service would also need to
+    know the state of the system, general purpose and the `PSTATE` registers
+    in which it should arrange to return execution to the SP. The SP should
+    provide this information in an implementation defined way during the
+    registration phase if it is not known to the SPD service at build time.
+
+2.  __CSS=1, TEL3=1__. Interrupts are routed to EL3 when execution is in
+    non-secure state. They should be handled through the synchronous interrupt
+    handling model as described in 1. above.
+
+3.  __CSS=0, TEL3=1__. Secure interrupts are routed to EL3 when execution is in
+    secure state. They will not be visible to the SP. The `PSTATE.F` bit in
+    Secure-EL1/Secure-EL0 will not mask FIQs. The EL3 runtime firmware will
+    call the handler registered by the SPD service for Secure-EL1
+    interrupts. Secure-EL1 IHF should then handle all Secure-EL1 interrupt
+    through the synchronous interrupt handling model described in 1. above.
+
+
+##### 2.2.3.2 Secure payload IHF design w.r.t non-secure interrupts
+1.  __CSS=0, TEL3=0__. If `PSTATE.I=0`, non-secure interrupts will be
+    trigerred at one of the Secure-EL1 IRQ exception vectors . The Secure-EL1
+    IHF should co-ordinate with the SPD service to transfer execution to the
+    non-secure state where the interrupt should be handled e.g the SP could
+    allocate a function identifier to issue a SMC64 or SMC32 to the SPD
+    service which indicates that the SP execution has been pre-empted by a
+    non-secure interrupt. If this function identifier is not known to the SPD
+    service at compile time then the SP could provide it during the
+    registration phase.
+
+    If `PSTATE.I=1` then the non-secure interrupt will pend until execution
+    resumes in the non-secure state.
+
+2.  __CSS=0, TEL3=1__.  Non-secure interrupts are routed to EL3. They will not
+    be visible to the SP. The `PSTATE.I` bit in Secure-EL1/Secure-EL0 will
+    have not effect. The SPD service should register a non-secure interrupt
+    handler which should save the SP state correctly and resume execution in
+    the non-secure state where the interrupt will be handled. The Secure-EL1
+    IHF does not need to take any action.
+
+3.  __CSS=1, TEL3=0__.  Non-secure interrupts are handled in the FEL in
+    non-secure state (EL1/EL2) and are not visible to the SP. This routing
+    model does not affect the SP behavior.
+
+
+A Secure Payload must also ensure that all Secure-EL1 interrupts are correctly
+configured at the interrupt controller by the platform port of the EL3 runtime
+firmware. It should configure any additional Secure-EL1 interrupts which the EL3
+runtime firmware is not aware of through its platform port.
+
+#### 2.2.3.3 Test secure payload behavior
+The routing model for Secure-EL1 and non-secure interrupts chosen by the TSP is
+described in Section 2.2.2. It is known to the TSPD service at build time.
+
+The TSP implements an entrypoint (`tsp_fiq_entry()`) for handling Secure-EL1
+interrupts taken in non-secure state and routed through the TSPD service
+(synchronous handling model). It passes the reference to this entrypoint via
+`tsp_vectors` to the TSPD service.
+
+The TSP also replaces the default exception vector table referenced through the
+`early_exceptions` variable, with a vector table capable of handling FIQ and IRQ
+exceptions taken at the same (Secure-EL1) exception level. This table is
+referenced through the `tsp_exceptions` variable and programmed into the
+VBAR_EL1. It caters for the asynchronous handling model.
+
+The TSP also programs the Secure Physical Timer in the ARM Generic Timer block
+to raise a periodic interrupt (every half a second) for the purpose of testing
+interrupt management across all the software components listed in 2.1
+
+
+### 2.3 Interrupt handling
+This section describes in detail the role of each software component (see
+Section 2.1) in handling an interrupt of a particular type.
+
+#### 2.3.1 EL3 runtime firmware
+The EL3 runtime firmware populates the IRQ and FIQ exception vectors referenced
+by the `runtime_exceptions` variable as follows.
+
+1.  IRQ and FIQ exceptions taken from the current exception level with
+    `SP_EL0` or `SP_EL3` are reported as irrecoverable error conditions. As
+    mentioned earlier, EL3 runtime firmware always executes with the
+    `PSTATE.I` and `PSTATE.F` bits set.
+
+2.  The following text describes how the IRQ and FIQ exceptions taken from a
+    lower exception level using AArch64 or AArch32 are handled.
+
+When an interrupt is generated, the vector for each interrupt type is
+responsible for:
+
+1.  Saving the entire general purpose register context (x0-x30) immediately
+    upon exception entry. The registers are saved in the per-cpu `cpu_context`
+    data structure referenced by the `SP_EL3`register.
+
+2.  Saving the `ELR_EL3`, `SP_EL0` and `SPSR_EL3` system registers in the
+    per-cpu `cpu_context` data structure referenced by the `SP_EL3` register.
+
+3.  Switching to the C runtime stack by restoring the `CTX_RUNTIME_SP` value
+    from the per-cpu `cpu_context` data structure in `SP_EL0` and
+    executing the `msr spsel, #0` instruction.
+
+4.  Determining the type of interrupt. Secure-EL1 interrupts will be signalled
+    at the FIQ vector. Non-secure interrupts will be signalled at the IRQ
+    vector. The platform should implement the following API to determine the
+    type of the pending interrupt.
+
+        uint32_t plat_ic_get_interrupt_type(void);
+
+    It should return either `INTR_TYPE_S_EL1` or `INTR_TYPE_NS`.
+
+5.  Determining the handler for the type of interrupt that has been generated.
+    The following API has been added for this purpose.
+
+        interrupt_type_handler get_interrupt_type_handler(uint32_t interrupt_type);
+
+    It returns the reference to the registered handler for this interrupt
+    type. The `handler` is retrieved from the `intr_type_desc_t` structure as
+    described in Section 2. `NULL` is returned if no handler has been
+    registered for this type of interrupt. This scenario is reported as an
+    irrecoverable error condition.
+
+6.  Calling the registered handler function for the interrupt type generated.
+    The firmware also determines the interrupt id if the IMF_READ_INTERRUPT_ID
+    build time flag is set. The id is set to `INTR_ID_UNAVAILABLE` if the flag
+    is not set. The id along with the current security state and a reference to
+    the `cpu_context_t` structure for the current security state are passed to
+    the handler function as its arguments.
+
+    The handler function returns a reference to the per-cpu `cpu_context_t`
+    structure for the target security state.
+
+7.  Calling `el3_exit()` to return from EL3 into a lower exception level in
+    the security state determined by the handler routine. The `el3_exit()`
+    function is responsible for restoring the register context from the
+    `cpu_context_t` data structure for the target security state.
+
+
+#### 2.3.2 Secure payload dispatcher
+
+##### 2.3.2.1 Interrupt entry
+The SPD service begins handling an interrupt when the EL3 runtime firmware calls
+the handler function for that type of interrupt. The SPD service is responsible
+for the following:
+
+1.  Validating the interrupt. This involves ensuring that the interrupt was
+    generating according to the interrupt routing model specified by the SPD
+    service during registration. It should use the interrupt id and the
+    security state of the exception level (passed in the `flags` parameter of
+    the handler) where the interrupt was taken from to determine this. If the
+    interrupt is not recognised then the handler should treat it as an
+    irrecoverable error condition.
+
+    A SPD service can register a handler for Secure-EL1 and/or Non-secure
+    interrupts. The following text describes further error scenarios keeping
+    this in mind:
+
+    1.  __SPD service has registered a handler for Non-secure interrupts__:
+        When an interrupt is received by the handler, it could check its id
+        to ensure it has been configured as a non-secure interrupt at the
+        interrupt controller. A secure interrupt should never be handed to
+        the non-secure interrupt handler. A non-secure interrupt should
+        never be routed to EL3 when execution is in non-secure state. The
+        handler could check the security state flag to ensure this.
+
+    2.  __SPD service has registered a handler for Secure-EL1 interrupts__:
+        When an interrupt is received by the handler, it could check its id
+        to ensure it has been configured as a secure interrupt at the
+        interrupt controller. A non-secure interrupt should never be handed
+        to the secure interrupt handler. If the routing model chosen is such
+        that Secure-EL1 interrupts are not routed to EL3 when execution is
+        in non-secure state, then a Secure-EL1 interrupt generated in the
+        secure state would be invalid. The handler could use the security
+        state flag to check this.
+
+    The SPD service should use the platform API:
+    `plat_ic_get_interrupt_type()` to determine the type of interrupt for the
+    specified id.
+
+2.  Determining whether the security state of the exception level for handling
+    the interrupt is the same as the security state of the exception level
+    where the interrupt was generated. This depends upon the routing model and
+    type of the interrupt. The SPD should use this information to determine if
+    a context switch is required. The following two cases would require a
+    context switch from secure to non-secure or vice-versa.
+
+    1.  A Secure-EL1 interrupt taken from the non-secure state should be
+        routed to the Secure Payload.
+
+    2.  A non-secure interrupt taken from the secure state should be routed
+        to the last known non-secure exception level.
+
+    The SPD service must save the system register context of the current
+    security state. It must then restore the system register context of the
+    target security state. It should use the `cm_set_next_eret_context()` API
+    to ensure that the next `cpu_context` to be restored is of the target
+    security state.
+
+    If the target state is secure then execution should be handed to the SP as
+    per the synchronous interrupt handling model it implements. A Secure-EL1
+    interrupt can be routed to EL3 while execution is in the SP. This implies
+    that SP execution can be preempted while handling an interrupt by a
+    another higher priority Secure-EL1 interrupt (or a EL3 interrupt in the
+    future). The SPD service should manage secure interrupt priorities before
+    handing control to the SP to prevent this type of preemption which can
+    leave the system in an inconsistent state.
+
+3.  Setting the return value of the handler to the per-cpu `cpu_context` if
+    the interrupt has been successfully validated and ready to be handled at a
+    lower exception level.
+
+The routing model allows non-secure interrupts to be taken to Secure-EL1 when in
+secure state. The SPD service and the SP should implement a mechanism for
+routing these interrupts to the last known exception level in the non-secure
+state. The former should save the SP context, restore the non-secure context and
+arrange for entry into the non-secure state so that the interrupt can be
+handled.
+
+##### 2.3.2.2 Interrupt exit
+When the Secure Payload has finished handling a Secure-EL1 interrupt, it could
+return control back to the SPD service through a SMC32 or SMC64. The SPD service
+should handle this secure monitor call so that execution resumes in the
+exception level and the security state from where the Secure-EL1 interrupt was
+originally taken.
+
+##### 2.3.2.3 Test secure payload dispatcher behavior
+The example TSPD service registers a handler for Secure-EL1 interrupts taken
+from the non-secure state. Its handler `tspd_secure_el1_interrupt_handler()`
+takes the following actions upon being invoked.
+
+1.  It uses the `id` parameter to query the interrupt controller to ensure
+    that the interrupt is a Secure-EL1 interrupt. It asserts if this is not
+    the case.
+
+2.  It uses the security state provided in the `flags` parameter to ensure
+    that the secure interrupt originated from the non-secure state. It asserts
+    if this is not the case.
+
+3.  It saves the system register context for the non-secure state by calling
+    `cm_el1_sysregs_context_save(NON_SECURE);`.
+
+4.  It sets the `ELR_EL3` system register to `tsp_fiq_entry` and sets the
+    `SPSR_EL3.DAIF` bits in the secure CPU context. It sets `x0` to
+    `TSP_HANDLE_FIQ_AND_RETURN`. If the TSP was in the middle of handling a
+    standard SMC, then the `ELR_EL3` and `SPSR_EL3` registers in the secure CPU
+    context are saved first.
+
+5.  It restores the system register context for the secure state by calling
+    `cm_el1_sysregs_context_restore(SECURE);`.
+
+6.  It ensures that the secure CPU context is used to program the next
+    exception return from EL3 by calling `cm_set_next_eret_context(SECURE);`.
+
+7.  It returns the per-cpu `cpu_context` to indicate that the interrupt can
+    now be handled by the SP. `x1` is written with the value of `elr_el3`
+    register for the non-secure state. This information is used by the SP for
+    debugging purposes.
+
+The figure below describes how the interrupt handling is implemented by the TSPD
+when a Secure-EL1 interrupt is generated when execution is in the non-secure
+state.
+
+![Image 1](diagrams/sec-int-handling.png?raw=true)
+
+The TSP issues an SMC with `TSP_HANDLED_S_EL1_FIQ` as the function identifier to
+signal completion of interrupt handling.
+
+The TSP issues an SMC with `TSP_PREEMPTED` as the function identifier to signal
+generation of a non-secure interrupt in Secure-EL1.
+
+The TSPD service takes the following actions in `tspd_smc_handler()` function
+upon receiving an SMC with `TSP_HANDLED_S_EL1_FIQ` and `TSP_PREEMPTED` as the
+function identifiers:
+
+1.  It ensures that the call originated from the secure state otherwise
+    execution returns to the non-secure state with `SMC_UNK` in `x0`.
+
+2.  If the function identifier is `TSP_HANDLED_S_EL1_FIQ`, it restores the
+    saved `ELR_EL3` and `SPSR_EL3` system registers back to the secure CPU
+    context (see step 4 above) in case the TSP had been preempted by a non
+    secure interrupt earlier.  It does not save the secure context since the
+    TSP is expected to preserve it (see Section 2.2.2.1)
+
+3.  If the function identifier is `TSP_PREEMPTED`, it saves the system
+    register context for the secure state by calling
+    `cm_el1_sysregs_context_save(SECURE)`.
+
+4.  It restores the system register context for the non-secure state by
+    calling `cm_el1_sysregs_context_restore(NON_SECURE)`. It sets `x0` to
+    `SMC_PREEMPTED` if the incoming function identifier is
+    `TSP_PREEMPTED`. The Normal World is expected to resume the TSP after the
+    non-secure interrupt handling by issuing an SMC with `TSP_FID_RESUME` as
+    the function identifier.
+
+5.  It ensures that the non-secure CPU context is used to program the next
+    exception return from EL3 by calling
+    `cm_set_next_eret_context(NON_SECURE)`.
+
+6.  `tspd_smc_handler()` returns a reference to the non-secure `cpu_context`
+    as the return value.
+
+As mentioned in 4. above, if a non-secure interrupt preempts the TSP execution
+then the non-secure software issues an SMC with `TSP_FID_RESUME` as the function
+identifier to resume TSP execution. The TSPD service takes the following actions
+in `tspd_smc_handler()` function upon receiving this SMC:
+
+1.  It ensures that the call originated from the non secure state. An
+    assertion is raised otherwise.
+
+2.  Checks whether the TSP needs a resume i.e check if it was preempted. It
+    then saves the system register context for the secure state by calling
+    `cm_el1_sysregs_context_save(NON_SECURE)`.
+
+3.  Restores the secure context by calling
+    `cm_el1_sysregs_context_restore(SECURE)`
+
+4.  It ensures that the secure CPU context is used to program the next
+    exception return from EL3 by calling `cm_set_next_eret_context(SECURE)`.
+
+5.  `tspd_smc_handler()` returns a reference to the secure `cpu_context` as the
+    return value.
+
+The figure below describes how the TSP/TSPD handle a non-secure interrupt when
+it is generated during execution in the TSP with `PSTATE.I` = 0.
+
+![Image 2](diagrams/non-sec-int-handling.png?raw=true)
+
+
+#### 2.3.3 Secure payload
+The SP should implement one or both of the synchronous and asynchronous
+interrupt handling models depending upon the interrupt routing model it has
+chosen (as described in 2.2.3).
+
+In the synchronous model, it should begin handling a Secure-EL1 interrupt after
+receiving control from the SPD service at an entrypoint agreed upon during build
+time or during the registration phase. Before handling the interrupt, the SP
+should save any Secure-EL1 system register context which is needed for resuming
+normal execution in the SP later e.g. `SPSR_EL1, `ELR_EL1`. After handling the
+interrupt, the SP could return control back to the exception level and security
+state where the interrupt was originally taken from. The SP should use an SMC32
+or SMC64 to ask the SPD service to do this.
+
+In the asynchronous model, the Secure Payload is responsible for handling
+non-secure and Secure-EL1 interrupts at the IRQ and FIQ vectors in its exception
+vector table when `PSTATE.I` and `PSTATE.F` bits are 0. As described earlier,
+when a non-secure interrupt is generated, the SP should coordinate with the SPD
+service to pass control back to the non-secure state in the last known exception
+level. This will allow the non-secure interrupt to be handled in the non-secure
+state.
+
+##### 2.3.3.1 Test secure payload behavior
+The TSPD hands control of a Secure-EL1 interrupt to the TSP at the
+`tsp_fiq_entry()`.  The TSP handles the interrupt while ensuring that the
+handover agreement described in Section 2.2.2.1 is maintained. It updates some
+statistics by calling `tsp_update_sync_fiq_stats()`. It then calls
+`tsp_fiq_handler()` which.
+
+1.  Checks whether the interrupt is the secure physical timer interrupt. It
+    uses the platform API `plat_ic_get_pending_interrupt_id()` to get the
+    interrupt number.
+
+2.   Handles the interrupt by acknowledging it using the
+    `plat_ic_acknowledge_interrupt()` platform API, calling
+    `tsp_generic_timer_handler()` to reprogram the secure physical generic
+    timer and calling the `plat_ic_end_of_interrupt()` platform API to signal
+    end of interrupt processing.
+
+The TSP passes control back to the TSPD by issuing an SMC64 with
+`TSP_HANDLED_S_EL1_FIQ` as the function identifier.
+
+The TSP handles interrupts under the asynchronous model as follows.
+
+1.  Secure-EL1 interrupts are handled by calling the `tsp_fiq_handler()`
+    function. The function has been described above.
+
+2.  Non-secure interrupts are handled by issuing an SMC64 with `TSP_PREEMPTED`
+    as the function identifier. Execution resumes at the instruction that
+    follows this SMC instruction when the TSPD hands control to the TSP in
+    response to an SMC with `TSP_FID_RESUME` as the function identifier from
+    the non-secure state (see section 2.3.2.1).
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2014, ARM Limited and Contributors. All rights reserved._
+
+[Porting Guide]:             ./porting-guide.md
diff --git a/uefi/arm-trusted-firmware/docs/optee-dispatcher.md b/uefi/arm-trusted-firmware/docs/optee-dispatcher.md
new file mode 100644
index 0000000..c154f6b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/optee-dispatcher.md
@@ -0,0 +1,13 @@
+OP-TEE Dispatcher
+=================
+
+[OP-TEE OS] is a Trusted OS running as Secure EL1.
+
+To build and execute [OP-TEE OS] follow the instructions at
+[ARM Trusted Firmware with OP-TEE] [OP-TEE OS]
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2014, ARM Limited and Contributors. All rights reserved._
+
+[OP-TEE OS]:  http://github.com/OP-TEE/optee_os/tree/master/documentation/arm_trusted_firmware.md
diff --git a/uefi/arm-trusted-firmware/docs/porting-guide.md b/uefi/arm-trusted-firmware/docs/porting-guide.md
new file mode 100644
index 0000000..5e85023
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/porting-guide.md
@@ -0,0 +1,1569 @@
+ARM Trusted Firmware Porting Guide
+==================================
+
+Contents
+--------
+
+1.  [Introduction](#1--introduction)
+2.  [Common Modifications](#2--common-modifications)
+    *   [Common mandatory modifications](#21-common-mandatory-modifications)
+    *   [Handling reset](#22-handling-reset)
+    *   [Common optional modifications](#23-common-optional-modifications)
+3.  [Boot Loader stage specific modifications](#3--modifications-specific-to-a-boot-loader-stage)
+    *   [Boot Loader stage 1 (BL1)](#31-boot-loader-stage-1-bl1)
+    *   [Boot Loader stage 2 (BL2)](#32-boot-loader-stage-2-bl2)
+    *   [Boot Loader stage 3-1 (BL3-1)](#32-boot-loader-stage-3-1-bl3-1)
+    *   [PSCI implementation (in BL3-1)](#33-power-state-coordination-interface-in-bl3-1)
+    *   [Interrupt Management framework (in BL3-1)](#34--interrupt-management-framework-in-bl3-1)
+    *   [Crash Reporting mechanism (in BL3-1)](#35--crash-reporting-mechanism-in-bl3-1)
+4.  [Build flags](#4--build-flags)
+5.  [C Library](#5--c-library)
+6.  [Storage abstraction layer](#6--storage-abstraction-layer)
+
+- - - - - - - - - - - - - - - - - -
+
+1.  Introduction
+----------------
+
+Porting the ARM Trusted Firmware to a new platform involves making some
+mandatory and optional modifications for both the cold and warm boot paths.
+Modifications consist of:
+
+*   Implementing a platform-specific function or variable,
+*   Setting up the execution context in a certain way, or
+*   Defining certain constants (for example #defines).
+
+The platform-specific functions and variables are all declared in
+[include/plat/common/platform.h]. The firmware provides a default implementation
+of variables and functions to fulfill the optional requirements. These
+implementations are all weakly defined; they are provided to ease the porting
+effort. Each platform port can override them with its own implementation if the
+default implementation is inadequate.
+
+Some modifications are common to all Boot Loader (BL) stages. Section 2
+discusses these in detail. The subsequent sections discuss the remaining
+modifications for each BL stage in detail.
+
+This document should be read in conjunction with the ARM Trusted Firmware
+[User Guide].
+
+
+2.  Common modifications
+------------------------
+
+This section covers the modifications that should be made by the platform for
+each BL stage to correctly port the firmware stack. They are categorized as
+either mandatory or optional.
+
+
+2.1 Common mandatory modifications
+----------------------------------
+A platform port must enable the Memory Management Unit (MMU) with identity
+mapped page tables, and enable both the instruction and data caches for each BL
+stage. In the ARM FVP port, each BL stage configures the MMU in its platform-
+specific architecture setup function, for example `blX_plat_arch_setup()`.
+
+If the build option `USE_COHERENT_MEM` is enabled, each platform must allocate a
+block of identity mapped secure memory with Device-nGnRE attributes aligned to
+page boundary (4K) for each BL stage. This memory is identified by the section
+name `tzfw_coherent_mem` so that its possible for the firmware to place
+variables in it using the following C code directive:
+
+    __attribute__ ((section("tzfw_coherent_mem")))
+
+Or alternatively the following assembler code directive:
+
+    .section tzfw_coherent_mem
+
+The `tzfw_coherent_mem` section is used to allocate any data structures that are
+accessed both when a CPU is executing with its MMU and caches enabled, and when
+it's running with its MMU and caches disabled. Examples are given below.
+
+The following variables, functions and constants must be defined by the platform
+for the firmware to work correctly.
+
+
+### File : platform_def.h [mandatory]
+
+Each platform must ensure that a header file of this name is in the system
+include path with the following constants defined. This may require updating the
+list of `PLAT_INCLUDES` in the `platform.mk` file. In the ARM FVP port, this
+file is found in [plat/fvp/include/platform_def.h].
+
+*   **#define : PLATFORM_LINKER_FORMAT**
+
+    Defines the linker format used by the platform, for example
+    `elf64-littleaarch64` used by the FVP.
+
+*   **#define : PLATFORM_LINKER_ARCH**
+
+    Defines the processor architecture for the linker by the platform, for
+    example `aarch64` used by the FVP.
+
+*   **#define : PLATFORM_STACK_SIZE**
+
+    Defines the normal stack memory available to each CPU. This constant is used
+    by [plat/common/aarch64/platform_mp_stack.S] and
+    [plat/common/aarch64/platform_up_stack.S].
+
+*   **#define : FIRMWARE_WELCOME_STR**
+
+    Defines the character string printed by BL1 upon entry into the `bl1_main()`
+    function.
+
+*   **#define : BL2_IMAGE_NAME**
+
+    Name of the BL2 binary image on the host file-system. This name is used by
+    BL1 to load BL2 into secure memory from non-volatile storage.
+
+*   **#define : BL31_IMAGE_NAME**
+
+    Name of the BL3-1 binary image on the host file-system. This name is used by
+    BL2 to load BL3-1 into secure memory from platform storage.
+
+*   **#define : BL33_IMAGE_NAME**
+
+    Name of the BL3-3 binary image on the host file-system. This name is used by
+    BL2 to load BL3-3 into non-secure memory from platform storage.
+
+*   **#define : BL2_CERT_NAME**
+
+    Name of the BL2 content certificate on the host file-system (mandatory when
+    Trusted Board Boot is enabled).
+
+*   **#define : TRUSTED_KEY_CERT_NAME**
+
+    Name of the Trusted Key certificate on the host file-system (mandatory when
+    Trusted Board Boot is enabled).
+
+*   **#define : BL31_KEY_CERT_NAME**
+
+    Name of the BL3-1 Key certificate on the host file-system (mandatory when
+    Trusted Board Boot is enabled).
+
+*   **#define : BL31_CERT_NAME**
+
+    Name of the BL3-1 Content certificate on the host file-system (mandatory
+    when Trusted Board Boot is enabled).
+
+*   **#define : BL33_KEY_CERT_NAME**
+
+    Name of the BL3-3 Key certificate on the host file-system (mandatory when
+    Trusted Board Boot is enabled).
+
+*   **#define : BL33_CERT_NAME**
+
+    Name of the BL3-3 Content certificate on the host file-system (mandatory
+    when Trusted Board Boot is enabled).
+
+*   **#define : PLATFORM_CACHE_LINE_SIZE**
+
+    Defines the size (in bytes) of the largest cache line across all the cache
+    levels in the platform.
+
+*   **#define : PLATFORM_CLUSTER_COUNT**
+
+    Defines the total number of clusters implemented by the platform in the
+    system.
+
+*   **#define : PLATFORM_CORE_COUNT**
+
+    Defines the total number of CPUs implemented by the platform across all
+    clusters in the system.
+
+*   **#define : PLATFORM_MAX_CPUS_PER_CLUSTER**
+
+    Defines the maximum number of CPUs that can be implemented within a cluster
+    on the platform.
+
+*   **#define : PLATFORM_NUM_AFFS**
+
+    Defines the total number of nodes in the affinity heirarchy at all affinity
+    levels used by the platform.
+
+*   **#define : BL1_RO_BASE**
+
+    Defines the base address in secure ROM where BL1 originally lives. Must be
+    aligned on a page-size boundary.
+
+*   **#define : BL1_RO_LIMIT**
+
+    Defines the maximum address in secure ROM that BL1's actual content (i.e.
+    excluding any data section allocated at runtime) can occupy.
+
+*   **#define : BL1_RW_BASE**
+
+    Defines the base address in secure RAM where BL1's read-write data will live
+    at runtime. Must be aligned on a page-size boundary.
+
+*   **#define : BL1_RW_LIMIT**
+
+    Defines the maximum address in secure RAM that BL1's read-write data can
+    occupy at runtime.
+
+*   **#define : BL2_BASE**
+
+    Defines the base address in secure RAM where BL1 loads the BL2 binary image.
+    Must be aligned on a page-size boundary.
+
+*   **#define : BL2_LIMIT**
+
+    Defines the maximum address in secure RAM that the BL2 image can occupy.
+
+*   **#define : BL31_BASE**
+
+    Defines the base address in secure RAM where BL2 loads the BL3-1 binary
+    image. Must be aligned on a page-size boundary.
+
+*   **#define : BL31_LIMIT**
+
+    Defines the maximum address in secure RAM that the BL3-1 image can occupy.
+
+*   **#define : NS_IMAGE_OFFSET**
+
+    Defines the base address in non-secure DRAM where BL2 loads the BL3-3 binary
+    image. Must be aligned on a page-size boundary.
+
+If a BL3-0 image is supported by the platform, the following constants must
+also be defined:
+
+*   **#define : BL30_IMAGE_NAME**
+
+    Name of the BL3-0 binary image on the host file-system. This name is used by
+    BL2 to load BL3-0 into secure memory from platform storage before being
+    transfered to the SCP.
+
+*   **#define : BL30_KEY_CERT_NAME**
+
+    Name of the BL3-0 Key certificate on the host file-system (mandatory when
+    Trusted Board Boot is enabled).
+
+*   **#define : BL30_CERT_NAME**
+
+    Name of the BL3-0 Content certificate on the host file-system (mandatory
+    when Trusted Board Boot is enabled).
+
+If a BL3-2 image is supported by the platform, the following constants must
+also be defined:
+
+*   **#define : BL32_IMAGE_NAME**
+
+    Name of the BL3-2 binary image on the host file-system. This name is used by
+    BL2 to load BL3-2 into secure memory from platform storage.
+
+*   **#define : BL32_KEY_CERT_NAME**
+
+    Name of the BL3-2 Key certificate on the host file-system (mandatory when
+    Trusted Board Boot is enabled).
+
+*   **#define : BL32_CERT_NAME**
+
+    Name of the BL3-2 Content certificate on the host file-system (mandatory
+    when Trusted Board Boot is enabled).
+
+*   **#define : BL32_BASE**
+
+    Defines the base address in secure memory where BL2 loads the BL3-2 binary
+    image. Must be aligned on a page-size boundary.
+
+*   **#define : BL32_LIMIT**
+
+    Defines the maximum address that the BL3-2 image can occupy.
+
+If the Test Secure-EL1 Payload (TSP) instantiation of BL3-2 is supported by the
+platform, the following constants must also be defined:
+
+*   **#define : TSP_SEC_MEM_BASE**
+
+    Defines the base address of the secure memory used by the TSP image on the
+    platform. This must be at the same address or below `BL32_BASE`.
+
+*   **#define : TSP_SEC_MEM_SIZE**
+
+    Defines the size of the secure memory used by the BL3-2 image on the
+    platform. `TSP_SEC_MEM_BASE` and `TSP_SEC_MEM_SIZE` must fully accomodate
+    the memory required by the BL3-2 image, defined by `BL32_BASE` and
+    `BL32_LIMIT`.
+
+*   **#define : TSP_IRQ_SEC_PHY_TIMER**
+
+    Defines the ID of the secure physical generic timer interrupt used by the
+    TSP's interrupt handling code.
+
+If the platform port uses the IO storage framework, the following constants
+must also be defined:
+
+*   **#define : MAX_IO_DEVICES**
+
+    Defines the maximum number of registered IO devices. Attempting to register
+    more devices than this value using `io_register_device()` will fail with
+    IO_RESOURCES_EXHAUSTED.
+
+*   **#define : MAX_IO_HANDLES**
+
+    Defines the maximum number of open IO handles. Attempting to open more IO
+    entities than this value using `io_open()` will fail with
+    IO_RESOURCES_EXHAUSTED.
+
+If the platform needs to allocate data within the per-cpu data framework in
+BL3-1, it should define the following macro. Currently this is only required if
+the platform decides not to use the coherent memory section by undefining the
+USE_COHERENT_MEM build flag. In this case, the framework allocates the required
+memory within the the per-cpu data to minimize wastage.
+
+*   **#define : PLAT_PCPU_DATA_SIZE**
+
+    Defines the memory (in bytes) to be reserved within the per-cpu data
+    structure for use by the platform layer.
+
+The following constants are optional. They should be defined when the platform
+memory layout implies some image overlaying like on FVP.
+
+*   **#define : BL31_PROGBITS_LIMIT**
+
+    Defines the maximum address in secure RAM that the BL3-1's progbits sections
+    can occupy.
+
+*   **#define : TSP_PROGBITS_LIMIT**
+
+    Defines the maximum address that the TSP's progbits sections can occupy.
+
+### File : plat_macros.S [mandatory]
+
+Each platform must ensure a file of this name is in the system include path with
+the following macro defined. In the ARM FVP port, this file is found in
+[plat/fvp/include/plat_macros.S].
+
+*   **Macro : plat_print_gic_regs**
+
+    This macro allows the crash reporting routine to print GIC registers
+    in case of an unhandled exception in BL3-1. This aids in debugging and
+    this macro can be defined to be empty in case GIC register reporting is
+    not desired.
+
+*   **Macro : plat_print_interconnect_regs**
+
+    This macro allows the crash reporting routine to print interconnect registers
+    in case of an unhandled exception in BL3-1. This aids in debugging and
+    this macro can be defined to be empty in case interconnect register reporting
+    is not desired. In the ARM FVP port, the CCI snoop control registers are
+    reported.
+
+### Other mandatory modifications
+
+The following mandatory modifications may be implemented in any file
+the implementer chooses. In the ARM FVP port, they are implemented in
+[plat/fvp/aarch64/plat_common.c].
+
+*   **Function : uint64_t plat_get_syscnt_freq(void)**
+
+    This function is used by the architecture setup code to retrieve the
+    counter frequency for the CPU's generic timer.  This value will be
+    programmed into the `CNTFRQ_EL0` register.
+    In the ARM FVP port, it returns the base frequency of the system counter,
+    which is retrieved from the first entry in the frequency modes table.
+
+
+2.2 Handling Reset
+------------------
+
+BL1 by default implements the reset vector where execution starts from a cold
+or warm boot. BL3-1 can be optionally set as a reset vector using the
+RESET_TO_BL31 make variable.
+
+For each CPU, the reset vector code is responsible for the following tasks:
+
+1.  Distinguishing between a cold boot and a warm boot.
+
+2.  In the case of a cold boot and the CPU being a secondary CPU, ensuring that
+    the CPU is placed in a platform-specific state until the primary CPU
+    performs the necessary steps to remove it from this state.
+
+3.  In the case of a warm boot, ensuring that the CPU jumps to a platform-
+    specific address in the BL3-1 image in the same processor mode as it was
+    when released from reset.
+
+The following functions need to be implemented by the platform port to enable
+reset vector code to perform the above tasks.
+
+
+### Function : platform_get_entrypoint() [mandatory]
+
+    Argument : unsigned long
+    Return   : unsigned int
+
+This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The CPU
+is identified by its `MPIDR`, which is passed as the argument. The function is
+responsible for distinguishing between a warm and cold reset using platform-
+specific means. If it's a warm reset then it returns the entrypoint into the
+BL3-1 image that the CPU must jump to. If it's a cold reset then this function
+must return zero.
+
+This function is also responsible for implementing a platform-specific mechanism
+to handle the condition where the CPU has been warm reset but there is no
+entrypoint to jump to.
+
+This function does not follow the Procedure Call Standard used by the
+Application Binary Interface for the ARM 64-bit architecture. The caller should
+not assume that callee saved registers are preserved across a call to this
+function.
+
+This function fulfills requirement 1 and 3 listed above.
+
+
+### Function : plat_secondary_cold_boot_setup() [mandatory]
+
+    Argument : void
+    Return   : void
+
+This function is called with the MMU and data caches disabled. It is responsible
+for placing the executing secondary CPU in a platform-specific state until the
+primary CPU performs the necessary actions to bring it out of that state and
+allow entry into the OS.
+
+In the ARM FVP port, each secondary CPU powers itself off. The primary CPU is
+responsible for powering up the secondary CPU when normal world software
+requires them.
+
+This function fulfills requirement 2 above.
+
+
+### Function : platform_is_primary_cpu() [mandatory]
+
+    Argument : unsigned long
+    Return   : unsigned int
+
+This function identifies a CPU by its `MPIDR`, which is passed as the argument,
+to determine whether this CPU is the primary CPU or a secondary CPU. A return
+value of zero indicates that the CPU is not the primary CPU, while a non-zero
+return value indicates that the CPU is the primary CPU.
+
+
+### Function : platform_mem_init() [mandatory]
+
+    Argument : void
+    Return   : void
+
+This function is called before any access to data is made by the firmware, in
+order to carry out any essential memory initialization.
+
+The ARM FVP port uses this function to initialize the mailbox memory used for
+providing the warm-boot entry-point addresses.
+
+
+### Function: plat_match_rotpk()
+
+    Argument : const unsigned char *, unsigned int
+    Return   : int
+
+This function is mandatory when Trusted Board Boot is enabled. It receives a
+pointer to a buffer containing a signing key and its size as parameters and
+returns 0 (success) if that key matches the ROT (Root Of Trust) key stored in
+the platform. Any other return value means a mismatch.
+
+
+
+2.3 Common optional modifications
+---------------------------------
+
+The following are helper functions implemented by the firmware that perform
+common platform-specific tasks. A platform may choose to override these
+definitions.
+
+
+### Function : platform_get_core_pos()
+
+    Argument : unsigned long
+    Return   : int
+
+A platform may need to convert the `MPIDR` of a CPU to an absolute number, which
+can be used as a CPU-specific linear index into blocks of memory (for example
+while allocating per-CPU stacks). This routine contains a simple mechanism
+to perform this conversion, using the assumption that each cluster contains a
+maximum of 4 CPUs:
+
+    linear index = cpu_id + (cluster_id * 4)
+
+    cpu_id = 8-bit value in MPIDR at affinity level 0
+    cluster_id = 8-bit value in MPIDR at affinity level 1
+
+
+### Function : platform_set_stack()
+
+    Argument : unsigned long
+    Return   : void
+
+This function sets the current stack pointer to the normal memory stack that
+has been allocated for the CPU specificed by MPIDR. For BL images that only
+require a stack for the primary CPU the parameter is ignored. The size of
+the stack allocated to each CPU is specified by the platform defined constant
+`PLATFORM_STACK_SIZE`.
+
+Common implementations of this function for the UP and MP BL images are
+provided in [plat/common/aarch64/platform_up_stack.S] and
+[plat/common/aarch64/platform_mp_stack.S]
+
+
+### Function : platform_get_stack()
+
+    Argument : unsigned long
+    Return   : unsigned long
+
+This function returns the base address of the normal memory stack that
+has been allocated for the CPU specificed by MPIDR. For BL images that only
+require a stack for the primary CPU the parameter is ignored. The size of
+the stack allocated to each CPU is specified by the platform defined constant
+`PLATFORM_STACK_SIZE`.
+
+Common implementations of this function for the UP and MP BL images are
+provided in [plat/common/aarch64/platform_up_stack.S] and
+[plat/common/aarch64/platform_mp_stack.S]
+
+
+### Function : plat_report_exception()
+
+    Argument : unsigned int
+    Return   : void
+
+A platform may need to report various information about its status when an
+exception is taken, for example the current exception level, the CPU security
+state (secure/non-secure), the exception type, and so on. This function is
+called in the following circumstances:
+
+*   In BL1, whenever an exception is taken.
+*   In BL2, whenever an exception is taken.
+
+The default implementation doesn't do anything, to avoid making assumptions
+about the way the platform displays its status information.
+
+This function receives the exception type as its argument. Possible values for
+exceptions types are listed in the [include/runtime_svc.h] header file. Note
+that these constants are not related to any architectural exception code; they
+are just an ARM Trusted Firmware convention.
+
+
+### Function : plat_reset_handler()
+
+    Argument : void
+    Return   : void
+
+A platform may need to do additional initialization after reset. This function
+allows the platform to do the platform specific intializations. Platform
+specific errata workarounds could also be implemented here. The api should
+preserve the values of callee saved registers x19 to x29.
+
+The default implementation doesn't do anything. If a platform needs to override
+the default implementation, refer to the [Firmware Design Guide] for general
+guidelines regarding placement of code in a reset handler.
+
+### Function : plat_disable_acp()
+
+    Argument : void
+    Return   : void
+
+This api allows a platform to disable the Accelerator Coherency Port (if
+present) during a cluster power down sequence. The default weak implementation
+doesn't do anything. Since this api is called during the power down sequence,
+it has restrictions for stack usage and it can use the registers x0 - x17 as
+scratch registers. It should preserve the value in x18 register as it is used
+by the caller to store the return address.
+
+
+3.  Modifications specific to a Boot Loader stage
+-------------------------------------------------
+
+3.1 Boot Loader Stage 1 (BL1)
+-----------------------------
+
+BL1 implements the reset vector where execution starts from after a cold or
+warm boot. For each CPU, BL1 is responsible for the following tasks:
+
+1.  Handling the reset as described in section 2.2
+
+2.  In the case of a cold boot and the CPU being the primary CPU, ensuring that
+    only this CPU executes the remaining BL1 code, including loading and passing
+    control to the BL2 stage.
+
+3.  Loading the BL2 image from non-volatile storage into secure memory at the
+    address specified by the platform defined constant `BL2_BASE`.
+
+4.  Populating a `meminfo` structure with the following information in memory,
+    accessible by BL2 immediately upon entry.
+
+        meminfo.total_base = Base address of secure RAM visible to BL2
+        meminfo.total_size = Size of secure RAM visible to BL2
+        meminfo.free_base  = Base address of secure RAM available for
+                             allocation to BL2
+        meminfo.free_size  = Size of secure RAM available for allocation to BL2
+
+    BL1 places this `meminfo` structure at the beginning of the free memory
+    available for its use. Since BL1 cannot allocate memory dynamically at the
+    moment, its free memory will be available for BL2's use as-is. However, this
+    means that BL2 must read the `meminfo` structure before it starts using its
+    free memory (this is discussed in Section 3.2).
+
+    In future releases of the ARM Trusted Firmware it will be possible for
+    the platform to decide where it wants to place the `meminfo` structure for
+    BL2.
+
+    BL1 implements the `bl1_init_bl2_mem_layout()` function to populate the
+    BL2 `meminfo` structure. The platform may override this implementation, for
+    example if the platform wants to restrict the amount of memory visible to
+    BL2. Details of how to do this are given below.
+
+The following functions need to be implemented by the platform port to enable
+BL1 to perform the above tasks.
+
+
+### Function : bl1_plat_arch_setup() [mandatory]
+
+    Argument : void
+    Return   : void
+
+This function performs any platform-specific and architectural setup that the
+platform requires.  Platform-specific setup might include configuration of
+memory controllers, configuration of the interconnect to allow the cluster
+to service cache snoop requests from another cluster, and so on.
+
+In the ARM FVP port, this function enables CCI snoops into the cluster that the
+primary CPU is part of. It also enables the MMU.
+
+This function helps fulfill requirement 2 above.
+
+
+### Function : bl1_platform_setup() [mandatory]
+
+    Argument : void
+    Return   : void
+
+This function executes with the MMU and data caches enabled. It is responsible
+for performing any remaining platform-specific setup that can occur after the
+MMU and data cache have been enabled.
+
+This function is also responsible for initializing the storage abstraction layer
+which is used to load further bootloader images.
+
+This function helps fulfill requirement 3 above.
+
+
+### Function : bl1_plat_sec_mem_layout() [mandatory]
+
+    Argument : void
+    Return   : meminfo *
+
+This function should only be called on the cold boot path. It executes with the
+MMU and data caches enabled. The pointer returned by this function must point to
+a `meminfo` structure containing the extents and availability of secure RAM for
+the BL1 stage.
+
+    meminfo.total_base = Base address of secure RAM visible to BL1
+    meminfo.total_size = Size of secure RAM visible to BL1
+    meminfo.free_base  = Base address of secure RAM available for allocation
+                         to BL1
+    meminfo.free_size  = Size of secure RAM available for allocation to BL1
+
+This information is used by BL1 to load the BL2 image in secure RAM. BL1 also
+populates a similar structure to tell BL2 the extents of memory available for
+its own use.
+
+This function helps fulfill requirement 3 above.
+
+
+### Function : bl1_init_bl2_mem_layout() [optional]
+
+    Argument : meminfo *, meminfo *, unsigned int, unsigned long
+    Return   : void
+
+BL1 needs to tell the next stage the amount of secure RAM available
+for it to use. This information is populated in a `meminfo`
+structure.
+
+Depending upon where BL2 has been loaded in secure RAM (determined by
+`BL2_BASE`), BL1 calculates the amount of free memory available for BL2 to use.
+BL1 also ensures that its data sections resident in secure RAM are not visible
+to BL2. An illustration of how this is done in the ARM FVP port is given in the
+[User Guide], in the Section "Memory layout on Base FVP".
+
+
+### Function : bl1_plat_set_bl2_ep_info() [mandatory]
+
+    Argument : image_info *, entry_point_info *
+    Return   : void
+
+This function is called after loading BL2 image and it can be used to overwrite
+the entry point set by loader and also set the security state and SPSR which
+represents the entry point system state for BL2.
+
+On FVP, we are setting the security state and the SPSR for the BL2 entrypoint
+
+
+3.2 Boot Loader Stage 2 (BL2)
+-----------------------------
+
+The BL2 stage is executed only by the primary CPU, which is determined in BL1
+using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at
+`BL2_BASE`. BL2 executes in Secure EL1 and is responsible for:
+
+1.  (Optional) Loading the BL3-0 binary image (if present) from platform
+    provided non-volatile storage. To load the BL3-0 image, BL2 makes use of
+    the `meminfo` returned by the `bl2_plat_get_bl30_meminfo()` function.
+    The platform also defines the address in memory where BL3-0 is loaded
+    through the optional constant `BL30_BASE`. BL2 uses this information
+    to determine if there is enough memory to load the BL3-0 image.
+    Subsequent handling of the BL3-0 image is platform-specific and is
+    implemented in the `bl2_plat_handle_bl30()` function.
+    If `BL30_BASE` is not defined then this step is not performed.
+
+2.  Loading the BL3-1 binary image into secure RAM from non-volatile storage. To
+    load the BL3-1 image, BL2 makes use of the `meminfo` structure passed to it
+    by BL1. This structure allows BL2 to calculate how much secure RAM is
+    available for its use. The platform also defines the address in secure RAM
+    where BL3-1 is loaded through the constant `BL31_BASE`. BL2 uses this
+    information to determine if there is enough memory to load the BL3-1 image.
+
+3.  (Optional) Loading the BL3-2 binary image (if present) from platform
+    provided non-volatile storage. To load the BL3-2 image, BL2 makes use of
+    the `meminfo` returned by the `bl2_plat_get_bl32_meminfo()` function.
+    The platform also defines the address in memory where BL3-2 is loaded
+    through the optional constant `BL32_BASE`. BL2 uses this information
+    to determine if there is enough memory to load the BL3-2 image.
+    If `BL32_BASE` is not defined then this and the next step is not performed.
+
+4.  (Optional) Arranging to pass control to the BL3-2 image (if present) that
+    has been pre-loaded at `BL32_BASE`. BL2 populates an `entry_point_info`
+    structure in memory provided by the platform with information about how
+    BL3-1 should pass control to the BL3-2 image.
+
+5.  Loading the normal world BL3-3 binary image into non-secure DRAM from
+    platform storage and arranging for BL3-1 to pass control to this image. This
+    address is determined using the `plat_get_ns_image_entrypoint()` function
+    described below.
+
+6.  BL2 populates an `entry_point_info` structure in memory provided by the
+    platform with information about how BL3-1 should pass control to the
+    other BL images.
+
+The following functions must be implemented by the platform port to enable BL2
+to perform the above tasks.
+
+
+### Function : bl2_early_platform_setup() [mandatory]
+
+    Argument : meminfo *
+    Return   : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU. The arguments to this function is the address of the
+`meminfo` structure populated by BL1.
+
+The platform must copy the contents of the `meminfo` structure into a private
+variable as the original memory may be subsequently overwritten by BL2. The
+copied structure is made available to all BL2 code through the
+`bl2_plat_sec_mem_layout()` function.
+
+
+### Function : bl2_plat_arch_setup() [mandatory]
+
+    Argument : void
+    Return   : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU.
+
+The purpose of this function is to perform any architectural initialization
+that varies across platforms, for example enabling the MMU (since the memory
+map differs across platforms).
+
+
+### Function : bl2_platform_setup() [mandatory]
+
+    Argument : void
+    Return   : void
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initialization in `bl2_plat_arch_setup()`. It is only
+called by the primary CPU.
+
+The purpose of this function is to perform any platform initialization
+specific to BL2. Platform security components are configured if required.
+For the Base FVP the TZC-400 TrustZone controller is configured to only
+grant non-secure access to DRAM. This avoids aliasing between secure and
+non-secure accesses in the TLB and cache - secure execution states can use
+the NS attributes in the MMU translation tables to access the DRAM.
+
+This function is also responsible for initializing the storage abstraction layer
+which is used to load further bootloader images.
+
+
+### Function : bl2_plat_sec_mem_layout() [mandatory]
+
+    Argument : void
+    Return   : meminfo *
+
+This function should only be called on the cold boot path. It may execute with
+the MMU and data caches enabled if the platform port does the necessary
+initialization in `bl2_plat_arch_setup()`. It is only called by the primary CPU.
+
+The purpose of this function is to return a pointer to a `meminfo` structure
+populated with the extents of secure RAM available for BL2 to use. See
+`bl2_early_platform_setup()` above.
+
+
+### Function : bl2_plat_get_bl30_meminfo() [mandatory]
+
+    Argument : meminfo *
+    Return   : void
+
+This function is used to get the memory limits where BL2 can load the
+BL3-0 image. The meminfo provided by this is used by load_image() to
+validate whether the BL3-0 image can be loaded within the given
+memory from the given base.
+
+
+### Function : bl2_plat_handle_bl30() [mandatory]
+
+    Argument : image_info *
+    Return   : int
+
+This function is called after loading BL3-0 image and it is used to perform any
+platform-specific actions required to handle the SCP firmware. Typically it
+transfers the image into SCP memory using a platform-specific protocol and waits
+until SCP executes it and signals to the Application Processor (AP) for BL2
+execution to continue.
+
+This function returns 0 on success, a negative error code otherwise.
+
+
+### Function : bl2_plat_get_bl31_params() [mandatory]
+
+    Argument : void
+    Return   : bl31_params *
+
+BL2 platform code needs to return a pointer to a `bl31_params` structure it
+will use for passing information to BL3-1. The `bl31_params` structure carries
+the following information.
+    - Header describing the version information for interpreting the bl31_param
+      structure
+    - Information about executing the BL3-3 image in the `bl33_ep_info` field
+    - Information about executing the BL3-2 image in the `bl32_ep_info` field
+    - Information about the type and extents of BL3-1 image in the
+      `bl31_image_info` field
+    - Information about the type and extents of BL3-2 image in the
+      `bl32_image_info` field
+    - Information about the type and extents of BL3-3 image in the
+      `bl33_image_info` field
+
+The memory pointed by this structure and its sub-structures should be
+accessible from BL3-1 initialisation code. BL3-1 might choose to copy the
+necessary content, or maintain the structures until BL3-3 is initialised.
+
+
+### Funtion : bl2_plat_get_bl31_ep_info() [mandatory]
+
+    Argument : void
+    Return   : entry_point_info *
+
+BL2 platform code returns a pointer which is used to populate the entry point
+information for BL3-1 entry point. The location pointed by it should be
+accessible from BL1 while processing the synchronous exception to run to BL3-1.
+
+On FVP this is allocated inside an bl2_to_bl31_params_mem structure which
+is allocated at an address pointed by PARAMS_BASE.
+
+
+### Function : bl2_plat_set_bl31_ep_info() [mandatory]
+
+    Argument : image_info *, entry_point_info *
+    Return   : void
+
+This function is called after loading BL3-1 image and it can be used to
+overwrite the entry point set by loader and also set the security state
+and SPSR which represents the entry point system state for BL3-1.
+
+On FVP, we are setting the security state and the SPSR for the BL3-1
+entrypoint.
+
+### Function : bl2_plat_set_bl32_ep_info() [mandatory]
+
+    Argument : image_info *, entry_point_info *
+    Return   : void
+
+This function is called after loading BL3-2 image and it can be used to
+overwrite the entry point set by loader and also set the security state
+and SPSR which represents the entry point system state for BL3-2.
+
+On FVP, we are setting the security state and the SPSR for the BL3-2
+entrypoint
+
+### Function : bl2_plat_set_bl33_ep_info() [mandatory]
+
+    Argument : image_info *, entry_point_info *
+    Return   : void
+
+This function is called after loading BL3-3 image and it can be used to
+overwrite the entry point set by loader and also set the security state
+and SPSR which represents the entry point system state for BL3-3.
+
+On FVP, we are setting the security state and the SPSR for the BL3-3
+entrypoint
+
+### Function : bl2_plat_get_bl32_meminfo() [mandatory]
+
+    Argument : meminfo *
+    Return   : void
+
+This function is used to get the memory limits where BL2 can load the
+BL3-2 image. The meminfo provided by this is used by load_image() to
+validate whether the BL3-2 image can be loaded with in the given
+memory from the given base.
+
+### Function : bl2_plat_get_bl33_meminfo() [mandatory]
+
+    Argument : meminfo *
+    Return   : void
+
+This function is used to get the memory limits where BL2 can load the
+BL3-3 image. The meminfo provided by this is used by load_image() to
+validate whether the BL3-3 image can be loaded with in the given
+memory from the given base.
+
+### Function : bl2_plat_flush_bl31_params() [mandatory]
+
+    Argument : void
+    Return   : void
+
+Once BL2 has populated all the structures that needs to be read by BL1
+and BL3-1 including the bl31_params structures and its sub-structures,
+the bl31_ep_info structure and any platform specific data. It flushes
+all these data to the main memory so that it is available when we jump to
+later Bootloader stages with MMU off
+
+### Function : plat_get_ns_image_entrypoint() [mandatory]
+
+    Argument : void
+    Return   : unsigned long
+
+As previously described, BL2 is responsible for arranging for control to be
+passed to a normal world BL image through BL3-1. This function returns the
+entrypoint of that image, which BL3-1 uses to jump to it.
+
+BL2 is responsible for loading the normal world BL3-3 image (e.g. UEFI).
+
+
+3.2 Boot Loader Stage 3-1 (BL3-1)
+---------------------------------
+
+During cold boot, the BL3-1 stage is executed only by the primary CPU. This is
+determined in BL1 using the `platform_is_primary_cpu()` function. BL1 passes
+control to BL3-1 at `BL31_BASE`. During warm boot, BL3-1 is executed by all
+CPUs. BL3-1 executes at EL3 and is responsible for:
+
+1.  Re-initializing all architectural and platform state. Although BL1 performs
+    some of this initialization, BL3-1 remains resident in EL3 and must ensure
+    that EL3 architectural and platform state is completely initialized. It
+    should make no assumptions about the system state when it receives control.
+
+2.  Passing control to a normal world BL image, pre-loaded at a platform-
+    specific address by BL2. BL3-1 uses the `entry_point_info` structure that BL2
+    populated in memory to do this.
+
+3.  Providing runtime firmware services. Currently, BL3-1 only implements a
+    subset of the Power State Coordination Interface (PSCI) API as a runtime
+    service. See Section 3.3 below for details of porting the PSCI
+    implementation.
+
+4.  Optionally passing control to the BL3-2 image, pre-loaded at a platform-
+    specific address by BL2. BL3-1 exports a set of apis that allow runtime
+    services to specify the security state in which the next image should be
+    executed and run the corresponding image. BL3-1 uses the `entry_point_info`
+    structure populated by BL2 to do this.
+
+If BL3-1 is a reset vector, It also needs to handle the reset as specified in
+section 2.2 before the tasks described above.
+
+The following functions must be implemented by the platform port to enable BL3-1
+to perform the above tasks.
+
+
+### Function : bl31_early_platform_setup() [mandatory]
+
+    Argument : bl31_params *, void *
+    Return   : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU. The arguments to this function are:
+
+*   The address of the `bl31_params` structure populated by BL2.
+*   An opaque pointer that the platform may use as needed.
+
+The platform can copy the contents of the `bl31_params` structure and its
+sub-structures into private variables if the original memory may be
+subsequently overwritten by BL3-1 and similarly the `void *` pointing
+to the platform data also needs to be saved.
+
+On the ARM FVP port, BL2 passes a pointer to a `bl31_params` structure populated
+in the secure DRAM at address `0x6000000` in the bl31_params * argument and it
+does not use opaque pointer mentioned earlier. BL3-1 does not copy this
+information to internal data structures as it guarantees that the secure
+DRAM memory will not be overwritten. It maintains an internal reference to this
+information in the `bl2_to_bl31_params` variable.
+
+### Function : bl31_plat_arch_setup() [mandatory]
+
+    Argument : void
+    Return   : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU.
+
+The purpose of this function is to perform any architectural initialization
+that varies across platforms, for example enabling the MMU (since the memory
+map differs across platforms).
+
+
+### Function : bl31_platform_setup() [mandatory]
+
+    Argument : void
+    Return   : void
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initialization in `bl31_plat_arch_setup()`. It is only
+called by the primary CPU.
+
+The purpose of this function is to complete platform initialization so that both
+BL3-1 runtime services and normal world software can function correctly.
+
+The ARM FVP port does the following:
+*   Initializes the generic interrupt controller.
+*   Configures the CLCD controller.
+*   Enables system-level implementation of the generic timer counter.
+*   Grants access to the system counter timer module
+*   Initializes the FVP power controller device
+*   Detects the system topology.
+
+
+### Function : bl31_get_next_image_info() [mandatory]
+
+    Argument : unsigned int
+    Return   : entry_point_info *
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initializations in `bl31_plat_arch_setup()`.
+
+This function is called by `bl31_main()` to retrieve information provided by
+BL2 for the next image in the security state specified by the argument. BL3-1
+uses this information to pass control to that image in the specified security
+state. This function must return a pointer to the `entry_point_info` structure
+(that was copied during `bl31_early_platform_setup()`) if the image exists. It
+should return NULL otherwise.
+
+
+3.3 Power State Coordination Interface (in BL3-1)
+------------------------------------------------
+
+The ARM Trusted Firmware's implementation of the PSCI API is based around the
+concept of an _affinity instance_. Each _affinity instance_ can be uniquely
+identified in a system by a CPU ID (the processor `MPIDR` is used in the PSCI
+interface) and an _affinity level_. A processing element (for example, a
+CPU) is at level 0. If the CPUs in the system are described in a tree where the
+node above a CPU is a logical grouping of CPUs that share some state, then
+affinity level 1 is that group of CPUs (for example, a cluster), and affinity
+level 2 is a group of clusters (for example, the system). The implementation
+assumes that the affinity level 1 ID can be computed from the affinity level 0
+ID (for example, a unique cluster ID can be computed from the CPU ID). The
+current implementation computes this on the basis of the recommended use of
+`MPIDR` affinity fields in the ARM Architecture Reference Manual.
+
+BL3-1's platform initialization code exports a pointer to the platform-specific
+power management operations required for the PSCI implementation to function
+correctly. This information is populated in the `plat_pm_ops` structure. The
+PSCI implementation calls members of the `plat_pm_ops` structure for performing
+power management operations for each affinity instance. For example, the target
+CPU is specified by its `MPIDR` in a PSCI `CPU_ON` call. The `affinst_on()`
+handler (if present) is called for each affinity instance as the PSCI
+implementation powers up each affinity level implemented in the `MPIDR` (for
+example, CPU, cluster and system).
+
+The following functions must be implemented to initialize PSCI functionality in
+the ARM Trusted Firmware.
+
+
+### Function : plat_get_aff_count() [mandatory]
+
+    Argument : unsigned int, unsigned long
+    Return   : unsigned int
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
+called by the primary CPU.
+
+This function is called by the PSCI initialization code to detect the system
+topology. Its purpose is to return the number of affinity instances implemented
+at a given `affinity level` (specified by the first argument) and a given
+`MPIDR` (specified by the second argument). For example, on a dual-cluster
+system where first cluster implements 2 CPUs and the second cluster implements 4
+CPUs, a call to this function with an `MPIDR` corresponding to the first cluster
+(`0x0`) and affinity level 0, would return 2. A call to this function with an
+`MPIDR` corresponding to the second cluster (`0x100`) and affinity level 0,
+would return 4.
+
+
+### Function : plat_get_aff_state() [mandatory]
+
+    Argument : unsigned int, unsigned long
+    Return   : unsigned int
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
+called by the primary CPU.
+
+This function is called by the PSCI initialization code. Its purpose is to
+return the state of an affinity instance. The affinity instance is determined by
+the affinity ID at a given `affinity level` (specified by the first argument)
+and an `MPIDR` (specified by the second argument). The state can be one of
+`PSCI_AFF_PRESENT` or `PSCI_AFF_ABSENT`. The latter state is used to cater for
+system topologies where certain affinity instances are unimplemented. For
+example, consider a platform that implements a single cluster with 4 CPUs and
+another CPU implemented directly on the interconnect with the cluster. The
+`MPIDR`s of the cluster would range from `0x0-0x3`. The `MPIDR` of the single
+CPU would be 0x100 to indicate that it does not belong to cluster 0. Cluster 1
+is missing but needs to be accounted for to reach this single CPU in the
+topology tree. Hence it is marked as `PSCI_AFF_ABSENT`.
+
+
+### Function : plat_get_max_afflvl() [mandatory]
+
+    Argument : void
+    Return   : int
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
+called by the primary CPU.
+
+This function is called by the PSCI implementation both during cold and warm
+boot, to determine the maximum affinity level that the power management
+operations should apply to. ARMv8-A has support for 4 affinity levels. It is
+likely that hardware will implement fewer affinity levels. This function allows
+the PSCI implementation to consider only those affinity levels in the system
+that the platform implements. For example, the Base AEM FVP implements two
+clusters with a configurable number of CPUs. It reports the maximum affinity
+level as 1, resulting in PSCI power control up to the cluster level.
+
+
+### Function : platform_setup_pm() [mandatory]
+
+    Argument : const plat_pm_ops **
+    Return   : int
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
+called by the primary CPU.
+
+This function is called by PSCI initialization code. Its purpose is to export
+handler routines for platform-specific power management actions by populating
+the passed pointer with a pointer to BL3-1's private `plat_pm_ops` structure.
+
+A description of each member of this structure is given below. Please refer to
+the ARM FVP specific implementation of these handlers in [plat/fvp/fvp_pm.c]
+as an example. A platform port is expected to implement these handlers if the
+corresponding PSCI operation is to be supported and these handlers are expected
+to succeed if the return type is `void`.
+
+#### plat_pm_ops.affinst_standby()
+
+Perform the platform-specific setup to enter the standby state indicated by the
+passed argument. The generic code expects the handler to succeed.
+
+#### plat_pm_ops.affinst_on()
+
+Perform the platform specific setup to power on an affinity instance, specified
+by the `MPIDR` (first argument) and `affinity level` (third argument). The
+`state` (fourth argument) contains the current state of that affinity instance
+(ON or OFF). This is useful to determine whether any action must be taken. For
+example, while powering on a CPU, the cluster that contains this CPU might
+already be in the ON state. The platform decides what actions must be taken to
+transition from the current state to the target state (indicated by the power
+management operation). The generic code expects the platform to return
+E_SUCCESS on success or E_INTERN_FAIL for any failure.
+
+#### plat_pm_ops.affinst_off()
+
+Perform the platform specific setup to power off an affinity instance of the
+calling CPU. It is called by the PSCI `CPU_OFF` API implementation.
+
+The `affinity level` (first argument) and `state` (second argument) have
+a similar meaning as described in the `affinst_on()` operation. They are
+used to identify the affinity instance on which the call is made and its
+current state. This gives the platform port an indication of the
+state transition it must make to perform the requested action. For example, if
+the calling CPU is the last powered on CPU in the cluster, after powering down
+affinity level 0 (CPU), the platform port should power down affinity level 1
+(the cluster) as well. The generic code expects the handler to succeed.
+
+#### plat_pm_ops.affinst_suspend()
+
+Perform the platform specific setup to power off an affinity instance of the
+calling CPU. It is called by the PSCI `CPU_SUSPEND` API and `SYSTEM_SUSPEND`
+API implementation
+
+The `affinity level` (second argument) and `state` (third argument) have a
+similar meaning as described in the `affinst_on()` operation. They are used to
+identify the affinity instance on which the call is made and its current state.
+This gives the platform port an indication of the state transition it must
+make to perform the requested action. For example, if the calling CPU is the
+last powered on CPU in the cluster, after powering down affinity level 0 (CPU),
+the platform port should power down affinity level 1 (the cluster) as well.
+
+The difference between turning an affinity instance off versus suspending it
+is that in the former case, the affinity instance is expected to re-initialize
+its state when its next powered on (see `affinst_on_finish()`). In the latter
+case, the affinity instance is expected to save enough state so that it can
+resume execution by restoring this state when its powered on (see
+`affinst_suspend_finish()`).The generic code expects the handler to succeed.
+
+#### plat_pm_ops.affinst_on_finish()
+
+This function is called by the PSCI implementation after the calling CPU is
+powered on and released from reset in response to an earlier PSCI `CPU_ON` call.
+It performs the platform-specific setup required to initialize enough state for
+this CPU to enter the normal world and also provide secure runtime firmware
+services.
+
+The `affinity level` (first argument) and `state` (second argument) have a
+similar meaning as described in the previous operations. The generic code
+expects the handler to succeed.
+
+#### plat_pm_ops.affinst_suspend_finish()
+
+This function is called by the PSCI implementation after the calling CPU is
+powered on and released from reset in response to an asynchronous wakeup
+event, for example a timer interrupt that was programmed by the CPU during the
+`CPU_SUSPEND` call or `SYSTEM_SUSPEND` call. It performs the platform-specific
+setup required to restore the saved state for this CPU to resume execution
+in the normal world and also provide secure runtime firmware services.
+
+The `affinity level` (first argument) and `state` (second argument) have a
+similar meaning as described in the previous operations. The generic code
+expects the platform to succeed.
+
+#### plat_pm_ops.validate_power_state()
+
+This function is called by the PSCI implementation during the `CPU_SUSPEND`
+call to validate the `power_state` parameter of the PSCI API. If the
+`power_state` is known to be invalid, the platform must return
+PSCI_E_INVALID_PARAMS as error, which is propagated back to the normal
+world PSCI client.
+
+#### plat_pm_ops.validate_ns_entrypoint()
+
+This function is called by the PSCI implementation during the `CPU_SUSPEND`,
+`SYSTEM_SUSPEND` and `CPU_ON` calls to validate the non-secure `entry_point`
+parameter passed by the normal world. If the `entry_point` is known to be
+invalid, the platform must return PSCI_E_INVALID_PARAMS as error, which is
+propagated back to the normal world PSCI client.
+
+#### plat_pm_ops.get_sys_suspend_power_state()
+
+This function is called by the PSCI implementation during the `SYSTEM_SUSPEND`
+call to return the `power_state` parameter. This allows the platform to encode
+the appropriate State-ID field within the `power_state` parameter which can be
+utilized in `affinst_suspend()` to suspend to system affinity level. The
+`power_state` parameter should be in the same format as specified by the
+PSCI specification for the CPU_SUSPEND API.
+
+BL3-1 platform initialization code must also detect the system topology and
+the state of each affinity instance in the topology. This information is
+critical for the PSCI runtime service to function correctly. More details are
+provided in the description of the `plat_get_aff_count()` and
+`plat_get_aff_state()` functions above.
+
+3.4  Interrupt Management framework (in BL3-1)
+----------------------------------------------
+BL3-1 implements an Interrupt Management Framework (IMF) to manage interrupts
+generated in either security state and targeted to EL1 or EL2 in the non-secure
+state or EL3/S-EL1 in the secure state.  The design of this framework is
+described in the [IMF Design Guide]
+
+A platform should export the following APIs to support the IMF. The following
+text briefly describes each api and its implementation on the FVP port. The API
+implementation depends upon the type of interrupt controller present in the
+platform. The FVP implements an ARM Generic Interrupt Controller (ARM GIC) as
+per the version 2.0 of the [ARM GIC Architecture Specification]
+
+### Function : plat_interrupt_type_to_line() [mandatory]
+
+    Argument : uint32_t, uint32_t
+    Return   : uint32_t
+
+The ARM processor signals an interrupt exception either through the IRQ or FIQ
+interrupt line. The specific line that is signaled depends on how the interrupt
+controller (IC) reports different interrupt types from an execution context in
+either security state. The IMF uses this API to determine which interrupt line
+the platform IC uses to signal each type of interrupt supported by the framework
+from a given security state.
+
+The first parameter will be one of the `INTR_TYPE_*` values (see [IMF Design
+Guide]) indicating the target type of the interrupt, the second parameter is the
+security state of the originating execution context. The return result is the
+bit position in the `SCR_EL3` register of the respective interrupt trap: IRQ=1,
+FIQ=2.
+
+The FVP port configures the ARM GIC to signal S-EL1 interrupts as FIQs and
+Non-secure interrupts as IRQs from either security state.
+
+
+### Function : plat_ic_get_pending_interrupt_type() [mandatory]
+
+    Argument : void
+    Return   : uint32_t
+
+This API returns the type of the highest priority pending interrupt at the
+platform IC. The IMF uses the interrupt type to retrieve the corresponding
+handler function. `INTR_TYPE_INVAL` is returned when there is no interrupt
+pending. The valid interrupt types that can be returned are `INTR_TYPE_EL3`,
+`INTR_TYPE_S_EL1` and `INTR_TYPE_NS`.
+
+The FVP port reads the _Highest Priority Pending Interrupt Register_
+(`GICC_HPPIR`) to determine the id of the pending interrupt. The type of interrupt
+depends upon the id value as follows.
+
+1. id < 1022 is reported as a S-EL1 interrupt
+2. id = 1022 is reported as a Non-secure interrupt.
+3. id = 1023 is reported as an invalid interrupt type.
+
+
+### Function : plat_ic_get_pending_interrupt_id() [mandatory]
+
+    Argument : void
+    Return   : uint32_t
+
+This API returns the id of the highest priority pending interrupt at the
+platform IC. The IMF passes the id returned by this API to the registered
+handler for the pending interrupt if the `IMF_READ_INTERRUPT_ID` build time flag
+is set. INTR_ID_UNAVAILABLE is returned when there is no interrupt pending.
+
+The FVP port reads the _Highest Priority Pending Interrupt Register_
+(`GICC_HPPIR`) to determine the id of the pending interrupt. The id that is
+returned by API depends upon the value of the id read from the interrupt
+controller as follows.
+
+1. id < 1022. id is returned as is.
+2. id = 1022. The _Aliased Highest Priority Pending Interrupt Register_
+   (`GICC_AHPPIR`) is read to determine the id of the non-secure interrupt. This
+   id is returned by the API.
+3. id = 1023. `INTR_ID_UNAVAILABLE` is returned.
+
+
+### Function : plat_ic_acknowledge_interrupt() [mandatory]
+
+    Argument : void
+    Return   : uint32_t
+
+This API is used by the CPU to indicate to the platform IC that processing of
+the highest pending interrupt has begun. It should return the id of the
+interrupt which is being processed.
+
+The FVP port reads the _Interrupt Acknowledge Register_ (`GICC_IAR`). This
+changes the state of the highest priority pending interrupt from pending to
+active in the interrupt controller. It returns the value read from the
+`GICC_IAR`. This value is the id of the interrupt whose state has been changed.
+
+The TSP uses this API to start processing of the secure physical timer
+interrupt.
+
+
+### Function : plat_ic_end_of_interrupt() [mandatory]
+
+    Argument : uint32_t
+    Return   : void
+
+This API is used by the CPU to indicate to the platform IC that processing of
+the interrupt corresponding to the id (passed as the parameter) has
+finished. The id should be the same as the id returned by the
+`plat_ic_acknowledge_interrupt()` API.
+
+The FVP port writes the id to the _End of Interrupt Register_
+(`GICC_EOIR`). This deactivates the corresponding interrupt in the interrupt
+controller.
+
+The TSP uses this API to finish processing of the secure physical timer
+interrupt.
+
+
+### Function : plat_ic_get_interrupt_type() [mandatory]
+
+    Argument : uint32_t
+    Return   : uint32_t
+
+This API returns the type of the interrupt id passed as the parameter.
+`INTR_TYPE_INVAL` is returned if the id is invalid. If the id is valid, a valid
+interrupt type (one of `INTR_TYPE_EL3`, `INTR_TYPE_S_EL1` and `INTR_TYPE_NS`) is
+returned depending upon how the interrupt has been configured by the platform
+IC.
+
+The FVP port configures S-EL1 interrupts as Group0 interrupts and Non-secure
+interrupts as Group1 interrupts. It reads the group value corresponding to the
+interrupt id from the relevant _Interrupt Group Register_ (`GICD_IGROUPRn`). It
+uses the group value to determine the type of interrupt.
+
+3.5  Crash Reporting mechanism (in BL3-1)
+----------------------------------------------
+BL3-1 implements a crash reporting mechanism which prints the various registers
+of the CPU to enable quick crash analysis and debugging. It requires that a
+console is designated as the crash console by the platform which will be used to
+print the register dump.
+
+The following functions must be implemented by the platform if it wants crash
+reporting mechanism in BL3-1. The functions are implemented in assembly so that
+they can be invoked without a C Runtime stack.
+
+### Function : plat_crash_console_init
+
+    Argument : void
+    Return   : int
+
+This API is used by the crash reporting mechanism to initialize the crash
+console. It should only use the general purpose registers x0 to x2 to do the
+initialization and returns 1 on success.
+
+The FVP port designates the `PL011_UART0` as the crash console and calls the
+console_core_init() to initialize the console.
+
+### Function : plat_crash_console_putc
+
+    Argument : int
+    Return   : int
+
+This API is used by the crash reporting mechanism to print a character on the
+designated crash console. It should only use general purpose registers x1 and
+x2 to do its work. The parameter and the return value are in general purpose
+register x0.
+
+The FVP port designates the `PL011_UART0` as the crash console and calls the
+console_core_putc() to print the character on the console.
+
+4.  Build flags
+---------------
+
+There are some build flags which can be defined by the platform to control
+inclusion or exclusion of certain BL stages from the FIP image. These flags
+need to be defined in the platform makefile which will get included by the
+build system.
+
+*   **NEED_BL30**
+    This flag if defined by the platform mandates that a BL3-0 binary should
+    be included in the FIP image. The path to the BL3-0 binary can be specified
+    by the `BL30` build option (see build options in the [User Guide]).
+
+*   **NEED_BL33**
+    By default, this flag is defined `yes` by the build system and `BL33`
+    build option should be supplied as a build option. The platform has the option
+    of excluding the BL3-3 image in the `fip` image by defining this flag to
+    `no`.
+
+5.  C Library
+-------------
+
+To avoid subtle toolchain behavioral dependencies, the header files provided
+by the compiler are not used. The software is built with the `-nostdinc` flag
+to ensure no headers are included from the toolchain inadvertently. Instead the
+required headers are included in the ARM Trusted Firmware source tree. The
+library only contains those C library definitions required by the local
+implementation. If more functionality is required, the needed library functions
+will need to be added to the local implementation.
+
+Versions of [FreeBSD] headers can be found in `include/stdlib`. Some of these
+headers have been cut down in order to simplify the implementation. In order to
+minimize changes to the header files, the [FreeBSD] layout has been maintained.
+The generic C library definitions can be found in `include/stdlib` with more
+system and machine specific declarations in `include/stdlib/sys` and
+`include/stdlib/machine`.
+
+The local C library implementations can be found in `lib/stdlib`. In order to
+extend the C library these files may need to be modified. It is recommended to
+use a release version of [FreeBSD] as a starting point.
+
+The C library header files in the [FreeBSD] source tree are located in the
+`include` and `sys/sys` directories. [FreeBSD] machine specific definitions
+can be found in the `sys/<machine-type>` directories. These files define things
+like 'the size of a pointer' and 'the range of an integer'. Since an AArch64
+port for [FreeBSD] does not yet exist, the machine specific definitions are
+based on existing machine types with similar properties (for example SPARC64).
+
+Where possible, C library function implementations were taken from [FreeBSD]
+as found in the `lib/libc` directory.
+
+A copy of the [FreeBSD] sources can be downloaded with `git`.
+
+    git clone git://github.com/freebsd/freebsd.git -b origin/release/9.2.0
+
+
+6.  Storage abstraction layer
+-----------------------------
+
+In order to improve platform independence and portability an storage abstraction
+layer is used to load data from non-volatile platform storage.
+
+Each platform should register devices and their drivers via the Storage layer.
+These drivers then need to be initialized by bootloader phases as
+required in their respective `blx_platform_setup()` functions.  Currently
+storage access is only required by BL1 and BL2 phases. The `load_image()`
+function uses the storage layer to access non-volatile platform storage.
+
+It is mandatory to implement at least one storage driver. For the FVP the
+Firmware Image Package(FIP) driver is provided as the default means to load data
+from storage (see the "Firmware Image Package" section in the [User Guide]).
+The storage layer is described in the header file
+`include/drivers/io/io_storage.h`.  The implementation of the common library
+is in `drivers/io/io_storage.c` and the driver files are located in
+`drivers/io/`.
+
+Each IO driver must provide `io_dev_*` structures, as described in
+`drivers/io/io_driver.h`.  These are returned via a mandatory registration
+function that is called on platform initialization.  The semi-hosting driver
+implementation in `io_semihosting.c` can be used as an example.
+
+The Storage layer provides mechanisms to initialize storage devices before
+IO operations are called.  The basic operations supported by the layer
+include `open()`, `close()`, `read()`, `write()`, `size()` and `seek()`.
+Drivers do not have to implement all operations, but each platform must
+provide at least one driver for a device capable of supporting generic
+operations such as loading a bootloader image.
+
+The current implementation only allows for known images to be loaded by the
+firmware.  These images are specified by using their names, as defined in
+[include/plat/common/platform.h]. The platform layer (`plat_get_image_source()`)
+then returns a reference to a device and a driver-specific `spec` which will be
+understood by the driver to allow access to the image data.
+
+The layer is designed in such a way that is it possible to chain drivers with
+other drivers.  For example, file-system drivers may be implemented on top of
+physical block devices, both represented by IO devices with corresponding
+drivers.  In such a case, the file-system "binding" with the block device may
+be deferred until the file-system device is initialised.
+
+The abstraction currently depends on structures being statically allocated
+by the drivers and callers, as the system does not yet provide a means of
+dynamically allocating memory.  This may also have the affect of limiting the
+amount of open resources per driver.
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._
+
+
+[ARM GIC Architecture Specification]: http://arminfo.emea.arm.com/help/topic/com.arm.doc.ihi0048b/IHI0048B_gic_architecture_specification.pdf
+[IMF Design Guide]:                   interrupt-framework-design.md
+[User Guide]:                         user-guide.md
+[FreeBSD]:                            http://www.freebsd.org
+[Firmware Design Guide]:              firmware-design.md
+
+[plat/common/aarch64/platform_mp_stack.S]: ../plat/common/aarch64/platform_mp_stack.S
+[plat/common/aarch64/platform_up_stack.S]: ../plat/common/aarch64/platform_up_stack.S
+[plat/fvp/include/platform_def.h]:         ../plat/fvp/include/platform_def.h
+[plat/fvp/include/plat_macros.S]:          ../plat/fvp/include/plat_macros.S
+[plat/fvp/aarch64/plat_common.c]:          ../plat/fvp/aarch64/plat_common.c
+[plat/fvp/plat_pm.c]:                      ../plat/fvp/plat_pm.c
+[include/runtime_svc.h]:                   ../include/runtime_svc.h
+[include/plat/common/platform.h]:          ../include/plat/common/platform.h
diff --git a/uefi/arm-trusted-firmware/docs/rt-svc-writers-guide.md b/uefi/arm-trusted-firmware/docs/rt-svc-writers-guide.md
new file mode 100644
index 0000000..13f5310
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/rt-svc-writers-guide.md
@@ -0,0 +1,309 @@
+EL3 Runtime Service Writers Guide for ARM Trusted Firmware
+==========================================================
+
+Contents
+--------
+
+1.  [Introduction](#1--introduction)
+2.  [Owning Entities, Call Types and Function IDs](#2--owning-entities-call-types-and-function-ids)
+3.  [Getting started](#3--getting-started)
+4.  [Registering a runtime service](#4--registering-a-runtime-service)
+5.  [Initializing a runtime service](#5-initializing-a-runtime-service)
+6.  [Handling runtime service requests](#6--handling-runtime-service-requests)
+7.  [Services that contain multiple sub-services](#7--services-that-contain-multiple-sub-services)
+8.  [Secure-EL1 Payload Dispatcher service (SPD)](#8--secure-el1-payload-dispatcher-service-spd)
+
+- - - - - - - - - - - - - - - - - -
+
+1.  Introduction
+----------------
+
+This document describes how to add a runtime service to the EL3 Runtime
+Firmware component of ARM Trusted Firmware (BL3-1).
+
+Software executing in the normal world and in the trusted world at exception
+levels lower than EL3 will request runtime services using the Secure Monitor
+Call (SMC) instruction. These requests will follow the convention described in
+the SMC Calling Convention PDD ([SMCCC]). The [SMCCC] assigns function
+identifiers to each SMC request and describes how arguments are passed and
+results are returned.
+
+SMC Functions are grouped together based on the implementor of the service, for
+example a subset of the Function IDs are designated as "OEM Calls" (see [SMCCC]
+for full details). The EL3 runtime services framework in BL3-1 enables the
+independent implementation of services for each group, which are then compiled
+into the BL3-1 image. This simplifies the integration of common software from
+ARM to support [PSCI], Secure Monitor for a Trusted OS and SoC specific
+software. The common runtime services framework ensures that SMC Functions are
+dispatched to their respective service implementation - the [Firmware Design]
+provides details of how this is achieved.
+
+The interface and operation of the runtime services depends heavily on the
+concepts and definitions described in the [SMCCC], in particular SMC Function
+IDs, Owning Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and
+SMC64 calling conventions. Please refer to that document for a full explanation
+of these terms.
+
+
+2.  Owning Entities, Call Types and Function IDs
+------------------------------------------------
+
+The SMC Function Identifier includes a OEN field. These values and their
+meaning are described in [SMCCC] and summarized in table 1 below. Some entities
+are allocated a range of of OENs. The OEN must be interpreted in conjunction
+with the SMC call type, which is either _Fast_ or _Standard_. Fast calls are
+uninterruptible whereas Standard calls can be pre-empted. The majority of
+Owning Entities only have allocated ranges for Fast calls: Standard calls are
+reserved exclusively for Trusted OS providers or for interoperability with
+legacy 32-bit software that predates the [SMCCC].
+
+    Type    OEN     Service
+    Fast     0      ARM Architecture calls
+    Fast     1      CPU Service calls
+    Fast     2      SiP Service calls
+    Fast     3      OEM Service calls
+    Fast     4      Standard Service calls
+    Fast    5-47    Reserved for future use
+    Fast   48-49    Trusted Application calls
+    Fast   50-63    Trusted OS calls
+
+    Std     0- 1    Reserved for existing ARMv7 calls
+    Std     2-63    Trusted OS Standard Calls
+
+_Table 1: Service types and their corresponding Owning Entity Numbers_
+
+Each individual entity can allocate the valid identifiers within the entity
+range as they need - it is not necessary to coordinate with other entities of
+the same type. For example, two SoC providers can use the same Function ID
+within the SiP Service calls OEN range to mean different things - as these
+calls should be specific to the SoC. The Standard Runtime Calls OEN is used for
+services defined by ARM standards, such as [PSCI].
+
+The SMC Function ID also indicates whether the call has followed the SMC32
+calling convention, where all parameters are 32-bit, or the SMC64 calling
+convention, where the parameters are 64-bit. The framework identifies and
+rejects invalid calls that use the SMC64 calling convention but that originate
+from an AArch32 caller.
+
+The EL3 runtime services framework uses the call type and OEN to identify a
+specific handler for each SMC call, but it is expected that an individual
+handler will be responsible for all SMC Functions within a given service type.
+
+
+3.  Getting started
+-------------------
+
+ARM Trusted Firmware has a [`services`] directory in the source tree under which
+each owning entity can place the implementation of its runtime service.  The
+[PSCI] implementation is located here in the [`services/std_svc/psci`]
+directory.
+
+Runtime service sources will need to include the [`runtime_svc.h`] header file.
+
+
+4.  Registering a runtime service
+---------------------------------
+
+A runtime service is registered using the `DECLARE_RT_SVC()` macro, specifying
+the name of the service, the range of OENs covered, the type of service and
+initialization and call handler functions.
+
+    #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch)
+
+*   `_name` is used to identify the data structure declared by this macro, and
+    is also used for diagnostic purposes
+
+*   `_start` and `_end` values must be based on the `OEN_*` values defined in
+    [`runtime_svc.h`]
+
+*   `_type` must be one of `SMC_TYPE_FAST` or `SMC_TYPE_STD`
+
+*   `_setup` is the initialization function with the `rt_svc_init` signature:
+
+        typedef int32_t (*rt_svc_init)(void);
+
+*   `_smch` is the SMC handler function with the `rt_svc_handle` signature:
+
+        typedef uint64_t (*rt_svc_handle)(uint32_t smc_fid,
+                                          uint64_t x1, uint64_t x2,
+                                          uint64_t x3, uint64_t x4,
+                                          void *reserved,
+                                          void *handle,
+                                          uint64_t flags);
+
+Details of the requirements and behavior of the two callbacks is provided in
+the following sections.
+
+During initialization the services framework validates each declared service
+to ensure that the following conditions are met:
+
+1.  The `_start` OEN is not greater than the `_end` OEN
+2.  The `_end` OEN does not exceed the maximum OEN value (63)
+3.  The `_type` is one of `SMC_TYPE_FAST` or `SMC_TYPE_STD`
+4.  `_setup` and `_smch` routines have been specified
+
+[`std_svc_setup.c`] provides an example of registering a runtime service:
+
+    /* Register Standard Service Calls as runtime service */
+    DECLARE_RT_SVC(
+            std_svc,
+            OEN_STD_START,
+            OEN_STD_END,
+            SMC_TYPE_FAST,
+            std_svc_setup,
+            std_svc_smc_handler
+    );
+
+
+5. Initializing a runtime service
+---------------------------------
+
+Runtime services are initialized once, during cold boot, by the primary CPU
+after platform and architectural initialization is complete. The framework
+performs basic validation of the declared service before calling
+the service initialization function (`_setup` in the declaration). This
+function must carry out any essential EL3 initialization prior to receiving a
+SMC Function call via the handler function.
+
+On success, the initialization function must return `0`. Any other return value
+will cause the framework to issue a diagnostic:
+
+    Error initializing runtime service <name of the service>
+
+and then ignore the service - the system will continue to boot but SMC calls
+will not be passed to the service handler and instead return the _Unknown SMC
+Function ID_ result `0xFFFFFFFF`.
+
+If the system must not be allowed to proceed without the service, the
+initialization function must itself cause the firmware boot to be halted.
+
+If the service uses per-CPU data this must either be initialized for all CPUs
+during this call, or be done lazily when a CPU first issues an SMC call to that
+service.
+
+
+6.  Handling runtime service requests
+-------------------------------------
+
+SMC calls for a service are forwarded by the framework to the service's SMC
+handler function (`_smch` in the service declaration). This function must have
+the following signature:
+
+    typedef uint64_t (*rt_svc_handle)(uint32_t smc_fid,
+                                      uint64_t x1, uint64_t x2,
+                                      uint64_t x3, uint64_t x4,
+                                      void *reserved,
+                                      void *handle,
+                                      uint64_t flags);
+
+The handler is responsible for:
+
+1.  Determining that `smc_fid` is a valid and supported SMC Function ID,
+    otherwise completing the request with the _Unknown SMC Function ID_:
+
+        SMC_RET1(handle, SMC_UNK);
+
+2.  Determining if the requested function is valid for the calling security
+    state. SMC Calls can be made from both the normal and trusted worlds and
+    the framework will forward all calls to the service handler.
+
+    The `flags` parameter to this function indicates the caller security state
+    in bit[0], where a value of `1` indicates  a non-secure caller. The
+    `is_caller_secure(flags)` and `is_caller_non_secure(flags)` can be used to
+    test this condition.
+
+    If invalid, the request should be completed with:
+
+        SMC_RET1(handle, SMC_UNK);
+
+3.  Truncating parameters for calls made using the SMC32 calling convention.
+    Such calls can be determined by checking the CC field in bit[30] of the
+    `smc_fid` parameter, for example by using:
+
+        if (GET_SMC_CC(smc_fid) == SMC_32) ...
+
+    For such calls, the upper bits of the parameters x1-x4 and the saved
+    parameters X5-X7 are UNDEFINED and must be explicitly ignored by the
+    handler. This can be done by truncating the values to a suitable 32-bit
+    integer type before use, for example by ensuring that functions defined
+    to handle individual SMC Functions use appropriate 32-bit parameters.
+
+4.  Providing the service requested by the SMC Function, utilizing the
+    immediate parameters x1-x4 and/or the additional saved parameters X5-X7.
+    The latter can be retrieved using the `SMC_GET_GP(handle, ref)` function,
+    supplying the appropriate `CTX_GPREG_Xn` reference, e.g.
+
+        uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+
+5.  Implementing the standard SMC32 Functions that provide information about
+    the implementation of the service. These are the Call Count, Implementor
+    UID and Revision Details for each service documented in section 6 of the
+    [SMCCC].
+
+    The ARM Trusted Firmware expects owning entities to follow this
+    recommendation.
+
+5.  Returning the result to the caller. The [SMCCC] allows for up to 256 bits
+    of return value in SMC64 using X0-X3 and 128 bits in SMC32 using W0-W3. The
+    framework provides a family of macros to set the multi-register return
+    value and complete the handler:
+
+        SMC_RET1(handle, x0);
+        SMC_RET2(handle, x0, x1);
+        SMC_RET3(handle, x0, x1, x2);
+        SMC_RET4(handle, x0, x1, x2, x3);
+
+The `reserved` parameter to the handler is reserved for future use and can be
+ignored. The value returned by a SMC handler is also reserved for future use -
+completion of the handler function must always be via one of the `SMC_RETn()`
+macros.
+
+NOTE: The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow
+all of the above requirements yet.
+
+
+7.  Services that contain multiple sub-services
+-----------------------------------------------
+
+It is possible that a single owning entity implements multiple sub-services. For
+example, the Standard calls service handles `0x84000000`-`0x8400FFFF` and
+`0xC4000000`-`0xC400FFFF` functions. Within that range, the [PSCI] service
+handles the `0x84000000`-`0x8400001F` and `0xC4000000`-`0xC400001F` functions.
+In that respect, [PSCI] is a 'sub-service' of the Standard calls service. In
+future, there could be additional such sub-services in the Standard calls
+service which perform independent functions.
+
+In this situation it may be valuable to introduce a second level framework to
+enable independent implementation of sub-services. Such a framework might look
+very similar to the current runtime services framework, but using a different
+part of the SMC Function ID to identify the sub-service. Trusted Firmware does
+not provide such a framework at present.
+
+
+8.  Secure-EL1 Payload Dispatcher service (SPD)
+-----------------------------------------------
+
+Services that handle SMC Functions targeting a Trusted OS, Trusted Application,
+or other Secure-EL1 Payload are special. These services need to manage the
+Secure-EL1 context, provide the _Secure Monitor_ functionality of switching
+between the normal and secure worlds, deliver SMC Calls through to Secure-EL1
+and generally manage the Secure-EL1 Payload through CPU power-state transitions.
+
+TODO: Provide details of the additional work required to implement a SPD and
+the BL3-1 support for these services. Or a reference to the document that will
+provide this information....
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2014, ARM Limited and Contributors. All rights reserved._
+
+
+[Firmware Design]:  ./firmware-design.md
+
+[`services`]:               ../services
+[`services/std_svc/psci`]:  ../services/std_svc/psci
+[`std_svc_setup.c`]:        ../services/std_svc/std_svc_setup.c
+[`runtime_svc.h`]:          ../include/runtime_svc.h
+[PSCI]:                     http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)"
+[SMCCC]:                    http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)"
diff --git a/uefi/arm-trusted-firmware/docs/trusted-board-boot.md b/uefi/arm-trusted-firmware/docs/trusted-board-boot.md
new file mode 100644
index 0000000..abba030
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/trusted-board-boot.md
@@ -0,0 +1,261 @@
+Trusted Board Boot Design Guide
+===============================
+
+Contents :
+
+1.  [Introduction](#1--introduction)
+2.  [Chain of Trust](#2--chain-of-trust)
+3.  [Trusted Board Boot Sequence](#3--trusted-board-boot-sequence)
+4.  [Authentication Module](#4--authentication-module)
+5.  [Certificate Generation Tool](#5--certificate-generation-tool)
+
+
+1.  Introduction
+----------------
+
+The Trusted Board Boot (TBB) feature prevents malicious firmware from running on
+the platform by authenticating all firmware images up to and including the
+normal world bootloader. It does this by establishing a Chain of Trust using
+Public-Key-Cryptography Standards (PKCS).
+
+This document describes the design of the ARM Trusted Firmware TBB
+implementation. The current implementation is a proof of concept; future
+versions will provide stronger architectural interfaces and implement the
+missing functionality required in a production TBB-enabled system.
+
+
+2.  Chain of Trust
+------------------
+
+A Chain of Trust (CoT) starts with a set of implicitly trusted components. On
+the ARM development platforms, these components are:
+
+*   A SHA-256 hash of the Root of Trust Public Key (ROTPK). It is stored in the
+    trusted root-key storage registers.
+
+*   The BL1 image, on the assumption that it resides in ROM so cannot be
+    tampered with.
+
+The remaining components in the CoT are either certificates or boot loader
+images. The certificates follow the [X.509 v3] standard. This standard
+enables adding custom extensions to the certificates, which are used to store
+essential information to establish the CoT.
+
+In the TBB CoT all certificates are self-signed. There is no need for a
+Certificate Authority (CA) because the CoT is not established by verifying the
+validity of a certificate's issuer but by the content of the certificate
+extensions. To sign the certificates, the PKCS#1 SHA-1 with RSA Encryption
+signature scheme is used with a RSA key length of 2048 bits. Future version of
+Trusted Firmware will replace SHA-1 usage with SHA-256 and support additional
+cryptographic algorithms.
+
+The certificates are categorised as "Key" and "Content" certificates. Key
+cer