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/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
+certificates are used to verify public keys which have been used to sign content
+certificates. Content certificates are used to store the hash of a boot loader
+image. An image can be authenticated by calculating its hash and matching it
+with the hash extracted from the content certificate. The SHA-256 function is
+used to calculate all hashes. The public keys and hashes are included as
+non-standard extension fields in the [X.509 v3] certificates.
+
+The keys used to establish the CoT are:
+
+*   **Root of trust key**
+
+    The private part of this key is used to sign the BL2 content certificate and
+    the trusted key certificate. The public part is the ROTPK.
+
+*   **Trusted world key**
+
+    The private part is used to sign the key certificates corresponding to the
+    secure world images (BL3-0, BL3-1 and BL3-2). The public part is stored in
+    one of the extension fields in the trusted world certificate.
+
+*   **Non-trusted world key**
+
+    The private part is used to sign the key certificate corresponding to the
+    non secure world image (BL3-3). The public part is stored in one of the
+    extension fields in the trusted world certificate.
+
+*   **BL3-X keys**
+
+    For each of BL3-0, BL3-1, BL3-2 and BL3-3, the private part is used to sign
+    the content certificate for the BL3-X image. The public part is stored in
+    one of the extension fields in the corresponding key certificate.
+
+The following images are included in the CoT:
+
+*   BL1
+*   BL2
+*   BL3-0 (optional)
+*   BL3-1
+*   BL3-3
+*   BL3-2 (optional)
+
+The following certificates are used to authenticate the images.
+
+*   **BL2 content certificate**
+
+    It is self-signed with the private part of the ROT key. It contains a hash
+    of the BL2 image.
+
+*   **Trusted key certificate**
+
+    It is self-signed with the private part of the ROT key. It contains the
+    public part of the trusted world key and the public part of the non-trusted
+    world key.
+
+*   **BL3-0 key certificate**
+
+    It is self-signed with the trusted world key. It contains the public part of
+    the BL3-0 key.
+
+*   **BL3-0 content certificate**
+
+    It is self-signed with the BL3-0 key. It contains a hash of the BL3-0 image.
+
+*   **BL3-1 key certificate**
+
+    It is self-signed with the trusted world key. It contains the public part of
+    the BL3-1 key.
+
+*   **BL3-1 content certificate**
+
+    It is self-signed with the BL3-1 key. It contains a hash of the BL3-1 image.
+
+*   **BL3-2 key certificate**
+
+    It is self-signed with the trusted world key. It contains the public part of
+    the BL3-2 key.
+
+*   **BL3-2 content certificate**
+
+    It is self-signed with the BL3-2 key. It contains a hash of the BL3-2 image.
+
+*   **BL3-3 key certificate**
+
+    It is self-signed with the non-trusted world key. It contains the public
+    part of the BL3-3 key.
+
+*   **BL3-3 content certificate**
+
+    It is self-signed with the BL3-3 key. It contains a hash of the BL3-3 image.
+
+The BL3-0 and BL3-2 certificates are optional, but they must be present if the
+corresponding BL3-0 or BL3-2 images are present.
+
+
+3.  Trusted Board Boot Sequence
+-------------------------------
+
+The CoT is verified through the following sequence of steps. The system panics
+if any of the steps fail.
+
+*   BL1 loads and verifies the BL2 content certificate. The issuer public key is
+    read from the verified certificate. A hash of that key is calculated and
+    compared with the hash of the ROTPK read from the trusted root-key storage
+    registers. If they match, the BL2 hash is read from the certificate.
+
+    Note: the matching operation is platform specific and is currently
+    unimplemented on the ARM development platforms.
+
+*   BL1 loads the BL2 image. Its hash is calculated and compared with the hash
+    read from the certificate. Control is transferred to the BL2 image if all
+    the comparisons succeed.
+
+*   BL2 loads and verifies the trusted key certificate. The issuer public key is
+    read from the verified certificate. A hash of that key is calculated and
+    compared with the hash of the ROTPK read from the trusted root-key storage
+    registers. If the comparison succeeds, BL2 reads and saves the trusted and
+    non-trusted world public keys from the verified certificate.
+
+The next two steps are executed for each of the BL3-0, BL3-1 & BL3-2 images. The
+steps for the optional BL3-0 and BL3-2 images are skipped if these images are
+not present.
+
+*   BL2 loads and verifies the BL3-x key certificate. The certificate signature
+    is verified using the trusted world public key. If the signature
+    verification succeeds, BL2 reads and saves the BL3-x public key from the
+    certificate.
+
+*   BL2 loads and verifies the BL3-x content certificate. The signature is
+    verified using the BL3-x public key. If the signature verification succeeds,
+    BL2 reads and saves the BL3-x image hash from the certificate.
+
+The next two steps are executed only for the BL3-3 image.
+
+*   BL2 loads and verifies the BL3-3 key certificate. If the signature
+    verification succeeds, BL2 reads and saves the BL3-3 public key from the
+    certificate.
+
+*   BL2 loads and verifies the BL3-3 content certificate. If the signature
+    verification succeeds, BL2 reads and saves the BL3-3 image hash from the
+    certificate.
+
+The next step is executed for all the boot loader images.
+
+*   BL2 calculates the hash of each image. It compares it with the hash obtained
+    from the corresponding content certificate. The image authentication succeeds
+    if the hashes match.
+
+The Trusted Board Boot implementation spans both generic and platform-specific
+BL1 and BL2 code, and in tool code on the host build machine. The feature is
+enabled through use of specific build flags as described in the [User Guide].
+
+On the host machine, a tool generates the certificates, which are included in
+the FIP along with the boot loader images. These certificates are loaded in
+Trusted SRAM using the IO storage framework. They are then verified by an
+Authentication module included in the Trusted Firmware.
+
+The mechanism used for generating the FIP and the Authentication module are
+described in the following sections.
+
+
+4.  Authentication Module
+-------------------------
+
+The authentication module implements the required support to authenticate the
+corresponding certificates or images at each step in the Trusted Board Boot
+sequence. The module relies on the PolarSSL library (v1.3.9) to perform the
+following operations:
+
+*   Parsing X.509 certificates and verifying them using SHA-1 with RSA
+    Encryption.
+*   Extracting public keys and hashes from the certificates.
+*   Generating hashes (SHA-256) of boot loader images
+
+At each step, the module is responsible for allocating memory to store the
+public keys or hashes that will be used in later steps. The step identifier is
+used to determine what information must be saved, according to the CoT model
+detailed in the previous sections.
+
+The authentication module resides in the `common/auth/polarssl` directory.
+Instructions for including the necessary modules of the PolarSSL SSL library and
+building the authentication module can be found in the [User Guide].
+
+
+5.  Certificate Generation Tool
+-------------------------------
+
+The `cert_create` tool is built and runs on the host machine as part of the
+Trusted Firmware build process when `GENERATE_COT=1`. It takes the boot loader
+images and keys as inputs (keys must be in PEM format) and generates the
+certificates (in DER format) required to establish the CoT. New keys can be
+generated by the tool in case they are not provided. The certificates are then
+passed as inputs to the `fip_create` tool for creating the FIP.
+
+The certificates are also stored individually in the in the output build
+directory.
+
+The tool resides in the `tools/cert_create` directory. It uses OpenSSL SSL
+library version 1.0.1 or later to generate the X.509 certificates. Instructions
+for building and using the tool can be found in the [User Guide].
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2015, ARM Limited and Contributors. All rights reserved._
+
+
+[X.509 v3]:          http://www.ietf.org/rfc/rfc5280.txt
+[X.690]:             http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
+[User Guide]:        user-guide.md
diff --git a/uefi/arm-trusted-firmware/docs/user-guide.md b/uefi/arm-trusted-firmware/docs/user-guide.md
new file mode 100644
index 0000000..1badc0c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/docs/user-guide.md
@@ -0,0 +1,1102 @@
+ARM Trusted Firmware User Guide
+===============================
+
+Contents :
+
+1.  [Introduction](#1--introduction)
+2.  [Host machine requirements](#2--host-machine-requirements)
+3.  [Tools](#3--tools)
+4.  [Building the Trusted Firmware](#4--building-the-trusted-firmware)
+5.  [Obtaining the normal world software](#5--obtaining-the-normal-world-software)
+6.  [Preparing the images to run on FVP](#6--preparing-the-images-to-run-on-fvp)
+7.  [Running the software on FVP](#7--running-the-software-on-fvp)
+8.  [Running the software on Juno](#8--running-the-software-on-juno)
+
+
+1.  Introduction
+----------------
+This document describes how to build ARM Trusted Firmware and run it with a
+tested set of other software components using defined configurations on the Juno
+ARM development platform and ARM Fixed Virtual Platform (FVP) models. It is
+possible to use other software components, configurations and platforms but that
+is outside the scope of this document.
+
+This document should be used in conjunction with the [Firmware Design].
+
+
+2.  Host machine requirements
+-----------------------------
+
+The minimum recommended machine specification for building the software and
+running the FVP models is a dual-core processor running at 2GHz with 12GB of
+RAM.  For best performance, use a machine with a quad-core processor running at
+2.6GHz with 16GB of RAM.
+
+The software has been tested on Ubuntu 12.04.04 (64-bit).  Packages used
+for building the software were installed from that distribution unless
+otherwise specified.
+
+
+3.  Tools
+---------
+
+The following tools are required to use the ARM Trusted Firmware:
+
+*   `git` package to obtain source code.
+
+*   `build-essential`, `uuid-dev` and `iasl` packages for building UEFI and the
+    Firmware Image Package (FIP) tool.
+
+*   `bc` and `ncurses-dev` packages for building Linux.
+
+*   `device-tree-compiler` package for building the Flattened Device Tree (FDT)
+    source files (`.dts` files) provided with this software.
+
+*   Baremetal GNU GCC tools. Verified packages can be downloaded from [Linaro]
+    [Linaro Toolchain]. The rest of this document assumes that the
+    `gcc-linaro-aarch64-none-elf-4.9-2014.07_linux.tar.xz` tools are used.
+
+        wget http://releases.linaro.org/14.07/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.9-2014.07_linux.tar.xz
+        tar -xf gcc-linaro-aarch64-none-elf-4.9-2014.07_linux.tar.xz
+
+*   (Optional) For debugging, ARM [Development Studio 5 (DS-5)][DS-5] v5.20.
+
+
+4.  Building the Trusted Firmware
+---------------------------------
+
+To build the Trusted Firmware images, follow these steps:
+
+1.  Clone the ARM Trusted Firmware repository from GitHub:
+
+        git clone https://github.com/ARM-software/arm-trusted-firmware.git
+
+2.  Change to the trusted firmware directory:
+
+        cd arm-trusted-firmware
+
+3.  Set the compiler path, specify a Non-trusted Firmware image (BL3-3) and
+    a valid platform, and then build:
+
+        CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+        BL33=<path-to>/<bl33_image>                               \
+        make PLAT=<platform> all fip
+
+    If `PLAT` is not specified, `fvp` is assumed by default. See the "Summary of
+    build options" for more information on available build options.
+
+    The BL3-3 image corresponds to the software that is executed after switching
+    to the non-secure world. UEFI can be used as the BL3-3 image. Refer to the
+    "Obtaining the normal world software" section below.
+
+    The TSP (Test Secure Payload), corresponding to the BL3-2 image, is not
+    compiled in by default. Refer to the "Building the Test Secure Payload"
+    section below.
+
+    By default this produces a release version of the build. To produce a debug
+    version instead, refer to the "Debugging options" section below.
+
+    The build process creates products in a `build` directory tree, building
+    the objects and binaries for each boot loader stage in separate
+    sub-directories.  The following boot loader binary files are created from
+    the corresponding ELF files:
+
+    *   `build/<platform>/<build-type>/bl1.bin`
+    *   `build/<platform>/<build-type>/bl2.bin`
+    *   `build/<platform>/<build-type>/bl31.bin`
+
+    where `<platform>` is the name of the chosen platform and `<build-type>` is
+    either `debug` or `release`. A Firmare Image Package (FIP) will be created
+    as part of the build. It contains all boot loader images except for
+    `bl1.bin`.
+
+    *   `build/<platform>/<build-type>/fip.bin`
+
+    For more information on FIPs, see the "Firmware Image Package" section in
+    the [Firmware Design].
+
+4.  (Optional) Some platforms may require a BL3-0 image to boot. This image can
+    be included in the FIP when building the Trusted Firmware by specifying the
+    `BL30` build option:
+
+        BL30=<path-to>/<bl30_image>
+
+5.  Output binary files `bl1.bin` and `fip.bin` are both required to boot the
+    system. How these files are used is platform specific. Refer to the
+    platform documentation on how to use the firmware images.
+
+6.  (Optional) Build products for a specific build variant can be removed using:
+
+        make DEBUG=<D> PLAT=<platform> clean
+
+    ... where `<D>` is `0` or `1`, as specified when building.
+
+    The build tree can be removed completely using:
+
+        make realclean
+
+7.  (Optional) Path to binary for certain BL stages (BL2, BL3-1 and BL3-2) can be
+    provided by specifying the BLx=<path-to>/<blx_image> where BLx is the BL stage.
+    This will bypass the build of the BL component from source, but will include
+    the specified binary in the final FIP image. Please note that BL3-2 will be
+    included in the build, only if the `SPD` build option is specified.
+
+    For example, specifying BL2=<path-to>/<bl2_image> in the build option, will
+    skip compilation of BL2 source in trusted firmware, but include the BL2
+    binary specified in the final FIP image.
+
+### Summary of build options
+
+ARM Trusted Firmware build system supports the following build options. Unless
+mentioned otherwise, these options are expected to be specified at the build
+command line and are not to be modified in any component makefiles. Note that
+the build system doesn't track dependency for build options. Therefore, if any
+of the build options are changed from a previous build, a clean build must be
+performed.
+
+#### Common build options
+
+*   `BL30`: Path to BL3-0 image in the host file system. This image is optional.
+    If a BL3-0 image is present then this option must be passed for the `fip`
+    target.
+
+*   `BL33`: Path to BL3-3 image in the host file system. This is mandatory for
+    `fip` target in case the BL2 from ARM Trusted Firmware is used.
+
+*   `BL2`: This is an optional build option which specifies the path to BL2
+    image for the `fip` target. In this case, the BL2 in the ARM Trusted
+    Firmware will not be built.
+
+*   `BL31`:  This is an optional build option which specifies the path to
+    BL3-1 image for the `fip` target. In this case, the BL3-1 in the ARM
+    Trusted Firmware will not be built.
+
+*   `BL32`:  This is an optional build option which specifies the path to
+    BL3-2 image for the `fip` target. In this case, the BL3-2 in the ARM
+    Trusted Firmware will not be built.
+
+*   `FIP_NAME`: This is an optional build option which specifies the FIP
+    filename for the `fip` target. Default is `fip.bin`.
+
+*   `CROSS_COMPILE`: Prefix to toolchain binaries. Please refer to examples in
+    this document for usage.
+
+*   `DEBUG`: Chooses between a debug and release build. It can take either 0
+    (release) or 1 (debug) as values. 0 is the default.
+
+*   `LOG_LEVEL`: Chooses the log level, which controls the amount of console log
+    output compiled into the build. This should be one of the following:
+
+        0  (LOG_LEVEL_NONE)
+        10 (LOG_LEVEL_NOTICE)
+        20 (LOG_LEVEL_ERROR)
+        30 (LOG_LEVEL_WARNING)
+        40 (LOG_LEVEL_INFO)
+        50 (LOG_LEVEL_VERBOSE)
+
+    All log output up to and including the log level is compiled into the build.
+    The default value is 40 in debug builds and 20 in release builds.
+
+*   `NS_TIMER_SWITCH`: Enable save and restore for non-secure timer register
+    contents upon world switch. It can take either 0 (don't save and restore) or
+    1 (do save and restore). 0 is the default. An SPD may set this to 1 if it
+    wants the timer registers to be saved and restored.
+
+*   `PLAT`: Choose a platform to build ARM Trusted Firmware for. The chosen
+    platform name must be the name of one of the directories under the `plat/`
+    directory other than `common`.
+
+*   `SPD`: Choose a Secure Payload Dispatcher component to be built into the
+    Trusted Firmware. The value should be the path to the directory containing
+    the SPD source, relative to `services/spd/`; the directory is expected to
+    contain a makefile called `<spd-value>.mk`.
+
+*   `V`: Verbose build. If assigned anything other than 0, the build commands
+    are printed. Default is 0.
+
+*   `ARM_GIC_ARCH`: Choice of ARM GIC architecture version used by the ARM GIC
+    driver for implementing the platform GIC API. This API is used
+    by the interrupt management framework. Default is 2 (that is, version 2.0).
+
+*   `IMF_READ_INTERRUPT_ID`: Boolean flag used by the interrupt management
+    framework to enable passing of the interrupt id to its handler. The id is
+    read using a platform GIC API. `INTR_ID_UNAVAILABLE` is passed instead if
+    this option set to 0. Default is 0.
+
+*   `RESET_TO_BL31`: Enable BL3-1 entrypoint as the CPU reset vector instead
+    of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
+    entrypoint) or 1 (CPU reset to BL3-1 entrypoint).
+    The default value is 0.
+
+*   `CRASH_REPORTING`: A non-zero value enables a console dump of processor
+    register state when an unexpected exception occurs during execution of
+    BL3-1. This option defaults to the value of `DEBUG` - i.e. by default
+    this is only enabled for a debug build of the firmware.
+
+*   `ASM_ASSERTION`: This flag determines whether the assertion checks within
+    assembly source files are enabled or not. This option defaults to the
+    value of `DEBUG` - that is, by default this is only enabled for a debug
+    build of the firmware.
+
+*   `TSP_INIT_ASYNC`: Choose BL3-2 initialization method as asynchronous or
+    synchronous, (see "Initializing a BL3-2 Image" section in [Firmware
+    Design]). It can take the value 0 (BL3-2 is initialized using
+    synchronous method) or 1 (BL3-2 is initialized using asynchronous method).
+    Default is 0.
+
+*   `USE_COHERENT_MEM`: This flag determines whether to include the coherent
+    memory region in the BL memory map or not (see "Use of Coherent memory in
+    Trusted Firmware" section in [Firmware Design]). It can take the value 1
+    (Coherent memory region is included) or 0 (Coherent memory region is
+    excluded). Default is 1.
+
+*   `TSPD_ROUTE_IRQ_TO_EL3`: A non zero value enables the routing model
+    for non-secure interrupts in which they are routed to EL3 (TSPD). The
+    default model (when the value is 0) is to route non-secure interrupts
+    to S-EL1 (TSP).
+
+*   `TRUSTED_BOARD_BOOT`: Boolean flag to include support for the Trusted Board
+    Boot feature. When set to '1', BL1 and BL2 images include support to load
+    and verify the certificates and images in a FIP. The default value is '0'.
+    A successful build, when `TRUSTED_BOARD_BOOT=1`, depends upon the correct
+    initialization of the `AUTH_MOD` option. Generation and inclusion of
+    certificates in the FIP depends upon the value of the `GENERATE_COT` option.
+
+*   `AUTH_MOD`: This option is used when `TRUSTED_BOARD_BOOT=1`. It specifies
+    the name of the authentication module that will be used in the Trusted Board
+    Boot sequence. The module must be located in `common/auth/<module name>`
+    directory. The directory must contain a makefile `<module name>.mk` which
+    will be used to build the module. More information can be found in
+    [Trusted Board Boot]. The default module name is 'none'.
+
+*   `GENERATE_COT`: Boolean flag used to build and execute the `cert_create`
+    tool to create certificates as per the Chain of Trust described in
+    [Trusted Board Boot].  The build system then calls the `fip_create` tool to
+    include the certificates in the FIP. Default value is '0'.
+
+    Specify `TRUSTED_BOARD_BOOT=1` and `GENERATE_COT=1` to include support for
+    the Trusted Board Boot Sequence in the BL1 and BL2 images and the FIP.
+
+    Note that if `TRUSTED_BOARD_BOOT=0` and `GENERATE_COT=1`, the BL1 and BL2
+    images will not include support for Trusted Board Boot. The FIP will still
+    include the key and content certificates. This FIP can be used to verify the
+    Chain of Trust on the host machine through other mechanisms.
+
+    Note that if `TRUSTED_BOARD_BOOT=1` and `GENERATE_COT=0`, the BL1 and BL2
+    images will include support for Trusted Board Boot, but the FIP will not
+    include the key and content certificates, causing a boot failure.
+
+*   `CREATE_KEYS`: This option is used when `GENERATE_COT=1`. It tells the
+    certificate generation tool to create new keys in case no valid keys are
+    present or specified. Allowed options are '0' or '1'. Default is '1'.
+
+*   `ROT_KEY`: This option is used when `GENERATE_COT=1`. It specifies the
+    file that contains the ROT private key in PEM format.
+
+*   `TRUSTED_WORLD_KEY`: This option is used when `GENERATE_COT=1`. It
+    specifies the file that contains the Trusted World private key in PEM
+    format.
+
+*   `NON_TRUSTED_WORLD_KEY`: This option is used when `GENERATE_COT=1`. It
+    specifies the file that contains the Non-Trusted World private key in PEM
+    format.
+
+*   `BL30_KEY`: This option is used when `GENERATE_COT=1`. It specifies the
+    file that contains the BL3-0 private key in PEM format.
+
+*   `BL31_KEY`: This option is used when `GENERATE_COT=1`. It specifies the
+    file that contains the BL3-1 private key in PEM format.
+
+*   `BL32_KEY`: This option is used when `GENERATE_COT=1`. It specifies the
+    file that contains the BL3-2 private key in PEM format.
+
+*   `BL33_KEY`: This option is used when `GENERATE_COT=1`. It specifies the
+    file that contains the BL3-3 private key in PEM format.
+
+#### FVP specific build options
+
+*   `FVP_TSP_RAM_LOCATION`: location of the TSP binary. Options:
+    -   `tsram` : Trusted SRAM (default option)
+    -   `tdram` : Trusted DRAM
+    -   `dram`  : Secure region in DRAM (configured by the TrustZone controller)
+
+For a better understanding of FVP options, the FVP memory map is explained in
+the [Firmware Design].
+
+#### Juno specific build options
+
+*   `PLAT_TSP_LOCATION`: location of the TSP binary. Options:
+    -   `tsram` : Trusted SRAM (default option)
+    -   `dram`  : Secure region in DRAM (set by the TrustZone controller)
+
+### Creating a Firmware Image Package
+
+FIPs are automatically created as part of the build instructions described in
+the previous section. It is also possible to independently build the FIP
+creation tool and FIPs if required. To do this, follow these steps:
+
+Build the tool:
+
+    make -C tools/fip_create
+
+It is recommended to remove the build artifacts before rebuilding:
+
+    make -C tools/fip_create clean
+
+Create a Firmware package that contains existing BL2 and BL3-1 images:
+
+    # fip_create --help to print usage information
+    # fip_create <fip_name> <images to add> [--dump to show result]
+    ./tools/fip_create/fip_create fip.bin --dump \
+       --bl2 build/<platform>/debug/bl2.bin --bl31 build/<platform>/debug/bl31.bin
+
+     Firmware Image Package ToC:
+    ---------------------------
+    - Trusted Boot Firmware BL2: offset=0x88, size=0x81E8
+      file: 'build/<platform>/debug/bl2.bin'
+    - EL3 Runtime Firmware BL3-1: offset=0x8270, size=0xC218
+      file: 'build/<platform>/debug/bl31.bin'
+    ---------------------------
+    Creating "fip.bin"
+
+View the contents of an existing Firmware package:
+
+    ./tools/fip_create/fip_create fip.bin --dump
+
+     Firmware Image Package ToC:
+    ---------------------------
+    - Trusted Boot Firmware BL2: offset=0x88, size=0x81E8
+    - EL3 Runtime Firmware BL3-1: offset=0x8270, size=0xC218
+    ---------------------------
+
+Existing package entries can be individially updated:
+
+    # Change the BL2 from Debug to Release version
+    ./tools/fip_create/fip_create fip.bin --dump \
+      --bl2 build/<platform>/release/bl2.bin
+
+    Firmware Image Package ToC:
+    ---------------------------
+    - Trusted Boot Firmware BL2: offset=0x88, size=0x7240
+      file: 'build/<platform>/release/bl2.bin'
+    - EL3 Runtime Firmware BL3-1: offset=0x72C8, size=0xC218
+    ---------------------------
+    Updating "fip.bin"
+
+
+### Debugging options
+
+To compile a debug version and make the build more verbose use
+
+    CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+    BL33=<path-to>/<bl33_image>                               \
+    make PLAT=<platform> DEBUG=1 V=1 all fip
+
+AArch64 GCC uses DWARF version 4 debugging symbols by default. Some tools (for
+example DS-5) might not support this and may need an older version of DWARF
+symbols to be emitted by GCC. This can be achieved by using the
+`-gdwarf-<version>` flag, with the version being set to 2 or 3. Setting the
+version to 2 is recommended for DS-5 versions older than 5.16.
+
+When debugging logic problems it might also be useful to disable all compiler
+optimizations by using `-O0`.
+
+NOTE: Using `-O0` could cause output images to be larger and base addresses
+might need to be recalculated (see the "Memory layout of BL images" section in
+the [Firmware Design]).
+
+Extra debug options can be passed to the build system by setting `CFLAGS`:
+
+    CFLAGS='-O0 -gdwarf-2'                                    \
+    CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+    BL33=<path-to>/<bl33_image>                               \
+    make PLAT=<platform> DEBUG=1 V=1 all fip
+
+
+### Building the Test Secure Payload
+
+The TSP is coupled with a companion runtime service in the BL3-1 firmware,
+called the TSPD. Therefore, if you intend to use the TSP, the BL3-1 image
+must be recompiled as well. For more information on SPs and SPDs, see the
+"Secure-EL1 Payloads and Dispatchers" section in the [Firmware Design].
+
+First clean the Trusted Firmware build directory to get rid of any previous
+BL3-1 binary. Then to build the TSP image and include it into the FIP use:
+
+    CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+    BL33=<path-to>/<bl33_image>                               \
+    make PLAT=<platform> SPD=tspd all fip
+
+An additional boot loader binary file is created in the `build` directory:
+
+*   `build/<platform>/<build-type>/bl32.bin`
+
+The FIP will now contain the additional BL3-2 image. Here is an example
+output from an FVP build in release mode including BL3-2 and using
+FVP_AARCH64_EFI.fd as BL3-3 image:
+
+    Firmware Image Package ToC:
+    ---------------------------
+    - Trusted Boot Firmware BL2: offset=0xD8, size=0x6000
+      file: './build/fvp/release/bl2.bin'
+    - EL3 Runtime Firmware BL3-1: offset=0x60D8, size=0x9000
+      file: './build/fvp/release/bl31.bin'
+    - Secure Payload BL3-2 (Trusted OS): offset=0xF0D8, size=0x3000
+      file: './build/fvp/release/bl32.bin'
+    - Non-Trusted Firmware BL3-3: offset=0x120D8, size=0x280000
+      file: '../FVP_AARCH64_EFI.fd'
+    ---------------------------
+    Creating "build/fvp/release/fip.bin"
+
+
+### Building the Certificate Generation Tool
+
+The `cert_create` tool can be built separately through the following commands:
+
+    $ cd tools/cert_create
+    $ make [DEBUG=1] [V=1]
+
+`DEBUG=1` builds the tool in debug mode. `V=1` makes the build process more
+verbose. The following command should be used to obtain help about the tool:
+
+    $ ./cert_create -h
+
+The `cert_create` tool is automatically built with the `fip` target when
+`GENERATE_COT=1`.
+
+
+### Building a FIP image with support for Trusted Board Boot
+
+The Trusted Board Boot feature is described in [Trusted Board Boot]. The
+following steps should be followed to build a FIP image with support for this
+feature.
+
+1.  Fulfill the dependencies of the `polarssl` authentication module by checking
+    out the tag `polarssl-1.3.9` from the [PolarSSL Repository].
+
+    The `common/auth/polarssl/polarssl.mk` contains the list of PolarSSL source
+    files the module depends upon. `common/auth/polarssl/polarssl_config.h`
+    contains the configuration options required to build the PolarSSL sources.
+
+    Note that the PolarSSL SSL library is licensed under the GNU GPL version 2
+    or later license. Using PolarSSL source code will affect the licensing of
+    Trusted Firmware binaries that are built using this library.
+
+2.  Ensure that the following command line variables are set while invoking
+    `make` to build Trusted Firmware:
+
+    *   `POLARSSL_DIR=<path of the directory containing PolarSSL sources>`
+    *   `AUTH_MOD=polarssl`
+    *   `TRUSTED_BOARD_BOOT=1`
+    *   `GENERATE_COT=1`
+
+
+### Checking source code style
+
+When making changes to the source for submission to the project, the source
+must be in compliance with the Linux style guide, and to assist with this check
+the project Makefile contains two targets, which both utilise the
+`checkpatch.pl` script that ships with the Linux source tree.
+
+To check the entire source tree, you must first download a copy of
+`checkpatch.pl` (or the full Linux source), set the `CHECKPATCH` environment
+variable to point to the script and build the target checkcodebase:
+
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
+
+To just check the style on the files that differ between your local branch and
+the remote master, use:
+
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
+
+If you wish to check your patch against something other than the remote master,
+set the `BASE_COMMIT` variable to your desired branch. By default, `BASE_COMMIT`
+is set to `origin/master`.
+
+
+5.  Obtaining the normal world software
+---------------------------------------
+
+### Obtaining EDK2
+
+Potentially any kind of non-trusted firmware may be used with the ARM Trusted
+Firmware but the software has only been tested with the EFI Development Kit 2
+(EDK2) open source implementation of the UEFI specification.
+
+To build the software to be compatible with the Foundation and Base FVPs, or the
+Juno platform, follow these steps:
+
+1.  Clone the [EDK2 source code][EDK2] from GitHub:
+
+        git clone -n https://github.com/tianocore/edk2.git
+
+    Not all required features are available in the EDK2 mainline yet. These can
+    be obtained from the ARM-software EDK2 repository instead:
+
+        cd edk2
+        git remote add -f --tags arm-software https://github.com/ARM-software/edk2.git
+        git checkout --detach v2.1-rc0
+
+2.  Copy build config templates to local workspace
+
+        # in edk2/
+        . edksetup.sh
+
+3.  Build the EDK2 host tools
+
+        make -C BaseTools clean
+        make -C BaseTools
+
+4.  Build the EDK2 software
+
+    1.  Build for FVP
+
+            GCC49_AARCH64_PREFIX=<absolute-path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+            make -f ArmPlatformPkg/Scripts/Makefile EDK2_ARCH=AARCH64 \
+            EDK2_DSC=ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc \
+            EDK2_TOOLCHAIN=GCC49 EDK2_BUILD=RELEASE \
+            EDK2_MACROS="-n 6 -D ARM_FOUNDATION_FVP=1"
+
+        The EDK2 binary for use with the ARM Trusted Firmware can then be found
+        here:
+
+             Build/ArmVExpress-FVP-AArch64/RELEASE_GCC49/FV/FVP_AARCH64_EFI.fd
+
+    2.  Build for Juno
+
+            GCC49_AARCH64_PREFIX=<absolute-path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+            make -f ArmPlatformPkg/ArmJunoPkg/Makefile EDK2_ARCH=AARCH64 \
+            EDK2_TOOLCHAIN=GCC49 EDK2_BUILD=RELEASE
+
+        The EDK2 binary for use with the ARM Trusted Firmware can then be found
+        here:
+
+            Build/ArmJuno/RELEASE_GCC49/FV/BL33_AP_UEFI.fd
+
+    The EDK2 binary should be specified as `BL33` in in the `make` command line
+    when building the Trusted Firmware. See the "Building the Trusted Firmware"
+    section above.
+
+5.  (Optional) To build EDK2 in debug mode, remove `EDK2_BUILD=RELEASE` from the
+    command line.
+
+6.  (Optional) To boot Linux using a VirtioBlock file-system, the command line
+    passed from EDK2 to the Linux kernel must be modified as described in the
+    "Obtaining a root file-system" section below.
+
+7.  (Optional) If legacy GICv2 locations are used, the EDK2 platform description
+    must be updated. This is required as EDK2 does not support probing for the
+    GIC location. To do this, first clean the EDK2 build directory.
+
+        make -f ArmPlatformPkg/Scripts/Makefile EDK2_ARCH=AARCH64          \
+        EDK2_DSC=ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc \
+        EDK2_TOOLCHAIN=ARMGCC clean
+
+    Then rebuild EDK2 as described in step 3, using the following flag:
+
+        -D ARM_FVP_LEGACY_GICV2_LOCATION=1
+
+    Finally rebuild the Trusted Firmware to generate a new FIP using the
+    instructions in the "Building the Trusted Firmware" section.
+
+
+### Obtaining a Linux kernel
+
+Preparing a Linux kernel for use on the FVPs can be done as follows
+(GICv2 support only):
+
+1.  Clone Linux:
+
+        git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+
+    Not all required features are available in the kernel mainline yet. These
+    can be obtained from the ARM-software Linux repository instead:
+
+        cd linux
+        git remote add -f --tags arm-software https://github.com/ARM-software/linux.git
+        git checkout --detach 1.3-Juno
+
+2.  Build with the Linaro GCC tools.
+
+        # in linux/
+        make mrproper
+        make ARCH=arm64 defconfig
+
+        CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- \
+        make -j6 ARCH=arm64
+
+The compiled Linux image will now be found at `arch/arm64/boot/Image`.
+
+
+6.  Preparing the images to run on FVP
+--------------------------------------
+
+### Obtaining the Flattened Device Trees
+
+Depending on the FVP configuration and Linux configuration used, different
+FDT files are required. FDTs for the Foundation and Base FVPs can be found in
+the Trusted Firmware source directory under `fdts/`. The Foundation FVP has a
+subset of the Base FVP components. For example, the Foundation FVP lacks CLCD
+and MMC support, and has only one CPU cluster.
+
+*   `fvp-base-gicv2-psci.dtb`
+
+    (Default) For use with both AEMv8 and Cortex-A57-A53 Base FVPs with
+    Base memory map configuration.
+
+*   `fvp-base-gicv2legacy-psci.dtb`
+
+    For use with AEMv8 Base FVP with legacy VE GIC memory map configuration.
+
+*   `fvp-base-gicv3-psci.dtb`
+
+    For use with both AEMv8 and Cortex-A57-A53 Base FVPs with Base memory map
+    configuration and Linux GICv3 support.
+
+*   `fvp-foundation-gicv2-psci.dtb`
+
+    (Default) For use with Foundation FVP with Base memory map configuration.
+
+*   `fvp-foundation-gicv2legacy-psci.dtb`
+
+    For use with Foundation FVP with legacy VE GIC memory map configuration.
+
+*   `fvp-foundation-gicv3-psci.dtb`
+
+    For use with Foundation FVP with Base memory map configuration and Linux
+    GICv3 support.
+
+
+Copy the chosen FDT blob as `fdt.dtb` to the directory from which the FVP
+is launched. Alternatively a symbolic link may be used.
+
+### Preparing the kernel image
+
+Copy the kernel image file `arch/arm64/boot/Image` to the directory from which
+the FVP is launched. Alternatively a symbolic link may be used.
+
+### Obtaining a root file-system
+
+To prepare a Linaro LAMP based Open Embedded file-system, the following
+instructions can be used as a guide. The file-system can be provided to Linux
+via VirtioBlock or as a RAM-disk. Both methods are described below.
+
+#### Prepare VirtioBlock
+
+To prepare a VirtioBlock file-system, do the following:
+
+1.  Download and unpack the disk image.
+
+    NOTE: The unpacked disk image grows to 3 GiB in size.
+
+        wget http://releases.linaro.org/14.12/openembedded/aarch64/vexpress64-openembedded_lamp-armv8-gcc-4.9_20141211-701.img.gz
+        gunzip vexpress64-openembedded_lamp-armv8-gcc-4.9_20141211-701.img.gz
+
+2.  Make sure the Linux kernel has Virtio support enabled using
+    `make ARCH=arm64 menuconfig`.
+
+        Device Drivers  ---> Virtio drivers  ---> <*> Platform bus driver for memory mapped virtio devices
+        Device Drivers  ---> [*] Block devices  --->  <*> Virtio block driver
+        File systems    ---> <*> The Extended 4 (ext4) filesystem
+
+    If some of these configurations are missing, enable them, save the kernel
+    configuration, then rebuild the kernel image using the instructions
+    provided in the section "Obtaining a Linux kernel".
+
+3.  Change the Kernel command line to include `root=/dev/vda2`. This can either
+    be done in the EDK2 boot menu or in the platform file. Editing the platform
+    file and rebuilding EDK2 will make the change persist. To do this:
+
+    1.  In EDK2, edit the following file:
+
+            ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc
+
+    2.  Add `root=/dev/vda2` to:
+
+            gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"<Other default options>"
+
+    3.  Remove the entry:
+
+            gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|""
+
+    4.  Rebuild EDK2 (see "Obtaining UEFI" section above).
+
+4.  The file-system image file should be provided to the model environment by
+    passing it the correct command line option. In the FVPs the following
+    option should be provided in addition to the ones described in the
+    "Running the software on FVP" section below.
+
+    NOTE: A symbolic link to this file cannot be used with the FVP; the path
+    to the real file must be provided.
+
+    On the Base FVPs:
+
+        -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
+
+    On the Foundation FVP:
+
+        --block-device="<path-to>/<file-system-image>"
+
+5.  Ensure that the FVP doesn't output any error messages. If the following
+    error message is displayed:
+
+        ERROR: BlockDevice: Failed to open "<path-to>/<file-system-image>"!
+
+    then make sure the path to the file-system image in the model parameter is
+    correct and that read permission is correctly set on the file-system image
+    file.
+
+#### Prepare RAM-disk
+
+To prepare a RAM-disk root file-system, do the following:
+
+1.  Download the file-system image:
+
+        wget http://releases.linaro.org/14.12/openembedded/aarch64/linaro-image-lamp-genericarmv8-20141212-729.rootfs.tar.gz
+
+2.  Modify the Linaro image:
+
+        # Prepare for use as RAM-disk. Normally use MMC, NFS or VirtioBlock.
+        # Be careful, otherwise you could damage your host file-system.
+        mkdir tmp; cd tmp
+        sudo sh -c "zcat ../linaro-image-lamp-genericarmv8-20141212-729.rootfs.tar.gz | cpio -id"
+        sudo ln -s sbin/init .
+        sudo sh -c "echo 'devtmpfs /dev devtmpfs mode=0755,nosuid 0 0' >> etc/fstab"
+        sudo sh -c "find . | cpio --quiet -H newc -o | gzip -3 -n > ../filesystem.cpio.gz"
+        cd ..
+
+3.  Copy the resultant `filesystem.cpio.gz` to the directory where the FVP is
+    launched from. Alternatively a symbolic link may be used.
+
+
+7.  Running the software on FVP
+-------------------------------
+
+This version of the ARM Trusted Firmware has been tested on the following ARM
+FVPs (64-bit versions only).
+
+*   `Foundation_Platform` (Version 9.1, Build 9.1.33)
+*   `FVP_Base_AEMv8A-AEMv8A` (Version 6.2, Build 0.8.6202)
+*   `FVP_Base_Cortex-A57x4-A53x4` (Version 6.2, Build 0.8.6202)
+*   `FVP_Base_Cortex-A57x1-A53x1` (Version 6.2, Build 0.8.6202)
+*   `FVP_Base_Cortex-A57x2-A53x4` (Version 6.2, Build 0.8.6202)
+
+NOTE: The build numbers quoted above are those reported by launching the FVP
+with the `--version` parameter.
+
+NOTE: The software will not work on Version 1.0 of the Foundation FVP.
+The commands below would report an `unhandled argument` error in this case.
+
+NOTE: The Foundation FVP does not provide a debugger interface.
+
+Please refer to the FVP documentation for a detailed description of the model
+parameter options. A brief description of the important ones that affect the
+ARM Trusted Firmware and normal world software behavior is provided below.
+
+The Foundation FVP is a cut down version of the AArch64 Base FVP. It can be
+downloaded for free from [ARM's website][ARM FVP website].
+
+
+### Running on the Foundation FVP with reset to BL1 entrypoint
+
+The following `Foundation_Platform` parameters should be used to boot Linux with
+4 CPUs using the ARM Trusted Firmware.
+
+NOTE: Using the `--block-device` parameter is not necessary if a Linux RAM-disk
+file-system is used (see the "Obtaining a File-system" section above).
+
+NOTE: The `--data="<path to FIP binary>"@0x8000000` parameter is used to load a
+Firmware Image Package at the start of NOR FLASH0 (see the "Building the
+Trusted Firmware" section above).
+
+    <path-to>/Foundation_Platform             \
+    --cores=4                                 \
+    --secure-memory                           \
+    --visualization                           \
+    --gicv3                                   \
+    --data="<path-to>/<bl1-binary>"@0x0       \
+    --data="<path-to>/<FIP-binary>"@0x8000000 \
+    --block-device="<path-to>/<file-system-image>"
+
+The default use-case for the Foundation FVP is to enable the GICv3 device in
+the model but use the GICv2 FDT, in order for Linux to drive the GIC in GICv2
+emulation mode.
+
+The memory mapped addresses `0x0` and `0x8000000` correspond to the start of
+trusted ROM and NOR FLASH0 respectively.
+
+### Notes regarding Base FVP configuration options
+
+Please refer to these notes in the subsequent "Running on the Base FVP"
+sections.
+
+1.  The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image
+    Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware"
+    section above).
+
+2.  Using `cache_state_modelled=1` makes booting very slow. The software will
+    still work (and run much faster) without this option but this will hide any
+    cache maintenance defects in the software.
+
+3.  Using the `-C bp.virtioblockdevice.image_path` parameter is not necessary
+    if a Linux RAM-disk file-system is used (see the "Obtaining a root
+    file-system" section above).
+
+4.  Setting the `-C bp.secure_memory` parameter to `1` is only supported on
+    Base FVP versions 5.4 and newer. Setting this parameter to `0` is also
+    supported. The `-C bp.tzc_400.diagnostics=1` parameter is optional. It
+    instructs the FVP to provide some helpful information if a secure memory
+    violation occurs.
+
+5.  This and the following notes only apply when the firmware is built with
+    the `RESET_TO_BL31` option.
+
+    The `--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>`
+    parameter is used to load bootloader images into Base FVP memory (see the
+    "Building the Trusted Firmware" section above). The base addresses used
+    should match the image base addresses in `platform_def.h` used while linking
+    the images. The BL3-2 image is only needed if BL3-1 has been built to expect
+    a Secure-EL1 Payload.
+
+6.  The `-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>` parameter, where
+    X and Y are the cluster and CPU numbers respectively, is used to set the
+    reset vector for each core.
+
+7.  Changing the default value of `FVP_SHARED_DATA_LOCATION` will also require
+    changing the value of
+    `--data="<path-to><bl31-binary>"@<base-address-of-bl31>` and
+    `-C cluster<X>.cpu<X>.RVBAR=@<base-address-of-bl31>`, to the new value of
+    `BL31_BASE` in `platform_def.h`.
+
+8.  Changing the default value of `FVP_TSP_RAM_LOCATION` will also require
+    changing the value of
+    `--data="<path-to><bl32-binary>"@<base-address-of-bl32>` to the new value of
+    `BL32_BASE` in `platform_def.h`.
+
+
+### Running on the AEMv8 Base FVP with reset to BL1 entrypoint
+
+Please read "Notes regarding Base FVP configuration options" section above for
+information about some of the options to run the software.
+
+The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
+with 8 CPUs using the ARM Trusted Firmware.
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                       \
+    -C pctl.startup=0.0.0.0                                \
+    -C bp.secure_memory=1                                  \
+    -C bp.tzc_400.diagnostics=1                            \
+    -C cluster0.NUM_CORES=4                                \
+    -C cluster1.NUM_CORES=4                                \
+    -C cache_state_modelled=1                              \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"      \
+    -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
+
+### Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
+
+Please read "Notes regarding Base FVP configuration options" section above for
+information about some of the options to run the software.
+
+The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to
+boot Linux with 8 CPUs using the ARM Trusted Firmware.
+
+    <path-to>/FVP_Base_Cortex-A57x4-A53x4                  \
+    -C pctl.startup=0.0.0.0                                \
+    -C bp.secure_memory=1                                  \
+    -C bp.tzc_400.diagnostics=1                            \
+    -C cache_state_modelled=1                              \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"      \
+    -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
+
+### Running on the AEMv8 Base FVP with reset to BL3-1 entrypoint
+
+Please read "Notes regarding Base FVP configuration options" section above for
+information about some of the options to run the software.
+
+The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
+with 8 CPUs using the ARM Trusted Firmware.
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                             \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cluster0.NUM_CORES=4                                      \
+    -C cluster1.NUM_CORES=4                                      \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.RVBAR=0x04023000                            \
+    -C cluster0.cpu1.RVBAR=0x04023000                            \
+    -C cluster0.cpu2.RVBAR=0x04023000                            \
+    -C cluster0.cpu3.RVBAR=0x04023000                            \
+    -C cluster1.cpu0.RVBAR=0x04023000                            \
+    -C cluster1.cpu1.RVBAR=0x04023000                            \
+    -C cluster1.cpu2.RVBAR=0x04023000                            \
+    -C cluster1.cpu3.RVBAR=0x04023000                            \
+    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04023000    \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04001000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
+
+### Running on the Cortex-A57-A53 Base FVP with reset to BL3-1 entrypoint
+
+Please read "Notes regarding Base FVP configuration options" section above for
+information about some of the options to run the software.
+
+The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to
+boot Linux with 8 CPUs using the ARM Trusted Firmware.
+
+    <path-to>/FVP_Base_Cortex-A57x4-A53x4                        \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.RVBARADDR=0x04023000                        \
+    -C cluster0.cpu1.RVBARADDR=0x04023000                        \
+    -C cluster0.cpu2.RVBARADDR=0x04023000                        \
+    -C cluster0.cpu3.RVBARADDR=0x04023000                        \
+    -C cluster1.cpu0.RVBARADDR=0x04023000                        \
+    -C cluster1.cpu1.RVBARADDR=0x04023000                        \
+    -C cluster1.cpu2.RVBARADDR=0x04023000                        \
+    -C cluster1.cpu3.RVBARADDR=0x04023000                        \
+    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04023000    \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04001000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
+
+### Configuring the GICv2 memory map
+
+The Base FVP models support GICv2 with the default model parameters at the
+following addresses. The Foundation FVP also supports these addresses when
+configured for GICv3 in GICv2 emulation mode.
+
+    GICv2 Distributor Interface     0x2f000000
+    GICv2 CPU Interface             0x2c000000
+    GICv2 Virtual CPU Interface     0x2c010000
+    GICv2 Hypervisor Interface      0x2c02f000
+
+The AEMv8 Base FVP can be configured to support GICv2 at addresses
+corresponding to the legacy (Versatile Express) memory map as follows. These are
+the default addresses when using the Foundation FVP in GICv2 mode.
+
+    GICv2 Distributor Interface     0x2c001000
+    GICv2 CPU Interface             0x2c002000
+    GICv2 Virtual CPU Interface     0x2c004000
+    GICv2 Hypervisor Interface      0x2c006000
+
+The choice of memory map is reflected in the build variant field (bits[15:12])
+in the `SYS_ID` register (Offset `0x0`) in the Versatile Express System
+registers memory map (`0x1c010000`).
+
+*   `SYS_ID.Build[15:12]`
+
+    `0x1` corresponds to the presence of the Base GIC memory map. This is the
+    default value on the Base FVPs.
+
+*   `SYS_ID.Build[15:12]`
+
+    `0x0` corresponds to the presence of the Legacy VE GIC memory map. This is
+    the default value on the Foundation FVP.
+
+This register can be configured as described in the following sections.
+
+NOTE: If the legacy VE GIC memory map is used, then the corresponding FDT and
+BL3-3 images should be used.
+
+#### Configuring AEMv8 Foundation FVP GIC for legacy VE memory map
+
+The following parameters configure the Foundation FVP to use GICv2 with the
+legacy VE memory map:
+
+    <path-to>/Foundation_Platform             \
+    --cores=4                                 \
+    --secure-memory                           \
+    --visualization                           \
+    --no-gicv3                                \
+    --data="<path-to>/<bl1-binary>"@0x0       \
+    --data="<path-to>/<FIP-binary>"@0x8000000 \
+    --block-device="<path-to>/<file-system-image>"
+
+Explicit configuration of the `SYS_ID` register is not required.
+
+#### Configuring AEMv8 Base FVP GIC for legacy VE memory map
+
+The following parameters configure the AEMv8 Base FVP to use GICv2 with the
+legacy VE memory map. They must added to the parameters described in the
+"Running on the AEMv8 Base FVP" section above:
+
+    -C cluster0.gic.GICD-offset=0x1000                  \
+    -C cluster0.gic.GICC-offset=0x2000                  \
+    -C cluster0.gic.GICH-offset=0x4000                  \
+    -C cluster0.gic.GICH-other-CPU-offset=0x5000        \
+    -C cluster0.gic.GICV-offset=0x6000                  \
+    -C cluster0.gic.PERIPH-size=0x8000                  \
+    -C cluster1.gic.GICD-offset=0x1000                  \
+    -C cluster1.gic.GICC-offset=0x2000                  \
+    -C cluster1.gic.GICH-offset=0x4000                  \
+    -C cluster1.gic.GICH-other-CPU-offset=0x5000        \
+    -C cluster1.gic.GICV-offset=0x6000                  \
+    -C cluster1.gic.PERIPH-size=0x8000                  \
+    -C gic_distributor.GICD-alias=0x2c001000            \
+    -C gicv3.gicv2-only=1                               \
+    -C bp.variant=0x0
+
+The `bp.variant` parameter corresponds to the build variant field of the
+`SYS_ID` register.  Setting this to `0x0` allows the ARM Trusted Firmware to
+detect the legacy VE memory map while configuring the GIC.
+
+
+8.  Running the software on Juno
+--------------------------------
+
+### Preparing Trusted Firmware images
+
+To execute the versions of software components on Juno referred to in this
+document, the latest [Juno Board Recovery Image] must be installed. If you
+have an earlier version installed or are unsure which version is installed,
+follow the recovery image update instructions in the [Juno Software Guide]
+on the [ARM Connected Community] website.
+
+The Juno platform requires a BL3-0 image to boot up. This image contains the
+runtime firmware that runs on the SCP (System Control Processor). This image is
+embedded within the [Juno Board Recovery Image] but can also be
+[downloaded directly][Juno SCP Firmware].
+
+Rebuild the Trusted Firmware specifying the BL3-0 image. Refer to the section
+"Building the Trusted Firmware". Alternatively, the FIP image can be updated
+manually with the BL3-0 image:
+
+    fip_create --dump --bl30 <path-to>/<bl30-binary> <path-to>/<FIP-binary>
+
+### Obtaining the Flattened Device Tree
+
+Juno's device tree blob is built along with the kernel. It is located in:
+
+    <path-to-linux>/arch/arm64/boot/dts/juno.dtb
+
+### Other Juno software information
+
+Please refer to the [Juno Software Guide] to:
+
+*   Deploy a root filesystem
+*   Install and run the Juno binaries on the board
+*   Obtain any other Juno software information
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved._
+
+
+[Firmware Design]:  ./firmware-design.md
+
+[ARM FVP website]:             http://www.arm.com/fvp
+[ARM Connected Community]:     http://community.arm.com
+[Juno Software Guide]:         http://community.arm.com/docs/DOC-8396
+[Juno Board Recovery Image]:   http://community.arm.com/servlet/JiveServlet/download/9427-1-15432/board_recovery_image_0.10.1.zip
+[Juno SCP Firmware]:           http://community.arm.com/servlet/JiveServlet/download/9427-1-15422/bl30.bin.zip
+[Linaro Toolchain]:            http://releases.linaro.org/14.07/components/toolchain/binaries/
+[EDK2]:                        http://github.com/tianocore/edk2
+[DS-5]:                        http://www.arm.com/products/tools/software-tools/ds-5/index.php
+[Polarssl Repository]:         https://github.com/polarssl/polarssl.git
+[Trusted Board Boot]:          trusted-board-boot.md
diff --git a/uefi/arm-trusted-firmware/drivers/arm/cci400/cci400.c b/uefi/arm-trusted-firmware/drivers/arm/cci400/cci400.c
new file mode 100644
index 0000000..6a8737a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/arm/cci400/cci400.c
@@ -0,0 +1,107 @@
+/*
+ * 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 <assert.h>
+#include <cci400.h>
+#include <mmio.h>
+
+#define MAX_CLUSTERS		2
+
+static unsigned long cci_base_addr;
+static unsigned int cci_cluster_ix_to_iface[MAX_CLUSTERS];
+
+
+void cci_init(unsigned long cci_base,
+		int slave_iface3_cluster_ix,
+		int slave_iface4_cluster_ix)
+{
+	/*
+	 * Check the passed arguments are valid. The cluster indices must be
+	 * less than MAX_CLUSTERS, not the same as each other and at least one
+	 * of them must be refer to a valid cluster index.
+	 */
+	assert(cci_base);
+	assert(slave_iface3_cluster_ix < MAX_CLUSTERS);
+	assert(slave_iface4_cluster_ix < MAX_CLUSTERS);
+	assert(slave_iface3_cluster_ix != slave_iface4_cluster_ix);
+	assert((slave_iface3_cluster_ix >= 0) ||
+		(slave_iface3_cluster_ix >= 0));
+
+	cci_base_addr = cci_base;
+	if (slave_iface3_cluster_ix >= 0)
+		cci_cluster_ix_to_iface[slave_iface3_cluster_ix] =
+			SLAVE_IFACE3_OFFSET;
+	if (slave_iface4_cluster_ix >= 0)
+		cci_cluster_ix_to_iface[slave_iface4_cluster_ix] =
+			SLAVE_IFACE4_OFFSET;
+}
+
+static inline unsigned long get_slave_iface_base(unsigned long mpidr)
+{
+	/*
+	 * We assume the TF topology code allocates affinity instances
+	 * consecutively from zero.
+	 * It is a programming error if this is called without initializing
+	 * the slave interface to use for this cluster.
+	 */
+	unsigned int cluster_id =
+		(mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	assert(cluster_id < MAX_CLUSTERS);
+	assert(cci_cluster_ix_to_iface[cluster_id] != 0);
+
+	return cci_base_addr + cci_cluster_ix_to_iface[cluster_id];
+}
+
+void cci_enable_cluster_coherency(unsigned long mpidr)
+{
+	assert(cci_base_addr);
+	/* Enable Snoops and DVM messages */
+	mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG,
+		      DVM_EN_BIT | SNOOP_EN_BIT);
+
+	/* Wait for the dust to settle down */
+	while (mmio_read_32(cci_base_addr + STATUS_REG) & CHANGE_PENDING_BIT)
+		;
+}
+
+void cci_disable_cluster_coherency(unsigned long mpidr)
+{
+	assert(cci_base_addr);
+	/* Disable Snoops and DVM messages */
+	mmio_write_32(get_slave_iface_base(mpidr) + SNOOP_CTRL_REG,
+		      ~(DVM_EN_BIT | SNOOP_EN_BIT));
+
+	/* Wait for the dust to settle down */
+	while (mmio_read_32(cci_base_addr + STATUS_REG) & CHANGE_PENDING_BIT)
+		;
+}
+
diff --git a/uefi/arm-trusted-firmware/drivers/arm/gic/arm_gic.c b/uefi/arm-trusted-firmware/drivers/arm/gic/arm_gic.c
new file mode 100644
index 0000000..58fbc89
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/arm/gic/arm_gic.c
@@ -0,0 +1,476 @@
+/*
+ * 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 <arch_helpers.h>
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <gic_v2.h>
+#include <gic_v3.h>
+#include <interrupt_mgmt.h>
+#include <platform.h>
+#include <stdint.h>
+
+/* Value used to initialize Non-Secure IRQ priorities four at a time */
+#define GICD_IPRIORITYR_DEF_VAL \
+	(GIC_HIGHEST_NS_PRIORITY | \
+	(GIC_HIGHEST_NS_PRIORITY << 8) | \
+	(GIC_HIGHEST_NS_PRIORITY << 16) | \
+	(GIC_HIGHEST_NS_PRIORITY << 24))
+
+static unsigned int g_gicc_base;
+static unsigned int g_gicd_base;
+static unsigned long g_gicr_base;
+static const unsigned int *g_irq_sec_ptr;
+static unsigned int g_num_irqs;
+
+
+/*******************************************************************************
+ * This function does some minimal GICv3 configuration. The Firmware itself does
+ * not fully support GICv3 at this time and relies on GICv2 emulation as
+ * provided by GICv3. This function allows software (like Linux) in later stages
+ * to use full GICv3 features.
+ ******************************************************************************/
+static void gicv3_cpuif_setup(void)
+{
+	unsigned int scr_val, val;
+	uintptr_t base;
+
+	/*
+	 * When CPUs come out of reset they have their GICR_WAKER.ProcessorSleep
+	 * bit set. In order to allow interrupts to get routed to the CPU we
+	 * need to clear this bit if set and wait for GICR_WAKER.ChildrenAsleep
+	 * to clear (GICv3 Architecture specification 5.4.23).
+	 * GICR_WAKER is NOT banked per CPU, compute the correct base address
+	 * per CPU.
+	 */
+	assert(g_gicr_base);
+	base = gicv3_get_rdist(g_gicr_base, read_mpidr());
+	if (base == (uintptr_t)NULL) {
+		/* No re-distributor base address. This interface cannot be
+		 * configured.
+		 */
+		panic();
+	}
+
+	val = gicr_read_waker(base);
+
+	val &= ~WAKER_PS;
+	gicr_write_waker(base, val);
+	dsb();
+
+	/* We need to wait for ChildrenAsleep to clear. */
+	val = gicr_read_waker(base);
+	while (val & WAKER_CA)
+		val = gicr_read_waker(base);
+
+	/*
+	 * We need to set SCR_EL3.NS in order to see GICv3 non-secure state.
+	 * Restore SCR_EL3.NS again before exit.
+	 */
+	scr_val = read_scr();
+	write_scr(scr_val | SCR_NS_BIT);
+	isb();	/* ensure NS=1 takes effect before accessing ICC_SRE_EL2 */
+
+	/*
+	 * By default EL2 and NS-EL1 software should be able to enable GICv3
+	 * System register access without any configuration at EL3. But it turns
+	 * out that GICC PMR as set in GICv2 mode does not affect GICv3 mode. So
+	 * we need to set it here again. In order to do that we need to enable
+	 * register access. We leave it enabled as it should be fine and might
+	 * prevent problems with later software trying to access GIC System
+	 * Registers.
+	 */
+	val = read_icc_sre_el3();
+	write_icc_sre_el3(val | ICC_SRE_EN | ICC_SRE_SRE);
+
+	val = read_icc_sre_el2();
+	write_icc_sre_el2(val | ICC_SRE_EN | ICC_SRE_SRE);
+
+	write_icc_pmr_el1(GIC_PRI_MASK);
+	isb();	/* commit ICC_* changes before setting NS=0 */
+
+	/* Restore SCR_EL3 */
+	write_scr(scr_val);
+	isb();	/* ensure NS=0 takes effect immediately */
+}
+
+/*******************************************************************************
+ * This function does some minimal GICv3 configuration when cores go
+ * down.
+ ******************************************************************************/
+static void gicv3_cpuif_deactivate(void)
+{
+	unsigned int val;
+	uintptr_t base;
+
+	/*
+	 * When taking CPUs down we need to set GICR_WAKER.ProcessorSleep and
+	 * wait for GICR_WAKER.ChildrenAsleep to get set.
+	 * (GICv3 Architecture specification 5.4.23).
+	 * GICR_WAKER is NOT banked per CPU, compute the correct base address
+	 * per CPU.
+	 */
+	assert(g_gicr_base);
+	base = gicv3_get_rdist(g_gicr_base, read_mpidr());
+	if (base == (uintptr_t)NULL) {
+		/* No re-distributor base address. This interface cannot be
+		 * configured.
+		 */
+		panic();
+	}
+
+	val = gicr_read_waker(base);
+	val |= WAKER_PS;
+	gicr_write_waker(base, val);
+	dsb();
+
+	/* We need to wait for ChildrenAsleep to set. */
+	val = gicr_read_waker(base);
+	while ((val & WAKER_CA) == 0)
+		val = gicr_read_waker(base);
+}
+
+
+/*******************************************************************************
+ * Enable secure interrupts and use FIQs to route them. Disable legacy bypass
+ * and set the priority mask register to allow all interrupts to trickle in.
+ ******************************************************************************/
+void arm_gic_cpuif_setup(void)
+{
+	unsigned int val;
+
+	assert(g_gicc_base);
+	val = gicc_read_iidr(g_gicc_base);
+
+	/*
+	 * If GICv3 we need to do a bit of additional setup. We want to
+	 * allow default GICv2 behaviour but allow the next stage to
+	 * enable full gicv3 features.
+	 */
+	if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3)
+		gicv3_cpuif_setup();
+
+	val = ENABLE_GRP0 | FIQ_EN | FIQ_BYP_DIS_GRP0;
+	val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
+
+	gicc_write_pmr(g_gicc_base, GIC_PRI_MASK);
+	gicc_write_ctlr(g_gicc_base, val);
+}
+
+/*******************************************************************************
+ * Place the cpu interface in a state where it can never make a cpu exit wfi as
+ * as result of an asserted interrupt. This is critical for powering down a cpu
+ ******************************************************************************/
+void arm_gic_cpuif_deactivate(void)
+{
+	unsigned int val;
+
+	/* Disable secure, non-secure interrupts and disable their bypass */
+	assert(g_gicc_base);
+	val = gicc_read_ctlr(g_gicc_base);
+	val &= ~(ENABLE_GRP0 | ENABLE_GRP1);
+	val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0;
+	val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1;
+	gicc_write_ctlr(g_gicc_base, val);
+
+	val = gicc_read_iidr(g_gicc_base);
+
+	/*
+	 * If GICv3 we need to do a bit of additional setup. Make sure the
+	 * RDIST is put to sleep.
+	 */
+	if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3)
+		gicv3_cpuif_deactivate();
+}
+
+/*******************************************************************************
+ * Per cpu gic distributor setup which will be done by all cpus after a cold
+ * boot/hotplug. This marks out the secure interrupts & enables them.
+ ******************************************************************************/
+void arm_gic_pcpu_distif_setup(void)
+{
+	unsigned int index, irq_num;
+
+	assert(g_gicd_base);
+
+	/* Mark all 32 SGI+PPI interrupts as Group 1 (non-secure) */
+	gicd_write_igroupr(g_gicd_base, 0, ~0);
+
+	/* Setup PPI priorities doing four at a time */
+	for (index = 0; index < 32; index += 4) {
+		gicd_write_ipriorityr(g_gicd_base, index,
+				GICD_IPRIORITYR_DEF_VAL);
+	}
+
+	assert(g_irq_sec_ptr);
+	for (index = 0; index < g_num_irqs; index++) {
+		irq_num = g_irq_sec_ptr[index];
+		if (irq_num < MIN_SPI_ID) {
+			/* We have an SGI or a PPI */
+			gicd_clr_igroupr(g_gicd_base, irq_num);
+			gicd_set_ipriorityr(g_gicd_base, irq_num,
+				GIC_HIGHEST_SEC_PRIORITY);
+			gicd_set_isenabler(g_gicd_base, irq_num);
+		}
+	}
+}
+
+/*******************************************************************************
+ * Get the current CPU bit mask from GICD_ITARGETSR0
+ ******************************************************************************/
+static unsigned int arm_gic_get_cpuif_id(void)
+{
+	unsigned int val;
+
+	val = gicd_read_itargetsr(g_gicd_base, 0);
+	return val & GIC_TARGET_CPU_MASK;
+}
+
+/*******************************************************************************
+ * Global gic distributor setup which will be done by the primary cpu after a
+ * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It
+ * then enables the secure GIC distributor interface.
+ ******************************************************************************/
+static void arm_gic_distif_setup(void)
+{
+	unsigned int num_ints, ctlr, index, irq_num;
+	uint8_t target_cpu;
+
+	/* Disable the distributor before going further */
+	assert(g_gicd_base);
+	ctlr = gicd_read_ctlr(g_gicd_base);
+	ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1);
+	gicd_write_ctlr(g_gicd_base, ctlr);
+
+	/*
+	 * Mark out non-secure SPI interrupts. The number of interrupts is
+	 * calculated as 32 * (IT_LINES + 1). We do 32 at a time.
+	 */
+	num_ints = gicd_read_typer(g_gicd_base) & IT_LINES_NO_MASK;
+	num_ints = (num_ints + 1) << 5;
+	for (index = MIN_SPI_ID; index < num_ints; index += 32)
+		gicd_write_igroupr(g_gicd_base, index, ~0);
+
+	/* Setup SPI priorities doing four at a time */
+	for (index = MIN_SPI_ID; index < num_ints; index += 4) {
+		gicd_write_ipriorityr(g_gicd_base, index,
+				GICD_IPRIORITYR_DEF_VAL);
+	}
+
+	/* Read the target CPU mask */
+	target_cpu = arm_gic_get_cpuif_id();
+
+	/* Configure SPI secure interrupts now */
+	assert(g_irq_sec_ptr);
+	for (index = 0; index < g_num_irqs; index++) {
+		irq_num = g_irq_sec_ptr[index];
+		if (irq_num >= MIN_SPI_ID) {
+			/* We have an SPI */
+			gicd_clr_igroupr(g_gicd_base, irq_num);
+			gicd_set_ipriorityr(g_gicd_base, irq_num,
+				GIC_HIGHEST_SEC_PRIORITY);
+			gicd_set_itargetsr(g_gicd_base, irq_num, target_cpu);
+			gicd_set_isenabler(g_gicd_base, irq_num);
+		}
+	}
+
+	/*
+	 * Configure the SGI and PPI. This is done in a separated function
+	 * because each CPU is responsible for initializing its own private
+	 * interrupts.
+	 */
+	arm_gic_pcpu_distif_setup();
+
+	gicd_write_ctlr(g_gicd_base, ctlr | ENABLE_GRP0);
+}
+
+/*******************************************************************************
+ * Initialize the ARM GIC driver with the provided platform inputs
+******************************************************************************/
+void arm_gic_init(unsigned int gicc_base,
+		unsigned int gicd_base,
+		unsigned long gicr_base,
+		const unsigned int *irq_sec_ptr,
+		unsigned int num_irqs
+		)
+{
+	unsigned int val;
+
+	assert(gicc_base);
+	assert(gicd_base);
+	assert(irq_sec_ptr);
+
+	g_gicc_base = gicc_base;
+	g_gicd_base = gicd_base;
+
+	val = gicc_read_iidr(g_gicc_base);
+
+	if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3) {
+		assert(gicr_base);
+		g_gicr_base = gicr_base;
+	}
+
+	g_irq_sec_ptr = irq_sec_ptr;
+	g_num_irqs = num_irqs;
+}
+
+/*******************************************************************************
+ * Setup the ARM GIC CPU and distributor interfaces.
+******************************************************************************/
+void arm_gic_setup(void)
+{
+	arm_gic_cpuif_setup();
+	arm_gic_distif_setup();
+}
+
+/*******************************************************************************
+ * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins.
+ * The interrupt controller knows which pin/line it uses to signal a type of
+ * interrupt. This function provides a common implementation of
+ * plat_interrupt_type_to_line() in an ARM GIC environment for optional re-use
+ * across platforms. It lets the interrupt management framework determine
+ * for a type of interrupt and security state, which line should be used in the
+ * SCR_EL3 to control its routing to EL3. The interrupt line is represented as
+ * the bit position of the IRQ or FIQ bit in the SCR_EL3.
+ ******************************************************************************/
+uint32_t arm_gic_interrupt_type_to_line(uint32_t type,
+				uint32_t security_state)
+{
+	assert(type == INTR_TYPE_S_EL1 ||
+	       type == INTR_TYPE_EL3 ||
+	       type == INTR_TYPE_NS);
+
+	assert(sec_state_is_valid(security_state));
+
+	/*
+	 * We ignore the security state parameter under the assumption that
+	 * both normal and secure worlds are using ARM GICv2. This parameter
+	 * will be used when the secure world starts using GICv3.
+	 */
+#if ARM_GIC_ARCH == 2
+	return gicv2_interrupt_type_to_line(g_gicc_base, type);
+#else
+#error "Invalid ARM GIC architecture version specified for platform port"
+#endif /* ARM_GIC_ARCH */
+}
+
+#if ARM_GIC_ARCH == 2
+/*******************************************************************************
+ * This function returns the type of the highest priority pending interrupt at
+ * the GIC cpu interface. INTR_TYPE_INVAL is returned when there is no
+ * interrupt pending.
+ ******************************************************************************/
+uint32_t arm_gic_get_pending_interrupt_type(void)
+{
+	uint32_t id;
+
+	assert(g_gicc_base);
+	id = gicc_read_hppir(g_gicc_base);
+
+	/* Assume that all secure interrupts are S-EL1 interrupts */
+	if (id < 1022)
+		return INTR_TYPE_S_EL1;
+
+	if (id == GIC_SPURIOUS_INTERRUPT)
+		return INTR_TYPE_INVAL;
+
+	return INTR_TYPE_NS;
+}
+
+/*******************************************************************************
+ * This function returns the id of the highest priority pending interrupt at
+ * the GIC cpu interface. INTR_ID_UNAVAILABLE is returned when there is no
+ * interrupt pending.
+ ******************************************************************************/
+uint32_t arm_gic_get_pending_interrupt_id(void)
+{
+	uint32_t id;
+
+	assert(g_gicc_base);
+	id = gicc_read_hppir(g_gicc_base);
+
+	if (id < 1022)
+		return id;
+
+	if (id == 1023)
+		return INTR_ID_UNAVAILABLE;
+
+	/*
+	 * Find out which non-secure interrupt it is under the assumption that
+	 * the GICC_CTLR.AckCtl bit is 0.
+	 */
+	return gicc_read_ahppir(g_gicc_base);
+}
+
+/*******************************************************************************
+ * This functions reads the GIC cpu interface Interrupt Acknowledge register
+ * to start handling the pending interrupt. It returns the contents of the IAR.
+ ******************************************************************************/
+uint32_t arm_gic_acknowledge_interrupt(void)
+{
+	assert(g_gicc_base);
+	return gicc_read_IAR(g_gicc_base);
+}
+
+/*******************************************************************************
+ * This functions writes the GIC cpu interface End Of Interrupt register with
+ * the passed value to finish handling the active interrupt
+ ******************************************************************************/
+void arm_gic_end_of_interrupt(uint32_t id)
+{
+	assert(g_gicc_base);
+	gicc_write_EOIR(g_gicc_base, id);
+}
+
+/*******************************************************************************
+ * This function returns the type of the interrupt id depending upon the group
+ * this interrupt has been configured under by the interrupt controller i.e.
+ * group0 or group1.
+ ******************************************************************************/
+uint32_t arm_gic_get_interrupt_type(uint32_t id)
+{
+	uint32_t group;
+
+	assert(g_gicd_base);
+	group = gicd_get_igroupr(g_gicd_base, id);
+
+	/* Assume that all secure interrupts are S-EL1 interrupts */
+	if (group == GRP0)
+		return INTR_TYPE_S_EL1;
+	else
+		return INTR_TYPE_NS;
+}
+
+#else
+#error "Invalid ARM GIC architecture version specified for platform port"
+#endif /* ARM_GIC_ARCH */
diff --git a/uefi/arm-trusted-firmware/drivers/arm/gic/gic_v2.c b/uefi/arm-trusted-firmware/drivers/arm/gic/gic_v2.c
new file mode 100644
index 0000000..41603a9
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/arm/gic/gic_v2.c
@@ -0,0 +1,317 @@
+/*
+ * 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 <assert.h>
+#include <gic_v2.h>
+#include <interrupt_mgmt.h>
+#include <mmio.h>
+
+/*******************************************************************************
+ * GIC Distributor interface accessors for reading entire registers
+ ******************************************************************************/
+
+unsigned int gicd_read_igroupr(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> IGROUPR_SHIFT;
+	return mmio_read_32(base + GICD_IGROUPR + (n << 2));
+}
+
+unsigned int gicd_read_isenabler(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> ISENABLER_SHIFT;
+	return mmio_read_32(base + GICD_ISENABLER + (n << 2));
+}
+
+unsigned int gicd_read_icenabler(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> ICENABLER_SHIFT;
+	return mmio_read_32(base + GICD_ICENABLER + (n << 2));
+}
+
+unsigned int gicd_read_ispendr(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> ISPENDR_SHIFT;
+	return mmio_read_32(base + GICD_ISPENDR + (n << 2));
+}
+
+unsigned int gicd_read_icpendr(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> ICPENDR_SHIFT;
+	return mmio_read_32(base + GICD_ICPENDR + (n << 2));
+}
+
+unsigned int gicd_read_isactiver(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> ISACTIVER_SHIFT;
+	return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
+}
+
+unsigned int gicd_read_icactiver(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> ICACTIVER_SHIFT;
+	return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
+}
+
+unsigned int gicd_read_ipriorityr(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> IPRIORITYR_SHIFT;
+	return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
+}
+
+unsigned int gicd_read_itargetsr(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> ITARGETSR_SHIFT;
+	return mmio_read_32(base + GICD_ITARGETSR + (n << 2));
+}
+
+unsigned int gicd_read_icfgr(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> ICFGR_SHIFT;
+	return mmio_read_32(base + GICD_ICFGR + (n << 2));
+}
+
+unsigned int gicd_read_cpendsgir(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> CPENDSGIR_SHIFT;
+	return mmio_read_32(base + GICD_CPENDSGIR + (n << 2));
+}
+
+unsigned int gicd_read_spendsgir(unsigned int base, unsigned int id)
+{
+	unsigned n = id >> SPENDSGIR_SHIFT;
+	return mmio_read_32(base + GICD_SPENDSGIR + (n << 2));
+}
+
+/*******************************************************************************
+ * GIC Distributor interface accessors for writing entire registers
+ ******************************************************************************/
+
+void gicd_write_igroupr(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> IGROUPR_SHIFT;
+	mmio_write_32(base + GICD_IGROUPR + (n << 2), val);
+}
+
+void gicd_write_isenabler(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> ISENABLER_SHIFT;
+	mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
+}
+
+void gicd_write_icenabler(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> ICENABLER_SHIFT;
+	mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
+}
+
+void gicd_write_ispendr(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> ISPENDR_SHIFT;
+	mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
+}
+
+void gicd_write_icpendr(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> ICPENDR_SHIFT;
+	mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
+}
+
+void gicd_write_isactiver(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> ISACTIVER_SHIFT;
+	mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
+}
+
+void gicd_write_icactiver(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> ICACTIVER_SHIFT;
+	mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
+}
+
+void gicd_write_ipriorityr(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> IPRIORITYR_SHIFT;
+	mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
+}
+
+void gicd_write_itargetsr(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> ITARGETSR_SHIFT;
+	mmio_write_32(base + GICD_ITARGETSR + (n << 2), val);
+}
+
+void gicd_write_icfgr(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> ICFGR_SHIFT;
+	mmio_write_32(base + GICD_ICFGR + (n << 2), val);
+}
+
+void gicd_write_cpendsgir(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> CPENDSGIR_SHIFT;
+	mmio_write_32(base + GICD_CPENDSGIR + (n << 2), val);
+}
+
+void gicd_write_spendsgir(unsigned int base, unsigned int id, unsigned int val)
+{
+	unsigned n = id >> SPENDSGIR_SHIFT;
+	mmio_write_32(base + GICD_SPENDSGIR + (n << 2), val);
+}
+
+/*******************************************************************************
+ * GIC Distributor interface accessors for individual interrupt manipulation
+ ******************************************************************************/
+unsigned int gicd_get_igroupr(unsigned int base, unsigned int id)
+{
+	unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
+	unsigned int reg_val = gicd_read_igroupr(base, id);
+
+	return (reg_val >> bit_num) & 0x1;
+}
+
+void gicd_set_igroupr(unsigned int base, unsigned int id)
+{
+	unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
+	unsigned int reg_val = gicd_read_igroupr(base, id);
+
+	gicd_write_igroupr(base, id, reg_val | (1 << bit_num));
+}
+
+void gicd_clr_igroupr(unsigned int base, unsigned int id)
+{
+	unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
+	unsigned int reg_val = gicd_read_igroupr(base, id);
+
+	gicd_write_igroupr(base, id, reg_val & ~(1 << bit_num));
+}
+
+void gicd_set_isenabler(unsigned int base, unsigned int id)
+{
+	unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1);
+
+	gicd_write_isenabler(base, id, (1 << bit_num));
+}
+
+void gicd_set_icenabler(unsigned int base, unsigned int id)
+{
+	unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1);
+
+	gicd_write_icenabler(base, id, (1 << bit_num));
+}
+
+void gicd_set_ispendr(unsigned int base, unsigned int id)
+{
+	unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1);
+
+	gicd_write_ispendr(base, id, (1 << bit_num));
+}
+
+void gicd_set_icpendr(unsigned int base, unsigned int id)
+{
+	unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1);
+
+	gicd_write_icpendr(base, id, (1 << bit_num));
+}
+
+void gicd_set_isactiver(unsigned int base, unsigned int id)
+{
+	unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
+
+	gicd_write_isactiver(base, id, (1 << bit_num));
+}
+
+void gicd_set_icactiver(unsigned int base, unsigned int id)
+{
+	unsigned bit_num = id & ((1 << ICACTIVER_SHIFT) - 1);
+
+	gicd_write_icactiver(base, id, (1 << bit_num));
+}
+
+/*
+ * Make sure that the interrupt's group is set before expecting
+ * this function to do its job correctly.
+ */
+void gicd_set_ipriorityr(unsigned int base, unsigned int id, unsigned int pri)
+{
+	unsigned int reg = base + GICD_IPRIORITYR + (id & ~3);
+	unsigned int shift = (id & 3) << 3;
+	unsigned int reg_val = mmio_read_32(reg);
+
+	/*
+	 * Enforce ARM recommendation to manage priority values such
+	 * that group1 interrupts always have a lower priority than
+	 * group0 interrupts.
+	 * Note, lower numerical values are higher priorities so the comparison
+	 * checks below are reversed from what might be expected.
+	 */
+	assert(gicd_get_igroupr(base, id) == GRP1 ?
+		pri >= GIC_HIGHEST_NS_PRIORITY &&
+			pri <= GIC_LOWEST_NS_PRIORITY :
+		pri >= GIC_HIGHEST_SEC_PRIORITY &&
+			pri <= GIC_LOWEST_SEC_PRIORITY);
+
+	reg_val &= ~(GIC_PRI_MASK << shift);
+	reg_val |= (pri & GIC_PRI_MASK) << shift;
+	mmio_write_32(reg, reg_val);
+}
+
+void gicd_set_itargetsr(unsigned int base, unsigned int id, unsigned int target)
+{
+	unsigned byte_off = id & ((1 << ITARGETSR_SHIFT) - 1);
+	unsigned int reg_val = gicd_read_itargetsr(base, id);
+
+	gicd_write_itargetsr(base, id, reg_val | (target << (byte_off << 3)));
+}
+
+/*******************************************************************************
+ * This function allows the interrupt management framework to determine (through
+ * the platform) which interrupt line (IRQ/FIQ) to use for an interrupt type to
+ * route it to EL3. The interrupt line is represented as the bit position of the
+ * IRQ or FIQ bit in the SCR_EL3.
+ ******************************************************************************/
+uint32_t gicv2_interrupt_type_to_line(uint32_t cpuif_base, uint32_t type)
+{
+	uint32_t gicc_ctlr;
+
+	/* Non-secure interrupts are signalled on the IRQ line always */
+	if (type == INTR_TYPE_NS)
+		return __builtin_ctz(SCR_IRQ_BIT);
+
+	/*
+	 * Secure interrupts are signalled using the IRQ line if the FIQ_EN
+	 * bit is not set else they are signalled using the FIQ line.
+	 */
+	gicc_ctlr = gicc_read_ctlr(cpuif_base);
+	if (gicc_ctlr & FIQ_EN)
+		return __builtin_ctz(SCR_FIQ_BIT);
+	else
+		return __builtin_ctz(SCR_IRQ_BIT);
+}
diff --git a/uefi/arm-trusted-firmware/drivers/arm/gic/gic_v3.c b/uefi/arm-trusted-firmware/drivers/arm/gic/gic_v3.c
new file mode 100644
index 0000000..f429662
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/arm/gic/gic_v3.c
@@ -0,0 +1,80 @@
+/*
+ * 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 <debug.h>
+#include <gic_v3.h>
+
+uintptr_t gicv3_get_rdist(uintptr_t gicr_base, uint64_t mpidr)
+{
+	uint32_t  cpu_aff, gicr_aff;
+	uint64_t  gicr_typer;
+	uintptr_t addr;
+
+	/* Construct the affinity as used by GICv3. MPIDR and GIC affinity level
+	 * mask is the same.
+	 */
+	cpu_aff  = ((mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK) <<
+			GICV3_AFF0_SHIFT;
+	cpu_aff |= ((mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK) <<
+			GICV3_AFF1_SHIFT;
+	cpu_aff |= ((mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK) <<
+			GICV3_AFF2_SHIFT;
+	cpu_aff |= ((mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK) <<
+			GICV3_AFF3_SHIFT;
+
+	addr = gicr_base;
+	do {
+		gicr_typer = gicr_read_typer(addr);
+
+		gicr_aff = (gicr_typer >> GICR_TYPER_AFF_SHIFT) &
+				GICR_TYPER_AFF_MASK;
+		if (cpu_aff == gicr_aff) {
+			/* Disable this print for now as it appears every time
+			 * when using PSCI CPU_SUSPEND.
+			 * TODO: Print this only the first time for each CPU.
+			 * INFO("GICv3 - Found RDIST for MPIDR(0x%lx) at 0x%lx\n",
+			 *	mpidr, addr);
+			 */
+			return addr;
+		}
+
+		/* TODO:
+		 * For GICv4 we need to adjust the Base address based on
+		 * GICR_TYPER.VLPIS
+		 */
+		addr += (1 << GICR_PCPUBASE_SHIFT);
+
+	} while (!(gicr_typer & GICR_TYPER_LAST));
+
+	/* If we get here we did not find a match. */
+	ERROR("GICv3 - Did not find RDIST for CPU with MPIDR 0x%lx\n", mpidr);
+	return (uintptr_t)NULL;
+}
diff --git a/uefi/arm-trusted-firmware/drivers/arm/gpio/gpio.c b/uefi/arm-trusted-firmware/drivers/arm/gpio/gpio.c
new file mode 100644
index 0000000..a38db94
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/arm/gpio/gpio.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd and Contributors. All rights reserved.
+ *
+ * GPIO driver for PL061
+ *
+ * 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 <console.h>
+#include <debug.h>
+#include <errno.h>
+#include <gpio.h>
+#include <mmio.h>
+
+#define MAX_GPIO_DEVICES	32
+#define GPIOS_PER_DEV		8
+#define GPIO_DIR		0x400
+
+#define BIT(nr)			(1UL << (nr))
+
+struct gpio_device_t {
+	unsigned int	base[MAX_GPIO_DEVICES];
+	unsigned int	count;
+};
+
+static struct gpio_device_t gpio_dev;
+
+/* return 0 for failure */
+static unsigned int find_gc_base(unsigned int gpio)
+{
+	int gc;
+
+	gc = gpio / GPIOS_PER_DEV;
+	if (gc >= gpio_dev.count)
+		return 0;
+	return gpio_dev.base[gc];
+}
+
+int gpio_direction_input(unsigned int gpio)
+{
+	unsigned int gc_base, offset, data;
+
+	gc_base = find_gc_base(gpio);
+	if (!gc_base)
+		return -EINVAL;
+	offset = gpio % GPIOS_PER_DEV;
+
+	data = mmio_read_8(gc_base + GPIO_DIR);
+	data &= ~(1 << offset);
+	mmio_write_8(gc_base + GPIO_DIR, data);
+	return 0;
+}
+
+int gpio_direction_output(unsigned int gpio)
+{
+	unsigned int gc_base, offset, data;
+
+	gc_base = find_gc_base(gpio);
+	if (!gc_base)
+		return -EINVAL;
+	offset = gpio % 8;
+
+	data = mmio_read_8(gc_base + GPIO_DIR);
+	data |= 1 << offset;
+	mmio_write_8(gc_base + GPIO_DIR, data);
+	return 0;
+}
+
+int gpio_get_value(unsigned int gpio)
+{
+	unsigned int gc_base, offset;
+
+	gc_base = find_gc_base(gpio);
+	if (!gc_base)
+		return -EINVAL;
+	offset = gpio % 8;
+
+	return !!mmio_read_8(gc_base + (BIT(offset + 2)));
+}
+
+int gpio_set_value(unsigned int gpio, unsigned int value)
+{
+	unsigned int gc_base, offset;
+
+	gc_base = find_gc_base(gpio);
+	if (!gc_base)
+		return -EINVAL;
+	offset = gpio % 8;
+	mmio_write_8(gc_base + (BIT(offset + 2)), !!value << offset); 
+	return 0;
+}
+
+int gpio_register_device(unsigned int base)
+{
+	int i;
+	if (gpio_dev.count > MAX_GPIO_DEVICES)
+		return -EINVAL;
+	for (i = 0; i < gpio_dev.count; i++) {
+		if (gpio_dev.base[i] == base) {
+			WARN("%s: duplicated gpio base\n", __func__);
+			return -EINVAL;
+		}
+	}
+	gpio_dev.base[gpio_dev.count] = base;
+	gpio_dev.count++;
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/drivers/arm/pl011/pl011_console.S b/uefi/arm-trusted-firmware/drivers/arm/pl011/pl011_console.S
new file mode 100644
index 0000000..5ff1582
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/arm/pl011/pl011_console.S
@@ -0,0 +1,178 @@
+/*
+ * 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 <pl011.h>
+
+	.globl	console_init
+	.globl	console_putc
+	.globl	console_core_init
+	.globl	console_core_putc
+	.globl	console_getc
+
+	/*
+	 *  The console base is in the data section and not in .bss
+	 *  even though it is zero-init. In particular, this allows
+	 *  the console functions to start using this variable before
+	 *  the runtime memory is initialized for images which do not
+	 *  need to copy the .data section from ROM to RAM.
+	 */
+.section .data.console_base ; .align 3
+	console_base: .quad 0x0
+
+	/* -----------------------------------------------
+	 * int console_init(unsigned long base_addr,
+	 * unsigned int uart_clk, unsigned int baud_rate)
+	 * Function to initialize the console without a
+	 * C Runtime to print debug information. It saves
+	 * the console base to the data section.
+	 * In: x0 - console base address
+	 *     w1 - Uart clock in Hz
+	 *     w2 - Baud rate
+	 * out: return 1 on success.
+	 * Clobber list : x1 - x3
+	 * -----------------------------------------------
+	 */
+func console_init
+	adrp	x3, console_base
+	str	x0, [x3, :lo12:console_base]
+	b	console_core_init
+
+	/* -----------------------------------------------
+	 * int console_core_init(unsigned long base_addr,
+	 * unsigned int uart_clk, unsigned int baud_rate)
+	 * Function to initialize the console without a
+	 * C Runtime to print debug information. This
+	 * function will be accessed by console_init and
+	 * crash reporting.
+	 * In: x0 - console base address
+	 *     w1 - Uart clock in Hz
+	 *     w2 - Baud rate
+	 * Out: return 1 on success
+	 * Clobber list : x1, x2
+	 * -----------------------------------------------
+	 */
+func console_core_init
+	/* Check the input base address */
+	cbz	x0, init_fail
+	/* Check baud rate and uart clock for sanity */
+	cbz	w1, init_fail
+	cbz	w2, init_fail
+	/* Program the baudrate */
+	/* Divisor =  (Uart clock * 4) / baudrate */
+	lsl	w1, w1, #2
+	udiv	w2, w1, w2
+	/* IBRD = Divisor >> 6 */
+	lsr	w1, w2, #6
+	/* Write the IBRD */
+	str	w1, [x0, #UARTIBRD]
+	/* FBRD = Divisor & 0x3F */
+	and	w1, w2, #0x3f
+	/* Write the FBRD */
+	str	w1, [x0, #UARTFBRD]
+	mov	w1, #PL011_LINE_CONTROL
+	str	w1, [x0, #UARTLCR_H]
+	/* Clear any pending errors */
+	str	wzr, [x0, #UARTECR]
+	/* Enable tx, rx, and uart overall */
+	mov	w1, #(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN)
+	str	w1, [x0, #UARTCR]
+	mov	w0, #1
+init_fail:
+	ret
+
+	/* ---------------------------------------------
+	 * int console_putc(int c)
+	 * Function to output a character over the
+	 * console. It returns the character printed on
+	 * success or -1 on error.
+	 * In : x0 - character to be printed
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func console_putc
+	adrp	x2, console_base
+	ldr	x1, [x2, :lo12:console_base]
+	b	console_core_putc
+
+	/* --------------------------------------------------------
+	 * int console_core_putc(int c, unsigned int base_addr)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - console base address
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_core_putc
+	/* Check the input parameter */
+	cbz	x1, putc_error
+	/* Prepend '\r' to '\n' */
+	cmp	w0, #0xA
+	b.ne	2f
+1:
+	/* Check if the transmit FIFO is full */
+	ldr	w2, [x1, #UARTFR]
+	tbnz	w2, #PL011_UARTFR_TXFF_BIT, 1b
+	mov	w2, #0xD
+	str	w2, [x1, #UARTDR]
+2:
+	/* Check if the transmit FIFO is full */
+	ldr	w2, [x1, #UARTFR]
+	tbnz	w2, #PL011_UARTFR_TXFF_BIT, 2b
+	str	w0, [x1, #UARTDR]
+	ret
+putc_error:
+	mov	w0, #-1
+	ret
+
+	/* ---------------------------------------------
+	 * int console_getc(void)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 on error.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_getc
+	adrp	x0, console_base
+	ldr	x1, [x0, :lo12:console_base]
+	cbz	x1, getc_error
+1:
+	/* Check if the receive FIFO is empty */
+	ldr	w0, [x1, #UARTFR]
+	tbnz	w0, #PL011_UARTFR_RXFE_BIT, 1b
+	ldr	w0, [x1, #UARTDR]
+	ret
+getc_error:
+	mov	w0, #-1
+	ret
diff --git a/uefi/arm-trusted-firmware/drivers/arm/tzc400/tzc400.c b/uefi/arm-trusted-firmware/drivers/arm/tzc400/tzc400.c
new file mode 100644
index 0000000..df52c9c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/arm/tzc400/tzc400.c
@@ -0,0 +1,307 @@
+/*
+ * 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 <debug.h>
+#include <mmio.h>
+#include <stddef.h>
+#include <tzc400.h>
+
+/*
+ * Implementation defined values used to validate inputs later.
+ * Filters : max of 4 ; 0 to 3
+ * Regions : max of 9 ; 0 to 8
+ * Address width : Values between 32 to 64
+ */
+typedef struct tzc_instance {
+	uint64_t base;
+	uint8_t addr_width;
+	uint8_t num_filters;
+	uint8_t num_regions;
+} tzc_instance_t;
+
+tzc_instance_t tzc;
+
+
+static inline uint32_t tzc_read_build_config(uint64_t base)
+{
+	return mmio_read_32(base + BUILD_CONFIG_OFF);
+}
+
+static inline uint32_t tzc_read_gate_keeper(uint64_t base)
+{
+	return mmio_read_32(base + GATE_KEEPER_OFF);
+}
+
+static inline void tzc_write_gate_keeper(uint64_t base, uint32_t val)
+{
+	mmio_write_32(base + GATE_KEEPER_OFF, val);
+}
+
+static inline void tzc_write_action(uint64_t base, tzc_action_t action)
+{
+	mmio_write_32(base + ACTION_OFF, action);
+}
+
+static inline void tzc_write_region_base_low(uint64_t base,
+					uint32_t region,
+					uint32_t val)
+{
+	mmio_write_32(base + REGION_BASE_LOW_OFF +
+		REGION_NUM_OFF(region), val);
+}
+
+static inline void tzc_write_region_base_high(uint64_t base,
+					uint32_t region,
+					uint32_t val)
+{
+	mmio_write_32(base + REGION_BASE_HIGH_OFF +
+		REGION_NUM_OFF(region), val);
+}
+
+static inline void tzc_write_region_top_low(uint64_t base,
+					uint32_t region,
+					uint32_t val)
+{
+	mmio_write_32(base + REGION_TOP_LOW_OFF +
+		REGION_NUM_OFF(region), val);
+}
+
+static inline void tzc_write_region_top_high(uint64_t base,
+					uint32_t region,
+					uint32_t val)
+{
+	mmio_write_32(base + REGION_TOP_HIGH_OFF +
+		REGION_NUM_OFF(region), val);
+}
+
+static inline void tzc_write_region_attributes(uint64_t base,
+					uint32_t region,
+					uint32_t val)
+{
+	mmio_write_32(base + REGION_ATTRIBUTES_OFF +
+		REGION_NUM_OFF(region), val);
+}
+
+static inline void tzc_write_region_id_access(uint64_t base,
+					uint32_t region,
+					uint32_t val)
+{
+	mmio_write_32(base + REGION_ID_ACCESS_OFF +
+		REGION_NUM_OFF(region), val);
+}
+
+static uint32_t tzc_read_component_id(uint64_t base)
+{
+	uint32_t id;
+
+	id = mmio_read_8(base + CID0_OFF);
+	id |= (mmio_read_8(base + CID1_OFF) << 8);
+	id |= (mmio_read_8(base + CID2_OFF) << 16);
+	id |= (mmio_read_8(base + CID3_OFF) << 24);
+
+	return id;
+}
+
+static uint32_t tzc_get_gate_keeper(uint64_t base, uint8_t filter)
+{
+	uint32_t tmp;
+
+	tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
+		GATE_KEEPER_OS_MASK;
+
+	return (tmp >> filter) & GATE_KEEPER_FILTER_MASK;
+}
+
+/* This function is not MP safe. */
+static void tzc_set_gate_keeper(uint64_t base, uint8_t filter, uint32_t val)
+{
+	uint32_t tmp;
+
+	/* Upper half is current state. Lower half is requested state. */
+	tmp = (tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
+		GATE_KEEPER_OS_MASK;
+
+	if (val)
+		tmp |=  (1 << filter);
+	else
+		tmp &= ~(1 << filter);
+
+	tzc_write_gate_keeper(base, (tmp & GATE_KEEPER_OR_MASK) <<
+			      GATE_KEEPER_OR_SHIFT);
+
+	/* Wait here until we see the change reflected in the TZC status. */
+	while (((tzc_read_gate_keeper(base) >> GATE_KEEPER_OS_SHIFT) &
+		GATE_KEEPER_OS_MASK) != tmp)
+	  ;
+}
+
+
+void tzc_init(uint64_t base)
+{
+	uint32_t tzc_id, tzc_build;
+
+	assert(base);
+	tzc.base = base;
+
+	/*
+	 * We expect to see a tzc400. Check component ID. The TZC-400 TRM shows
+	 * component ID is expected to be "0xB105F00D".
+	 */
+	tzc_id = tzc_read_component_id(tzc.base);
+	if (tzc_id != TZC400_COMPONENT_ID) {
+		ERROR("TZC : Wrong device ID (0x%x).\n", tzc_id);
+		panic();
+	}
+
+	/* Save values we will use later. */
+	tzc_build = tzc_read_build_config(tzc.base);
+	tzc.num_filters = ((tzc_build >> BUILD_CONFIG_NF_SHIFT) &
+			   BUILD_CONFIG_NF_MASK) + 1;
+	tzc.addr_width  = ((tzc_build >> BUILD_CONFIG_AW_SHIFT) &
+			   BUILD_CONFIG_AW_MASK) + 1;
+	tzc.num_regions = ((tzc_build >> BUILD_CONFIG_NR_SHIFT) &
+			   BUILD_CONFIG_NR_MASK) + 1;
+}
+
+
+/*
+ * `tzc_configure_region` is used to program regions into the TrustZone
+ * controller. A region can be associated with more than one filter. The
+ * associated filters are passed in as a bitmap (bit0 = filter0).
+ * NOTE:
+ * The region 0 covers the whole address space and is enabled on all filters,
+ * this cannot be changed. It is, however, possible to change some region 0
+ * permissions.
+ */
+void tzc_configure_region(uint32_t filters,
+			  uint8_t  region,
+			  uint64_t region_base,
+			  uint64_t region_top,
+			  tzc_region_attributes_t sec_attr,
+			  uint32_t ns_device_access)
+{
+	assert(tzc.base);
+
+	/* Do range checks on filters and regions. */
+	assert(((filters >> tzc.num_filters) == 0) &&
+	       (region < tzc.num_regions));
+
+	/*
+	 * Do address range check based on TZC configuration. A 64bit address is
+	 * the max and expected case.
+	 */
+	assert(((region_top <= (UINT64_MAX >> (64 - tzc.addr_width))) &&
+		(region_base < region_top)));
+
+	/* region_base and (region_top + 1) must be 4KB aligned */
+	assert(((region_base | (region_top + 1)) & (4096 - 1)) == 0);
+
+	assert(sec_attr <= TZC_REGION_S_RDWR);
+
+	/*
+	 * Inputs look ok, start programming registers.
+	 * All the address registers are 32 bits wide and have a LOW and HIGH
+	 * component used to construct a up to a 64bit address.
+	 */
+	tzc_write_region_base_low(tzc.base, region,
+				(uint32_t)(region_base));
+	tzc_write_region_base_high(tzc.base, region,
+				(uint32_t)(region_base >> 32));
+
+	tzc_write_region_top_low(tzc.base, region,
+				(uint32_t)(region_top));
+	tzc_write_region_top_high(tzc.base, region,
+				(uint32_t)(region_top >> 32));
+
+	/* Assign the region to a filter and set secure attributes */
+	tzc_write_region_attributes(tzc.base, region,
+		(sec_attr << REG_ATTR_SEC_SHIFT) | filters);
+
+	/*
+	 * Specify which non-secure devices have permission to access this
+	 * region.
+	 */
+	tzc_write_region_id_access(tzc.base, region, ns_device_access);
+}
+
+
+void tzc_set_action(tzc_action_t action)
+{
+	assert(tzc.base);
+
+	/*
+	 * - Currently no handler is provided to trap an error via interrupt
+	 *   or exception.
+	 * - The interrupt action has not been tested.
+	 */
+	tzc_write_action(tzc.base, action);
+}
+
+
+void tzc_enable_filters(void)
+{
+	uint32_t state;
+	uint32_t filter;
+
+	assert(tzc.base);
+
+	for (filter = 0; filter < tzc.num_filters; filter++) {
+		state = tzc_get_gate_keeper(tzc.base, filter);
+		if (state) {
+			/* The TZC filter is already configured. Changing the
+			 * programmer's view in an active system can cause
+			 * unpredictable behavior therefore panic for now rather
+			 * than try to determine whether this is safe in this
+			 * instance. See:
+			 * http://infocenter.arm.com/help/index.jsp?\
+			 * topic=/com.arm.doc.ddi0504c/CJHHECBF.html */
+			ERROR("TZC : Filter %d Gatekeeper already enabled.\n",
+				filter);
+			panic();
+		}
+		tzc_set_gate_keeper(tzc.base, filter, 1);
+	}
+}
+
+
+void tzc_disable_filters(void)
+{
+	uint32_t filter;
+
+	assert(tzc.base);
+
+	/*
+	 * We don't do the same state check as above as the Gatekeepers are
+	 * disabled after reset.
+	 */
+	for (filter = 0; filter < tzc.num_filters; filter++)
+		tzc_set_gate_keeper(tzc.base, filter, 0);
+}
diff --git a/uefi/arm-trusted-firmware/drivers/io/io_block.c b/uefi/arm-trusted-firmware/drivers/io/io_block.c
new file mode 100644
index 0000000..4047227
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/io/io_block.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <debug.h>
+#include <errno.h>
+#include <io_block.h>
+#include <io_driver.h>
+#include <io_storage.h>
+#include <mmio.h>
+#include <stdint.h>
+#include <string.h>
+
+/* As we need to be able to keep state for seek, only one file can be open
+ * at a time. Make this a structure and point to the entity->info. When we
+ * can malloc memory we can change this to support more open files.
+ */
+typedef struct {
+	/* Use the 'in_use' flag as any value for base and file_pos could be
+	 * valid.
+	 */
+	int		in_use;
+	uintptr_t	base;
+	size_t		file_pos;
+	uint32_t	flags;
+} file_state_t;
+
+struct block_info {
+	struct block_ops	ops;
+	int			init;
+	uint32_t		flags;
+};
+
+static file_state_t current_file = {0};
+
+static struct block_info block_info;
+
+static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
+		      io_entity_t *entity);
+static int block_seek(io_entity_t *entity, int mode, ssize_t offset);
+static int block_read(io_entity_t *entity, uintptr_t buffer,
+		      size_t length, size_t *length_read);
+static int block_write(io_entity_t *entity, uintptr_t buffer,
+		       size_t length, size_t *length_written);
+static int block_close(io_entity_t *entity);
+
+static int blk_dev_init(io_dev_info_t *dev_info,
+			const uintptr_t init_params);
+static int blk_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
+static int blk_dev_close(io_dev_info_t *dev_info);
+
+/* Identify the device type as block */
+io_type_t device_type_block(void)
+{
+	return IO_TYPE_BLOCK;
+}
+
+static const io_dev_connector_t blk_dev_connector = {
+	.dev_open = blk_dev_open
+};
+
+static const io_dev_funcs_t blk_dev_funcs = {
+	.type = device_type_block,
+	.open = block_open,
+	.seek = block_seek,
+	.size = NULL,
+	.read = block_read,
+	.write = block_write,
+	.close = block_close,
+	.dev_init = blk_dev_init,
+	.dev_close = blk_dev_close,
+};
+
+
+/* No state associated with this device so structure can be const */
+static const io_dev_info_t blk_dev_info = {
+	.funcs = &blk_dev_funcs,
+	.info = (uintptr_t)&block_info,
+};
+
+/* Open a connection to the block device */
+static int blk_dev_open(const uintptr_t dev_spec __attribute__((unused)),
+			   io_dev_info_t **dev_info)
+{
+	struct block_ops	*funcs, *block_spec;
+
+	assert(dev_info != NULL);
+	*dev_info = (io_dev_info_t *)&blk_dev_info; /* cast away const */
+
+	if (dev_spec) {
+		funcs = &block_info.ops;
+		block_spec = (struct block_ops *)dev_spec;
+		funcs->init = block_spec->init;
+		funcs->read = block_spec->read;
+		funcs->write = block_spec->write;
+	}
+
+	return IO_SUCCESS;
+}
+
+/* Close a connection to the block device */
+static int blk_dev_close(io_dev_info_t *dev_info)
+{
+	/* NOP */
+	/* TODO: Consider tracking open files and cleaning them up here */
+	return IO_SUCCESS;
+}
+
+
+/* Open a file on the block device */
+/* TODO: Can we do any sensible limit checks on requested memory */
+static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
+			     io_entity_t *entity)
+{
+	int result = IO_FAIL;
+	const io_block_spec_t *block_spec = (io_block_spec_t *)spec;
+	struct block_info *info = (struct block_info *)(dev_info->info);
+
+	/* Since we need to track open state for seek() we only allow one open
+	 * spec at a time. When we have dynamic memory we can malloc and set
+	 * entity->info.
+	 */
+	if (current_file.in_use == 0) {
+		assert(block_spec != NULL);
+		assert(entity != NULL);
+
+		current_file.in_use = 1;
+		current_file.base = block_spec->offset;
+		/* File cursor offset for seek and incremental reads etc. */
+		current_file.file_pos = 0;
+		current_file.flags = info->flags;
+		entity->info = (uintptr_t)&current_file;
+		result = IO_SUCCESS;
+	} else {
+		WARN("A block device is already active. Close first.\n");
+		result = IO_RESOURCES_EXHAUSTED;
+	}
+
+	return result;
+}
+
+/* Seek to a particular file offset on the block device */
+static int block_seek(io_entity_t *entity, int mode, ssize_t offset)
+{
+	int result = IO_FAIL;
+
+	/* We only support IO_SEEK_SET for the moment. */
+	if (mode == IO_SEEK_SET) {
+		assert(entity != NULL);
+
+		/* TODO: can we do some basic limit checks on seek? */
+		((file_state_t *)entity->info)->file_pos = offset;
+		result = IO_SUCCESS;
+	} else {
+		result = IO_FAIL;
+	}
+
+	return result;
+}
+
+
+/* Read data from a file on the block device */
+static int block_read(io_entity_t *entity, uintptr_t buffer,
+		      size_t length, size_t *length_read)
+{
+	file_state_t *fp;
+	int result;
+
+	assert(entity != NULL);
+	assert(buffer != (uintptr_t)NULL);
+	assert(length_read != NULL);
+
+	fp = (file_state_t *)entity->info;
+
+	if (!block_info.ops.read) {
+		ERROR("There's no read function on the block device.\n");
+		return IO_NOT_SUPPORTED;
+	}
+	result = block_info.ops.read(fp->base + fp->file_pos, length,
+				     buffer, fp->flags);
+	if (result) {
+		WARN("Failed to read block offset 0x%x\n",
+		     fp->base + fp->file_pos);
+		return result;
+	}
+
+	*length_read = length;
+	/* advance the file 'cursor' for incremental reads */
+	fp->file_pos += length;
+
+	return IO_SUCCESS;
+}
+
+static int block_write(io_entity_t *entity, uintptr_t buffer,
+		       size_t length, size_t *length_written)
+{
+	file_state_t *fp;
+	int result;
+
+	assert(entity != NULL);
+	assert(buffer != (uintptr_t)NULL);
+	assert(length_written != NULL);
+
+	fp = (file_state_t *)entity->info;
+
+	if (!block_info.ops.write) {
+		ERROR("There's no write function on the block device.\n");
+		return IO_NOT_SUPPORTED;
+	}
+	result = block_info.ops.write(fp->base + fp->file_pos, length,
+				      buffer, fp->flags);
+	if (result) {
+		WARN("Failed to write block offset 0x%x\n",
+		     fp->base + fp->file_pos);
+		return result;
+	}
+
+	*length_written = length;
+	/* advance the file 'cursor' for incremental reads */
+	fp->file_pos += length;
+
+	return IO_SUCCESS;
+}
+
+/* Close a file on the BLOCK device */
+static int block_close(io_entity_t *entity)
+{
+	assert(entity != NULL);
+
+	entity->info = 0;
+
+	/* This would be a mem free() if we had malloc.*/
+	memset((void *)&current_file, 0, sizeof(current_file));
+
+	return IO_SUCCESS;
+}
+
+static int blk_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params)
+{
+	struct block_info *info = (struct block_info *)(dev_info->info);
+
+	if (!info->init) {
+		if (block_info.ops.init)
+			block_info.ops.init();
+		info->init = 1;
+	}
+	info->flags = init_params;
+	return IO_SUCCESS;
+}
+
+/* Exported functions */
+
+/* Register the block driver with the IO abstraction */
+int register_io_dev_block(const io_dev_connector_t **dev_con)
+{
+	int result = IO_FAIL;
+	assert(dev_con != NULL);
+
+	result = io_register_device(&blk_dev_info);
+	if (result == IO_SUCCESS)
+		*dev_con = &blk_dev_connector;
+
+	return result;
+}
diff --git a/uefi/arm-trusted-firmware/drivers/io/io_fip.c b/uefi/arm-trusted-firmware/drivers/io/io_fip.c
new file mode 100644
index 0000000..0cec804
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/io/io_fip.c
@@ -0,0 +1,438 @@
+/*
+ * 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 <debug.h>
+#include <errno.h>
+#include <firmware_image_package.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_storage.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <stdint.h>
+#include <string.h>
+#include <uuid.h>
+
+/* Useful for printing UUIDs when debugging.*/
+#define PRINT_UUID2(x)								\
+	"%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",	\
+		x.time_low, x.time_mid, x.time_hi_and_version,			\
+		x.clock_seq_hi_and_reserved, x.clock_seq_low,			\
+		x.node[0], x.node[1], x.node[2], x.node[3],			\
+		x.node[4], x.node[5]
+
+typedef struct {
+	const char	*name;
+	const uuid_t	 uuid;
+} plat_fip_name_uuid_t;
+
+typedef struct {
+	/* Put file_pos above the struct to allow {0} on static init.
+	 * It is a workaround for a known bug in GCC
+	 * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
+	 */
+	unsigned int file_pos;
+	fip_toc_entry_t entry;
+} file_state_t;
+
+static const plat_fip_name_uuid_t name_uuid[] = {
+	{BL2_IMAGE_NAME, UUID_TRUSTED_BOOT_FIRMWARE_BL2},
+#ifdef BL30_IMAGE_NAME
+	/* BL3-0 is optional in the platform */
+	{BL30_IMAGE_NAME, UUID_SCP_FIRMWARE_BL30},
+#endif /* BL30_IMAGE_NAME */
+	{BL31_IMAGE_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31},
+#ifdef BL32_IMAGE_NAME
+	/* BL3-2 is optional in the platform */
+	{BL32_IMAGE_NAME, UUID_SECURE_PAYLOAD_BL32},
+#endif /* BL32_IMAGE_NAME */
+	{BL33_IMAGE_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33},
+#if TRUSTED_BOARD_BOOT
+	/* Certificates */
+	{BL2_CERT_NAME, UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT},
+	{TRUSTED_KEY_CERT_NAME, UUID_TRUSTED_KEY_CERT},
+#ifdef BL30_KEY_CERT_NAME
+	{BL30_KEY_CERT_NAME, UUID_SCP_FIRMWARE_BL30_KEY_CERT},
+#endif
+	{BL31_KEY_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT},
+	{BL32_KEY_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_KEY_CERT},
+	{BL33_KEY_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT},
+#ifdef BL30_CERT_NAME
+	{BL30_CERT_NAME, UUID_SCP_FIRMWARE_BL30_CERT},
+#endif
+	{BL31_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT},
+	{BL32_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_CERT},
+	{BL33_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_CERT},
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+static const uuid_t uuid_null = {0};
+static file_state_t current_file = {0};
+static uintptr_t backend_dev_handle;
+static uintptr_t backend_image_spec;
+
+
+/* Firmware Image Package driver functions */
+static int fip_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
+static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
+			  io_entity_t *entity);
+static int fip_file_len(io_entity_t *entity, size_t *length);
+static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+			  size_t *length_read);
+static int fip_file_close(io_entity_t *entity);
+static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
+static int fip_dev_close(io_dev_info_t *dev_info);
+
+
+static inline int copy_uuid(uuid_t *dst, const uuid_t *src)
+{
+	memcpy(dst, src, sizeof(uuid_t));
+	return 0;
+}
+
+
+/* Return 0 for equal uuids. */
+static inline int compare_uuids(const uuid_t *uuid1, const uuid_t *uuid2)
+{
+	return memcmp(uuid1, uuid2, sizeof(uuid_t));
+}
+
+
+/* TODO: We could check version numbers or do a package checksum? */
+static inline int is_valid_header(fip_toc_header_t *header)
+{
+	if ((header->name == TOC_HEADER_NAME) && (header->serial_number != 0)) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+
+static int file_to_uuid(const char *filename, uuid_t *uuid)
+{
+	int i;
+	int status = -EINVAL;
+
+	for (i = 0; i < (sizeof(name_uuid) / sizeof(name_uuid[0])); i++) {
+		if (strcmp(filename, name_uuid[i].name) == 0) {
+			copy_uuid(uuid, &name_uuid[i].uuid);
+			status = 0;
+			break;
+		}
+	}
+	return status;
+}
+
+
+/* Identify the device type as a virtual driver */
+io_type_t device_type_fip(void)
+{
+	return IO_TYPE_FIRMWARE_IMAGE_PACKAGE;
+}
+
+
+static const io_dev_connector_t fip_dev_connector = {
+	.dev_open = fip_dev_open
+};
+
+
+static const io_dev_funcs_t fip_dev_funcs = {
+	.type = device_type_fip,
+	.open = fip_file_open,
+	.seek = NULL,
+	.size = fip_file_len,
+	.read = fip_file_read,
+	.write = NULL,
+	.close = fip_file_close,
+	.dev_init = fip_dev_init,
+	.dev_close = fip_dev_close,
+};
+
+
+/* No state associated with this device so structure can be const */
+static const io_dev_info_t fip_dev_info = {
+	.funcs = &fip_dev_funcs,
+	.info = (uintptr_t)NULL
+};
+
+
+/* Open a connection to the FIP device */
+static int fip_dev_open(const uintptr_t dev_spec __attribute__((unused)),
+			 io_dev_info_t **dev_info)
+{
+	assert(dev_info != NULL);
+	*dev_info = (io_dev_info_t *)&fip_dev_info; /* cast away const */
+
+	return IO_SUCCESS;
+}
+
+
+/* Do some basic package checks. */
+static int fip_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params)
+{
+	int result = IO_FAIL;
+	char *image_name = (char *)init_params;
+	uintptr_t backend_handle;
+	fip_toc_header_t header;
+	size_t bytes_read;
+
+	/* Obtain a reference to the image by querying the platform layer */
+	result = plat_get_image_source(image_name, &backend_dev_handle,
+				       &backend_image_spec);
+	if (result != IO_SUCCESS) {
+		WARN("Failed to obtain reference to image '%s' (%i)\n",
+			image_name, result);
+		result = IO_FAIL;
+		goto fip_dev_init_exit;
+	}
+
+	/* Attempt to access the FIP image */
+	result = io_open(backend_dev_handle, backend_image_spec,
+			 &backend_handle);
+	if (result != IO_SUCCESS) {
+		WARN("Failed to access image '%s' (%i)\n", image_name, result);
+		result = IO_FAIL;
+		goto fip_dev_init_exit;
+	}
+
+	result = io_read(backend_handle, (uintptr_t)&header, sizeof(header),
+			&bytes_read);
+	if (result == IO_SUCCESS) {
+		if (!is_valid_header(&header)) {
+			WARN("Firmware Image Package header check failed.\n");
+			result = IO_FAIL;
+		} else {
+			VERBOSE("FIP header looks OK.\n");
+		}
+	}
+
+	io_close(backend_handle);
+
+ fip_dev_init_exit:
+	return result;
+}
+
+/* Close a connection to the FIP device */
+static int fip_dev_close(io_dev_info_t *dev_info)
+{
+	/* TODO: Consider tracking open files and cleaning them up here */
+
+	/* Clear the backend. */
+	backend_dev_handle = (uintptr_t)NULL;
+	backend_image_spec = (uintptr_t)NULL;
+
+	return IO_SUCCESS;
+}
+
+
+/* Open a file for access from package. */
+static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
+			 io_entity_t *entity)
+{
+	int result = IO_FAIL;
+	uintptr_t backend_handle;
+	uuid_t file_uuid;
+	const io_file_spec_t *file_spec = (io_file_spec_t *)spec;
+	size_t bytes_read;
+	int found_file = 0;
+
+	assert(file_spec != NULL);
+	assert(entity != NULL);
+
+	/* Can only have one file open at a time for the moment. We need to
+	 * track state like file cursor position. We know the header lives at
+	 * offset zero, so this entry should never be zero for an active file.
+	 * When the system supports dynamic memory allocation we can allow more
+	 * than one open file at a time if needed.
+	 */
+	if (current_file.entry.offset_address != 0) {
+		WARN("fip_file_open : Only one open file at a time.\n");
+		return IO_RESOURCES_EXHAUSTED;
+	}
+
+	/* Attempt to access the FIP image */
+	result = io_open(backend_dev_handle, backend_image_spec,
+			 &backend_handle);
+	if (result != IO_SUCCESS) {
+		WARN("Failed to open Firmware Image Package (%i)\n", result);
+		result = IO_FAIL;
+		goto fip_file_open_exit;
+	}
+
+	/* Seek past the FIP header into the Table of Contents */
+	result = io_seek(backend_handle, IO_SEEK_SET, sizeof(fip_toc_header_t));
+	if (result != IO_SUCCESS) {
+		WARN("fip_file_open: failed to seek\n");
+		result = IO_FAIL;
+		goto fip_file_open_close;
+	}
+
+	file_to_uuid(file_spec->path, &file_uuid);
+
+	found_file = 0;
+	do {
+		result = io_read(backend_handle,
+				 (uintptr_t)&current_file.entry,
+				 sizeof(current_file.entry),
+				 &bytes_read);
+		if (result == IO_SUCCESS) {
+			if (compare_uuids(&current_file.entry.uuid,
+					  &file_uuid) == 0) {
+				found_file = 1;
+				break;
+			}
+		} else {
+			WARN("Failed to read FIP (%i)\n", result);
+			goto fip_file_open_close;
+		}
+	} while (compare_uuids(&current_file.entry.uuid, &uuid_null) != 0);
+
+	if (found_file == 1) {
+		/* All fine. Update entity info with file state and return. Set
+		 * the file position to 0. The 'current_file.entry' holds the
+		 * base and size of the file.
+		 */
+		current_file.file_pos = 0;
+		entity->info = (uintptr_t)&current_file;
+	} else {
+		/* Did not find the file in the FIP. */
+		current_file.entry.offset_address = 0;
+		result = IO_FAIL;
+	}
+
+ fip_file_open_close:
+	io_close(backend_handle);
+
+ fip_file_open_exit:
+	return result;
+}
+
+
+/* Return the size of a file in package */
+static int fip_file_len(io_entity_t *entity, size_t *length)
+{
+	assert(entity != NULL);
+	assert(length != NULL);
+
+	*length =  ((file_state_t *)entity->info)->entry.size;
+
+	return IO_SUCCESS;
+}
+
+
+/* Read data from a file in package */
+static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+			  size_t *length_read)
+{
+	int result = IO_FAIL;
+	file_state_t *fp;
+	size_t file_offset;
+	size_t bytes_read;
+	uintptr_t backend_handle;
+
+	assert(entity != NULL);
+	assert(buffer != (uintptr_t)NULL);
+	assert(length_read != NULL);
+	assert(entity->info != (uintptr_t)NULL);
+
+	/* Open the backend, attempt to access the blob image */
+	result = io_open(backend_dev_handle, backend_image_spec,
+			 &backend_handle);
+	if (result != IO_SUCCESS) {
+		WARN("Failed to open FIP (%i)\n", result);
+		result = IO_FAIL;
+		goto fip_file_read_exit;
+	}
+
+	fp = (file_state_t *)entity->info;
+
+	/* Seek to the position in the FIP where the payload lives */
+	file_offset = fp->entry.offset_address + fp->file_pos;
+	result = io_seek(backend_handle, IO_SEEK_SET, file_offset);
+	if (result != IO_SUCCESS) {
+		WARN("fip_file_read: failed to seek\n");
+		result = IO_FAIL;
+		goto fip_file_read_close;
+	}
+
+	result = io_read(backend_handle, buffer, length, &bytes_read);
+	if (result != IO_SUCCESS) {
+		/* We cannot read our data. Fail. */
+		WARN("Failed to read payload (%i)\n", result);
+		result = IO_FAIL;
+		goto fip_file_read_close;
+	} else {
+		/* Set caller length and new file position. */
+		*length_read = bytes_read;
+		fp->file_pos += bytes_read;
+	}
+
+/* Close the backend. */
+ fip_file_read_close:
+	io_close(backend_handle);
+
+ fip_file_read_exit:
+	return result;
+}
+
+
+/* Close a file in package */
+static int fip_file_close(io_entity_t *entity)
+{
+	/* Clear our current file pointer.
+	 * If we had malloc() we would free() here.
+	 */
+	if (current_file.entry.offset_address != 0) {
+		memset(&current_file, 0, sizeof(current_file));
+	}
+
+	/* Clear the Entity info. */
+	entity->info = 0;
+
+	return IO_SUCCESS;
+}
+
+/* Exported functions */
+
+/* Register the Firmware Image Package driver with the IO abstraction */
+int register_io_dev_fip(const io_dev_connector_t **dev_con)
+{
+	int result = IO_FAIL;
+	assert(dev_con != NULL);
+
+	result = io_register_device(&fip_dev_info);
+	if (result == IO_SUCCESS)
+		*dev_con = &fip_dev_connector;
+
+	return result;
+}
diff --git a/uefi/arm-trusted-firmware/drivers/io/io_memmap.c b/uefi/arm-trusted-firmware/drivers/io/io_memmap.c
new file mode 100644
index 0000000..fc06fbb
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/io/io_memmap.c
@@ -0,0 +1,241 @@
+/*
+ * 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 <debug.h>
+#include <io_driver.h>
+#include <io_storage.h>
+#include <string.h>
+
+/* As we need to be able to keep state for seek, only one file can be open
+ * at a time. Make this a structure and point to the entity->info. When we
+ * can malloc memory we can change this to support more open files.
+ */
+typedef struct {
+	/* Use the 'in_use' flag as any value for base and file_pos could be
+	 * valid.
+	 */
+	int		in_use;
+	uintptr_t	base;
+	size_t		file_pos;
+} file_state_t;
+
+static file_state_t current_file = {0};
+
+/* Identify the device type as memmap */
+io_type_t device_type_memmap(void)
+{
+	return IO_TYPE_MEMMAP;
+}
+
+/* Memmap device functions */
+static int memmap_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
+static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
+			     io_entity_t *entity);
+static int memmap_block_seek(io_entity_t *entity, int mode,
+			     ssize_t offset);
+static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
+			     size_t length, size_t *length_read);
+static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer,
+			      size_t length, size_t *length_written);
+static int memmap_block_close(io_entity_t *entity);
+static int memmap_dev_close(io_dev_info_t *dev_info);
+
+
+static const io_dev_connector_t memmap_dev_connector = {
+	.dev_open = memmap_dev_open
+};
+
+
+static const io_dev_funcs_t memmap_dev_funcs = {
+	.type = device_type_memmap,
+	.open = memmap_block_open,
+	.seek = memmap_block_seek,
+	.size = NULL,
+	.read = memmap_block_read,
+	.write = memmap_block_write,
+	.close = memmap_block_close,
+	.dev_init = NULL,
+	.dev_close = memmap_dev_close,
+};
+
+
+/* No state associated with this device so structure can be const */
+static const io_dev_info_t memmap_dev_info = {
+	.funcs = &memmap_dev_funcs,
+	.info = (uintptr_t)NULL
+};
+
+
+/* Open a connection to the memmap device */
+static int memmap_dev_open(const uintptr_t dev_spec __attribute__((unused)),
+			   io_dev_info_t **dev_info)
+{
+	assert(dev_info != NULL);
+	*dev_info = (io_dev_info_t *)&memmap_dev_info; /* cast away const */
+
+	return IO_SUCCESS;
+}
+
+
+
+/* Close a connection to the memmap device */
+static int memmap_dev_close(io_dev_info_t *dev_info)
+{
+	/* NOP */
+	/* TODO: Consider tracking open files and cleaning them up here */
+	return IO_SUCCESS;
+}
+
+
+/* Open a file on the memmap device */
+/* TODO: Can we do any sensible limit checks on requested memory */
+static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
+			     io_entity_t *entity)
+{
+	int result = IO_FAIL;
+	const io_block_spec_t *block_spec = (io_block_spec_t *)spec;
+
+	/* Since we need to track open state for seek() we only allow one open
+	 * spec at a time. When we have dynamic memory we can malloc and set
+	 * entity->info.
+	 */
+	if (current_file.in_use == 0) {
+		assert(block_spec != NULL);
+		assert(entity != NULL);
+
+		current_file.in_use = 1;
+		current_file.base = block_spec->offset;
+		/* File cursor offset for seek and incremental reads etc. */
+		current_file.file_pos = 0;
+		entity->info = (uintptr_t)&current_file;
+		result = IO_SUCCESS;
+	} else {
+		WARN("A Memmap device is already active. Close first.\n");
+		result = IO_RESOURCES_EXHAUSTED;
+	}
+
+	return result;
+}
+
+
+/* Seek to a particular file offset on the memmap device */
+static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset)
+{
+	int result = IO_FAIL;
+
+	/* We only support IO_SEEK_SET for the moment. */
+	if (mode == IO_SEEK_SET) {
+		assert(entity != NULL);
+
+		/* TODO: can we do some basic limit checks on seek? */
+		((file_state_t *)entity->info)->file_pos = offset;
+		result = IO_SUCCESS;
+	} else {
+		result = IO_FAIL;
+	}
+
+	return result;
+}
+
+
+/* Read data from a file on the memmap device */
+static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
+			     size_t length, size_t *length_read)
+{
+	file_state_t *fp;
+
+	assert(entity != NULL);
+	assert(buffer != (uintptr_t)NULL);
+	assert(length_read != NULL);
+
+	fp = (file_state_t *)entity->info;
+
+	memcpy((void *)buffer, (void *)(fp->base + fp->file_pos), length);
+
+	*length_read = length;
+	/* advance the file 'cursor' for incremental reads */
+	fp->file_pos += length;
+
+	return IO_SUCCESS;
+}
+
+
+/* Write data to a file on the memmap device */
+static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer,
+			      size_t length, size_t *length_written)
+{
+	file_state_t *fp;
+
+	assert(entity != NULL);
+	assert(buffer != (uintptr_t)NULL);
+	assert(length_written != NULL);
+
+	fp = (file_state_t *)entity->info;
+
+	memcpy((void *)(fp->base + fp->file_pos), (void *)buffer, length);
+
+	*length_written = length;
+
+	/* advance the file 'cursor' for incremental writes */
+	fp->file_pos += length;
+
+	return IO_SUCCESS;
+}
+
+
+/* Close a file on the memmap device */
+static int memmap_block_close(io_entity_t *entity)
+{
+	assert(entity != NULL);
+
+	entity->info = 0;
+
+	/* This would be a mem free() if we had malloc.*/
+	memset((void *)&current_file, 0, sizeof(current_file));
+
+	return IO_SUCCESS;
+}
+
+
+/* Exported functions */
+
+/* Register the memmap driver with the IO abstraction */
+int register_io_dev_memmap(const io_dev_connector_t **dev_con)
+{
+	int result = IO_FAIL;
+	assert(dev_con != NULL);
+
+	result = io_register_device(&memmap_dev_info);
+	if (result == IO_SUCCESS)
+		*dev_con = &memmap_dev_connector;
+
+	return result;
+}
diff --git a/uefi/arm-trusted-firmware/drivers/io/io_semihosting.c b/uefi/arm-trusted-firmware/drivers/io/io_semihosting.c
new file mode 100644
index 0000000..3c92c6d
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/io/io_semihosting.c
@@ -0,0 +1,241 @@
+/*
+ * 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 <io_driver.h>
+#include <io_storage.h>
+#include <semihosting.h>
+
+
+
+/* Identify the device type as semihosting */
+static io_type_t device_type_sh(void)
+{
+	return IO_TYPE_SEMIHOSTING;
+}
+
+
+/* Semi-hosting functions, device info and handle */
+
+static int sh_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
+static int sh_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
+		io_entity_t *entity);
+static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset);
+static int sh_file_len(io_entity_t *entity, size_t *length);
+static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+		size_t *length_read);
+static int sh_file_write(io_entity_t *entity, const uintptr_t buffer,
+		size_t length, size_t *length_written);
+static int sh_file_close(io_entity_t *entity);
+
+static const io_dev_connector_t sh_dev_connector = {
+	.dev_open = sh_dev_open
+};
+
+
+static const io_dev_funcs_t sh_dev_funcs = {
+	.type = device_type_sh,
+	.open = sh_file_open,
+	.seek = sh_file_seek,
+	.size = sh_file_len,
+	.read = sh_file_read,
+	.write = sh_file_write,
+	.close = sh_file_close,
+	.dev_init = NULL,	/* NOP */
+	.dev_close = NULL,	/* NOP */
+};
+
+
+/* No state associated with this device so structure can be const */
+static const io_dev_info_t sh_dev_info = {
+	.funcs = &sh_dev_funcs,
+	.info = (uintptr_t)NULL
+};
+
+
+/* Open a connection to the semi-hosting device */
+static int sh_dev_open(const uintptr_t dev_spec __unused,
+		io_dev_info_t **dev_info)
+{
+	int result = IO_SUCCESS;
+	assert(dev_info != NULL);
+	*dev_info = (io_dev_info_t *)&sh_dev_info; /* cast away const */
+	return result;
+}
+
+
+/* Open a file on the semi-hosting device */
+static int sh_file_open(io_dev_info_t *dev_info __attribute__((unused)),
+		const uintptr_t spec, io_entity_t *entity)
+{
+	int result = IO_FAIL;
+	long sh_result = -1;
+	const io_file_spec_t *file_spec = (const io_file_spec_t *)spec;
+
+	assert(file_spec != NULL);
+	assert(entity != NULL);
+
+	sh_result = semihosting_file_open(file_spec->path, file_spec->mode);
+
+	if (sh_result > 0) {
+		entity->info = (uintptr_t)sh_result;
+		result = IO_SUCCESS;
+	} else {
+		result = IO_FAIL;
+	}
+	return result;
+}
+
+
+/* Seek to a particular file offset on the semi-hosting device */
+static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset)
+{
+	int result = IO_FAIL;
+	long file_handle, sh_result;
+
+	assert(entity != NULL);
+
+	file_handle = (long)entity->info;
+
+	sh_result = semihosting_file_seek(file_handle, offset);
+
+	result = (sh_result == 0) ? IO_SUCCESS : IO_FAIL;
+
+	return result;
+}
+
+
+/* Return the size of a file on the semi-hosting device */
+static int sh_file_len(io_entity_t *entity, size_t *length)
+{
+	int result = IO_FAIL;
+
+	assert(entity != NULL);
+	assert(length != NULL);
+
+	long sh_handle = (long)entity->info;
+	long sh_result = semihosting_file_length(sh_handle);
+
+	if (sh_result >= 0) {
+		result = IO_SUCCESS;
+		*length = (size_t)sh_result;
+	}
+
+	return result;
+}
+
+
+/* Read data from a file on the semi-hosting device */
+static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+		size_t *length_read)
+{
+	int result = IO_FAIL;
+	long sh_result = -1;
+	size_t bytes = length;
+	long file_handle;
+
+	assert(entity != NULL);
+	assert(buffer != (uintptr_t)NULL);
+	assert(length_read != NULL);
+
+	file_handle = (long)entity->info;
+
+	sh_result = semihosting_file_read(file_handle, &bytes, buffer);
+
+	if (sh_result >= 0) {
+		*length_read = (bytes != length) ? bytes : length;
+		result = IO_SUCCESS;
+	} else
+		result = IO_FAIL;
+
+	return result;
+}
+
+
+/* Write data to a file on the semi-hosting device */
+static int sh_file_write(io_entity_t *entity, const uintptr_t buffer,
+		size_t length, size_t *length_written)
+{
+	int result = IO_FAIL;
+	long sh_result = -1;
+	long file_handle;
+	size_t bytes = length;
+
+	assert(entity != NULL);
+	assert(buffer != (uintptr_t)NULL);
+	assert(length_written != NULL);
+
+	file_handle = (long)entity->info;
+
+	sh_result = semihosting_file_write(file_handle, &bytes, buffer);
+
+	if (sh_result >= 0) {
+		*length_written = sh_result;
+		result = IO_SUCCESS;
+	} else
+		result = IO_FAIL;
+
+	return result;
+}
+
+
+/* Close a file on the semi-hosting device */
+static int sh_file_close(io_entity_t *entity)
+{
+	int result = IO_FAIL;
+	long sh_result = -1;
+	long file_handle;
+
+	assert(entity != NULL);
+
+	file_handle = (long)entity->info;
+
+	sh_result = semihosting_file_close(file_handle);
+
+	result = (sh_result >= 0) ? IO_SUCCESS : IO_FAIL;
+
+	return result;
+}
+
+
+/* Exported functions */
+
+/* Register the semi-hosting driver with the IO abstraction */
+int register_io_dev_sh(const io_dev_connector_t **dev_con)
+{
+	int result = IO_FAIL;
+	assert(dev_con != NULL);
+
+	result = io_register_device(&sh_dev_info);
+	if (result == IO_SUCCESS)
+		*dev_con = &sh_dev_connector;
+
+	return result;
+}
diff --git a/uefi/arm-trusted-firmware/drivers/io/io_storage.c b/uefi/arm-trusted-firmware/drivers/io/io_storage.c
new file mode 100644
index 0000000..a3a8186
--- /dev/null
+++ b/uefi/arm-trusted-firmware/drivers/io/io_storage.c
@@ -0,0 +1,373 @@
+/*
+ * 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 <io_driver.h>
+#include <io_storage.h>
+#include <platform_def.h>
+#include <stddef.h>
+
+
+/* Storage for a fixed maximum number of IO entities, definable by platform */
+static io_entity_t entity_pool[MAX_IO_HANDLES];
+
+/* Simple way of tracking used storage - each entry is NULL or a pointer to an
+ * entity */
+static io_entity_t *entity_map[MAX_IO_HANDLES];
+
+/* Track number of allocated entities */
+static unsigned int entity_count;
+
+/* Array of fixed maximum of registered devices, definable by platform */
+static const io_dev_info_t *devices[MAX_IO_DEVICES];
+
+/* Number of currently registered devices */
+static unsigned int dev_count;
+
+
+#if DEBUG	/* Extra validation functions only used in debug builds */
+
+/* Return a boolean value indicating whether a device connector is valid */
+static int is_valid_dev_connector(const io_dev_connector_t *dev_con)
+{
+	int result = (dev_con != NULL) && (dev_con->dev_open != NULL);
+	return result;
+}
+
+
+/* Return a boolean value indicating whether a device handle is valid */
+static int is_valid_dev(const uintptr_t dev_handle)
+{
+	const io_dev_info_t *dev = (io_dev_info_t *)dev_handle;
+	int result = (dev != NULL) && (dev->funcs != NULL) &&
+			(dev->funcs->type != NULL) &&
+			(dev->funcs->type() < IO_TYPE_MAX);
+	return result;
+}
+
+
+/* Return a boolean value indicating whether an IO entity is valid */
+static int is_valid_entity(const uintptr_t handle)
+{
+	const io_entity_t *entity = (io_entity_t *)handle;
+	int result = (entity != NULL) &&
+			(is_valid_dev((uintptr_t)entity->dev_handle));
+	return result;
+}
+
+
+/* Return a boolean value indicating whether a seek mode is valid */
+static int is_valid_seek_mode(io_seek_mode_t mode)
+{
+	return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX));
+}
+
+#endif	/* End of debug-only validation functions */
+
+
+/* Open a connection to a specific device */
+static int dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec,
+		io_dev_info_t **dev_info)
+{
+	int result = IO_FAIL;
+	assert(dev_info != NULL);
+	assert(is_valid_dev_connector(dev_con));
+
+	result = dev_con->dev_open(dev_spec, dev_info);
+	return result;
+}
+
+
+/* Set a handle to track an entity */
+static void set_handle(uintptr_t *handle, io_entity_t *entity)
+{
+	assert(handle != NULL);
+	*handle = (uintptr_t)entity;
+}
+
+
+/* Locate an entity in the pool, specified by address */
+static int find_first_entity(const io_entity_t *entity, unsigned int *index_out)
+{
+	int result = IO_FAIL;
+	for (int index = 0; index < MAX_IO_HANDLES; ++index) {
+		if (entity_map[index] == entity) {
+			result = IO_SUCCESS;
+			*index_out = index;
+			break;
+		}
+	}
+	return result;
+}
+
+
+/* Allocate an entity from the pool and return a pointer to it */
+static int allocate_entity(io_entity_t **entity)
+{
+	int result = IO_FAIL;
+	assert(entity != NULL);
+
+	if (entity_count < MAX_IO_HANDLES) {
+		unsigned int index = 0;
+		result = find_first_entity(NULL, &index);
+		assert(result == IO_SUCCESS);
+		*entity = entity_map[index] = &entity_pool[index];
+		++entity_count;
+	} else
+		result = IO_RESOURCES_EXHAUSTED;
+
+	return result;
+}
+
+
+/* Release an entity back to the pool */
+static int free_entity(const io_entity_t *entity)
+{
+	int result = IO_FAIL;
+	unsigned int index = 0;
+	assert(entity != NULL);
+
+	result = find_first_entity(entity, &index);
+	if (result ==  IO_SUCCESS) {
+		entity_map[index] = NULL;
+		--entity_count;
+	}
+
+	return result;
+}
+
+
+/* Exported API */
+
+/* Register a device driver */
+int io_register_device(const io_dev_info_t *dev_info)
+{
+	int result = IO_FAIL;
+	assert(dev_info != NULL);
+
+	if (dev_count < MAX_IO_DEVICES) {
+		devices[dev_count] = dev_info;
+		dev_count++;
+		result = IO_SUCCESS;
+	} else {
+		result = IO_RESOURCES_EXHAUSTED;
+	}
+
+	return result;
+}
+
+
+/* Open a connection to an IO device */
+int io_dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec,
+		uintptr_t *handle)
+{
+	int result = IO_FAIL;
+	assert(handle != NULL);
+
+	result = dev_open(dev_con, dev_spec, (io_dev_info_t **)handle);
+	return result;
+}
+
+
+/* Initialise an IO device explicitly - to permit lazy initialisation or
+ * re-initialisation */
+int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params)
+{
+	int result = IO_FAIL;
+	assert(dev_handle != (uintptr_t)NULL);
+	assert(is_valid_dev(dev_handle));
+
+	io_dev_info_t *dev = (io_dev_info_t *)dev_handle;
+
+	if (dev->funcs->dev_init != NULL) {
+		result = dev->funcs->dev_init(dev, init_params);
+	} else {
+		/* Absence of registered function implies NOP here */
+		result = IO_SUCCESS;
+	}
+	return result;
+}
+
+
+/* TODO: Consider whether an explicit "shutdown" API should be included */
+
+/* Close a connection to a device */
+int io_dev_close(uintptr_t dev_handle)
+{
+	int result = IO_FAIL;
+	assert(dev_handle != (uintptr_t)NULL);
+	assert(is_valid_dev(dev_handle));
+
+	io_dev_info_t *dev = (io_dev_info_t *)dev_handle;
+
+	if (dev->funcs->dev_close != NULL) {
+		result = dev->funcs->dev_close(dev);
+	} else {
+		/* Absence of registered function implies NOP here */
+		result = IO_SUCCESS;
+	}
+
+	return result;
+}
+
+
+/* Synchronous operations */
+
+
+/* Open an IO entity */
+int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle)
+{
+	int result = IO_FAIL;
+	assert((spec != (uintptr_t)NULL) && (handle != NULL));
+	assert(is_valid_dev(dev_handle));
+
+	io_dev_info_t *dev = (io_dev_info_t *)dev_handle;
+	io_entity_t *entity;
+
+	result = allocate_entity(&entity);
+
+	if (result == IO_SUCCESS) {
+		assert(dev->funcs->open != NULL);
+		result = dev->funcs->open(dev, spec, entity);
+
+		if (result == IO_SUCCESS) {
+			entity->dev_handle = dev;
+			set_handle(handle, entity);
+		} else
+			free_entity(entity);
+	}
+	return result;
+}
+
+
+/* Seek to a specific position in an IO entity */
+int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset)
+{
+	int result = IO_FAIL;
+	assert(is_valid_entity(handle) && is_valid_seek_mode(mode));
+
+	io_entity_t *entity = (io_entity_t *)handle;
+
+	io_dev_info_t *dev = entity->dev_handle;
+
+	if (dev->funcs->seek != NULL)
+		result = dev->funcs->seek(entity, mode, offset);
+	else
+		result = IO_NOT_SUPPORTED;
+
+	return result;
+}
+
+
+/* Determine the length of an IO entity */
+int io_size(uintptr_t handle, size_t *length)
+{
+	int result = IO_FAIL;
+	assert(is_valid_entity(handle) && (length != NULL));
+
+	io_entity_t *entity = (io_entity_t *)handle;
+
+	io_dev_info_t *dev = entity->dev_handle;
+
+	if (dev->funcs->size != NULL)
+		result = dev->funcs->size(entity, length);
+	else
+		result = IO_NOT_SUPPORTED;
+
+	return result;
+}
+
+
+/* Read data from an IO entity */
+int io_read(uintptr_t handle,
+		uintptr_t buffer,
+		size_t length,
+		size_t *length_read)
+{
+	int result = IO_FAIL;
+	assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL));
+
+	io_entity_t *entity = (io_entity_t *)handle;
+
+	io_dev_info_t *dev = entity->dev_handle;
+
+	if (dev->funcs->read != NULL)
+		result = dev->funcs->read(entity, buffer, length, length_read);
+	else
+		result = IO_NOT_SUPPORTED;
+
+	return result;
+}
+
+
+/* Write data to an IO entity */
+int io_write(uintptr_t handle,
+		const uintptr_t buffer,
+		size_t length,
+		size_t *length_written)
+{
+	int result = IO_FAIL;
+	assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL));
+
+	io_entity_t *entity = (io_entity_t *)handle;
+
+	io_dev_info_t *dev = entity->dev_handle;
+
+	if (dev->funcs->write != NULL) {
+		result = dev->funcs->write(entity, buffer, length,
+				length_written);
+	} else
+		result = IO_NOT_SUPPORTED;
+
+	return result;
+}
+
+
+/* Close an IO entity */
+int io_close(uintptr_t handle)
+{
+	int result = IO_FAIL;
+	assert(is_valid_entity(handle));
+
+	io_entity_t *entity = (io_entity_t *)handle;
+
+	io_dev_info_t *dev = entity->dev_handle;
+
+	if (dev->funcs->close != NULL)
+		result = dev->funcs->close(entity);
+	else {
+		/* Absence of registered function implies NOP here */
+		result = IO_SUCCESS;
+	}
+	/* Ignore improbable free_entity failure */
+	(void)free_entity(entity);
+
+	return result;
+}
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2-psci.dtb b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2-psci.dtb
new file mode 100644
index 0000000..b8a31ce
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2-psci.dtb
Binary files differ
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2-psci.dts b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2-psci.dts
new file mode 100644
index 0000000..c1c9efb
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2-psci.dts
@@ -0,0 +1,317 @@
+/*
+ * 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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+};
+
+/ {
+	model = "FVP Base";
+	compatible = "arm,vfp-base", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+		cpu_suspend = <0xc4000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0xc4000003>;
+		sys_poweroff = <0x84000008>;
+		sys_reset = <0x84000009>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&CPU4>;
+				};
+				core1 {
+					cpu = <&CPU5>;
+				};
+				core2 {
+					cpu = <&CPU6>;
+				};
+				core3 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <40>;
+				exit-latency-us = <100>;
+				min-residency-us = <150>;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x1010000>;
+				entry-latency-us = <500>;
+				exit-latency-us = <1000>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		CPU0:cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU1:cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU2:cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU3:cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU4:cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU5:cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU6:cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x102>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU7:cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x103>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x7F000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+	};
+
+	gic: interrupt-controller@2f000000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x0 0x2f000000 0 0x10000>,
+		      <0x0 0x2c000000 0 0x2000>,
+		      <0x0 0x2c010000 0 0x2000>,
+		      <0x0 0x2c02F000 0 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+			     <1 14 0xff01>,
+			     <1 11 0xff01>,
+			     <1 10 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0x0 0x10000>;
+			clock-frequency = <100000000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			frame@2a830000 {
+				frame-number = <1>;
+				interrupts = <0 26 4>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+
+		/include/ "rtsm_ve-motherboard.dtsi"
+	};
+
+	panels {
+		panel@0 {
+			compatible	= "panel";
+			mode		= "XVGA";
+			refresh		= <60>;
+			xres		= <1024>;
+			yres		= <768>;
+			pixclock	= <15748>;
+			left_margin	= <152>;
+			right_margin	= <48>;
+			upper_margin	= <23>;
+			lower_margin	= <3>;
+			hsync_len	= <104>;
+			vsync_len	= <4>;
+			sync		= <0>;
+			vmode		= "FB_VMODE_NONINTERLACED";
+			tim2		= "TIM2_BCD", "TIM2_IPC";
+			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
+			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
+			bpp		= <16>;
+		};
+	};
+};
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2legacy-psci.dtb b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2legacy-psci.dtb
new file mode 100644
index 0000000..4270623
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2legacy-psci.dtb
Binary files differ
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2legacy-psci.dts b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2legacy-psci.dts
new file mode 100644
index 0000000..7bd5ea2
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv2legacy-psci.dts
@@ -0,0 +1,317 @@
+/*
+ * 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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+};
+
+/ {
+	model = "FVP Base";
+	compatible = "arm,vfp-base", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+		cpu_suspend = <0xc4000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0xc4000003>;
+		sys_poweroff = <0x84000008>;
+		sys_reset = <0x84000009>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&CPU4>;
+				};
+				core1 {
+					cpu = <&CPU5>;
+				};
+				core2 {
+					cpu = <&CPU6>;
+				};
+				core3 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <40>;
+				exit-latency-us = <100>;
+				min-residency-us = <150>;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x1010000>;
+				entry-latency-us = <500>;
+				exit-latency-us = <1000>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		CPU0:cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU1:cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU2:cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU3:cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU4:cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU5:cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU6:cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x102>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU7:cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x103>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x7F000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+	};
+
+	gic: interrupt-controller@2c001000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x0 0x2c001000 0 0x1000>,
+		      <0x0 0x2c002000 0 0x1000>,
+		      <0x0 0x2c004000 0 0x2000>,
+		      <0x0 0x2c006000 0 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+			     <1 14 0xff01>,
+			     <1 11 0xff01>,
+			     <1 10 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0x0 0x10000>;
+			clock-frequency = <100000000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			frame@2a830000 {
+				frame-number = <1>;
+				interrupts = <0 26 4>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+
+		/include/ "rtsm_ve-motherboard.dtsi"
+	};
+
+	panels {
+		panel@0 {
+			compatible	= "panel";
+			mode		= "XVGA";
+			refresh		= <60>;
+			xres		= <1024>;
+			yres		= <768>;
+			pixclock	= <15748>;
+			left_margin	= <152>;
+			right_margin	= <48>;
+			upper_margin	= <23>;
+			lower_margin	= <3>;
+			hsync_len	= <104>;
+			vsync_len	= <4>;
+			sync		= <0>;
+			vmode		= "FB_VMODE_NONINTERLACED";
+			tim2		= "TIM2_BCD", "TIM2_IPC";
+			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
+			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
+			bpp		= <16>;
+		};
+	};
+};
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-base-gicv3-psci.dtb b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv3-psci.dtb
new file mode 100644
index 0000000..27c3f93
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv3-psci.dtb
Binary files differ
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-base-gicv3-psci.dts b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv3-psci.dts
new file mode 100644
index 0000000..32e577a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-base-gicv3-psci.dts
@@ -0,0 +1,324 @@
+/*
+ * 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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+};
+
+/ {
+	model = "FVP Base";
+	compatible = "arm,vfp-base", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+		cpu_suspend = <0xc4000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0xc4000003>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&CPU4>;
+				};
+				core1 {
+					cpu = <&CPU5>;
+				};
+				core2 {
+					cpu = <&CPU6>;
+				};
+				core3 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <40>;
+				exit-latency-us = <100>;
+				min-residency-us = <150>;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x1010000>;
+				entry-latency-us = <500>;
+				exit-latency-us = <1000>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		CPU0:cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU1:cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU2:cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU3:cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU4:cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU5:cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU6:cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x102>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU7:cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x103>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x7F000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+	};
+
+	gic: interrupt-controller@2f000000 {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		interrupt-controller;
+		reg = <0x0 0x2f000000 0 0x10000>,	// GICD
+		      <0x0 0x2f100000 0 0x200000>,	// GICR
+		      <0x0 0x2c000000 0 0x2000>,	// GICC
+		      <0x0 0x2c010000 0 0x2000>,	// GICH
+		      <0x0 0x2c02f000 0 0x2000>;	// GICV
+		interrupts = <1 9 4>;
+
+		its: its@2f020000 {
+			compatible = "arm,gic-v3-its";
+			msi-controller;
+			reg = <0x0 0x2f020000 0x0 0x20000>; // GITS
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+			     <1 14 0xff01>,
+			     <1 11 0xff01>,
+			     <1 10 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0x0 0x10000>;
+			clock-frequency = <100000000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			frame@2a830000 {
+				frame-number = <1>;
+				interrupts = <0 26 4>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0 0 0  0 4>,
+				<0 0  1 &gic 0 0 0  1 4>,
+				<0 0  2 &gic 0 0 0  2 4>,
+				<0 0  3 &gic 0 0 0  3 4>,
+				<0 0  4 &gic 0 0 0  4 4>,
+				<0 0  5 &gic 0 0 0  5 4>,
+				<0 0  6 &gic 0 0 0  6 4>,
+				<0 0  7 &gic 0 0 0  7 4>,
+				<0 0  8 &gic 0 0 0  8 4>,
+				<0 0  9 &gic 0 0 0  9 4>,
+				<0 0 10 &gic 0 0 0 10 4>,
+				<0 0 11 &gic 0 0 0 11 4>,
+				<0 0 12 &gic 0 0 0 12 4>,
+				<0 0 13 &gic 0 0 0 13 4>,
+				<0 0 14 &gic 0 0 0 14 4>,
+				<0 0 15 &gic 0 0 0 15 4>,
+				<0 0 16 &gic 0 0 0 16 4>,
+				<0 0 17 &gic 0 0 0 17 4>,
+				<0 0 18 &gic 0 0 0 18 4>,
+				<0 0 19 &gic 0 0 0 19 4>,
+				<0 0 20 &gic 0 0 0 20 4>,
+				<0 0 21 &gic 0 0 0 21 4>,
+				<0 0 22 &gic 0 0 0 22 4>,
+				<0 0 23 &gic 0 0 0 23 4>,
+				<0 0 24 &gic 0 0 0 24 4>,
+				<0 0 25 &gic 0 0 0 25 4>,
+				<0 0 26 &gic 0 0 0 26 4>,
+				<0 0 27 &gic 0 0 0 27 4>,
+				<0 0 28 &gic 0 0 0 28 4>,
+				<0 0 29 &gic 0 0 0 29 4>,
+				<0 0 30 &gic 0 0 0 30 4>,
+				<0 0 31 &gic 0 0 0 31 4>,
+				<0 0 32 &gic 0 0 0 32 4>,
+				<0 0 33 &gic 0 0 0 33 4>,
+				<0 0 34 &gic 0 0 0 34 4>,
+				<0 0 35 &gic 0 0 0 35 4>,
+				<0 0 36 &gic 0 0 0 36 4>,
+				<0 0 37 &gic 0 0 0 37 4>,
+				<0 0 38 &gic 0 0 0 38 4>,
+				<0 0 39 &gic 0 0 0 39 4>,
+				<0 0 40 &gic 0 0 0 40 4>,
+				<0 0 41 &gic 0 0 0 41 4>,
+				<0 0 42 &gic 0 0 0 42 4>;
+
+		/include/ "rtsm_ve-motherboard-no_psci.dtsi"
+	};
+
+	panels {
+		panel@0 {
+			compatible	= "panel";
+			mode		= "XVGA";
+			refresh		= <60>;
+			xres		= <1024>;
+			yres		= <768>;
+			pixclock	= <15748>;
+			left_margin	= <152>;
+			right_margin	= <48>;
+			upper_margin	= <23>;
+			lower_margin	= <3>;
+			hsync_len	= <104>;
+			vsync_len	= <4>;
+			sync		= <0>;
+			vmode		= "FB_VMODE_NONINTERLACED";
+			tim2		= "TIM2_BCD", "TIM2_IPC";
+			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
+			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
+			bpp		= <16>;
+		};
+	};
+};
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2-psci.dtb b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2-psci.dtb
new file mode 100644
index 0000000..5b92e5e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2-psci.dtb
Binary files differ
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2-psci.dts b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2-psci.dts
new file mode 100644
index 0000000..c04d535
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2-psci.dts
@@ -0,0 +1,247 @@
+/*
+ * 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 the 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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+};
+
+/ {
+	model = "FVP Foundation";
+	compatible = "arm,fvp-base", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+		cpu_suspend = <0xc4000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0xc4000003>;
+		sys_poweroff = <0x84000008>;
+		sys_reset = <0x84000009>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <40>;
+				exit-latency-us = <100>;
+				min-residency-us = <150>;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x1010000>;
+				entry-latency-us = <500>;
+				exit-latency-us = <1000>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		CPU0:cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU1:cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU2:cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU3:cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x7F000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+	};
+
+	gic: interrupt-controller@2f000000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x0 0x2f000000 0 0x10000>,
+		      <0x0 0x2c000000 0 0x2000>,
+		      <0x0 0x2c010000 0 0x2000>,
+		      <0x0 0x2c02F000 0 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+			     <1 14 0xff01>,
+			     <1 11 0xff01>,
+			     <1 10 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0x0 0x10000>;
+			clock-frequency = <100000000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			frame@2a830000 {
+				frame-number = <1>;
+				interrupts = <0 26 4>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+
+		/include/ "fvp-foundation-motherboard.dtsi"
+	};
+};
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2legacy-psci.dtb b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2legacy-psci.dtb
new file mode 100644
index 0000000..71f6ae2
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2legacy-psci.dtb
Binary files differ
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2legacy-psci.dts b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2legacy-psci.dts
new file mode 100644
index 0000000..8dba04c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv2legacy-psci.dts
@@ -0,0 +1,247 @@
+/*
+ * 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 the 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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+};
+
+/ {
+	model = "FVP Foundation";
+	compatible = "arm,fvp-base", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	psci {
+		compatible = "arm,psci";
+		method = "smc";
+		cpu_suspend = <0xc4000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0xc4000003>;
+		sys_poweroff = <0x84000008>;
+		sys_reset = <0x84000009>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <40>;
+				exit-latency-us = <100>;
+				min-residency-us = <150>;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x1010000>;
+				entry-latency-us = <500>;
+				exit-latency-us = <1000>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		CPU0:cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU1:cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU2:cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU3:cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x7F000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+	};
+
+	gic: interrupt-controller@2c001000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x0 0x2c001000 0 0x1000>,
+		      <0x0 0x2c002000 0 0x1000>,
+		      <0x0 0x2c004000 0 0x2000>,
+		      <0x0 0x2c006000 0 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+			     <1 14 0xff01>,
+			     <1 11 0xff01>,
+			     <1 10 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0x0 0x10000>;
+			clock-frequency = <100000000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			frame@2a830000 {
+				frame-number = <1>;
+				interrupts = <0 26 4>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+
+		/include/ "fvp-foundation-motherboard.dtsi"
+	};
+};
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv3-psci.dtb b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv3-psci.dtb
new file mode 100644
index 0000000..d7d9e14
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv3-psci.dtb
Binary files differ
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv3-psci.dts b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv3-psci.dts
new file mode 100644
index 0000000..48a1afc
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-foundation-gicv3-psci.dts
@@ -0,0 +1,254 @@
+/*
+ * 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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+};
+
+/ {
+	model = "FVP Foundation";
+	compatible = "arm,fvp-base", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+		cpu_suspend = <0xc4000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0xc4000003>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <40>;
+				exit-latency-us = <100>;
+				min-residency-us = <150>;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-method-param = <0x1010000>;
+				entry-latency-us = <500>;
+				exit-latency-us = <1000>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		CPU0:cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU1:cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU2:cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+
+		CPU3:cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x7F000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+	};
+
+	gic: interrupt-controller@2f000000 {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		interrupt-controller;
+		reg = <0x0 0x2f000000 0 0x10000>,	// GICD
+		      <0x0 0x2f100000 0 0x200000>,	// GICR
+		      <0x0 0x2c000000 0 0x2000>,	// GICC
+		      <0x0 0x2c010000 0 0x2000>,	// GICH
+		      <0x0 0x2c02f000 0 0x2000>;	// GICV
+		interrupts = <1 9 4>;
+
+		its: its@2f020000 {
+			compatible = "arm,gic-v3-its";
+			msi-controller;
+			reg = <0x0 0x2f020000 0x0 0x20000>; // GITS
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+			     <1 14 0xff01>,
+			     <1 11 0xff01>,
+			     <1 10 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0x0 0x10000>;
+			clock-frequency = <100000000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			frame@2a830000 {
+				frame-number = <1>;
+				interrupts = <0 26 4>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0 0 0  0 4>,
+				<0 0  1 &gic 0 0 0  1 4>,
+				<0 0  2 &gic 0 0 0  2 4>,
+				<0 0  3 &gic 0 0 0  3 4>,
+				<0 0  4 &gic 0 0 0  4 4>,
+				<0 0  5 &gic 0 0 0  5 4>,
+				<0 0  6 &gic 0 0 0  6 4>,
+				<0 0  7 &gic 0 0 0  7 4>,
+				<0 0  8 &gic 0 0 0  8 4>,
+				<0 0  9 &gic 0 0 0  9 4>,
+				<0 0 10 &gic 0 0 0 10 4>,
+				<0 0 11 &gic 0 0 0 11 4>,
+				<0 0 12 &gic 0 0 0 12 4>,
+				<0 0 13 &gic 0 0 0 13 4>,
+				<0 0 14 &gic 0 0 0 14 4>,
+				<0 0 15 &gic 0 0 0 15 4>,
+				<0 0 16 &gic 0 0 0 16 4>,
+				<0 0 17 &gic 0 0 0 17 4>,
+				<0 0 18 &gic 0 0 0 18 4>,
+				<0 0 19 &gic 0 0 0 19 4>,
+				<0 0 20 &gic 0 0 0 20 4>,
+				<0 0 21 &gic 0 0 0 21 4>,
+				<0 0 22 &gic 0 0 0 22 4>,
+				<0 0 23 &gic 0 0 0 23 4>,
+				<0 0 24 &gic 0 0 0 24 4>,
+				<0 0 25 &gic 0 0 0 25 4>,
+				<0 0 26 &gic 0 0 0 26 4>,
+				<0 0 27 &gic 0 0 0 27 4>,
+				<0 0 28 &gic 0 0 0 28 4>,
+				<0 0 29 &gic 0 0 0 29 4>,
+				<0 0 30 &gic 0 0 0 30 4>,
+				<0 0 31 &gic 0 0 0 31 4>,
+				<0 0 32 &gic 0 0 0 32 4>,
+				<0 0 33 &gic 0 0 0 33 4>,
+				<0 0 34 &gic 0 0 0 34 4>,
+				<0 0 35 &gic 0 0 0 35 4>,
+				<0 0 36 &gic 0 0 0 36 4>,
+				<0 0 37 &gic 0 0 0 37 4>,
+				<0 0 38 &gic 0 0 0 38 4>,
+				<0 0 39 &gic 0 0 0 39 4>,
+				<0 0 40 &gic 0 0 0 40 4>,
+				<0 0 41 &gic 0 0 0 41 4>,
+				<0 0 42 &gic 0 0 0 42 4>;
+
+		/include/ "fvp-foundation-motherboard-no_psci.dtsi"
+	};
+};
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-foundation-motherboard-no_psci.dtsi b/uefi/arm-trusted-firmware/fdts/fvp-foundation-motherboard-no_psci.dtsi
new file mode 100644
index 0000000..fd41c8a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-foundation-motherboard-no_psci.dtsi
@@ -0,0 +1,197 @@
+/*
+ * 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 the 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.
+ */
+
+	motherboard {
+		arm,v2m-memory-map = "rs1";
+		compatible = "arm,vexpress,v2m-p1", "simple-bus";
+		#address-cells = <2>; /* SMB chipselect number and offset */
+		#size-cells = <1>;
+		#interrupt-cells = <1>;
+		ranges;
+
+		ethernet@2,02000000 {
+			compatible = "smsc,lan91c111";
+			reg = <2 0x02000000 0x10000>;
+			interrupts = <15>;
+		};
+
+		v2m_clk24mhz: clk24mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-output-names = "v2m:clk24mhz";
+		};
+
+		v2m_refclk1mhz: refclk1mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1000000>;
+			clock-output-names = "v2m:refclk1mhz";
+		};
+
+		v2m_refclk32khz: refclk32khz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "v2m:refclk32khz";
+		};
+
+		iofpga@3,00000000 {
+			compatible = "arm,amba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 3 0 0x200000>;
+
+			v2m_sysreg: sysreg@010000 {
+				compatible = "arm,vexpress-sysreg";
+				reg = <0x010000 0x1000>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+
+			v2m_sysctl: sysctl@020000 {
+				compatible = "arm,sp810", "arm,primecell";
+				reg = <0x020000 0x1000>;
+				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
+				clock-names = "refclk", "timclk", "apb_pclk";
+				#clock-cells = <1>;
+				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+			};
+
+			v2m_serial0: uart@090000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x090000 0x1000>;
+				interrupts = <5>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial1: uart@0a0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0a0000 0x1000>;
+				interrupts = <6>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial2: uart@0b0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0b0000 0x1000>;
+				interrupts = <7>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial3: uart@0c0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0c0000 0x1000>;
+				interrupts = <8>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			wdt@0f0000 {
+				compatible = "arm,sp805", "arm,primecell";
+				reg = <0x0f0000 0x1000>;
+				interrupts = <0>;
+				clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
+				clock-names = "wdogclk", "apb_pclk";
+			};
+
+			v2m_timer01: timer@110000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x110000 0x1000>;
+				interrupts = <2>;
+				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			v2m_timer23: timer@120000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x120000 0x1000>;
+				interrupts = <3>;
+				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			rtc@170000 {
+				compatible = "arm,pl031", "arm,primecell";
+				reg = <0x170000 0x1000>;
+				interrupts = <4>;
+				clocks = <&v2m_clk24mhz>;
+				clock-names = "apb_pclk";
+			};
+
+			virtio_block@0130000 {
+				compatible = "virtio,mmio";
+				reg = <0x130000 0x1000>;
+				interrupts = <0x2a>;
+			};
+		};
+
+		v2m_fixed_3v3: fixedregulator@0 {
+			compatible = "regulator-fixed";
+			regulator-name = "3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+
+		mcc {
+			compatible = "arm,vexpress,config-bus", "simple-bus";
+			arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+			reset@0 {
+				compatible = "arm,vexpress-reset";
+				arm,vexpress-sysreg,func = <5 0>;
+			};
+
+			muxfpga@0 {
+				compatible = "arm,vexpress-muxfpga";
+				arm,vexpress-sysreg,func = <7 0>;
+			};
+
+			shutdown@0 {
+				compatible = "arm,vexpress-shutdown";
+				arm,vexpress-sysreg,func = <8 0>;
+			};
+
+			reboot@0 {
+				compatible = "arm,vexpress-reboot";
+				arm,vexpress-sysreg,func = <9 0>;
+			};
+
+			dvimode@0 {
+				compatible = "arm,vexpress-dvimode";
+				arm,vexpress-sysreg,func = <11 0>;
+			};
+		};
+	};
diff --git a/uefi/arm-trusted-firmware/fdts/fvp-foundation-motherboard.dtsi b/uefi/arm-trusted-firmware/fdts/fvp-foundation-motherboard.dtsi
new file mode 100644
index 0000000..9d29e48
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/fvp-foundation-motherboard.dtsi
@@ -0,0 +1,209 @@
+/*
+ * 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 the 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.
+ */
+
+	motherboard {
+		arm,v2m-memory-map = "rs1";
+		compatible = "arm,vexpress,v2m-p1", "simple-bus";
+		#address-cells = <2>; /* SMB chipselect number and offset */
+		#size-cells = <1>;
+		#interrupt-cells = <1>;
+		ranges;
+
+		ethernet@2,02000000 {
+			compatible = "smsc,lan91c111";
+			reg = <2 0x02000000 0x10000>;
+			interrupts = <15>;
+		};
+
+		v2m_clk24mhz: clk24mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-output-names = "v2m:clk24mhz";
+		};
+
+		v2m_refclk1mhz: refclk1mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1000000>;
+			clock-output-names = "v2m:refclk1mhz";
+		};
+
+		v2m_refclk32khz: refclk32khz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "v2m:refclk32khz";
+		};
+
+		iofpga@3,00000000 {
+			compatible = "arm,amba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 3 0 0x200000>;
+
+			v2m_sysreg: sysreg@010000 {
+				compatible = "arm,vexpress-sysreg";
+				reg = <0x010000 0x1000>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+
+			v2m_sysctl: sysctl@020000 {
+				compatible = "arm,sp810", "arm,primecell";
+				reg = <0x020000 0x1000>;
+				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
+				clock-names = "refclk", "timclk", "apb_pclk";
+				#clock-cells = <1>;
+				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+			};
+
+			v2m_serial0: uart@090000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x090000 0x1000>;
+				interrupts = <5>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial1: uart@0a0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0a0000 0x1000>;
+				interrupts = <6>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial2: uart@0b0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0b0000 0x1000>;
+				interrupts = <7>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial3: uart@0c0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0c0000 0x1000>;
+				interrupts = <8>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			wdt@0f0000 {
+				compatible = "arm,sp805", "arm,primecell";
+				reg = <0x0f0000 0x1000>;
+				interrupts = <0>;
+				clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
+				clock-names = "wdogclk", "apb_pclk";
+			};
+
+			v2m_timer01: timer@110000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x110000 0x1000>;
+				interrupts = <2>;
+				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			v2m_timer23: timer@120000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x120000 0x1000>;
+				interrupts = <3>;
+				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			rtc@170000 {
+				compatible = "arm,pl031", "arm,primecell";
+				reg = <0x170000 0x1000>;
+				interrupts = <4>;
+				clocks = <&v2m_clk24mhz>;
+				clock-names = "apb_pclk";
+			};
+
+			virtio_block@0130000 {
+				compatible = "virtio,mmio";
+				reg = <0x130000 0x1000>;
+				interrupts = <0x2a>;
+			};
+		};
+
+		v2m_fixed_3v3: fixedregulator@0 {
+			compatible = "regulator-fixed";
+			regulator-name = "3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+
+		mcc {
+			compatible = "arm,vexpress,config-bus", "simple-bus";
+			arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+			/*
+			 * Not supported in FVP models
+			 *
+			 * reset@0 {
+			 * 	compatible = "arm,vexpress-reset";
+			 * 	arm,vexpress-sysreg,func = <5 0>;
+			 * };
+			 */
+
+			muxfpga@0 {
+				compatible = "arm,vexpress-muxfpga";
+				arm,vexpress-sysreg,func = <7 0>;
+			};
+
+			/*
+			 * Not used - Superseded by PSCI sys_poweroff
+			 *
+			 * shutdown@0 {
+			 * 	compatible = "arm,vexpress-shutdown";
+			 * 	arm,vexpress-sysreg,func = <8 0>;
+			 * };
+			 */
+
+			/*
+			 * Not used - Superseded by PSCI sys_reset
+			 *
+			 * reboot@0 {
+			 * 	compatible = "arm,vexpress-reboot";
+			 * 	arm,vexpress-sysreg,func = <9 0>;
+			 * };
+			 */
+
+			dvimode@0 {
+				compatible = "arm,vexpress-dvimode";
+				arm,vexpress-sysreg,func = <11 0>;
+			};
+		};
+	};
diff --git a/uefi/arm-trusted-firmware/fdts/rtsm_ve-motherboard-no_psci.dtsi b/uefi/arm-trusted-firmware/fdts/rtsm_ve-motherboard-no_psci.dtsi
new file mode 100644
index 0000000..7ba575e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/rtsm_ve-motherboard-no_psci.dtsi
@@ -0,0 +1,264 @@
+/*
+ * 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.
+ */
+
+	motherboard {
+		arm,v2m-memory-map = "rs1";
+		compatible = "arm,vexpress,v2m-p1", "simple-bus";
+		#address-cells = <2>; /* SMB chipselect number and offset */
+		#size-cells = <1>;
+		#interrupt-cells = <1>;
+		ranges;
+
+		flash@0,00000000 {
+			compatible = "arm,vexpress-flash", "cfi-flash";
+			reg = <0 0x00000000 0x04000000>,
+			      <4 0x00000000 0x04000000>;
+			bank-width = <4>;
+		};
+
+		vram@2,00000000 {
+			compatible = "arm,vexpress-vram";
+			reg = <2 0x00000000 0x00800000>;
+		};
+
+		ethernet@2,02000000 {
+			compatible = "smsc,lan91c111";
+			reg = <2 0x02000000 0x10000>;
+			interrupts = <15>;
+		};
+
+		v2m_clk24mhz: clk24mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-output-names = "v2m:clk24mhz";
+		};
+
+		v2m_refclk1mhz: refclk1mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1000000>;
+			clock-output-names = "v2m:refclk1mhz";
+		};
+
+		v2m_refclk32khz: refclk32khz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "v2m:refclk32khz";
+		};
+
+		iofpga@3,00000000 {
+			compatible = "arm,amba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 3 0 0x200000>;
+
+			v2m_sysreg: sysreg@010000 {
+				compatible = "arm,vexpress-sysreg";
+				reg = <0x010000 0x1000>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+
+			v2m_sysctl: sysctl@020000 {
+				compatible = "arm,sp810", "arm,primecell";
+				reg = <0x020000 0x1000>;
+				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
+				clock-names = "refclk", "timclk", "apb_pclk";
+				#clock-cells = <1>;
+				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+			};
+
+			aaci@040000 {
+				compatible = "arm,pl041", "arm,primecell";
+				reg = <0x040000 0x1000>;
+				interrupts = <11>;
+				clocks = <&v2m_clk24mhz>;
+				clock-names = "apb_pclk";
+			};
+
+			mmci@050000 {
+				compatible = "arm,pl180", "arm,primecell";
+				reg = <0x050000 0x1000>;
+				interrupts = <9 10>;
+				cd-gpios = <&v2m_sysreg 0 0>;
+				wp-gpios = <&v2m_sysreg 1 0>;
+				max-frequency = <12000000>;
+				vmmc-supply = <&v2m_fixed_3v3>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "mclk", "apb_pclk";
+			};
+
+			kmi@060000 {
+				compatible = "arm,pl050", "arm,primecell";
+				reg = <0x060000 0x1000>;
+				interrupts = <12>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "KMIREFCLK", "apb_pclk";
+			};
+
+			kmi@070000 {
+				compatible = "arm,pl050", "arm,primecell";
+				reg = <0x070000 0x1000>;
+				interrupts = <13>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "KMIREFCLK", "apb_pclk";
+			};
+
+			v2m_serial0: uart@090000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x090000 0x1000>;
+				interrupts = <5>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial1: uart@0a0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0a0000 0x1000>;
+				interrupts = <6>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial2: uart@0b0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0b0000 0x1000>;
+				interrupts = <7>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial3: uart@0c0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0c0000 0x1000>;
+				interrupts = <8>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			wdt@0f0000 {
+				compatible = "arm,sp805", "arm,primecell";
+				reg = <0x0f0000 0x1000>;
+				interrupts = <0>;
+				clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
+				clock-names = "wdogclk", "apb_pclk";
+			};
+
+			v2m_timer01: timer@110000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x110000 0x1000>;
+				interrupts = <2>;
+				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			v2m_timer23: timer@120000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x120000 0x1000>;
+				interrupts = <3>;
+				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			rtc@170000 {
+				compatible = "arm,pl031", "arm,primecell";
+				reg = <0x170000 0x1000>;
+				interrupts = <4>;
+				clocks = <&v2m_clk24mhz>;
+				clock-names = "apb_pclk";
+			};
+
+			clcd@1f0000 {
+				compatible = "arm,pl111", "arm,primecell";
+				reg = <0x1f0000 0x1000>;
+				interrupts = <14>;
+				clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
+				clock-names = "clcdclk", "apb_pclk";
+				mode = "XVGA";
+				use_dma = <0>;
+				framebuffer = <0x18000000 0x00180000>;
+			};
+
+			virtio_block@0130000 {
+				compatible = "virtio,mmio";
+				reg = <0x130000 0x1000>;
+				interrupts = <0x2a>;
+			};
+		};
+
+		v2m_fixed_3v3: fixedregulator@0 {
+			compatible = "regulator-fixed";
+			regulator-name = "3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		mcc {
+			compatible = "arm,vexpress,config-bus", "simple-bus";
+			arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+			v2m_oscclk1: osc@1 {
+				/* CLCD clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 1>;
+				freq-range = <23750000 63500000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk1";
+			};
+
+			reset@0 {
+				compatible = "arm,vexpress-reset";
+				arm,vexpress-sysreg,func = <5 0>;
+			};
+
+			muxfpga@0 {
+				compatible = "arm,vexpress-muxfpga";
+				arm,vexpress-sysreg,func = <7 0>;
+			};
+
+			shutdown@0 {
+				compatible = "arm,vexpress-shutdown";
+				arm,vexpress-sysreg,func = <8 0>;
+			};
+
+			reboot@0 {
+				compatible = "arm,vexpress-reboot";
+				arm,vexpress-sysreg,func = <9 0>;
+			};
+
+			dvimode@0 {
+				compatible = "arm,vexpress-dvimode";
+				arm,vexpress-sysreg,func = <11 0>;
+			};
+		};
+	};
diff --git a/uefi/arm-trusted-firmware/fdts/rtsm_ve-motherboard.dtsi b/uefi/arm-trusted-firmware/fdts/rtsm_ve-motherboard.dtsi
new file mode 100644
index 0000000..6aa40ff
--- /dev/null
+++ b/uefi/arm-trusted-firmware/fdts/rtsm_ve-motherboard.dtsi
@@ -0,0 +1,276 @@
+/*
+ * 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.
+ */
+
+	motherboard {
+		arm,v2m-memory-map = "rs1";
+		compatible = "arm,vexpress,v2m-p1", "simple-bus";
+		#address-cells = <2>; /* SMB chipselect number and offset */
+		#size-cells = <1>;
+		#interrupt-cells = <1>;
+		ranges;
+
+		flash@0,00000000 {
+			compatible = "arm,vexpress-flash", "cfi-flash";
+			reg = <0 0x00000000 0x04000000>,
+			      <4 0x00000000 0x04000000>;
+			bank-width = <4>;
+		};
+
+		vram@2,00000000 {
+			compatible = "arm,vexpress-vram";
+			reg = <2 0x00000000 0x00800000>;
+		};
+
+		ethernet@2,02000000 {
+			compatible = "smsc,lan91c111";
+			reg = <2 0x02000000 0x10000>;
+			interrupts = <15>;
+		};
+
+		v2m_clk24mhz: clk24mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+			clock-output-names = "v2m:clk24mhz";
+		};
+
+		v2m_refclk1mhz: refclk1mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1000000>;
+			clock-output-names = "v2m:refclk1mhz";
+		};
+
+		v2m_refclk32khz: refclk32khz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "v2m:refclk32khz";
+		};
+
+		iofpga@3,00000000 {
+			compatible = "arm,amba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 3 0 0x200000>;
+
+			v2m_sysreg: sysreg@010000 {
+				compatible = "arm,vexpress-sysreg";
+				reg = <0x010000 0x1000>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+
+			v2m_sysctl: sysctl@020000 {
+				compatible = "arm,sp810", "arm,primecell";
+				reg = <0x020000 0x1000>;
+				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
+				clock-names = "refclk", "timclk", "apb_pclk";
+				#clock-cells = <1>;
+				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+			};
+
+			aaci@040000 {
+				compatible = "arm,pl041", "arm,primecell";
+				reg = <0x040000 0x1000>;
+				interrupts = <11>;
+				clocks = <&v2m_clk24mhz>;
+				clock-names = "apb_pclk";
+			};
+
+			mmci@050000 {
+				compatible = "arm,pl180", "arm,primecell";
+				reg = <0x050000 0x1000>;
+				interrupts = <9 10>;
+				cd-gpios = <&v2m_sysreg 0 0>;
+				wp-gpios = <&v2m_sysreg 1 0>;
+				max-frequency = <12000000>;
+				vmmc-supply = <&v2m_fixed_3v3>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "mclk", "apb_pclk";
+			};
+
+			kmi@060000 {
+				compatible = "arm,pl050", "arm,primecell";
+				reg = <0x060000 0x1000>;
+				interrupts = <12>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "KMIREFCLK", "apb_pclk";
+			};
+
+			kmi@070000 {
+				compatible = "arm,pl050", "arm,primecell";
+				reg = <0x070000 0x1000>;
+				interrupts = <13>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "KMIREFCLK", "apb_pclk";
+			};
+
+			v2m_serial0: uart@090000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x090000 0x1000>;
+				interrupts = <5>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial1: uart@0a0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0a0000 0x1000>;
+				interrupts = <6>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial2: uart@0b0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0b0000 0x1000>;
+				interrupts = <7>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			v2m_serial3: uart@0c0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0c0000 0x1000>;
+				interrupts = <8>;
+				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+				clock-names = "uartclk", "apb_pclk";
+			};
+
+			wdt@0f0000 {
+				compatible = "arm,sp805", "arm,primecell";
+				reg = <0x0f0000 0x1000>;
+				interrupts = <0>;
+				clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
+				clock-names = "wdogclk", "apb_pclk";
+			};
+
+			v2m_timer01: timer@110000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x110000 0x1000>;
+				interrupts = <2>;
+				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			v2m_timer23: timer@120000 {
+				compatible = "arm,sp804", "arm,primecell";
+				reg = <0x120000 0x1000>;
+				interrupts = <3>;
+				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
+				clock-names = "timclken1", "timclken2", "apb_pclk";
+			};
+
+			rtc@170000 {
+				compatible = "arm,pl031", "arm,primecell";
+				reg = <0x170000 0x1000>;
+				interrupts = <4>;
+				clocks = <&v2m_clk24mhz>;
+				clock-names = "apb_pclk";
+			};
+
+			clcd@1f0000 {
+				compatible = "arm,pl111", "arm,primecell";
+				reg = <0x1f0000 0x1000>;
+				interrupts = <14>;
+				clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
+				clock-names = "clcdclk", "apb_pclk";
+				mode = "XVGA";
+				use_dma = <0>;
+				framebuffer = <0x18000000 0x00180000>;
+			};
+
+			virtio_block@0130000 {
+				compatible = "virtio,mmio";
+				reg = <0x130000 0x1000>;
+				interrupts = <0x2a>;
+			};
+		};
+
+		v2m_fixed_3v3: fixedregulator@0 {
+			compatible = "regulator-fixed";
+			regulator-name = "3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		mcc {
+			compatible = "arm,vexpress,config-bus", "simple-bus";
+			arm,vexpress,config-bridge = <&v2m_sysreg>;
+
+			v2m_oscclk1: osc@1 {
+				/* CLCD clock */
+				compatible = "arm,vexpress-osc";
+				arm,vexpress-sysreg,func = <1 1>;
+				freq-range = <23750000 63500000>;
+				#clock-cells = <0>;
+				clock-output-names = "v2m:oscclk1";
+			};
+
+			/*
+			 * Not supported in FVP models
+			 *
+			 * reset@0 {
+			 * 	compatible = "arm,vexpress-reset";
+			 * 	arm,vexpress-sysreg,func = <5 0>;
+			 * };
+			 */
+
+			muxfpga@0 {
+				compatible = "arm,vexpress-muxfpga";
+				arm,vexpress-sysreg,func = <7 0>;
+			};
+
+			/*
+			 * Not used - Superseded by PSCI sys_poweroff
+			 *
+			 * shutdown@0 {
+			 * 	compatible = "arm,vexpress-shutdown";
+			 * 	arm,vexpress-sysreg,func = <8 0>;
+			 * };
+			 */
+
+			/*
+			 * Not used - Superseded by PSCI sys_reset
+			 *
+			 * reboot@0 {
+			 * 	compatible = "arm,vexpress-reboot";
+			 * 	arm,vexpress-sysreg,func = <9 0>;
+			 * };
+			 */
+
+			dvimode@0 {
+				compatible = "arm,vexpress-dvimode";
+				arm,vexpress-sysreg,func = <11 0>;
+			};
+		};
+	};
diff --git a/uefi/arm-trusted-firmware/include/bl31/bl31.h b/uefi/arm-trusted-firmware/include/bl31/bl31.h
new file mode 100644
index 0000000..96867b0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl31/bl31.h
@@ -0,0 +1,46 @@
+/*
+ * 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 __BL31_H__
+#define __BL31_H__
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * Function prototypes
+ ******************************************************************************/
+void bl31_arch_setup(void);
+void bl31_next_el_arch_setup(uint32_t security_state);
+void bl31_set_next_image_type(uint32_t type);
+uint32_t bl31_get_next_image_type(void);
+void bl31_prepare_next_image_entry(void);
+void bl31_register_bl32_init(int32_t (*)(void));
+
+#endif /* __BL31_H__ */
diff --git a/uefi/arm-trusted-firmware/include/bl31/context.h b/uefi/arm-trusted-firmware/include/bl31/context.h
new file mode 100644
index 0000000..0dfebe0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl31/context.h
@@ -0,0 +1,341 @@
+/*
+ * 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 __CONTEXT_H__
+#define __CONTEXT_H__
+
+/*******************************************************************************
+ * Constants that allow assembler code to access members of and the 'gp_regs'
+ * structure at their correct offsets.
+ ******************************************************************************/
+#define CTX_GPREGS_OFFSET	0x0
+#define CTX_GPREG_X0		0x0
+#define CTX_GPREG_X1		0x8
+#define CTX_GPREG_X2		0x10
+#define CTX_GPREG_X3		0x18
+#define CTX_GPREG_X4		0x20
+#define CTX_GPREG_X5		0x28
+#define CTX_GPREG_X6		0x30
+#define CTX_GPREG_X7		0x38
+#define CTX_GPREG_X8		0x40
+#define CTX_GPREG_X9		0x48
+#define CTX_GPREG_X10		0x50
+#define CTX_GPREG_X11		0x58
+#define CTX_GPREG_X12		0x60
+#define CTX_GPREG_X13		0x68
+#define CTX_GPREG_X14		0x70
+#define CTX_GPREG_X15		0x78
+#define CTX_GPREG_X16		0x80
+#define CTX_GPREG_X17		0x88
+#define CTX_GPREG_X18		0x90
+#define CTX_GPREG_X19		0x98
+#define CTX_GPREG_X20		0xa0
+#define CTX_GPREG_X21		0xa8
+#define CTX_GPREG_X22		0xb0
+#define CTX_GPREG_X23		0xb8
+#define CTX_GPREG_X24		0xc0
+#define CTX_GPREG_X25		0xc8
+#define CTX_GPREG_X26		0xd0
+#define CTX_GPREG_X27		0xd8
+#define CTX_GPREG_X28		0xe0
+#define CTX_GPREG_X29		0xe8
+#define CTX_GPREG_LR		0xf0
+#define CTX_GPREG_SP_EL0	0xf8
+#define CTX_GPREGS_END		0x100
+
+/*******************************************************************************
+ * Constants that allow assembler code to access members of and the 'el3_state'
+ * structure at their correct offsets. Note that some of the registers are only
+ * 32-bits wide but are stored as 64-bit values for convenience
+ ******************************************************************************/
+#define CTX_EL3STATE_OFFSET	(CTX_GPREGS_OFFSET + CTX_GPREGS_END)
+#define CTX_SCR_EL3		0x0
+#define CTX_RUNTIME_SP		0x8
+#define CTX_SPSR_EL3		0x10
+#define CTX_ELR_EL3		0x18
+#define CTX_EL3STATE_END	0x20
+
+/*******************************************************************************
+ * Constants that allow assembler code to access members of and the
+ * 'el1_sys_regs' structure at their correct offsets. Note that some of the
+ * registers are only 32-bits wide but are stored as 64-bit values for
+ * convenience
+ ******************************************************************************/
+#define CTX_SYSREGS_OFFSET	(CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
+#define CTX_SPSR_EL1		0x0
+#define CTX_ELR_EL1		0x8
+#define CTX_SPSR_ABT		0x10
+#define CTX_SPSR_UND		0x18
+#define CTX_SPSR_IRQ		0x20
+#define CTX_SPSR_FIQ		0x28
+#define CTX_SCTLR_EL1		0x30
+#define CTX_ACTLR_EL1		0x38
+#define CTX_CPACR_EL1		0x40
+#define CTX_CSSELR_EL1		0x48
+#define CTX_SP_EL1		0x50
+#define CTX_ESR_EL1		0x58
+#define CTX_TTBR0_EL1		0x60
+#define CTX_TTBR1_EL1		0x68
+#define CTX_MAIR_EL1		0x70
+#define CTX_AMAIR_EL1		0x78
+#define CTX_TCR_EL1		0x80
+#define CTX_TPIDR_EL1		0x88
+#define CTX_TPIDR_EL0		0x90
+#define CTX_TPIDRRO_EL0		0x98
+#define CTX_DACR32_EL2		0xa0
+#define CTX_IFSR32_EL2		0xa8
+#define CTX_PAR_EL1		0xb0
+#define CTX_FAR_EL1		0xb8
+#define CTX_AFSR0_EL1		0xc0
+#define CTX_AFSR1_EL1		0xc8
+#define CTX_CONTEXTIDR_EL1	0xd0
+#define CTX_VBAR_EL1		0xd8
+/*
+ * If the timer registers aren't saved and restored, we don't have to reserve
+ * space for them in the context
+ */
+#if NS_TIMER_SWITCH
+#define CTX_CNTP_CTL_EL0	0xe0
+#define CTX_CNTP_CVAL_EL0	0xe8
+#define CTX_CNTV_CTL_EL0	0xf0
+#define CTX_CNTV_CVAL_EL0	0xf8
+#define CTX_CNTKCTL_EL1		0x100
+#define CTX_FP_FPEXC32_EL2	0x108
+#define CTX_SYSREGS_END		0x110
+#else
+#define CTX_FP_FPEXC32_EL2	0xe0
+#define CTX_SYSREGS_END		0xf0
+#endif
+
+/*******************************************************************************
+ * Constants that allow assembler code to access members of and the 'fp_regs'
+ * structure at their correct offsets.
+ ******************************************************************************/
+#if CTX_INCLUDE_FPREGS
+#define CTX_FPREGS_OFFSET	(CTX_SYSREGS_OFFSET + CTX_SYSREGS_END)
+#define CTX_FP_Q0		0x0
+#define CTX_FP_Q1		0x10
+#define CTX_FP_Q2		0x20
+#define CTX_FP_Q3		0x30
+#define CTX_FP_Q4		0x40
+#define CTX_FP_Q5		0x50
+#define CTX_FP_Q6		0x60
+#define CTX_FP_Q7		0x70
+#define CTX_FP_Q8		0x80
+#define CTX_FP_Q9		0x90
+#define CTX_FP_Q10		0xa0
+#define CTX_FP_Q11		0xb0
+#define CTX_FP_Q12		0xc0
+#define CTX_FP_Q13		0xd0
+#define CTX_FP_Q14		0xe0
+#define CTX_FP_Q15		0xf0
+#define CTX_FP_Q16		0x100
+#define CTX_FP_Q17		0x110
+#define CTX_FP_Q18		0x120
+#define CTX_FP_Q19		0x130
+#define CTX_FP_Q20		0x140
+#define CTX_FP_Q21		0x150
+#define CTX_FP_Q22		0x160
+#define CTX_FP_Q23		0x170
+#define CTX_FP_Q24		0x180
+#define CTX_FP_Q25		0x190
+#define CTX_FP_Q26		0x1a0
+#define CTX_FP_Q27		0x1b0
+#define CTX_FP_Q28		0x1c0
+#define CTX_FP_Q29		0x1d0
+#define CTX_FP_Q30		0x1e0
+#define CTX_FP_Q31		0x1f0
+#define CTX_FP_FPSR		0x200
+#define CTX_FP_FPCR		0x208
+#define CTX_FPREGS_END		0x210
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <platform_def.h>	/* for CACHE_WRITEBACK_GRANULE */
+#include <stdint.h>
+
+/*
+ * Common constants to help define the 'cpu_context' structure and its
+ * members below.
+ */
+#define DWORD_SHIFT		3
+#define DEFINE_REG_STRUCT(name, num_regs)	\
+	typedef struct name {			\
+		uint64_t _regs[num_regs];	\
+	}  __aligned(16) name##_t
+
+/* Constants to determine the size of individual context structures */
+#define CTX_GPREG_ALL		(CTX_GPREGS_END >> DWORD_SHIFT)
+#define CTX_SYSREG_ALL		(CTX_SYSREGS_END >> DWORD_SHIFT)
+#if CTX_INCLUDE_FPREGS
+#define CTX_FPREG_ALL		(CTX_FPREGS_END >> DWORD_SHIFT)
+#endif
+#define CTX_EL3STATE_ALL	(CTX_EL3STATE_END >> DWORD_SHIFT)
+
+/*
+ * AArch64 general purpose register context structure. Usually x0-x18,
+ * lr are saved as the compiler is expected to preserve the remaining
+ * callee saved registers if used by the C runtime and the assembler
+ * does not touch the remaining. But in case of world switch during
+ * exception handling, we need to save the callee registers too.
+ */
+DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL);
+
+/*
+ * AArch64 EL1 system register context structure for preserving the
+ * architectural state during switches from one security state to
+ * another in EL1.
+ */
+DEFINE_REG_STRUCT(el1_sys_regs, CTX_SYSREG_ALL);
+
+/*
+ * AArch64 floating point register context structure for preserving
+ * the floating point state during switches from one security state to
+ * another.
+ */
+#if CTX_INCLUDE_FPREGS
+DEFINE_REG_STRUCT(fp_regs, CTX_FPREG_ALL);
+#endif
+
+/*
+ * Miscellaneous registers used by EL3 firmware to maintain its state
+ * across exception entries and exits
+ */
+DEFINE_REG_STRUCT(el3_state, CTX_EL3STATE_ALL);
+
+/*
+ * Macros to access members of any of the above structures using their
+ * offsets
+ */
+#define read_ctx_reg(ctx, offset)	((ctx)->_regs[offset >> DWORD_SHIFT])
+#define write_ctx_reg(ctx, offset, val)	(((ctx)->_regs[offset >> DWORD_SHIFT]) \
+					 = val)
+
+/*
+ * Top-level context structure which is used by EL3 firmware to
+ * preserve the state of a core at EL1 in one of the two security
+ * states and save enough EL3 meta data to be able to return to that
+ * EL and security state. The context management library will be used
+ * to ensure that SP_EL3 always points to an instance of this
+ * structure at exception entry and exit. Each instance will
+ * correspond to either the secure or the non-secure state.
+ */
+typedef struct cpu_context {
+	gp_regs_t gpregs_ctx;
+	el3_state_t el3state_ctx;
+	el1_sys_regs_t sysregs_ctx;
+#if CTX_INCLUDE_FPREGS
+	fp_regs_t fpregs_ctx;
+#endif
+} cpu_context_t;
+
+/* Macros to access members of the 'cpu_context_t' structure */
+#define get_el3state_ctx(h)	(&((cpu_context_t *) h)->el3state_ctx)
+#if CTX_INCLUDE_FPREGS
+#define get_fpregs_ctx(h)	(&((cpu_context_t *) h)->fpregs_ctx)
+#endif
+#define get_sysregs_ctx(h)	(&((cpu_context_t *) h)->sysregs_ctx)
+#define get_gpregs_ctx(h)	(&((cpu_context_t *) h)->gpregs_ctx)
+
+/*
+ * Compile time assertions related to the 'cpu_context' structure to
+ * ensure that the assembler and the compiler view of the offsets of
+ * the structure members is the same.
+ */
+CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx), \
+	assert_core_context_gp_offset_mismatch);
+CASSERT(CTX_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, sysregs_ctx), \
+	assert_core_context_sys_offset_mismatch);
+#if CTX_INCLUDE_FPREGS
+CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx), \
+	assert_core_context_fp_offset_mismatch);
+#endif
+CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx), \
+	assert_core_context_el3state_offset_mismatch);
+
+/*
+ * Helper macro to set the general purpose registers that correspond to
+ * parameters in an aapcs_64 call i.e. x0-x7
+ */
+#define set_aapcs_args0(ctx, x0)				do {	\
+		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0, x0);	\
+	} while (0);
+#define set_aapcs_args1(ctx, x0, x1)				do {	\
+		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1, x1);	\
+		set_aapcs_args0(ctx, x0);				\
+	} while (0);
+#define set_aapcs_args2(ctx, x0, x1, x2)			do {	\
+		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2, x2);	\
+		set_aapcs_args1(ctx, x0, x1);				\
+	} while (0);
+#define set_aapcs_args3(ctx, x0, x1, x2, x3)			do {	\
+		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3, x3);	\
+		set_aapcs_args2(ctx, x0, x1, x2);			\
+	} while (0);
+#define set_aapcs_args4(ctx, x0, x1, x2, x3, x4)		do {	\
+		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X4, x4);	\
+		set_aapcs_args3(ctx, x0, x1, x2, x3);			\
+	} while (0);
+#define set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5)		do {	\
+		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X5, x5);	\
+		set_aapcs_args4(ctx, x0, x1, x2, x3, x4);		\
+	} while (0);
+#define set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6)	do {	\
+		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X6, x6);	\
+		set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5);		\
+	} while (0);
+#define set_aapcs_args7(ctx, x0, x1, x2, x3, x4, x5, x6, x7)	do {	\
+		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X7, x7);	\
+		set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6);	\
+	} while (0);
+
+/*******************************************************************************
+ * Function prototypes
+ ******************************************************************************/
+void el1_sysregs_context_save(el1_sys_regs_t *regs);
+void el1_sysregs_context_restore(el1_sys_regs_t *regs);
+#if CTX_INCLUDE_FPREGS
+void fpregs_context_save(fp_regs_t *regs);
+void fpregs_context_restore(fp_regs_t *regs);
+#endif
+
+
+#undef CTX_SYSREG_ALL
+#if CTX_INCLUDE_FPREGS
+#undef CTX_FPREG_ALL
+#endif
+#undef CTX_GPREG_ALL
+#undef CTX_EL3STATE_ALL
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __CONTEXT_H__ */
diff --git a/uefi/arm-trusted-firmware/include/bl31/context_mgmt.h b/uefi/arm-trusted-firmware/include/bl31/context_mgmt.h
new file mode 100644
index 0000000..6e82fb7
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl31/context_mgmt.h
@@ -0,0 +1,91 @@
+/*
+ * 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 __CM_H__
+#define __CM_H__
+
+#include <cpu_data.h>
+#include <stdint.h>
+
+/*******************************************************************************
+ * Forward declarations
+ ******************************************************************************/
+struct entry_point_info;
+
+/*******************************************************************************
+ * Function & variable prototypes
+ ******************************************************************************/
+void cm_init(void);
+void *cm_get_context_by_mpidr(uint64_t mpidr, uint32_t security_state);
+static inline void *cm_get_context(uint32_t security_state);
+void cm_set_context_by_mpidr(uint64_t mpidr,
+			     void *context,
+			     uint32_t security_state);
+static inline void cm_set_context(void *context, uint32_t security_state);
+void cm_init_context(uint64_t mpidr, const struct entry_point_info *ep);
+void cm_prepare_el3_exit(uint32_t security_state);
+void cm_el1_sysregs_context_save(uint32_t security_state);
+void cm_el1_sysregs_context_restore(uint32_t security_state);
+void cm_set_elr_el3(uint32_t security_state, uint64_t entrypoint);
+void cm_set_elr_spsr_el3(uint32_t security_state,
+			 uint64_t entrypoint, uint32_t spsr);
+void cm_write_scr_el3_bit(uint32_t security_state,
+			  uint32_t bit_pos,
+			  uint32_t value);
+void cm_set_next_eret_context(uint32_t security_state);
+uint32_t cm_get_scr_el3(uint32_t security_state);
+
+/* Inline definitions */
+
+/*******************************************************************************
+ * This function returns a pointer to the most recent 'cpu_context' structure
+ * for the calling CPU 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(uint32_t security_state)
+{
+	assert(security_state <= NON_SECURE);
+
+	return get_cpu_data(cpu_context[security_state]);
+}
+
+/*******************************************************************************
+ * This function sets the pointer to the current 'cpu_context' structure for the
+ * specified security state for the calling CPU
+ ******************************************************************************/
+void cm_set_context(void *context, uint32_t security_state)
+{
+	assert(security_state <= NON_SECURE);
+
+	set_cpu_data(cpu_context[security_state], context);
+}
+
+
+#endif /* __CM_H__ */
diff --git a/uefi/arm-trusted-firmware/include/bl31/cpu_data.h b/uefi/arm-trusted-firmware/include/bl31/cpu_data.h
new file mode 100644
index 0000000..1926e29
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl31/cpu_data.h
@@ -0,0 +1,138 @@
+/*
+ * 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 __CPU_DATA_H__
+#define __CPU_DATA_H__
+
+/* Offsets for the cpu_data structure */
+#define CPU_DATA_CRASH_BUF_OFFSET	0x18
+#if CRASH_REPORTING
+#define CPU_DATA_LOG2SIZE		7
+#else
+#define CPU_DATA_LOG2SIZE		6
+#endif
+/* need enough space in crash buffer to save 8 registers */
+#define CPU_DATA_CRASH_BUF_SIZE		64
+#define CPU_DATA_CPU_OPS_PTR		0x10
+
+#ifndef __ASSEMBLY__
+
+#include <arch_helpers.h>
+#include <cassert.h>
+#include <platform_def.h>
+#include <psci.h>
+#include <stdint.h>
+
+/* Offsets for the cpu_data structure */
+#define CPU_DATA_PSCI_LOCK_OFFSET	__builtin_offsetof\
+		(cpu_data_t, psci_svc_cpu_data.pcpu_bakery_info)
+
+#if PLAT_PCPU_DATA_SIZE
+#define CPU_DATA_PLAT_PCPU_OFFSET	__builtin_offsetof\
+		(cpu_data_t, platform_cpu_data)
+#endif
+
+/*******************************************************************************
+ * Function & variable prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Cache of frequently used per-cpu data:
+ *   Pointers to non-secure and secure security state contexts
+ *   Address of the crash stack
+ * It is aligned to the cache line boundary to allow efficient concurrent
+ * manipulation of these pointers on different cpus
+ *
+ * TODO: Add other commonly used variables to this (tf_issues#90)
+ *
+ * The data structure and the _cpu_data accessors should not be used directly
+ * by components that have per-cpu members. The member access macros should be
+ * used for this.
+ ******************************************************************************/
+typedef struct cpu_data {
+	void *cpu_context[2];
+	uint64_t cpu_ops_ptr;
+#if CRASH_REPORTING
+	uint64_t crash_buf[CPU_DATA_CRASH_BUF_SIZE >> 3];
+#endif
+	struct psci_cpu_data psci_svc_cpu_data;
+#if PLAT_PCPU_DATA_SIZE
+	uint8_t platform_cpu_data[PLAT_PCPU_DATA_SIZE];
+#endif
+} __aligned(CACHE_WRITEBACK_GRANULE) cpu_data_t;
+
+#if CRASH_REPORTING
+/* verify assembler offsets match data structures */
+CASSERT(CPU_DATA_CRASH_BUF_OFFSET == __builtin_offsetof
+	(cpu_data_t, crash_buf),
+	assert_cpu_data_crash_stack_offset_mismatch);
+#endif
+
+CASSERT((1 << CPU_DATA_LOG2SIZE) == sizeof(cpu_data_t),
+	assert_cpu_data_log2size_mismatch);
+
+CASSERT(CPU_DATA_CPU_OPS_PTR == __builtin_offsetof
+		(cpu_data_t, cpu_ops_ptr),
+		assert_cpu_data_cpu_ops_ptr_offset_mismatch);
+
+struct cpu_data *_cpu_data_by_index(uint32_t cpu_index);
+struct cpu_data *_cpu_data_by_mpidr(uint64_t mpidr);
+
+/* Return the cpu_data structure for the current CPU. */
+static inline struct cpu_data *_cpu_data(void)
+{
+	return (cpu_data_t *)read_tpidr_el3();
+}
+
+
+/**************************************************************************
+ * APIs for initialising and accessing per-cpu data
+ *************************************************************************/
+
+void init_cpu_data_ptr(void);
+
+#define get_cpu_data(_m)		   _cpu_data()->_m
+#define set_cpu_data(_m, _v)		   _cpu_data()->_m = _v
+#define get_cpu_data_by_index(_ix, _m)	   _cpu_data_by_index(_ix)->_m
+#define set_cpu_data_by_index(_ix, _m, _v) _cpu_data_by_index(_ix)->_m = _v
+#define get_cpu_data_by_mpidr(_id, _m)	   _cpu_data_by_mpidr(_id)->_m
+#define set_cpu_data_by_mpidr(_id, _m, _v) _cpu_data_by_mpidr(_id)->_m = _v
+
+#define flush_cpu_data(_m)	   flush_dcache_range((uint64_t) 	  \
+						      &(_cpu_data()->_m), \
+						      sizeof(_cpu_data()->_m))
+#define flush_cpu_data_by_index(_ix, _m)	\
+				   flush_dcache_range((uint64_t)	  \
+					 &(_cpu_data_by_index(_ix)->_m),  \
+					 sizeof(_cpu_data_by_index(_ix)->_m))
+
+
+#endif /* __ASSEMBLY__ */
+#endif /* __CPU_DATA_H__ */
diff --git a/uefi/arm-trusted-firmware/include/bl31/interrupt_mgmt.h b/uefi/arm-trusted-firmware/include/bl31/interrupt_mgmt.h
new file mode 100644
index 0000000..e07ddf8
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl31/interrupt_mgmt.h
@@ -0,0 +1,131 @@
+/*
+ * 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 __INTERRUPT_MGMT_H__
+#define __INTERRUPT_MGMT_H__
+
+#include <arch.h>
+
+/*******************************************************************************
+ * Constants for the types of interrupts recognised by the IM framework
+ ******************************************************************************/
+#define INTR_TYPE_S_EL1			0
+#define INTR_TYPE_EL3			1
+#define INTR_TYPE_NS			2
+#define MAX_INTR_TYPES			3
+#define INTR_TYPE_INVAL			MAX_INTR_TYPES
+/*
+ * Constant passed to the interrupt handler in the 'id' field when the
+ * framework does not read the gic registers to determine the interrupt id.
+ */
+#define INTR_ID_UNAVAILABLE		0xFFFFFFFF
+
+
+/*******************************************************************************
+ * Mask for _both_ the routing model bits in the 'flags' parameter and
+ * constants to define the valid routing models for each supported interrupt
+ * type
+ ******************************************************************************/
+#define INTR_RM_FLAGS_SHIFT		0x0
+#define INTR_RM_FLAGS_MASK		0x3
+/* Routed to EL3 from NS. Taken to S-EL1 from Secure */
+#define INTR_SEL1_VALID_RM0		0x2
+/* Routed to EL3 from NS and Secure */
+#define INTR_SEL1_VALID_RM1		0x3
+/* Routed to EL1/EL2 from NS and to S-EL1 from Secure */
+#define INTR_NS_VALID_RM0		0x0
+/* Routed to EL1/EL2 from NS and to EL3 from Secure */
+#define INTR_NS_VALID_RM1		0x1
+/* This is the default routing model */
+#define INTR_DEFAULT_RM		0x0
+
+/*******************************************************************************
+ * Constants for the _individual_ routing model bits in the 'flags' field for
+ * each interrupt type and mask to validate the 'flags' parameter while
+ * registering an interrupt handler
+ ******************************************************************************/
+#define INTR_TYPE_FLAGS_MASK		0xFFFFFFFC
+
+#define INTR_RM_FROM_SEC_SHIFT		SECURE		/* BIT[0] */
+#define INTR_RM_FROM_NS_SHIFT		NON_SECURE	/* BIT[1] */
+#define INTR_RM_FROM_FLAG_MASK		1
+#define get_interrupt_rm_flag(flag, ss)	(((flag >> INTR_RM_FLAGS_SHIFT) >> ss) \
+					 & INTR_RM_FROM_FLAG_MASK)
+#define set_interrupt_rm_flag(flag, ss)	(flag |= 1 << ss)
+#define clr_interrupt_rm_flag(flag, ss)	(flag &= ~(1 << ss))
+
+
+/*******************************************************************************
+ * Macros to validate the routing model bits in the 'flags' for a type
+ * of interrupt. If the model does not match one of the valid masks
+ * -EINVAL is returned.
+ ******************************************************************************/
+#define validate_sel1_interrupt_rm(x)	(x == INTR_SEL1_VALID_RM0 ? 0 : \
+					 (x == INTR_SEL1_VALID_RM1 ? 0 :\
+					  -EINVAL))
+
+#define validate_ns_interrupt_rm(x)	(x == INTR_NS_VALID_RM0 ? 0 : \
+					 (x == INTR_NS_VALID_RM1 ? 0 :\
+					  -EINVAL))
+
+/*******************************************************************************
+ * Macros to set the 'flags' parameter passed to an interrupt type handler. Only
+ * the flag to indicate the security state when the exception was generated is
+ * supported.
+ ******************************************************************************/
+#define INTR_SRC_SS_FLAG_SHIFT		0		/* BIT[0] */
+#define INTR_SRC_SS_FLAG_MASK		1
+#define set_interrupt_src_ss(flag, val)	(flag |= val << INTR_SRC_SS_FLAG_SHIFT)
+#define clr_interrupt_src_ss(flag)	(flag &= ~(1 << INTR_SRC_SS_FLAG_SHIFT))
+#define get_interrupt_src_ss(flag)	((flag >> INTR_SRC_SS_FLAG_SHIFT) & \
+					 INTR_SRC_SS_FLAG_MASK)
+
+#ifndef __ASSEMBLY__
+
+/* Prototype for defining a handler for an interrupt type */
+typedef uint64_t (*interrupt_type_handler_t)(uint32_t id,
+					     uint32_t flags,
+					     void *handle,
+					     void *cookie);
+
+/*******************************************************************************
+ * Function & variable prototypes
+ ******************************************************************************/
+uint32_t get_scr_el3_from_routing_model(uint32_t security_state);
+int32_t set_routing_model(uint32_t type, uint32_t flags);
+int32_t register_interrupt_type_handler(uint32_t type,
+					interrupt_type_handler_t handler,
+					uint32_t flags);
+interrupt_type_handler_t get_interrupt_type_handler(uint32_t interrupt_type);
+int disable_intr_rm_local(uint32_t type, uint32_t security_state);
+int enable_intr_rm_local(uint32_t type, uint32_t security_state);
+
+#endif /*__ASSEMBLY__*/
+#endif /* __INTERRUPT_MGMT_H__ */
diff --git a/uefi/arm-trusted-firmware/include/bl31/runtime_svc.h b/uefi/arm-trusted-firmware/include/bl31/runtime_svc.h
new file mode 100644
index 0000000..f112418
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl31/runtime_svc.h
@@ -0,0 +1,281 @@
+/*
+ * 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 __RUNTIME_SVC_H__
+#define __RUNTIME_SVC_H__
+
+/*******************************************************************************
+ * Bit definitions inside the function id as per the SMC calling convention
+ ******************************************************************************/
+#define FUNCID_TYPE_SHIFT		31
+#define FUNCID_CC_SHIFT			30
+#define FUNCID_OEN_SHIFT		24
+#define FUNCID_NUM_SHIFT		0
+
+#define FUNCID_TYPE_MASK		0x1
+#define FUNCID_CC_MASK			0x1
+#define FUNCID_OEN_MASK			0x3f
+#define FUNCID_NUM_MASK			0xffff
+
+#define FUNCID_TYPE_WIDTH		1
+#define FUNCID_CC_WIDTH			1
+#define FUNCID_OEN_WIDTH		6
+#define FUNCID_NUM_WIDTH		16
+
+#define GET_SMC_CC(id)			((id >> FUNCID_CC_SHIFT) & \
+					 FUNCID_CC_MASK)
+#define GET_SMC_TYPE(id)		((id >> FUNCID_TYPE_SHIFT) & \
+					 FUNCID_TYPE_MASK)
+
+#define SMC_64				1
+#define SMC_32				0
+#define SMC_UNK				0xffffffff
+#define SMC_TYPE_FAST			1
+#define SMC_TYPE_STD			0
+#define SMC_PREEMPTED		0xfffffffe
+/*******************************************************************************
+ * Owning entity number definitions inside the function id as per the SMC
+ * calling convention
+ ******************************************************************************/
+#define OEN_ARM_START			0
+#define OEN_ARM_END			0
+#define OEN_CPU_START			1
+#define OEN_CPU_END			1
+#define OEN_SIP_START			2
+#define OEN_SIP_END			2
+#define OEN_OEM_START			3
+#define OEN_OEM_END			3
+#define OEN_STD_START			4	/* Standard Calls */
+#define OEN_STD_END			4
+#define OEN_TAP_START			48	/* Trusted Applications */
+#define OEN_TAP_END			49
+#define OEN_TOS_START			50	/* Trusted OS */
+#define OEN_TOS_END			63
+#define OEN_LIMIT			64
+
+/*******************************************************************************
+ * Constants to indicate type of exception to the common exception handler.
+ ******************************************************************************/
+#define SYNC_EXCEPTION_SP_EL0		0x0
+#define IRQ_SP_EL0			0x1
+#define FIQ_SP_EL0			0x2
+#define SERROR_SP_EL0			0x3
+#define SYNC_EXCEPTION_SP_ELX		0x4
+#define IRQ_SP_ELX			0x5
+#define FIQ_SP_ELX			0x6
+#define SERROR_SP_ELX			0x7
+#define SYNC_EXCEPTION_AARCH64		0x8
+#define IRQ_AARCH64			0x9
+#define FIQ_AARCH64			0xa
+#define SERROR_AARCH64			0xb
+#define SYNC_EXCEPTION_AARCH32		0xc
+#define IRQ_AARCH32			0xd
+#define FIQ_AARCH32			0xe
+#define SERROR_AARCH32			0xf
+
+/*******************************************************************************
+ * Structure definition, typedefs & constants for the runtime service framework
+ ******************************************************************************/
+
+/*
+ * Constants to allow the assembler access a runtime service
+ * descriptor
+ */
+#define RT_SVC_SIZE_LOG2	5
+#define SIZEOF_RT_SVC_DESC	(1 << RT_SVC_SIZE_LOG2)
+#define RT_SVC_DESC_INIT	16
+#define RT_SVC_DESC_HANDLE	24
+
+/*
+ * The function identifier has 6 bits for the owning entity number and
+ * single bit for the type of smc call. When taken together these
+ * values limit the maximum number of runtime services to 128.
+ */
+#define MAX_RT_SVCS		128
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <context.h>
+#include <stdint.h>
+
+/* Various flags passed to SMC handlers */
+#define SMC_FROM_SECURE		(0 << 0)
+#define SMC_FROM_NON_SECURE	(1 << 0)
+
+#define is_caller_non_secure(_f)	(!!(_f & SMC_FROM_NON_SECURE))
+#define is_caller_secure(_f)		(!(is_caller_non_secure(_f)))
+
+/* Prototype for runtime service initializing function */
+typedef int32_t (*rt_svc_init_t)(void);
+
+/* Convenience macros to return from SMC handler */
+#define SMC_RET0(_h)	{ \
+	return (uint64_t) (_h);		\
+}
+#define SMC_RET1(_h, _x0)	{ \
+	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X0, (_x0)); \
+	SMC_RET0(_h);						\
+}
+#define SMC_RET2(_h, _x0, _x1)	{ \
+	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X1, (_x1)); \
+	SMC_RET1(_h, (_x0)); \
+}
+#define SMC_RET3(_h, _x0, _x1, _x2)	{ \
+	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X2, (_x2)); \
+	SMC_RET2(_h, (_x0), (_x1)); \
+}
+#define SMC_RET4(_h, _x0, _x1, _x2, _x3)	{ \
+	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X3, (_x3)); \
+	SMC_RET3(_h, (_x0), (_x1), (_x2)); \
+}
+
+
+/*
+ * Convenience macros to access general purpose registers using handle provided
+ * to SMC handler. These takes the offset values defined in context.h
+ */
+#define SMC_GET_GP(_h, _g) \
+	read_ctx_reg(get_gpregs_ctx(_h), (_g));
+#define SMC_SET_GP(_h, _g, _v) \
+	write_ctx_reg(get_gpregs_ctx(_h), (_g), (_v));
+
+/*
+ * Convenience macros to access EL3 context registers using handle provided to
+ * SMC handler. These takes the offset values defined in context.h
+ */
+#define SMC_GET_EL3(_h, _e) \
+	read_ctx_reg(get_el3state_ctx(_h), (_e));
+#define SMC_SET_EL3(_h, _e, _v) \
+	write_ctx_reg(get_el3state_ctx(_h), (_e), (_v));
+
+/* The macro below is used to identify a Standard Service SMC call */
+#define is_std_svc_call(_fid)		((((_fid) >> FUNCID_OEN_SHIFT) & \
+					   FUNCID_OEN_MASK) == OEN_STD_START)
+
+/* The macro below is used to identify a valid Fast SMC call */
+#define is_valid_fast_smc(_fid)		((!(((_fid) >> 16) & 0xff)) && \
+					   (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST))
+
+/*
+ * Prototype for runtime service SMC handler function. x0 (SMC Function ID) to
+ * x4 are as passed by the caller. Rest of the arguments to SMC and the context
+ * can be accessed using the handle pointer. The cookie parameter is reserved
+ * for future use
+ */
+typedef uint64_t (*rt_svc_handle_t)(uint32_t smc_fid,
+				  uint64_t x1,
+				  uint64_t x2,
+				  uint64_t x3,
+				  uint64_t x4,
+				  void *cookie,
+				  void *handle,
+				  uint64_t flags);
+typedef struct rt_svc_desc {
+	uint8_t start_oen;
+	uint8_t end_oen;
+	uint8_t call_type;
+	const char *name;
+	rt_svc_init_t init;
+	rt_svc_handle_t handle;
+} rt_svc_desc_t;
+
+/*
+ * Convenience macro to declare a service descriptor
+ */
+#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \
+	static const rt_svc_desc_t __svc_desc_ ## _name \
+		__attribute__ ((section("rt_svc_descs"), used)) = { \
+			_start, \
+			_end, \
+			_type, \
+			#_name, \
+			_setup, \
+			_smch }
+
+/*
+ * Compile time assertions related to the 'rt_svc_desc' structure to:
+ * 1. ensure that the assembler and the compiler view of the size
+ *    of the structure are the same.
+ * 2. ensure that the assembler and the compiler see the initialisation
+ *    routine at the same offset.
+ * 3. ensure that the assembler and the compiler see the handler
+ *    routine at the same offset.
+ */
+CASSERT((sizeof(rt_svc_desc_t) == SIZEOF_RT_SVC_DESC), \
+	assert_sizeof_rt_svc_desc_mismatch);
+CASSERT(RT_SVC_DESC_INIT == __builtin_offsetof(rt_svc_desc_t, init), \
+	assert_rt_svc_desc_init_offset_mismatch);
+CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle), \
+	assert_rt_svc_desc_handle_offset_mismatch);
+
+
+/*
+ * This macro combines the call type and the owning entity number corresponding
+ * to a runtime service to generate a unique owning entity number. This unique
+ * oen is used to access an entry in the 'rt_svc_descs_indices' array. The entry
+ * contains the index of the service descriptor in the 'rt_svc_descs' array.
+ */
+#define get_unique_oen(oen, call_type)	((oen & FUNCID_OEN_MASK) |	\
+					((call_type & FUNCID_TYPE_MASK) \
+					 << FUNCID_OEN_WIDTH))
+
+
+/*
+ * Macro to define UUID for services. Apart from defining and initializing a
+ * uuid_t structure, this macro verifies that the first word of the defined UUID
+ * does not equal SMC_UNK. This is to ensure that the caller won't mistake the
+ * returned UUID in x0 for an invalid SMC error return
+ */
+#define DEFINE_SVC_UUID(_name, _tl, _tm, _th, _cl, _ch, \
+		_n0, _n1, _n2, _n3, _n4, _n5) \
+	CASSERT(_tl != SMC_UNK, invalid_svc_uuid);\
+	static const uuid_t _name = { \
+		_tl, _tm, _th, _cl, _ch, \
+		{ _n0, _n1, _n2, _n3, _n4, _n5 } \
+	}
+
+/* Return a UUID in the SMC return registers */
+#define SMC_UUID_RET(_h, _uuid) \
+	SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \
+			 ((const uint32_t *) &(_uuid))[1], \
+			 ((const uint32_t *) &(_uuid))[2], \
+			 ((const uint32_t *) &(_uuid))[3])
+
+/*******************************************************************************
+ * Function & variable prototypes
+ ******************************************************************************/
+void runtime_svc_init(void);
+extern uint64_t __RT_SVC_DESCS_START__;
+extern uint64_t __RT_SVC_DESCS_END__;
+void init_crash_reporting(void);
+
+#endif /*__ASSEMBLY__*/
+#endif /* __RUNTIME_SVC_H__ */
diff --git a/uefi/arm-trusted-firmware/include/bl31/services/psci.h b/uefi/arm-trusted-firmware/include/bl31/services/psci.h
new file mode 100644
index 0000000..dd1891c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl31/services/psci.h
@@ -0,0 +1,259 @@
+/*
+ * 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 __PSCI_H__
+#define __PSCI_H__
+
+#include <bakery_lock.h>
+#include <platform_def.h>	/* for PLATFORM_NUM_AFFS */
+
+/*******************************************************************************
+ * Number of affinity instances whose state this psci imp. can track
+ ******************************************************************************/
+#ifdef PLATFORM_NUM_AFFS
+#define PSCI_NUM_AFFS		PLATFORM_NUM_AFFS
+#else
+#define PSCI_NUM_AFFS		(2 * PLATFORM_CORE_COUNT)
+#endif
+
+/*******************************************************************************
+ * Defines for runtime services func ids
+ ******************************************************************************/
+#define PSCI_VERSION			0x84000000
+#define PSCI_CPU_SUSPEND_AARCH32	0x84000001
+#define PSCI_CPU_SUSPEND_AARCH64	0xc4000001
+#define PSCI_CPU_OFF			0x84000002
+#define PSCI_CPU_ON_AARCH32		0x84000003
+#define PSCI_CPU_ON_AARCH64		0xc4000003
+#define PSCI_AFFINITY_INFO_AARCH32	0x84000004
+#define PSCI_AFFINITY_INFO_AARCH64	0xc4000004
+#define PSCI_MIG_AARCH32		0x84000005
+#define PSCI_MIG_AARCH64		0xc4000005
+#define PSCI_MIG_INFO_TYPE		0x84000006
+#define PSCI_MIG_INFO_UP_CPU_AARCH32	0x84000007
+#define PSCI_MIG_INFO_UP_CPU_AARCH64	0xc4000007
+#define PSCI_SYSTEM_OFF			0x84000008
+#define PSCI_SYSTEM_RESET		0x84000009
+#define PSCI_FEATURES			0x8400000A
+#define PSCI_SYSTEM_SUSPEND_AARCH32	0x8400000E
+#define PSCI_SYSTEM_SUSPEND_AARCH64	0xc400000E
+
+/* Macro to help build the psci capabilities bitfield */
+#define define_psci_cap(x)		(1 << (x & 0x1f))
+
+/*
+ * Number of PSCI calls (above) implemented
+ */
+#define PSCI_NUM_CALLS			18
+
+/*******************************************************************************
+ * PSCI Migrate and friends
+ ******************************************************************************/
+#define PSCI_TOS_UP_MIG_CAP	0
+#define PSCI_TOS_NOT_UP_MIG_CAP	1
+#define PSCI_TOS_NOT_PRESENT_MP	2
+
+/*******************************************************************************
+ * PSCI CPU_SUSPEND 'power_state' parameter specific defines
+ ******************************************************************************/
+#define PSTATE_ID_SHIFT		0
+#define PSTATE_TYPE_SHIFT	16
+#define PSTATE_AFF_LVL_SHIFT	24
+
+#define PSTATE_ID_MASK		0xffff
+#define PSTATE_TYPE_MASK	0x1
+#define PSTATE_AFF_LVL_MASK	0x3
+#define PSTATE_VALID_MASK     0xFCFE0000
+
+#define PSTATE_TYPE_STANDBY	0x0
+#define PSTATE_TYPE_POWERDOWN	0x1
+
+#define psci_get_pstate_id(pstate)	(((pstate) >> PSTATE_ID_SHIFT) & \
+					PSTATE_ID_MASK)
+#define psci_get_pstate_type(pstate)	(((pstate) >> PSTATE_TYPE_SHIFT) & \
+					PSTATE_TYPE_MASK)
+#define psci_get_pstate_afflvl(pstate)	(((pstate) >> PSTATE_AFF_LVL_SHIFT) & \
+					PSTATE_AFF_LVL_MASK)
+#define psci_make_powerstate(state_id, type, afflvl) \
+			(((state_id) & PSTATE_ID_MASK) << PSTATE_ID_SHIFT) |\
+			(((type) & PSTATE_TYPE_MASK) << PSTATE_TYPE_SHIFT) |\
+			(((afflvl) & PSTATE_AFF_LVL_MASK) << PSTATE_AFF_LVL_SHIFT)
+
+/*******************************************************************************
+ * PSCI CPU_FEATURES feature flag specific defines
+ ******************************************************************************/
+/* Features flags for CPU SUSPEND power state parameter format. Bits [1:1] */
+#define FF_PSTATE_SHIFT		1
+#define FF_PSTATE_ORIG		0
+#define FF_PSTATE_EXTENDED	1
+
+/* Features flags for CPU SUSPEND OS Initiated mode support. Bits [0:0] */
+#define FF_MODE_SUPPORT_SHIFT		0
+#define FF_SUPPORTS_OS_INIT_MODE	1
+
+/*******************************************************************************
+ * PSCI version
+ ******************************************************************************/
+#define PSCI_MAJOR_VER		(1 << 16)
+#define PSCI_MINOR_VER		0x0
+
+/*******************************************************************************
+ * PSCI error codes
+ ******************************************************************************/
+#define PSCI_E_SUCCESS		0
+#define PSCI_E_NOT_SUPPORTED	-1
+#define PSCI_E_INVALID_PARAMS	-2
+#define PSCI_E_DENIED		-3
+#define PSCI_E_ALREADY_ON	-4
+#define PSCI_E_ON_PENDING	-5
+#define PSCI_E_INTERN_FAIL	-6
+#define PSCI_E_NOT_PRESENT	-7
+#define PSCI_E_DISABLED		-8
+
+/*******************************************************************************
+ * PSCI affinity state related constants. An affinity instance could be present
+ * or absent physically to cater for asymmetric topologies. If present then it
+ * could in one of the 4 further defined states.
+ ******************************************************************************/
+#define PSCI_STATE_SHIFT	1
+#define PSCI_STATE_MASK		0xff
+
+#define PSCI_AFF_ABSENT		0x0
+#define PSCI_AFF_PRESENT	0x1
+#define PSCI_STATE_ON		0x0
+#define PSCI_STATE_OFF		0x1
+#define PSCI_STATE_ON_PENDING	0x2
+#define PSCI_STATE_SUSPEND	0x3
+
+#define PSCI_INVALID_DATA -1
+
+#define get_phys_state(x)	(x != PSCI_STATE_ON ? \
+				 PSCI_STATE_OFF : PSCI_STATE_ON)
+
+#define psci_validate_power_state(pstate) (pstate & PSTATE_VALID_MASK)
+
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * Structure used to store per-cpu information relevant to the PSCI service.
+ * It is populated in the per-cpu data array. In return we get a guarantee that
+ * this information will not reside on a cache line shared with another cpu.
+ ******************************************************************************/
+typedef struct psci_cpu_data {
+	uint32_t power_state;
+	uint32_t max_phys_off_afflvl;	/* Highest affinity level in physically
+					   powered off state */
+#if !USE_COHERENT_MEM
+	bakery_info_t pcpu_bakery_info[PSCI_NUM_AFFS];
+#endif
+} psci_cpu_data_t;
+
+/*******************************************************************************
+ * Structure populated by platform specific code to export routines which
+ * perform common low level pm functions
+ ******************************************************************************/
+typedef struct plat_pm_ops {
+	void (*affinst_standby)(unsigned int power_state);
+	int (*affinst_on)(unsigned long mpidr,
+			  unsigned long sec_entrypoint,
+			  unsigned int afflvl,
+			  unsigned int state);
+	void (*affinst_off)(unsigned int afflvl, unsigned int state);
+	void (*affinst_suspend)(unsigned long sec_entrypoint,
+			       unsigned int afflvl,
+			       unsigned int state);
+	void (*affinst_on_finish)(unsigned int afflvl, unsigned int state);
+	void (*affinst_suspend_finish)(unsigned int afflvl,
+				      unsigned int state);
+	void (*system_off)(void) __dead2;
+	void (*system_reset)(void) __dead2;
+	int (*validate_power_state)(unsigned int power_state);
+	int (*validate_ns_entrypoint)(unsigned long ns_entrypoint);
+	unsigned int (*get_sys_suspend_power_state)(void);
+} plat_pm_ops_t;
+
+/*******************************************************************************
+ * Optional structure populated by the Secure Payload Dispatcher to be given a
+ * chance to perform any bookkeeping before PSCI executes a power mgmt.
+ * operation. It also allows PSCI to determine certain properties of the SP e.g.
+ * migrate capability etc.
+ ******************************************************************************/
+typedef struct spd_pm_ops {
+	void (*svc_on)(uint64_t target_cpu);
+	int32_t (*svc_off)(uint64_t __unused);
+	void (*svc_suspend)(uint64_t __unused);
+	void (*svc_on_finish)(uint64_t __unused);
+	void (*svc_suspend_finish)(uint64_t suspend_level);
+	int32_t (*svc_migrate)(uint64_t from_cpu, uint64_t to_cpu);
+	int32_t (*svc_migrate_info)(uint64_t *resident_cpu);
+	void (*svc_system_off)(void);
+	void (*svc_system_reset)(void);
+} spd_pm_ops_t;
+
+/*******************************************************************************
+ * Function & Data prototypes
+ ******************************************************************************/
+unsigned int psci_version(void);
+int psci_affinity_info(unsigned long, unsigned int);
+int psci_migrate(unsigned long);
+int psci_migrate_info_type(void);
+long psci_migrate_info_up_cpu(void);
+int psci_cpu_on(unsigned long,
+		unsigned long,
+		unsigned long);
+void __dead2 psci_power_down_wfi(void);
+void psci_aff_on_finish_entry(void);
+void psci_aff_suspend_finish_entry(void);
+void psci_register_spd_pm_hook(const spd_pm_ops_t *);
+int psci_get_suspend_stateid_by_mpidr(unsigned long);
+int psci_get_suspend_stateid(void);
+int psci_get_suspend_afflvl(void);
+uint32_t psci_get_max_phys_off_afflvl(void);
+
+uint64_t psci_smc_handler(uint32_t smc_fid,
+			  uint64_t x1,
+			  uint64_t x2,
+			  uint64_t x3,
+			  uint64_t x4,
+			  void *cookie,
+			  void *handle,
+			  uint64_t flags);
+
+/* PSCI setup function */
+int32_t psci_setup(void);
+
+
+#endif /*__ASSEMBLY__*/
+
+
+#endif /* __PSCI_H__ */
diff --git a/uefi/arm-trusted-firmware/include/bl31/services/std_svc.h b/uefi/arm-trusted-firmware/include/bl31/services/std_svc.h
new file mode 100644
index 0000000..cbd5b62
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl31/services/std_svc.h
@@ -0,0 +1,51 @@
+/*
+ * 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 __STD_SVC_H__
+#define __STD_SVC_H__
+
+/* SMC function IDs for Standard Service queries */
+
+#define ARM_STD_SVC_CALL_COUNT		0x8400ff00
+#define ARM_STD_SVC_UID			0x8400ff01
+/*					0x8400ff02 is reserved */
+#define ARM_STD_SVC_VERSION		0x8400ff03
+
+/* ARM Standard Service Calls version numbers */
+#define STD_SVC_VERSION_MAJOR		0x0
+#define STD_SVC_VERSION_MINOR		0x1
+
+/* The macros below are used to identify PSCI calls from the SMC function ID */
+#define PSCI_FID_MASK			0xffe0u
+#define PSCI_FID_VALUE			0u
+#define is_psci_fid(_fid) \
+	(((_fid) & PSCI_FID_MASK) == PSCI_FID_VALUE)
+
+#endif /* __STD_SVC_H__ */
diff --git a/uefi/arm-trusted-firmware/include/bl32/tsp/platform_tsp.h b/uefi/arm-trusted-firmware/include/bl32/tsp/platform_tsp.h
new file mode 100644
index 0000000..f6f7391
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl32/tsp/platform_tsp.h
@@ -0,0 +1,44 @@
+/*
+ * 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 __PLATFORM_TSP_H__
+
+
+/*******************************************************************************
+ * Mandatory TSP functions (only if platform contains a TSP)
+ ******************************************************************************/
+void tsp_early_platform_setup(void);
+void tsp_plat_arch_setup(void);
+void tsp_platform_setup(void);
+
+
+#define __PLATFORM_H__
+
+#endif
diff --git a/uefi/arm-trusted-firmware/include/bl32/tsp/tsp.h b/uefi/arm-trusted-firmware/include/bl32/tsp/tsp.h
new file mode 100644
index 0000000..c6578b7
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/bl32/tsp/tsp.h
@@ -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.
+ */
+
+#ifndef __TSP_H__
+#define __TSP_H__
+
+/*
+ * SMC function IDs that TSP uses to signal various forms of completions
+ * to the secure payload dispatcher.
+ */
+#define TSP_ENTRY_DONE		0xf2000000
+#define TSP_ON_DONE		0xf2000001
+#define TSP_OFF_DONE		0xf2000002
+#define TSP_SUSPEND_DONE	0xf2000003
+#define TSP_RESUME_DONE		0xf2000004
+#define TSP_PREEMPTED		0xf2000005
+#define TSP_SYSTEM_OFF_DONE	0xf2000008
+#define TSP_SYSTEM_RESET_DONE	0xf2000009
+
+/*
+ * Function identifiers to handle FIQs through the synchronous handling model.
+ * If the TSP was previously interrupted then control has to be returned to
+ * the TSPD after handling the interrupt else execution can remain in the TSP.
+ */
+#define TSP_HANDLED_S_EL1_FIQ		0xf2000006
+#define TSP_EL3_FIQ			0xf2000007
+
+/* SMC function ID that TSP uses to request service from secure monitor */
+#define TSP_GET_ARGS		0xf2001000
+
+/*
+ * Identifiers for various TSP services. Corresponding function IDs (whether
+ * fast or standard) are generated by macros defined below
+ */
+#define TSP_ADD		0x2000
+#define TSP_SUB		0x2001
+#define TSP_MUL		0x2002
+#define TSP_DIV		0x2003
+#define TSP_HANDLE_FIQ_AND_RETURN	0x2004
+
+/*
+ * Generate function IDs for TSP services to be used in SMC calls, by
+ * appropriately setting bit 31 to differentiate standard and fast SMC calls
+ */
+#define TSP_STD_FID(fid)	((fid) | 0x72000000 | (0 << 31))
+#define TSP_FAST_FID(fid)	((fid) | 0x72000000 | (1 << 31))
+
+/* SMC function ID to request a previously preempted std smc */
+#define TSP_FID_RESUME		TSP_STD_FID(0x3000)
+
+/*
+ * Identify a TSP service from function ID filtering the last 16 bits from the
+ * SMC function ID
+ */
+#define TSP_BARE_FID(fid)	((fid) & 0xffff)
+
+/*
+ * Total number of function IDs implemented for services offered to NS clients.
+ * The function IDs are defined above
+ */
+#define TSP_NUM_FID		0x4
+
+/* TSP implementation version numbers */
+#define TSP_VERSION_MAJOR	0x0 /* Major version */
+#define TSP_VERSION_MINOR	0x1 /* Minor version */
+
+/*
+ * Standard Trusted OS Function IDs that fall under Trusted OS call range
+ * according to SMC calling convention
+ */
+#define TOS_CALL_COUNT		0xbf00ff00 /* Number of calls implemented */
+#define TOS_UID			0xbf00ff01 /* Implementation UID */
+/*				0xbf00ff02 is reserved */
+#define TOS_CALL_VERSION	0xbf00ff03 /* Trusted OS Call Version */
+
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+
+typedef uint32_t tsp_vector_isn_t;
+
+typedef struct tsp_vectors {
+	tsp_vector_isn_t std_smc_entry;
+	tsp_vector_isn_t fast_smc_entry;
+	tsp_vector_isn_t cpu_on_entry;
+	tsp_vector_isn_t cpu_off_entry;
+	tsp_vector_isn_t cpu_resume_entry;
+	tsp_vector_isn_t cpu_suspend_entry;
+	tsp_vector_isn_t fiq_entry;
+	tsp_vector_isn_t system_off_entry;
+	tsp_vector_isn_t system_reset_entry;
+} tsp_vectors_t;
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __TSP_H__ */
diff --git a/uefi/arm-trusted-firmware/include/common/asm_macros.S b/uefi/arm-trusted-firmware/include/common/asm_macros.S
new file mode 100644
index 0000000..238fa82
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/common/asm_macros.S
@@ -0,0 +1,197 @@
+/*
+ * 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>
+
+
+	.macro	func_prologue
+	stp	x29, x30, [sp, #-0x10]!
+	mov	x29,sp
+	.endm
+
+	.macro	func_epilogue
+	ldp	x29, x30, [sp], #0x10
+	.endm
+
+
+	.macro	dcache_line_size  reg, tmp
+	mrs	\tmp, ctr_el0
+	ubfx	\tmp, \tmp, #16, #4
+	mov	\reg, #4
+	lsl	\reg, \reg, \tmp
+	.endm
+
+
+	.macro	icache_line_size  reg, tmp
+	mrs	\tmp, ctr_el0
+	and	\tmp, \tmp, #0xf
+	mov	\reg, #4
+	lsl	\reg, \reg, \tmp
+	.endm
+
+
+	.macro	smc_check  label
+	mrs	x0, esr_el3
+	ubfx	x0, x0, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+	cmp	x0, #EC_AARCH64_SMC
+	b.ne	$label
+	.endm
+
+
+	/*
+	 * This macro verifies that the a given vector doesn't exceed the
+	 * architectural limit of 32 instructions. This is meant to be placed
+	 * immedately after the last instruction in the vector. It takes the
+	 * vector entry as the parameter
+	 */
+	.macro check_vector_size since
+	  .if (. - \since) > (32 * 4)
+	    .error "Vector exceeds 32 instructions"
+	  .endif
+	.endm
+
+	/*
+	 * This macro is used to create a function label and place the
+	 * code into a separate text section based on the function name
+	 * to enable elimination of unused code during linking
+	 */
+	.macro func _name
+	.section .text.\_name, "ax"
+	.type \_name, %function
+	\_name:
+	.endm
+
+	/* ---------------------------------------------
+	 * Find the type of reset and jump to handler
+	 * if present. If the handler is null then it is
+	 * a cold boot. The primary cpu will set up the
+	 * platform while the secondaries wait for
+	 * their turn to be woken up
+	 * ---------------------------------------------
+	 */
+	.macro wait_for_entrypoint
+wait_for_entrypoint:
+	mrs	x0, mpidr_el1
+	bl	platform_get_entrypoint
+	cbnz	x0, do_warm_boot
+	mrs	x0, mpidr_el1
+	bl	platform_is_primary_cpu
+	cbnz	x0, do_cold_boot
+
+	/* ---------------------------------------------
+	 * Perform any platform specific secondary cpu
+	 * actions
+	 * ---------------------------------------------
+	 */
+	bl	plat_secondary_cold_boot_setup
+	b	wait_for_entrypoint
+
+	do_warm_boot:
+	/* ---------------------------------------------
+	 * Jump to BL31 for all warm boot init.
+	 * ---------------------------------------------
+	 */
+	blr	x0
+
+	do_cold_boot:
+	.endm
+
+	/*
+	 * This macro declares an array of 1 or more stacks, properly
+	 * aligned and in the requested section
+	 */
+#define STACK_ALIGN	6
+
+	.macro declare_stack _name, _section, _size, _count
+	.if ((\_size & ((1 << STACK_ALIGN) - 1)) <> 0)
+	  .error "Stack size not correctly aligned"
+	.endif
+	.section    \_section, "aw", %nobits
+	.align STACK_ALIGN
+	\_name:
+	.space ((\_count) * (\_size)), 0
+	.endm
+
+	/*
+	 * This macro calculates the base address of an MP stack using the
+	 * platform_get_core_pos() index, the name of the stack storage and
+	 * the size of each stack
+	 * In: X0 = MPIDR of CPU whose stack is wanted
+	 * Out: X0 = physical address of stack base
+	 * Clobber: X30, X1, X2
+	 */
+	.macro get_mp_stack _name, _size
+	bl  platform_get_core_pos
+	ldr x2, =(\_name + \_size)
+	mov x1, #\_size
+	madd x0, x0, x1, x2
+	.endm
+
+	/*
+	 * This macro calculates the base address of a UP stack using the
+	 * name of the stack storage and the size of the stack
+	 * Out: X0 = physical address of stack base
+	 */
+	.macro get_up_stack _name, _size
+	ldr x0, =(\_name + \_size)
+	.endm
+
+	/*
+	 * Helper macro to generate the best mov/movk combinations according
+	 * the value to be moved. The 16 bits from '_shift' are tested and
+	 * if not zero, they are moved into '_reg' without affecting
+	 * other bits.
+	 */
+	.macro _mov_imm16 _reg, _val, _shift
+		.if (\_val >> \_shift) & 0xffff
+			.if (\_val & (1 << \_shift - 1))
+				movk	\_reg, (\_val >> \_shift) & 0xffff, LSL \_shift
+			.else
+				mov	\_reg, \_val & (0xffff << \_shift)
+			.endif
+		.endif
+	.endm
+
+	/*
+	 * Helper macro to load arbitrary values into 32 or 64-bit registers
+	 * which generates the best mov/movk combinations. Many base addresses
+	 * are 64KB aligned the macro will eliminate updating bits 15:0 in
+	 * that case
+	 */
+	.macro mov_imm _reg, _val
+		.if (\_val) == 0
+			mov	\_reg, #0
+		.else
+			_mov_imm16	\_reg, (\_val), 0
+			_mov_imm16	\_reg, (\_val), 16
+			_mov_imm16	\_reg, (\_val), 32
+			_mov_imm16	\_reg, (\_val), 48
+		.endif
+	.endm
diff --git a/uefi/arm-trusted-firmware/include/common/assert_macros.S b/uefi/arm-trusted-firmware/include/common/assert_macros.S
new file mode 100644
index 0000000..807972f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/common/assert_macros.S
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+	/*
+	 * Assembler macro to enable asm_assert. Use this macro wherever
+	 * assert is required in assembly. Please note that the macro makes
+	 * use of label '300' to provide the logic and the caller
+	 * should make sure that this label is not used to branch prior
+	 * to calling this macro.
+	 */
+#define ASM_ASSERT(_cc) \
+.ifndef .L_assert_filename ;\
+	.pushsection .rodata.str1.1, "aS" ;\
+	.L_assert_filename: ;\
+			.string	__FILE__ ;\
+	.popsection ;\
+.endif ;\
+	b._cc	300f ;\
+	adr	x0, .L_assert_filename ;\
+	mov	x1, __LINE__ ;\
+	b	asm_assert ;\
+300:
diff --git a/uefi/arm-trusted-firmware/include/common/auth.h b/uefi/arm-trusted-firmware/include/common/auth.h
new file mode 100644
index 0000000..3c3a6bd
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/common/auth.h
@@ -0,0 +1,88 @@
+/*
+ * 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 AUTH_H_
+#define AUTH_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/*
+ * Authentication infrastructure for Trusted Boot
+ *
+ * This infrastructure provides an API to access the authentication module. This
+ * module will implement the required operations for Trusted Boot by creating an
+ * instance of the structure 'auth_mod_t'. This instance must be called
+ * 'auth_mod' and must provide the functions to initialize the module and
+ * verify the authenticity of the images.
+ */
+
+/* Objects (images and certificates) involved in the TBB process */
+enum {
+	AUTH_BL2_IMG_CERT,
+	AUTH_BL2_IMG,
+	AUTH_TRUSTED_KEY_CERT,
+	AUTH_BL30_KEY_CERT,
+	AUTH_BL30_IMG_CERT,
+	AUTH_BL30_IMG,
+	AUTH_BL31_KEY_CERT,
+	AUTH_BL31_IMG_CERT,
+	AUTH_BL31_IMG,
+	AUTH_BL32_KEY_CERT,
+	AUTH_BL32_IMG_CERT,
+	AUTH_BL32_IMG,
+	AUTH_BL33_KEY_CERT,
+	AUTH_BL33_IMG_CERT,
+	AUTH_BL33_IMG,
+	AUTH_NUM_OBJ
+};
+
+/* Authentication module structure */
+typedef struct auth_mod_s {
+	/* [mandatory] Module name. Printed to the log during initialization */
+	const char *name;
+
+	/* [mandatory] Initialize the authentication module */
+	int (*init)(void);
+
+	/* [mandatory] This function will be called to authenticate a new
+	 * object loaded into memory. The obj_id corresponds to one of the
+	 * values in the enumeration above */
+	int (*verify)(unsigned int obj_id, uintptr_t obj_buf, size_t len);
+} auth_mod_t;
+
+/* This variable must be instantiated by the authentication module */
+extern const auth_mod_t auth_mod;
+
+/* Public functions */
+void auth_init(void);
+int auth_verify_obj(unsigned int obj_id, uintptr_t obj_buf, size_t len);
+
+#endif /* AUTH_H_ */
diff --git a/uefi/arm-trusted-firmware/include/common/bl_common.h b/uefi/arm-trusted-firmware/include/common/bl_common.h
new file mode 100644
index 0000000..0959c89
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/common/bl_common.h
@@ -0,0 +1,233 @@
+/*
+ * 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 __BL_COMMON_H__
+#define __BL_COMMON_H__
+
+#define SECURE		0x0
+#define NON_SECURE	0x1
+#define sec_state_is_valid(s) (((s) == SECURE) || ((s) == NON_SECURE))
+
+#define UP	1
+#define DOWN	0
+
+/*******************************************************************************
+ * Constants to identify the location of a memory region in a given memory
+ * layout.
+******************************************************************************/
+#define TOP	0x1
+#define BOTTOM	!TOP
+
+/******************************************************************************
+ * Opcode passed in x0 to tell next EL that we want to run an image.
+ * Corresponds to the function ID of the only SMC that the BL1 exception
+ * handlers service. That's why the chosen value is the first function ID of
+ * the ARM SMC64 range.
+ *****************************************************************************/
+#define RUN_IMAGE	0xC0000000
+
+/*******************************************************************************
+ * Constants that allow assembler code to access members of and the
+ * 'entry_point_info' structure at their correct offsets.
+ ******************************************************************************/
+#define ENTRY_POINT_INFO_PC_OFFSET	0x08
+#define ENTRY_POINT_INFO_ARGS_OFFSET	0x18
+
+#define PARAM_EP_SECURITY_MASK    0x1
+#define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK)
+#define SET_SECURITY_STATE(x, security) \
+			((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security))
+
+#define EP_EE_MASK	0x2
+#define EP_EE_LITTLE	0x0
+#define EP_EE_BIG	0x2
+#define EP_GET_EE(x) (x & EP_EE_MASK)
+#define EP_SET_EE(x, ee) ((x) = ((x) & ~EP_EE_MASK) | (ee))
+
+#define EP_ST_MASK	0x4
+#define EP_ST_DISABLE	0x0
+#define EP_ST_ENABLE	0x4
+#define EP_GET_ST(x) (x & EP_ST_MASK)
+#define EP_SET_ST(x, ee) ((x) = ((x) & ~EP_ST_MASK) | (ee))
+
+#define PARAM_EP     0x01
+#define PARAM_IMAGE_BINARY  0x02
+#define PARAM_BL31       0x03
+
+#define VERSION_1		0x01
+
+#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
+	(_p)->h.type = (uint8_t)(_type); \
+	(_p)->h.version = (uint8_t)(_ver); \
+	(_p)->h.size = (uint16_t)sizeof(*_p); \
+	(_p)->h.attr = (uint32_t)(_attr) ; \
+	} while (0)
+
+/*******************************************************************************
+ * Constant that indicates if this is the first version of the reset handler
+ * contained in an image. This will be the case when the image is BL1 or when
+ * its BL3-1 and RESET_TO_BL31 is true. This constant enables a subsequent
+ * version of the reset handler to perform actions that override the ones
+ * performed in the first version of the code. This will be required when the
+ * first version exists in an un-modifiable image e.g. a BootROM image.
+ ******************************************************************************/
+#if IMAGE_BL1 || (IMAGE_BL31 && RESET_TO_BL31)
+#define FIRST_RESET_HANDLER_CALL
+#endif
+
+#ifndef __ASSEMBLY__
+#include <cdefs.h> /* For __dead2 */
+#include <cassert.h>
+#include <stdint.h>
+#include <stddef.h>
+
+/*******************************************************************************
+ * Structure used for telling the next BL how much of a particular type of
+ * memory is available for its use and how much is already used.
+ ******************************************************************************/
+typedef struct meminfo {
+	uint64_t total_base;
+	size_t total_size;
+	uint64_t free_base;
+	size_t free_size;
+} meminfo_t;
+
+typedef struct aapcs64_params {
+	unsigned long arg0;
+	unsigned long arg1;
+	unsigned long arg2;
+	unsigned long arg3;
+	unsigned long arg4;
+	unsigned long arg5;
+	unsigned long arg6;
+	unsigned long arg7;
+} aapcs64_params_t;
+
+/***************************************************************************
+ * This structure provides version information and the size of the
+ * structure, attributes for the structure it represents
+ ***************************************************************************/
+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;
+
+/*****************************************************************************
+ * This structure represents the superset of information needed while
+ * switching exception levels. The only two mechanisms to do so are
+ * ERET & SMC. Security state is indicated using bit zero of header
+ * attribute
+ * NOTE: BL1 expects entrypoint followed by spsr while processing
+ * SMC to jump to BL31 from the start of entry_point_info
+ *****************************************************************************/
+typedef struct entry_point_info {
+	param_header_t h;
+	uintptr_t pc;
+	uint32_t spsr;
+	aapcs64_params_t args;
+} entry_point_info_t;
+
+/*****************************************************************************
+ * Image info binary provides information from the image loader that
+ * can be used by the firmware to manage available trusted RAM.
+ * More advanced firmware image formats can provide additional
+ * information that enables optimization or greater flexibility in the
+ * common firmware code
+ *****************************************************************************/
+typedef struct image_info {
+	param_header_t h;
+	uintptr_t image_base;   /* physical address of base of image */
+	uint32_t image_size;    /* bytes read from image file */
+} image_info_t;
+
+/*******************************************************************************
+ * This structure represents the superset of information that can be passed to
+ * BL31 e.g. while passing control to it from BL2. The BL32 parameters will be
+ * populated only if BL2 detects its presence. A pointer to a structure of this
+ * type should be passed in X3 to BL31's cold boot entrypoint
+ *
+ * Use of this structure and the X3 parameter is not mandatory: the BL3-1
+ * platform code can use other mechanisms to provide the necessary information
+ * about BL3-2 and BL3-3 to the common and SPD code.
+ *
+ * BL3-1 image information is mandatory if this structure is used. If either of
+ * the optional BL3-2 and BL3-3 image information is not provided, this is
+ * indicated by the respective image_info pointers being zero.
+ ******************************************************************************/
+typedef struct bl31_params {
+	param_header_t h;
+	image_info_t *bl31_image_info;
+	entry_point_info_t *bl32_ep_info;
+	image_info_t *bl32_image_info;
+	entry_point_info_t *bl33_ep_info;
+	image_info_t *bl33_image_info;
+} bl31_params_t;
+
+
+/*
+ * Compile time assertions related to the 'entry_point_info' structure to
+ * ensure that the assembler and the compiler view of the offsets of
+ * the structure members is the same.
+ */
+CASSERT(ENTRY_POINT_INFO_PC_OFFSET ==
+		__builtin_offsetof(entry_point_info_t, pc), \
+		assert_BL31_pc_offset_mismatch);
+
+CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \
+		__builtin_offsetof(entry_point_info_t, args), \
+		assert_BL31_args_offset_mismatch);
+
+CASSERT(sizeof(unsigned long) ==
+		__builtin_offsetof(entry_point_info_t, spsr) - \
+		__builtin_offsetof(entry_point_info_t, pc), \
+		assert_entrypoint_and_spsr_should_be_adjacent);
+
+/*******************************************************************************
+ * Function & variable prototypes
+ ******************************************************************************/
+unsigned long page_align(unsigned long, unsigned);
+void change_security_state(unsigned int);
+unsigned long image_size(const char *);
+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);
+extern const char build_message[];
+extern const char version_string[];
+
+void reserve_mem(uint64_t *free_base, size_t *free_size,
+		uint64_t addr, size_t size);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __BL_COMMON_H__ */
diff --git a/uefi/arm-trusted-firmware/include/common/debug.h b/uefi/arm-trusted-firmware/include/common/debug.h
new file mode 100644
index 0000000..a8dcb8d
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/common/debug.h
@@ -0,0 +1,89 @@
+/*
+ * 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 __DEBUG_H__
+#define __DEBUG_H__
+
+#include <stdio.h>
+
+/* The log output macros print output to the console. These macros produce
+ * compiled log output only if the LOG_LEVEL defined in the makefile (or the
+ * make command line) is greater or equal than the level required for that
+ * type of log output.
+ * The format expected is the same as for printf(). For example:
+ * INFO("Info %s.\n", "message")    -> INFO:    Info message.
+ * WARN("Warning %s.\n", "message") -> WARNING: Warning message.
+ */
+
+#define LOG_LEVEL_NONE			0
+#define LOG_LEVEL_ERROR			10
+#define LOG_LEVEL_NOTICE		20
+#define LOG_LEVEL_WARNING		30
+#define LOG_LEVEL_INFO			40
+#define LOG_LEVEL_VERBOSE		50
+
+
+#if LOG_LEVEL >= LOG_LEVEL_NOTICE
+# define NOTICE(...)	tf_printf("NOTICE:  " __VA_ARGS__)
+#else
+# define NOTICE(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_ERROR
+# define ERROR(...)	tf_printf("ERROR:   " __VA_ARGS__)
+#else
+# define ERROR(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_WARNING
+# define WARN(...)	tf_printf("WARNING: " __VA_ARGS__)
+#else
+# define WARN(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+# define INFO(...)	tf_printf("INFO:    " __VA_ARGS__)
+#else
+# define INFO(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+# define VERBOSE(...)	tf_printf("VERBOSE: " __VA_ARGS__)
+#else
+# define VERBOSE(...)
+#endif
+
+
+void __dead2 do_panic(void);
+#define panic()	do_panic()
+
+void tf_printf(const char *fmt, ...);
+
+#endif /* __DEBUG_H__ */
diff --git a/uefi/arm-trusted-firmware/include/common/firmware_image_package.h b/uefi/arm-trusted-firmware/include/common/firmware_image_package.h
new file mode 100644
index 0000000..8fb669e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/common/firmware_image_package.h
@@ -0,0 +1,92 @@
+/*
+ * 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 __FIRMWARE_IMAGE_PACKAGE_H__
+#define __FIRMWARE_IMAGE_PACKAGE_H__
+
+#include <stdint.h>
+#include <uuid.h>
+
+/* This is used as a signature to validate the blob header */
+#define TOC_HEADER_NAME	0xAA640001
+
+
+/* ToC Entry UUIDs */
+#define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \
+	{0x0becf95f, 0x224d, 0x4d3e, 0xa5, 0x44, {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} }
+#define UUID_SCP_FIRMWARE_BL30 \
+	{0x3dfd6697, 0xbe89, 0x49e8, 0xae, 0x5d, {0x78, 0xa1, 0x40, 0x60, 0x82, 0x13} }
+#define UUID_EL3_RUNTIME_FIRMWARE_BL31 \
+	{0x6d08d447, 0xfe4c, 0x4698, 0x9b, 0x95, {0x29, 0x50, 0xcb, 0xbd, 0x5a, 0x00} }
+#define UUID_SECURE_PAYLOAD_BL32 \
+	{0x89e1d005, 0xdc53, 0x4713, 0x8d, 0x2b, {0x50, 0x0a, 0x4b, 0x7a, 0x3e, 0x38} }
+#define UUID_NON_TRUSTED_FIRMWARE_BL33 \
+	{0xa7eed0d6, 0xeafc, 0x4bd5, 0x97, 0x82, {0x99, 0x34, 0xf2, 0x34, 0xb6, 0xe4} }
+/* Key certificates */
+#define UUID_ROT_KEY_CERT \
+	{0x721d2d86, 0x60f8, 0x11e4, 0x92, 0x0b, {0x8b, 0xe7, 0x62, 0x16, 0x0f, 0x24} }
+#define UUID_TRUSTED_KEY_CERT \
+	{0x90e87e82, 0x60f8, 0x11e4, 0xa1, 0xb4, {0x77, 0x7a, 0x21, 0xb4, 0xf9, 0x4c} }
+#define UUID_NON_TRUSTED_WORLD_KEY_CERT \
+	{0x3d87671c, 0x635f, 0x11e4, 0x97, 0x8d, {0x27, 0xc0, 0xc7, 0x14, 0x8a, 0xbd} }
+#define UUID_SCP_FIRMWARE_BL30_KEY_CERT \
+	{0xa1214202, 0x60f8, 0x11e4, 0x8d, 0x9b, {0xf3, 0x3c, 0x0e, 0x15, 0xa0, 0x14} }
+#define UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT \
+	{0xccbeb88a, 0x60f9, 0x11e4, 0x9a, 0xd0, {0xeb, 0x48, 0x22, 0xd8, 0xdc, 0xf8} }
+#define UUID_SECURE_PAYLOAD_BL32_KEY_CERT \
+	{0x03d67794, 0x60fb, 0x11e4, 0x85, 0xdd, {0xb7, 0x10, 0x5b, 0x8c, 0xee, 0x04} }
+#define UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT \
+	{0x2a83d58a, 0x60fb, 0x11e4, 0x8a, 0xaf, {0xdf, 0x30, 0xbb, 0xc4, 0x98, 0x59} }
+/* Content certificates */
+#define UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT \
+	{0xea69e2d6, 0x635d, 0x11e4, 0x8d, 0x8c, {0x9f, 0xba, 0xbe, 0x99, 0x56, 0xa5} }
+#define UUID_SCP_FIRMWARE_BL30_CERT \
+	{0x046fbe44, 0x635e, 0x11e4, 0xb2, 0x8b, {0x73, 0xd8, 0xea, 0xae, 0x96, 0x56} }
+#define UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT \
+	{0x200cb2e2, 0x635e, 0x11e4, 0x9c, 0xe8, {0xab, 0xcc, 0xf9, 0x2b, 0xb6, 0x66} }
+#define UUID_SECURE_PAYLOAD_BL32_CERT \
+	{0x11449fa4, 0x635e, 0x11e4, 0x87, 0x28, {0x3f, 0x05, 0x72, 0x2a, 0xf3, 0x3d} }
+#define UUID_NON_TRUSTED_FIRMWARE_BL33_CERT \
+	{0xf3c1c48e, 0x635d, 0x11e4, 0xa7, 0xa9, {0x87, 0xee, 0x40, 0xb2, 0x3f, 0xa7} }
+
+typedef struct fip_toc_header {
+	uint32_t	name;
+	uint32_t	serial_number;
+	uint64_t	flags;
+} fip_toc_header_t;
+
+typedef struct fip_toc_entry {
+	uuid_t		uuid;
+	uint64_t	offset_address;
+	uint64_t	size;
+	uint64_t	flags;
+} fip_toc_entry_t;
+
+#endif /* __FIRMWARE_IMAGE_PACKAGE_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/arm/arm_gic.h b/uefi/arm-trusted-firmware/include/drivers/arm/arm_gic.h
new file mode 100644
index 0000000..9ab1a95
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/arm/arm_gic.h
@@ -0,0 +1,57 @@
+/*
+ * 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 __ARM_GIC_H__
+#define __ARM_GIC_H__
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * Function declarations
+ ******************************************************************************/
+void arm_gic_init(unsigned int gicc_base,
+		unsigned int gicd_base,
+		unsigned long gicr_base,
+		const unsigned int *irq_sec_ptr,
+		unsigned int num_irqs);
+void arm_gic_setup(void);
+void arm_gic_cpuif_deactivate(void);
+void arm_gic_cpuif_setup(void);
+void arm_gic_pcpu_distif_setup(void);
+
+uint32_t arm_gic_interrupt_type_to_line(uint32_t type,
+				uint32_t security_state);
+uint32_t arm_gic_get_pending_interrupt_type(void);
+uint32_t arm_gic_get_pending_interrupt_id(void);
+uint32_t arm_gic_acknowledge_interrupt(void);
+void arm_gic_end_of_interrupt(uint32_t id);
+uint32_t arm_gic_get_interrupt_type(uint32_t id);
+
+#endif /* __GIC_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/arm/cci400.h b/uefi/arm-trusted-firmware/include/drivers/arm/cci400.h
new file mode 100644
index 0000000..7756bdf
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/arm/cci400.h
@@ -0,0 +1,90 @@
+/*
+ * 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 __CCI_400_H__
+#define __CCI_400_H__
+
+/* Slave interface offsets from PERIPHBASE */
+#define SLAVE_IFACE4_OFFSET		0x5000
+#define SLAVE_IFACE3_OFFSET		0x4000
+#define SLAVE_IFACE2_OFFSET		0x3000
+#define SLAVE_IFACE1_OFFSET		0x2000
+#define SLAVE_IFACE0_OFFSET		0x1000
+#define SLAVE_IFACE_OFFSET(index)	SLAVE_IFACE0_OFFSET +	\
+					(0x1000 * (index))
+
+/* Control and ID register offsets */
+#define CTRL_OVERRIDE_REG		0x0
+#define SPEC_CTRL_REG			0x4
+#define SECURE_ACCESS_REG		0x8
+#define STATUS_REG			0xc
+#define IMPRECISE_ERR_REG		0x10
+#define PERFMON_CTRL_REG		0x100
+
+/* Slave interface register offsets */
+#define SNOOP_CTRL_REG			0x0
+#define SH_OVERRIDE_REG			0x4
+#define READ_CHNL_QOS_VAL_OVERRIDE_REG	0x100
+#define WRITE_CHNL_QOS_VAL_OVERRIDE_REG	0x104
+#define QOS_CTRL_REG			0x10c
+#define MAX_OT_REG			0x110
+#define TARGET_LATENCY_REG		0x130
+#define LATENCY_REGULATION_REG		0x134
+#define QOS_RANGE_REG			0x138
+
+/* Snoop Control register bit definitions */
+#define DVM_EN_BIT			(1 << 1)
+#define SNOOP_EN_BIT			(1 << 0)
+
+/* Status register bit definitions */
+#define CHANGE_PENDING_BIT		(1 << 0)
+
+#ifndef __ASSEMBLY__
+
+/* Function declarations */
+
+/*
+ * The CCI-400 driver must be initialized with the base address of the
+ * CCI-400 device in the platform memory map, and the cluster indices for
+ * the CCI-400 slave interfaces 3 and 4 respectively. These are the fully
+ * coherent ACE slave interfaces of CCI-400.
+ * The cluster indices must either be 0 or 1, corresponding to the level 1
+ * affinity instance of the mpidr representing the cluster. A negative cluster
+ * index indicates that no cluster is present on that slave interface.
+ */
+void cci_init(unsigned long cci_base,
+		int slave_iface3_cluster_ix,
+		int slave_iface4_cluster_ix);
+
+void cci_enable_cluster_coherency(unsigned long mpidr);
+void cci_disable_cluster_coherency(unsigned long mpidr);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __CCI_400_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/arm/gic_v2.h b/uefi/arm-trusted-firmware/include/drivers/arm/gic_v2.h
new file mode 100644
index 0000000..a2d3eee
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/arm/gic_v2.h
@@ -0,0 +1,321 @@
+/*
+ * 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 __GIC_V2_H__
+#define __GIC_V2_H__
+
+
+#define GIC400_NUM_SPIS		480
+#define MAX_PPIS		14
+#define MAX_SGIS		16
+
+#define MIN_SGI_ID		0
+#define MIN_PPI_ID		16
+#define MIN_SPI_ID		32
+
+#define GRP0			0
+#define GRP1			1
+#define GIC_PRI_MASK		0xff
+#define GIC_HIGHEST_SEC_PRIORITY 0
+#define GIC_LOWEST_SEC_PRIORITY	127
+#define GIC_HIGHEST_NS_PRIORITY	128
+#define GIC_LOWEST_NS_PRIORITY	254 /* 255 would disable an interrupt */
+#define GIC_SPURIOUS_INTERRUPT	1023
+#define GIC_TARGET_CPU_MASK	0xff
+
+#define ENABLE_GRP0		(1 << 0)
+#define ENABLE_GRP1		(1 << 1)
+
+/* Distributor interface definitions */
+#define GICD_CTLR		0x0
+#define GICD_TYPER		0x4
+#define GICD_IGROUPR		0x80
+#define GICD_ISENABLER		0x100
+#define GICD_ICENABLER		0x180
+#define GICD_ISPENDR		0x200
+#define GICD_ICPENDR		0x280
+#define GICD_ISACTIVER		0x300
+#define GICD_ICACTIVER		0x380
+#define GICD_IPRIORITYR		0x400
+#define GICD_ITARGETSR		0x800
+#define GICD_ICFGR		0xC00
+#define GICD_SGIR		0xF00
+#define GICD_CPENDSGIR		0xF10
+#define GICD_SPENDSGIR		0xF20
+
+#define IGROUPR_SHIFT		5
+#define ISENABLER_SHIFT		5
+#define ICENABLER_SHIFT		ISENABLER_SHIFT
+#define ISPENDR_SHIFT		5
+#define ICPENDR_SHIFT		ISPENDR_SHIFT
+#define ISACTIVER_SHIFT		5
+#define ICACTIVER_SHIFT		ISACTIVER_SHIFT
+#define IPRIORITYR_SHIFT	2
+#define ITARGETSR_SHIFT		2
+#define ICFGR_SHIFT		4
+#define CPENDSGIR_SHIFT		2
+#define SPENDSGIR_SHIFT		CPENDSGIR_SHIFT
+
+/* GICD_TYPER bit definitions */
+#define IT_LINES_NO_MASK	0x1f
+
+/* Physical CPU Interface registers */
+#define GICC_CTLR		0x0
+#define GICC_PMR		0x4
+#define GICC_BPR		0x8
+#define GICC_IAR		0xC
+#define GICC_EOIR		0x10
+#define GICC_RPR		0x14
+#define GICC_HPPIR		0x18
+#define GICC_AHPPIR		0x28
+#define GICC_IIDR		0xFC
+#define GICC_DIR		0x1000
+#define GICC_PRIODROP           GICC_EOIR
+
+/* GICC_CTLR bit definitions */
+#define EOI_MODE_NS		(1 << 10)
+#define EOI_MODE_S		(1 << 9)
+#define IRQ_BYP_DIS_GRP1	(1 << 8)
+#define FIQ_BYP_DIS_GRP1	(1 << 7)
+#define IRQ_BYP_DIS_GRP0	(1 << 6)
+#define FIQ_BYP_DIS_GRP0	(1 << 5)
+#define CBPR			(1 << 4)
+#define FIQ_EN			(1 << 3)
+#define ACK_CTL			(1 << 2)
+
+/* GICC_IIDR bit masks and shifts */
+#define GICC_IIDR_PID_SHIFT	20
+#define GICC_IIDR_ARCH_SHIFT	16
+#define GICC_IIDR_REV_SHIFT	12
+#define GICC_IIDR_IMP_SHIFT	0
+
+#define GICC_IIDR_PID_MASK	0xfff
+#define GICC_IIDR_ARCH_MASK	0xf
+#define GICC_IIDR_REV_MASK	0xf
+#define GICC_IIDR_IMP_MASK	0xfff
+
+/* HYP view virtual CPU Interface registers */
+#define GICH_CTL		0x0
+#define GICH_VTR		0x4
+#define GICH_ELRSR0		0x30
+#define GICH_ELRSR1		0x34
+#define GICH_APR0		0xF0
+#define GICH_LR_BASE		0x100
+
+/* Virtual CPU Interface registers */
+#define GICV_CTL		0x0
+#define GICV_PRIMASK		0x4
+#define GICV_BP			0x8
+#define GICV_INTACK		0xC
+#define GICV_EOI		0x10
+#define GICV_RUNNINGPRI		0x14
+#define GICV_HIGHESTPEND	0x18
+#define GICV_DEACTIVATE		0x1000
+
+#ifndef __ASSEMBLY__
+
+#include <mmio.h>
+
+
+/*******************************************************************************
+ * GIC Distributor function prototypes
+ ******************************************************************************/
+
+unsigned int gicd_read_igroupr(unsigned int, unsigned int);
+unsigned int gicd_read_isenabler(unsigned int, unsigned int);
+unsigned int gicd_read_icenabler(unsigned int, unsigned int);
+unsigned int gicd_read_ispendr(unsigned int, unsigned int);
+unsigned int gicd_read_icpendr(unsigned int, unsigned int);
+unsigned int gicd_read_isactiver(unsigned int, unsigned int);
+unsigned int gicd_read_icactiver(unsigned int, unsigned int);
+unsigned int gicd_read_ipriorityr(unsigned int, unsigned int);
+unsigned int gicd_read_itargetsr(unsigned int, unsigned int);
+unsigned int gicd_read_icfgr(unsigned int, unsigned int);
+unsigned int gicd_read_cpendsgir(unsigned int, unsigned int);
+unsigned int gicd_read_spendsgir(unsigned int, unsigned int);
+void gicd_write_igroupr(unsigned int, unsigned int, unsigned int);
+void gicd_write_isenabler(unsigned int, unsigned int, unsigned int);
+void gicd_write_icenabler(unsigned int, unsigned int, unsigned int);
+void gicd_write_ispendr(unsigned int, unsigned int, unsigned int);
+void gicd_write_icpendr(unsigned int, unsigned int, unsigned int);
+void gicd_write_isactiver(unsigned int, unsigned int, unsigned int);
+void gicd_write_icactiver(unsigned int, unsigned int, unsigned int);
+void gicd_write_ipriorityr(unsigned int, unsigned int, unsigned int);
+void gicd_write_itargetsr(unsigned int, unsigned int, unsigned int);
+void gicd_write_icfgr(unsigned int, unsigned int, unsigned int);
+void gicd_write_cpendsgir(unsigned int, unsigned int, unsigned int);
+void gicd_write_spendsgir(unsigned int, unsigned int, unsigned int);
+unsigned int gicd_get_igroupr(unsigned int, unsigned int);
+void gicd_set_igroupr(unsigned int, unsigned int);
+void gicd_clr_igroupr(unsigned int, unsigned int);
+void gicd_set_isenabler(unsigned int, unsigned int);
+void gicd_set_icenabler(unsigned int, unsigned int);
+void gicd_set_ispendr(unsigned int, unsigned int);
+void gicd_set_icpendr(unsigned int, unsigned int);
+void gicd_set_isactiver(unsigned int, unsigned int);
+void gicd_set_icactiver(unsigned int, unsigned int);
+void gicd_set_ipriorityr(unsigned int, unsigned int, unsigned int);
+void gicd_set_itargetsr(unsigned int, unsigned int, unsigned int);
+
+
+/*******************************************************************************
+ * GIC Distributor interface accessors for reading entire registers
+ ******************************************************************************/
+
+static inline unsigned int gicd_read_ctlr(unsigned int base)
+{
+	return mmio_read_32(base + GICD_CTLR);
+}
+
+static inline unsigned int gicd_read_typer(unsigned int base)
+{
+	return mmio_read_32(base + GICD_TYPER);
+}
+
+static inline unsigned int gicd_read_sgir(unsigned int base)
+{
+	return mmio_read_32(base + GICD_SGIR);
+}
+
+
+/*******************************************************************************
+ * GIC Distributor interface accessors for writing entire registers
+ ******************************************************************************/
+
+static inline void gicd_write_ctlr(unsigned int base, unsigned int val)
+{
+	mmio_write_32(base + GICD_CTLR, val);
+}
+
+static inline void gicd_write_sgir(unsigned int base, unsigned int val)
+{
+	mmio_write_32(base + GICD_SGIR, val);
+}
+
+
+/*******************************************************************************
+ * GIC CPU interface accessors for reading entire registers
+ ******************************************************************************/
+
+static inline unsigned int gicc_read_ctlr(unsigned int base)
+{
+	return mmio_read_32(base + GICC_CTLR);
+}
+
+static inline unsigned int gicc_read_pmr(unsigned int base)
+{
+	return mmio_read_32(base + GICC_PMR);
+}
+
+static inline unsigned int gicc_read_BPR(unsigned int base)
+{
+	return mmio_read_32(base + GICC_BPR);
+}
+
+static inline unsigned int gicc_read_IAR(unsigned int base)
+{
+	return mmio_read_32(base + GICC_IAR);
+}
+
+static inline unsigned int gicc_read_EOIR(unsigned int base)
+{
+	return mmio_read_32(base + GICC_EOIR);
+}
+
+static inline unsigned int gicc_read_hppir(unsigned int base)
+{
+	return mmio_read_32(base + GICC_HPPIR);
+}
+
+static inline unsigned int gicc_read_ahppir(unsigned int base)
+{
+	return mmio_read_32(base + GICC_AHPPIR);
+}
+
+static inline unsigned int gicc_read_dir(unsigned int base)
+{
+	return mmio_read_32(base + GICC_DIR);
+}
+
+static inline unsigned int gicc_read_iidr(unsigned int base)
+{
+	return mmio_read_32(base + GICC_IIDR);
+}
+
+
+/*******************************************************************************
+ * GIC CPU interface accessors for writing entire registers
+ ******************************************************************************/
+
+static inline void gicc_write_ctlr(unsigned int base, unsigned int val)
+{
+	mmio_write_32(base + GICC_CTLR, val);
+}
+
+static inline void gicc_write_pmr(unsigned int base, unsigned int val)
+{
+	mmio_write_32(base + GICC_PMR, val);
+}
+
+static inline void gicc_write_BPR(unsigned int base, unsigned int val)
+{
+	mmio_write_32(base + GICC_BPR, val);
+}
+
+
+static inline void gicc_write_IAR(unsigned int base, unsigned int val)
+{
+	mmio_write_32(base + GICC_IAR, val);
+}
+
+static inline void gicc_write_EOIR(unsigned int base, unsigned int val)
+{
+	mmio_write_32(base + GICC_EOIR, val);
+}
+
+static inline void gicc_write_hppir(unsigned int base, unsigned int val)
+{
+	mmio_write_32(base + GICC_HPPIR, val);
+}
+
+static inline void gicc_write_dir(unsigned int base, unsigned int val)
+{
+	mmio_write_32(base + GICC_DIR, val);
+}
+
+/*******************************************************************************
+ * Prototype of function to map an interrupt type to the interrupt line used to
+ * signal it.
+ ******************************************************************************/
+uint32_t gicv2_interrupt_type_to_line(uint32_t cpuif_base, uint32_t type);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __GIC_V2_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/arm/gic_v3.h b/uefi/arm-trusted-firmware/include/drivers/arm/gic_v3.h
new file mode 100644
index 0000000..c410626
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/arm/gic_v3.h
@@ -0,0 +1,90 @@
+/*
+ * 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 __GIC_V3_H__
+#define __GIC_V3_H__
+
+#include <mmio.h>
+#include <stdint.h>
+
+
+/* GICv3 Re-distributor interface registers & shifts */
+#define GICR_PCPUBASE_SHIFT	0x11
+#define GICR_TYPER		0x08
+#define GICR_WAKER		0x14
+
+/* GICR_WAKER bit definitions */
+#define WAKER_CA		(1UL << 2)
+#define WAKER_PS		(1UL << 1)
+
+/* GICR_TYPER bit definitions */
+#define GICR_TYPER_AFF_SHIFT	32
+#define GICR_TYPER_AFF_MASK	0xffffffff
+#define GICR_TYPER_LAST		(1UL << 4)
+
+/* GICv3 ICC_SRE register bit definitions*/
+#define ICC_SRE_EN		(1UL << 3)
+#define ICC_SRE_SRE		(1UL << 0)
+
+/*******************************************************************************
+ * GICv3 defintions
+ ******************************************************************************/
+#define GICV3_AFFLVL_MASK	0xff
+#define GICV3_AFF0_SHIFT	0
+#define GICV3_AFF1_SHIFT	8
+#define GICV3_AFF2_SHIFT	16
+#define GICV3_AFF3_SHIFT	24
+#define GICV3_AFFINITY_MASK	0xffffffff
+
+/*******************************************************************************
+ * Function prototypes
+ ******************************************************************************/
+uintptr_t gicv3_get_rdist(uintptr_t gicr_base, uint64_t mpidr);
+
+/*******************************************************************************
+ * GIC Redistributor interface accessors
+ ******************************************************************************/
+static inline uint32_t gicr_read_waker(uintptr_t base)
+{
+	return mmio_read_32(base + GICR_WAKER);
+}
+
+static inline void gicr_write_waker(uintptr_t base, uint32_t val)
+{
+	mmio_write_32(base + GICR_WAKER, val);
+}
+
+static inline uint64_t gicr_read_typer(uintptr_t base)
+{
+	return mmio_read_64(base + GICR_TYPER);
+}
+
+
+#endif /* __GIC_V3_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/arm/gpio.h b/uefi/arm-trusted-firmware/include/drivers/arm/gpio.h
new file mode 100644
index 0000000..06a41ad
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/arm/gpio.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __GPIO_H__
+#define __GPIO_H__
+
+extern int gpio_direction_input(unsigned int gpio);
+extern int gpio_direction_output(unsigned int gpio);
+extern int gpio_get_value(unsigned int gpio);
+extern int gpio_set_value(unsigned int gpio, unsigned int value);
+extern int gpio_register_device(unsigned int base);
+
+#endif	/* __GPIO_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/arm/pl011.h b/uefi/arm-trusted-firmware/include/drivers/arm/pl011.h
new file mode 100644
index 0000000..7c4df62
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/arm/pl011.h
@@ -0,0 +1,98 @@
+/*
+ * 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 __PL011_H__
+#define __PL011_H__
+
+/* PL011 Registers */
+#define UARTDR                    0x000
+#define UARTRSR                   0x004
+#define UARTECR                   0x004
+#define UARTFR                    0x018
+#define UARTILPR                  0x020
+#define UARTIBRD                  0x024
+#define UARTFBRD                  0x028
+#define UARTLCR_H                 0x02C
+#define UARTCR                    0x030
+#define UARTIFLS                  0x034
+#define UARTIMSC                  0x038
+#define UARTRIS                   0x03C
+#define UARTMIS                   0x040
+#define UARTICR                   0x044
+#define UARTDMACR                 0x048
+
+/* Data status bits */
+#define UART_DATA_ERROR_MASK      0x0F00
+
+/* Status reg bits */
+#define UART_STATUS_ERROR_MASK    0x0F
+
+/* Flag reg bits */
+#define PL011_UARTFR_RI           (1 << 8)	/* Ring indicator */
+#define PL011_UARTFR_TXFE         (1 << 7)	/* Transmit FIFO empty */
+#define PL011_UARTFR_RXFF         (1 << 6)	/* Receive  FIFO full */
+#define PL011_UARTFR_TXFF         (1 << 5)	/* Transmit FIFO full */
+#define PL011_UARTFR_RXFE         (1 << 4)	/* Receive  FIFO empty */
+#define PL011_UARTFR_BUSY         (1 << 3)	/* UART busy */
+#define PL011_UARTFR_DCD          (1 << 2)	/* Data carrier detect */
+#define PL011_UARTFR_DSR          (1 << 1)	/* Data set ready */
+#define PL011_UARTFR_CTS          (1 << 0)	/* Clear to send */
+
+#define PL011_UARTFR_TXFF_BIT	5	/* Transmit FIFO full bit in UARTFR register */
+#define PL011_UARTFR_RXFE_BIT	4	/* Receive FIFO empty bit in UARTFR register */
+
+/* Control reg bits */
+#define PL011_UARTCR_CTSEN        (1 << 15)	/* CTS hardware flow control enable */
+#define PL011_UARTCR_RTSEN        (1 << 14)	/* RTS hardware flow control enable */
+#define PL011_UARTCR_RTS          (1 << 11)	/* Request to send */
+#define PL011_UARTCR_DTR          (1 << 10)	/* Data transmit ready. */
+#define PL011_UARTCR_RXE          (1 << 9)	/* Receive enable */
+#define PL011_UARTCR_TXE          (1 << 8)	/* Transmit enable */
+#define PL011_UARTCR_LBE          (1 << 7)	/* Loopback enable */
+#define PL011_UARTCR_UARTEN       (1 << 0)	/* UART Enable */
+
+#if !defined(PL011_LINE_CONTROL)
+/* FIFO Enabled / No Parity / 8 Data bit / One Stop Bit */
+#define PL011_LINE_CONTROL  (PL011_UARTLCR_H_FEN | PL011_UARTLCR_H_WLEN_8)
+#endif
+
+/* Line Control Register Bits */
+#define PL011_UARTLCR_H_SPS       (1 << 7)	/* Stick parity select */
+#define PL011_UARTLCR_H_WLEN_8    (3 << 5)
+#define PL011_UARTLCR_H_WLEN_7    (2 << 5)
+#define PL011_UARTLCR_H_WLEN_6    (1 << 5)
+#define PL011_UARTLCR_H_WLEN_5    (0 << 5)
+#define PL011_UARTLCR_H_FEN       (1 << 4)	/* FIFOs Enable */
+#define PL011_UARTLCR_H_STP2      (1 << 3)	/* Two stop bits select */
+#define PL011_UARTLCR_H_EPS       (1 << 2)	/* Even parity select */
+#define PL011_UARTLCR_H_PEN       (1 << 1)	/* Parity Enable */
+#define PL011_UARTLCR_H_BRK       (1 << 0)	/* Send break */
+
+#endif	/* __PL011_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/arm/tzc400.h b/uefi/arm-trusted-firmware/include/drivers/arm/tzc400.h
new file mode 100644
index 0000000..d62e67b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/arm/tzc400.h
@@ -0,0 +1,201 @@
+/*
+ * 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 __TZC400_H__
+#define __TZC400_H__
+
+#include <stdint.h>
+
+#define BUILD_CONFIG_OFF	0x000
+#define ACTION_OFF		0x004
+#define GATE_KEEPER_OFF		0x008
+#define SPECULATION_CTRL_OFF	0x00c
+#define INT_STATUS		0x010
+#define INT_CLEAR		0x014
+
+#define FAIL_ADDRESS_LOW_OFF	0x020
+#define FAIL_ADDRESS_HIGH_OFF	0x024
+#define FAIL_CONTROL_OFF	0x028
+#define FAIL_ID			0x02c
+
+#define REGION_BASE_LOW_OFF	0x100
+#define REGION_BASE_HIGH_OFF	0x104
+#define REGION_TOP_LOW_OFF	0x108
+#define REGION_TOP_HIGH_OFF	0x10c
+#define REGION_ATTRIBUTES_OFF	0x110
+#define REGION_ID_ACCESS_OFF	0x114
+#define REGION_NUM_OFF(region)  (0x20 * region)
+
+/* ID Registers */
+#define PID0_OFF		0xfe0
+#define PID1_OFF		0xfe4
+#define PID2_OFF		0xfe8
+#define PID3_OFF		0xfec
+#define PID4_OFF		0xfd0
+#define PID5_OFF		0xfd4
+#define PID6_OFF		0xfd8
+#define PID7_OFF		0xfdc
+#define CID0_OFF		0xff0
+#define CID1_OFF		0xff4
+#define CID2_OFF		0xff8
+#define CID3_OFF		0xffc
+
+#define BUILD_CONFIG_NF_SHIFT	24
+#define BUILD_CONFIG_NF_MASK	0x3
+#define BUILD_CONFIG_AW_SHIFT	8
+#define BUILD_CONFIG_AW_MASK	0x3f
+#define BUILD_CONFIG_NR_SHIFT	0
+#define BUILD_CONFIG_NR_MASK	0x1f
+
+/* Not describing the case where regions 1 to 8 overlap */
+#define ACTION_RV_SHIFT		0
+#define ACTION_RV_MASK		0x3
+#define  ACTION_RV_LOWOK	0x0
+#define  ACTION_RV_LOWERR	0x1
+#define  ACTION_RV_HIGHOK	0x2
+#define  ACTION_RV_HIGHERR	0x3
+
+/*
+ * Number of gate keepers is implementation defined. But we know the max for
+ * this device is 4. Get implementation details from BUILD_CONFIG.
+ */
+#define GATE_KEEPER_OS_SHIFT	16
+#define GATE_KEEPER_OS_MASK	0xf
+#define GATE_KEEPER_OR_SHIFT	0
+#define GATE_KEEPER_OR_MASK	0xf
+#define GATE_KEEPER_FILTER_MASK	0x1
+
+/* Speculation is enabled by default. */
+#define SPECULATION_CTRL_WRITE_DISABLE	(1 << 1)
+#define SPECULATION_CTRL_READ_DISABLE	(1 << 0)
+
+/* Max number of filters allowed is 4. */
+#define INT_STATUS_OVERLAP_SHIFT	16
+#define INT_STATUS_OVERLAP_MASK		0xf
+#define INT_STATUS_OVERRUN_SHIFT	8
+#define INT_STATUS_OVERRUN_MASK		0xf
+#define INT_STATUS_STATUS_SHIFT		0
+#define INT_STATUS_STATUS_MASK		0xf
+
+#define INT_CLEAR_CLEAR_SHIFT		0
+#define INT_CLEAR_CLEAR_MASK		0xf
+
+#define FAIL_CONTROL_DIR_SHIFT		(1 << 24)
+#define  FAIL_CONTROL_DIR_READ		0x0
+#define  FAIL_CONTROL_DIR_WRITE		0x1
+#define FAIL_CONTROL_NS_SHIFT		(1 << 21)
+#define  FAIL_CONTROL_NS_SECURE		0x0
+#define  FAIL_CONTROL_NS_NONSECURE	0x1
+#define FAIL_CONTROL_PRIV_SHIFT		(1 << 20)
+#define  FAIL_CONTROL_PRIV_PRIV		0x0
+#define  FAIL_CONTROL_PRIV_UNPRIV	0x1
+
+/*
+ * FAIL_ID_ID_MASK depends on AID_WIDTH which is platform specific.
+ * Platform should provide the value on initialisation.
+ */
+#define FAIL_ID_VNET_SHIFT		24
+#define FAIL_ID_VNET_MASK		0xf
+#define FAIL_ID_ID_SHIFT		0
+
+/* Used along with 'tzc_region_attributes_t' below */
+#define REG_ATTR_SEC_SHIFT		30
+#define REG_ATTR_F_EN_SHIFT		0
+#define REG_ATTR_F_EN_MASK		0xf
+#define REG_ATTR_FILTER_BIT(x)		((1 << x) << REG_ATTR_F_EN_SHIFT)
+#define REG_ATTR_FILTER_BIT_ALL		(REG_ATTR_F_EN_MASK << \
+					REG_ATTR_F_EN_SHIFT)
+
+#define REGION_ID_ACCESS_NSAID_WR_EN_SHIFT	16
+#define REGION_ID_ACCESS_NSAID_RD_EN_SHIFT	0
+#define REGION_ID_ACCESS_NSAID_ID_MASK		0xf
+
+
+/* Macros for setting Region ID access permissions based on NSAID */
+#define TZC_REGION_ACCESS_RD(id)					\
+		((1 << (id & REGION_ID_ACCESS_NSAID_ID_MASK)) <<	\
+		 REGION_ID_ACCESS_NSAID_RD_EN_SHIFT)
+#define TZC_REGION_ACCESS_WR(id)					\
+		((1 << (id & REGION_ID_ACCESS_NSAID_ID_MASK)) <<	\
+		 REGION_ID_ACCESS_NSAID_WR_EN_SHIFT)
+#define TZC_REGION_ACCESS_RDWR(id)					\
+		(TZC_REGION_ACCESS_RD(id) | TZC_REGION_ACCESS_WR(id))
+
+/* Filters are bit mapped 0 to 3. */
+#define TZC400_COMPONENT_ID	0xb105f00d
+
+/*******************************************************************************
+ * Function & variable prototypes
+ ******************************************************************************/
+
+/*
+ * What type of action is expected when an access violation occurs.
+ * The memory requested is zeroed. But we can also raise and event to
+ * let the system know it happened.
+ * We can raise an interrupt(INT) and/or cause an exception(ERR).
+ *  TZC_ACTION_NONE    - No interrupt, no Exception
+ *  TZC_ACTION_ERR     - No interrupt, raise exception -> sync external
+ *                       data abort
+ *  TZC_ACTION_INT     - Raise interrupt, no exception
+ *  TZC_ACTION_ERR_INT - Raise interrupt, raise exception -> sync
+ *                       external data abort
+ */
+typedef enum {
+	TZC_ACTION_NONE = 0,
+	TZC_ACTION_ERR = 1,
+	TZC_ACTION_INT = 2,
+	TZC_ACTION_ERR_INT = (TZC_ACTION_ERR | TZC_ACTION_INT)
+} tzc_action_t;
+
+/*
+ * Controls secure access to a region. If not enabled secure access is not
+ * allowed to region.
+ */
+typedef enum {
+	TZC_REGION_S_NONE = 0,
+	TZC_REGION_S_RD = 1,
+	TZC_REGION_S_WR = 2,
+	TZC_REGION_S_RDWR = (TZC_REGION_S_RD | TZC_REGION_S_WR)
+} tzc_region_attributes_t;
+
+
+void tzc_init(uint64_t base);
+void tzc_configure_region(uint32_t filters,
+			uint8_t region,
+			uint64_t region_base,
+			uint64_t region_top,
+			tzc_region_attributes_t sec_attr,
+			uint32_t ns_device_access);
+void tzc_enable_filters(void);
+void tzc_disable_filters(void);
+void tzc_set_action(tzc_action_t action);
+
+
+#endif /* __TZC400__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/console.h b/uefi/arm-trusted-firmware/include/drivers/console.h
new file mode 100644
index 0000000..f144ab9
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/console.h
@@ -0,0 +1,40 @@
+/*
+ * 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 __CONSOLE_H__
+#define __CONSOLE_H__
+
+int console_init(unsigned long base_addr,
+		unsigned int uart_clk, unsigned int baud_rate);
+int console_putc(int c);
+int console_getc(void);
+
+#endif /* __CONSOLE_H__ */
+
diff --git a/uefi/arm-trusted-firmware/include/drivers/fastboot.h b/uefi/arm-trusted-firmware/include/drivers/fastboot.h
new file mode 100644
index 0000000..d5bf965
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/fastboot.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, Linaro Ltd. 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 __FASTBOOT_H__
+#define __FASTBOOT_H__
+
+#include <sys/types.h>
+
+typedef struct sparse_header {
+	uint32_t	magic;
+	uint16_t	major_version;
+	uint16_t	minor_version;
+	uint16_t	file_hdr_sz;
+	uint16_t	chunk_hdr_sz;
+	uint32_t	blk_sz;
+	uint32_t	total_blks;
+	uint32_t	total_chunks;
+	uint32_t	image_checksum;
+} sparse_header_t;
+
+#define SPARSE_HEADER_MAGIC	0xed26ff3a
+
+#define CHUNK_TYPE_RAW		0xCAC1
+#define CHUNK_TYPE_FILL		0xCAC2
+#define CHUNK_TYPE_DONT_CARE	0xCAC3
+#define CHUNK_TYPE_CRC32	0xCAC4
+
+typedef struct chunk_header {
+	uint16_t	chunk_type;     /* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */
+	uint16_t	reserved1;
+	uint32_t	chunk_sz;       /* in blocks in output image */
+	uint32_t	total_sz;       /* in bytes of chunk input file including chunk header and data */
+} chunk_header_t;
+
+#endif /* __FASTBOOT_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/io/io_block.h b/uefi/arm-trusted-firmware/include/drivers/io/io_block.h
new file mode 100644
index 0000000..a0a8558
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/io/io_block.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __IO_BLOCK_H__
+#define __IO_BLOCK_H__
+
+struct io_dev_connector;
+
+struct block_ops {
+	int	(*init)(void);
+	int	(*read)(unsigned long, unsigned long, size_t, uint32_t);
+	int	(*write)(unsigned long, unsigned long, size_t, uint32_t);
+};
+
+int register_io_dev_block(const struct io_dev_connector **dev_con);
+
+#endif /* __IO_BLOCK_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/io/io_driver.h b/uefi/arm-trusted-firmware/include/drivers/io/io_driver.h
new file mode 100644
index 0000000..adb38b0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/io/io_driver.h
@@ -0,0 +1,83 @@
+/*
+ * 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 __IO_DRIVER_H__
+#define __IO_DRIVER_H__
+
+#include <io_storage.h>
+#include <stdint.h>
+
+
+/* Generic IO entity structure,representing an accessible IO construct on the
+ * device, such as a file */
+typedef struct io_entity {
+	struct io_dev_info *dev_handle;
+	uintptr_t info;
+} io_entity_t;
+
+
+/* Device info structure, providing device-specific functions and a means of
+ * adding driver-specific state */
+typedef struct io_dev_info {
+	const struct io_dev_funcs *funcs;
+	uintptr_t info;
+} io_dev_info_t;
+
+
+/* Structure used to create a connection to a type of device */
+typedef struct io_dev_connector {
+	/* dev_open opens a connection to a particular device driver */
+	int (*dev_open)(const uintptr_t dev_spec, io_dev_info_t **dev_info);
+} io_dev_connector_t;
+
+
+/* Structure to hold device driver function pointers */
+typedef struct io_dev_funcs {
+	io_type_t (*type)(void);
+	int (*open)(io_dev_info_t *dev_info, const uintptr_t spec,
+			io_entity_t *entity);
+	int (*seek)(io_entity_t *entity, int mode, ssize_t offset);
+	int (*size)(io_entity_t *entity, size_t *length);
+	int (*read)(io_entity_t *entity, uintptr_t buffer, size_t length,
+			size_t *length_read);
+	int (*write)(io_entity_t *entity, const uintptr_t buffer,
+			size_t length, size_t *length_written);
+	int (*close)(io_entity_t *entity);
+	int (*dev_init)(io_dev_info_t *dev_info, const uintptr_t init_params);
+	int (*dev_close)(io_dev_info_t *dev_info);
+} io_dev_funcs_t;
+
+
+/* Operations intended to be performed during platform initialisation */
+
+/* Register an IO device */
+int io_register_device(const io_dev_info_t *dev_info);
+
+#endif  /* __IO_DRIVER_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/io/io_fip.h b/uefi/arm-trusted-firmware/include/drivers/io/io_fip.h
new file mode 100644
index 0000000..90b2fd0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/io/io_fip.h
@@ -0,0 +1,38 @@
+/*
+ * 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 __IO_FIP_H__
+#define __IO_FIP_H__
+
+struct io_dev_connector;
+
+int register_io_dev_fip(const struct io_dev_connector **dev_con);
+
+#endif /* __IO_FIP_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/io/io_memmap.h b/uefi/arm-trusted-firmware/include/drivers/io/io_memmap.h
new file mode 100644
index 0000000..7ee60fe
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/io/io_memmap.h
@@ -0,0 +1,38 @@
+/*
+ * 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 __IO_MEMMAP_H__
+#define __IO_MEMMAP_H__
+
+struct io_dev_connector;
+
+int register_io_dev_memmap(const struct io_dev_connector **dev_con);
+
+#endif /* __IO_MEMMAP_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/io/io_semihosting.h b/uefi/arm-trusted-firmware/include/drivers/io/io_semihosting.h
new file mode 100644
index 0000000..8902a6f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/io/io_semihosting.h
@@ -0,0 +1,38 @@
+/*
+ * 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 __IO_SH_H__
+#define __IO_SH_H__
+
+struct io_dev_connector;
+
+int register_io_dev_sh(const struct io_dev_connector **dev_con);
+
+#endif /* __IO_SH_H__ */
diff --git a/uefi/arm-trusted-firmware/include/drivers/io/io_storage.h b/uefi/arm-trusted-firmware/include/drivers/io/io_storage.h
new file mode 100644
index 0000000..1c2d26d
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/drivers/io/io_storage.h
@@ -0,0 +1,125 @@
+/*
+ * 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 __IO_H__
+#define __IO_H__
+
+#include <stdint.h>
+#include <stdio.h> /* For ssize_t */
+
+
+/* Device type which can be used to enable policy decisions about which device
+ * to access */
+typedef enum {
+	IO_TYPE_INVALID,
+	IO_TYPE_SEMIHOSTING,
+	IO_TYPE_MEMMAP,
+	IO_TYPE_FIRMWARE_IMAGE_PACKAGE,
+	IO_TYPE_BLOCK,
+	IO_TYPE_MAX
+} io_type_t;
+
+
+/* Modes used when seeking data on a supported device */
+typedef enum {
+	IO_SEEK_INVALID,
+	IO_SEEK_SET,
+	IO_SEEK_END,
+	IO_SEEK_CUR,
+	IO_SEEK_MAX
+} io_seek_mode_t;
+
+
+/* Connector type, providing a means of identifying a device to open */
+struct io_dev_connector;
+
+
+/* File specification - used to refer to data on a device supporting file-like
+ * entities */
+typedef struct io_file_spec {
+	const char *path;
+	unsigned int mode;
+} io_file_spec_t;
+
+
+/* Block specification - used to refer to data on a device supporting
+ * block-like entities */
+typedef struct io_block_spec {
+	size_t offset;
+	size_t length;
+} io_block_spec_t;
+
+
+/* Access modes used when accessing data on a device */
+#define IO_MODE_INVALID (0)
+#define IO_MODE_RO	(1 << 0)
+#define IO_MODE_RW	(1 << 1)
+
+
+/* Return codes reported by 'io_*' APIs */
+#define IO_SUCCESS		(0)
+#define IO_FAIL			(-1)
+#define IO_NOT_SUPPORTED	(-2)
+#define IO_RESOURCES_EXHAUSTED	(-3)
+
+
+/* Open a connection to a device */
+int io_dev_open(const struct io_dev_connector *dev_con,
+		const uintptr_t dev_spec,
+		uintptr_t *dev_handle);
+
+
+/* Initialise a device explicitly - to permit lazy initialisation or
+ * re-initialisation */
+int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params);
+
+/* TODO: Consider whether an explicit "shutdown" API should be included */
+
+/* Close a connection to a device */
+int io_dev_close(uintptr_t dev_handle);
+
+
+/* Synchronous operations */
+int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle);
+
+int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset);
+
+int io_size(uintptr_t handle, size_t *length);
+
+int io_read(uintptr_t handle, uintptr_t buffer, size_t length,
+		size_t *length_read);
+
+int io_write(uintptr_t handle, const uintptr_t buffer, size_t length,
+		size_t *length_written);
+
+int io_close(uintptr_t handle);
+
+
+#endif /* __IO_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/aarch64/arch.h b/uefi/arm-trusted-firmware/include/lib/aarch64/arch.h
new file mode 100644
index 0000000..5291684
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/aarch64/arch.h
@@ -0,0 +1,442 @@
+/*
+ * 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 __ARCH_H__
+#define __ARCH_H__
+
+
+/*******************************************************************************
+ * MIDR bit definitions
+ ******************************************************************************/
+#define MIDR_IMPL_MASK		0xff
+#define MIDR_IMPL_SHIFT		0x18
+#define MIDR_VAR_SHIFT		20
+#define MIDR_VAR_BITS		4
+#define MIDR_REV_SHIFT		0
+#define MIDR_REV_BITS		4
+#define MIDR_PN_MASK		0xfff
+#define MIDR_PN_SHIFT		0x4
+
+/*******************************************************************************
+ * MPIDR macros
+ ******************************************************************************/
+#define MPIDR_CPU_MASK		MPIDR_AFFLVL_MASK
+#define MPIDR_CLUSTER_MASK	MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS
+#define MPIDR_AFFINITY_BITS	8
+#define MPIDR_AFFLVL_MASK	0xff
+#define MPIDR_AFF0_SHIFT	0
+#define MPIDR_AFF1_SHIFT	8
+#define MPIDR_AFF2_SHIFT	16
+#define MPIDR_AFF3_SHIFT	32
+#define MPIDR_AFFINITY_MASK	0xff00ffffff
+#define MPIDR_AFFLVL_SHIFT	3
+#define MPIDR_AFFLVL0		0
+#define MPIDR_AFFLVL1		1
+#define MPIDR_AFFLVL2		2
+#define MPIDR_AFFLVL3		3
+/*
+ * The MPIDR_MAX_AFFLVL count starts from 0. Take care to
+ * add one while using this macro to define array sizes.
+ * TODO: Support only the first 3 affinity levels for now.
+ */
+#define MPIDR_MAX_AFFLVL	2
+
+/* Constant to highlight the assumption that MPIDR allocation starts from 0 */
+#define FIRST_MPIDR		0
+
+/*******************************************************************************
+ * Definitions for CPU system register interface to GICv3
+ ******************************************************************************/
+#define ICC_SRE_EL1     S3_0_C12_C12_5
+#define ICC_SRE_EL2     S3_4_C12_C9_5
+#define ICC_SRE_EL3     S3_6_C12_C12_5
+#define ICC_CTLR_EL1    S3_0_C12_C12_4
+#define ICC_CTLR_EL3    S3_6_C12_C12_4
+#define ICC_PMR_EL1     S3_0_C4_C6_0
+
+/*******************************************************************************
+ * Generic timer memory mapped registers & offsets
+ ******************************************************************************/
+#define CNTCR_OFF			0x000
+#define CNTFID_OFF			0x020
+
+#define CNTCR_EN			(1 << 0)
+#define CNTCR_HDBG			(1 << 1)
+#define CNTCR_FCREQ(x)			((x) << 8)
+
+/*******************************************************************************
+ * System register bit definitions
+ ******************************************************************************/
+/* CLIDR definitions */
+#define LOUIS_SHIFT		21
+#define LOC_SHIFT		24
+#define CLIDR_FIELD_WIDTH	3
+
+/* CSSELR definitions */
+#define LEVEL_SHIFT		1
+
+/* D$ set/way op type defines */
+#define DCISW			0x0
+#define DCCISW			0x1
+#define DCCSW			0x2
+
+/* ID_AA64PFR0_EL1 definitions */
+#define ID_AA64PFR0_EL0_SHIFT	0
+#define ID_AA64PFR0_EL1_SHIFT	4
+#define ID_AA64PFR0_EL2_SHIFT	8
+#define ID_AA64PFR0_EL3_SHIFT	12
+#define ID_AA64PFR0_ELX_MASK	0xf
+
+/* ID_PFR1_EL1 definitions */
+#define ID_PFR1_VIRTEXT_SHIFT	12
+#define ID_PFR1_VIRTEXT_MASK	0xf
+#define GET_VIRT_EXT(id)	((id >> ID_PFR1_VIRTEXT_SHIFT) \
+				 & ID_PFR1_VIRTEXT_MASK)
+
+/* SCTLR definitions */
+#define SCTLR_EL2_RES1  ((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22) | \
+			(1 << 18) | (1 << 16) | (1 << 11) | (1 << 5) |  \
+			(1 << 4))
+
+#define SCTLR_EL1_RES1  ((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22) | \
+			(1 << 11))
+#define SCTLR_AARCH32_EL1_RES1 \
+			((1 << 23) | (1 << 22) | (1 << 11) | (1 << 4) | \
+			(1 << 3))
+
+#define SCTLR_M_BIT		(1 << 0)
+#define SCTLR_A_BIT		(1 << 1)
+#define SCTLR_C_BIT		(1 << 2)
+#define SCTLR_SA_BIT		(1 << 3)
+#define SCTLR_I_BIT		(1 << 12)
+#define SCTLR_WXN_BIT		(1 << 19)
+#define SCTLR_EE_BIT		(1 << 25)
+
+/* CPACR_El1 definitions */
+#define CPACR_EL1_FPEN(x)	(x << 20)
+#define CPACR_EL1_FP_TRAP_EL0	0x1
+#define CPACR_EL1_FP_TRAP_ALL	0x2
+#define CPACR_EL1_FP_TRAP_NONE	0x3
+
+/* SCR definitions */
+#define SCR_RES1_BITS		((1 << 4) | (1 << 5))
+#define SCR_TWE_BIT		(1 << 13)
+#define SCR_TWI_BIT		(1 << 12)
+#define SCR_ST_BIT		(1 << 11)
+#define SCR_RW_BIT		(1 << 10)
+#define SCR_SIF_BIT		(1 << 9)
+#define SCR_HCE_BIT		(1 << 8)
+#define SCR_SMD_BIT		(1 << 7)
+#define SCR_EA_BIT		(1 << 3)
+#define SCR_FIQ_BIT		(1 << 2)
+#define SCR_IRQ_BIT		(1 << 1)
+#define SCR_NS_BIT		(1 << 0)
+#define SCR_VALID_BIT_MASK	0x2f8f
+
+/* HCR definitions */
+#define HCR_RW_BIT		(1ull << 31)
+#define HCR_AMO_BIT		(1 << 5)
+#define HCR_IMO_BIT		(1 << 4)
+#define HCR_FMO_BIT		(1 << 3)
+
+/* CNTHCTL_EL2 definitions */
+#define EVNTEN_BIT		(1 << 2)
+#define EL1PCEN_BIT		(1 << 1)
+#define EL1PCTEN_BIT		(1 << 0)
+
+/* CNTKCTL_EL1 definitions */
+#define EL0PTEN_BIT		(1 << 9)
+#define EL0VTEN_BIT		(1 << 8)
+#define EL0PCTEN_BIT		(1 << 0)
+#define EL0VCTEN_BIT		(1 << 1)
+#define EVNTEN_BIT		(1 << 2)
+#define EVNTDIR_BIT		(1 << 3)
+#define EVNTI_SHIFT		4
+#define EVNTI_MASK		0xf
+
+/* CPTR_EL3 definitions */
+#define TCPAC_BIT		(1 << 31)
+#define TTA_BIT			(1 << 20)
+#define TFP_BIT			(1 << 10)
+
+/* CPSR/SPSR definitions */
+#define DAIF_FIQ_BIT		(1 << 0)
+#define DAIF_IRQ_BIT		(1 << 1)
+#define DAIF_ABT_BIT		(1 << 2)
+#define DAIF_DBG_BIT		(1 << 3)
+#define SPSR_DAIF_SHIFT		6
+#define SPSR_DAIF_MASK		0xf
+
+#define SPSR_AIF_SHIFT		6
+#define SPSR_AIF_MASK		0x7
+
+#define SPSR_E_SHIFT		9
+#define SPSR_E_MASK			0x1
+#define SPSR_E_LITTLE		0x0
+#define SPSR_E_BIG			0x1
+
+#define SPSR_T_SHIFT		5
+#define SPSR_T_MASK			0x1
+#define SPSR_T_ARM			0x0
+#define SPSR_T_THUMB		0x1
+
+#define DISABLE_ALL_EXCEPTIONS \
+		(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
+
+
+/*
+ * TCR defintions
+ */
+#define TCR_EL3_RES1		((1UL << 31) | (1UL << 23))
+#define TCR_EL1_IPS_SHIFT	32
+#define TCR_EL3_PS_SHIFT	16
+
+/* (internal) physical address size bits in EL3/EL1 */
+#define TCR_PS_BITS_4GB		(0x0)
+#define TCR_PS_BITS_64GB	(0x1)
+#define TCR_PS_BITS_1TB		(0x2)
+#define TCR_PS_BITS_4TB		(0x3)
+#define TCR_PS_BITS_16TB	(0x4)
+#define TCR_PS_BITS_256TB	(0x5)
+
+#define ADDR_MASK_48_TO_63	0xFFFF000000000000UL
+#define ADDR_MASK_44_TO_47	0x0000F00000000000UL
+#define ADDR_MASK_42_TO_43	0x00000C0000000000UL
+#define ADDR_MASK_40_TO_41	0x0000030000000000UL
+#define ADDR_MASK_36_TO_39	0x000000F000000000UL
+#define ADDR_MASK_32_TO_35	0x0000000F00000000UL
+
+#define TCR_RGN_INNER_NC	(0x0 << 8)
+#define TCR_RGN_INNER_WBA	(0x1 << 8)
+#define TCR_RGN_INNER_WT	(0x2 << 8)
+#define TCR_RGN_INNER_WBNA	(0x3 << 8)
+
+#define TCR_RGN_OUTER_NC	(0x0 << 10)
+#define TCR_RGN_OUTER_WBA	(0x1 << 10)
+#define TCR_RGN_OUTER_WT	(0x2 << 10)
+#define TCR_RGN_OUTER_WBNA	(0x3 << 10)
+
+#define TCR_SH_NON_SHAREABLE	(0x0 << 12)
+#define TCR_SH_OUTER_SHAREABLE	(0x2 << 12)
+#define TCR_SH_INNER_SHAREABLE	(0x3 << 12)
+
+#define MODE_SP_SHIFT		0x0
+#define MODE_SP_MASK		0x1
+#define MODE_SP_EL0		0x0
+#define MODE_SP_ELX		0x1
+
+#define MODE_RW_SHIFT		0x4
+#define MODE_RW_MASK		0x1
+#define MODE_RW_64			0x0
+#define MODE_RW_32			0x1
+
+#define MODE_EL_SHIFT		0x2
+#define MODE_EL_MASK		0x3
+#define MODE_EL3		0x3
+#define MODE_EL2		0x2
+#define MODE_EL1		0x1
+#define MODE_EL0		0x0
+
+#define MODE32_SHIFT		0
+#define MODE32_MASK		0xf
+#define MODE32_usr		0x0
+#define MODE32_fiq		0x1
+#define MODE32_irq		0x2
+#define MODE32_svc		0x3
+#define MODE32_mon		0x6
+#define MODE32_abt		0x7
+#define MODE32_hyp		0xa
+#define MODE32_und		0xb
+#define MODE32_sys		0xf
+
+#define GET_RW(mode)		(((mode) >> MODE_RW_SHIFT) & MODE_RW_MASK)
+#define GET_EL(mode)		(((mode) >> MODE_EL_SHIFT) & MODE_EL_MASK)
+#define GET_SP(mode)		(((mode) >> MODE_SP_SHIFT) & MODE_SP_MASK)
+#define GET_M32(mode)		(((mode) >> MODE32_SHIFT) & MODE32_MASK)
+
+#define SPSR_64(el, sp, daif)				\
+	(MODE_RW_64 << MODE_RW_SHIFT |			\
+	((el) & MODE_EL_MASK) << MODE_EL_SHIFT |	\
+	((sp) & MODE_SP_MASK) << MODE_SP_SHIFT |	\
+	((daif) & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT)
+
+#define SPSR_MODE32(mode, isa, endian, aif)		\
+	(MODE_RW_32 << MODE_RW_SHIFT |			\
+	((mode) & MODE32_MASK) << MODE32_SHIFT |	\
+	((isa) & SPSR_T_MASK) << SPSR_T_SHIFT |		\
+	((endian) & SPSR_E_MASK) << SPSR_E_SHIFT |	\
+	((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT)
+
+
+/* Physical timer control register bit fields shifts and masks */
+#define CNTP_CTL_ENABLE_SHIFT   0
+#define CNTP_CTL_IMASK_SHIFT    1
+#define CNTP_CTL_ISTATUS_SHIFT  2
+
+#define CNTP_CTL_ENABLE_MASK    1
+#define CNTP_CTL_IMASK_MASK     1
+#define CNTP_CTL_ISTATUS_MASK   1
+
+#define get_cntp_ctl_enable(x)  ((x >> CNTP_CTL_ENABLE_SHIFT) & \
+					CNTP_CTL_ENABLE_MASK)
+#define get_cntp_ctl_imask(x)   ((x >> CNTP_CTL_IMASK_SHIFT) & \
+					CNTP_CTL_IMASK_MASK)
+#define get_cntp_ctl_istatus(x) ((x >> CNTP_CTL_ISTATUS_SHIFT) & \
+					CNTP_CTL_ISTATUS_MASK)
+
+#define set_cntp_ctl_enable(x)  (x |= 1 << CNTP_CTL_ENABLE_SHIFT)
+#define set_cntp_ctl_imask(x)   (x |= 1 << CNTP_CTL_IMASK_SHIFT)
+
+#define clr_cntp_ctl_enable(x)  (x &= ~(1 << CNTP_CTL_ENABLE_SHIFT))
+#define clr_cntp_ctl_imask(x)   (x &= ~(1 << CNTP_CTL_IMASK_SHIFT))
+
+/* Miscellaneous MMU related constants */
+#define NUM_2MB_IN_GB		(1 << 9)
+#define NUM_4K_IN_2MB		(1 << 9)
+#define NUM_GB_IN_4GB		(1 << 2)
+
+#define TWO_MB_SHIFT		21
+#define ONE_GB_SHIFT		30
+#define FOUR_KB_SHIFT		12
+
+#define ONE_GB_INDEX(x)		((x) >> ONE_GB_SHIFT)
+#define TWO_MB_INDEX(x)		((x) >> TWO_MB_SHIFT)
+#define FOUR_KB_INDEX(x)	((x) >> FOUR_KB_SHIFT)
+
+#define INVALID_DESC		0x0
+#define BLOCK_DESC		0x1
+#define TABLE_DESC		0x3
+
+#define FIRST_LEVEL_DESC_N	ONE_GB_SHIFT
+#define SECOND_LEVEL_DESC_N	TWO_MB_SHIFT
+#define THIRD_LEVEL_DESC_N	FOUR_KB_SHIFT
+
+#define LEVEL1			1
+#define LEVEL2			2
+#define LEVEL3			3
+
+#define XN			(1ull << 2)
+#define PXN			(1ull << 1)
+#define CONT_HINT		(1ull << 0)
+
+#define UPPER_ATTRS(x)		(x & 0x7) << 52
+#define NON_GLOBAL		(1 << 9)
+#define ACCESS_FLAG		(1 << 8)
+#define NSH			(0x0 << 6)
+#define OSH			(0x2 << 6)
+#define ISH			(0x3 << 6)
+
+#define PAGE_SIZE_SHIFT		FOUR_KB_SHIFT
+#define PAGE_SIZE		(1 << PAGE_SIZE_SHIFT)
+#define PAGE_SIZE_MASK		(PAGE_SIZE - 1)
+#define IS_PAGE_ALIGNED(addr)	(((addr) & PAGE_SIZE_MASK) == 0)
+
+#define XLAT_ENTRY_SIZE_SHIFT	3 /* Each MMU table entry is 8 bytes (1 << 3) */
+#define XLAT_ENTRY_SIZE		(1 << XLAT_ENTRY_SIZE_SHIFT)
+
+#define XLAT_TABLE_SIZE_SHIFT	PAGE_SIZE_SHIFT
+#define XLAT_TABLE_SIZE		(1 << XLAT_TABLE_SIZE_SHIFT)
+
+/* Values for number of entries in each MMU translation table */
+#define XLAT_TABLE_ENTRIES_SHIFT (XLAT_TABLE_SIZE_SHIFT - XLAT_ENTRY_SIZE_SHIFT)
+#define XLAT_TABLE_ENTRIES	(1 << XLAT_TABLE_ENTRIES_SHIFT)
+#define XLAT_TABLE_ENTRIES_MASK	(XLAT_TABLE_ENTRIES - 1)
+
+/* Values to convert a memory address to an index into a translation table */
+#define L3_XLAT_ADDRESS_SHIFT	PAGE_SIZE_SHIFT
+#define L2_XLAT_ADDRESS_SHIFT	(L3_XLAT_ADDRESS_SHIFT + XLAT_TABLE_ENTRIES_SHIFT)
+#define L1_XLAT_ADDRESS_SHIFT	(L2_XLAT_ADDRESS_SHIFT + XLAT_TABLE_ENTRIES_SHIFT)
+
+/*
+ * AP[1] bit is ignored by hardware and is
+ * treated as if it is One in EL2/EL3
+ */
+#define AP_RO			(0x1 << 5)
+#define AP_RW			(0x0 << 5)
+
+#define NS				(0x1 << 3)
+#define ATTR_SO_INDEX			0x2
+#define ATTR_DEVICE_INDEX		0x1
+#define ATTR_IWBWA_OWBWA_NTR_INDEX	0x0
+#define LOWER_ATTRS(x)			(((x) & 0xfff) << 2)
+#define ATTR_SO				(0x0)
+#define ATTR_DEVICE			(0x4)
+#define ATTR_IWBWA_OWBWA_NTR		(0xff)
+#define MAIR_ATTR_SET(attr, index)	(attr << (index << 3))
+
+/* Exception Syndrome register bits and bobs */
+#define ESR_EC_SHIFT			26
+#define ESR_EC_MASK			0x3f
+#define ESR_EC_LENGTH			6
+#define EC_UNKNOWN			0x0
+#define EC_WFE_WFI			0x1
+#define EC_AARCH32_CP15_MRC_MCR		0x3
+#define EC_AARCH32_CP15_MRRC_MCRR	0x4
+#define EC_AARCH32_CP14_MRC_MCR		0x5
+#define EC_AARCH32_CP14_LDC_STC		0x6
+#define EC_FP_SIMD			0x7
+#define EC_AARCH32_CP10_MRC		0x8
+#define EC_AARCH32_CP14_MRRC_MCRR	0xc
+#define EC_ILLEGAL			0xe
+#define EC_AARCH32_SVC			0x11
+#define EC_AARCH32_HVC			0x12
+#define EC_AARCH32_SMC			0x13
+#define EC_AARCH64_SVC			0x15
+#define EC_AARCH64_HVC			0x16
+#define EC_AARCH64_SMC			0x17
+#define EC_AARCH64_SYS			0x18
+#define EC_IABORT_LOWER_EL		0x20
+#define EC_IABORT_CUR_EL		0x21
+#define EC_PC_ALIGN			0x22
+#define EC_DABORT_LOWER_EL		0x24
+#define EC_DABORT_CUR_EL		0x25
+#define EC_SP_ALIGN			0x26
+#define EC_AARCH32_FP			0x28
+#define EC_AARCH64_FP			0x2c
+#define EC_SERROR			0x2f
+
+#define EC_BITS(x)			(x >> ESR_EC_SHIFT) & ESR_EC_MASK
+
+/*******************************************************************************
+ * Definitions of register offsets and fields in the CNTCTLBase Frame of the
+ * system level implementation of the Generic Timer.
+ ******************************************************************************/
+#define CNTNSAR			0x4
+#define CNTNSAR_NS_SHIFT(x)	x
+
+#define CNTACR_BASE(x)		(0x40 + (x << 2))
+#define CNTACR_RPCT_SHIFT	0x0
+#define CNTACR_RVCT_SHIFT	0x1
+#define CNTACR_RFRQ_SHIFT	0x2
+#define CNTACR_RVOFF_SHIFT	0x3
+#define CNTACR_RWVT_SHIFT	0x4
+#define CNTACR_RWPT_SHIFT	0x5
+
+#endif /* __ARCH_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/aarch64/arch_helpers.h b/uefi/arm-trusted-firmware/include/lib/aarch64/arch_helpers.h
new file mode 100644
index 0000000..65941e6
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/aarch64/arch_helpers.h
@@ -0,0 +1,308 @@
+/*
+ * 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 __ARCH_HELPERS_H__
+#define __ARCH_HELPERS_H__
+
+#include <arch.h>	/* for additional register definitions */
+#include <cdefs.h>	/* For __dead2 */
+#include <stdint.h>
+
+/**********************************************************************
+ * Macros which create inline functions to read or write CPU system
+ * registers
+ *********************************************************************/
+
+#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name)		\
+static inline uint64_t read_ ## _name(void)			\
+{								\
+	uint64_t v;						\
+	__asm__ volatile ("mrs %0, " #_reg_name : "=r" (v));	\
+	return v;						\
+}
+
+#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)			\
+static inline void write_ ## _name(uint64_t v)				\
+{									\
+	__asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v));	\
+}
+
+#define _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _reg_name)		\
+static inline void write_ ## _name(const uint64_t v)			\
+{									\
+	__asm__ volatile ("msr " #_reg_name ", %0" : : "i" (v));	\
+}
+
+/* Define read function for system register */
+#define DEFINE_SYSREG_READ_FUNC(_name) 			\
+	_DEFINE_SYSREG_READ_FUNC(_name, _name)
+
+/* Define read & write function for system register */
+#define DEFINE_SYSREG_RW_FUNCS(_name)			\
+	_DEFINE_SYSREG_READ_FUNC(_name, _name)		\
+	_DEFINE_SYSREG_WRITE_FUNC(_name, _name)
+
+/* Define read & write function for renamed system register */
+#define DEFINE_RENAME_SYSREG_RW_FUNCS(_name, _reg_name)	\
+	_DEFINE_SYSREG_READ_FUNC(_name, _reg_name)	\
+	_DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)
+
+/* Define write function for special system registers */
+#define DEFINE_SYSREG_WRITE_CONST_FUNC(_name)		\
+	_DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _name)
+
+
+/**********************************************************************
+ * Macros to create inline functions for system instructions
+ *********************************************************************/
+
+/* Define function for simple system instruction */
+#define DEFINE_SYSOP_FUNC(_op)				\
+static inline void _op(void)				\
+{							\
+	__asm__ (#_op);					\
+}
+
+/* Define function for system instruction with type specifier */
+#define DEFINE_SYSOP_TYPE_FUNC(_op, _type)		\
+static inline void _op ## _type(void)			\
+{							\
+	__asm__ (#_op " " #_type);			\
+}
+
+/* Define function for system instruction with register parameter */
+#define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type)	\
+static inline void _op ## _type(uint64_t v)		\
+{							\
+	 __asm__ (#_op " " #_type ", %0" : : "r" (v));	\
+}
+
+/*******************************************************************************
+ * Aarch64 translation tables manipulation helper prototypes
+******************************************************************************/
+uint64_t create_table_desc(uint64_t *next_table_ptr);
+uint64_t create_block_desc(uint64_t desc, uint64_t addr, uint32_t level);
+uint64_t create_device_block(uint64_t output_addr, uint32_t level, uint32_t ns);
+uint64_t create_romem_block(uint64_t output_addr, uint32_t level, uint32_t ns);
+uint64_t create_rwmem_block(uint64_t output_addr, uint32_t level, uint32_t ns);
+
+/*******************************************************************************
+ * TLB maintenance accessor prototypes
+ ******************************************************************************/
+DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1)
+DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1is)
+DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2)
+DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2is)
+DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3)
+DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3is)
+DEFINE_SYSOP_TYPE_FUNC(tlbi, vmalle1)
+
+/*******************************************************************************
+ * Cache maintenance accessor prototypes
+ ******************************************************************************/
+DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, isw)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cisw)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, csw)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvac)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, ivac)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, civac)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvau)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, zva)
+
+void flush_dcache_range(uint64_t, uint64_t);
+void inv_dcache_range(uint64_t, uint64_t);
+void dcsw_op_louis(uint32_t);
+void dcsw_op_all(uint32_t);
+
+void disable_mmu_el3(void);
+void disable_mmu_icache_el3(void);
+
+/*******************************************************************************
+ * Misc. accessor prototypes
+ ******************************************************************************/
+
+DEFINE_SYSREG_WRITE_CONST_FUNC(daifset)
+DEFINE_SYSREG_WRITE_CONST_FUNC(daifclr)
+
+#define enable_irq()			write_daifclr(DAIF_IRQ_BIT)
+#define enable_fiq()			write_daifclr(DAIF_FIQ_BIT)
+#define enable_serror()			write_daifclr(DAIF_ABT_BIT)
+#define enable_debug_exceptions()	write_daifclr(DAIF_DBG_BIT)
+#define disable_irq()			write_daifset(DAIF_IRQ_BIT)
+#define disable_fiq()			write_daifset(DAIF_FIQ_BIT)
+#define disable_serror()		write_daifset(DAIF_ABT_BIT)
+#define disable_debug_exceptions()	write_daifset(DAIF_DBG_BIT)
+
+DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
+DEFINE_SYSREG_READ_FUNC(CurrentEl)
+DEFINE_SYSREG_RW_FUNCS(daif)
+DEFINE_SYSREG_RW_FUNCS(spsr_el1)
+DEFINE_SYSREG_RW_FUNCS(spsr_el2)
+DEFINE_SYSREG_RW_FUNCS(spsr_el3)
+DEFINE_SYSREG_RW_FUNCS(elr_el1)
+DEFINE_SYSREG_RW_FUNCS(elr_el2)
+DEFINE_SYSREG_RW_FUNCS(elr_el3)
+
+DEFINE_SYSOP_FUNC(wfi)
+DEFINE_SYSOP_FUNC(wfe)
+DEFINE_SYSOP_FUNC(sev)
+DEFINE_SYSOP_TYPE_FUNC(dsb, sy)
+DEFINE_SYSOP_TYPE_FUNC(dmb, sy)
+DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
+DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
+DEFINE_SYSOP_FUNC(isb)
+
+uint32_t get_afflvl_shift(uint32_t);
+uint32_t mpidr_mask_lower_afflvls(uint64_t, uint32_t);
+
+
+void __dead2 eret(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3,
+		  uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7);
+void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3,
+		 uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7);
+
+/*******************************************************************************
+ * System register accessor prototypes
+ ******************************************************************************/
+DEFINE_SYSREG_READ_FUNC(midr_el1)
+DEFINE_SYSREG_READ_FUNC(mpidr_el1)
+
+DEFINE_SYSREG_RW_FUNCS(scr_el3)
+DEFINE_SYSREG_RW_FUNCS(hcr_el2)
+
+DEFINE_SYSREG_RW_FUNCS(vbar_el1)
+DEFINE_SYSREG_RW_FUNCS(vbar_el2)
+DEFINE_SYSREG_RW_FUNCS(vbar_el3)
+
+DEFINE_SYSREG_RW_FUNCS(sctlr_el1)
+DEFINE_SYSREG_RW_FUNCS(sctlr_el2)
+DEFINE_SYSREG_RW_FUNCS(sctlr_el3)
+
+DEFINE_SYSREG_RW_FUNCS(actlr_el1)
+DEFINE_SYSREG_RW_FUNCS(actlr_el2)
+DEFINE_SYSREG_RW_FUNCS(actlr_el3)
+
+DEFINE_SYSREG_RW_FUNCS(esr_el1)
+DEFINE_SYSREG_RW_FUNCS(esr_el2)
+DEFINE_SYSREG_RW_FUNCS(esr_el3)
+
+DEFINE_SYSREG_RW_FUNCS(afsr0_el1)
+DEFINE_SYSREG_RW_FUNCS(afsr0_el2)
+DEFINE_SYSREG_RW_FUNCS(afsr0_el3)
+
+DEFINE_SYSREG_RW_FUNCS(afsr1_el1)
+DEFINE_SYSREG_RW_FUNCS(afsr1_el2)
+DEFINE_SYSREG_RW_FUNCS(afsr1_el3)
+
+DEFINE_SYSREG_RW_FUNCS(far_el1)
+DEFINE_SYSREG_RW_FUNCS(far_el2)
+DEFINE_SYSREG_RW_FUNCS(far_el3)
+
+DEFINE_SYSREG_RW_FUNCS(mair_el1)
+DEFINE_SYSREG_RW_FUNCS(mair_el2)
+DEFINE_SYSREG_RW_FUNCS(mair_el3)
+
+DEFINE_SYSREG_RW_FUNCS(amair_el1)
+DEFINE_SYSREG_RW_FUNCS(amair_el2)
+DEFINE_SYSREG_RW_FUNCS(amair_el3)
+
+DEFINE_SYSREG_READ_FUNC(rvbar_el1)
+DEFINE_SYSREG_READ_FUNC(rvbar_el2)
+DEFINE_SYSREG_READ_FUNC(rvbar_el3)
+
+DEFINE_SYSREG_RW_FUNCS(rmr_el1)
+DEFINE_SYSREG_RW_FUNCS(rmr_el2)
+DEFINE_SYSREG_RW_FUNCS(rmr_el3)
+
+DEFINE_SYSREG_RW_FUNCS(tcr_el1)
+DEFINE_SYSREG_RW_FUNCS(tcr_el2)
+DEFINE_SYSREG_RW_FUNCS(tcr_el3)
+
+DEFINE_SYSREG_RW_FUNCS(ttbr0_el1)
+DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
+DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
+
+DEFINE_SYSREG_RW_FUNCS(ttbr1_el1)
+
+DEFINE_SYSREG_RW_FUNCS(cptr_el2)
+DEFINE_SYSREG_RW_FUNCS(cptr_el3)
+
+DEFINE_SYSREG_RW_FUNCS(cpacr_el1)
+DEFINE_SYSREG_RW_FUNCS(cntfrq_el0)
+DEFINE_SYSREG_RW_FUNCS(cntps_ctl_el1)
+DEFINE_SYSREG_RW_FUNCS(cntps_tval_el1)
+DEFINE_SYSREG_RW_FUNCS(cntps_cval_el1)
+DEFINE_SYSREG_READ_FUNC(cntpct_el0)
+DEFINE_SYSREG_RW_FUNCS(cnthctl_el2)
+
+DEFINE_SYSREG_RW_FUNCS(tpidr_el3)
+
+DEFINE_SYSREG_RW_FUNCS(cntvoff_el2)
+
+DEFINE_SYSREG_RW_FUNCS(vpidr_el2)
+DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)
+
+DEFINE_SYSREG_READ_FUNC(isr_el1)
+
+/* GICv3 System Registers */
+
+DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3)
+DEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1)
+
+
+#define IS_IN_EL(x) \
+	(GET_EL(read_CurrentEl()) == MODE_EL##x)
+
+#define IS_IN_EL1() IS_IN_EL(1)
+#define IS_IN_EL3() IS_IN_EL(3)
+
+/* Previously defined accesor functions with incomplete register names  */
+
+#define read_current_el()	read_CurrentEl()
+
+#define dsb()			dsbsy()
+
+#define read_midr()		read_midr_el1()
+
+#define read_mpidr()		read_mpidr_el1()
+
+#define read_scr()		read_scr_el3()
+#define write_scr(_v)		write_scr_el3(_v)
+
+#define read_hcr()		read_hcr_el2()
+#define write_hcr(_v)		write_hcr_el2(_v)
+
+#define read_cpacr()		read_cpacr_el1()
+#define write_cpacr(_v)		write_cpacr_el1(_v)
+
+#endif /* __ARCH_HELPERS_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/aarch64/xlat_tables.h b/uefi/arm-trusted-firmware/include/lib/aarch64/xlat_tables.h
new file mode 100644
index 0000000..0b5dbdf
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/aarch64/xlat_tables.h
@@ -0,0 +1,92 @@
+/*
+ * 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 __XLAT_TABLES_H__
+#define __XLAT_TABLES_H__
+
+
+/*
+ * Flags to override default values used to program system registers while
+ * enabling the MMU.
+ */
+#define DISABLE_DCACHE		(1 << 0)
+
+#ifndef __ASSEMBLY__
+#include <stdint.h>
+
+/* Helper macro to define entries for mmap_region_t. It creates
+ * identity mappings for each region.
+ */
+#define MAP_REGION_FLAT(adr, sz, attr) MAP_REGION(adr, adr, sz, attr)
+
+/* Helper macro to define entries for mmap_region_t. It allows to
+ * re-map address mappings from 'pa' to 'va' for each region.
+ */
+#define MAP_REGION(pa, va, sz, attr) {(pa), (va), (sz), (attr)}
+
+/*
+ * Flags for building up memory mapping attributes.
+ * These are organised so that a clear bit gives a more restrictive  mapping
+ * that a set bit, that way a bitwise-and two sets of attributes will never give
+ * an attribute which has greater access rights that any of the original
+ * attributes.
+ */
+typedef enum  {
+	MT_DEVICE	= 0 << 0,
+	MT_MEMORY	= 1 << 0,
+
+	MT_RO		= 0 << 1,
+	MT_RW		= 1 << 1,
+
+	MT_SECURE	= 0 << 2,
+	MT_NS		= 1 << 2
+} mmap_attr_t;
+
+/*
+ * Structure for specifying a single region of memory.
+ */
+typedef struct mmap_region {
+	unsigned long	base_pa;
+	unsigned long	base_va;
+	unsigned long	size;
+	mmap_attr_t	attr;
+} mmap_region_t;
+
+void mmap_add_region(unsigned long base_pa, unsigned long base_va,
+				unsigned long size, unsigned attr);
+void mmap_add(const mmap_region_t *mm);
+
+void init_xlat_tables(void);
+
+void enable_mmu_el1(uint32_t flags);
+void enable_mmu_el3(uint32_t flags);
+
+#endif /*__ASSEMBLY__*/
+#endif /* __XLAT_TABLES_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/bakery_lock.h b/uefi/arm-trusted-firmware/include/lib/bakery_lock.h
new file mode 100644
index 0000000..9736f85
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/bakery_lock.h
@@ -0,0 +1,73 @@
+/*
+ * 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 __BAKERY_LOCK_H__
+#define __BAKERY_LOCK_H__
+
+#include <platform_def.h>
+
+#define BAKERY_LOCK_MAX_CPUS		PLATFORM_CORE_COUNT
+
+#ifndef __ASSEMBLY__
+#include <stdint.h>
+
+#if USE_COHERENT_MEM
+
+typedef struct bakery_lock {
+	int owner;
+	volatile char entering[BAKERY_LOCK_MAX_CPUS];
+	volatile unsigned number[BAKERY_LOCK_MAX_CPUS];
+} bakery_lock_t;
+
+#define NO_OWNER (-1)
+
+void bakery_lock_init(bakery_lock_t *bakery);
+void bakery_lock_get(bakery_lock_t *bakery);
+void bakery_lock_release(bakery_lock_t *bakery);
+int bakery_lock_try(bakery_lock_t *bakery);
+
+#else
+
+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;
+
+void bakery_lock_get(unsigned int id, unsigned int offset);
+void bakery_lock_release(unsigned int id, unsigned int offset);
+
+#endif /* __USE_COHERENT_MEM__ */
+#endif /* __ASSEMBLY__ */
+#endif /* __BAKERY_LOCK_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/cassert.h b/uefi/arm-trusted-firmware/include/lib/cassert.h
new file mode 100644
index 0000000..0e5529d
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/cassert.h
@@ -0,0 +1,42 @@
+/*
+ * 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 __CASSERT_H__
+#define __CASSERT_H__
+
+/*******************************************************************************
+ * Macro to flag a compile time assertion. It uses the preprocessor to generate
+ * an invalid C construct if 'cond' evaluates to false.
+ * The following  compilation error is triggered if the assertion fails:
+ * "error: size of array 'msg' is negative"
+ ******************************************************************************/
+#define CASSERT(cond, msg)	typedef char msg[(cond) ? 1 : -1]
+
+#endif /* __CASSERT_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/aem_generic.h b/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/aem_generic.h
new file mode 100644
index 0000000..2f701d1
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/aem_generic.h
@@ -0,0 +1,41 @@
+/*
+ * 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 __AEM_GENERIC_H__
+#define __AEM_GENERIC_H__
+
+/* BASE AEM midr for revision 0 */
+#define BASE_AEM_MIDR 0x410FD0F0
+
+/* Foundation AEM midr for revision 0 */
+#define FOUNDATION_AEM_MIDR  0x410FD000
+
+
+#endif /* __AEM_GENERIC_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/cortex_a53.h b/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/cortex_a53.h
new file mode 100644
index 0000000..14821ab
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/cortex_a53.h
@@ -0,0 +1,44 @@
+/*
+ * 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 __CORTEX_A53_H__
+#define __CORTEX_A53_H__
+
+/* Cortex-A53 midr for revision 0 */
+#define CORTEX_A53_MIDR 0x410FD030
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CPUECTLR_EL1			S3_1_C15_C2_1	/* Instruction def. */
+
+#define CPUECTLR_SMP_BIT		(1 << 6)
+
+#endif /* __CORTEX_A53_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/cortex_a57.h b/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/cortex_a57.h
new file mode 100644
index 0000000..6128b16
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/cortex_a57.h
@@ -0,0 +1,66 @@
+/*
+ * 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 __CORTEX_A57_H__
+#define __CORTEX_A57_H__
+
+/* Cortex-A57 midr for revision 0 */
+#define CORTEX_A57_MIDR 0x410FD070
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CPUECTLR_EL1			S3_1_C15_C2_1	/* Instruction def. */
+
+#define CPUECTLR_SMP_BIT		(1 << 6)
+#define CPUECTLR_DIS_TWD_ACC_PFTCH_BIT	(1 << 38)
+#define CPUECTLR_L2_IPFTCH_DIST_MASK	(0x3 << 35)
+#define CPUECTLR_L2_DPFTCH_DIST_MASK	(0x3 << 32)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CPUACTLR_EL1			S3_1_C15_C2_0	/* Instruction def. */
+
+#define CPUACTLR_NO_ALLOC_WBWA         (1 << 49)
+#define CPUACTLR_DCC_AS_DCCI           (1 << 44)
+
+/*******************************************************************************
+ * L2 Control register specific definitions.
+ ******************************************************************************/
+#define L2CTLR_EL1			S3_1_C11_C0_2	/* Instruction def. */
+
+#define L2CTLR_DATA_RAM_LATENCY_SHIFT	0
+#define L2CTLR_TAG_RAM_LATENCY_SHIFT	6
+
+#define L2_DATA_RAM_LATENCY_3_CYCLES	0x2
+#define L2_TAG_RAM_LATENCY_3_CYCLES	0x2
+
+#endif /* __CORTEX_A57_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/cpu_macros.S b/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/cpu_macros.S
new file mode 100644
index 0000000..089f09c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/cpus/aarch64/cpu_macros.S
@@ -0,0 +1,82 @@
+/*
+ * 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>
+
+#define CPU_IMPL_PN_MASK	(MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
+				(MIDR_PN_MASK << MIDR_PN_SHIFT)
+
+	/*
+	 * Define the offsets to the fields in cpu_ops structure.
+	 */
+	.struct 0
+CPU_MIDR: /* cpu_ops midr */
+	.space  8
+/* Reset fn is needed in BL at reset vector */
+#if IMAGE_BL1 || IMAGE_BL31
+CPU_RESET_FUNC: /* cpu_ops reset_func */
+	.space  8
+#endif
+#if IMAGE_BL31 /* The power down core and cluster is needed only in BL3-1 */
+CPU_PWR_DWN_CORE: /* cpu_ops core_pwr_dwn */
+	.space  8
+CPU_PWR_DWN_CLUSTER: /* cpu_ops cluster_pwr_dwn */
+	.space  8
+#endif
+#if (IMAGE_BL31 && CRASH_REPORTING)
+CPU_REG_DUMP: /* cpu specific register dump for crash reporting */
+	.space  8
+#endif
+CPU_OPS_SIZE = .
+
+	/*
+	 * Convenience macro to declare cpu_ops structure.
+	 * Make sure the structure fields are as per the offsets
+	 * defined above.
+	 */
+	.macro declare_cpu_ops _name:req, _midr:req, _noresetfunc = 0
+	.section cpu_ops, "a"; .align 3
+	.type cpu_ops_\_name, %object
+	.quad \_midr
+#if IMAGE_BL1 || IMAGE_BL31
+	.if \_noresetfunc
+	.quad 0
+	.else
+	.quad \_name\()_reset_func
+	.endif
+#endif
+#if IMAGE_BL31
+	.quad \_name\()_core_pwr_dwn
+	.quad \_name\()_cluster_pwr_dwn
+#endif
+#if (IMAGE_BL31 && CRASH_REPORTING)
+	.quad \_name\()_cpu_reg_dump
+#endif
+	.endm
diff --git a/uefi/arm-trusted-firmware/include/lib/mmio.h b/uefi/arm-trusted-firmware/include/lib/mmio.h
new file mode 100644
index 0000000..5b72218
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/mmio.h
@@ -0,0 +1,88 @@
+/*
+ * 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 __MMIO_H__
+#define __MMIO_H__
+
+#include <arch_helpers.h>
+#include <stdint.h>
+
+static inline void mmio_write_8(uintptr_t addr, uint8_t value)
+{
+	dsb();
+	isb();
+	*(volatile uint8_t*)addr = value;
+}
+
+static inline uint8_t mmio_read_8(uintptr_t addr)
+{
+	uint8_t val;
+
+	val = *(volatile uint8_t*)addr;
+	dsb();
+	isb();
+	return val;
+}
+
+static inline void mmio_write_32(uintptr_t addr, uint32_t value)
+{
+	dsb();
+	isb();
+	*(volatile uint32_t*)addr = value;
+}
+
+static inline uint32_t mmio_read_32(uintptr_t addr)
+{
+	uint32_t val;
+
+	val = *(volatile uint32_t*)addr;
+	dsb();
+	isb();
+	return val;
+}
+
+static inline void mmio_write_64(uintptr_t addr, uint64_t value)
+{
+	dsb();
+	isb();
+	*(volatile uint64_t*)addr = value;
+}
+
+static inline uint64_t mmio_read_64(uintptr_t addr)
+{
+	uint64_t val;
+
+	val = *(volatile uint64_t*)addr;
+	dsb();
+	isb();
+	return val;
+}
+
+#endif /* __MMIO_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/semihosting.h b/uefi/arm-trusted-firmware/include/lib/semihosting.h
new file mode 100644
index 0000000..b4eecc5
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/semihosting.h
@@ -0,0 +1,82 @@
+/*
+ * 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 __SEMIHOSTING_H__
+#define __SEMIHOSTING_H__
+
+#include <stdint.h>
+#include <stdio.h> /* For ssize_t */
+
+
+#define SEMIHOSTING_SYS_OPEN            0x01
+#define SEMIHOSTING_SYS_CLOSE           0x02
+#define SEMIHOSTING_SYS_WRITE0          0x04
+#define SEMIHOSTING_SYS_WRITEC          0x03
+#define SEMIHOSTING_SYS_WRITE           0x05
+#define SEMIHOSTING_SYS_READ            0x06
+#define SEMIHOSTING_SYS_READC           0x07
+#define SEMIHOSTING_SYS_SEEK            0x0A
+#define SEMIHOSTING_SYS_FLEN            0x0C
+#define SEMIHOSTING_SYS_REMOVE          0x0E
+#define SEMIHOSTING_SYS_SYSTEM          0x12
+#define SEMIHOSTING_SYS_ERRNO           0x13
+
+#define FOPEN_MODE_R			0x0
+#define FOPEN_MODE_RB			0x1
+#define FOPEN_MODE_RPLUS		0x2
+#define FOPEN_MODE_RPLUSB		0x3
+#define FOPEN_MODE_W			0x4
+#define FOPEN_MODE_WB			0x5
+#define FOPEN_MODE_WPLUS		0x6
+#define FOPEN_MODE_WPLUSB		0x7
+#define FOPEN_MODE_A			0x8
+#define FOPEN_MODE_AB			0x9
+#define FOPEN_MODE_APLUS		0xa
+#define FOPEN_MODE_APLUSB		0xb
+
+long semihosting_connection_supported(void);
+long semihosting_file_open(const char *file_name, size_t mode);
+long semihosting_file_seek(long file_handle, ssize_t offset);
+long semihosting_file_read(long file_handle, size_t *length, uintptr_t buffer);
+long semihosting_file_write(long file_handle,
+			    size_t *length,
+			    const uintptr_t buffer);
+long semihosting_file_close(long file_handle);
+long semihosting_file_length(long file_handle);
+long semihosting_system(char *command_line);
+long semihosting_get_flen(const char *file_name);
+long semihosting_download_file(const char *file_name,
+			       size_t buf_size,
+			       uintptr_t buf);
+void semihosting_write_char(char character);
+void semihosting_write_string(char *string);
+char semihosting_read_char(void);
+
+#endif /* __SEMIHOSTING_H__ */
diff --git a/uefi/arm-trusted-firmware/include/lib/spinlock.h b/uefi/arm-trusted-firmware/include/lib/spinlock.h
new file mode 100644
index 0000000..cb0bc3e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/lib/spinlock.h
@@ -0,0 +1,41 @@
+/*
+ * 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 __SPINLOCK_H__
+#define __SPINLOCK_H__
+
+typedef struct spinlock {
+	volatile unsigned int lock;
+} spinlock_t;
+
+void spin_lock(spinlock_t *lock);
+void spin_unlock(spinlock_t *lock);
+
+#endif /* __SPINLOCK_H__ */
diff --git a/uefi/arm-trusted-firmware/include/plat/common/plat_config.h b/uefi/arm-trusted-firmware/include/plat/common/plat_config.h
new file mode 100644
index 0000000..20d3c03
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/plat/common/plat_config.h
@@ -0,0 +1,78 @@
+/*
+ * 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 __PLAT_CONFIG_H__
+#define __PLAT_CONFIG_H__
+
+#define CONFIG_GICC_BASE_OFFSET		0x4
+
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+
+
+enum plat_config_flags {
+	/* Whether Base FVP memory map is in use */
+	CONFIG_BASE_MMAP		= 0x1,
+	/* Whether CCI should be enabled */
+	CONFIG_HAS_CCI			= 0x2,
+	/* Whether TZC should be configured */
+	CONFIG_HAS_TZC			= 0x4
+};
+
+typedef struct plat_config {
+	unsigned int gicd_base;
+	unsigned int gicc_base;
+	unsigned int gich_base;
+	unsigned int gicv_base;
+	unsigned int max_aff0;
+	unsigned int max_aff1;
+	unsigned long flags;
+} plat_config_t;
+
+inline const plat_config_t *get_plat_config();
+
+
+CASSERT(CONFIG_GICC_BASE_OFFSET == __builtin_offsetof(
+	plat_config_t, gicc_base),
+	assert_gicc_base_offset_mismatch);
+
+/* If used, plat_config must be defined and populated in the platform port*/
+extern plat_config_t plat_config;
+
+inline const plat_config_t *get_plat_config()
+{
+	return &plat_config;
+}
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __PLAT_CONFIG_H__ */
diff --git a/uefi/arm-trusted-firmware/include/plat/common/platform.h b/uefi/arm-trusted-firmware/include/plat/common/platform.h
new file mode 100644
index 0000000..66d7bc9
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/plat/common/platform.h
@@ -0,0 +1,200 @@
+/*
+ * 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 __PLATFORM_H__
+#define __PLATFORM_H__
+
+#include <stdint.h>
+
+
+/*******************************************************************************
+ * Forward declarations
+ ******************************************************************************/
+struct plat_pm_ops;
+struct meminfo;
+struct image_info;
+struct entry_point_info;
+struct bl31_params;
+
+/*******************************************************************************
+ * Function declarations
+ ******************************************************************************/
+/*******************************************************************************
+ * Mandatory common functions
+ ******************************************************************************/
+uint64_t plat_get_syscnt_freq(void);
+int plat_get_image_source(const char *image_name,
+			uintptr_t *dev_handle,
+			uintptr_t *image_spec);
+unsigned long plat_get_ns_image_entrypoint(void);
+
+/*******************************************************************************
+ * Mandatory interrupt management functions
+ ******************************************************************************/
+uint32_t plat_ic_get_pending_interrupt_id(void);
+uint32_t plat_ic_get_pending_interrupt_type(void);
+uint32_t plat_ic_acknowledge_interrupt(void);
+uint32_t plat_ic_get_interrupt_type(uint32_t id);
+void plat_ic_end_of_interrupt(uint32_t id);
+uint32_t plat_interrupt_type_to_line(uint32_t type,
+				     uint32_t security_state);
+
+/*******************************************************************************
+ * Optional common functions (may be overridden)
+ ******************************************************************************/
+unsigned int platform_get_core_pos(unsigned long mpidr);
+unsigned long platform_get_stack(unsigned long mpidr);
+void plat_report_exception(unsigned long);
+int plat_crash_console_init(void);
+int plat_crash_console_putc(int c);
+
+/*******************************************************************************
+ * Mandatory BL1 functions
+ ******************************************************************************/
+void bl1_early_platform_setup(void);
+void bl1_plat_arch_setup(void);
+void bl1_platform_setup(void);
+struct meminfo *bl1_plat_sec_mem_layout(void);
+
+/*
+ * This function allows the platform to change the entrypoint information for
+ * BL2, after BL1 has loaded BL2 into memory but before BL2 is executed.
+ */
+void bl1_plat_set_bl2_ep_info(struct image_info *image,
+			      struct entry_point_info *ep);
+
+/*******************************************************************************
+ * Optional BL1 functions (may be overridden)
+ ******************************************************************************/
+void bl1_init_bl2_mem_layout(const struct meminfo *bl1_mem_layout,
+			     struct meminfo *bl2_mem_layout);
+
+/*******************************************************************************
+ * Mandatory BL2 functions
+ ******************************************************************************/
+void bl2_early_platform_setup(struct meminfo *mem_layout);
+void bl2_plat_arch_setup(void);
+void bl2_platform_setup(void);
+struct meminfo *bl2_plat_sec_mem_layout(void);
+
+/*
+ * This function returns a pointer to the shared memory that the platform has
+ * kept aside to pass trusted firmware related information that BL3-1
+ * could need
+ */
+struct bl31_params *bl2_plat_get_bl31_params(void);
+
+/*
+ * This function returns a pointer to the shared memory that the platform
+ * has kept to point to entry point information of BL31 to BL2
+ */
+struct entry_point_info *bl2_plat_get_bl31_ep_info(void);
+
+/*
+ * This function flushes to main memory all the params that are
+ * passed to BL3-1
+ */
+void bl2_plat_flush_bl31_params(void);
+
+/*
+ * The next 2 functions allow the platform to change the entrypoint information
+ * for the mandatory 3rd level BL images, BL3-1 and BL3-3. This is done after
+ * BL2 has loaded those images into memory but before BL3-1 is executed.
+ */
+void bl2_plat_set_bl31_ep_info(struct image_info *image,
+			       struct entry_point_info *ep);
+
+void bl2_plat_set_bl33_ep_info(struct image_info *image,
+			       struct entry_point_info *ep);
+
+/* Gets the memory layout for BL3-3 */
+void bl2_plat_get_bl33_meminfo(struct meminfo *mem_info);
+
+/*******************************************************************************
+ * Conditionally mandatory BL2 functions: must be implemented if BL3-0 image
+ * is supported
+ ******************************************************************************/
+/* Gets the memory layout for BL3-0 */
+void bl2_plat_get_bl30_meminfo(struct meminfo *mem_info);
+
+/*
+ * 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.
+ */
+int bl2_plat_handle_bl30(struct image_info *bl30_image_info);
+
+/*******************************************************************************
+ * Conditionally mandatory BL2 functions: must be implemented if BL3-2 image
+ * is supported
+ ******************************************************************************/
+void bl2_plat_set_bl32_ep_info(struct image_info *image,
+			       struct entry_point_info *ep);
+
+/* Gets the memory layout for BL3-2 */
+void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info);
+
+/*******************************************************************************
+ * Optional BL2 functions (may be overridden)
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Mandatory BL3-1 functions
+ ******************************************************************************/
+void bl31_early_platform_setup(struct bl31_params *from_bl2,
+				void *plat_params_from_bl2);
+void bl31_plat_arch_setup(void);
+void bl31_platform_setup(void);
+struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type);
+struct image_info *bl31_plat_get_next_image_image_info(uint32_t type);
+
+/*******************************************************************************
+ * Mandatory PSCI functions (BL3-1)
+ ******************************************************************************/
+int platform_setup_pm(const struct plat_pm_ops **);
+int plat_get_max_afflvl(void);
+unsigned int plat_get_aff_count(unsigned int, unsigned long);
+unsigned int plat_get_aff_state(unsigned int, unsigned long);
+
+/*******************************************************************************
+ * Optional BL3-1 functions (may be overridden)
+ ******************************************************************************/
+void bl31_plat_enable_mmu(uint32_t flags);
+
+/*******************************************************************************
+ * Optional BL3-2 functions (may be overridden)
+ ******************************************************************************/
+void bl32_plat_enable_mmu(uint32_t flags);
+
+/*******************************************************************************
+ * Trusted Boot functions
+ ******************************************************************************/
+int plat_match_rotpk(const unsigned char *, unsigned int);
+
+#endif /* __PLATFORM_H__ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/assert.h b/uefi/arm-trusted-firmware/include/stdlib/assert.h
new file mode 100644
index 0000000..5621f8c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/assert.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)assert.h	8.2 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+
+/*
+ * Unlike other ANSI header files, <assert.h> may usefully be included
+ * multiple times, with and without NDEBUG defined.
+ */
+
+#undef assert
+#undef _assert
+
+#ifdef NDEBUG
+#define	assert(e)	((void)0)
+#define	_assert(e)	((void)0)
+#else
+#define	_assert(e)	assert(e)
+
+#define	assert(e)	((e) ? (void)0 : __assert(__func__, __FILE__, \
+			    __LINE__, #e))
+#endif /* NDEBUG */
+
+#ifndef _ASSERT_H_
+#define _ASSERT_H_
+__BEGIN_DECLS
+void __assert(const char *, const char *, int, const char *) __dead2;
+__END_DECLS
+#endif /* !_ASSERT_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/inttypes.h b/uefi/arm-trusted-firmware/include/stdlib/inttypes.h
new file mode 100644
index 0000000..269f3e7
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/inttypes.h
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _INTTYPES_H_
+#define	_INTTYPES_H_
+
+#include <machine/_inttypes.h>
+#include <sys/stdint.h>
+
+typedef struct {
+	intmax_t	quot;		/* Quotient. */
+	intmax_t	rem;		/* Remainder. */
+} imaxdiv_t;
+
+__BEGIN_DECLS
+#ifdef _XLOCALE_H_
+#include <xlocale/_inttypes.h>
+#endif
+intmax_t	imaxabs(intmax_t) __pure2;
+imaxdiv_t	imaxdiv(intmax_t, intmax_t) __pure2;
+
+intmax_t	strtoimax(const char *__restrict, char **__restrict, int);
+uintmax_t	strtoumax(const char *__restrict, char **__restrict, int);
+
+__END_DECLS
+
+#endif /* !_INTTYPES_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/machine/_inttypes.h b/uefi/arm-trusted-firmware/include/stdlib/machine/_inttypes.h
new file mode 100644
index 0000000..8dd07d6
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/machine/_inttypes.h
@@ -0,0 +1,39 @@
+/*
+ * 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 _MACHINE_INTTYPES_H_
+#define _MACHINE_INTTYPES_H_
+
+/*
+ * Trusted Firmware does not depend on any definitions in this file. Content
+ * will be added as needed.
+ */
+
+#endif /* !_MACHINE_INTTYPES_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/machine/_limits.h b/uefi/arm-trusted-firmware/include/stdlib/machine/_limits.h
new file mode 100644
index 0000000..49a768b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/machine/_limits.h
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)limits.h	8.3 (Berkeley) 1/4/94
+ * $FreeBSD$
+ */
+
+#ifndef	_MACHINE__LIMITS_H_
+#define	_MACHINE__LIMITS_H_
+
+/*
+ * According to ANSI (section 2.2.4.2), the values below must be usable by
+ * #if preprocessing directives.  Additionally, the expression must have the
+ * same type as would an expression that is an object of the corresponding
+ * type converted according to the integral promotions.  The subtraction for
+ * INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an
+ * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2).
+ */
+
+#define	__CHAR_BIT	8		/* number of bits in a char */
+
+#define	__SCHAR_MAX	0x7f		/* max value for a signed char */
+#define	__SCHAR_MIN	(-0x7f-1)	/* min value for a signed char */
+
+#define	__UCHAR_MAX	0xff		/* max value for an unsigned char */
+
+#define	__USHRT_MAX	0xffff		/* max value for an unsigned short */
+#define	__SHRT_MAX	0x7fff		/* max value for a short */
+#define	__SHRT_MIN	(-0x7fff-1)	/* min value for a short */
+
+#define	__UINT_MAX	0xffffffff	/* max value for an unsigned int */
+#define	__INT_MAX	0x7fffffff	/* max value for an int */
+#define	__INT_MIN	(-0x7fffffff-1)	/* min value for an int */
+
+#define	__ULONG_MAX	0xffffffffffffffff	/* max for an unsigned long */
+#define	__LONG_MAX	0x7fffffffffffffff	/* max for a long */
+#define	__LONG_MIN	(-0x7fffffffffffffff-1) /* min for a long */
+
+/* Long longs have the same size but not the same type as longs. */
+					/* max for an unsigned long long */
+#define	__ULLONG_MAX	0xffffffffffffffffULL
+#define	__LLONG_MAX	0x7fffffffffffffffLL	/* max for a long long */
+#define	__LLONG_MIN	(-0x7fffffffffffffffLL-1) /* min for a long long */
+
+#define	__SSIZE_MAX	__LONG_MAX	/* max value for a ssize_t */
+
+#define	__SIZE_T_MAX	__ULONG_MAX	/* max value for a size_t */
+
+#define	__OFF_MAX	__LONG_MAX	/* max value for an off_t */
+#define	__OFF_MIN	__LONG_MIN	/* min value for an off_t */
+
+/* Quads and longs are the same size.  Ensure they stay in sync. */
+#define	__UQUAD_MAX	(__ULONG_MAX)	/* max value for a uquad_t */
+#define	__QUAD_MAX	(__LONG_MAX)	/* max value for a quad_t */
+#define	__QUAD_MIN	(__LONG_MIN)	/* min value for a quad_t */
+
+#define	__LONG_BIT	64
+#define	__WORD_BIT	32
+
+/* Minimum signal stack size. */
+#define	__MINSIGSTKSZ	(1024 * 4)
+
+#endif /* !_MACHINE__LIMITS_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/machine/_stdint.h b/uefi/arm-trusted-firmware/include/stdlib/machine/_stdint.h
new file mode 100644
index 0000000..e36c659
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/machine/_stdint.h
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2001, 2002 Mike Barcroft <mike@FreeBSD.org>
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	_MACHINE__STDINT_H_
+#define	_MACHINE__STDINT_H_
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+
+#define	INT8_C(c)		(c)
+#define	INT16_C(c)		(c)
+#define	INT32_C(c)		(c)
+#define	INT64_C(c)		(c ## L)
+
+#define	UINT8_C(c)		(c)
+#define	UINT16_C(c)		(c)
+#define	UINT32_C(c)		(c ## U)
+#define	UINT64_C(c)		(c ## UL)
+
+#define	INTMAX_C(c)		INT64_C(c)
+#define	UINTMAX_C(c)		UINT64_C(c)
+
+#endif /* !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) */
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.1 Limits of exact-width integer types
+ */
+/* Minimum values of exact-width signed integer types. */
+#define	INT8_MIN	(-0x7f-1)
+#define	INT16_MIN	(-0x7fff-1)
+#define	INT32_MIN	(-0x7fffffff-1)
+#define	INT64_MIN	(-0x7fffffffffffffffL-1)
+
+/* Maximum values of exact-width signed integer types. */
+#define	INT8_MAX	0x7f
+#define	INT16_MAX	0x7fff
+#define	INT32_MAX	0x7fffffff
+#define	INT64_MAX	0x7fffffffffffffffL
+
+/* Maximum values of exact-width unsigned integer types. */
+#define	UINT8_MAX	0xff
+#define	UINT16_MAX	0xffff
+#define	UINT32_MAX	0xffffffffU
+#define	UINT64_MAX	0xffffffffffffffffUL
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.2  Limits of minimum-width integer types
+ */
+/* Minimum values of minimum-width signed integer types. */
+#define	INT_LEAST8_MIN	INT8_MIN
+#define	INT_LEAST16_MIN	INT16_MIN
+#define	INT_LEAST32_MIN	INT32_MIN
+#define	INT_LEAST64_MIN	INT64_MIN
+
+/* Maximum values of minimum-width signed integer types. */
+#define	INT_LEAST8_MAX	INT8_MAX
+#define	INT_LEAST16_MAX	INT16_MAX
+#define	INT_LEAST32_MAX	INT32_MAX
+#define	INT_LEAST64_MAX	INT64_MAX
+
+/* Maximum values of minimum-width unsigned integer types. */
+#define	UINT_LEAST8_MAX	 UINT8_MAX
+#define	UINT_LEAST16_MAX UINT16_MAX
+#define	UINT_LEAST32_MAX UINT32_MAX
+#define	UINT_LEAST64_MAX UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.3  Limits of fastest minimum-width integer types
+ */
+/* Minimum values of fastest minimum-width signed integer types. */
+#define	INT_FAST8_MIN	INT32_MIN
+#define	INT_FAST16_MIN	INT32_MIN
+#define	INT_FAST32_MIN	INT32_MIN
+#define	INT_FAST64_MIN	INT64_MIN
+
+/* Maximum values of fastest minimum-width signed integer types. */
+#define	INT_FAST8_MAX	INT32_MAX
+#define	INT_FAST16_MAX	INT32_MAX
+#define	INT_FAST32_MAX	INT32_MAX
+#define	INT_FAST64_MAX	INT64_MAX
+
+/* Maximum values of fastest minimum-width unsigned integer types. */
+#define	UINT_FAST8_MAX	UINT32_MAX
+#define	UINT_FAST16_MAX	UINT32_MAX
+#define	UINT_FAST32_MAX	UINT32_MAX
+#define	UINT_FAST64_MAX	UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.4  Limits of integer types capable of holding object pointers
+ */
+#define	INTPTR_MIN	INT64_MIN
+#define	INTPTR_MAX	INT64_MAX
+#define	UINTPTR_MAX	UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.5  Limits of greatest-width integer types
+ */
+#define	INTMAX_MIN	INT64_MIN
+#define	INTMAX_MAX	INT64_MAX
+#define	UINTMAX_MAX	UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.3  Limits of other integer types
+ */
+/* Limits of ptrdiff_t. */
+#define	PTRDIFF_MIN	INT64_MIN	
+#define	PTRDIFF_MAX	INT64_MAX
+
+/* Limits of sig_atomic_t. */
+#define	SIG_ATOMIC_MIN	INT32_MIN
+#define	SIG_ATOMIC_MAX	INT32_MAX
+
+/* Limit of size_t. */
+#define	SIZE_MAX	UINT64_MAX
+
+#ifndef WCHAR_MIN /* Also possibly defined in <wchar.h> */
+/* Limits of wchar_t. */
+#define	WCHAR_MIN	INT32_MIN
+#define	WCHAR_MAX	INT32_MAX
+#endif
+
+/* Limits of wint_t. */
+#define	WINT_MIN	INT32_MIN
+#define	WINT_MAX	INT32_MAX
+
+#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */
+
+#endif /* !_MACHINE__STDINT_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/machine/_types.h b/uefi/arm-trusted-firmware/include/stdlib/machine/_types.h
new file mode 100644
index 0000000..7e993c4
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/machine/_types.h
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	From: @(#)ansi.h	8.2 (Berkeley) 1/4/94
+ *	From: @(#)types.h	8.3 (Berkeley) 1/5/94
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE__TYPES_H_
+#define	_MACHINE__TYPES_H_
+
+#ifndef _SYS_CDEFS_H_
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+
+/*
+ * Basic types upon which most other types are built.
+ */
+typedef	__signed char		__int8_t;
+typedef	unsigned char		__uint8_t;
+typedef	short			__int16_t;
+typedef	unsigned short		__uint16_t;
+typedef	int			__int32_t;
+typedef	unsigned int		__uint32_t;
+typedef	long			__int64_t;
+typedef	unsigned long		__uint64_t;
+
+/*
+ * Standard type definitions.
+ */
+typedef	__int32_t	__clock_t;		/* clock()... */
+typedef	__int64_t	__critical_t;
+typedef	double		__double_t;
+typedef	float		__float_t;
+typedef	__int64_t	__intfptr_t;
+typedef	__int64_t	__intmax_t;
+typedef	__int64_t	__intptr_t;
+typedef	__int32_t	__int_fast8_t;
+typedef	__int32_t	__int_fast16_t;
+typedef	__int32_t	__int_fast32_t;
+typedef	__int64_t	__int_fast64_t;
+typedef	__int8_t	__int_least8_t;
+typedef	__int16_t	__int_least16_t;
+typedef	__int32_t	__int_least32_t;
+typedef	__int64_t	__int_least64_t;
+typedef	__int64_t	__ptrdiff_t;		/* ptr1 - ptr2 */
+typedef	__int64_t	__register_t;
+typedef	__int64_t	__segsz_t;		/* segment size (in pages) */
+typedef	__uint64_t	__size_t;		/* sizeof() */
+typedef	__int64_t	__ssize_t;		/* byte count or error */
+typedef	__int64_t	__time_t;		/* time()... */
+typedef	__uint64_t	__uintfptr_t;
+typedef	__uint64_t	__uintmax_t;
+typedef	__uint64_t	__uintptr_t;
+typedef	__uint32_t	__uint_fast8_t;
+typedef	__uint32_t	__uint_fast16_t;
+typedef	__uint32_t	__uint_fast32_t;
+typedef	__uint64_t	__uint_fast64_t;
+typedef	__uint8_t	__uint_least8_t;
+typedef	__uint16_t	__uint_least16_t;
+typedef	__uint32_t	__uint_least32_t;
+typedef	__uint64_t	__uint_least64_t;
+typedef	__uint64_t	__u_register_t;
+typedef	__uint64_t	__vm_offset_t;
+typedef	__int64_t	__vm_ooffset_t;
+typedef	__uint64_t	__vm_paddr_t;
+typedef	__uint64_t	__vm_pindex_t;
+typedef	__uint64_t	__vm_size_t;
+
+/*
+ * Unusual type definitions.
+ */
+#ifdef __GNUCLIKE_BUILTIN_VARARGS
+typedef __builtin_va_list	__va_list;	/* internally known to gcc */
+#else
+typedef	char *			__va_list;
+#endif /* __GNUCLIKE_BUILTIN_VARARGS */
+#if defined(__GNUCLIKE_BUILTIN_VAALIST) && !defined(__GNUC_VA_LIST) \
+    && !defined(__NO_GNUC_VA_LIST)
+#define __GNUC_VA_LIST
+typedef __va_list		__gnuc_va_list;	/* compatibility w/GNU headers*/
+#endif
+
+#endif /* !_MACHINE__TYPES_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/stddef.h b/uefi/arm-trusted-firmware/include/stdlib/stddef.h
new file mode 100644
index 0000000..ea88214
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/stddef.h
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)stddef.h	8.1 (Berkeley) 6/2/93
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _STDDEF_H_
+#define _STDDEF_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+typedef	__ptrdiff_t	ptrdiff_t;
+
+#if __BSD_VISIBLE
+#ifndef _RUNE_T_DECLARED
+typedef	__rune_t	rune_t;
+#define	_RUNE_T_DECLARED
+#endif
+#endif
+
+#ifndef _SIZE_T_DECLARED
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#endif
+
+#ifndef	__cplusplus
+#ifndef _WCHAR_T_DECLARED
+typedef	__wchar_t	wchar_t;
+#define	_WCHAR_T_DECLARED
+#endif
+#endif
+
+#define	offsetof(type, member)	__offsetof(type, member)
+
+#endif /* _STDDEF_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/stdio.h b/uefi/arm-trusted-firmware/include/stdlib/stdio.h
new file mode 100644
index 0000000..60e081b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/stdio.h
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)stdio.h	8.5 (Berkeley) 4/29/95
+ * $FreeBSD$
+ */
+
+/*
+ * Portions copyright (c) 2013-2014, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+
+#ifndef	_STDIO_H_
+#define	_STDIO_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#ifndef _SIZE_T_DECLARED
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#endif
+
+#ifndef _SSIZE_T_DECLARED
+#define	_SSIZE_T_DECLARED
+typedef	__ssize_t	ssize_t;
+#endif
+
+#define	EOF	(-1)
+
+int	 printf(const char * __restrict, ...);
+int	 putchar(int);
+int	 puts(const char *);
+int	 sprintf(char * __restrict, const char * __restrict, ...);
+int	 vsprintf(char * __restrict, const char * __restrict,
+	   __va_list);
+
+int	 sscanf(const char *__restrict, char const *__restrict, ...);
+
+#if __ISO_C_VISIBLE >= 1999
+int	 snprintf(char * __restrict, size_t, const char * __restrict,
+	   ...) __printflike(3, 4);
+int	 vsnprintf(char * __restrict, size_t, const char * __restrict,
+	   __va_list) __printflike(3, 0);
+#endif
+
+#endif /* !_STDIO_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/stdlib.h b/uefi/arm-trusted-firmware/include/stdlib/stdlib.h
new file mode 100644
index 0000000..b1ac1bf
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/stdlib.h
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)stdlib.h	8.5 (Berkeley) 5/19/95
+ * $FreeBSD$
+ */
+
+#ifndef _STDLIB_H_
+#define	_STDLIB_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#if __BSD_VISIBLE
+#ifndef _RUNE_T_DECLARED
+typedef	__rune_t	rune_t;
+#define	_RUNE_T_DECLARED
+#endif
+#endif
+
+#ifndef _SIZE_T_DECLARED
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#endif
+
+typedef struct {
+	int	quot;		/* quotient */
+	int	rem;		/* remainder */
+} div_t;
+
+typedef struct {
+	long	quot;
+	long	rem;
+} ldiv_t;
+
+#define	EXIT_FAILURE	1
+#define	EXIT_SUCCESS	0
+
+#define	RAND_MAX	0x7ffffffd
+
+__BEGIN_DECLS
+#ifdef _XLOCALE_H_
+#include <xlocale/_stdlib.h>
+#endif
+extern int __mb_cur_max;
+extern int ___mb_cur_max(void);
+#define	MB_CUR_MAX	(___mb_cur_max())
+
+_Noreturn void	 abort(void);
+int	 abs(int) __pure2;
+int	 atexit(void (*)(void));
+double	 atof(const char *);
+int	 atoi(const char *);
+long	 atol(const char *);
+void	*bsearch(const void *, const void *, size_t,
+	    size_t, int (*)(const void *, const void *));
+void	*calloc(size_t, size_t) __malloc_like;
+div_t	 div(int, int) __pure2;
+_Noreturn void	 exit(int);
+void	 free(void *);
+char	*getenv(const char *);
+long	 labs(long) __pure2;
+ldiv_t	 ldiv(long, long) __pure2;
+void	*malloc(size_t) __malloc_like;
+int	 mblen(const char *, size_t);
+void	 qsort(void *, size_t, size_t,
+	    int (*)(const void *, const void *));
+int	 rand(void);
+void	*realloc(void *, size_t);
+void	 srand(unsigned);
+double	 strtod(const char *__restrict, char **__restrict);
+float	 strtof(const char *__restrict, char **__restrict);
+long	 strtol(const char *__restrict, char **__restrict, int);
+long double
+	 strtold(const char *__restrict, char **__restrict);
+unsigned long
+	 strtoul(const char *__restrict, char **__restrict, int);
+int	 system(const char *);
+
+/*
+ * Functions added in C99 which we make conditionally available in the
+ * BSD^C89 namespace if the compiler supports `long long'.
+ * The #if test is more complicated than it ought to be because
+ * __BSD_VISIBLE implies __ISO_C_VISIBLE == 1999 *even if* `long long'
+ * is not supported in the compilation environment (which therefore means
+ * that it can't really be ISO C99).
+ *
+ * (The only other extension made by C99 in thie header is _Exit().)
+ */
+#if __ISO_C_VISIBLE >= 1999
+#ifdef __LONG_LONG_SUPPORTED
+/* LONGLONG */
+typedef struct {
+	long long quot;
+	long long rem;
+} lldiv_t;
+
+/* LONGLONG */
+long long
+	 atoll(const char *);
+/* LONGLONG */
+long long
+	 llabs(long long) __pure2;
+/* LONGLONG */
+lldiv_t	 lldiv(long long, long long) __pure2;
+/* LONGLONG */
+long long
+	 strtoll(const char *__restrict, char **__restrict, int);
+/* LONGLONG */
+unsigned long long
+	 strtoull(const char *__restrict, char **__restrict, int);
+#endif /* __LONG_LONG_SUPPORTED */
+
+_Noreturn void	 _Exit(int);
+#endif /* __ISO_C_VISIBLE >= 1999 */
+
+/*
+ * If we're in a mode greater than C99, expose C11 functions.
+ */
+#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
+void *aligned_alloc(size_t, size_t) __malloc_like;
+int	at_quick_exit(void (*)(void));
+_Noreturn void
+	quick_exit(int);
+#endif /* __ISO_C_VISIBLE >= 2011 */
+/*
+ * Extensions made by POSIX relative to C.
+ */
+#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE
+char	*realpath(const char *__restrict, char *__restrict);
+#endif
+#if __POSIX_VISIBLE >= 199506
+int	 rand_r(unsigned *);			/* (TSF) */
+#endif
+#if __POSIX_VISIBLE >= 200112
+int	 posix_memalign(void **, size_t, size_t); /* (ADV) */
+int	 setenv(const char *, const char *, int);
+int	 unsetenv(const char *);
+#endif
+
+#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE
+int	 getsubopt(char **, char *const *, char **);
+#ifndef _MKDTEMP_DECLARED
+char	*mkdtemp(char *);
+#define	_MKDTEMP_DECLARED
+#endif
+#ifndef _MKSTEMP_DECLARED
+int	 mkstemp(char *);
+#define	_MKSTEMP_DECLARED
+#endif
+#endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */
+
+/*
+ * The only changes to the XSI namespace in revision 6 were the deletion
+ * of the ttyslot() and valloc() functions, which FreeBSD never declared
+ * in this header.  For revision 7, ecvt(), fcvt(), and gcvt(), which
+ * FreeBSD also does not have, and mktemp(), are to be deleted.
+ */
+#if __XSI_VISIBLE
+/* XXX XSI requires pollution from <sys/wait.h> here.  We'd rather not. */
+long	 a64l(const char *);
+double	 drand48(void);
+/* char	*ecvt(double, int, int * __restrict, int * __restrict); */
+double	 erand48(unsigned short[3]);
+/* char	*fcvt(double, int, int * __restrict, int * __restrict); */
+/* char	*gcvt(double, int, int * __restrict, int * __restrict); */
+int	 grantpt(int);
+char	*initstate(unsigned long /* XSI requires u_int */, char *, long);
+long	 jrand48(unsigned short[3]);
+char	*l64a(long);
+void	 lcong48(unsigned short[7]);
+long	 lrand48(void);
+#if !defined(_MKTEMP_DECLARED) && (__BSD_VISIBLE || __XSI_VISIBLE <= 600)
+char	*mktemp(char *);
+#define	_MKTEMP_DECLARED
+#endif
+long	 mrand48(void);
+long	 nrand48(unsigned short[3]);
+int	 posix_openpt(int);
+char	*ptsname(int);
+int	 putenv(char *);
+long	 random(void);
+unsigned short
+	*seed48(unsigned short[3]);
+#ifndef _SETKEY_DECLARED
+int	 setkey(const char *);
+#define	_SETKEY_DECLARED
+#endif
+char	*setstate(/* const */ char *);
+void	 srand48(long);
+void	 srandom(unsigned long);
+int	 unlockpt(int);
+#endif /* __XSI_VISIBLE */
+
+#if __BSD_VISIBLE
+extern const char *malloc_conf;
+extern void (*malloc_message)(void *, const char *);
+
+/*
+ * The alloca() function can't be implemented in C, and on some
+ * platforms it can't be implemented at all as a callable function.
+ * The GNU C compiler provides a built-in alloca() which we can use;
+ * in all other cases, provide a prototype, mainly to pacify various
+ * incarnations of lint.  On platforms where alloca() is not in libc,
+ * programs which use it will fail to link when compiled with non-GNU
+ * compilers.
+ */
+#if __GNUC__ >= 2 || defined(__INTEL_COMPILER)
+#undef  alloca	/* some GNU bits try to get cute and define this on their own */
+#define alloca(sz) __builtin_alloca(sz)
+#elif defined(lint)
+void	*alloca(size_t);
+#endif
+
+void	 abort2(const char *, int, void **) __dead2;
+__uint32_t
+	 arc4random(void);
+void	 arc4random_addrandom(unsigned char *, int);
+void	 arc4random_buf(void *, size_t);
+void	 arc4random_stir(void);
+__uint32_t
+	 arc4random_uniform(__uint32_t);
+#ifdef __BLOCKS__
+int	 atexit_b(void (^)(void));
+void	*bsearch_b(const void *, const void *, size_t,
+	    size_t, int (^)(const void *, const void *));
+#endif
+char	*getbsize(int *, long *);
+					/* getcap(3) functions */
+char	*cgetcap(char *, const char *, int);
+int	 cgetclose(void);
+int	 cgetent(char **, char **, const char *);
+int	 cgetfirst(char **, char **);
+int	 cgetmatch(const char *, const char *);
+int	 cgetnext(char **, char **);
+int	 cgetnum(char *, const char *, long *);
+int	 cgetset(const char *);
+int	 cgetstr(char *, const char *, char **);
+int	 cgetustr(char *, const char *, char **);
+
+int	 daemon(int, int);
+char	*devname(__dev_t, __mode_t);
+char 	*devname_r(__dev_t, __mode_t, char *, int);
+char	*fdevname(int);
+char 	*fdevname_r(int, char *, int);
+int	 getloadavg(double [], int);
+const char *
+	 getprogname(void);
+
+int	 heapsort(void *, size_t, size_t, int (*)(const void *, const void *));
+#ifdef __BLOCKS__
+int	 heapsort_b(void *, size_t, size_t, int (^)(const void *, const void *));
+void	 qsort_b(void *, size_t, size_t,
+	    int (^)(const void *, const void *));
+#endif
+int	 l64a_r(long, char *, int);
+int	 mergesort(void *, size_t, size_t, int (*)(const void *, const void *));
+#ifdef __BLOCKS__
+int	 mergesort_b(void *, size_t, size_t, int (^)(const void *, const void *));
+#endif
+int	 mkostemp(char *, int);
+int	 mkostemps(char *, int, int);
+void	 qsort_r(void *, size_t, size_t, void *,
+	    int (*)(void *, const void *, const void *));
+int	 radixsort(const unsigned char **, int, const unsigned char *,
+	    unsigned);
+void    *reallocf(void *, size_t);
+int	 rpmatch(const char *);
+void	 setprogname(const char *);
+int	 sradixsort(const unsigned char **, int, const unsigned char *,
+	    unsigned);
+void	 sranddev(void);
+void	 srandomdev(void);
+long long
+	strtonum(const char *, long long, long long, const char **);
+
+/* Deprecated interfaces, to be removed in FreeBSD 6.0. */
+__int64_t
+	 strtoq(const char *, char **, int);
+__uint64_t
+	 strtouq(const char *, char **, int);
+
+extern char *suboptarg;			/* getsubopt(3) external variable */
+#endif /* __BSD_VISIBLE */
+__END_DECLS
+
+#endif /* !_STDLIB_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/string.h b/uefi/arm-trusted-firmware/include/stdlib/string.h
new file mode 100644
index 0000000..61e8102
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/string.h
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)string.h	8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+/*
+ * Portions copyright (c) 2013-2014, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef _STRING_H_
+#define	_STRING_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#ifndef _SIZE_T_DECLARED
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#endif
+
+__BEGIN_DECLS
+
+void	*memchr(const void *, int, size_t) __pure;
+int	 memcmp(const void *, const void *, size_t) __pure;
+void	*memcpy(void * __restrict, const void * __restrict, size_t);
+void	*memmove(void *, const void *, size_t);
+void	*memset(void *, int, size_t);
+
+char	*strchr(const char *, int) __pure;
+int	 strcmp(const char *, const char *) __pure;
+size_t	 strlen(const char *) __pure;
+int	 strncmp(const char *, const char *, size_t) __pure;
+int	 strcasecmp(const char *, const char *);
+
+__END_DECLS
+
+#endif /* _STRING_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/strings.h b/uefi/arm-trusted-firmware/include/stdlib/strings.h
new file mode 100644
index 0000000..2210df0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/strings.h
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _STRINGS_H_
+#define	_STRINGS_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _SIZE_T_DECLARED
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#endif
+
+__BEGIN_DECLS
+#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112
+int	 bcmp(const void *, const void *, size_t) __pure;	/* LEGACY */
+void	 bcopy(const void *, void *, size_t);			/* LEGACY */
+void	 bzero(void *, size_t);					/* LEGACY */
+#endif
+#if __BSD_VISIBLE
+void	 explicit_bzero(void *, size_t);
+#endif
+#if __XSI_VISIBLE
+int	 ffs(int) __pure2;
+#endif
+#if __BSD_VISIBLE
+int	 ffsl(long) __pure2;
+int	 ffsll(long long) __pure2;
+int	 fls(int) __pure2;
+int	 flsl(long) __pure2;
+int	 flsll(long long) __pure2;
+#endif
+#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112
+char	*index(const char *, int) __pure;			/* LEGACY */
+char	*rindex(const char *, int) __pure;			/* LEGACY */
+#endif
+int	 strcasecmp(const char *, const char *) __pure;
+int	 strncasecmp(const char *, const char *, size_t) __pure;
+
+#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_)
+#include <xlocale/_strings.h>
+#endif
+__END_DECLS
+
+#endif /* _STRINGS_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/_null.h b/uefi/arm-trusted-firmware/include/stdlib/sys/_null.h
new file mode 100644
index 0000000..92706c6
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/_null.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef NULL
+
+#if !defined(__cplusplus)
+#define	NULL	((void *)0)
+#else
+#if __cplusplus >= 201103L
+#define	NULL	nullptr
+#elif defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4
+#define	NULL	__null
+#else
+#if defined(__LP64__)
+#define	NULL	(0L)
+#else
+#define	NULL	0
+#endif	/* __LP64__ */
+#endif	/* __GNUG__ */
+#endif	/* !__cplusplus */
+
+#endif
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/_stdint.h b/uefi/arm-trusted-firmware/include/stdlib/sys/_stdint.h
new file mode 100644
index 0000000..d0f9249
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/_stdint.h
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2011 David E. O'Brien <obrien@FreeBSD.org>
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__STDINT_H_
+#define _SYS__STDINT_H_
+
+#ifndef _INT8_T_DECLARED
+typedef	__int8_t		int8_t;
+#define	_INT8_T_DECLARED
+#endif
+
+#ifndef _INT16_T_DECLARED
+typedef	__int16_t		int16_t;
+#define	_INT16_T_DECLARED
+#endif
+
+#ifndef _INT32_T_DECLARED
+typedef	__int32_t		int32_t;
+#define	_INT32_T_DECLARED
+#endif
+
+#ifndef _INT64_T_DECLARED
+typedef	__int64_t		int64_t;
+#define	_INT64_T_DECLARED
+#endif
+
+#ifndef _UINT8_T_DECLARED
+typedef	__uint8_t		uint8_t;
+#define	_UINT8_T_DECLARED
+#endif
+
+#ifndef _UINT16_T_DECLARED
+typedef	__uint16_t		uint16_t;
+#define	_UINT16_T_DECLARED
+#endif
+
+#ifndef _UINT32_T_DECLARED
+typedef	__uint32_t		uint32_t;
+#define	_UINT32_T_DECLARED
+#endif
+
+#ifndef _UINT64_T_DECLARED
+typedef	__uint64_t		uint64_t;
+#define	_UINT64_T_DECLARED
+#endif
+
+#ifndef _INTPTR_T_DECLARED
+typedef	__intptr_t		intptr_t;
+#define	_INTPTR_T_DECLARED
+#endif
+#ifndef _UINTPTR_T_DECLARED
+typedef	__uintptr_t		uintptr_t;
+#define	_UINTPTR_T_DECLARED
+#endif
+
+#endif /* !_SYS__STDINT_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/_timespec.h b/uefi/arm-trusted-firmware/include/stdlib/sys/_timespec.h
new file mode 100644
index 0000000..d51559c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/_timespec.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)time.h	8.5 (Berkeley) 5/4/95
+ * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp
+ *	$FreeBSD$
+ */
+
+#ifndef _SYS__TIMESPEC_H_
+#define	_SYS__TIMESPEC_H_
+
+#include <sys/_types.h>
+
+#ifndef _TIME_T_DECLARED
+typedef	__time_t	time_t;
+#define	_TIME_T_DECLARED
+#endif
+
+struct timespec {
+	time_t	tv_sec;		/* seconds */
+	long	tv_nsec;	/* and nanoseconds */
+};
+
+#endif /* !_SYS__TIMESPEC_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/_types.h b/uefi/arm-trusted-firmware/include/stdlib/sys/_types.h
new file mode 100644
index 0000000..c59afd3
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/_types.h
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__TYPES_H_
+#define _SYS__TYPES_H_
+
+#include <sys/cdefs.h>
+#include <machine/_types.h>
+
+/*
+ * Standard type definitions.
+ */
+typedef	__uint32_t	__blksize_t;	/* file block size */
+typedef	__int64_t	__blkcnt_t;	/* file block count */
+typedef	__int32_t	__clockid_t;	/* clock_gettime()... */
+typedef	__uint64_t	__cap_rights_t;	/* capability rights */
+typedef	__uint32_t	__fflags_t;	/* file flags */
+typedef	__uint64_t	__fsblkcnt_t;
+typedef	__uint64_t	__fsfilcnt_t;
+typedef	__uint32_t	__gid_t;
+typedef	__int64_t	__id_t;		/* can hold a gid_t, pid_t, or uid_t */
+typedef	__uint32_t	__ino_t;	/* inode number */
+typedef	long		__key_t;	/* IPC key (for Sys V IPC) */
+typedef	__int32_t	__lwpid_t;	/* Thread ID (a.k.a. LWP) */
+typedef	__uint16_t	__mode_t;	/* permissions */
+typedef	int		__accmode_t;	/* access permissions */
+typedef	int		__nl_item;
+typedef	__uint16_t	__nlink_t;	/* link count */
+typedef	__int64_t	__off_t;	/* file offset */
+typedef	__int32_t	__pid_t;	/* process [group] */
+typedef	__int64_t	__rlim_t;	/* resource limit - intentionally */
+					/* signed, because of legacy code */
+					/* that uses -1 for RLIM_INFINITY */
+typedef	__uint8_t	__sa_family_t;
+typedef	__uint32_t	__socklen_t;
+typedef	long		__suseconds_t;	/* microseconds (signed) */
+typedef	struct __timer	*__timer_t;	/* timer_gettime()... */
+typedef	struct __mq	*__mqd_t;	/* mq_open()... */
+typedef	__uint32_t	__uid_t;
+typedef	unsigned int	__useconds_t;	/* microseconds (unsigned) */
+typedef	int		__cpuwhich_t;	/* which parameter for cpuset. */
+typedef	int		__cpulevel_t;	/* level parameter for cpuset. */
+typedef int		__cpusetid_t;	/* cpuset identifier. */
+
+/*
+ * Unusual type definitions.
+ */
+/*
+ * rune_t is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''.  Two things are happening here.  It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used.  Also,
+ * it looks like 10646 will be a 31 bit standard.  This means that if your
+ * ints cannot hold 32 bits, you will be in trouble.  The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use __ct_rune_t instead of int.
+ *
+ * NOTE: rune_t is not covered by ANSI nor other standards, and should not
+ * be instantiated outside of lib/libc/locale.  Use wchar_t.  wchar_t and
+ * rune_t must be the same type.  Also, wint_t must be no narrower than
+ * wchar_t, and should be able to hold all members of the largest
+ * character set plus one extra value (WEOF), and must be at least 16 bits.
+ */
+typedef	int		__ct_rune_t;	/* arg type for ctype funcs */
+typedef	__ct_rune_t	__rune_t;	/* rune_t (see above) */
+typedef	__ct_rune_t	__wchar_t;	/* wchar_t (see above) */
+typedef	__ct_rune_t	__wint_t;	/* wint_t (see above) */
+
+typedef	__uint32_t	__dev_t;	/* device number */
+
+typedef	__uint32_t	__fixpt_t;	/* fixed point number */
+
+/*
+ * mbstate_t is an opaque object to keep conversion state during multibyte
+ * stream conversions.
+ */
+typedef union {
+	char		__mbstate8[128];
+	__int64_t	_mbstateL;	/* for alignment */
+} __mbstate_t;
+
+#endif /* !_SYS__TYPES_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/cdefs.h b/uefi/arm-trusted-firmware/include/stdlib/sys/cdefs.h
new file mode 100644
index 0000000..16fb151
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/cdefs.h
@@ -0,0 +1,686 @@
+/*-
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)cdefs.h	8.8 (Berkeley) 1/9/95
+ * $FreeBSD$
+ */
+
+#ifndef	_SYS_CDEFS_H_
+#define	_SYS_CDEFS_H_
+
+#if defined(__cplusplus)
+#define	__BEGIN_DECLS	extern "C" {
+#define	__END_DECLS	}
+#else
+#define	__BEGIN_DECLS
+#define	__END_DECLS
+#endif
+
+/*
+ * This code has been put in place to help reduce the addition of
+ * compiler specific defines in FreeBSD code.  It helps to aid in
+ * having a compiler-agnostic source tree.
+ */
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
+
+#if __GNUC__ >= 3 || defined(__INTEL_COMPILER)
+#define __GNUCLIKE_ASM 3
+#define __GNUCLIKE_MATH_BUILTIN_CONSTANTS
+#else
+#define __GNUCLIKE_ASM 2
+#endif
+#define __GNUCLIKE___TYPEOF 1
+#define __GNUCLIKE___OFFSETOF 1
+#define __GNUCLIKE___SECTION 1
+
+#ifndef __INTEL_COMPILER
+# define __GNUCLIKE_CTOR_SECTION_HANDLING 1
+#endif
+
+#define __GNUCLIKE_BUILTIN_CONSTANT_P 1
+# if defined(__INTEL_COMPILER) && defined(__cplusplus) \
+    && __INTEL_COMPILER < 800
+#  undef __GNUCLIKE_BUILTIN_CONSTANT_P
+# endif
+
+#if (__GNUC_MINOR__ > 95 || __GNUC__ >= 3) && !defined(__INTEL_COMPILER)
+# define __GNUCLIKE_BUILTIN_VARARGS 1
+# define __GNUCLIKE_BUILTIN_STDARG 1
+# define __GNUCLIKE_BUILTIN_VAALIST 1
+#endif
+
+#if defined(__GNUC__)
+# define __GNUC_VA_LIST_COMPATIBILITY 1
+#endif
+
+#ifndef __INTEL_COMPILER
+# define __GNUCLIKE_BUILTIN_NEXT_ARG 1
+# define __GNUCLIKE_MATH_BUILTIN_RELOPS
+#endif
+
+#define __GNUCLIKE_BUILTIN_MEMCPY 1
+
+/* XXX: if __GNUC__ >= 2: not tested everywhere originally, where replaced */
+#define __CC_SUPPORTS_INLINE 1
+#define __CC_SUPPORTS___INLINE 1
+#define __CC_SUPPORTS___INLINE__ 1
+
+#define __CC_SUPPORTS___FUNC__ 1
+#define __CC_SUPPORTS_WARNING 1
+
+#define __CC_SUPPORTS_VARADIC_XXX 1 /* see varargs.h */
+
+#define __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1
+
+#endif /* __GNUC__ || __INTEL_COMPILER */
+
+/*
+ * Macro to test if we're using a specific version of gcc or later.
+ */
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+#define	__GNUC_PREREQ__(ma, mi)	\
+	(__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
+#else
+#define	__GNUC_PREREQ__(ma, mi)	0
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI
+ * mode -- there must be no spaces between its arguments, and for nested
+ * __CONCAT's, all the __CONCAT's must be at the left.  __CONCAT can also
+ * concatenate double-quoted strings produced by the __STRING macro, but
+ * this only works with ANSI C.
+ *
+ * __XSTRING is like __STRING, but it expands any macros in its argument
+ * first.  It is only available with ANSI C.
+ */
+#if defined(__STDC__) || defined(__cplusplus)
+#define	__P(protos)	protos		/* full-blown ANSI C */
+#define	__CONCAT1(x,y)	x ## y
+#define	__CONCAT(x,y)	__CONCAT1(x,y)
+#define	__STRING(x)	#x		/* stringify without expanding x */
+#define	__XSTRING(x)	__STRING(x)	/* expand x, then stringify */
+
+#define	__const		const		/* define reserved names to standard */
+#define	__signed	signed
+#define	__volatile	volatile
+#if defined(__cplusplus)
+#define	__inline	inline		/* convert to C++ keyword */
+#else
+#if !(defined(__CC_SUPPORTS___INLINE))
+#define	__inline			/* delete GCC keyword */
+#endif /* ! __CC_SUPPORTS___INLINE */
+#endif /* !__cplusplus */
+
+#else	/* !(__STDC__ || __cplusplus) */
+#define	__P(protos)	()		/* traditional C preprocessor */
+#define	__CONCAT(x,y)	x/**/y
+#define	__STRING(x)	"x"
+
+#if !defined(__CC_SUPPORTS___INLINE)
+#define	__const				/* delete pseudo-ANSI C keywords */
+#define	__inline
+#define	__signed
+#define	__volatile
+/*
+ * In non-ANSI C environments, new programs will want ANSI-only C keywords
+ * deleted from the program and old programs will want them left alone.
+ * When using a compiler other than gcc, programs using the ANSI C keywords
+ * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
+ * When using "gcc -traditional", we assume that this is the intent; if
+ * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
+ */
+#ifndef	NO_ANSI_KEYWORDS
+#define	const				/* delete ANSI C keywords */
+#define	inline
+#define	signed
+#define	volatile
+#endif	/* !NO_ANSI_KEYWORDS */
+#endif	/* !__CC_SUPPORTS___INLINE */
+#endif	/* !(__STDC__ || __cplusplus) */
+
+/*
+ * Compiler-dependent macros to help declare dead (non-returning) and
+ * pure (no side effects) functions, and unused variables.  They are
+ * null except for versions of gcc that are known to support the features
+ * properly (old versions of gcc-2 supported the dead and pure features
+ * in a different (wrong) way).  If we do not provide an implementation
+ * for a given compiler, let the compile fail if it is told to use
+ * a feature that we cannot live without.
+ */
+#ifdef lint
+#define	__dead2
+#define	__pure2
+#define	__unused
+#define	__packed
+#define	__aligned(x)
+#define	__section(x)
+#else
+#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER)
+#define	__dead2
+#define	__pure2
+#define	__unused
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER)
+#define	__dead2		__attribute__((__noreturn__))
+#define	__pure2		__attribute__((__const__))
+#define	__unused
+/* XXX Find out what to do for __packed, __aligned and __section */
+#endif
+#if __GNUC_PREREQ__(2, 7)
+#define	__dead2		__attribute__((__noreturn__))
+#define	__pure2		__attribute__((__const__))
+#define	__unused	__attribute__((__unused__))
+#define	__used		__attribute__((__used__))
+#define	__packed	__attribute__((__packed__))
+#define	__aligned(x)	__attribute__((__aligned__(x)))
+#define	__section(x)	__attribute__((__section__(x)))
+#endif
+#if defined(__INTEL_COMPILER)
+#define __dead2		__attribute__((__noreturn__))
+#define __pure2		__attribute__((__const__))
+#define __unused	__attribute__((__unused__))
+#define __used		__attribute__((__used__))
+#define __packed	__attribute__((__packed__))
+#define __aligned(x)	__attribute__((__aligned__(x)))
+#define __section(x)	__attribute__((__section__(x)))
+#endif
+#endif
+
+#if !__GNUC_PREREQ__(2, 95)
+#define	__alignof(x)	__offsetof(struct { char __a; x __b; }, __b)
+#endif
+
+/*
+ * Keywords added in C11.
+ */
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define	_Alignas(e)		alignas(e)
+#define	_Alignof(e)		alignof(e)
+#define	_Noreturn		[[noreturn]]
+#define	_Static_assert(e, s)	static_assert(e, s)
+/* FIXME: change this to thread_local when clang in base supports it */
+#define	_Thread_local		__thread
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+/* Do nothing.  They are language keywords. */
+#else
+/* Not supported.  Implement them using our versions. */
+#define	_Alignas(x)		__aligned(x)
+#define	_Alignof(x)		__alignof(x)
+#define	_Noreturn		__dead2
+#define	_Thread_local		__thread
+#ifdef __COUNTER__
+#define	_Static_assert(x, y)	__Static_assert(x, __COUNTER__)
+#define	__Static_assert(x, y)	___Static_assert(x, y)
+#define	___Static_assert(x, y)	typedef char __assert_ ## y[(x) ? 1 : -1]
+#else
+#define	_Static_assert(x, y)	struct __hack
+#endif
+#endif
+
+/*
+ * Emulation of C11 _Generic().  Unlike the previously defined C11
+ * keywords, it is not possible to implement this using exactly the same
+ * syntax.  Therefore implement something similar under the name
+ * __generic().  Unlike _Generic(), this macro can only distinguish
+ * between a single type, so it requires nested invocations to
+ * distinguish multiple cases.
+ */
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#define	__generic(expr, t, yes, no)					\
+	_Generic(expr, t: yes, default: no)
+#elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus)
+#define	__generic(expr, t, yes, no)					\
+	__builtin_choose_expr(						\
+	    __builtin_types_compatible_p(__typeof(expr), t), yes, no)
+#endif
+
+#if __GNUC_PREREQ__(2, 96)
+#define	__malloc_like	__attribute__((__malloc__))
+#define	__pure		__attribute__((__pure__))
+#else
+#define	__malloc_like
+#define	__pure
+#endif
+
+#if __GNUC_PREREQ__(3, 1) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800)
+#define	__always_inline	__attribute__((__always_inline__))
+#else
+#define	__always_inline
+#endif
+
+#if __GNUC_PREREQ__(3, 1)
+#define	__noinline	__attribute__ ((__noinline__))
+#else
+#define	__noinline
+#endif
+
+#if __GNUC_PREREQ__(3, 3)
+#define __nonnull(x)	__attribute__((__nonnull__(x)))
+#else
+#define __nonnull(x)
+#endif
+
+#if __GNUC_PREREQ__(3, 4)
+#define	__fastcall	__attribute__((__fastcall__))
+#else
+#define	__fastcall
+#endif
+
+#if __GNUC_PREREQ__(4, 1)
+#define	__returns_twice	__attribute__((__returns_twice__))
+#else
+#define	__returns_twice
+#endif
+
+/* XXX: should use `#if __STDC_VERSION__ < 199901'. */
+#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
+#define	__func__	NULL
+#endif
+
+#if (defined(__INTEL_COMPILER) || (defined(__GNUC__) && __GNUC__ >= 2)) && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901
+#define	__LONG_LONG_SUPPORTED
+#endif
+
+/* C++11 exposes a load of C99 stuff */
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define	__LONG_LONG_SUPPORTED
+#ifndef	__STDC_LIMIT_MACROS
+#define	__STDC_LIMIT_MACROS
+#endif
+#ifndef	__STDC_CONSTANT_MACROS
+#define	__STDC_CONSTANT_MACROS
+#endif
+#endif
+
+/*
+ * GCC 2.95 provides `__restrict' as an extension to C90 to support the
+ * C99-specific `restrict' type qualifier.  We happen to use `__restrict' as
+ * a way to define the `restrict' type qualifier without disturbing older
+ * software that is unaware of C99 keywords.
+ */
+#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95)
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901 || defined(lint)
+#define	__restrict
+#else
+#define	__restrict	restrict
+#endif
+#endif
+
+/*
+ * GNU C version 2.96 adds explicit branch prediction so that
+ * the CPU back-end can hint the processor and also so that
+ * code blocks can be reordered such that the predicted path
+ * sees a more linear flow, thus improving cache behavior, etc.
+ *
+ * The following two macros provide us with a way to utilize this
+ * compiler feature.  Use __predict_true() if you expect the expression
+ * to evaluate to true, and __predict_false() if you expect the
+ * expression to evaluate to false.
+ *
+ * A few notes about usage:
+ *
+ *	* Generally, __predict_false() error condition checks (unless
+ *	  you have some _strong_ reason to do otherwise, in which case
+ *	  document it), and/or __predict_true() `no-error' condition
+ *	  checks, assuming you want to optimize for the no-error case.
+ *
+ *	* Other than that, if you don't know the likelihood of a test
+ *	  succeeding from empirical or other `hard' evidence, don't
+ *	  make predictions.
+ *
+ *	* These are meant to be used in places that are run `a lot'.
+ *	  It is wasteful to make predictions in code that is run
+ *	  seldomly (e.g. at subsystem initialization time) as the
+ *	  basic block reordering that this affects can often generate
+ *	  larger code.
+ */
+#if __GNUC_PREREQ__(2, 96)
+#define __predict_true(exp)     __builtin_expect((exp), 1)
+#define __predict_false(exp)    __builtin_expect((exp), 0)
+#else
+#define __predict_true(exp)     (exp)
+#define __predict_false(exp)    (exp)
+#endif
+
+#if __GNUC_PREREQ__(4, 2)
+#define	__hidden	__attribute__((__visibility__("hidden")))
+#define	__exported	__attribute__((__visibility__("default")))
+#else
+#define	__hidden
+#define	__exported
+#endif
+
+/*
+ * We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
+ * require it.
+ */
+#if __GNUC_PREREQ__(4, 1)
+#define __offsetof(type, field)	 __builtin_offsetof(type, field)
+#else
+#ifndef __cplusplus
+#define	__offsetof(type, field) \
+	((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field))
+#else
+#define __offsetof(type, field)					\
+  (__offsetof__ (reinterpret_cast <__size_t>			\
+                 (&reinterpret_cast <const volatile char &>	\
+                  (static_cast<type *> (0)->field))))
+#endif
+#endif
+#define	__rangeof(type, start, end) \
+	(__offsetof(type, end) - __offsetof(type, start))
+
+/*
+ * Given the pointer x to the member m of the struct s, return
+ * a pointer to the containing structure.  When using GCC, we first
+ * assign pointer x to a local variable, to check that its type is
+ * compatible with member m.
+ */
+#if __GNUC_PREREQ__(3, 1)
+#define	__containerof(x, s, m) ({					\
+	const volatile __typeof(((s *)0)->m) *__x = (x);		\
+	__DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\
+})
+#else
+#define	__containerof(x, s, m)						\
+	__DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m))
+#endif
+
+/*
+ * Compiler-dependent macros to declare that functions take printf-like
+ * or scanf-like arguments.  They are null except for versions of gcc
+ * that are known to support the features properly (old versions of gcc-2
+ * didn't permit keeping the keywords out of the application namespace).
+ */
+#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
+#define	__printflike(fmtarg, firstvararg)
+#define	__scanflike(fmtarg, firstvararg)
+#define	__format_arg(fmtarg)
+#define	__strfmonlike(fmtarg, firstvararg)
+#define	__strftimelike(fmtarg, firstvararg)
+#else
+#define	__printflike(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+#define	__scanflike(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__scanf__, fmtarg, firstvararg)))
+#define	__format_arg(fmtarg)	__attribute__((__format_arg__ (fmtarg)))
+#define	__strfmonlike(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__strfmon__, fmtarg, firstvararg)))
+#define	__strftimelike(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__strftime__, fmtarg, firstvararg)))
+#endif
+
+/* Compiler-dependent macros that rely on FreeBSD-specific extensions. */
+#if __FreeBSD_cc_version >= 300001 && defined(__GNUC__) && !defined(__INTEL_COMPILER)
+#define	__printf0like(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__printf0__, fmtarg, firstvararg)))
+#else
+#define	__printf0like(fmtarg, firstvararg)
+#endif
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
+#ifndef __INTEL_COMPILER
+#define	__strong_reference(sym,aliassym)	\
+	extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)))
+#endif
+#ifdef __STDC__
+#define	__weak_reference(sym,alias)	\
+	__asm__(".weak " #alias);	\
+	__asm__(".equ "  #alias ", " #sym)
+#define	__warn_references(sym,msg)	\
+	__asm__(".section .gnu.warning." #sym);	\
+	__asm__(".asciz \"" msg "\"");	\
+	__asm__(".previous")
+#define	__sym_compat(sym,impl,verid)	\
+	__asm__(".symver " #impl ", " #sym "@" #verid)
+#define	__sym_default(sym,impl,verid)	\
+	__asm__(".symver " #impl ", " #sym "@@" #verid)
+#else
+#define	__weak_reference(sym,alias)	\
+	__asm__(".weak alias");		\
+	__asm__(".equ alias, sym")
+#define	__warn_references(sym,msg)	\
+	__asm__(".section .gnu.warning.sym"); \
+	__asm__(".asciz \"msg\"");	\
+	__asm__(".previous")
+#define	__sym_compat(sym,impl,verid)	\
+	__asm__(".symver impl, sym@verid")
+#define	__sym_default(impl,sym,verid)	\
+	__asm__(".symver impl, sym@@verid")
+#endif	/* __STDC__ */
+#endif	/* __GNUC__ || __INTEL_COMPILER */
+
+#define	__GLOBL1(sym)	__asm__(".globl " #sym)
+#define	__GLOBL(sym)	__GLOBL1(sym)
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
+#define	__IDSTRING(name,string)	__asm__(".ident\t\"" string "\"")
+#else
+/*
+ * The following definition might not work well if used in header files,
+ * but it should be better than nothing.  If you want a "do nothing"
+ * version, then it should generate some harmless declaration, such as:
+ *    #define __IDSTRING(name,string)	struct __hack
+ */
+#define	__IDSTRING(name,string)	static const char name[] __unused = string
+#endif
+
+/*
+ * Embed the rcs id of a source file in the resulting library.  Note that in
+ * more recent ELF binutils, we use .ident allowing the ID to be stripped.
+ * Usage:
+ *	__FBSDID("$FreeBSD$");
+ */
+#ifndef	__FBSDID
+#if !defined(lint) && !defined(STRIP_FBSDID)
+#define	__FBSDID(s)	__IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+#else
+#define	__FBSDID(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__RCSID
+#ifndef	NO__RCSID
+#define	__RCSID(s)	__IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+#else
+#define	__RCSID(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__RCSID_SOURCE
+#ifndef	NO__RCSID_SOURCE
+#define	__RCSID_SOURCE(s)	__IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s)
+#else
+#define	__RCSID_SOURCE(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__SCCSID
+#ifndef	NO__SCCSID
+#define	__SCCSID(s)	__IDSTRING(__CONCAT(__sccsid_,__LINE__),s)
+#else
+#define	__SCCSID(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__COPYRIGHT
+#ifndef	NO__COPYRIGHT
+#define	__COPYRIGHT(s)	__IDSTRING(__CONCAT(__copyright_,__LINE__),s)
+#else
+#define	__COPYRIGHT(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__DECONST
+#define	__DECONST(type, var)	((type)(__uintptr_t)(const void *)(var))
+#endif
+
+#ifndef	__DEVOLATILE
+#define	__DEVOLATILE(type, var)	((type)(__uintptr_t)(volatile void *)(var))
+#endif
+
+#ifndef	__DEQUALIFY
+#define	__DEQUALIFY(type, var)	((type)(__uintptr_t)(const volatile void *)(var))
+#endif
+
+/*-
+ * The following definitions are an extension of the behavior originally
+ * implemented in <sys/_posix.h>, but with a different level of granularity.
+ * POSIX.1 requires that the macros we test be defined before any standard
+ * header file is included.
+ *
+ * Here's a quick run-down of the versions:
+ *  defined(_POSIX_SOURCE)		1003.1-1988
+ *  _POSIX_C_SOURCE == 1		1003.1-1990
+ *  _POSIX_C_SOURCE == 2		1003.2-1992 C Language Binding Option
+ *  _POSIX_C_SOURCE == 199309		1003.1b-1993
+ *  _POSIX_C_SOURCE == 199506		1003.1c-1995, 1003.1i-1995,
+ *					and the omnibus ISO/IEC 9945-1: 1996
+ *  _POSIX_C_SOURCE == 200112		1003.1-2001
+ *  _POSIX_C_SOURCE == 200809		1003.1-2008
+ *
+ * In addition, the X/Open Portability Guide, which is now the Single UNIX
+ * Specification, defines a feature-test macro which indicates the version of
+ * that specification, and which subsumes _POSIX_C_SOURCE.
+ *
+ * Our macros begin with two underscores to avoid namespace screwage.
+ */
+
+/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1
+#undef _POSIX_C_SOURCE		/* Probably illegal, but beyond caring now. */
+#define	_POSIX_C_SOURCE		199009
+#endif
+
+/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		199209
+#endif
+
+/* Deal with various X/Open Portability Guides and Single UNIX Spec. */
+#ifdef _XOPEN_SOURCE
+#if _XOPEN_SOURCE - 0 >= 700
+#define	__XSI_VISIBLE		700
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		200809
+#elif _XOPEN_SOURCE - 0 >= 600
+#define	__XSI_VISIBLE		600
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		200112
+#elif _XOPEN_SOURCE - 0 >= 500
+#define	__XSI_VISIBLE		500
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		199506
+#endif
+#endif
+
+/*
+ * Deal with all versions of POSIX.  The ordering relative to the tests above is
+ * important.
+ */
+#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
+#define	_POSIX_C_SOURCE		198808
+#endif
+#ifdef _POSIX_C_SOURCE
+#if _POSIX_C_SOURCE >= 200809
+#define	__POSIX_VISIBLE		200809
+#define	__ISO_C_VISIBLE		1999
+#elif _POSIX_C_SOURCE >= 200112
+#define	__POSIX_VISIBLE		200112
+#define	__ISO_C_VISIBLE		1999
+#elif _POSIX_C_SOURCE >= 199506
+#define	__POSIX_VISIBLE		199506
+#define	__ISO_C_VISIBLE		1990
+#elif _POSIX_C_SOURCE >= 199309
+#define	__POSIX_VISIBLE		199309
+#define	__ISO_C_VISIBLE		1990
+#elif _POSIX_C_SOURCE >= 199209
+#define	__POSIX_VISIBLE		199209
+#define	__ISO_C_VISIBLE		1990
+#elif _POSIX_C_SOURCE >= 199009
+#define	__POSIX_VISIBLE		199009
+#define	__ISO_C_VISIBLE		1990
+#else
+#define	__POSIX_VISIBLE		198808
+#define	__ISO_C_VISIBLE		0
+#endif /* _POSIX_C_SOURCE */
+#else
+/*-
+ * Deal with _ANSI_SOURCE:
+ * If it is defined, and no other compilation environment is explicitly
+ * requested, then define our internal feature-test macros to zero.  This
+ * makes no difference to the preprocessor (undefined symbols in preprocessing
+ * expressions are defined to have value zero), but makes it more convenient for
+ * a test program to print out the values.
+ *
+ * If a program mistakenly defines _ANSI_SOURCE and some other macro such as
+ * _POSIX_C_SOURCE, we will assume that it wants the broader compilation
+ * environment (and in fact we will never get here).
+ */
+#if defined(_ANSI_SOURCE)	/* Hide almost everything. */
+#define	__POSIX_VISIBLE		0
+#define	__XSI_VISIBLE		0
+#define	__BSD_VISIBLE		0
+#define	__ISO_C_VISIBLE		1990
+#elif defined(_C99_SOURCE)	/* Localism to specify strict C99 env. */
+#define	__POSIX_VISIBLE		0
+#define	__XSI_VISIBLE		0
+#define	__BSD_VISIBLE		0
+#define	__ISO_C_VISIBLE		1999
+#else				/* Default environment: show everything. */
+#define	__POSIX_VISIBLE		200809
+#define	__XSI_VISIBLE		700
+#define	__BSD_VISIBLE		1
+#define	__ISO_C_VISIBLE		1999
+#endif
+#endif
+
+#ifndef	__has_feature
+#define	__has_feature(x) 0
+#endif
+#ifndef	__has_include
+#define	__has_include(x) 0
+#endif
+#ifndef	__has_builtin
+#define	__has_builtin(x) 0
+#endif
+
+#if defined(__mips) || defined(__powerpc64__) || defined(__arm__)
+#define __NO_TLS 1
+#endif
+
+#endif /* !_SYS_CDEFS_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/ctype.h b/uefi/arm-trusted-firmware/include/stdlib/sys/ctype.h
new file mode 100644
index 0000000..f2758b7
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/ctype.h
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1982, 1988, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Portions copyright (c) 2009-2014, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef _SYS_CTYPE_H_
+#define	_SYS_CTYPE_H_
+
+#define isspace(c)	((c) == ' ' || ((c) >= '\t' && (c) <= '\r'))
+#define isascii(c)	(((c) & ~0x7f) == 0)
+#define isupper(c)	((c) >= 'A' && (c) <= 'Z')
+#define islower(c)	((c) >= 'a' && (c) <= 'z')
+#define isalpha(c)	(isupper(c) || islower(c))
+#define isdigit(c)	((c) >= '0' && (c) <= '9')
+#define isxdigit(c)	(isdigit(c) \
+			  || ((c) >= 'A' && (c) <= 'F') \
+			  || ((c) >= 'a' && (c) <= 'f'))
+#define isprint(c)	((c) >= ' ' && (c) <= '~')
+
+#define toupper(c)	((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))
+#define tolower(c)	((c) + 0x20 * (((c) >= 'A') && ((c) <= 'Z')))
+
+#endif /* !_SYS_CTYPE_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/errno.h b/uefi/arm-trusted-firmware/include/stdlib/sys/errno.h
new file mode 100644
index 0000000..f595514
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/errno.h
@@ -0,0 +1,193 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)errno.h	8.5 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ERRNO_H_
+#define _SYS_ERRNO_H_
+
+#ifndef _KERNEL
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+int *	__error(void);
+__END_DECLS
+#define	errno		(* __error())
+#endif
+
+#define	EPERM		1		/* Operation not permitted */
+#define	ENOENT		2		/* No such file or directory */
+#define	ESRCH		3		/* No such process */
+#define	EINTR		4		/* Interrupted system call */
+#define	EIO		5		/* Input/output error */
+#define	ENXIO		6		/* Device not configured */
+#define	E2BIG		7		/* Argument list too long */
+#define	ENOEXEC		8		/* Exec format error */
+#define	EBADF		9		/* Bad file descriptor */
+#define	ECHILD		10		/* No child processes */
+#define	EDEADLK		11		/* Resource deadlock avoided */
+					/* 11 was EAGAIN */
+#define	ENOMEM		12		/* Cannot allocate memory */
+#define	EACCES		13		/* Permission denied */
+#define	EFAULT		14		/* Bad address */
+#ifndef _POSIX_SOURCE
+#define	ENOTBLK		15		/* Block device required */
+#endif
+#define	EBUSY		16		/* Device busy */
+#define	EEXIST		17		/* File exists */
+#define	EXDEV		18		/* Cross-device link */
+#define	ENODEV		19		/* Operation not supported by device */
+#define	ENOTDIR		20		/* Not a directory */
+#define	EISDIR		21		/* Is a directory */
+#define	EINVAL		22		/* Invalid argument */
+#define	ENFILE		23		/* Too many open files in system */
+#define	EMFILE		24		/* Too many open files */
+#define	ENOTTY		25		/* Inappropriate ioctl for device */
+#ifndef _POSIX_SOURCE
+#define	ETXTBSY		26		/* Text file busy */
+#endif
+#define	EFBIG		27		/* File too large */
+#define	ENOSPC		28		/* No space left on device */
+#define	ESPIPE		29		/* Illegal seek */
+#define	EROFS		30		/* Read-only filesystem */
+#define	EMLINK		31		/* Too many links */
+#define	EPIPE		32		/* Broken pipe */
+
+/* math software */
+#define	EDOM		33		/* Numerical argument out of domain */
+#define	ERANGE		34		/* Result too large */
+
+/* non-blocking and interrupt i/o */
+#define	EAGAIN		35		/* Resource temporarily unavailable */
+#ifndef _POSIX_SOURCE
+#define	EWOULDBLOCK	EAGAIN		/* Operation would block */
+#define	EINPROGRESS	36		/* Operation now in progress */
+#define	EALREADY	37		/* Operation already in progress */
+
+/* ipc/network software -- argument errors */
+#define	ENOTSOCK	38		/* Socket operation on non-socket */
+#define	EDESTADDRREQ	39		/* Destination address required */
+#define	EMSGSIZE	40		/* Message too long */
+#define	EPROTOTYPE	41		/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	42		/* Protocol not available */
+#define	EPROTONOSUPPORT	43		/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	44		/* Socket type not supported */
+#define	EOPNOTSUPP	45		/* Operation not supported */
+#define	ENOTSUP		EOPNOTSUPP	/* Operation not supported */
+#define	EPFNOSUPPORT	46		/* Protocol family not supported */
+#define	EAFNOSUPPORT	47		/* Address family not supported by protocol family */
+#define	EADDRINUSE	48		/* Address already in use */
+#define	EADDRNOTAVAIL	49		/* Can't assign requested address */
+
+/* ipc/network software -- operational errors */
+#define	ENETDOWN	50		/* Network is down */
+#define	ENETUNREACH	51		/* Network is unreachable */
+#define	ENETRESET	52		/* Network dropped connection on reset */
+#define	ECONNABORTED	53		/* Software caused connection abort */
+#define	ECONNRESET	54		/* Connection reset by peer */
+#define	ENOBUFS		55		/* No buffer space available */
+#define	EISCONN		56		/* Socket is already connected */
+#define	ENOTCONN	57		/* Socket is not connected */
+#define	ESHUTDOWN	58		/* Can't send after socket shutdown */
+#define	ETOOMANYREFS	59		/* Too many references: can't splice */
+#define	ETIMEDOUT	60		/* Operation timed out */
+#define	ECONNREFUSED	61		/* Connection refused */
+
+#define	ELOOP		62		/* Too many levels of symbolic links */
+#endif /* _POSIX_SOURCE */
+#define	ENAMETOOLONG	63		/* File name too long */
+
+/* should be rearranged */
+#ifndef _POSIX_SOURCE
+#define	EHOSTDOWN	64		/* Host is down */
+#define	EHOSTUNREACH	65		/* No route to host */
+#endif /* _POSIX_SOURCE */
+#define	ENOTEMPTY	66		/* Directory not empty */
+
+/* quotas & mush */
+#ifndef _POSIX_SOURCE
+#define	EPROCLIM	67		/* Too many processes */
+#define	EUSERS		68		/* Too many users */
+#define	EDQUOT		69		/* Disc quota exceeded */
+
+/* Network File System */
+#define	ESTALE		70		/* Stale NFS file handle */
+#define	EREMOTE		71		/* Too many levels of remote in path */
+#define	EBADRPC		72		/* RPC struct is bad */
+#define	ERPCMISMATCH	73		/* RPC version wrong */
+#define	EPROGUNAVAIL	74		/* RPC prog. not avail */
+#define	EPROGMISMATCH	75		/* Program version wrong */
+#define	EPROCUNAVAIL	76		/* Bad procedure for program */
+#endif /* _POSIX_SOURCE */
+
+#define	ENOLCK		77		/* No locks available */
+#define	ENOSYS		78		/* Function not implemented */
+
+#ifndef _POSIX_SOURCE
+#define	EFTYPE		79		/* Inappropriate file type or format */
+#define	EAUTH		80		/* Authentication error */
+#define	ENEEDAUTH	81		/* Need authenticator */
+#define	EIDRM		82		/* Identifier removed */
+#define	ENOMSG		83		/* No message of desired type */
+#define	EOVERFLOW	84		/* Value too large to be stored in data type */
+#define	ECANCELED	85		/* Operation canceled */
+#define	EILSEQ		86		/* Illegal byte sequence */
+#define	ENOATTR		87		/* Attribute not found */
+
+#define	EDOOFUS		88		/* Programming error */
+#endif /* _POSIX_SOURCE */
+
+#define	EBADMSG		89		/* Bad message */
+#define	EMULTIHOP	90		/* Multihop attempted */
+#define	ENOLINK		91		/* Link has been severed */
+#define	EPROTO		92		/* Protocol error */
+
+#ifndef _POSIX_SOURCE
+#define	ENOTCAPABLE	93		/* Capabilities insufficient */
+#define	ECAPMODE	94		/* Not permitted in capability mode */
+#endif /* _POSIX_SOURCE */
+
+#ifndef _POSIX_SOURCE
+#define	ELAST		94		/* Must be equal largest errno */
+#endif /* _POSIX_SOURCE */
+
+#ifdef _KERNEL
+/* pseudo-errors returned inside kernel to modify return to process */
+#define	ERESTART	(-1)		/* restart syscall */
+#define	EJUSTRETURN	(-2)		/* don't modify regs, just return */
+#define	ENOIOCTL	(-3)		/* ioctl not handled by this layer */
+#define	EDIRIOCTL	(-4)		/* do direct ioctl in GEOM */
+#endif
+
+#endif
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/limits.h b/uefi/arm-trusted-firmware/include/stdlib/sys/limits.h
new file mode 100644
index 0000000..c56a337
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/limits.h
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_LIMITS_H_
+#define	_SYS_LIMITS_H_
+
+#include <sys/cdefs.h>
+#include <machine/_limits.h>
+
+#define	CHAR_BIT	__CHAR_BIT	/* number of bits in a char */
+
+#define	SCHAR_MAX	__SCHAR_MAX	/* max value for a signed char */
+#define	SCHAR_MIN	__SCHAR_MIN	/* min value for a signed char */
+
+#define	UCHAR_MAX	__UCHAR_MAX	/* max value for an unsigned char */
+
+#ifdef __CHAR_UNSIGNED__
+#define	CHAR_MAX	UCHAR_MAX	/* max value for a char */
+#define	CHAR_MIN	0		/* min value for a char */
+#else
+#define	CHAR_MAX	SCHAR_MAX
+#define	CHAR_MIN	SCHAR_MIN
+#endif
+
+#define	USHRT_MAX	__USHRT_MAX	/* max value for an unsigned short */
+#define	SHRT_MAX	__SHRT_MAX	/* max value for a short */
+#define	SHRT_MIN	__SHRT_MIN	/* min value for a short */
+
+#define	UINT_MAX	__UINT_MAX	/* max value for an unsigned int */
+#define	INT_MAX		__INT_MAX	/* max value for an int */
+#define	INT_MIN		__INT_MIN	/* min value for an int */
+
+#define	ULONG_MAX	__ULONG_MAX	/* max for an unsigned long */
+#define	LONG_MAX	__LONG_MAX	/* max for a long */
+#define	LONG_MIN	__LONG_MIN	/* min for a long */
+
+#ifdef __LONG_LONG_SUPPORTED
+#define	ULLONG_MAX	__ULLONG_MAX	/* max for an unsigned long long */
+#define	LLONG_MAX	__LLONG_MAX	/* max for a long long */
+#define	LLONG_MIN	__LLONG_MIN	/* min for a long long */
+#endif
+
+#if __POSIX_VISIBLE || __XSI_VISIBLE
+#define	SSIZE_MAX	__SSIZE_MAX	/* max value for an ssize_t */
+#endif
+
+#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
+#define	SIZE_T_MAX	__SIZE_T_MAX	/* max value for a size_t */
+
+#define	OFF_MAX		__OFF_MAX	/* max value for an off_t */
+#define	OFF_MIN		__OFF_MIN	/* min value for an off_t */
+#endif
+
+#if __BSD_VISIBLE
+#define	GID_MAX		UINT_MAX	/* max value for a gid_t */
+#define	UID_MAX		UINT_MAX	/* max value for a uid_t */
+
+#define	UQUAD_MAX	(__UQUAD_MAX)	/* max value for a uquad_t */
+#define	QUAD_MAX	(__QUAD_MAX)	/* max value for a quad_t */
+#define	QUAD_MIN	(__QUAD_MIN)	/* min value for a quad_t */
+#endif
+
+#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809
+#define	LONG_BIT	__LONG_BIT
+#define	WORD_BIT	__WORD_BIT
+#endif
+
+#if __POSIX_VISIBLE
+#define	MQ_PRIO_MAX	64
+#endif
+
+#endif /* !_SYS_LIMITS_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/stdarg.h b/uefi/arm-trusted-firmware/include/stdlib/sys/stdarg.h
new file mode 100644
index 0000000..c315dfc
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/stdarg.h
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2002 David E. O'Brien.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_STDARG_H_
+#define	_MACHINE_STDARG_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _VA_LIST_DECLARED
+#define	_VA_LIST_DECLARED
+typedef	__va_list	va_list;
+#endif
+
+#ifdef __GNUCLIKE_BUILTIN_STDARG
+
+#define	va_start(ap, last) \
+	__builtin_va_start((ap), (last))
+
+#define	va_arg(ap, type) \
+	__builtin_va_arg((ap), type)
+
+#define	__va_copy(dest, src) \
+	__builtin_va_copy((dest), (src))
+
+#if __ISO_C_VISIBLE >= 1999
+#define	va_copy(dest, src) \
+	__va_copy(dest, src)
+#endif
+
+#define	va_end(ap) \
+	__builtin_va_end(ap)
+
+#elif defined(lint)
+/* Provide a fake implementation for lint's benefit */
+#define	__va_size(type) \
+	(((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))
+#define	va_start(ap, last) \
+	((ap) = (va_list)&(last) + __va_size(last))
+#define	va_arg(ap, type) \
+	(*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))
+#define	va_end(ap)
+
+#else
+#error this file needs to be ported to your compiler
+#endif
+
+#endif /* !_MACHINE_STDARG_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/stdint.h b/uefi/arm-trusted-firmware/include/stdlib/sys/stdint.h
new file mode 100644
index 0000000..aa5ac81
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/stdint.h
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_STDINT_H_
+#define _SYS_STDINT_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#include <machine/_stdint.h>
+#include <sys/_stdint.h>
+
+typedef	__int_least8_t		int_least8_t;
+typedef	__int_least16_t		int_least16_t;
+typedef	__int_least32_t		int_least32_t;
+typedef	__int_least64_t		int_least64_t;
+
+typedef	__uint_least8_t		uint_least8_t;
+typedef	__uint_least16_t	uint_least16_t;
+typedef	__uint_least32_t	uint_least32_t;
+typedef	__uint_least64_t	uint_least64_t;
+
+typedef	__int_fast8_t		int_fast8_t;
+typedef	__int_fast16_t		int_fast16_t;
+typedef	__int_fast32_t		int_fast32_t;
+typedef	__int_fast64_t		int_fast64_t;
+
+typedef	__uint_fast8_t		uint_fast8_t;
+typedef	__uint_fast16_t		uint_fast16_t;
+typedef	__uint_fast32_t		uint_fast32_t;
+typedef	__uint_fast64_t		uint_fast64_t;
+
+#ifndef _INTMAX_T_DECLARED
+typedef	__intmax_t		intmax_t;
+#define	_INTMAX_T_DECLARED
+#endif
+#ifndef _UINTMAX_T_DECLARED
+typedef	__uintmax_t		uintmax_t;
+#define	_UINTMAX_T_DECLARED
+#endif
+
+/* GNU and Darwin define this and people seem to think it's portable */
+#if defined(UINTPTR_MAX) && defined(UINT64_MAX) && (UINTPTR_MAX == UINT64_MAX)
+#define	__WORDSIZE		64
+#else
+#define	__WORDSIZE		32
+#endif
+
+#endif /* !_SYS_STDINT_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/timespec.h b/uefi/arm-trusted-firmware/include/stdlib/sys/timespec.h
new file mode 100644
index 0000000..2505cef
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/timespec.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)time.h	8.5 (Berkeley) 5/4/95
+ * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp
+ *	$FreeBSD$
+ */
+
+#ifndef _SYS_TIMESPEC_H_
+#define _SYS_TIMESPEC_H_
+
+#include <sys/cdefs.h>
+#include <sys/_timespec.h>
+
+#if __BSD_VISIBLE
+#define	TIMEVAL_TO_TIMESPEC(tv, ts)					\
+	do {								\
+		(ts)->tv_sec = (tv)->tv_sec;				\
+		(ts)->tv_nsec = (tv)->tv_usec * 1000;			\
+	} while (0)
+#define	TIMESPEC_TO_TIMEVAL(tv, ts)					\
+	do {								\
+		(tv)->tv_sec = (ts)->tv_sec;				\
+		(tv)->tv_usec = (ts)->tv_nsec / 1000;			\
+	} while (0)
+
+#endif /* __BSD_VISIBLE */
+
+/*
+ * Structure defined by POSIX.1b to be like a itimerval, but with
+ * timespecs. Used in the timer_*() system calls.
+ */
+struct itimerspec {
+	struct timespec  it_interval;
+	struct timespec  it_value;
+};
+
+#endif /* _SYS_TIMESPEC_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/types.h b/uefi/arm-trusted-firmware/include/stdlib/sys/types.h
new file mode 100644
index 0000000..ae2ea33
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/types.h
@@ -0,0 +1,245 @@
+/*-
+ * Copyright (c) 1982, 1986, 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)types.h	8.6 (Berkeley) 2/19/95
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_TYPES_H_
+#define	_SYS_TYPES_H_
+
+#include <sys/cdefs.h>
+
+/* Machine type dependent parameters. */
+#include <sys/_types.h>
+
+#if __BSD_VISIBLE
+typedef	unsigned char	u_char;
+typedef	unsigned short	u_short;
+typedef	unsigned int	u_int;
+typedef	unsigned long	u_long;
+#ifndef _KERNEL
+typedef	unsigned short	ushort;		/* Sys V compatibility */
+typedef	unsigned int	uint;		/* Sys V compatibility */
+#endif
+#endif
+
+/*
+ * XXX POSIX sized integrals that should appear only in <sys/stdint.h>.
+ */
+#include <sys/_stdint.h>
+
+typedef __uint8_t	u_int8_t;	/* unsigned integrals (deprecated) */
+typedef __uint16_t	u_int16_t;
+typedef __uint32_t	u_int32_t;
+typedef __uint64_t	u_int64_t;
+
+typedef	__uint64_t	u_quad_t;	/* quads (deprecated) */
+typedef	__int64_t	quad_t;
+typedef	quad_t		*qaddr_t;
+
+typedef	char		*caddr_t;	/* core address */
+typedef	const char	*c_caddr_t;	/* core address, pointer to const */
+
+#ifndef _BLKSIZE_T_DECLARED
+typedef	__blksize_t	blksize_t;
+#define	_BLKSIZE_T_DECLARED
+#endif
+
+typedef	__cpuwhich_t	cpuwhich_t;
+typedef	__cpulevel_t	cpulevel_t;
+typedef	__cpusetid_t	cpusetid_t;
+
+#ifndef _BLKCNT_T_DECLARED
+typedef	__blkcnt_t	blkcnt_t;
+#define	_BLKCNT_T_DECLARED
+#endif
+
+#ifndef _CLOCK_T_DECLARED
+typedef	__clock_t	clock_t;
+#define	_CLOCK_T_DECLARED
+#endif
+
+#ifndef _CLOCKID_T_DECLARED
+typedef	__clockid_t	clockid_t;
+#define	_CLOCKID_T_DECLARED
+#endif
+
+typedef	__critical_t	critical_t;	/* Critical section value */
+typedef	__int64_t	daddr_t;	/* disk address */
+
+#ifndef _DEV_T_DECLARED
+typedef	__dev_t		dev_t;		/* device number or struct cdev */
+#define	_DEV_T_DECLARED
+#endif
+
+#ifndef _FFLAGS_T_DECLARED
+typedef	__fflags_t	fflags_t;	/* file flags */
+#define	_FFLAGS_T_DECLARED
+#endif
+
+typedef	__fixpt_t	fixpt_t;	/* fixed point number */
+
+#ifndef _FSBLKCNT_T_DECLARED		/* for statvfs() */
+typedef	__fsblkcnt_t	fsblkcnt_t;
+typedef	__fsfilcnt_t	fsfilcnt_t;
+#define	_FSBLKCNT_T_DECLARED
+#endif
+
+#ifndef _GID_T_DECLARED
+typedef	__gid_t		gid_t;		/* group id */
+#define	_GID_T_DECLARED
+#endif
+
+#ifndef _IN_ADDR_T_DECLARED
+typedef	__uint32_t	in_addr_t;	/* base type for internet address */
+#define	_IN_ADDR_T_DECLARED
+#endif
+
+#ifndef _IN_PORT_T_DECLARED
+typedef	__uint16_t	in_port_t;
+#define	_IN_PORT_T_DECLARED
+#endif
+
+#ifndef _ID_T_DECLARED
+typedef	__id_t		id_t;		/* can hold a uid_t or pid_t */
+#define	_ID_T_DECLARED
+#endif
+
+#ifndef _INO_T_DECLARED
+typedef	__ino_t		ino_t;		/* inode number */
+#define	_INO_T_DECLARED
+#endif
+
+#ifndef _KEY_T_DECLARED
+typedef	__key_t		key_t;		/* IPC key (for Sys V IPC) */
+#define	_KEY_T_DECLARED
+#endif
+
+#ifndef _LWPID_T_DECLARED
+typedef	__lwpid_t	lwpid_t;	/* Thread ID (a.k.a. LWP) */
+#define	_LWPID_T_DECLARED
+#endif
+
+#ifndef _MODE_T_DECLARED
+typedef	__mode_t	mode_t;		/* permissions */
+#define	_MODE_T_DECLARED
+#endif
+
+#ifndef _ACCMODE_T_DECLARED
+typedef	__accmode_t	accmode_t;	/* access permissions */
+#define	_ACCMODE_T_DECLARED
+#endif
+
+#ifndef _NLINK_T_DECLARED
+typedef	__nlink_t	nlink_t;	/* link count */
+#define	_NLINK_T_DECLARED
+#endif
+
+#ifndef _OFF_T_DECLARED
+typedef	__off_t		off_t;		/* file offset */
+#define	_OFF_T_DECLARED
+#endif
+
+#ifndef _PID_T_DECLARED
+typedef	__pid_t		pid_t;		/* process id */
+#define	_PID_T_DECLARED
+#endif
+
+typedef	__register_t	register_t;
+
+#ifndef _RLIM_T_DECLARED
+typedef	__rlim_t	rlim_t;		/* resource limit */
+#define	_RLIM_T_DECLARED
+#endif
+
+typedef	__int64_t	sbintime_t;
+
+typedef	__segsz_t	segsz_t;	/* segment size (in pages) */
+
+#ifndef _SIZE_T_DECLARED
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#endif
+
+#ifndef _SSIZE_T_DECLARED
+typedef	__ssize_t	ssize_t;
+#define	_SSIZE_T_DECLARED
+#endif
+
+#ifndef _SUSECONDS_T_DECLARED
+typedef	__suseconds_t	suseconds_t;	/* microseconds (signed) */
+#define	_SUSECONDS_T_DECLARED
+#endif
+
+#ifndef _TIME_T_DECLARED
+typedef	__time_t	time_t;
+#define	_TIME_T_DECLARED
+#endif
+
+#ifndef _TIMER_T_DECLARED
+typedef	__timer_t	timer_t;
+#define	_TIMER_T_DECLARED
+#endif
+
+#ifndef _MQD_T_DECLARED
+typedef	__mqd_t	mqd_t;
+#define	_MQD_T_DECLARED
+#endif
+
+typedef	__u_register_t	u_register_t;
+
+#ifndef _UID_T_DECLARED
+typedef	__uid_t		uid_t;		/* user id */
+#define	_UID_T_DECLARED
+#endif
+
+#ifndef _USECONDS_T_DECLARED
+typedef	__useconds_t	useconds_t;	/* microseconds (unsigned) */
+#define	_USECONDS_T_DECLARED
+#endif
+
+#ifndef _CAP_RIGHTS_T_DECLARED
+#define	_CAP_RIGHTS_T_DECLARED
+struct cap_rights;
+
+typedef	struct cap_rights	cap_rights_t;
+#endif
+
+typedef	__vm_offset_t	vm_offset_t;
+typedef	__vm_ooffset_t	vm_ooffset_t;
+typedef	__vm_paddr_t	vm_paddr_t;
+typedef	__vm_pindex_t	vm_pindex_t;
+typedef	__vm_size_t	vm_size_t;
+
+#endif /* !_SYS_TYPES_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/sys/uuid.h b/uefi/arm-trusted-firmware/include/stdlib/sys/uuid.h
new file mode 100644
index 0000000..5c4767b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/sys/uuid.h
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Portions copyright (c) 2014, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef _SYS_UUID_H_
+#define _SYS_UUID_H_
+
+#include <sys/cdefs.h>
+
+/* Length of a node address (an IEEE 802 address). */
+#define	_UUID_NODE_LEN		6
+
+/*
+ * See also:
+ *      http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
+ *      http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
+ *
+ * A DCE 1.1 compatible source representation of UUIDs.
+ */
+struct uuid {
+	uint32_t	time_low;
+	uint16_t	time_mid;
+	uint16_t	time_hi_and_version;
+	uint8_t		clock_seq_hi_and_reserved;
+	uint8_t		clock_seq_low;
+	uint8_t		node[_UUID_NODE_LEN];
+};
+
+/* XXX namespace pollution? */
+typedef struct uuid uuid_t;
+
+#endif /* _SYS_UUID_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/time.h b/uefi/arm-trusted-firmware/include/stdlib/time.h
new file mode 100644
index 0000000..08200cf
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/time.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)time.h	8.3 (Berkeley) 1/21/94
+ */
+
+/*
+ * $FreeBSD$
+ */
+
+#ifndef _TIME_H_
+#define	_TIME_H_
+
+#include <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#if __POSIX_VISIBLE > 0 && __POSIX_VISIBLE < 200112 || __BSD_VISIBLE
+/*
+ * Frequency of the clock ticks reported by times().  Deprecated - use
+ * sysconf(_SC_CLK_TCK) instead.  (Removed in 1003.1-2001.)
+ */
+#define	CLK_TCK		128
+#endif
+
+/* Frequency of the clock ticks reported by clock().  */
+#define	CLOCKS_PER_SEC	128
+
+#ifndef _CLOCK_T_DECLARED
+typedef	__clock_t	clock_t;
+#define	_CLOCK_T_DECLARED
+#endif
+
+#ifndef _TIME_T_DECLARED
+typedef	__time_t	time_t;
+#define	_TIME_T_DECLARED
+#endif
+
+#ifndef _SIZE_T_DECLARED
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#endif
+
+#if __POSIX_VISIBLE >= 199309
+/*
+ * New in POSIX 1003.1b-1993.
+ */
+#ifndef _CLOCKID_T_DECLARED
+typedef	__clockid_t	clockid_t;
+#define	_CLOCKID_T_DECLARED
+#endif
+
+#ifndef _TIMER_T_DECLARED
+typedef	__timer_t	timer_t;
+#define	_TIMER_T_DECLARED
+#endif
+
+#include <sys/timespec.h>
+#endif /* __POSIX_VISIBLE >= 199309 */
+
+#if __POSIX_VISIBLE >= 200112
+#ifndef _PID_T_DECLARED
+typedef	__pid_t		pid_t;
+#define	_PID_T_DECLARED
+#endif
+#endif
+
+/* These macros are also in sys/time.h. */
+#if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112
+#define CLOCK_REALTIME	0
+#ifdef __BSD_VISIBLE
+#define CLOCK_VIRTUAL	1
+#define CLOCK_PROF	2
+#endif
+#define CLOCK_MONOTONIC	4
+#define CLOCK_UPTIME	5		/* FreeBSD-specific. */
+#define CLOCK_UPTIME_PRECISE	7	/* FreeBSD-specific. */
+#define CLOCK_UPTIME_FAST	8	/* FreeBSD-specific. */
+#define CLOCK_REALTIME_PRECISE	9	/* FreeBSD-specific. */
+#define CLOCK_REALTIME_FAST	10	/* FreeBSD-specific. */
+#define CLOCK_MONOTONIC_PRECISE	11	/* FreeBSD-specific. */
+#define CLOCK_MONOTONIC_FAST	12	/* FreeBSD-specific. */
+#define CLOCK_SECOND	13		/* FreeBSD-specific. */
+#define CLOCK_THREAD_CPUTIME_ID	14
+#define	CLOCK_PROCESS_CPUTIME_ID	15
+#endif /* !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 */
+
+#if !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112
+#if __BSD_VISIBLE
+#define TIMER_RELTIME	0x0	/* relative timer */
+#endif
+#define TIMER_ABSTIME	0x1	/* absolute timer */
+#endif /* !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112 */
+
+struct tm {
+	int	tm_sec;		/* seconds after the minute [0-60] */
+	int	tm_min;		/* minutes after the hour [0-59] */
+	int	tm_hour;	/* hours since midnight [0-23] */
+	int	tm_mday;	/* day of the month [1-31] */
+	int	tm_mon;		/* months since January [0-11] */
+	int	tm_year;	/* years since 1900 */
+	int	tm_wday;	/* days since Sunday [0-6] */
+	int	tm_yday;	/* days since January 1 [0-365] */
+	int	tm_isdst;	/* Daylight Savings Time flag */
+	long	tm_gmtoff;	/* offset from UTC in seconds */
+	char	*tm_zone;	/* timezone abbreviation */
+};
+
+#if __POSIX_VISIBLE
+extern char *tzname[];
+#endif
+
+__BEGIN_DECLS
+char *asctime(const struct tm *);
+clock_t clock(void);
+char *ctime(const time_t *);
+double difftime(time_t, time_t);
+/* XXX missing: getdate() */
+struct tm *gmtime(const time_t *);
+struct tm *localtime(const time_t *);
+time_t mktime(struct tm *);
+size_t strftime(char *__restrict, size_t, const char *__restrict,
+    const struct tm *__restrict);
+time_t time(time_t *);
+#if __POSIX_VISIBLE >= 200112
+struct sigevent;
+int timer_create(clockid_t, struct sigevent *__restrict, timer_t *__restrict);
+int timer_delete(timer_t);
+int timer_gettime(timer_t, struct itimerspec *);
+int timer_getoverrun(timer_t);
+int timer_settime(timer_t, int, const struct itimerspec *__restrict,
+	struct itimerspec *__restrict);
+#endif
+#if __POSIX_VISIBLE
+void tzset(void);
+#endif
+
+#if __POSIX_VISIBLE >= 199309
+int clock_getres(clockid_t, struct timespec *);
+int clock_gettime(clockid_t, struct timespec *);
+int clock_settime(clockid_t, const struct timespec *);
+/* XXX missing: clock_nanosleep() */
+int nanosleep(const struct timespec *, struct timespec *);
+#endif /* __POSIX_VISIBLE >= 199309 */
+
+#if __POSIX_VISIBLE >= 200112
+int clock_getcpuclockid(pid_t, clockid_t *);
+#endif
+
+#if __POSIX_VISIBLE >= 199506
+char *asctime_r(const struct tm *, char *);
+char *ctime_r(const time_t *, char *);
+struct tm *gmtime_r(const time_t *, struct tm *);
+struct tm *localtime_r(const time_t *, struct tm *);
+#endif
+
+#if __XSI_VISIBLE
+char *strptime(const char *__restrict, const char *__restrict,
+    struct tm *__restrict);
+#endif
+
+#if __BSD_VISIBLE
+char *timezone(int, int);	/* XXX XSI conflict */
+void tzsetwall(void);
+time_t timelocal(struct tm * const);
+time_t timegm(struct tm * const);
+#endif /* __BSD_VISIBLE */
+
+#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_)
+#include <xlocale/_time.h>
+#endif
+__END_DECLS
+
+#endif /* !_TIME_H_ */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/xlocale/_strings.h b/uefi/arm-trusted-firmware/include/stdlib/xlocale/_strings.h
new file mode 100644
index 0000000..da1cff3
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/xlocale/_strings.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2011, 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LOCALE_T_DEFINED
+#define _LOCALE_T_DEFINED
+typedef struct	_xlocale *locale_t;
+#endif
+
+/*
+ * This file is included from both strings.h and xlocale.h.  We need to expose
+ * the declarations unconditionally if we are included from xlocale.h, but only
+ * if we are in POSIX2008 mode if included from string.h.
+ */
+
+#ifndef _XLOCALE_STRINGS1_H
+#define _XLOCALE_STRINGS1_H
+
+/*
+ * POSIX2008 functions
+ */
+int	 strcasecmp_l(const char *, const char *, locale_t);
+int	 strncasecmp_l(const char *, const char *, size_t, locale_t);
+#endif /* _XLOCALE_STRINGS1_H */
diff --git a/uefi/arm-trusted-firmware/include/stdlib/xlocale/_time.h b/uefi/arm-trusted-firmware/include/stdlib/xlocale/_time.h
new file mode 100644
index 0000000..6da49a4
--- /dev/null
+++ b/uefi/arm-trusted-firmware/include/stdlib/xlocale/_time.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2011, 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by David Chisnall under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LOCALE_T_DEFINED
+#define _LOCALE_T_DEFINED
+typedef struct	_xlocale *locale_t;
+#endif
+
+/*
+ * This file is included from both locale.h and xlocale.h.  We need to expose
+ * the declarations unconditionally if we are included from xlocale.h, but only
+ * if we are in POSIX2008 mode if included from locale.h.
+ */
+#ifndef _XLOCALE_LOCALE1_H
+#define _XLOCALE_LOCALE1_H
+
+size_t	 strftime_l(char *__restrict, size_t, const char *__restrict,
+	    const struct tm *__restrict, locale_t) __strftimelike(3, 0);
+
+#endif /* _XLOCALE_LOCALE1_H */
+
+#ifdef _XLOCALE_H_
+#ifndef _XLOCALE_LOCALE2_H
+#define _XLOCALE_LOCALE2_H
+
+char	*strptime_l(const char *__restrict, const char *__restrict,
+		struct tm *__restrict, locale_t);
+
+#endif /* _XLOCALE_LOCALE2_H */
+#endif /* _XLOCALE_H_ */
diff --git a/uefi/arm-trusted-firmware/lib/aarch64/cache_helpers.S b/uefi/arm-trusted-firmware/lib/aarch64/cache_helpers.S
new file mode 100644
index 0000000..dc60102
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/aarch64/cache_helpers.S
@@ -0,0 +1,211 @@
+/*
+ * 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	flush_dcache_range
+	.globl	inv_dcache_range
+	.globl	dcsw_op_louis
+	.globl	dcsw_op_all
+	.globl	dcsw_op_level1
+	.globl	dcsw_op_level2
+	.globl	dcsw_op_level3
+
+	/* ------------------------------------------
+	 * Clean+Invalidate from base address till
+	 * size. 'x0' = addr, 'x1' = size
+	 * ------------------------------------------
+	 */
+func flush_dcache_range
+	dcache_line_size x2, x3
+	add	x1, x0, x1
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+flush_loop:
+	dc	civac, x0
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo    flush_loop
+	dsb	sy
+	ret
+
+
+	/* ------------------------------------------
+	 * Invalidate from base address till
+	 * size. 'x0' = addr, 'x1' = size
+	 * ------------------------------------------
+	 */
+func inv_dcache_range
+	dcache_line_size x2, x3
+	add	x1, x0, x1
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+inv_loop:
+	dc	ivac, x0
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo    inv_loop
+	dsb	sy
+	ret
+
+
+	/* ---------------------------------------------------------------
+	 * Data cache operations by set/way to the level specified
+	 *
+	 * The main function, do_dcsw_op requires:
+	 * x0: The operation type (0-2), as defined in arch.h
+	 * x3: The last cache level to operate on
+	 * x9: clidr_el1
+	 * x10: The cache level to begin operation from
+	 * and will carry out the operation on each data cache from level 0
+	 * to the level in x3 in sequence
+	 *
+	 * The dcsw_op macro sets up the x3 and x9 parameters based on
+	 * clidr_el1 cache information before invoking the main function
+	 * ---------------------------------------------------------------
+	 */
+
+	.macro	dcsw_op shift, fw, ls
+	mrs	x9, clidr_el1
+	ubfx	x3, x9, \shift, \fw
+	lsl	x3, x3, \ls
+	mov	x10, xzr
+	b	do_dcsw_op
+	.endm
+
+func do_dcsw_op
+	cbz	x3, exit
+	adr	x14, dcsw_loop_table	// compute inner loop address
+	add	x14, x14, x0, lsl #5	// inner loop is 8x32-bit instructions
+	mov	x0, x9
+	mov	w8, #1
+loop1:
+	add	x2, x10, x10, lsr #1	// work out 3x current cache level
+	lsr	x1, x0, x2		// extract cache type bits from clidr
+	and	x1, x1, #7		// mask the bits for current cache only
+	cmp	x1, #2			// see what cache we have at this level
+	b.lt	level_done		// nothing to do if no cache or icache
+
+	msr	csselr_el1, x10		// select current cache level in csselr
+	isb				// isb to sych the new cssr&csidr
+	mrs	x1, ccsidr_el1		// read the new ccsidr
+	and	x2, x1, #7		// extract the length of the cache lines
+	add	x2, x2, #4		// add 4 (line length offset)
+	ubfx	x4, x1, #3, #10		// maximum way number
+	clz	w5, w4			// bit position of way size increment
+	lsl	w9, w4, w5		// w9 = aligned max way number
+	lsl	w16, w8, w5		// w16 = way number loop decrement
+	orr	w9, w10, w9		// w9 = combine way and cache number
+	ubfx	w6, w1, #13, #15	// w6 = max set number
+	lsl	w17, w8, w2		// w17 = set number loop decrement
+	dsb	sy			// barrier before we start this level
+	br	x14			// jump to DC operation specific loop
+
+	.macro	dcsw_loop _op
+loop2_\_op:
+	lsl	w7, w6, w2		// w7 = aligned max set number
+
+loop3_\_op:
+	orr	w11, w9, w7		// combine cache, way and set number
+	dc	\_op, x11
+	subs	w7, w7, w17		// decrement set number
+	b.ge	loop3_\_op
+
+	subs	x9, x9, x16		// decrement way number
+	b.ge	loop2_\_op
+
+	b	level_done
+	.endm
+
+level_done:
+	add	x10, x10, #2		// increment cache number
+	cmp	x3, x10
+	b.gt    loop1
+	msr	csselr_el1, xzr		// select cache level 0 in csselr
+	dsb	sy			// barrier to complete final cache operation
+	isb
+exit:
+	ret
+
+dcsw_loop_table:
+	dcsw_loop isw
+	dcsw_loop cisw
+	dcsw_loop csw
+
+
+func dcsw_op_louis
+	dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
+
+
+func dcsw_op_all
+	dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
+
+	/* ---------------------------------------------------------------
+	 *  Helper macro for data cache operations by set/way for the
+	 *  level specified
+	 * ---------------------------------------------------------------
+	 */
+	.macro dcsw_op_level level
+	mrs	x9, clidr_el1
+	mov	x3, \level
+	sub	x10, x3, #2
+	b	do_dcsw_op
+	.endm
+
+	/* ---------------------------------------------------------------
+	 * Data cache operations by set/way for level 1 cache
+	 *
+	 * The main function, do_dcsw_op requires:
+	 * x0: The operation type (0-2), as defined in arch.h
+	 * ---------------------------------------------------------------
+	 */
+func dcsw_op_level1
+	dcsw_op_level #(1 << LEVEL_SHIFT)
+
+	/* ---------------------------------------------------------------
+	 * Data cache operations by set/way for level 2 cache
+	 *
+	 * The main function, do_dcsw_op requires:
+	 * x0: The operation type (0-2), as defined in arch.h
+	 * ---------------------------------------------------------------
+	 */
+func dcsw_op_level2
+	dcsw_op_level #(2 << LEVEL_SHIFT)
+
+	/* ---------------------------------------------------------------
+	 * Data cache operations by set/way for level 3 cache
+	 *
+	 * The main function, do_dcsw_op requires:
+	 * x0: The operation type (0-2), as defined in arch.h
+	 * ---------------------------------------------------------------
+	 */
+func dcsw_op_level3
+	dcsw_op_level #(3 << LEVEL_SHIFT)
diff --git a/uefi/arm-trusted-firmware/lib/aarch64/misc_helpers.S b/uefi/arm-trusted-firmware/lib/aarch64/misc_helpers.S
new file mode 100644
index 0000000..f605bf4
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/aarch64/misc_helpers.S
@@ -0,0 +1,172 @@
+/*
+ * 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 <assert_macros.S>
+
+	.globl	get_afflvl_shift
+	.globl	mpidr_mask_lower_afflvls
+	.globl	eret
+	.globl	smc
+
+	.globl	zeromem16
+	.globl	memcpy16
+
+	.globl	disable_mmu_el3
+	.globl	disable_mmu_icache_el3
+
+#if SUPPORT_VFP
+	.globl	enable_vfp
+#endif
+
+func get_afflvl_shift
+	cmp	x0, #3
+	cinc	x0, x0, eq
+	mov	x1, #MPIDR_AFFLVL_SHIFT
+	lsl	x0, x0, x1
+	ret
+
+func mpidr_mask_lower_afflvls
+	cmp	x1, #3
+	cinc	x1, x1, eq
+	mov	x2, #MPIDR_AFFLVL_SHIFT
+	lsl	x2, x1, x2
+	lsr	x0, x0, x2
+	lsl	x0, x0, x2
+	ret
+
+
+func eret
+	eret
+
+
+func smc
+	smc	#0
+
+/* -----------------------------------------------------------------------
+ * void zeromem16(void *mem, unsigned int length);
+ *
+ * Initialise a memory region to 0.
+ * The memory address must be 16-byte aligned.
+ * -----------------------------------------------------------------------
+ */
+func zeromem16
+#if ASM_ASSERTION
+	tst	x0, #0xf
+	ASM_ASSERT(eq)
+#endif
+	add	x2, x0, x1
+/* zero 16 bytes at a time */
+z_loop16:
+	sub	x3, x2, x0
+	cmp	x3, #16
+	b.lt	z_loop1
+	stp	xzr, xzr, [x0], #16
+	b	z_loop16
+/* zero byte per byte */
+z_loop1:
+	cmp	x0, x2
+	b.eq	z_end
+	strb	wzr, [x0], #1
+	b	z_loop1
+z_end:	ret
+
+
+/* --------------------------------------------------------------------------
+ * void memcpy16(void *dest, const void *src, unsigned int length)
+ *
+ * Copy length bytes from memory area src to memory area dest.
+ * The memory areas should not overlap.
+ * Destination and source addresses must be 16-byte aligned.
+ * --------------------------------------------------------------------------
+ */
+func memcpy16
+#if ASM_ASSERTION
+	orr	x3, x0, x1
+	tst	x3, #0xf
+	ASM_ASSERT(eq)
+#endif
+/* copy 16 bytes at a time */
+m_loop16:
+	cmp	x2, #16
+	b.lt	m_loop1
+	ldp	x3, x4, [x1], #16
+	stp	x3, x4, [x0], #16
+	sub	x2, x2, #16
+	b	m_loop16
+/* copy byte per byte */
+m_loop1:
+	cbz	x2, m_end
+	ldrb	w3, [x1], #1
+	strb	w3, [x0], #1
+	subs	x2, x2, #1
+	b.ne	m_loop1
+m_end:	ret
+
+/* ---------------------------------------------------------------------------
+ * Disable the MMU at EL3
+ * This is implemented in assembler to ensure that the data cache is cleaned
+ * and invalidated after the MMU is disabled without any intervening cacheable
+ * data accesses
+ * ---------------------------------------------------------------------------
+ */
+
+func disable_mmu_el3
+	mov	x1, #(SCTLR_M_BIT | SCTLR_C_BIT)
+do_disable_mmu:
+	mrs	x0, sctlr_el3
+	bic	x0, x0, x1
+	msr	sctlr_el3, x0
+	isb				// ensure MMU is off
+	mov	x0, #DCCISW		// DCache clean and invalidate
+	b	dcsw_op_all
+
+
+func disable_mmu_icache_el3
+	mov	x1, #(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT)
+	b	do_disable_mmu
+
+/* ---------------------------------------------------------------------------
+ * Enable the use of VFP at EL3
+ * ---------------------------------------------------------------------------
+ */
+#if SUPPORT_VFP
+func enable_vfp
+	mrs	x0, cpacr_el1
+	orr	x0, x0, #CPACR_VFP_BITS
+	msr	cpacr_el1, x0
+	mrs	x0, cptr_el3
+	mov	x1, #AARCH64_CPTR_TFP
+	bic	x0, x0, x1
+	msr	cptr_el3, x0
+	isb
+	ret
+#endif
diff --git a/uefi/arm-trusted-firmware/lib/aarch64/xlat_helpers.c b/uefi/arm-trusted-firmware/lib/aarch64/xlat_helpers.c
new file mode 100644
index 0000000..d401ffc
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/aarch64/xlat_helpers.c
@@ -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 <arch.h>
+#include <assert.h>
+
+/*******************************************************************************
+ * Helper to create a level 1/2 table descriptor which points to a level 2/3
+ * table.
+ ******************************************************************************/
+unsigned long create_table_desc(unsigned long *next_table_ptr)
+{
+	unsigned long desc = (unsigned long) next_table_ptr;
+
+	/* Clear the last 12 bits */
+	desc >>= FOUR_KB_SHIFT;
+	desc <<= FOUR_KB_SHIFT;
+
+	desc |= TABLE_DESC;
+
+	return desc;
+}
+
+/*******************************************************************************
+ * Helper to create a level 1/2/3 block descriptor which maps the va to addr
+ ******************************************************************************/
+unsigned long create_block_desc(unsigned long desc,
+				unsigned long addr,
+				unsigned int level)
+{
+	switch (level) {
+	case LEVEL1:
+		desc |= (addr << FIRST_LEVEL_DESC_N) | BLOCK_DESC;
+		break;
+	case LEVEL2:
+		desc |= (addr << SECOND_LEVEL_DESC_N) | BLOCK_DESC;
+		break;
+	case LEVEL3:
+		desc |= (addr << THIRD_LEVEL_DESC_N) | TABLE_DESC;
+		break;
+	default:
+		assert(0);
+	}
+
+	return desc;
+}
+
+/*******************************************************************************
+ * Helper to create a level 1/2/3 block descriptor which maps the va to output_
+ * addr with Device nGnRE attributes.
+ ******************************************************************************/
+unsigned long create_device_block(unsigned long output_addr,
+				  unsigned int level,
+				  unsigned int ns)
+{
+	unsigned long upper_attrs, lower_attrs, desc;
+
+	lower_attrs = LOWER_ATTRS(ACCESS_FLAG | OSH | AP_RW);
+	lower_attrs |= LOWER_ATTRS(ns | ATTR_DEVICE_INDEX);
+	upper_attrs = UPPER_ATTRS(XN);
+	desc = upper_attrs | lower_attrs;
+
+	return create_block_desc(desc, output_addr, level);
+}
+
+/*******************************************************************************
+ * Helper to create a level 1/2/3 block descriptor which maps the va to output_
+ * addr with inner-shareable normal wbwa read-only memory attributes.
+ ******************************************************************************/
+unsigned long create_romem_block(unsigned long output_addr,
+				 unsigned int level,
+				 unsigned int ns)
+{
+	unsigned long upper_attrs, lower_attrs, desc;
+
+	lower_attrs = LOWER_ATTRS(ACCESS_FLAG | ISH | AP_RO);
+	lower_attrs |= LOWER_ATTRS(ns | ATTR_IWBWA_OWBWA_NTR_INDEX);
+	upper_attrs = UPPER_ATTRS(0ull);
+	desc = upper_attrs | lower_attrs;
+
+	return create_block_desc(desc, output_addr, level);
+}
+
+/*******************************************************************************
+ * Helper to create a level 1/2/3 block descriptor which maps the va to output_
+ * addr with inner-shareable normal wbwa read-write memory attributes.
+ ******************************************************************************/
+unsigned long create_rwmem_block(unsigned long output_addr,
+				 unsigned int level,
+				 unsigned int ns)
+{
+	unsigned long upper_attrs, lower_attrs, desc;
+
+	lower_attrs = LOWER_ATTRS(ACCESS_FLAG | ISH | AP_RW);
+	lower_attrs |= LOWER_ATTRS(ns | ATTR_IWBWA_OWBWA_NTR_INDEX);
+	upper_attrs = UPPER_ATTRS(XN);
+	desc = upper_attrs | lower_attrs;
+
+	return create_block_desc(desc, output_addr, level);
+}
diff --git a/uefi/arm-trusted-firmware/lib/aarch64/xlat_tables.c b/uefi/arm-trusted-firmware/lib/aarch64/xlat_tables.c
new file mode 100644
index 0000000..ddc9ba8
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/aarch64/xlat_tables.c
@@ -0,0 +1,351 @@
+/*
+ * 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 <arch_helpers.h>
+#include <assert.h>
+#include <cassert.h>
+#include <platform_def.h>
+#include <string.h>
+#include <xlat_tables.h>
+
+
+#ifndef DEBUG_XLAT_TABLE
+#define DEBUG_XLAT_TABLE 0
+#endif
+
+#if DEBUG_XLAT_TABLE
+#define debug_print(...) printf(__VA_ARGS__)
+#else
+#define debug_print(...) ((void)0)
+#endif
+
+CASSERT(ADDR_SPACE_SIZE > 0, assert_valid_addr_space_size);
+
+#define UNSET_DESC	~0ul
+
+#define NUM_L1_ENTRIES (ADDR_SPACE_SIZE >> L1_XLAT_ADDRESS_SHIFT)
+
+static uint64_t l1_xlation_table[NUM_L1_ENTRIES]
+__aligned(NUM_L1_ENTRIES * sizeof(uint64_t));
+
+static uint64_t xlat_tables[MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES]
+__aligned(XLAT_TABLE_SIZE) __attribute__((section("xlat_table")));
+
+static unsigned next_xlat;
+static unsigned long max_pa;
+static unsigned long max_va;
+static unsigned long tcr_ps_bits;
+
+/*
+ * Array of all memory regions stored in order of ascending base address.
+ * The list is terminated by the first entry with size == 0.
+ */
+static mmap_region_t mmap[MAX_MMAP_REGIONS + 1];
+
+
+static void print_mmap(void)
+{
+#if DEBUG_XLAT_TABLE
+	debug_print("mmap:\n");
+	mmap_region_t *mm = mmap;
+	while (mm->size) {
+		debug_print(" %010lx %010lx %10lx %x\n", mm->base_va,
+					mm->base_pa, mm->size, mm->attr);
+		++mm;
+	};
+	debug_print("\n");
+#endif
+}
+
+void mmap_add_region(unsigned long base_pa, unsigned long base_va,
+			unsigned long size, unsigned attr)
+{
+	mmap_region_t *mm = mmap;
+	mmap_region_t *mm_last = mm + sizeof(mmap) / sizeof(mmap[0]) - 1;
+	unsigned long pa_end = base_pa + size - 1;
+	unsigned long va_end = base_va + size - 1;
+
+	assert(IS_PAGE_ALIGNED(base_pa));
+	assert(IS_PAGE_ALIGNED(base_va));
+	assert(IS_PAGE_ALIGNED(size));
+
+	if (!size)
+		return;
+
+	/* Find correct place in mmap to insert new region */
+	while (mm->base_va < base_va && mm->size)
+		++mm;
+
+	/* Make room for new region by moving other regions up by one place */
+	memmove(mm + 1, mm, (uintptr_t)mm_last - (uintptr_t)mm);
+
+	/* Check we haven't lost the empty sentinal from the end of the array */
+	assert(mm_last->size == 0);
+
+	mm->base_pa = base_pa;
+	mm->base_va = base_va;
+	mm->size = size;
+	mm->attr = attr;
+
+	if (pa_end > max_pa)
+		max_pa = pa_end;
+	if (va_end > max_va)
+		max_va = va_end;
+}
+
+void mmap_add(const mmap_region_t *mm)
+{
+	while (mm->size) {
+		mmap_add_region(mm->base_pa, mm->base_va, mm->size, mm->attr);
+		++mm;
+	}
+}
+
+static unsigned long mmap_desc(unsigned attr, unsigned long addr_pa,
+					unsigned level)
+{
+	unsigned long desc = addr_pa;
+
+	desc |= level == 3 ? TABLE_DESC : BLOCK_DESC;
+
+	desc |= attr & MT_NS ? LOWER_ATTRS(NS) : 0;
+
+	desc |= attr & MT_RW ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
+
+	desc |= LOWER_ATTRS(ACCESS_FLAG);
+
+	if (attr & MT_MEMORY) {
+		desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH);
+		if (attr & MT_RW)
+			desc |= UPPER_ATTRS(XN);
+	} else {
+		desc |= LOWER_ATTRS(ATTR_DEVICE_INDEX | OSH);
+		desc |= UPPER_ATTRS(XN);
+	}
+
+	debug_print(attr & MT_MEMORY ? "MEM" : "DEV");
+	debug_print(attr & MT_RW ? "-RW" : "-RO");
+	debug_print(attr & MT_NS ? "-NS" : "-S");
+
+	return desc;
+}
+
+static int mmap_region_attr(mmap_region_t *mm, unsigned long base_va,
+					unsigned long size)
+{
+	int attr = mm->attr;
+
+	for (;;) {
+		++mm;
+
+		if (!mm->size)
+			return attr; /* Reached end of list */
+
+		if (mm->base_va >= base_va + size)
+			return attr; /* Next region is after area so end */
+
+		if (mm->base_va + mm->size <= base_va)
+			continue; /* Next region has already been overtaken */
+
+		if ((mm->attr & attr) == attr)
+			continue; /* Region doesn't override attribs so skip */
+
+		attr &= mm->attr;
+
+		if (mm->base_va > base_va ||
+			mm->base_va + mm->size < base_va + size)
+			return -1; /* Region doesn't fully cover our area */
+	}
+}
+
+static mmap_region_t *init_xlation_table(mmap_region_t *mm,
+					unsigned long base_va,
+					unsigned long *table, unsigned level)
+{
+	unsigned level_size_shift = L1_XLAT_ADDRESS_SHIFT - (level - 1) *
+						XLAT_TABLE_ENTRIES_SHIFT;
+	unsigned level_size = 1 << level_size_shift;
+	unsigned long level_index_mask = XLAT_TABLE_ENTRIES_MASK << level_size_shift;
+
+	assert(level <= 3);
+
+	debug_print("New xlat table:\n");
+
+	do  {
+		unsigned long desc = UNSET_DESC;
+
+		if (mm->base_va + mm->size <= base_va) {
+			/* Area now after the region so skip it */
+			++mm;
+			continue;
+		}
+
+		debug_print("      %010lx %8lx " + 6 - 2 * level, base_va,
+				level_size);
+
+		if (mm->base_va >= base_va + level_size) {
+			/* Next region is after area so nothing to map yet */
+			desc = INVALID_DESC;
+		} else if (mm->base_va <= base_va && mm->base_va + mm->size >=
+				base_va + level_size) {
+			/* Next region covers all of area */
+			int attr = mmap_region_attr(mm, base_va, level_size);
+			if (attr >= 0)
+				desc = mmap_desc(attr,
+					base_va - mm->base_va + mm->base_pa,
+					level);
+		}
+		/* else Next region only partially covers area, so need */
+
+		if (desc == UNSET_DESC) {
+			/* Area not covered by a region so need finer table */
+			unsigned long *new_table = xlat_tables[next_xlat++];
+			assert(next_xlat <= MAX_XLAT_TABLES);
+			desc = TABLE_DESC | (unsigned long)new_table;
+
+			/* Recurse to fill in new table */
+			mm = init_xlation_table(mm, base_va,
+						new_table, level+1);
+		}
+
+		debug_print("\n");
+
+		*table++ = desc;
+		base_va += level_size;
+	} while (mm->size && (base_va & level_index_mask));
+
+	return mm;
+}
+
+static unsigned int calc_physical_addr_size_bits(unsigned long max_addr)
+{
+	/* Physical address can't exceed 48 bits */
+	assert((max_addr & ADDR_MASK_48_TO_63) == 0);
+
+	/* 48 bits address */
+	if (max_addr & ADDR_MASK_44_TO_47)
+		return TCR_PS_BITS_256TB;
+
+	/* 44 bits address */
+	if (max_addr & ADDR_MASK_42_TO_43)
+		return TCR_PS_BITS_16TB;
+
+	/* 42 bits address */
+	if (max_addr & ADDR_MASK_40_TO_41)
+		return TCR_PS_BITS_4TB;
+
+	/* 40 bits address */
+	if (max_addr & ADDR_MASK_36_TO_39)
+		return TCR_PS_BITS_1TB;
+
+	/* 36 bits address */
+	if (max_addr & ADDR_MASK_32_TO_35)
+		return TCR_PS_BITS_64GB;
+
+	return TCR_PS_BITS_4GB;
+}
+
+void init_xlat_tables(void)
+{
+	print_mmap();
+	init_xlation_table(mmap, 0, l1_xlation_table, 1);
+	tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
+	assert(max_va < ADDR_SPACE_SIZE);
+}
+
+/*******************************************************************************
+ * Macro generating the code for the function enabling the MMU in the given
+ * exception level, assuming that the pagetables have already been created.
+ *
+ *   _el:		Exception level at which the function will run
+ *   _tcr_extra:	Extra bits to set in the TCR register. This mask will
+ *			be OR'ed with the default TCR value.
+ *   _tlbi_fct:		Function to invalidate the TLBs at the current
+ *			exception level
+ ******************************************************************************/
+#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct)		\
+	void enable_mmu_el##_el(uint32_t flags)				\
+	{								\
+		uint64_t mair, tcr, ttbr;				\
+		uint32_t sctlr;						\
+									\
+		assert(IS_IN_EL(_el));					\
+		assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0);	\
+									\
+		/* Set attributes in the right indices of the MAIR */	\
+		mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);	\
+		mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,		\
+				ATTR_IWBWA_OWBWA_NTR_INDEX);		\
+		write_mair_el##_el(mair);				\
+									\
+		/* Invalidate TLBs at the current exception level */	\
+		_tlbi_fct();						\
+									\
+		/* Set TCR bits as well. */				\
+		/* Inner & outer WBWA & shareable + T0SZ = 32 */	\
+		tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA |	\
+			TCR_RGN_INNER_WBA |				\
+			(64 - __builtin_ctzl(ADDR_SPACE_SIZE));		\
+		tcr |= _tcr_extra;					\
+		write_tcr_el##_el(tcr);					\
+									\
+		/* Set TTBR bits as well */				\
+		ttbr = (uint64_t) l1_xlation_table;			\
+		write_ttbr0_el##_el(ttbr);				\
+									\
+		/* Ensure all translation table writes have drained */	\
+		/* into memory, the TLB invalidation is complete, */	\
+		/* and translation register writes are committed */	\
+		/* before enabling the MMU */				\
+		dsb();							\
+		isb();							\
+									\
+		sctlr = read_sctlr_el##_el();				\
+		sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT;			\
+									\
+		if (flags & DISABLE_DCACHE)				\
+			sctlr &= ~SCTLR_C_BIT;				\
+		else							\
+			sctlr |= SCTLR_C_BIT;				\
+									\
+		write_sctlr_el##_el(sctlr);				\
+									\
+		/* Ensure the MMU enable takes effect immediately */	\
+		isb();							\
+	}
+
+/* Define EL1 and EL3 variants of the function enabling the MMU */
+DEFINE_ENABLE_MMU_EL(1,
+		(tcr_ps_bits << TCR_EL1_IPS_SHIFT),
+		tlbivmalle1)
+DEFINE_ENABLE_MMU_EL(3,
+		TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT),
+		tlbialle3)
diff --git a/uefi/arm-trusted-firmware/lib/cpus/aarch64/aem_generic.S b/uefi/arm-trusted-firmware/lib/cpus/aarch64/aem_generic.S
new file mode 100644
index 0000000..58a64a6
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/cpus/aarch64/aem_generic.S
@@ -0,0 +1,89 @@
+/*
+ * 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 <aem_generic.h>
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+
+func aem_generic_core_pwr_dwn
+	/* ---------------------------------------------
+	 * Disable the Data Cache.
+	 * ---------------------------------------------
+	 */
+	mrs	x1, sctlr_el3
+	bic	x1, x1, #SCTLR_C_BIT
+	msr	sctlr_el3, x1
+	isb
+
+	mov	x0, #DCCISW
+
+	/* ---------------------------------------------
+	 * Flush L1 cache to PoU.
+	 * ---------------------------------------------
+	 */
+	b	dcsw_op_louis
+
+
+func aem_generic_cluster_pwr_dwn
+	/* ---------------------------------------------
+	 * Disable the Data Cache.
+	 * ---------------------------------------------
+	 */
+	mrs	x1, sctlr_el3
+	bic	x1, x1, #SCTLR_C_BIT
+	msr	sctlr_el3, x1
+	isb
+
+	/* ---------------------------------------------
+	 * Flush L1 and L2 caches to PoC.
+	 * ---------------------------------------------
+	 */
+	mov	x0, #DCCISW
+	b	dcsw_op_all
+
+	/* ---------------------------------------------
+	 * This function provides cpu specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+func aem_generic_cpu_reg_dump
+	mov	x6, #0 /* no registers to report */
+	ret
+
+
+/* cpu_ops for Base AEM FVP */
+declare_cpu_ops aem_generic, BASE_AEM_MIDR, 1
+
+/* cpu_ops for Foundation FVP */
+declare_cpu_ops aem_generic, FOUNDATION_AEM_MIDR, 1
diff --git a/uefi/arm-trusted-firmware/lib/cpus/aarch64/cortex_a53.S b/uefi/arm-trusted-firmware/lib/cpus/aarch64/cortex_a53.S
new file mode 100644
index 0000000..188f3c1
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/cpus/aarch64/cortex_a53.S
@@ -0,0 +1,153 @@
+/*
+ * 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 <bl_common.h>
+#include <cortex_a53.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+	/* ---------------------------------------------
+	 * Disable L1 data cache and unified L2 cache
+	 * ---------------------------------------------
+	 */
+func cortex_a53_disable_dcache
+	mrs	x1, sctlr_el3
+	bic	x1, x1, #SCTLR_C_BIT
+	msr	sctlr_el3, x1
+	isb
+	ret
+
+	/* ---------------------------------------------
+	 * Disable intra-cluster coherency
+	 * ---------------------------------------------
+	 */
+func cortex_a53_disable_smp
+	mrs	x0, CPUECTLR_EL1
+	bic	x0, x0, #CPUECTLR_SMP_BIT
+	msr	CPUECTLR_EL1, x0
+	isb
+	dsb	sy
+	ret
+
+func cortex_a53_reset_func
+	/* ---------------------------------------------
+	 * As a bare minimum enable the SMP bit if it is
+	 * not already set.
+	 * Clobbers : x0
+	 * ---------------------------------------------
+	 */
+	mrs	x0, CPUECTLR_EL1
+	tst	x0, #CPUECTLR_SMP_BIT
+	b.ne	skip_smp_setup
+	orr	x0, x0, #CPUECTLR_SMP_BIT
+	msr	CPUECTLR_EL1, x0
+	isb
+skip_smp_setup:
+	ret
+
+func cortex_a53_core_pwr_dwn
+	mov	x18, x30
+
+	/* ---------------------------------------------
+	 * Turn off caches.
+	 * ---------------------------------------------
+	 */
+	bl	cortex_a53_disable_dcache
+
+	/* ---------------------------------------------
+	 * Flush L1 caches.
+	 * ---------------------------------------------
+	 */
+	mov	x0, #DCCISW
+	bl	dcsw_op_level1
+
+	/* ---------------------------------------------
+	 * Come out of intra cluster coherency
+	 * ---------------------------------------------
+	 */
+	mov	x30, x18
+	b	cortex_a53_disable_smp
+
+func cortex_a53_cluster_pwr_dwn
+	mov	x18, x30
+
+	/* ---------------------------------------------
+	 * Turn off caches.
+	 * ---------------------------------------------
+	 */
+	bl	cortex_a53_disable_dcache
+
+	/* ---------------------------------------------
+	 * Flush L1 caches.
+	 * ---------------------------------------------
+	 */
+	mov	x0, #DCCISW
+	bl	dcsw_op_level1
+
+	/* ---------------------------------------------
+	 * Disable the optional ACP.
+	 * ---------------------------------------------
+	 */
+	bl	plat_disable_acp
+
+	/* ---------------------------------------------
+	 * Flush L2 caches.
+	 * ---------------------------------------------
+	 */
+	mov	x0, #DCCISW
+	bl	dcsw_op_level2
+
+	/* ---------------------------------------------
+	 * Come out of intra cluster coherency
+	 * ---------------------------------------------
+	 */
+	mov	x30, x18
+	b	cortex_a53_disable_smp
+
+	/* ---------------------------------------------
+	 * This function provides cortex_a53 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a53_regs, "aS"
+cortex_a53_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a53_cpu_reg_dump
+	adr	x6, cortex_a53_regs
+	mrs	x8, CPUECTLR_EL1
+	ret
+
+declare_cpu_ops cortex_a53, CORTEX_A53_MIDR
diff --git a/uefi/arm-trusted-firmware/lib/cpus/aarch64/cortex_a57.S b/uefi/arm-trusted-firmware/lib/cpus/aarch64/cortex_a57.S
new file mode 100644
index 0000000..eb6c736
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/cpus/aarch64/cortex_a57.S
@@ -0,0 +1,303 @@
+/*
+ * 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 <assert_macros.S>
+#include <bl_common.h>
+#include <cortex_a57.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+	/* ---------------------------------------------
+	 * Disable L1 data cache and unified L2 cache
+	 * ---------------------------------------------
+	 */
+func cortex_a57_disable_dcache
+	mrs	x1, sctlr_el3
+	bic	x1, x1, #SCTLR_C_BIT
+	msr	sctlr_el3, x1
+	isb
+	ret
+
+	/* ---------------------------------------------
+	 * Disable all types of L2 prefetches.
+	 * ---------------------------------------------
+	 */
+func cortex_a57_disable_l2_prefetch
+	mrs	x0, CPUECTLR_EL1
+	orr	x0, x0, #CPUECTLR_DIS_TWD_ACC_PFTCH_BIT
+	mov	x1, #CPUECTLR_L2_IPFTCH_DIST_MASK
+	orr	x1, x1, #CPUECTLR_L2_DPFTCH_DIST_MASK
+	bic	x0, x0, x1
+	msr	CPUECTLR_EL1, x0
+	isb
+	dsb	ish
+	ret
+
+	/* ---------------------------------------------
+	 * Disable intra-cluster coherency
+	 * ---------------------------------------------
+	 */
+func cortex_a57_disable_smp
+	mrs	x0, CPUECTLR_EL1
+	bic	x0, x0, #CPUECTLR_SMP_BIT
+	msr	CPUECTLR_EL1, x0
+	ret
+
+	/* ---------------------------------------------
+	 * Disable debug interfaces
+	 * ---------------------------------------------
+	 */
+func cortex_a57_disable_ext_debug
+	mov	x0, #1
+	msr	osdlr_el1, x0
+	isb
+	dsb	sy
+	ret
+
+	/* --------------------------------------------------
+	 * Errata Workaround for Cortex A57 Errata #806969.
+	 * This applies only to revision r0p0 of Cortex A57.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Clobbers : x0 - x5
+	 * --------------------------------------------------
+	 */
+func errata_a57_806969_wa
+	/*
+	 * Compare x0 against revision r0p0
+	 */
+	cbz	x0, apply_806969
+#if DEBUG
+	b	print_revision_warning
+#else
+	ret
+#endif
+apply_806969:
+	/*
+	 * Test if errata has already been applied in an earlier
+	 * invocation of the reset handler and does not need to
+	 * be applied again.
+	 */
+	mrs	x1, CPUACTLR_EL1
+	tst	x1, #CPUACTLR_NO_ALLOC_WBWA
+	b.ne	skip_806969
+	orr	x1, x1, #CPUACTLR_NO_ALLOC_WBWA
+	msr	CPUACTLR_EL1, x1
+skip_806969:
+	ret
+
+
+	/* ---------------------------------------------------
+	 * Errata Workaround for Cortex A57 Errata #813420.
+	 * This applies only to revision r0p0 of Cortex A57.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Clobbers : x0 - x5
+	 * ---------------------------------------------------
+	 */
+func errata_a57_813420_wa
+	/*
+	 * Compare x0 against revision r0p0
+	 */
+	cbz	x0, apply_813420
+#if DEBUG
+	b	print_revision_warning
+#else
+	ret
+#endif
+apply_813420:
+	/*
+	 * Test if errata has already been applied in an earlier
+	 * invocation of the reset handler and does not need to
+	 * be applied again.
+	 */
+	mrs	x1, CPUACTLR_EL1
+	tst	x1, #CPUACTLR_DCC_AS_DCCI
+	b.ne	skip_813420
+	orr	x1, x1, #CPUACTLR_DCC_AS_DCCI
+	msr	CPUACTLR_EL1, x1
+skip_813420:
+	ret
+
+	/* -------------------------------------------------
+	 * The CPU Ops reset function for Cortex-A57.
+	 * Clobbers: x0-x5, x15, x19, x30
+	 * -------------------------------------------------
+	 */
+func cortex_a57_reset_func
+	mov	x19, x30
+	mrs	x0, midr_el1
+
+	/*
+	 * Extract the variant[20:23] and revision[0:3] from x0
+	 * and pack it in x15[0:7] as variant[4:7] and revision[0:3].
+	 * First extract x0[16:23] to x15[0:7] and zero fill the rest.
+	 * Then extract x0[0:3] into x15[0:3] retaining other bits.
+	 */
+	ubfx	x15, x0, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), #(MIDR_REV_BITS + MIDR_VAR_BITS)
+	bfxil	x15, x0, #MIDR_REV_SHIFT, #MIDR_REV_BITS
+
+#if ERRATA_A57_806969
+	mov	x0, x15
+	bl	errata_a57_806969_wa
+#endif
+
+#if ERRATA_A57_813420
+	mov	x0, x15
+	bl	errata_a57_813420_wa
+#endif
+
+	/* ---------------------------------------------
+	 * As a bare minimum enable the SMP bit if it is
+	 * not already set.
+	 * ---------------------------------------------
+	 */
+	mrs	x0, CPUECTLR_EL1
+	tst	x0, #CPUECTLR_SMP_BIT
+	b.ne	skip_smp_setup
+	orr	x0, x0, #CPUECTLR_SMP_BIT
+	msr	CPUECTLR_EL1, x0
+skip_smp_setup:
+	isb
+	ret	x19
+
+	/* ----------------------------------------------------
+	 * The CPU Ops core power down function for Cortex-A57.
+	 * ----------------------------------------------------
+	 */
+func cortex_a57_core_pwr_dwn
+	mov	x18, x30
+
+	/* ---------------------------------------------
+	 * Turn off caches.
+	 * ---------------------------------------------
+	 */
+	bl	cortex_a57_disable_dcache
+
+	/* ---------------------------------------------
+	 * Disable the L2 prefetches.
+	 * ---------------------------------------------
+	 */
+	bl	cortex_a57_disable_l2_prefetch
+
+	/* ---------------------------------------------
+	 * Flush L1 caches.
+	 * ---------------------------------------------
+	 */
+	mov	x0, #DCCISW
+	bl	dcsw_op_level1
+
+	/* ---------------------------------------------
+	 * Come out of intra cluster coherency
+	 * ---------------------------------------------
+	 */
+	bl	cortex_a57_disable_smp
+
+	/* ---------------------------------------------
+	 * Force the debug interfaces to be quiescent
+	 * ---------------------------------------------
+	 */
+	mov	x30, x18
+	b	cortex_a57_disable_ext_debug
+
+	/* -------------------------------------------------------
+	 * The CPU Ops cluster power down function for Cortex-A57.
+	 * -------------------------------------------------------
+	 */
+func cortex_a57_cluster_pwr_dwn
+	mov	x18, x30
+
+	/* ---------------------------------------------
+	 * Turn off caches.
+	 * ---------------------------------------------
+	 */
+	bl	cortex_a57_disable_dcache
+
+	/* ---------------------------------------------
+	 * Disable the L2 prefetches.
+	 * ---------------------------------------------
+	 */
+	bl	cortex_a57_disable_l2_prefetch
+
+#if !SKIP_A57_L1_FLUSH_PWR_DWN
+	/* -------------------------------------------------
+	 * Flush the L1 caches.
+	 * -------------------------------------------------
+	 */
+	mov	x0, #DCCISW
+	bl	dcsw_op_level1
+#endif
+	/* ---------------------------------------------
+	 * Disable the optional ACP.
+	 * ---------------------------------------------
+	 */
+	bl	plat_disable_acp
+
+	/* -------------------------------------------------
+	 * Flush the L2 caches.
+	 * -------------------------------------------------
+	 */
+	mov	x0, #DCCISW
+	bl	dcsw_op_level2
+
+	/* ---------------------------------------------
+	 * Come out of intra cluster coherency
+	 * ---------------------------------------------
+	 */
+	bl	cortex_a57_disable_smp
+
+	/* ---------------------------------------------
+	 * Force the debug interfaces to be quiescent
+	 * ---------------------------------------------
+	 */
+	mov	x30, x18
+	b	cortex_a57_disable_ext_debug
+
+	/* ---------------------------------------------
+	 * This function provides cortex_a57 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_a57_regs, "aS"
+cortex_a57_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_a57_cpu_reg_dump
+	adr	x6, cortex_a57_regs
+	mrs	x8, CPUECTLR_EL1
+	ret
+
+
+declare_cpu_ops cortex_a57, CORTEX_A57_MIDR
diff --git a/uefi/arm-trusted-firmware/lib/cpus/aarch64/cpu_helpers.S b/uefi/arm-trusted-firmware/lib/cpus/aarch64/cpu_helpers.S
new file mode 100644
index 0000000..bebe7c0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/cpus/aarch64/cpu_helpers.S
@@ -0,0 +1,236 @@
+/*
+ * 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 <assert_macros.S>
+#include <cpu_macros.S>
+#if IMAGE_BL31
+#include <cpu_data.h>
+#endif
+
+ /* Reset fn is needed in BL at reset vector */
+#if IMAGE_BL1 || IMAGE_BL31
+	/*
+	 * The reset handler common to all platforms.  After a matching
+	 * cpu_ops structure entry is found, the correponding reset_handler
+	 * in the cpu_ops is invoked.
+	 * Clobbers: x0 - x19, x30
+	 */
+	.globl	reset_handler
+func reset_handler
+	mov	x19, x30
+
+	/* The plat_reset_handler can clobber x0 - x18, x30 */
+	bl	plat_reset_handler
+
+	/* Get the matching cpu_ops pointer */
+	bl	get_cpu_ops_ptr
+#if ASM_ASSERTION
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
+
+	/* Get the cpu_ops reset handler */
+	ldr	x2, [x0, #CPU_RESET_FUNC]
+	mov	x30, x19
+	cbz	x2, 1f
+
+	/* The cpu_ops reset handler can clobber x0 - x19, x30 */
+	br	x2
+1:
+	ret
+
+#endif /* IMAGE_BL1 || IMAGE_BL31 */
+
+#if IMAGE_BL31 /* The power down core and cluster is needed only in  BL31 */
+	/*
+	 * The prepare core power down function for all platforms.  After
+	 * the cpu_ops pointer is retrieved from cpu_data, the corresponding
+	 * pwr_dwn_core in the cpu_ops is invoked.
+	 */
+	.globl	prepare_core_pwr_dwn
+func prepare_core_pwr_dwn
+	mrs	x1, tpidr_el3
+	ldr	x0, [x1, #CPU_DATA_CPU_OPS_PTR]
+#if ASM_ASSERTION
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
+
+	/* Get the cpu_ops core_pwr_dwn handler */
+	ldr	x1, [x0, #CPU_PWR_DWN_CORE]
+	br	x1
+
+	/*
+	 * The prepare cluster power down function for all platforms.  After
+	 * the cpu_ops pointer is retrieved from cpu_data, the corresponding
+	 * pwr_dwn_cluster in the cpu_ops is invoked.
+	 */
+	.globl	prepare_cluster_pwr_dwn
+func prepare_cluster_pwr_dwn
+	mrs	x1, tpidr_el3
+	ldr	x0, [x1, #CPU_DATA_CPU_OPS_PTR]
+#if ASM_ASSERTION
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
+
+	/* Get the cpu_ops cluster_pwr_dwn handler */
+	ldr	x1, [x0, #CPU_PWR_DWN_CLUSTER]
+	br	x1
+
+
+	/*
+	 * Initializes the cpu_ops_ptr if not already initialized
+	 * in cpu_data. This can be called without a runtime stack.
+	 * clobbers: x0 - x6, x10
+	 */
+	.globl	init_cpu_ops
+func init_cpu_ops
+	mrs	x6, tpidr_el3
+	ldr	x0, [x6, #CPU_DATA_CPU_OPS_PTR]
+	cbnz	x0, 1f
+	mov	x10, x30
+	bl	get_cpu_ops_ptr
+#if ASM_ASSERTION
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
+	str	x0, [x6, #CPU_DATA_CPU_OPS_PTR]!
+
+	/*
+	 * Make sure that any pre-fetched cache copies are invalidated.
+	 * Ensure that we are running with cache disable else we
+	 * invalidate our own update.
+	 */
+#if ASM_ASSERTION
+	mrs	x1, sctlr_el3
+	tst	x1, #SCTLR_C_BIT
+	ASM_ASSERT(eq)
+#endif
+	dc	ivac, x6
+	mov x30, x10
+1:
+	ret
+#endif /* IMAGE_BL31 */
+
+#if IMAGE_BL31 && CRASH_REPORTING
+	/*
+	 * The cpu specific registers which need to be reported in a crash
+	 * are reported via cpu_ops cpu_reg_dump function. After a matching
+	 * cpu_ops structure entry is found, the correponding cpu_reg_dump
+	 * in the cpu_ops is invoked.
+	 */
+	.globl	do_cpu_reg_dump
+func do_cpu_reg_dump
+	mov	x16, x30
+
+	/* Get the matching cpu_ops pointer */
+	bl	get_cpu_ops_ptr
+	cbz	x0, 1f
+
+	/* Get the cpu_ops cpu_reg_dump */
+	ldr	x2, [x0, #CPU_REG_DUMP]
+	cbz	x2, 1f
+	blr	x2
+1:
+	mov	x30, x16
+	ret
+#endif
+
+	/*
+	 * The below function returns the cpu_ops structure matching the
+	 * midr of the core. It reads the MIDR_EL1 and finds the matching
+	 * entry in cpu_ops entries. Only the implementation and part number
+	 * are used to match the entries.
+	 * Return :
+	 *     x0 - The matching cpu_ops pointer on Success
+	 *     x0 - 0 on failure.
+	 * Clobbers : x0 - x5
+	 */
+	.globl	get_cpu_ops_ptr
+func get_cpu_ops_ptr
+	/* Get the cpu_ops start and end locations */
+	adr	x4, (__CPU_OPS_START__ + CPU_MIDR)
+	adr	x5, (__CPU_OPS_END__ + CPU_MIDR)
+
+	/* Initialize the return parameter */
+	mov	x0, #0
+
+	/* Read the MIDR_EL1 */
+	mrs	x2, midr_el1
+	mov_imm	x3, CPU_IMPL_PN_MASK
+
+	/* Retain only the implementation and part number using mask */
+	and	w2, w2, w3
+1:
+	/* Check if we have reached end of list */
+	cmp	x4, x5
+	b.eq	error_exit
+
+	/* load the midr from the cpu_ops */
+	ldr	x1, [x4], #CPU_OPS_SIZE
+	and	w1, w1, w3
+
+	/* Check if midr matches to midr of this core */
+	cmp	w1, w2
+	b.ne	1b
+
+	/* Subtract the increment and offset to get the cpu-ops pointer */
+	sub	x0, x4, #(CPU_OPS_SIZE + CPU_MIDR)
+error_exit:
+	ret
+
+#if DEBUG
+	/*
+	 * This function prints a warning message to the crash console
+	 * if the CPU revision/part number does not match the errata
+	 * workaround enabled in the build.
+	 * Clobber: x30, x0 - x5
+	 */
+.section .rodata.rev_warn_str, "aS"
+rev_warn_str:
+	.asciz "Warning: Skipping Errata workaround for non matching CPU revision number.\n"
+
+	.globl	print_revision_warning
+func print_revision_warning
+	mov	x5, x30
+	/* Ensure the console is initialized */
+	bl	plat_crash_console_init
+	/* Check if the console is initialized */
+	cbz	x0, 1f
+	/* The console is initialized */
+	adr	x4, rev_warn_str
+	bl	asm_print_str
+1:
+	ret	x5
+#endif
+
diff --git a/uefi/arm-trusted-firmware/lib/cpus/cpu-ops.mk b/uefi/arm-trusted-firmware/lib/cpus/cpu-ops.mk
new file mode 100644
index 0000000..1c5512e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/cpus/cpu-ops.mk
@@ -0,0 +1,57 @@
+#
+# 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.
+#
+
+# Cortex A57 specific optimisation to skip L1 cache flush when
+# cluster is powered down.
+SKIP_A57_L1_FLUSH_PWR_DWN	?=0
+
+# Process SKIP_A57_L1_FLUSH_PWR_DWN flag
+$(eval $(call assert_boolean,SKIP_A57_L1_FLUSH_PWR_DWN))
+$(eval $(call add_define,SKIP_A57_L1_FLUSH_PWR_DWN))
+
+
+# CPU Errata Build flags. These should be enabled by the
+# platform if the errata needs to be applied.
+
+# Flag to apply errata 806969 during reset. This errata applies only to
+# revision r0p0 of the Cortex A57 cpu.
+ERRATA_A57_806969	?=0
+
+# Flag to apply errata 813420 during reset. This errata applies only to
+# revision r0p0 of the Cortex A57 cpu.
+ERRATA_A57_813420	?=0
+
+# Process ERRATA_A57_806969 flag
+$(eval $(call assert_boolean,ERRATA_A57_806969))
+$(eval $(call add_define,ERRATA_A57_806969))
+
+# Process ERRATA_A57_813420 flag
+$(eval $(call assert_boolean,ERRATA_A57_813420))
+$(eval $(call add_define,ERRATA_A57_813420))
diff --git a/uefi/arm-trusted-firmware/lib/locks/bakery/bakery_lock_coherent.c b/uefi/arm-trusted-firmware/lib/locks/bakery/bakery_lock_coherent.c
new file mode 100644
index 0000000..5d538ce
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/locks/bakery/bakery_lock_coherent.c
@@ -0,0 +1,195 @@
+/*
+ * 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 <assert.h>
+#include <bakery_lock.h>
+#include <cpu_data.h>
+#include <platform.h>
+#include <string.h>
+
+/*
+ * Functions in this file implement Bakery Algorithm for mutual exclusion with the
+ * bakery lock data structures in coherent memory.
+ *
+ * ARM architecture offers a family of exclusive access instructions to
+ * efficiently implement mutual exclusion with hardware support. However, as
+ * well as depending on external hardware, the these instructions have defined
+ * behavior only on certain memory types (cacheable and Normal memory in
+ * particular; see ARMv8 Architecture Reference Manual section B2.10). Use cases
+ * in trusted firmware are such that mutual exclusion implementation cannot
+ * expect that accesses to the lock have the specific type required by the
+ * architecture for these primitives to function (for example, not all
+ * contenders may have address translation enabled).
+ *
+ * This implementation does not use mutual exclusion primitives. It expects
+ * memory regions where the locks reside to be fully ordered and coherent
+ * (either by disabling address translation, or by assigning proper attributes
+ * when translation is enabled).
+ *
+ * Note that the ARM architecture guarantees single-copy atomicity for aligned
+ * accesses regardless of status of address translation.
+ */
+
+#define assert_bakery_entry_valid(entry, bakery) do {	\
+	assert(bakery);					\
+	assert(entry < BAKERY_LOCK_MAX_CPUS);		\
+} while (0)
+
+/* Convert a ticket to priority */
+#define PRIORITY(t, pos)	(((t) << 8) | (pos))
+
+
+/* Initialize Bakery Lock to reset ownership and all ticket values */
+void bakery_lock_init(bakery_lock_t *bakery)
+{
+	assert(bakery);
+
+	/* All ticket values need to be 0 */
+	memset(bakery, 0, sizeof(*bakery));
+	bakery->owner = NO_OWNER;
+}
+
+
+/* Obtain a ticket for a given CPU */
+static unsigned int bakery_get_ticket(bakery_lock_t *bakery, unsigned int me)
+{
+	unsigned int my_ticket, their_ticket;
+	unsigned int they;
+
+	/*
+	 * Flag that we're busy getting our ticket. All CPUs are iterated in the
+	 * order of their ordinal position to decide the maximum ticket value
+	 * observed so far. Our priority is set to be greater than the maximum
+	 * observed priority
+	 *
+	 * Note that it's possible that more than one contender gets the same
+	 * ticket value. That's OK as the lock is acquired based on the priority
+	 * value, not the ticket value alone.
+	 */
+	my_ticket = 0;
+	bakery->entering[me] = 1;
+	for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) {
+		their_ticket = bakery->number[they];
+		if (their_ticket > my_ticket)
+			my_ticket = their_ticket;
+	}
+
+	/*
+	 * Compute ticket; then signal to other contenders waiting for us to
+	 * finish calculating our ticket value that we're done
+	 */
+	++my_ticket;
+	bakery->number[me] = my_ticket;
+	bakery->entering[me] = 0;
+
+	return my_ticket;
+}
+
+
+/*
+ * Acquire bakery lock
+ *
+ * Contending CPUs need first obtain a non-zero ticket and then calculate
+ * priority value. A contending CPU iterate over all other CPUs in the platform,
+ * which may be contending for the same lock, in the order of their ordinal
+ * position (CPU0, CPU1 and so on). A non-contending CPU will have its ticket
+ * (and priority) value as 0. The contending CPU compares its priority with that
+ * of others'. The CPU with the highest priority (lowest numerical value)
+ * acquires the lock
+ */
+void bakery_lock_get(bakery_lock_t *bakery)
+{
+	unsigned int they, me;
+	unsigned int my_ticket, my_prio, their_ticket;
+
+	me = platform_get_core_pos(read_mpidr_el1());
+
+	assert_bakery_entry_valid(me, bakery);
+
+	/* Prevent recursive acquisition */
+	assert(bakery->owner != me);
+
+	/* Get a ticket */
+	my_ticket = bakery_get_ticket(bakery, me);
+
+	/*
+	 * Now that we got our ticket, compute our priority value, then compare
+	 * with that of others, and proceed to acquire the lock
+	 */
+	my_prio = PRIORITY(my_ticket, me);
+	for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) {
+		if (me == they)
+			continue;
+
+		/* Wait for the contender to get their ticket */
+		while (bakery->entering[they])
+			;
+
+		/*
+		 * If the other party is a contender, they'll have non-zero
+		 * (valid) ticket value. If they do, compare priorities
+		 */
+		their_ticket = bakery->number[they];
+		if (their_ticket && (PRIORITY(their_ticket, they) < my_prio)) {
+			/*
+			 * They have higher priority (lower value). Wait for
+			 * their ticket value to change (either release the lock
+			 * to have it dropped to 0; or drop and probably content
+			 * again for the same lock to have an even higher value)
+			 */
+			do {
+				wfe();
+			} while (their_ticket == bakery->number[they]);
+		}
+	}
+
+	/* Lock acquired */
+	bakery->owner = me;
+}
+
+
+/* Release the lock and signal contenders */
+void bakery_lock_release(bakery_lock_t *bakery)
+{
+	unsigned int me = platform_get_core_pos(read_mpidr_el1());
+
+	assert_bakery_entry_valid(me, bakery);
+	assert(bakery->owner == me);
+
+	/*
+	 * Release lock by resetting ownership and ticket. Then signal other
+	 * waiting contenders
+	 */
+	bakery->owner = NO_OWNER;
+	bakery->number[me] = 0;
+	dsb();
+	sev();
+}
diff --git a/uefi/arm-trusted-firmware/lib/locks/bakery/bakery_lock_normal.c b/uefi/arm-trusted-firmware/lib/locks/bakery/bakery_lock_normal.c
new file mode 100644
index 0000000..a325fd4
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/locks/bakery/bakery_lock_normal.c
@@ -0,0 +1,217 @@
+/*
+ * 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 <arch_helpers.h>
+#include <assert.h>
+#include <bakery_lock.h>
+#include <cpu_data.h>
+#include <platform.h>
+#include <string.h>
+
+/*
+ * Functions in this file implement Bakery Algorithm for mutual exclusion with the
+ * bakery lock data structures in cacheable and Normal memory.
+ *
+ * ARM architecture offers a family of exclusive access instructions to
+ * efficiently implement mutual exclusion with hardware support. However, as
+ * well as depending on external hardware, these instructions have defined
+ * behavior only on certain memory types (cacheable and Normal memory in
+ * particular; see ARMv8 Architecture Reference Manual section B2.10). Use cases
+ * in trusted firmware are such that mutual exclusion implementation cannot
+ * expect that accesses to the lock have the specific type required by the
+ * architecture for these primitives to function (for example, not all
+ * contenders may have address translation enabled).
+ *
+ * This implementation does not use mutual exclusion primitives. It expects
+ * memory regions where the locks reside to be cacheable and Normal.
+ *
+ * Note that the ARM architecture guarantees single-copy atomicity for aligned
+ * accesses regardless of status of address translation.
+ */
+
+/* Convert a ticket to priority */
+#define PRIORITY(t, pos)	(((t) << 8) | (pos))
+
+#define CHOOSING_TICKET		0x1
+#define CHOOSING_DONE		0x0
+
+#define bakery_is_choosing(info)	(info & 0x1)
+#define bakery_ticket_number(info)	((info >> 1) & 0x7FFF)
+#define make_bakery_data(choosing, number) \
+		(((choosing & 0x1) | (number << 1)) & 0xFFFF)
+
+/* This macro assumes that the bakery_info array is located at the offset specified */
+#define get_my_bakery_info(offset, id)		\
+	(((bakery_info_t *) (((uint8_t *)_cpu_data()) + offset)) + id)
+
+#define get_bakery_info_by_index(offset, id, ix)	\
+	(((bakery_info_t *) (((uint8_t *)_cpu_data_by_index(ix)) + offset)) + id)
+
+#define write_cache_op(addr, cached)	\
+				do {	\
+					(cached ? dccvac((uint64_t)addr) :\
+						dcivac((uint64_t)addr));\
+						dsbish();\
+				} while (0)
+
+#define read_cache_op(addr, cached)	if (cached) \
+					    dccivac((uint64_t)addr)
+
+static unsigned int bakery_get_ticket(int id, unsigned int offset,
+						unsigned int me, int is_cached)
+{
+	unsigned int my_ticket, their_ticket;
+	unsigned int they;
+	bakery_info_t *my_bakery_info, *their_bakery_info;
+
+	/*
+	 * Obtain a reference to the bakery information for this cpu and ensure
+	 * it is not NULL.
+	 */
+	my_bakery_info = get_my_bakery_info(offset, id);
+	assert(my_bakery_info);
+
+	/*
+	 * Tell other contenders that we are through the bakery doorway i.e.
+	 * going to allocate a ticket for this cpu.
+	 */
+	my_ticket = 0;
+	my_bakery_info->lock_data = make_bakery_data(CHOOSING_TICKET, my_ticket);
+
+	write_cache_op(my_bakery_info, is_cached);
+
+	/*
+	 * Iterate through the bakery information of each contender to allocate
+	 * the highest ticket number for this cpu.
+	 */
+	for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) {
+		if (me == they)
+			continue;
+
+		/*
+		 * Get a reference to the other contender's bakery info and
+		 * ensure that a stale copy is not read.
+		 */
+		their_bakery_info = get_bakery_info_by_index(offset, id, they);
+		assert(their_bakery_info);
+
+		read_cache_op(their_bakery_info, is_cached);
+
+		/*
+		 * Update this cpu's ticket number if a higher ticket number is
+		 * seen
+		 */
+		their_ticket = bakery_ticket_number(their_bakery_info->lock_data);
+		if (their_ticket > my_ticket)
+			my_ticket = their_ticket;
+	}
+
+	/*
+	 * Compute ticket; then signal to other contenders waiting for us to
+	 * finish calculating our ticket value that we're done
+	 */
+	++my_ticket;
+	my_bakery_info->lock_data = make_bakery_data(CHOOSING_DONE, my_ticket);
+
+	write_cache_op(my_bakery_info, is_cached);
+
+	return my_ticket;
+}
+
+void bakery_lock_get(unsigned int id, unsigned int offset)
+{
+	unsigned int they, me, is_cached;
+	unsigned int my_ticket, my_prio, their_ticket;
+	bakery_info_t *their_bakery_info;
+	uint16_t their_bakery_data;
+
+	me = platform_get_core_pos(read_mpidr_el1());
+
+	is_cached = read_sctlr_el3() & SCTLR_C_BIT;
+
+	/* Get a ticket */
+	my_ticket = bakery_get_ticket(id, offset, me, is_cached);
+
+	/*
+	 * Now that we got our ticket, compute our priority value, then compare
+	 * with that of others, and proceed to acquire the lock
+	 */
+	my_prio = PRIORITY(my_ticket, me);
+	for (they = 0; they < BAKERY_LOCK_MAX_CPUS; they++) {
+		if (me == they)
+			continue;
+
+		/*
+		 * Get a reference to the other contender's bakery info and
+		 * ensure that a stale copy is not read.
+		 */
+		their_bakery_info = get_bakery_info_by_index(offset, id, they);
+		assert(their_bakery_info);
+		read_cache_op(their_bakery_info, is_cached);
+
+		their_bakery_data = their_bakery_info->lock_data;
+
+		/* Wait for the contender to get their ticket */
+		while (bakery_is_choosing(their_bakery_data)) {
+			read_cache_op(their_bakery_info, is_cached);
+			their_bakery_data = their_bakery_info->lock_data;
+		}
+
+		/*
+		 * If the other party is a contender, they'll have non-zero
+		 * (valid) ticket value. If they do, compare priorities
+		 */
+		their_ticket = bakery_ticket_number(their_bakery_data);
+		if (their_ticket && (PRIORITY(their_ticket, they) < my_prio)) {
+			/*
+			 * They have higher priority (lower value). Wait for
+			 * their ticket value to change (either release the lock
+			 * to have it dropped to 0; or drop and probably content
+			 * again for the same lock to have an even higher value)
+			 */
+			do {
+				wfe();
+				read_cache_op(their_bakery_info, is_cached);
+			} while (their_ticket
+				== bakery_ticket_number(their_bakery_info->lock_data));
+		}
+	}
+}
+
+void bakery_lock_release(unsigned int id, unsigned int offset)
+{
+	bakery_info_t *my_bakery_info;
+	unsigned int is_cached = read_sctlr_el3() & SCTLR_C_BIT;
+
+	my_bakery_info = get_my_bakery_info(offset, id);
+	my_bakery_info->lock_data = 0;
+	write_cache_op(my_bakery_info, is_cached);
+	sev();
+}
diff --git a/uefi/arm-trusted-firmware/lib/locks/exclusive/spinlock.S b/uefi/arm-trusted-firmware/lib/locks/exclusive/spinlock.S
new file mode 100644
index 0000000..5eae2b0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/locks/exclusive/spinlock.S
@@ -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 <asm_macros.S>
+
+	.globl	spin_lock
+	.globl	spin_unlock
+
+
+func spin_lock
+	mov	w2, #1
+	sevl
+l1:	wfe
+l2:	ldaxr	w1, [x0]
+	cbnz	w1, l1
+	stxr	w1, w2, [x0]
+	cbnz	w1, l2
+	ret
+
+
+func spin_unlock
+	stlr	wzr, [x0]
+	ret
diff --git a/uefi/arm-trusted-firmware/lib/semihosting/aarch64/semihosting_call.S b/uefi/arm-trusted-firmware/lib/semihosting/aarch64/semihosting_call.S
new file mode 100644
index 0000000..e6a9675
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/semihosting/aarch64/semihosting_call.S
@@ -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.
+ */
+
+#include <asm_macros.S>
+
+	.globl	semihosting_call
+
+func semihosting_call
+	hlt	#0xf000
+	ret
diff --git a/uefi/arm-trusted-firmware/lib/semihosting/semihosting.c b/uefi/arm-trusted-firmware/lib/semihosting/semihosting.c
new file mode 100644
index 0000000..849ec12
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/semihosting/semihosting.c
@@ -0,0 +1,238 @@
+/*
+ * 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 <assert.h>
+#include <errno.h>
+#include <semihosting.h>
+#include <string.h>
+
+#ifndef SEMIHOSTING_SUPPORTED
+#define SEMIHOSTING_SUPPORTED  1
+#endif
+
+long semihosting_call(unsigned long operation,
+			void *system_block_address);
+
+typedef struct {
+	const char *file_name;
+	unsigned long mode;
+	size_t name_length;
+} smh_file_open_block_t;
+
+typedef struct {
+	long handle;
+	uintptr_t buffer;
+	size_t length;
+} smh_file_read_write_block_t;
+
+typedef struct {
+	long handle;
+	ssize_t location;
+} smh_file_seek_block_t;
+
+typedef struct {
+	char *command_line;
+	size_t command_length;
+} smh_system_block_t;
+
+long semihosting_connection_supported(void)
+{
+	return SEMIHOSTING_SUPPORTED;
+}
+
+long semihosting_file_open(const char *file_name, size_t mode)
+{
+	smh_file_open_block_t open_block;
+
+	open_block.file_name = file_name;
+	open_block.mode = mode;
+	open_block.name_length = strlen(file_name);
+
+	return semihosting_call(SEMIHOSTING_SYS_OPEN,
+				(void *) &open_block);
+}
+
+long semihosting_file_seek(long file_handle, ssize_t offset)
+{
+	smh_file_seek_block_t seek_block;
+	long result;
+
+	seek_block.handle = file_handle;
+	seek_block.location = offset;
+
+	result = semihosting_call(SEMIHOSTING_SYS_SEEK,
+				  (void *) &seek_block);
+
+	if (result)
+		result = semihosting_call(SEMIHOSTING_SYS_ERRNO, 0);
+
+	return result;
+}
+
+long semihosting_file_read(long file_handle, size_t *length, uintptr_t buffer)
+{
+	smh_file_read_write_block_t read_block;
+	long result = -EINVAL;
+
+	if ((length == NULL) || (buffer == (uintptr_t)NULL))
+		return result;
+
+	read_block.handle = file_handle;
+	read_block.buffer = buffer;
+	read_block.length = *length;
+
+	result = semihosting_call(SEMIHOSTING_SYS_READ,
+				  (void *) &read_block);
+
+	if (result == *length) {
+		return -EINVAL;
+	} else if (result < *length) {
+		*length -= result;
+		return 0;
+	} else
+		return result;
+}
+
+long semihosting_file_write(long file_handle,
+			    size_t *length,
+			    const uintptr_t buffer)
+{
+	smh_file_read_write_block_t write_block;
+
+	if ((length == NULL) || (buffer == (uintptr_t)NULL))
+		return -EINVAL;
+
+	write_block.handle = file_handle;
+	write_block.buffer = (uintptr_t)buffer; /* cast away const */
+	write_block.length = *length;
+
+	*length = semihosting_call(SEMIHOSTING_SYS_WRITE,
+				   (void *) &write_block);
+
+	return *length;
+}
+
+long semihosting_file_close(long file_handle)
+{
+	return semihosting_call(SEMIHOSTING_SYS_CLOSE,
+				(void *) &file_handle);
+}
+
+long semihosting_file_length(long file_handle)
+{
+	return semihosting_call(SEMIHOSTING_SYS_FLEN,
+				(void *) &file_handle);
+}
+
+char semihosting_read_char(void)
+{
+	return semihosting_call(SEMIHOSTING_SYS_READC, NULL);
+}
+
+void semihosting_write_char(char character)
+{
+	semihosting_call(SEMIHOSTING_SYS_WRITEC, (void *) &character);
+}
+
+void semihosting_write_string(char *string)
+{
+	semihosting_call(SEMIHOSTING_SYS_WRITE0, (void *) string);
+}
+
+long semihosting_system(char *command_line)
+{
+	smh_system_block_t system_block;
+
+	system_block.command_line = command_line;
+	system_block.command_length = strlen(command_line);
+
+	return semihosting_call(SEMIHOSTING_SYS_SYSTEM,
+				(void *) &system_block);
+}
+
+long semihosting_get_flen(const char *file_name)
+{
+	long file_handle;
+	size_t length;
+
+	assert(semihosting_connection_supported());
+
+	file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB);
+	if (file_handle == -1)
+		return file_handle;
+
+	/* Find the length of the file */
+	length = semihosting_file_length(file_handle);
+
+	return semihosting_file_close(file_handle) ? -1 : length;
+}
+
+long semihosting_download_file(const char *file_name,
+			      size_t buf_size,
+			      uintptr_t buf)
+{
+	long ret = -EINVAL;
+	size_t length;
+	long file_handle;
+
+	/* Null pointer check */
+	if (!buf)
+		return ret;
+
+	assert(semihosting_connection_supported());
+
+	file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB);
+	if (file_handle == -1)
+		return ret;
+
+	/* Find the actual length of the file */
+	length = semihosting_file_length(file_handle);
+	if (length == -1)
+		goto semihosting_fail;
+
+	/* Signal error if we do not have enough space for the file */
+	if (length > buf_size)
+		goto semihosting_fail;
+
+	/*
+	 * A successful read will return 0 in which case we pass back
+	 * the actual number of bytes read. Else we pass a negative
+	 * value indicating an error.
+	 */
+	ret = semihosting_file_read(file_handle, &length, buf);
+	if (ret)
+		goto semihosting_fail;
+	else
+		ret = length;
+
+semihosting_fail:
+	semihosting_file_close(file_handle);
+	return ret;
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/abort.c b/uefi/arm-trusted-firmware/lib/stdlib/abort.c
new file mode 100644
index 0000000..862bf9c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/abort.c
@@ -0,0 +1,40 @@
+/*
+ * 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>
+
+/*
+ * This is a basic implementation. This could be improved.
+ */
+void abort (void)
+{
+	ERROR("ABORT\n");
+	panic();
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/assert.c b/uefi/arm-trusted-firmware/lib/stdlib/assert.c
new file mode 100644
index 0000000..90a1afe
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/assert.c
@@ -0,0 +1,41 @@
+/*
+ * 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>
+
+/*
+ * This is a basic implementation. This could be improved.
+ */
+void __assert (const char *function, const char *file, unsigned int line,
+		const char *assertion)
+{
+	tf_printf("ASSERT: %s <%d> : %s\n", function, line, assertion);
+	while(1);
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/exit.c b/uefi/arm-trusted-firmware/lib/stdlib/exit.c
new file mode 100644
index 0000000..3e77591
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/exit.c
@@ -0,0 +1,37 @@
+/*
+ * 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 <debug.h>
+
+void exit(int v)
+{
+	ERROR("EXIT\n");
+	panic();
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/mem.c b/uefi/arm-trusted-firmware/lib/stdlib/mem.c
new file mode 100644
index 0000000..f1f335a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/mem.c
@@ -0,0 +1,121 @@
+/*
+ * 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 <stddef.h> /* size_t */
+
+/*
+ * Fill @count bytes of memory pointed to by @dst with @val
+ */
+void *memset(void *dst, int val, size_t count)
+{
+	char *ptr = dst;
+
+	while (count--)
+		*ptr++ = val;
+
+	return dst;
+}
+
+/*
+ * Compare @len bytes of @s1 and @s2
+ */
+int memcmp(const void *s1, const void *s2, size_t len)
+{
+	const char *s = s1;
+	const char *d = s2;
+	char dc;
+	char sc;
+
+	while (len--) {
+		sc = *s++;
+		dc = *d++;
+		if (sc - dc)
+			return (sc - dc);
+	}
+
+	return 0;
+}
+
+/*
+ * Copy @len bytes from @src to @dst
+ */
+void *memcpy(void *dst, const void *src, size_t len)
+{
+	const char *s = src;
+	char *d = dst;
+
+	while (len--)
+		*d++ = *s++;
+
+	return dst;
+}
+
+/*
+ * Move @len bytes from @src to @dst
+ */
+void *memmove(void *dst, const void *src, size_t len)
+{
+	/*
+	 * The following test makes use of unsigned arithmetic overflow to
+	 * more efficiently test the condition !(src <= dst && dst < str+len).
+	 * It also avoids the situation where the more explicit test would give
+	 * incorrect results were the calculation str+len to overflow (though
+	 * that issue is probably moot as such usage is probably undefined
+	 * behaviour and a bug anyway.
+	 */
+	if ((size_t)dst - (size_t)src >= len) {
+		/* destination not in source data, so can safely use memcpy */
+		return memcpy(dst, src, len);
+	} else {
+		/* copy backwards... */
+		const char *end = dst;
+		const char *s = (const char *)src + len;
+		char *d = (char *)dst + len;
+		while (d != end)
+			*--d = *--s;
+	}
+	return dst;
+}
+
+/*
+ * Scan @len bytes of @src for value @c
+ */
+void *memchr(const void *src, int c, size_t len)
+{
+	const char *s = src;
+
+	while (len--) {
+		if (*s == c)
+			return (void *) s;
+		s++;
+	}
+
+	return NULL;
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/printf.c b/uefi/arm-trusted-firmware/lib/stdlib/printf.c
new file mode 100644
index 0000000..323ec0f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/printf.c
@@ -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.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+/* Choose max of 128 chars for now. */
+#define PRINT_BUFFER_SIZE 128
+int printf(const char *fmt, ...)
+{
+	va_list args;
+	char buf[PRINT_BUFFER_SIZE];
+	int count;
+
+	va_start(args, fmt);
+	vsnprintf(buf, sizeof(buf) - 1, fmt, args);
+	va_end(args);
+
+	/* Use putchar directly as 'puts()' adds a newline. */
+	buf[PRINT_BUFFER_SIZE - 1] = '\0';
+	count = 0;
+	while (buf[count])
+	{
+		if (putchar(buf[count]) != EOF) {
+			count++;
+		} else {
+			count = EOF;
+			break;
+		}
+	}
+
+	return count;
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/putchar.c b/uefi/arm-trusted-firmware/lib/stdlib/putchar.c
new file mode 100644
index 0000000..85e4fbd
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/putchar.c
@@ -0,0 +1,48 @@
+/*
+ * 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 <stdio.h>
+#include <console.h>
+
+/* Putchar() should either return the character printed or EOF in case of error.
+ * Our current console_putc() function assumes success and returns the
+ * character. Write all other printing functions in terms of putchar(), if
+ * possible, so they all benefit when this is improved.
+ */
+int putchar(int c)
+{
+	int res;
+	if (console_putc((unsigned char)c) >= 0)
+		res = c;
+	else
+		res = EOF;
+
+	return res;
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/puts.c b/uefi/arm-trusted-firmware/lib/stdlib/puts.c
new file mode 100644
index 0000000..ca88fc5
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/puts.c
@@ -0,0 +1,55 @@
+/*
+ * 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 <stdio.h>
+
+int puts(const char *s)
+{
+	int count = 0;
+	while(*s)
+	{
+		if (putchar(*s++) != EOF) {
+			count++;
+		} else {
+			count = EOF;
+			break;
+		}
+	}
+
+	/* According to the puts(3) manpage, the function should write a
+	 * trailing newline.
+	 */
+	if ((count != EOF) && (putchar('\n') != EOF))
+		count++;
+	else
+		count = EOF;
+
+	return count;
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/sscanf.c b/uefi/arm-trusted-firmware/lib/stdlib/sscanf.c
new file mode 100644
index 0000000..e9f5c4a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/sscanf.c
@@ -0,0 +1,50 @@
+/*
+ * 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 <sys/cdefs.h>
+
+/*
+ * TODO: This is not a real implementation of the sscanf() function. It just
+ * returns the number of expected arguments based on the number of '%' found
+ * in the format string.
+ */
+int
+sscanf(const char *__restrict str, char const *__restrict fmt, ...)
+{
+	int ret = 0;
+
+	while (*fmt != '\0') {
+		if (*fmt++ == '%') {
+			ret++;
+		}
+	}
+
+	return ret;
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/std.c b/uefi/arm-trusted-firmware/lib/stdlib/std.c
new file mode 100644
index 0000000..5f6ef75
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/std.c
@@ -0,0 +1,45 @@
+/*
+ * 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 the various implemented functions */
+#include "abort.c"
+#include "assert.c"
+#include "exit.c"
+#include "mem.c"
+#include "printf.c"
+#include "putchar.c"
+#include "puts.c"
+#include "sscanf.c"
+#include "strchr.c"
+#include "strcmp.c"
+#include "strlen.c"
+#include "strncmp.c"
+#include "subr_prf.c"
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/strchr.c b/uefi/arm-trusted-firmware/lib/stdlib/strchr.c
new file mode 100644
index 0000000..4247dcd
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/strchr.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * Portions copyright (c) 2013-2014, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#include <sys/cdefs.h>
+#include <stddef.h>
+#include <string.h>
+
+char *
+strchr(const char *p, int ch)
+{
+	char c;
+
+	c = ch;
+	for (;; ++p) {
+		if (*p == c)
+			return ((char *)p);
+		if (*p == '\0')
+			return (NULL);
+	}
+	/* NOTREACHED */
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/strcmp.c b/uefi/arm-trusted-firmware/lib/stdlib/strcmp.c
new file mode 100644
index 0000000..bb86e0f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/strcmp.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * Portions copyright (c) 2014, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/ctype.h>
+#include <string.h>
+
+/*
+ * Compare strings.
+ */
+int
+strcmp(const char *s1, const char *s2)
+{
+	while (*s1 == *s2++)
+		if (*s1++ == '\0')
+			return 0;
+	return *(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1);
+}
+
+int
+strcasecmp(const char *s1, const char *s2)
+{
+	const unsigned char *us1 = (const unsigned char *)s1;
+	const unsigned char *us2 = (const unsigned char *)s2;
+
+	while (tolower(*us1) == tolower(*us2)) {
+		if (*us1++ == '\0')
+			return 0;
+		us2++;
+	}
+	return tolower(*us1) - tolower(*us2);
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/strlen.c b/uefi/arm-trusted-firmware/lib/stdlib/strlen.c
new file mode 100644
index 0000000..23c3d39
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/strlen.c
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * Portions copyright (c) 2009-2014, ARM Limited and Contributors. All rights reserved.
+ */
+
+#include <stddef.h>
+
+size_t
+strlen(str)
+	const char *str;
+{
+	register const char *s;
+
+	for (s = str; *s; ++s);
+	return(s - str);
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/strncmp.c b/uefi/arm-trusted-firmware/lib/stdlib/strncmp.c
new file mode 100644
index 0000000..f45f4a2
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/strncmp.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * Portions copyright (c) 2014, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#include <sys/cdefs.h>
+#include <string.h>
+
+int
+strncmp(const char *s1, const char *s2, size_t n)
+{
+
+	if (n == 0)
+		return 0;
+	do {
+		if (*s1 != *s2++)
+			return (*(const unsigned char *)s1 -
+				*(const unsigned char *)(s2 - 1));
+		if (*s1++ == '\0')
+			break;
+	} while (--n != 0);
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/lib/stdlib/subr_prf.c b/uefi/arm-trusted-firmware/lib/stdlib/subr_prf.c
new file mode 100644
index 0000000..c103562
--- /dev/null
+++ b/uefi/arm-trusted-firmware/lib/stdlib/subr_prf.c
@@ -0,0 +1,548 @@
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *	@(#)subr_prf.c	8.3 (Berkeley) 1/21/94
+ */
+
+/*
+ * Portions copyright (c) 2009-2014, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+
+typedef unsigned char u_char;
+typedef unsigned int u_int;
+typedef int64_t quad_t;
+typedef uint64_t u_quad_t;
+typedef unsigned long u_long;
+typedef unsigned short u_short;
+
+static inline int imax(int a, int b) { return (a > b ? a : b); }
+
+/*
+ * Note that stdarg.h and the ANSI style va_start macro is used for both
+ * ANSI and traditional C compilers.
+ */
+
+#define TOCONS	0x01
+#define TOTTY	0x02
+#define TOLOG	0x04
+
+/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
+#define MAXNBUF	(sizeof(intmax_t) * 8 + 1)
+
+struct putchar_arg {
+	int	flags;
+	int	pri;
+	struct	tty *tty;
+	char	*p_bufr;
+	size_t	n_bufr;
+	char	*p_next;
+	size_t	remain;
+};
+
+struct snprintf_arg {
+	char	*str;
+	size_t	remain;
+};
+
+extern	int log_open;
+
+static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper);
+static void  snprintf_func(int ch, void *arg);
+static int kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap);
+
+int vsnprintf(char *str, size_t size, const char *format, va_list ap);
+
+static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+#define hex2ascii(hex) (hex2ascii_data[hex])
+
+/*
+ * Scaled down version of sprintf(3).
+ */
+int
+sprintf(char *buf, const char *cfmt, ...)
+{
+	int retval;
+	va_list ap;
+
+	va_start(ap, cfmt);
+	retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
+	buf[retval] = '\0';
+	va_end(ap);
+	return (retval);
+}
+
+/*
+ * Scaled down version of vsprintf(3).
+ */
+int
+vsprintf(char *buf, const char *cfmt, va_list ap)
+{
+	int retval;
+
+	retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
+	buf[retval] = '\0';
+	return (retval);
+}
+
+/*
+ * Scaled down version of snprintf(3).
+ */
+int
+snprintf(char *str, size_t size, const char *format, ...)
+{
+	int retval;
+	va_list ap;
+
+	va_start(ap, format);
+	retval = vsnprintf(str, size, format, ap);
+	va_end(ap);
+	return(retval);
+}
+
+/*
+ * Scaled down version of vsnprintf(3).
+ */
+int
+vsnprintf(char *str, size_t size, const char *format, va_list ap)
+{
+	struct snprintf_arg info;
+	int retval;
+
+	info.str = str;
+	info.remain = size;
+	retval = kvprintf(format, snprintf_func, &info, 10, ap);
+	if (info.remain >= 1)
+		*info.str++ = '\0';
+	return (retval);
+}
+
+static void
+snprintf_func(int ch, void *arg)
+{
+	struct snprintf_arg *const info = arg;
+
+	if (info->remain >= 2) {
+		*info->str++ = ch;
+		info->remain--;
+	}
+}
+
+
+/*
+ * Kernel version which takes radix argument vsnprintf(3).
+ */
+int
+vsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap)
+{
+	struct snprintf_arg info;
+	int retval;
+
+	info.str = str;
+	info.remain = size;
+	retval = kvprintf(format, snprintf_func, &info, radix, ap);
+	if (info.remain >= 1)
+		*info.str++ = '\0';
+	return (retval);
+}
+
+
+/*
+ * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
+ * order; return an optional length and a pointer to the last character
+ * written in the buffer (i.e., the first character of the string).
+ * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
+ */
+static char *
+ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
+{
+	char *p, c;
+
+	p = nbuf;
+	*p = '\0';
+	do {
+		c = hex2ascii(num % base);
+		*++p = upper ? toupper(c) : c;
+	} while (num /= base);
+	if (lenp)
+		*lenp = p - nbuf;
+	return (p);
+}
+
+/*
+ * Scaled down version of printf(3).
+ *
+ * Two additional formats:
+ *
+ * The format %b is supported to decode error registers.
+ * Its usage is:
+ *
+ *	printf("reg=%b\n", regval, "<base><arg>*");
+ *
+ * where <base> is the output base expressed as a control character, e.g.
+ * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
+ * the first of which gives the bit number to be inspected (origin 1), and
+ * the next characters (up to a control character, i.e. a character <= 32),
+ * give the name of the register.  Thus:
+ *
+ *	kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
+ *
+ * would produce output:
+ *
+ *	reg=3<BITTWO,BITONE>
+ *
+ * XXX:  %D  -- Hexdump, takes pointer and separator string:
+ *		("%6D", ptr, ":")   -> XX:XX:XX:XX:XX:XX
+ *		("%*D", len, ptr, " " -> XX XX XX XX ...
+ */
+int
+kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
+{
+#define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
+	char nbuf[MAXNBUF];
+	char *d;
+	const char *p, *percent, *q;
+	u_char *up;
+	int ch, n;
+	uintmax_t num;
+	int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+	int cflag, hflag, jflag, tflag, zflag;
+	int dwidth, upper;
+	char padc;
+	int stop = 0, retval = 0;
+
+	num = 0;
+	if (!func)
+		d = (char *) arg;
+	else
+		d = NULL;
+
+	if (fmt == NULL)
+		fmt = "(fmt null)\n";
+
+	if (radix < 2 || radix > 36)
+		radix = 10;
+
+	for (;;) {
+		padc = ' ';
+		width = 0;
+		while ((ch = (u_char)*fmt++) != '%' || stop) {
+			if (ch == '\0')
+				return (retval);
+			PCHAR(ch);
+		}
+		percent = fmt - 1;
+		qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
+		sign = 0; dot = 0; dwidth = 0; upper = 0;
+		cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
+reswitch:	switch (ch = (u_char)*fmt++) {
+		case '.':
+			dot = 1;
+			goto reswitch;
+		case '#':
+			sharpflag = 1;
+			goto reswitch;
+		case '+':
+			sign = 1;
+			goto reswitch;
+		case '-':
+			ladjust = 1;
+			goto reswitch;
+		case '%':
+			PCHAR(ch);
+			break;
+		case '*':
+			if (!dot) {
+				width = va_arg(ap, int);
+				if (width < 0) {
+					ladjust = !ladjust;
+					width = -width;
+				}
+			} else {
+				dwidth = va_arg(ap, int);
+			}
+			goto reswitch;
+		case '0':
+			if (!dot) {
+				padc = '0';
+				goto reswitch;
+			}
+		case '1': case '2': case '3': case '4':
+		case '5': case '6': case '7': case '8': case '9':
+				for (n = 0;; ++fmt) {
+					n = n * 10 + ch - '0';
+					ch = *fmt;
+					if (ch < '0' || ch > '9')
+						break;
+				}
+			if (dot)
+				dwidth = n;
+			else
+				width = n;
+			goto reswitch;
+		case 'b':
+			num = (u_int)va_arg(ap, int);
+			p = va_arg(ap, char *);
+			for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
+				PCHAR(*q--);
+
+			if (num == 0)
+				break;
+
+			for (tmp = 0; *p;) {
+				n = *p++;
+				if (num & (1 << (n - 1))) {
+					PCHAR(tmp ? ',' : '<');
+					for (; (n = *p) > ' '; ++p)
+						PCHAR(n);
+					tmp = 1;
+				} else
+					for (; *p > ' '; ++p)
+						continue;
+			}
+			if (tmp)
+				PCHAR('>');
+			break;
+		case 'c':
+			PCHAR(va_arg(ap, int));
+			break;
+		case 'D':
+			up = va_arg(ap, u_char *);
+			p = va_arg(ap, char *);
+			if (!width)
+				width = 16;
+			while(width--) {
+				PCHAR(hex2ascii(*up >> 4));
+				PCHAR(hex2ascii(*up & 0x0f));
+				up++;
+				if (width)
+					for (q=p;*q;q++)
+						PCHAR(*q);
+			}
+			break;
+		case 'd':
+		case 'i':
+			base = 10;
+			sign = 1;
+			goto handle_sign;
+		case 'h':
+			if (hflag) {
+				hflag = 0;
+				cflag = 1;
+			} else
+				hflag = 1;
+			goto reswitch;
+		case 'j':
+			jflag = 1;
+			goto reswitch;
+		case 'l':
+			if (lflag) {
+				lflag = 0;
+				qflag = 1;
+			} else
+				lflag = 1;
+			goto reswitch;
+		case 'n':
+			if (jflag)
+				*(va_arg(ap, intmax_t *)) = retval;
+			else if (qflag)
+				*(va_arg(ap, quad_t *)) = retval;
+			else if (lflag)
+				*(va_arg(ap, long *)) = retval;
+			else if (zflag)
+				*(va_arg(ap, size_t *)) = retval;
+			else if (hflag)
+				*(va_arg(ap, short *)) = retval;
+			else if (cflag)
+				*(va_arg(ap, char *)) = retval;
+			else
+				*(va_arg(ap, int *)) = retval;
+			break;
+		case 'o':
+			base = 8;
+			goto handle_nosign;
+		case 'p':
+			base = 16;
+			sharpflag = (width == 0);
+			sign = 0;
+			num = (uintptr_t)va_arg(ap, void *);
+			goto number;
+		case 'q':
+			qflag = 1;
+			goto reswitch;
+		case 'r':
+			base = radix;
+			if (sign)
+				goto handle_sign;
+			goto handle_nosign;
+		case 's':
+			p = va_arg(ap, char *);
+			if (p == NULL)
+				p = "(null)";
+			if (!dot)
+				n = strlen (p);
+			else
+				for (n = 0; n < dwidth && p[n]; n++)
+					continue;
+
+			width -= n;
+
+			if (!ladjust && width > 0)
+				while (width--)
+					PCHAR(padc);
+			while (n--)
+				PCHAR(*p++);
+			if (ladjust && width > 0)
+				while (width--)
+					PCHAR(padc);
+			break;
+		case 't':
+			tflag = 1;
+			goto reswitch;
+		case 'u':
+			base = 10;
+			goto handle_nosign;
+		case 'X':
+			upper = 1;
+		case 'x':
+			base = 16;
+			goto handle_nosign;
+		case 'y':
+			base = 16;
+			sign = 1;
+			goto handle_sign;
+		case 'z':
+			zflag = 1;
+			goto reswitch;
+handle_nosign:
+			sign = 0;
+			if (jflag)
+				num = va_arg(ap, uintmax_t);
+			else if (qflag)
+				num = va_arg(ap, u_quad_t);
+			else if (tflag)
+				num = va_arg(ap, ptrdiff_t);
+			else if (lflag)
+				num = va_arg(ap, u_long);
+			else if (zflag)
+				num = va_arg(ap, size_t);
+			else if (hflag)
+				num = (u_short)va_arg(ap, int);
+			else if (cflag)
+				num = (u_char)va_arg(ap, int);
+			else
+				num = va_arg(ap, u_int);
+			goto number;
+handle_sign:
+			if (jflag)
+				num = va_arg(ap, intmax_t);
+			else if (qflag)
+				num = va_arg(ap, quad_t);
+			else if (tflag)
+				num = va_arg(ap, ptrdiff_t);
+			else if (lflag)
+				num = va_arg(ap, long);
+			else if (zflag)
+				num = va_arg(ap, ssize_t);
+			else if (hflag)
+				num = (short)va_arg(ap, int);
+			else if (cflag)
+				num = (char)va_arg(ap, int);
+			else
+				num = va_arg(ap, int);
+number:
+			if (sign && (intmax_t)num < 0) {
+				neg = 1;
+				num = -(intmax_t)num;
+			}
+			p = ksprintn(nbuf, num, base, &n, upper);
+			tmp = 0;
+			if (sharpflag && num != 0) {
+				if (base == 8)
+					tmp++;
+				else if (base == 16)
+					tmp += 2;
+			}
+			if (neg)
+				tmp++;
+
+			if (!ladjust && padc == '0')
+				dwidth = width - tmp;
+			width -= tmp + imax(dwidth, n);
+			dwidth -= n;
+			if (!ladjust)
+				while (width-- > 0)
+					PCHAR(' ');
+			if (neg)
+				PCHAR('-');
+			if (sharpflag && num != 0) {
+				if (base == 8) {
+					PCHAR('0');
+				} else if (base == 16) {
+					PCHAR('0');
+					PCHAR('x');
+				}
+			}
+			while (dwidth-- > 0)
+				PCHAR('0');
+
+			while (*p)
+				PCHAR(*p--);
+
+			if (ladjust)
+				while (width-- > 0)
+					PCHAR(' ');
+
+			break;
+		default:
+			while (percent < fmt)
+				PCHAR(*percent++);
+			/*
+			 * Since we ignore an formatting argument it is no 
+			 * longer safe to obey the remaining formatting
+			 * arguments as the arguments will no longer match
+			 * the format specs.
+			 */
+			stop = 1;
+			break;
+		}
+	}
+#undef PCHAR
+}
diff --git a/uefi/arm-trusted-firmware/license.md b/uefi/arm-trusted-firmware/license.md
new file mode 100644
index 0000000..941b741
--- /dev/null
+++ b/uefi/arm-trusted-firmware/license.md
@@ -0,0 +1,26 @@
+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.
diff --git a/uefi/arm-trusted-firmware/plat/common/aarch64/plat_common.c b/uefi/arm-trusted-firmware/plat/common/aarch64/plat_common.c
new file mode 100644
index 0000000..90574fd
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/common/aarch64/plat_common.c
@@ -0,0 +1,49 @@
+/*
+ * 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 <xlat_tables.h>
+
+/*
+ * The following 2 platform setup functions are weakly defined. They
+ * provide typical implementations that may be re-used by multiple
+ * platforms but may also be overridden by a platform if required.
+ */
+#pragma weak bl31_plat_enable_mmu
+#pragma weak bl32_plat_enable_mmu
+
+void bl31_plat_enable_mmu(uint32_t flags)
+{
+	enable_mmu_el3(flags);
+}
+
+void bl32_plat_enable_mmu(uint32_t flags)
+{
+	enable_mmu_el1(flags);
+}
diff --git a/uefi/arm-trusted-firmware/plat/common/aarch64/platform_helpers.S b/uefi/arm-trusted-firmware/plat/common/aarch64/platform_helpers.S
new file mode 100644
index 0000000..c236fd7
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/common/aarch64/platform_helpers.S
@@ -0,0 +1,105 @@
+/*
+ * 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 <platform_def.h>
+
+
+	.weak	platform_get_core_pos
+	.weak	platform_check_mpidr
+	.weak	plat_report_exception
+	.weak	plat_crash_console_init
+	.weak	plat_crash_console_putc
+	.weak	plat_reset_handler
+	.weak	plat_disable_acp
+
+	/* -----------------------------------------------------
+	 *  int platform_get_core_pos(int mpidr);
+	 *  With this function: CorePos = (ClusterId * 4) +
+	 *  				  CoreId
+	 * -----------------------------------------------------
+	 */
+func platform_get_core_pos
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform.
+	 * -----------------------------------------------------
+	 */
+func platform_check_mpidr
+	mov	x0, xzr
+	ret
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform.
+	 * -----------------------------------------------------
+	 */
+func plat_report_exception
+	ret
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform.
+	 * -----------------------------------------------------
+	 */
+func plat_crash_console_init
+	mov	x0, #0
+	ret
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform.
+	 * -----------------------------------------------------
+	 */
+func plat_crash_console_putc
+	ret
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform. This function should preserve x10.
+	 * -----------------------------------------------------
+	 */
+func plat_reset_handler
+	ret
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform. This function is allowed to use
+	 * registers x0 - x17.
+	 * -----------------------------------------------------
+	 */
+func plat_disable_acp
+	ret
diff --git a/uefi/arm-trusted-firmware/plat/common/aarch64/platform_mp_stack.S b/uefi/arm-trusted-firmware/plat/common/aarch64/platform_mp_stack.S
new file mode 100644
index 0000000..8eb1aa6
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/common/aarch64/platform_mp_stack.S
@@ -0,0 +1,72 @@
+/*
+ * 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 <platform_def.h>
+
+
+	.local	platform_normal_stacks
+	.weak	platform_set_stack
+	.weak	platform_get_stack
+
+
+	/* -----------------------------------------------------
+	 * unsigned long platform_get_stack (unsigned long mpidr)
+	 *
+	 * For a given CPU, this function returns the stack
+	 * pointer for a stack allocated in device memory.
+	 * -----------------------------------------------------
+	 */
+func platform_get_stack
+	mov x10, x30 // lr
+	get_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
+	ret x10
+
+	/* -----------------------------------------------------
+	 * void platform_set_stack (unsigned long mpidr)
+	 *
+	 * For a given CPU, this function sets the stack pointer
+	 * to a stack allocated in normal memory.
+	 * -----------------------------------------------------
+	 */
+func platform_set_stack
+	mov x9, x30 // lr
+	bl  platform_get_stack
+	mov sp, x0
+	ret x9
+
+	/* -----------------------------------------------------
+	 * Per-cpu stacks in normal memory. Each cpu gets a
+	 * stack of PLATFORM_STACK_SIZE bytes.
+	 * -----------------------------------------------------
+	 */
+declare_stack platform_normal_stacks, tzfw_normal_stacks, \
+		PLATFORM_STACK_SIZE, PLATFORM_CORE_COUNT
diff --git a/uefi/arm-trusted-firmware/plat/common/aarch64/platform_up_stack.S b/uefi/arm-trusted-firmware/plat/common/aarch64/platform_up_stack.S
new file mode 100644
index 0000000..73b74b2
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/common/aarch64/platform_up_stack.S
@@ -0,0 +1,72 @@
+/*
+ * 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 <platform_def.h>
+
+
+	.local	platform_normal_stacks
+	.globl	platform_set_stack
+	.globl	platform_get_stack
+
+	/* -----------------------------------------------------
+	 * unsigned long platform_get_stack (unsigned long)
+	 *
+	 * For cold-boot BL images, only the primary CPU needs a
+	 * stack. This function returns the stack pointer for a
+	 * stack allocated in device memory.
+	 * -----------------------------------------------------
+	 */
+func platform_get_stack
+	get_up_stack platform_normal_stacks, PLATFORM_STACK_SIZE
+	ret
+
+	/* -----------------------------------------------------
+	 * void platform_set_stack (unsigned long)
+	 *
+	 * For cold-boot BL images, only the primary CPU needs a
+	 * stack. This function sets the stack pointer to a stack
+	 * allocated in normal memory.
+	 * -----------------------------------------------------
+	 */
+func platform_set_stack
+	get_up_stack platform_normal_stacks, PLATFORM_STACK_SIZE
+	mov sp, x0
+	ret
+
+	/* -----------------------------------------------------
+	 * Single cpu stack in normal memory.
+	 * Used for C code during boot, PLATFORM_STACK_SIZE bytes
+	 * are allocated
+	 * -----------------------------------------------------
+	 */
+declare_stack platform_normal_stacks, tzfw_normal_stacks, \
+		PLATFORM_STACK_SIZE, 1
diff --git a/uefi/arm-trusted-firmware/plat/common/plat_gic.c b/uefi/arm-trusted-firmware/plat/common/plat_gic.c
new file mode 100644
index 0000000..f736e55
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/common/plat_gic.c
@@ -0,0 +1,73 @@
+/*
+ * 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 <arm_gic.h>
+
+/*
+ * The following platform GIC functions are weakly defined. They
+ * provide typical implementations that may be re-used by multiple
+ * platforms but may also be overridden by a platform if required.
+ */
+#pragma weak plat_ic_get_pending_interrupt_id
+#pragma weak plat_ic_get_pending_interrupt_type
+#pragma weak plat_ic_acknowledge_interrupt
+#pragma weak plat_ic_get_interrupt_type
+#pragma weak plat_ic_end_of_interrupt
+#pragma weak plat_interrupt_type_to_line
+
+uint32_t plat_ic_get_pending_interrupt_id(void)
+{
+	return arm_gic_get_pending_interrupt_id();
+}
+
+uint32_t plat_ic_get_pending_interrupt_type(void)
+{
+	return arm_gic_get_pending_interrupt_type();
+}
+
+uint32_t plat_ic_acknowledge_interrupt(void)
+{
+	return arm_gic_acknowledge_interrupt();
+}
+
+uint32_t plat_ic_get_interrupt_type(uint32_t id)
+{
+	return arm_gic_get_interrupt_type(id);
+}
+
+void plat_ic_end_of_interrupt(uint32_t id)
+{
+	arm_gic_end_of_interrupt(id);
+}
+
+uint32_t plat_interrupt_type_to_line(uint32_t type,
+				uint32_t security_state)
+{
+	return arm_gic_interrupt_type_to_line(type, security_state);
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/aarch64/fvp_common.c b/uefi/arm-trusted-firmware/plat/fvp/aarch64/fvp_common.c
new file mode 100644
index 0000000..d89e1e6
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/aarch64/fvp_common.c
@@ -0,0 +1,368 @@
+/*
+ * 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 <arm_gic.h>
+#include <bl_common.h>
+#include <cci400.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <plat_config.h>
+#include <xlat_tables.h>
+#include "../fvp_def.h"
+
+/*******************************************************************************
+ * plat_config holds the characteristics of the differences between the three
+ * FVP platforms (Base, A53_A57 & Foundation). It will be populated during cold
+ * boot at each boot stage by the primary before enabling the MMU (to allow cci
+ * configuration) & used thereafter. Each BL will have its own copy to allow
+ * independent operation.
+ ******************************************************************************/
+plat_config_t plat_config;
+
+#define MAP_SHARED_RAM	MAP_REGION_FLAT(FVP_SHARED_MEM_BASE,		\
+					FVP_SHARED_MEM_SIZE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_FLASH0	MAP_REGION_FLAT(FLASH0_BASE,			\
+					FLASH0_SIZE,			\
+					MT_MEMORY | MT_RO | MT_SECURE)
+
+#define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
+					DEVICE0_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_DEVICE1	MAP_REGION_FLAT(DEVICE1_BASE,			\
+					DEVICE1_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_DRAM1_NS	MAP_REGION_FLAT(DRAM1_NS_BASE,			\
+					DRAM1_NS_SIZE,			\
+					MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_TSP_SEC_MEM	MAP_REGION_FLAT(TSP_SEC_MEM_BASE,		\
+					TSP_SEC_MEM_SIZE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
+/*
+ * Table of regions for various BL stages to map using the MMU.
+ * This doesn't include TZRAM as the 'mem_layout' argument passed to
+ * configure_mmu_elx() will give the available subset of that,
+ */
+#if IMAGE_BL1
+const mmap_region_t fvp_mmap[] = {
+	MAP_SHARED_RAM,
+	MAP_FLASH0,
+	MAP_DEVICE0,
+	MAP_DEVICE1,
+	{0}
+};
+#endif
+#if IMAGE_BL2
+const mmap_region_t fvp_mmap[] = {
+	MAP_SHARED_RAM,
+	MAP_FLASH0,
+	MAP_DEVICE0,
+	MAP_DEVICE1,
+	MAP_DRAM1_NS,
+	MAP_TSP_SEC_MEM,
+	{0}
+};
+#endif
+#if IMAGE_BL31
+const mmap_region_t fvp_mmap[] = {
+	MAP_SHARED_RAM,
+	MAP_DEVICE0,
+	MAP_DEVICE1,
+	MAP_TSP_SEC_MEM,
+	{0}
+};
+#endif
+#if IMAGE_BL32
+const mmap_region_t fvp_mmap[] = {
+	MAP_DEVICE0,
+	MAP_DEVICE1,
+	{0}
+};
+#endif
+
+/* Array of secure interrupts to be configured by the gic driver */
+const unsigned int irq_sec_array[] = {
+	IRQ_TZ_WDOG,
+	IRQ_SEC_PHY_TIMER,
+	IRQ_SEC_SGI_0,
+	IRQ_SEC_SGI_1,
+	IRQ_SEC_SGI_2,
+	IRQ_SEC_SGI_3,
+	IRQ_SEC_SGI_4,
+	IRQ_SEC_SGI_5,
+	IRQ_SEC_SGI_6,
+	IRQ_SEC_SGI_7
+};
+
+const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
+	sizeof(irq_sec_array[0]);
+
+/*******************************************************************************
+ * Macro generating the code for the function setting up the pagetables as per
+ * the platform memory map & initialize the mmu, for the given exception level
+ ******************************************************************************/
+#if USE_COHERENT_MEM
+#define DEFINE_CONFIGURE_MMU_EL(_el)				\
+	void fvp_configure_mmu_el##_el(unsigned long total_base,	\
+				   unsigned long total_size,		\
+				   unsigned long ro_start,		\
+				   unsigned long ro_limit,		\
+				   unsigned long coh_start,		\
+				   unsigned long coh_limit)		\
+	{								\
+		mmap_add_region(total_base, total_base,			\
+				total_size,				\
+				MT_MEMORY | MT_RW | MT_SECURE);		\
+		mmap_add_region(ro_start, ro_start,			\
+				ro_limit - ro_start,			\
+				MT_MEMORY | MT_RO | MT_SECURE);		\
+		mmap_add_region(coh_start, coh_start,			\
+				coh_limit - coh_start,			\
+				MT_DEVICE | MT_RW | MT_SECURE);		\
+		mmap_add(fvp_mmap);					\
+		init_xlat_tables();					\
+									\
+		enable_mmu_el##_el(0);					\
+	}
+#else
+#define DEFINE_CONFIGURE_MMU_EL(_el)				\
+	void fvp_configure_mmu_el##_el(unsigned long total_base,	\
+				   unsigned long total_size,		\
+				   unsigned long ro_start,		\
+				   unsigned long ro_limit)		\
+	{								\
+		mmap_add_region(total_base, total_base,			\
+				total_size,				\
+				MT_MEMORY | MT_RW | MT_SECURE);		\
+		mmap_add_region(ro_start, ro_start,			\
+				ro_limit - ro_start,			\
+				MT_MEMORY | MT_RO | MT_SECURE);		\
+		mmap_add(fvp_mmap);					\
+		init_xlat_tables();					\
+									\
+		enable_mmu_el##_el(0);					\
+	}
+#endif
+
+/* Define EL1 and EL3 variants of the function initialising the MMU */
+DEFINE_CONFIGURE_MMU_EL(1)
+DEFINE_CONFIGURE_MMU_EL(3)
+
+/*******************************************************************************
+ * A single boot loader stack is expected to work on both the Foundation FVP
+ * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
+ * SYS_ID register provides a mechanism for detecting the differences between
+ * these platforms. This information is stored in a per-BL array to allow the
+ * code to take the correct path.Per BL platform configuration.
+ ******************************************************************************/
+int fvp_config_setup(void)
+{
+	unsigned int rev, hbi, bld, arch, sys_id;
+
+	sys_id = mmio_read_32(VE_SYSREGS_BASE + V2M_SYS_ID);
+	rev = (sys_id >> SYS_ID_REV_SHIFT) & SYS_ID_REV_MASK;
+	hbi = (sys_id >> SYS_ID_HBI_SHIFT) & SYS_ID_HBI_MASK;
+	bld = (sys_id >> SYS_ID_BLD_SHIFT) & SYS_ID_BLD_MASK;
+	arch = (sys_id >> SYS_ID_ARCH_SHIFT) & SYS_ID_ARCH_MASK;
+
+	if (arch != ARCH_MODEL) {
+		ERROR("This firmware is for FVP models\n");
+		panic();
+	}
+
+	/*
+	 * The build field in the SYS_ID tells which variant of the GIC
+	 * memory is implemented by the model.
+	 */
+	switch (bld) {
+	case BLD_GIC_VE_MMAP:
+		plat_config.gicd_base = VE_GICD_BASE;
+		plat_config.gicc_base = VE_GICC_BASE;
+		plat_config.gich_base = VE_GICH_BASE;
+		plat_config.gicv_base = VE_GICV_BASE;
+		break;
+	case BLD_GIC_A53A57_MMAP:
+		plat_config.gicd_base = BASE_GICD_BASE;
+		plat_config.gicc_base = BASE_GICC_BASE;
+		plat_config.gich_base = BASE_GICH_BASE;
+		plat_config.gicv_base = BASE_GICV_BASE;
+		break;
+	default:
+		ERROR("Unsupported board build %x\n", bld);
+		panic();
+	}
+
+	/*
+	 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
+	 * for the Foundation FVP.
+	 */
+	switch (hbi) {
+	case HBI_FOUNDATION:
+		plat_config.max_aff0 = 4;
+		plat_config.max_aff1 = 1;
+		plat_config.flags = 0;
+
+		/*
+		 * Check for supported revisions of Foundation FVP
+		 * Allow future revisions to run but emit warning diagnostic
+		 */
+		switch (rev) {
+		case REV_FOUNDATION_V2_0:
+		case REV_FOUNDATION_V2_1:
+			break;
+		default:
+			WARN("Unrecognized Foundation FVP revision %x\n", rev);
+			break;
+		}
+		break;
+	case HBI_FVP_BASE:
+		plat_config.max_aff0 = 4;
+		plat_config.max_aff1 = 2;
+		plat_config.flags |= CONFIG_BASE_MMAP | CONFIG_HAS_CCI |
+			CONFIG_HAS_TZC;
+
+		/*
+		 * Check for supported revisions
+		 * Allow future revisions to run but emit warning diagnostic
+		 */
+		switch (rev) {
+		case REV_FVP_BASE_V0:
+			break;
+		default:
+			WARN("Unrecognized Base FVP revision %x\n", rev);
+			break;
+		}
+		break;
+	default:
+		ERROR("Unsupported board HBI number 0x%x\n", hbi);
+		panic();
+	}
+
+	return 0;
+}
+
+unsigned long plat_get_ns_image_entrypoint(void)
+{
+	return NS_IMAGE_OFFSET;
+}
+
+uint64_t plat_get_syscnt_freq(void)
+{
+	uint64_t counter_base_frequency;
+
+	/* Read the frequency from Frequency modes table */
+	counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
+
+	/* The first entry of the frequency modes table must not be 0 */
+	if (counter_base_frequency == 0)
+		panic();
+
+	return counter_base_frequency;
+}
+
+void fvp_cci_init(void)
+{
+	/*
+	 * Initialize CCI-400 driver
+	 */
+	if (plat_config.flags & CONFIG_HAS_CCI)
+		cci_init(CCI400_BASE,
+			CCI400_SL_IFACE3_CLUSTER_IX,
+			CCI400_SL_IFACE4_CLUSTER_IX);
+}
+
+void fvp_cci_enable(void)
+{
+	/*
+	 * Enable CCI-400 coherency for this cluster. No need
+	 * for locks as no other cpu is active at the
+	 * moment
+	 */
+	if (plat_config.flags & CONFIG_HAS_CCI)
+		cci_enable_cluster_coherency(read_mpidr());
+}
+
+void fvp_gic_init(void)
+{
+	arm_gic_init(plat_config.gicc_base,
+		plat_config.gicd_base,
+		BASE_GICR_BASE,
+		irq_sec_array,
+		num_sec_irqs);
+}
+
+
+/*******************************************************************************
+ * Gets SPSR for BL32 entry
+ ******************************************************************************/
+uint32_t fvp_get_spsr_for_bl32_entry(void)
+{
+	/*
+	 * The Secure Payload Dispatcher service is responsible for
+	 * setting the SPSR prior to entry into the BL32 image.
+	 */
+	return 0;
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL33 entry
+ ******************************************************************************/
+uint32_t fvp_get_spsr_for_bl33_entry(void)
+{
+	unsigned long el_status;
+	unsigned int mode;
+	uint32_t spsr;
+
+	/* Figure out what mode we enter the non-secure world in */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	if (el_status)
+		mode = MODE_EL2;
+	else
+		mode = MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/aarch64/fvp_helpers.S b/uefi/arm-trusted-firmware/plat/fvp/aarch64/fvp_helpers.S
new file mode 100644
index 0000000..e678b43
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/aarch64/fvp_helpers.S
@@ -0,0 +1,226 @@
+/*
+ * 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 <gic_v2.h>
+#include <platform_def.h>
+#include <pl011.h>
+#include "../drivers/pwrc/fvp_pwrc.h"
+
+	.globl	platform_get_entrypoint
+	.globl	plat_secondary_cold_boot_setup
+	.globl	platform_mem_init
+	.globl	plat_report_exception
+	.globl	platform_is_primary_cpu
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+
+	.macro	fvp_choose_gicmmap  param1, param2, x_tmp, w_tmp, res
+	ldr	\x_tmp, =VE_SYSREGS_BASE + V2M_SYS_ID
+	ldr	\w_tmp, [\x_tmp]
+	ubfx	\w_tmp, \w_tmp, #SYS_ID_BLD_SHIFT, #SYS_ID_BLD_LENGTH
+	cmp	\w_tmp, #BLD_GIC_VE_MMAP
+	csel	\res, \param1, \param2, eq
+	.endm
+
+	/* -----------------------------------------------------
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * This function performs any platform specific actions
+	 * needed for a secondary cpu after a cold reset e.g
+	 * mark the cpu's presence, mechanism to place it in a
+	 * holding pen etc.
+	 * TODO: Should we read the PSYS register to make sure
+	 * that the request has gone through.
+	 * -----------------------------------------------------
+	 */
+func plat_secondary_cold_boot_setup
+	/* ---------------------------------------------
+	 * Power down this cpu.
+	 * TODO: Do we need to worry about powering the
+	 * cluster down as well here. That will need
+	 * locks which we won't have unless an elf-
+	 * loader zeroes out the zi section.
+	 * ---------------------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	ldr	x1, =PWRC_BASE
+	str	w0, [x1, #PPOFFR_OFF]
+
+	/* ---------------------------------------------
+	 * Deactivate the gic cpu interface as well
+	 * ---------------------------------------------
+	 */
+	ldr	x0, =VE_GICC_BASE
+	ldr	x1, =BASE_GICC_BASE
+	fvp_choose_gicmmap	x0, x1, x2, w2, x1
+	mov	w0, #(IRQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP1)
+	orr	w0, w0, #(IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP0)
+	str	w0, [x1, #GICC_CTLR]
+
+	/* ---------------------------------------------
+	 * There is no sane reason to come out of this
+	 * wfi so panic if we do. This cpu will be pow-
+	 * ered on and reset by the cpu_on pm api
+	 * ---------------------------------------------
+	 */
+	dsb	sy
+	wfi
+cb_panic:
+	b	cb_panic
+
+
+	/* -----------------------------------------------------
+	 * void platform_get_entrypoint (unsigned int mpid);
+	 *
+	 * Main job of this routine is to distinguish between
+	 * a cold and warm boot.
+	 * On a cold boot the secondaries first wait for the
+	 * platform to be initialized after which they are
+	 * hotplugged in. The primary proceeds to perform the
+	 * platform initialization.
+	 * On a warm boot, each cpu jumps to the address in its
+	 * mailbox.
+	 *
+	 * TODO: Not a good idea to save lr in a temp reg
+	 * TODO: PSYSR is a common register and should be
+	 * 	accessed using locks. Since its not possible
+	 * 	to use locks immediately after a cold reset
+	 * 	we are relying on the fact that after a cold
+	 * 	reset all cpus will read the same WK field
+	 * -----------------------------------------------------
+	 */
+func platform_get_entrypoint
+	mov	x9, x30 // lr
+	mov	x2, x0
+	ldr	x1, =PWRC_BASE
+	str	w2, [x1, #PSYSR_OFF]
+	ldr	w2, [x1, #PSYSR_OFF]
+	ubfx	w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_MASK
+	cmp	w2, #WKUP_PPONR
+	beq	warm_reset
+	cmp	w2, #WKUP_GICREQ
+	beq	warm_reset
+	mov	x0, #0
+	b	exit
+warm_reset:
+	/* ---------------------------------------------
+	 * A per-cpu mailbox is maintained in the tru-
+	 * sted DRAM. Its flushed out of the caches
+	 * after every update using normal memory so
+	 * its safe to read it here with SO attributes
+	 * ---------------------------------------------
+	 */
+	ldr	x10, =MBOX_BASE
+	bl	platform_get_core_pos
+	lsl	x0, x0, #CACHE_WRITEBACK_SHIFT
+	ldr	x0, [x10, x0]
+	cbz	x0, _panic
+exit:
+	ret	x9
+_panic:	b	_panic
+
+
+	/* -----------------------------------------------------
+	 * void platform_mem_init (void);
+	 *
+	 * Zero out the mailbox registers in the shared memory.
+	 * The mmu is turned off right now and only the primary can
+	 * ever execute this code. Secondaries will read the
+	 * mailboxes using SO accesses. In short, BL31 will
+	 * update the mailboxes after mapping the tzdram as
+	 * normal memory. It will flush its copy after update.
+	 * BL1 will always read the mailboxes with the MMU off
+	 * -----------------------------------------------------
+	 */
+func platform_mem_init
+	ldr	x0, =MBOX_BASE
+	mov	w1, #PLATFORM_CORE_COUNT
+loop:
+	str	xzr, [x0], #CACHE_WRITEBACK_GRANULE
+	subs	w1, w1, #1
+	b.gt	loop
+	ret
+
+	/* ---------------------------------------------
+	 * void plat_report_exception(unsigned int type)
+	 * Function to report an unhandled exception
+	 * with platform-specific means.
+	 * On FVP platform, it updates the LEDs
+	 * to indicate where we are
+	 * ---------------------------------------------
+	 */
+func plat_report_exception
+	mrs	x1, CurrentEl
+	lsr	x1, x1, #MODE_EL_SHIFT
+	lsl	x1, x1, #SYS_LED_EL_SHIFT
+	lsl	x0, x0, #SYS_LED_EC_SHIFT
+	mov	x2, #(SECURE << SYS_LED_SS_SHIFT)
+	orr	x0, x0, x2
+	orr	x0, x0, x1
+	mov	x1, #VE_SYSREGS_BASE
+	add	x1, x1, #V2M_SYS_LED
+	str	w0, [x1]
+	ret
+
+func platform_is_primary_cpu
+	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+	cmp	x0, #FVP_PRIMARY_CPU
+	cset	x0, eq
+	ret
+
+	/* Define a crash console for the plaform */
+#define FVP_CRASH_CONSOLE_BASE		PL011_UART1_BASE
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize the crash console
+	 * without a C Runtime to print crash report.
+	 * Clobber list : x0, x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+	mov_imm	x0, FVP_CRASH_CONSOLE_BASE
+	mov_imm	x1, PL011_UART1_CLK_IN_HZ
+	mov_imm	x2, PL011_BAUDRATE
+	b	console_core_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to print a character on the crash
+	 * console without a C Runtime.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, FVP_CRASH_CONSOLE_BASE
+	b	console_core_putc
diff --git a/uefi/arm-trusted-firmware/plat/fvp/bl1_fvp_setup.c b/uefi/arm-trusted-firmware/plat/fvp/bl1_fvp_setup.c
new file mode 100644
index 0000000..4b421d7
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/bl1_fvp_setup.c
@@ -0,0 +1,141 @@
+/*
+ * 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 <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <console.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include "../../bl1/bl1_private.h"
+#include "fvp_def.h"
+#include "fvp_private.h"
+
+#if USE_COHERENT_MEM
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted SRAM
+ ******************************************************************************/
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+#endif
+
+/* Data structure which holds the extents of the trusted SRAM for BL1*/
+static meminfo_t bl1_tzram_layout;
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+	return &bl1_tzram_layout;
+}
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+	const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
+
+	/* Initialize the console to provide early debug support */
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Allow BL1 to see the whole Trusted RAM */
+	bl1_tzram_layout.total_base = FVP_TRUSTED_SRAM_BASE;
+	bl1_tzram_layout.total_size = FVP_TRUSTED_SRAM_SIZE;
+
+	/* Calculate how much RAM BL1 is using and how much remains free */
+	bl1_tzram_layout.free_base = FVP_TRUSTED_SRAM_BASE;
+	bl1_tzram_layout.free_size = FVP_TRUSTED_SRAM_SIZE;
+	reserve_mem(&bl1_tzram_layout.free_base,
+		    &bl1_tzram_layout.free_size,
+		    BL1_RAM_BASE,
+		    bl1_size);
+
+	/* Initialize the platform config for future decision making */
+	fvp_config_setup();
+}
+
+/*******************************************************************************
+ * Function which will evaluate how much of the trusted ram has been gobbled
+ * up by BL1 and return the base and size of whats available for loading BL2.
+ * Its called after coherency and the MMU have been turned on.
+ ******************************************************************************/
+void bl1_platform_setup(void)
+{
+	/* Initialise the IO layer and register platform IO devices */
+	fvp_io_setup();
+}
+
+
+/*******************************************************************************
+ * Perform the very early platform specific architecture setup here. At the
+ * moment this only does basic initialization. Later architectural setup
+ * (bl1_arch_setup()) does not do anything platform specific.
+ ******************************************************************************/
+void bl1_plat_arch_setup(void)
+{
+	fvp_cci_init();
+	fvp_cci_enable();
+
+	fvp_configure_mmu_el3(bl1_tzram_layout.total_base,
+			      bl1_tzram_layout.total_size,
+			      BL1_RO_BASE,
+			      BL1_RO_LIMIT
+#if USE_COHERENT_MEM
+			      , BL1_COHERENT_RAM_BASE,
+			      BL1_COHERENT_RAM_LIMIT
+#endif
+			     );
+}
+
+
+/*******************************************************************************
+ * Before calling this function BL2 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL2 and set SPSR and security state.
+ * On FVP we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image,
+				entry_point_info_t *bl2_ep)
+{
+	SET_SECURITY_STATE(bl2_ep->h.attr, SECURE);
+	bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/bl2_fvp_setup.c b/uefi/arm-trusted-firmware/plat/fvp/bl2_fvp_setup.c
new file mode 100644
index 0000000..364833f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/bl2_fvp_setup.c
@@ -0,0 +1,291 @@
+/*
+ * 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 <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include "fvp_def.h"
+#include "fvp_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 __RO_END__;
+
+#if USE_COHERENT_MEM
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+#endif
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL2_RO_BASE (unsigned long)(&__RO_START__)
+#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
+
+#if USE_COHERENT_MEM
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+#endif
+
+/* Data structure which holds the extents of the trusted SRAM for BL2 */
+static meminfo_t bl2_tzram_layout
+__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE)));
+
+/* Assert that BL3-1 parameters fit in shared memory */
+CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t)) <
+	(FVP_SHARED_MEM_BASE + FVP_SHARED_MEM_SIZE),
+	assert_bl31_params_do_not_fit_in_shared_memory);
+
+/*******************************************************************************
+ * Reference to structures which holds the arguments which need to be passed
+ * to BL31
+ ******************************************************************************/
+static bl31_params_t *bl2_to_bl31_params;
+static entry_point_info_t *bl31_ep_info;
+
+meminfo_t *bl2_plat_sec_mem_layout(void)
+{
+	return &bl2_tzram_layout;
+}
+
+/*******************************************************************************
+ * This function assigns a pointer to the memory that the platform has kept
+ * aside to pass platform specific and trusted firmware related information
+ * to BL31. This memory is allocated by allocating memory to
+ * bl2_to_bl31_params_mem_t structure which is a superset of all the
+ * structure whose information is passed to BL31
+ * NOTE: This function should be called only once and should be done
+ * before generating params to BL31
+ ******************************************************************************/
+bl31_params_t *bl2_plat_get_bl31_params(void)
+{
+	bl2_to_bl31_params_mem_t *bl31_params_mem;
+
+	/*
+	 * Allocate the memory for all the arguments that needs to
+	 * be passed to BL31
+	 */
+	bl31_params_mem = (bl2_to_bl31_params_mem_t *)PARAMS_BASE;
+	memset((void *)PARAMS_BASE, 0, sizeof(bl2_to_bl31_params_mem_t));
+
+	/* Assign memory for TF related information */
+	bl2_to_bl31_params = &bl31_params_mem->bl31_params;
+	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
+
+	/* Fill BL31 related information */
+	bl31_ep_info = &bl31_params_mem->bl31_ep_info;
+	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem->bl31_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
+						VERSION_1, 0);
+
+	/* Fill BL32 related information if it exists */
+	if (BL32_BASE) {
+		bl2_to_bl31_params->bl32_ep_info =
+					&bl31_params_mem->bl32_ep_info;
+		SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info,
+					PARAM_EP, VERSION_1, 0);
+		bl2_to_bl31_params->bl32_image_info =
+					&bl31_params_mem->bl32_image_info;
+		SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info,
+					PARAM_IMAGE_BINARY,
+					VERSION_1, 0);
+	}
+
+	/* Fill BL33 related information */
+	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem->bl33_ep_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
+					PARAM_EP, VERSION_1, 0);
+	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem->bl33_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
+					VERSION_1, 0);
+
+	return bl2_to_bl31_params;
+}
+
+
+/*******************************************************************************
+ * This function returns a pointer to the shared memory that the platform
+ * has kept to point to entry point information of BL31 to BL2
+ ******************************************************************************/
+struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
+{
+#if DEBUG
+	bl31_ep_info->args.arg1 = FVP_BL31_PLAT_PARAM_VAL;
+#endif
+	return bl31_ep_info;
+}
+
+
+/*******************************************************************************
+ * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
+ * in x0. This memory layout is sitting at the base of the free trusted SRAM.
+ * Copy it to a safe loaction before its reclaimed by later BL2 functionality.
+ ******************************************************************************/
+void bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Setup the BL2 memory layout */
+	bl2_tzram_layout = *mem_layout;
+
+	/* Initialize the platform config for future decision making */
+	fvp_config_setup();
+
+	/* Initialise the IO layer and register platform IO devices */
+	fvp_io_setup();
+}
+
+/*******************************************************************************
+ * Perform platform specific setup. For now just initialize the memory location
+ * to use for passing arguments to BL31.
+ ******************************************************************************/
+void bl2_platform_setup(void)
+{
+	/*
+	 * Do initial security configuration to allow DRAM/device access. On
+	 * Base FVP only DRAM security is programmable (via TrustZone), but
+	 * other platforms might have more programmable security devices
+	 * present.
+	 */
+	fvp_security_setup();
+}
+
+/* Flush the TF params and the TF plat params */
+void bl2_plat_flush_bl31_params(void)
+{
+	flush_dcache_range((unsigned long)PARAMS_BASE, \
+				sizeof(bl2_to_bl31_params_mem_t));
+}
+
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl2_plat_arch_setup(void)
+{
+	fvp_configure_mmu_el1(bl2_tzram_layout.total_base,
+			      bl2_tzram_layout.total_size,
+			      BL2_RO_BASE,
+			      BL2_RO_LIMIT
+#if USE_COHERENT_MEM
+			      , BL2_COHERENT_RAM_BASE,
+			      BL2_COHERENT_RAM_LIMIT
+#endif
+			      );
+}
+
+/*******************************************************************************
+ * Before calling this function BL31 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL31 and set SPSR and security state.
+ * On FVP we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
+					entry_point_info_t *bl31_ep_info)
+{
+	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
+	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS);
+}
+
+
+/*******************************************************************************
+ * Before calling this function BL32 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL32 and set SPSR and security state.
+ * On FVP we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
+					entry_point_info_t *bl32_ep_info)
+{
+	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
+	bl32_ep_info->spsr = fvp_get_spsr_for_bl32_entry();
+}
+
+/*******************************************************************************
+ * Before calling this function BL33 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL33 and set SPSR and security state.
+ * On FVP we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl33_ep_info(image_info_t *image,
+					entry_point_info_t *bl33_ep_info)
+{
+	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+	bl33_ep_info->spsr = fvp_get_spsr_for_bl33_entry();
+}
+
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL32
+ ******************************************************************************/
+void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
+{
+	/*
+	 * Populate the extents of memory available for loading BL32.
+	 */
+	bl32_meminfo->total_base = BL32_BASE;
+	bl32_meminfo->free_base = BL32_BASE;
+	bl32_meminfo->total_size =
+			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+	bl32_meminfo->free_size =
+			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+}
+
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL33
+ ******************************************************************************/
+void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
+{
+	bl33_meminfo->total_base = DRAM1_NS_BASE;
+	bl33_meminfo->total_size = DRAM1_NS_SIZE;
+	bl33_meminfo->free_base = DRAM1_NS_BASE;
+	bl33_meminfo->free_size = DRAM1_NS_SIZE;
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/bl31_fvp_setup.c b/uefi/arm-trusted-firmware/plat/fvp/bl31_fvp_setup.c
new file mode 100644
index 0000000..977cbb4
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/bl31_fvp_setup.c
@@ -0,0 +1,286 @@
+/*
+ * 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 <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <bl31.h>
+#include <console.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stddef.h>
+#include "drivers/pwrc/fvp_pwrc.h"
+#include "fvp_def.h"
+#include "fvp_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 __RO_END__;
+extern unsigned long __BL31_END__;
+
+#if USE_COHERENT_MEM
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+#endif
+
+/*
+ * The next 3 constants identify the extents of the code, RO data region and the
+ * limit of the BL3-1 image.  These addresses are used by the MMU setup code and
+ * therefore they must be page-aligned.  It is the responsibility of the linker
+ * script to ensure that __RO_START__, __RO_END__ & __BL31_END__ linker symbols
+ * refer to page-aligned addresses.
+ */
+#define BL31_RO_BASE (unsigned long)(&__RO_START__)
+#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
+#define BL31_END (unsigned long)(&__BL31_END__)
+
+#if USE_COHERENT_MEM
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols
+ * refer to page-aligned addresses.
+ */
+#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+#endif
+
+#if RESET_TO_BL31
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+#else
+/*******************************************************************************
+ * Reference to structure which holds the arguments that have been passed to
+ * BL31 from BL2.
+ ******************************************************************************/
+static bl31_params_t *bl2_to_bl31_params;
+#endif
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for the
+ * security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+#if RESET_TO_BL31
+	assert(sec_state_is_valid(type));
+
+	if (type == NON_SECURE)
+		return &bl33_image_ep_info;
+	else
+		return &bl32_image_ep_info;
+#else
+	entry_point_info_t *next_image_info;
+
+	assert(sec_state_is_valid(type));
+
+	next_image_info = (type == NON_SECURE) ?
+		bl2_to_bl31_params->bl33_ep_info :
+		bl2_to_bl31_params->bl32_ep_info;
+
+	/* None of the images on this platform can have 0x0 as the entrypoint */
+	if (next_image_info->pc)
+		return next_image_info;
+	else
+		return NULL;
+#endif
+}
+
+/*******************************************************************************
+ * Return a pointer to the 'image_info' structure of the next image for the
+ * security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+image_info_t *bl31_plat_get_next_image_image_info(uint32_t type)
+{
+#if RESET_TO_BL31
+	assert(sec_state_is_valid(type));
+
+	if (type == NON_SECURE)
+		return NULL;
+	else
+		return NULL;
+#else
+	image_info_t *next_image_info;
+
+	assert(sec_state_is_valid(type));
+
+	next_image_info = (type == NON_SECURE) ?
+		bl2_to_bl31_params->bl33_image_info :
+		bl2_to_bl31_params->bl32_image_info;
+
+	/* None of the images on this platform can have size 0x0 */
+	if (next_image_info->image_size)
+		return next_image_info;
+	else
+		return NULL;
+#endif
+}
+
+
+
+/*******************************************************************************
+ * Perform any BL31 specific platform actions. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
+ * are lost (potentially). This needs to be done before the MMU is initialized
+ * so that the memory layout can be used while creating page tables. On the FVP
+ * we know that BL2 has populated the parameters in secure DRAM. So we just use
+ * the reference passed in 'from_bl2' instead of copying. The 'data' parameter
+ * is not used since all the information is contained in 'from_bl2'. Also, BL2
+ * has flushed this information to memory, so we are guaranteed to pick up good
+ * data
+ ******************************************************************************/
+void bl31_early_platform_setup(bl31_params_t *from_bl2,
+				void *plat_params_from_bl2)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Initialize the platform config for future decision making */
+	fvp_config_setup();
+
+#if RESET_TO_BL31
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(from_bl2 == NULL);
+	assert(plat_params_from_bl2 == NULL);
+
+	/*
+	 * Do initial security configuration to allow DRAM/device access. On
+	 * Base FVP only DRAM security is programmable (via TrustZone), but
+	 * other platforms might have more programmable security devices
+	 * present.
+	 */
+	fvp_security_setup();
+
+	/* Populate entry point information for BL3-2 and BL3-3 */
+	SET_PARAM_HEAD(&bl32_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = fvp_get_spsr_for_bl32_entry();
+
+	SET_PARAM_HEAD(&bl33_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = fvp_get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#else
+	/* Check params passed from BL2 should not be NULL,
+	 * We are not checking plat_params_from_bl2 as NULL as we are not
+	 * using it on FVP
+	 */
+	assert(from_bl2 != NULL);
+	assert(from_bl2->h.type == PARAM_BL31);
+	assert(from_bl2->h.version >= VERSION_1);
+
+	bl2_to_bl31_params = from_bl2;
+	assert(((unsigned long)plat_params_from_bl2) == FVP_BL31_PLAT_PARAM_VAL);
+#endif
+}
+
+/*******************************************************************************
+ * Initialize the gic, configure the CLCD and zero out variables needed by the
+ * secondaries to boot up correctly.
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+	unsigned int reg_val;
+
+	/* Initialize the gic cpu and distributor interfaces */
+	fvp_gic_init();
+	arm_gic_setup();
+
+	/*
+	 * TODO: Configure the CLCD before handing control to
+	 * linux. Need to see if a separate driver is needed
+	 * instead.
+	 */
+	mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGDATA, 0);
+	mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGCTRL,
+		      (1ull << 31) | (1 << 30) | (7 << 20) | (0 << 16));
+
+	/* Enable and initialize the System level generic timer */
+	mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
+
+	/* Allow access to the System counter timer module */
+	reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
+	reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
+	reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT);
+	mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(0), reg_val);
+	mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(1), reg_val);
+
+	reg_val = (1 << CNTNSAR_NS_SHIFT(0)) | (1 << CNTNSAR_NS_SHIFT(1));
+	mmio_write_32(SYS_TIMCTL_BASE + CNTNSAR, reg_val);
+
+	/* Intialize the power controller */
+	fvp_pwrc_setup();
+
+	/* Topologies are best known to the platform. */
+	fvp_setup_topology();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup(void)
+{
+	fvp_cci_init();
+#if RESET_TO_BL31
+	fvp_cci_enable();
+#endif
+	fvp_configure_mmu_el3(BL31_RO_BASE,
+			      (BL31_END - BL31_RO_BASE),
+			      BL31_RO_BASE,
+			      BL31_RO_LIMIT
+#if USE_COHERENT_MEM
+			      , BL31_COHERENT_RAM_BASE,
+			      BL31_COHERENT_RAM_LIMIT
+#endif
+			      );
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/drivers/pwrc/fvp_pwrc.c b/uefi/arm-trusted-firmware/plat/fvp/drivers/pwrc/fvp_pwrc.c
new file mode 100644
index 0000000..0497c2b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/drivers/pwrc/fvp_pwrc.c
@@ -0,0 +1,109 @@
+/*
+ * 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 <bakery_lock.h>
+#include <mmio.h>
+#include "../../fvp_def.h"
+#include "../../fvp_private.h"
+#include "fvp_pwrc.h"
+
+/*
+ * TODO: Someday there will be a generic power controller api. At the moment
+ * each platform has its own pwrc so just exporting functions is fine.
+ */
+#if USE_COHERENT_MEM
+static bakery_lock_t pwrc_lock __attribute__ ((section("tzfw_coherent_mem")));
+#define LOCK_ARG	&pwrc_lock
+#else
+#define LOCK_ARG	FVP_PWRC_BAKERY_ID
+#endif
+
+unsigned int fvp_pwrc_get_cpu_wkr(unsigned long mpidr)
+{
+	return PSYSR_WK(fvp_pwrc_read_psysr(mpidr));
+}
+
+unsigned int fvp_pwrc_read_psysr(unsigned long mpidr)
+{
+	unsigned int rc;
+	fvp_lock_get(LOCK_ARG);
+	mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr);
+	rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
+	fvp_lock_release(LOCK_ARG);
+	return rc;
+}
+
+void fvp_pwrc_write_pponr(unsigned long mpidr)
+{
+	fvp_lock_get(LOCK_ARG);
+	mmio_write_32(PWRC_BASE + PPONR_OFF, (unsigned int) mpidr);
+	fvp_lock_release(LOCK_ARG);
+}
+
+void fvp_pwrc_write_ppoffr(unsigned long mpidr)
+{
+	fvp_lock_get(LOCK_ARG);
+	mmio_write_32(PWRC_BASE + PPOFFR_OFF, (unsigned int) mpidr);
+	fvp_lock_release(LOCK_ARG);
+}
+
+void fvp_pwrc_set_wen(unsigned long mpidr)
+{
+	fvp_lock_get(LOCK_ARG);
+	mmio_write_32(PWRC_BASE + PWKUPR_OFF,
+		      (unsigned int) (PWKUPR_WEN | mpidr));
+	fvp_lock_release(LOCK_ARG);
+}
+
+void fvp_pwrc_clr_wen(unsigned long mpidr)
+{
+	fvp_lock_get(LOCK_ARG);
+	mmio_write_32(PWRC_BASE + PWKUPR_OFF,
+		      (unsigned int) mpidr);
+	fvp_lock_release(LOCK_ARG);
+}
+
+void fvp_pwrc_write_pcoffr(unsigned long mpidr)
+{
+	fvp_lock_get(LOCK_ARG);
+	mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr);
+	fvp_lock_release(LOCK_ARG);
+}
+
+/* Nothing else to do here apart from initializing the lock */
+int fvp_pwrc_setup(void)
+{
+	fvp_lock_init(LOCK_ARG);
+
+	return 0;
+}
+
+
+
diff --git a/uefi/arm-trusted-firmware/plat/fvp/drivers/pwrc/fvp_pwrc.h b/uefi/arm-trusted-firmware/plat/fvp/drivers/pwrc/fvp_pwrc.h
new file mode 100644
index 0000000..ad1ea85
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/drivers/pwrc/fvp_pwrc.h
@@ -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.
+ */
+
+#ifndef __FVP_PWRC_H__
+#define __FVP_PWRC_H__
+
+/* FVP Power controller register offset etc */
+#define PPOFFR_OFF		0x0
+#define PPONR_OFF		0x4
+#define PCOFFR_OFF		0x8
+#define PWKUPR_OFF		0xc
+#define PSYSR_OFF		0x10
+
+#define PWKUPR_WEN		(1ull << 31)
+
+#define PSYSR_AFF_L2		(1 << 31)
+#define PSYSR_AFF_L1		(1 << 30)
+#define PSYSR_AFF_L0		(1 << 29)
+#define PSYSR_WEN		(1 << 28)
+#define PSYSR_PC		(1 << 27)
+#define PSYSR_PP		(1 << 26)
+
+#define PSYSR_WK_SHIFT		24
+#define PSYSR_WK_MASK		0x3
+#define PSYSR_WK(x)		(x >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK
+
+#define WKUP_COLD		0x0
+#define WKUP_RESET		0x1
+#define WKUP_PPONR		0x2
+#define WKUP_GICREQ		0x3
+
+#define PSYSR_INVALID		0xffffffff
+
+#ifndef __ASSEMBLY__
+
+/*******************************************************************************
+ * Function & variable prototypes
+ ******************************************************************************/
+int fvp_pwrc_setup(void);
+void fvp_pwrc_write_pcoffr(unsigned long);
+void fvp_pwrc_write_ppoffr(unsigned long);
+void fvp_pwrc_write_pponr(unsigned long);
+void fvp_pwrc_set_wen(unsigned long);
+void fvp_pwrc_clr_wen(unsigned long);
+unsigned int fvp_pwrc_read_psysr(unsigned long);
+unsigned int fvp_pwrc_get_cpu_wkr(unsigned long);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __FVP_PWRC_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/fvp/fvp_def.h b/uefi/arm-trusted-firmware/plat/fvp/fvp_def.h
new file mode 100644
index 0000000..d1d9adb
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/fvp_def.h
@@ -0,0 +1,288 @@
+/*
+ * 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 __FVP_DEF_H__
+#define __FVP_DEF_H__
+
+/* Firmware Image Package */
+#define FIP_IMAGE_NAME			"fip.bin"
+#define FVP_PRIMARY_CPU			0x0
+
+/* Memory location options for TSP */
+#define FVP_TRUSTED_SRAM_ID		0
+#define FVP_TRUSTED_DRAM_ID		1
+#define FVP_DRAM_ID			2
+
+/*
+ * Some of the definitions in this file use the 'ull' suffix in order to avoid
+ * subtle integer overflow errors due to implicit integer type promotion when
+ * working with 32-bit values.
+ *
+ * The TSP linker script includes some of these definitions to define the BL3-2
+ * memory map, but the GNU LD does not support the 'ull' suffix, causing the
+ * build process to fail. To solve this problem, the auxiliary macro MAKE_ULL(x)
+ * will add the 'ull' suffix only when the macro __LINKER__  is not defined
+ * (__LINKER__ is defined in the command line to preprocess the linker script).
+ * Constants in the linker script will not have the 'ull' suffix, but this is
+ * not a problem since the linker evaluates all constant expressions to 64 bit
+ * (assuming the target architecture is 64 bit).
+ */
+#ifndef __LINKER__
+  #define MAKE_ULL(x)			x##ull
+#else
+  #define MAKE_ULL(x)			x
+#endif
+
+/*******************************************************************************
+ * FVP memory map related constants
+ ******************************************************************************/
+
+#define FVP_TRUSTED_ROM_BASE	0x00000000
+#define FVP_TRUSTED_ROM_SIZE	0x04000000	/* 64 MB */
+
+/* The first 4KB of Trusted SRAM are used as shared memory */
+#define FVP_SHARED_MEM_BASE	0x04000000
+#define FVP_SHARED_MEM_SIZE	0x00001000	/* 4 KB */
+
+/* The remaining Trusted SRAM is used to load the BL images */
+#define FVP_TRUSTED_SRAM_BASE	0x04001000
+#define FVP_TRUSTED_SRAM_SIZE	0x0003F000	/* 252 KB */
+
+#define FVP_TRUSTED_DRAM_BASE	0x06000000
+#define FVP_TRUSTED_DRAM_SIZE	0x02000000	/* 32 MB */
+
+#define FLASH0_BASE		0x08000000
+#define FLASH0_SIZE		0x04000000
+
+#define FLASH1_BASE		0x0c000000
+#define FLASH1_SIZE		0x04000000
+
+#define PSRAM_BASE		0x14000000
+#define PSRAM_SIZE		0x04000000
+
+#define VRAM_BASE		0x18000000
+#define VRAM_SIZE		0x02000000
+
+/* Aggregate of all devices in the first GB */
+#define DEVICE0_BASE		0x1a000000
+#define DEVICE0_SIZE		0x12200000
+
+#define DEVICE1_BASE		0x2f000000
+#define DEVICE1_SIZE		0x200000
+
+#define NSRAM_BASE		0x2e000000
+#define NSRAM_SIZE		0x10000
+
+#define DRAM1_BASE		MAKE_ULL(0x80000000)
+#define DRAM1_SIZE		MAKE_ULL(0x80000000)
+#define DRAM1_END		(DRAM1_BASE + DRAM1_SIZE - 1)
+
+/* Define the top 16 MB of DRAM1 as secure */
+#define DRAM1_SEC_SIZE		MAKE_ULL(0x01000000)
+#define DRAM1_SEC_BASE		(DRAM1_BASE + DRAM1_SIZE - DRAM1_SEC_SIZE)
+#define DRAM1_SEC_END		(DRAM1_SEC_BASE + DRAM1_SEC_SIZE - 1)
+
+#define DRAM1_NS_BASE		DRAM1_BASE
+#define DRAM1_NS_SIZE		(DRAM1_SIZE - DRAM1_SEC_SIZE)
+#define DRAM1_NS_END		(DRAM1_NS_BASE + DRAM1_NS_SIZE - 1)
+
+#define DRAM_BASE		DRAM1_BASE
+#define DRAM_SIZE		DRAM1_SIZE
+
+#define DRAM2_BASE		MAKE_ULL(0x880000000)
+#define DRAM2_SIZE		MAKE_ULL(0x780000000)
+#define DRAM2_END		(DRAM2_BASE + DRAM2_SIZE - 1)
+
+#define PCIE_EXP_BASE		0x40000000
+#define TZRNG_BASE		0x7fe60000
+#define TZNVCTR_BASE		0x7fe70000
+#define TZROOTKEY_BASE		0x7fe80000
+
+/* Memory mapped Generic timer interfaces  */
+#define SYS_CNTCTL_BASE		0x2a430000
+#define SYS_CNTREAD_BASE	0x2a800000
+#define SYS_TIMCTL_BASE		0x2a810000
+
+/* V2M motherboard system registers & offsets */
+#define VE_SYSREGS_BASE		0x1c010000
+#define V2M_SYS_ID		0x0
+#define V2M_SYS_SWITCH		0x4
+#define V2M_SYS_LED		0x8
+#define V2M_SYS_CFGDATA		0xa0
+#define V2M_SYS_CFGCTRL		0xa4
+#define V2M_SYS_CFGSTATUS	0xa8
+
+#define CFGCTRL_START		(1 << 31)
+#define CFGCTRL_RW		(1 << 30)
+#define CFGCTRL_FUNC_SHIFT	20
+#define CFGCTRL_FUNC(fn)	(fn << CFGCTRL_FUNC_SHIFT)
+#define FUNC_CLK_GEN		0x01
+#define FUNC_TEMP		0x04
+#define FUNC_DB_RESET		0x05
+#define FUNC_SCC_CFG		0x06
+#define FUNC_SHUTDOWN		0x08
+#define FUNC_REBOOT		0x09
+
+/* Load address of BL33 in the FVP port */
+#define NS_IMAGE_OFFSET		(DRAM1_BASE + 0x8000000) /* DRAM + 128MB */
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define FVP_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
+
+/*
+ * V2M sysled bit definitions. The values written to this
+ * register are defined in arch.h & runtime_svc.h. Only
+ * used by the primary cpu to diagnose any cold boot issues.
+ *
+ * SYS_LED[0]   - Security state (S=0/NS=1)
+ * SYS_LED[2:1] - Exception Level (EL3-EL0)
+ * SYS_LED[7:3] - Exception Class (Sync/Async & origin)
+ *
+ */
+#define SYS_LED_SS_SHIFT		0x0
+#define SYS_LED_EL_SHIFT		0x1
+#define SYS_LED_EC_SHIFT		0x3
+
+#define SYS_LED_SS_MASK		0x1
+#define SYS_LED_EL_MASK		0x3
+#define SYS_LED_EC_MASK		0x1f
+
+/* V2M sysid register bits */
+#define SYS_ID_REV_SHIFT	28
+#define SYS_ID_HBI_SHIFT	16
+#define SYS_ID_BLD_SHIFT	12
+#define SYS_ID_ARCH_SHIFT	8
+#define SYS_ID_FPGA_SHIFT	0
+
+#define SYS_ID_REV_MASK	0xf
+#define SYS_ID_HBI_MASK	0xfff
+#define SYS_ID_BLD_MASK	0xf
+#define SYS_ID_ARCH_MASK	0xf
+#define SYS_ID_FPGA_MASK	0xff
+
+#define SYS_ID_BLD_LENGTH	4
+
+#define HBI_FVP_BASE		0x020
+#define REV_FVP_BASE_V0		0x0
+
+#define HBI_FOUNDATION		0x010
+#define REV_FOUNDATION_V2_0	0x0
+#define REV_FOUNDATION_V2_1	0x1
+
+#define BLD_GIC_VE_MMAP	0x0
+#define BLD_GIC_A53A57_MMAP	0x1
+
+#define ARCH_MODEL		0x1
+
+/* FVP Power controller base address*/
+#define PWRC_BASE		0x1c100000
+
+
+/*******************************************************************************
+ * CCI-400 related constants
+ ******************************************************************************/
+#define CCI400_BASE			0x2c090000
+#define CCI400_SL_IFACE3_CLUSTER_IX	0
+#define CCI400_SL_IFACE4_CLUSTER_IX	1
+
+/*******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+/* VE compatible GIC memory map */
+#define VE_GICD_BASE			0x2c001000
+#define VE_GICC_BASE			0x2c002000
+#define VE_GICH_BASE			0x2c004000
+#define VE_GICV_BASE			0x2c006000
+
+/* Base FVP compatible GIC memory map */
+#define BASE_GICD_BASE			0x2f000000
+#define BASE_GICR_BASE			0x2f100000
+#define BASE_GICC_BASE			0x2c000000
+#define BASE_GICH_BASE			0x2c010000
+#define BASE_GICV_BASE			0x2c02f000
+
+#define IRQ_TZ_WDOG			56
+#define IRQ_SEC_PHY_TIMER		29
+#define IRQ_SEC_SGI_0			8
+#define IRQ_SEC_SGI_1			9
+#define IRQ_SEC_SGI_2			10
+#define IRQ_SEC_SGI_3			11
+#define IRQ_SEC_SGI_4			12
+#define IRQ_SEC_SGI_5			13
+#define IRQ_SEC_SGI_6			14
+#define IRQ_SEC_SGI_7			15
+
+/*******************************************************************************
+ * PL011 related constants
+ ******************************************************************************/
+#define PL011_UART0_BASE		0x1c090000
+#define PL011_UART1_BASE		0x1c0a0000
+#define PL011_UART2_BASE		0x1c0b0000
+#define PL011_UART3_BASE		0x1c0c0000
+
+#define PL011_BAUDRATE  115200
+
+#define PL011_UART0_CLK_IN_HZ 24000000
+#define PL011_UART1_CLK_IN_HZ 24000000
+#define PL011_UART2_CLK_IN_HZ 24000000
+#define PL011_UART3_CLK_IN_HZ 24000000
+
+/*******************************************************************************
+ * TrustZone address space controller related constants
+ ******************************************************************************/
+#define TZC400_BASE			0x2a4a0000
+
+/*
+ * The NSAIDs for this platform as used to program the TZC400.
+ */
+
+/* NSAIDs used by devices in TZC filter 0 on FVP */
+#define FVP_NSAID_DEFAULT		0
+#define FVP_NSAID_PCI			1
+#define FVP_NSAID_VIRTIO		8  /* from FVP v5.6 onwards */
+#define FVP_NSAID_AP			9  /* Application Processors */
+#define FVP_NSAID_VIRTIO_OLD		15 /* until FVP v5.5 */
+
+/* NSAIDs used by devices in TZC filter 2 on FVP */
+#define FVP_NSAID_HDLCD0		2
+#define FVP_NSAID_CLCD			7
+
+/*******************************************************************************
+ *  Shared Data
+ ******************************************************************************/
+
+/* Entrypoint mailboxes */
+#define MBOX_BASE		FVP_SHARED_MEM_BASE
+#define MBOX_SIZE		0x200
+
+/* Base address where parameters to BL31 are stored */
+#define PARAMS_BASE		(MBOX_BASE + MBOX_SIZE)
+
+#endif /* __FVP_DEF_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/fvp/fvp_io_storage.c b/uefi/arm-trusted-firmware/plat/fvp/fvp_io_storage.c
new file mode 100644
index 0000000..ec1fe58
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/fvp_io_storage.c
@@ -0,0 +1,338 @@
+/*
+ * 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 <debug.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <io_semihosting.h>
+#include <platform_def.h>
+#include <semihosting.h>	/* For FOPEN_MODE_... */
+#include <string.h>
+
+/* IO devices */
+static const io_dev_connector_t *sh_dev_con;
+static uintptr_t sh_dev_spec;
+static uintptr_t sh_init_params;
+static uintptr_t sh_dev_handle;
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_spec;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_spec;
+static uintptr_t memmap_init_params;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fip_block_spec = {
+	.offset = FLASH0_BASE,
+	.length = FLASH0_SIZE
+};
+
+static const io_file_spec_t bl2_file_spec = {
+	.path = BL2_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_file_spec = {
+	.path = BL31_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_file_spec = {
+	.path = BL32_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_file_spec = {
+	.path = BL33_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+#if TRUSTED_BOARD_BOOT
+static const io_file_spec_t bl2_cert_file_spec = {
+	.path = BL2_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t trusted_key_cert_file_spec = {
+	.path = TRUSTED_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_key_cert_file_spec = {
+	.path = BL30_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_key_cert_file_spec = {
+	.path = BL31_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_key_cert_file_spec = {
+	.path = BL32_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_key_cert_file_spec = {
+	.path = BL33_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_cert_file_spec = {
+	.path = BL30_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_cert_file_spec = {
+	.path = BL31_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_cert_file_spec = {
+	.path = BL32_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_cert_file_spec = {
+	.path = BL33_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
+static int open_fip(const uintptr_t spec);
+static int open_memmap(const uintptr_t spec);
+
+struct plat_io_policy {
+	char *image_name;
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+	{
+		FIP_IMAGE_NAME,
+		&memmap_dev_handle,
+		(uintptr_t)&fip_block_spec,
+		open_memmap
+	}, {
+		BL2_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl2_file_spec,
+		open_fip
+	}, {
+		BL31_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl31_file_spec,
+		open_fip
+	}, {
+		BL32_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl32_file_spec,
+		open_fip
+	}, {
+		BL33_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl33_file_spec,
+		open_fip
+	}, {
+#if TRUSTED_BOARD_BOOT
+		BL2_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl2_cert_file_spec,
+		open_fip
+	}, {
+		TRUSTED_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&trusted_key_cert_file_spec,
+		open_fip
+	}, {
+		BL30_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl30_key_cert_file_spec,
+		open_fip
+	}, {
+		BL31_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl31_key_cert_file_spec,
+		open_fip
+	}, {
+		BL32_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl32_key_cert_file_spec,
+		open_fip
+	}, {
+		BL33_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl33_key_cert_file_spec,
+		open_fip
+	}, {
+		BL30_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl30_cert_file_spec,
+		open_fip
+	}, {
+		BL31_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl31_cert_file_spec,
+		open_fip
+	}, {
+		BL32_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl32_cert_file_spec,
+		open_fip
+	}, {
+		BL33_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl33_cert_file_spec,
+		open_fip
+	}, {
+#endif /* TRUSTED_BOARD_BOOT */
+		0, 0, 0
+	}
+};
+
+
+static int open_fip(const uintptr_t spec)
+{
+	int result = IO_FAIL;
+
+	/* See if a Firmware Image Package is available */
+	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME);
+	if (result == IO_SUCCESS) {
+		VERBOSE("Using FIP\n");
+		/*TODO: Check image defined in spec is present in FIP. */
+	}
+	return result;
+}
+
+
+static int open_memmap(const uintptr_t spec)
+{
+	int result = IO_FAIL;
+	uintptr_t local_image_handle;
+
+	result = io_dev_init(memmap_dev_handle, memmap_init_params);
+	if (result == IO_SUCCESS) {
+		result = io_open(memmap_dev_handle, spec, &local_image_handle);
+		if (result == IO_SUCCESS) {
+			VERBOSE("Using Memmap IO\n");
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+
+static int open_semihosting(const uintptr_t spec)
+{
+	int result = IO_FAIL;
+	uintptr_t local_image_handle;
+
+	/* See if the file exists on semi-hosting.*/
+	result = io_dev_init(sh_dev_handle, sh_init_params);
+	if (result == IO_SUCCESS) {
+		result = io_open(sh_dev_handle, spec, &local_image_handle);
+		if (result == IO_SUCCESS) {
+			VERBOSE("Using Semi-hosting IO\n");
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+void fvp_io_setup (void)
+{
+	int io_result = IO_FAIL;
+
+	/* Register the IO devices on this platform */
+	io_result = register_io_dev_sh(&sh_dev_con);
+	assert(io_result == IO_SUCCESS);
+
+	io_result = register_io_dev_fip(&fip_dev_con);
+	assert(io_result == IO_SUCCESS);
+
+	io_result = register_io_dev_memmap(&memmap_dev_con);
+	assert(io_result == IO_SUCCESS);
+
+	/* Open connections to devices and cache the handles */
+	io_result = io_dev_open(sh_dev_con, sh_dev_spec, &sh_dev_handle);
+	assert(io_result == IO_SUCCESS);
+
+	io_result = io_dev_open(fip_dev_con, fip_dev_spec, &fip_dev_handle);
+	assert(io_result == IO_SUCCESS);
+
+	io_result = io_dev_open(memmap_dev_con, memmap_dev_spec,
+				&memmap_dev_handle);
+	assert(io_result == IO_SUCCESS);
+
+	/* Ignore improbable errors in release builds */
+	(void)io_result;
+}
+
+
+/* Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy */
+int plat_get_image_source(const char *image_name, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	int result = IO_FAIL;
+	const struct plat_io_policy *policy;
+
+	if ((image_name != NULL) && (dev_handle != NULL) &&
+	    (image_spec != NULL)) {
+		policy = policies;
+		while (policy->image_name != NULL) {
+			if (strcmp(policy->image_name, image_name) == 0) {
+				result = policy->check(policy->image_spec);
+				if (result == IO_SUCCESS) {
+					*image_spec = policy->image_spec;
+					*dev_handle = *(policy->dev_handle);
+					break;
+				} else {
+					result = open_semihosting(
+							policy->image_spec);
+					if (result == IO_SUCCESS) {
+						*dev_handle = sh_dev_handle;
+						*image_spec =
+							policy->image_spec;
+					}
+				}
+			}
+			policy++;
+		}
+	} else {
+		result = IO_FAIL;
+	}
+	return result;
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/fvp_pm.c b/uefi/arm-trusted-firmware/plat/fvp/fvp_pm.c
new file mode 100644
index 0000000..9044e69
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/fvp_pm.c
@@ -0,0 +1,370 @@
+/*
+ * 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 <arm_gic.h>
+#include <assert.h>
+#include <bakery_lock.h>
+#include <cci400.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <plat_config.h>
+#include <platform_def.h>
+#include <psci.h>
+#include <errno.h>
+#include "drivers/pwrc/fvp_pwrc.h"
+#include "fvp_def.h"
+#include "fvp_private.h"
+
+/*******************************************************************************
+ * Private FVP function to program the mailbox for a cpu before it is released
+ * from reset.
+ ******************************************************************************/
+static void fvp_program_mailbox(uint64_t mpidr, uint64_t address)
+{
+	uint64_t linear_id;
+	mailbox_t *fvp_mboxes;
+
+	linear_id = platform_get_core_pos(mpidr);
+	fvp_mboxes = (mailbox_t *)MBOX_BASE;
+	fvp_mboxes[linear_id].value = address;
+	flush_dcache_range((unsigned long) &fvp_mboxes[linear_id],
+			   sizeof(unsigned long));
+}
+
+/*******************************************************************************
+ * Function which implements the common FVP specific operations to power down a
+ * cpu in response to a CPU_OFF or CPU_SUSPEND request.
+ ******************************************************************************/
+static void fvp_cpu_pwrdwn_common()
+{
+	/* Prevent interrupts from spuriously waking up this cpu */
+	arm_gic_cpuif_deactivate();
+
+	/* Program the power controller to power off this cpu. */
+	fvp_pwrc_write_ppoffr(read_mpidr_el1());
+}
+
+/*******************************************************************************
+ * Function which implements the common FVP specific operations to power down a
+ * cluster in response to a CPU_OFF or CPU_SUSPEND request.
+ ******************************************************************************/
+static void fvp_cluster_pwrdwn_common()
+{
+	uint64_t mpidr = read_mpidr_el1();
+
+	/* Disable coherency if this cluster is to be turned off */
+	if (get_plat_config()->flags & CONFIG_HAS_CCI)
+		cci_disable_cluster_coherency(mpidr);
+
+	/* Program the power controller to turn the cluster off */
+	fvp_pwrc_write_pcoffr(mpidr);
+}
+
+/*******************************************************************************
+ * Private FVP function which is used to determine if any platform actions
+ * should be performed for the specified affinity instance given its
+ * state. Nothing needs to be done if the 'state' is not off or if this is not
+ * the highest affinity level which will enter the 'state'.
+ ******************************************************************************/
+static int32_t fvp_do_plat_actions(unsigned int afflvl, unsigned int state)
+{
+	unsigned int max_phys_off_afflvl;
+
+	assert(afflvl <= MPIDR_AFFLVL1);
+
+	if (state != PSCI_STATE_OFF)
+		return -EAGAIN;
+
+	/*
+	 * Find the highest affinity level which will be suspended and postpone
+	 * all the platform specific actions until that level is hit.
+	 */
+	max_phys_off_afflvl = psci_get_max_phys_off_afflvl();
+	assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
+	if (afflvl != max_phys_off_afflvl)
+		return -EAGAIN;
+
+	return 0;
+}
+
+/*******************************************************************************
+ * FVP handler called when an affinity instance is about to enter standby.
+ ******************************************************************************/
+void fvp_affinst_standby(unsigned int power_state)
+{
+	/*
+	 * Enter standby state
+	 * dsb is good practice before using wfi to enter low power states
+	 */
+	dsb();
+	wfi();
+}
+
+/*******************************************************************************
+ * FVP handler called when an affinity instance is about to be turned on. The
+ * level and mpidr determine the affinity instance.
+ ******************************************************************************/
+int fvp_affinst_on(unsigned long mpidr,
+		   unsigned long sec_entrypoint,
+		   unsigned int afflvl,
+		   unsigned int state)
+{
+	int rc = PSCI_E_SUCCESS;
+	unsigned int psysr;
+
+	/*
+	 * It's possible to turn on only affinity level 0 i.e. a cpu
+	 * on the FVP. Ignore any other affinity level.
+	 */
+	if (afflvl != MPIDR_AFFLVL0)
+		return rc;
+
+	/*
+	 * Ensure that we do not cancel an inflight power off request
+	 * for the target cpu. That would leave it in a zombie wfi.
+	 * Wait for it to power off, program the jump address for the
+	 * target cpu and then program the power controller to turn
+	 * that cpu on
+	 */
+	do {
+		psysr = fvp_pwrc_read_psysr(mpidr);
+	} while (psysr & PSYSR_AFF_L0);
+
+	fvp_program_mailbox(mpidr, sec_entrypoint);
+	fvp_pwrc_write_pponr(mpidr);
+
+	return rc;
+}
+
+/*******************************************************************************
+ * FVP handler called when an affinity instance is about to be turned off. The
+ * level and mpidr determine the affinity instance. The 'state' arg. allows the
+ * platform to decide whether the cluster is being turned off and take apt
+ * actions.
+ *
+ * CAUTION: There is no guarantee that caches will remain turned on across calls
+ * to this function as each affinity level is dealt with. So do not write & read
+ * global variables across calls. It will be wise to do flush a write to the
+ * global to prevent unpredictable results.
+ ******************************************************************************/
+void fvp_affinst_off(unsigned int afflvl,
+		    unsigned int state)
+{
+	/* Determine if any platform actions need to be executed */
+	if (fvp_do_plat_actions(afflvl, state) == -EAGAIN)
+		return;
+
+	/*
+	 * If execution reaches this stage then this affinity level will be
+	 * suspended. Perform at least the cpu specific actions followed the
+	 * cluster specific operations if applicable.
+	 */
+	fvp_cpu_pwrdwn_common();
+
+	if (afflvl != MPIDR_AFFLVL0)
+		fvp_cluster_pwrdwn_common();
+
+}
+
+/*******************************************************************************
+ * FVP handler called when an affinity instance is about to be suspended. The
+ * level and mpidr determine the affinity instance. The 'state' arg. allows the
+ * platform to decide whether the cluster is being turned off and take apt
+ * actions.
+ *
+ * CAUTION: There is no guarantee that caches will remain turned on across calls
+ * to this function as each affinity level is dealt with. So do not write & read
+ * global variables across calls. It will be wise to do flush a write to the
+ * global to prevent unpredictable results.
+ ******************************************************************************/
+void fvp_affinst_suspend(unsigned long sec_entrypoint,
+			unsigned int afflvl,
+			unsigned int state)
+{
+	unsigned long mpidr;
+
+	/* Determine if any platform actions need to be executed. */
+	if (fvp_do_plat_actions(afflvl, state) == -EAGAIN)
+		return;
+
+	/* Get the mpidr for this cpu */
+	mpidr = read_mpidr_el1();
+
+	/* Program the jump address for the this cpu */
+	fvp_program_mailbox(mpidr, sec_entrypoint);
+
+	/* Program the power controller to enable wakeup interrupts. */
+	fvp_pwrc_set_wen(mpidr);
+
+	/* Perform the common cpu specific operations */
+	fvp_cpu_pwrdwn_common();
+
+	/* Perform the common cluster specific operations */
+	if (afflvl != MPIDR_AFFLVL0)
+		fvp_cluster_pwrdwn_common();
+}
+
+/*******************************************************************************
+ * FVP handler called when an affinity instance has just been powered on after
+ * being turned off earlier. The level and mpidr determine the affinity
+ * instance. The 'state' arg. allows the platform to decide whether the cluster
+ * was turned off prior to wakeup and do what's necessary to setup it up
+ * correctly.
+ ******************************************************************************/
+void fvp_affinst_on_finish(unsigned int afflvl,
+			  unsigned int state)
+{
+	unsigned long mpidr;
+
+	/* Determine if any platform actions need to be executed. */
+	if (fvp_do_plat_actions(afflvl, state) == -EAGAIN)
+		return;
+
+	/* Get the mpidr for this cpu */
+	mpidr = read_mpidr_el1();
+
+	/* Perform the common cluster specific operations */
+	if (afflvl != MPIDR_AFFLVL0) {
+		/*
+		 * This CPU might have woken up whilst the cluster was
+		 * attempting to power down. In this case the FVP power
+		 * controller will have a pending cluster power off request
+		 * which needs to be cleared by writing to the PPONR register.
+		 * This prevents the power controller from interpreting a
+		 * subsequent entry of this cpu into a simple wfi as a power
+		 * down request.
+		 */
+		fvp_pwrc_write_pponr(mpidr);
+
+		/* Enable coherency if this cluster was off */
+		fvp_cci_enable();
+	}
+
+	/*
+	 * Clear PWKUPR.WEN bit to ensure interrupts do not interfere
+	 * with a cpu power down unless the bit is set again
+	 */
+	fvp_pwrc_clr_wen(mpidr);
+
+	/* Zero the jump address in the mailbox for this cpu */
+	fvp_program_mailbox(mpidr, 0);
+
+	/* Enable the gic cpu interface */
+	arm_gic_cpuif_setup();
+
+	/* TODO: This setup is needed only after a cold boot */
+	arm_gic_pcpu_distif_setup();
+}
+
+/*******************************************************************************
+ * FVP handler called when an affinity instance has just been powered on after
+ * having been suspended earlier. The level and mpidr determine the affinity
+ * instance.
+ * TODO: At the moment we reuse the on finisher and reinitialize the secure
+ * context. Need to implement a separate suspend finisher.
+ ******************************************************************************/
+void fvp_affinst_suspend_finish(unsigned int afflvl,
+			       unsigned int state)
+{
+	fvp_affinst_on_finish(afflvl, state);
+}
+
+/*******************************************************************************
+ * FVP handlers to shutdown/reboot the system
+ ******************************************************************************/
+static void __dead2 fvp_system_off(void)
+{
+	/* Write the System Configuration Control Register */
+	mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGCTRL,
+		CFGCTRL_START | CFGCTRL_RW | CFGCTRL_FUNC(FUNC_SHUTDOWN));
+	wfi();
+	ERROR("FVP System Off: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 fvp_system_reset(void)
+{
+	/* Write the System Configuration Control Register */
+	mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGCTRL,
+		CFGCTRL_START | CFGCTRL_RW | CFGCTRL_FUNC(FUNC_REBOOT));
+	wfi();
+	ERROR("FVP System Reset: operation not handled.\n");
+	panic();
+}
+
+/*******************************************************************************
+ * FVP handler called to check the validity of the power state parameter.
+ ******************************************************************************/
+int fvp_validate_power_state(unsigned int power_state)
+{
+	/* Sanity check the requested state */
+	if (psci_get_pstate_type(power_state) == PSTATE_TYPE_STANDBY) {
+		/*
+		 * It's possible to enter standby only on affinity level 0
+		 * i.e. a cpu on the fvp. Ignore any other affinity level.
+		 */
+		if (psci_get_pstate_afflvl(power_state) != MPIDR_AFFLVL0)
+			return PSCI_E_INVALID_PARAMS;
+	}
+
+	/*
+	 * We expect the 'state id' to be zero.
+	 */
+	if (psci_get_pstate_id(power_state))
+		return PSCI_E_INVALID_PARAMS;
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Export the platform handlers to enable psci to invoke them
+ ******************************************************************************/
+static const plat_pm_ops_t fvp_plat_pm_ops = {
+	.affinst_standby = fvp_affinst_standby,
+	.affinst_on = fvp_affinst_on,
+	.affinst_off = fvp_affinst_off,
+	.affinst_suspend = fvp_affinst_suspend,
+	.affinst_on_finish = fvp_affinst_on_finish,
+	.affinst_suspend_finish = fvp_affinst_suspend_finish,
+	.system_off = fvp_system_off,
+	.system_reset = fvp_system_reset,
+	.validate_power_state = fvp_validate_power_state
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops & initialize the fvp power controller
+ ******************************************************************************/
+int platform_setup_pm(const plat_pm_ops_t **plat_ops)
+{
+	*plat_ops = &fvp_plat_pm_ops;
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/fvp_private.h b/uefi/arm-trusted-firmware/plat/fvp/fvp_private.h
new file mode 100644
index 0000000..3949754
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/fvp_private.h
@@ -0,0 +1,160 @@
+/*
+ * 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 __FVP_PRIVATE_H__
+#define __FVP_PRIVATE_H__
+
+#include <bakery_lock.h>
+#include <bl_common.h>
+#include <cpu_data.h>
+#include <platform_def.h>
+
+
+typedef volatile struct mailbox {
+	unsigned long value
+	__attribute__((__aligned__(CACHE_WRITEBACK_GRANULE)));
+} mailbox_t;
+
+/*******************************************************************************
+ * This structure represents the superset of information that is passed to
+ * BL31 e.g. while passing control to it from BL2 which is bl31_params
+ * and bl31_plat_params and its elements
+ ******************************************************************************/
+typedef struct bl2_to_bl31_params_mem {
+	bl31_params_t bl31_params;
+	image_info_t bl31_image_info;
+	image_info_t bl32_image_info;
+	image_info_t bl33_image_info;
+	entry_point_info_t bl33_ep_info;
+	entry_point_info_t bl32_ep_info;
+	entry_point_info_t bl31_ep_info;
+} bl2_to_bl31_params_mem_t;
+
+#if USE_COHERENT_MEM
+/*
+ * These are wrapper macros to the Coherent Memory Bakery Lock API.
+ */
+#define fvp_lock_init(_lock_arg)	bakery_lock_init(_lock_arg)
+#define fvp_lock_get(_lock_arg)		bakery_lock_get(_lock_arg)
+#define fvp_lock_release(_lock_arg)	bakery_lock_release(_lock_arg)
+
+#else
+
+/*******************************************************************************
+ * Constants to specify how many bakery locks this platform implements. These
+ * are used if the platform chooses not to use coherent memory for bakery lock
+ * data structures.
+ ******************************************************************************/
+#define FVP_MAX_BAKERIES	1
+#define FVP_PWRC_BAKERY_ID	0
+
+/*******************************************************************************
+ * Definition of structure which holds platform specific per-cpu data. Currently
+ * it holds only the bakery lock information for each cpu. Constants to
+ * specify how many bakeries this platform implements and bakery ids are
+ * specified in fvp_def.h
+ ******************************************************************************/
+typedef struct fvp_cpu_data {
+	bakery_info_t pcpu_bakery_info[FVP_MAX_BAKERIES];
+} fvp_cpu_data_t;
+
+/* Macro to define the offset of bakery_info_t in fvp_cpu_data_t */
+#define FVP_CPU_DATA_LOCK_OFFSET	__builtin_offsetof\
+					    (fvp_cpu_data_t, pcpu_bakery_info)
+
+
+/*******************************************************************************
+ * Helper macros for bakery lock api when using the above fvp_cpu_data_t for
+ * bakery lock data structures. It assumes that the bakery_info is at the
+ * beginning of the platform specific per-cpu data.
+ ******************************************************************************/
+#define fvp_lock_init(_lock_arg)	/* No init required */
+#define fvp_lock_get(_lock_arg)		bakery_lock_get(_lock_arg,  	    \
+						CPU_DATA_PLAT_PCPU_OFFSET + \
+						FVP_CPU_DATA_LOCK_OFFSET)
+#define fvp_lock_release(_lock_arg)	bakery_lock_release(_lock_arg,	    \
+						CPU_DATA_PLAT_PCPU_OFFSET + \
+						FVP_CPU_DATA_LOCK_OFFSET)
+
+/*
+ * Ensure that the size of the FVP specific per-cpu data structure and the size
+ * of the memory allocated in generic per-cpu data for the platform are the same.
+ */
+CASSERT(PLAT_PCPU_DATA_SIZE == sizeof(fvp_cpu_data_t),	\
+	fvp_pcpu_data_size_mismatch);
+
+#endif /* __USE_COHERENT_MEM__ */
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void fvp_configure_mmu_el1(unsigned long total_base,
+			   unsigned long total_size,
+			   unsigned long,
+			   unsigned long
+#if USE_COHERENT_MEM
+			   , unsigned long,
+			   unsigned long
+#endif
+			   );
+void fvp_configure_mmu_el3(unsigned long total_base,
+			   unsigned long total_size,
+			   unsigned long,
+			   unsigned long
+#if USE_COHERENT_MEM
+			   , unsigned long,
+			   unsigned long
+#endif
+			   );
+
+int fvp_config_setup(void);
+
+void fvp_cci_init(void);
+void fvp_cci_enable(void);
+
+void fvp_gic_init(void);
+
+/* Declarations for fvp_topology.c */
+int fvp_setup_topology(void);
+
+/* Declarations for fvp_io_storage.c */
+void fvp_io_setup(void);
+
+/* Declarations for fvp_security.c */
+void fvp_security_setup(void);
+
+/* Gets the SPR for BL32 entry */
+uint32_t fvp_get_spsr_for_bl32_entry(void);
+
+/* Gets the SPSR for BL33 entry */
+uint32_t fvp_get_spsr_for_bl33_entry(void);
+
+
+#endif /* __FVP_PRIVATE_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/fvp/fvp_security.c b/uefi/arm-trusted-firmware/plat/fvp/fvp_security.c
new file mode 100644
index 0000000..62bde08
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/fvp_security.c
@@ -0,0 +1,134 @@
+/*
+ * 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 <debug.h>
+#include <plat_config.h>
+#include <tzc400.h>
+#include "fvp_def.h"
+#include "fvp_private.h"
+
+/* Used to improve readability for configuring regions. */
+#define FILTER_SHIFT(filter)	(1 << filter)
+
+/*
+ * For the moment we assume that all security programming is done by the
+ * primary core.
+ * TODO:
+ * Might want to enable interrupt on violations when supported?
+ */
+void fvp_security_setup(void)
+{
+	/*
+	 * The Base FVP has a TrustZone address space controller, the Foundation
+	 * FVP does not. Trying to program the device on the foundation FVP will
+	 * cause an abort.
+	 *
+	 * If the platform had additional peripheral specific security
+	 * configurations, those would be configured here.
+	 */
+
+	if (!(get_plat_config()->flags & CONFIG_HAS_TZC))
+		return;
+
+	/*
+	 * The TrustZone controller controls access to main DRAM. Give
+	 * full NS access for the moment to use with OS.
+	 */
+	INFO("Configuring TrustZone Controller\n");
+
+	/*
+	 * The driver does some error checking and will assert.
+	 * - Provide base address of device on platform.
+	 * - Provide width of ACE-Lite IDs on platform.
+	 */
+	tzc_init(TZC400_BASE);
+
+	/*
+	 * Currently only filters 0 and 2 are connected on Base FVP.
+	 * Filter 0 : CPU clusters (no access to DRAM by default)
+	 * Filter 1 : not connected
+	 * Filter 2 : LCDs (access to VRAM allowed by default)
+	 * Filter 3 : not connected
+	 * Programming unconnected filters will have no effect at the
+	 * moment. These filter could, however, be connected in future.
+	 * So care should be taken not to configure the unused filters.
+	 */
+
+	/* Disable all filters before programming. */
+	tzc_disable_filters();
+
+	/*
+	 * Allow only non-secure access to all DRAM to supported devices.
+	 * Give access to the CPUs and Virtio. Some devices
+	 * would normally use the default ID so allow that too. We use
+	 * two regions to cover the blocks of physical memory in the FVPs
+	 * plus one region to reserve some memory as secure.
+	 *
+	 * Software executing in the secure state, such as a secure
+	 * boot-loader, can access the DRAM by using the NS attributes in
+	 * the MMU translation tables and descriptors.
+	 */
+
+	/* Region 1 set to cover the Non-Secure DRAM */
+	tzc_configure_region(FILTER_SHIFT(0), 1,
+			DRAM1_NS_BASE, DRAM1_NS_END,
+			TZC_REGION_S_NONE,
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) |
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_PCI) |
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_AP) |
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO) |
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO_OLD));
+
+	/* Region 2 set to cover the Secure DRAM */
+	tzc_configure_region(FILTER_SHIFT(0), 2,
+			DRAM1_SEC_BASE, DRAM1_SEC_END,
+			TZC_REGION_S_RDWR,
+			0x0);
+
+	/* Region 3 set to cover the second block of DRAM */
+	tzc_configure_region(FILTER_SHIFT(0), 3,
+			DRAM2_BASE, DRAM2_END, TZC_REGION_S_NONE,
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_DEFAULT) |
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_PCI) |
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_AP) |
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO) |
+			TZC_REGION_ACCESS_RDWR(FVP_NSAID_VIRTIO_OLD));
+
+	/*
+	 * TODO: Interrupts are not currently supported. The only
+	 * options we have are for access errors to occur quietly or to
+	 * cause an exception. We choose to cause an exception.
+	 */
+	tzc_set_action(TZC_ACTION_ERR);
+
+	/* Enable filters. */
+	tzc_enable_filters();
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/fvp_topology.c b/uefi/arm-trusted-firmware/plat/fvp/fvp_topology.c
new file mode 100644
index 0000000..49f7daf
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/fvp_topology.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 <assert.h>
+#include <platform_def.h>
+/* TODO: Reusing psci error codes & state information. Get our own! */
+#include <psci.h>
+#include "drivers/pwrc/fvp_pwrc.h"
+
+/* We treat '255' as an invalid affinity instance */
+#define AFFINST_INVAL	0xff
+
+/*******************************************************************************
+ * We support 3 flavours of the FVP: Foundation, Base AEM & Base Cortex. Each
+ * flavour has a different topology. The common bit is that there can be a max.
+ * of 2 clusters (affinity 1) and 4 cpus (affinity 0) per cluster. So we define
+ * a tree like data structure which caters to these maximum bounds. It simply
+ * marks the absent affinity level instances as PSCI_AFF_ABSENT e.g. there is no
+ * cluster 1 on the Foundation FVP. The 'data' field is currently unused.
+ ******************************************************************************/
+typedef struct affinity_info {
+	unsigned char sibling;
+	unsigned char child;
+	unsigned char state;
+	unsigned int data;
+} affinity_info_t;
+
+/*******************************************************************************
+ * The following two data structures store the topology tree for the fvp. There
+ * is a separate array for each affinity level i.e. cpus and clusters. The child
+ * and sibling references allow traversal inside and in between the two arrays.
+ ******************************************************************************/
+static affinity_info_t fvp_aff1_topology_map[PLATFORM_CLUSTER_COUNT];
+static affinity_info_t fvp_aff0_topology_map[PLATFORM_CORE_COUNT];
+
+/* Simple global variable to safeguard us from stupidity */
+static unsigned int topology_setup_done;
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform to allow the former to detect the platform
+ * topology. psci queries the platform to determine how many affinity instances
+ * are present at a particular level for a given mpidr e.g. consider a dual
+ * cluster platform where each cluster has 4 cpus. A call to this function with
+ * (0, 0x100) will return the number of cpus implemented under cluster 1 i.e. 4.
+ * Similarly a call with (1, 0x100) will return 2 i.e. the number of clusters.
+ * This is 'cause we are effectively asking how many affinity level 1 instances
+ * are implemented under affinity level 2 instance 0.
+ ******************************************************************************/
+unsigned int plat_get_aff_count(unsigned int aff_lvl,
+				unsigned long mpidr)
+{
+	unsigned int aff_count = 1, ctr;
+	unsigned char parent_aff_id;
+
+	assert(topology_setup_done == 1);
+
+	switch (aff_lvl) {
+	case 3:
+	case 2:
+		/*
+		 * Assert if the parent affinity instance is not 0.
+		 * This also takes care of level 3 in an obfuscated way
+		 */
+		parent_aff_id = (mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK;
+		assert(parent_aff_id == 0);
+
+		/*
+		 * Report that we implement a single instance of
+		 * affinity levels 2 & 3 which are AFF_ABSENT
+		 */
+		break;
+	case 1:
+		/* Assert if the parent affinity instance is not 0. */
+		parent_aff_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
+		assert(parent_aff_id == 0);
+
+		/* Fetch the starting index in the aff1 array */
+		for (ctr = 0;
+		     fvp_aff1_topology_map[ctr].sibling != AFFINST_INVAL;
+		     ctr = fvp_aff1_topology_map[ctr].sibling) {
+			aff_count++;
+		}
+
+		break;
+	case 0:
+		/* Assert if the cluster id is anything apart from 0 or 1 */
+		parent_aff_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+		assert(parent_aff_id < PLATFORM_CLUSTER_COUNT);
+
+		/* Fetch the starting index in the aff0 array */
+		for (ctr = fvp_aff1_topology_map[parent_aff_id].child;
+		     fvp_aff0_topology_map[ctr].sibling != AFFINST_INVAL;
+		     ctr = fvp_aff0_topology_map[ctr].sibling) {
+			aff_count++;
+		}
+
+		break;
+	default:
+		assert(0);
+	}
+
+	return aff_count;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform to allow the former to detect the state of a
+ * affinity instance in the platform topology. psci queries the platform to
+ * determine whether an affinity instance is present or absent. This caters for
+ * topologies where an intermediate affinity level instance is missing e.g.
+ * consider a platform which implements a single cluster with 4 cpus and there
+ * is another cpu sitting directly on the interconnect along with the cluster.
+ * The mpidrs of the cluster would range from 0x0-0x3. The mpidr of the single
+ * cpu would be 0x100 to highlight that it does not belong to cluster 0. Cluster
+ * 1 is however missing but needs to be accounted to reach this single cpu in
+ * the topology tree. Hence it will be marked as PSCI_AFF_ABSENT. This is not
+ * applicable to the FVP but depicted as an example.
+ ******************************************************************************/
+unsigned int plat_get_aff_state(unsigned int aff_lvl,
+				unsigned long mpidr)
+{
+	unsigned int aff_state = PSCI_AFF_ABSENT, idx;
+	idx = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	assert(topology_setup_done == 1);
+
+	switch (aff_lvl) {
+	case 3:
+	case 2:
+		/* Report affinity levels 2 & 3 as absent */
+		break;
+	case 1:
+		aff_state = fvp_aff1_topology_map[idx].state;
+		break;
+	case 0:
+		/*
+		 * First get start index of the aff0 in its array & then add
+		 * to it the affinity id that we want the state of
+		 */
+		idx = fvp_aff1_topology_map[idx].child;
+		idx += (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+		aff_state = fvp_aff0_topology_map[idx].state;
+		break;
+	default:
+		assert(0);
+	}
+
+	return aff_state;
+}
+
+/*******************************************************************************
+ * Handy optimization to prevent the psci implementation from traversing through
+ * affinity levels which are not present while detecting the platform topology.
+ ******************************************************************************/
+int plat_get_max_afflvl(void)
+{
+	return MPIDR_AFFLVL1;
+}
+
+/*******************************************************************************
+ * This function populates the FVP specific topology information depending upon
+ * the FVP flavour its running on. We construct all the mpidrs we can handle
+ * and rely on the PWRC.PSYSR to flag absent cpus when their status is queried.
+ ******************************************************************************/
+int fvp_setup_topology(void)
+{
+	unsigned char aff0, aff1, aff_state, aff0_offset = 0;
+	unsigned long mpidr;
+
+	topology_setup_done = 0;
+
+	for (aff1 = 0; aff1 < PLATFORM_CLUSTER_COUNT; aff1++) {
+
+		fvp_aff1_topology_map[aff1].child = aff0_offset;
+		fvp_aff1_topology_map[aff1].sibling = aff1 + 1;
+
+		for (aff0 = 0; aff0 < PLATFORM_MAX_CPUS_PER_CLUSTER; aff0++) {
+
+			mpidr = aff1 << MPIDR_AFF1_SHIFT;
+			mpidr |= aff0 << MPIDR_AFF0_SHIFT;
+
+			if (fvp_pwrc_read_psysr(mpidr) != PSYSR_INVALID) {
+				/*
+				 * Presence of even a single aff0 indicates
+				 * presence of parent aff1 on the FVP.
+				 */
+				aff_state = PSCI_AFF_PRESENT;
+				fvp_aff1_topology_map[aff1].state =
+					PSCI_AFF_PRESENT;
+			} else {
+				aff_state = PSCI_AFF_ABSENT;
+			}
+
+			fvp_aff0_topology_map[aff0_offset].child = AFFINST_INVAL;
+			fvp_aff0_topology_map[aff0_offset].state = aff_state;
+			fvp_aff0_topology_map[aff0_offset].sibling =
+				aff0_offset + 1;
+
+			/* Increment the absolute number of aff0s traversed */
+			aff0_offset++;
+		}
+
+		/* Tie-off the last aff0 sibling to -1 to avoid overflow */
+		fvp_aff0_topology_map[aff0_offset - 1].sibling = AFFINST_INVAL;
+	}
+
+	/* Tie-off the last aff1 sibling to AFFINST_INVAL to avoid overflow */
+	fvp_aff1_topology_map[aff1 - 1].sibling = AFFINST_INVAL;
+
+	topology_setup_done = 1;
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/fvp_trusted_boot.c b/uefi/arm-trusted-firmware/plat/fvp/fvp_trusted_boot.c
new file mode 100644
index 0000000..e7dcc01
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/fvp_trusted_boot.c
@@ -0,0 +1,45 @@
+/*
+ * 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 <debug.h>
+#include "fvp_def.h"
+#include "fvp_private.h"
+
+/*
+ * Check the validity of the key
+ *
+ * 0 = success, Otherwise = error
+ */
+int plat_match_rotpk(const unsigned char *key_buf, unsigned int key_len)
+{
+	/* TODO: check against the ROT key stored in the platform */
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/fvp/include/plat_macros.S b/uefi/arm-trusted-firmware/plat/fvp/include/plat_macros.S
new file mode 100644
index 0000000..f050261
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/include/plat_macros.S
@@ -0,0 +1,119 @@
+/*
+ * 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 <cci400.h>
+#include <gic_v2.h>
+#include <plat_config.h>
+#include "../fvp_def.h"
+
+.section .rodata.gic_reg_name, "aS"
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+	/* ---------------------------------------------
+	 * The below macro prints out relevant GIC
+	 * registers whenever an unhandled exception is
+	 * taken in BL3-1.
+	 * Clobbers: x0 - x10, x16, x17, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_print_gic_regs
+	mov_imm	x0, (VE_SYSREGS_BASE + V2M_SYS_ID)
+	ldr	w16, [x0]
+	/* Extract BLD (12th - 15th bits) from the SYS_ID */
+	ubfx	x16, x16, #SYS_ID_BLD_SHIFT, #4
+	/* Check if VE mmap */
+	cmp	w16, #BLD_GIC_VE_MMAP
+	b.eq	use_ve_mmap
+	/* Check if Cortex-A53/A57 mmap */
+	cmp	w16, #BLD_GIC_A53A57_MMAP
+	b.ne	exit_print_gic_regs
+	mov_imm	x17, BASE_GICC_BASE
+	mov_imm	x16, BASE_GICD_BASE
+	b	print_gicc_regs
+use_ve_mmap:
+	mov_imm	x17, VE_GICC_BASE
+	mov_imm	x16, VE_GICD_BASE
+print_gicc_regs:
+	/* gicc base address is now in x17 */
+	adr	x6, gicc_regs	/* Load the gicc reg list to x6 */
+	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+	ldr	w8, [x17, #GICC_HPPIR]
+	ldr	w9, [x17, #GICC_AHPPIR]
+	ldr	w10, [x17, #GICC_CTLR]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+
+	/* Print the GICD_ISPENDR regs */
+	add	x7, x16, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+gicd_ispendr_loop:
+	sub	x4, x7, x16
+	cmp	x4, #0x280
+	b.eq	exit_print_gic_regs
+	bl	asm_print_hex
+	adr	x4, spacer
+	bl	asm_print_str
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+	adr	x4, newline
+	bl	asm_print_str
+	b	gicd_ispendr_loop
+exit_print_gic_regs:
+	.endm
+
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+	.asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+	/* ------------------------------------------------
+	 * The below macro prints out relevant interconnect
+	 * registers whenever an unhandled exception is
+	 * taken in BL3-1.
+	 * Clobbers: x0 - x9, sp
+	 * ------------------------------------------------
+	 */
+	.macro plat_print_interconnect_regs
+	adr	x6, cci_iface_regs
+	/* Store in x7 the base address of the first interface */
+	mov_imm	x7, (CCI400_BASE + SLAVE_IFACE3_OFFSET)
+	ldr	w8, [x7, #SNOOP_CTRL_REG]
+	/* Store in x7 the base address of the second interface */
+	mov_imm	x7, (CCI400_BASE + SLAVE_IFACE4_OFFSET)
+	ldr	w9, [x7, #SNOOP_CTRL_REG]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+	.endm
diff --git a/uefi/arm-trusted-firmware/plat/fvp/include/platform_def.h b/uefi/arm-trusted-firmware/plat/fvp/include/platform_def.h
new file mode 100644
index 0000000..182c150
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/include/platform_def.h
@@ -0,0 +1,232 @@
+/*
+ * 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 __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include "../fvp_def.h"
+
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT          "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH            aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if DEBUG_XLAT_TABLE
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL1
+#if TRUSTED_BOARD_BOOT
+#define PLATFORM_STACK_SIZE 0x1000
+#else
+#define PLATFORM_STACK_SIZE 0x440
+#endif
+#elif IMAGE_BL2
+#if TRUSTED_BOARD_BOOT
+#define PLATFORM_STACK_SIZE 0x1000
+#else
+#define PLATFORM_STACK_SIZE 0x400
+#endif
+#elif IMAGE_BL31
+#define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL32
+#define PLATFORM_STACK_SIZE 0x440
+#endif
+
+#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+
+/* Trusted Boot Firmware BL2 */
+#define BL2_IMAGE_NAME			"bl2.bin"
+
+/* EL3 Runtime Firmware BL31 */
+#define BL31_IMAGE_NAME			"bl31.bin"
+
+/* Secure Payload BL32 (Trusted OS) */
+#define BL32_IMAGE_NAME			"bl32.bin"
+
+/* Non-Trusted Firmware BL33 */
+#define BL33_IMAGE_NAME			"bl33.bin" /* e.g. UEFI */
+
+#if TRUSTED_BOARD_BOOT
+/* Certificates */
+# define BL2_CERT_NAME			"bl2.crt"
+# define TRUSTED_KEY_CERT_NAME		"trusted_key.crt"
+
+# define BL30_KEY_CERT_NAME		"bl30_key.crt"
+# define BL31_KEY_CERT_NAME		"bl31_key.crt"
+# define BL32_KEY_CERT_NAME		"bl32_key.crt"
+# define BL33_KEY_CERT_NAME		"bl33_key.crt"
+
+# define BL30_CERT_NAME			"bl30.crt"
+# define BL31_CERT_NAME			"bl31.crt"
+# define BL32_CERT_NAME			"bl32.crt"
+# define BL33_CERT_NAME			"bl33.crt"
+#endif /* TRUSTED_BOARD_BOOT */
+
+#define PLATFORM_CACHE_LINE_SIZE	64
+#define PLATFORM_CLUSTER_COUNT		2ull
+#define PLATFORM_CLUSTER0_CORE_COUNT	4
+#define PLATFORM_CLUSTER1_CORE_COUNT	4
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER1_CORE_COUNT + \
+						PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	4
+#define PLATFORM_NUM_AFFS		(PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+#define MAX_IO_DEVICES			3
+#define MAX_IO_HANDLES			4
+
+/*******************************************************************************
+ * BL1 specific defines.
+ * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of
+ * addresses.
+ ******************************************************************************/
+#define BL1_RO_BASE			FVP_TRUSTED_ROM_BASE
+#define BL1_RO_LIMIT			(FVP_TRUSTED_ROM_BASE \
+					+ FVP_TRUSTED_ROM_SIZE)
+/*
+ * Put BL1 RW at the top of the Trusted SRAM. BL1_RW_BASE is calculated using
+ * the current BL1 RW debug size plus a little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+#define BL1_RW_BASE			(FVP_TRUSTED_SRAM_BASE \
+					+ FVP_TRUSTED_SRAM_SIZE - 0x8000)
+#else
+#define BL1_RW_BASE			(FVP_TRUSTED_SRAM_BASE \
+					+ FVP_TRUSTED_SRAM_SIZE - 0x6000)
+#endif
+#define BL1_RW_LIMIT			(FVP_TRUSTED_SRAM_BASE \
+					+ FVP_TRUSTED_SRAM_SIZE)
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
+ * size plus a little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+#define BL2_BASE			(BL31_BASE - 0x1C000)
+#else
+#define BL2_BASE			(BL31_BASE - 0xC000)
+#endif
+#define BL2_LIMIT			BL31_BASE
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
+ * current BL3-1 debug size plus a little space for growth.
+ */
+#define BL31_BASE			(FVP_TRUSTED_SRAM_BASE \
+					+ FVP_TRUSTED_SRAM_SIZE - 0x1D000)
+#define BL31_PROGBITS_LIMIT		BL1_RW_BASE
+#define BL31_LIMIT			(FVP_TRUSTED_SRAM_BASE \
+					+ FVP_TRUSTED_SRAM_SIZE)
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+/*
+ * The TSP can execute either from Trusted SRAM or Trusted DRAM.
+ */
+#define BL32_SRAM_BASE			FVP_TRUSTED_SRAM_BASE
+#define BL32_SRAM_LIMIT			BL31_BASE
+#define BL32_DRAM_BASE			FVP_TRUSTED_DRAM_BASE
+#define BL32_DRAM_LIMIT			(FVP_TRUSTED_DRAM_BASE + (1 << 21))
+
+#if FVP_TSP_RAM_LOCATION_ID == FVP_IN_TRUSTED_SRAM
+# define TSP_SEC_MEM_BASE		FVP_TRUSTED_SRAM_BASE
+# define TSP_SEC_MEM_SIZE		FVP_TRUSTED_SRAM_SIZE
+# define TSP_PROGBITS_LIMIT		BL2_BASE
+# define BL32_BASE			BL32_SRAM_BASE
+# define BL32_LIMIT			BL32_SRAM_LIMIT
+#elif FVP_TSP_RAM_LOCATION_ID == FVP_IN_TRUSTED_DRAM
+# define TSP_SEC_MEM_BASE		FVP_TRUSTED_DRAM_BASE
+# define TSP_SEC_MEM_SIZE		FVP_TRUSTED_DRAM_SIZE
+# define BL32_BASE			BL32_DRAM_BASE
+# define BL32_LIMIT			BL32_DRAM_LIMIT
+#else
+# error "Unsupported FVP_TSP_RAM_LOCATION_ID value"
+#endif
+
+/*
+ * ID of the secure physical generic timer interrupt used by the TSP.
+ */
+#define TSP_IRQ_SEC_PHY_TIMER		IRQ_SEC_PHY_TIMER
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define ADDR_SPACE_SIZE			(1ull << 32)
+
+#if IMAGE_BL1
+# define MAX_XLAT_TABLES		2
+#elif IMAGE_BL2
+# define MAX_XLAT_TABLES		3
+#elif IMAGE_BL31
+# define MAX_XLAT_TABLES		2
+#elif IMAGE_BL32
+# if FVP_TSP_RAM_LOCATION_ID == FVP_DRAM_ID
+#  define MAX_XLAT_TABLES		3
+# else
+#  define MAX_XLAT_TABLES		2
+# endif
+#endif
+
+#define MAX_MMAP_REGIONS		16
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT   6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+#if !USE_COHERENT_MEM
+/*******************************************************************************
+ * Size of the per-cpu data in bytes that should be reserved in the generic
+ * per-cpu data structure for the FVP port.
+ ******************************************************************************/
+#define PLAT_PCPU_DATA_SIZE	2
+#endif
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/fvp/include/platform_oid.h b/uefi/arm-trusted-firmware/plat/fvp/include/platform_oid.h
new file mode 100644
index 0000000..38aca12
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/include/platform_oid.h
@@ -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.
+ */
+
+#ifndef PLATFORM_OID_H_
+#define PLATFORM_OID_H_
+
+/*
+ * This is the list of the different extensions containing relevant information
+ * to establish the chain of trust.
+ *
+ * The OIDs shown here are just an example. Real OIDs should be obtained from
+ * the ITU-T.
+ */
+
+/* Non-volatile counter extensions */
+#define TZ_FW_NVCOUNTER_OID		"1.2.3.1"
+#define NTZ_FW_NVCOUNTER_OID		"1.2.3.2"
+
+/* BL2 extensions */
+#define BL2_HASH_OID			"1.2.3.3"
+
+/* Trusted Key extensions */
+#define TZ_WORLD_PK_OID			"1.2.3.4"
+#define NTZ_WORLD_PK_OID		"1.2.3.5"
+
+/* BL3-1 extensions */
+#define BL31_CONTENT_CERT_PK_OID	"1.2.3.6"
+#define BL31_HASH_OID			"1.2.3.7"
+
+/* BL3-0 extensions */
+#define BL30_CONTENT_CERT_PK_OID	"1.2.3.8"
+#define BL30_HASH_OID			"1.2.3.9"
+
+/* BL3-2 extensions */
+#define BL32_CONTENT_CERT_PK_OID	"1.2.3.10"
+#define BL32_HASH_OID			"1.2.3.11"
+
+/* BL3-3 extensions */
+#define BL33_CONTENT_CERT_PK_OID	"1.2.3.12"
+#define BL33_HASH_OID			"1.2.3.13"
+
+#endif /* PLATFORM_OID_H_ */
diff --git a/uefi/arm-trusted-firmware/plat/fvp/platform.mk b/uefi/arm-trusted-firmware/plat/fvp/platform.mk
new file mode 100644
index 0000000..bcee328
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/platform.mk
@@ -0,0 +1,96 @@
+#
+# 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.
+#
+
+# On FVP, the TSP can execute either from Trusted SRAM or Trusted DRAM.
+# Trusted SRAM is the default.
+FVP_TSP_RAM_LOCATION	:=	tsram
+ifeq (${FVP_TSP_RAM_LOCATION}, tsram)
+  FVP_TSP_RAM_LOCATION_ID := FVP_TRUSTED_SRAM_ID
+else ifeq (${FVP_TSP_RAM_LOCATION}, tdram)
+  FVP_TSP_RAM_LOCATION_ID := FVP_TRUSTED_DRAM_ID
+else ifeq (${FVP_TSP_RAM_LOCATION}, dram)
+  FVP_TSP_RAM_LOCATION_ID := FVP_DRAM_ID
+else
+  $(error "Unsupported FVP_TSP_RAM_LOCATION value")
+endif
+
+# Process flags
+$(eval $(call add_define,FVP_TSP_RAM_LOCATION_ID))
+
+PLAT_INCLUDES		:=	-Iplat/fvp/include/
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/arm/pl011/pl011_console.S		\
+				drivers/io/io_fip.c				\
+				drivers/io/io_memmap.c				\
+				drivers/io/io_semihosting.c			\
+				drivers/io/io_storage.c				\
+				lib/aarch64/xlat_tables.c			\
+				lib/semihosting/semihosting.c			\
+				lib/semihosting/aarch64/semihosting_call.S	\
+				plat/common/aarch64/plat_common.c		\
+				plat/fvp/fvp_io_storage.c
+
+BL1_SOURCES		+=	drivers/arm/cci400/cci400.c			\
+				lib/cpus/aarch64/aem_generic.S			\
+				lib/cpus/aarch64/cortex_a53.S			\
+				lib/cpus/aarch64/cortex_a57.S			\
+				plat/common/aarch64/platform_up_stack.S		\
+				plat/fvp/bl1_fvp_setup.c			\
+				plat/fvp/aarch64/fvp_common.c			\
+				plat/fvp/aarch64/fvp_helpers.S
+
+BL2_SOURCES		+=	drivers/arm/tzc400/tzc400.c			\
+				plat/common/aarch64/platform_up_stack.S		\
+				plat/fvp/bl2_fvp_setup.c			\
+				plat/fvp/fvp_security.c				\
+				plat/fvp/aarch64/fvp_common.c
+
+BL31_SOURCES		+=	drivers/arm/cci400/cci400.c			\
+				drivers/arm/gic/arm_gic.c			\
+				drivers/arm/gic/gic_v2.c			\
+				drivers/arm/gic/gic_v3.c			\
+				drivers/arm/tzc400/tzc400.c			\
+				lib/cpus/aarch64/aem_generic.S			\
+				lib/cpus/aarch64/cortex_a53.S			\
+				lib/cpus/aarch64/cortex_a57.S			\
+				plat/common/plat_gic.c				\
+				plat/common/aarch64/platform_mp_stack.S		\
+				plat/fvp/bl31_fvp_setup.c			\
+				plat/fvp/fvp_pm.c				\
+				plat/fvp/fvp_security.c				\
+				plat/fvp/fvp_topology.c				\
+				plat/fvp/aarch64/fvp_helpers.S			\
+				plat/fvp/aarch64/fvp_common.c			\
+				plat/fvp/drivers/pwrc/fvp_pwrc.c
+
+ifneq (${TRUSTED_BOARD_BOOT},0)
+  BL1_SOURCES		+=	plat/fvp/fvp_trusted_boot.c
+  BL2_SOURCES		+=	plat/fvp/fvp_trusted_boot.c
+endif
diff --git a/uefi/arm-trusted-firmware/plat/fvp/tsp/tsp-fvp.mk b/uefi/arm-trusted-firmware/plat/fvp/tsp/tsp-fvp.mk
new file mode 100644
index 0000000..d2e112a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/tsp/tsp-fvp.mk
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+# TSP source files specific to FVP platform
+BL32_SOURCES		+=	drivers/arm/gic/arm_gic.c			\
+				drivers/arm/gic/gic_v2.c			\
+				plat/common/aarch64/platform_mp_stack.S		\
+				plat/common/plat_gic.c				\
+				plat/fvp/aarch64/fvp_common.c			\
+				plat/fvp/aarch64/fvp_helpers.S			\
+				plat/fvp/tsp/tsp_fvp_setup.c
diff --git a/uefi/arm-trusted-firmware/plat/fvp/tsp/tsp_fvp_setup.c b/uefi/arm-trusted-firmware/plat/fvp/tsp/tsp_fvp_setup.c
new file mode 100644
index 0000000..d8f46bd
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/fvp/tsp/tsp_fvp_setup.c
@@ -0,0 +1,111 @@
+/*
+ * 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 <console.h>
+#include <platform_tsp.h>
+#include "../fvp_def.h"
+#include "../fvp_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 __RO_END__;
+extern unsigned long __BL32_END__;
+
+#if USE_COHERENT_MEM
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+#endif
+
+/*
+ * The next 3 constants identify the extents of the code & RO data region and
+ * the limit of the BL3-2 image. These addresses are used by the MMU setup code
+ * and therefore they must be page-aligned.  It is the responsibility of the
+ * linker script to ensure that __RO_START__, __RO_END__ & & __BL32_END__
+ * linker symbols refer to page-aligned addresses.
+ */
+#define BL32_RO_BASE (unsigned long)(&__RO_START__)
+#define BL32_RO_LIMIT (unsigned long)(&__RO_END__)
+#define BL32_END (unsigned long)(&__BL32_END__)
+
+#if USE_COHERENT_MEM
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+#endif
+
+/*******************************************************************************
+ * Initialize the UART
+ ******************************************************************************/
+void tsp_early_platform_setup(void)
+{
+	/*
+	 * Initialize a different console than already in use to display
+	 * messages from TSP
+	 */
+	console_init(PL011_UART2_BASE, PL011_UART2_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Initialize the platform config for future decision making */
+	fvp_config_setup();
+}
+
+/*******************************************************************************
+ * Perform platform specific setup placeholder
+ ******************************************************************************/
+void tsp_platform_setup(void)
+{
+	fvp_gic_init();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the MMU
+ ******************************************************************************/
+void tsp_plat_arch_setup(void)
+{
+	fvp_configure_mmu_el1(BL32_RO_BASE,
+			      (BL32_END - BL32_RO_BASE),
+			      BL32_RO_BASE,
+			      BL32_RO_LIMIT
+#if USE_COHERENT_MEM
+			      , BL32_COHERENT_RAM_BASE,
+			      BL32_COHERENT_RAM_LIMIT
+#endif
+			      );
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/aarch64/bl1_plat_helpers.S b/uefi/arm-trusted-firmware/plat/hikey/aarch64/bl1_plat_helpers.S
new file mode 100644
index 0000000..d3e6ff6
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/aarch64/bl1_plat_helpers.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 "../hikey_def.h"
+
+	.globl	platform_is_primary_cpu
+	.globl	platform_get_entrypoint
+	.globl	platform_cold_boot_init
+	.globl	plat_secondary_cold_boot_setup
+
+func platform_is_primary_cpu
+	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+	cmp	x0, #0
+	cset	x0, eq
+	ret
+
+	/*
+	 * Do we need to know whether it's a warm boot?
+	 */
+func platform_get_entrypoint
+	mov	x0, #0
+	ret
+
+func plat_secondary_cold_boot_setup
+cb_panic:
+	b	cb_panic
diff --git a/uefi/arm-trusted-firmware/plat/hikey/aarch64/hikey_common.c b/uefi/arm-trusted-firmware/plat/hikey/aarch64/hikey_common.c
new file mode 100644
index 0000000..ba1313d
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/aarch64/hikey_common.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <xlat_tables.h>
+#include <../hikey_def.h>
+
+#define MAP_DEVICE	MAP_REGION_FLAT(DEVICE_BASE,			\
+					DEVICE_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_NS_DRAM	MAP_REGION_FLAT(DRAM_NS_BASE,			\
+					DRAM_NS_SIZE,			\
+					MT_DEVICE | MT_RW | MT_NS)
+
+#define MAP_TSP_MEM	MAP_REGION_FLAT(TSP_SEC_MEM_BASE, 		\
+					TSP_SEC_MEM_SIZE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_ROM_PARAM	MAP_REGION_FLAT(XG2RAM0_BASE,			\
+					0x1000,				\
+					MT_DEVICE | MT_RW | MT_NS)
+
+#define MAP_SRAM	MAP_REGION_FLAT(SRAM_BASE,			\
+					SRAM_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * configure_mmu_elx() will give the available subset of that,
+ */
+#if IMAGE_BL1
+static const mmap_region_t hikey_mmap[] = {
+	MAP_DEVICE,
+	MAP_NS_DRAM,
+	MAP_ROM_PARAM,
+	{0}
+};
+#endif
+#if IMAGE_BL2
+static const mmap_region_t hikey_mmap[] = {
+	MAP_DEVICE,
+	MAP_NS_DRAM,
+	MAP_TSP_MEM,
+	MAP_SRAM,
+	{0}
+};
+#endif
+#if IMAGE_BL31
+static const mmap_region_t hikey_mmap[] = {
+	MAP_DEVICE,
+	MAP_NS_DRAM,
+	MAP_TSP_MEM,
+	MAP_SRAM,
+	{0}
+};
+#endif
+#if IMAGE_BL32
+static const mmap_region_t hikey_mmap[] = {
+	MAP_DEVICE,
+	MAP_NS_DRAM,
+	{0}
+};
+#endif
+
+/* Array of secure interrupts to be configured by the gic driver */
+const unsigned int irq_sec_array[] = {
+	IRQ_SEC_PHY_TIMER,
+	IRQ_SEC_SGI_0,
+	IRQ_SEC_SGI_1,
+	IRQ_SEC_SGI_2,
+	IRQ_SEC_SGI_3,
+	IRQ_SEC_SGI_4,
+	IRQ_SEC_SGI_5,
+	IRQ_SEC_SGI_6,
+	IRQ_SEC_SGI_7
+};
+
+const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
+	sizeof(irq_sec_array[0]);
+
+/*******************************************************************************
+ * Macro generating the code for the function setting up the pagetables as per
+ * the platform memory map & initialize the mmu, for the given exception level
+ ******************************************************************************/
+#define DEFINE_CONFIGURE_MMU_EL(_el)				\
+	void configure_mmu_el##_el(unsigned long total_base,	\
+				  unsigned long total_size,	\
+				  unsigned long ro_start,	\
+				  unsigned long ro_limit,	\
+				  unsigned long coh_start,	\
+				  unsigned long coh_limit)	\
+	{							\
+	       mmap_add_region(total_base, total_base,		\
+			       total_size,			\
+			       MT_MEMORY | MT_RW | MT_SECURE);	\
+	       mmap_add_region(ro_start, ro_start,		\
+			       ro_limit - ro_start,		\
+			       MT_MEMORY | MT_RO | MT_SECURE);	\
+	       mmap_add_region(coh_start, coh_start,		\
+			       coh_limit - coh_start,		\
+			       MT_DEVICE | MT_RW | MT_SECURE);	\
+	       mmap_add(hikey_mmap);				\
+	       init_xlat_tables();				\
+								\
+	       enable_mmu_el##_el(0);				\
+	}
+
+/* Define EL1 and EL3 variants of the function initialising the MMU */
+DEFINE_CONFIGURE_MMU_EL(1)
+DEFINE_CONFIGURE_MMU_EL(3)
+
+unsigned long plat_get_ns_image_entrypoint(void)
+{
+	return NS_IMAGE_OFFSET;
+}
+
+uint64_t plat_get_syscnt_freq(void)
+{
+	return 1200000;
+}
+
+void plat_gic_init(void)
+{
+	arm_gic_init(GICC_BASE, GICD_BASE, 0, irq_sec_array, num_sec_irqs);
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/aarch64/plat_helpers.S b/uefi/arm-trusted-firmware/plat/hikey/aarch64/plat_helpers.S
new file mode 100644
index 0000000..02f739c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/aarch64/plat_helpers.S
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <cortex_a53.h>
+#include <cpu_macros.S>
+#include <platform_def.h>
+#include "../hikey_def.h"
+
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_report_exception
+	.globl	plat_reset_handler
+	.globl	platform_get_core_pos
+	.globl	platform_mem_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize the crash console
+	 * without a C Runtime to print crash report.
+	 * Clobber list : x0, x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+	mov_imm	x0, CRASH_CONSOLE_BASE
+	mov_imm	x1, PL011_UART_CLK_IN_HZ
+	mov_imm	x2, PL011_BAUDRATE
+	b	console_core_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to print a character on the crash
+	 * console without a C Runtime.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, CRASH_CONSOLE_BASE
+	b	console_core_putc
+
+	/* ---------------------------------------------
+	 * void plat_report_exception(unsigned int type)
+	 * Function to report an unhandled exception
+	 * with platform-specific means.
+	 * On HIKEY platform, it updates the LEDs
+	 * to indicate where we are
+	 * ---------------------------------------------
+	 */
+func plat_report_exception
+	mov	x8, x30
+
+	/* Turn on LED according to x0 (0 -- f) */
+	/*
+	ldr	x2, =0xf7020000
+	and	x1, x0, #1
+	str	w1, [x2, #4]
+	and	x1, x0, #2
+	str	w1, [x2, #8]
+	and	x1, x0, #4
+	str	w1, [x2, #16]
+	and	x1, x0, #8
+	str	w1, [x2, #32]
+	*/
+
+	adr	x4, plat_err_str
+	bl	asm_print_str
+
+	adr	x4, esr_el3_str
+	bl	asm_print_str
+
+	mrs	x4, esr_el3
+	bl	asm_print_hex
+
+	adr	x4, elr_el3_str
+	bl	asm_print_str
+
+	mrs	x4, elr_el3
+	bl	asm_print_hex
+
+	mov	x30, x8
+	ret
+
+	/* -----------------------------------------------------
+	 * void plat_reset_handler(void);
+	 *
+	 * Implement workaround for defect id 831273 by enabling
+	 * an event stream every 65536 cycles and set the L2 RAM
+	 * latencies for Cortex-A57.
+	 * -----------------------------------------------------
+	 */
+func plat_reset_handler
+	/* In juno, it sets the latency of L2 Data and Tag. How about hikey? */
+	/* Do anything just after reset. At here, do we need? */
+	ret
+
+	/*
+	 * Return 0 to 7
+	 */
+func platform_get_core_pos
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+
+	/* -----------------------------------------------------
+	 * void platform_mem_init(void);
+	 *
+	 * We don't need to carry out any memory initialization
+	 * on HIKEY. The Secure RAM is accessible straight away.
+	 * -----------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+
+.section .rodata.rev_err_str, "aS"
+plat_err_str:
+	.asciz "\nPlatform exception reporting:"
+esr_el3_str:
+	.asciz "\nESR_EL3: "
+elr_el3_str:
+	.asciz "\nELR_EL3: "
diff --git a/uefi/arm-trusted-firmware/plat/hikey/bl1_plat_setup.c b/uefi/arm-trusted-firmware/plat/hikey/bl1_plat_setup.c
new file mode 100644
index 0000000..984c0ee
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/bl1_plat_setup.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <bl_common.h>
+#include <cci400.h>
+#include <console.h>
+#include <ctype.h>
+#include <debug.h>
+#include <errno.h>
+#include <gpio.h>
+#include <hi6220.h>
+#include <hi6553.h>
+#include <mmio.h>
+#include <partitions.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <sp804_timer.h>
+#include <string.h>
+#include "../../bl1/bl1_private.h"
+#include "hikey_def.h"
+#include "hikey_private.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ ******************************************************************************/
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/* Data structure which holds the extents of the trusted RAM for BL1 */
+static meminfo_t bl1_tzram_layout;
+
+static void hi6220_pmussi_init(void);
+static void hikey_gpio_init(void);
+static void hikey_hi6553_init(void);
+static int query_boot_mode(void);
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+	return &bl1_tzram_layout;
+}
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+	const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
+
+	/* Initialize the console to provide early debug support */
+	console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
+
+	hi6220_timer_init();
+	/*
+	 * Enable CCI-400 for this cluster. No need for locks as no other cpu is
+	 * active at the moment
+	 */
+	cci_init(CCI400_BASE,
+		 CCI400_SL_IFACE3_CLUSTER_IX,
+		 CCI400_SL_IFACE4_CLUSTER_IX);
+	cci_enable_cluster_coherency(read_mpidr());
+
+	/* Allow BL1 to see the whole Trusted RAM */
+	bl1_tzram_layout.total_base = BL1_RW_BASE;
+	bl1_tzram_layout.total_size = BL1_RW_SIZE;
+
+	/* Calculate how much RAM BL1 is using and how much remains free */
+	bl1_tzram_layout.free_base = BL1_RW_BASE;
+	bl1_tzram_layout.free_size = BL1_RW_SIZE;
+	reserve_mem(&bl1_tzram_layout.free_base,
+		    &bl1_tzram_layout.free_size,
+		    BL1_RAM_BASE,
+		    bl1_size);
+
+	INFO("BL1: 0x%lx - 0x%lx [size = %u]\n", BL1_RAM_BASE, BL1_RAM_LIMIT,
+	     bl1_size);
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architecture setup here. At the
+ * moment this only does basic initialization. Later architectural setup
+ * (bl1_arch_setup()) does not do anything platform specific.
+ ******************************************************************************/
+void bl1_plat_arch_setup(void)
+{
+	configure_mmu_el3(bl1_tzram_layout.total_base,
+			  bl1_tzram_layout.total_size,
+			  BL1_RO_BASE,
+			  BL1_RO_LIMIT,
+			  BL1_COHERENT_RAM_BASE,
+			  BL1_COHERENT_RAM_LIMIT);
+}
+
+static int sd_card_detect(void)
+{
+	int ret;
+	/* configure GPIO8 as nopull */
+	mmio_write_32(0xf8001830, 0);
+	gpio_direction_input(8);
+	ret = gpio_get_value(8);
+	if (!ret)
+		return 1;
+	return 0;
+}
+
+static void hikey_sd_init(void)
+{
+	int ret;
+
+	/* switch pinmux to SD */
+	mmio_write_32(0xf701000c, 0);
+	mmio_write_32(0xf7010010, 0);
+	mmio_write_32(0xf7010014, 0);
+	mmio_write_32(0xf7010018, 0);
+	mmio_write_32(0xf701001c, 0);
+	mmio_write_32(0xf7010020, 0);
+
+	/* input, 16mA or 12mA */
+	mmio_write_32(0xf701080c, 0x64);
+	mmio_write_32(0xf7010810, 0x54);
+	mmio_write_32(0xf7010814, 0x54);
+	mmio_write_32(0xf7010818, 0x54);
+	mmio_write_32(0xf701081c, 0x54);
+	mmio_write_32(0xf7010820, 0x54);
+	ret = sd_card_detect();
+	if (ret)
+		INFO("SD Card has been detected.\n");
+}
+
+static void hikey_jumper_init(void)
+{
+	/* configure GPIO24 as nopull */
+	mmio_write_32(0xf7010950, 0);
+	/* configure GPIO24 as gpio */
+	mmio_write_32(0xf7010140, 0);
+	gpio_direction_input(24);
+	VERBOSE("Jumper value:%d\n", gpio_get_value(24));
+}
+
+static inline char hex2str(unsigned int data)
+{
+	data &= 0xf;
+	if ((data >= 0) && (data <= 9))
+		return (char)(data + 0x30);
+	return (char)(data - 10 + 0x41);
+}
+
+static uint64_t rand(unsigned int data)
+{
+	int64_t quotient, remainder, t;
+
+	quotient = data / 127773;
+	remainder = data % 127773;
+	t = 16807 * remainder - 2836 * quotient;
+	if (t <= 0)
+		t += RANDOM_MAX;
+	return (t % ((uint64_t)RANDOM_MAX + 1));
+}
+
+void generate_serialno(struct random_serial_num *random)
+{
+	unsigned int data, t;
+	int i;
+
+	data = mmio_read_32(AO_SC_SYSTEST_SLICER_CNT0);
+	t = rand(data);
+	random->data = ((uint64_t)t << 32) | data;
+	for (i = 0; i < 8; i++) {
+		random->serialno[i] = hex2str((t >> ((7 - i) << 2)) & 0xf);
+	}
+	for (i = 0; i < 8; i++) {
+		random->serialno[i + 8] = hex2str((data >> ((7 - i) << 2)) & 0xf);
+	}
+	random->serialno[16] = '\0';
+	random->magic = RANDOM_MAGIC;
+}
+
+int assign_serialno(char *cmdbuf, struct random_serial_num *random)
+{
+	int offset, i;
+
+	offset = 0;
+	while (*(cmdbuf + offset) == ' ')
+		offset++;
+	for (i = 0; i < 16; i++) {
+		if (isxdigit(*(cmdbuf + offset + i)))
+			continue;
+		return -EINVAL;
+	}
+	memcpy(random->serialno, cmdbuf + offset, 16);
+	random->serialno[16] = '\0';
+	random->magic = RANDOM_MAGIC;
+	return 0;
+}
+
+static void hikey_verify_serialno(struct random_serial_num *random)
+{
+	char *serialno;
+
+	serialno = load_serialno();
+	if (serialno == NULL) {
+		generate_serialno(random);
+		flush_random_serialno((unsigned long)&random, sizeof(random));
+	}
+}
+
+/*******************************************************************************
+ * Function which will perform any remaining platform-specific setup that can
+ * occur after the MMU and data cache have been enabled.
+ ******************************************************************************/
+void bl1_platform_setup(void)
+{
+	struct random_serial_num random;
+
+	hikey_gpio_init();
+	hi6220_pmussi_init();
+	hikey_hi6553_init();
+	hi6220_pll_init();
+	hikey_sd_init();
+	hikey_jumper_init();
+
+	io_setup();
+	get_partition();
+	INFO("Hisilicon HiKey platform is initialized\n");
+	if (query_boot_mode()) {
+		NOTICE("Enter fastboot mode...\n");
+		flush_loader_image();
+		hikey_verify_serialno(&random);
+		usb_download();
+	}
+}
+
+/* Get the boot mode (normal boot/usb download/uart download) */
+static int query_boot_mode(void)
+{
+	int boot_mode;
+
+	boot_mode = mmio_read_32(ONCHIPROM_PARAM_BASE);
+	if ((boot_mode < 0) || (boot_mode > 2)) {
+		NOTICE("Invalid boot mode is found:%d\n", boot_mode);
+		panic();
+	}
+	return boot_mode;
+}
+
+/* PMU SSI is the device that could map external PMU register to IO */
+static void hi6220_pmussi_init(void)
+{
+	uint32_t data;
+
+	/*
+	 * After reset, PMUSSI stays in reset mode.
+	 * Now make it out of reset.
+	 */
+	mmio_write_32(AO_SC_PERIPH_RSTDIS4,
+		AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N);
+	do {
+		data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
+	} while (data & AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N);
+
+	/* set PMU SSI clock latency for read operation */
+	data = mmio_read_32(AO_SC_MCU_SUBSYS_CTRL3);
+	data &= ~AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK;
+	data |= AO_SC_MCU_SUBSYS_CTRL3_RCLK_3;
+	mmio_write_32(AO_SC_MCU_SUBSYS_CTRL3, data);
+
+	/* enable PMUSSI clock */
+	data = AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU |
+	       AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU;
+	mmio_write_32(AO_SC_PERIPH_CLKEN5, data);
+	data = AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI;
+	mmio_write_32(AO_SC_PERIPH_CLKEN4, data);
+
+	/* output high on gpio0 */
+	gpio_direction_output(0);
+	gpio_set_value(0, 1);
+}
+
+static void hikey_hi6553_init(void)
+{
+	int data;
+
+	hi6553_write_8(PERI_EN_MARK, 0x1e);
+	hi6553_write_8(NP_REG_ADJ1, 0);
+	data = DISABLE6_XO_CLK_CONN | DISABLE6_XO_CLK_NFC |
+		DISABLE6_XO_CLK_RF1 | DISABLE6_XO_CLK_RF2;
+	hi6553_write_8(DISABLE6_XO_CLK, data);
+
+	/* configure BUCK0 & BUCK1 */
+	hi6553_write_8(BUCK01_CTRL2, 0x5e);
+	hi6553_write_8(BUCK0_CTRL7, 0x10);
+	hi6553_write_8(BUCK1_CTRL7, 0x10);
+	hi6553_write_8(BUCK0_CTRL5, 0x1e);
+	hi6553_write_8(BUCK1_CTRL5, 0x1e);
+	hi6553_write_8(BUCK0_CTRL1, 0xfc);
+	hi6553_write_8(BUCK1_CTRL1, 0xfc);
+
+	/* configure BUCK2 */
+	hi6553_write_8(BUCK2_REG1, 0x4f);
+	hi6553_write_8(BUCK2_REG5, 0x99);
+	hi6553_write_8(BUCK2_REG6, 0x45);
+	mdelay(1);
+	hi6553_write_8(VSET_BUCK2_ADJ, 0x22);
+	mdelay(1);
+
+	/* configure BUCK3 */
+	hi6553_write_8(BUCK3_REG3, 0x02);
+	hi6553_write_8(BUCK3_REG5, 0x99);
+	hi6553_write_8(BUCK3_REG6, 0x41);
+	hi6553_write_8(VSET_BUCK3_ADJ, 0x02);
+	mdelay(1);
+
+	/* configure BUCK4 */
+	hi6553_write_8(BUCK4_REG2, 0x9a);
+	hi6553_write_8(BUCK4_REG5, 0x99);
+	hi6553_write_8(BUCK4_REG6, 0x45);
+
+	/* configure LDO20 */
+	hi6553_write_8(LDO20_REG_ADJ, 0x50);
+
+	hi6553_write_8(NP_REG_CHG, 0x0f);
+	hi6553_write_8(CLK_TOP0, 0x06);
+	hi6553_write_8(CLK_TOP3, 0xc0);
+	hi6553_write_8(CLK_TOP4, 0x00);
+
+	/* configure LDO7 & LDO10 for SD slot */
+	data = hi6553_read_8(LDO7_REG_ADJ);
+	data = (data & 0xf8) | 0x2;
+	hi6553_write_8(LDO7_REG_ADJ, data);
+	mdelay(5);
+	/* enable LDO7 */
+	hi6553_write_8(ENABLE2_LDO1_8, 1 << 6);
+	mdelay(5);
+	data = hi6553_read_8(LDO10_REG_ADJ);
+	data = (data & 0xf8) | 0x5;
+	hi6553_write_8(LDO10_REG_ADJ, data);
+	mdelay(5);
+	/* enable LDO10 */
+	hi6553_write_8(ENABLE3_LDO9_16, 1 << 1);
+	mdelay(5);
+	/* enable LDO15 */
+	data = hi6553_read_8(LDO15_REG_ADJ);
+	data = (data & 0xf8) | 0x4;
+	hi6553_write_8(LDO15_REG_ADJ, data);
+	hi6553_write_8(ENABLE3_LDO9_16, 1 << 6);
+	mdelay(5);
+	/* enable LDO22 */
+	data = hi6553_read_8(LDO22_REG_ADJ);
+	data = (data & 0xf8) | 0x7;
+	hi6553_write_8(LDO22_REG_ADJ, data);
+	hi6553_write_8(ENABLE4_LDO17_22, 1 << 5);
+	mdelay(5);
+
+	/* select 32.764KHz */
+	hi6553_write_8(CLK19M2_600_586_EN, 0x01);
+}
+
+static void hikey_gpio_init(void)
+{
+	gpio_register_device(GPIO0_BASE);
+	gpio_register_device(GPIO1_BASE);
+	gpio_register_device(GPIO2_BASE);
+	gpio_register_device(GPIO3_BASE);
+	gpio_register_device(GPIO4_BASE);
+	gpio_register_device(GPIO5_BASE);
+	gpio_register_device(GPIO6_BASE);
+	gpio_register_device(GPIO7_BASE);
+	gpio_register_device(GPIO8_BASE);
+	gpio_register_device(GPIO9_BASE);
+	gpio_register_device(GPIO10_BASE);
+	gpio_register_device(GPIO11_BASE);
+	gpio_register_device(GPIO12_BASE);
+	gpio_register_device(GPIO13_BASE);
+	gpio_register_device(GPIO14_BASE);
+	gpio_register_device(GPIO15_BASE);
+	gpio_register_device(GPIO16_BASE);
+	gpio_register_device(GPIO17_BASE);
+	gpio_register_device(GPIO18_BASE);
+	gpio_register_device(GPIO19_BASE);
+
+	/* Power on indicator LED (User LED0). */
+	gpio_direction_output(32);
+	gpio_set_value(32, 1);
+	gpio_direction_output(33);
+	gpio_direction_output(34);
+	gpio_direction_output(35);
+
+	/* Initialize PWR_HOLD GPIO */
+	gpio_set_value(0, 1);
+	gpio_direction_output(0);
+}
+
+/*******************************************************************************
+ * Before calling this function BL2 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL2 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image,
+			      entry_point_info_t *bl2_ep)
+{
+	SET_SECURITY_STATE(bl2_ep->h.attr, SECURE);
+	bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/bl2_plat_setup.c b/uefi/arm-trusted-firmware/plat/hikey/bl2_plat_setup.c
new file mode 100644
index 0000000..0824394
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/bl2_plat_setup.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <partitions.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include <mmio.h>
+#include <hi6220.h>
+#include "hikey_def.h"
+#include "hikey_private.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __RO_END__;
+
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL2_RO_BASE (unsigned long)(&__RO_START__)
+#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/* Data structure which holds the extents of the trusted RAM for BL2 */
+static meminfo_t bl2_tzram_layout
+__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
+		section("tzfw_coherent_mem")));
+
+/*******************************************************************************
+ * Structure which holds the arguments which need to be passed to BL3-1
+ ******************************************************************************/
+static bl2_to_bl31_params_mem_t bl31_params_mem;
+
+meminfo_t *bl2_plat_sec_mem_layout(void)
+{
+	return &bl2_tzram_layout;
+}
+
+/*******************************************************************************
+ * This function assigns a pointer to the memory that the platform has kept
+ * aside to pass platform specific and trusted firmware related information
+ * to BL31. This memory is allocated by allocating memory to
+ * bl2_to_bl31_params_mem_t structure which is a superset of all the
+ * structure whose information is passed to BL31
+ * NOTE: This function should be called only once and should be done
+ * before generating params to BL31
+ ******************************************************************************/
+bl31_params_t *bl2_plat_get_bl31_params(void)
+{
+	bl31_params_t *bl2_to_bl31_params;
+
+	/*
+	 * Initialise the memory for all the arguments that needs to
+	 * be passed to BL3-1
+	 */
+	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
+
+	/* Assign memory for TF related information */
+	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
+	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
+
+	/* Fill BL3-1 related information */
+	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
+		VERSION_1, 0);
+
+	/* Fill BL3-2 related information if it exists */
+#if BL32_BASE
+	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
+		VERSION_1, 0);
+	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
+		VERSION_1, 0);
+#endif
+
+	/* Fill BL3-3 related information */
+	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
+		PARAM_EP, VERSION_1, 0);
+
+	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
+	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
+
+	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
+		VERSION_1, 0);
+
+	return bl2_to_bl31_params;
+}
+
+/*******************************************************************************
+ * This function returns a pointer to the shared memory that the platform
+ * has kept to point to entry point information of BL31 to BL2
+ ******************************************************************************/
+struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
+{
+	return &bl31_params_mem.bl31_ep_info;
+}
+
+void init_boardid(void)
+{
+	unsigned int reg;
+
+	/* Set chip id to sram */
+	reg = read_midr_el1();
+	mmio_write_32(MEMORY_AXI_CHIP_ADDR, reg);
+	INFO("[BDID] [%x] midr: 0x%x\n", MEMORY_AXI_CHIP_ADDR, reg);
+
+	/* Set board type to sram */
+	mmio_write_32(MEMORY_AXI_BOARD_TYPE_ADDR, 0x0);
+	INFO("[BDID] [%x] board type: 0\n", MEMORY_AXI_BOARD_TYPE_ADDR);
+
+	/* Set board id to sram */
+	mmio_write_32(MEMORY_AXI_BOARD_ID_ADDR, 0x2b);
+	INFO("[BDID] [%x] board id: 0x2b\n", MEMORY_AXI_BOARD_ID_ADDR);
+
+	mmio_write_32(ACPU_ARM64_FLAGA, 0x1234);
+	mmio_write_32(ACPU_ARM64_FLAGB, 0x5678);
+	return;
+}
+
+/*******************************************************************************
+ * BL1 has passed the extents of the trusted RAM that should be visible to BL2
+ * in x0. This memory layout is sitting at the base of the free trusted RAM.
+ * Copy it to a safe loaction before its reclaimed by later BL2 functionality.
+ ******************************************************************************/
+void bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Setup the BL2 memory layout */
+	bl2_tzram_layout = *mem_layout;
+
+	init_boardid();
+	init_acpu_dvfs();
+
+	io_setup();
+	get_partition();
+}
+
+/*******************************************************************************
+ * Perform platform specific setup, i.e. initialize the IO layer, load BL3-0
+ * image and initialise the memory location to use for passing arguments to
+ * BL3-1.
+ ******************************************************************************/
+void bl2_platform_setup(void)
+{
+	plat_security_setup();
+}
+
+/* Flush the TF params and the TF plat params */
+void bl2_plat_flush_bl31_params(void)
+{
+	flush_dcache_range((unsigned long)&bl31_params_mem,
+			sizeof(bl2_to_bl31_params_mem_t));
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl2_plat_arch_setup(void)
+{
+	configure_mmu_el1(bl2_tzram_layout.total_base,
+			  bl2_tzram_layout.total_size,
+			  BL2_RO_BASE,
+			  BL2_RO_LIMIT,
+			  BL2_COHERENT_RAM_BASE,
+			  BL2_COHERENT_RAM_LIMIT);
+}
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL3-0, i.e. anywhere
+ * in trusted RAM as long as it doesn't overwrite BL2.
+ ******************************************************************************/
+void bl2_plat_get_bl30_meminfo(meminfo_t *bl30_meminfo)
+{
+	bl30_meminfo->total_base = BL30_BASE;
+	bl30_meminfo->total_size = BL30_SIZE;
+	bl30_meminfo->free_base  = BL30_BASE;
+	bl30_meminfo->free_size  = BL30_SIZE;
+}
+
+/*******************************************************************************
+ * Transfer BL3-0 from Trusted RAM using the SCP Download protocol.
+ * Return 0 on success, -1 otherwise.
+ ******************************************************************************/
+int bl2_plat_handle_bl30(image_info_t *bl30_image_info)
+{
+	int *buf = (int *)bl30_image_info->image_base;
+
+	INFO("%s: [%x] %x %x %x %x\n",
+	     __func__, buf, buf[0], buf[1], buf[2], buf[3]);
+
+	buf += 50;
+	INFO("%s: [%x] %x %x %x %x\n",
+	     __func__, buf, buf[0], buf[1], buf[2], buf[3]);
+
+	buf += 50;
+	INFO("%s: [%x] %x %x %x %x\n",
+	     __func__, buf, buf[0], buf[1], buf[2], buf[3]);
+
+	buf  = (int *)(bl30_image_info->image_base +
+		       bl30_image_info->image_size);
+	buf -= 4;
+	INFO("%s: [%x] %x %x %x %x\n",
+	     __func__, buf, buf[0], buf[1], buf[2], buf[3]);
+
+	/* enable mcu sram */
+	hisi_mcu_enable_sram();
+
+	/* load mcu binary to sram */
+	hisi_mcu_load_image(bl30_image_info->image_base,
+			    bl30_image_info->image_size);
+
+	/* let mcu to run */
+	hisi_mcu_start_run();
+
+	INFO("%s: mcu pc is %x\n",
+		__func__, mmio_read_32(AO_SC_MCU_SUBSYS_STAT2));
+
+	INFO("%s: AO_SC_PERIPH_CLKSTAT4	is %x\n",
+		__func__, mmio_read_32(AO_SC_PERIPH_CLKSTAT4));
+	return 0;
+}
+
+/*******************************************************************************
+ * Before calling this function BL31 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL31 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
+			       entry_point_info_t *bl31_ep_info)
+{
+	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
+	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+				       DISABLE_ALL_EXCEPTIONS);
+}
+
+/*******************************************************************************
+ * Before calling this function BL32 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL32 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
+			       entry_point_info_t *bl32_ep_info)
+{
+	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
+	/*
+	* The Secure Payload Dispatcher service is responsible for
+	* setting the SPSR prior to entry into the BL32 image.
+	*/
+	bl32_ep_info->spsr = 0;
+}
+
+/*******************************************************************************
+ * Before calling this function BL33 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL33 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl33_ep_info(image_info_t *image,
+				       entry_point_info_t *bl33_ep_info)
+{
+	unsigned long el_status;
+	unsigned int mode;
+
+	/* Figure out what mode we enter the non-secure world in */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	if (el_status)
+		mode = MODE_EL2;
+	else
+		mode = MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
+				       DISABLE_ALL_EXCEPTIONS);
+	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+}
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL3-2
+ ******************************************************************************/
+void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
+{
+	/*
+	 * Populate the extents of memory available for loading BL3-2.
+	 */
+	bl32_meminfo->total_base = BL32_BASE;
+	bl32_meminfo->free_base = BL32_BASE;
+	bl32_meminfo->total_size =
+		       (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+	bl32_meminfo->free_size =
+		       (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+}
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL3-3
+ ******************************************************************************/
+void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
+{
+	bl33_meminfo->total_base = DRAM_NS_BASE;
+	bl33_meminfo->total_size = DRAM_NS_SIZE;
+	bl33_meminfo->free_base = DRAM_NS_BASE;
+	bl33_meminfo->free_size = DRAM_NS_SIZE;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/bl31_plat_setup.c b/uefi/arm-trusted-firmware/plat/hikey/bl31_plat_setup.c
new file mode 100644
index 0000000..305835c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/bl31_plat_setup.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <arm_gic.h>
+#include <assert.h>
+#include <bl31.h>
+#include <bl_common.h>
+#include <cci400.h>
+#include <console.h>
+#include <debug.h>
+#include <hisi_ipc.h>
+#include <hisi_pwrc.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stddef.h>
+#include <hi6220_regs_ao.h>
+#include <hi6220.h>
+
+#include "hikey_def.h"
+#include "hikey_private.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __RO_END__;
+
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL31_RO_BASE (unsigned long)(&__RO_START__)
+#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols
+ * refer to page-aligned addresses.
+ */
+#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/******************************************************************************
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL3-1 from BL2.
+ ******************************************************************************/
+static entry_point_info_t bl32_ep_info;
+static entry_point_info_t bl33_ep_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL3-3 corresponds to the non-secure image type
+ * while BL3-2 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	entry_point_info_t *next_image_info;
+
+	next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
+
+	/* None of the images on this platform can have 0x0 as the entrypoint */
+	if (next_image_info->pc)
+		return next_image_info;
+	else
+		return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL3-1 specific platform actions. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
+ * are lost (potentially). This needs to be done before the MMU is initialized
+ * so that the memory layout can be used while creating page tables. Also, BL2
+ * has flushed this information to memory, so we are guaranteed to pick up good
+ * data
+ ******************************************************************************/
+void bl31_early_platform_setup(bl31_params_t *from_bl2,
+			       void *plat_params_from_bl2)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/*
+	 * Initialise the CCI-400 driver for BL31 so that it is accessible after
+	 * a warm boot. BL1 should have already enabled CCI coherency for this
+	 * cluster during cold boot.
+	 */
+	cci_init(CCI400_BASE,
+		 CCI400_SL_IFACE3_CLUSTER_IX,
+		 CCI400_SL_IFACE4_CLUSTER_IX);
+
+	/*
+	 * Copy BL3-2 and BL3-3 entry point information.
+	 * They are stored in Secure RAM, in BL2's address space.
+	 */
+	bl32_ep_info = *from_bl2->bl32_ep_info;
+	bl33_ep_info = *from_bl2->bl33_ep_info;
+}
+
+static void init_rtc(void)
+{
+	uint32_t data;
+
+	data = mmio_read_32(AO_SC_PERIPH_CLKEN4);
+	data |= AO_SC_PERIPH_RSTDIS4_RESET_RTC0_N;
+	mmio_write_32(AO_SC_PERIPH_CLKEN4, data);
+}
+
+static void init_edma(void)
+{
+	int i;
+
+	mmio_write_32(EDMAC_SEC_CTRL, 0x3);
+
+	for (i = 0; i <= 15; i++) {
+		VERBOSE("EDMAC_AXI_CONF(%d): data:0x%x\n", i, mmio_read_32(EDMAC_AXI_CONF(i)));
+		mmio_write_32(EDMAC_AXI_CONF(i), (1 << 6) | (1 << 18));
+		VERBOSE("EDMAC_AXI_CONF(%d): data:0x%x\n", i, mmio_read_32(EDMAC_AXI_CONF(i)));
+	}
+}
+
+/*******************************************************************************
+ * Initialize the GIC.
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+	/* Initialize the gic cpu and distributor interfaces */
+	plat_gic_init();
+	arm_gic_setup();
+
+	init_rtc();
+	init_edma();
+	hisi_ipc_init();
+	hisi_pwrc_setup();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup()
+{
+	configure_mmu_el3(BL31_RO_BASE,
+			  BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE,
+			  BL31_RO_BASE,
+			  BL31_RO_LIMIT,
+			  BL31_COHERENT_RAM_BASE,
+			  BL31_COHERENT_RAM_LIMIT);
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/drivers/dw_mmc.c b/uefi/arm-trusted-firmware/plat/hikey/drivers/dw_mmc.c
new file mode 100644
index 0000000..5eecd0c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/drivers/dw_mmc.c
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd. 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 <console.h>
+#include <debug.h>
+#include <errno.h>
+#include <mmio.h>
+#include <string.h>
+#include <sp804_timer.h>
+#include <dw_mmc.h>
+#include <partitions.h>
+#include <platform_def.h>
+#include <hi6220.h>
+#include <hi6553.h>
+
+#define MMC_PLL			100000000
+
+#define IDMAC_DES0_DIC		(1 << 1)
+#define IDMAC_DES0_LD		(1 << 2)
+#define IDMAC_DES0_FS		(1 << 3)
+#define IDMAC_DES0_CH		(1 << 4)
+#define IDMAC_DES0_ER		(1 << 5)
+#define IDMAC_DES0_CES		(1 << 30)
+#define IDMAC_DES0_OWN		(1 << 31)
+
+#define IDMAC_DES1_BS1(x)	((x) & 0x1fff)
+#define IDMAC_DES2_BS2(x)	(((x) & 0x1fff) << 13)
+
+struct idmac_desc {
+	unsigned int		des0;
+	unsigned int		des1;
+	unsigned int		des2;
+	unsigned int		des3;
+};
+
+static inline int mmc_state(unsigned int data)
+{
+	return ((data & MMC_STATUS_CURRENT_STATE_MASK) >>
+		MMC_STATUS_CURRENT_STATE_SHIFT);
+}
+
+static inline int wait_data_ready(void)
+{
+	unsigned int data;
+
+	while (1) {
+		data = mmio_read_32(MMC0_RINTSTS);
+		if (data & (MMC_INT_DCRC | MMC_INT_DRT | MMC_INT_SBE |
+		    MMC_INT_EBE)) {
+			NOTICE("unwanted interrupts:0x%x\n", data);
+			return -EINVAL;
+		}
+		if (data & MMC_INT_DTO)
+			break;
+	}
+	/* clear interrupts */
+	mmio_write_32(MMC0_RINTSTS, ~0);
+	return 0;
+}
+
+static int update_mmc0_clock(void)
+{
+	unsigned int data;
+
+	/* CMD_UPDATE_CLK */
+	data = BIT_CMD_WAIT_PRVDATA_COMPLETE | BIT_CMD_UPDATE_CLOCK_ONLY |
+		BIT_CMD_START;
+	mmio_write_32(MMC0_CMD, data);
+	while (1) {
+		data = mmio_read_32(MMC0_CMD);
+		if (!(data & CMD_START_BIT))
+			break;
+		data = mmio_read_32(MMC0_RINTSTS);
+		if (data & MMC_INT_HLE) {
+			NOTICE("fail to update mmc clock frequency\n");
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int set_mmc0_clock(int rate)
+{
+	int ret, divider, found = 0;
+	unsigned int data;
+
+	for (divider = 1; divider < 256; divider++) {
+		if ((MMC_PLL / (2 * divider)) <= rate) {
+			found = 1;
+			break;
+		}
+	}
+	if (!found)
+		return -EINVAL;
+
+	/* wait until mmc is idle */
+	do {
+		data = mmio_read_32(MMC0_STATUS);
+	} while (data & MMC_STS_DATA_BUSY);
+
+	/* Disable mmc clock first */
+	mmio_write_32(MMC0_CLKENA, 0);
+	do {
+		ret = update_mmc0_clock();
+	} while (ret);
+
+	/* enable mmc clock */
+	do {
+		mmio_write_32(MMC0_CLKENA, 1);
+		mmio_write_32(MMC0_CLKSRC, 0);
+		mmio_write_32(MMC0_CLKDIV, divider);
+		ret = update_mmc0_clock();
+	} while (ret);
+	return 0;
+}
+
+static void set_mmc0_io(void)
+{
+	mmio_write_32(MMC0_CTYPE, MMC_8BIT_MODE);
+	mmio_write_32(MMC0_TMOUT, ~0);	/* maxium timeout value */
+	mmio_write_32(MMC0_DEBNCE, 0x00ffffff);
+	mmio_write_32(MMC0_BLKSIZ, MMC_BLOCK_SIZE);
+	mmio_write_32(MMC0_BYTCNT, 256 * 1024);
+}
+
+static int mmc0_send_cmd(unsigned int cmd, unsigned int arg, unsigned int *buf)
+{
+	unsigned int data, err_mask;
+
+	if (!buf) {
+		NOTICE("buf is invalid\n");
+		return -EFAULT;
+	}
+
+	mmio_write_32(MMC0_CMDARG, arg);
+
+	/* clear interrupts */
+	mmio_write_32(MMC0_RINTSTS, ~0);
+
+	switch (cmd) {
+	case 0:
+		data = BIT_CMD_SEND_INIT;
+		break;
+	case 1:
+		data = BIT_CMD_RESPONSE_EXPECT;
+		break;
+	case 2:
+		data = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_LONG_RESPONSE |
+			BIT_CMD_CHECK_RESPONSE_CRC | BIT_CMD_SEND_INIT;
+		break;
+	case 3:
+		data = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+			BIT_CMD_SEND_INIT;
+		break;
+	case 8:
+		data = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+			BIT_CMD_DATA_EXPECTED | BIT_CMD_READ |
+			BIT_CMD_WAIT_PRVDATA_COMPLETE;
+		break;
+	case 9:
+		data = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+			BIT_CMD_LONG_RESPONSE;
+		break;
+	case 12:
+		data = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+			BIT_CMD_STOP_ABORT_CMD;
+		break;
+	case 17:
+	case 18:
+		data = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+			BIT_CMD_DATA_EXPECTED | BIT_CMD_READ |
+			BIT_CMD_WAIT_PRVDATA_COMPLETE;
+		break;
+	case 24:
+	case 25:
+		data = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+			BIT_CMD_DATA_EXPECTED | BIT_CMD_WRITE |
+			BIT_CMD_WAIT_PRVDATA_COMPLETE;
+		break;
+	case 30:
+		data = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+			BIT_CMD_DATA_EXPECTED;
+		break;
+	case 7:
+		if (arg)
+			data = BIT_CMD_RESPONSE_EXPECT |
+				BIT_CMD_CHECK_RESPONSE_CRC;
+		else
+			data = 0;
+		break;
+	default:
+		data = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
+		break;
+	}
+	data |= (cmd & 0x3f) | BIT_CMD_USE_HOLD_REG | BIT_CMD_START;
+	mmio_write_32(MMC0_CMD, data);
+	err_mask = MMC_INT_EBE | MMC_INT_HLE | MMC_INT_RTO | MMC_INT_RCRC |
+		   MMC_INT_RE;
+	do {
+		data = mmio_read_32(MMC0_RINTSTS);
+		if (data & err_mask) {
+			NOTICE("mmc: error status 0x%x\n", data);
+			return -EIO;
+		}
+	} while (!(data & MMC_INT_CMD_DONE));
+
+	buf[0] = mmio_read_32(MMC0_RESP0);
+	if ((cmd == 2) || (cmd == 9)) {
+		buf[1] = mmio_read_32(MMC0_RESP1);
+		buf[2] = mmio_read_32(MMC0_RESP2);
+		buf[3] = mmio_read_32(MMC0_RESP3);
+	}
+	return 0;
+}
+
+/* Only print error message if it meets failure? */
+static void mmc0_check_tran_mode(void)
+{
+	unsigned int buf[4];
+	int ret;
+
+	mmio_write_32(MMC0_RINTSTS, ~0);
+
+	while (1) {
+		ret = mmc0_send_cmd(13, EMMC_FIX_RCA << 16, buf);
+		if (ret) {
+			NOTICE("failed on command 13\n");
+			return;
+		}
+		if (((buf[0] >> 9) & 0xf) == 4)
+			return;
+	}
+}
+
+static int mmc0_update_ext_csd(int index, int value)
+{
+	unsigned int arg, data, buf[4];
+	int ret;
+
+	arg = 3 << 24;
+	arg |= (index & 0xff) << 16;
+	arg |= (value & 0xff) << 8;
+	arg |= 1;
+	memset(buf, 0, 4 * sizeof(buf[0]));
+
+	ret = mmc0_send_cmd(6, arg, buf);
+	if (ret) {
+		NOTICE("failed to send command 6\n");
+		return ret;
+	}
+
+	/* wait busy de-assert */
+	while (1) {
+		data = mmio_read_32(MMC0_STATUS);
+		if (!(data & MMC_STS_DATA_BUSY))
+			break;
+	}
+
+	do {
+		ret = mmc0_send_cmd(13, EMMC_FIX_RCA << 16, buf);
+		if (ret) {
+			NOTICE("failed to send command 13\n");
+			return ret;
+		}
+
+		if (buf[0] & MMC_STATUS_SWITCH_ERROR) {
+			NOTICE("maybe switch mmc mode error\n");
+			return -1;
+		}
+	} while (mmc_state(buf[0]) == MMC_STATE_PRG);
+
+	return 0;
+}
+
+#define EXTCSD_BUS_WIDTH		183
+
+static int mmc0_set_clock_and_width(int rate, int width)
+{
+	int ret;
+
+	switch (width) {
+	case 0:
+		mmio_write_32(MMC0_CTYPE, 0);
+		ret = mmc0_update_ext_csd(EXTCSD_BUS_WIDTH, 0);
+		break;
+	case 8:
+		mmio_write_32(MMC0_CTYPE, 1 << 16);
+		ret = mmc0_update_ext_csd(EXTCSD_BUS_WIDTH, 2 + 4);
+		mmio_write_32(MMC0_UHSREG, 1 << 16);
+		break;
+	default:
+		NOTICE("wrong bus width:%d\n", width);
+		return -EINVAL;
+	}
+	if (ret) {
+		NOTICE("return failure on %s, %d\n", __func__, __LINE__);
+		return ret;
+	}
+
+	set_mmc0_clock(rate);
+	return 0;
+}
+
+static int manu_id;
+
+#define EXTCSD_HS_TIMING		185
+
+#ifdef EMMC_READ_EXT_CSD
+static int mmc0_read_ext_csd(unsigned int dst_start);
+#endif
+static int enum_mmc0_card(void)
+{
+	unsigned int buf[4], cid[4];
+	int ret = 0, i, version;
+
+	/* CMD0: reset to IDLE */
+	ret = mmc0_send_cmd(0, 0, buf);
+	if (ret) {
+		NOTICE("failed to send IDLE command\n");
+		return ret;
+	}
+
+	while (1) {
+		udelay(100);
+		/* CMD1: READY */
+		ret = mmc0_send_cmd(1, 0x40ff8000, buf);
+		if (ret) {
+			NOTICE("failed to send READY command\n");
+			return ret;
+		}
+		if (buf[0] & 0x80000000)
+			break;
+	}
+
+	/* CMD2: IDENT */
+	ret = mmc0_send_cmd(2, 0, buf);
+	if (ret) {
+		NOTICE("failed to send IDENT command\n");
+		return ret;
+	}
+	VERBOSE("manuid:");
+	for (i = 0; i < 4; i++) {
+		cid[i] = buf[i];
+		VERBOSE(" 0x%x", cid[i]);
+	}
+	VERBOSE("\n");
+
+	/* CMD3: STBY */
+	ret = mmc0_send_cmd(3, EMMC_FIX_RCA << 16, buf);
+	if (ret) {
+		NOTICE("failed to send STBY command\n");
+		return ret;
+	}
+
+	/* CMD9: get CSD */
+	ret = mmc0_send_cmd(9, EMMC_FIX_RCA << 16, buf);
+	if (ret) {
+		NOTICE("failed to get CSD\n");
+		return ret;
+	}
+	VERBOSE("CSD: %x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]);
+	version = (buf[3] >> 26) & 0xf;
+	switch (version) {
+	case 0:	/* MMC v1.0-v1.2 */
+	case 1:	/* MMC v1.4 */
+		manu_id = (cid[3] >> 8) & 0xffffff;
+		break;
+	case 2:	/* MMC v2.0-v2.2 */
+	case 3:	/* MMC v3.1-v3.3 */
+	case 4:	/* MMC v4 */
+		manu_id = (cid[3] >> 24) & 0xff;
+		break;
+	default:
+		WARN("wrong mmc version (%d) is specified.\n", version);
+		break;
+	}
+
+	VERBOSE("mmc version:%d\n", version);
+	/* CMD7: TRAN */
+	ret = mmc0_send_cmd(7, EMMC_FIX_RCA << 16, buf);
+	if (ret) {
+		NOTICE("failed to send TRAN command\n");
+		return ret;
+	}
+	mmc0_check_tran_mode();
+
+	mmc0_set_clock_and_width(400000, 0);
+#ifdef EMMC_READ_EXT_CSD
+	mmc0_read_ext_csd(0x50000);
+#endif
+	ret = mmc0_update_ext_csd(EXTCSD_HS_TIMING, 1);
+	if (ret) {
+		NOTICE("alter HS mode fail\n");
+	}
+
+	ret = mmc0_set_clock_and_width(50000000, 8);
+	return ret;
+}
+
+static int enable_mmc0(void)
+{
+	unsigned int data;
+
+	/* reset mmc0 */
+	data = MMC_CTRL_RESET | MMC_FIFO_RESET | MMC_DMA_RESET;
+	mmio_write_32(MMC0_CTRL, data);
+	/* wait until reset operation finished */
+	do {
+		data = mmio_read_32(MMC0_CTRL);
+	} while (data);
+
+	data = MMC_INT_EN | MMC_DMA_EN;
+	mmio_write_32(MMC0_CTRL, data);
+
+	mmio_write_32(MMC0_INTMASK, 0x0);
+	mmio_write_32(MMC0_RINTSTS, ~0);
+	mmio_write_32(MMC0_IDINTEN, ~0);
+	mmio_write_32(MMC0_IDSTS, ~0);
+
+	mmio_write_32(MMC0_BLKSIZ, MMC_BLOCK_SIZE);
+	mmio_write_32(MMC0_BMOD, MMC_IDMAC_SWRESET);
+	do {
+		data = mmio_read_32(MMC0_BMOD);
+	} while (data & MMC_IDMAC_SWRESET);
+
+	data |= MMC_IDMAC_ENABLE | MMC_IDMAC_FB;
+	mmio_write_32(MMC0_BMOD, data);
+
+	data = MMC_DMA_BURST_SIZE(2) | MMC_FIFO_TWMARK(8) | MMC_FIFO_RWMARK(7);
+	mmio_write_32(MMC0_FIFOTH, data);
+	data = MMC_CARD_RD_THR(512) | MMC_CARD_RD_THR_EN;
+	mmio_write_32(MMC0_CARDTHRCTL, data);
+
+	udelay(100);
+	set_mmc0_clock(378000);
+	udelay(100);
+
+	set_mmc0_io();
+	return 0;
+}
+
+#define MMC_BLOCK_SIZE			512
+#define MMC_DMA_MAX_BUFFER_SIZE		(512 * 8)
+
+#ifdef EMMC_READ_EXT_CSD
+static int mmc0_read_ext_csd(unsigned int dst_start)
+{
+	unsigned int blk_cnt, bytes, desc_num, buf[4], data;
+	struct idmac_desc *desc = NULL;
+	int i, ret, last_idx;
+	uintptr_t src_addr, dst_addr = dst_start;
+
+	blk_cnt = 1;
+	bytes = blk_cnt * MMC_BLOCK_SIZE;
+	memset((void *)MMC_DATA_BASE, 0, bytes);
+
+	mmio_write_32(MMC0_BYTCNT, bytes);
+
+	mmio_write_32(MMC0_RINTSTS, ~0);
+
+	desc_num = (bytes + MMC_DMA_MAX_BUFFER_SIZE - 1) /
+		   MMC_DMA_MAX_BUFFER_SIZE;
+
+	desc = (struct idmac_desc *)MMC_DESC_BASE;
+
+	for (i = 0; i < desc_num; i++) {
+		(desc + i)->des0 = IDMAC_DES0_OWN | IDMAC_DES0_CH |
+				   IDMAC_DES0_DIC;
+		(desc + i)->des1 = IDMAC_DES1_BS1(MMC_DMA_MAX_BUFFER_SIZE);
+		/* buffer address */
+		(desc + i)->des2 = MMC_DATA_BASE + MMC_DMA_MAX_BUFFER_SIZE * i;
+		/* next descriptor address */
+		(desc + i)->des3 = MMC_DESC_BASE +
+				   (sizeof(struct idmac_desc) * (i + 1));
+	}
+	/* first descriptor */
+	desc->des0 |= IDMAC_DES0_FS;
+	/* last descriptor */
+	last_idx = desc_num - 1;
+	(desc + last_idx)->des0 |= IDMAC_DES0_LD;
+	(desc + last_idx)->des0 &= ~(IDMAC_DES0_DIC | IDMAC_DES0_CH);
+	(desc + last_idx)->des1 = IDMAC_DES1_BS1(bytes - (last_idx *
+				  MMC_DMA_MAX_BUFFER_SIZE));
+	/* set next descriptor address as 0 */
+	(desc + last_idx)->des3 = 0;
+
+	mmio_write_32(MMC0_DBADDR, MMC_DESC_BASE);
+
+	/* read extended CSD */
+	ret = mmc0_send_cmd(8, EMMC_FIX_RCA << 16, buf);
+	if (ret) {
+		NOTICE("failed to send CMD8\n");
+		mmio_write_32(MMC0_RINTSTS, ~0);
+		return -EFAULT;
+	}
+
+	ret = wait_data_ready();
+	if (ret)
+		return ret;
+
+	if (blk_cnt > 1) {
+		ret = mmc0_send_cmd(12, EMMC_FIX_RCA << 16, buf);
+		if (ret) {
+			NOTICE("failed to send Stop Transmission command\n");
+			return ret;
+		}
+		mmio_write_32(MMC0_RINTSTS, ~0);
+	}
+	src_addr = MMC_DATA_BASE;
+	memcpy((void *)dst_addr, (void *)src_addr, MMC_BLOCK_SIZE);
+
+	return 0;
+}
+#endif
+
+int mmc0_read(unsigned long src_start, size_t src_size,
+		unsigned long dst_start, uint32_t boot_partition)
+{
+	unsigned int src_blk_start = src_start / MMC_BLOCK_SIZE;
+	unsigned int src_blk_cnt, offset, bytes, desc_num, buf[4];
+	struct idmac_desc *desc = NULL;
+	int i, ret, last_idx;
+	uintptr_t src_addr, dst_addr = dst_start;
+
+	if (boot_partition) {
+		/* switch to boot partition 1 */
+		ret = mmc0_update_ext_csd(EXT_CSD_PARTITION_CONFIG,
+					  PART_CFG_BOOT_PARTITION1_ENABLE |
+					  PART_CFG_PARTITION1_ACCESS);
+		if (ret) {
+			NOTICE("fail to switch eMMC boot partition\n");
+			return ret;
+		}
+	}
+	offset = src_start % MMC_BLOCK_SIZE;
+	src_blk_cnt = (src_size + offset + MMC_BLOCK_SIZE - 1) / MMC_BLOCK_SIZE;
+	bytes = src_blk_cnt * MMC_BLOCK_SIZE;
+
+	mmio_write_32(MMC0_BYTCNT, bytes);
+
+	mmio_write_32(MMC0_RINTSTS, ~0);
+
+	desc_num = (bytes + MMC_DMA_MAX_BUFFER_SIZE - 1) /
+		   MMC_DMA_MAX_BUFFER_SIZE;
+
+	desc = (struct idmac_desc *)MMC_DESC_BASE;
+
+	for (i = 0; i < desc_num; i++) {
+		(desc + i)->des0 = IDMAC_DES0_OWN | IDMAC_DES0_CH |
+				   IDMAC_DES0_DIC;
+		(desc + i)->des1 = IDMAC_DES1_BS1(MMC_DMA_MAX_BUFFER_SIZE);
+		/* buffer address */
+		(desc + i)->des2 = MMC_DATA_BASE + MMC_DMA_MAX_BUFFER_SIZE * i;
+		/* next descriptor address */
+		(desc + i)->des3 = MMC_DESC_BASE +
+				   (sizeof(struct idmac_desc) * (i + 1));
+	}
+	/* first descriptor */
+	desc->des0 |= IDMAC_DES0_FS;
+	/* last descriptor */
+	last_idx = desc_num - 1;
+	(desc + last_idx)->des0 |= IDMAC_DES0_LD;
+	(desc + last_idx)->des0 &= ~(IDMAC_DES0_DIC | IDMAC_DES0_CH);
+	(desc + last_idx)->des1 = IDMAC_DES1_BS1(bytes - (last_idx *
+				  MMC_DMA_MAX_BUFFER_SIZE));
+	/* set next descriptor address as 0 */
+	(desc + last_idx)->des3 = 0;
+
+	mmio_write_32(MMC0_DBADDR, MMC_DESC_BASE);
+
+	ret = mmc0_send_cmd(23, src_blk_cnt & 0xffff, buf);
+	if (ret) {
+		NOTICE("failed to send CMD23\n");
+		mmio_write_32(MMC0_RINTSTS, ~0);
+		return -EFAULT;
+	}
+	/* multiple read */
+	ret = mmc0_send_cmd(18, src_blk_start, buf);
+	if (ret) {
+		NOTICE("failed to send CMD18\n");
+		mmio_write_32(MMC0_RINTSTS, ~0);
+		return -EFAULT;
+	}
+
+	ret = wait_data_ready();
+	if (ret)
+		return ret;
+
+	src_addr = MMC_DATA_BASE + offset;
+	memcpy((void *)dst_addr, (void *)src_addr, src_size);
+
+	if (boot_partition) {
+		/* switch back to normal partition */
+		ret = mmc0_update_ext_csd(EXT_CSD_PARTITION_CONFIG,
+					  PART_CFG_BOOT_PARTITION1_ENABLE);
+		if (ret)
+			NOTICE("fail to switch eMMC normal partition\n");
+	}
+	return ret;
+}
+
+static int write_multi_blocks(unsigned int lba, unsigned int count,
+			      unsigned int buffer, unsigned int boot_partition)
+{
+	unsigned int bytes, resp_buf[4], desc_num;
+	struct idmac_desc *desc = NULL;
+	int ret, last_idx, i;
+
+	if (buffer % 4) {
+		NOTICE("invalid buffer address:0x%x\n", buffer);
+		return -EINVAL;
+	}
+	if (boot_partition) {
+		/* switch to boot partition 1 */
+		ret = mmc0_update_ext_csd(EXT_CSD_PARTITION_CONFIG,
+					  PART_CFG_BOOT_PARTITION1_ENABLE |
+					  PART_CFG_PARTITION1_ACCESS);
+		if (ret) {
+			NOTICE("fail to switch eMMC boot partition\n");
+			return ret;
+		}
+	}
+	bytes = MMC_BLOCK_SIZE * count;
+
+	mmio_write_32(MMC0_BYTCNT, bytes);
+	mmio_write_32(MMC0_RINTSTS, ~0);
+
+	desc_num = (bytes + MMC_DMA_MAX_BUFFER_SIZE - 1) /
+		   MMC_DMA_MAX_BUFFER_SIZE;
+
+	desc = (struct idmac_desc *)MMC_DESC_BASE;
+
+	for (i = 0; i < desc_num; i++) {
+		(desc + i)->des0 = IDMAC_DES0_OWN | IDMAC_DES0_CH |
+				   IDMAC_DES0_DIC;
+		(desc + i)->des1 = IDMAC_DES1_BS1(MMC_DMA_MAX_BUFFER_SIZE);
+		/* buffer address */
+		(desc + i)->des2 = buffer + MMC_DMA_MAX_BUFFER_SIZE * i;
+		/* next descriptor address */
+		(desc + i)->des3 = MMC_DESC_BASE +
+				   (sizeof(struct idmac_desc) * (i + 1));
+	}
+	/* first descriptor */
+	desc->des0 |= IDMAC_DES0_FS;
+	/* last descriptor */
+	last_idx = desc_num - 1;
+	(desc + last_idx)->des0 |= IDMAC_DES0_LD;
+	(desc + last_idx)->des0 &= ~(IDMAC_DES0_DIC | IDMAC_DES0_CH);
+	(desc + last_idx)->des1 = IDMAC_DES1_BS1(bytes - (last_idx *
+				  MMC_DMA_MAX_BUFFER_SIZE));
+	/* set next descriptor address as 0 */
+	(desc + last_idx)->des3 = 0;
+
+	mmio_write_32(MMC0_DBADDR, MMC_DESC_BASE);
+
+	ret = mmc0_send_cmd(25, lba, resp_buf);
+	if (ret) {
+		NOTICE("failed to send CMD25\n");
+		mmio_write_32(MMC0_RINTSTS, ~0);
+		return -EFAULT;
+	}
+	ret = wait_data_ready();
+	if (ret)
+		return ret;
+
+	ret = mmc0_send_cmd(12, EMMC_FIX_RCA << 16, resp_buf);
+	if (ret) {
+		NOTICE("failed to send CMD12\n");
+		mmio_write_32(MMC0_RINTSTS, ~0);
+		return -EFAULT;
+	}
+
+	do {
+		ret = mmc0_send_cmd(13, EMMC_FIX_RCA << 16, resp_buf);
+		if (ret) {
+			NOTICE("failed to send command 13\n");
+			return ret;
+		}
+	} while (!(resp_buf[0] & MMC_STATUS_READY_FOR_DATA) ||
+		 (mmc_state(resp_buf[0] != MMC_STATE_TRAN)));
+
+	if (boot_partition) {
+		/* switch back to normal partition */
+		ret = mmc0_update_ext_csd(EXT_CSD_PARTITION_CONFIG,
+					  PART_CFG_BOOT_PARTITION1_ENABLE);
+		if (ret)
+			NOTICE("fail to switch eMMC normal partition\n");
+	}
+	return ret;
+}
+
+int mmc0_write(unsigned long mmc_start, size_t size,
+		unsigned long buffer, uint32_t boot_partition)
+{
+	unsigned int mmc_blk_start = mmc_start / MMC_BLOCK_SIZE;
+	unsigned int mmc_blk_cnt, offset;
+
+	offset = mmc_start % MMC_BLOCK_SIZE;
+	mmc_blk_cnt = (size + offset + MMC_BLOCK_SIZE - 1) / MMC_BLOCK_SIZE;
+
+	return write_multi_blocks(mmc_blk_start, mmc_blk_cnt, buffer,
+				  boot_partition);
+}
+
+int init_mmc(void)
+{
+	int ret;
+
+	enable_mmc0();
+
+	ret = enum_mmc0_card();
+	if (ret)
+		return ret;
+
+	/* set boot mode to 8-bit */
+	mmc0_update_ext_csd(177, 2);
+	/* response to RESET signal */
+	mmc0_update_ext_csd(162, 1);
+	/* set access userdata area */
+	mmc0_update_ext_csd(EXT_CSD_PARTITION_CONFIG,
+			    PART_CFG_BOOT_PARTITION1_ENABLE);
+
+	mmio_write_32(MMC0_RINTSTS, ~0);
+
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/drivers/hi6553.c b/uefi/arm-trusted-firmware/plat/hikey/drivers/hi6553.c
new file mode 100644
index 0000000..521c59a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/drivers/hi6553.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <assert.h>
+#include <mmio.h>
+#include <hi6553.h>
+#include <hi6220.h>
+
+unsigned char hi6553_read_8(unsigned int offset)
+{
+	return mmio_read_8(PMUSSI_BASE + (offset << 2));
+}
+
+void hi6553_write_8(unsigned int offset, unsigned int value)
+{
+	mmio_write_8(PMUSSI_BASE + (offset << 2), value);
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_dvfs.c b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_dvfs.c
new file mode 100644
index 0000000..3fb4a8e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_dvfs.c
@@ -0,0 +1,808 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <partitions.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include <mmio.h>
+#include <hi6220.h>
+#include <hi6553.h>
+
+#define ACPU_FREQ_MAX_NUM  		5
+#define	ACPU_OPP_NUM			7
+
+#define ACPU_VALID_VOLTAGE_MAGIC	(0x5A5AC5C5)
+
+#define ACPU_WAIT_TIMEOUT		(200)
+#define ACPU_WAIT_FOR_WFI_TIMOUT	(2000)
+#define ACPU_DFS_STATE_CNT		(0x10000)
+
+struct acpu_dvfs_sram_stru {
+	unsigned int magic;
+	unsigned int support_freq_num;
+	unsigned int support_freq_max;
+	unsigned int start_prof;
+	unsigned int vol[ACPU_OPP_NUM];
+};
+
+struct acpu_volt_cal_para {
+	unsigned int freq;
+	unsigned int ul_vol;
+	unsigned int dl_vol;
+	unsigned int core_ref_hpm;
+};
+
+struct ddr_volt_cal_para {
+	unsigned int freq;
+	unsigned int ul_vol;
+	unsigned int dl_vol;
+	unsigned int ddr_ref_hpm;
+};
+
+struct acpu_dvfs_opp_para {
+	unsigned int freq;
+	unsigned int acpu_clk_profile0;
+	unsigned int acpu_clk_profile1;
+	unsigned int acpu_vol_profile;
+	unsigned int acpu_pll_freq;
+	unsigned int acpu_pll_frac;
+};
+
+unsigned int efuse_acpu_freq[]= {
+	1200000, 1250000, 1300000, 1350000,
+	1400000, 1450000, 1500000, 1550000,
+	1600000, 1650000, 1700000, 1750000,
+	1800000, 1850000, 1900000, 1950000,
+};
+
+struct acpu_dvfs_opp_para hi6220_acpu_profile[] = {
+	{ 208000,  0x61E5, 0x022, 0x3A, 0x5220102B, 0x05555555 },
+	{ 432000,  0x10A6, 0x121, 0x3A, 0x5120102D, 0x10000005 },
+	{ 729000,  0x2283, 0x100, 0x4A, 0x51101026, 0x10000005 },
+	{ 960000,  0x1211, 0x100, 0x5B, 0x51101032, 0x10000005 },
+	{ 1200000, 0x1211, 0x100, 0x6B, 0x5110207D, 0x10000005 },
+	{ 1400000, 0x1211, 0x100, 0x6B, 0x51101049, 0x10000005 },
+	{ 1500000, 0x1211, 0x100, 0x6B, 0x51101049, 0x10000005 },
+};
+
+struct acpu_dvfs_opp_para *acpu_dvfs_profile = hi6220_acpu_profile;
+struct acpu_dvfs_sram_stru *acpu_dvfs_sram_buf =
+	(struct acpu_dvfs_sram_stru *)MEMORY_AXI_ACPU_FREQ_VOL_ADDR;
+
+static inline void write_reg_mask(uintptr_t addr,
+				  uint32_t val, uint32_t mask)
+{
+	uint32_t reg;
+
+	reg = mmio_read_32(addr);
+	reg = (reg & ~(mask)) | val;
+	mmio_write_32(addr, reg);
+}
+
+static inline uint32_t read_reg_mask(uintptr_t addr,
+				     uint32_t mask, uint32_t offset)
+{
+	uint32_t reg;
+
+	reg = mmio_read_32(addr);
+	reg &= (mask << offset);
+	return (reg >> offset);
+}
+
+static int acpu_dvfs_syspll_cfg(unsigned int prof_id)
+{
+	uint32_t reg0 = 0;
+	uint32_t count = 0;
+	uint32_t clk_div_status = 0;
+
+	/*
+	 * step 1:
+	 *  - ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x3;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x1;
+	 */
+	write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x3 << 12, 0x3 << 12);
+	write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x1 << 4,  0x1 << 4);
+
+	/*
+	 * step 2:
+	 *  - ACPUSYSPLLCFG.acpu_syspll_div_cfg:
+	 *     208MHz, set to 0x5;
+	 *     500MHz, set to 0x2;
+	 *     other opps set to 0x1
+	 */
+	if (prof_id == 0)
+		write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x5 << 0, 0x7 << 0);
+	else if (prof_id == 1)
+		write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x2 << 0, 0x7 << 0);
+	else
+		write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x1 << 0, 0x7 << 0);
+
+	/*
+	 * step 3:
+	 *  - Polling ACPU_SC_CPU_STAT.clk_div_status_vd == 0x3;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0
+	 *  - PMCTRL_ACPUCLKDIV.acpu_ddr_clk_div_cfg = 0x1
+	 *  - PMCTRL_ACPUPLLSEL.acpu_pllsw_cfg = 0x1
+	 */
+	clk_div_status = 0x3;
+	do {
+		reg0 = read_reg_mask(ACPU_SC_CPU_STAT, 0x3, 20);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: clk div status timeout!\n", __func__);
+			return -1;
+		}
+	} while(clk_div_status != reg0);
+
+	write_reg_mask(ACPU_SC_VD_CTRL, 0x0, (0x1 << 0) | (0x1 << 11));
+	write_reg_mask(PMCTRL_ACPUCLKDIV, 0x1 << 8, 0x3 << 8);
+	write_reg_mask(PMCTRL_ACPUPLLSEL, 0x1 << 0, 0x1 << 0);
+
+	return 0;
+}
+
+static void acpu_dvfs_clk_div_cfg(unsigned int prof_id,
+				  unsigned int *cpuext_cfg,
+				  unsigned int *acpu_ddr_cfg)
+{
+	if (0 == prof_id) {
+		write_reg_mask(PMCTRL_ACPUCLKDIV,
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START),
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START));
+		*cpuext_cfg = 0x1;
+		*acpu_ddr_cfg = 0x1;
+	} else if (1 == prof_id) {
+		write_reg_mask(PMCTRL_ACPUCLKDIV,
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START),
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START));
+		*cpuext_cfg = 0x1;
+		*acpu_ddr_cfg = 0x1;
+	} else {
+		/* ddr has not been inited */
+		write_reg_mask(PMCTRL_ACPUCLKDIV,
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x0 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START),
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START));
+		*cpuext_cfg = 0x1;
+		*acpu_ddr_cfg = 0x0;
+	}
+
+	return;
+}
+
+static int acpu_dvfs_freq_ascend(unsigned int cur_prof, unsigned int tar_prof)
+{
+	unsigned int reg0 = 0;
+	unsigned int reg1 = 0;
+	unsigned int reg2 = 0;
+	unsigned int count = 0;
+	unsigned int cpuext_cfg_val = 0;
+	unsigned int acpu_ddr_cfg_val = 0;
+	int ret = 0;
+
+	/*
+	 * step 1:
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x3;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x1;
+	 *
+	 * step 2:
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_syspll_div_cfg = 0x5 (208MHz)
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_syspll_div_cfg = 0x2 (500MHz)
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_syspll_div_cfg = 0x1 (Other OPPs)
+	 *
+	 * step 3:
+	 *  - ACPU_SC_CPU_STAT.clk_div_status_vd = 0x3;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0x0;
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0x0;
+	 *  - PMCTRL_ACPUCLKDIV.acpu_ddr_clk_div_cfg = 0x1;
+	 *  - PMCTRL_ACPUPLLSEL.acpu_pllsw_cfg = 0x1
+	 */
+	ret = acpu_dvfs_syspll_cfg(cur_prof);
+	if (ret)
+		return -1;
+
+	/*
+	 * step 4:
+	 *  - Polling PMCTRL_ACPUPLLSEL.syspll_sw_stat == 0x1
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLSEL, 0x1,
+			SOC_PMCTRL_ACPUPLLSEL_syspll_sw_stat_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: syspll sw status timeout\n", __func__);
+			return -1;
+		}
+	} while(0x1 != reg0);
+
+	/* Enable VD functionality if > 800MHz */
+	if (acpu_dvfs_profile[tar_prof].freq > 800000) {
+
+		write_reg_mask(ACPU_SC_VD_HPM_CTRL,
+			HPM_OSC_DIV_VAL, HPM_OSC_DIV_MASK);
+
+		/*
+		 * step 5:
+		 *  - ACPU_SC_VD_HPM_CTRL.hpm_dly_exp = 0xC7A;
+		 *  - ACPU_SC_VD_MASK_PATTERN_CTRL[12:0] = 0xCCB;
+		 */
+		write_reg_mask(ACPU_SC_VD_HPM_CTRL,
+			HPM_DLY_EXP_VAL, HPM_DLY_EXP_MASK);
+		write_reg_mask(ACPU_SC_VD_MASK_PATTERN_CTRL,
+			ACPU_SC_VD_MASK_PATTERN_VAL,
+			ACPU_SC_VD_MASK_PATTERN_MASK);
+
+		/*
+		 * step 6:
+		 *  - ACPU_SC_VD_DLY_TABLE0_CTRL = 0x1FFF;
+		 *  - ACPU_SC_VD_DLY_TABLE1_CTRL = 0x1FFFFFF;
+		 *  - ACPU_SC_VD_DLY_TABLE2_CTRL = 0x7FFFFFFF;
+		 *  - ACPU_SC_VD_DLY_FIXED_CTRL  = 0x1;
+		 */
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE0_CTRL, 0x1FFF);
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE1_CTRL, 0x1FFFFFF);
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE2_CTRL, 0x7FFFFFFF);
+		mmio_write_32(ACPU_SC_VD_DLY_FIXED_CTRL, 0x1);
+
+		/*
+		 * step 7:
+		 *  - ACPU_SC_VD_CTRL.shift_table0 = 0x1;
+		 *  - ACPU_SC_VD_CTRL.shift_table1 = 0x3;
+		 *  - ACPU_SC_VD_CTRL.shift_table2 = 0x5;
+		 *  - ACPU_SC_VD_CTRL.shift_table3 = 0x6;
+		 *
+		 * step 8:
+		 *  - ACPU_SC_VD_CTRL.tune = 0x7;
+		 */
+		write_reg_mask(ACPU_SC_VD_CTRL,
+			ACPU_SC_VD_SHIFT_TABLE_TUNE_VAL,
+			ACPU_SC_VD_SHIFT_TABLE_TUNE_MASK);
+	}
+
+	/* step 9: ACPUPLLCTRL.acpupll_en_cfg = 0x0 */
+	write_reg_mask(PMCTRL_ACPUPLLCTRL, 0x0,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START);
+
+	/* step 10: set PMCTRL_ACPUPLLFREQ and PMCTRL_ACPUPLLFRAC */
+	mmio_write_32(PMCTRL_ACPUPLLFREQ,
+		acpu_dvfs_profile[tar_prof].acpu_pll_freq);
+	mmio_write_32(PMCTRL_ACPUPLLFRAC,
+		acpu_dvfs_profile[tar_prof].acpu_pll_frac);
+
+	/*
+	 * step 11:
+	 *  - wait for 1us;
+	 *  - PMCTRL_ACPUPLLCTRL.acpupll_en_cfg = 0x1
+	 */
+	count = 0 ;
+	while (count < ACPU_WAIT_TIMEOUT) {
+		count++;
+	}
+	write_reg_mask(PMCTRL_ACPUPLLCTRL,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START);
+
+	/* step 12: PMCTRL_ACPUVOLPMUADDR = 0x100da */
+	mmio_write_32(PMCTRL_ACPUVOLPMUADDR, 0x100da);
+
+	/*
+	 * step 13:
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x13 (208MHz);
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x13 (500MHz);
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x20 (798MHz);
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x3A (1300MHz);
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x3A (1500MHz);
+	 */
+	write_reg_mask(PMCTRL_ACPUDESTVOL,
+		acpu_dvfs_profile[tar_prof].acpu_vol_profile,
+		((0x1 << (SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_END + 1)) - 1));
+
+	/*
+	 * step 14:
+	 *  - Polling PMCTRL_ACPUDESTVOL.acpu_vol_using == ACPUDESTVOL.acpu_dest_vol
+	 *  - Polling ACPUVOLTIMEOUT.acpu_vol_timeout == 0x1
+	 *  - Config PMCTRL_ACPUCLKDIV.acpu_ddr_clk_div_cfg
+	 *  - Config ACPUCLKDIV.cpuext_clk_div_cfg;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUDESTVOL, 0x7F,
+			SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_START);
+		reg1 = read_reg_mask(PMCTRL_ACPUDESTVOL, 0x7F,
+			SOC_PMCTRL_ACPUDESTVOL_acpu_vol_using_START);
+		reg2 = read_reg_mask(PMCTRL_ACPUVOLTTIMEOUT, 0x1,
+			SOC_PMCTRL_ACPUVOLTIMEOUT_acpu_vol_timeout_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu destvol cfg timeout.\n", __func__);
+			return -1;
+		}
+	} while((reg0 != reg1) || (0x1 != reg2));
+
+	acpu_dvfs_clk_div_cfg(tar_prof, &cpuext_cfg_val, &acpu_ddr_cfg_val);
+
+	/*
+	 * step 15:
+	 *  - Polling PMCTRL_ACPUCLKDIV.cpuext_clk_div_stat;
+	 *  - Polling ACPUCLKDIV.acpu_ddr_clk_div_stat;
+	 *  - ACPUPLLCTRL.acpupll_timeout = 0x1;
+	 *  - PMCTRL_ACPUPLLSEL.acpu_pllsw_cfg = 0x0;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUCLKDIV, 0x3,
+			SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_stat_START);
+		reg1 = read_reg_mask(PMCTRL_ACPUCLKDIV, 0x3,
+			SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_stat_START);
+		reg2 = read_reg_mask(PMCTRL_ACPUPLLCTRL, 0x1,
+			SOC_PMCTRL_ACPUPLLCTRL_acpupll_timeout_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu clk div cfg timeout.\n", __func__);
+			return -1;
+		}
+	} while((cpuext_cfg_val != reg1) ||
+		(acpu_ddr_cfg_val != reg0) ||
+		(0x1 != reg2));
+
+	write_reg_mask(PMCTRL_ACPUPLLSEL, 0x0,
+		0x1 << SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_cfg_START);
+
+	/*
+	 * step 16:
+	 *  - Polling PMCTRL_ACPUPLLSEL.acpupll_sw_stat == 0x1;
+	 *  - ACPU_SC_VD_CTRL.force_clk_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.clk_dis_cnt_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_ini = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_dif = 0x0;
+	 *  - ACPU_SC_VD_CTRL.div_en_dif = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0x1;
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x0;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x0;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLSEL, 0x1,
+			SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_stat_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu pll sw status timeout.\n", __func__);
+			return -1;
+		}
+	} while(0x1 != reg0);
+
+	if (acpu_dvfs_profile[tar_prof].freq > 800000)
+		write_reg_mask(ACPU_SC_VD_CTRL,
+			ACPU_SC_VD_EN_ASIC_VAL, ACPU_SC_VD_EN_MASK);
+
+	write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x0,
+		(0x3 << SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_sw_START) |
+		(0x1 << SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_cfg_START));
+
+	return 0;
+}
+
+static int acpu_dvfs_freq_descend(unsigned int cur_prof, unsigned int tar_prof)
+{
+	unsigned int reg0 = 0;
+	unsigned int reg1 = 0;
+	unsigned int reg2 = 0;
+	unsigned int count = 0;
+	unsigned int cpuext_cfg_val = 0;
+	unsigned int acpu_ddr_cfg_val = 0;
+	int ret = 0;
+
+	ret = acpu_dvfs_syspll_cfg(tar_prof);
+	if (ret)
+		return -1;
+
+	/*
+	 * step 4:
+	 *  - Polling PMCTRL_ACPUPLLSEL.syspll_sw_stat == 0x1
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLSEL, 0x1, 2);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: syspll sw status timeout.\n", __func__);
+			return -1;
+		}
+	} while(0x1 != reg0);
+
+	/*
+	 * Step 5:
+	 *  - PMCTRL_ACPUPLLCTRL.acpupll_en_cfg = 0x0
+	 */
+	write_reg_mask(PMCTRL_ACPUPLLCTRL, 0x0, 0x1 << 0);
+
+	/*
+	 * step 6
+	 *  - Config PMCTRL_ACPUPLLFREQ and ACPUPLLFRAC
+	 */
+	mmio_write_32(PMCTRL_ACPUPLLFREQ, acpu_dvfs_profile[tar_prof].acpu_pll_freq);
+	mmio_write_32(PMCTRL_ACPUPLLFRAC, acpu_dvfs_profile[tar_prof].acpu_pll_frac);
+
+	/*
+	 * step 7:
+	 *  - Wait 1us;
+	 *  - Config PMCTRL_ACPUPLLCTRL.acpupll_en_cfg = 0x1
+	 */
+	count = 0 ;
+	while (count < ACPU_WAIT_TIMEOUT) {
+		count++;
+	}
+
+	write_reg_mask(PMCTRL_ACPUPLLCTRL,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START);
+
+	/* Enable VD functionality if > 800MHz */
+	if (acpu_dvfs_profile[tar_prof].freq > 800000) {
+
+		write_reg_mask(ACPU_SC_VD_HPM_CTRL,
+			HPM_OSC_DIV_VAL, HPM_OSC_DIV_MASK);
+
+		/*
+		 * step 9:
+		 *  - ACPU_SC_VD_HPM_CTRL.hpm_dly_exp = 0xC7A;
+		 *  - ACPU_SC_VD_MASK_PATTERN_CTRL[12:0] = 0xCCB;
+		 */
+		write_reg_mask(ACPU_SC_VD_HPM_CTRL,
+			HPM_DLY_EXP_VAL, HPM_DLY_EXP_MASK);
+		write_reg_mask(ACPU_SC_VD_MASK_PATTERN_CTRL,
+			ACPU_SC_VD_MASK_PATTERN_VAL,
+			ACPU_SC_VD_MASK_PATTERN_MASK);
+
+		/*
+		 * step 10:
+		 *  - ACPU_SC_VD_DLY_TABLE0_CTRL = 0x1FFF;
+		 *  - ACPU_SC_VD_DLY_TABLE1_CTRL = 0x1FFFFFF;
+		 *  - ACPU_SC_VD_DLY_TABLE2_CTRL = 0x7FFFFFFF;
+		 *  - ACPU_SC_VD_DLY_FIXED_CTRL  = 0x1;
+		 */
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE0_CTRL, 0x1FFF);
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE1_CTRL, 0x1FFFFFF);
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE2_CTRL, 0x7FFFFFFF);
+		mmio_write_32(ACPU_SC_VD_DLY_FIXED_CTRL, 0x1);
+
+		/*
+		 * step 11:
+		 *  - ACPU_SC_VD_CTRL.shift_table0 = 0x1;
+		 *  - ACPU_SC_VD_CTRL.shift_table1 = 0x3;
+		 *  - ACPU_SC_VD_CTRL.shift_table2 = 0x5;
+		 *  - ACPU_SC_VD_CTRL.shift_table3 = 0x6;
+		 *
+		 * step 12:
+		 *  - ACPU_SC_VD_CTRL.tune = 0x7;
+		 */
+		write_reg_mask(ACPU_SC_VD_CTRL,
+			ACPU_SC_VD_SHIFT_TABLE_TUNE_VAL,
+			ACPU_SC_VD_SHIFT_TABLE_TUNE_MASK);
+	}
+
+	/*
+	 * step 13:
+	 *  - Pollig PMCTRL_ACPUPLLCTRL.acpupll_timeout == 0x1;
+	 *  - PMCTRL_ACPUPLLSEL.acpu_pllsw_cfg = 0x0;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLCTRL, 0x1,
+			SOC_PMCTRL_ACPUPLLCTRL_acpupll_timeout_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpupll timeout.\n", __func__);
+			return -1;
+		}
+	} while(0x1 != reg0);
+
+	write_reg_mask(PMCTRL_ACPUPLLSEL, 0x0,
+		0x1 << SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_cfg_START);
+
+	/*
+	 * step 14:
+	 *  - Polling PMCTRL_ACPUPLLSEL.acpupll_sw_stat == 0x1;
+	 *  - ACPU_SC_VD_CTRL.force_clk_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.clk_dis_cnt_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_ini = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_dif = 0x0;
+	 *  - ACPU_SC_VD_CTRL.div_en_dif = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0x1;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLSEL, 0x1,
+			SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_stat_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpupll sw status timeout.\n", __func__);
+			return -1;
+		}
+	} while(0x1 != reg0);
+
+	if (acpu_dvfs_profile[tar_prof].freq > 800000)
+		write_reg_mask(ACPU_SC_VD_CTRL,
+			ACPU_SC_VD_EN_ASIC_VAL, ACPU_SC_VD_EN_MASK);
+
+	/*
+	 * step 15:
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x0;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x0;
+	 */
+	write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x0,
+		(0x3 << SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_sw_START) |
+		(0x1 << SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_cfg_START));
+
+	/*
+	 * step 16:
+	 *  - Polling ACPU_SC_CPU_STAT.clk_div_status_vd == 0x0;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(ACPU_SC_CPU_STAT, 0x3,
+			ACPU_SC_CPU_STAT_CLK_DIV_STATUS_VD_SHIFT);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: clk div status timeout.\n", __func__);
+			return -1;
+		}
+	} while(0x0 != reg0);
+
+	acpu_dvfs_clk_div_cfg(tar_prof, &cpuext_cfg_val, &acpu_ddr_cfg_val);
+
+	/*
+	 * step 17:
+	 *  - Polling PMCTRL_ACPUCLKDIV.cpuext_clk_div_stat;
+	 *  - Polling ACPUCLKDIV.acpu_ddr_clk_div_stat;
+	 *  - PMCTRL_ACPUVOLPMUADDR = 0x1006C;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUCLKDIV, 0x3,
+			SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_stat_START);
+		reg1 = read_reg_mask(PMCTRL_ACPUCLKDIV, 0x3,
+			SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_stat_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu clk div cfg timeout.\n", __func__);
+			return -1;
+		}
+	} while((cpuext_cfg_val != reg0) || (acpu_ddr_cfg_val != reg1));
+
+	mmio_write_32(PMCTRL_ACPUVOLPMUADDR, 0x100da);
+
+	/*
+	 * step 16:
+	 *  - Polling PMCTRL_ACPUPLLSEL.acpupll_sw_stat == 0x1;
+	 *  - ACPU_SC_VD_CTRL.force_clk_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.clk_dis_cnt_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_ini = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_dif = 0x0;
+	 *  - ACPU_SC_VD_CTRL.div_en_dif = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0x1;
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x0;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x0;
+	 */
+	write_reg_mask(PMCTRL_ACPUDESTVOL,
+		acpu_dvfs_profile[tar_prof].acpu_vol_profile,
+		((0x1 << (SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_END + 1)) - 1));
+
+	/*
+	 * step 19:
+	 *  - Polling PMCTRL_ACPUDESTVOL.acpu_vol_using == ACPUDESTVOL.acpu_dest_vol
+	 *  - ACPUVOLTIMEOUT.acpu_vol_timeout = 0x1;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUDESTVOL, 0x7F,
+			SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_START);
+		reg1 = read_reg_mask(PMCTRL_ACPUDESTVOL, 0x7F,
+			SOC_PMCTRL_ACPUDESTVOL_acpu_vol_using_START);
+		reg2 = read_reg_mask(PMCTRL_ACPUVOLTTIMEOUT, 0x1,
+			SOC_PMCTRL_ACPUVOLTIMEOUT_acpu_vol_timeout_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu destvol cfg timeout.\n", __func__);
+			return -1;
+		}
+	} while((reg0 != reg1) || (0x1 != reg2));
+
+	return 0;
+}
+
+int acpu_dvfs_target(unsigned int curr_prof, unsigned int target_prof)
+{
+	int ret = 0;
+
+	if (curr_prof == target_prof) {
+		INFO("%s: target_prof is equal curr_prof: is %d!\n",
+			__func__, curr_prof);
+		return 0;
+	}
+
+	if ((curr_prof >= ACPU_FREQ_MAX_NUM) ||
+	    (target_prof >= ACPU_FREQ_MAX_NUM)) {
+		INFO("%s: invalid parameter %d %d\n",
+			__func__, curr_prof, target_prof);
+		return -1;
+	}
+
+	if (target_prof > acpu_dvfs_sram_buf->support_freq_num)
+		target_prof = acpu_dvfs_sram_buf->support_freq_num;
+
+	if (target_prof < curr_prof)
+		ret = acpu_dvfs_freq_descend(curr_prof, target_prof);
+	else if (target_prof > curr_prof)
+		ret = acpu_dvfs_freq_ascend(curr_prof, target_prof);
+
+	if (ret) {
+		ERROR("%s: acpu_dvfs_target failed!\n");
+		return -1;
+	}
+
+	/* Complete acpu dvfs setting and set magic number */
+	acpu_dvfs_sram_buf->start_prof = target_prof;
+	acpu_dvfs_sram_buf->magic = ACPU_VALID_VOLTAGE_MAGIC;
+
+	mmio_write_32(DDR_DFS_FREQ_ADDR, 800000);
+	return 0;
+}
+
+static int acpu_dvfs_set_freq(void)
+{
+	unsigned int i;
+	unsigned int curr_prof;
+	unsigned int target_prof;
+	unsigned int max_freq = 0;
+
+	max_freq = acpu_dvfs_sram_buf->support_freq_max;
+
+	for (i = 0; i < acpu_dvfs_sram_buf->support_freq_num; i++) {
+
+		if (max_freq == hi6220_acpu_profile[i].freq) {
+			target_prof = i;
+			break;
+		}
+	}
+
+	if (i == acpu_dvfs_sram_buf->support_freq_num) {
+		ERROR("%s: cannot found max freq profile\n", __func__);
+		return -1;
+	}
+
+	curr_prof = 0;
+	target_prof = i;
+
+	/* if max freq is 208MHz, do nothing */
+	if (curr_prof == target_prof)
+		return 0;
+
+	if (acpu_dvfs_target(curr_prof, target_prof)) {
+		ERROR("%s: set acpu freq failed!", __func__);
+		return -1;
+	}
+
+	INFO("%s: support freq num is %d\n",
+		__func__, acpu_dvfs_sram_buf->support_freq_num);
+	INFO("%s: start prof is 0x%x\n",
+		__func__,  acpu_dvfs_sram_buf->start_prof);
+	INFO("%s: magic is 0x%x\n",
+		__func__, acpu_dvfs_sram_buf->magic);
+	INFO("%s: voltage:\n", __func__);
+	for (i = 0; i < acpu_dvfs_sram_buf->support_freq_num; i++)
+		INFO("  - %d: 0x%x\n", i, acpu_dvfs_sram_buf->vol[i]);
+
+	NOTICE("%s: set acpu freq success!", __func__);
+        return 0;
+}
+
+struct acpu_dvfs_volt_setting
+{
+	unsigned int magic;
+	unsigned int support_freq_num;
+	unsigned int support_freq_max;
+	unsigned int start_prof;
+	unsigned int vol[7];
+	unsigned int hmp_dly_threshold[7];
+};
+
+static void acpu_dvfs_volt_init(void)
+{
+	struct acpu_dvfs_volt_setting *volt;
+
+	/*
+	 * - set default voltage;
+	 * - set pmu address;
+	 * - set voltage up and down step;
+	 * - set voltage stable time;
+	 */
+	mmio_write_32(PMCTRL_ACPUDFTVOL, 0x4a);
+	mmio_write_32(PMCTRL_ACPUVOLPMUADDR, 0xda);
+	mmio_write_32(PMCTRL_ACPUVOLUPSTEP, 0x1);
+	mmio_write_32(PMCTRL_ACPUVOLDNSTEP, 0x1);
+	mmio_write_32(PMCTRL_ACPUPMUVOLUPTIME, 0x60);
+	mmio_write_32(PMCTRL_ACPUPMUVOLDNTIME, 0x60);
+	mmio_write_32(PMCTRL_ACPUCLKOFFCFG, 0x1000);
+
+	volt= (void *)MEMORY_AXI_ACPU_FREQ_VOL_ADDR;
+	volt->magic = 0x5a5ac5c5;
+	volt->support_freq_num = 5;
+	volt->support_freq_max = 1200000;
+	volt->start_prof = 4;
+	volt->vol[0] = 0x49;
+	volt->vol[1] = 0x49;
+	volt->vol[2] = 0x50;
+	volt->vol[3] = 0x60;
+	volt->vol[4] = 0x78;
+	volt->vol[5] = 0x78;
+	volt->vol[6] = 0x78;
+
+	volt->hmp_dly_threshold[0] = 0x0;
+	volt->hmp_dly_threshold[1] = 0x0;
+	volt->hmp_dly_threshold[2] = 0x0;
+	volt->hmp_dly_threshold[3] = 0x0e8b0e45;
+	volt->hmp_dly_threshold[4] = 0x10691023;
+	volt->hmp_dly_threshold[5] = 0x10691023;
+	volt->hmp_dly_threshold[6] = 0x10691023;
+
+	INFO("%s: success!\n", __func__);
+}
+
+void init_acpu_dvfs(void)
+{
+	unsigned int i = 0;
+
+	INFO("%s: pmic version %d\n", __func__, hi6553_read_8(VERSION_REG));
+
+	/* init parameters */
+	mmio_write_32(ACPU_CHIP_MAX_FREQ, efuse_acpu_freq[8]);
+	INFO("%s: ACPU_CHIP_MAX_FREQ=0x%x.\n",
+		__func__, mmio_read_32(ACPU_CHIP_MAX_FREQ));
+
+        /* set maximum support frequency to 1.2GHz */
+        for(i = 0; i < ACPU_FREQ_MAX_NUM; i++)
+		acpu_dvfs_sram_buf->vol[i] = hi6220_acpu_profile[i].acpu_vol_profile;
+
+        acpu_dvfs_sram_buf->support_freq_num = ACPU_FREQ_MAX_NUM;
+        acpu_dvfs_sram_buf->support_freq_max = 1200000;
+
+	/* init acpu dvfs */
+	acpu_dvfs_volt_init();
+	acpu_dvfs_set_freq();
+
+	return;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_ipc.c b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_ipc.c
new file mode 100644
index 0000000..c3b34d3
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_ipc.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <hisi_ipc.h>
+#include <hisi_sram_map.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define BIT(x)	(0x1 << (x))
+
+static int  _ipc_init = 0;
+
+static unsigned int cpu_ipc_num[PLATFORM_CLUSTER_COUNT][PLATFORM_CORE_COUNT_PER_CLUSTER] = {
+	{
+		HISI_IPC_MCU_INT_SRC_ACPU0_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU1_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU2_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU3_PD,
+	},
+	{
+		HISI_IPC_MCU_INT_SRC_ACPU4_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU5_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU6_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU7_PD,
+	}
+};
+
+int hisi_cpus_pd_in_cluster_besides_curr(unsigned int cpu,
+					 unsigned int cluster)
+{
+	unsigned int val = 0, cpu_val = 0;
+	int i;
+
+	val = mmio_read_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR);
+	val = val >> (cluster * 16);
+
+	for (i = 0; i < PLATFORM_CORE_COUNT_PER_CLUSTER; i++) {
+
+		if (cpu == i)
+			continue;
+
+		cpu_val = (val >> (i * 4)) & 0xF;
+		if (cpu_val == 0x8)
+			return 0;
+        }
+
+	return 1;
+}
+
+int hisi_cpus_powered_off_besides_curr(unsigned int cpu)
+{
+	unsigned int val;
+
+	val = mmio_read_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR);
+	return (val == (0x8 << (cpu * 4)));
+}
+
+static void hisi_ipc_send(unsigned int ipc_num)
+{
+	if (!_ipc_init) {
+		printf("error ipc base is null!!!\n");
+		return;
+	}
+
+	mmio_write_32(HISI_IPC_CPU_RAW_INT_ADDR, 1 << ipc_num);
+}
+
+void hisi_ipc_spin_lock(unsigned int signal)
+{
+	unsigned int hs_ctrl;
+
+	if (signal >= HISI_IPC_INT_SRC_NUM)
+		return;
+
+	do {
+		hs_ctrl = mmio_read_32(HISI_IPC_ACPU_CTRL(signal));
+	} while (hs_ctrl);
+}
+
+void hisi_ipc_spin_unlock(unsigned int signal)
+{
+	if (signal >= HISI_IPC_INT_SRC_NUM)
+		return;
+
+	mmio_write_32(HISI_IPC_ACPU_CTRL(signal), 0);
+}
+
+void hisi_ipc_cpu_on_off(unsigned int cpu, unsigned int cluster,
+			 unsigned int mode)
+{
+	unsigned int val = 0;
+	unsigned int offset;
+
+	if (mode == HISI_IPC_PM_ON)
+		offset = cluster * 16 + cpu * 4;
+	else
+		offset = cluster * 16 + cpu * 4 + 1;
+
+	hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+	val = mmio_read_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR);
+	val |= (0x01 << offset);
+	mmio_write_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR, val);
+	hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+	hisi_ipc_send(cpu_ipc_num[cluster][cpu]);
+}
+
+void hisi_ipc_cpu_on(unsigned int cpu, unsigned int cluster)
+{
+	hisi_ipc_cpu_on_off(cpu, cluster, HISI_IPC_PM_ON);
+}
+
+void hisi_ipc_cpu_off(unsigned int cpu, unsigned int cluster)
+{
+	hisi_ipc_cpu_on_off(cpu, cluster, HISI_IPC_PM_OFF);
+}
+
+void hisi_ipc_cluster_on_off(unsigned int cpu, unsigned int cluster,
+			     unsigned int mode)
+{
+	unsigned int val = 0;
+	unsigned int offset;
+
+	if (mode == HISI_IPC_PM_ON)
+		offset = cluster * 4;
+	else
+		offset = cluster * 4 + 1;
+
+	hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+	val = mmio_read_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR);
+	val |= (0x01 << offset);
+	mmio_write_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR, val);
+	hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+	hisi_ipc_send(cpu_ipc_num[cluster][cpu]);
+}
+
+void hisi_ipc_cluster_on(unsigned int cpu, unsigned int cluster)
+{
+	hisi_ipc_cluster_on_off(cpu, cluster, HISI_IPC_PM_ON);
+}
+
+void hisi_ipc_cluster_off(unsigned int cpu, unsigned int cluster)
+{
+	hisi_ipc_cluster_on_off(cpu, cluster, HISI_IPC_PM_OFF);
+}
+
+void hisi_ipc_cpu_suspend(unsigned int cpu, unsigned int cluster)
+{
+	unsigned int val = 0;
+	unsigned int offset;
+
+	offset = cluster * 16 + cpu * 4 + 2;
+
+	hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+	val = mmio_read_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR);
+	val |= (0x01 << offset);
+	mmio_write_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR, val);
+	hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+	hisi_ipc_send(cpu_ipc_num[cluster][cpu]);
+}
+
+void hisi_ipc_cluster_suspend(unsigned int cpu, unsigned int cluster)
+{
+	unsigned int val;
+	unsigned int offset;
+
+	offset = cluster * 4 + 1;
+
+	hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+	if (hisi_cpus_pd_in_cluster_besides_curr(cpu, cluster)) {
+		val = mmio_read_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR);
+		val |= (0x01 << offset);
+		mmio_write_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR, val);
+	}
+	hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+	hisi_ipc_send(cpu_ipc_num[cluster][cpu]);
+}
+
+void hisi_ipc_psci_system_off(void)
+{
+	hisi_ipc_send(HISI_IPC_MCU_INT_SRC_ACPU_PD);
+}
+
+int hisi_ipc_init(void)
+{
+	_ipc_init = 1;
+
+	mmio_write_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR, 0x8);
+	mmio_write_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR, 0x8);
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_mcu.c b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_mcu.c
new file mode 100644
index 0000000..50d5f54
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_mcu.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <partitions.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include <mmio.h>
+#include <hi6220.h>
+
+#define MCU_SECTION_MAX		30
+
+enum MCU_IMAGE_SEC_TYPE_ENUM {
+	MCU_IMAGE_SEC_TYPE_TEXT = 0,	/* text section */
+	MCU_IMAGE_SEC_TYPE_DATA,	/* data section */
+	MCU_IMAGE_SEC_TYPE_BUTT
+};
+
+enum MCU_IMAGE_SEC_LOAD_ENUM {
+	MCU_IMAGE_SEC_LOAD_STATIC = 0,
+	MCU_IMAGE_SEC_LOAD_DYNAMIC,
+	MCU_IMAGE_SEC_LOAD_BUFFER,
+	MCU_IMAGE_SEC_LOAD_MODEM_ENTRY,
+	MCU_IMAGE_SEC_LOAD_BUTT
+};
+
+struct mcu_image_sec {
+	unsigned short serial;
+	char type;
+	char load_attr;
+	uint32_t src_offset;		/* offset in image */
+	uint32_t dst_offset;		/* offset in memory */
+	uint32_t size;
+};
+
+struct mcu_image_head {
+	char time_stamp[24];
+	uint32_t image_size;
+	uint32_t secs_num;
+	struct mcu_image_sec secs[MCU_SECTION_MAX];
+};
+
+#define SOC_SRAM_M3_BASE_ADDR		(0xF6000000)
+
+#define MCU_SRAM_SIZE			(0x0000C000)
+#define MCU_CACHE_SIZE			(0x00004000)
+#define MCU_CODE_SIZE			(MCU_SRAM_SIZE - MCU_CACHE_SIZE)
+
+#define MCU_SYS_MEM_ADDR		(0x05E00000)
+#define MCU_SYS_MEM_SIZE		(0x00100000)
+
+#if 0
+static uint32_t ap2mcu_addr(uint32_t ap_addr)
+{
+	if (ap_addr >= SOC_SRAM_M3_BASE_ADDR &&
+	    ap_addr < SOC_SRAM_M3_BASE_ADDR + MCU_SRAM_SIZE)
+		return ap_addr - SOC_SRAM_M3_BASE_ADDR;
+	else if (ap_addr >= MCU_SYS_MEM_ADDR &&
+		 ap_addr < MCU_SYS_MEM_ADDR + MCU_SYS_MEM_SIZE )
+		return ap_addr - MCU_SYS_MEM_ADDR + MCU_SRAM_SIZE;
+	else
+		return ap_addr;
+}
+#endif
+
+static uint32_t mcu2ap_addr(uint32_t mcu_addr)
+{
+	if (mcu_addr < MCU_CODE_SIZE)
+		return (mcu_addr + SOC_SRAM_M3_BASE_ADDR);
+	else if ((mcu_addr >= MCU_SRAM_SIZE) &&
+		 (mcu_addr < MCU_SRAM_SIZE + MCU_SYS_MEM_SIZE))
+		return mcu_addr - MCU_SRAM_SIZE + MCU_SYS_MEM_ADDR;
+	else
+		return mcu_addr;
+}
+
+static int is_binary_header_invalid(struct mcu_image_head *head,
+				    unsigned length)
+{
+	/* invalid cases */
+	if ((head->image_size == 0) ||
+	    (head->image_size > length) ||
+	    (head->secs_num > MCU_SECTION_MAX) ||
+	    (head->secs_num == 0))
+		return 1;
+
+        return 0;
+}
+
+static int is_binary_section_invalid(struct mcu_image_sec *sec,
+				     struct mcu_image_head *head)
+{
+	unsigned long ap_dst_offset = 0;
+
+	if ((sec->serial >= head->secs_num) ||
+	    (sec->src_offset + sec->size > head->image_size))
+		return 1;
+
+	if ((sec->type >= MCU_IMAGE_SEC_TYPE_BUTT) ||
+	    (sec->load_attr >= MCU_IMAGE_SEC_LOAD_BUTT))
+		return 1;
+
+        ap_dst_offset = mcu2ap_addr(sec->dst_offset);
+        if ((ap_dst_offset >= SOC_SRAM_M3_BASE_ADDR) &&
+	    (ap_dst_offset < SOC_SRAM_M3_BASE_ADDR + 0x20000 - sec->size))
+		return 0;
+        else if ((ap_dst_offset >= MCU_SYS_MEM_ADDR) &&
+		 (ap_dst_offset < MCU_SYS_MEM_ADDR + MCU_SYS_MEM_SIZE - sec->size))
+		return 0;
+        else if ((ap_dst_offset >= 0xfff8e000) &&
+		 (ap_dst_offset < 0xfff91c00 - sec->size))
+		return 0;
+
+	ERROR("%s: mcu destination address invalid.\n", __func__);
+	ERROR("%s: number=%d, dst offset=%d size=%d\n",
+		__func__, sec->serial, sec->dst_offset, sec->size);
+	return 1;
+}
+
+void hisi_mcu_enable_sram(void)
+{
+	mmio_write_32(AO_SC_PERIPH_CLKEN4,
+		      AO_SC_PERIPH_CLKEN4_HCLK_IPC_S |
+		      AO_SC_PERIPH_CLKEN4_HCLK_IPC_NS);
+
+	/* set register to enable dvfs which is used by mcu */
+	mmio_write_32(PERI_SC_RESERVED8_ADDR, 0x0A001022);
+
+	/* mcu mem is powered on, need de-assert reset */
+	mmio_write_32(AO_SC_PERIPH_RSTDIS4,
+		      AO_SC_PERIPH_RSTDIS4_RESET_MCU_ECTR_N);
+
+	/* enable mcu hclk */
+	mmio_write_32(AO_SC_PERIPH_CLKEN4,
+		      AO_SC_PERIPH_CLKEN4_HCLK_MCU |
+		      AO_SC_PERIPH_CLKEN4_CLK_MCU_DAP);
+}
+
+void hisi_mcu_start_run(void)
+{
+	unsigned int val;
+
+#if 0
+        /* set mcu's self loop instruction 0xE7FE at entry point */
+        val = mmio_read_32((SOC_SRAM_M3_BASE_ADDR + 0x200));
+        val &= 0xFFFF0000;
+        val |= 0xE7FE;
+        mmio_write_32((SOC_SRAM_M3_BASE_ADDR + 0x200), val);
+#endif
+
+	/* set mcu ddr remap configuration */
+	mmio_write_32(AO_SC_MCU_SUBSYS_CTRL2, MCU_SYS_MEM_ADDR);
+
+	/* de-assert reset for mcu and to run */
+	mmio_write_32(AO_SC_PERIPH_RSTDIS4,
+		AO_SC_PERIPH_RSTDIS4_RESET_MCU_ECTR_N |
+		AO_SC_PERIPH_RSTDIS4_RESET_MCU_SYS_N |
+		AO_SC_PERIPH_RSTDIS4_RESET_MCU_POR_N |
+		AO_SC_PERIPH_RSTDIS4_RESET_MCU_DAP_N);
+
+	val = mmio_read_32(AO_SC_SYS_CTRL2);
+	mmio_write_32(AO_SC_SYS_CTRL2,
+		val | AO_SC_SYS_CTRL2_GLB_SRST_STAT_CLEAR);
+
+	INFO("%s: AO_SC_SYS_CTRL2=%x\n", __func__,
+		mmio_read_32(AO_SC_SYS_CTRL2));
+}
+
+int hisi_mcu_load_image(uintptr_t image_base, uint32_t image_size)
+{
+	unsigned int i;
+	struct mcu_image_head *head;
+	char *buf;
+
+	head = (struct mcu_image_head *)image_base;
+	if (is_binary_header_invalid(head, image_size)) {
+		ERROR("Invalid %s image header.\n", head->time_stamp);
+		return -1;
+	}
+
+	buf = (char *)head;
+	for (i = 0; i < head->secs_num; i++) {
+
+		int *src, *dst;
+
+		/* check the sections */
+		if (is_binary_section_invalid(&head->secs[i], head)) {
+			ERROR("Invalid mcu section.\n");
+			return -1;
+		}
+
+		/* check if the section is static-loaded */
+		if (head->secs[i].load_attr != MCU_IMAGE_SEC_LOAD_STATIC)
+			continue;
+
+		/* copy the sections */
+		src = (int *)(intptr_t)(buf + head->secs[i].src_offset);
+		dst = (int *)(intptr_t)mcu2ap_addr(head->secs[i].dst_offset);
+
+		memcpy((void *)dst, (void *)src, head->secs[i].size);
+
+		INFO("%s: mcu sections %d:\n", __func__, i);
+	        INFO("%s:  src  = 0x%x\n", __func__, src);
+	        INFO("%s:  dst  = 0x%x\n", __func__, dst);
+		INFO("%s:  size = %d\n", __func__, head->secs[i].size);
+
+		INFO("%s:  [SRC 0x%x] 0x%x 0x%x 0x%x 0x%x\n", __func__,
+			src, src[0], src[1], src[2], src[3]);
+		INFO("%s:  [DST 0x%x] 0x%x 0x%x 0x%x 0x%x\n", __func__,
+			dst, dst[0], dst[1], dst[2], dst[3]);
+	}
+
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_pwrc.c b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_pwrc.c
new file mode 100644
index 0000000..9f189da
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_pwrc.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <bakery_lock.h>
+#include <mmio.h>
+#include <hisi_ipc.h>
+#include <hisi_pwrc.h>
+#include <hisi_sram_map.h>
+#include <hi6220_regs_acpu.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <platform_def.h>
+
+#define CLUSTER_CORE_COUNT		(4)
+#define CLUSTER_CORE_MASK		((1 << CLUSTER_CORE_COUNT) - 1)
+
+#define BIT(x) (0x1 << (x))
+
+void hisi_pwrc_set_core_bx_addr(unsigned int core, unsigned int cluster,
+				uintptr_t entry_point)
+{
+	uintptr_t *core_entry = (uintptr_t *)PWRCTRL_ACPU_ASM_D_ARM_PARA_AD;
+	unsigned int i;
+
+	if (!core_entry) {
+		printf("%s: core entry point is null!\n", __func__);
+		return;
+	}
+
+	i = cluster * CLUSTER_CORE_COUNT + core;
+	mmio_write_64((uintptr_t)(core_entry + i), entry_point);
+}
+
+void hisi_pwrc_set_cluster_wfi(unsigned int cluster)
+{
+	unsigned int reg = 0;
+
+	if (cluster == 0) {
+		reg = mmio_read_32(ACPU_CTRL_BASE + 0x0E4);
+		reg |= BIT(0);
+		mmio_write_32(ACPU_CTRL_BASE + 0x0E4, reg);
+	} else if (cluster == 1) {
+		reg = mmio_read_32(ACPU_CTRL_BASE + 0x0E4);
+		reg |= BIT(16);
+		mmio_write_32(ACPU_CTRL_BASE + 0x0E4, reg);
+	}
+}
+
+int hisi_pwrc_setup(void)
+{
+	unsigned int reg;
+	extern char pm_asm_code[], pm_asm_code_end[];
+	extern char v7_asm[], v7_asm_end[];
+
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(0), PWRCTRL_ACPU_ASM_CODE_BASE >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(1), PWRCTRL_ACPU_ASM_CODE_BASE >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(2), PWRCTRL_ACPU_ASM_CODE_BASE >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(3), PWRCTRL_ACPU_ASM_CODE_BASE >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(4), PWRCTRL_ACPU_ASM_CODE_BASE >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(5), PWRCTRL_ACPU_ASM_CODE_BASE >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(6), PWRCTRL_ACPU_ASM_CODE_BASE >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(7), PWRCTRL_ACPU_ASM_CODE_BASE >> 2);
+
+	memset((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, 0, 0x400);
+	memcpy((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, (void *)v7_asm,
+	       v7_asm_end - v7_asm);
+
+	memcpy((void *)PWRCTRL_ACPU_ASM_CODE_BASE, (void *)pm_asm_code,
+	       pm_asm_code_end - pm_asm_code);
+
+	reg = mmio_read_32(0xF7800000 + 0x004);
+	reg |= BIT(0x1) | BIT(17);
+	mmio_write_32(0xF7800000 + 0x004, reg);
+
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_pwrc_sram.S b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_pwrc_sram.S
new file mode 100644
index 0000000..ae8eec4
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/drivers/hisi_pwrc_sram.S
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <hisi_sram_map.h>
+
+	.global pm_asm_code
+	.global pm_asm_code_end
+	.global v7_asm
+	.global v7_asm_end
+
+	.align	3
+func pm_asm_code
+	mov	x0, 0
+	msr	oslar_el1, x0
+
+	mrs	x0, s3_1_c15_c2_0
+	bic	x0, x0, #0x1E000000
+ 	orr	x0, x0, #0x180000
+	orr	x0, x0, #0xe000
+	msr	s3_1_c15_c2_0, x0
+
+	mrs	x3, actlr_el3
+        orr	x3, x3, #(0x1<<5)
+        msr	actlr_el3, x3
+
+        mrs	x3, actlr_el2
+        orr	x3, x3, #(0x1<<5)
+        msr	actlr_el2, x3
+
+	ldr	x3, =PWRCTRL_ACPU_ASM_D_ARM_PARA_AD
+	mrs	x0, mpidr_el1
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+pen:	ldr	x4, [x3, x0, LSL #3]
+	cbz	x4, pen
+
+	mov	x0, #0x0
+	mov	x1, #0x0
+	mov	x2, #0x0
+	mov	x3, #0x0
+	br	x4
+
+	.ltorg
+
+pm_asm_code_end:
+
+	.align	3
+	.section .rodata.v7_asm, "aS"
+v7_asm:
+	.word	0xE1A00000	// nop
+	.word	0xE3A02003	// mov r2, #3
+	.word	0xEE0C2F50	// mcr 15, 0, r2, cr12, cr0, {2}
+	.word	0xE320F003	// wfi
+
+	.ltorg
+v7_asm_end:
diff --git a/uefi/arm-trusted-firmware/plat/hikey/drivers/sp804_timer.c b/uefi/arm-trusted-firmware/plat/hikey/drivers/sp804_timer.c
new file mode 100644
index 0000000..269bf1c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/drivers/sp804_timer.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <console.h>
+#include <debug.h>
+#include <errno.h>
+#include <hi6220.h>
+#include <mmio.h>
+#include <sp804_timer.h>
+
+/* Init dual timer0 (TIMER00 & TIMER01) */
+void hi6220_timer_init(void)
+{
+	unsigned int data;
+
+	/* select 32KHz as the clock of dual timer0 */
+	/* FIXME: But I find that it's 19.2MHz, not 32KHz. */
+	data = mmio_read_32(AO_SC_TIMER_EN0);
+	while (data & 3) {
+		data &= ~3;
+		data |= 3 << 16;
+		mmio_write_32(AO_SC_TIMER_EN0, data);
+		data = mmio_read_32(AO_SC_TIMER_EN0);
+	}
+	/* enable the pclk of dual timer0 */
+	data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4);
+	while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)) {
+		mmio_write_32(AO_SC_PERIPH_CLKEN4, PCLK_TIMER1 | PCLK_TIMER0);
+		data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4);
+	}
+	/* reset dual timer0 */
+	data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
+	mmio_write_32(AO_SC_PERIPH_RSTEN4, PCLK_TIMER1 | PCLK_TIMER0);
+	do {
+		data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
+	} while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0));
+	/* unreset dual timer0 */
+	mmio_write_32(AO_SC_PERIPH_RSTDIS4, PCLK_TIMER1 | PCLK_TIMER0);
+	do {
+		data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
+	} while ((data & PCLK_TIMER1) || (data & PCLK_TIMER0));
+	
+	/* disable timer00 */
+	mmio_write_32(TIMER00_CONTROL, 0);
+	mmio_write_32(TIMER00_LOAD, 0xffffffff);
+	/* free running */
+	mmio_write_32(TIMER00_CONTROL, 0x82);
+}
+
+static unsigned int get_timer_value(void)
+{
+	return mmio_read_32(TIMER00_VALUE);
+}
+
+void udelay(int us)
+{
+	unsigned int start, cnt, delta, delta_us;
+
+	if (us <= 0)
+		us = 1;
+	/* counter is decreasing */
+	start = get_timer_value();
+	do {
+		cnt = get_timer_value();
+		if (cnt > start) {
+			delta = 0xffffffff - cnt;
+			delta += start;
+		} else
+			delta = start - cnt;
+		delta_us = (delta * 10) / 192;
+	} while (delta_us < us);
+}
+
+void mdelay(int ms)
+{
+	unsigned int start, cnt, delta, delta_ms;
+
+	if (ms <= 0)
+		ms = 1;
+
+	/* counter is decreasing */
+	start = get_timer_value();
+	do {
+		cnt = get_timer_value();
+		if (cnt > start) {
+			delta = 0xffffffff - cnt;
+			delta += start;
+		} else
+			delta = start - cnt;
+		delta_ms = delta / 19200;
+	} while (delta_ms < ms);
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/hikey_def.h b/uefi/arm-trusted-firmware/plat/hikey/hikey_def.h
new file mode 100644
index 0000000..2007633
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/hikey_def.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __HIKEY_DEF_H__
+#define __HIKEY_DEF_H__
+
+#define DEVICE_BASE			0xf4000000
+#define DEVICE_SIZE			0x05800000
+
+/* The size of DDR RAM is 1GB. */
+#define DRAM_BASE			0x00000000
+#define DRAM_SIZE			0x40000000
+
+#define XG2RAM0_BASE			0xF9800000
+#define XG2RAM0_SIZE			0x00400000
+
+#define PLAT_TRUSTED_SRAM_ID	0
+#define PLAT_TRUSTED_DRAM_ID	1
+
+/*
+ * DRAM at 0x0000_0000 is divided in two regions:
+ *   - Secure DRAM (default is the top 16MB)
+ *   - Non-Secure DRAM (remaining DRAM starting at DRAM_BASE)
+ */
+#define DRAM_SEC_SIZE			0x01000000
+#define DRAM_SEC_BASE			(DRAM_BASE + DRAM_SIZE - DRAM_SEC_SIZE)
+
+#define DRAM_NS_BASE			DRAM_BASE
+#define DRAM_NS_SIZE			(DRAM_SIZE - DRAM_SEC_SIZE)
+
+#define SRAM_BASE			0xFFF80000
+#define SRAM_SIZE			0x00012000
+
+/*******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+#define GICD_BASE			0xF6801000
+#define GICC_BASE			0xF6802000
+
+#define IRQ_SEC_PHY_TIMER		29
+#define IRQ_SEC_SGI_0			8
+#define IRQ_SEC_SGI_1			9
+#define IRQ_SEC_SGI_2			10
+#define IRQ_SEC_SGI_3			11
+#define IRQ_SEC_SGI_4			12
+#define IRQ_SEC_SGI_5			13
+#define IRQ_SEC_SGI_6			14
+#define IRQ_SEC_SGI_7			15
+#define IRQ_SEC_SGI_8			16
+
+/*******************************************************************************
+ * PL011 related constants
+ ******************************************************************************/
+#define PL011_UART0_BASE		0xF8015000
+#define PL011_UART3_BASE		0xF7113000
+
+#define PL011_BAUDRATE			115200
+
+#define PL011_UART_CLK_IN_HZ		19200000
+
+/*******************************************************************************
+ * CCI-400 related constants
+ ******************************************************************************/
+#define CCI400_BASE			0xF6E90000
+#define CCI400_SL_IFACE3_CLUSTER_IX	0
+#define CCI400_SL_IFACE4_CLUSTER_IX	1
+
+#endif /* __HIKEY_DEF_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/hikey_private.h b/uefi/arm-trusted-firmware/plat/hikey/hikey_private.h
new file mode 100644
index 0000000..0627687
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/hikey_private.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __HIKEY_PRIVATE_H__
+#define __HIKEY_PRIVATE_H__
+
+#include <bl_common.h>
+
+/*******************************************************************************
+ * This structure represents the superset of information that is passed to
+ * BL3-1 e.g. while passing control to it from BL2 which is bl31_params
+ * and other platform specific params
+ ******************************************************************************/
+typedef struct bl2_to_bl31_params_mem {
+	struct bl31_params bl31_params;
+	struct image_info bl31_image_info;
+	struct image_info bl32_image_info;
+	struct image_info bl33_image_info;
+	struct entry_point_info bl33_ep_info;
+	struct entry_point_info bl32_ep_info;
+	struct entry_point_info bl31_ep_info;
+} bl2_to_bl31_params_mem_t;
+
+#define RANDOM_MAX		0x7fffffffffffffff
+#define RANDOM_MAGIC		0x9a4dbeaf
+
+struct random_serial_num {
+	uint64_t	magic;
+	uint64_t	data;
+	char		serialno[32];
+};
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void configure_mmu_el1(unsigned long total_base,
+		       unsigned long total_size,
+		       unsigned long ro_start,
+		       unsigned long ro_limit,
+		       unsigned long coh_start,
+		       unsigned long coh_limit);
+void configure_mmu_el3(unsigned long total_base,
+		       unsigned long total_size,
+		       unsigned long ro_start,
+		       unsigned long ro_limit,
+		       unsigned long coh_start,
+		       unsigned long coh_limit);
+extern int flush_loader_image(void);
+extern int flush_user_images(char *cmdbuf, unsigned long addr,
+			     unsigned long length);
+extern int flush_random_serialno(unsigned long addr, unsigned long length);
+extern void generate_serialno(struct random_serial_num *random);
+extern int assign_serialno(char *cmdbuf, struct random_serial_num *random);
+extern char *load_serialno(void);
+extern void hi6220_pll_init(void);
+extern void io_setup(void);
+extern int plat_get_image_source(const char *image_name,
+				 uintptr_t *dev_handle,
+				 uintptr_t *image_spec);
+extern void plat_gic_init(void);
+extern void usb_download(void);
+
+void plat_security_setup(void);
+
+#endif /* __HIKEY_PRIVATE_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/dw_mmc.h b/uefi/arm-trusted-firmware/plat/hikey/include/dw_mmc.h
new file mode 100644
index 0000000..fc12018
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/dw_mmc.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2014, Hisilicon Ltd.
+ * Copyright (c) 2014, Linaro Ltd.
+ *
+ * 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 __DW_MMC_H__
+#define __DW_MMC_H__
+
+#include <stdint.h>
+
+#define MMC0_CTRL				(MMC0_BASE + 0x000)
+#define MMC0_CLKDIV				(MMC0_BASE + 0x008)
+#define MMC0_CLKSRC				(MMC0_BASE + 0x00c)
+#define MMC0_CLKENA				(MMC0_BASE + 0x010)
+#define MMC0_TMOUT				(MMC0_BASE + 0x014)
+#define MMC0_CTYPE				(MMC0_BASE + 0x018)
+#define MMC0_BLKSIZ				(MMC0_BASE + 0x01c)
+#define MMC0_BYTCNT				(MMC0_BASE + 0x020)
+#define MMC0_INTMASK				(MMC0_BASE + 0x024)
+#define MMC0_CMDARG				(MMC0_BASE + 0x028)
+#define MMC0_CMD				(MMC0_BASE + 0x02c)
+#define MMC0_RESP0				(MMC0_BASE + 0x030)
+#define MMC0_RESP1				(MMC0_BASE + 0x034)
+#define MMC0_RESP2				(MMC0_BASE + 0x038)
+#define MMC0_RESP3				(MMC0_BASE + 0x03c)
+#define MMC0_RINTSTS				(MMC0_BASE + 0x044)
+#define MMC0_STATUS				(MMC0_BASE + 0x048)
+#define MMC0_FIFOTH				(MMC0_BASE + 0x04c)
+#define MMC0_DEBNCE				(MMC0_BASE + 0x064)
+#define MMC0_UHSREG				(MMC0_BASE + 0x074)
+#define MMC0_BMOD				(MMC0_BASE + 0x080)
+#define MMC0_DBADDR				(MMC0_BASE + 0x088)
+#define MMC0_IDSTS				(MMC0_BASE + 0x08c)
+#define MMC0_IDINTEN				(MMC0_BASE + 0x090)
+#define MMC0_DSCADDR				(MMC0_BASE + 0x094)
+#define MMC0_BUFADDR				(MMC0_BASE + 0x098)
+#define MMC0_CARDTHRCTL				(MMC0_BASE + 0X100)
+
+#define CMD_UPDATE_CLK				0x80202000
+#define CMD_START_BIT				(1 << 31)
+
+#define MMC_8BIT_MODE				(1 << 16)
+
+#define MMC_BLOCK_SIZE				512
+
+#define BIT_CMD_RESPONSE_EXPECT			(1 << 6)
+#define BIT_CMD_LONG_RESPONSE			(1 << 7)
+#define BIT_CMD_CHECK_RESPONSE_CRC		(1 << 8)
+#define BIT_CMD_DATA_EXPECTED			(1 << 9)
+#define BIT_CMD_READ				(0 << 10)
+#define BIT_CMD_WRITE				(1 << 10)
+#define BIT_CMD_BLOCK_TRANSFER			(0 << 11)
+#define BIT_CMD_STREAM_TRANSFER			(1 << 11)
+#define BIT_CMD_SEND_AUTO_STOP			(1 << 12)
+#define BIT_CMD_WAIT_PRVDATA_COMPLETE		(1 << 13)
+#define BIT_CMD_STOP_ABORT_CMD			(1 << 14)
+#define BIT_CMD_SEND_INIT			(1 << 15)
+#define BIT_CMD_UPDATE_CLOCK_ONLY		(1 << 21)
+#define BIT_CMD_READ_CEATA_DEVICE		(1 << 22)
+#define BIT_CMD_CCS_EXPECTED			(1 << 23)
+#define BIT_CMD_ENABLE_BOOT			(1 << 24)
+#define BIT_CMD_EXPECT_BOOT_ACK			(1 << 25)
+#define BIT_CMD_DISABLE_BOOT			(1 << 26)
+#define BIT_CMD_MANDATORY_BOOT			(0 << 27)
+#define BIT_CMD_ALTERNATE_BOOT			(1 << 27)
+#define BIT_CMD_VOLT_SWITCH			(1 << 28)
+#define BIT_CMD_USE_HOLD_REG			(1 << 29)
+#define BIT_CMD_START				(1 << 31)
+
+#define MMC_INT_EBE			(1 << 15)	/* End-bit Err */
+#define MMC_INT_SBE			(1 << 13)	/* Start-bit  Err */
+#define MMC_INT_HLE			(1 << 12)	/* Hardware-lock Err */
+#define MMC_INT_FRUN			(1 << 11)	/* FIFO UN/OV RUN */
+#define MMC_INT_DRT			(1 << 9)	/* Data timeout */
+#define MMC_INT_RTO			(1 << 8)	/* Response timeout */
+#define MMC_INT_DCRC			(1 << 7)	/* Data CRC err */
+#define MMC_INT_RCRC			(1 << 6)	/* Response CRC err */
+#define MMC_INT_RXDR			(1 << 5)
+#define MMC_INT_TXDR			(1 << 4)
+#define MMC_INT_DTO			(1 << 3)	/* Data trans over */
+#define MMC_INT_CMD_DONE		(1 << 2)
+#define MMC_INT_RE			(1 << 1)
+
+#define EMMC_FIX_RCA				6
+
+/* bits in MMC0_CTRL */
+#define MMC_CTRL_RESET				(1 << 0)
+#define MMC_FIFO_RESET				(1 << 1)
+#define MMC_DMA_RESET				(1 << 2)
+#define MMC_INT_EN				(1 << 4)
+#define MMC_DMA_EN				(1 << 25)
+
+#define MMC_STS_DATA_BUSY			(1 << 9)
+
+#define MMC_STATUS_CURRENT_STATE_MASK	(0xf << 9)
+#define MMC_STATUS_CURRENT_STATE_SHIFT	9
+#define MMC_STATUS_READY_FOR_DATA	(1 << 8)
+#define MMC_STATUS_SWITCH_ERROR		(1 << 7)
+
+#define MMC_STATE_IDLE			0
+#define MMC_STATE_READY			1
+#define MMC_STATE_IDENT			2
+#define MMC_STATE_STBY			3
+#define MMC_STATE_TRAN			4
+#define MMC_STATE_DATA			5
+#define MMC_STATE_RCV			6
+#define MMC_STATE_PRG			7
+#define MMC_STATE_DIS			8
+#define MMC_STATE_BTST			9
+#define MMC_STATE_SLP			10
+
+#define EXT_CSD_CACHE_CTRL		33
+#define EXT_CSD_PARTITION_CONFIG	179
+
+#define PART_CFG_BOOT_PARTITION1_ENABLE	(1 << 3)
+#define PART_CFG_PARTITION1_ACCESS	(1 << 0)
+
+#define MMC_IDMAC_ENABLE			(1 << 7)
+#define MMC_IDMAC_FB				(1 << 1)
+#define MMC_IDMAC_SWRESET			(1 << 0)
+
+#define MMC_FIFO_TWMARK(x)			(x & 0xfff)
+#define MMC_FIFO_RWMARK(x)			((x & 0x1ff) << 16)
+#define MMC_DMA_BURST_SIZE(x)			((x & 0x7) << 28)
+
+#define MMC_CARD_RD_THR(x)			((x & 0xfff) << 16)
+#define MMC_CARD_RD_THR_EN			(1 << 0)
+
+extern int init_mmc(void);
+extern int mmc0_read(unsigned long, size_t, unsigned long, uint32_t);
+extern int mmc0_write(unsigned long, size_t, unsigned long, uint32_t);
+
+#endif /* __DW_MMC_H */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hi6220.h b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220.h
new file mode 100644
index 0000000..7ec414d
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __HI6220_H__
+#define __HI6220_H__
+
+#include <hi6220_regs_acpu.h>
+#include <hi6220_regs_ao.h>
+#include <hi6220_regs_peri.h>
+#include <hi6220_regs_pmctrl.h>
+
+#include <hisi_mcu.h>
+#include <hisi_sram_map.h>
+
+#define MEDIA_CTRL_BASE				0xf4410000
+#define MEDIA_SUBSYS_CTRL2			(MEDIA_CTRL_BASE + 0x508)
+#define MEDIA_SUBSYS_NOC_DFS			(MEDIA_CTRL_BASE + 0x510)
+#define MEDIA_SUBSYS_CTRL5			(MEDIA_CTRL_BASE + 0x51c)
+
+#define MMC0_BASE				0xf723d000
+#define MMC1_BASE				0xf723e000
+
+#define EDMAC_BASE				0xf7370000
+#define EDMAC_SEC_CTRL				(EDMAC_BASE + 0x694)
+#define EDMAC_AXI_CONF(x)			(EDMAC_BASE + 0x820 + (x << 6))
+
+#define PMUSSI_BASE				0xf8000000
+
+#define TIMER0_BASE				0xf8008000
+#define TIMER00_LOAD				(TIMER0_BASE + 0x000)
+#define TIMER00_VALUE				(TIMER0_BASE + 0x004)
+#define TIMER00_CONTROL				(TIMER0_BASE + 0x008)
+#define TIMER00_BGLOAD				(TIMER0_BASE + 0x018)
+
+#define GPIO0_BASE				0xf8011000
+#define GPIO1_BASE				0xf8012000
+#define GPIO2_BASE				0xf8013000
+#define GPIO3_BASE				0xf8014000
+#define GPIO4_BASE				0xf7020000
+#define GPIO5_BASE				0xf7021000
+#define GPIO6_BASE				0xf7022000
+#define GPIO7_BASE				0xf7023000
+#define GPIO8_BASE				0xf7024000
+#define GPIO9_BASE				0xf7025000
+#define GPIO10_BASE				0xf7026000
+#define GPIO11_BASE				0xf7027000
+#define GPIO12_BASE				0xf7028000
+#define GPIO13_BASE				0xf7029000
+#define GPIO14_BASE				0xf702a000
+#define GPIO15_BASE				0xf702b000
+#define GPIO16_BASE				0xf702c000
+#define GPIO17_BASE				0xf702d000
+#define GPIO18_BASE				0xf702e000
+#define GPIO19_BASE				0xf702f000
+
+extern void init_acpu_dvfs(void);
+
+#endif	/* __HI6220_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_acpu.h b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_acpu.h
new file mode 100644
index 0000000..19dc15d
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_acpu.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __HI6220_REGS_ACPU_H__
+#define __HI6220_REGS_ACPU_H__
+
+#define ACPU_CTRL_BASE				0xF6504000
+
+#define ACPU_SC_CPU_CTRL			(ACPU_CTRL_BASE + 0x000)
+#define ACPU_SC_CPU_STAT			(ACPU_CTRL_BASE + 0x008)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFIL2		(1 << 0)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFIL2_SHIFT		(0)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI0			(1 << 1)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI0_SHIFT		(1)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI1			(1 << 2)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI1_SHIFT		(2)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI2			(1 << 3)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI2_SHIFT		(3)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI3			(1 << 4)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI3_SHIFT		(4)
+#define ACPU_SC_CPU_STAT_A53_1_STANDBYWFIL2		(1 << 8)
+#define ACPU_SC_CPU_STAT_A53_1_STANDBYWFIL2_SHIFT	(8)
+#define ACPU_SC_CPU_STAT_A53_1_STANDBYWFI		(1 << 9)
+#define ACPU_SC_CPU_STAT_A53_1_STANDBYWFI_SHIFT		(9)
+#define ACPU_SC_CPU_STAT_L2FLSHUDONE0			(1 << 16)
+#define ACPU_SC_CPU_STAT_L2FLSHUDONE0_SHIFT		(16)
+#define ACPU_SC_CPU_STAT_L2FLSHUDONE1			(1 << 17)
+#define ACPU_SC_CPU_STAT_L2FLSHUDONE1_SHIFT		(17)
+#define ACPU_SC_CPU_STAT_CCI400_ACTIVE			(1 << 18)
+#define ACPU_SC_CPU_STAT_CCI400_ACTIVE_SHIFT		(18)
+#define ACPU_SC_CPU_STAT_CLK_DIV_STATUS_VD		(1 << 20)
+#define ACPU_SC_CPU_STAT_CLK_DIV_STATUS_VD_SHIFT	(20)
+
+#define ACPU_SC_CLKEN				(ACPU_CTRL_BASE + 0x00c)
+#define HPM_L2_1_CLKEN				(1 << 9)
+#define G_CPU_1_CLKEN				(1 << 8)
+#define HPM_L2_CLKEN				(1 << 1)
+#define G_CPU_CLKEN				(1 << 0)
+
+#define ACPU_SC_CLKDIS				(ACPU_CTRL_BASE + 0x010)
+#define ACPU_SC_CLK_STAT			(ACPU_CTRL_BASE + 0x014)
+#define ACPU_SC_RSTEN				(ACPU_CTRL_BASE + 0x018)
+#define SRST_PRESET1_RSTEN			(1 << 11)
+#define SRST_PRESET0_RSTEN			(1 << 10)
+#define SRST_CLUSTER1_RSTEN			(1 << 9)
+#define SRST_CLUSTER0_RSTEN			(1 << 8)
+#define SRST_L2_HPM_1_RSTEN			(1 << 5)
+#define SRST_AARM_L2_1_RSTEN			(1 << 4)
+#define SRST_L2_HPM_0_RSTEN			(1 << 3)
+#define SRST_AARM_L2_0_RSTEN			(1 << 1)
+#define SRST_CLUSTER1				(SRST_PRESET1_RSTEN | \
+						 SRST_CLUSTER1_RSTEN | \
+						 SRST_L2_HPM_1_RSTEN | \
+						 SRST_AARM_L2_1_RSTEN)
+#define SRST_CLUSTER0				(SRST_PRESET0_RSTEN | \
+						 SRST_CLUSTER0_RSTEN | \
+						 SRST_L2_HPM_0_RSTEN | \
+						 SRST_AARM_L2_0_RSTEN)
+
+#define ACPU_SC_RSTDIS				(ACPU_CTRL_BASE + 0x01c)
+#define ACPU_SC_RST_STAT			(ACPU_CTRL_BASE + 0x020)
+#define ACPU_SC_PDBGUP_MBIST			(ACPU_CTRL_BASE + 0x02c)
+#define PDBGUP_CLUSTER1_SHIFT			8
+
+#define ACPU_SC_VD_CTRL				(ACPU_CTRL_BASE + 0x054)
+#define ACPU_SC_VD_MASK_PATTERN_CTRL		(ACPU_CTRL_BASE + 0x058)
+#define ACPU_SC_VD_MASK_PATTERN_VAL		(0xCCB << 12)
+#define ACPU_SC_VD_MASK_PATTERN_MASK		((0x1 << 13) - 1)
+
+#define ACPU_SC_VD_DLY_FIXED_CTRL		(ACPU_CTRL_BASE + 0x05c)
+#define ACPU_SC_VD_DLY_TABLE0_CTRL		(ACPU_CTRL_BASE + 0x060)
+#define ACPU_SC_VD_DLY_TABLE1_CTRL		(ACPU_CTRL_BASE + 0x064)
+#define ACPU_SC_VD_DLY_TABLE2_CTRL		(ACPU_CTRL_BASE + 0x068)
+#define ACPU_SC_VD_HPM_CTRL			(ACPU_CTRL_BASE + 0x06c)
+#define ACPU_SC_A53_CLUSTER_MTCMOS_EN		(ACPU_CTRL_BASE + 0x088)
+#define PW_MTCMOS_EN_A53_1_EN			(1 << 1)
+#define PW_MTCMOS_EN_A53_0_EN			(1 << 0)
+
+#define ACPU_SC_A53_CLUSTER_MTCMOS_STA		(ACPU_CTRL_BASE + 0x090)
+#define ACPU_SC_A53_CLUSTER_ISO_EN		(ACPU_CTRL_BASE + 0x098)
+#define PW_ISO_A53_1_EN				(1 << 1)
+#define PW_ISO_A53_0_EN				(1 << 0)
+
+#define ACPU_SC_A53_CLUSTER_ISO_DIS		(ACPU_CTRL_BASE + 0x09c)
+#define ACPU_SC_A53_CLUSTER_ISO_STA		(ACPU_CTRL_BASE + 0x0a0)
+#define ACPU_SC_A53_1_MTCMOS_TIMER		(ACPU_CTRL_BASE + 0x0b4)
+#define ACPU_SC_A53_0_MTCMOS_TIMER		(ACPU_CTRL_BASE + 0x0bc)
+#define ACPU_SC_A53_x_MTCMOS_TIMER(x)		((x) ? ACPU_SC_A53_1_MTCMOS_TIMER : ACPU_SC_A53_0_MTCMOS_TIMER)
+
+#define ACPU_SC_CPU0_CTRL			(ACPU_CTRL_BASE + 0x100)
+#define CPU_CTRL_AARCH64_MODE			(1 << 7)
+
+#define ACPU_SC_CPU0_STAT			(ACPU_CTRL_BASE + 0x104)
+#define ACPU_SC_CPU0_CLKEN			(ACPU_CTRL_BASE + 0x108)
+#define CPU_CLKEN_HPM				(1 << 1)
+
+#define ACPU_SC_CPU0_CLK_STAT			(ACPU_CTRL_BASE + 0x110)
+
+#define ACPU_SC_CPU0_RSTEN			(ACPU_CTRL_BASE + 0x114)
+#define ACPU_SC_CPU0_RSTDIS			(ACPU_CTRL_BASE + 0x118)
+#define ACPU_SC_CPU0_MTCMOS_EN			(ACPU_CTRL_BASE + 0x120)
+#define CPU_MTCMOS_PW				(1 << 0)
+
+#define ACPU_SC_CPU0_PW_ISOEN			(ACPU_CTRL_BASE + 0x130)
+#define CPU_PW_ISO				(1 << 0)
+
+#define ACPU_SC_CPU0_PW_ISODIS			(ACPU_CTRL_BASE + 0x134)
+#define ACPU_SC_CPU0_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x138)
+#define ACPU_SC_CPU0_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x154)
+#define CPU_MTCMOS_TIMER_STA			(1 << 0)
+
+#define ACPU_SC_CPU0_RVBARADDR			(ACPU_CTRL_BASE + 0x158)
+#define ACPU_SC_CPU1_CTRL			(ACPU_CTRL_BASE + 0x200)
+#define ACPU_SC_CPU1_STAT			(ACPU_CTRL_BASE + 0x204)
+#define ACPU_SC_CPU1_CLKEN			(ACPU_CTRL_BASE + 0x208)
+#define ACPU_SC_CPU1_CLK_STAT			(ACPU_CTRL_BASE + 0x210)
+#define ACPU_SC_CPU1_RSTEN			(ACPU_CTRL_BASE + 0x214)
+#define ACPU_SC_CPU1_RSTDIS			(ACPU_CTRL_BASE + 0x218)
+#define ACPU_SC_CPU1_MTCMOS_EN			(ACPU_CTRL_BASE + 0x220)
+#define ACPU_SC_CPU1_PW_ISODIS			(ACPU_CTRL_BASE + 0x234)
+#define ACPU_SC_CPU1_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x238)
+#define ACPU_SC_CPU1_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x254)
+#define ACPU_SC_CPU1_RVBARADDR			(ACPU_CTRL_BASE + 0x258)
+#define ACPU_SC_CPU2_CTRL			(ACPU_CTRL_BASE + 0x300)
+#define ACPU_SC_CPU2_STAT			(ACPU_CTRL_BASE + 0x304)
+#define ACPU_SC_CPU2_CLKEN			(ACPU_CTRL_BASE + 0x308)
+#define ACPU_SC_CPU2_CLK_STAT			(ACPU_CTRL_BASE + 0x310)
+#define ACPU_SC_CPU2_RSTEN			(ACPU_CTRL_BASE + 0x314)
+#define ACPU_SC_CPU2_RSTDIS			(ACPU_CTRL_BASE + 0x318)
+#define ACPU_SC_CPU2_MTCMOS_EN			(ACPU_CTRL_BASE + 0x320)
+#define ACPU_SC_CPU2_PW_ISODIS			(ACPU_CTRL_BASE + 0x334)
+#define ACPU_SC_CPU2_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x338)
+#define ACPU_SC_CPU2_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x354)
+#define ACPU_SC_CPU2_RVBARADDR			(ACPU_CTRL_BASE + 0x358)
+#define ACPU_SC_CPU3_CTRL			(ACPU_CTRL_BASE + 0x400)
+#define ACPU_SC_CPU3_STAT			(ACPU_CTRL_BASE + 0x404)
+#define ACPU_SC_CPU3_CLKEN			(ACPU_CTRL_BASE + 0x408)
+#define ACPU_SC_CPU3_CLK_STAT			(ACPU_CTRL_BASE + 0x410)
+#define ACPU_SC_CPU3_RSTEN			(ACPU_CTRL_BASE + 0x414)
+#define ACPU_SC_CPU3_RSTDIS			(ACPU_CTRL_BASE + 0x418)
+#define ACPU_SC_CPU3_MTCMOS_EN			(ACPU_CTRL_BASE + 0x420)
+#define ACPU_SC_CPU3_PW_ISODIS			(ACPU_CTRL_BASE + 0x434)
+#define ACPU_SC_CPU3_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x438)
+#define ACPU_SC_CPU3_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x454)
+#define ACPU_SC_CPU3_RVBARADDR			(ACPU_CTRL_BASE + 0x458)
+#define ACPU_SC_CPU4_CTRL			(ACPU_CTRL_BASE + 0x500)
+#define ACPU_SC_CPU4_STAT			(ACPU_CTRL_BASE + 0x504)
+#define ACPU_SC_CPU4_CLKEN			(ACPU_CTRL_BASE + 0x508)
+#define ACPU_SC_CPU4_CLK_STAT			(ACPU_CTRL_BASE + 0x510)
+#define ACPU_SC_CPU4_RSTEN			(ACPU_CTRL_BASE + 0x514)
+#define ACPU_SC_CPU4_RSTDIS			(ACPU_CTRL_BASE + 0x518)
+#define ACPU_SC_CPU4_MTCMOS_EN			(ACPU_CTRL_BASE + 0x520)
+#define ACPU_SC_CPU4_PW_ISODIS			(ACPU_CTRL_BASE + 0x534)
+#define ACPU_SC_CPU4_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x538)
+#define ACPU_SC_CPU4_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x554)
+#define ACPU_SC_CPU4_RVBARADDR			(ACPU_CTRL_BASE + 0x558)
+#define ACPU_SC_CPU5_CTRL			(ACPU_CTRL_BASE + 0x600)
+#define ACPU_SC_CPU5_STAT			(ACPU_CTRL_BASE + 0x604)
+#define ACPU_SC_CPU5_CLKEN			(ACPU_CTRL_BASE + 0x608)
+#define ACPU_SC_CPU5_CLK_STAT			(ACPU_CTRL_BASE + 0x610)
+#define ACPU_SC_CPU5_RSTEN			(ACPU_CTRL_BASE + 0x614)
+#define ACPU_SC_CPU5_RSTDIS			(ACPU_CTRL_BASE + 0x618)
+#define ACPU_SC_CPU5_MTCMOS_EN			(ACPU_CTRL_BASE + 0x620)
+#define ACPU_SC_CPU5_PW_ISODIS			(ACPU_CTRL_BASE + 0x634)
+#define ACPU_SC_CPU5_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x638)
+#define ACPU_SC_CPU5_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x654)
+#define ACPU_SC_CPU5_RVBARADDR			(ACPU_CTRL_BASE + 0x658)
+#define ACPU_SC_CPU6_CTRL			(ACPU_CTRL_BASE + 0x700)
+#define ACPU_SC_CPU6_STAT			(ACPU_CTRL_BASE + 0x704)
+#define ACPU_SC_CPU6_CLKEN			(ACPU_CTRL_BASE + 0x708)
+#define ACPU_SC_CPU6_CLK_STAT			(ACPU_CTRL_BASE + 0x710)
+#define ACPU_SC_CPU6_RSTEN			(ACPU_CTRL_BASE + 0x714)
+#define ACPU_SC_CPU6_RSTDIS			(ACPU_CTRL_BASE + 0x718)
+#define ACPU_SC_CPU6_MTCMOS_EN			(ACPU_CTRL_BASE + 0x720)
+#define ACPU_SC_CPU6_PW_ISODIS			(ACPU_CTRL_BASE + 0x734)
+#define ACPU_SC_CPU6_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x738)
+#define ACPU_SC_CPU6_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x754)
+#define ACPU_SC_CPU6_RVBARADDR			(ACPU_CTRL_BASE + 0x758)
+#define ACPU_SC_CPU7_CTRL			(ACPU_CTRL_BASE + 0x800)
+#define ACPU_SC_CPU7_STAT			(ACPU_CTRL_BASE + 0x804)
+#define ACPU_SC_CPU7_CLKEN			(ACPU_CTRL_BASE + 0x808)
+#define ACPU_SC_CPU7_CLK_STAT			(ACPU_CTRL_BASE + 0x810)
+#define ACPU_SC_CPU7_RSTEN			(ACPU_CTRL_BASE + 0x814)
+#define ACPU_SC_CPU7_RSTDIS			(ACPU_CTRL_BASE + 0x818)
+#define ACPU_SC_CPU7_MTCMOS_EN			(ACPU_CTRL_BASE + 0x820)
+#define ACPU_SC_CPU7_PW_ISODIS			(ACPU_CTRL_BASE + 0x834)
+#define ACPU_SC_CPU7_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x838)
+#define ACPU_SC_CPU7_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x854)
+#define ACPU_SC_CPU7_RVBARADDR			(ACPU_CTRL_BASE + 0x858)
+#define ACPU_SC_CPUx_CTRL(x)			((x < 8) ? (ACPU_SC_CPU0_CTRL + 0x100 * x) : ACPU_SC_CPU0_CTRL)
+#define ACPU_SC_CPUx_STAT(x)			((x < 8) ? (ACPU_SC_CPU0_STAT + 0x100 * x) : ACPU_SC_CPU0_STAT)
+#define ACPU_SC_CPUx_CLKEN(x)			((x < 8) ? (ACPU_SC_CPU0_CLKEN + 0x100 * x) : ACPU_SC_CPU0_CLKEN)
+#define ACPU_SC_CPUx_CLK_STAT(x)		((x < 8) ? (ACPU_SC_CPU0_CLK_STAT + 0x100 *x) : ACPU_SC_CPU0_CLK_STAT)
+#define ACPU_SC_CPUx_RSTEN(x)			((x < 8) ? (ACPU_SC_CPU0_RSTEN + 0x100 * x) : ACPU_SC_CPU0_RSTEN)
+#define ACPU_SC_CPUx_RSTDIS(x)			((x < 8) ? (ACPU_SC_CPU0_RSTDIS + 0x100 * x) : ACPU_SC_CPU0_RSTDIS)
+#define ACPU_SC_CPUx_MTCMOS_EN(x)		((x < 8) ? (ACPU_SC_CPU0_MTCMOS_EN + 0x100 * x) : ACPU_SC_CPU0_MTCMOS_EN)
+#define ACPU_SC_CPUx_PW_ISODIS(x)		((x < 8) ? (ACPU_SC_CPU0_PW_ISODIS + 0x100 * x) : ACPU_SC_CPU0_PW_ISODIS)
+#define ACPU_SC_CPUx_PW_ISO_STAT(x)		((x < 8) ? (ACPU_SC_CPU0_PW_ISO_STAT + 0x100 * x) : ACPU_SC_CPU0_PW_ISO_STAT)
+#define ACPU_SC_CPUx_MTCMOS_TIMER_STAT(x)	((x < 8) ? (ACPU_SC_CPU0_MTCMOS_TIMER_STAT + 0x100 * x) : ACPU_SC_CPU0_MTCMOS_TIMER_STAT)
+#define ACPU_SC_CPUx_RVBARADDR(x)		((x < 8) ? (ACPU_SC_CPU0_RVBARADDR + 0x100 * x) : ACPU_SC_CPU0_RVBARADDR)
+
+#define ACPU_SC_CPU_STAT_CLKDIV_VD_MASK		(3 << 20)
+
+#define ACPU_SC_VD_CTRL_TUNE_EN_DIF		(1 << 0)
+#define ACPU_SC_VD_CTRL_TUNE_EN_DIF_SHIFT	(0)
+#define ACPU_SC_VD_CTRL_TUNE			(1 << 1)
+#define ACPU_SC_VD_CTRL_TUNE_SHIFT		(1)
+#define ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF	(1 << 7)
+#define ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF_SHIFT	(7)
+#define ACPU_SC_VD_CTRL_CALIBRATE_EN_INI	(1 << 8)
+#define ACPU_SC_VD_CTRL_CALIBRATE_EN_INI_SHIFT	(8)
+#define ACPU_SC_VD_CTRL_CLK_DIS_CNT_CLR		(1 << 9)
+#define ACPU_SC_VD_CTRL_CLK_DIS_CNT_CLR_SHIFT	(9)
+#define ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN		(1 << 10)
+#define ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN_SHIFT	(10)
+#define ACPU_SC_VD_CTRL_TUNE_EN_INT		(1 << 11)
+#define ACPU_SC_VD_CTRL_TUNE_EN_INT_SHIFT	(11)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE0		(1 << 12)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE0_MASK	(0xf << 12)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE0_SHIFT	(12)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE1		(1 << 16)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE1_MASK	(0xf << 16)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE1_SHIFT	(16)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE2		(1 << 20)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE2_MASK	(0xf << 20)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE2_SHIFT	(20)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE3		(1 << 24)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE3_MASK	(0xf << 24)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE3_SHIFT	(24)
+#define ACPU_SC_VD_CTRL_FORCE_CLK_EN		(1 << 28)
+#define ACPU_SC_VD_CTRL_FORCE_CLK_EN_SHIFT	(28)
+#define ACPU_SC_VD_CTRL_DIV_EN_DIF		(1 << 29)
+#define ACPU_SC_VD_CTRL_DIV_EN_DIF_SHIFT	(29)
+
+#define ACPU_SC_VD_SHIFT_TABLE_TUNE_VAL			\
+	((0x1 << ACPU_SC_VD_CTRL_SHIFT_TABLE0_SHIFT) | 	\
+	 (0x3 << ACPU_SC_VD_CTRL_SHIFT_TABLE1_SHIFT) | 	\
+	 (0x5 << ACPU_SC_VD_CTRL_SHIFT_TABLE2_SHIFT) | 	\
+	 (0x6 << ACPU_SC_VD_CTRL_SHIFT_TABLE3_SHIFT) | 	\
+         (0x7 << ACPU_SC_VD_CTRL_TUNE_SHIFT))
+
+#define ACPU_SC_VD_SHIFT_TABLE_TUNE_MASK		\
+	((0xF << ACPU_SC_VD_CTRL_SHIFT_TABLE0_SHIFT) |	\
+	 (0xF << ACPU_SC_VD_CTRL_SHIFT_TABLE1_SHIFT) |	\
+	 (0xF << ACPU_SC_VD_CTRL_SHIFT_TABLE2_SHIFT) |	\
+	 (0xF << ACPU_SC_VD_CTRL_SHIFT_TABLE3_SHIFT) |	\
+	 (0x3F << ACPU_SC_VD_CTRL_TUNE_SHIFT))
+
+#define ACPU_SC_VD_HPM_CTRL_OSC_DIV		(1 << 0)
+#define ACPU_SC_VD_HPM_CTRL_OSC_DIV_SHIFT	(0)
+#define ACPU_SC_VD_HPM_CTRL_OSC_DIV_MASK	(0x000000FF)
+#define ACPU_SC_VD_HPM_CTRL_DLY_EXP		(1 << 8)
+#define ACPU_SC_VD_HPM_CTRL_DLY_EXP_SHIFT	(8)
+#define ACPU_SC_VD_HPM_CTRL_DLY_EXP_MASK	(0x001FFF00)
+
+#define HPM_OSC_DIV_VAL \
+	(0x56 << ACPU_SC_VD_HPM_CTRL_OSC_DIV_SHIFT)
+#define HPM_OSC_DIV_MASK \
+	(ACPU_SC_VD_HPM_CTRL_OSC_DIV_MASK)
+
+#define HPM_DLY_EXP_VAL \
+	(0xC7A << ACPU_SC_VD_HPM_CTRL_DLY_EXP_SHIFT)
+#define HPM_DLY_EXP_MASK \
+	(ACPU_SC_VD_HPM_CTRL_DLY_EXP_MASK)
+
+#define ACPU_SC_VD_EN_ASIC_VAL					\
+	((0x0 << ACPU_SC_VD_CTRL_FORCE_CLK_EN_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_CALIBRATE_EN_INI_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF_SHIFT) |	\
+	 (0X0 << ACPU_SC_VD_CTRL_DIV_EN_DIF_SHIFT) |		\
+	 (0X0 << ACPU_SC_VD_CTRL_TUNE_EN_INT_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_TUNE_EN_DIF_SHIFT))
+
+#define ACPU_SC_VD_EN_SFT_VAL					\
+	((0x0 << ACPU_SC_VD_CTRL_FORCE_CLK_EN_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_CALIBRATE_EN_INI_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_DIV_EN_DIF_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_TUNE_EN_INT_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_TUNE_EN_DIF_SHIFT))
+
+#define ACPU_SC_VD_EN_MASK					\
+	((0x1 << ACPU_SC_VD_CTRL_FORCE_CLK_EN_SHIFT) |		\
+	 (0x1 << ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN_SHIFT) |	\
+	 (0x1 << ACPU_SC_VD_CTRL_CALIBRATE_EN_INI_SHIFT) |	\
+	 (0x1 << ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF_SHIFT) |	\
+	 (0x1 << ACPU_SC_VD_CTRL_DIV_EN_DIF_SHIFT) |		\
+	 (0x1 << ACPU_SC_VD_CTRL_TUNE_EN_INT_SHIFT) |		\
+	 (0x1 << ACPU_SC_VD_CTRL_TUNE_EN_DIF_SHIFT))
+
+#endif /* __HI6220_REGS_ACPU_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_ao.h b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_ao.h
new file mode 100644
index 0000000..448d18e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_ao.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __HI6220_AO_H__
+#define __HI6220_AO_H__
+
+#define AO_CTRL_BASE				0xF7800000
+
+#define AO_SC_SYS_CTRL0				(AO_CTRL_BASE + 0x000)
+#define AO_SC_SYS_CTRL1				(AO_CTRL_BASE + 0x004)
+#define AO_SC_SYS_CTRL2				(AO_CTRL_BASE + 0x008)
+#define AO_SC_SYS_STAT0				(AO_CTRL_BASE + 0x010)
+#define AO_SC_SYS_STAT1				(AO_CTRL_BASE + 0x014)
+#define AO_SC_MCU_IMCTRL			(AO_CTRL_BASE + 0x018)
+#define AO_SC_MCU_IMSTAT			(AO_CTRL_BASE + 0x01C)
+#define AO_SC_SECONDRY_INT_EN0			(AO_CTRL_BASE + 0x044)
+#define AO_SC_SECONDRY_INT_STATR0		(AO_CTRL_BASE + 0x048)
+#define AO_SC_SECONDRY_INT_STATM0		(AO_CTRL_BASE + 0x04C)
+#define AO_SC_MCU_WKUP_INT_EN6			(AO_CTRL_BASE + 0x054)
+#define AO_SC_MCU_WKUP_INT_STATR6		(AO_CTRL_BASE + 0x058)
+#define AO_SC_MCU_WKUP_INT_STATM6		(AO_CTRL_BASE + 0x05C)
+#define AO_SC_MCU_WKUP_INT_EN5			(AO_CTRL_BASE + 0x064)
+#define AO_SC_MCU_WKUP_INT_STATR5		(AO_CTRL_BASE + 0x068)
+#define AO_SC_MCU_WKUP_INT_STATM5		(AO_CTRL_BASE + 0x06C)
+#define AO_SC_MCU_WKUP_INT_EN4			(AO_CTRL_BASE + 0x094)
+#define AO_SC_MCU_WKUP_INT_STATR4		(AO_CTRL_BASE + 0x098)
+#define AO_SC_MCU_WKUP_INT_STATM4		(AO_CTRL_BASE + 0x09C)
+#define AO_SC_MCU_WKUP_INT_EN0			(AO_CTRL_BASE + 0x0A8)
+#define AO_SC_MCU_WKUP_INT_STATR0		(AO_CTRL_BASE + 0x0AC)
+#define AO_SC_MCU_WKUP_INT_STATM0		(AO_CTRL_BASE + 0x0B0)
+#define AO_SC_MCU_WKUP_INT_EN1			(AO_CTRL_BASE + 0x0B4)
+#define AO_SC_MCU_WKUP_INT_STATR1		(AO_CTRL_BASE + 0x0B8)
+#define AO_SC_MCU_WKUP_INT_STATM1		(AO_CTRL_BASE + 0x0BC)
+#define AO_SC_INT_STATR				(AO_CTRL_BASE + 0x0C4)
+#define AO_SC_INT_STATM				(AO_CTRL_BASE + 0x0C8)
+#define AO_SC_INT_CLEAR				(AO_CTRL_BASE + 0x0CC)
+#define AO_SC_INT_EN_SET			(AO_CTRL_BASE + 0x0D0)
+#define AO_SC_INT_EN_DIS			(AO_CTRL_BASE + 0x0D4)
+#define AO_SC_INT_EN_STAT			(AO_CTRL_BASE + 0x0D8)
+#define AO_SC_INT_STATR1			(AO_CTRL_BASE + 0x0E4)
+#define AO_SC_INT_STATM1			(AO_CTRL_BASE + 0x0E8)
+#define AO_SC_INT_CLEAR1			(AO_CTRL_BASE + 0x0EC)
+#define AO_SC_INT_EN_SET1			(AO_CTRL_BASE + 0x0F0)
+#define AO_SC_INT_EN_DIS1			(AO_CTRL_BASE + 0x0F4)
+#define AO_SC_INT_EN_STAT1			(AO_CTRL_BASE + 0x0F8)
+#define AO_SC_TIMER_EN0				(AO_CTRL_BASE + 0x1D0)
+#define AO_SC_TIMER_EN1				(AO_CTRL_BASE + 0x1D4)
+#define AO_SC_TIMER_EN4				(AO_CTRL_BASE + 0x1F0)
+#define AO_SC_TIMER_EN5				(AO_CTRL_BASE + 0x1F4)
+#define AO_SC_MCU_SUBSYS_CTRL0			(AO_CTRL_BASE + 0x400)
+#define AO_SC_MCU_SUBSYS_CTRL1			(AO_CTRL_BASE + 0x404)
+#define AO_SC_MCU_SUBSYS_CTRL2			(AO_CTRL_BASE + 0x408)
+#define AO_SC_MCU_SUBSYS_CTRL3			(AO_CTRL_BASE + 0x40C)
+#define AO_SC_MCU_SUBSYS_CTRL4			(AO_CTRL_BASE + 0x410)
+#define AO_SC_MCU_SUBSYS_CTRL5			(AO_CTRL_BASE + 0x414)
+#define AO_SC_MCU_SUBSYS_CTRL6			(AO_CTRL_BASE + 0x418)
+#define AO_SC_MCU_SUBSYS_CTRL7			(AO_CTRL_BASE + 0x41C)
+#define AO_SC_MCU_SUBSYS_STAT0			(AO_CTRL_BASE + 0x440)
+#define AO_SC_MCU_SUBSYS_STAT1			(AO_CTRL_BASE + 0x444)
+#define AO_SC_MCU_SUBSYS_STAT2			(AO_CTRL_BASE + 0x448)
+#define AO_SC_MCU_SUBSYS_STAT3			(AO_CTRL_BASE + 0x44C)
+#define AO_SC_MCU_SUBSYS_STAT4			(AO_CTRL_BASE + 0x450)
+#define AO_SC_MCU_SUBSYS_STAT5			(AO_CTRL_BASE + 0x454)
+#define AO_SC_MCU_SUBSYS_STAT6			(AO_CTRL_BASE + 0x458)
+#define AO_SC_MCU_SUBSYS_STAT7			(AO_CTRL_BASE + 0x45C)
+#define AO_SC_PERIPH_CLKEN4			(AO_CTRL_BASE + 0x630)
+#define AO_SC_PERIPH_CLKDIS4			(AO_CTRL_BASE + 0x634)
+#define AO_SC_PERIPH_CLKSTAT4			(AO_CTRL_BASE + 0x638)
+#define AO_SC_PERIPH_CLKEN5			(AO_CTRL_BASE + 0x63C)
+#define AO_SC_PERIPH_CLKDIS5			(AO_CTRL_BASE + 0x640)
+#define AO_SC_PERIPH_CLKSTAT5			(AO_CTRL_BASE + 0x644)
+#define AO_SC_PERIPH_RSTEN4			(AO_CTRL_BASE + 0x6F0)
+#define AO_SC_PERIPH_RSTDIS4			(AO_CTRL_BASE + 0x6F4)
+#define AO_SC_PERIPH_RSTSTAT4			(AO_CTRL_BASE + 0x6F8)
+#define AO_SC_PERIPH_RSTEN5			(AO_CTRL_BASE + 0x6FC)
+#define AO_SC_PERIPH_RSTDIS5			(AO_CTRL_BASE + 0x700)
+#define AO_SC_PERIPH_RSTSTAT5			(AO_CTRL_BASE + 0x704)
+#define AO_SC_PW_CLKEN0				(AO_CTRL_BASE + 0x800)
+#define AO_SC_PW_CLKDIS0			(AO_CTRL_BASE + 0x804)
+#define AO_SC_PW_CLK_STAT0			(AO_CTRL_BASE + 0x808)
+#define AO_SC_PW_RSTEN0				(AO_CTRL_BASE + 0x810)
+#define AO_SC_PW_RSTDIS0			(AO_CTRL_BASE + 0x814)
+#define AO_SC_PW_RST_STAT0			(AO_CTRL_BASE + 0x818)
+#define AO_SC_PW_ISOEN0				(AO_CTRL_BASE + 0x820)
+#define AO_SC_PW_ISODIS0			(AO_CTRL_BASE + 0x824)
+#define AO_SC_PW_ISO_STAT0			(AO_CTRL_BASE + 0x828)
+#define AO_SC_PW_MTCMOS_EN0			(AO_CTRL_BASE + 0x830)
+#define AO_SC_PW_MTCMOS_DIS0			(AO_CTRL_BASE + 0x834)
+#define AO_SC_PW_MTCMOS_STAT0			(AO_CTRL_BASE + 0x838)
+#define AO_SC_PW_MTCMOS_ACK_STAT0		(AO_CTRL_BASE + 0x83C)
+#define AO_SC_PW_MTCMOS_TIMEOUT_STAT0		(AO_CTRL_BASE + 0x840)
+#define AO_SC_PW_STAT0				(AO_CTRL_BASE + 0x850)
+#define AO_SC_PW_STAT1				(AO_CTRL_BASE + 0x854)
+#define AO_SC_SYSTEST_STAT			(AO_CTRL_BASE + 0x880)
+#define AO_SC_SYSTEST_SLICER_CNT0		(AO_CTRL_BASE + 0x890)
+#define AO_SC_SYSTEST_SLICER_CNT1		(AO_CTRL_BASE + 0x894)
+#define AO_SC_PW_CTRL1				(AO_CTRL_BASE + 0x8C8)
+#define AO_SC_PW_CTRL				(AO_CTRL_BASE + 0x8CC)
+#define AO_SC_MCPU_VOTEEN			(AO_CTRL_BASE + 0x8D0)
+#define AO_SC_MCPU_VOTEDIS			(AO_CTRL_BASE + 0x8D4)
+#define AO_SC_MCPU_VOTESTAT			(AO_CTRL_BASE + 0x8D8)
+#define AO_SC_MCPU_VOTE_MSK0			(AO_CTRL_BASE + 0x8E0)
+#define AO_SC_MCPU_VOTE_MSK1			(AO_CTRL_BASE + 0x8E4)
+#define AO_SC_MCPU_VOTESTAT0_MSK		(AO_CTRL_BASE + 0x8E8)
+#define AO_SC_MCPU_VOTESTAT1_MSK		(AO_CTRL_BASE + 0x8EC)
+#define AO_SC_PERI_VOTEEN			(AO_CTRL_BASE + 0x8F0)
+#define AO_SC_PERI_VOTEDIS			(AO_CTRL_BASE + 0x8F4)
+#define AO_SC_PERI_VOTESTAT			(AO_CTRL_BASE + 0x8F8)
+#define AO_SC_PERI_VOTE_MSK0			(AO_CTRL_BASE + 0x900)
+#define AO_SC_PERI_VOTE_MSK1			(AO_CTRL_BASE + 0x904)
+#define AO_SC_PERI_VOTESTAT0_MSK		(AO_CTRL_BASE + 0x908)
+#define AO_SC_PERI_VOTESTAT1_MSK		(AO_CTRL_BASE + 0x90C)
+#define AO_SC_ACPU_VOTEEN			(AO_CTRL_BASE + 0x910)
+#define AO_SC_ACPU_VOTEDIS			(AO_CTRL_BASE + 0x914)
+#define AO_SC_ACPU_VOTESTAT			(AO_CTRL_BASE + 0x918)
+#define AO_SC_ACPU_VOTE_MSK0			(AO_CTRL_BASE + 0x920)
+#define AO_SC_ACPU_VOTE_MSK1			(AO_CTRL_BASE + 0x924)
+#define AO_SC_ACPU_VOTESTAT0_MSK		(AO_CTRL_BASE + 0x928)
+#define AO_SC_ACPU_VOTESTAT1_MSK		(AO_CTRL_BASE + 0x92C)
+#define AO_SC_MCU_VOTEEN			(AO_CTRL_BASE + 0x930)
+#define AO_SC_MCU_VOTEDIS			(AO_CTRL_BASE + 0x934)
+#define AO_SC_MCU_VOTESTAT			(AO_CTRL_BASE + 0x938)
+#define AO_SC_MCU_VOTE_MSK0			(AO_CTRL_BASE + 0x940)
+#define AO_SC_MCU_VOTE_MSK1			(AO_CTRL_BASE + 0x944)
+#define AO_SC_MCU_VOTESTAT0_MSK			(AO_CTRL_BASE + 0x948)
+#define AO_SC_MCU_VOTESTAT1_MSK			(AO_CTRL_BASE + 0x94C)
+#define AO_SC_MCU_VOTE1EN			(AO_CTRL_BASE + 0x960)
+#define AO_SC_MCU_VOTE1DIS			(AO_CTRL_BASE + 0x964)
+#define AO_SC_MCU_VOTE1STAT			(AO_CTRL_BASE + 0x968)
+#define AO_SC_MCU_VOTE1_MSK0			(AO_CTRL_BASE + 0x970)
+#define AO_SC_MCU_VOTE1_MSK1			(AO_CTRL_BASE + 0x974)
+#define AO_SC_MCU_VOTE1STAT0_MSK		(AO_CTRL_BASE + 0x978)
+#define AO_SC_MCU_VOTE1STAT1_MSK		(AO_CTRL_BASE + 0x97C)
+#define AO_SC_MCU_VOTE2EN			(AO_CTRL_BASE + 0x980)
+#define AO_SC_MCU_VOTE2DIS			(AO_CTRL_BASE + 0x984)
+#define AO_SC_MCU_VOTE2STAT			(AO_CTRL_BASE + 0x988)
+#define AO_SC_MCU_VOTE2_MSK0			(AO_CTRL_BASE + 0x990)
+#define AO_SC_MCU_VOTE2_MSK1			(AO_CTRL_BASE + 0x994)
+#define AO_SC_MCU_VOTE2STAT0_MSK		(AO_CTRL_BASE + 0x998)
+#define AO_SC_MCU_VOTE2STAT1_MSK		(AO_CTRL_BASE + 0x99C)
+#define AO_SC_VOTE_CTRL				(AO_CTRL_BASE + 0x9A0)
+#define AO_SC_VOTE_STAT				(AO_CTRL_BASE + 0x9A4)
+#define AO_SC_ECONUM				(AO_CTRL_BASE + 0xF00)
+#define AO_SCCHIPID				(AO_CTRL_BASE + 0xF10)
+#define AO_SCSOCID				(AO_CTRL_BASE + 0xF1C)
+#define AO_SC_SOC_FPGA_RTL_DEF			(AO_CTRL_BASE + 0xFE0)
+#define AO_SC_SOC_FPGA_PR_DEF			(AO_CTRL_BASE + 0xFE4)
+#define AO_SC_SOC_FPGA_RES_DEF0			(AO_CTRL_BASE + 0xFE8)
+#define AO_SC_SOC_FPGA_RES_DEF1			(AO_CTRL_BASE + 0xFEC)
+#define AO_SC_XTAL_CTRL0			(AO_CTRL_BASE + 0x102)
+#define AO_SC_XTAL_CTRL1			(AO_CTRL_BASE + 0x102)
+#define AO_SC_XTAL_CTRL3			(AO_CTRL_BASE + 0x103)
+#define AO_SC_XTAL_CTRL5			(AO_CTRL_BASE + 0x103)
+#define AO_SC_XTAL_STAT0			(AO_CTRL_BASE + 0x106)
+#define AO_SC_XTAL_STAT1			(AO_CTRL_BASE + 0x107)
+#define AO_SC_EFUSE_CHIPID0			(AO_CTRL_BASE + 0x108)
+#define AO_SC_EFUSE_CHIPID1			(AO_CTRL_BASE + 0x108)
+#define AO_SC_EFUSE_SYS_CTRL			(AO_CTRL_BASE + 0x108)
+#define AO_SC_DEBUG_CTRL1			(AO_CTRL_BASE + 0x128)
+#define AO_SC_DBG_STAT				(AO_CTRL_BASE + 0x12B)
+#define AO_SC_ARM_DBG_KEY0			(AO_CTRL_BASE + 0x12B)
+#define AO_SC_RESERVED31			(AO_CTRL_BASE + 0x13A)
+#define AO_SC_RESERVED32			(AO_CTRL_BASE + 0x13A)
+#define AO_SC_RESERVED33			(AO_CTRL_BASE + 0x13A)
+#define AO_SC_RESERVED34			(AO_CTRL_BASE + 0x13A)
+#define AO_SC_RESERVED35			(AO_CTRL_BASE + 0x13B)
+#define AO_SC_RESERVED36			(AO_CTRL_BASE + 0x13B)
+#define AO_SC_RESERVED37			(AO_CTRL_BASE + 0x13B)
+#define AO_SC_RESERVED38			(AO_CTRL_BASE + 0x13B)
+#define AO_SC_ALWAYSON_SYS_CTRL0		(AO_CTRL_BASE + 0x148)
+#define AO_SC_ALWAYSON_SYS_CTRL1		(AO_CTRL_BASE + 0x148)
+#define AO_SC_ALWAYSON_SYS_CTRL2		(AO_CTRL_BASE + 0x148)
+#define AO_SC_ALWAYSON_SYS_CTRL3		(AO_CTRL_BASE + 0x148)
+#define AO_SC_ALWAYSON_SYS_CTRL10		(AO_CTRL_BASE + 0x14A)
+#define AO_SC_ALWAYSON_SYS_CTRL11		(AO_CTRL_BASE + 0x14A)
+#define AO_SC_ALWAYSON_SYS_STAT0		(AO_CTRL_BASE + 0x14C)
+#define AO_SC_ALWAYSON_SYS_STAT1		(AO_CTRL_BASE + 0x14C)
+#define AO_SC_ALWAYSON_SYS_STAT2		(AO_CTRL_BASE + 0x14C)
+#define AO_SC_ALWAYSON_SYS_STAT3		(AO_CTRL_BASE + 0x14C)
+#define AO_SC_PWUP_TIME0			(AO_CTRL_BASE + 0x188)
+#define AO_SC_PWUP_TIME1			(AO_CTRL_BASE + 0x188)
+#define AO_SC_PWUP_TIME2			(AO_CTRL_BASE + 0x188)
+#define AO_SC_PWUP_TIME3			(AO_CTRL_BASE + 0x188)
+#define AO_SC_PWUP_TIME4			(AO_CTRL_BASE + 0x189)
+#define AO_SC_PWUP_TIME5			(AO_CTRL_BASE + 0x189)
+#define AO_SC_PWUP_TIME6			(AO_CTRL_BASE + 0x189)
+#define AO_SC_PWUP_TIME7			(AO_CTRL_BASE + 0x189)
+#define AO_SC_SECURITY_CTRL1			(AO_CTRL_BASE + 0x1C0)
+#define AO_SC_SYSTEST_SLICER_CNT0		(AO_CTRL_BASE + 0x890)
+#define AO_SC_SYSTEST_SLICER_CNT1		(AO_CTRL_BASE + 0x894)
+
+#define AO_SC_SYS_CTRL0_MODE_NORMAL				0x004
+#define AO_SC_SYS_CTRL0_MODE_MASK				0x007
+
+#define AO_SC_SYS_CTRL1_AARM_WD_RST_CFG				(1 << 0)
+#define AO_SC_SYS_CTRL1_REMAP_SRAM_AARM				(1 << 1)
+#define AO_SC_SYS_CTRL1_EFUSEC_REMAP				(1 << 2)
+#define AO_SC_SYS_CTRL1_EXT_PLL_SEL				(1 << 3)
+#define AO_SC_SYS_CTRL1_MCU_WDG0_RSTMCU_CFG			(1 << 4)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_DE_BOUNCE_CFG			(1 << 6)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_OE_CFG			(1 << 7)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_DE_BOUNCE_CFG			(1 << 8)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_OE_CFG			(1 << 9)
+#define AO_SC_SYS_CTRL1_BUS_DFS_FORE_HD_CFG			(1 << 10)
+#define AO_SC_SYS_CTRL1_BUS_DFS_FORE_HD_CFG1			(1 << 11)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_OE_SFT			(1 << 12)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_OE_SFT			(1 << 13)
+#define AO_SC_SYS_CTRL1_MCU_CLKEN_HARDCFG			(1 << 15)
+#define AO_SC_SYS_CTRL1_AARM_WD_RST_CFG_MSK			(1 << 16)
+#define AO_SC_SYS_CTRL1_REMAP_SRAM_AARM_MSK			(1 << 17)
+#define AO_SC_SYS_CTRL1_EFUSEC_REMAP_MSK			(1 << 18)
+#define AO_SC_SYS_CTRL1_EXT_PLL_SEL_MSK				(1 << 19)
+#define AO_SC_SYS_CTRL1_MCU_WDG0_RSTMCU_CFG_MSK			(1 << 20)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_DE_BOUNCE_CFG_MSK		(1 << 22)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_OE_CFG_MSK			(1 << 23)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_DE_BOUNCE_CFG_MSK		(1 << 24)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_OE_CFG_MSK			(1 << 25)
+#define AO_SC_SYS_CTRL1_BUS_DFS_FORE_HD_CFG_MSK			(1 << 26)
+#define AO_SC_SYS_CTRL1_BUS_DFS_FORE_HD_CFG1_MSK		(1 << 27)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_OE_SFT_MSK			(1 << 28)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_OE_SFT_MSK			(1 << 29)
+#define AO_SC_SYS_CTRL1_MCU_CLKEN_HARDCFG_MSK			(1 << 31)
+
+#define AO_SC_SYS_CTRL2_MCU_SFT_RST_STAT_CLEAR			(1 << 26)
+#define AO_SC_SYS_CTRL2_MCU_WDG0_RST_STAT_CLEAR			(1 << 27)
+#define AO_SC_SYS_CTRL2_TSENSOR_RST_STAT_CLEAR			(1 << 28)
+#define AO_SC_SYS_CTRL2_ACPU_WDG_RST_STAT_CLEAR			(1 << 29)
+#define AO_SC_SYS_CTRL2_MCU_WDG1_RST_STAT_CLEAR			(1 << 30)
+#define AO_SC_SYS_CTRL2_GLB_SRST_STAT_CLEAR			(1 << 31)
+
+#define AO_SC_SYS_STAT0_MCU_RST_STAT				(1 << 25)
+#define AO_SC_SYS_STAT0_MCU_SOFTRST_STAT			(1 << 26)
+#define AO_SC_SYS_STAT0_MCU_WDGRST_STAT				(1 << 27)
+#define AO_SC_SYS_STAT0_TSENSOR_HARDRST_STAT			(1 << 28)
+#define AO_SC_SYS_STAT0_ACPU_WD_GLB_RST_STAT			(1 << 29)
+#define AO_SC_SYS_STAT0_CM3_WDG1_RST_STAT			(1 << 30)
+#define AO_SC_SYS_STAT0_GLB_SRST_STAT				(1 << 31)
+
+#define AO_SC_SYS_STAT1_MODE_STATUS				(1 << 0)
+#define AO_SC_SYS_STAT1_BOOT_SEL_LOCK				(1 << 16)
+#define AO_SC_SYS_STAT1_FUNC_MODE_LOCK				(1 << 17)
+#define AO_SC_SYS_STAT1_BOOT_MODE_LOCK				(1 << 19)
+#define AO_SC_SYS_STAT1_FUN_JTAG_MODE_OUT			(1 << 20)
+#define AO_SC_SYS_STAT1_SECURITY_BOOT_FLG			(1 << 27)
+#define AO_SC_SYS_STAT1_EFUSE_NANDBOOT_MSK			(1 << 28)
+#define AO_SC_SYS_STAT1_EFUSE_NAND_BITWIDE			(1 << 29)
+
+#define AO_SC_PERIPH_RSTDIS4_RESET_MCU_ECTR_N			(1 << 0)
+#define AO_SC_PERIPH_RSTDIS4_RESET_MCU_SYS_N			(1 << 1)
+#define AO_SC_PERIPH_RSTDIS4_RESET_MCU_POR_N			(1 << 2)
+#define AO_SC_PERIPH_RSTDIS4_RESET_MCU_DAP_N			(1 << 3)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_CM3_TIMER0_N		(1 << 4)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_CM3_TIMER1_N		(1 << 5)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_CM3_WDT0_N			(1 << 6)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_CM3_WDT1_N			(1 << 7)
+#define AO_SC_PERIPH_RSTDIS4_HRESET_IPC_S_N			(1 << 8)
+#define AO_SC_PERIPH_RSTDIS4_HRESET_IPC_NS_N			(1 << 9)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_EFUSEC_N			(1 << 10)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_WDT0_N			(1 << 12)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_WDT1_N			(1 << 13)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_WDT2_N			(1 << 14)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER0_N			(1 << 15)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER1_N			(1 << 16)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER2_N			(1 << 17)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER3_N			(1 << 18)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER4_N			(1 << 19)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER5_N			(1 << 20)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER6_N			(1 << 21)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER7_N			(1 << 22)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER8_N			(1 << 23)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_UART0_N			(1 << 24)
+#define AO_SC_PERIPH_RSTDIS4_RESET_RTC0_N			(1 << 25)
+#define AO_SC_PERIPH_RSTDIS4_RESET_RTC1_N			(1 << 26)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N			(1 << 27)
+#define AO_SC_PERIPH_RSTDIS4_RESET_JTAG_AUTH_N			(1 << 28)
+#define AO_SC_PERIPH_RSTDIS4_RESET_CS_DAPB_ON_N			(1 << 29)
+#define AO_SC_PERIPH_RSTDIS4_MDM_SUBSYS_GLB			(1 << 30)
+
+#define AO_SC_PERIPH_CLKEN4_HCLK_MCU				(1 << 0)
+#define AO_SC_PERIPH_CLKEN4_CLK_MCU_DAP				(1 << 3)
+#define AO_SC_PERIPH_CLKEN4_PCLK_CM3_TIMER0			(1 << 4)
+#define AO_SC_PERIPH_CLKEN4_PCLK_CM3_TIMER1			(1 << 5)
+#define AO_SC_PERIPH_CLKEN4_PCLK_CM3_WDT0			(1 << 6)
+#define AO_SC_PERIPH_CLKEN4_PCLK_CM3_WDT1			(1 << 7)
+#define AO_SC_PERIPH_CLKEN4_HCLK_IPC_S				(1 << 8)
+#define AO_SC_PERIPH_CLKEN4_HCLK_IPC_NS				(1 << 9)
+#define AO_SC_PERIPH_CLKEN4_PCLK_EFUSEC				(1 << 10)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TZPC				(1 << 11)
+#define AO_SC_PERIPH_CLKEN4_PCLK_WDT0				(1 << 12)
+#define AO_SC_PERIPH_CLKEN4_PCLK_WDT1				(1 << 13)
+#define AO_SC_PERIPH_CLKEN4_PCLK_WDT2				(1 << 14)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER0				(1 << 15)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER1				(1 << 16)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER2				(1 << 17)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER3				(1 << 18)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER4				(1 << 19)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER5				(1 << 20)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER6				(1 << 21)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER7				(1 << 22)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER8				(1 << 23)
+#define AO_SC_PERIPH_CLKEN4_CLK_UART0				(1 << 24)
+#define AO_SC_PERIPH_CLKEN4_CLK_RTC0				(1 << 25)
+#define AO_SC_PERIPH_CLKEN4_CLK_RTC1				(1 << 26)
+#define AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI				(1 << 27)
+#define AO_SC_PERIPH_CLKEN4_CLK_JTAG_AUTH			(1 << 28)
+#define AO_SC_PERIPH_CLKEN4_CLK_CS_DAPB_ON			(1 << 29)
+#define AO_SC_PERIPH_CLKEN4_CLK_PDM				(1 << 30)
+#define AO_SC_PERIPH_CLKEN4_CLK_SSI_PAD				(1 << 31)
+
+#define AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU			(1 << 0)
+#define AO_SC_PERIPH_CLKEN5_PCLK_EFUSEC_CCPU			(1 << 1)
+#define AO_SC_PERIPH_CLKEN5_HCLK_IPC_CCPU			(1 << 2)
+#define AO_SC_PERIPH_CLKEN5_HCLK_IPC_NS_CCPU			(1 << 3)
+#define AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU			(1 << 16)
+#define AO_SC_PERIPH_CLKEN5_PCLK_EFUSEC_MCU			(1 << 17)
+#define AO_SC_PERIPH_CLKEN5_HCLK_IPC_MCU			(1 << 18)
+#define AO_SC_PERIPH_CLKEN5_HCLK_IPC_NS_MCU			(1 << 19)
+
+#define AO_SC_MCU_SUBSYS_CTRL3_RCLK_3				0x003
+#define AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK			0x007
+#define AO_SC_MCU_SUBSYS_CTRL3_CSSYS_CTRL_PROT			(1 << 3)
+#define AO_SC_MCU_SUBSYS_CTRL3_TCXO_AFC_OEN_CRG			(1 << 4)
+#define AO_SC_MCU_SUBSYS_CTRL3_AOB_IO_SEL18_USIM1		(1 << 8)
+#define AO_SC_MCU_SUBSYS_CTRL3_AOB_IO_SEL18_USIM0		(1 << 9)
+#define AO_SC_MCU_SUBSYS_CTRL3_AOB_IO_SEL18_SD			(1 << 10)
+#define AO_SC_MCU_SUBSYS_CTRL3_MCU_SUBSYS_CTRL3_RESERVED	(1 << 11)
+
+#define PCLK_TIMER1						(1 << 16)
+#define PCLK_TIMER0						(1 << 15)
+
+#endif /* __HI6220_AO_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_peri.h b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_peri.h
new file mode 100644
index 0000000..9b79d5a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_peri.h
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __HI6220_PERI_H__
+#define __HI6220_PERI_H__
+
+#define PERI_BASE				0xF7030000
+
+#define PERI_SC_PERIPH_CTRL1			(PERI_BASE + 0x000)
+#define PERI_SC_PERIPH_CTRL2			(PERI_BASE + 0x004)
+#define PERI_SC_PERIPH_CTRL3			(PERI_BASE + 0x008)
+#define PERI_SC_PERIPH_CTRL4			(PERI_BASE + 0x00c)
+#define PERI_SC_PERIPH_CTRL5			(PERI_BASE + 0x010)
+#define PERI_SC_PERIPH_CTRL6			(PERI_BASE + 0x014)
+#define PERI_SC_PERIPH_CTRL8			(PERI_BASE + 0x018)
+#define PERI_SC_PERIPH_CTRL9			(PERI_BASE + 0x01c)
+#define PERI_SC_PERIPH_CTRL10			(PERI_BASE + 0x020)
+#define PERI_SC_PERIPH_CTRL12			(PERI_BASE + 0x024)
+#define PERI_SC_PERIPH_CTRL13			(PERI_BASE + 0x028)
+#define PERI_SC_PERIPH_CTRL14			(PERI_BASE + 0x02c)
+
+#define PERI_SC_DDR_CTRL0			(PERI_BASE + 0x050)
+#define PERI_SC_PERIPH_STAT1			(PERI_BASE + 0x094)
+
+#define PERI_SC_PERIPH_CLKEN0			(PERI_BASE + 0x200)
+#define PERI_SC_PERIPH_CLKDIS0			(PERI_BASE + 0x204)
+#define PERI_SC_PERIPH_CLKSTAT0			(PERI_BASE + 0x208)
+#define PERI_SC_PERIPH_CLKEN1			(PERI_BASE + 0x210)
+#define PERI_SC_PERIPH_CLKDIS1			(PERI_BASE + 0x214)
+#define PERI_SC_PERIPH_CLKSTAT1			(PERI_BASE + 0x218)
+#define PERI_SC_PERIPH_CLKEN2			(PERI_BASE + 0x220)
+#define PERI_SC_PERIPH_CLKDIS2			(PERI_BASE + 0x224)
+#define PERI_SC_PERIPH_CLKSTAT2			(PERI_BASE + 0x228)
+#define PERI_SC_PERIPH_CLKEN3			(PERI_BASE + 0x230)
+#define PERI_SC_PERIPH_CLKDIS3			(PERI_BASE + 0x234)
+#define PERI_SC_PERIPH_CLKSTAT3			(PERI_BASE + 0x238)
+#define PERI_SC_PERIPH_CLKEN8			(PERI_BASE + 0x240)
+#define PERI_SC_PERIPH_CLKDIS8			(PERI_BASE + 0x244)
+#define PERI_SC_PERIPH_CLKSTAT8			(PERI_BASE + 0x248)
+#define PERI_SC_PERIPH_CLKEN9			(PERI_BASE + 0x250)
+#define PERI_SC_PERIPH_CLKDIS9			(PERI_BASE + 0x254)
+#define PERI_SC_PERIPH_CLKSTAT9			(PERI_BASE + 0x258)
+#define PERI_SC_PERIPH_CLKEN10			(PERI_BASE + 0x260)
+#define PERI_SC_PERIPH_CLKDIS10			(PERI_BASE + 0x264)
+#define PERI_SC_PERIPH_CLKSTAT10		(PERI_BASE + 0x268)
+#define PERI_SC_PERIPH_CLKEN12			(PERI_BASE + 0x270)
+#define PERI_SC_PERIPH_CLKDIS12			(PERI_BASE + 0x274)
+#define PERI_SC_PERIPH_CLKSTAT12		(PERI_BASE + 0x278)
+
+#define PERI_SC_PERIPH_RSTEN0			(PERI_BASE + 0x300)
+#define PERI_SC_PERIPH_RSTDIS0			(PERI_BASE + 0x304)
+#define PERI_SC_PERIPH_RSTSTAT0			(PERI_BASE + 0x308)
+#define PERI_SC_PERIPH_RSTEN1			(PERI_BASE + 0x310)
+#define PERI_SC_PERIPH_RSTDIS1			(PERI_BASE + 0x314)
+#define PERI_SC_PERIPH_RSTSTAT1			(PERI_BASE + 0x318)
+#define PERI_SC_PERIPH_RSTEN2			(PERI_BASE + 0x320)
+#define PERI_SC_PERIPH_RSTDIS2			(PERI_BASE + 0x324)
+#define PERI_SC_PERIPH_RSTSTAT2			(PERI_BASE + 0x328)
+#define PERI_SC_PERIPH_RSTEN3			(PERI_BASE + 0x330)
+#define PERI_SC_PERIPH_RSTDIS3			(PERI_BASE + 0x334)
+#define PERI_SC_PERIPH_RSTSTAT3			(PERI_BASE + 0x338)
+#define PERI_SC_PERIPH_RSTEN8			(PERI_BASE + 0x340)
+#define PERI_SC_PERIPH_RSTDIS8			(PERI_BASE + 0x344)
+#define PERI_SC_PERIPH_RSTSTAT8			(PERI_BASE + 0x338)
+
+#define PERI_SC_CLK_SEL0			(PERI_BASE + 0x400)
+#define PERI_SC_CLKCFG8BIT1			(PERI_BASE + 0x494)
+#define PERI_SC_CLKCFG8BIT2			(PERI_BASE + 0x498)
+#define PERI_SC_RESERVED8_ADDR			(PERI_BASE + 0xd04)
+
+/* PERI_SC_PERIPH_CTRL1 */
+#define PERI_CTRL1_ETR_AXI_CSYSREQ_N		(1 << 0)
+#define PERI_CTRL1_ETR_AXI_CSYSREQ_N		(1 << 0)
+#define PERI_CTRL1_HIFI_INT_MASK		(1 << 1)
+#define PERI_CTRL1_HIFI_ALL_INT_MASK		(1 << 2)
+#define PERI_CTRL1_ETR_AXI_CSYSREQ_N_MSK	(1 << 16)
+#define PERI_CTRL1_HIFI_INT_MASK_MSK		(1 << 17)
+#define PERI_CTRL1_HIFI_ALL_INT_MASK_MSK	(1 << 18)
+
+/* PERI_SC_PERIPH_CTRL2	*/
+#define PERI_CTRL2_MMC_CLK_PHASE_BYPASS_EN_MMC0	(1 << 0)
+#define PERI_CTRL2_MMC_CLK_PHASE_BYPASS_EN_MMC1	(1 << 2)
+#define PERI_CTRL2_NAND_SYS_MEM_SEL		(1 << 6)
+#define PERI_CTRL2_G3D_DDRT_AXI_SEL		(1 << 7)
+#define PERI_CTRL2_GU_MDM_BBP_TESTPIN_SEL	(1 << 8)
+#define PERI_CTRL2_CODEC_SSI_MASTER_CHECK	(1 << 9)
+#define PERI_CTRL2_FUNC_TEST_SOFT		(1 << 12)
+#define PERI_CTRL2_CSSYS_TS_ENABLE		(1 << 15)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_EMA		(1 << 16)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_EMAW		(1 << 20)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_EMAS		(1 << 22)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_RET1N		(1 << 26)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_RET2N		(1 << 27)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_PGEN		(1 << 28)
+
+/* PERI_SC_PERIPH_CTRL3 */
+#define PERI_CTRL3_HIFI_DDR_HARQMEM_ADDR	(1 << 0)
+#define PERI_CTRL3_HIFI_HARQMEMRMP_EN		(1 << 12)
+#define PERI_CTRL3_HARQMEM_SYS_MED_SEL		(1 << 13)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP1		(1 << 14)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP2		(1 << 16)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP3		(1 << 18)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP4		(1 << 20)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP5		(1 << 22)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP6		(1 << 24)
+
+/* PERI_SC_PERIPH_CTRL4 */
+#define PERI_CTRL4_PICO_FSELV			(1 << 0)
+#define PERI_CTRL4_FPGA_EXT_PHY_SEL		(1 << 3)
+#define PERI_CTRL4_PICO_REFCLKSEL		(1 << 4)
+#define PERI_CTRL4_PICO_SIDDQ			(1 << 6)
+#define PERI_CTRL4_PICO_SUSPENDM_SLEEPM		(1 << 7)
+#define PERI_CTRL4_PICO_OGDISABLE		(1 << 8)
+#define PERI_CTRL4_PICO_COMMONONN		(1 << 9)
+#define PERI_CTRL4_PICO_VBUSVLDEXT		(1 << 10)
+#define PERI_CTRL4_PICO_VBUSVLDEXTSEL		(1 << 11)
+#define PERI_CTRL4_PICO_VATESTENB		(1 << 12)
+#define PERI_CTRL4_PICO_SUSPENDM		(1 << 14)
+#define PERI_CTRL4_PICO_SLEEPM			(1 << 15)
+#define PERI_CTRL4_BC11_C			(1 << 16)
+#define PERI_CTRL4_BC11_B			(1 << 17)
+#define PERI_CTRL4_BC11_A			(1 << 18)
+#define PERI_CTRL4_BC11_GND			(1 << 19)
+#define PERI_CTRL4_BC11_FLOAT			(1 << 20)
+#define PERI_CTRL4_OTG_PHY_SEL			(1 << 21)
+#define PERI_CTRL4_USB_OTG_SS_SCALEDOWN_MODE	(1 << 22)
+#define PERI_CTRL4_OTG_DM_PULLDOWN		(1 << 24)
+#define PERI_CTRL4_OTG_DP_PULLDOWN		(1 << 25)
+#define PERI_CTRL4_OTG_IDPULLUP			(1 << 26)
+#define PERI_CTRL4_OTG_DRVBUS			(1 << 27)
+#define PERI_CTRL4_OTG_SESSEND			(1 << 28)
+#define PERI_CTRL4_OTG_BVALID			(1 << 29)
+#define PERI_CTRL4_OTG_AVALID			(1 << 30)
+#define PERI_CTRL4_OTG_VBUSVALID		(1 << 31)
+
+/* PERI_SC_PERIPH_CTRL5 */
+#define PERI_CTRL5_USBOTG_RES_SEL		(1 << 3)
+#define PERI_CTRL5_PICOPHY_ACAENB		(1 << 4)
+#define PERI_CTRL5_PICOPHY_BC_MODE		(1 << 5)
+#define PERI_CTRL5_PICOPHY_CHRGSEL		(1 << 6)
+#define PERI_CTRL5_PICOPHY_VDATSRCEND		(1 << 7)
+#define PERI_CTRL5_PICOPHY_VDATDETENB		(1 << 8)
+#define PERI_CTRL5_PICOPHY_DCDENB		(1 << 9)
+#define PERI_CTRL5_PICOPHY_IDDIG		(1 << 10)
+#define PERI_CTRL5_DBG_MUX			(1 << 11)
+
+/* PERI_SC_PERIPH_CTRL6 */
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_EMA	(1 << 0)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_EMAW	(1 << 4)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_EMAS	(1 << 6)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_RET1N	(1 << 10)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_RET2N	(1 << 11)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_PGEN	(1 << 12)
+
+/* PERI_SC_PERIPH_CTRL8 */
+#define PERI_CTRL8_PICOPHY_TXRISETUNE0		(1 << 0)
+#define PERI_CTRL8_PICOPHY_TXPREEMPAMPTUNE0	(1 << 2)
+#define PERI_CTRL8_PICOPHY_TXRESTUNE0		(1 << 4)
+#define PERI_CTRL8_PICOPHY_TXHSSVTUNE0		(1 << 6)
+#define PERI_CTRL8_PICOPHY_COMPDISTUNE0		(1 << 8)
+#define PERI_CTRL8_PICOPHY_TXPREEMPPULSETUNE0	(1 << 11)
+#define PERI_CTRL8_PICOPHY_OTGTUNE0		(1 << 12)
+#define PERI_CTRL8_PICOPHY_SQRXTUNE0		(1 << 16)
+#define PERI_CTRL8_PICOPHY_TXVREFTUNE0		(1 << 20)
+#define PERI_CTRL8_PICOPHY_TXFSLSTUNE0		(1 << 28)
+
+/* PERI_SC_PERIPH_CTRL9	*/
+#define PERI_CTRL9_PICOPLY_TESTCLKEN		(1 << 0)
+#define PERI_CTRL9_PICOPLY_TESTDATAOUTSEL	(1 << 1)
+#define PERI_CTRL9_PICOPLY_TESTADDR		(1 << 4)
+#define PERI_CTRL9_PICOPLY_TESTDATAIN		(1 << 8)
+
+/*
+ * PERI_SC_PERIPH_CLKEN0
+ * PERI_SC_PERIPH_CLKDIS0
+ * PERI_SC_PERIPH_CLKSTAT0
+ */
+#define PERI_CLK0_MMC0				(1 << 0)
+#define PERI_CLK0_MMC1				(1 << 1)
+#define PERI_CLK0_MMC2				(1 << 2)
+#define PERI_CLK0_NANDC				(1 << 3)
+#define PERI_CLK0_USBOTG			(1 << 4)
+#define PERI_CLK0_PICOPHY			(1 << 5)
+#define PERI_CLK0_PLL				(1 << 6)
+
+/*
+ * PERI_SC_PERIPH_CLKEN1
+ * PERI_SC_PERIPH_CLKDIS1
+ * PERI_SC_PERIPH_CLKSTAT1
+ */
+#define PERI_CLK1_HIFI				(1 << 0)
+#define PERI_CLK1_DIGACODEC			(1 << 5)
+
+/*
+ * PERI_SC_PERIPH_CLKEN2
+ * PERI_SC_PERIPH_CLKDIS2
+ * PERI_SC_PERIPH_CLKSTAT2
+ */
+#define PERI_CLK2_IPF				(1 << 0)
+#define PERI_CLK2_SOCP				(1 << 1)
+#define PERI_CLK2_DMAC				(1 << 2)
+#define PERI_CLK2_SECENG			(1 << 3)
+#define PERI_CLK2_HPM0				(1 << 5)
+#define PERI_CLK2_HPM1				(1 << 6)
+#define PERI_CLK2_HPM2				(1 << 7)
+#define PERI_CLK2_HPM3				(1 << 8)
+
+/*
+ * PERI_SC_PERIPH_CLKEN3
+ * PERI_SC_PERIPH_CLKDIS3
+ * PERI_SC_PERIPH_CLKSTAT3
+ */
+#define PERI_CLK3_CSSYS				(1 << 0)
+#define PERI_CLK3_I2C0				(1 << 1)
+#define PERI_CLK3_I2C1				(1 << 2)
+#define PERI_CLK3_I2C2				(1 << 3)
+#define PERI_CLK3_I2C3				(1 << 4)
+#define PERI_CLK3_UART1				(1 << 5)
+#define PERI_CLK3_UART2				(1 << 6)
+#define PERI_CLK3_UART3				(1 << 7)
+#define PERI_CLK3_UART4				(1 << 8)
+#define PERI_CLK3_SSP				(1 << 9)
+#define PERI_CLK3_PWM				(1 << 10)
+#define PERI_CLK3_BLPWM				(1 << 11)
+#define PERI_CLK3_TSENSOR			(1 << 12)
+#define PERI_CLK3_GPS				(1 << 15)
+#define PERI_CLK3_TCXO_PAD0			(1 << 16)
+#define PERI_CLK3_TCXO_PAD1			(1 << 17)
+#define PERI_CLK3_DAPB				(1 << 18)
+#define PERI_CLK3_HKADC				(1 << 19)
+#define PERI_CLK3_CODEC_SSI			(1 << 20)
+#define PERI_CLK3_TZPC_DEP			(1 << 21)
+
+/*
+ * PERI_SC_PERIPH_CLKEN8
+ * PERI_SC_PERIPH_CLKDIS8
+ * PERI_SC_PERIPH_CLKSTAT8
+ */
+#define PERI_CLK8_RS0				(1 << 0)
+#define PERI_CLK8_RS2				(1 << 1)
+#define PERI_CLK8_RS3				(1 << 2)
+#define PERI_CLK8_MS0				(1 << 3)
+#define PERI_CLK8_MS2				(1 << 5)
+#define PERI_CLK8_XG2RAM0			(1 << 6)
+#define PERI_CLK8_X2SRAM			(1 << 7)
+#define PERI_CLK8_SRAM				(1 << 8)
+#define PERI_CLK8_ROM				(1 << 9)
+#define PERI_CLK8_HARQ				(1 << 10)
+#define PERI_CLK8_MMU				(1 << 11)
+#define PERI_CLK8_DDRC				(1 << 12)
+#define PERI_CLK8_DDRPHY			(1 << 13)
+#define PERI_CLK8_DDRPHY_REF			(1 << 14)
+#define PERI_CLK8_X2X_SYSNOC			(1 << 15)
+#define PERI_CLK8_X2X_CCPU			(1 << 16)
+#define PERI_CLK8_DDRT				(1 << 17)
+#define PERI_CLK8_DDRPACK_RS			(1 << 18)
+
+/*
+ * PERI_SC_PERIPH_CLKEN9
+ * PERI_SC_PERIPH_CLKDIS9
+ * PERI_SC_PERIPH_CLKSTAT9
+ */
+#define PERI_CLK9_CARM_DAP			(1 << 0)
+#define PERI_CLK9_CARM_ATB			(1 << 1)
+#define PERI_CLK9_CARM_LBUS			(1 << 2)
+#define PERI_CLK9_CARM_KERNEL			(1 << 3)
+
+/*
+ * PERI_SC_PERIPH_CLKEN10
+ * PERI_SC_PERIPH_CLKDIS10
+ * PERI_SC_PERIPH_CLKSTAT10
+ */
+#define PERI_CLK10_IPF_CCPU			(1 << 0)
+#define PERI_CLK10_SOCP_CCPU			(1 << 1)
+#define PERI_CLK10_SECENG_CCPU			(1 << 2)
+#define PERI_CLK10_HARQ_CCPU			(1 << 3)
+#define PERI_CLK10_IPF_MCU			(1 << 16)
+#define PERI_CLK10_SOCP_MCU			(1 << 17)
+#define PERI_CLK10_SECENG_MCU			(1 << 18)
+#define PERI_CLK10_HARQ_MCU			(1 << 19)
+
+/*
+ * PERI_SC_PERIPH_CLKEN12
+ * PERI_SC_PERIPH_CLKDIS12
+ * PERI_SC_PERIPH_CLKSTAT12
+ */
+#define PERI_CLK12_HIFI_SRC			(1 << 0)
+#define PERI_CLK12_MMC0_SRC			(1 << 1)
+#define PERI_CLK12_MMC1_SRC			(1 << 2)
+#define PERI_CLK12_MMC2_SRC			(1 << 3)
+#define PERI_CLK12_SYSPLL_DIV			(1 << 4)
+#define PERI_CLK12_TPIU_SRC			(1 << 5)
+#define PERI_CLK12_MMC0_HF			(1 << 6)
+#define PERI_CLK12_MMC1_HF			(1 << 7)
+#define PERI_CLK12_PLL_TEST_SRC			(1 << 8)
+#define PERI_CLK12_CODEC_SOC			(1 << 9)
+#define PERI_CLK12_MEDIA			(1 << 10)
+
+/*
+ * PERI_SC_PERIPH_RSTEN0
+ * PERI_SC_PERIPH_RSTDIS0
+ * PERI_SC_PERIPH_RSTSTAT0
+ */
+#define PERI_RST0_MMC0				(1 << 0)
+#define PERI_RST0_MMC1				(1 << 1)
+#define PERI_RST0_MMC2				(1 << 2)
+#define PERI_RST0_NANDC				(1 << 3)
+#define PERI_RST0_USBOTG_BUS			(1 << 4)
+#define PERI_RST0_POR_PICOPHY			(1 << 5)
+#define PERI_RST0_USBOTG			(1 << 6)
+#define PERI_RST0_USBOTG_32K			(1 << 7)
+
+/*
+ * PERI_SC_PERIPH_RSTEN1
+ * PERI_SC_PERIPH_RSTDIS1
+ * PERI_SC_PERIPH_RSTSTAT1
+ */
+#define PERI_RST1_HIFI				(1 << 0)
+#define PERI_RST1_DIGACODEC			(1 << 5)
+
+/*
+ * PERI_SC_PERIPH_RSTEN2
+ * PERI_SC_PERIPH_RSTDIS2
+ * PERI_SC_PERIPH_RSTSTAT2
+ */
+#define PERI_RST2_IPF				(1 << 0)
+#define PERI_RST2_SOCP				(1 << 1)
+#define PERI_RST2_DMAC				(1 << 2)
+#define PERI_RST2_SECENG			(1 << 3)
+#define PERI_RST2_ABB				(1 << 4)
+#define PERI_RST2_HPM0				(1 << 5)
+#define PERI_RST2_HPM1				(1 << 6)
+#define PERI_RST2_HPM2				(1 << 7)
+#define PERI_RST2_HPM3				(1 << 8)
+
+/*
+ * PERI_SC_PERIPH_RSTEN3
+ * PERI_SC_PERIPH_RSTDIS3
+ * PERI_SC_PERIPH_RSTSTAT3
+ */
+#define PERI_RST3_CSSYS				(1 << 0)
+#define PERI_RST3_I2C0				(1 << 1)
+#define PERI_RST3_I2C1				(1 << 2)
+#define PERI_RST3_I2C2				(1 << 3)
+#define PERI_RST3_I2C3				(1 << 4)
+#define PERI_RST3_UART1				(1 << 5)
+#define PERI_RST3_UART2				(1 << 6)
+#define PERI_RST3_UART3				(1 << 7)
+#define PERI_RST3_UART4				(1 << 8)
+#define PERI_RST3_SSP				(1 << 9)
+#define PERI_RST3_PWM				(1 << 10)
+#define PERI_RST3_BLPWM				(1 << 11)
+#define PERI_RST3_TSENSOR			(1 << 12)
+#define PERI_RST3_DAPB				(1 << 18)
+#define PERI_RST3_HKADC				(1 << 19)
+#define PERI_RST3_CODEC				(1 << 20)
+
+/*
+ * PERI_SC_PERIPH_RSTEN8
+ * PERI_SC_PERIPH_RSTDIS8
+ * PERI_SC_PERIPH_RSTSTAT8
+ */
+#define PERI_RST8_RS0				(1 << 0)
+#define PERI_RST8_RS2				(1 << 1)
+#define PERI_RST8_RS3				(1 << 2)
+#define PERI_RST8_MS0				(1 << 3)
+#define PERI_RST8_MS2				(1 << 5)
+#define PERI_RST8_XG2RAM0			(1 << 6)
+#define PERI_RST8_X2SRAM_TZMA			(1 << 7)
+#define PERI_RST8_SRAM				(1 << 8)
+#define PERI_RST8_HARQ				(1 << 10)
+#define PERI_RST8_DDRC				(1 << 12)
+#define PERI_RST8_DDRC_APB			(1 << 13)
+#define PERI_RST8_DDRPACK_APB			(1 << 14)
+#define PERI_RST8_DDRT				(1 << 17)
+
+#endif /* __HI6220_PERI_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_pmctrl.h b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_pmctrl.h
new file mode 100644
index 0000000..4a2e905
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hi6220_regs_pmctrl.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __HI6220_REGS_PMCTRL_H__
+#define __HI6220_REGS_PMCTRL_H__
+
+#define PMCTRL_BASE				0xF7032000
+
+#define PMCTRL_ACPUPLLCTRL			(PMCTRL_BASE + 0x000)
+#define PMCTRL_ACPUPLLFREQ			(PMCTRL_BASE + 0x004)
+#define PMCTRL_DDRPLL1CTRL			(PMCTRL_BASE + 0x010)
+#define PMCTRL_DDRPLL0CTRL			(PMCTRL_BASE + 0x030)
+#define PMCTRL_MEDPLLCTRL			(PMCTRL_BASE + 0x038)
+#define PMCTRL_ACPUPLLSEL			(PMCTRL_BASE + 0x100)
+#define PMCTRL_ACPUCLKDIV			(PMCTRL_BASE + 0x104)
+#define PMCTRL_ACPUSYSPLLCFG			(PMCTRL_BASE + 0x110)
+#define PMCTRL_ACPUCLKOFFCFG			(PMCTRL_BASE + 0x114)
+#define PMCTRL_ACPUPLLFRAC			(PMCTRL_BASE + 0x134)
+#define PMCTRL_ACPUPMUVOLUPTIME			(PMCTRL_BASE + 0x360)
+#define PMCTRL_ACPUPMUVOLDNTIME			(PMCTRL_BASE + 0x364)
+#define PMCTRL_ACPUVOLPMUADDR			(PMCTRL_BASE + 0x368)
+#define PMCTRL_ACPUVOLUPSTEP			(PMCTRL_BASE + 0x36c)
+#define PMCTRL_ACPUVOLDNSTEP			(PMCTRL_BASE + 0x370)
+#define PMCTRL_ACPUDFTVOL			(PMCTRL_BASE + 0x374)
+#define PMCTRL_ACPUDESTVOL			(PMCTRL_BASE + 0x378)
+#define PMCTRL_ACPUVOLTTIMEOUT			(PMCTRL_BASE + 0x37c)
+
+#define PMCTRL_ACPUPLLCTRL_EN_CFG		(1 << 0)
+
+#define PMCTRL_ACPUCLKDIV_CPUEXT_CFG_MASK	(3 << 0)
+#define PMCTRL_ACPUCLKDIV_DDR_CFG_MASK		(3 << 8)
+#define PMCTRL_ACPUCLKDIV_CPUEXT_STAT_MASK	(3 << 16)
+#define PMCTRL_ACPUCLKDIV_DDR_STAT_MASK		(3 << 24)
+
+#define PMCTRL_ACPUPLLSEL_ACPUPLL_CFG		(1 << 0)
+#define PMCTRL_ACPUPLLSEL_ACPUPLL_STAT		(1 << 1)
+#define PMCTRL_ACPUPLLSEL_SYSPLL_STAT		(1 << 2)
+
+#define PMCTRL_ACPUSYSPLL_CLKDIV_CFG_MASK	0x7
+#define PMCTRL_ACPUSYSPLL_CLKEN_CFG		(1 << 4)
+#define PMCTRL_ACPUSYSPLL_CLKDIV_SW		(3 << 12)
+
+#define PMCTRL_ACPUSYSPLLCFG_SYSPLL_CLKEN	(1 << 4)
+#define PMCTRL_ACPUSYSPLLCFG_CLKDIV_MASK	(3 << 12)
+
+#define PMCTRL_ACPUDESTVOL_DEST_VOL_MASK	0x7f
+#define PMCTRL_ACPUDESTVOL_CURR_VOL_MASK	(0x7f << 8)
+
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START   (0)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_END     (0)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_rst_START      (2)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_rst_END        (2)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_time_START     (4)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_time_END       (27)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_timeout_START  (28)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_timeout_END    (28)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_lock_START     (29)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_lock_END       (29)
+
+#define SOC_PMCTRL_ACPUPLLFRAC_ADDR(base)   ((base) + (0x134))
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_sw_START   (12)
+
+#define SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_cfg_START   (0)
+#define SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_cfg_END     (0)
+#define SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_stat_START  (1)
+#define SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_stat_END    (1)
+#define SOC_PMCTRL_ACPUPLLSEL_syspll_sw_stat_START   (2)
+#define SOC_PMCTRL_ACPUPLLSEL_syspll_sw_stat_END     (2)
+
+#define SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START     (0)
+#define SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_END       (1)
+#define SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START   (8)
+#define SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_END     (9)
+#define SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_stat_START    (16)
+#define SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_stat_END      (17)
+#define SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_stat_START  (24)
+#define SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_stat_END    (25)
+
+#define SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_START   (0)
+#define SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_END     (6)
+#define SOC_PMCTRL_ACPUDESTVOL_acpu_vol_using_START  (8)
+#define SOC_PMCTRL_ACPUDESTVOL_acpu_vol_using_END    (14)
+
+#define SOC_PMCTRL_ACPUVOLTIMEOUT_acpu_vol_timeout_START  (0)
+#define SOC_PMCTRL_ACPUVOLTIMEOUT_acpu_vol_timeout_END    (0)
+
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_div_cfg_START      (0)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_div_cfg_END        (2)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_cfg_START    (4)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_cfg_END      (4)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_cfg_START  (8)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_cfg_END    (9)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_div_stat_START     (16)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_div_stat_END       (19)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_stat_START   (20)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_stat_END     (20)
+
+#endif /* __HI6220_REGS_PMCTRL_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hi6553.h b/uefi/arm-trusted-firmware/plat/hikey/include/hi6553.h
new file mode 100644
index 0000000..9efc580
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hi6553.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __HI6553_H__
+#define __HI6553_H__
+
+#define DISABLE6_XO_CLK				0x036
+
+#define DISABLE6_XO_CLK_BB			(1 << 0)
+#define DISABLE6_XO_CLK_CONN			(1 << 1)
+#define DISABLE6_XO_CLK_NFC			(1 << 2)
+#define DISABLE6_XO_CLK_RF1			(1 << 3)
+#define DISABLE6_XO_CLK_RF2			(1 << 4)
+
+#define VERSION_REG				0x000
+#define ENABLE2_LDO1_8				0x029
+#define DISABLE2_LDO1_8				0x02a
+#define ONOFF_STATUS2_LDO1_8			0x02b
+#define ENABLE3_LDO9_16				0x02c
+#define DISABLE3_LDO9_16			0x02d
+#define ONOFF_STATUS3_LDO9_16			0x02e
+#define ENABLE4_LDO17_22			0x02f
+#define DISABLE4_LDO17_22			0x030
+#define ONOFF_STATUS4_LDO17_22			0x031
+#define PERI_EN_MARK				0x040
+#define BUCK2_REG1				0x04a
+#define BUCK2_REG5				0x04e
+#define BUCK2_REG6				0x04f
+#define BUCK3_REG3				0x054
+#define BUCK3_REG5				0x056
+#define BUCK3_REG6				0x057
+#define BUCK4_REG2				0x05b
+#define BUCK4_REG5				0x05e
+#define BUCK4_REG6				0x05f
+#define CLK_TOP0				0x063
+#define CLK_TOP3				0x066
+#define CLK_TOP4				0x067
+#define VSET_BUCK2_ADJ				0x06d
+#define VSET_BUCK3_ADJ				0x06e
+#define LDO7_REG_ADJ				0x078
+#define LDO10_REG_ADJ				0x07b
+#define LDO15_REG_ADJ				0x080
+#define LDO19_REG_ADJ				0x084
+#define LDO20_REG_ADJ				0x085
+#define LDO22_REG_ADJ				0x087
+#define DR_LED_CTRL				0x098
+#define DR_OUT_CTRL				0x099
+#define DR3_ISET				0x09a
+#define DR3_START_DEL				0x09b
+#define DR4_ISET				0x09c
+#define DR4_START_DEL				0x09d
+#define DR345_TIM_CONF0				0x0a0
+#define NP_REG_ADJ1				0x0be
+#define NP_REG_CHG				0x0c0
+#define BUCK01_CTRL2				0x0d9
+#define BUCK0_CTRL1				0x0dd
+#define BUCK0_CTRL5				0x0e1
+#define BUCK0_CTRL7				0x0e3
+#define BUCK1_CTRL1				0x0e8
+#define BUCK1_CTRL5				0x0ec
+#define BUCK1_CTRL7				0x0ef
+#define CLK19M2_600_586_EN			0x0fe
+
+#define LED_START_DELAY_TIME			0x00
+#define LED_ELEC_VALUE				0x07
+#define LED_LIGHT_TIME				0xf0
+#define LED_GREEN_ENABLE			(1 << 1)
+#define LED_OUT_CTRL				0x00
+
+#define PMU_HI6552_V300				0x30
+#define PMU_HI6552_V310				0x31
+
+extern unsigned char hi6553_read_8(unsigned int offset);
+extern void hi6553_write_8(unsigned int offset, unsigned int value);
+
+#endif	/* __HI6553_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hisi_ipc.h b/uefi/arm-trusted-firmware/plat/hikey/include/hisi_ipc.h
new file mode 100644
index 0000000..0afe011
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hisi_ipc.h
@@ -0,0 +1,40 @@
+#ifndef __HISI_IPC_H__
+#define __HISI_IPC_H__
+
+#define HISI_IPC_CORE_ACPU		0x0
+
+#define HISI_IPC_MCU_INT_SRC_ACPU0_PD	10
+#define HISI_IPC_MCU_INT_SRC_ACPU1_PD	11
+#define HISI_IPC_MCU_INT_SRC_ACPU2_PD	12
+#define HISI_IPC_MCU_INT_SRC_ACPU3_PD	13
+#define HISI_IPC_MCU_INT_SRC_ACPU_PD 	16
+#define HISI_IPC_MCU_INT_SRC_ACPU4_PD	26
+#define HISI_IPC_MCU_INT_SRC_ACPU5_PD	27
+#define HISI_IPC_MCU_INT_SRC_ACPU6_PD	28
+#define HISI_IPC_MCU_INT_SRC_ACPU7_PD	29
+
+#define HISI_IPC_SEM_CPUIDLE		27
+#define HISI_IPC_INT_SRC_NUM		32
+
+#define HISI_IPC_PM_ON			0
+#define HISI_IPC_PM_OFF			1
+
+#define HISI_IPC_OK			(0)
+#define HISI_IPC_ERROR			(-1)
+
+#define HISI_IPC_BASE_ADDR		(0xF7510000)
+#define HISI_IPC_CPU_RAW_INT_ADDR	(0xF7510420)
+#define HISI_IPC_ACPU_CTRL(i)		(0xF7510800 + (i << 3))
+
+void hisi_ipc_spin_lock(unsigned int signal);
+void hisi_ipc_spin_unlock(unsigned int signal);
+void hisi_ipc_cpu_on(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cpu_off(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cpu_suspend(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cluster_on(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cluster_off(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cluster_suspend(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_psci_system_off(void);
+int hisi_ipc_init(void);
+
+#endif
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hisi_mcu.h b/uefi/arm-trusted-firmware/plat/hikey/include/hisi_mcu.h
new file mode 100644
index 0000000..74dbf17
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hisi_mcu.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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	__MCU_H__
+#define	__MCU_H__
+
+#include <stdint.h>
+
+extern void hisi_mcu_enable_sram(void);
+extern void hisi_mcu_start_run(void);
+extern int hisi_mcu_load_image(uintptr_t image_base, uint32_t image_size);
+
+#endif	/* __MCU_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hisi_pwrc.h b/uefi/arm-trusted-firmware/plat/hikey/include/hisi_pwrc.h
new file mode 100644
index 0000000..d7907fb
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hisi_pwrc.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __HISI_PWRC_H__
+#define __HISI_PWRC_H__
+
+#ifndef __ASSEMBLY__
+
+void hisi_pwrc_set_cluster_wfi(unsigned int id);
+void hisi_pwrc_set_core_bx_addr(unsigned int core,
+				unsigned int cluster,
+				uintptr_t entry_point);
+int hisi_pwrc_setup(void);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __HISI_PWRC_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/hisi_sram_map.h b/uefi/arm-trusted-firmware/plat/hikey/include/hisi_sram_map.h
new file mode 100644
index 0000000..dc4425d
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/hisi_sram_map.h
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __SRAM_MAP_H__
+#define __SRAM_MAP_H__
+
+/*
+ * SRAM Memory Region Layout
+ *
+ *  +-----------------------+
+ *  |  Low Power Mode       | 7KB
+ *  +-----------------------+
+ *  |  Secure OS            | 64KB
+ *  +-----------------------+
+ *  |  Software Flag        | 1KB
+ *  +-----------------------+
+ *
+ */
+
+#define SOC_SRAM_OFF_BASE_ADDR		(0xFFF80000)
+
+/* PM Section: 7KB */
+#define SRAM_PM_ADDR			(SOC_SRAM_OFF_BASE_ADDR)
+#define SRAM_PM_SIZE			(0x00001C00)
+
+/* TEE OS Section: 64KB */
+#define SRAM_TEEOS_ADDR			(SRAM_PM_ADDR + SRAM_PM_SIZE)
+#define SRAM_TEEOS_SIZE			(0x00010000)
+
+/* General Use Section: 1KB */
+#define SRAM_GENERAL_ADDR		(SRAM_TEEOS_ADDR + SRAM_TEEOS_SIZE)
+#define SRAM_GENERAL_SIZE		(0x00000400)
+
+/*
+ * General Usage Section Layout:
+ *
+ *  +-----------------------+
+ *  |  AP boot flag         | 64B
+ *  +-----------------------+
+ *  |  DICC flag            | 32B
+ *  +-----------------------+
+ *  |  Soft flag            | 256B
+ *  +-----------------------+
+ *  |  Thermal flag         | 128B
+ *  +-----------------------+
+ *  |  CSHELL               | 4B
+ *  +-----------------------+
+ *  |  Uart Switching       | 4B
+ *  +-----------------------+
+ *  |  ICC                  | 1024B
+ *  +-----------------------+
+ *  |  Memory Management    | 1024B
+ *  +-----------------------+
+ *  |  IFC                  | 32B
+ *  +-----------------------+
+ *  |  HIFI                 | 32B
+ *  +-----------------------+
+ *  |  DDR capacity         | 4B
+ *  +-----------------------+
+ *  |  Reserved             |
+ *  +-----------------------+
+ *
+ */
+
+/* App Core Boot Flags */
+#define MEMORY_AXI_ACPU_START_ADDR		(SRAM_GENERAL_ADDR)
+#define MEMORY_AXI_ACPU_START_SIZE		(64)
+
+#define MEMORY_AXI_SRESET_FLAG_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0000)
+#define MEMORY_AXI_SECOND_CPU_BOOT_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0004)
+#define MEMORY_AXI_READY_FLAG_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0008)
+#define MEMORY_AXI_FASTBOOT_ENTRY_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x000C)
+#define MEMORY_AXI_PD_CHARGE_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0010)
+#define MEMORY_AXI_DBG_ALARM_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0014)
+#define MEMORY_AXI_CHIP_ADDR			(MEMORY_AXI_ACPU_START_ADDR + 0x0018)
+#define MEMORY_AXI_BOARD_TYPE_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x001C)
+#define MEMORY_AXI_BOARD_ID_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0020)
+#define MEMORY_AXI_CHARGETYPE_FLAG_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0024)
+#define MEMORY_AXI_COLD_START_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0028)
+#define MEMORY_AXI_ANDROID_REBOOT_FLAG_ADDR	(MEMORY_AXI_ACPU_START_ADDR + 0x002C)
+#define MEMORY_AXI_ACPU_WDTRST_REBOOT_FLAG_ADDR	(MEMORY_AXI_ACPU_START_ADDR + 0x0030)
+#define MEMORY_AXI_ABNRST_BITMAP_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0034)
+#define MEMORY_AXI_32K_CLK_TYPE_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0038)
+#define AXI_MODEM_PANIC_FLAG_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x003C)
+#define AXI_MODEM_PANIC_FLAG			(0x68697369)
+#define MEMORY_AXI_ACPU_END_ADDR		(AXI_MODEM_PANIC_FLAG_ADDR + 4)
+
+/* DICC Flags */
+#define MEMORY_AXI_DICC_ADDR			(MEMORY_AXI_ACPU_START_ADDR + MEMORY_AXI_ACPU_START_SIZE)
+#define MEMORY_AXI_DICC_SIZE			(32)
+
+#define MEMORY_AXI_SOFT_FLAG_ADDR		(MEMORY_AXI_DICC_ADDR + MEMORY_AXI_DICC_SIZE)
+#define MEMORY_AXI_SOFT_FLAG_SIZE		(256)
+
+/* Thermal Flags */
+#define MEMORY_AXI_TEMP_PROTECT_ADDR		(MEMORY_AXI_SOFT_FLAG_ADDR + MEMORY_AXI_SOFT_FLAG_SIZE)
+#define MEMORY_AXI_TEMP_PROTECT_SIZE		(128)
+
+/* CSHELL */
+#define MEMORY_AXI_USB_CSHELL_ADDR		(MEMORY_AXI_TEMP_PROTECT_ADDR + MEMORY_AXI_TEMP_PROTECT_SIZE)
+#define MEMORY_AXI_USB_CSHELL_SIZE		(4)
+
+/* Uart and A/C Shell Switch Flags */
+#define MEMORY_AXI_UART_INOUT_ADDR		(MEMORY_AXI_USB_CSHELL_ADDR + MEMORY_AXI_USB_CSHELL_SIZE)
+#define MEMORY_AXI_UART_INOUT_SIZE		(4)
+
+/* IFC Flags */
+#define MEMORY_AXI_IFC_ADDR			(MEMORY_AXI_UART_INOUT_ADDR + MEMORY_AXI_UART_INOUT_SIZE)
+#define MEMORY_AXI_IFC_SIZE			(32)
+
+/* HIFI Data */
+#define MEMORY_AXI_HIFI_ADDR			(MEMORY_AXI_IFC_ADDR + MEMORY_AXI_IFC_SIZE)
+#define MEMORY_AXI_HIFI_SIZE			(32)
+
+/* CONFIG Flags */
+#define MEMORY_AXI_CONFIG_ADDR			(MEMORY_AXI_HIFI_ADDR + MEMORY_AXI_HIFI_SIZE)
+#define MEMORY_AXI_CONFIG_SIZE			(32)
+
+/* DDR Capacity Flags */
+#define MEMORY_AXI_DDR_CAPACITY_ADDR		(MEMORY_AXI_CONFIG_ADDR + MEMORY_AXI_CONFIG_SIZE)
+#define MEMORY_AXI_DDR_CAPACITY_SIZE		(4)
+
+/* USB Shell Flags */
+#define MEMORY_AXI_USB_SHELL_FLAG_ADDR		(MEMORY_AXI_DDR_CAPACITY_ADDR + MEMORY_AXI_DDR_CAPACITY_SIZE )
+#define MEMORY_AXI_USB_SHELL_FLAG_SIZE		(4)
+
+/* MCU WDT Switch Flag */
+#define MEMORY_AXI_MCU_WDT_FLAG_ADDR		(MEMORY_AXI_USB_SHELL_FLAG_ADDR + MEMORY_AXI_USB_SHELL_FLAG_SIZE)
+#define MEMORY_AXI_MCU_WDT_FLAG_SIZE		(4)
+
+/* TLDSP Mailbox MNTN */
+#define SRAM_DSP_MNTN_INFO_ADDR			(MEMORY_AXI_MCU_WDT_FLAG_ADDR + MEMORY_AXI_MCU_WDT_FLAG_SIZE)
+#define SRAM_DSP_MNTN_SIZE			(32)
+
+/* TLDSP ARM Mailbox Protect Flag */
+#define SRAM_DSP_ARM_MAILBOX_PROTECT_FLAG_ADDR	(SRAM_DSP_MNTN_INFO_ADDR + SRAM_DSP_MNTN_SIZE)
+#define SRAM_DSP_ARM_MAILBOX_PROTECT_FLAG_SIZE	(4)
+
+/* RTT Sleep Flag */
+#define SRAM_RTT_SLEEP_FLAG_ADDR                (SRAM_DSP_ARM_MAILBOX_PROTECT_FLAG_ADDR + SRAM_DSP_ARM_MAILBOX_PROTECT_FLAG_SIZE)
+#define SRAM_RTT_SLEEP_FLAG_SIZE                (32)
+
+/* LDSP Awake Flag */
+#define MEMORY_AXI_LDSP_AWAKE_ADDR              (SRAM_RTT_SLEEP_FLAG_ADDR + SRAM_RTT_SLEEP_FLAG_SIZE)
+#define MEMORY_AXI_LDSP_AWAKE_SIZE              (4)
+
+#define NVUPDATE_SUCCESS			0x5555AAAA
+#define NVUPDATE_FAILURE			0xAAAA5555
+
+/*
+ * Low Power Mode Region
+ */
+#define PWRCTRL_ACPU_ASM_SPACE_ADDR		(SRAM_PM_ADDR)
+#define PWRCTRL_ACPU_ASM_SPACE_SIZE		(SRAM_PM_SIZE)
+
+#define PWRCTRL_ACPU_ASM_MEM_BASE		(PWRCTRL_ACPU_ASM_SPACE_ADDR)
+#define PWRCTRL_ACPU_ASM_MEM_SIZE		(PWRCTRL_ACPU_ASM_SPACE_SIZE)
+#define PWRCTRL_ACPU_ASM_CODE_BASE		(PWRCTRL_ACPU_ASM_MEM_BASE + 0x200)
+#define PWRCTRL_ACPU_ASM_DATA_BASE		(PWRCTRL_ACPU_ASM_MEM_BASE + 0xE00)
+#define PWRCTRL_ACPU_ASM_DATA_SIZE		(0xE00)
+
+#define PWRCTRL_ACPU_ASM_D_C0_ADDR		(PWRCTRL_ACPU_ASM_DATA_BASE)
+#define PWRCTRL_ACPU_ASM_D_C0_MMU_PARA_AD	(PWRCTRL_ACPU_ASM_DATA_BASE + 0)
+#define PWRCTRL_ACPU_ASM_D_ARM_PARA_AD		(PWRCTRL_ACPU_ASM_DATA_BASE + 0x20)
+
+#define PWRCTRL_ACPU_ASM_D_COMM_ADDR		(PWRCTRL_ACPU_ASM_DATA_BASE + 0x700)
+
+#define PWRCTRL_ACPU_REBOOT			(PWRCTRL_ACPU_ASM_D_COMM_ADDR)
+#define PWRCTRL_ACPU_REBOOT_SIZE		(0x200)
+#define PWRCTRL_ACPU_ASM_SLICE_BAK_ADDR		(PWRCTRL_ACPU_REBOOT + PWRCTRL_ACPU_REBOOT_SIZE)
+#define PWRCTRL_ACPU_ASM_SLICE_BAK_SIZE		(4)
+#define PWRCTRL_ACPU_ASM_DEBUG_FLAG_ADDR	(PWRCTRL_ACPU_ASM_SLICE_BAK_ADDR + PWRCTRL_ACPU_ASM_SLICE_BAK_SIZE)
+#define PWRCTRL_ACPU_ASM_DEBUG_FLAG_SIZE	(4)
+#define EXCH_A_CORE_POWRCTRL_CONV_ADDR		(PWRCTRL_ACPU_ASM_DEBUG_FLAG_ADDR + PWRCTRL_ACPU_ASM_DEBUG_FLAG_SIZE)
+#define EXCH_A_CORE_POWRCTRL_CONV_SIZE		(4)
+
+/*
+ * Below region memory mapping is:
+ * 4 + 12 + 16 + 28 + 28 + 16 + 28 + 12 + 24 + 20 + 64 +
+ * 4 + 4 + 4 + 4 + 12 + 4 + 4 + 4 + 4 + 16 + 4 + 0x2BC +
+ * 24 + 20 + 12 + 16
+ */
+
+#define MEMORY_AXI_CPU_IDLE_ADDR		(EXCH_A_CORE_POWRCTRL_CONV_ADDR + EXCH_A_CORE_POWRCTRL_CONV_SIZE)
+#define MEMORY_AXI_CPU_IDLE_SIZE		(4)
+
+#define MEMORY_AXI_CUR_FREQ_ADDR		(MEMORY_AXI_CPU_IDLE_ADDR + MEMORY_AXI_CPU_IDLE_SIZE)
+#define MEMORY_AXI_CUR_FREQ_SIZE		(12)
+
+#define MEMORY_AXI_ACPU_FREQ_VOL_ADDR		(MEMORY_AXI_CUR_FREQ_ADDR + MEMORY_AXI_CUR_FREQ_SIZE)
+#define MEMORY_AXI_ACPU_FREQ_VOL_SIZE		(16 + 28 + 28)
+
+#define MEMORY_AXI_DDR_FREQ_VOL_ADDR		(MEMORY_AXI_ACPU_FREQ_VOL_ADDR + MEMORY_AXI_ACPU_FREQ_VOL_SIZE)
+#define MEMORY_AXI_DDR_FREQ_VOL_SIZE		(16 + 28)
+
+#define MEMORY_AXI_ACPU_FIQ_TEST_ADDR		(MEMORY_AXI_DDR_FREQ_VOL_ADDR + MEMORY_AXI_DDR_FREQ_VOL_SIZE)
+#define MEMORY_AXI_ACPU_FIQ_TEST_SIZE		(12)
+
+#define MEMORY_AXI_ACPU_FIQ_CPU_INFO_ADDR	(MEMORY_AXI_ACPU_FIQ_TEST_ADDR + MEMORY_AXI_ACPU_FIQ_TEST_SIZE)
+#define MEMORY_AXI_ACPU_FIQ_CPU_INFO_SIZE	(24)
+
+#define MEMORY_AXI_ACPU_FIQ_DEBUG_INFO_ADDR	(MEMORY_AXI_ACPU_FIQ_CPU_INFO_ADDR + MEMORY_AXI_ACPU_FIQ_CPU_INFO_SIZE)
+#define MEMORY_AXI_ACPU_FIQ_DEBUG_INFO_SIZE	(20)
+
+#define MEMORY_FREQDUMP_ADDR			(MEMORY_AXI_ACPU_FIQ_DEBUG_INFO_ADDR + MEMORY_AXI_ACPU_FIQ_DEBUG_INFO_SIZE)
+#define MEMORY_FREQDUMP_SIZE			(64)
+
+#define MEMORY_AXI_CCPU_LOG_ADDR		(MEMORY_FREQDUMP_ADDR + MEMORY_FREQDUMP_SIZE)
+#define MEMORY_AXI_CCPU_LOG_SIZE		(4)
+
+#define MEMORY_AXI_MCU_LOG_ADDR			(MEMORY_AXI_CCPU_LOG_ADDR + MEMORY_AXI_CCPU_LOG_SIZE)
+#define MEMORY_AXI_MCU_LOG_SIZE			(4)
+
+#define MEMORY_AXI_SEC_CORE_BOOT_ADDR		(MEMORY_AXI_MCU_LOG_ADDR + MEMORY_AXI_MCU_LOG_SIZE)
+#define MEMORY_AXI_SEC_CORE_BOOT_SIZE		(4)
+
+#define MEMORY_AXI_BBP_PS_VOTE_FLAG_ADDR	(MEMORY_AXI_SEC_CORE_BOOT_ADDR + MEMORY_AXI_SEC_CORE_BOOT_SIZE)
+#define MEMORY_AXI_BBP_PS_VOTE_FLAG_SIZE	(0x4)
+
+#define POLICY_AREA_RESERVED			(MEMORY_AXI_BBP_PS_VOTE_FLAG_ADDR + MEMORY_AXI_BBP_PS_VOTE_FLAG_SIZE)
+#define POLICY_AREA_RESERVED_SIZE		(12)
+
+#define DDR_POLICY_VALID_MAGIC			(POLICY_AREA_RESERVED + POLICY_AREA_RESERVED_SIZE)
+#define DDR_POLICY_VALID_MAGIC_SIZE		(4)
+
+#define DDR_POLICY_MAX_NUM			(DDR_POLICY_VALID_MAGIC + DDR_POLICY_VALID_MAGIC_SIZE)
+#define DDR_POLICY_MAX_NUM_SIZE			(4)
+
+#define DDR_POLICY_SUPPORT_NUM			(DDR_POLICY_MAX_NUM + DDR_POLICY_MAX_NUM_SIZE)
+#define DDR_POLICY_SUPPORT_NUM_SIZE		(4)
+
+#define DDR_POLICY_CUR_POLICY			(DDR_POLICY_SUPPORT_NUM + DDR_POLICY_SUPPORT_NUM_SIZE)
+#define DDR_POLICY_CUR_POLICY_SIZE		(4)
+
+#define ACPU_POLICY_VALID_MAGIC			(DDR_POLICY_CUR_POLICY + DDR_POLICY_CUR_POLICY_SIZE)
+#define ACPU_POLICY_VALID_MAGIC_SIZE		(4)
+
+#define ACPU_POLICY_MAX_NUM			(ACPU_POLICY_VALID_MAGIC + ACPU_POLICY_VALID_MAGIC_SIZE)
+#define ACPU_POLICY_MAX_NUM_SIZE		(4)
+
+#define ACPU_POLICY_SUPPORT_NUM			(ACPU_POLICY_MAX_NUM + ACPU_POLICY_MAX_NUM_SIZE)
+#define ACPU_POLICY_SUPPORT_NUM_SIZE		(4)
+
+#define ACPU_POLICY_CUR_POLICY			(ACPU_POLICY_SUPPORT_NUM + ACPU_POLICY_SUPPORT_NUM_SIZE)
+#define ACPU_POLICY_CUR_POLICY_SIZE		(4)
+
+#define LPDDR_OPTION_ADDR			(ACPU_POLICY_CUR_POLICY + ACPU_POLICY_CUR_POLICY_SIZE)
+#define LPDDR_OPTION_SIZE			(4)
+
+#define MEMORY_AXI_DDR_DDL_ADDR			(LPDDR_OPTION_ADDR + LPDDR_OPTION_SIZE)
+#define MEMORY_AXI_DDR_DDL_SIZE			(0x2BC)
+
+#define DDR_TEST_DFS_ADDR			(MEMORY_AXI_DDR_DDL_ADDR + MEMORY_AXI_DDR_DDL_SIZE)
+#define DDR_TEST_DFS_ADDR_SIZE			(4)
+
+#define DDR_TEST_DFS_TIMES_ADDR			(DDR_TEST_DFS_ADDR + DDR_TEST_DFS_ADDR_SIZE)
+#define DDR_TEST_DFS_TIMES_ADDR_SIZE		(4)
+
+#define DDR_TEST_QOS_ADDR			(DDR_TEST_DFS_TIMES_ADDR + DDR_TEST_DFS_TIMES_ADDR_SIZE)
+#define DDR_TEST_QOS_ADDR_SIZE			(4)
+
+#define DDR_TEST_FUN_ADDR			(DDR_TEST_QOS_ADDR + DDR_TEST_QOS_ADDR_SIZE)
+#define DDR_TEST_FUN_ADDR_SIZE			(4)
+
+#define BOARD_TYPE_ADDR				(DDR_TEST_FUN_ADDR + DDR_TEST_FUN_ADDR_SIZE)
+#define BOARD_ADDR_SIZE				(4)
+#define DDR_DFS_FREQ_ADDR			(BOARD_TYPE_ADDR + BOARD_ADDR_SIZE)
+#define DDR_DFS_FREQ_SIZE			(4)
+
+#define DDR_PASR_ADDR				(DDR_DFS_FREQ_ADDR + DDR_DFS_FREQ_SIZE)
+#define DDR_PASR_SIZE				(20)
+
+#define ACPU_DFS_FREQ_ADDR			(DDR_PASR_ADDR + DDR_PASR_SIZE)
+#define ACPU_DFS_FREQ_ADDR_SIZE			(12)
+
+#define ACPU_CHIP_MAX_FREQ			(ACPU_DFS_FREQ_ADDR + ACPU_DFS_FREQ_ADDR_SIZE)
+#define ACPU_CHIP_MAX_FREQ_SIZE			(4)
+
+#define MEMORY_MEDPLL_STATE_ADDR		(ACPU_CHIP_MAX_FREQ + ACPU_CHIP_MAX_FREQ_SIZE)
+#define MEMORY_MEDPLL_STATE_SIZE		(8)
+
+#define MEMORY_CCPU_LOAD_FLAG_ADDR		(MEMORY_MEDPLL_STATE_ADDR + MEMORY_MEDPLL_STATE_SIZE)
+#define MEMORY_CCPU_LOAD_FLAG_SIZE		(4)
+
+
+#define ACPU_CORE_BITS_ADDR			(MEMORY_CCPU_LOAD_FLAG_ADDR + MEMORY_CCPU_LOAD_FLAG_SIZE)
+#define ACPU_CORE_BITS_SIZE			(4)
+
+#define ACPU_CLUSTER_IDLE_ADDR			(ACPU_CORE_BITS_ADDR + ACPU_CORE_BITS_SIZE)
+#define ACPU_CLUSTER_IDLE_SIZE			(4)
+
+#define ACPU_A53_FLAGS_ADDR			(ACPU_CLUSTER_IDLE_ADDR + ACPU_CLUSTER_IDLE_SIZE)
+#define ACPU_A53_FLAGS_SIZE			(4)
+
+#define ACPU_POWER_STATE_QOS_ADDR		(ACPU_A53_FLAGS_ADDR+ACPU_A53_FLAGS_SIZE)
+#define ACPU_POWER_STATE_QOS_SIZE		(4)
+
+#define ACPU_UNLOCK_CORE_FLAGS_ADDR		(ACPU_POWER_STATE_QOS_ADDR+ACPU_POWER_STATE_QOS_SIZE)
+#define ACPU_UNLOCK_CORE_FLAGS_SIZE		(8)
+
+#define ACPU_SUBSYS_POWERDOWN_FLAGS_ADDR	(ACPU_UNLOCK_CORE_FLAGS_ADDR + ACPU_UNLOCK_CORE_FLAGS_SIZE)
+#define ACPU_SUBSYS_POWERDOWN_FLAGS_SIZE	(4)
+
+#define ACPU_CORE_POWERDOWN_FLAGS_ADDR		(ACPU_SUBSYS_POWERDOWN_FLAGS_ADDR + ACPU_SUBSYS_POWERDOWN_FLAGS_SIZE)
+#define ACPU_CORE_POWERDOWN_FLAGS_SIZE		(4)
+
+#define ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR	(ACPU_CORE_POWERDOWN_FLAGS_ADDR + ACPU_CORE_POWERDOWN_FLAGS_SIZE)
+#define ACPU_CLUSTER_POWERDOWN_FLAGS_SIZE	(4)
+
+#define ACPU_ARM64_FLAGA			(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR + ACPU_CLUSTER_POWERDOWN_FLAGS_SIZE)
+#define ACPU_ARM64_FLAGA_SIZE			(4)
+
+#define ACPU_ARM64_FLAGB			(ACPU_ARM64_FLAGA + ACPU_ARM64_FLAGA_SIZE)
+#define ACPU_ARM64_FLAGB_SIZE			(4)
+
+#define MCU_EXCEPTION_FLAGS_ADDR		(ACPU_ARM64_FLAGB + ACPU_ARM64_FLAGB_SIZE)
+#define MCU_EXCEPTION_FLAGS_SIZE		(4)
+
+#define ACPU_MASTER_CORE_STATE_ADDR		(MCU_EXCEPTION_FLAGS_ADDR + MCU_EXCEPTION_FLAGS_SIZE)
+#define ACPU_MASTER_CORE_STATE_SIZE		(4)
+
+#define PWRCTRL_AXI_RESERVED_ADDR		(ACPU_MASTER_CORE_STATE_ADDR + ACPU_MASTER_CORE_STATE_SIZE)
+
+#endif /* __SRAM_MAP_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/partitions.h b/uefi/arm-trusted-firmware/plat/hikey/include/partitions.h
new file mode 100644
index 0000000..b386186
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/partitions.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __PARTITIONS_H__
+#define __PARTITIONS_H__
+
+#define MAX_PARTITION_NUM		128
+#define EFI_NAMELEN			36
+
+struct ptentry {
+	uint64_t	start;
+	uint64_t	length;
+	unsigned int	flags;
+	unsigned int	loadaddr;
+	unsigned int	loadsize;
+	int		id;
+	char		name[EFI_NAMELEN];
+};
+
+extern int get_partition(void);
+extern struct ptentry *find_ptn(const char *str);
+extern int update_fip_spec(void);
+
+#endif /* __PARTITIONS_H__ */
+
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/plat_macros.S b/uefi/arm-trusted-firmware/plat/hikey/include/plat_macros.S
new file mode 100644
index 0000000..624c49f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/plat_macros.S
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <cci400.h>
+#include <gic_v2.h>
+#include "platform_def.h"
+#include "../hikey_def.h"
+
+.section .rodata.gic_reg_name, "aS"
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+
+	/* ---------------------------------------------
+	 * The below macro prints out relevant GIC
+	 * registers whenever an unhandled exception is
+	 * taken in BL3-1.
+	 * Clobbers: x0 - x10, x16, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_print_gic_regs
+	mov_imm	x16, GICD_BASE
+	mov_imm	x17, GICC_BASE
+	/* Load the gicc reg list to x6 */
+	adr	x6, gicc_regs
+	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+	ldr	w8, [x17, #GICC_HPPIR]
+	ldr	w9, [x17, #GICC_AHPPIR]
+	ldr	w10, [x17, #GICC_CTLR]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+
+	/* Print the GICD_ISPENDR regs */
+	add	x7, x16, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+gicd_ispendr_loop:
+	sub	x4, x7, x16
+	cmp	x4, #0x280
+	b.eq	exit_print_gic_regs
+	bl	asm_print_hex
+
+	adr	x4, spacer
+	bl	asm_print_str
+
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+
+	adr	x4, newline
+	bl	asm_print_str
+	b	gicd_ispendr_loop
+exit_print_gic_regs:
+	.endm
+
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+	.asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+	/* ------------------------------------------------
+	 * The below macro prints out relevant interconnect
+	 * registers whenever an unhandled exception is
+	 * taken in BL3-1.
+	 * Clobbers: x0 - x9, sp
+	 * ------------------------------------------------
+	 */
+	.macro plat_print_interconnect_regs
+	adr	x6, cci_iface_regs
+	/* Store in x7 the base address of the first interface */
+	mov_imm	x7, (CCI400_BASE + SLAVE_IFACE3_OFFSET)
+	ldr	w8, [x7, #SNOOP_CTRL_REG]
+	/* Store in x7 the base address of the second interface */
+	mov_imm	x7, (CCI400_BASE + SLAVE_IFACE4_OFFSET)
+	ldr	w9, [x7, #SNOOP_CTRL_REG]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+	.endm
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/platform_def.h b/uefi/arm-trusted-firmware/plat/hikey/include/platform_def.h
new file mode 100644
index 0000000..d8694da
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/platform_def.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include "../hikey_def.h"
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT          "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH            aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE		0x800
+
+#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+
+#define LOADER_MEM_NAME			"loader_mem"
+
+#define BOOT_EMMC_NAME			"l-loader.bin"
+
+#define NORMAL_EMMC_NAME		"normal emmc"
+
+/* Trusted Boot Firmware BL2 */
+#define BL2_IMAGE_NAME			"bl2.bin"
+
+/* EL3 Runtime Firmware BL3-1 */
+#define BL31_IMAGE_NAME			"bl31.bin"
+
+/* SCP Firmware BL3-0 */
+#define BL30_IMAGE_NAME			"bl30.bin"
+
+/* Secure Payload BL3-2 (Trusted OS) */
+#define BL32_IMAGE_NAME			"bl32.bin"
+
+/* Non-Trusted Firmware BL3-3 */
+#define BL33_IMAGE_NAME			"bl33.bin" /* e.g. UEFI */
+
+/* Firmware Image Package */
+#define FIP_IMAGE_NAME			"fip.bin"
+
+#define PLATFORM_CACHE_LINE_SIZE	64
+#define PLATFORM_CLUSTER_COUNT		2
+#define PLATFORM_CORE_COUNT_PER_CLUSTER	4
+#define PLATFORM_CORE_COUNT             8
+#define PLATFORM_NUM_AFFS		(PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+#define PLATFORM_MAX_AFFLVL             MPIDR_AFFLVL1
+
+#define MAX_IO_DEVICES			3
+#define MAX_IO_HANDLES			4
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+
+/*******************************************************************************
+ * BL1 is stored in XG2RAM0_HIRQ that is 784KB large. Could we use 8MB size?
+ * The first part is BL1_RAM, and the second part is TZRAM. The name isn't good
+ * enough. We need to update it later.
+ ******************************************************************************/
+#define MMC_BASE			0x00000000
+#define MMC_SIZE			0x80000000
+#define MMC_LOADER_BASE			MMC_BASE		/* boot */
+#define MMC_BL1_SIZE			0x00200000
+
+#define ONCHIPROM_PARAM_BASE		(XG2RAM0_BASE + 0x700)
+#define LOADER_RAM_BASE			(XG2RAM0_BASE + 0x800)
+#define BL1_XG2RAM0_OFFSET		0x1000
+
+#define DDR_BASE			0x00000000
+
+#define MMC_DESC_BASE			(DDR_BASE + 0x0080000)
+#define MMC_DESC_SIZE			0x00080000
+#define MMC_DATA_BASE			(MMC_DESC_BASE + MMC_DESC_SIZE)
+#define MMC_DATA_SIZE			0x00800000
+
+/*******************************************************************************
+ * BL1 specific defines.
+ * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 base
+ * addresses.
+ ******************************************************************************/
+#define BL1_RO_BASE			(XG2RAM0_BASE + BL1_XG2RAM0_OFFSET)
+#define BL1_RO_LIMIT			(XG2RAM0_BASE + 0x10000)
+#define BL1_RW_BASE			(BL1_RO_LIMIT)	/* 0xf981_0000 */
+#define BL1_RW_SIZE			(BL31_LIMIT - BL1_RW_BASE)
+#define BL1_RW_LIMIT			(BL31_LIMIT)
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+/* Set it in DDR first. If necessary, we can set them into SRAM again. */
+#define BL2_BASE			(BL1_RW_BASE + 0x8000)	/* 0xf981_8000 */
+#define BL2_LIMIT			(BL2_BASE + 0x40000)
+
+/*******************************************************************************
+ * BL3-1 specific defines.
+ ******************************************************************************/
+#define BL31_BASE			(BL2_LIMIT)	/* 0xf985_8000 */
+#define BL31_LIMIT			(BL31_BASE + 0x40000)
+
+/*******************************************************************************
+ * BL3-2 specific defines.
+ ******************************************************************************/
+
+/*
+ * The TSP can execute either from Trusted SRAM or Trusted DRAM.
+ */
+#define BL32_SRAM_BASE                  BL31_LIMIT
+#define BL32_SRAM_LIMIT                 (BL31_LIMIT+0x00080000) /* 512K */
+
+#define BL32_DRAM_BASE                  DRAM_SEC_BASE
+#define BL32_DRAM_LIMIT                 (DRAM_SEC_BASE+DRAM_SEC_SIZE)
+
+#if (PLAT_TSP_LOCATION_ID == PLAT_TRUSTED_SRAM_ID)
+#define TSP_SEC_MEM_BASE		BL32_SRAM_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_SRAM_LIMIT - BL32_SRAM_BASE)
+#define BL32_BASE			BL32_SRAM_BASE
+#define BL32_LIMIT			BL32_SRAM_LIMIT
+#elif (PLAT_TSP_LOCATION_ID == PLAT_TRUSTED_DRAM_ID)
+#define TSP_SEC_MEM_BASE		BL32_DRAM_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_DRAM_LIMIT - BL32_DRAM_BASE)
+#define BL32_BASE			BL32_DRAM_BASE
+#define BL32_LIMIT			BL32_DRAM_LIMIT
+#else
+#error "Unsupported PLAT_TSP_LOCATION_ID value"
+#endif
+
+/*******************************************************************************
+ * BL3-0 specific defines:
+ *
+ * BL3-0 is loaded for mcu firmware, firstly load it into temperary buffer
+ * into 0x0100_0000; then BL2 will parse the sections and load then into
+ * seperated buffers as needed.
+ *
+ ******************************************************************************/
+#define BL30_BASE			(DRAM_NS_BASE + 0x01000000)
+#define BL30_LIMIT			(DRAM_NS_BASE + 0x01100000)
+#define BL30_SIZE			(BL30_LIMIT - BL30_BASE)
+
+/*******************************************************************************
+ * Load address of BL3-3 in the HiKey port
+ ******************************************************************************/
+#define NS_IMAGE_OFFSET			(DRAM_BASE + 0x35000000)  /* 848MB */
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define ADDR_SPACE_SIZE			(1ull << 32)
+
+#if IMAGE_BL1 || IMAGE_BL32
+# define MAX_XLAT_TABLES		3
+#endif
+
+#if IMAGE_BL2
+# define MAX_XLAT_TABLES		4
+#endif
+
+#if IMAGE_BL31
+# define MAX_XLAT_TABLES		4
+#endif
+
+#define MAX_MMAP_REGIONS		16
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT   6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/sp804_timer.h b/uefi/arm-trusted-firmware/plat/hikey/include/sp804_timer.h
new file mode 100644
index 0000000..6d1b664
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/sp804_timer.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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	__SP804_TIMER_H__
+#define	__SP804_TIMER_H__
+
+extern void hi6220_timer_init(void);
+extern void udelay(int);
+extern void mdelay(int);
+
+#endif	/* __SP804_TIMER_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/hikey/include/usb.h b/uefi/arm-trusted-firmware/plat/hikey/include/usb.h
new file mode 100644
index 0000000..8fdcc6c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/include/usb.h
@@ -0,0 +1,878 @@
+/*
+ * Copyright (c) 2014, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014, Hisilicon Ltd 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 __DWC_USB_H__
+#define __DWC_USB_H__
+
+#define USB_DMA
+
+#define DWC_OTG_BASE			0xF72C0000
+
+#define USB_NUM_ENDPOINTS		2
+#define MAX_EPS_CHANNELS		16
+
+#define BULK_OUT_EP			1
+#define BULK_IN_EP			1
+
+#define RX_REQ_LEN			512
+#define MAX_PACKET_LEN			512
+
+#define DATA_FIFO_CONFIG		(0x780 << GDFIFOCFG_EPINFOBASE_SHIFT |\
+					 0x800 << GDFIFOCFG_GDFIFOCFG_SHIFT)
+/* RX FIFO: 2048 bytes */
+#define RX_SIZE				0x00000200
+/* Non-periodic TX FIFO: 128 bytes. start address: 0x200 * 4. */
+#define ENDPOINT_TX_SIZE		0x00200200
+
+/* EP1  TX FIFO: 1024 bytes. start address: 0x220 * 4. */
+/* EP2  TX FIFO: 1024 bytes. start address: 0x320 * 4. */
+/* EP3  TX FIFO: 1024 bytes. start address: 0x420 * 4. */
+/* EP4  TX FIFO: 1024 bytes. start address: 0x520 * 4. */
+/* EP5  TX FIFO: 128  bytes. start address: 0x620 * 4. */
+/* EP6  TX FIFO: 128  bytes. start address: 0x640 * 4. */
+/* EP7  TX FIFO: 128  bytes. start address: 0x660 * 4. */
+/* EP8  TX FIFO: 128  bytes. start address: 0x680 * 4. */
+/* EP9  TX FIFO: 128  bytes. start address: 0x6a0 * 4. */
+/* EP10 TX FIFO: 128  bytes. start address: 0x6c0 * 4. */
+/* EP11 TX FIFO: 128  bytes. start address: 0x6e0 * 4. */
+/* EP12 TX FIFO: 128  bytes. start address: 0x700 * 4. */
+/* EP13 TX FIFO: 128  bytes. start address: 0x720 * 4. */
+/* EP14 TX FIFO: 128  bytes. start address: 0x740 * 4. */
+/* EP15 TX FIFO: 128  bytes. start address: 0x760 * 4. */
+
+#define DATA_IN_ENDPOINT_TX_FIFO1	0x01000220
+#define DATA_IN_ENDPOINT_TX_FIFO2	0x01000320
+#define DATA_IN_ENDPOINT_TX_FIFO3	0x01000420
+#define DATA_IN_ENDPOINT_TX_FIFO4	0x01000520
+#define DATA_IN_ENDPOINT_TX_FIFO5	0x00200620
+#define DATA_IN_ENDPOINT_TX_FIFO6	0x00200640
+#define DATA_IN_ENDPOINT_TX_FIFO7	0x00200660
+#define DATA_IN_ENDPOINT_TX_FIFO8	0x00200680
+#define DATA_IN_ENDPOINT_TX_FIFO9	0x002006a0
+#define DATA_IN_ENDPOINT_TX_FIFO10	0x002006c0
+#define DATA_IN_ENDPOINT_TX_FIFO11	0x002006e0
+#define DATA_IN_ENDPOINT_TX_FIFO12	0x00200700
+#define DATA_IN_ENDPOINT_TX_FIFO13	0x00200720
+#define DATA_IN_ENDPOINT_TX_FIFO14	0x00200740
+#define DATA_IN_ENDPOINT_TX_FIFO15	0x00200760
+
+typedef struct {
+	unsigned char		type;
+	unsigned char		request;
+	unsigned short		value;
+	unsigned short		index;
+	unsigned short		length;
+} setup_packet;
+
+struct ept_queue_item {
+	unsigned int		next;
+	unsigned int		info;
+};
+
+struct usb_request {
+	struct ept_queue_item	*item;
+	void			*buf;
+	unsigned int		length;
+	void (*complete)(unsigned int actual, int status);
+	void			*context;
+};
+
+/*DWC_OTG regsiter descriptor*/
+/*Global CSR MAP*/
+#define GLOBAL_CSR_BASE		(DWC_OTG_BASE)
+/*Device mode CSR MAP*/
+#define DEVICE_CSR_BASE		(DWC_OTG_BASE+0x800)
+/*Device mode CSR MAP*/
+#define DEVICE_INEP_BASE	(DWC_OTG_BASE+0x900)
+/*Device mode CSR MAP*/
+#define DEVICE_OUTEP_BASE	(DWC_OTG_BASE+0xB00)
+
+/*** OTG LINK CORE REGISTERS ***/
+/* Core Global Registers */
+#define GOTGCTL			(DWC_OTG_BASE + 0x000)
+#define GOTGINT			(DWC_OTG_BASE + 0x004)
+#define GOTGINT_DBNCE_DONE		(1 << 19)
+#define GOTGINT_A_DEV_TOUT_CHG		(1 << 18)
+#define GOTGINT_HST_NEG_DET		(1 << 17)
+#define GOTGINT_HST_NEG_SUC_STS_CHNG	(1 << 9)
+#define GOTGINT_SES_REQ_SUC_STS_CHNG	(1 << 8)
+#define GOTGINT_SES_END_DET		(1 << 2)
+
+#define GAHBCFG			(DWC_OTG_BASE + 0x008)
+#define GAHBCFG_P_TXF_EMP_LVL           (1 << 8)
+#define GAHBCFG_NP_TXF_EMP_LVL          (1 << 7)
+#define GAHBCFG_DMA_EN                  (1 << 5)
+#define GAHBCFG_GLBL_INTR_EN            (1 << 0)
+#define GAHBCFG_CTRL_MASK               (GAHBCFG_P_TXF_EMP_LVL | \
+					 GAHBCFG_NP_TXF_EMP_LVL | \
+					 GAHBCFG_DMA_EN | \
+					 GAHBCFG_GLBL_INTR_EN)
+
+#define GUSBCFG			(DWC_OTG_BASE + 0x00C)
+#define GRSTCTL			(DWC_OTG_BASE + 0x010)
+#define GRSTCTL_AHBIDLE		(1 << 31)
+#define GRSTCTL_CSFTRST		(1 << 0)
+
+#define GINTSTS			(DWC_OTG_BASE + 0x014)
+#define GINTMSK			(DWC_OTG_BASE + 0x018)
+#define GINTSTS_WKUPINT			(1 << 31)
+#define GINTSTS_SESSREQINT		(1 << 30)
+#define GINTSTS_DISCONNINT		(1 << 29)
+#define GINTSTS_CONIDSTSCHNG		(1 << 28)
+#define GINTSTS_LPMTRANRCVD		(1 << 27)
+#define GINTSTS_PTXFEMP			(1 << 26)
+#define GINTSTS_HCHINT			(1 << 25)
+#define GINTSTS_PRTINT			(1 << 24)
+#define GINTSTS_RESETDET		(1 << 23)
+#define GINTSTS_FET_SUSP		(1 << 22)
+#define GINTSTS_INCOMPL_IP		(1 << 21)
+#define GINTSTS_INCOMPL_SOIN		(1 << 20)
+#define GINTSTS_OEPINT			(1 << 19)
+#define GINTSTS_IEPINT			(1 << 18)
+#define GINTSTS_EPMIS			(1 << 17)
+#define GINTSTS_RESTOREDONE		(1 << 16)
+#define GINTSTS_EOPF			(1 << 15)
+#define GINTSTS_ISOUTDROP		(1 << 14)
+#define GINTSTS_ENUMDONE		(1 << 13)
+#define GINTSTS_USBRST			(1 << 12)
+#define GINTSTS_USBSUSP			(1 << 11)
+#define GINTSTS_ERLYSUSP		(1 << 10)
+#define GINTSTS_I2CINT			(1 << 9)
+#define GINTSTS_ULPI_CK_INT		(1 << 8)
+#define GINTSTS_GOUTNAKEFF		(1 << 7)
+#define GINTSTS_GINNAKEFF		(1 << 6)
+#define GINTSTS_NPTXFEMP		(1 << 5)
+#define GINTSTS_RXFLVL			(1 << 4)
+#define GINTSTS_SOF			(1 << 3)
+#define GINTSTS_OTGINT			(1 << 2)
+#define GINTSTS_MODEMIS			(1 << 1)
+#define GINTSTS_CURMODE_HOST		(1 << 0)
+
+#define GRXSTSR			(DWC_OTG_BASE + 0x01C)
+#define GRXSTSP			(DWC_OTG_BASE + 0x020)
+#define GRXFSIZ			(DWC_OTG_BASE + 0x024)
+#define GNPTXFSIZ		(DWC_OTG_BASE + 0x028)
+#define GNPTXSTS		(DWC_OTG_BASE + 0x02C)
+
+#define GHWCFG1			(DWC_OTG_BASE + 0x044)
+#define GHWCFG2			(DWC_OTG_BASE + 0x048)
+#define GHWCFG3			(DWC_OTG_BASE + 0x04c)
+#define GHWCFG4			(DWC_OTG_BASE + 0x050)
+#define GLPMCFG			(DWC_OTG_BASE + 0x054)
+
+#define GDFIFOCFG		(DWC_OTG_BASE + 0x05c)
+#define GDFIFOCFG_EPINFOBASE_MASK	(0xffff << 16)
+#define GDFIFOCFG_EPINFOBASE_SHIFT	16
+#define GDFIFOCFG_GDFIFOCFG_MASK	(0xffff << 0)
+#define GDFIFOCFG_GDFIFOCFG_SHIFT	0
+
+
+#define HPTXFSIZ		(DWC_OTG_BASE + 0x100)
+#define DIEPTXF(x)		(DWC_OTG_BASE + 0x100 + 4 * (x))
+#define DIEPTXF1		(DWC_OTG_BASE + 0x104)
+#define DIEPTXF2		(DWC_OTG_BASE + 0x108)
+#define DIEPTXF3		(DWC_OTG_BASE + 0x10C)
+#define DIEPTXF4		(DWC_OTG_BASE + 0x110)
+#define DIEPTXF5		(DWC_OTG_BASE + 0x114)
+#define DIEPTXF6		(DWC_OTG_BASE + 0x118)
+#define DIEPTXF7		(DWC_OTG_BASE + 0x11C)
+#define DIEPTXF8		(DWC_OTG_BASE + 0x120)
+#define DIEPTXF9		(DWC_OTG_BASE + 0x124)
+#define DIEPTXF10		(DWC_OTG_BASE + 0x128)
+#define DIEPTXF11		(DWC_OTG_BASE + 0x12C)
+#define DIEPTXF12		(DWC_OTG_BASE + 0x130)
+#define DIEPTXF13		(DWC_OTG_BASE + 0x134)
+#define DIEPTXF14		(DWC_OTG_BASE + 0x138)
+#define DIEPTXF15		(DWC_OTG_BASE + 0x13C)
+
+/*** HOST MODE REGISTERS ***/
+/* Host Global Registers */
+#define HCFG			(DWC_OTG_BASE + 0x400)
+#define HFIR			(DWC_OTG_BASE + 0x404)
+#define HFNUM			(DWC_OTG_BASE + 0x408)
+#define HPTXSTS			(DWC_OTG_BASE + 0x410)
+#define HAINT			(DWC_OTG_BASE + 0x414)
+#define HAINTMSK		(DWC_OTG_BASE + 0x418)
+
+/* Host Port Control and Status Registers */
+#define HPRT			(DWC_OTG_BASE + 0x440)
+
+/* Host Channel-Specific Registers */
+#define HCCHAR(x)		(DWC_OTG_BASE + 0x500 + 0x20 * (x))
+#define HCSPLT(x)		(DWC_OTG_BASE + 0x504 + 0x20 * (x))
+#define HCINT(x)		(DWC_OTG_BASE + 0x508 + 0x20 * (x))
+#define HCINTMSK(x)		(DWC_OTG_BASE + 0x50C + 0x20 * (x))
+#define HCTSIZ(x)		(DWC_OTG_BASE + 0x510 + 0x20 * (x))
+#define HCDMA(x)		(DWC_OTG_BASE + 0x514 + 0x20 * (x))
+#define HCCHAR0			(DWC_OTG_BASE + 0x500)
+#define HCSPLT0			(DWC_OTG_BASE + 0x504)
+#define HCINT0			(DWC_OTG_BASE + 0x508)
+#define HCINTMSK0		(DWC_OTG_BASE + 0x50C)
+#define HCTSIZ0			(DWC_OTG_BASE + 0x510)
+#define HCDMA0			(DWC_OTG_BASE + 0x514)
+#define HCCHAR1			(DWC_OTG_BASE + 0x520)
+#define HCSPLT1			(DWC_OTG_BASE + 0x524)
+#define HCINT1			(DWC_OTG_BASE + 0x528)
+#define HCINTMSK1		(DWC_OTG_BASE + 0x52C)
+#define HCTSIZ1			(DWC_OTG_BASE + 0x530)
+#define HCDMA1			(DWC_OTG_BASE + 0x534)
+#define HCCHAR2			(DWC_OTG_BASE + 0x540)
+#define HCSPLT2			(DWC_OTG_BASE + 0x544)
+#define HCINT2			(DWC_OTG_BASE + 0x548)
+#define HCINTMSK2		(DWC_OTG_BASE + 0x54C)
+#define HCTSIZ2			(DWC_OTG_BASE + 0x550)
+#define HCDMA2			(DWC_OTG_BASE + 0x554)
+#define HCCHAR3			(DWC_OTG_BASE + 0x560)
+#define HCSPLT3			(DWC_OTG_BASE + 0x564)
+#define HCINT3			(DWC_OTG_BASE + 0x568)
+#define HCINTMSK3   		(DWC_OTG_BASE + 0x56C)
+#define HCTSIZ3     		(DWC_OTG_BASE + 0x570)
+#define HCDMA3      		(DWC_OTG_BASE + 0x574)
+#define HCCHAR4     		(DWC_OTG_BASE + 0x580)
+#define HCSPLT4     		(DWC_OTG_BASE + 0x584)
+#define HCINT4      		(DWC_OTG_BASE + 0x588)
+#define HCINTMSK4   		(DWC_OTG_BASE + 0x58C)
+#define HCTSIZ4     		(DWC_OTG_BASE + 0x590)
+#define HCDMA4      		(DWC_OTG_BASE + 0x594)
+#define HCCHAR5     		(DWC_OTG_BASE + 0x5A0)
+#define HCSPLT5     		(DWC_OTG_BASE + 0x5A4)
+#define HCINT5      		(DWC_OTG_BASE + 0x5A8)
+#define HCINTMSK5   		(DWC_OTG_BASE + 0x5AC)
+#define HCTSIZ5     		(DWC_OTG_BASE + 0x5B0)
+#define HCDMA5      		(DWC_OTG_BASE + 0x5B4)
+#define HCCHAR6     		(DWC_OTG_BASE + 0x5C0)
+#define HCSPLT6     		(DWC_OTG_BASE + 0x5C4)
+#define HCINT6      		(DWC_OTG_BASE + 0x5C8)
+#define HCINTMSK6   		(DWC_OTG_BASE + 0x5CC)
+#define HCTSIZ6     		(DWC_OTG_BASE + 0x5D0)
+#define HCDMA6      		(DWC_OTG_BASE + 0x5D4)
+#define HCCHAR7     		(DWC_OTG_BASE + 0x5E0)
+#define HCSPLT7     		(DWC_OTG_BASE + 0x5E4)
+#define HCINT7      		(DWC_OTG_BASE + 0x5E8)
+#define HCINTMSK7   		(DWC_OTG_BASE + 0x5EC)
+#define HCTSIZ7     		(DWC_OTG_BASE + 0x5F0)
+#define HCDMA7      		(DWC_OTG_BASE + 0x5F4)
+#define HCCHAR8     		(DWC_OTG_BASE + 0x600)
+#define HCSPLT8     		(DWC_OTG_BASE + 0x604)
+#define HCINT8      		(DWC_OTG_BASE + 0x608)
+#define HCINTMSK8   		(DWC_OTG_BASE + 0x60C)
+#define HCTSIZ8     		(DWC_OTG_BASE + 0x610)
+#define HCDMA8      		(DWC_OTG_BASE + 0x614)
+#define HCCHAR9     		(DWC_OTG_BASE + 0x620)
+#define HCSPLT9     		(DWC_OTG_BASE + 0x624)
+#define HCINT9      		(DWC_OTG_BASE + 0x628)
+#define HCINTMSK9   		(DWC_OTG_BASE + 0x62C)
+#define HCTSIZ9     		(DWC_OTG_BASE + 0x630)
+#define HCDMA9      		(DWC_OTG_BASE + 0x634)
+#define HCCHAR10    		(DWC_OTG_BASE + 0x640)
+#define HCSPLT10    		(DWC_OTG_BASE + 0x644)
+#define HCINT10     		(DWC_OTG_BASE + 0x648)
+#define HCINTMSK10  		(DWC_OTG_BASE + 0x64C)
+#define HCTSIZ10    		(DWC_OTG_BASE + 0x650)
+#define HCDMA10     		(DWC_OTG_BASE + 0x654)
+#define HCCHAR11    		(DWC_OTG_BASE + 0x660)
+#define HCSPLT11    		(DWC_OTG_BASE + 0x664)
+#define HCINT11     		(DWC_OTG_BASE + 0x668)
+#define HCINTMSK11  		(DWC_OTG_BASE + 0x66C)
+#define HCTSIZ11    		(DWC_OTG_BASE + 0x670)
+#define HCDMA11     		(DWC_OTG_BASE + 0x674)
+#define HCCHAR12    		(DWC_OTG_BASE + 0x680)
+#define HCSPLT12    		(DWC_OTG_BASE + 0x684)
+#define HCINT12     		(DWC_OTG_BASE + 0x688)
+#define HCINTMSK12  		(DWC_OTG_BASE + 0x68C)
+#define HCTSIZ12    		(DWC_OTG_BASE + 0x690)
+#define HCDMA12     		(DWC_OTG_BASE + 0x694)
+#define HCCHAR13    		(DWC_OTG_BASE + 0x6A0)
+#define HCSPLT13    		(DWC_OTG_BASE + 0x6A4)
+#define HCINT13     		(DWC_OTG_BASE + 0x6A8)
+#define HCINTMSK13  		(DWC_OTG_BASE + 0x6AC)
+#define HCTSIZ13    		(DWC_OTG_BASE + 0x6B0)
+#define HCDMA13     		(DWC_OTG_BASE + 0x6B4)
+#define HCCHAR14    		(DWC_OTG_BASE + 0x6C0)
+#define HCSPLT14    		(DWC_OTG_BASE + 0x6C4)
+#define HCINT14     		(DWC_OTG_BASE + 0x6C8)
+#define HCINTMSK14  		(DWC_OTG_BASE + 0x6CC)
+#define HCTSIZ14    		(DWC_OTG_BASE + 0x6D0)
+#define HCDMA14     		(DWC_OTG_BASE + 0x6D4)
+#define HCCHAR15    		(DWC_OTG_BASE + 0x6E0)
+#define HCSPLT15    		(DWC_OTG_BASE + 0x6E4)
+#define HCINT15     		(DWC_OTG_BASE + 0x6E8)
+#define HCINTMSK15  		(DWC_OTG_BASE + 0x6EC)
+#define HCTSIZ15    		(DWC_OTG_BASE + 0x6F0)
+#define HCDMA15     		(DWC_OTG_BASE + 0x6F4)
+
+/*** DEVICE MODE REGISTERS ***/
+/* Device Global Registers */
+#define DCFG        		(DWC_OTG_BASE + 0x800)
+#define DCFG_EPMISCNT_MASK		(0x1f << 18)
+#define DCFG_EPMISCNT_SHIFT		18
+#define DCFG_NZ_STS_OUT_HSHK		(1 << 2)
+
+#define DCTL        		(DWC_OTG_BASE + 0x804)
+#define DSTS        		(DWC_OTG_BASE + 0x808)
+#define DIEPMSK     		(DWC_OTG_BASE + 0x810)
+#define DOEPMSK     		(DWC_OTG_BASE + 0x814)
+#define DAINT       		(DWC_OTG_BASE + 0x818)
+#define DAINTMSK    		(DWC_OTG_BASE + 0x81C)
+#define DAINT_OUTEP_SHIFT		16
+#define DAINT_OUTEP(_x)			(1 << ((_x) + 16))
+#define DAINT_INEP(_x)			(1 << (_x))
+
+#define DTKNQR1     		(DWC_OTG_BASE + 0x820)
+#define DTKNQR2     		(DWC_OTG_BASE + 0x824)
+#define DVBUSDIS    		(DWC_OTG_BASE + 0x828)
+#define DVBUSPULSE  		(DWC_OTG_BASE + 0x82C)
+#define DTHRCTL     		(DWC_OTG_BASE + 0x830)
+
+/* Device Logical IN Endpoint-Specific Registers */
+#define DIEPCTL(x)  		(DWC_OTG_BASE + 0x900 + 0x20 * (x))
+#define DIEPINT(x)  		(DWC_OTG_BASE + 0x908 + 0x20 * (x))
+#define DIEPTSIZ(x) 		(DWC_OTG_BASE + 0x910 + 0x20 * (x))
+#define DIEPDMA(x)  		(DWC_OTG_BASE + 0x914 + 0x20 * (x))
+#define DTXFSTS(x)  		(DWC_OTG_BASE + 0x918 + 0x20 * (x))
+
+#define DIEPCTL0    		(DWC_OTG_BASE + 0x900)
+#define DIEPINT0    		(DWC_OTG_BASE + 0x908)
+#define DIEPTSIZ0   		(DWC_OTG_BASE + 0x910)
+#define DIEPDMA0    		(DWC_OTG_BASE + 0x914)
+#define DIEPCTL1    		(DWC_OTG_BASE + 0x920)
+#define DIEPINT1    		(DWC_OTG_BASE + 0x928)
+#define DIEPTSIZ1   		(DWC_OTG_BASE + 0x930)
+#define DIEPDMA1    		(DWC_OTG_BASE + 0x934)
+#define DIEPCTL2    		(DWC_OTG_BASE + 0x940)
+#define DIEPINT2    		(DWC_OTG_BASE + 0x948)
+#define DIEPTSIZ2  		(DWC_OTG_BASE + 0x950)
+#define DIEPDMA2    		(DWC_OTG_BASE + 0x954)
+#define DIEPCTL3    		(DWC_OTG_BASE + 0x960)
+#define DIEPINT3    		(DWC_OTG_BASE + 0x968)
+#define DIEPTSIZ3   		(DWC_OTG_BASE + 0x970)
+#define DIEPDMA3    		(DWC_OTG_BASE + 0x974)
+#define DIEPCTL4    		(DWC_OTG_BASE + 0x980)
+#define DIEPINT4    		(DWC_OTG_BASE + 0x988)
+#define DIEPTSIZ4   		(DWC_OTG_BASE + 0x990)
+#define DIEPDMA4    		(DWC_OTG_BASE + 0x994)
+#define DIEPCTL5    		(DWC_OTG_BASE + 0x9A0)
+#define DIEPINT5    		(DWC_OTG_BASE + 0x9A8)
+#define DIEPTSIZ5   		(DWC_OTG_BASE + 0x9B0)
+#define DIEPDMA5    		(DWC_OTG_BASE + 0x9B4)
+#define DIEPCTL6    		(DWC_OTG_BASE + 0x9C0)
+#define DIEPINT6    		(DWC_OTG_BASE + 0x9C8)
+#define DIEPTSIZ6   		(DWC_OTG_BASE + 0x9D0)
+#define DIEPDMA6    		(DWC_OTG_BASE + 0x9D4)
+#define DIEPCTL7    		(DWC_OTG_BASE + 0x9E0)
+#define DIEPINT7    		(DWC_OTG_BASE + 0x9E8)
+#define DIEPTSIZ7   		(DWC_OTG_BASE + 0x9F0)
+#define DIEPDMA7    		(DWC_OTG_BASE + 0x9F4)
+#define DIEPCTL8    		(DWC_OTG_BASE + 0xA00)
+#define DIEPINT8    		(DWC_OTG_BASE + 0xA08)
+#define DIEPTSIZ8   		(DWC_OTG_BASE + 0xA10)
+#define DIEPDMA8    		(DWC_OTG_BASE + 0xA14)
+#define DIEPCTL9    		(DWC_OTG_BASE + 0xA20)
+#define DIEPINT9    		(DWC_OTG_BASE + 0xA28)
+#define DIEPTSIZ9   		(DWC_OTG_BASE + 0xA30)
+#define DIEPDMA9    		(DWC_OTG_BASE + 0xA34)
+#define DIEPCTL10   		(DWC_OTG_BASE + 0xA40)
+#define DIEPINT10   		(DWC_OTG_BASE + 0xA48)
+#define DIEPTSIZ10  		(DWC_OTG_BASE + 0xA50)
+#define DIEPDMA10   		(DWC_OTG_BASE + 0xA54)
+#define DIEPCTL11   		(DWC_OTG_BASE + 0xA60)
+#define DIEPINT11   		(DWC_OTG_BASE + 0xA68)
+#define DIEPTSIZ11  		(DWC_OTG_BASE + 0xA70)
+#define DIEPDMA11   		(DWC_OTG_BASE + 0xA74)
+#define DIEPCTL12   		(DWC_OTG_BASE + 0xA80)
+#define DIEPINT12   		(DWC_OTG_BASE + 0xA88)
+#define DIEPTSIZ12  		(DWC_OTG_BASE + 0xA90)
+#define DIEPDMA12   		(DWC_OTG_BASE + 0xA94)
+#define DIEPCTL13   		(DWC_OTG_BASE + 0xAA0)
+#define DIEPINT13   		(DWC_OTG_BASE + 0xAA8)
+#define DIEPTSIZ13  		(DWC_OTG_BASE + 0xAB0)
+#define DIEPDMA13   		(DWC_OTG_BASE + 0xAB4)
+#define DIEPCTL14   		(DWC_OTG_BASE + 0xAC0)
+#define DIEPINT14   		(DWC_OTG_BASE + 0xAC8)
+#define DIEPTSIZ14  		(DWC_OTG_BASE + 0xAD0)
+#define DIEPDMA14   		(DWC_OTG_BASE + 0xAD4)
+#define DIEPCTL15   		(DWC_OTG_BASE + 0xAE0)
+#define DIEPINT15   		(DWC_OTG_BASE + 0xAE8)
+#define DIEPTSIZ15  		(DWC_OTG_BASE + 0xAF0)
+#define DIEPDMA15   		(DWC_OTG_BASE + 0xAF4)
+
+/* Device Logical OUT Endpoint-Specific Registers */
+#define DOEPCTL(x)  		(DWC_OTG_BASE + 0xB00 + 0x20 * (x))
+#define DXEPCTL_EPENA			(1 << 31)
+#define DXEPCTL_EPDIS			(1 << 30)
+#define DXEPCTL_SETD1PID		(1 << 29)
+#define DXEPCTL_SETODDFR		(1 << 29)
+#define DXEPCTL_SETD0PID		(1 << 28)
+#define DXEPCTL_SETEVENFR		(1 << 28)
+#define DXEPCTL_SNAK			(1 << 27)
+#define DXEPCTL_CNAK			(1 << 26)
+#define DXEPCTL_NAKSTS			(1 << 17)
+#define DXEPCTL_DPID			(1 << 16)
+#define DXEPCTL_EOFRNUM			(1 << 16)
+#define DXEPCTL_USBACTEP		(1 << 15)
+#define DXEPCTL_NEXTEP_MASK		(0xf << 11)
+#define DXEPCTL_NEXTEP_SHIFT		11
+#define DXEPCTL_NEXTEP_LIMIT		0xf
+#define DXEPCTL_NEXTEP(_x)		((_x) << 11)
+
+
+#define DOEPINT(x)  		(DWC_OTG_BASE + 0xB08 + 0x20 * (x))
+#define DXEPINT_INEPNAKEFF              (1 << 6)
+#define DXEPINT_BACK2BACKSETUP          (1 << 6)
+#define DXEPINT_INTKNEPMIS              (1 << 5)
+#define DXEPINT_INTKNTXFEMP             (1 << 4)
+#define DXEPINT_OUTTKNEPDIS             (1 << 4)
+#define DXEPINT_TIMEOUT                 (1 << 3)
+#define DXEPINT_SETUP                   (1 << 3)
+#define DXEPINT_AHBERR                  (1 << 2)
+#define DXEPINT_EPDISBLD                (1 << 1)
+#define DXEPINT_XFERCOMPL               (1 << 0)
+
+#define DOEPTSIZ(x) 		(DWC_OTG_BASE + 0xB10 + 0x20 * (x))
+#define DXEPTSIZ_MC_MASK		(0x3 << 29)
+#define DXEPTSIZ_MC_SHIFT		29
+#define DXEPTSIZ_MC_LIMIT		0x3
+#define DXEPTSIZ_MC(_x)			((_x) << 29)
+#define DXEPTSIZ_PKTCNT_MASK		(0x3ff << 19)
+#define DXEPTSIZ_PKTCNT_SHIFT		19
+#define DXEPTSIZ_PKTCNT_LIMIT		0x3ff
+#define DXEPTSIZ_PKTCNT_GET(_v)		(((_v) >> 19) & 0x3ff)
+#define DXEPTSIZ_PKTCNT(_x)		((_x) << 19)
+#define DXEPTSIZ_XFERSIZE_MASK		(0x7ffff << 0)
+#define DXEPTSIZ_XFERSIZE_SHIFT		0
+#define DXEPTSIZ_XFERSIZE_LIMIT		0x7ffff
+#define DXEPTSIZ_XFERSIZE_GET(_v)	(((_v) >> 0) & 0x7ffff)
+#define DXEPTSIZ_XFERSIZE(_x)		((_x) << 0)
+
+#define DOEPDMA(x)  		(DWC_OTG_BASE + 0xB14 + 0x20 * (x))
+#define DOEPCTL0    		(DWC_OTG_BASE + 0xB00)
+#define DOEPINT0    		(DWC_OTG_BASE + 0xB08)
+#define DOEPTSIZ0   		(DWC_OTG_BASE + 0xB10)
+#define DOEPTSIZ0_SUPCNT_MASK		(0x3 << 29)
+#define DOEPTSIZ0_SUPCNT_SHIFT		29
+#define DOEPTSIZ0_SUPCNT_LIMIT		0x3
+#define DOEPTSIZ0_SUPCNT(_x)		((_x) << 29)
+#define DOEPTSIZ0_PKTCNT		(1 << 19)
+#define DOEPTSIZ0_XFERSIZE_MASK		(0x7f << 0)
+#define DOEPTSIZ0_XFERSIZE_SHIFT	0
+
+#define DOEPDMA0    		(DWC_OTG_BASE + 0xB14)
+#define DOEPCTL1    		(DWC_OTG_BASE + 0xB20)
+#define DOEPINT1    		(DWC_OTG_BASE + 0xB28)
+#define DOEPTSIZ1   		(DWC_OTG_BASE + 0xB30)
+#define DOEPDMA1    		(DWC_OTG_BASE + 0xB34)
+#define DOEPCTL2    		(DWC_OTG_BASE + 0xB40)
+#define DOEPINT2    		(DWC_OTG_BASE + 0xB48)
+#define DOEPTSIZ2   		(DWC_OTG_BASE + 0xB50)
+#define DOEPDMA2    		(DWC_OTG_BASE + 0xB54)
+#define DOEPCTL3    		(DWC_OTG_BASE + 0xB60)
+#define DOEPINT3    		(DWC_OTG_BASE + 0xB68)
+#define DOEPTSIZ3   		(DWC_OTG_BASE + 0xB70)
+#define DOEPDMA3    		(DWC_OTG_BASE + 0xB74)
+#define DOEPCTL4    		(DWC_OTG_BASE + 0xB80)
+#define DOEPINT4    		(DWC_OTG_BASE + 0xB88)
+#define DOEPTSIZ4   		(DWC_OTG_BASE + 0xB90)
+#define DOEPDMA4    		(DWC_OTG_BASE + 0xB94)
+#define DOEPCTL5    		(DWC_OTG_BASE + 0xBA0)
+#define DOEPINT5    		(DWC_OTG_BASE + 0xBA8)
+#define DOEPTSIZ5   		(DWC_OTG_BASE + 0xBB0)
+#define DOEPDMA5    		(DWC_OTG_BASE + 0xBB4)
+#define DOEPCTL6    		(DWC_OTG_BASE + 0xBC0)
+#define DOEPINT6    		(DWC_OTG_BASE + 0xBC8)
+#define DOEPTSIZ6   		(DWC_OTG_BASE + 0xBD0)
+#define DOEPDMA6    		(DWC_OTG_BASE + 0xBD4)
+#define DOEPCTL7    		(DWC_OTG_BASE + 0xBE0)
+#define DOEPINT7    		(DWC_OTG_BASE + 0xBE8)
+#define DOEPTSIZ7   		(DWC_OTG_BASE + 0xBF0)
+#define DOEPDMA7    		(DWC_OTG_BASE + 0xBF4)
+#define DOEPCTL8    		(DWC_OTG_BASE + 0xC00)
+#define DOEPINT8    		(DWC_OTG_BASE + 0xC08)
+#define DOEPTSIZ8   		(DWC_OTG_BASE + 0xC10)
+#define DOEPDMA8    		(DWC_OTG_BASE + 0xC14)
+#define DOEPCTL9    		(DWC_OTG_BASE + 0xC20)
+#define DOEPINT9    		(DWC_OTG_BASE + 0xC28)
+#define DOEPTSIZ9   		(DWC_OTG_BASE + 0xC30)
+#define DOEPDMA9    		(DWC_OTG_BASE + 0xC34)
+#define DOEPCTL10   		(DWC_OTG_BASE + 0xC40)
+#define DOEPINT10   		(DWC_OTG_BASE + 0xC48)
+#define DOEPTSIZ10  		(DWC_OTG_BASE + 0xC50)
+#define DOEPDMA10   		(DWC_OTG_BASE + 0xC54)
+#define DOEPCTL11   		(DWC_OTG_BASE + 0xC60)
+#define DOEPINT11   		(DWC_OTG_BASE + 0xC68)
+#define DOEPTSIZ11  		(DWC_OTG_BASE + 0xC70)
+#define DOEPDMA11   		(DWC_OTG_BASE + 0xC74)
+#define DOEPCTL12   		(DWC_OTG_BASE + 0xC80)
+#define DOEPINT12   		(DWC_OTG_BASE + 0xC88)
+#define DOEPTSIZ12  		(DWC_OTG_BASE + 0xC90)
+#define DOEPDMA12   		(DWC_OTG_BASE + 0xC94)
+#define DOEPCTL13   		(DWC_OTG_BASE + 0xCA0)
+#define DOEPINT13   		(DWC_OTG_BASE + 0xCA8)
+#define DOEPTSIZ13  		(DWC_OTG_BASE + 0xCB0)
+#define DOEPDMA13   		(DWC_OTG_BASE + 0xCB4)
+#define DOEPCTL14   		(DWC_OTG_BASE + 0xCC0)
+#define DOEPINT14   		(DWC_OTG_BASE + 0xCC8)
+#define DOEPTSIZ14  		(DWC_OTG_BASE + 0xCD0)
+#define DOEPDMA14   		(DWC_OTG_BASE + 0xCD4)
+#define DOEPCTL15   		(DWC_OTG_BASE + 0xCE0)
+#define DOEPINT15   		(DWC_OTG_BASE + 0xCE8)
+#define DOEPTSIZ15  		(DWC_OTG_BASE + 0xCF0)
+#define DOEPDMA15   		(DWC_OTG_BASE + 0xCF4)
+
+/* Power and Clock Gating Register */
+#define PCGCCTL			(DWC_OTG_BASE + 0xE00)
+
+#define EP0FIFO			(DWC_OTG_BASE + 0x1000)
+
+#define PERI_CTRL16_PICOPHY_SIDDQ_BIT		(1<<0)
+#define PERI_CTRL16_PICOPHY_TXPREEMPHASISTUNE	(1<<31)
+#define PERI_CTRL15_HSICPHY_SIDDQ_BIT		(1<<16)
+#define PERI_CTRL14_NANOPHY_SIDDQ_BIT		(1<<0)
+#define PERI_CTRL0_USB2DVC_NANOPHY_BIT		(1<<7)
+#define NANOPHY_DMPULLDOWN    (1 << 6)    /* bit[6]:nanophy_dmpulldown;为1'b0 */
+#define NANOPHY_DPPULLDOWN    (1 << 5)    /* bit[5]:nanophy_dppulldown;为1'b0 */
+
+#define EN_LDO4_INT (1 << 4)
+#define EN_LDO8_INT (1 << 4)
+
+/* SCPEREN1/DIS1 */
+#define GT_CLK_USBHSICPHY480            (1<<26)
+#define GT_CLK_USBHSICPHY               (1<<25)
+#define GT_CLK_USBPICOPHY               (1<<24)
+#define GT_CLK_USBNANOPHY               (1<<23)
+/* SCPEREN3/DIS3 */
+#define GT_CLK_USB2HST                  (1<<18)
+#define GT_CLK_USB2DVC                  (1<<17)
+/* SCPERRSTEN3 */
+#define IP_RST_PICOPHY_POR              (1<<31)
+#define IP_RST_HSICPHY_POR              (1<<30)
+#define IP_RST_NANOPHY_POR              (1<<29)
+#define IP_RST_USB2DVC_PHY              (1<<28)
+#define IP_RST_USB2H_UTMI1              (1<<21)
+#define IP_RST_USB2H_UTMI0              (1<<20)
+#define IP_RST_USB2H_PHY                (1<<19)
+#define IP_RST_USB2HST                  (1<<18)
+#define IP_RST_USB2DVC                  (1<<17)
+/* SCPERRSTEN1 */
+#define IP_RST_HSICPHY                  (1<<25)
+#define IP_RST_PICOPHY                  (1<<24)
+#define IP_RST_NANOPHY                  (1<<23)
+
+/*
+ * USB directions
+ *
+ * This bit flag is used in endpoint descriptors' bEndpointAddress field.
+ * It's also one of three fields in control requests bRequestType.
+ */
+#define USB_DIR_OUT                     0               /* to device */
+#define USB_DIR_IN                      0x80            /* to host */
+
+/*
+ * Descriptor types ... USB 2.0 spec table 9.5
+ */
+#define USB_DT_DEVICE                   0x01
+#define USB_DT_CONFIG                   0x02
+#define USB_DT_STRING                   0x03
+#define USB_DT_INTERFACE                0x04
+#define USB_DT_ENDPOINT                 0x05
+#define USB_DT_DEVICE_QUALIFIER         0x06
+#define USB_DT_OTHER_SPEED_CONFIG       0x07
+#define USB_DT_INTERFACE_POWER          0x08
+/* these are from a minor usb 2.0 revision (ECN) */
+#define USB_DT_OTG                      0x09
+#define USB_DT_DEBUG                    0x0a
+#define USB_DT_INTERFACE_ASSOCIATION    0x0b
+/* these are from the Wireless USB spec */
+#define USB_DT_SECURITY                 0x0c
+#define USB_DT_KEY                      0x0d
+#define USB_DT_ENCRYPTION_TYPE          0x0e
+#define USB_DT_BOS                      0x0f
+#define USB_DT_DEVICE_CAPABILITY        0x10
+#define USB_DT_WIRELESS_ENDPOINT_COMP   0x11
+#define USB_DT_WIRE_ADAPTER             0x21
+#define USB_DT_RPIPE                    0x22
+#define USB_DT_CS_RADIO_CONTROL         0x23
+
+/*
+ * USB recipients, the third of three bRequestType fields
+ */
+#define USB_RECIP_MASK                  0x1f
+#define USB_RECIP_DEVICE                0x00
+#define USB_RECIP_INTERFACE             0x01
+#define USB_RECIP_ENDPOINT              0x02
+#define USB_RECIP_OTHER                 0x03
+
+/* IN/OUT will STALL */
+#define USB_ENDPOINT_HALT      			0
+
+/*
+ * Endpoints
+ */
+#define USB_ENDPOINT_NUMBER_MASK        0x0f    /* in bEndpointAddress */
+#define USB_ENDPOINT_DIR_MASK           0x80
+
+#define USB_ENDPOINT_XFERTYPE_MASK      0x03    /* in bmAttributes */
+#define USB_ENDPOINT_XFER_CONTROL       0
+#define USB_ENDPOINT_XFER_ISOC          1
+#define USB_ENDPOINT_XFER_BULK          2
+#define USB_ENDPOINT_XFER_INT           3
+#define USB_ENDPOINT_MAX_ADJUSTABLE     0x80
+
+/*
+ * Standard requests, for the bRequest field of a SETUP packet.
+ *
+ * These are qualified by the bRequestType field, so that for example
+ * TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
+ * by a GET_STATUS request.
+ */
+#define USB_REQ_GET_STATUS              0x00
+#define USB_REQ_CLEAR_FEATURE           0x01
+#define USB_REQ_SET_FEATURE             0x03
+#define USB_REQ_SET_ADDRESS             0x05
+#define USB_REQ_GET_DESCRIPTOR          0x06
+#define USB_REQ_SET_DESCRIPTOR          0x07
+#define USB_REQ_GET_CONFIGURATION       0x08
+#define USB_REQ_SET_CONFIGURATION       0x09
+#define USB_REQ_GET_INTERFACE           0x0A
+#define USB_REQ_SET_INTERFACE           0x0B
+#define USB_REQ_SYNCH_FRAME             0x0C
+
+/* USB_DT_DEVICE: Device descriptor */
+struct usb_device_descriptor {
+        unsigned char  bLength;
+        unsigned char  bDescriptorType;
+
+        unsigned short bcdUSB;
+        unsigned char  bDeviceClass;
+        unsigned char  bDeviceSubClass;
+        unsigned char  bDeviceProtocol;
+        unsigned char  bMaxPacketSize0;
+        unsigned short idVendor;
+        unsigned short idProduct;
+        unsigned short bcdDevice;
+        unsigned char  iManufacturer;
+        unsigned char  iProduct;
+        unsigned char  iSerialNumber;
+        unsigned char  bNumConfigurations;
+} __attribute__ ((packed));
+
+#define USB_DT_DEVICE_SIZE              18
+
+/*
+ * Device and/or Interface Class codes
+ * as found in bDeviceClass or bInterfaceClass
+ * and defined by www.usb.org documents
+ */
+#define USB_CLASS_PER_INTERFACE         0       /* for DeviceClass */
+#define USB_CLASS_AUDIO                 1
+#define USB_CLASS_COMM                  2
+#define USB_CLASS_HID                   3
+#define USB_CLASS_PHYSICAL              5
+#define USB_CLASS_STILL_IMAGE           6
+#define USB_CLASS_PRINTER               7
+#define USB_CLASS_MASS_STORAGE          8
+#define USB_CLASS_HUB                   9
+#define USB_CLASS_CDC_DATA              0x0a
+#define USB_CLASS_CSCID                 0x0b    /* chip+ smart card */
+#define USB_CLASS_CONTENT_SEC           0x0d    /* content security */
+#define USB_CLASS_VIDEO                 0x0e
+#define USB_CLASS_WIRELESS_CONTROLLER   0xe0
+#define USB_CLASS_MISC                  0xef
+#define USB_CLASS_APP_SPEC              0xfe
+#define USB_CLASS_VENDOR_SPEC           0xff
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_CONFIG: Configuration descriptor information.
+ *
+ * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
+ * descriptor type is different.  Highspeed-capable devices can look
+ * different depending on what speed they're currently running.  Only
+ * devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
+ * descriptors.
+ */
+struct usb_config_descriptor {
+       unsigned char  bLength;
+       unsigned char  bDescriptorType;
+
+       unsigned short wTotalLength;
+       unsigned char  bNumInterfaces;
+       unsigned char  bConfigurationValue;
+       unsigned char  iConfiguration;
+       unsigned char  bmAttributes;
+       unsigned char  bMaxPower;
+} __attribute__((packed));
+
+#define USB_DT_CONFIG_SIZE              9
+
+/* from config descriptor bmAttributes */
+#define USB_CONFIG_ATT_ONE              (1 << 7)        /* must be set */
+#define USB_CONFIG_ATT_SELFPOWER        (1 << 6)        /* self powered */
+#define USB_CONFIG_ATT_WAKEUP           (1 << 5)        /* can wakeup */
+#define USB_CONFIG_ATT_BATTERY          (1 << 4)        /* battery powered */
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_STRING: String descriptor */
+struct usb_string_descriptor {
+        unsigned char  bLength;
+        unsigned char  bDescriptorType;
+
+        unsigned short wString[16];             /* UTF-16LE encoded */
+} __attribute__((packed));
+
+/*-------------------------------------------------------------------------*/
+/* USB_DT_INTERFACE: Interface descriptor */
+struct usb_interface_descriptor {
+        unsigned char  bLength;
+        unsigned char  bDescriptorType;
+
+        unsigned char  bInterfaceNumber;
+        unsigned char  bAlternateSetting;
+        unsigned char  bNumEndpoints;
+        unsigned char  bInterfaceClass;
+        unsigned char  bInterfaceSubClass;
+        unsigned char  bInterfaceProtocol;
+        unsigned char  iInterface;
+};
+
+#define USB_DT_INTERFACE_SIZE           9
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_ENDPOINT: Endpoint descriptor */
+struct usb_endpoint_descriptor {
+        unsigned char  bLength;
+        unsigned char  bDescriptorType;
+
+        unsigned char  bEndpointAddress;
+        unsigned char  bmAttributes;
+        unsigned short wMaxPacketSize;
+        unsigned char  bInterval;
+} __attribute__ ((packed));
+
+#define USB_DT_ENDPOINT_SIZE            7
+#define USB_DT_ENDPOINT_AUDIO_SIZE      9       /* Audio extension */
+
+extern int usb_need_reset;
+
+/**
+ * This union represents the bit fields in the DMA Descriptor
+ * status quadlet. Read the quadlet into the <i>d32</i> member then
+ * set/clear the bits using the <i>b</i>it, <i>b_iso_out</i> and
+ * <i>b_iso_in</i> elements.
+ */
+typedef union dev_dma_desc_sts {
+		/** raw register data */
+	unsigned int d32;
+		/** quadlet bits */
+	struct {
+		/** Received number of bytes */
+		unsigned bytes:16;
+		/** NAK bit - only for OUT EPs */
+		unsigned nak:1;
+		unsigned reserved17_22:6;
+		/** Multiple Transfer - only for OUT EPs */
+		unsigned mtrf:1;
+		/** Setup Packet received - only for OUT EPs */
+		unsigned sr:1;
+		/** Interrupt On Complete */
+		unsigned ioc:1;
+		/** Short Packet */
+		unsigned sp:1;
+		/** Last */
+		unsigned l:1;
+		/** Receive Status */
+		unsigned sts:2;
+		/** Buffer Status */
+		unsigned bs:2;
+	} b;
+
+//#ifdef DWC_EN_ISOC
+		/** iso out quadlet bits */
+	struct {
+		/** Received number of bytes */
+		unsigned rxbytes:11;
+
+		unsigned reserved11:1;
+		/** Frame Number */
+		unsigned framenum:11;
+		/** Received ISO Data PID */
+		unsigned pid:2;
+		/** Interrupt On Complete */
+		unsigned ioc:1;
+		/** Short Packet */
+		unsigned sp:1;
+		/** Last */
+		unsigned l:1;
+		/** Receive Status */
+		unsigned rxsts:2;
+		/** Buffer Status */
+		unsigned bs:2;
+	} b_iso_out;
+
+		/** iso in quadlet bits */
+	struct {
+		/** Transmited number of bytes */
+		unsigned txbytes:12;
+		/** Frame Number */
+		unsigned framenum:11;
+		/** Transmited ISO Data PID */
+		unsigned pid:2;
+		/** Interrupt On Complete */
+		unsigned ioc:1;
+		/** Short Packet */
+		unsigned sp:1;
+		/** Last */
+		unsigned l:1;
+		/** Transmit Status */
+		unsigned txsts:2;
+		/** Buffer Status */
+		unsigned bs:2;
+	} b_iso_in;
+//#endif                                /* DWC_EN_ISOC */
+} dev_dma_desc_sts_t;
+
+/**
+ * DMA Descriptor structure
+ *
+ * DMA Descriptor structure contains two quadlets:
+ * Status quadlet and Data buffer pointer.
+ */
+typedef struct dwc_otg_dev_dma_desc {
+	/** DMA Descriptor status quadlet */
+	dev_dma_desc_sts_t status;
+	/** DMA Descriptor data buffer pointer */
+	unsigned int buf;
+} dwc_otg_dev_dma_desc_t;
+
+extern void usb_reinit(void);
+
+#endif	/* __DWC_USB_H__*/
diff --git a/uefi/arm-trusted-firmware/plat/hikey/partitions.c b/uefi/arm-trusted-firmware/plat/hikey/partitions.c
new file mode 100644
index 0000000..e4d303c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/partitions.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <dw_mmc.h>
+#include <errno.h>
+#include <io_storage.h>
+#include <mmio.h>
+#include <partitions.h>
+#include <platform_def.h>
+#include <string.h>
+#include "hikey_private.h"
+
+#define EFI_ENTRIES		128
+#define EFI_ENTRY_SIZE		(sizeof(struct efi_entry))
+#define EFI_MBR_SIZE		512
+#define EFI_HEADER_SIZE		512
+#define EFI_TOTAL_SIZE		(EFI_MBR_SIZE + EFI_HEADER_SIZE +	\
+				EFI_ENTRY_SIZE * EFI_ENTRIES)
+
+struct efi_header {
+	char		signature[8];
+	uint32_t	revision;
+	uint32_t	size;
+	uint32_t	header_crc;
+	uint32_t	reserved;
+	uint64_t	current_lba;
+	uint64_t	backup_lba;
+	uint64_t	first_lba;
+	uint64_t	last_lba;
+	uint8_t		disk_uuid[16];
+	/* starting LBA of array of partition entries */
+	uint64_t	part_lba;
+	/* number of partition entries in array */
+	uint32_t	part_num;
+	/* size of a single partition entry (usually 128) */
+	uint32_t	part_size;
+	uint32_t	part_crc;
+};
+
+struct efi_entry {
+	uint8_t		type_uuid[16];
+	uint8_t		uniq_uuid[16];
+	uint64_t	first_lba;
+	uint64_t	last_lba;
+	uint64_t	attr;
+	uint16_t	name[EFI_NAMELEN];
+};
+
+/* the first entry is dummy for ptable (covers both primary & secondary) */
+static struct ptentry ptable[EFI_ENTRIES + 1];
+static int entries;	/* partition entry entries */
+
+static void dump_entries(void)
+{
+	int i;
+
+	VERBOSE("Partition table with %d entries:\n", entries);
+	for (i = 0; i < entries; i++) {
+		VERBOSE("%s %llx-%llx\n", ptable[i].name,
+			ptable[i].start,
+			ptable[i].start + ptable[i].length - 4);
+	}
+}
+
+static int convert_ascii_string(uint16_t *str_in, uint8_t *str_out)
+{
+	uint8_t *name = (uint8_t *)str_in;
+	int i;
+
+	if (name[0] == '\0' || !str_in || !str_out)
+		return -EINVAL;
+	for (i = 1; i < (EFI_NAMELEN << 1); i += 2) {
+		if (name[i] != '\0')
+			return -EINVAL;
+	}
+	for (i = 0; i < (EFI_NAMELEN << 1); i += 2) {
+		str_out[i >> 1] = name[i];
+		if (name[i] == '\0')
+			break;
+	}
+	return 0;
+}
+
+static int parse_entry(uintptr_t buf)
+{
+	struct efi_entry *entry = (struct efi_entry *)buf;
+	int ret;
+
+	/* exhaused partition entry */
+	if ((entry->first_lba == 0) && (entry->last_lba == 0))
+		return 1;
+	ret = convert_ascii_string(entry->name, (uint8_t *)ptable[entries].name);
+	if (ret < 0)
+		return ret;
+	ptable[entries].start = (uint64_t)entry->first_lba * 512;
+	ptable[entries].length = (uint64_t)(entry->last_lba - entry->first_lba + 1) * 512;
+	entries++;
+	return 0;
+}
+
+/* create dummy entry for ptable */
+static void create_dummy_entry(void)
+{
+	int bytes;
+	ptable[entries].start = 0;
+	ptable[entries].length = 0;
+	bytes = sprintf(ptable[entries].name, "ptable");
+	ptable[entries].name[bytes] = '\0';
+	entries++;
+}
+
+struct ptentry *find_ptn(const char *str)
+{
+	struct ptentry *ptn = NULL;
+	int i;
+
+	for (i = 0; i < entries; i++) {
+		if (!strcmp(ptable[i].name, str)) {
+			ptn = &ptable[i];
+			break;
+		}
+	}
+	return ptn;
+}
+
+int get_partition(void)
+{
+	int result = IO_FAIL;
+	int i, ret, num_entries;
+	size_t bytes_read;
+	uintptr_t emmc_dev_handle, spec, img_handle;
+	unsigned int buf[MMC_BLOCK_SIZE >> 2];
+	struct efi_header *hd = NULL;
+
+	create_dummy_entry();
+	result = plat_get_image_source(NORMAL_EMMC_NAME, &emmc_dev_handle,
+				       &spec);
+	if (result) {
+		WARN("failed to open eMMC normal partition\n");
+		return result;
+	}
+	result = io_open(emmc_dev_handle, spec, &img_handle);
+	if (result != IO_SUCCESS) {
+		WARN("Failed to open eMMC device\n");
+		return result;
+	}
+	result = io_seek(img_handle, IO_SEEK_SET, 0);
+	if (result)
+		goto exit;
+	result = io_read(img_handle, (uintptr_t)buf, EFI_MBR_SIZE,
+			 &bytes_read);
+	if ((result != IO_SUCCESS) || (bytes_read < EFI_MBR_SIZE)) {
+		WARN("Failed to read eMMC (%i)\n", result);
+		goto exit;
+	}
+	/* check the magic number in last word */
+	if (buf[(MMC_BLOCK_SIZE >> 2) - 1] != 0xaa550000) {
+		WARN("Can't find MBR protection information\n");
+		goto exit;
+	}
+
+	result = io_read(img_handle, (uintptr_t)buf, EFI_HEADER_SIZE,
+			 &bytes_read);
+	if ((result != IO_SUCCESS) || (bytes_read < EFI_HEADER_SIZE)) {
+		WARN("Failed to read eMMC (%i)\n", result);
+		goto exit;
+	}
+	hd = (struct efi_header *)((uintptr_t)buf);
+	if (strncmp(hd->signature, "EFI PART", 8)) {
+		WARN("Failed to find partition table\n");
+		goto exit;
+	}
+	num_entries = hd->part_num;
+	for (i = 0; i < num_entries; i++) {
+		result = io_read(img_handle, (uintptr_t)buf, EFI_HEADER_SIZE,
+				 &bytes_read);
+		if ((result != IO_SUCCESS) || (bytes_read < EFI_HEADER_SIZE)) {
+			WARN("Failed to read eMMC (%i)\n", result);
+			goto exit;
+		}
+		/* each header contains four partition entries */
+		ret = parse_entry((uintptr_t)buf);
+		if (ret)
+			break;
+		ret = parse_entry((uintptr_t)buf + EFI_ENTRY_SIZE);
+		if (ret)
+			break;
+		ret = parse_entry((uintptr_t)buf + EFI_ENTRY_SIZE * 2);
+		if (ret)
+			break;
+		ret = parse_entry((uintptr_t)buf + EFI_ENTRY_SIZE * 3);
+		if (ret)
+			break;
+	}
+exit:
+	io_close(img_handle);
+	update_fip_spec();
+	dump_entries();
+	return result;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/plat_io_storage.c b/uefi/arm-trusted-firmware/plat/hikey/plat_io_storage.c
new file mode 100644
index 0000000..6158710
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/plat_io_storage.c
@@ -0,0 +1,694 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <dw_mmc.h>
+#include <fastboot.h>
+#include <io_block.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <mmio.h>
+#include <partitions.h>
+#include <platform_def.h>
+#include <semihosting.h>	/* For FOPEN_MODE_... */
+#include <string.h>
+#include "hikey_private.h"
+
+#define LOADER_MAX_ENTRIES		2
+#define PTABLE_MAX_ENTRIES		3
+#define USER_MAX_ENTRIES		2
+
+#define FLUSH_BASE			(DDR_BASE + 0x100000)
+
+struct entry_head {
+	unsigned char	magic[8];
+	unsigned char	name[8];
+	unsigned int	start;	/* lba */
+	unsigned int	count;	/* lba */
+	unsigned int	flag;
+};
+
+static const io_dev_connector_t *bl1_mem_dev_con;
+static uintptr_t bl1_mem_dev_spec;
+static uintptr_t loader_mem_dev_handle;
+static uintptr_t bl1_mem_init_params;
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_spec;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *dw_mmc_dev_con;
+static struct block_ops dw_mmc_ops;
+static uintptr_t emmc_dev_handle;
+
+#define SPARSE_FILL_BUFFER_ADDRESS	0x18000000
+#define SPARSE_FILL_BUFFER_SIZE		0x08000000
+
+/* Page 1024, since only a few pages before 2048 are used as partition table */
+#define SERIALNO_OFFSET			(1024 * 512)
+
+static const io_block_spec_t loader_mem_spec = {
+	/* l-loader.bin that contains bl1.bin */
+	.offset = LOADER_RAM_BASE,
+	.length = BL1_RO_LIMIT - LOADER_RAM_BASE,
+};
+
+static const io_block_spec_t boot_emmc_spec = {
+	.offset = MMC_LOADER_BASE,
+	.length = BL1_RO_LIMIT - LOADER_RAM_BASE,
+};
+
+static const io_block_spec_t normal_emmc_spec = {
+	.offset = MMC_BASE,
+	.length = MMC_SIZE,
+};
+
+static io_block_spec_t fip_block_spec = {
+	.offset = 0,
+	.length = 0,
+};
+
+static const io_file_spec_t bl2_file_spec = {
+	.path = BL2_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_file_spec = {
+	.path = BL30_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_file_spec = {
+	.path = BL31_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_file_spec = {
+	.path = BL32_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_file_spec = {
+	.path = BL33_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static int open_loader_mem(const uintptr_t spec);
+static int open_fip(const uintptr_t spec);
+static int open_dw_mmc(const uintptr_t spec);
+static int open_dw_mmc_boot(const uintptr_t spec);
+
+struct plat_io_policy {
+	const char	*image_name;
+	uintptr_t	*dev_handle;
+	uintptr_t	image_spec;
+	int		(*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+	{
+		LOADER_MEM_NAME,
+		&loader_mem_dev_handle,
+		(uintptr_t)&loader_mem_spec,
+		open_loader_mem
+	}, {
+		BOOT_EMMC_NAME,
+		&emmc_dev_handle,
+		(uintptr_t)&boot_emmc_spec,
+		open_dw_mmc_boot
+	}, {
+		NORMAL_EMMC_NAME,
+		&emmc_dev_handle,
+		(uintptr_t)&normal_emmc_spec,
+		open_dw_mmc
+	}, {
+		FIP_IMAGE_NAME,
+		&emmc_dev_handle,
+		(uintptr_t)&fip_block_spec,
+		open_dw_mmc
+	}, {
+		BL2_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl2_file_spec,
+		open_fip
+	}, {
+		BL30_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl30_file_spec,
+		open_fip
+	}, {
+		BL31_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl31_file_spec,
+		open_fip
+	}, {
+		BL32_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl32_file_spec,
+		open_fip
+	}, {
+		BL33_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl33_file_spec,
+		open_fip
+	}, {
+		0, 0, 0, 0
+	}
+};
+
+static int open_loader_mem(const uintptr_t spec)
+{
+	int result = IO_FAIL;
+	uintptr_t image_handle;
+
+	result = io_dev_init(loader_mem_dev_handle, bl1_mem_init_params);
+	if (result == IO_SUCCESS) {
+		result = io_open(loader_mem_dev_handle, spec, &image_handle);
+		if (result == IO_SUCCESS) {
+			io_close(image_handle);
+		}
+	}
+	return result;
+}
+
+static int open_fip(const uintptr_t spec)
+{
+	int result = IO_FAIL;
+
+	/* See if a Firmware Image Package is available */
+	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME);
+	if (result == IO_SUCCESS) {
+		INFO("Using FIP\n");
+		/*TODO: Check image defined in spec is present in FIP. */
+	}
+	return result;
+}
+
+
+static int open_dw_mmc(const uintptr_t spec)
+{
+	int result = IO_FAIL;
+	uintptr_t image_handle;
+
+	/* indicate to select normal partition in eMMC */
+	result = io_dev_init(emmc_dev_handle, 0);
+	if (result == IO_SUCCESS) {
+		result = io_open(emmc_dev_handle, spec, &image_handle);
+		if (result == IO_SUCCESS) {
+			/* INFO("Using DW MMC IO\n"); */
+			io_close(image_handle);
+		}
+	}
+	return result;
+}
+
+static int open_dw_mmc_boot(const uintptr_t spec)
+{
+	int result = IO_FAIL;
+	uintptr_t image_handle;
+
+	/* indicate to select boot partition in eMMC */
+	result = io_dev_init(emmc_dev_handle, 1);
+	if (result == IO_SUCCESS) {
+		result = io_open(emmc_dev_handle, spec, &image_handle);
+		if (result == IO_SUCCESS) {
+			/* INFO("Using DW MMC IO\n"); */
+			io_close(image_handle);
+		}
+	}
+	return result;
+}
+
+void io_setup(void)
+{
+	int io_result = IO_FAIL;
+
+	/* Register the IO devices on this platform */
+	io_result = register_io_dev_fip(&fip_dev_con);
+	assert(io_result == IO_SUCCESS);
+
+	io_result = register_io_dev_block(&dw_mmc_dev_con);
+	assert(io_result == IO_SUCCESS);
+
+	io_result = register_io_dev_memmap(&bl1_mem_dev_con);
+	assert(io_result == IO_SUCCESS);
+
+	/* Open connections to devices and cache the handles */
+	io_result = io_dev_open(fip_dev_con, fip_dev_spec, &fip_dev_handle);
+	assert(io_result == IO_SUCCESS);
+
+	dw_mmc_ops.init = init_mmc;
+	dw_mmc_ops.read = mmc0_read;
+	dw_mmc_ops.write = mmc0_write;
+	io_result = io_dev_open(dw_mmc_dev_con, (uintptr_t)&dw_mmc_ops,
+				&emmc_dev_handle);
+	assert(io_result == IO_SUCCESS);
+
+	io_result = io_dev_open(bl1_mem_dev_con, bl1_mem_dev_spec,
+				&loader_mem_dev_handle);
+	assert(io_result == IO_SUCCESS);
+
+	/* Ignore improbable errors in release builds */
+	(void)io_result;
+}
+
+/* Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy */
+int plat_get_image_source(const char *image_name, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	int result = IO_FAIL;
+	const struct plat_io_policy *policy;
+
+	if ((image_name != NULL) && (dev_handle != NULL) &&
+	    (image_spec != NULL)) {
+		policy = policies;
+		while (policy->image_name != NULL) {
+			if (strcmp(policy->image_name, image_name) == 0) {
+				result = policy->check(policy->image_spec);
+				if (result == IO_SUCCESS) {
+					*image_spec = policy->image_spec;
+					*dev_handle = *(policy->dev_handle);
+					break;
+				}
+			}
+			policy++;
+		}
+	} else {
+		result = IO_FAIL;
+	}
+	return result;
+}
+
+int update_fip_spec(void)
+{
+	struct ptentry *ptn;
+
+	ptn = find_ptn("fastboot");
+	if (!ptn) {
+		WARN("failed to find partition fastboot\n");
+		ptn = find_ptn("bios");
+		if (!ptn) {
+			WARN("failed to find partition bios\n");
+			return IO_FAIL;
+		}
+	}
+	VERBOSE("%s: name:%s, start:%llx, length:%llx\n",
+		__func__, ptn->name, ptn->start, ptn->length);
+	fip_block_spec.offset = ptn->start;
+	fip_block_spec.length = ptn->length;
+	return IO_SUCCESS;
+}
+
+static int fetch_entry_head(void *buf, int num, struct entry_head *hd)
+{
+	unsigned char magic[8] = "ENTRYHDR";
+	if (hd == NULL)
+		return IO_FAIL;
+	memcpy((void *)hd, buf, sizeof(struct entry_head) * num);
+	if (!strncmp((void *)hd->magic, (void *)magic, 8))
+		return IO_SUCCESS;
+	return IO_NOT_SUPPORTED;
+}
+
+static int flush_loader(void)
+{
+	struct entry_head entries[5];
+	uintptr_t img_handle, spec;
+	int result = IO_FAIL;
+	size_t bytes_read, length;
+	ssize_t offset;
+	int i, fp;
+
+	result = fetch_entry_head((void *)(FLUSH_BASE + 28),
+				  LOADER_MAX_ENTRIES, entries);
+	if (result) {
+		WARN("failed to parse entries in loader image\n");
+		return result;
+	}
+
+	spec = 0;
+	for (i = 0, fp = 0; i < LOADER_MAX_ENTRIES; i++) {
+		if (entries[i].flag != 1) {
+			WARN("Invalid flag in entry:0x%x\n", entries[i].flag);
+			return IO_NOT_SUPPORTED;
+		}
+		result = plat_get_image_source(BOOT_EMMC_NAME, &emmc_dev_handle,
+					       &spec);
+		if (result) {
+			WARN("failed to open emmc boot area\n");
+			return result;
+		}
+		/* offset in Boot Area1 */
+		offset = MMC_LOADER_BASE + entries[i].start * 512;
+
+		result = io_open(emmc_dev_handle, spec, &img_handle);
+		if (result != IO_SUCCESS) {
+			WARN("Failed to open memmap device\n");
+			return result;
+		}
+		length = entries[i].count * 512;
+
+		result = io_seek(img_handle, IO_SEEK_SET, offset);
+		if (result)
+			goto exit;
+
+		if (i == 1)
+			fp = (entries[1].start - entries[0].start) * 512;
+		result = io_write(img_handle, FLUSH_BASE + fp, length,
+				  &bytes_read);
+		if ((result != IO_SUCCESS) || (bytes_read < length)) {
+			WARN("Failed to write '%s' file (%i)\n",
+			     LOADER_MEM_NAME, result);
+			goto exit;
+		}
+		io_close(img_handle);
+	}
+	return result;
+exit:
+	io_close(img_handle);
+	return result;
+}
+
+/*
+ * Flush l-loader.bin (loader & bl1.bin) into Boot Area1 of eMMC.
+ */
+int flush_loader_image(void)
+{
+	uintptr_t bl1_image_spec;
+	int result = IO_FAIL;
+	size_t bytes_read, length;
+	uintptr_t img_handle;
+
+	result = plat_get_image_source(LOADER_MEM_NAME, &loader_mem_dev_handle,
+				       &bl1_image_spec);
+
+	result = io_open(loader_mem_dev_handle, bl1_image_spec, &img_handle);
+	if (result != IO_SUCCESS) {
+		WARN("Failed to open memmap device\n");
+		goto exit;
+	}
+	length = loader_mem_spec.length;
+	result = io_read(img_handle, FLUSH_BASE, length, &bytes_read);
+	if ((result != IO_SUCCESS) || (bytes_read < length)) {
+		WARN("Failed to load '%s' file (%i)\n", LOADER_MEM_NAME, result);
+		goto exit;
+	}
+	io_close(img_handle);
+
+	result = flush_loader();
+	if (result != IO_SUCCESS) {
+		io_dev_close(loader_mem_dev_handle);
+		return result;
+	}
+exit:
+	io_close(img_handle);
+	io_dev_close(loader_mem_dev_handle);
+	return result;
+}
+
+static int flush_single_image(const char *mmc_name, unsigned long img_addr,
+				ssize_t offset, size_t length)
+{
+	uintptr_t img_handle, spec = 0;
+	size_t bytes_read;
+	int result = IO_FAIL;
+
+	result = plat_get_image_source(mmc_name, &emmc_dev_handle,
+				       &spec);
+	if (result) {
+		NOTICE("failed to open emmc user data area\n");
+		return result;
+	}
+
+	result = io_open(emmc_dev_handle, spec, &img_handle);
+	if (result != IO_SUCCESS) {
+		NOTICE("Failed to open memmap device\n");
+		return result;
+	}
+
+	result = io_seek(img_handle, IO_SEEK_SET, offset);
+	if (result) {
+		NOTICE("Failed to seek at offset:0x%x\n", offset);
+		goto exit;
+	}
+
+	result = io_write(img_handle, img_addr, length,
+			  &bytes_read);
+	if ((result != IO_SUCCESS) || (bytes_read < length)) {
+		NOTICE("Failed to write file (%i)\n", result);
+		goto exit;
+	}
+exit:
+	io_close(img_handle);
+	return result;
+}
+
+static int is_sparse_image(unsigned long img_addr)
+{
+	if (*(uint32_t *)img_addr == SPARSE_HEADER_MAGIC)
+		return 1;
+	return 0;
+}
+
+static int do_unsparse(char *cmdbuf, unsigned long img_addr, unsigned long img_length)
+{
+	sparse_header_t *header = (sparse_header_t *)img_addr;
+	chunk_header_t *chunk = NULL;
+	struct ptentry *ptn;
+	void *data = (void *)img_addr;
+	uint64_t out_blks = 0, out_length = 0;
+	uint64_t length;
+	uint32_t fill_value;
+	uint64_t left, count;
+	int i, result;
+
+	ptn = find_ptn(cmdbuf);
+	if (!ptn) {
+		NOTICE("failed to find partition %s\n", cmdbuf);
+		return IO_FAIL;
+	}
+	length = (uint64_t)(header->total_blks) * (uint64_t)(header->blk_sz);
+	if (length > ptn->length) {
+		NOTICE("Unsparsed image length is %lld, pentry length is %lld.\n",
+			length, ptn->length);
+		return IO_FAIL;
+	}
+
+	data = (void *)((unsigned long)data + header->file_hdr_sz);
+	for (i = 0; i < header->total_chunks; i++) {
+		chunk = (chunk_header_t *)data;
+		data = (void *)((unsigned long)data + sizeof(chunk_header_t));
+		length = (uint64_t)chunk->chunk_sz * (uint64_t)header->blk_sz;
+
+		switch (chunk->chunk_type) {
+		case CHUNK_TYPE_RAW:
+			result = flush_single_image(NORMAL_EMMC_NAME,
+						    (unsigned long)data,
+						    ptn->start + out_length, length);
+			if (result < 0) {
+				NOTICE("sparse: failed to flush raw chunk\n");
+				return result;
+			}
+			out_blks += length / 512;
+			out_length += length;
+			/* next chunk is just after the raw data */
+			data = (void *)((unsigned long)data + length);
+			break;
+		case CHUNK_TYPE_FILL:
+			if (chunk->total_sz != (sizeof(unsigned int) + sizeof(chunk_header_t))) {
+				NOTICE("sparse: bad chunk size\n");
+				return IO_FAIL;
+			}
+			fill_value = *(unsigned int *)data;
+			if (fill_value != 0) {
+				NOTICE("sparse: filled value shouldn't be zero.\n");
+			}
+			memset((void *)SPARSE_FILL_BUFFER_ADDRESS,
+				0, SPARSE_FILL_BUFFER_SIZE);
+			left = length;
+			while (left > 0) {
+				if (left < SPARSE_FILL_BUFFER_SIZE)
+					count = left;
+				else
+					count = SPARSE_FILL_BUFFER_SIZE;
+				result = flush_single_image(NORMAL_EMMC_NAME,
+							    SPARSE_FILL_BUFFER_ADDRESS,
+							    ptn->start + out_length, count);
+				if (result < 0) {
+					WARN("sparse: failed to flush fill chunk\n");
+					return result;
+				}
+				out_blks += count / 512;
+				out_length += count;
+				left = left - count;
+			}
+			/* next chunk is just after the filled data */
+			data = (void *)((unsigned long)data + sizeof(unsigned int));
+			break;
+		case CHUNK_TYPE_DONT_CARE:
+			if (chunk->total_sz != sizeof(chunk_header_t)) {
+				NOTICE("sparse: unmatched chunk size\n");
+				return IO_FAIL;
+			}
+			out_blks += length / 512;
+			out_length += length;
+			break;
+		default:
+			NOTICE("sparse: unrecognized type 0x%x\n", chunk->chunk_type);
+			break;
+		}
+	}
+	return 0;
+}
+
+/* Page 1024 is used to store serial number */
+int flush_random_serialno(unsigned long addr, unsigned long length)
+{
+	int result;
+
+	memset((void *)SPARSE_FILL_BUFFER_ADDRESS, 0, 512);
+	memcpy((void *)SPARSE_FILL_BUFFER_ADDRESS, (void *)addr, length);
+	result = flush_single_image(NORMAL_EMMC_NAME, SPARSE_FILL_BUFFER_ADDRESS,
+				    SERIALNO_OFFSET, 512);
+	return result;
+}
+
+char *load_serialno(void)
+{
+	uintptr_t img_handle, spec = 0;
+	size_t bytes_read;
+	struct random_serial_num *random = NULL;
+	int result;
+
+	result = plat_get_image_source(NORMAL_EMMC_NAME, &emmc_dev_handle,
+				       &spec);
+	if (result) {
+		NOTICE("failed to open emmc user data area\n");
+		return NULL;
+	}
+
+	result = io_open(emmc_dev_handle, spec, &img_handle);
+	if (result != IO_SUCCESS) {
+		NOTICE("Failed to open memmap device\n");
+		return NULL;
+	}
+
+	result = io_seek(img_handle, IO_SEEK_SET, SERIALNO_OFFSET);
+	if (result) {
+		NOTICE("Failed to seek at offset 0\n");
+		goto exit;
+	}
+	result = io_read(img_handle, SPARSE_FILL_BUFFER_ADDRESS, 512, &bytes_read);
+	if ((result != IO_SUCCESS) || (bytes_read < 512)) {
+		NOTICE("Failed to load '%s' file (%i)\n", LOADER_MEM_NAME, result);
+		goto exit;
+	}
+	io_close(img_handle);
+
+	random = (struct random_serial_num *)SPARSE_FILL_BUFFER_ADDRESS;
+	if (random->magic != RANDOM_MAGIC)
+		return NULL;
+
+	return random->serialno;
+exit:
+	io_close(img_handle);
+	return NULL;
+}
+
+/*
+ * Flush bios.bin into User Data Area in eMMC
+ */
+int flush_user_images(char *cmdbuf, unsigned long img_addr,
+		      unsigned long img_length)
+{
+	struct entry_head entries[5];
+	struct ptentry *ptn;
+	size_t length;
+	ssize_t offset;
+	int result = IO_FAIL;
+	int i, fp;
+
+	result = fetch_entry_head((void *)img_addr, USER_MAX_ENTRIES, entries);
+	switch (result) {
+	case IO_NOT_SUPPORTED:
+		if (!strncmp(cmdbuf, "fastboot", 8) ||
+		    !strncmp(cmdbuf, "bios", 4)) {
+			update_fip_spec();
+		}
+		if (is_sparse_image(img_addr)) {
+			result = do_unsparse(cmdbuf, img_addr, img_length);
+		} else {
+			ptn = find_ptn(cmdbuf);
+			if (!ptn) {
+				WARN("failed to find partition %s\n", cmdbuf);
+				return IO_FAIL;
+			}
+			img_length = (img_length + 512 - 1) / 512 * 512;
+			result = flush_single_image(NORMAL_EMMC_NAME, img_addr,
+						    ptn->start, img_length);
+		}
+		break;
+	case IO_SUCCESS:
+		if (strncmp(cmdbuf, "ptable", 6)) {
+			WARN("it's not for ptable\n");
+			return IO_FAIL;
+		}
+		/* currently it's for partition table */
+		/* the first block is for entry headers */
+		fp = 512;
+
+		for (i = 0; i < USER_MAX_ENTRIES; i++) {
+			if (entries[i].flag != 0) {
+				WARN("Invalid flag in entry:0x%x\n",
+					entries[i].flag);
+				return IO_NOT_SUPPORTED;
+			}
+			if (entries[i].count == 0)
+				continue;
+			length = entries[i].count * 512;
+			offset = MMC_BASE + entries[i].start * 512;
+			VERBOSE("i:%d, start:%x, count:%x\n",
+				i, entries[i].start, entries[i].count);
+			result = flush_single_image(NORMAL_EMMC_NAME,
+						img_addr + fp, offset, length);
+			fp += entries[i].count * 512;
+		}
+		get_partition();
+		break;
+	case IO_FAIL:
+		WARN("failed to parse entries in user image.\n");
+		return result;
+	}
+	return result;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/plat_pm.c b/uefi/arm-trusted-firmware/plat/hikey/plat_pm.c
new file mode 100644
index 0000000..7cc4b61
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/plat_pm.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <arch_helpers.h>
+#include <arm_gic.h>
+#include <debug.h>
+#include <cci400.h>
+#include <errno.h>
+#include <gic_v2.h>
+#include <gpio.h>
+#include <hi6220.h>
+#include <hisi_ipc.h>
+#include <hisi_pwrc.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <psci.h>
+#include <sp804_timer.h>
+
+#include "hikey_def.h"
+#include "hikey_private.h"
+
+#define PLAT_SOC_SUSPEND_STATE	0x4
+
+static int32_t hikey_do_plat_actions(uint32_t afflvl, uint32_t state)
+{
+	assert(afflvl <= MPIDR_AFFLVL1);
+
+	if (state != PSCI_STATE_OFF)
+		return -EAGAIN;
+
+	return 0;
+}
+
+int32_t hikey_affinst_on(uint64_t mpidr,
+			 uint64_t sec_entrypoint,
+			 uint32_t afflvl,
+			 uint32_t state)
+{
+	int cpu, cluster;
+
+	cluster = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFF1_SHIFT;
+	cpu = mpidr & MPIDR_CPU_MASK;
+
+	VERBOSE("#%s, mpidr:%llx, afflvl:%x, state:%x\n", __func__, mpidr, afflvl, state);
+
+	/* directly return for power on */
+	if (state == PSCI_STATE_ON)
+		return PSCI_E_SUCCESS;
+
+	switch (afflvl) {
+	case MPIDR_AFFLVL0:
+		hisi_pwrc_set_core_bx_addr(cpu, cluster, sec_entrypoint);
+		hisi_ipc_cpu_on(cpu, cluster);
+		break;
+
+	case MPIDR_AFFLVL1:
+		hisi_ipc_cluster_on(cpu, cluster);
+		break;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+
+static void hikey_affinst_off(uint32_t afflvl, uint32_t state)
+{
+	unsigned int mpidr = read_mpidr_el1();
+	int cpu, cluster;
+
+	cluster = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFF1_SHIFT;
+	cpu = mpidr & MPIDR_CPU_MASK;
+
+	if (hikey_do_plat_actions(afflvl, state) == -EAGAIN)
+		return;
+
+	switch (afflvl) {
+	case MPIDR_AFFLVL1:
+		hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+		cci_disable_cluster_coherency(mpidr);
+		hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+		hisi_ipc_cluster_off(cpu, cluster);
+		break;
+
+	case MPIDR_AFFLVL0:
+		arm_gic_cpuif_deactivate();
+		hisi_ipc_cpu_off(cpu, cluster);
+		break;
+	}
+
+	return;
+}
+
+static void hikey_affinst_suspend(uint64_t sec_entrypoint,
+				  uint32_t afflvl,
+				  uint32_t state)
+{
+	unsigned int mpidr = read_mpidr_el1();
+	int cpu, cluster;
+
+	cluster = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFF1_SHIFT;
+	cpu = mpidr & MPIDR_CPU_MASK;
+
+	if (hikey_do_plat_actions(afflvl, state) == -EAGAIN)
+		return;
+
+	switch (afflvl) {
+	case MPIDR_AFFLVL1:
+
+		hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+		cci_disable_cluster_coherency(mpidr);
+		hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+		if (psci_get_suspend_stateid() == PLAT_SOC_SUSPEND_STATE) {
+			hisi_pwrc_set_cluster_wfi(1);
+			hisi_pwrc_set_cluster_wfi(0);
+			hisi_ipc_psci_system_off();
+		} else
+			hisi_ipc_cluster_suspend(cpu, cluster);
+
+		break;
+
+	case MPIDR_AFFLVL0:
+
+		/* Program the jump address for the target cpu */
+		hisi_pwrc_set_core_bx_addr(cpu, cluster, sec_entrypoint);
+
+		arm_gic_cpuif_deactivate();
+
+		if (psci_get_suspend_stateid() != PLAT_SOC_SUSPEND_STATE)
+			hisi_ipc_cpu_suspend(cpu, cluster);
+		break;
+	}
+
+	return;
+}
+
+void hikey_affinst_on_finish(uint32_t afflvl, uint32_t state)
+{
+	unsigned long mpidr;
+	int cpu, cluster;
+
+	if (hikey_do_plat_actions(afflvl, state) == -EAGAIN)
+		return;
+
+	/* Get the mpidr for this cpu */
+	mpidr = read_mpidr_el1();
+	cluster = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFF1_SHIFT;
+	cpu = mpidr & MPIDR_CPU_MASK;
+
+	/* Perform the common cluster specific operations */
+	if (afflvl != MPIDR_AFFLVL0)
+		cci_enable_cluster_coherency(mpidr);
+
+	/* Zero the jump address in the mailbox for this cpu */
+	hisi_pwrc_set_core_bx_addr(cpu, cluster, 0);
+
+	if (psci_get_suspend_stateid() == PLAT_SOC_SUSPEND_STATE) {
+		arm_gic_setup();
+	} else {
+		/* Enable the gic cpu interface */
+		arm_gic_cpuif_setup();
+
+		/* TODO: This setup is needed only after a cold boot */
+		arm_gic_pcpu_distif_setup();
+	}
+
+	return;
+}
+
+static void hikey_affinst_suspend_finish(uint32_t afflvl,
+					 uint32_t state)
+{
+	hikey_affinst_on_finish(afflvl, state);
+	return;
+}
+
+static void __dead2 hikey_system_off(void)
+{
+	gpio_set_value(0, 0);
+	mdelay(1000);
+	/* Send the system reset request since it fails to power off */
+	mmio_write_32(AO_SC_SYS_STAT0, 0x48698284);
+	wfi();
+	panic();
+}
+
+static void __dead2 hikey_system_reset(void)
+{
+	VERBOSE("%s: reset system\n", __func__);
+
+	/* Send the system reset request */
+	mmio_write_32(AO_SC_SYS_STAT0, 0x48698284);
+
+	wfi();
+	panic();
+}
+
+unsigned int hikey_get_sys_suspend_power_state(void)
+{
+	unsigned int power_state;
+
+	power_state = psci_make_powerstate(PLAT_SOC_SUSPEND_STATE,
+			PSTATE_TYPE_POWERDOWN, MPIDR_AFFLVL1);
+
+	return power_state;
+}
+
+static const plat_pm_ops_t hikey_plat_pm_ops = {
+	.affinst_on		     = hikey_affinst_on,
+	.affinst_on_finish	     = hikey_affinst_on_finish,
+	.affinst_off		     = hikey_affinst_off,
+	.affinst_standby	     = NULL,
+	.affinst_suspend	     = hikey_affinst_suspend,
+	.affinst_suspend_finish	     = hikey_affinst_suspend_finish,
+	.system_off		     = hikey_system_off,
+	.system_reset		     = hikey_system_reset,
+	.get_sys_suspend_power_state = hikey_get_sys_suspend_power_state,
+};
+
+int platform_setup_pm(const plat_pm_ops_t **plat_ops)
+{
+	*plat_ops = &hikey_plat_pm_ops;
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/plat_security.c b/uefi/arm-trusted-firmware/plat/hikey/plat_security.c
new file mode 100644
index 0000000..b2cd602
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/plat_security.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2015, Hisilicon Ltd 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 <stdint.h>
+#include <strings.h>
+#include <platform_def.h>
+
+#define PORTNUM_MAX		5
+
+#define MDDRC_SECURITY_BASE	0xF7121000
+
+struct int_en_reg {
+	unsigned in_en:1;
+	unsigned reserved:31;
+};
+
+struct rgn_map_reg {
+	unsigned rgn_base_addr:24;
+	unsigned rgn_size:6;
+	unsigned reserved:1;
+	unsigned rgn_en:1;
+};
+
+struct rgn_attr_reg {
+	unsigned sp:4;
+	unsigned security_inv:1;
+	unsigned reserved_0:3;
+	unsigned mid_en:1;
+	unsigned mid_inv:1;
+	unsigned reserved_1:6;
+	unsigned rgn_en:1;
+	unsigned subrgn_disable:16;
+};
+
+static volatile struct int_en_reg *get_int_en_reg(uint32_t base)
+{
+	uint64_t addr = base + 0x20;
+	return (struct int_en_reg *)addr;
+}
+
+static volatile struct rgn_map_reg *get_rgn_map_reg(uint32_t base, int region, int port)
+{
+	uint64_t addr = base + 0x100 + 0x10 * region + 0x400 * port;
+	return (struct rgn_map_reg *)addr;
+}
+
+static volatile struct rgn_attr_reg *get_rgn_attr_reg(uint32_t base, int region,
+					     int port)
+{
+	uint64_t addr = base + 0x104 + 0x10 * region + 0x400 * port;
+	return (struct rgn_attr_reg *)addr;
+}
+
+static int is_power_of_two(uint32_t x)
+{
+	return ((x != 0) && !(x & (x - 1)));
+}
+
+/*
+ * Configure secure memory region
+ * region_size must be a power of 2 and at least 64KB
+ * region_base must be region_size aligned
+ */
+static void sec_protect(uint32_t region_base, uint32_t region_size)
+{
+	volatile struct int_en_reg *int_en_reg ;
+	volatile struct rgn_map_reg *rgn_map_reg;
+	volatile struct rgn_attr_reg *rgn_attr_reg;
+	uint32_t i = 0;
+
+	if (!is_power_of_two(region_size) || region_size < 0x10000) {
+		ERROR("Secure region size is not a power of 2 >= 64KB\n");
+		return;
+	}
+	if (region_base & (region_size - 1)) {
+		ERROR("Secure region address is not aligned to region size\n");
+		return;
+	}
+
+	INFO("BL2: TrustZone: protecting %u bytes of memory at 0x%x\n", region_size,
+	     region_base);
+
+	int_en_reg = get_int_en_reg(MDDRC_SECURITY_BASE);
+	int_en_reg->in_en = 0x1;
+
+	for (i = 0; i < PORTNUM_MAX; i++) {
+		rgn_map_reg = get_rgn_map_reg(MDDRC_SECURITY_BASE, 1, i);
+		rgn_attr_reg = get_rgn_attr_reg(MDDRC_SECURITY_BASE, 1, i);
+		rgn_map_reg->rgn_base_addr = region_base >> 16;
+		rgn_attr_reg->subrgn_disable = 0x0;
+		rgn_attr_reg->sp = (i == 3) ? 0xC : 0x0;
+		rgn_map_reg->rgn_size = __builtin_ffs(region_size) - 2;
+		rgn_map_reg->rgn_en = 0x1;
+	}
+}
+
+/*******************************************************************************
+ * Initialize the secure environment.
+ ******************************************************************************/
+void plat_security_setup(void)
+{
+	sec_protect(DRAM_SEC_BASE, DRAM_SEC_SIZE);
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/plat_topology.c b/uefi/arm-trusted-firmware/plat/hikey/plat_topology.c
new file mode 100644
index 0000000..1e9fa90
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/plat_topology.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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>
+#include <psci.h>
+
+unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr)
+{
+	/* Report 1 (absent) instance at levels higher that the cluster level */
+	if (aff_lvl > MPIDR_AFFLVL1)
+		return 1;
+
+	if (aff_lvl == MPIDR_AFFLVL1)
+		return 2; /* We have two clusters */
+
+	return 4; /* 4 cpus in cluster 1 or cluster 0 */
+}
+
+unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr)
+{
+	return aff_lvl <= MPIDR_AFFLVL1 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT;
+}
+
+int plat_get_max_afflvl()
+{
+	return MPIDR_AFFLVL1;
+}
+
+int plat_setup_topology()
+{
+	/* Juno todo: Make topology configurable via SCC */
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/platform.mk b/uefi/arm-trusted-firmware/plat/hikey/platform.mk
new file mode 100644
index 0000000..fd32307
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/platform.mk
@@ -0,0 +1,105 @@
+#
+# Copyright (c) 2014-2015, Linaro Ltd. All rights reserved.
+# Copyright (c) 2014-2015, Hisilicon Ltd.
+#
+# 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.
+#
+
+# On Hikey, the TSP can execute either from Trusted SRAM or Trusted DRAM.
+# Trusted DRAM is the default.
+#
+PLAT_TSP_LOCATION	:=	tdram
+ifeq (${PLAT_TSP_LOCATION}, tsram)
+  PLAT_TSP_LOCATION_ID := PLAT_TRUSTED_SRAM_ID
+else ifeq (${PLAT_TSP_LOCATION}, tdram)
+  PLAT_TSP_LOCATION_ID := PLAT_TRUSTED_DRAM_ID
+else
+  $(error "Unsupported PLAT_TSP_LOCATION value")
+endif
+
+CONSOLE_BASE		:=	PL011_UART3_BASE
+CRASH_CONSOLE_BASE	:=	PL011_UART3_BASE
+
+# Process flags
+$(eval $(call add_define,PLAT_TSP_LOCATION_ID))
+$(eval $(call add_define,CONSOLE_BASE))
+$(eval $(call add_define,CRASH_CONSOLE_BASE))
+
+
+PLAT_INCLUDES		:=	-Iplat/hikey/include/
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/arm/pl011/pl011_console.S	\
+				drivers/io/io_block.c			\
+				drivers/io/io_fip.c			\
+				drivers/io/io_memmap.c			\
+				drivers/io/io_storage.c			\
+				lib/aarch64/xlat_tables.c		\
+				plat/common/aarch64/plat_common.c	\
+				plat/common/plat_gic.c			\
+				plat/hikey/aarch64/hikey_common.c	\
+				plat/hikey/aarch64/plat_helpers.S	\
+				plat/hikey/plat_io_storage.c
+
+BL1_SOURCES		+=	drivers/arm/cci400/cci400.c		\
+				drivers/arm/gpio/gpio.c			\
+				lib/cpus/aarch64/cortex_a53.S		\
+				plat/common/aarch64/platform_up_stack.S	\
+				plat/hikey/aarch64/bl1_plat_helpers.S	\
+				plat/hikey/bl1_plat_setup.c		\
+				plat/hikey/drivers/dw_mmc.c		\
+				plat/hikey/drivers/hi6553.c		\
+				plat/hikey/drivers/sp804_timer.c	\
+				plat/hikey/partitions.c			\
+				plat/hikey/pll.c			\
+				plat/hikey/usb.c
+
+BL2_SOURCES		+=	plat/common/aarch64/platform_up_stack.S	\
+				plat/hikey/bl2_plat_setup.c		\
+				plat/hikey/plat_security.c		\
+				plat/hikey/drivers/dw_mmc.c		\
+				plat/hikey/drivers/hi6553.c		\
+				plat/hikey/drivers/hisi_dvfs.c		\
+				plat/hikey/drivers/hisi_mcu.c           \
+				plat/hikey/drivers/sp804_timer.c	\
+				plat/hikey/partitions.c
+
+BL31_SOURCES		+=	drivers/arm/cci400/cci400.c		\
+				drivers/arm/gic/arm_gic.c		\
+				drivers/arm/gic/gic_v2.c		\
+				drivers/arm/gic/gic_v3.c		\
+				drivers/arm/gpio/gpio.c			\
+				lib/cpus/aarch64/cortex_a53.S		\
+				plat/common/aarch64/platform_mp_stack.S	\
+				plat/hikey/bl31_plat_setup.c		\
+				plat/hikey/drivers/hisi_pwrc.c		\
+				plat/hikey/drivers/hisi_pwrc_sram.S	\
+				plat/hikey/drivers/hisi_ipc.c		\
+				plat/hikey/drivers/sp804_timer.c	\
+				plat/hikey/plat_pm.c			\
+				plat/hikey/plat_topology.c
+
+NEED_BL30		:=	yes
diff --git a/uefi/arm-trusted-firmware/plat/hikey/pll.c b/uefi/arm-trusted-firmware/plat/hikey/pll.c
new file mode 100644
index 0000000..0a5dd28
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/pll.c
@@ -0,0 +1,1166 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <console.h>
+#include <debug.h>
+#include <errno.h>
+#include <hi6220.h>
+#include <hi6553.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <sp804_timer.h>
+
+static void init_pll(void)
+{
+	unsigned int data;
+
+	data = mmio_read_32((0xf7032000 + 0x000));
+	data |= 0x1;
+	mmio_write_32((0xf7032000 + 0x000), data);
+	dsb();
+	do {
+		data = mmio_read_32((0xf7032000 + 0x000));
+	} while (!(data & (1 << 28)));
+
+	data = mmio_read_32((0xf7800000 + 0x000));
+	data &= ~0x007;
+	data |= 0x004;
+	mmio_write_32((0xf7800000 + 0x000), data);
+	dsb();
+	do {
+		data = mmio_read_32((0xf7800000 + 0x014));
+		data &= 0x007;
+	} while (data != 0x004);
+
+	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
+	data = mmio_read_32(PERI_SC_PERIPH_STAT1);
+	mmio_write_32(0xf7032000 + 0x02c, 0x5110103e);
+	data = mmio_read_32(0xf7032000 + 0x050);
+	data |= 1 << 28;
+	mmio_write_32(0xf7032000 + 0x050, data);
+	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
+	mdelay(1);
+	data = mmio_read_32(PERI_SC_PERIPH_STAT1);
+	NOTICE("syspll frequency:%dHz\n", data);
+}
+
+static void init_freq(void)
+{
+	unsigned int data, tmp;
+	unsigned int cpuext_cfg, ddr_cfg;
+
+	mmio_write_32((0xf7032000 + 0x374), 0x4a);
+	mmio_write_32((0xf7032000 + 0x368), 0xda);
+	mmio_write_32((0xf7032000 + 0x36c), 0x01);
+	mmio_write_32((0xf7032000 + 0x370), 0x01);
+	mmio_write_32((0xf7032000 + 0x360), 0x60);
+	mmio_write_32((0xf7032000 + 0x364), 0x60);
+
+	mmio_write_32((0xf7032000 + 0x114), 0x1000);
+
+	data = mmio_read_32((0xf7032000 + 0x110));
+	data |= (3 << 12);
+	mmio_write_32((0xf7032000 + 0x110), data);
+
+	data = mmio_read_32((0xf7032000 + 0x110));
+	data |= (1 << 4);
+	mmio_write_32((0xf7032000 + 0x110), data);
+
+
+	data = mmio_read_32((0xf7032000 + 0x110));
+	data &= ~0x7;
+	data |= 0x5;
+	mmio_write_32((0xf7032000 + 0x110), data);
+	dsb();
+	mdelay(10);
+
+
+	do {
+		data = mmio_read_32((0xf6504000 + 0x008));
+		data &= (3 << 20);
+	} while (data != (3 << 20));
+	dsb();
+	mdelay(10);
+
+
+	data = mmio_read_32((0xf6504000 + 0x054));
+	data &= ~((1 << 0) | (1 << 11));
+	mmio_write_32((0xf6504000 + 0x054), data);
+	mdelay(10);
+
+	data = mmio_read_32((0xf7032000 + 0x104));
+	data &= ~(3 << 8);
+	data |= (1 << 8);
+	mmio_write_32((0xf7032000 + 0x104), data);
+
+	data = mmio_read_32((0xf7032000 + 0x100));
+	data |= (1 << 0);
+	mmio_write_32((0xf7032000 + 0x100), data);
+	dsb();
+
+	do {
+		data = mmio_read_32((0xf7032000 + 0x100));
+		data &= (1 << 2);
+	} while (data != (1 << 2));
+
+	data = mmio_read_32((0xf6504000 + 0x06c));
+	data &= ~0xffff;
+	data |= 0x56;
+	mmio_write_32((0xf6504000 + 0x06c), data);
+
+	data = mmio_read_32((0xf6504000 + 0x06c));
+	data &= ~(0xffffff << 8);
+	data |= 0xc7a << 8;
+	mmio_write_32((0xf6504000 + 0x06c), data);
+
+	data = mmio_read_32((0xf6504000 + 0x058));
+	data &= ((1 << 13) - 1);
+	data |= 0xccb;
+	mmio_write_32((0xf6504000 + 0x058), data);
+
+	mmio_write_32((0xf6504000 + 0x060), 0x1fff);
+	mmio_write_32((0xf6504000 + 0x064), 0x1ffffff);
+	mmio_write_32((0xf6504000 + 0x068), 0x7fffffff);
+	mmio_write_32((0xf6504000 + 0x05c), 0x1);
+
+	data = mmio_read_32((0xf6504000 + 0x054));
+	data &= ~(0xf << 12);
+	data |= 1 << 12;
+	mmio_write_32((0xf6504000 + 0x054), data);
+	dsb();
+
+
+	data = mmio_read_32((0xf7032000 + 0x000));
+	data &= ~(1 << 0);
+	mmio_write_32((0xf7032000 + 0x000), data);
+
+	mmio_write_32((0xf7032000 + 0x004), 0x5110207d);
+	mmio_write_32((0xf7032000 + 0x134), 0x10000005);
+	data = mmio_read_32((0xf7032000 + 0x134));
+
+
+	data = mmio_read_32((0xf7032000 + 0x000));
+	data |= (1 << 0);
+	mmio_write_32((0xf7032000 + 0x000), data);
+
+	mmio_write_32((0xf7032000 + 0x368), 0x100da);
+	data = mmio_read_32((0xf7032000 + 0x378));
+	data &= ~((1 << 7) - 1);
+	data |= 0x6b;
+	mmio_write_32((0xf7032000 + 0x378), data);
+	dsb();
+	do {
+		data = mmio_read_32((0xf7032000 + 0x378));
+		tmp = data & 0x7f;
+		data = (data & (0x7f << 8)) >> 8;
+		if (data != tmp)
+			continue;
+		data = mmio_read_32((0xf7032000 + 0x37c));
+	} while (!(data & 1));
+
+	data = mmio_read_32((0xf7032000 + 0x104));
+	data &= ~((3 << 0) |
+			(3 << 8));
+	cpuext_cfg = 1;
+	ddr_cfg = 1;
+	data |= cpuext_cfg | (ddr_cfg << 8);
+	mmio_write_32((0xf7032000 + 0x104), data);
+	dsb();
+
+	do {
+		data = mmio_read_32((0xf7032000 + 0x104));
+		tmp = (data & (3 << 16)) >> 16;
+		if (cpuext_cfg != tmp)
+			continue;
+		tmp = (data & (3 << 24)) >> 24;
+		if (ddr_cfg != tmp)
+			continue;
+		data = mmio_read_32((0xf7032000 + 0x000));
+		data &= 1 << 28;
+	} while (!data);
+
+	data = mmio_read_32((0xf7032000 + 0x100));
+	data &= ~(1 << 0);
+	mmio_write_32((0xf7032000 + 0x100), data);
+	dsb();
+	do {
+		data = mmio_read_32((0xf7032000 + 0x100));
+		data &= (1 << 1);
+	} while (data != (1 << 1));
+	mdelay(1000);
+
+	data = mmio_read_32((0xf6504000 + 0x054));
+	data &= ~(1 << 28);
+	mmio_write_32((0xf6504000 + 0x054), data);
+	dsb();
+
+	data = mmio_read_32((0xf7032000 + 0x110));
+	data &= ~((1 << 4) |
+			(3 << 12));
+	mmio_write_32((0xf7032000 + 0x110), data);
+}
+
+int cat_533mhz_800mhz(void)
+{
+	unsigned int data, i;
+	unsigned int bdl[5];
+
+
+	data = mmio_read_32((0xf712c000 + 0x1c8));
+	data &= 0xfffff0f0;
+	data |= 0x100f0f;
+	mmio_write_32((0xf712c000 + 0x1c8), data);
+
+	for (i = 0; i < 0x20; i++) {
+		mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+		data = (i << 0x10) + i;
+		mmio_write_32((0xf712c000 + 0x140), data);
+		mmio_write_32((0xf712c000 + 0x144), data);
+		mmio_write_32((0xf712c000 + 0x148), data);
+		mmio_write_32((0xf712c000 + 0x14c), data);
+		mmio_write_32((0xf712c000 + 0x150), data);
+
+
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data |= 0x80000;
+		mmio_write_32((0xf712c000 + 0x070), data);
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data &= 0xfff7ffff;
+		mmio_write_32((0xf712c000 + 0x070), data);
+
+
+		mmio_write_32((0xf712c000 + 0x004), 0x8000);
+		mmio_write_32((0xf712c000 + 0x004), 0x0);
+		mmio_write_32((0xf712c000 + 0x004), 0x801);
+		do {
+			data = mmio_read_32((0xf712c000 + 0x004));
+		} while (data & 1);
+
+		data = mmio_read_32((0xf712c000 + 0x008));
+		if (!(data & 0x400)) {
+			mdelay(10);
+			return 0;
+		}
+		tf_printf("WARN:  " "lpddr3 cat fail\n");
+		data = mmio_read_32((0xf712c000 + 0x1d4));
+		if ((data & 0x1f00) && ((data & 0x1f) == 0)) {
+			bdl[0] = mmio_read_32((0xf712c000 + 0x140));
+			bdl[1] = mmio_read_32((0xf712c000 + 0x144));
+			bdl[2] = mmio_read_32((0xf712c000 + 0x148));
+			bdl[3] = mmio_read_32((0xf712c000 + 0x14c));
+			bdl[4] = mmio_read_32((0xf712c000 + 0x150));
+			if ((!(bdl[0] & 0x1f001f)) || (!(bdl[1] & 0x1f001f)) ||
+					(!(bdl[2] & 0x1f001f)) || (!(bdl[3] & 0x1f001f)) ||
+					(!(bdl[4] & 0x1f001f))) {
+				tf_printf("WARN:  " "lpddr3 cat deskew error\n");
+				if (i == 0x1f) {
+					tf_printf("WARN:  " "addrnbdl is max\n");
+					return -22;
+				}
+				mmio_write_32((0xf712c000 + 0x008), 0x400);
+			} else {
+				tf_printf("WARN:  " "lpddr3 cat other error1\n");
+				return -22;
+			}
+		} else {
+			tf_printf("WARN:  " "lpddr3 cat other error2\n");
+			return -22;
+		}
+	}
+	return -22;
+}
+
+static void ddrx_rdet(void)
+{
+	unsigned int data, rdet, bdl[4];
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= 0xf800ffff;
+	data |= 0x8f0000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+
+	data = mmio_read_32((0xf712c000 + 0x0dc));
+	data &= 0xfffffff0;
+	data |= 0xf;
+	mmio_write_32((0xf712c000 + 0x0dc), data);
+
+
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data |= 0x80000;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= 0xfff7ffff;
+	mmio_write_32((0xf712c000 + 0x070), data);
+
+	mmio_write_32((0xf712c000 + 0x004), 0x8000);
+	mmio_write_32((0xf712c000 + 0x004), 0);
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf0000000;
+	data |= 0x80000000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+
+	mmio_write_32((0xf712c000 + 0x004), 0x101);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (!(data & 1));
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x100)
+		tf_printf("WARN:    " "rdet lbs fail\n");
+
+	bdl[0] = mmio_read_32((0xf712c000 + 0x22c)) & 0x7f;
+	bdl[1] = mmio_read_32((0xf712c000 + 0x2ac)) & 0x7f;
+	bdl[2] = mmio_read_32((0xf712c000 + 0x32c)) & 0x7f;
+	bdl[3] = mmio_read_32((0xf712c000 + 0x3ac)) & 0x7f;
+	do {
+		data = mmio_read_32((0xf712c000 + 0x22c));
+		data &= ~0x7f;
+		data |= bdl[0];
+		mmio_write_32((0xf712c000 + 0x22c), data);
+		data = mmio_read_32((0xf712c000 + 0x2ac));
+		data &= ~0x7f;
+		data |= bdl[1];
+		mmio_write_32((0xf712c000 + 0x2ac), data);
+		data = mmio_read_32((0xf712c000 + 0x32c));
+		data &= ~0x7f;
+		data |= bdl[2];
+		mmio_write_32((0xf712c000 + 0x32c), data);
+		data = mmio_read_32((0xf712c000 + 0x3ac));
+		data &= ~0x7f;
+		data |= bdl[3];
+		mmio_write_32((0xf712c000 + 0x3ac), data);
+
+
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data |= 0x80000;
+		mmio_write_32((0xf712c000 + 0x070), data);
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data &= 0xfff7ffff;
+		mmio_write_32((0xf712c000 + 0x070), data);
+
+		mmio_write_32((0xf712c000 + 0x004), 0x8000);
+		mmio_write_32((0xf712c000 + 0x004), 0);
+
+		data = mmio_read_32((0xf712c000 + 0x0d0));
+		data &= ~0xf0000000;
+		data |= 0x40000000;
+		mmio_write_32((0xf712c000 + 0x0d0), data);
+		mmio_write_32((0xf712c000 + 0x004), 0x101);
+		do {
+			data = mmio_read_32((0xf712c000 + 0x004));
+		} while (data & 1);
+
+		data = mmio_read_32((0xf712c000 + 0x008));
+		rdet = data & 0x100;
+		if (rdet) {
+			tf_printf("INFO:    " "rdet ds fail\n");
+			mmio_write_32((0xf712c000 + 0x008), 0x100);
+		}
+		bdl[0]++;
+		bdl[1]++;
+		bdl[2]++;
+		bdl[3]++;
+	} while (rdet);
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf0000000;
+	data |= 0x30000000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+
+	mmio_write_32((0xf712c000 + 0x004), 0x101);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x100)
+		tf_printf("INFO:    " "rdet rbs av fail\n");
+}
+
+static void ddrx_wdet(void)
+{
+	unsigned int data, wdet, zero_bdl, dq[4];
+	int i;
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf;
+	data |= 0xf;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data |= 0x80000;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= ~0x80000;
+	mmio_write_32((0xf712c000 + 0x070), data);
+
+	mmio_write_32((0xf712c000 + 0x004), 0x8000);
+	mmio_write_32((0xf712c000 + 0x004), 0);
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf000;
+	data |= 0x8000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x201);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x200)
+		tf_printf("INFO:    " "wdet lbs fail\n");
+
+	dq[0] = mmio_read_32((0xf712c000 + 0x234)) & 0x1f00;
+	dq[1] = mmio_read_32((0xf712c000 + 0x2b4)) & 0x1f00;
+	dq[2] = mmio_read_32((0xf712c000 + 0x334)) & 0x1f00;
+	dq[3] = mmio_read_32((0xf712c000 + 0x3b4)) & 0x1f00;
+
+	do {
+		mmio_write_32((0xf712c000 + 0x234), dq[0]);
+		mmio_write_32((0xf712c000 + 0x2b4), dq[1]);
+		mmio_write_32((0xf712c000 + 0x334), dq[2]);
+		mmio_write_32((0xf712c000 + 0x3b4), dq[3]);
+
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data |= 0x80000;
+		mmio_write_32((0xf712c000 + 0x070), data);
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data &= ~0x80000;
+		mmio_write_32((0xf712c000 + 0x070), data);
+		mmio_write_32((0xf712c000 + 0x004), 0x8000);
+		mmio_write_32((0xf712c000 + 0x004), 0);
+
+		data = mmio_read_32((0xf712c000 + 0x0d0));
+		data &= ~0xf000;
+		data |= 0x4000;
+		mmio_write_32((0xf712c000 + 0x0d0), data);
+		mmio_write_32((0xf712c000 + 0x004), 0x201);
+		do {
+			data = mmio_read_32((0xf712c000 + 0x004));
+		} while (data & 1);
+
+		data = mmio_read_32((0xf712c000 + 0x008));
+		wdet = data & 0x200;
+		if (wdet) {
+			tf_printf("INFO:    " "wdet ds fail\n");
+			mmio_write_32((0xf712c000 + 0x008), 0x200);
+		}
+		mdelay(10);
+
+		for (i = 0; i < 4; i++) {
+			data = mmio_read_32((0xf712c000 + 0x210 + i * 0x80));
+			if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
+					(!(data & 0x1f0000)) || (!(data & 0x1f000000)))
+				zero_bdl = 1;
+			data = mmio_read_32((0xf712c000 + 0x214 + i * 0x80));
+			if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
+					(!(data & 0x1f0000)) || (!(data & 0x1f000000)))
+				zero_bdl = 1;
+			data = mmio_read_32((0xf712c000 + 0x218 + i * 0x80));
+			if (!(data & 0x1f))
+				zero_bdl = 1;
+			if (zero_bdl) {
+				if (i == 0)
+					dq[0] = dq[0] - 0x100;
+				if (i == 1)
+					dq[1] = dq[1] - 0x100;
+				if (i == 2)
+					dq[2] = dq[2] - 0x100;
+				if (i == 3)
+					dq[3] = dq[3] - 0x100;
+			}
+		}
+	} while (wdet);
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf000;
+	data |= 0x3000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x201);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x200)
+		tf_printf("INFO:    " "wdet rbs av fail\n");
+}
+
+static void set_ddrc_533mhz(void)
+{
+	unsigned int data;
+
+	mmio_write_32((0xf7032000 + 0x580), 0x3);
+	mmio_write_32((0xf7032000 + 0x5a8), 0x11111);
+	data = mmio_read_32((0xf7032000 + 0x104));
+	data |= 0x100;
+	mmio_write_32((0xf7032000 + 0x104), data);
+
+	mmio_write_32((0xf7030000 + 0x050), 0x30);
+	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+	mmio_write_32((0xf712c000 + 0x00c), 0x400);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x090), 0x6400000);
+	mmio_write_32((0xf712c000 + 0x258), 0x640);
+	mmio_write_32((0xf712c000 + 0x2d8), 0x640);
+	mmio_write_32((0xf712c000 + 0x358), 0x640);
+	mmio_write_32((0xf712c000 + 0x3d8), 0x640);
+	mmio_write_32((0xf712c000 + 0x018), 0x0);
+	mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
+	mmio_write_32((0xf712c000 + 0x0b4), 0xf);
+	mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
+	mmio_write_32((0xf712c000 + 0x070), 0x8940000);
+
+	data = mmio_read_32((0xf712c000 + 0x078));
+	data |= 4;
+	mmio_write_32((0xf712c000 + 0x078), data);
+	mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= 0xfffffffe;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+	mmio_write_32((0xf712c000 + 0x010), 0x500000f);
+	mmio_write_32((0xf712c000 + 0x014), 0x10);
+	data = mmio_read_32((0xf712c000 + 0x1e4));
+	data &= 0xffffff00;
+	mmio_write_32((0xf712c000 + 0x1e4), data);
+	mmio_write_32((0xf712c000 + 0x030), 0x9dd87855);
+	mmio_write_32((0xf712c000 + 0x034), 0xa7138bb);
+	mmio_write_32((0xf712c000 + 0x038), 0x20091477);
+	mmio_write_32((0xf712c000 + 0x03c), 0x84534e16);
+	mmio_write_32((0xf712c000 + 0x040), 0x3008817);
+	mmio_write_32((0xf712c000 + 0x064), 0x106c3);
+	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= 0xffff0000;
+	data |= 0x305;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 0x40000000;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= ~0x10;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	data = mmio_read_32((0xf712c000 + 0x080));
+	data &= ~0x2000;
+	mmio_write_32((0xf712c000 + 0x080), data);
+	mmio_write_32((0xf712c000 + 0x270), 0x3);
+	mmio_write_32((0xf712c000 + 0x2f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x370), 0x3);
+	mmio_write_32((0xf712c000 + 0x3f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x048), 0xd0420900);
+
+	mmio_write_32((0xf7128000 + 0x040), 0x0);
+	mmio_write_32((0xf712c000 + 0x004), 0x140f);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe) {
+		tf_printf("NOTICE:  " "failed to init lpddr3 rank0 dram phy\n");
+		return;
+	}
+	tf_printf("NOTICE:  " "succeed to init lpddr3 rank0 dram phy\n");
+}
+
+static void set_ddrc_800mhz(void)
+{
+	unsigned int data;
+
+	mmio_write_32((0xf7032000 + 0x580), 0x2);
+	mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
+	data = mmio_read_32((0xf7032000 + 0x104));
+	data &= 0xfffffcff;
+	mmio_write_32((0xf7032000 + 0x104), data);
+
+	mmio_write_32((0xf7030000 + 0x050), 0x30);
+	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+	mmio_write_32((0xf712c000 + 0x00c), 0x400);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x090), 0x5400000);
+	mmio_write_32((0xf712c000 + 0x258), 0x540);
+	mmio_write_32((0xf712c000 + 0x2d8), 0x540);
+	mmio_write_32((0xf712c000 + 0x358), 0x540);
+	mmio_write_32((0xf712c000 + 0x3d8), 0x540);
+	mmio_write_32((0xf712c000 + 0x018), 0x0);
+	mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
+	mmio_write_32((0xf712c000 + 0x0b4), 0xf);
+	mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
+	mmio_write_32((0xf712c000 + 0x070), 0x8940000);
+
+	data = mmio_read_32((0xf712c000 + 0x078));
+	data |= 4;
+	mmio_write_32((0xf712c000 + 0x078), data);
+	mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= 0xfffffffe;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+	mmio_write_32((0xf712c000 + 0x010), 0x500000f);
+	mmio_write_32((0xf712c000 + 0x014), 0x10);
+	data = mmio_read_32((0xf712c000 + 0x1e4));
+	data &= 0xffffff00;
+	mmio_write_32((0xf712c000 + 0x1e4), data);
+	mmio_write_32((0xf712c000 + 0x030), 0xe663ab77);
+	mmio_write_32((0xf712c000 + 0x034), 0xea952db);
+	mmio_write_32((0xf712c000 + 0x038), 0x200d1cb1);
+	mmio_write_32((0xf712c000 + 0x03c), 0xc67d0721);
+	mmio_write_32((0xf712c000 + 0x040), 0x3008aa1);
+	mmio_write_32((0xf712c000 + 0x064), 0x11a43);
+	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= 0xffff0000;
+	data |= 0x507;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 0x40000000;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= 0xffffffef;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	data = mmio_read_32((0xf712c000 + 0x080));
+	data &= 0xffffdfff;
+	mmio_write_32((0xf712c000 + 0x080), data);
+	mmio_write_32((0xf712c000 + 0x270), 0x3);
+	mmio_write_32((0xf712c000 + 0x2f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x370), 0x3);
+	mmio_write_32((0xf712c000 + 0x3f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x048), 0xd0420900);
+
+	mmio_write_32((0xf7128000 + 0x040), 0x2001);
+	mmio_write_32((0xf712c000 + 0x004), 0x140f);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe) {
+		WARN("failed to init lpddr3 rank0 dram phy\n");
+		return;
+	}
+}
+
+static void ddrc_common_init(int ddr800)
+{
+	unsigned int data;
+
+	mmio_write_32((0xf7120000 + 0x020), 0x1);
+	mmio_write_32((0xf7120000 + 0x100), 0x1700);
+	mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+	mmio_write_32((0xf7121400 + 0x104), 0xf);
+	mmio_write_32((0xf7121800 + 0x104), 0xf);
+	mmio_write_32((0xf7121800 + 0x104), 0xf);
+	mmio_write_32((0xf7121c00 + 0x104), 0xf);
+	mmio_write_32((0xf7122000 + 0x104), 0xf);
+	mmio_write_32((0xf7128000 + 0x02c), 0x6);
+	mmio_write_32((0xf7128000 + 0x020), 0x1);
+	mmio_write_32((0xf7128000 + 0x028), 0x310201);
+	mmio_write_32((0xf712c000 + 0x1e4), 0xfe007600);
+	mmio_write_32((0xf7128000 + 0x01c), 0xaf001);
+
+
+	data = mmio_read_32((0xf7128000 + 0x280));
+	data |= 1 << 7;
+	mmio_write_32((0xf7128000 + 0x280), data);
+	mmio_write_32((0xf7128000 + 0x244), 0x3);
+
+	if (ddr800)
+		mmio_write_32((0xf7128000 + 0x240), 167 * 400000 / 1024);
+	else
+		mmio_write_32((0xf7128000 + 0x240), 167 * 533000 / 1024);
+
+	data = mmio_read_32((0xf712c000 + 0x080));
+	data &= 0xffff;
+	data |= 0x4002000;
+	mmio_write_32((0xf712c000 + 0x080), data);
+	mmio_write_32((0xf7128000 + 0x000), 0x0);
+	do {
+		data = mmio_read_32((0xf7128000 + 0x294));
+	} while (data & 1);
+	mmio_write_32((0xf7128000 + 0x000), 0x2);
+}
+
+
+static int dienum_det_and_rowcol_cfg(void)
+{
+	unsigned int data;
+
+	mmio_write_32((0xf7128000 + 0x210), 0x87);
+	mmio_write_32((0xf7128000 + 0x218), 0x10000);
+	mmio_write_32((0xf7128000 + 0x00c), 0x1);
+	do {
+		data = mmio_read_32((0xf7128000 + 0x00c));
+	} while (data & 1);
+	data = mmio_read_32((0xf7128000 + 0x4a8)) & 0xfc;
+	switch (data) {
+		case 0x18:
+			mmio_write_32((0xf7128000 + 0x060), 0x132);
+			mmio_write_32((0xf7128000 + 0x064), 0x132);
+			mmio_write_32((0xf7120000 + 0x100), 0x1600);
+			mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+			break;
+		case 0x1c:
+			mmio_write_32((0xf7128000 + 0x060), 0x142);
+			mmio_write_32((0xf7128000 + 0x064), 0x142);
+			mmio_write_32((0xf7120000 + 0x100), 0x1700);
+			mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+			break;
+		case 0x58:
+			mmio_write_32((0xf7128000 + 0x060), 0x133);
+			mmio_write_32((0xf7128000 + 0x064), 0x133);
+			mmio_write_32((0xf7120000 + 0x100), 0x1700);
+			mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+			break;
+		default:
+			break;
+	}
+	if (!data)
+		return -22;
+	return 0;
+}
+
+static int detect_ddr_chip_info(void)
+{
+	unsigned int data, mr5, mr6, mr7;
+
+	mmio_write_32((0xf7128000 + 0x210), 0x57);
+	mmio_write_32((0xf7128000 + 0x218), 0x10000);
+	mmio_write_32((0xf7128000 + 0x00c), 0x1);
+
+	do {
+		data = mmio_read_32((0xf7128000 + 0x00c));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf7128000 + 0x4a8));
+	mr5 = data & 0xff;
+	switch (mr5) {
+		case 1:
+			tf_printf("INFO:    " "Samsung DDR\n");
+			break;
+		case 6:
+			tf_printf("INFO:    " "Hynix DDR\n");
+			break;
+		case 3:
+			tf_printf("INFO:    " "Elpida DDR\n");
+			break;
+		default:
+			tf_printf("INFO:    " "DDR from other vendors\n");
+			break;
+	}
+
+	mmio_write_32((0xf7128000 + 0x210), 0x67);
+	mmio_write_32((0xf7128000 + 0x218), 0x10000);
+	mmio_write_32((0xf7128000 + 0x00c), 0x1);
+	do {
+		data = mmio_read_32((0xf7128000 + 0x00c));
+	} while (data & 1);
+	data = mmio_read_32((0xf7128000 + 0x4a8));
+	mr6 = data & 0xff;
+	mmio_write_32((0xf7128000 + 0x210), 0x77);
+	mmio_write_32((0xf7128000 + 0x218), 0x10000);
+	mmio_write_32((0xf7128000 + 0x00c), 0x1);
+	do {
+		data = mmio_read_32((0xf7128000 + 0x00c));
+	} while (data & 1);
+	data = mmio_read_32((0xf7128000 + 0x4a8));
+	mr7 = data & 0xff;
+	data = mr5 + (mr6 << 8) + (mr7 << 16);
+	return data;
+}
+
+int lpddr3_freq_init(int ddr800)
+{
+	unsigned int data;
+
+	if (ddr800) {
+		set_ddrc_800mhz();
+		tf_printf("INFO:    " "%s, set ddrc 800mhz\n", __func__);
+	} else {
+		set_ddrc_533mhz();
+		tf_printf("INFO:    " "%s, set ddrc 533mhz\n", __func__);
+	}
+
+	data = cat_533mhz_800mhz();
+	if (data)
+		tf_printf("NOTICE:  " "fail to set eye diagram\n");
+
+	mmio_write_32((0xf712c000 + 0x004), 0xf1);
+	if (ddr800)
+		mmio_write_32((0xf7128000 + 0x050), 0x100023);
+	else
+		mmio_write_32((0xf7128000 + 0x050), 0x100123);
+	mmio_write_32((0xf7128000 + 0x060), 0x133);
+	mmio_write_32((0xf7128000 + 0x064), 0x133);
+	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+	if (ddr800) {
+		mmio_write_32((0xf7128000 + 0x100), 0x755a9d12);
+		mmio_write_32((0xf7128000 + 0x104), 0x1753b055);
+		mmio_write_32((0xf7128000 + 0x108), 0x7401505f);
+		mmio_write_32((0xf7128000 + 0x10c), 0x578ca244);
+		mmio_write_32((0xf7128000 + 0x110), 0x10700000);
+		mmio_write_32((0xf7128000 + 0x114), 0x13141306);
+	} else {
+		mmio_write_32((0xf7128000 + 0x100), 0xb77b6718);
+		mmio_write_32((0xf7128000 + 0x104), 0x1e82a071);
+		mmio_write_32((0xf7128000 + 0x108), 0x9501c07e);
+		mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255);
+		mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+		mmio_write_32((0xf7128000 + 0x114), 0x13181908);
+	}
+	mmio_write_32((0xf7128000 + 0x118), 0x44);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe) {
+		tf_printf("NOTICE:  " "fail to init ddr3 rank0\n");
+		return -14;
+	}
+	tf_printf("INFO:    " "init ddr3 rank0\n");
+	ddrx_rdet();
+	ddrx_wdet();
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 1;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x21);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe)
+		tf_printf("NOTICE:  " "ddr3 rank1 init failure\n");
+	else
+		tf_printf("INFO:    " "ddr3 rank1 init pass\n");
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= ~0xf;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	return 0;
+}
+
+static void init_ddr(int ddr800)
+{
+	unsigned int data;
+	int ret;
+
+
+	data = mmio_read_32((0xf7032000 + 0x030));
+	data |= 1;
+	mmio_write_32((0xf7032000 + 0x030), data);
+	data = mmio_read_32((0xf7032000 + 0x010));
+	data |= 1;
+	mmio_write_32((0xf7032000 + 0x010), data);
+	
+	udelay(100);
+	do {
+		data = mmio_read_32((0xf7032000 + 0x030));
+		data &= 3 << 28;
+	} while (data != (3 << 28));
+	do {
+		data = mmio_read_32((0xf7032000 + 0x010));
+		data &= 3 << 28;
+	} while (data != (3 << 28));
+
+	ret = lpddr3_freq_init(ddr800);
+	if (ret)
+		return;
+}
+
+static void init_ddrc_qos(void)
+{
+	unsigned int port, data;
+
+	mmio_write_32((0xf7124000 + 0x088), 1);
+
+
+	port = 0;
+	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
+	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x11111111);
+	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x11111111);
+	mmio_write_32((0xf7120000 + 0x400 + 0 * 0x10), 0x001d0007);
+
+
+	for (port = 3; port <= 4; port++) {
+		mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
+		mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x77777777);
+		mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x77777777);
+	}
+
+
+	port = 1;
+	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
+	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
+	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
+
+
+	mmio_write_32((0xf7124000 + 0x1f0), 0);
+	mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
+	mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
+	mmio_write_32((0xf7124000 + 0x1f4), 0x01000100);
+	mmio_write_32((0xf7124000 + 0x08c + 0 * 4), 0xd0670402);
+	mmio_write_32((0xf7124000 + 0x068 + 0 * 4), 0x31);
+	mmio_write_32((0xf7124000 + 0x000), 0x7);
+
+	data = mmio_read_32((0xf7124000 + 0x09c));
+	data &= ~0xff0000;
+	data |= 0x400000;
+	mmio_write_32((0xf7124000 + 0x09c), data);
+	data = mmio_read_32((0xf7124000 + 0x0ac));
+	data &= ~0xff0000;
+	data |= 0x400000;
+	mmio_write_32((0xf7124000 + 0x0ac), data);
+	port = 2;
+	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
+	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
+	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
+
+
+	mmio_write_32((0xf7124000 + 0x09c), 0xff7fff);
+	mmio_write_32((0xf7124000 + 0x0a0), 0xff);
+	mmio_write_32((0xf7124000 + 0x0ac), 0xff7fff);
+	mmio_write_32((0xf7124000 + 0x0b0), 0xff);
+	mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
+	mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
+}
+
+static void init_mmc0_pll(void)
+{
+	unsigned int data;
+
+	data = hi6553_read_8(0x084);
+	data |= 0x7;
+	hi6553_write_8(0x084, data);
+
+	/* select SYSPLL as the source of MMC0 */
+	/* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */
+	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 5 | 1 << 21);
+	do {
+		data = mmio_read_32(PERI_SC_CLK_SEL0);
+	} while (!(data & (1 << 5)));
+	/* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */
+	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 29);
+	do {
+		data = mmio_read_32(PERI_SC_CLK_SEL0);
+	} while (data & (1 << 13));
+
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 0));
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (!(data & (1 << 0)));
+
+	data = mmio_read_32(PERI_SC_PERIPH_CLKEN12);
+	data |= 1 << 1;
+	mmio_write_32(PERI_SC_PERIPH_CLKEN12, data);
+
+	do {
+		mmio_write_32(PERI_SC_CLKCFG8BIT1, (1 << 7) | 0xb);
+		data = mmio_read_32(PERI_SC_CLKCFG8BIT1);
+	} while ((data & 0xb) != 0xb);
+}
+
+static void reset_mmc0_clk(void)
+{
+	unsigned int data;
+
+	/* disable mmc0 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (data & PERI_CLK0_MMC0);
+	/* enable mmc0 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (!(data & PERI_CLK0_MMC0));
+	/* reset mmc0 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0);
+
+	/* bypass mmc0 clock phase */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
+	data |= 3;
+	mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
+
+	/* disable low power */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
+	data |= 1 << 3;
+	mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (!(data & PERI_RST0_MMC0));
+
+	/* unreset mmc0 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (data & PERI_RST0_MMC0);
+}
+
+static void init_media_clk(void)
+{
+	unsigned int data, value;
+
+	data = mmio_read_32(PMCTRL_MEDPLLCTRL);
+	data |= 1;
+	mmio_write_32(PMCTRL_MEDPLLCTRL, data);
+
+	for (;;) {
+		data = mmio_read_32(PMCTRL_MEDPLLCTRL);
+		value = 1 << 28;
+		if ((data & value) == value)
+			break;
+	}
+
+	data = mmio_read_32(PERI_SC_PERIPH_CLKEN12);
+	data = 1 << 10;
+	mmio_write_32(PERI_SC_PERIPH_CLKEN12, data);
+}
+
+static void init_mmc1_pll(void)
+{
+	uint32_t data;
+
+	/* select SYSPLL as the source of MMC1 */
+	/* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */
+	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 11 | 1 << 27);
+	do {
+		data = mmio_read_32(PERI_SC_CLK_SEL0);
+	} while (!(data & (1 << 11)));
+	/* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */
+	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 30);
+	do {
+		data = mmio_read_32(PERI_SC_CLK_SEL0);
+	} while (data & (1 << 14));
+
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 1));
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (!(data & (1 << 1)));
+
+	data = mmio_read_32(PERI_SC_PERIPH_CLKEN12);
+	data |= 1 << 2;
+	mmio_write_32(PERI_SC_PERIPH_CLKEN12, data);
+
+	do {
+		/* 1.2GHz / 50 = 24MHz */
+		mmio_write_32(PERI_SC_CLKCFG8BIT2, 0x31 | (1 << 7));
+		data = mmio_read_32(PERI_SC_CLKCFG8BIT2);
+	} while ((data & 0x31) != 0x31);
+}
+
+static void reset_mmc1_clk(void)
+{
+	unsigned int data;
+
+	/* disable mmc1 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC1);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (data & PERI_CLK0_MMC1);
+	/* enable mmc1 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC1);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (!(data & PERI_CLK0_MMC1));
+	/* reset mmc1 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC1);
+
+	/* bypass mmc1 clock phase */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
+	data |= 3 << 2;
+	mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
+
+	/* disable low power */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
+	data |= 1 << 4;
+	mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (!(data & PERI_RST0_MMC1));
+
+	/* unreset mmc0 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC1);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (data & PERI_RST0_MMC1);
+}
+
+static void ddr_phy_reset(void)
+{
+	mmio_write_32(0xf7030340, 0xa000);
+	mmio_write_32(0xf7030344, 0xa000);
+}
+
+void hi6220_pll_init(void)
+{
+	uint32_t data;
+
+	init_pll();
+	init_freq();
+
+	/*
+	 * Init DDR with 533MHz. Otherwise, DDR initialization
+	 * may fail on 800MHz on some boards.
+	 */
+	ddr_phy_reset();
+	init_ddr(0);
+	/* Init DDR with 800MHz. */
+	ddr_phy_reset();
+	init_ddr(1);
+
+
+	ddrc_common_init(1);
+	dienum_det_and_rowcol_cfg();
+	detect_ddr_chip_info();
+
+	data = mmio_read_32(0xf7032000 + 0x010);
+	data &= ~0x1;
+	mmio_write_32(0xf7032000 + 0x010, data);
+	data = mmio_read_32(0xf7032000 + 0x010);
+
+	/*
+	 * Test memory access. Do not use address 0x0 because the compiler
+	 * may assume it is not a valid address and generate incorrect code
+	 * (GCC 4.9.1 without -fno-delete-null-pointer-checks for instance).
+	 */
+	mmio_write_32(0x4, 0xa5a55a5a);
+	INFO("ddr test value:0x%x\n", mmio_read_32(0x4));
+	init_ddrc_qos();
+
+	init_mmc0_pll();
+	reset_mmc0_clk();
+	init_media_clk();
+
+	dsb();
+
+	init_mmc1_pll();
+	reset_mmc1_clk();
+}
diff --git a/uefi/arm-trusted-firmware/plat/hikey/usb.c b/uefi/arm-trusted-firmware/plat/hikey/usb.c
new file mode 100644
index 0000000..538912f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/hikey/usb.c
@@ -0,0 +1,1466 @@
+/*
+ * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, Hisilicon Ltd 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 <ctype.h>
+#include <debug.h>
+#include <gpio.h>
+#include <hi6220.h>
+#include <mmio.h>
+#include <partitions.h>
+#include <platform_def.h>
+#include <sp804_timer.h>
+#include <string.h>
+#include <usb.h>
+#include "hikey_private.h"
+
+#define NUM_ENDPOINTS			16
+
+#define USB_BLOCK_HIGH_SPEED_SIZE	512
+
+struct ep_type {
+	unsigned char		active;
+	unsigned char		busy;
+	unsigned char		done;
+	unsigned int		rc;
+	unsigned int		size;
+};
+
+struct usb_endpoint {
+	struct usb_endpoint	*next;
+	unsigned int		maxpkt;
+	struct usb_request	*req;
+	unsigned char		num;
+	unsigned char		in;
+};
+
+struct usb_config_bundle {
+	struct usb_config_descriptor config;
+	struct usb_interface_descriptor interface;
+	struct usb_endpoint_descriptor ep1;
+	struct usb_endpoint_descriptor ep2;
+} __attribute__ ((packed));
+
+static setup_packet ctrl_req[NUM_ENDPOINTS]
+__attribute__ ((section("tzfw_coherent_mem")));
+static unsigned char ctrl_resp[2]
+__attribute__ ((section("tzfw_coherent_mem")));
+
+static struct ep_type endpoints[NUM_ENDPOINTS]
+__attribute__ ((section("tzfw_coherent_mem")));
+
+dwc_otg_dev_dma_desc_t dma_desc
+__attribute__ ((section("tzfw_coherent_mem")));
+dwc_otg_dev_dma_desc_t dma_desc_ep0
+__attribute__ ((section("tzfw_coherent_mem")));
+dwc_otg_dev_dma_desc_t dma_desc_in
+__attribute__ ((section("tzfw_coherent_mem")));
+dwc_otg_dev_dma_desc_t dma_desc_addr
+__attribute__ ((section("tzfw_coherent_mem")));
+
+static struct usb_config_bundle config_bundle
+__attribute__ ((section("tzfw_coherent_mem")));
+static struct usb_device_descriptor device_descriptor
+__attribute__ ((section("tzfw_coherent_mem")));
+
+static struct usb_request rx_req
+__attribute__ ((section("tzfw_coherent_mem")));
+static struct usb_request tx_req
+__attribute__ ((section("tzfw_coherent_mem")));
+
+static struct usb_string_descriptor serial_string
+__attribute__ ((section("tzfw_coherent_mem")));
+
+static const struct usb_string_descriptor string_devicename = {
+	24,
+	USB_DT_STRING,
+	{'A', 'n', 'd', 'r', 'o', 'i', 'd', ' ', '2', '.', '0'}
+};
+
+static const struct usb_string_descriptor serial_string_descriptor = {
+	34,
+	USB_DT_STRING,
+	{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}
+};
+
+static const struct usb_string_descriptor lang_descriptor = {
+	4,
+	USB_DT_STRING,
+	{0x0409}	/* en-US */
+};
+
+static void usb_rx_cmd_complete(unsigned actual, int stat);
+static void usb_rx_data_complete(unsigned actual, int status);
+
+static unsigned int rx_desc_bytes = 0;
+static unsigned long rx_addr;
+static unsigned long rx_length;
+static unsigned int last_one = 0;
+static char *cmdbuf;
+static struct usb_endpoint ep1in, ep1out;
+static int g_usb_enum_flag = 0;
+
+int usb_need_reset = 0;
+
+static int usb_drv_port_speed(void)
+{
+	/* 2'b00 High speed (PHY clock is at 30MHz or 60MHz) */
+	return (mmio_read_32(DSTS) & 2) == 0 ? 1 : 0;
+}
+
+static void reset_endpoints(void)
+{
+	int i;
+	unsigned int data;
+
+	INFO("enter reset_endpoints.\n");
+	for (i = 0; i < NUM_ENDPOINTS; i++) {
+		endpoints[i].active = 0;
+		endpoints[i].busy = 0;
+		endpoints[i].rc = -1;
+		endpoints[i].done = 1;
+	}
+
+	/* EP0 IN ACTIVE NEXT=1 */
+	mmio_write_32(DIEPCTL0, 0x8800);
+
+	/* EP0 OUT ACTIVE */
+	mmio_write_32(DOEPCTL0, 0x8000);
+
+	/* Clear any pending OTG Interrupts */
+	mmio_write_32(GOTGINT, ~0);
+
+	/* Clear any pending interrupts */
+	mmio_write_32(GINTSTS, ~0);
+	mmio_write_32(DIEPINT0, ~0);
+	mmio_write_32(DOEPINT0, ~0);
+	mmio_write_32(DIEPINT1, ~0);
+	mmio_write_32(DOEPINT1, ~0);
+
+	/* IN EP interrupt mask */
+	mmio_write_32(DIEPMSK, 0x0D);
+	/* OUT EP interrupt mask */
+	mmio_write_32(DOEPMSK, 0x0D);
+	/* Enable interrupts on Ep0 */
+	mmio_write_32(DAINTMSK, 0x00010001);
+
+	/* EP0 OUT Transfer Size:64 Bytes, 1 Packet, 3 Setup Packet, Read to receive setup packet*/
+	data = DOEPTSIZ0_SUPCNT(3) | DOEPTSIZ0_PKTCNT |
+		(64 << DOEPTSIZ0_XFERSIZE_SHIFT);
+	mmio_write_32(DOEPTSIZ0, data);
+	//notes that:the compulsive conversion is expectable.
+	dma_desc_ep0.status.b.bs = 0x3;
+	dma_desc_ep0.status.b.mtrf = 0;
+	dma_desc_ep0.status.b.sr = 0;
+	dma_desc_ep0.status.b.l = 1;
+	dma_desc_ep0.status.b.ioc = 1;
+	dma_desc_ep0.status.b.sp = 0;
+	dma_desc_ep0.status.b.bytes = 64;
+	dma_desc_ep0.buf = (unsigned long)&ctrl_req;
+	dma_desc_ep0.status.b.sts = 0;
+	dma_desc_ep0.status.b.bs = 0x0;
+	mmio_write_32(DOEPDMA0, ((unsigned long)&(dma_desc_ep0)));
+	VERBOSE("%s, &ctrl_req:%llx:%x, &dms_desc_ep0:%llx:%x\n",
+		__func__, (unsigned long)&ctrl_req, (unsigned long)&ctrl_req,
+		(unsigned long)&dma_desc_ep0, (unsigned long)&dma_desc_ep0);
+	/* EP0 OUT ENABLE CLEARNAK */
+	data = mmio_read_32(DOEPCTL0);
+	mmio_write_32(DOEPCTL0, (data | 0x84000000));
+
+	VERBOSE("exit reset_endpoints. \n");
+}
+
+static int usb_drv_request_endpoint(int type, int dir)
+{
+	int ep = 1;    /*FIXME*/
+	unsigned int newbits, data;
+
+	newbits = (type << 18) | 0x10000000;
+
+	/*
+	 * (type << 18):Endpoint Type (EPType)
+	 * 0x10000000:Endpoint Enable (EPEna)
+	 * 0x000C000:Endpoint Type (EPType);Hardcoded to 00 for control.
+	 * (ep<<22):TxFIFO Number (TxFNum)
+	 * 0x20000:NAK Status (NAKSts);The core is transmitting NAK handshakes on this endpoint.
+	 */
+	if (dir) {  // IN: to host
+		data = mmio_read_32(DIEPCTL(ep));
+		data &= ~0x000c0000;
+		data |= newbits | (ep << 22) | 0x20000;
+		mmio_write_32(DIEPCTL(ep), data);
+	} else {    // OUT: to device
+		data = mmio_read_32(DOEPCTL(ep));
+		data &= ~0x000c0000;
+		data |= newbits;
+		mmio_write_32(DOEPCTL(ep), data);
+	}
+	endpoints[ep].active = 1;	// true
+
+    return ep | dir;
+}
+
+void usb_drv_release_endpoint(int ep)
+{
+	ep = ep % NUM_ENDPOINTS;
+	if (ep < 1 || ep > NUM_ENDPOINTS)
+		return;
+
+	endpoints[ep].active = 0;
+}
+
+void usb_config(void)
+{
+	unsigned int data;
+
+	INFO("enter usb_config\n");
+
+	mmio_write_32(GDFIFOCFG, DATA_FIFO_CONFIG);
+	mmio_write_32(GRXFSIZ, RX_SIZE);
+	mmio_write_32(GNPTXFSIZ, ENDPOINT_TX_SIZE);
+
+	mmio_write_32(DIEPTXF1, DATA_IN_ENDPOINT_TX_FIFO1);
+	mmio_write_32(DIEPTXF2, DATA_IN_ENDPOINT_TX_FIFO2);
+	mmio_write_32(DIEPTXF3, DATA_IN_ENDPOINT_TX_FIFO3);
+	mmio_write_32(DIEPTXF4, DATA_IN_ENDPOINT_TX_FIFO4);
+	mmio_write_32(DIEPTXF5, DATA_IN_ENDPOINT_TX_FIFO5);
+	mmio_write_32(DIEPTXF6, DATA_IN_ENDPOINT_TX_FIFO6);
+	mmio_write_32(DIEPTXF7, DATA_IN_ENDPOINT_TX_FIFO7);
+	mmio_write_32(DIEPTXF8, DATA_IN_ENDPOINT_TX_FIFO8);
+	mmio_write_32(DIEPTXF9, DATA_IN_ENDPOINT_TX_FIFO9);
+	mmio_write_32(DIEPTXF10, DATA_IN_ENDPOINT_TX_FIFO10);
+	mmio_write_32(DIEPTXF11, DATA_IN_ENDPOINT_TX_FIFO11);
+	mmio_write_32(DIEPTXF12, DATA_IN_ENDPOINT_TX_FIFO12);
+	mmio_write_32(DIEPTXF13, DATA_IN_ENDPOINT_TX_FIFO13);
+	mmio_write_32(DIEPTXF14, DATA_IN_ENDPOINT_TX_FIFO14);
+	mmio_write_32(DIEPTXF15, DATA_IN_ENDPOINT_TX_FIFO15);
+
+	/*Init global csr register.*/
+
+	/*
+	 * set Periodic TxFIFO Empty Level,
+	 * Non-Periodic TxFIFO Empty Level,
+	 * Enable DMA, Unmask Global Intr
+	 */
+	INFO("USB: DMA mode.\n");
+	mmio_write_32(GAHBCFG, GAHBCFG_CTRL_MASK);
+
+	/*select 8bit UTMI+, ULPI Inerface*/
+	INFO("USB ULPI PHY\n");
+	mmio_write_32(GUSBCFG, 0x2400);
+
+	/* Detect usb work mode,host or device? */
+	do {
+		data = mmio_read_32(GINTSTS);
+	} while (data & GINTSTS_CURMODE_HOST);
+	VERBOSE("Enter device mode\n");
+	udelay(3);
+
+	/*Init global and device mode csr register.*/
+	/*set Non-Zero-Length status out handshake */
+	data = (0x20 << DCFG_EPMISCNT_SHIFT) | DCFG_NZ_STS_OUT_HSHK;
+	mmio_write_32(DCFG, data);
+
+	/* Interrupt unmask: IN event, OUT event, bus reset */
+	data = GINTSTS_OEPINT | GINTSTS_IEPINT | GINTSTS_ENUMDONE |
+	       GINTSTS_USBRST | GINTSTS_USBSUSP | GINTSTS_ERLYSUSP |
+	       GINTSTS_GOUTNAKEFF;
+	mmio_write_32(GINTMSK, data);
+
+	do {
+		data = mmio_read_32(GINTSTS) & GINTSTS_ENUMDONE;
+	} while (data);
+	VERBOSE("USB Enum Done.\n");
+
+	/* Clear any pending OTG Interrupts */
+	mmio_write_32(GOTGINT, ~0);
+	/* Clear any pending interrupts */
+	mmio_write_32(GINTSTS, ~0);
+	mmio_write_32(GINTMSK, ~0);
+	data = mmio_read_32(GOTGINT);
+	data &= ~0x3000;
+	mmio_write_32(GOTGINT, data);
+	/*endpoint settings cfg*/
+	reset_endpoints();
+
+	udelay(1);
+
+	/*init finish. and ready to transfer data*/
+
+	/* Soft Disconnect */
+	mmio_write_32(DCTL, 0x802);
+	udelay(10000);
+
+	/* Soft Reconnect */
+	mmio_write_32(DCTL, 0x800);
+	VERBOSE("exit usb_config.\n");
+}
+
+void usb_drv_set_address(int address)
+{
+	unsigned int cfg;
+
+	cfg = mmio_read_32(DCFG);
+	cfg &= ~0x7F0;
+	cfg |= address << 4;
+	mmio_write_32(DCFG, cfg);	// 0x7F0: device address
+}
+
+static void ep_send(int ep, const void *ptr, int len)
+{
+	unsigned int data;
+
+	endpoints[ep].busy = 1;		// true
+	endpoints[ep].size = len;
+
+	/* EPx OUT ACTIVE */
+	data = mmio_read_32(DIEPCTL(ep)) | DXEPCTL_USBACTEP;
+	mmio_write_32(DIEPCTL(ep), data);
+
+	/* set DMA Address */
+	if (!len) {
+		/* send one empty packet */
+		dma_desc_in.buf = 0;
+	} else {
+		dma_desc_in.buf = (unsigned long)ptr;
+	}
+	dma_desc_in.status.b.bs = 0x3;
+	dma_desc_in.status.b.l = 1;
+	dma_desc_in.status.b.ioc = 1;
+	dma_desc_in.status.b.sp = 1;
+	dma_desc_in.status.b.sts = 0;
+	dma_desc_in.status.b.bs = 0x0;
+	dma_desc_in.status.b.bytes = len;
+	mmio_write_32(DIEPDMA(ep), (unsigned long)&dma_desc_in);
+
+	data = mmio_read_32(DIEPCTL(ep));
+	data |= DXEPCTL_EPENA | DXEPCTL_CNAK | DXEPCTL_NEXTEP(ep + 1);
+	mmio_write_32(DIEPCTL(ep), data);
+}
+
+void usb_drv_stall(int endpoint, char stall, char in)
+{
+	unsigned int data;
+
+	/*
+	 * STALL Handshake (Stall)
+	 */
+
+	data = mmio_read_32(DIEPCTL(endpoint));
+	if (in) {
+		if (stall)
+			mmio_write_32(DIEPCTL(endpoint), data | 0x00200000);
+		else
+			mmio_write_32(DIEPCTL(endpoint), data & ~0x00200000);
+	} else {
+		if (stall)
+			mmio_write_32(DOEPCTL(endpoint), data | 0x00200000);
+		else
+			mmio_write_32(DOEPCTL(endpoint), data & ~0x00200000);
+	}
+}
+
+int usb_drv_send_nonblocking(int endpoint, const void *ptr, int len)
+{
+	VERBOSE("%s, endpoint = %d, ptr = 0x%x, Len=%d.\n",
+		__func__, endpoint, ptr, len);
+	ep_send(endpoint % NUM_ENDPOINTS, ptr, len);
+	return 0;
+}
+
+void usb_drv_cancel_all_transfers(void)
+{
+	reset_endpoints();
+}
+
+int hiusb_epx_tx(unsigned ep, void *buf, unsigned len)
+{
+	int blocksize,packets;
+	unsigned int epints;
+	unsigned int cycle = 0;
+	unsigned int data;
+
+	endpoints[ep].busy = 1;		//true
+	endpoints[ep].size = len;
+
+	while (mmio_read_32(GINTSTS) & 0x40) {
+		data = mmio_read_32(DCTL);
+		data |= 0x100;
+		mmio_write_32(DCTL, data);
+	}
+
+	data = mmio_read_32(DIEPCTL(ep));
+	data |= 0x08000000;
+	mmio_write_32(DIEPCTL(ep), data);
+
+	/* EPx OUT ACTIVE */
+	mmio_write_32(DIEPCTL(ep), data | 0x8000);
+	if (!ep) {
+		blocksize = 64;
+	} else {
+		blocksize = usb_drv_port_speed() ? USB_BLOCK_HIGH_SPEED_SIZE : 64;
+	}
+	packets = (len + blocksize - 1) / blocksize;
+
+	if (!len) {
+		/* one empty packet */
+		mmio_write_32(DIEPTSIZ(ep), 1 << 19);
+		/* NULL */
+		dma_desc_in.status.b.bs = 0x3;
+		dma_desc_in.status.b.l = 1;
+		dma_desc_in.status.b.ioc = 1;
+		dma_desc_in.status.b.sp = last_one;
+		dma_desc_in.status.b.bytes = 0;
+		dma_desc_in.buf = 0;
+		dma_desc_in.status.b.sts = 0;
+		dma_desc_in.status.b.bs = 0x0;
+		mmio_write_32(DIEPDMA(ep), (unsigned long)&dma_desc_in);
+	} else {
+		mmio_write_32(DIEPTSIZ(ep), len | (packets << 19));
+		dma_desc_in.status.b.bs = 0x3;
+		dma_desc_in.status.b.l = 1;
+		dma_desc_in.status.b.ioc = 1;
+		dma_desc_in.status.b.sp = last_one;
+		dma_desc_in.status.b.bytes = len;
+		dma_desc_in.buf = (unsigned long)buf;
+		dma_desc_in.status.b.sts = 0;
+		dma_desc_in.status.b.bs = 0x0;
+		mmio_write_32(DIEPDMA(ep), (unsigned long)&dma_desc_in);
+	}
+
+	cycle = 0;
+	while(1){
+		data = mmio_read_32(DIEPINT(ep));
+		if ((data & 0x2000) || (cycle > 10000)) {
+			if (cycle > 10000) {
+				NOTICE("Phase 2:ep(%d) status, DIEPCTL(%d) is [0x%x],"
+				       "DTXFSTS(%d) is [0x%x], DIEPINT(%d) is [0x%x],"
+				       "DIEPTSIZ(%d) is [0x%x] GINTSTS is [0x%x]\n",
+					ep, ep, data,
+					ep, mmio_read_32(DTXFSTS(ep)),
+					ep, mmio_read_32(DIEPINT(ep)),
+					ep, mmio_read_32(DIEPTSIZ(ep)),
+					mmio_read_32(GINTSTS));
+			}
+			break;
+		}
+
+		cycle++;
+		udelay(10);
+	}
+	VERBOSE("ep(%d) enable, DIEPCTL(%d) is [0x%x], DTXFSTS(%d) is [0x%x],"
+		"DIEPINT(%d) is [0x%x], DIEPTSIZ(%d) is [0x%x] \n",
+		ep, ep, mmio_read_32(DIEPCTL(ep)),
+		ep, mmio_read_32(DTXFSTS(ep)),
+		ep, mmio_read_32(DIEPINT(ep)),
+		ep, mmio_read_32(DIEPTSIZ(ep)));
+
+	__asm__ volatile("dsb	sy\n"
+			 "isb	sy\n");
+	data = mmio_read_32(DIEPCTL(ep));
+	data |= 0x84000000;
+	/* epena & cnak*/
+	mmio_write_32(DIEPCTL(ep), data);
+	__asm__ volatile("dsb	sy\n"
+			 "isb	sy\n");
+
+	cycle = 0;
+	while (1) {
+		epints = mmio_read_32(DIEPINT(ep)) & 1;
+		if ((mmio_read_32(GINTSTS) & 0x40000) && epints) {
+			VERBOSE("Tx succ:ep(%d), DTXFSTS(%d) is [0x%x] \n",
+				ep, ep, mmio_read_32(DTXFSTS(ep)));
+			mmio_write_32(DIEPINT(ep), epints);
+			if (endpoints[ep].busy) {
+				endpoints[ep].busy = 0;//false
+				endpoints[ep].rc = 0;
+				endpoints[ep].done = 1;//true
+			}
+			break;
+		}
+		cycle++;
+		udelay(10);
+		VERBOSE("loop for intr: ep(%d), DIEPCTL(%d) is [0x%x], ",
+			"DTXFSTS(%d) is [0x%x], DIEPINT(%d) is [0x%x] \n",
+			ep, ep, mmio_read_32(DIEPCTL(ep)),
+			ep, mmio_read_32(DTXFSTS(ep)),
+			ep, mmio_read_32(DIEPINT(ep)));
+
+		if (cycle > 1000000) {
+			WARN("Wait IOC intr over 10s! USB will reset\n");
+			usb_need_reset = 1;
+			return 1;
+		}
+	}
+
+	cycle = 0;
+	while (1) {
+		if ((mmio_read_32(DIEPINT(ep)) & 0x2000) || (cycle > 100000)) {
+			if (cycle > 100000){
+				WARN("all wait cycle is [%d]\n",cycle);
+			}
+			break;
+		}
+
+		cycle++;
+		udelay(10);
+	}
+
+	return 0;
+}
+
+int hiusb_epx_rx(unsigned ep, void *buf, unsigned len)
+{
+	unsigned int blocksize = 0, data;
+	int packets;
+
+	VERBOSE("ep%d rx, len = 0x%x, buf = 0x%x.\n", ep, len, buf);
+
+	endpoints[ep].busy = 1;//true
+	/* EPx UNSTALL */
+	data = mmio_read_32(DOEPCTL(ep)) & ~0x00200000;
+	mmio_write_32(DOEPCTL(ep), data);
+	/* EPx OUT ACTIVE */
+	data = mmio_read_32(DOEPCTL(ep)) | 0x8000;
+	mmio_write_32(DOEPCTL(ep), data);
+
+	blocksize = usb_drv_port_speed() ? USB_BLOCK_HIGH_SPEED_SIZE : 64;
+	packets = (len + blocksize - 1) / blocksize;
+
+#define MAX_RX_PACKET 0x3FF
+
+	/*Max recv packets is 1023*/
+	if (packets > MAX_RX_PACKET) {
+		endpoints[ep].size = MAX_RX_PACKET * blocksize;
+		len = MAX_RX_PACKET * blocksize;
+	} else {
+		endpoints[ep].size = len;
+	}
+
+	if (!len) {
+		/* one empty packet */
+		mmio_write_32(DOEPTSIZ(ep), 1 << 19);
+		//NULL  /* dummy address */
+		dma_desc.status.b.bs = 0x3;
+		dma_desc.status.b.mtrf = 0;
+		dma_desc.status.b.sr = 0;
+		dma_desc.status.b.l = 1;
+		dma_desc.status.b.ioc = 1;
+		dma_desc.status.b.sp = 0;
+		dma_desc.status.b.bytes = 0;
+		dma_desc.buf = 0;
+		dma_desc.status.b.sts = 0;
+		dma_desc.status.b.bs = 0x0;
+
+		mmio_write_32(DOEPDMA(ep), (unsigned long)&dma_desc);
+	} else {
+		if (len >= blocksize * 64) {
+			rx_desc_bytes = blocksize*64;
+		} else {
+			rx_desc_bytes = len;
+		}
+		VERBOSE("rx len %d, rx_desc_bytes %d \n",len,rx_desc_bytes);
+		dma_desc.status.b.bs = 0x3;
+		dma_desc.status.b.mtrf = 0;
+		dma_desc.status.b.sr = 0;
+		dma_desc.status.b.l = 1;
+		dma_desc.status.b.ioc = 1;
+		dma_desc.status.b.sp = 0;
+		dma_desc.status.b.bytes = rx_desc_bytes;
+		dma_desc.buf = (unsigned long)buf;
+		dma_desc.status.b.sts = 0;
+		dma_desc.status.b.bs = 0x0;
+
+		mmio_write_32(DOEPDMA(ep), (unsigned long)&dma_desc);
+	}
+	/* EPx OUT ENABLE CLEARNAK */
+	data = mmio_read_32(DOEPCTL(ep));
+	data |= 0x84000000;
+	mmio_write_32(DOEPCTL(ep), data);
+	return 0;
+}
+
+int usb_queue_req(struct usb_endpoint *ept, struct usb_request *req)
+{
+	if (ept->in)
+		hiusb_epx_tx(ept->num, req->buf, req->length);
+	else
+		hiusb_epx_rx(ept->num, req->buf, req->length);
+
+	return 0;
+}
+
+static void rx_cmd(void)
+{
+	struct usb_request *req = &rx_req;
+	req->buf = cmdbuf;
+	req->length = RX_REQ_LEN;
+	req->complete = usb_rx_cmd_complete;
+	usb_queue_req(&ep1out, req);
+}
+
+static void rx_data(void)
+{
+	struct usb_request *req = &rx_req;
+
+	req->buf = (void *)((unsigned long) rx_addr);
+	req->length = rx_length;
+	req->complete = usb_rx_data_complete;
+	usb_queue_req(&ep1out, req);
+}
+
+void tx_status(const char *status)
+{
+	struct usb_request *req = &tx_req;
+	int len = strlen(status);
+
+	memcpy(req->buf, status, (unsigned int)len);
+	req->length = (unsigned int)len;
+	req->complete = 0;
+	usb_queue_req(&ep1in, req);
+}
+
+void fastboot_tx_status(const char *status)
+{
+	tx_status(status);
+	rx_cmd();
+}
+
+void tx_dump_page(const char *ptr, int len)
+{
+	struct usb_request *req = &tx_req;
+
+	memcpy(req->buf, ptr, (unsigned int)len);
+	req->length = (unsigned int)len;
+	req->complete = 0;
+	usb_queue_req(&ep1in, req);
+}
+
+
+static void usb_rx_data_complete(unsigned actual, int status)
+{
+
+	if(status != 0)
+		return;
+
+	if(actual > rx_length) {
+		actual = rx_length;
+	}
+
+	rx_addr += actual;
+	rx_length -= actual;
+
+	if(rx_length > 0) {
+		rx_data();
+	} else {
+		tx_status("OKAY");
+		rx_cmd();
+	}
+}
+
+static void usb_status(unsigned online, unsigned highspeed)
+{
+	if (online) {
+		INFO("usb: online (%s)\n", highspeed ? "highspeed" : "fullspeed");
+		rx_cmd();
+	}
+}
+
+void usb_handle_control_request(setup_packet* req)
+{
+	const void* addr = NULL;
+	int size = -1;
+	int i;
+	int maxpacket;
+	unsigned int data;
+	char *serialno;
+	struct usb_endpoint_descriptor epx;
+	struct usb_config_bundle const_bundle = {
+		.config = {
+			.bLength	= sizeof(struct usb_config_descriptor),
+			.bDescriptorType	= USB_DT_CONFIG,
+			.wTotalLength	= sizeof(struct usb_config_descriptor) +
+				sizeof(struct usb_interface_descriptor) +
+				sizeof(struct usb_endpoint_descriptor) *
+				USB_NUM_ENDPOINTS,
+			.bNumInterfaces		= 1,
+			.bConfigurationValue	= 1,
+			.iConfiguration		= 0,
+			.bmAttributes		= USB_CONFIG_ATT_ONE,
+			.bMaxPower		= 0x80
+		},
+		.interface = {
+			.bLength	= sizeof(struct usb_interface_descriptor),
+			.bDescriptorType	= USB_DT_INTERFACE,
+			.bInterfaceNumber	= 0,
+			.bAlternateSetting	= 0,
+			.bNumEndpoints		= USB_NUM_ENDPOINTS,
+			.bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
+			.bInterfaceSubClass	= 0x42,
+			.bInterfaceProtocol	= 0x03,
+			.iInterface		= 0
+		}
+	};
+
+	/* avoid to hang on accessing unaligned memory */
+	struct usb_endpoint_descriptor const_ep1 = {
+		.bLength	= sizeof(struct usb_endpoint_descriptor),
+		.bDescriptorType	= USB_DT_ENDPOINT,
+		.bEndpointAddress	= 0x81,
+		.bmAttributes		= USB_ENDPOINT_XFER_BULK,
+		.wMaxPacketSize		= 0,
+		.bInterval		= 0
+	};
+
+	struct usb_endpoint_descriptor const_ep2 = {
+		.bLength	= sizeof(struct usb_endpoint_descriptor),
+		.bDescriptorType	= USB_DT_ENDPOINT,
+		.bEndpointAddress	= 0x01,
+		.bmAttributes		= USB_ENDPOINT_XFER_BULK,
+		.wMaxPacketSize		= 0,
+		.bInterval		= 1
+	};
+
+	struct usb_device_descriptor const_device = {
+		.bLength		= sizeof(struct usb_device_descriptor),
+		.bDescriptorType	= USB_DT_DEVICE,
+		.bcdUSB			= 0x0200,
+		.bDeviceClass		= 0,
+		.bDeviceClass		= 0,
+		.bDeviceProtocol	= 0,
+		.bMaxPacketSize0	= 0x40,
+		.idVendor		= 0x18d1,
+		.idProduct		= 0xd00d,
+		.bcdDevice		= 0x0100,
+		.iManufacturer		= 1,
+		.iProduct		= 2,
+		.iSerialNumber		= 3,
+		.bNumConfigurations	= 1
+	};
+
+	memcpy(&config_bundle, &const_bundle, sizeof(struct usb_config_bundle));
+	memcpy(&config_bundle.ep1, &const_ep1, sizeof(struct usb_endpoint_descriptor));
+	memcpy(&config_bundle.ep2, &const_ep2, sizeof(struct usb_endpoint_descriptor));
+	memcpy(&device_descriptor, &const_device,
+		sizeof(struct usb_device_descriptor));
+
+	switch (req->request) {
+	case USB_REQ_GET_STATUS:
+		if (req->type == USB_DIR_IN)
+			ctrl_resp[0] = 1;
+		else
+			ctrl_resp[0] = 0;
+		ctrl_resp[1] = 0;
+		addr = ctrl_resp;
+		size = 2;
+		break;
+
+	case USB_REQ_CLEAR_FEATURE:
+		if ((req->type == USB_RECIP_ENDPOINT) &&
+		    (req->value == USB_ENDPOINT_HALT))
+			usb_drv_stall(req->index & 0xf, 0, req->index >> 7);
+		size = 0;
+		break;
+
+	case USB_REQ_SET_FEATURE:
+		size = 0;
+		break;
+
+	case USB_REQ_SET_ADDRESS:
+		size = 0;
+		usb_drv_cancel_all_transfers();     // all endpoints reset
+		usb_drv_set_address(req->value);   // set device address
+		break;
+
+	case USB_REQ_GET_DESCRIPTOR:
+		VERBOSE("USB_REQ_GET_DESCRIPTOR: 0x%x\n", req->value >> 8);
+		switch (req->value >> 8) {
+		case USB_DT_DEVICE:
+			addr = &device_descriptor;
+			size = sizeof(device_descriptor);
+			VERBOSE("Get device descriptor.\n");
+			break;
+
+		case USB_DT_OTHER_SPEED_CONFIG:
+		case USB_DT_CONFIG:
+			if ((req->value >> 8) == USB_DT_CONFIG) {
+				maxpacket = usb_drv_port_speed() ? USB_BLOCK_HIGH_SPEED_SIZE : 64;
+				config_bundle.config.bDescriptorType = USB_DT_CONFIG;
+			} else {
+				maxpacket = usb_drv_port_speed() ? 64 : USB_BLOCK_HIGH_SPEED_SIZE;
+				config_bundle.config.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG;
+			}
+			/* avoid hang when access unaligned structure */
+			memcpy(&epx, &config_bundle.ep1, sizeof(struct usb_endpoint_descriptor));
+			epx.wMaxPacketSize = maxpacket;
+			memcpy(&config_bundle.ep1, &epx, sizeof(struct usb_endpoint_descriptor));
+			memcpy(&epx, &config_bundle.ep2, sizeof(struct usb_endpoint_descriptor));
+			epx.wMaxPacketSize = maxpacket;
+			memcpy(&config_bundle.ep2, &epx, sizeof(struct usb_endpoint_descriptor));
+			addr = &config_bundle;
+			size = sizeof(config_bundle);
+			VERBOSE("Get config descriptor.\n");
+			break;
+
+		case USB_DT_STRING:
+			switch (req->value & 0xff) {
+			case 0:
+				addr = &lang_descriptor;
+				size = lang_descriptor.bLength;
+				break;
+			case 1:
+				addr = &string_devicename;
+				size = 14;
+				break;
+			case 2:
+				addr = &string_devicename;
+				size = string_devicename.bLength;
+				break;
+			case 3:
+				serialno = load_serialno();
+				if (serialno == NULL) {
+					addr = &serial_string_descriptor;
+					size = serial_string_descriptor.bLength;
+				} else {
+					i = 0;
+					memcpy((void *)&serial_string,
+					       (void *)&serial_string_descriptor,
+					       sizeof(serial_string));
+					while (1) {
+						serial_string.wString[i] = serialno[i];
+						if (serialno[i] == '\0')
+							break;
+						i++;
+					}
+					addr = &serial_string;
+					size = serial_string.bLength;
+				}
+				break;
+			default:
+				break;
+			}
+			break;
+
+		default:
+			break;
+		}
+		break;
+
+	case USB_REQ_GET_CONFIGURATION:
+		ctrl_resp[0] = 1;
+		addr = ctrl_resp;
+		size = 1;
+		break;
+
+	case USB_REQ_SET_CONFIGURATION:
+		usb_drv_cancel_all_transfers();     // call reset_endpoints  reset all EPs
+
+		usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT);
+		usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN);
+		/*
+		 * 0x10088800:
+		 * 1:EP enable; 8:EP type:BULK; 8:USB Active Endpoint; 8:Next Endpoint
+		 */
+		data = mmio_read_32(DIEPCTL1) | 0x10088800;
+		mmio_write_32(DIEPCTL1, data);
+		data = mmio_read_32(DIEPCTL(1)) | 0x08000000;
+		mmio_write_32(DIEPCTL(1), data);
+
+		/* Enable interrupts on all endpoints */
+		mmio_write_32(DAINTMSK, 0xffffffff);
+
+		usb_status(req->value? 1 : 0, usb_drv_port_speed() ? 1 : 0);
+		size = 0;
+		VERBOSE("Set config descriptor.\n");
+
+		/* USB ö¾Ù³É¹¦µã,ÖÃÉϱêʶ */
+		g_usb_enum_flag = 1;
+		break;
+
+	default:
+		break;
+	}
+
+	if (!size) {
+		usb_drv_send_nonblocking(0, 0, 0);  // send an empty packet
+	} else if (size == -1) { // stall:Applies to non-control, non-isochronous IN and OUT endpoints only.
+		usb_drv_stall(0, 1, 1);     // IN
+		usb_drv_stall(0, 1, 0);     // OUT
+	} else { // stall:Applies to control endpoints only.
+		usb_drv_stall(0, 0, 1);     // IN
+		usb_drv_stall(0, 0, 0);     // OUT
+
+		usb_drv_send_nonblocking(0, addr, size > req->length ? req->length : size);
+	}
+}
+
+/* IRQ handler */
+static void usb_poll(void)
+{
+	uint32_t ints;
+	uint32_t epints, data;
+
+	ints = mmio_read_32(GINTSTS);		/* interrupt status */
+
+
+	if ((ints & 0xc3010) == 0)
+		return;
+	/*
+	 * bus reset
+	 * The core sets this bit to indicate that a reset is detected on the USB.
+	 */
+	if (ints & GINTSTS_USBRST) {
+		VERBOSE("bus reset intr\n");
+		/*set Non-Zero-Length status out handshake */
+		/*
+		 * DCFG:This register configures the core in Device mode after power-on
+		 * or after certain control commands or enumeration. Do not make changes
+		 * to this register after initial programming.
+		 * Send a STALL handshake on a nonzero-length status OUT transaction and
+		 * do not send the received OUT packet to the application.
+		 */
+		mmio_write_32(DCFG, 0x800004);
+		reset_endpoints();
+	}
+	/*
+	 * enumeration done, we now know the speed
+	 * The core sets this bit to indicate that speed enumeration is complete. The
+	 * application must read the Device Status (DSTS) register to obtain the
+	 * enumerated speed.
+	 */
+	if (ints & GINTSTS_ENUMDONE) {
+		/* Set up the maximum packet sizes accordingly */
+		uint32_t maxpacket = usb_drv_port_speed() ? USB_BLOCK_HIGH_SPEED_SIZE : 64;  // high speed maxpacket=512
+		VERBOSE("enum done intr. Maxpacket:%d\n", maxpacket);
+		//Set Maximum In Packet Size (MPS)
+		data = mmio_read_32(DIEPCTL1) & ~0x000003ff;
+		mmio_write_32(DIEPCTL1, data | maxpacket);
+		//Set Maximum Out Packet Size (MPS)
+		data = mmio_read_32(DOEPCTL1) & ~0x000003ff;
+		mmio_write_32(DOEPCTL1, data | maxpacket);
+	}
+
+	/*
+	 * IN EP event
+	 * The core sets this bit to indicate that an interrupt is pending on one of the IN
+	 * endpoints of the core (in Device mode). The application must read the
+	 * Device All Endpoints Interrupt (DAINT) register to determine the exact
+	 * number of the IN endpoint on which the interrupt occurred, and then read
+	 * the corresponding Device IN Endpoint-n Interrupt (DIEPINTn) register to
+	 * determine the exact cause of the interrupt. The application must clear the
+	 * appropriate status bit in the corresponding DIEPINTn register to clear this bit.
+	 */
+	if (ints & GINTSTS_IEPINT) {
+		epints = mmio_read_32(DIEPINT0);
+		mmio_write_32(DIEPINT0, epints);
+
+		//VERBOSE("IN EP event,ints:0x%x, DIEPINT0:%x, DAINT:%x, DAINTMSK:%x.\n",
+		//	ints, epints, mmio_read_32(DAINT), mmio_read_32(DAINTMSK));
+		if (epints & 0x1) { /* Transfer Completed Interrupt (XferCompl) */
+			VERBOSE("TX completed.DIEPTSIZ(0) = 0x%x.\n", mmio_read_32(DIEPTSIZ0));
+			/*FIXME,Maybe you can use bytes*/
+			/*int bytes = endpoints[0].size - (DIEPTSIZ(0) & 0x3FFFF);*/ //actual transfer
+			if (endpoints[0].busy) {
+				endpoints[0].busy = 0;//false
+				endpoints[0].rc = 0;
+				endpoints[0].done = 1;//true
+			}
+		}
+		if (epints & 0x4) { /* AHB error */
+			WARN("AHB error on IN EP0.\n");
+		}
+
+		if (epints & 0x8) { /* Timeout */
+			WARN("Timeout on IN EP0.\n");
+			if (endpoints[0].busy) {
+				endpoints[0].busy = 1;//false
+				endpoints[0].rc = 1;
+				endpoints[0].done = 1;//true
+			}
+		}
+	}
+
+	/*
+	 * OUT EP event
+	 * The core sets this bit to indicate that an interrupt is pending on one of the
+	 * OUT endpoints of the core (in Device mode). The application must read the
+	 * Device All Endpoints Interrupt (DAINT) register to determine the exact
+	 * number of the OUT endpoint on which the interrupt occurred, and then read
+	 * the corresponding Device OUT Endpoint-n Interrupt (DOEPINTn) register
+	 * to determine the exact cause of the interrupt. The application must clear the
+	 * appropriate status bit in the corresponding DOEPINTn register to clear this bit.
+	 */
+	if (ints & GINTSTS_OEPINT) {
+		/* indicates the status of an endpoint
+		 * with respect to USB- and AHB-related events. */
+		epints = mmio_read_32(DOEPINT(0));
+		//VERBOSE("OUT EP event,ints:0x%x, DOEPINT0:%x, DAINT:%x, DAINTMSK:%x.\n",
+		//	ints, epints, mmio_read_32(DAINT), mmio_read_32(DAINTMSK));
+		if (epints) {
+			mmio_write_32(DOEPINT(0), epints);
+			/* Transfer completed */
+			if (epints & DXEPINT_XFERCOMPL) {
+				/*FIXME,need use bytes*/
+				VERBOSE("EP0 RX completed. DOEPTSIZ(0) = 0x%x.\n",
+					mmio_read_32(DOEPTSIZ(0)));
+				if (endpoints[0].busy) {
+					endpoints[0].busy = 0;
+					endpoints[0].rc = 0;
+					endpoints[0].done = 1;
+				}
+			}
+			if (epints & DXEPINT_AHBERR) { /* AHB error */
+				WARN("AHB error on OUT EP0.\n");
+			}
+
+			/*
+			 * IN Token Received When TxFIFO is Empty (INTknTXFEmp)
+			 * Indicates that an IN token was received when the associated TxFIFO (periodic/nonperiodic)
+			 * was empty. This interrupt is asserted on the endpoint for which the IN token
+			 * was received.
+			 */
+			if (epints & DXEPINT_SETUP) { /* SETUP phase done */
+				VERBOSE("Setup phase \n");
+				data = mmio_read_32(DIEPCTL(0)) | DXEPCTL_SNAK;
+				mmio_write_32(DIEPCTL(0), data);
+				data = mmio_read_32(DOEPCTL(0)) | DXEPCTL_SNAK;
+				mmio_write_32(DOEPCTL(0), data);
+				/*clear IN EP intr*/
+				mmio_write_32(DIEPINT(0), ~0);
+				usb_handle_control_request((setup_packet *)&ctrl_req);
+			}
+
+			/* Make sure EP0 OUT is set up to accept the next request */
+			/* memset(p_ctrlreq, 0, NUM_ENDPOINTS*8); */
+			data = DOEPTSIZ0_SUPCNT(3) | DOEPTSIZ0_PKTCNT |
+				(64 << DOEPTSIZ0_XFERSIZE_SHIFT);
+			mmio_write_32(DOEPTSIZ0, data);
+			/*
+			 * IN Token Received When TxFIFO is Empty (INTknTXFEmp)
+			 * Indicates that an IN token was received when the associated TxFIFO (periodic/nonperiodic)
+			 * was empty. This interrupt is asserted on the endpoint for which the IN token
+			 * was received.
+			 */
+			// notes that:the compulsive conversion is expectable.
+			// Holds the start address of the external memory for storing or fetching endpoint data.
+			dma_desc_ep0.status.b.bs = 0x3;
+			dma_desc_ep0.status.b.mtrf = 0;
+			dma_desc_ep0.status.b.sr = 0;
+			dma_desc_ep0.status.b.l = 1;
+			dma_desc_ep0.status.b.ioc = 1;
+			dma_desc_ep0.status.b.sp = 0;
+			dma_desc_ep0.status.b.bytes = 64;
+			dma_desc_ep0.buf = (uintptr_t)&ctrl_req;
+			dma_desc_ep0.status.b.sts = 0;
+			dma_desc_ep0.status.b.bs = 0x0;
+			mmio_write_32(DOEPDMA0, (uintptr_t)&dma_desc_ep0);
+			// endpoint enable; clear NAK
+			mmio_write_32(DOEPCTL0, 0x84000000);
+		}
+
+		epints = mmio_read_32(DOEPINT1);
+		if(epints) {
+			mmio_write_32(DOEPINT1, epints);
+			VERBOSE("OUT EP1: epints :0x%x,DOEPTSIZ1 :0x%x.\n",epints, mmio_read_32(DOEPTSIZ1));
+			/* Transfer Completed Interrupt (XferCompl);Transfer completed */
+			if (epints & DXEPINT_XFERCOMPL) {
+				/* ((readl(DOEPTSIZ(1))) & 0x7FFFF is Transfer Size (XferSize) */
+				/*int bytes = (p_endpoints + 1)->size - ((readl(DOEPTSIZ(1))) & 0x7FFFF);*/
+				int bytes = rx_desc_bytes - dma_desc.status.b.bytes;
+				VERBOSE("OUT EP1: recv %d bytes \n",bytes);
+				if (endpoints[1].busy) {
+					endpoints[1].busy = 0;
+					endpoints[1].rc = 0;
+					endpoints[1].done = 1;
+					rx_req.complete(bytes, 0);
+				}
+			}
+
+			if (epints & DXEPINT_AHBERR) { /* AHB error */
+				WARN("AHB error on OUT EP1.\n");
+			}
+			if (epints & DXEPINT_SETUP) { /* SETUP phase done */
+				WARN("SETUP phase done  on OUT EP1.\n");
+			}
+		}
+	}
+	/* write to clear interrupts */
+	mmio_write_32(GINTSTS, ints);
+}
+
+#define EYE_PATTERN	0x70533483
+
+/*
+* pico phy exit siddq, nano phy enter siddq,
+* and open the clock of pico phy and dvc,
+*/
+static void dvc_and_picophy_init_chip(void)
+{
+	unsigned int data;
+
+	/* enable USB clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_USBOTG);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while ((data & PERI_CLK0_USBOTG) == 0);
+
+
+	/* out of reset */
+	mmio_write_32(PERI_SC_PERIPH_RSTDIS0,
+		      PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY |
+		      PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+		data &= PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY |
+			PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K;
+	} while (data);
+
+	mmio_write_32(PERI_SC_PERIPH_CTRL8, EYE_PATTERN);
+
+	/* configure USB PHY */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL4);
+	/* make PHY out of low power mode */
+	data &= ~PERI_CTRL4_PICO_SIDDQ;
+	/* detect VBUS by external circuit, switch D+ to 1.5KOhm pullup */
+	data |= PERI_CTRL4_PICO_VBUSVLDEXTSEL | PERI_CTRL4_PICO_VBUSVLDEXT;
+	data &= ~PERI_CTRL4_FPGA_EXT_PHY_SEL;
+	/* select PHY */
+	data &= ~PERI_CTRL4_OTG_PHY_SEL;
+	mmio_write_32(PERI_SC_PERIPH_CTRL4, data);
+
+	udelay(1000);
+
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL5);
+	data &= ~PERI_CTRL5_PICOPHY_BC_MODE;
+	mmio_write_32(PERI_SC_PERIPH_CTRL5, data);
+    
+	udelay(20000);
+}
+
+int init_usb(void)
+{
+	static int init_flag = 0;
+	uint32_t	data;
+
+	if (init_flag == 0) {
+		memset(&ctrl_req, 0, sizeof(setup_packet));
+		memset(&ctrl_resp, 0, 2);
+		memset(&endpoints, 0, sizeof(struct ep_type) * NUM_ENDPOINTS);
+		memset(&dma_desc, 0, sizeof(struct dwc_otg_dev_dma_desc));
+		memset(&dma_desc_ep0, 0, sizeof(struct dwc_otg_dev_dma_desc));
+		memset(&dma_desc_in, 0, sizeof(struct dwc_otg_dev_dma_desc));
+	}
+
+	VERBOSE("Pico PHY and DVC init start.\n");
+
+	dvc_and_picophy_init_chip();
+	VERBOSE("Pico PHY and DVC init done.\n");
+
+	/* wait for OTG AHB master idle */
+	do {
+		data = mmio_read_32(GRSTCTL) & GRSTCTL_AHBIDLE;
+	} while (data == 0);
+	VERBOSE("Reset usb controller\n");
+
+	/* OTG: Assert software reset */
+	mmio_write_32(GRSTCTL, GRSTCTL_CSFTRST);
+
+	/* wait for OTG to ack reset */
+	while (mmio_read_32(GRSTCTL) & GRSTCTL_CSFTRST);
+
+	/* wait for OTG AHB master idle */
+	while ((mmio_read_32(GRSTCTL) & GRSTCTL_AHBIDLE) == 0);
+
+	VERBOSE("Reset usb controller done\n");
+
+	usb_config();
+	VERBOSE("exit usb_init()\n");
+	return 0;
+}
+
+#define LOCK_STATE_LOCKED		0
+#define LOCK_STATE_UNLOCKED		1
+#define LOCK_STATE_RELOCKED		2
+
+#define FB_MAX_FILE_SIZE		(256 * 1024 * 1024)
+
+static struct ptentry *flash_ptn = NULL;
+
+static void fb_getvar(char *cmdbuf)
+{
+	char response[64];
+	char part_name[32];
+	int bytes;
+	struct ptentry *ptn = 0;
+
+	if (!strncmp(cmdbuf + 7, "max-download-size", 17)) {
+		bytes = sprintf(response, "OKAY0x%08x",
+				FB_MAX_FILE_SIZE);
+		response[bytes] = '\0';
+		tx_status(response);
+		rx_cmd();
+	} else if (!strncmp(cmdbuf + 7, "partition-type:", 15)) {
+		bytes = sprintf(part_name, "%s", cmdbuf + 22);
+		ptn = find_ptn(part_name);
+		if (ptn == NULL) {
+			bytes = sprintf(response, "FAIL%s",
+					"invalid partition");
+			response[bytes] = '\0';
+			flash_ptn = NULL;
+		} else {
+			bytes = sprintf(response, "OKAY");
+			response[bytes] = '\0';
+			flash_ptn = ptn;
+		}
+		tx_status(response);
+		rx_cmd();
+	} else if (!strncmp(cmdbuf + 7, "serialno", 8)) {
+		bytes = sprintf(response, "OKAY%s",
+				load_serialno());
+		response[bytes] = '\0';
+		tx_status(response);
+		rx_cmd();
+	}
+}
+
+/* FIXME: do not support endptr yet */
+static unsigned long strtoul(const char *nptr, char **endptr, int base)
+{
+	unsigned long step, data;
+	int i;
+
+	if (base == 0)
+		step = 10;
+	else if ((base < 2) || (base > 36)) {
+		VERBOSE("%s: invalid base %d\n", __func__, base);
+		return 0;
+	} else
+		step = base;
+
+	for (i = 0, data = 0; ; i++) {
+		if (nptr[i] == '\0')
+			break;
+		else if (!isalpha(nptr[i]) && !isdigit(nptr[i])) {
+			VERBOSE("%s: invalid string %s at %d [%x]\n",
+				__func__, nptr, i, nptr[i]);
+			return 0;
+		} else {
+			data *= step;
+			if (isupper(nptr[i]))
+				data += nptr[i] - 'A' + 10;
+			else if (islower(nptr[i]))
+				data += nptr[i] - 'a' + 10;
+			else if (isdigit(nptr[i]))
+				data += nptr[i] - '0';
+		}
+	}
+	return data;
+}
+
+static void fb_serialno(char *cmdbuf)
+{
+	struct random_serial_num random;
+
+	generate_serialno(&random);
+	flush_random_serialno((unsigned long)&random, sizeof(random));
+}
+
+static int fb_assigned_sn(char *cmdbuf)
+{
+	struct random_serial_num random;
+	int ret;
+
+	ret = assign_serialno(cmdbuf, &random);
+	if (ret < 0)
+		return ret;
+	flush_random_serialno((unsigned long)&random, sizeof(random));
+	return 0;
+}
+
+#define FB_DOWNLOAD_BASE	0x20000000
+
+static unsigned long fb_download_base, fb_download_size;
+
+static void fb_download(char *cmdbuf)
+{
+	char response[64];
+	int bytes;
+
+	if (!flash_ptn) {
+		bytes = sprintf(response, "FAIL%s",
+				"invalid partition");
+		response[bytes] = '\0';
+		tx_status(response);
+		rx_cmd();
+	} else {
+		rx_addr = FB_DOWNLOAD_BASE;
+		rx_length = strtoul(cmdbuf + 9, NULL, 16);
+		fb_download_base = rx_addr;
+		fb_download_size = rx_length;
+		if (rx_length > FB_MAX_FILE_SIZE) {
+			bytes = sprintf(response, "FAIL%s",
+					"file is too large");
+			response[bytes] = '\0';
+			tx_status(response);
+			rx_cmd();
+		} else {
+			bytes = sprintf(response, "DATA%08x",
+					rx_length);
+			VERBOSE("start:0x%x, length:0x%x, res:%s\n",
+				rx_addr, rx_length, response);
+			response[bytes] = '\0';
+			tx_status(response);
+			rx_data();
+		}
+	}
+}
+
+static void fb_flash(char *cmdbuf)
+{
+	flush_user_images(cmdbuf + 6, fb_download_base, fb_download_size);
+	tx_status("OKAY");
+	rx_cmd();
+}
+
+static void fb_reboot(char *cmdbuf)
+{
+	/* Send the system reset request */
+	mmio_write_32(AO_SC_SYS_STAT0, 0x48698284);
+
+	wfi();
+	panic();
+}
+
+static void usb_rx_cmd_complete(unsigned actual, int stat)
+{
+	if(stat != 0) return;
+
+	if(actual > 4095)
+		actual = 4095;
+	cmdbuf[actual] = 0;
+
+	INFO("cmd :%s\n",cmdbuf);
+
+	if(memcmp(cmdbuf, (void *)"reboot", 6) == 0) {
+		tx_status("OKAY");
+		fb_reboot(cmdbuf);
+		return;
+	} else if (!memcmp(cmdbuf, (void *)"getvar:", 7)) {
+		fb_getvar(cmdbuf);
+		return;
+	} else if (!memcmp(cmdbuf, (void *)"download:", 9)) {
+		fb_download(cmdbuf);
+		return;
+	} else if(memcmp(cmdbuf, (void *)"erase:", 6) == 0) {
+	} else if(memcmp(cmdbuf, (void *)"flash:", 6) == 0) {
+		INFO("recog updatefile\n");
+		fb_flash(cmdbuf);
+		return;
+	} else if(memcmp(cmdbuf, (void *)"boot", 4) == 0) {
+		INFO(" - OKAY\n");
+
+		return;
+	} else if (memcmp(cmdbuf, (void *)"oem serialno", 12) == 0) {
+		if (*(cmdbuf + 12) == '\0') {
+			fb_serialno(cmdbuf);
+			tx_status("OKAY");
+			rx_cmd();
+			return;
+		} else if (memcmp(cmdbuf + 12, (void *)" set", 4) == 0) {
+			if (fb_assigned_sn(cmdbuf + 16) == 0) {
+				tx_status("OKAY");
+				rx_cmd();
+				return;
+			}
+		}
+	} else if (memcmp(cmdbuf, (void *)"oem led", 7) == 0) {
+		if ((*(cmdbuf + 7) >= '1') && (*(cmdbuf + 7) <= '4')) {
+			int led;
+			led = *(cmdbuf + 7) - '0';
+			if (memcmp(cmdbuf + 8, (void *)" on", 3) == 0) {
+				gpio_set_value(31 + led, 1);
+				tx_status("OKAY");
+				rx_cmd();
+				return;
+			} else if (memcmp(cmdbuf + 8, (void *)" off", 4) == 0) {
+				gpio_set_value(31 + led, 0);
+				tx_status("OKAY");
+				rx_cmd();
+				return;
+			}
+		}
+	}
+
+	tx_status("FAILinvalid command");
+	rx_cmd();
+}
+
+static void usbloader_init(void)
+{
+	VERBOSE("enter usbloader_init\n");
+
+	/*usb sw and hw init*/
+	init_usb();
+
+	/*alloc and init sth for transfer*/
+	ep1in.num = BULK_IN_EP;
+	ep1in.in = 1;
+	ep1in.req = NULL;
+	ep1in.maxpkt = MAX_PACKET_LEN;
+	ep1in.next = &ep1in;
+	ep1out.num = BULK_OUT_EP;
+	ep1out.in = 0;
+	ep1out.req = NULL;
+	ep1out.maxpkt = MAX_PACKET_LEN;
+	ep1out.next = &ep1out;
+	cmdbuf = (char *)(rx_req.buf);
+
+	VERBOSE("exit usbloader_init\n");
+}
+
+void usb_reinit()
+{
+	if (usb_need_reset)
+	{
+		usb_need_reset = 0;
+		init_usb();
+	}
+}
+
+void usb_download(void)
+{
+	usbloader_init();
+	INFO("Enter downloading mode. Please run fastboot command on Host.\n");
+	for (;;) {
+		usb_poll();
+		usb_reinit();
+	}
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/aarch64/bl1_plat_helpers.S b/uefi/arm-trusted-firmware/plat/juno/aarch64/bl1_plat_helpers.S
new file mode 100644
index 0000000..3054eab
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/aarch64/bl1_plat_helpers.S
@@ -0,0 +1,142 @@
+/*
+ * 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 "../juno_def.h"
+
+	.globl	platform_is_primary_cpu
+	.globl	platform_get_entrypoint
+	.globl	platform_cold_boot_init
+	.globl	plat_secondary_cold_boot_setup
+
+	/* -----------------------------------------------------
+	 * unsigned int platform_is_primary_cpu (unsigned int mpid);
+	 *
+	 * Given the mpidr say whether this cpu is the primary
+	 * cpu (applicable ony after a cold boot)
+	 * -----------------------------------------------------
+	 */
+func platform_is_primary_cpu
+	mov	x9, x30
+	bl	platform_get_core_pos
+	ldr	x1, =SCP_BOOT_CFG_ADDR
+	ldr	x1, [x1]
+	ubfx	x1, x1, #PRIMARY_CPU_SHIFT, #PRIMARY_CPU_MASK
+	cmp	x0, x1
+	cset	x0, eq
+	ret	x9
+
+	/* -----------------------------------------------------
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * This function performs any platform specific actions
+	 * needed for a secondary cpu after a cold reset e.g
+	 * mark the cpu's presence, mechanism to place it in a
+	 * holding pen etc.
+	 * -----------------------------------------------------
+	 */
+func plat_secondary_cold_boot_setup
+	/* Juno todo: Implement secondary CPU cold boot setup on Juno */
+cb_panic:
+	b	cb_panic
+
+
+	/* -----------------------------------------------------
+	 * void platform_get_entrypoint (unsigned int mpid);
+	 *
+	 * Main job of this routine is to distinguish between
+	 * a cold and warm boot.
+	 * On a cold boot the secondaries first wait for the
+	 * platform to be initialized after which they are
+	 * hotplugged in. The primary proceeds to perform the
+	 * platform initialization.
+	 * On a warm boot, each cpu jumps to the address in its
+	 * mailbox.
+	 *
+	 * TODO: Not a good idea to save lr in a temp reg
+	 * -----------------------------------------------------
+	 */
+func platform_get_entrypoint
+	mov	x9, x30 // lr
+	bl	platform_get_core_pos
+	ldr	x1, =TRUSTED_MAILBOXES_BASE
+	lsl	x0, x0, #TRUSTED_MAILBOX_SHIFT
+	ldr	x0, [x1, x0]
+	ret	x9
+
+
+	/* -----------------------------------------------------
+	 * void platform_cold_boot_init (bl1_main function);
+	 *
+	 * Routine called only by the primary cpu after a cold
+	 * boot to perform early platform initialization
+	 * -----------------------------------------------------
+	 */
+func platform_cold_boot_init
+	mov	x20, x0
+
+	/* ---------------------------------------------
+	 * Give ourselves a small coherent stack to
+	 * ease the pain of initializing the MMU and
+	 * CCI in assembler
+	 * ---------------------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	bl	platform_set_coherent_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
+
+	/* ---------------------------------------------
+	 * Give ourselves a stack allocated in Normal
+	 * -IS-WBWA memory
+	 * ---------------------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	bl	platform_set_stack
+
+	/* ---------------------------------------------
+	 * Jump to the main function. Returning from it
+	 * is a terminal error.
+	 * ---------------------------------------------
+	 */
+	blr	x20
+
+cb_init_panic:
+	b	cb_init_panic
diff --git a/uefi/arm-trusted-firmware/plat/juno/aarch64/juno_common.c b/uefi/arm-trusted-firmware/plat/juno/aarch64/juno_common.c
new file mode 100644
index 0000000..27d4c8f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/aarch64/juno_common.c
@@ -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 <arch_helpers.h>
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <xlat_tables.h>
+#include "../juno_def.h"
+
+#define MAP_MHU_SECURE	MAP_REGION_FLAT(MHU_SECURE_BASE,		\
+					MHU_SECURE_SIZE,		\
+					(MHU_PAYLOAD_CACHED ?		\
+					 MT_MEMORY : MT_DEVICE)		\
+					| MT_RW | MT_SECURE)
+
+#define MAP_FLASH	MAP_REGION_FLAT(FLASH_BASE,			\
+					FLASH_SIZE,			\
+					MT_MEMORY | MT_RO | MT_SECURE)
+
+#define MAP_IOFPGA	MAP_REGION_FLAT(IOFPGA_BASE,			\
+					IOFPGA_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
+					DEVICE0_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_DEVICE1	MAP_REGION_FLAT(DEVICE1_BASE,			\
+					DEVICE1_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_NS_DRAM	MAP_REGION_FLAT(DRAM_NS_BASE,			\
+					DRAM_NS_SIZE,			\
+					MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_TSP_MEM	MAP_REGION_FLAT(TSP_SEC_MEM_BASE, 		\
+					TSP_SEC_MEM_SIZE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * configure_mmu_elx() will give the available subset of that,
+ */
+#if IMAGE_BL1
+static const mmap_region_t juno_mmap[] = {
+	MAP_MHU_SECURE,
+	MAP_FLASH,
+	MAP_IOFPGA,
+	MAP_DEVICE0,
+	MAP_DEVICE1,
+	{0}
+};
+#endif
+#if IMAGE_BL2
+static const mmap_region_t juno_mmap[] = {
+	MAP_MHU_SECURE,
+	MAP_FLASH,
+	MAP_IOFPGA,
+	MAP_DEVICE0,
+	MAP_DEVICE1,
+	MAP_NS_DRAM,
+	MAP_TSP_MEM,
+	{0}
+};
+#endif
+#if IMAGE_BL31
+static const mmap_region_t juno_mmap[] = {
+	MAP_MHU_SECURE,
+	MAP_IOFPGA,
+	MAP_DEVICE0,
+	MAP_DEVICE1,
+	MAP_TSP_MEM,
+	{0}
+};
+#endif
+#if IMAGE_BL32
+static const mmap_region_t juno_mmap[] = {
+	MAP_IOFPGA,
+	MAP_DEVICE0,
+	MAP_DEVICE1,
+	{0}
+};
+#endif
+
+/* Array of secure interrupts to be configured by the gic driver */
+const unsigned int irq_sec_array[] = {
+	IRQ_MHU,
+	IRQ_GPU_SMMU_0,
+	IRQ_GPU_SMMU_1,
+	IRQ_ETR_SMMU,
+	IRQ_TZC400,
+	IRQ_TZ_WDOG,
+	IRQ_SEC_PHY_TIMER,
+	IRQ_SEC_SGI_0,
+	IRQ_SEC_SGI_1,
+	IRQ_SEC_SGI_2,
+	IRQ_SEC_SGI_3,
+	IRQ_SEC_SGI_4,
+	IRQ_SEC_SGI_5,
+	IRQ_SEC_SGI_6,
+	IRQ_SEC_SGI_7
+};
+
+const unsigned int num_sec_irqs = sizeof(irq_sec_array) /
+	sizeof(irq_sec_array[0]);
+
+/*******************************************************************************
+ * Macro generating the code for the function setting up the pagetables as per
+ * the platform memory map & initialize the mmu, for the given exception level
+ ******************************************************************************/
+#if USE_COHERENT_MEM
+#define DEFINE_CONFIGURE_MMU_EL(_el)				\
+	void configure_mmu_el##_el(unsigned long total_base,	\
+				  unsigned long total_size,	\
+				  unsigned long ro_start,	\
+				  unsigned long ro_limit,	\
+				  unsigned long coh_start,	\
+				  unsigned long coh_limit)	\
+	{							\
+	       mmap_add_region(total_base, total_base,		\
+			       total_size,			\
+			       MT_MEMORY | MT_RW | MT_SECURE);	\
+	       mmap_add_region(ro_start, ro_start,		\
+			       ro_limit - ro_start,		\
+			       MT_MEMORY | MT_RO | MT_SECURE);	\
+	       mmap_add_region(coh_start, coh_start,		\
+			       coh_limit - coh_start,		\
+			       MT_DEVICE | MT_RW | MT_SECURE);	\
+	       mmap_add(juno_mmap);				\
+	       init_xlat_tables();				\
+								\
+	       enable_mmu_el##_el(0);				\
+	}
+#else
+#define DEFINE_CONFIGURE_MMU_EL(_el)				\
+	void configure_mmu_el##_el(unsigned long total_base,	\
+				  unsigned long total_size,	\
+				  unsigned long ro_start,	\
+				  unsigned long ro_limit)	\
+	{							\
+	       mmap_add_region(total_base, total_base,		\
+			       total_size,			\
+			       MT_MEMORY | MT_RW | MT_SECURE);	\
+	       mmap_add_region(ro_start, ro_start,		\
+			       ro_limit - ro_start,		\
+			       MT_MEMORY | MT_RO | MT_SECURE);	\
+	       mmap_add(juno_mmap);				\
+	       init_xlat_tables();				\
+								\
+	       enable_mmu_el##_el(0);				\
+	}
+#endif
+/* Define EL1 and EL3 variants of the function initialising the MMU */
+DEFINE_CONFIGURE_MMU_EL(1)
+DEFINE_CONFIGURE_MMU_EL(3)
+
+
+unsigned long plat_get_ns_image_entrypoint(void)
+{
+	return NS_IMAGE_OFFSET;
+}
+
+uint64_t plat_get_syscnt_freq(void)
+{
+	uint64_t counter_base_frequency;
+
+	/* Read the frequency from Frequency modes table */
+	counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
+
+	/* The first entry of the frequency modes table must not be 0 */
+	if (counter_base_frequency == 0)
+		panic();
+
+	return counter_base_frequency;
+}
+
+void plat_gic_init(void)
+{
+	arm_gic_init(GICC_BASE, GICD_BASE, 0, irq_sec_array, num_sec_irqs);
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/aarch64/plat_helpers.S b/uefi/arm-trusted-firmware/plat/juno/aarch64/plat_helpers.S
new file mode 100644
index 0000000..37966a3
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/aarch64/plat_helpers.S
@@ -0,0 +1,154 @@
+/*
+ * 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 <cortex_a57.h>
+#include <cpu_macros.S>
+#include <platform_def.h>
+#include "../juno_def.h"
+
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_report_exception
+	.globl	plat_reset_handler
+	.globl	platform_get_core_pos
+	.globl	platform_mem_init
+
+	/* Define a crash console for the plaform */
+#define JUNO_CRASH_CONSOLE_BASE		PL011_UART3_BASE
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize the crash console
+	 * without a C Runtime to print crash report.
+	 * Clobber list : x0, x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+	mov_imm	x0, JUNO_CRASH_CONSOLE_BASE
+	mov_imm	x1, PL011_UART3_CLK_IN_HZ
+	mov_imm	x2, PL011_BAUDRATE
+	b	console_core_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to print a character on the crash
+	 * console without a C Runtime.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, JUNO_CRASH_CONSOLE_BASE
+	b	console_core_putc
+
+	/* ---------------------------------------------
+	 * void plat_report_exception(unsigned int type)
+	 * Function to report an unhandled exception
+	 * with platform-specific means.
+	 * On Juno platform, it updates the LEDs
+	 * to indicate where we are
+	 * ---------------------------------------------
+	 */
+func plat_report_exception
+	mrs	x1, CurrentEl
+	lsr	x1, x1, #MODE_EL_SHIFT
+	lsl	x1, x1, #SYS_LED_EL_SHIFT
+	lsl	x0, x0, #SYS_LED_EC_SHIFT
+	mov	x2, #(SECURE << SYS_LED_SS_SHIFT)
+	orr	x0, x0, x2
+	orr	x0, x0, x1
+	mov	x1, #VE_SYSREGS_BASE
+	add	x1, x1, #V2M_SYS_LED
+	str	w0, [x1]
+	ret
+
+	/*
+	 * Return 0 to 3 for the A53s and 4 or 5 for the A57s
+	 */
+func platform_get_core_pos
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	eor	x0, x0, #(1 << MPIDR_AFFINITY_BITS)  // swap A53/A57 order
+	add	x0, x1, x0, LSR #6
+	ret
+
+
+	/* -----------------------------------------------------
+	 * void platform_mem_init(void);
+	 *
+	 * We don't need to carry out any memory initialization
+	 * on Juno. The Secure RAM is accessible straight away.
+	 * -----------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+
+	/* -----------------------------------------------------
+	 * void plat_reset_handler(void);
+	 *
+	 * Before adding code in this function, refer to the
+	 * guidelines in docs/firmware-design.md to determine
+	 * whether the code should reside within the
+	 * FIRST_RESET_HANDLER_CALL block or not.
+	 *
+	 * Implement workaround for defect id 831273 by enabling
+	 * an event stream every 65536 cycles and set the L2 RAM
+	 * latencies for Cortex-A57. This code is included only
+	 * when FIRST_RESET_HANDLER_CALL is defined since it
+	 * should be executed only during BL1.
+	 * -----------------------------------------------------
+	 */
+func plat_reset_handler
+#ifdef FIRST_RESET_HANDLER_CALL
+	/* Read the MIDR_EL1 */
+	mrs	x0, midr_el1
+	ubfx	x1, x0, MIDR_PN_SHIFT, #12
+	cmp     w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+	b.ne    1f
+
+	/* Change the L2 Data and Tag Ram latency to 3 cycles */
+	mov	x0, #(L2_DATA_RAM_LATENCY_3_CYCLES |    \
+			(L2_TAG_RAM_LATENCY_3_CYCLES << \
+			 L2CTLR_TAG_RAM_LATENCY_SHIFT))
+	msr     L2CTLR_EL1, x0
+
+1:
+	/* ---------------------------------------------
+	 * Enable the event stream every 65536 cycles
+	 * ---------------------------------------------
+	 */
+	mov     x0, #(0xf << EVNTI_SHIFT)
+	orr     x0, x0, #EVNTEN_BIT
+	msr     CNTKCTL_EL1, x0
+	isb
+#endif /* FIRST_RESET_HANDLER_CALL */
+	ret
diff --git a/uefi/arm-trusted-firmware/plat/juno/bl1_plat_setup.c b/uefi/arm-trusted-firmware/plat/juno/bl1_plat_setup.c
new file mode 100644
index 0000000..23e8592
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/bl1_plat_setup.c
@@ -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 <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <cci400.h>
+#include <console.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include "../../bl1/bl1_private.h"
+#include "juno_def.h"
+#include "juno_private.h"
+
+#if USE_COHERENT_MEM
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ ******************************************************************************/
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+#endif
+
+/* Data structure which holds the extents of the trusted RAM for BL1 */
+static meminfo_t bl1_tzram_layout;
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+	return &bl1_tzram_layout;
+}
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+	const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
+
+	/* Initialize the console to provide early debug support */
+	console_init(PL011_UART2_BASE, PL011_UART2_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/*
+	 * Enable CCI-400 for this cluster. No need for locks as no other cpu is
+	 * active at the moment
+	 */
+	cci_init(CCI400_BASE,
+		 CCI400_SL_IFACE3_CLUSTER_IX,
+		 CCI400_SL_IFACE4_CLUSTER_IX);
+	cci_enable_cluster_coherency(read_mpidr());
+
+	/* Allow BL1 to see the whole Trusted RAM */
+	bl1_tzram_layout.total_base = TZRAM_BASE;
+	bl1_tzram_layout.total_size = TZRAM_SIZE;
+
+	/* Calculate how much RAM BL1 is using and how much remains free */
+	bl1_tzram_layout.free_base = TZRAM_BASE;
+	bl1_tzram_layout.free_size = TZRAM_SIZE;
+	reserve_mem(&bl1_tzram_layout.free_base,
+		    &bl1_tzram_layout.free_size,
+		    BL1_RAM_BASE,
+		    bl1_size);
+
+	INFO("BL1: 0x%lx - 0x%lx [size = %u]\n", BL1_RAM_BASE, BL1_RAM_LIMIT,
+	     bl1_size);
+}
+
+
+/*
+ * Address of slave 'n' security setting in the NIC-400 address region
+ * control
+ * TODO: Ideally this macro should be moved in a "nic-400.h" header file but
+ * it would be the only thing in there so it's not worth it at the moment.
+ */
+#define NIC400_ADDR_CTRL_SECURITY_REG(n)	(0x8 + (n) * 4)
+
+static void init_nic400(void)
+{
+	/*
+	 * NIC-400 Access Control Initialization
+	 *
+	 * Define access privileges by setting each corresponding bit to:
+	 *   0 = Secure access only
+	 *   1 = Non-secure access allowed
+	 */
+
+	/*
+	 * Allow non-secure access to some SOC regions, excluding UART1, which
+	 * remains secure.
+	 * Note: This is the NIC-400 device on the SOC
+	 */
+	mmio_write_32(SOC_NIC400_BASE +
+		      NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_USB_EHCI), ~0);
+	mmio_write_32(SOC_NIC400_BASE +
+		      NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_TLX_MASTER), ~0);
+	mmio_write_32(SOC_NIC400_BASE +
+		      NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_USB_OHCI), ~0);
+	mmio_write_32(SOC_NIC400_BASE +
+		      NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_PL354_SMC), ~0);
+	mmio_write_32(SOC_NIC400_BASE +
+		      NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_APB4_BRIDGE), ~0);
+	mmio_write_32(SOC_NIC400_BASE +
+		      NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_BOOTSEC_BRIDGE),
+		      ~SOC_NIC400_BOOTSEC_BRIDGE_UART1);
+
+	/*
+	 * Allow non-secure access to some CSS regions.
+	 * Note: This is the NIC-400 device on the CSS
+	 */
+	mmio_write_32(CSS_NIC400_BASE +
+		      NIC400_ADDR_CTRL_SECURITY_REG(CSS_NIC400_SLAVE_BOOTSECURE),
+		      ~0);
+}
+
+
+#define PCIE_SECURE_REG		0x3000
+#define PCIE_SEC_ACCESS_MASK	((1 << 0) | (1 << 1)) /* REG and MEM access bits */
+
+static void init_pcie(void)
+{
+	/*
+	 * PCIE Root Complex Security settings to enable non-secure
+	 * access to config registers.
+	 */
+	mmio_write_32(PCIE_CONTROL_BASE + PCIE_SECURE_REG, PCIE_SEC_ACCESS_MASK);
+}
+
+
+/*******************************************************************************
+ * Function which will perform any remaining platform-specific setup that can
+ * occur after the MMU and data cache have been enabled.
+ ******************************************************************************/
+void bl1_platform_setup(void)
+{
+	init_nic400();
+	init_pcie();
+
+	/* Initialise the IO layer and register platform IO devices */
+	io_setup();
+
+	/* Enable and initialize the System level generic timer */
+	mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
+}
+
+
+/*******************************************************************************
+ * Perform the very early platform specific architecture setup here. At the
+ * moment this only does basic initialization. Later architectural setup
+ * (bl1_arch_setup()) does not do anything platform specific.
+ ******************************************************************************/
+void bl1_plat_arch_setup(void)
+{
+	configure_mmu_el3(bl1_tzram_layout.total_base,
+			  bl1_tzram_layout.total_size,
+			  TZROM_BASE,
+			  TZROM_BASE + TZROM_SIZE
+#if USE_COHERENT_MEM
+			  , BL1_COHERENT_RAM_BASE,
+			  BL1_COHERENT_RAM_LIMIT
+#endif
+			  );
+}
+
+/*******************************************************************************
+ * Before calling this function BL2 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL2 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image,
+			      entry_point_info_t *bl2_ep)
+{
+	SET_SECURITY_STATE(bl2_ep->h.attr, SECURE);
+	bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/bl2_plat_setup.c b/uefi/arm-trusted-firmware/plat/juno/bl2_plat_setup.c
new file mode 100644
index 0000000..8e7b2a0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/bl2_plat_setup.c
@@ -0,0 +1,325 @@
+/*
+ * 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 <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include "juno_def.h"
+#include "juno_private.h"
+#include "scp_bootloader.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __RO_END__;
+
+#if USE_COHERENT_MEM
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+#endif
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL2_RO_BASE (unsigned long)(&__RO_START__)
+#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
+
+#if USE_COHERENT_MEM
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+#endif
+
+/* Data structure which holds the extents of the trusted RAM for BL2 */
+static meminfo_t bl2_tzram_layout
+__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE)));
+
+/*******************************************************************************
+ * Structure which holds the arguments which need to be passed to BL3-1
+ ******************************************************************************/
+static bl2_to_bl31_params_mem_t bl31_params_mem;
+
+meminfo_t *bl2_plat_sec_mem_layout(void)
+{
+	return &bl2_tzram_layout;
+}
+
+/*******************************************************************************
+ * This function assigns a pointer to the memory that the platform has kept
+ * aside to pass platform specific and trusted firmware related information
+ * to BL31. This memory is allocated by allocating memory to
+ * bl2_to_bl31_params_mem_t structure which is a superset of all the
+ * structure whose information is passed to BL31
+ * NOTE: This function should be called only once and should be done
+ * before generating params to BL31
+ ******************************************************************************/
+bl31_params_t *bl2_plat_get_bl31_params(void)
+{
+	bl31_params_t *bl2_to_bl31_params;
+
+	/*
+	 * Initialise the memory for all the arguments that needs to
+	 * be passed to BL3-1
+	 */
+	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
+
+	/* Assign memory for TF related information */
+	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
+	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
+
+	/* Fill BL3-1 related information */
+	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
+		VERSION_1, 0);
+
+	/* Fill BL3-2 related information if it exists */
+#if BL32_BASE
+	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
+		VERSION_1, 0);
+	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
+		VERSION_1, 0);
+#endif
+
+	/* Fill BL3-3 related information */
+	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
+		PARAM_EP, VERSION_1, 0);
+
+	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
+	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
+
+	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
+		VERSION_1, 0);
+
+	return bl2_to_bl31_params;
+}
+
+/*******************************************************************************
+ * This function returns a pointer to the shared memory that the platform
+ * has kept to point to entry point information of BL31 to BL2
+ ******************************************************************************/
+struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
+{
+#if DEBUG
+	bl31_params_mem.bl31_ep_info.args.arg1 = JUNO_BL31_PLAT_PARAM_VAL;
+#endif
+
+	return &bl31_params_mem.bl31_ep_info;
+}
+
+/*******************************************************************************
+ * BL1 has passed the extents of the trusted RAM that should be visible to BL2
+ * in x0. This memory layout is sitting at the base of the free trusted RAM.
+ * Copy it to a safe loaction before its reclaimed by later BL2 functionality.
+ ******************************************************************************/
+void bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(PL011_UART2_BASE, PL011_UART2_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Setup the BL2 memory layout */
+	bl2_tzram_layout = *mem_layout;
+
+	/* Initialise the IO layer and register platform IO devices */
+	io_setup();
+}
+
+/*******************************************************************************
+ * Perform platform specific setup, i.e. initialize the IO layer, load BL3-0
+ * image and initialise the memory location to use for passing arguments to
+ * BL3-1.
+ ******************************************************************************/
+void bl2_platform_setup(void)
+{
+	/* Initialize the secure environment */
+	plat_security_setup();
+}
+
+/* Flush the TF params and the TF plat params */
+void bl2_plat_flush_bl31_params(void)
+{
+	flush_dcache_range((unsigned long)&bl31_params_mem,
+			sizeof(bl2_to_bl31_params_mem_t));
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl2_plat_arch_setup(void)
+{
+	configure_mmu_el1(bl2_tzram_layout.total_base,
+			  bl2_tzram_layout.total_size,
+			  BL2_RO_BASE,
+			  BL2_RO_LIMIT
+#if USE_COHERENT_MEM
+			  , BL2_COHERENT_RAM_BASE,
+			  BL2_COHERENT_RAM_LIMIT
+#endif
+			  );
+}
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL3-0, i.e. anywhere
+ * in trusted RAM as long as it doesn't overwrite BL2.
+ ******************************************************************************/
+void bl2_plat_get_bl30_meminfo(meminfo_t *bl30_meminfo)
+{
+	*bl30_meminfo = bl2_tzram_layout;
+}
+
+/*******************************************************************************
+ * Transfer BL3-0 from Trusted RAM using the SCP Download protocol.
+ * Return 0 on success, -1 otherwise.
+ ******************************************************************************/
+int bl2_plat_handle_bl30(image_info_t *bl30_image_info)
+{
+	int ret;
+
+	ret = scp_bootloader_transfer((void *)bl30_image_info->image_base,
+		bl30_image_info->image_size);
+
+	if (ret == 0)
+		INFO("BL2: BL3-0 transferred to SCP\n\r");
+	else
+		ERROR("BL2: BL3-0 transfer failure\n\r");
+
+	return ret;
+}
+
+/*******************************************************************************
+ * Before calling this function BL31 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL31 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
+			       entry_point_info_t *bl31_ep_info)
+{
+	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
+	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+				       DISABLE_ALL_EXCEPTIONS);
+}
+
+
+/*******************************************************************************
+ * Before calling this function BL32 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL32 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
+			       entry_point_info_t *bl32_ep_info)
+{
+	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
+	/*
+	* The Secure Payload Dispatcher service is responsible for
+	* setting the SPSR prior to entry into the BL32 image.
+	*/
+	bl32_ep_info->spsr = 0;
+}
+
+/*******************************************************************************
+ * Before calling this function BL33 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL33 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl33_ep_info(image_info_t *image,
+				       entry_point_info_t *bl33_ep_info)
+{
+	unsigned long el_status;
+	unsigned int mode;
+
+	/* Figure out what mode we enter the non-secure world in */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	if (el_status)
+		mode = MODE_EL2;
+	else
+		mode = MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
+				       DISABLE_ALL_EXCEPTIONS);
+	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+}
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL3-2
+ ******************************************************************************/
+void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
+{
+	/*
+	 * Populate the extents of memory available for loading BL3-2.
+	 */
+	bl32_meminfo->total_base = BL32_BASE;
+	bl32_meminfo->free_base = BL32_BASE;
+	bl32_meminfo->total_size =
+		       (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+	bl32_meminfo->free_size =
+		       (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+}
+
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL3-3
+ ******************************************************************************/
+void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
+{
+	bl33_meminfo->total_base = DRAM_NS_BASE;
+	bl33_meminfo->total_size = DRAM_NS_SIZE;
+	bl33_meminfo->free_base = DRAM_NS_BASE;
+	bl33_meminfo->free_size = DRAM_NS_SIZE;
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/bl31_plat_setup.c b/uefi/arm-trusted-firmware/plat/juno/bl31_plat_setup.c
new file mode 100644
index 0000000..ad8ea43
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/bl31_plat_setup.c
@@ -0,0 +1,197 @@
+/*
+ * 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 <arm_gic.h>
+#include <assert.h>
+#include <bl31.h>
+#include <bl_common.h>
+#include <cci400.h>
+#include <console.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stddef.h>
+#include "juno_def.h"
+#include "juno_private.h"
+#include "mhu.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __RO_END__;
+extern unsigned long __BL31_END__;
+
+#if USE_COHERENT_MEM
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+#endif
+
+/*
+ * The next 3 constants identify the extents of the code, RO data region and the
+ * limit of the BL3-1 image.  These addresses are used by the MMU setup code and
+ * therefore they must be page-aligned.  It is the responsibility of the linker
+ * script to ensure that __RO_START__, __RO_END__ & __BL31_END__ linker symbols
+ * refer to page-aligned addresses.
+ */
+#define BL31_RO_BASE (unsigned long)(&__RO_START__)
+#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
+#define BL31_END (unsigned long)(&__BL31_END__)
+
+#if USE_COHERENT_MEM
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols
+ * refer to page-aligned addresses.
+ */
+#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+#endif
+
+/******************************************************************************
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL3-1 from BL2.
+ ******************************************************************************/
+static entry_point_info_t bl32_ep_info;
+static entry_point_info_t bl33_ep_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL3-3 corresponds to the non-secure image type
+ * while BL3-2 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	entry_point_info_t *next_image_info;
+
+	next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
+
+	/* None of the images on this platform can have 0x0 as the entrypoint */
+	if (next_image_info->pc)
+		return next_image_info;
+	else
+		return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL3-1 specific platform actions. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
+ * are lost (potentially). This needs to be done before the MMU is initialized
+ * so that the memory layout can be used while creating page tables. Also, BL2
+ * has flushed this information to memory, so we are guaranteed to pick up good
+ * data
+ ******************************************************************************/
+void bl31_early_platform_setup(bl31_params_t *from_bl2,
+			       void *plat_params_from_bl2)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(PL011_UART2_BASE, PL011_UART2_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/*
+	 * Initialise the CCI-400 driver for BL31 so that it is accessible after
+	 * a warm boot. BL1 should have already enabled CCI coherency for this
+	 * cluster during cold boot.
+	 */
+	cci_init(CCI400_BASE,
+		 CCI400_SL_IFACE3_CLUSTER_IX,
+		 CCI400_SL_IFACE4_CLUSTER_IX);
+
+	/*
+	 * Check params passed from BL2 should not be NULL,
+	 */
+	assert(from_bl2 != NULL);
+	assert(from_bl2->h.type == PARAM_BL31);
+	assert(from_bl2->h.version >= VERSION_1);
+	/*
+	 * In debug builds, we pass a special value in 'plat_params_from_bl2'
+	 * to verify platform parameters from BL2 to BL3-1.
+	 * In release builds, it's not used.
+	 */
+	assert(((unsigned long long)plat_params_from_bl2) ==
+		JUNO_BL31_PLAT_PARAM_VAL);
+
+	/*
+	 * Copy BL3-2 and BL3-3 entry point information.
+	 * They are stored in Secure RAM, in BL2's address space.
+	 */
+	bl32_ep_info = *from_bl2->bl32_ep_info;
+	bl33_ep_info = *from_bl2->bl33_ep_info;
+}
+
+/*******************************************************************************
+ * Initialize the MHU and the GIC.
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+	unsigned int reg_val;
+
+	mhu_secure_init();
+
+	/* Initialize the gic cpu and distributor interfaces */
+	plat_gic_init();
+	arm_gic_setup();
+
+	/* Enable and initialize the System level generic timer */
+	mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
+
+	/* Allow access to the System counter timer module */
+	reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
+	reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
+	reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT);
+	mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(1), reg_val);
+
+	reg_val = (1 << CNTNSAR_NS_SHIFT(1));
+	mmio_write_32(SYS_TIMCTL_BASE + CNTNSAR, reg_val);
+
+	/* Topologies are best known to the platform. */
+	plat_setup_topology();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup()
+{
+	configure_mmu_el3(BL31_RO_BASE,
+			  (BL31_END - BL31_RO_BASE),
+			  BL31_RO_BASE,
+			  BL31_RO_LIMIT
+#if USE_COHERENT_MEM
+			  ,
+			  BL31_COHERENT_RAM_BASE,
+			  BL31_COHERENT_RAM_LIMIT
+#endif
+			  );
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/include/plat_macros.S b/uefi/arm-trusted-firmware/plat/juno/include/plat_macros.S
new file mode 100644
index 0000000..a9d2466
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/include/plat_macros.S
@@ -0,0 +1,109 @@
+/*
+ * 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 <cci400.h>
+#include <gic_v2.h>
+#include "platform_def.h"
+#include "../juno_def.h"
+
+.section .rodata.gic_reg_name, "aS"
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+
+	/* ---------------------------------------------
+	 * The below macro prints out relevant GIC
+	 * registers whenever an unhandled exception is
+	 * taken in BL3-1.
+	 * Clobbers: x0 - x10, x16, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_print_gic_regs
+	mov_imm	x16, GICD_BASE
+	mov_imm	x17, GICC_BASE
+	/* Load the gicc reg list to x6 */
+	adr	x6, gicc_regs
+	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+	ldr	w8, [x17, #GICC_HPPIR]
+	ldr	w9, [x17, #GICC_AHPPIR]
+	ldr	w10, [x17, #GICC_CTLR]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+
+	/* Print the GICD_ISPENDR regs */
+	add	x7, x16, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+gicd_ispendr_loop:
+	sub	x4, x7, x16
+	cmp	x4, #0x280
+	b.eq	exit_print_gic_regs
+	bl	asm_print_hex
+
+	adr	x4, spacer
+	bl	asm_print_str
+
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+
+	adr	x4, newline
+	bl	asm_print_str
+	b	gicd_ispendr_loop
+exit_print_gic_regs:
+	.endm
+
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+	.asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+	/* ------------------------------------------------
+	 * The below macro prints out relevant interconnect
+	 * registers whenever an unhandled exception is
+	 * taken in BL3-1.
+	 * Clobbers: x0 - x9, sp
+	 * ------------------------------------------------
+	 */
+	.macro plat_print_interconnect_regs
+	adr	x6, cci_iface_regs
+	/* Store in x7 the base address of the first interface */
+	mov_imm	x7, (CCI400_BASE + SLAVE_IFACE3_OFFSET)
+	ldr	w8, [x7, #SNOOP_CTRL_REG]
+	/* Store in x7 the base address of the second interface */
+	mov_imm	x7, (CCI400_BASE + SLAVE_IFACE4_OFFSET)
+	ldr	w9, [x7, #SNOOP_CTRL_REG]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+	.endm
diff --git a/uefi/arm-trusted-firmware/plat/juno/include/platform_def.h b/uefi/arm-trusted-firmware/plat/juno/include/platform_def.h
new file mode 100644
index 0000000..31c191c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/include/platform_def.h
@@ -0,0 +1,221 @@
+/*
+ * 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 __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include "../juno_def.h"
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT          "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH            aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if TRUSTED_BOARD_BOOT && (IMAGE_BL1 || IMAGE_BL2)
+#define PLATFORM_STACK_SIZE 0x1000
+#else
+#define PLATFORM_STACK_SIZE 0x800
+#endif
+
+#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+
+/* Trusted Boot Firmware BL2 */
+#define BL2_IMAGE_NAME			"bl2.bin"
+
+/* EL3 Runtime Firmware BL3-1 */
+#define BL31_IMAGE_NAME			"bl31.bin"
+
+/* SCP Firmware BL3-0 */
+#define BL30_IMAGE_NAME			"bl30.bin"
+
+/* Secure Payload BL3-2 (Trusted OS) */
+#define BL32_IMAGE_NAME			"bl32.bin"
+
+/* Non-Trusted Firmware BL3-3 */
+#define BL33_IMAGE_NAME			"bl33.bin" /* e.g. UEFI */
+
+/* Firmware Image Package */
+#define FIP_IMAGE_NAME			"fip.bin"
+
+#if TRUSTED_BOARD_BOOT
+/* Certificates */
+# define BL2_CERT_NAME			"bl2.crt"
+# define TRUSTED_KEY_CERT_NAME		"trusted_key.crt"
+
+# define BL30_KEY_CERT_NAME		"bl30_key.crt"
+# define BL31_KEY_CERT_NAME		"bl31_key.crt"
+# define BL32_KEY_CERT_NAME		"bl32_key.crt"
+# define BL33_KEY_CERT_NAME		"bl33_key.crt"
+
+# define BL30_CERT_NAME			"bl30.crt"
+# define BL31_CERT_NAME			"bl31.crt"
+# define BL32_CERT_NAME			"bl32.crt"
+# define BL33_CERT_NAME			"bl33.crt"
+#endif /* TRUSTED_BOARD_BOOT */
+
+#define PLATFORM_CACHE_LINE_SIZE	64
+#define PLATFORM_CLUSTER_COUNT		2
+#define PLATFORM_CORE_COUNT             6
+#define PLATFORM_NUM_AFFS		(PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+#define MAX_IO_DEVICES			3
+#define MAX_IO_HANDLES			4
+
+/*******************************************************************************
+ * BL1 specific defines.
+ * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 base
+ * addresses.
+ ******************************************************************************/
+#define BL1_RO_BASE			TZROM_BASE
+#define BL1_RO_LIMIT			(TZROM_BASE + TZROM_SIZE)
+
+/*
+ * Put BL1 RW at the top of the Trusted SRAM. BL1_RW_BASE is calculated using
+ * the current BL1 RW debug size plus a little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+#define BL1_RW_BASE			(TZRAM_BASE + TZRAM_SIZE - 0x8000)
+#else
+#define BL1_RW_BASE			(TZRAM_BASE + TZRAM_SIZE - 0x6000)
+#endif
+#define BL1_RW_LIMIT			(TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
+ * size plus a little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+#define BL2_BASE			(BL31_BASE - 0x1D000)
+#else
+#define BL2_BASE			(BL31_BASE - 0xC000)
+#endif
+#define BL2_LIMIT			BL31_BASE
+
+/*******************************************************************************
+ * Load address of BL3-0 in the Juno port
+ * BL3-0 is loaded to the same place as BL3-1.  Once BL3-0 is transferred to the
+ * SCP, it is discarded and BL3-1 is loaded over the top.
+ ******************************************************************************/
+#define BL30_BASE			BL31_BASE
+
+/*******************************************************************************
+ * BL3-1 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
+ * current BL3-1 debug size plus a little space for growth.
+ */
+#define BL31_BASE			(TZRAM_BASE + TZRAM_SIZE - 0x1D000)
+#define BL31_PROGBITS_LIMIT		BL1_RW_BASE
+#define BL31_LIMIT			(TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * BL3-2 specific defines.
+ ******************************************************************************/
+
+/*
+ * The TSP can execute either from Trusted SRAM or Trusted DRAM.
+ */
+#define BL32_SRAM_BASE                  TZRAM_BASE
+#define BL32_SRAM_LIMIT                 BL31_BASE
+#define BL32_DRAM_BASE                  DRAM_SEC_BASE
+#define BL32_DRAM_LIMIT                 (DRAM_SEC_BASE + DRAM_SEC_SIZE)
+
+#if (PLAT_TSP_LOCATION_ID == PLAT_TRUSTED_SRAM_ID)
+# define TSP_SEC_MEM_BASE		TZRAM_BASE
+# define TSP_SEC_MEM_SIZE		TZRAM_SIZE
+# define BL32_BASE			BL32_SRAM_BASE
+# define BL32_LIMIT			BL32_SRAM_LIMIT
+//# define BL32_PROGBITS_LIMIT	BL2_BASE
+#elif (PLAT_TSP_LOCATION_ID == PLAT_DRAM_ID)
+# define TSP_SEC_MEM_BASE		DRAM_SEC_BASE
+# define TSP_SEC_MEM_SIZE		DRAM_SEC_SIZE
+# define BL32_BASE			BL32_DRAM_BASE
+# define BL32_LIMIT			BL32_DRAM_LIMIT
+#else
+# error "Unsupported PLAT_TSP_LOCATION_ID value"
+#endif
+
+/*******************************************************************************
+ * Load address of BL3-3 in the Juno port
+ ******************************************************************************/
+#define NS_IMAGE_OFFSET			0xE0000000
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define ADDR_SPACE_SIZE			(1ull << 32)
+
+#if IMAGE_BL1 || IMAGE_BL31
+# define MAX_XLAT_TABLES		3
+#endif
+
+#if IMAGE_BL2 || IMAGE_BL32
+# define MAX_XLAT_TABLES		3
+#endif
+
+#define MAX_MMAP_REGIONS		16
+
+/*******************************************************************************
+ * ID of the secure physical generic timer interrupt used by the TSP
+ ******************************************************************************/
+#define TSP_IRQ_SEC_PHY_TIMER		IRQ_SEC_PHY_TIMER
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT   6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+#if !USE_COHERENT_MEM
+/*******************************************************************************
+ * Size of the per-cpu data in bytes that should be reserved in the generic
+ * per-cpu data structure for the Juno port.
+ ******************************************************************************/
+#define PLAT_PCPU_DATA_SIZE	2
+#endif
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/juno/include/platform_oid.h b/uefi/arm-trusted-firmware/plat/juno/include/platform_oid.h
new file mode 100644
index 0000000..38aca12
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/include/platform_oid.h
@@ -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.
+ */
+
+#ifndef PLATFORM_OID_H_
+#define PLATFORM_OID_H_
+
+/*
+ * This is the list of the different extensions containing relevant information
+ * to establish the chain of trust.
+ *
+ * The OIDs shown here are just an example. Real OIDs should be obtained from
+ * the ITU-T.
+ */
+
+/* Non-volatile counter extensions */
+#define TZ_FW_NVCOUNTER_OID		"1.2.3.1"
+#define NTZ_FW_NVCOUNTER_OID		"1.2.3.2"
+
+/* BL2 extensions */
+#define BL2_HASH_OID			"1.2.3.3"
+
+/* Trusted Key extensions */
+#define TZ_WORLD_PK_OID			"1.2.3.4"
+#define NTZ_WORLD_PK_OID		"1.2.3.5"
+
+/* BL3-1 extensions */
+#define BL31_CONTENT_CERT_PK_OID	"1.2.3.6"
+#define BL31_HASH_OID			"1.2.3.7"
+
+/* BL3-0 extensions */
+#define BL30_CONTENT_CERT_PK_OID	"1.2.3.8"
+#define BL30_HASH_OID			"1.2.3.9"
+
+/* BL3-2 extensions */
+#define BL32_CONTENT_CERT_PK_OID	"1.2.3.10"
+#define BL32_HASH_OID			"1.2.3.11"
+
+/* BL3-3 extensions */
+#define BL33_CONTENT_CERT_PK_OID	"1.2.3.12"
+#define BL33_HASH_OID			"1.2.3.13"
+
+#endif /* PLATFORM_OID_H_ */
diff --git a/uefi/arm-trusted-firmware/plat/juno/juno_def.h b/uefi/arm-trusted-firmware/plat/juno/juno_def.h
new file mode 100644
index 0000000..8a85aec
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/juno_def.h
@@ -0,0 +1,247 @@
+/*
+ * 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 __JUNO_DEF_H__
+#define __JUNO_DEF_H__
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define JUNO_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
+
+/*******************************************************************************
+ * Juno memory map related constants
+ ******************************************************************************/
+#define FLASH_BASE		0x08000000
+#define FLASH_SIZE		0x04000000
+
+/* Bypass offset from start of NOR flash */
+#define BL1_ROM_BYPASS_OFFSET	0x03EC0000
+
+#ifndef TZROM_BASE
+/* Use the bypass address */
+#define TZROM_BASE		FLASH_BASE + BL1_ROM_BYPASS_OFFSET
+#endif
+/* Actual ROM size on Juno is 64 KB, but TBB requires at least 80 KB in debug
+ * mode. We can test TBB on Juno bypassing the ROM and using 128 KB of flash */
+#if TRUSTED_BOARD_BOOT
+#define TZROM_SIZE		0x00020000
+#else
+#define TZROM_SIZE		0x00010000
+#endif
+
+#define TZRAM_BASE		0x04001000
+#define TZRAM_SIZE		0x0003F000
+
+#define PLAT_TRUSTED_SRAM_ID	0
+#define PLAT_DRAM_ID		1
+
+#define MHU_SECURE_BASE		0x04000000
+#define MHU_SECURE_SIZE		0x00001000
+
+#define MHU_PAYLOAD_CACHED	0
+
+#define TRUSTED_MAILBOXES_BASE	MHU_SECURE_BASE
+#define TRUSTED_MAILBOX_SHIFT	4
+
+#define EMMC_BASE		0x0c000000
+#define EMMC_SIZE		0x04000000
+
+#define PSRAM_BASE		0x14000000
+#define PSRAM_SIZE		0x02000000
+
+#define IOFPGA_BASE		0x1c000000
+#define IOFPGA_SIZE		0x03000000
+
+#define NSROM_BASE		0x1f000000
+#define NSROM_SIZE		0x00001000
+
+/* Following covers Columbus Peripherals excluding NSROM and NSRAM  */
+#define DEVICE0_BASE		0x20000000
+#define DEVICE0_SIZE		0x0e000000
+#define MHU_BASE		0x2b1f0000
+
+#define NSRAM_BASE		0x2e000000
+#define NSRAM_SIZE		0x00008000
+
+/* Following covers Juno Peripherals and PCIe expansion area */
+#define DEVICE1_BASE		0x40000000
+#define DEVICE1_SIZE		0x40000000
+#define PCIE_CONTROL_BASE	0x7ff20000
+
+#define DRAM_BASE		0x80000000
+#define DRAM_SIZE		0x80000000
+
+/*
+ * DRAM at 0x8000_0000 is divided in two regions:
+ *   - Secure DRAM (default is the top 16MB except for the last 2MB, which are
+ *     used by the SCP for DDR retraining)
+ *   - Non-Secure DRAM (remaining DRAM starting at DRAM_BASE)
+ */
+
+#define DRAM_SCP_SIZE		0x00200000
+#define DRAM_SCP_BASE		(DRAM_BASE + DRAM_SIZE - DRAM_SCP_SIZE)
+
+#define DRAM_SEC_SIZE		0x00E00000
+#define DRAM_SEC_BASE		(DRAM_SCP_BASE - DRAM_SEC_SIZE)
+
+#define DRAM_NS_BASE		DRAM_BASE
+#define DRAM_NS_SIZE		(DRAM_SIZE - DRAM_SCP_SIZE - DRAM_SEC_SIZE)
+
+/* Second region of DRAM */
+#define DRAM2_BASE		0x880000000
+#define DRAM2_SIZE		0x180000000
+
+/* Memory mapped Generic timer interfaces  */
+#define SYS_CNTCTL_BASE		0x2a430000
+#define SYS_CNTREAD_BASE	0x2a800000
+#define SYS_TIMCTL_BASE		0x2a810000
+
+/* V2M motherboard system registers & offsets */
+#define VE_SYSREGS_BASE		0x1c010000
+#define V2M_SYS_LED		0x8
+
+/*
+ * V2M sysled bit definitions. The values written to this
+ * register are defined in arch.h & runtime_svc.h. Only
+ * used by the primary cpu to diagnose any cold boot issues.
+ *
+ * SYS_LED[0]   - Security state (S=0/NS=1)
+ * SYS_LED[2:1] - Exception Level (EL3-EL0)
+ * SYS_LED[7:3] - Exception Class (Sync/Async & origin)
+ *
+ */
+#define SYS_LED_SS_SHIFT		0x0
+#define SYS_LED_EL_SHIFT		0x1
+#define SYS_LED_EC_SHIFT		0x3
+
+/*******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+#define GICD_BASE			0x2c010000
+#define GICC_BASE			0x2c02f000
+#define GICH_BASE			0x2c04f000
+#define GICV_BASE			0x2c06f000
+
+#define IRQ_MHU			69
+#define IRQ_GPU_SMMU_0		71
+#define IRQ_GPU_SMMU_1		73
+#define IRQ_ETR_SMMU		75
+#define IRQ_TZC400		80
+#define IRQ_TZ_WDOG		86
+
+#define IRQ_SEC_PHY_TIMER		29
+#define IRQ_SEC_SGI_0			8
+#define IRQ_SEC_SGI_1			9
+#define IRQ_SEC_SGI_2			10
+#define IRQ_SEC_SGI_3			11
+#define IRQ_SEC_SGI_4			12
+#define IRQ_SEC_SGI_5			13
+#define IRQ_SEC_SGI_6			14
+#define IRQ_SEC_SGI_7			15
+
+/*******************************************************************************
+ * PL011 related constants
+ ******************************************************************************/
+/* FPGA UART0 */
+#define PL011_UART0_BASE		0x1c090000
+/* FPGA UART1 */
+#define PL011_UART1_BASE		0x1c0a0000
+/* SoC UART0 */
+#define PL011_UART2_BASE		0x7ff80000
+/* SoC UART1 */
+#define PL011_UART3_BASE		0x7ff70000
+
+#define PL011_BAUDRATE			115200
+
+#define PL011_UART0_CLK_IN_HZ		24000000
+#define PL011_UART1_CLK_IN_HZ		24000000
+#define PL011_UART2_CLK_IN_HZ		7273800
+#define PL011_UART3_CLK_IN_HZ		7273800
+
+/*******************************************************************************
+ * NIC-400 related constants
+ ******************************************************************************/
+
+/* CSS NIC-400 Global Programmers View (GPV) */
+#define CSS_NIC400_BASE		0x2a000000
+
+/* The slave_bootsecure controls access to GPU, DMC and CS. */
+#define CSS_NIC400_SLAVE_BOOTSECURE		8
+
+/* SoC NIC-400 Global Programmers View (GPV) */
+#define SOC_NIC400_BASE		0x7fd00000
+
+#define SOC_NIC400_USB_EHCI	0
+#define SOC_NIC400_TLX_MASTER	1
+#define SOC_NIC400_USB_OHCI	2
+#define SOC_NIC400_PL354_SMC	3
+/*
+ * The apb4_bridge controls access to:
+ *   - the PCIe configuration registers
+ *   - the MMU units for USB, HDLCD and DMA
+ */
+#define SOC_NIC400_APB4_BRIDGE	4
+/*
+ * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs.
+ */
+#define SOC_NIC400_BOOTSEC_BRIDGE		5
+#define SOC_NIC400_BOOTSEC_BRIDGE_UART1         (1 << 12)
+
+/*******************************************************************************
+ * TZC-400 related constants
+ ******************************************************************************/
+#define TZC400_BASE		0x2a4a0000
+
+#define TZC400_NSAID_CCI400	0  /* Note: Same as default NSAID!! */
+#define TZC400_NSAID_PCIE	1
+#define TZC400_NSAID_HDLCD0	2
+#define TZC400_NSAID_HDLCD1	3
+#define TZC400_NSAID_USB	4
+#define TZC400_NSAID_DMA330	5
+#define TZC400_NSAID_THINLINKS	6
+#define TZC400_NSAID_AP		9
+#define TZC400_NSAID_GPU	10
+#define TZC400_NSAID_SCP	11
+#define TZC400_NSAID_CORESIGHT	12
+
+/*******************************************************************************
+ * CCI-400 related constants
+ ******************************************************************************/
+#define CCI400_BASE			0x2c090000
+#define CCI400_SL_IFACE3_CLUSTER_IX	1
+#define CCI400_SL_IFACE4_CLUSTER_IX	0
+
+/*******************************************************************************
+ * SCP <=> AP boot configuration
+ ******************************************************************************/
+#define SCP_BOOT_CFG_ADDR	0x04000080
+#define PRIMARY_CPU_SHIFT	8
+#define PRIMARY_CPU_MASK	0xf
+
+#endif /* __JUNO_DEF_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/juno/juno_private.h b/uefi/arm-trusted-firmware/plat/juno/juno_private.h
new file mode 100644
index 0000000..70439e8
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/juno_private.h
@@ -0,0 +1,215 @@
+/*
+ * 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 __JUNO_PRIVATE_H__
+#define __JUNO_PRIVATE_H__
+
+#include <bakery_lock.h>
+#include <bl_common.h>
+#include <cpu_data.h>
+#include <platform_def.h>
+#include <stdint.h>
+
+/*******************************************************************************
+ * Forward declarations
+ ******************************************************************************/
+struct plat_pm_ops;
+struct meminfo;
+struct bl31_params;
+struct image_info;
+struct entry_point_info;
+
+/*******************************************************************************
+ * This structure represents the superset of information that is passed to
+ * BL3-1 e.g. while passing control to it from BL2 which is bl31_params
+ * and other platform specific params
+ ******************************************************************************/
+typedef struct bl2_to_bl31_params_mem {
+	struct bl31_params bl31_params;
+	struct image_info bl31_image_info;
+	struct image_info bl32_image_info;
+	struct image_info bl33_image_info;
+	struct entry_point_info bl33_ep_info;
+	struct entry_point_info bl32_ep_info;
+	struct entry_point_info bl31_ep_info;
+} bl2_to_bl31_params_mem_t;
+
+#if IMAGE_BL31
+#if USE_COHERENT_MEM
+/*
+ * These are wrapper macros to the Coherent Memory Bakery Lock API.
+ */
+#define juno_lock_init(_lock_arg)		bakery_lock_init(_lock_arg)
+#define juno_lock_get(_lock_arg)		bakery_lock_get(_lock_arg)
+#define juno_lock_release(_lock_arg)		bakery_lock_release(_lock_arg)
+
+#else
+
+/*******************************************************************************
+ * Constants that specify how many bakeries this platform implements and bakery
+ * ids.
+ ******************************************************************************/
+#define JUNO_MAX_BAKERIES	1
+#define JUNO_MHU_BAKERY_ID	0
+
+/*******************************************************************************
+ * Definition of structure which holds platform specific per-cpu data. Currently
+ * it holds only the bakery lock information for each cpu. Constants to specify
+ * how many bakeries this platform implements and bakery ids are specified in
+ * juno_def.h
+ ******************************************************************************/
+typedef struct juno_cpu_data {
+	bakery_info_t pcpu_bakery_info[JUNO_MAX_BAKERIES];
+} juno_cpu_data_t;
+
+/* Macro to define the offset of bakery_info_t in juno_cpu_data_t */
+#define JUNO_CPU_DATA_LOCK_OFFSET	__builtin_offsetof\
+					    (juno_cpu_data_t, pcpu_bakery_info)
+
+/*******************************************************************************
+ * Helper macros for bakery lock api when using the above juno_cpu_data_t for
+ * bakery lock data structures. It assumes that the bakery_info is at the
+ * beginning of the platform specific per-cpu data.
+ ******************************************************************************/
+#define juno_lock_init(_lock_arg)		/* No init required */
+#define juno_lock_get(_lock_arg)		bakery_lock_get(_lock_arg,	\
+						    CPU_DATA_PLAT_PCPU_OFFSET + \
+						    JUNO_CPU_DATA_LOCK_OFFSET)
+#define juno_lock_release(_lock_arg)		bakery_lock_release(_lock_arg,	\
+						    CPU_DATA_PLAT_PCPU_OFFSET + \
+						    JUNO_CPU_DATA_LOCK_OFFSET)
+
+/*
+ * Ensure that the size of the Juno specific per-cpu data structure and the size
+ * of the memory allocated in generic per-cpu data for the platform are the same.
+ */
+CASSERT(PLAT_PCPU_DATA_SIZE == sizeof(juno_cpu_data_t),	\
+	juno_pcpu_data_size_mismatch);
+#endif /* __USE_COHERENT_MEM__ */
+#else
+/*
+ * Dummy wrapper macros for all other BL stages other than BL3-1
+ */
+#define juno_lock_init(_lock_arg)
+#define juno_lock_get(_lock_arg)
+#define juno_lock_release(_lock_arg)
+
+#endif /* __IMAGE_BL31__ */
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void bl1_plat_arch_setup(void);
+void bl2_plat_arch_setup(void);
+void bl31_plat_arch_setup(void);
+int platform_setup_pm(const struct plat_pm_ops **plat_ops);
+unsigned int platform_get_core_pos(unsigned long mpidr);
+void configure_mmu_el1(unsigned long total_base,
+		       unsigned long total_size,
+		       unsigned long ro_start,
+		       unsigned long ro_limit
+#if USE_COHERENT_MEM
+		       , unsigned long coh_start,
+		       unsigned long coh_limit
+#endif
+		       );
+void configure_mmu_el3(unsigned long total_base,
+		       unsigned long total_size,
+		       unsigned long ro_start,
+		       unsigned long ro_limit
+#if USE_COHERENT_MEM
+		       , unsigned long coh_start,
+		       unsigned long coh_limit
+#endif
+		       );
+void plat_report_exception(unsigned long type);
+unsigned long plat_get_ns_image_entrypoint(void);
+unsigned long platform_get_stack(unsigned long mpidr);
+uint64_t plat_get_syscnt_freq(void);
+void plat_gic_init(void);
+
+/* Declarations for plat_topology.c */
+int plat_setup_topology(void);
+int plat_get_max_afflvl(void);
+unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr);
+unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr);
+
+/* Declarations for plat_io_storage.c */
+void io_setup(void);
+int plat_get_image_source(const char *image_name,
+			  uintptr_t *dev_handle,
+			  uintptr_t *image_spec);
+
+/* Declarations for security.c */
+void plat_security_setup(void);
+
+/*
+ * Before calling this function BL2 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL2 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ */
+void bl1_plat_set_bl2_ep_info(struct image_info *image,
+			      struct entry_point_info *ep);
+
+/*
+ * Before calling this function BL3-1 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL3-1 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ */
+void bl2_plat_set_bl31_ep_info(struct image_info *image,
+			       struct entry_point_info *ep);
+
+/*
+ * Before calling this function BL3-2 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL3-2 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ */
+void bl2_plat_set_bl32_ep_info(struct image_info *image,
+			       struct entry_point_info *ep);
+
+/*
+ * Before calling this function BL3-3 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL3-3 and set SPSR and security state.
+ * On Juno we are only setting the security state, entrypoint
+ */
+void bl2_plat_set_bl33_ep_info(struct image_info *image,
+			       struct entry_point_info *ep);
+
+/* Gets the memory layout for BL3-2 */
+void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info);
+
+/* Gets the memory layout for BL3-3 */
+void bl2_plat_get_bl33_meminfo(struct meminfo *mem_info);
+
+#endif /* __JUNO_PRIVATE_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/juno/juno_trusted_boot.c b/uefi/arm-trusted-firmware/plat/juno/juno_trusted_boot.c
new file mode 100644
index 0000000..e63d4b2
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/juno_trusted_boot.c
@@ -0,0 +1,45 @@
+/*
+ * 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 <debug.h>
+#include "juno_def.h"
+#include "juno_private.h"
+
+/*
+ * Check the validity of the key
+ *
+ * 0 = success, Otherwise = error
+ */
+int plat_match_rotpk(const unsigned char *key_buf, unsigned int key_len)
+{
+	/* TODO: check against the ROT key stored in the platform */
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/mhu.c b/uefi/arm-trusted-firmware/plat/juno/mhu.c
new file mode 100644
index 0000000..c1c414c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/mhu.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <bakery_lock.h>
+#include <mmio.h>
+#include "juno_def.h"
+#include "juno_private.h"
+#include "mhu.h"
+
+/* SCP MHU secure channel registers */
+#define SCP_INTR_S_STAT		0x200
+#define SCP_INTR_S_SET		0x208
+#define SCP_INTR_S_CLEAR	0x210
+
+/* CPU MHU secure channel registers */
+#define CPU_INTR_S_STAT		0x300
+#define CPU_INTR_S_SET		0x308
+#define CPU_INTR_S_CLEAR	0x310
+
+#if IMAGE_BL31
+#if USE_COHERENT_MEM
+static bakery_lock_t mhu_secure_lock __attribute__ ((section("tzfw_coherent_mem")));
+#define LOCK_ARG		&mhu_secure_lock
+#else
+#define LOCK_ARG		JUNO_MHU_BAKERY_ID
+#endif /*__USE_COHERENT_MEM__ */
+#else
+#define LOCK_ARG	/* Locks required only for BL3-1 images */
+#endif /* __IMAGE_BL31__ */
+
+void mhu_secure_message_start(void)
+{
+	juno_lock_get(LOCK_ARG);
+
+	/* Make sure any previous command has finished */
+	while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
+		;
+}
+
+void mhu_secure_message_send(uint32_t command)
+{
+	/* Send command to SCP and wait for it to pick it up */
+	mmio_write_32(MHU_BASE + CPU_INTR_S_SET, command);
+	while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
+		;
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+	/* Wait for response from SCP */
+	uint32_t response;
+	while (!(response = mmio_read_32(MHU_BASE + SCP_INTR_S_STAT)))
+		;
+
+	return response;
+}
+
+void mhu_secure_message_end(void)
+{
+	/* Clear any response we got by writing all ones to the CLEAR register */
+	mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 0xffffffffu);
+
+	juno_lock_release(LOCK_ARG);
+}
+
+void mhu_secure_init(void)
+{
+	juno_lock_init(LOCK_ARG);
+
+	/*
+	 * Clear the CPU's INTR register to make sure we don't see a stale
+	 * or garbage value and think it's a message we've already sent.
+	 */
+	mmio_write_32(MHU_BASE + CPU_INTR_S_CLEAR, 0xffffffffu);
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/mhu.h b/uefi/arm-trusted-firmware/plat/juno/mhu.h
new file mode 100644
index 0000000..5149c82
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/mhu.h
@@ -0,0 +1,43 @@
+/*
+ * 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 __MHU_H__
+#define __MHU_H__
+
+#include <stdint.h>
+
+extern void mhu_secure_message_start(void);
+extern void mhu_secure_message_send(uint32_t command);
+extern uint32_t mhu_secure_message_wait(void);
+extern void mhu_secure_message_end(void);
+
+extern void mhu_secure_init(void);
+
+#endif	/* __MHU_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/juno/plat-tsp.ld.S b/uefi/arm-trusted-firmware/plat/juno/plat-tsp.ld.S
new file mode 100644
index 0000000..16d6c17
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/plat-tsp.ld.S
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+    ASSERT(__BL32_END__ <= BL2_BASE, "BL3-2 image overlaps BL2 image.")
diff --git a/uefi/arm-trusted-firmware/plat/juno/plat_io_storage.c b/uefi/arm-trusted-firmware/plat/juno/plat_io_storage.c
new file mode 100644
index 0000000..b31865e
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/plat_io_storage.c
@@ -0,0 +1,311 @@
+/*
+ * 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 <debug.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <platform_def.h>
+#include <semihosting.h>	/* For FOPEN_MODE_... */
+#include <string.h>
+
+/* IO devices */
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_spec;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_spec;
+static uintptr_t memmap_init_params;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fip_block_spec = {
+	.offset = FLASH_BASE,
+	.length = FLASH_SIZE
+};
+
+static const io_file_spec_t bl2_file_spec = {
+	.path = BL2_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_file_spec = {
+	.path = BL30_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_file_spec = {
+	.path = BL31_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_file_spec = {
+	.path = BL32_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_file_spec = {
+	.path = BL33_IMAGE_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+#if TRUSTED_BOARD_BOOT
+static const io_file_spec_t bl2_cert_file_spec = {
+	.path = BL2_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t trusted_key_cert_file_spec = {
+	.path = TRUSTED_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_key_cert_file_spec = {
+	.path = BL30_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_key_cert_file_spec = {
+	.path = BL31_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_key_cert_file_spec = {
+	.path = BL32_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_key_cert_file_spec = {
+	.path = BL33_KEY_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl30_cert_file_spec = {
+	.path = BL30_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl31_cert_file_spec = {
+	.path = BL31_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl32_cert_file_spec = {
+	.path = BL32_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+
+static const io_file_spec_t bl33_cert_file_spec = {
+	.path = BL33_CERT_NAME,
+	.mode = FOPEN_MODE_RB
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
+static int open_fip(const uintptr_t spec);
+static int open_memmap(const uintptr_t spec);
+
+struct plat_io_policy {
+	const char *image_name;
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+	{
+		FIP_IMAGE_NAME,
+		&memmap_dev_handle,
+		(uintptr_t)&fip_block_spec,
+		open_memmap
+	}, {
+		BL2_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl2_file_spec,
+		open_fip
+	}, {
+		BL30_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl30_file_spec,
+		open_fip
+	}, {
+		BL31_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl31_file_spec,
+		open_fip
+	}, {
+		BL32_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl32_file_spec,
+		open_fip
+	}, {
+		BL33_IMAGE_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl33_file_spec,
+		open_fip
+	}, {
+#if TRUSTED_BOARD_BOOT
+		BL2_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl2_cert_file_spec,
+		open_fip
+	}, {
+		TRUSTED_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&trusted_key_cert_file_spec,
+		open_fip
+	}, {
+		BL30_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl30_key_cert_file_spec,
+		open_fip
+	}, {
+		BL31_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl31_key_cert_file_spec,
+		open_fip
+	}, {
+		BL32_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl32_key_cert_file_spec,
+		open_fip
+	}, {
+		BL33_KEY_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl33_key_cert_file_spec,
+		open_fip
+	}, {
+		BL30_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl30_cert_file_spec,
+		open_fip
+	}, {
+		BL31_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl31_cert_file_spec,
+		open_fip
+	}, {
+		BL32_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl32_cert_file_spec,
+		open_fip
+	}, {
+		BL33_CERT_NAME,
+		&fip_dev_handle,
+		(uintptr_t)&bl33_cert_file_spec,
+		open_fip
+	}, {
+#endif /* TRUSTED_BOARD_BOOT */
+		0, 0, 0
+	}
+};
+
+
+static int open_fip(const uintptr_t spec)
+{
+	int result = IO_FAIL;
+
+	/* See if a Firmware Image Package is available */
+	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME);
+	if (result == IO_SUCCESS) {
+		INFO("Using FIP\n");
+		/*TODO: Check image defined in spec is present in FIP. */
+	}
+	return result;
+}
+
+
+static int open_memmap(const uintptr_t spec)
+{
+	int result = IO_FAIL;
+	uintptr_t local_image_handle;
+
+	result = io_dev_init(memmap_dev_handle, memmap_init_params);
+	if (result == IO_SUCCESS) {
+		result = io_open(memmap_dev_handle, spec, &local_image_handle);
+		if (result == IO_SUCCESS) {
+			/* INFO("Using Memmap IO\n"); */
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+void io_setup(void)
+{
+	int io_result = IO_FAIL;
+
+	/* Register the IO devices on this platform */
+	io_result = register_io_dev_fip(&fip_dev_con);
+	assert(io_result == IO_SUCCESS);
+
+	io_result = register_io_dev_memmap(&memmap_dev_con);
+	assert(io_result == IO_SUCCESS);
+
+	/* Open connections to devices and cache the handles */
+	io_result = io_dev_open(fip_dev_con, fip_dev_spec, &fip_dev_handle);
+	assert(io_result == IO_SUCCESS);
+
+	io_result = io_dev_open(memmap_dev_con, memmap_dev_spec,
+				&memmap_dev_handle);
+	assert(io_result == IO_SUCCESS);
+
+	/* Ignore improbable errors in release builds */
+	(void)io_result;
+}
+
+
+/* Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy */
+int plat_get_image_source(const char *image_name, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	int result = IO_FAIL;
+	const struct plat_io_policy *policy;
+
+	if ((image_name != NULL) && (dev_handle != NULL) &&
+	    (image_spec != NULL)) {
+		policy = policies;
+		while (policy->image_name != NULL) {
+			if (strcmp(policy->image_name, image_name) == 0) {
+				result = policy->check(policy->image_spec);
+				if (result == IO_SUCCESS) {
+					*image_spec = policy->image_spec;
+					*dev_handle = *(policy->dev_handle);
+					break;
+				}
+			}
+			policy++;
+		}
+	} else {
+		result = IO_FAIL;
+	}
+	return result;
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/plat_pm.c b/uefi/arm-trusted-firmware/plat/juno/plat_pm.c
new file mode 100644
index 0000000..47338cf
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/plat_pm.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2013, 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 <arch_helpers.h>
+#include <arm_gic.h>
+#include <debug.h>
+#include <cci400.h>
+#include <errno.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <psci.h>
+#include "juno_def.h"
+#include "juno_private.h"
+#include "scpi.h"
+
+/*******************************************************************************
+ * Private Juno function to program the mailbox for a cpu before it is released
+ * from reset.
+ ******************************************************************************/
+static void juno_program_mailbox(uint64_t mpidr, uint64_t address)
+{
+	uint64_t linear_id;
+	uint64_t mbox;
+
+	linear_id = platform_get_core_pos(mpidr);
+	mbox = TRUSTED_MAILBOXES_BASE +	(linear_id << TRUSTED_MAILBOX_SHIFT);
+	*((uint64_t *) mbox) = address;
+	flush_dcache_range(mbox, sizeof(mbox));
+}
+
+/*******************************************************************************
+ * Private Juno function which is used to determine if any platform actions
+ * should be performed for the specified affinity instance given its
+ * state. Nothing needs to be done if the 'state' is not off or if this is not
+ * the highest affinity level which will enter the 'state'.
+ ******************************************************************************/
+static int32_t juno_do_plat_actions(uint32_t afflvl, uint32_t state)
+{
+	uint32_t max_phys_off_afflvl;
+
+	assert(afflvl <= MPIDR_AFFLVL1);
+
+	if (state != PSCI_STATE_OFF)
+		return -EAGAIN;
+
+	/*
+	 * Find the highest affinity level which will be suspended and postpone
+	 * all the platform specific actions until that level is hit.
+	 */
+	max_phys_off_afflvl = psci_get_max_phys_off_afflvl();
+	assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
+	assert(psci_get_suspend_afflvl() >= max_phys_off_afflvl);
+	if (afflvl != max_phys_off_afflvl)
+		return -EAGAIN;
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Juno handler called to check the validity of the power state parameter.
+ ******************************************************************************/
+int32_t juno_validate_power_state(unsigned int power_state)
+{
+	/* Sanity check the requested state */
+	if (psci_get_pstate_type(power_state) == PSTATE_TYPE_STANDBY) {
+		/*
+		 * It's possible to enter standby only on affinity level 0 i.e.
+		 * a cpu on the Juno. Ignore any other affinity level.
+		 */
+		if (psci_get_pstate_afflvl(power_state) != MPIDR_AFFLVL0)
+			return PSCI_E_INVALID_PARAMS;
+	}
+
+	/*
+	 * We expect the 'state id' to be zero.
+	 */
+	if (psci_get_pstate_id(power_state))
+		return PSCI_E_INVALID_PARAMS;
+
+	return PSCI_E_SUCCESS;
+}
+
+
+/*******************************************************************************
+ * Juno handler called when an affinity instance is about to be turned on. The
+ * level and mpidr determine the affinity instance.
+ ******************************************************************************/
+int32_t juno_affinst_on(uint64_t mpidr,
+			uint64_t sec_entrypoint,
+			uint32_t afflvl,
+			uint32_t state)
+{
+	/*
+	 * SCP takes care of powering up higher affinity levels so we
+	 * only need to care about level 0
+	 */
+	if (afflvl != MPIDR_AFFLVL0)
+		return PSCI_E_SUCCESS;
+
+	/*
+	 * Setup mailbox with address for CPU entrypoint when it next powers up
+	 */
+	juno_program_mailbox(mpidr, sec_entrypoint);
+
+	scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on,
+				 scpi_power_on);
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Juno handler called when an affinity instance has just been powered on after
+ * being turned off earlier. The level and mpidr determine the affinity
+ * instance. The 'state' arg. allows the platform to decide whether the cluster
+ * was turned off prior to wakeup and do what's necessary to setup it up
+ * correctly.
+ ******************************************************************************/
+void juno_affinst_on_finish(uint32_t afflvl, uint32_t state)
+{
+	unsigned long mpidr;
+
+	/* Determine if any platform actions need to be executed. */
+	if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
+		return;
+
+	/* Get the mpidr for this cpu */
+	mpidr = read_mpidr_el1();
+
+	/*
+	 * Perform the common cluster specific operations i.e enable coherency
+	 * if this cluster was off.
+	 */
+	if (afflvl != MPIDR_AFFLVL0)
+		cci_enable_cluster_coherency(mpidr);
+
+
+	/* Enable the gic cpu interface */
+	arm_gic_cpuif_setup();
+
+	/* Juno todo: Is this setup only needed after a cold boot? */
+	arm_gic_pcpu_distif_setup();
+
+	/* Clear the mailbox for this cpu. */
+	juno_program_mailbox(mpidr, 0);
+}
+
+/*******************************************************************************
+ * Common function called while turning a cpu off or suspending it. It is called
+ * from juno_off() or juno_suspend() when these functions in turn are called for
+ * the highest affinity level which will be powered down. It performs the
+ * actions common to the OFF and SUSPEND calls.
+ ******************************************************************************/
+static void juno_power_down_common(uint32_t afflvl)
+{
+	uint32_t cluster_state = scpi_power_on;
+
+	/* Prevent interrupts from spuriously waking up this cpu */
+	arm_gic_cpuif_deactivate();
+
+	/* Cluster is to be turned off, so disable coherency */
+	if (afflvl > MPIDR_AFFLVL0) {
+		cci_disable_cluster_coherency(read_mpidr_el1());
+		cluster_state = scpi_power_off;
+	}
+
+	/*
+	 * Ask the SCP to power down the appropriate components depending upon
+	 * their state.
+	 */
+	scpi_set_css_power_state(read_mpidr_el1(),
+				 scpi_power_off,
+				 cluster_state,
+				 scpi_power_on);
+}
+
+/*******************************************************************************
+ * Handler called when an affinity instance is about to be turned off. The
+ * level and mpidr determine the affinity instance. The 'state' arg. allows the
+ * platform to decide whether the cluster is being turned off and take
+ * appropriate actions.
+ *
+ * CAUTION: There is no guarantee that caches will remain turned on across calls
+ * to this function as each affinity level is dealt with. So do not write & read
+ * global variables across calls. It will be wise to do flush a write to the
+ * global to prevent unpredictable results.
+ ******************************************************************************/
+static void juno_affinst_off(uint32_t afflvl, uint32_t state)
+{
+	/* Determine if any platform actions need to be executed */
+	if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
+		return;
+
+	juno_power_down_common(afflvl);
+}
+
+/*******************************************************************************
+ * Handler called when an affinity instance is about to be suspended. The
+ * level and mpidr determine the affinity instance. The 'state' arg. allows the
+ * platform to decide whether the cluster is being turned off and take apt
+ * actions. The 'sec_entrypoint' determines the address in BL3-1 from where
+ * execution should resume.
+ *
+ * CAUTION: There is no guarantee that caches will remain turned on across calls
+ * to this function as each affinity level is dealt with. So do not write & read
+ * global variables across calls. It will be wise to do flush a write to the
+ * global to prevent unpredictable results.
+ ******************************************************************************/
+static void juno_affinst_suspend(uint64_t sec_entrypoint,
+				    uint32_t afflvl,
+				    uint32_t state)
+{
+	/* Determine if any platform actions need to be executed */
+	if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
+		return;
+
+	/*
+	 * Setup mailbox with address for CPU entrypoint when it next powers up.
+	 */
+	juno_program_mailbox(read_mpidr_el1(), sec_entrypoint);
+
+	juno_power_down_common(afflvl);
+}
+
+/*******************************************************************************
+ * Juno handler called when an affinity instance has just been powered on after
+ * having been suspended earlier. The level and mpidr determine the affinity
+ * instance.
+ * TODO: At the moment we reuse the on finisher and reinitialize the secure
+ * context. Need to implement a separate suspend finisher.
+ ******************************************************************************/
+static void juno_affinst_suspend_finish(uint32_t afflvl,
+					   uint32_t state)
+{
+	juno_affinst_on_finish(afflvl, state);
+}
+
+/*******************************************************************************
+ * Juno handlers to shutdown/reboot the system
+ ******************************************************************************/
+static void __dead2 juno_system_off(void)
+{
+	uint32_t response;
+
+	/* Send the power down request to the SCP */
+	response = scpi_sys_power_state(scpi_system_shutdown);
+
+	if (response != SCP_OK) {
+		ERROR("Juno System Off: SCP error %u.\n", response);
+		panic();
+	}
+	wfi();
+	ERROR("Juno System Off: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 juno_system_reset(void)
+{
+	uint32_t response;
+
+	/* Send the system reset request to the SCP */
+	response = scpi_sys_power_state(scpi_system_reboot);
+
+	if (response != SCP_OK) {
+		ERROR("Juno System Reset: SCP error %u.\n", response);
+		panic();
+	}
+	wfi();
+	ERROR("Juno System Reset: operation not handled.\n");
+	panic();
+}
+
+/*******************************************************************************
+ * Handler called when an affinity instance is about to enter standby.
+ ******************************************************************************/
+void juno_affinst_standby(unsigned int power_state)
+{
+	unsigned int scr;
+
+	scr = read_scr_el3();
+	/* Enable PhysicalIRQ bit for NS world to wake the CPU */
+	write_scr_el3(scr | SCR_IRQ_BIT);
+	isb();
+	dsb();
+	wfi();
+
+	/*
+	 * Restore SCR to the original value, synchronisation of scr_el3 is
+	 * done by eret while el3_exit to save some execution cycles.
+	 */
+	write_scr_el3(scr);
+}
+
+/*******************************************************************************
+ * Export the platform handlers to enable psci to invoke them
+ ******************************************************************************/
+static const plat_pm_ops_t juno_ops = {
+	.affinst_on		= juno_affinst_on,
+	.affinst_on_finish	= juno_affinst_on_finish,
+	.affinst_off		= juno_affinst_off,
+	.affinst_standby	= juno_affinst_standby,
+	.affinst_suspend	= juno_affinst_suspend,
+	.affinst_suspend_finish	= juno_affinst_suspend_finish,
+	.system_off		= juno_system_off,
+	.system_reset		= juno_system_reset,
+	.validate_power_state	= juno_validate_power_state
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int32_t platform_setup_pm(const plat_pm_ops_t **plat_ops)
+{
+	*plat_ops = &juno_ops;
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/plat_security.c b/uefi/arm-trusted-firmware/plat/juno/plat_security.c
new file mode 100644
index 0000000..64e493f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/plat_security.c
@@ -0,0 +1,104 @@
+/*
+ * 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 <tzc400.h>
+#include "juno_def.h"
+
+/*******************************************************************************
+ * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access
+ * and allow Non-Secure masters full access
+ ******************************************************************************/
+static void init_tzc400(void)
+{
+	tzc_init(TZC400_BASE);
+
+	/* Disable filters. */
+	tzc_disable_filters();
+
+	/* Region 1 set to cover Non-Secure DRAM at 0x8000_0000. Apply the
+	 * same configuration to all filters in the TZC. */
+	tzc_configure_region(REG_ATTR_FILTER_BIT_ALL, 1,
+			DRAM_NS_BASE, DRAM_NS_BASE + DRAM_NS_SIZE - 1,
+			TZC_REGION_S_NONE,
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CCI400)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_PCIE)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD0)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD1)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_USB)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_DMA330)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_THINLINKS)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_AP)		|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT));
+
+	/* Region 2 set to cover Secure DRAM */
+	tzc_configure_region(REG_ATTR_FILTER_BIT_ALL, 2,
+			DRAM_SEC_BASE, DRAM_SEC_BASE + DRAM_SEC_SIZE - 1,
+			TZC_REGION_S_RDWR,
+			0);
+
+	/* Region 3 set to cover DRAM used by SCP for DDR retraining */
+	tzc_configure_region(REG_ATTR_FILTER_BIT_ALL, 3,
+			DRAM_SCP_BASE, DRAM_SCP_BASE + DRAM_SCP_SIZE - 1,
+			TZC_REGION_S_NONE,
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_SCP));
+
+	/* Region 4 set to cover Non-Secure DRAM at 0x8_8000_0000 */
+	tzc_configure_region(REG_ATTR_FILTER_BIT_ALL, 4,
+			DRAM2_BASE, DRAM2_BASE + DRAM2_SIZE - 1,
+			TZC_REGION_S_NONE,
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CCI400)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_PCIE)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD0)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD1)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_USB)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_DMA330)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_THINLINKS)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_AP)		|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU)	|
+			TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT));
+
+	/* Raise an exception if a NS device tries to access secure memory */
+	tzc_set_action(TZC_ACTION_ERR);
+
+	/* Enable filters. */
+	tzc_enable_filters();
+}
+
+/*******************************************************************************
+ * Initialize the secure environment. At this moment only the TrustZone
+ * Controller is initialized.
+ ******************************************************************************/
+void plat_security_setup(void)
+{
+	/* Initialize the TrustZone Controller */
+	init_tzc400();
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/plat_topology.c b/uefi/arm-trusted-firmware/plat/juno/plat_topology.c
new file mode 100644
index 0000000..39d4dab
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/plat_topology.c
@@ -0,0 +1,60 @@
+/*
+ * 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 <platform_def.h>
+#include <psci.h>
+
+unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr)
+{
+	/* Report 1 (absent) instance at levels higher that the cluster level */
+	if (aff_lvl > MPIDR_AFFLVL1)
+		return 1;
+
+	if (aff_lvl == MPIDR_AFFLVL1)
+		return 2; /* We have two clusters */
+
+	return mpidr & 0x100 ? 4 : 2; /* 4 cpus in cluster 1, 2 in cluster 0 */
+}
+
+unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr)
+{
+	return aff_lvl <= MPIDR_AFFLVL1 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT;
+}
+
+int plat_get_max_afflvl()
+{
+	return MPIDR_AFFLVL1;
+}
+
+int plat_setup_topology()
+{
+	/* Juno todo: Make topology configurable via SCC */
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/platform.mk b/uefi/arm-trusted-firmware/plat/juno/platform.mk
new file mode 100644
index 0000000..8beaecf
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/platform.mk
@@ -0,0 +1,111 @@
+#
+# 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.
+#
+
+# On Juno, the Secure Payload can be loaded either in Trusted SRAM (default) or
+# Secure DRAM allocated by the TrustZone Controller.
+
+PLAT_TSP_LOCATION	:=	tsram
+
+ifeq (${PLAT_TSP_LOCATION}, tsram)
+  PLAT_TSP_LOCATION_ID := PLAT_TRUSTED_SRAM_ID
+else ifeq (${PLAT_TSP_LOCATION}, dram)
+  PLAT_TSP_LOCATION_ID := PLAT_DRAM_ID
+else
+  $(error "Unsupported PLAT_TSP_LOCATION value")
+endif
+
+# Process flags
+$(eval $(call add_define,PLAT_TSP_LOCATION_ID))
+
+
+PLAT_INCLUDES		:=	-Iplat/juno/include/
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/arm/pl011/pl011_console.S	\
+				drivers/io/io_fip.c			\
+				drivers/io/io_memmap.c			\
+				drivers/io/io_storage.c			\
+				lib/aarch64/xlat_tables.c		\
+				plat/common/aarch64/plat_common.c	\
+				plat/common/plat_gic.c			\
+				plat/juno/plat_io_storage.c
+
+BL1_SOURCES		+=	drivers/arm/cci400/cci400.c		\
+				lib/cpus/aarch64/cortex_a53.S		\
+				lib/cpus/aarch64/cortex_a57.S		\
+				plat/common/aarch64/platform_up_stack.S	\
+				plat/juno/bl1_plat_setup.c		\
+				plat/juno/aarch64/bl1_plat_helpers.S	\
+				plat/juno/aarch64/plat_helpers.S	\
+				plat/juno/aarch64/juno_common.c
+
+BL2_SOURCES		+=	drivers/arm/tzc400/tzc400.c		\
+				plat/common/aarch64/platform_up_stack.S	\
+				plat/juno/bl2_plat_setup.c		\
+				plat/juno/mhu.c				\
+				plat/juno/plat_security.c		\
+				plat/juno/aarch64/plat_helpers.S	\
+				plat/juno/aarch64/juno_common.c		\
+				plat/juno/scp_bootloader.c		\
+				plat/juno/scpi.c
+
+BL31_SOURCES		+=	drivers/arm/cci400/cci400.c		\
+				drivers/arm/gic/arm_gic.c		\
+				drivers/arm/gic/gic_v2.c		\
+				drivers/arm/gic/gic_v3.c		\
+				lib/cpus/aarch64/cortex_a53.S		\
+				lib/cpus/aarch64/cortex_a57.S		\
+				plat/common/aarch64/platform_mp_stack.S	\
+				plat/juno/bl31_plat_setup.c		\
+				plat/juno/mhu.c				\
+				plat/juno/aarch64/plat_helpers.S	\
+				plat/juno/aarch64/juno_common.c		\
+				plat/juno/plat_pm.c			\
+				plat/juno/plat_topology.c		\
+				plat/juno/scpi.c
+
+ifneq (${TRUSTED_BOARD_BOOT},0)
+  BL1_SOURCES		+=	plat/juno/juno_trusted_boot.c
+  BL2_SOURCES		+=	plat/juno/juno_trusted_boot.c
+endif
+
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL3-1 as the reset vector is not supported on Juno. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
+NEED_BL30		:=	yes
+
+# Enable workarounds for selected Cortex-A57 erratas.
+ERRATA_A57_806969	:=	1
+ERRATA_A57_813420	:=	1
+
+# Enable option to skip L1 data cache flush during the Cortex-A57 cluster
+# power down sequence
+SKIP_A57_L1_FLUSH_PWR_DWN	:=	 1
diff --git a/uefi/arm-trusted-firmware/plat/juno/scp_bootloader.c b/uefi/arm-trusted-firmware/plat/juno/scp_bootloader.c
new file mode 100644
index 0000000..a6d25d4
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/scp_bootloader.c
@@ -0,0 +1,153 @@
+/*
+ * 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 <platform.h>
+#include "juno_def.h"
+#include "mhu.h"
+#include "scp_bootloader.h"
+#include "scpi.h"
+
+/* Boot commands sent from AP -> SCP */
+#define BOOT_CMD_START	0x01
+#define BOOT_CMD_DATA	0x02
+
+typedef struct {
+	uint32_t image_size;
+} cmd_start_payload;
+
+typedef struct {
+	uint32_t sequence_num;
+	uint32_t offset;
+	uint32_t size;
+} cmd_data_payload;
+
+#define BOOT_DATA_MAX_SIZE  0x1000
+
+/* Boot commands sent from SCP -> AP */
+#define BOOT_CMD_ACK	0x03
+#define BOOT_CMD_NACK	0x04
+
+typedef struct {
+	uint32_t sequence_num;
+} cmd_ack_payload;
+
+/*
+ * Unlike the runtime protocol, the boot protocol uses the same memory region
+ * for both AP -> SCP and SCP -> AP transfers; define the address of this...
+ */
+static void * const cmd_payload = (void *)(MHU_SECURE_BASE + 0x0080);
+
+static void *scp_boot_message_start(void)
+{
+	mhu_secure_message_start();
+
+	return cmd_payload;
+}
+
+static void scp_boot_message_send(unsigned command, size_t size)
+{
+	/* Make sure payload can be seen by SCP */
+	if (MHU_PAYLOAD_CACHED)
+		flush_dcache_range((unsigned long)cmd_payload, size);
+
+	/* Send command to SCP */
+	mhu_secure_message_send(command | (size << 8));
+}
+
+static uint32_t scp_boot_message_wait(size_t size)
+{
+	uint32_t response =  mhu_secure_message_wait();
+
+	/* Make sure we see the reply from the SCP and not any stale data */
+	if (MHU_PAYLOAD_CACHED)
+		inv_dcache_range((unsigned long)cmd_payload, size);
+
+	return response & 0xff;
+}
+
+static void scp_boot_message_end(void)
+{
+	mhu_secure_message_end();
+}
+
+static int transfer_block(uint32_t sequence_num, uint32_t offset, uint32_t size)
+{
+	cmd_data_payload *cmd_data = scp_boot_message_start();
+	cmd_data->sequence_num = sequence_num;
+	cmd_data->offset = offset;
+	cmd_data->size = size;
+
+	scp_boot_message_send(BOOT_CMD_DATA, sizeof(*cmd_data));
+
+	cmd_ack_payload *cmd_ack = cmd_payload;
+	int ok = scp_boot_message_wait(sizeof(*cmd_ack)) == BOOT_CMD_ACK
+		 && cmd_ack->sequence_num == sequence_num;
+
+	scp_boot_message_end();
+
+	return ok;
+}
+
+int scp_bootloader_transfer(void *image, unsigned int image_size)
+{
+	uintptr_t offset = (uintptr_t)image - MHU_SECURE_BASE;
+	uintptr_t end = offset + image_size;
+	uint32_t response;
+
+	mhu_secure_init();
+
+	/* Initiate communications with SCP */
+	do {
+		cmd_start_payload *cmd_start = scp_boot_message_start();
+		cmd_start->image_size = image_size;
+
+		scp_boot_message_send(BOOT_CMD_START, sizeof(*cmd_start));
+
+		response = scp_boot_message_wait(0);
+
+		scp_boot_message_end();
+	} while (response != BOOT_CMD_ACK);
+
+	/* Transfer image to SCP a block at a time */
+	uint32_t sequence_num = 1;
+	size_t size;
+	while ((size = end - offset) != 0) {
+		if (size > BOOT_DATA_MAX_SIZE)
+			size = BOOT_DATA_MAX_SIZE;
+		while (!transfer_block(sequence_num, offset, size))
+			; /* Retry forever */
+		offset += size;
+		sequence_num++;
+	}
+
+	/* Wait for SCP to signal it's ready */
+	return scpi_wait_ready();
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/scp_bootloader.h b/uefi/arm-trusted-firmware/plat/juno/scp_bootloader.h
new file mode 100644
index 0000000..e872513
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/scp_bootloader.h
@@ -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.
+ */
+
+#ifndef __SCP_BOOTLOADER_H__
+#define __SCP_BOOTLOADER_H__
+
+int scp_bootloader_transfer(void *image, unsigned int image_size);
+
+#endif
diff --git a/uefi/arm-trusted-firmware/plat/juno/scpi.c b/uefi/arm-trusted-firmware/plat/juno/scpi.c
new file mode 100644
index 0000000..950c00b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/scpi.c
@@ -0,0 +1,140 @@
+/*
+ * 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 <platform.h>
+#include "juno_def.h"
+#include "mhu.h"
+#include "scpi.h"
+
+#define MHU_SECURE_SCP_TO_AP_PAYLOAD	(MHU_SECURE_BASE+0x0080)
+#define MHU_SECURE_AP_TO_SCP_PAYLOAD	(MHU_SECURE_BASE+0x0280)
+
+#define SIZE_SHIFT	20	/* Bit position for size value in MHU header */
+#define SIZE_MASK	0x1ff	/* Mask to extract size value in MHU header*/
+
+
+void *scpi_secure_message_start(void)
+{
+	mhu_secure_message_start();
+
+	/* Return address of payload area. */
+	return (void *)MHU_SECURE_AP_TO_SCP_PAYLOAD;
+}
+
+void scpi_secure_message_send(unsigned command, size_t size)
+{
+	/* Make sure payload can be seen by SCP */
+	if (MHU_PAYLOAD_CACHED)
+		flush_dcache_range(MHU_SECURE_AP_TO_SCP_PAYLOAD, size);
+
+	mhu_secure_message_send(command | (size << SIZE_SHIFT));
+}
+
+unsigned scpi_secure_message_receive(void **message_out, size_t *size_out)
+{
+	uint32_t response =  mhu_secure_message_wait();
+
+	/* Get size of payload */
+	size_t size = (response >> SIZE_SHIFT) & SIZE_MASK;
+
+	/* Clear size from response */
+	response &= ~(SIZE_MASK << SIZE_SHIFT);
+
+	/* Make sure we don't read stale data */
+	if (MHU_PAYLOAD_CACHED)
+		inv_dcache_range(MHU_SECURE_SCP_TO_AP_PAYLOAD, size);
+
+	if (size_out)
+		*size_out = size;
+
+	if (message_out)
+		*message_out = (void *)MHU_SECURE_SCP_TO_AP_PAYLOAD;
+
+	return response;
+}
+
+void scpi_secure_message_end(void)
+{
+	mhu_secure_message_end();
+}
+
+static void scpi_secure_send32(unsigned command, uint32_t message)
+{
+	*(__typeof__(message) *)scpi_secure_message_start() = message;
+	scpi_secure_message_send(command, sizeof(message));
+	scpi_secure_message_end();
+}
+
+int scpi_wait_ready(void)
+{
+	/* Get a message from the SCP */
+	scpi_secure_message_start();
+	size_t size;
+	unsigned command = scpi_secure_message_receive(NULL, &size);
+	scpi_secure_message_end();
+
+	/* We are expecting 'SCP Ready', produce correct error if it's not */
+	scpi_status_t response = SCP_OK;
+	if (command != SCPI_CMD_SCP_READY)
+		response = SCP_E_SUPPORT;
+	else if (size != 0)
+		response = SCP_E_SIZE;
+
+	/* Send our response back to SCP */
+	scpi_secure_send32(command, response);
+
+	return response == SCP_OK ? 0 : -1;
+}
+
+void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
+		scpi_power_state_t cluster_state, scpi_power_state_t css_state)
+{
+	uint32_t state = mpidr & 0x0f;	/* CPU ID */
+	state |= (mpidr & 0xf00) >> 4;	/* Cluster ID */
+	state |= cpu_state << 8;
+	state |= cluster_state << 12;
+	state |= css_state << 16;
+	scpi_secure_send32(SCPI_CMD_SET_CSS_POWER_STATE, state);
+}
+
+uint32_t scpi_sys_power_state(scpi_system_state_t system_state)
+{
+	uint32_t *response;
+	size_t size;
+	uint8_t state = system_state & 0xff;
+
+	/* Send the command */
+	*(__typeof__(state) *)scpi_secure_message_start() = state;
+	scpi_secure_message_send(SCPI_CMD_SYS_POWER_STATE, sizeof(state));
+	scpi_secure_message_receive((void *)&response, &size);
+	scpi_secure_message_end();
+	return *response;
+}
diff --git a/uefi/arm-trusted-firmware/plat/juno/scpi.h b/uefi/arm-trusted-firmware/plat/juno/scpi.h
new file mode 100644
index 0000000..8a5ef65
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/scpi.h
@@ -0,0 +1,82 @@
+/*
+ * 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 __SCPI_H__
+#define __SCPI_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+extern void *scpi_secure_message_start(void);
+extern void scpi_secure_message_send(unsigned command, size_t size);
+extern unsigned scpi_secure_message_receive(void **message_out, size_t *size_out);
+extern void scpi_secure_message_end(void);
+
+
+enum {
+	SCP_OK = 0,	/* Success */
+	SCP_E_PARAM,	/* Invalid parameter(s) */
+	SCP_E_ALIGN,	/* Invalid alignment */
+	SCP_E_SIZE,	/* Invalid size */
+	SCP_E_HANDLER,	/* Invalid handler or callback */
+	SCP_E_ACCESS,	/* Invalid access or permission denied */
+	SCP_E_RANGE,	/* Value out of range */
+	SCP_E_TIMEOUT,	/* Time out has ocurred */
+	SCP_E_NOMEM,	/* Invalid memory area or pointer */
+	SCP_E_PWRSTATE,	/* Invalid power state */
+	SCP_E_SUPPORT,	/* Feature not supported or disabled */
+};
+
+typedef uint32_t scpi_status_t;
+
+typedef enum {
+	SCPI_CMD_SCP_READY = 0x01,
+	SCPI_CMD_SET_CSS_POWER_STATE = 0x04,
+	SCPI_CMD_SYS_POWER_STATE = 0x08
+} scpi_command_t;
+
+typedef enum {
+	scpi_power_on = 0,
+	scpi_power_retention = 1,
+	scpi_power_off = 3,
+} scpi_power_state_t;
+
+typedef enum {
+	scpi_system_shutdown = 0,
+	scpi_system_reboot = 1,
+	scpi_system_reset = 2
+} scpi_system_state_t;
+
+extern int scpi_wait_ready(void);
+extern void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
+		scpi_power_state_t cluster_state, scpi_power_state_t css_state);
+uint32_t scpi_sys_power_state(scpi_system_state_t system_state);
+
+#endif	/* __SCPI_H__ */
diff --git a/uefi/arm-trusted-firmware/plat/juno/tsp/tsp-juno.mk b/uefi/arm-trusted-firmware/plat/juno/tsp/tsp-juno.mk
new file mode 100644
index 0000000..4d56ea2
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/tsp/tsp-juno.mk
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+# TSP source files specific to Juno platform
+BL32_SOURCES		+=	drivers/arm/gic/arm_gic.c		\
+				drivers/arm/gic/gic_v2.c		\
+				plat/common/aarch64/platform_mp_stack.S	\
+				plat/juno/aarch64/juno_common.c		\
+				plat/juno/aarch64/plat_helpers.S	\
+				plat/juno/tsp/tsp_plat_setup.c
diff --git a/uefi/arm-trusted-firmware/plat/juno/tsp/tsp_plat_setup.c b/uefi/arm-trusted-firmware/plat/juno/tsp/tsp_plat_setup.c
new file mode 100644
index 0000000..8293a13
--- /dev/null
+++ b/uefi/arm-trusted-firmware/plat/juno/tsp/tsp_plat_setup.c
@@ -0,0 +1,108 @@
+/*
+ * 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 <bl_common.h>
+#include <console.h>
+#include <platform_tsp.h>
+#include "../juno_def.h"
+#include "../juno_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 __RO_END__;
+extern unsigned long __BL32_END__;
+
+#if USE_COHERENT_MEM
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+#endif
+
+/*
+ * The next 3 constants identify the extents of the code, RO data region and the
+ * limit of the BL3-2 image.  These addresses are used by the MMU setup code and
+ * therefore they must be page-aligned.  It is the responsibility of the linker
+ * script to ensure that __RO_START__, __RO_END__ & __BL32_END__ linker symbols
+ * refer to page-aligned addresses.
+ */
+#define BL32_RO_BASE (unsigned long)(&__RO_START__)
+#define BL32_RO_LIMIT (unsigned long)(&__RO_END__)
+#define BL32_END (unsigned long)(&__BL32_END__)
+
+#if USE_COHERENT_MEM
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+#endif
+
+/*******************************************************************************
+ * Initialize the UART
+ ******************************************************************************/
+void tsp_early_platform_setup(void)
+{
+	/*
+	 * Initialize a different console than already in use to display
+	 * messages from TSP
+	 */
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+}
+
+/*******************************************************************************
+ * Perform platform specific setup placeholder
+ ******************************************************************************/
+void tsp_platform_setup(void)
+{
+	plat_gic_init();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this only intializes the MMU
+ ******************************************************************************/
+void tsp_plat_arch_setup(void)
+{
+	configure_mmu_el1(BL32_RO_BASE,
+			  (BL32_END - BL32_RO_BASE),
+			  BL32_RO_BASE,
+			  BL32_RO_LIMIT
+#if USE_COHERENT_MEM
+			  , BL32_COHERENT_RAM_BASE,
+			  BL32_COHERENT_RAM_LIMIT
+#endif
+			  );
+}
diff --git a/uefi/arm-trusted-firmware/readme.md b/uefi/arm-trusted-firmware/readme.md
new file mode 100644
index 0000000..454b5f1
--- /dev/null
+++ b/uefi/arm-trusted-firmware/readme.md
@@ -0,0 +1,162 @@
+ARM Trusted Firmware - version 1.1
+==================================
+
+ARM Trusted Firmware provides a reference implementation of secure world
+software for [ARMv8-A], including Exception Level 3 (EL3) software. This release
+provides complete support for version 0.2 of the [PSCI] specification, initial
+support for the new version 1.0 of that specification, and prototype support for
+the Trusted Board Boot Requirements specification.
+
+The intent is to provide a reference implementation of various ARM interface
+standards, such as the Power State Coordination Interface ([PSCI]), Trusted
+Board Boot Requirements (TBBR) and [Secure Monitor] [TEE-SMC] code. As far as
+possible the code is designed for reuse or porting to other ARMv8-A model and
+hardware platforms.
+
+ARM will continue development in collaboration with interested parties to
+provide a full reference implementation of PSCI, TBBR and Secure Monitor code
+to the benefit of all developers working with ARMv8-A TrustZone technology.
+
+
+License
+-------
+
+The software is provided under a BSD 3-Clause [license]. Certain source files
+are derived from FreeBSD code: the original license is included in these
+source files.
+
+
+This Release
+------------
+
+This release is a limited functionality implementation of the Trusted Firmware.
+It provides a suitable starting point for productization. Future versions will
+contain new features, optimizations and quality improvements.
+
+### Functionality
+
+*   Prototype implementation of a subset of the Trusted Board Boot Requirements
+    Platform Design Document (PDD). This includes packaging the various firmware
+    images into a Firmware Image Package (FIP) to be loaded from non-volatile
+    storage, and a prototype of authenticated boot using key certificates stored
+    in the FIP.
+
+*   Initializes the secure world (for example, exception vectors, control
+    registers, GIC and interrupts for the platform), before transitioning into
+    the normal world.
+
+*   Supports both GICv2 and GICv3 initialization for use by normal world
+    software.
+
+*   Starts the normal world at the Exception Level and Register Width specified
+    by the platform port. Typically this is AArch64 EL2 if available.
+
+*   Handles SMCs (Secure Monitor Calls) conforming to the [SMC Calling
+    Convention PDD] [SMCCC] using an EL3 runtime services framework.
+
+*   Handles SMCs relating to the [Power State Coordination Interface PDD] [PSCI]
+    for the Secondary CPU Boot, CPU Hotplug, CPU Idle and System Shutdown/Reset
+    use-cases.
+
+*   A Test Secure-EL1 Payload and Dispatcher to demonstrate Secure Monitor
+    functionality such as world switching, EL1 context management and interrupt
+    routing. This also demonstrates Secure-EL1 interaction with PSCI. Some of
+    this functionality is provided in library form for re-use by other
+    Secure-EL1 Payload Dispatchers.
+
+*   Support for alternative Trusted Boot Firmware. Some platforms have their own
+    Trusted Boot implementation and only require the Secure Monitor
+    functionality provided by ARM Trusted Firmware.
+
+*   Isolation of memory accessible by the secure world from the normal world
+    through programming of a TrustZone controller.
+
+*   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.
+
+For a full description of functionality and implementation details, please
+see the [Firmware Design] and supporting documentation. The [Change Log]
+provides details of changes made since the last release.
+
+### Platforms
+
+This release of the Trusted Firmware has been tested on Revision B of the
+[Juno ARM Development Platform] [Juno] with Version r0p0-00rel7 of the
+[ARM SCP Firmware] [SCP download].
+
+The Trusted Firmware has also been tested on the 64-bit Linux versions of the
+following ARM [FVP]s:
+
+*   `Foundation_Platform` (Version 9.1, Build 9.1.33)
+*   `FVP_Base_AEMv8A-AEMv8A` (Version 6.2, Build 0.8.6202)
+*   `FVP_Base_Cortex-A57x4-A53x4` (Version 6.2, Build 0.8.6202)
+*   `FVP_Base_Cortex-A57x1-A53x1` (Version 6.2, Build 0.8.6202)
+*   `FVP_Base_Cortex-A57x2-A53x4` (Version 6.2, Build 0.8.6202)
+
+The Foundation FVP can be downloaded free of charge. The Base FVPs can be
+licensed from ARM: see [www.arm.com/fvp] [FVP].
+
+### Still to Come
+
+*   Complete and more flexible Trusted Board Boot implementation.
+
+*   Complete implementation of the [PSCI] v1.0 specification.
+
+*   Support for alternative types of Secure-EL1 Payloads.
+
+*   Extending the GICv3 support to the secure world.
+
+*   Support for new System IP devices.
+
+For a full list of detailed issues in the current code, please see the [Change
+Log] and the [GitHub issue tracker].
+
+
+Getting Started
+---------------
+
+Get the Trusted Firmware source code from
+[GitHub](https://www.github.com/ARM-software/arm-trusted-firmware).
+
+See the [User Guide] for instructions on how to install, build and use
+the Trusted Firmware with the ARM [FVP]s.
+
+See the [Firmware Design] for information on how the ARM Trusted Firmware works.
+
+See the [Porting Guide] as well for information about how to use this
+software on another ARMv8-A platform.
+
+See the [Contributing Guidelines] for information on how to contribute to this
+project and the [Acknowledgments] file for a list of contributors to the
+project.
+
+### Feedback and support
+
+ARM welcomes any feedback on the Trusted Firmware. Please send feedback using
+the [GitHub issue tracker].
+
+ARM licensees may contact ARM directly via their partner managers.
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - -
+
+_Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved._
+
+
+[License]:                  ./license.md "BSD license for ARM Trusted Firmware"
+[Contributing Guidelines]:  ./contributing.md "Guidelines for contributors"
+[Acknowledgments]:          ./acknowledgements.md "Contributor acknowledgments"
+[Change Log]:               ./docs/change-log.md
+[User Guide]:               ./docs/user-guide.md
+[Firmware Design]:          ./docs/firmware-design.md
+[Porting Guide]:            ./docs/porting-guide.md
+
+[ARMv8-A]:               http://www.arm.com/products/processors/armv8-architecture.php "ARMv8-A Architecture"
+[FVP]:                   http://www.arm.com/fvp "ARM's Fixed Virtual Platforms"
+[Juno]:                  http://www.arm.com/products/tools/development-boards/versatile-express/juno-arm-development-platform.php "Juno ARM Development Platform"
+[SCP download]:          https://silver.arm.com/download/download.tm?pv=1764630
+[PSCI]:                  http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)"
+[SMCCC]:                 http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)"
+[TEE-SMC]:               http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php "Secure Monitor and TEEs"
+[GitHub issue tracker]:  https://github.com/ARM-software/tf-issues/issues
diff --git a/uefi/arm-trusted-firmware/services/spd/opteed/opteed.mk b/uefi/arm-trusted-firmware/services/spd/opteed/opteed.mk
new file mode 100644
index 0000000..8057dcc
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/opteed/opteed.mk
@@ -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.
+#
+
+OPTEED_DIR		:=	services/spd/opteed
+SPD_INCLUDES		:=
+
+SPD_SOURCES		:=	services/spd/opteed/opteed_common.c	\
+				services/spd/opteed/opteed_helpers.S	\
+				services/spd/opteed/opteed_main.c	\
+				services/spd/opteed/opteed_pm.c
+
+NEED_BL32		:=	yes
diff --git a/uefi/arm-trusted-firmware/services/spd/opteed/opteed_common.c b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_common.c
new file mode 100644
index 0000000..5743102
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_common.c
@@ -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 <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <context_mgmt.h>
+#include <string.h>
+#include "opteed_private.h"
+
+/*******************************************************************************
+ * Given a OPTEE entrypoint info pointer, entry point PC, register width,
+ * cpu id & pointer to a context data structure, this function will
+ * initialize OPTEE context and entry point info for OPTEE.
+ ******************************************************************************/
+void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
+				uint32_t rw, uint64_t pc,
+				uint64_t paged_part, uint64_t mem_limit,
+				optee_context_t *optee_ctx)
+{
+	uint32_t ep_attr;
+
+	/* Passing a NULL context is a critical programming error */
+	assert(optee_ctx);
+	assert(optee_entry_point);
+	assert(pc);
+
+	/* Associate this context with the cpu specified */
+	optee_ctx->mpidr = read_mpidr_el1();
+	optee_ctx->state = 0;
+	set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_OFF);
+
+	cm_set_context(&optee_ctx->cpu_ctx, SECURE);
+
+	/* initialise an entrypoint to set up the CPU context */
+	ep_attr = SECURE | EP_ST_ENABLE;
+	if (read_sctlr_el3() & SCTLR_EE_BIT)
+		ep_attr |= EP_EE_BIG;
+	SET_PARAM_HEAD(optee_entry_point, PARAM_EP, VERSION_1, ep_attr);
+	optee_entry_point->pc = pc;
+	if (rw == OPTEE_AARCH64)
+		optee_entry_point->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+						  DISABLE_ALL_EXCEPTIONS);
+	else
+		optee_entry_point->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+						      SPSR_E_LITTLE,
+						      DAIF_FIQ_BIT |
+							DAIF_IRQ_BIT |
+							DAIF_ABT_BIT);
+	memset(&optee_entry_point->args, 0, sizeof(optee_entry_point->args));
+	optee_entry_point->args.arg0 = paged_part;
+	optee_entry_point->args.arg1 = mem_limit;
+}
+
+/*******************************************************************************
+ * This function takes an OPTEE context pointer and:
+ * 1. Applies the S-EL1 system register context from optee_ctx->cpu_ctx.
+ * 2. Saves the current C runtime state (callee saved registers) on the stack
+ *    frame and saves a reference to this state.
+ * 3. Calls el3_exit() so that the EL3 system and general purpose registers
+ *    from the optee_ctx->cpu_ctx are used to enter the OPTEE image.
+ ******************************************************************************/
+uint64_t opteed_synchronous_sp_entry(optee_context_t *optee_ctx)
+{
+	uint64_t rc;
+
+	assert(optee_ctx != NULL);
+	assert(optee_ctx->c_rt_ctx == 0);
+
+	/* Apply the Secure EL1 system register context and switch to it */
+	assert(cm_get_context(SECURE) == &optee_ctx->cpu_ctx);
+	cm_el1_sysregs_context_restore(SECURE);
+	cm_set_next_eret_context(SECURE);
+
+	rc = opteed_enter_sp(&optee_ctx->c_rt_ctx);
+#if DEBUG
+	optee_ctx->c_rt_ctx = 0;
+#endif
+
+	return rc;
+}
+
+
+/*******************************************************************************
+ * This function takes an OPTEE context pointer and:
+ * 1. Saves the S-EL1 system register context tp optee_ctx->cpu_ctx.
+ * 2. Restores the current C runtime state (callee saved registers) from the
+ *    stack frame using the reference to this state saved in opteed_enter_sp().
+ * 3. It does not need to save any general purpose or EL3 system register state
+ *    as the generic smc entry routine should have saved those.
+ ******************************************************************************/
+void opteed_synchronous_sp_exit(optee_context_t *optee_ctx, uint64_t ret)
+{
+	assert(optee_ctx != NULL);
+	/* Save the Secure EL1 system register context */
+	assert(cm_get_context(SECURE) == &optee_ctx->cpu_ctx);
+	cm_el1_sysregs_context_save(SECURE);
+
+	assert(optee_ctx->c_rt_ctx != 0);
+	opteed_exit_sp(optee_ctx->c_rt_ctx, ret);
+
+	/* Should never reach here */
+	assert(0);
+}
diff --git a/uefi/arm-trusted-firmware/services/spd/opteed/opteed_helpers.S b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_helpers.S
new file mode 100644
index 0000000..ef59540
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_helpers.S
@@ -0,0 +1,101 @@
+/*
+ * 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 "opteed_private.h"
+
+	.global	opteed_enter_sp
+	/* ---------------------------------------------
+	 * This function is called with SP_EL0 as stack.
+	 * Here we stash our EL3 callee-saved registers
+	 * on to the stack as a part of saving the C
+	 * runtime and enter the secure payload.
+	 * 'x0' contains a pointer to the memory where
+	 * the address of the C runtime context is to be
+	 * saved.
+	 * ---------------------------------------------
+	 */
+func opteed_enter_sp
+	/* Make space for the registers that we're going to save */
+	mov	x3, sp
+	str	x3, [x0, #0]
+	sub	sp, sp, #OPTEED_C_RT_CTX_SIZE
+
+	/* Save callee-saved registers on to the stack */
+	stp	x19, x20, [sp, #OPTEED_C_RT_CTX_X19]
+	stp	x21, x22, [sp, #OPTEED_C_RT_CTX_X21]
+	stp	x23, x24, [sp, #OPTEED_C_RT_CTX_X23]
+	stp	x25, x26, [sp, #OPTEED_C_RT_CTX_X25]
+	stp	x27, x28, [sp, #OPTEED_C_RT_CTX_X27]
+	stp	x29, x30, [sp, #OPTEED_C_RT_CTX_X29]
+
+	/* ---------------------------------------------
+	 * Everything is setup now. el3_exit() will
+	 * use the secure context to restore to the
+	 * general purpose and EL3 system registers to
+	 * ERET into OPTEE.
+	 * ---------------------------------------------
+	 */
+	b	el3_exit
+
+	/* ---------------------------------------------
+	 * This function is called 'x0' pointing to a C
+	 * runtime context saved in opteed_enter_sp().  It
+	 * restores the saved registers and jumps to
+	 * that runtime with 'x0' as the new sp. This
+	 * destroys the C runtime context that had been
+	 * built on the stack below the saved context by
+	 * the caller. Later the second parameter 'x1'
+	 * is passed as return value to the caller
+	 * ---------------------------------------------
+	 */
+	.global opteed_exit_sp
+func opteed_exit_sp
+	/* Restore the previous stack */
+	mov	sp, x0
+
+	/* Restore callee-saved registers on to the stack */
+	ldp	x19, x20, [x0, #(OPTEED_C_RT_CTX_X19 - OPTEED_C_RT_CTX_SIZE)]
+	ldp	x21, x22, [x0, #(OPTEED_C_RT_CTX_X21 - OPTEED_C_RT_CTX_SIZE)]
+	ldp	x23, x24, [x0, #(OPTEED_C_RT_CTX_X23 - OPTEED_C_RT_CTX_SIZE)]
+	ldp	x25, x26, [x0, #(OPTEED_C_RT_CTX_X25 - OPTEED_C_RT_CTX_SIZE)]
+	ldp	x27, x28, [x0, #(OPTEED_C_RT_CTX_X27 - OPTEED_C_RT_CTX_SIZE)]
+	ldp	x29, x30, [x0, #(OPTEED_C_RT_CTX_X29 - OPTEED_C_RT_CTX_SIZE)]
+
+	/* ---------------------------------------------
+	 * This should take us back to the instruction
+	 * after the call to the last opteed_enter_sp().
+	 * Place the second parameter to x0 so that the
+	 * caller will see it as a return value from the
+	 * original entry call
+	 * ---------------------------------------------
+	 */
+	mov	x0, x1
+	ret
diff --git a/uefi/arm-trusted-firmware/services/spd/opteed/opteed_main.c b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_main.c
new file mode 100644
index 0000000..d73fc71
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_main.c
@@ -0,0 +1,558 @@
+/*
+ * 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.
+ */
+
+
+/*******************************************************************************
+ * This is the Secure Payload Dispatcher (SPD). The dispatcher is meant to be a
+ * plug-in component to the Secure Monitor, registered as a runtime service. The
+ * SPD is expected to be a functional extension of the Secure Payload (SP) that
+ * executes in Secure EL1. The Secure Monitor will delegate all SMCs targeting
+ * the Trusted OS/Applications range to the dispatcher. The SPD will either
+ * handle the request locally or delegate it to the Secure Payload. It is also
+ * responsible for initialising and maintaining communication with the SP.
+ ******************************************************************************/
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <bl31.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <errno.h>
+#include <platform.h>
+#include <runtime_svc.h>
+#include <stddef.h>
+#include <string.h>
+#include <uuid.h>
+#include "opteed_private.h"
+#include "teesmc_opteed_macros.h"
+#include "teesmc_opteed.h"
+
+#define OPTEE_MAGIC		0x4554504f
+#define OPTEE_VERSION		1
+#define OPTEE_ARCH_ARM32	0
+#define OPTEE_ARCH_ARM64	1
+
+struct optee_header {
+	uint32_t magic;
+	uint8_t version;
+	uint8_t arch;
+	uint16_t flags;
+	uint32_t init_size;
+	uint32_t init_load_addr_hi;
+	uint32_t init_load_addr_lo;
+	uint32_t init_mem_usage;
+	uint32_t paged_size;
+};
+
+/*******************************************************************************
+ * Address of the entrypoint vector table in OPTEE. It is
+ * initialised once on the primary core after a cold boot.
+ ******************************************************************************/
+optee_vectors_t *optee_vectors;
+
+/*******************************************************************************
+ * Array to keep track of per-cpu OPTEE state
+ ******************************************************************************/
+optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
+uint32_t opteed_rw;
+
+
+
+static int32_t opteed_init(void);
+
+/*******************************************************************************
+ * This function is the handler registered for S-EL1 interrupts by the
+ * OPTEED. It validates the interrupt and upon success arranges entry into
+ * the OPTEE at 'optee_fiq_entry()' for handling the interrupt.
+ ******************************************************************************/
+static uint64_t opteed_sel1_interrupt_handler(uint32_t id,
+					    uint32_t flags,
+					    void *handle,
+					    void *cookie)
+{
+	uint32_t linear_id;
+	uint64_t mpidr;
+	optee_context_t *optee_ctx;
+
+	/* Check the security state when the exception was generated */
+	assert(get_interrupt_src_ss(flags) == NON_SECURE);
+
+#if IMF_READ_INTERRUPT_ID
+	/* Check the security status of the interrupt */
+	assert(plat_ic_get_interrupt_type(id) == INTR_TYPE_S_EL1);
+#endif
+
+	/* Sanity check the pointer to this cpu's context */
+	mpidr = read_mpidr();
+	assert(handle == cm_get_context(NON_SECURE));
+
+	/* Save the non-secure context before entering the OPTEE */
+	cm_el1_sysregs_context_save(NON_SECURE);
+
+	/* Get a reference to this cpu's OPTEE context */
+	linear_id = platform_get_core_pos(mpidr);
+	optee_ctx = &opteed_sp_context[linear_id];
+	assert(&optee_ctx->cpu_ctx == cm_get_context(SECURE));
+
+	cm_set_elr_el3(SECURE, (uint64_t)&optee_vectors->fiq_entry);
+	cm_el1_sysregs_context_restore(SECURE);
+	cm_set_next_eret_context(SECURE);
+
+	/*
+	 * Tell the OPTEE that it has to handle an FIQ (synchronously).
+	 * Also the instruction in normal world where the interrupt was
+	 * generated is passed for debugging purposes. It is safe to
+	 * retrieve this address from ELR_EL3 as the secure context will
+	 * not take effect until el3_exit().
+	 */
+	SMC_RET1(&optee_ctx->cpu_ctx, read_elr_el3());
+}
+
+
+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);
+}
+
+/*******************************************************************************
+ * OPTEE Dispatcher setup. The OPTEED finds out the OPTEE entrypoint and type
+ * (aarch32/aarch64) if not already known and initialises the context for entry
+ * into OPTEE for its initialization.
+ ******************************************************************************/
+int32_t opteed_setup(void)
+{
+	entry_point_info_t *ep_info;
+	struct optee_header *header;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id;
+	uintptr_t init_load_addr;
+	size_t init_size;
+	size_t init_mem_usage;
+	uintptr_t payload_addr;
+	uintptr_t mem_limit;
+	uintptr_t paged_part;
+	uintptr_t paged_size;
+
+	linear_id = platform_get_core_pos(mpidr);
+
+	/*
+	 * Get information about the Secure Payload (BL32) image. Its
+	 * absence is a critical failure.  TODO: Add support to
+	 * conditionally include the SPD service
+	 */
+	ep_info = bl31_plat_get_next_image_ep_info(SECURE);
+	if (!ep_info) {
+		WARN("No OPTEE provided by BL2 boot loader.\n");
+		goto err;
+	}
+
+	header = (struct optee_header *)ep_info->pc;
+
+	if (header->magic != OPTEE_MAGIC || header->version != OPTEE_VERSION) {
+		WARN("Invalid OPTEE header.\n");
+		goto err;
+	}
+
+	if (header->arch == OPTEE_ARCH_ARM32)
+		opteed_rw = OPTEE_AARCH32;
+	else if (header->arch == OPTEE_ARCH_ARM64)
+		opteed_rw = OPTEE_AARCH64;
+	else {
+		WARN("Invalid OPTEE architecture (%d)\n", header->arch);
+		goto err;
+	}
+
+	init_load_addr = ((uint64_t)header->init_load_addr_hi << 32) |
+				header->init_load_addr_lo;
+	init_size = header->init_size;
+	init_mem_usage = header->init_mem_usage;
+	payload_addr = (uintptr_t)(header + 1);
+	paged_size = header->paged_size;
+
+	/*
+	 * Move OPTEE binary to the required location in memory.
+	 *
+	 * There's two ways OPTEE can be running in memory:
+	 * 1. A memory large enough to keep the entire OPTEE binary
+	 *    (DRAM currently)
+	 * 2. A part of OPTEE in a smaller (and more secure) memory
+	 *    (SRAM currently). This is achieved with demand paging
+	 *    of read-only data/code against a backing store in some
+	 *    larger memory (DRAM currently).
+	 *
+	 * In either case dictates init_load_addr in the OPTEE
+	 * header the address where what's after the header
+	 * (payload) should be residing when started. init_size in
+	 * the header tells how much of the payload that need to be
+	 * copied. init_mem_usage tells how much runtime memory in
+	 * total is needed by OPTEE.
+	 *
+	 * In alternative 2 there's additional data after
+	 * init_size, this is the rest of OPTEE which is demand
+	 * paged into memory.  A pointer to that data is supplied
+	 * to OPTEE when initializing.
+	 *
+	 * Alternative 1 only uses DRAM when executing OPTEE while
+	 * alternative 2 uses both SRAM and DRAM to execute.
+	 *
+	 * All data written which is later read by OPTEE must be flushed
+	 * out to memory since OPTEE starts with MMU turned off and caches
+	 * disabled.
+	 */
+	if (is_mem_free(BL32_SRAM_BASE,
+			 BL32_SRAM_LIMIT - BL32_SRAM_BASE,
+			 init_load_addr, init_mem_usage)) {
+		/* Running in SRAM, paging some code against DRAM */
+		memcpy((void *)init_load_addr, (void *)payload_addr,
+		       init_size);
+		flush_dcache_range(init_load_addr, init_size);
+		paged_part = payload_addr + init_size;
+		mem_limit = BL32_SRAM_LIMIT;
+	} else if (is_mem_free(BL32_DRAM_BASE,
+			       BL32_DRAM_LIMIT - BL32_DRAM_BASE,
+			       init_load_addr, init_mem_usage)) {
+		/*
+		 * Running in DRAM.
+		 *
+		 * The paged part normally empty, but if it isn't,
+		 * move it to the end of DRAM before moving the
+		 * init part in place.
+		 */
+		paged_part = BL32_DRAM_LIMIT - paged_size;
+		if (paged_size) {
+			if (!is_mem_free(BL32_DRAM_BASE,
+					 BL32_DRAM_LIMIT - BL32_DRAM_BASE,
+					 init_load_addr,
+					 init_mem_usage + paged_size)) {
+				WARN("Failed to reserve memory 0x%lx - 0x%lx\n",
+				      init_load_addr,
+				      init_load_addr + init_mem_usage +
+					paged_size);
+				goto err;
+			}
+
+			memcpy((void *)paged_part,
+				(void *)(payload_addr + init_size),
+				paged_size);
+			flush_dcache_range(paged_part, paged_size);
+		}
+
+		memmove((void *)init_load_addr, (void *)payload_addr,
+			init_size);
+		flush_dcache_range(init_load_addr, init_size);
+		mem_limit = BL32_DRAM_LIMIT;
+	} else {
+		WARN("Failed to reserve memory 0x%lx - 0x%lx\n",
+			init_load_addr, init_load_addr + init_mem_usage);
+		goto err;
+	}
+
+
+	opteed_init_optee_ep_state(ep_info, opteed_rw, init_load_addr,
+				   paged_part, mem_limit,
+				   &opteed_sp_context[linear_id]);
+
+	/*
+	 * All OPTEED initialization done. Now register our init function with
+	 * BL31 for deferred invocation
+	 */
+	bl31_register_bl32_init(&opteed_init);
+
+	return 0;
+
+err:
+	WARN("Booting device without OPTEE initialization.\n");
+	WARN("SMC`s destined for OPTEE will return SMC_UNK\n");
+	return 1;
+}
+
+/*******************************************************************************
+ * This function passes control to the OPTEE image (BL32) for the first time
+ * on the primary cpu after a cold boot. It assumes that a valid secure
+ * context has already been created by opteed_setup() which can be directly
+ * used.  It also assumes that a valid non-secure context has been
+ * initialised by PSCI so it does not need to save and restore any
+ * non-secure state. This function performs a synchronous entry into
+ * OPTEE. OPTEE passes control back to this routine through a SMC.
+ ******************************************************************************/
+static int32_t opteed_init(void)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
+	entry_point_info_t *optee_entry_point;
+	uint64_t rc;
+
+	/*
+	 * Get information about the OPTEE (BL32) image. Its
+	 * absence is a critical failure.
+	 */
+	optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
+	assert(optee_entry_point);
+
+	cm_init_context(mpidr, optee_entry_point);
+
+	/*
+	 * Arrange for an entry into OPTEE. It will be returned via
+	 * OPTEE_ENTRY_DONE case
+	 */
+	rc = opteed_synchronous_sp_entry(optee_ctx);
+	assert(rc != 0);
+
+	return rc;
+}
+
+
+/*******************************************************************************
+ * This function is responsible for handling all SMCs in the Trusted OS/App
+ * range from the non-secure state as defined in the SMC Calling Convention
+ * Document. It is also responsible for communicating with the Secure
+ * payload to delegate work and return results back to the non-secure
+ * state. Lastly it will also return any information that OPTEE needs to do
+ * the work assigned to it.
+ ******************************************************************************/
+uint64_t opteed_smc_handler(uint32_t smc_fid,
+			 uint64_t x1,
+			 uint64_t x2,
+			 uint64_t x3,
+			 uint64_t x4,
+			 void *cookie,
+			 void *handle,
+			 uint64_t flags)
+{
+	cpu_context_t *ns_cpu_context;
+	unsigned long mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
+	uint64_t rc;
+
+	/*
+	 * Determine which security state this SMC originated from
+	 */
+
+	if (is_caller_non_secure(flags)) {
+		/*
+		 * This is a fresh request from the non-secure client.
+		 * The parameters are in x1 and x2. Figure out which
+		 * registers need to be preserved, save the non-secure
+		 * state and send the request to the secure payload.
+		 */
+		assert(handle == cm_get_context(NON_SECURE));
+
+		cm_el1_sysregs_context_save(NON_SECURE);
+
+		/*
+		 * We are done stashing the non-secure context. Ask the
+		 * OPTEE to do the work now.
+		 */
+
+		/*
+		 * Verify if there is a valid context to use, copy the
+		 * operation type and parameters to the secure context
+		 * and jump to the fast smc entry point in the secure
+		 * payload. Entry into S-EL1 will take place upon exit
+		 * from this function.
+		 */
+		assert(&optee_ctx->cpu_ctx == cm_get_context(SECURE));
+
+		/* Set appropriate entry for SMC.
+		 * We expect OPTEE to manage the PSTATE.I and PSTATE.F
+		 * flags as appropriate.
+		 */
+		if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_FAST) {
+			cm_set_elr_el3(SECURE, (uint64_t)
+					&optee_vectors->fast_smc_entry);
+		} else {
+			cm_set_elr_el3(SECURE, (uint64_t)
+					&optee_vectors->std_smc_entry);
+		}
+
+		cm_el1_sysregs_context_restore(SECURE);
+		cm_set_next_eret_context(SECURE);
+
+		/* Propagate hypervisor client ID */
+		write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx),
+			      CTX_GPREG_X7,
+			      read_ctx_reg(get_gpregs_ctx(handle),
+					   CTX_GPREG_X7));
+
+		SMC_RET4(&optee_ctx->cpu_ctx, smc_fid, x1, x2, x3);
+	}
+
+	/*
+	 * Returning from OPTEE
+	 */
+
+	switch (smc_fid) {
+	/*
+	 * OPTEE has finished initialising itself after a cold boot
+	 */
+	case TEESMC_OPTEED_RETURN_ENTRY_DONE:
+		/*
+		 * Stash the OPTEE entry points information. This is done
+		 * only once on the primary cpu
+		 */
+		assert(optee_vectors == NULL);
+		optee_vectors = (optee_vectors_t *) x1;
+
+		if (optee_vectors) {
+			set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_ON);
+
+			/*
+			 * OPTEE has been successfully initialized.
+			 * Register power management hooks with PSCI
+			 */
+			psci_register_spd_pm_hook(&opteed_pm);
+
+			/*
+			 * Register an interrupt handler for S-EL1 interrupts
+			 * when generated during code executing in the
+			 * non-secure state.
+			 */
+			flags = 0;
+			set_interrupt_rm_flag(flags, NON_SECURE);
+			rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+						opteed_sel1_interrupt_handler,
+						flags);
+			if (rc)
+				panic();
+		}
+
+		/*
+		 * OPTEE reports completion. The OPTEED must have initiated
+		 * the original request through a synchronous entry into
+		 * OPTEE. Jump back to the original C runtime context.
+		 */
+		opteed_synchronous_sp_exit(optee_ctx, x1);
+
+
+	/*
+	 * These function IDs is used only by OP-TEE to indicate it has
+	 * finished:
+	 * 1. turning itself on in response to an earlier psci
+	 *    cpu_on request
+	 * 2. resuming itself after an earlier psci cpu_suspend
+	 *    request.
+	 */
+	case TEESMC_OPTEED_RETURN_ON_DONE:
+	case TEESMC_OPTEED_RETURN_RESUME_DONE:
+
+
+	/*
+	 * These function IDs is used only by the SP to indicate it has
+	 * finished:
+	 * 1. suspending itself after an earlier psci cpu_suspend
+	 *    request.
+	 * 2. turning itself off in response to an earlier psci
+	 *    cpu_off request.
+	 */
+	case TEESMC_OPTEED_RETURN_OFF_DONE:
+	case TEESMC_OPTEED_RETURN_SUSPEND_DONE:
+	case TEESMC_OPTEED_RETURN_SYSTEM_OFF_DONE:
+	case TEESMC_OPTEED_RETURN_SYSTEM_RESET_DONE:
+
+		/*
+		 * OPTEE reports completion. The OPTEED must have initiated the
+		 * original request through a synchronous entry into OPTEE.
+		 * Jump back to the original C runtime context, and pass x1 as
+		 * return value to the caller
+		 */
+		opteed_synchronous_sp_exit(optee_ctx, x1);
+
+	/*
+	 * OPTEE is returning from a call or being preempted from a call, in
+	 * either case execution should resume in the normal world.
+	 */
+	case TEESMC_OPTEED_RETURN_CALL_DONE:
+		/*
+		 * This is the result from the secure client of an
+		 * earlier request. The results are in x0-x3. Copy it
+		 * into the non-secure context, save the secure state
+		 * and return to the non-secure state.
+		 */
+		assert(handle == cm_get_context(SECURE));
+		cm_el1_sysregs_context_save(SECURE);
+
+		/* Get a reference to the non-secure context */
+		ns_cpu_context = cm_get_context(NON_SECURE);
+		assert(ns_cpu_context);
+
+		/* Restore non-secure state */
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+
+		SMC_RET4(ns_cpu_context, x1, x2, x3, x4);
+
+	/*
+	 * OPTEE has finished handling a S-EL1 FIQ interrupt. Execution
+	 * should resume in the normal world.
+	 */
+	case TEESMC_OPTEED_RETURN_FIQ_DONE:
+		/* Get a reference to the non-secure context */
+		ns_cpu_context = cm_get_context(NON_SECURE);
+		assert(ns_cpu_context);
+
+		/*
+		 * Restore non-secure state. There is no need to save the
+		 * secure system register context since OPTEE was supposed
+		 * to preserve it during S-EL1 interrupt handling.
+		 */
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+
+		SMC_RET0((uint64_t) ns_cpu_context);
+
+	default:
+		panic();
+	}
+}
+
+/* Define an OPTEED runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+	opteed_fast,
+
+	OEN_TOS_START,
+	OEN_TOS_END,
+	SMC_TYPE_FAST,
+	opteed_setup,
+	opteed_smc_handler
+);
+
+/* Define an OPTEED runtime service descriptor for standard SMC calls */
+DECLARE_RT_SVC(
+	opteed_std,
+
+	OEN_TOS_START,
+	OEN_TOS_END,
+	SMC_TYPE_STD,
+	NULL,
+	opteed_smc_handler
+);
diff --git a/uefi/arm-trusted-firmware/services/spd/opteed/opteed_pm.c b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_pm.c
new file mode 100644
index 0000000..bce0d2f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_pm.c
@@ -0,0 +1,249 @@
+/*
+ * 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 <assert.h>
+#include <bl_common.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <platform.h>
+#include "opteed_private.h"
+
+/*******************************************************************************
+ * The target cpu is being turned on. Allow the OPTEED/OPTEE to perform any
+ * actions needed. Nothing at the moment.
+ ******************************************************************************/
+static void opteed_cpu_on_handler(uint64_t target_cpu)
+{
+}
+
+/*******************************************************************************
+ * This cpu is being turned off. Allow the OPTEED/OPTEE to perform any actions
+ * needed
+ ******************************************************************************/
+static int32_t opteed_cpu_off_handler(uint64_t unused)
+{
+	int32_t rc = 0;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
+
+	assert(optee_vectors);
+	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
+
+	/* Program the entry point and enter OPTEE */
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->cpu_off_entry);
+	rc = opteed_synchronous_sp_entry(optee_ctx);
+
+	/*
+	 * Read the response from OPTEE. A non-zero return means that
+	 * something went wrong while communicating with OPTEE.
+	 */
+	if (rc != 0)
+		panic();
+
+	/*
+	 * Reset OPTEE's context for a fresh start when this cpu is turned on
+	 * subsequently.
+	 */
+	set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_OFF);
+
+	 return 0;
+}
+
+/*******************************************************************************
+ * This cpu is being suspended. S-EL1 state must have been saved in the
+ * resident cpu (mpidr format) if it is a UP/UP migratable OPTEE.
+ ******************************************************************************/
+static void opteed_cpu_suspend_handler(uint64_t unused)
+{
+	int32_t rc = 0;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
+
+	assert(optee_vectors);
+	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
+
+	/* Program the entry point and enter OPTEE */
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->cpu_suspend_entry);
+	rc = opteed_synchronous_sp_entry(optee_ctx);
+
+	/*
+	 * Read the response from OPTEE. A non-zero return means that
+	 * something went wrong while communicating with OPTEE.
+	 */
+	if (rc != 0)
+		panic();
+
+	/* Update its context to reflect the state OPTEE is in */
+	set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_SUSPEND);
+}
+
+/*******************************************************************************
+ * This cpu has been turned on. Enter OPTEE to initialise S-EL1 and other bits
+ * before passing control back to the Secure Monitor. Entry in S-El1 is done
+ * after initialising minimal architectural state that guarantees safe
+ * execution.
+ ******************************************************************************/
+static void opteed_cpu_on_finish_handler(uint64_t unused)
+{
+	int32_t rc = 0;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
+	entry_point_info_t optee_on_entrypoint;
+
+	assert(optee_vectors);
+	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF);
+
+	opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
+				(uint64_t)&optee_vectors->cpu_on_entry,
+				0, 0, optee_ctx);
+
+	/* Initialise this cpu's secure context */
+	cm_init_context(mpidr, &optee_on_entrypoint);
+
+	/* Enter OPTEE */
+	rc = opteed_synchronous_sp_entry(optee_ctx);
+
+	/*
+	 * Read the response from OPTEE. A non-zero return means that
+	 * something went wrong while communicating with OPTEE.
+	 */
+	if (rc != 0)
+		panic();
+
+	/* Update its context to reflect the state OPTEE is in */
+	set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_ON);
+}
+
+/*******************************************************************************
+ * This cpu has resumed from suspend. The OPTEED saved the OPTEE context when it
+ * completed the preceding suspend call. Use that context to program an entry
+ * into OPTEE to allow it to do any remaining book keeping
+ ******************************************************************************/
+static void opteed_cpu_suspend_finish_handler(uint64_t suspend_level)
+{
+	int32_t rc = 0;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
+
+	assert(optee_vectors);
+	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_SUSPEND);
+
+	/* Program the entry point, suspend_level and enter the SP */
+	write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx),
+		      CTX_GPREG_X0,
+		      suspend_level);
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->cpu_resume_entry);
+	rc = opteed_synchronous_sp_entry(optee_ctx);
+
+	/*
+	 * Read the response from OPTEE. A non-zero return means that
+	 * something went wrong while communicating with OPTEE.
+	 */
+	if (rc != 0)
+		panic();
+
+	/* Update its context to reflect the state OPTEE is in */
+	set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_ON);
+}
+
+/*******************************************************************************
+ * Return the type of OPTEE the OPTEED is dealing with. Report the current
+ * resident cpu (mpidr format) if it is a UP/UP migratable OPTEE.
+ ******************************************************************************/
+static int32_t opteed_cpu_migrate_info(uint64_t *resident_cpu)
+{
+	return OPTEE_MIGRATE_INFO;
+}
+
+/*******************************************************************************
+ * System is about to be switched off. Allow the OPTEED/OPTEE to perform
+ * any actions needed.
+ ******************************************************************************/
+static void opteed_system_off(void)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
+
+	assert(optee_vectors);
+	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
+
+	/* Program the entry point */
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->system_off_entry);
+
+	/* Enter OPTEE. We do not care about the return value because we
+	 * must continue the shutdown anyway */
+	opteed_synchronous_sp_entry(optee_ctx);
+}
+
+/*******************************************************************************
+ * System is about to be reset. Allow the OPTEED/OPTEE to perform
+ * any actions needed.
+ ******************************************************************************/
+static void opteed_system_reset(void)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
+
+	assert(optee_vectors);
+	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
+
+	/* Program the entry point */
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->system_reset_entry);
+
+	/* Enter OPTEE. We do not care about the return value because we
+	 * must continue the reset anyway */
+	opteed_synchronous_sp_entry(optee_ctx);
+}
+
+
+/*******************************************************************************
+ * Structure populated by the OPTEE Dispatcher to be given a chance to
+ * perform any OPTEE bookkeeping before PSCI executes a power mgmt.
+ * operation.
+ ******************************************************************************/
+const spd_pm_ops_t opteed_pm = {
+	.svc_on = opteed_cpu_on_handler,
+	.svc_off = opteed_cpu_off_handler,
+	.svc_suspend = opteed_cpu_suspend_handler,
+	.svc_on_finish = opteed_cpu_on_finish_handler,
+	.svc_suspend_finish = opteed_cpu_suspend_finish_handler,
+	.svc_migrate = NULL,
+	.svc_migrate_info = opteed_cpu_migrate_info,
+	.svc_system_off = opteed_system_off,
+	.svc_system_reset = opteed_system_reset,
+};
+
diff --git a/uefi/arm-trusted-firmware/services/spd/opteed/opteed_private.h b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_private.h
new file mode 100644
index 0000000..72fd97a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/opteed/opteed_private.h
@@ -0,0 +1,181 @@
+/*
+ * 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 __OPTEED_PRIVATE_H__
+#define __OPTEED_PRIVATE_H__
+
+#include <arch.h>
+#include <context.h>
+#include <interrupt_mgmt.h>
+#include <platform_def.h>
+#include <psci.h>
+
+/*******************************************************************************
+ * OPTEE PM state information e.g. OPTEE is suspended, uninitialised etc
+ * and macros to access the state information in the per-cpu 'state' flags
+ ******************************************************************************/
+#define OPTEE_PSTATE_OFF		0
+#define OPTEE_PSTATE_ON			1
+#define OPTEE_PSTATE_SUSPEND		2
+#define OPTEE_PSTATE_SHIFT		0
+#define OPTEE_PSTATE_MASK		0x3
+#define get_optee_pstate(state)	((state >> OPTEE_PSTATE_SHIFT) & \
+				 OPTEE_PSTATE_MASK)
+#define clr_optee_pstate(state)	(state &= ~(OPTEE_PSTATE_MASK \
+					    << OPTEE_PSTATE_SHIFT))
+#define set_optee_pstate(st, pst) do {					       \
+					clr_optee_pstate(st);		       \
+					st |= (pst & OPTEE_PSTATE_MASK) <<     \
+						OPTEE_PSTATE_SHIFT;	       \
+				} while (0)
+
+
+/*******************************************************************************
+ * OPTEE execution state information i.e. aarch32 or aarch64
+ ******************************************************************************/
+#define OPTEE_AARCH32		MODE_RW_32
+#define OPTEE_AARCH64		MODE_RW_64
+
+/*******************************************************************************
+ * The OPTEED should know the type of OPTEE
+ ******************************************************************************/
+#define OPTEE_TYPE_UP		PSCI_TOS_NOT_UP_MIG_CAP
+#define OPTEE_TYPE_UPM		PSCI_TOS_UP_MIG_CAP
+#define OPTEE_TYPE_MP		PSCI_TOS_NOT_PRESENT_MP
+
+/*******************************************************************************
+ * OPTEE migrate type information as known to the OPTEED. We assume that
+ * the OPTEED is dealing with an MP Secure Payload.
+ ******************************************************************************/
+#define OPTEE_MIGRATE_INFO		OPTEE_TYPE_MP
+
+/*******************************************************************************
+ * Number of cpus that the present on this platform. TODO: Rely on a topology
+ * tree to determine this in the future to avoid assumptions about mpidr
+ * allocation
+ ******************************************************************************/
+#define OPTEED_CORE_COUNT		PLATFORM_CORE_COUNT
+
+/*******************************************************************************
+ * Constants that allow assembler code to preserve callee-saved registers of the
+ * C runtime context while performing a security state switch.
+ ******************************************************************************/
+#define OPTEED_C_RT_CTX_X19		0x0
+#define OPTEED_C_RT_CTX_X20		0x8
+#define OPTEED_C_RT_CTX_X21		0x10
+#define OPTEED_C_RT_CTX_X22		0x18
+#define OPTEED_C_RT_CTX_X23		0x20
+#define OPTEED_C_RT_CTX_X24		0x28
+#define OPTEED_C_RT_CTX_X25		0x30
+#define OPTEED_C_RT_CTX_X26		0x38
+#define OPTEED_C_RT_CTX_X27		0x40
+#define OPTEED_C_RT_CTX_X28		0x48
+#define OPTEED_C_RT_CTX_X29		0x50
+#define OPTEED_C_RT_CTX_X30		0x58
+#define OPTEED_C_RT_CTX_SIZE		0x60
+#define OPTEED_C_RT_CTX_ENTRIES		(OPTEED_C_RT_CTX_SIZE >> DWORD_SHIFT)
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <stdint.h>
+
+typedef uint32_t optee_vector_isn_t;
+
+typedef struct optee_vectors {
+	optee_vector_isn_t std_smc_entry;
+	optee_vector_isn_t fast_smc_entry;
+	optee_vector_isn_t cpu_on_entry;
+	optee_vector_isn_t cpu_off_entry;
+	optee_vector_isn_t cpu_resume_entry;
+	optee_vector_isn_t cpu_suspend_entry;
+	optee_vector_isn_t fiq_entry;
+	optee_vector_isn_t system_off_entry;
+	optee_vector_isn_t system_reset_entry;
+} optee_vectors_t;
+
+/*
+ * The number of arguments to save during a SMC call for OPTEE.
+ * Currently only x1 and x2 are used by OPTEE.
+ */
+#define OPTEE_NUM_ARGS	0x2
+
+/* AArch64 callee saved general purpose register context structure. */
+DEFINE_REG_STRUCT(c_rt_regs, OPTEED_C_RT_CTX_ENTRIES);
+
+/*
+ * Compile time assertion to ensure that both the compiler and linker
+ * have the same double word aligned view of the size of the C runtime
+ * register context.
+ */
+CASSERT(OPTEED_C_RT_CTX_SIZE == sizeof(c_rt_regs_t),	\
+	assert_spd_c_rt_regs_size_mismatch);
+
+/*******************************************************************************
+ * Structure which helps the OPTEED to maintain the per-cpu state of OPTEE.
+ * 'state'          - collection of flags to track OPTEE state e.g. on/off
+ * 'mpidr'          - mpidr to associate a context with a cpu
+ * 'c_rt_ctx'       - stack address to restore C runtime context from after
+ *                    returning from a synchronous entry into OPTEE.
+ * 'cpu_ctx'        - space to maintain OPTEE architectural state
+ ******************************************************************************/
+typedef struct optee_context {
+	uint32_t state;
+	uint64_t mpidr;
+	uint64_t c_rt_ctx;
+	cpu_context_t cpu_ctx;
+} optee_context_t;
+
+/* OPTEED power management handlers */
+extern const spd_pm_ops_t opteed_pm;
+
+/*******************************************************************************
+ * Forward declarations
+ ******************************************************************************/
+struct optee_vectors;
+
+/*******************************************************************************
+ * Function & Data prototypes
+ ******************************************************************************/
+uint64_t opteed_enter_sp(uint64_t *c_rt_ctx);
+void __dead2 opteed_exit_sp(uint64_t c_rt_ctx, uint64_t ret);
+uint64_t opteed_synchronous_sp_entry(optee_context_t *optee_ctx);
+void __dead2 opteed_synchronous_sp_exit(optee_context_t *optee_ctx, uint64_t ret);
+void opteed_init_optee_ep_state(struct entry_point_info *optee_ep,
+				uint32_t rw, uint64_t pc,
+				uint64_t paged_part, uint64_t mem_limit,
+				optee_context_t *optee_ctx);
+
+extern optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
+extern uint32_t opteed_rw;
+extern struct optee_vectors *optee_vectors;
+#endif /*__ASSEMBLY__*/
+
+#endif /* __OPTEED_PRIVATE_H__ */
diff --git a/uefi/arm-trusted-firmware/services/spd/opteed/teesmc_opteed.h b/uefi/arm-trusted-firmware/services/spd/opteed/teesmc_opteed.h
new file mode 100644
index 0000000..7968d1f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/opteed/teesmc_opteed.h
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+/* Copyright (c) 2014, Linaro Limited. All rights reserved. */
+
+#ifndef TEESMC_OPTEED_H
+#define TEESMC_OPTEED_H
+
+/*
+ * This file specify SMC function IDs used when returning from TEE to the
+ * secure monitor.
+ *
+ * All SMC Function IDs indicates SMC32 Calling Convention but will carry
+ * full 64 bit values in the argument registers if invoked from Aarch64
+ * mode. This violates the SMC Calling Convention, but since this
+ * convention only coveres API towards Normwal World it's something that
+ * only concerns the OP-TEE Dispatcher in ARM Trusted Firmware and OP-TEE
+ * OS at Secure EL1.
+ */
+
+/*
+ * Issued when returning from initial entry.
+ *
+ * Register usage:
+ * r0/x0	SMC Function ID, TEESMC_OPTEED_RETURN_ENTRY_DONE
+ * r1/x1	Pointer to entry vector
+ */
+#define TEESMC_OPTEED_FUNCID_RETURN_ENTRY_DONE		0
+#define TEESMC_OPTEED_RETURN_ENTRY_DONE \
+	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_ENTRY_DONE)
+
+
+
+/*
+ * Issued when returning from "cpu_on" vector
+ *
+ * Register usage:
+ * r0/x0	SMC Function ID, TEESMC_OPTEED_RETURN_ON_DONE
+ * r1/x1	0 on success and anything else to indicate error condition
+ */
+#define TEESMC_OPTEED_FUNCID_RETURN_ON_DONE		1
+#define TEESMC_OPTEED_RETURN_ON_DONE \
+	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_ON_DONE)
+
+/*
+ * Issued when returning from "cpu_off" vector
+ *
+ * Register usage:
+ * r0/x0	SMC Function ID, TEESMC_OPTEED_RETURN_OFF_DONE
+ * r1/x1	0 on success and anything else to indicate error condition
+ */
+#define TEESMC_OPTEED_FUNCID_RETURN_OFF_DONE		2
+#define TEESMC_OPTEED_RETURN_OFF_DONE \
+	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_OFF_DONE)
+
+/*
+ * Issued when returning from "cpu_suspend" vector
+ *
+ * Register usage:
+ * r0/x0	SMC Function ID, TEESMC_OPTEED_RETURN_SUSPEND_DONE
+ * r1/x1	0 on success and anything else to indicate error condition
+ */
+#define TEESMC_OPTEED_FUNCID_RETURN_SUSPEND_DONE	3
+#define TEESMC_OPTEED_RETURN_SUSPEND_DONE \
+	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_SUSPEND_DONE)
+
+/*
+ * Issued when returning from "cpu_resume" vector
+ *
+ * Register usage:
+ * r0/x0	SMC Function ID, TEESMC_OPTEED_RETURN_RESUME_DONE
+ * r1/x1	0 on success and anything else to indicate error condition
+ */
+#define TEESMC_OPTEED_FUNCID_RETURN_RESUME_DONE		4
+#define TEESMC_OPTEED_RETURN_RESUME_DONE \
+	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_RESUME_DONE)
+
+/*
+ * Issued when returning from "std_smc" or "fast_smc" vector
+ *
+ * Register usage:
+ * r0/x0	SMC Function ID, TEESMC_OPTEED_RETURN_CALL_DONE
+ * r1-4/x1-4	Return value 0-3 which will passed to normal world in
+ *		r0-3/x0-3
+ */
+#define TEESMC_OPTEED_FUNCID_RETURN_CALL_DONE		5
+#define TEESMC_OPTEED_RETURN_CALL_DONE \
+	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_CALL_DONE)
+
+/*
+ * Issued when returning from "fiq" vector
+ *
+ * Register usage:
+ * r0/x0	SMC Function ID, TEESMC_OPTEED_RETURN_FIQ_DONE
+ */
+#define TEESMC_OPTEED_FUNCID_RETURN_FIQ_DONE		6
+#define TEESMC_OPTEED_RETURN_FIQ_DONE \
+	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_FIQ_DONE)
+
+/*
+ * Issued when returning from "system_off" vector
+ *
+ * Register usage:
+ * r0/x0	SMC Function ID, TEESMC_OPTEED_RETURN_SYSTEM_OFF_DONE
+ */
+#define TEESMC_OPTEED_FUNCID_RETURN_SYSTEM_OFF_DONE	7
+#define TEESMC_OPTEED_RETURN_SYSTEM_OFF_DONE \
+	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_SYSTEM_OFF_DONE)
+
+/*
+ * Issued when returning from "system_reset" vector
+ *
+ * Register usage:
+ * r0/x0	SMC Function ID, TEESMC_OPTEED_RETURN_SYSTEM_RESET_DONE
+ */
+#define TEESMC_OPTEED_FUNCID_RETURN_SYSTEM_RESET_DONE	8
+#define TEESMC_OPTEED_RETURN_SYSTEM_RESET_DONE \
+	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_SYSTEM_RESET_DONE)
+
+#endif /*TEESMC_OPTEED_H*/
diff --git a/uefi/arm-trusted-firmware/services/spd/opteed/teesmc_opteed_macros.h b/uefi/arm-trusted-firmware/services/spd/opteed/teesmc_opteed_macros.h
new file mode 100644
index 0000000..2453c9a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/opteed/teesmc_opteed_macros.h
@@ -0,0 +1,41 @@
+/*
+ * 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 __TEESMC_OPTEED_MACROS_H__
+#define __TEESMC_OPTEED_MACROS_H__
+
+#include <runtime_svc.h>
+
+#define TEESMC_OPTEED_RV(func_num) \
+		((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+		 ((SMC_32) << FUNCID_CC_SHIFT) | \
+		 (62 << FUNCID_OEN_SHIFT) | \
+		 ((func_num) & FUNCID_NUM_MASK))
+
+#endif /*__TEESMC_OPTEED_MACROS_H__*/
diff --git a/uefi/arm-trusted-firmware/services/spd/tspd/tspd.mk b/uefi/arm-trusted-firmware/services/spd/tspd/tspd.mk
new file mode 100644
index 0000000..139c7d7
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/tspd/tspd.mk
@@ -0,0 +1,61 @@
+#
+# 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.
+#
+
+TSPD_DIR		:=	services/spd/tspd
+SPD_INCLUDES		:=	-Iinclude/bl32/tsp
+
+SPD_SOURCES		:=	services/spd/tspd/tspd_common.c		\
+				services/spd/tspd/tspd_helpers.S	\
+				services/spd/tspd/tspd_main.c		\
+				services/spd/tspd/tspd_pm.c
+
+# This dispatcher is paired with a Test Secure Payload source and we intend to
+# build the Test Secure Payload along with this dispatcher.
+#
+# In cases where an associated Secure Payload lies outside this build
+# system/source tree, the the dispatcher Makefile can either invoke an external
+# build command or assume it pre-built
+
+BL32_ROOT		:=	bl32/tsp
+
+# Include SP's Makefile. The assumption is that the TSP's build system is
+# compatible with that of Trusted Firmware, and it'll add and populate necessary
+# build targets and variables
+include ${BL32_ROOT}/tsp.mk
+
+# Let the top-level Makefile know that we intend to build the SP from source
+NEED_BL32		:=	yes
+
+# Flag used to enable routing of non-secure interrupts to EL3 when they are
+# generated while the code is executing in S-EL1/0.
+TSPD_ROUTE_IRQ_TO_EL3	:=	0
+
+$(eval $(call assert_boolean,TSPD_ROUTE_IRQ_TO_EL3))
+$(eval $(call add_define,TSPD_ROUTE_IRQ_TO_EL3))
diff --git a/uefi/arm-trusted-firmware/services/spd/tspd/tspd_common.c b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_common.c
new file mode 100644
index 0000000..322413c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_common.c
@@ -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 <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <context_mgmt.h>
+#include <string.h>
+#include "tspd_private.h"
+
+/*******************************************************************************
+ * Given a secure payload entrypoint info pointer, entry point PC, register
+ * width, cpu id & pointer to a context data structure, this function will
+ * initialize tsp context and entry point info for the secure payload
+ ******************************************************************************/
+void tspd_init_tsp_ep_state(struct entry_point_info *tsp_entry_point,
+				uint32_t rw,
+				uint64_t pc,
+				tsp_context_t *tsp_ctx)
+{
+	uint32_t ep_attr;
+
+	/* Passing a NULL context is a critical programming error */
+	assert(tsp_ctx);
+	assert(tsp_entry_point);
+	assert(pc);
+
+	/*
+	 * We support AArch64 TSP for now.
+	 * TODO: Add support for AArch32 TSP
+	 */
+	assert(rw == TSP_AARCH64);
+
+	/* Associate this context with the cpu specified */
+	tsp_ctx->mpidr = read_mpidr_el1();
+	tsp_ctx->state = 0;
+	set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_OFF);
+	clr_std_smc_active_flag(tsp_ctx->state);
+
+	cm_set_context(&tsp_ctx->cpu_ctx, SECURE);
+
+	/* initialise an entrypoint to set up the CPU context */
+	ep_attr = SECURE | EP_ST_ENABLE;
+	if (read_sctlr_el3() & SCTLR_EE_BIT)
+		ep_attr |= EP_EE_BIG;
+	SET_PARAM_HEAD(tsp_entry_point, PARAM_EP, VERSION_1, ep_attr);
+
+	tsp_entry_point->pc = pc;
+	tsp_entry_point->spsr = SPSR_64(MODE_EL1,
+					MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS);
+	memset(&tsp_entry_point->args, 0, sizeof(tsp_entry_point->args));
+}
+
+/*******************************************************************************
+ * This function takes an SP context pointer and:
+ * 1. Applies the S-EL1 system register context from tsp_ctx->cpu_ctx.
+ * 2. Saves the current C runtime state (callee saved registers) on the stack
+ *    frame and saves a reference to this state.
+ * 3. Calls el3_exit() so that the EL3 system and general purpose registers
+ *    from the tsp_ctx->cpu_ctx are used to enter the secure payload image.
+ ******************************************************************************/
+uint64_t tspd_synchronous_sp_entry(tsp_context_t *tsp_ctx)
+{
+	uint64_t rc;
+
+	assert(tsp_ctx != NULL);
+	assert(tsp_ctx->c_rt_ctx == 0);
+
+	/* Apply the Secure EL1 system register context and switch to it */
+	assert(cm_get_context(SECURE) == &tsp_ctx->cpu_ctx);
+	cm_el1_sysregs_context_restore(SECURE);
+	cm_set_next_eret_context(SECURE);
+
+	rc = tspd_enter_sp(&tsp_ctx->c_rt_ctx);
+#if DEBUG
+	tsp_ctx->c_rt_ctx = 0;
+#endif
+
+	return rc;
+}
+
+
+/*******************************************************************************
+ * This function takes an SP context pointer and:
+ * 1. Saves the S-EL1 system register context tp tsp_ctx->cpu_ctx.
+ * 2. Restores the current C runtime state (callee saved registers) from the
+ *    stack frame using the reference to this state saved in tspd_enter_sp().
+ * 3. It does not need to save any general purpose or EL3 system register state
+ *    as the generic smc entry routine should have saved those.
+ ******************************************************************************/
+void tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret)
+{
+	assert(tsp_ctx != NULL);
+	/* Save the Secure EL1 system register context */
+	assert(cm_get_context(SECURE) == &tsp_ctx->cpu_ctx);
+	cm_el1_sysregs_context_save(SECURE);
+
+	assert(tsp_ctx->c_rt_ctx != 0);
+	tspd_exit_sp(tsp_ctx->c_rt_ctx, ret);
+
+	/* Should never reach here */
+	assert(0);
+}
diff --git a/uefi/arm-trusted-firmware/services/spd/tspd/tspd_helpers.S b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_helpers.S
new file mode 100644
index 0000000..dd3b07b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_helpers.S
@@ -0,0 +1,101 @@
+/*
+ * 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 "tspd_private.h"
+
+	.global	tspd_enter_sp
+	/* ---------------------------------------------
+	 * This function is called with SP_EL0 as stack.
+	 * Here we stash our EL3 callee-saved registers
+	 * on to the stack as a part of saving the C
+	 * runtime and enter the secure payload.
+	 * 'x0' contains a pointer to the memory where
+	 * the address of the C runtime context is to be
+	 * saved.
+	 * ---------------------------------------------
+	 */
+func tspd_enter_sp
+	/* Make space for the registers that we're going to save */
+	mov	x3, sp
+	str	x3, [x0, #0]
+	sub	sp, sp, #TSPD_C_RT_CTX_SIZE
+
+	/* Save callee-saved registers on to the stack */
+	stp	x19, x20, [sp, #TSPD_C_RT_CTX_X19]
+	stp	x21, x22, [sp, #TSPD_C_RT_CTX_X21]
+	stp	x23, x24, [sp, #TSPD_C_RT_CTX_X23]
+	stp	x25, x26, [sp, #TSPD_C_RT_CTX_X25]
+	stp	x27, x28, [sp, #TSPD_C_RT_CTX_X27]
+	stp	x29, x30, [sp, #TSPD_C_RT_CTX_X29]
+
+	/* ---------------------------------------------
+	 * Everything is setup now. el3_exit() will
+	 * use the secure context to restore to the
+	 * general purpose and EL3 system registers to
+	 * ERET into the secure payload.
+	 * ---------------------------------------------
+	 */
+	b	el3_exit
+
+	/* ---------------------------------------------
+	 * This function is called 'x0' pointing to a C
+	 * runtime context saved in tspd_enter_sp().  It
+	 * restores the saved registers and jumps to
+	 * that runtime with 'x0' as the new sp. This
+	 * destroys the C runtime context that had been
+	 * built on the stack below the saved context by
+	 * the caller. Later the second parameter 'x1'
+	 * is passed as return value to the caller
+	 * ---------------------------------------------
+	 */
+	.global tspd_exit_sp
+func tspd_exit_sp
+	/* Restore the previous stack */
+	mov	sp, x0
+
+	/* Restore callee-saved registers on to the stack */
+	ldp	x19, x20, [x0, #(TSPD_C_RT_CTX_X19 - TSPD_C_RT_CTX_SIZE)]
+	ldp	x21, x22, [x0, #(TSPD_C_RT_CTX_X21 - TSPD_C_RT_CTX_SIZE)]
+	ldp	x23, x24, [x0, #(TSPD_C_RT_CTX_X23 - TSPD_C_RT_CTX_SIZE)]
+	ldp	x25, x26, [x0, #(TSPD_C_RT_CTX_X25 - TSPD_C_RT_CTX_SIZE)]
+	ldp	x27, x28, [x0, #(TSPD_C_RT_CTX_X27 - TSPD_C_RT_CTX_SIZE)]
+	ldp	x29, x30, [x0, #(TSPD_C_RT_CTX_X29 - TSPD_C_RT_CTX_SIZE)]
+
+	/* ---------------------------------------------
+	 * This should take us back to the instruction
+	 * after the call to the last tspd_enter_sp().
+	 * Place the second parameter to x0 so that the
+	 * caller will see it as a return value from the
+	 * original entry call
+	 * ---------------------------------------------
+	 */
+	mov	x0, x1
+	ret
diff --git a/uefi/arm-trusted-firmware/services/spd/tspd/tspd_main.c b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_main.c
new file mode 100644
index 0000000..ee17483
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_main.c
@@ -0,0 +1,724 @@
+/*
+ * 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.
+ */
+
+
+/*******************************************************************************
+ * This is the Secure Payload Dispatcher (SPD). The dispatcher is meant to be a
+ * plug-in component to the Secure Monitor, registered as a runtime service. The
+ * SPD is expected to be a functional extension of the Secure Payload (SP) that
+ * executes in Secure EL1. The Secure Monitor will delegate all SMCs targeting
+ * the Trusted OS/Applications range to the dispatcher. The SPD will either
+ * handle the request locally or delegate it to the Secure Payload. It is also
+ * responsible for initialising and maintaining communication with the SP.
+ ******************************************************************************/
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <bl31.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <errno.h>
+#include <platform.h>
+#include <runtime_svc.h>
+#include <stddef.h>
+#include <string.h>
+#include <tsp.h>
+#include <uuid.h>
+#include "tspd_private.h"
+
+/*******************************************************************************
+ * Address of the entrypoint vector table in the Secure Payload. It is
+ * initialised once on the primary core after a cold boot.
+ ******************************************************************************/
+tsp_vectors_t *tsp_vectors;
+
+/*******************************************************************************
+ * Array to keep track of per-cpu Secure Payload state
+ ******************************************************************************/
+tsp_context_t tspd_sp_context[TSPD_CORE_COUNT];
+
+
+/* TSP UID */
+DEFINE_SVC_UUID(tsp_uuid,
+		0x5b3056a0, 0x3291, 0x427b, 0x98, 0x11,
+		0x71, 0x68, 0xca, 0x50, 0xf3, 0xfa);
+
+int32_t tspd_init(void);
+
+uint64_t tspd_handle_sp_preemption(void *handle)
+{
+	cpu_context_t *ns_cpu_context;
+	assert(handle == cm_get_context(SECURE));
+	cm_el1_sysregs_context_save(SECURE);
+	/* Get a reference to the non-secure context */
+	ns_cpu_context = cm_get_context(NON_SECURE);
+	assert(ns_cpu_context);
+
+	/*
+	 * Restore non-secure state. The secure system
+	 * register context will be saved when required.
+	 */
+	cm_el1_sysregs_context_restore(NON_SECURE);
+	cm_set_next_eret_context(NON_SECURE);
+
+	SMC_RET1(ns_cpu_context, SMC_PREEMPTED);
+}
+/*******************************************************************************
+ * This function is the handler registered for S-EL1 interrupts by the TSPD. It
+ * validates the interrupt and upon success arranges entry into the TSP at
+ * 'tsp_fiq_entry()' for handling the interrupt.
+ ******************************************************************************/
+static uint64_t tspd_sel1_interrupt_handler(uint32_t id,
+					    uint32_t flags,
+					    void *handle,
+					    void *cookie)
+{
+	uint32_t linear_id;
+	uint64_t mpidr;
+	tsp_context_t *tsp_ctx;
+
+	/* Check the security state when the exception was generated */
+	assert(get_interrupt_src_ss(flags) == NON_SECURE);
+
+#if IMF_READ_INTERRUPT_ID
+	/* Check the security status of the interrupt */
+	assert(plat_ic_get_interrupt_type(id) == INTR_TYPE_S_EL1);
+#endif
+
+	/* Sanity check the pointer to this cpu's context */
+	mpidr = read_mpidr();
+	assert(handle == cm_get_context(NON_SECURE));
+
+	/* Save the non-secure context before entering the TSP */
+	cm_el1_sysregs_context_save(NON_SECURE);
+
+	/* Get a reference to this cpu's TSP context */
+	linear_id = platform_get_core_pos(mpidr);
+	tsp_ctx = &tspd_sp_context[linear_id];
+	assert(&tsp_ctx->cpu_ctx == cm_get_context(SECURE));
+
+	/*
+	 * Determine if the TSP was previously preempted. Its last known
+	 * context has to be preserved in this case.
+	 * The TSP should return control to the TSPD after handling this
+	 * FIQ. Preserve essential EL3 context to allow entry into the
+	 * TSP at the FIQ entry point using the 'cpu_context' structure.
+	 * There is no need to save the secure system register context
+	 * since the TSP is supposed to preserve it during S-EL1 interrupt
+	 * handling.
+	 */
+	if (get_std_smc_active_flag(tsp_ctx->state)) {
+		tsp_ctx->saved_spsr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx,
+						      CTX_SPSR_EL3);
+		tsp_ctx->saved_elr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx,
+						     CTX_ELR_EL3);
+#if TSPD_ROUTE_IRQ_TO_EL3
+		/*Need to save the previously interrupted secure context */
+		memcpy(&tsp_ctx->sp_ctx, &tsp_ctx->cpu_ctx, TSPD_SP_CTX_SIZE);
+#endif
+	}
+
+	cm_el1_sysregs_context_restore(SECURE);
+	cm_set_elr_spsr_el3(SECURE, (uint64_t) &tsp_vectors->fiq_entry,
+		    SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
+
+	cm_set_next_eret_context(SECURE);
+
+	/*
+	 * Tell the TSP that it has to handle an FIQ synchronously. Also the
+	 * instruction in normal world where the interrupt was generated is
+	 * passed for debugging purposes. It is safe to retrieve this address
+	 * from ELR_EL3 as the secure context will not take effect until
+	 * el3_exit().
+	 */
+	SMC_RET2(&tsp_ctx->cpu_ctx, TSP_HANDLE_FIQ_AND_RETURN, read_elr_el3());
+}
+
+#if TSPD_ROUTE_IRQ_TO_EL3
+/*******************************************************************************
+ * This function is the handler registered for S-EL1 interrupts by the TSPD. It
+ * validates the interrupt and upon success arranges entry into the TSP at
+ * 'tsp_fiq_entry()' for handling the interrupt.
+ ******************************************************************************/
+static uint64_t tspd_ns_interrupt_handler(uint32_t id,
+					    uint32_t flags,
+					    void *handle,
+					    void *cookie)
+{
+	/* Check the security state when the exception was generated */
+	assert(get_interrupt_src_ss(flags) == SECURE);
+
+#if IMF_READ_INTERRUPT_ID
+	/* Check the security status of the interrupt */
+	assert(plat_ic_get_interrupt_type(id) == INTR_TYPE_NS);
+#endif
+	/*
+	 * Disable the routing of NS interrupts from secure world to EL3 while
+	 * interrupted on this core.
+	 */
+	disable_intr_rm_local(INTR_TYPE_NS, SECURE);
+
+	return tspd_handle_sp_preemption(handle);
+}
+#endif
+
+/*******************************************************************************
+ * Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type
+ * (aarch32/aarch64) if not already known and initialises the context for entry
+ * into the SP for its initialisation.
+ ******************************************************************************/
+int32_t tspd_setup(void)
+{
+	entry_point_info_t *tsp_ep_info;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id;
+
+	linear_id = platform_get_core_pos(mpidr);
+
+	/*
+	 * Get information about the Secure Payload (BL32) image. Its
+	 * absence is a critical failure.  TODO: Add support to
+	 * conditionally include the SPD service
+	 */
+	tsp_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
+	if (!tsp_ep_info) {
+		WARN("No TSP provided by BL2 boot loader, Booting device"
+			" without TSP initialization. SMC`s destined for TSP"
+			" will return SMC_UNK\n");
+		return 1;
+	}
+
+	/*
+	 * If there's no valid entry point for SP, we return a non-zero value
+	 * signalling failure initializing the service. We bail out without
+	 * registering any handlers
+	 */
+	if (!tsp_ep_info->pc)
+		return 1;
+
+	/*
+	 * We could inspect the SP image and determine it's execution
+	 * state i.e whether AArch32 or AArch64. Assuming it's AArch64
+	 * for the time being.
+	 */
+	tspd_init_tsp_ep_state(tsp_ep_info,
+				TSP_AARCH64,
+				tsp_ep_info->pc,
+				&tspd_sp_context[linear_id]);
+
+#if TSP_INIT_ASYNC
+	bl31_set_next_image_type(SECURE);
+#else
+	/*
+	 * All TSPD initialization done. Now register our init function with
+	 * BL31 for deferred invocation
+	 */
+	bl31_register_bl32_init(&tspd_init);
+#endif
+	return 0;
+}
+
+/*******************************************************************************
+ * This function passes control to the Secure Payload image (BL32) for the first
+ * time on the primary cpu after a cold boot. It assumes that a valid secure
+ * context has already been created by tspd_setup() which can be directly used.
+ * It also assumes that a valid non-secure context has been initialised by PSCI
+ * so it does not need to save and restore any non-secure state. This function
+ * performs a synchronous entry into the Secure payload. The SP passes control
+ * back to this routine through a SMC.
+ ******************************************************************************/
+int32_t tspd_init(void)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
+	entry_point_info_t *tsp_entry_point;
+	uint64_t rc;
+
+	/*
+	 * Get information about the Secure Payload (BL32) image. Its
+	 * absence is a critical failure.
+	 */
+	tsp_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
+	assert(tsp_entry_point);
+
+	cm_init_context(mpidr, tsp_entry_point);
+
+	/*
+	 * Arrange for an entry into the test secure payload. It will be
+	 * returned via TSP_ENTRY_DONE case
+	 */
+	rc = tspd_synchronous_sp_entry(tsp_ctx);
+	assert(rc != 0);
+
+	return rc;
+}
+
+
+/*******************************************************************************
+ * This function is responsible for handling all SMCs in the Trusted OS/App
+ * range from the non-secure state as defined in the SMC Calling Convention
+ * Document. It is also responsible for communicating with the Secure payload
+ * to delegate work and return results back to the non-secure state. Lastly it
+ * will also return any information that the secure payload needs to do the
+ * work assigned to it.
+ ******************************************************************************/
+uint64_t tspd_smc_handler(uint32_t smc_fid,
+			 uint64_t x1,
+			 uint64_t x2,
+			 uint64_t x3,
+			 uint64_t x4,
+			 void *cookie,
+			 void *handle,
+			 uint64_t flags)
+{
+	cpu_context_t *ns_cpu_context;
+	unsigned long mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr), ns;
+	tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
+	uint64_t rc;
+#if TSP_INIT_ASYNC
+	entry_point_info_t *next_image_info;
+#endif
+
+	/* Determine which security state this SMC originated from */
+	ns = is_caller_non_secure(flags);
+
+	switch (smc_fid) {
+
+	/*
+	 * This function ID is used by TSP to indicate that it was
+	 * preempted by a normal world IRQ.
+	 *
+	 */
+	case TSP_PREEMPTED:
+		if (ns)
+			SMC_RET1(handle, SMC_UNK);
+
+		return tspd_handle_sp_preemption(handle);
+
+	/*
+	 * This function ID is used only by the TSP to indicate that it has
+	 * finished handling a S-EL1 FIQ interrupt. Execution should resume
+	 * in the normal world.
+	 */
+	case TSP_HANDLED_S_EL1_FIQ:
+		if (ns)
+			SMC_RET1(handle, SMC_UNK);
+
+		assert(handle == cm_get_context(SECURE));
+
+		/*
+		 * Restore the relevant EL3 state which saved to service
+		 * this SMC.
+		 */
+		if (get_std_smc_active_flag(tsp_ctx->state)) {
+			SMC_SET_EL3(&tsp_ctx->cpu_ctx,
+				    CTX_SPSR_EL3,
+				    tsp_ctx->saved_spsr_el3);
+			SMC_SET_EL3(&tsp_ctx->cpu_ctx,
+				    CTX_ELR_EL3,
+				    tsp_ctx->saved_elr_el3);
+#if TSPD_ROUTE_IRQ_TO_EL3
+			/*
+			 * Need to restore the previously interrupted
+			 * secure context.
+			 */
+			memcpy(&tsp_ctx->cpu_ctx, &tsp_ctx->sp_ctx,
+				TSPD_SP_CTX_SIZE);
+#endif
+		}
+
+		/* Get a reference to the non-secure context */
+		ns_cpu_context = cm_get_context(NON_SECURE);
+		assert(ns_cpu_context);
+
+		/*
+		 * Restore non-secure state. There is no need to save the
+		 * secure system register context since the TSP was supposed
+		 * to preserve it during S-EL1 interrupt handling.
+		 */
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+
+		SMC_RET0((uint64_t) ns_cpu_context);
+
+
+	/*
+	 * This function ID is used only by the TSP to indicate that it was
+	 * interrupted due to a EL3 FIQ interrupt. Execution should resume
+	 * in the normal world.
+	 */
+	case TSP_EL3_FIQ:
+		if (ns)
+			SMC_RET1(handle, SMC_UNK);
+
+		assert(handle == cm_get_context(SECURE));
+
+		/* Assert that standard SMC execution has been preempted */
+		assert(get_std_smc_active_flag(tsp_ctx->state));
+
+		/* Save the secure system register state */
+		cm_el1_sysregs_context_save(SECURE);
+
+		/* Get a reference to the non-secure context */
+		ns_cpu_context = cm_get_context(NON_SECURE);
+		assert(ns_cpu_context);
+
+		/* Restore non-secure state */
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+
+		SMC_RET1(ns_cpu_context, TSP_EL3_FIQ);
+
+
+	/*
+	 * This function ID is used only by the SP to indicate it has
+	 * finished initialising itself after a cold boot
+	 */
+	case TSP_ENTRY_DONE:
+		if (ns)
+			SMC_RET1(handle, SMC_UNK);
+
+		/*
+		 * Stash the SP entry points information. This is done
+		 * only once on the primary cpu
+		 */
+		assert(tsp_vectors == NULL);
+		tsp_vectors = (tsp_vectors_t *) x1;
+
+		if (tsp_vectors) {
+			set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON);
+
+			/*
+			 * TSP has been successfully initialized. Register power
+			 * managemnt hooks with PSCI
+			 */
+			psci_register_spd_pm_hook(&tspd_pm);
+
+			/*
+			 * Register an interrupt handler for S-EL1 interrupts
+			 * when generated during code executing in the
+			 * non-secure state.
+			 */
+			flags = 0;
+			set_interrupt_rm_flag(flags, NON_SECURE);
+			rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+						tspd_sel1_interrupt_handler,
+						flags);
+			if (rc)
+				panic();
+
+#if TSPD_ROUTE_IRQ_TO_EL3
+			/*
+			 * Register an interrupt handler for NS interrupts when
+			 * generated during code executing in secure state are
+			 * routed to EL3.
+			 */
+			flags = 0;
+			set_interrupt_rm_flag(flags, SECURE);
+
+			rc = register_interrupt_type_handler(INTR_TYPE_NS,
+						tspd_ns_interrupt_handler,
+						flags);
+			if (rc)
+				panic();
+
+			/*
+			 * Disable the interrupt NS locally since it will be enabled globally
+			 * within cm_init_context.
+			 */
+			disable_intr_rm_local(INTR_TYPE_NS, SECURE);
+#endif
+		}
+
+
+#if TSP_INIT_ASYNC
+		/* Save the Secure EL1 system register context */
+		assert(cm_get_context(SECURE) == &tsp_ctx->cpu_ctx);
+		cm_el1_sysregs_context_save(SECURE);
+
+		/* Program EL3 registers to enable entry into the next EL */
+		next_image_info = bl31_plat_get_next_image_ep_info(NON_SECURE);
+		assert(next_image_info);
+		assert(NON_SECURE ==
+				GET_SECURITY_STATE(next_image_info->h.attr));
+
+		cm_init_context(read_mpidr_el1(), next_image_info);
+		cm_prepare_el3_exit(NON_SECURE);
+		SMC_RET0(cm_get_context(NON_SECURE));
+#else
+		/*
+		 * SP reports completion. The SPD must have initiated
+		 * the original request through a synchronous entry
+		 * into the SP. Jump back to the original C runtime
+		 * context.
+		 */
+		tspd_synchronous_sp_exit(tsp_ctx, x1);
+#endif
+
+	/*
+	 * These function IDs is used only by the SP to indicate it has
+	 * finished:
+	 * 1. turning itself on in response to an earlier psci
+	 *    cpu_on request
+	 * 2. resuming itself after an earlier psci cpu_suspend
+	 *    request.
+	 */
+	case TSP_ON_DONE:
+	case TSP_RESUME_DONE:
+
+	/*
+	 * These function IDs is used only by the SP to indicate it has
+	 * finished:
+	 * 1. suspending itself after an earlier psci cpu_suspend
+	 *    request.
+	 * 2. turning itself off in response to an earlier psci
+	 *    cpu_off request.
+	 */
+	case TSP_OFF_DONE:
+	case TSP_SUSPEND_DONE:
+	case TSP_SYSTEM_OFF_DONE:
+	case TSP_SYSTEM_RESET_DONE:
+		if (ns)
+			SMC_RET1(handle, SMC_UNK);
+
+		/*
+		 * SP reports completion. The SPD must have initiated the
+		 * original request through a synchronous entry into the SP.
+		 * Jump back to the original C runtime context, and pass x1 as
+		 * return value to the caller
+		 */
+		tspd_synchronous_sp_exit(tsp_ctx, x1);
+
+		/*
+		 * Request from non-secure client to perform an
+		 * arithmetic operation or response from secure
+		 * payload to an earlier request.
+		 */
+	case TSP_FAST_FID(TSP_ADD):
+	case TSP_FAST_FID(TSP_SUB):
+	case TSP_FAST_FID(TSP_MUL):
+	case TSP_FAST_FID(TSP_DIV):
+
+	case TSP_STD_FID(TSP_ADD):
+	case TSP_STD_FID(TSP_SUB):
+	case TSP_STD_FID(TSP_MUL):
+	case TSP_STD_FID(TSP_DIV):
+		if (ns) {
+			/*
+			 * This is a fresh request from the non-secure client.
+			 * The parameters are in x1 and x2. Figure out which
+			 * registers need to be preserved, save the non-secure
+			 * state and send the request to the secure payload.
+			 */
+			assert(handle == cm_get_context(NON_SECURE));
+
+			/* Check if we are already preempted */
+			if (get_std_smc_active_flag(tsp_ctx->state))
+				SMC_RET1(handle, SMC_UNK);
+
+			cm_el1_sysregs_context_save(NON_SECURE);
+
+			/* Save x1 and x2 for use by TSP_GET_ARGS call below */
+			store_tsp_args(tsp_ctx, x1, x2);
+
+			/*
+			 * We are done stashing the non-secure context. Ask the
+			 * secure payload to do the work now.
+			 */
+
+			/*
+			 * Verify if there is a valid context to use, copy the
+			 * operation type and parameters to the secure context
+			 * and jump to the fast smc entry point in the secure
+			 * payload. Entry into S-EL1 will take place upon exit
+			 * from this function.
+			 */
+			assert(&tsp_ctx->cpu_ctx == cm_get_context(SECURE));
+
+			/* Set appropriate entry for SMC.
+			 * We expect the TSP to manage the PSTATE.I and PSTATE.F
+			 * flags as appropriate.
+			 */
+			if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_FAST) {
+				cm_set_elr_el3(SECURE, (uint64_t)
+						&tsp_vectors->fast_smc_entry);
+			} else {
+				set_std_smc_active_flag(tsp_ctx->state);
+				cm_set_elr_el3(SECURE, (uint64_t)
+						&tsp_vectors->std_smc_entry);
+#if TSPD_ROUTE_IRQ_TO_EL3
+				/*
+				 * Enable the routing of NS interrupts to EL3
+				 * during STD SMC processing on this core.
+				 */
+				enable_intr_rm_local(INTR_TYPE_NS, SECURE);
+#endif
+			}
+
+			cm_el1_sysregs_context_restore(SECURE);
+			cm_set_next_eret_context(SECURE);
+			SMC_RET3(&tsp_ctx->cpu_ctx, smc_fid, x1, x2);
+		} else {
+			/*
+			 * This is the result from the secure client of an
+			 * earlier request. The results are in x1-x3. Copy it
+			 * into the non-secure context, save the secure state
+			 * and return to the non-secure state.
+			 */
+			assert(handle == cm_get_context(SECURE));
+			cm_el1_sysregs_context_save(SECURE);
+
+			/* Get a reference to the non-secure context */
+			ns_cpu_context = cm_get_context(NON_SECURE);
+			assert(ns_cpu_context);
+
+			/* Restore non-secure state */
+			cm_el1_sysregs_context_restore(NON_SECURE);
+			cm_set_next_eret_context(NON_SECURE);
+			if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_STD) {
+				clr_std_smc_active_flag(tsp_ctx->state);
+#if TSPD_ROUTE_IRQ_TO_EL3
+				/*
+				 * Disable the routing of NS interrupts to EL3
+				 * after STD SMC processing is finished on this
+				 * core.
+				 */
+				disable_intr_rm_local(INTR_TYPE_NS, SECURE);
+#endif
+			}
+
+			SMC_RET3(ns_cpu_context, x1, x2, x3);
+		}
+
+		break;
+
+		/*
+		 * Request from non secure world to resume the preempted
+		 * Standard SMC call.
+		 */
+	case TSP_FID_RESUME:
+		/* RESUME should be invoked only by normal world */
+		if (!ns) {
+			assert(0);
+			break;
+		}
+
+		/*
+		 * This is a resume request from the non-secure client.
+		 * save the non-secure state and send the request to
+		 * the secure payload.
+		 */
+		assert(handle == cm_get_context(NON_SECURE));
+
+		/* Check if we are already preempted before resume */
+		if (!get_std_smc_active_flag(tsp_ctx->state))
+			SMC_RET1(handle, SMC_UNK);
+
+		cm_el1_sysregs_context_save(NON_SECURE);
+
+		/*
+		 * We are done stashing the non-secure context. Ask the
+		 * secure payload to do the work now.
+		 */
+#if TSPD_ROUTE_IRQ_TO_EL3
+		/*
+		 * Enable the routing of NS interrupts to EL3 during resumption
+		 * of STD SMC call on this core.
+		 */
+		enable_intr_rm_local(INTR_TYPE_NS, SECURE);
+#endif
+
+
+
+		/* We just need to return to the preempted point in
+		 * TSP and the execution will resume as normal.
+		 */
+		cm_el1_sysregs_context_restore(SECURE);
+		cm_set_next_eret_context(SECURE);
+		SMC_RET0(&tsp_ctx->cpu_ctx);
+
+		/*
+		 * This is a request from the secure payload for more arguments
+		 * for an ongoing arithmetic operation requested by the
+		 * non-secure world. Simply return the arguments from the non-
+		 * secure client in the original call.
+		 */
+	case TSP_GET_ARGS:
+		if (ns)
+			SMC_RET1(handle, SMC_UNK);
+
+		get_tsp_args(tsp_ctx, x1, x2);
+		SMC_RET2(handle, x1, x2);
+
+	case TOS_CALL_COUNT:
+		/*
+		 * Return the number of service function IDs implemented to
+		 * provide service to non-secure
+		 */
+		SMC_RET1(handle, TSP_NUM_FID);
+
+	case TOS_UID:
+		/* Return TSP UID to the caller */
+		SMC_UUID_RET(handle, tsp_uuid);
+
+	case TOS_CALL_VERSION:
+		/* Return the version of current implementation */
+		SMC_RET2(handle, TSP_VERSION_MAJOR, TSP_VERSION_MINOR);
+
+	default:
+		break;
+	}
+
+	SMC_RET1(handle, SMC_UNK);
+}
+
+/* Define a SPD runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+	tspd_fast,
+
+	OEN_TOS_START,
+	OEN_TOS_END,
+	SMC_TYPE_FAST,
+	tspd_setup,
+	tspd_smc_handler
+);
+
+/* Define a SPD runtime service descriptor for standard SMC calls */
+DECLARE_RT_SVC(
+	tspd_std,
+
+	OEN_TOS_START,
+	OEN_TOS_END,
+	SMC_TYPE_STD,
+	NULL,
+	tspd_smc_handler
+);
diff --git a/uefi/arm-trusted-firmware/services/spd/tspd/tspd_pm.c b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_pm.c
new file mode 100644
index 0000000..009ff5f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_pm.c
@@ -0,0 +1,256 @@
+/*
+ * 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 <assert.h>
+#include <bl_common.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <platform.h>
+#include <tsp.h>
+#include "tspd_private.h"
+
+/*******************************************************************************
+ * The target cpu is being turned on. Allow the TSPD/TSP to perform any actions
+ * needed. Nothing at the moment.
+ ******************************************************************************/
+static void tspd_cpu_on_handler(uint64_t target_cpu)
+{
+}
+
+/*******************************************************************************
+ * This cpu is being turned off. Allow the TSPD/TSP to perform any actions
+ * needed
+ ******************************************************************************/
+static int32_t tspd_cpu_off_handler(uint64_t unused)
+{
+	int32_t rc = 0;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
+
+	assert(tsp_vectors);
+	assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON);
+
+	/* Program the entry point and enter the TSP */
+	cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_off_entry);
+	rc = tspd_synchronous_sp_entry(tsp_ctx);
+
+	/*
+	 * Read the response from the TSP. A non-zero return means that
+	 * something went wrong while communicating with the TSP.
+	 */
+	if (rc != 0)
+		panic();
+
+	/*
+	 * Reset TSP's context for a fresh start when this cpu is turned on
+	 * subsequently.
+	 */
+	set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_OFF);
+
+	 return 0;
+}
+
+/*******************************************************************************
+ * This cpu is being suspended. S-EL1 state must have been saved in the
+ * resident cpu (mpidr format) if it is a UP/UP migratable TSP.
+ ******************************************************************************/
+static void tspd_cpu_suspend_handler(uint64_t unused)
+{
+	int32_t rc = 0;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
+
+	assert(tsp_vectors);
+	assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON);
+
+	/* Program the entry point and enter the TSP */
+	cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_suspend_entry);
+	rc = tspd_synchronous_sp_entry(tsp_ctx);
+
+	/*
+	 * Read the response from the TSP. A non-zero return means that
+	 * something went wrong while communicating with the TSP.
+	 */
+	if (rc != 0)
+		panic();
+
+	/* Update its context to reflect the state the TSP is in */
+	set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_SUSPEND);
+}
+
+/*******************************************************************************
+ * This cpu has been turned on. Enter the TSP to initialise S-EL1 and other bits
+ * before passing control back to the Secure Monitor. Entry in S-El1 is done
+ * after initialising minimal architectural state that guarantees safe
+ * execution.
+ ******************************************************************************/
+static void tspd_cpu_on_finish_handler(uint64_t unused)
+{
+	int32_t rc = 0;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
+	entry_point_info_t tsp_on_entrypoint;
+
+	assert(tsp_vectors);
+	assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_OFF);
+
+	tspd_init_tsp_ep_state(&tsp_on_entrypoint,
+				TSP_AARCH64,
+				(uint64_t) &tsp_vectors->cpu_on_entry,
+				tsp_ctx);
+
+	/* Initialise this cpu's secure context */
+	cm_init_context(mpidr, &tsp_on_entrypoint);
+
+#if TSPD_ROUTE_IRQ_TO_EL3
+	/*
+	 * Disable the NS interrupt locally since it will be enabled globally
+	 * within cm_init_context.
+	 */
+	disable_intr_rm_local(INTR_TYPE_NS, SECURE);
+#endif
+
+	/* Enter the TSP */
+	rc = tspd_synchronous_sp_entry(tsp_ctx);
+
+	/*
+	 * Read the response from the TSP. A non-zero return means that
+	 * something went wrong while communicating with the SP.
+	 */
+	if (rc != 0)
+		panic();
+
+	/* Update its context to reflect the state the SP is in */
+	set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON);
+}
+
+/*******************************************************************************
+ * This cpu has resumed from suspend. The SPD saved the TSP context when it
+ * completed the preceding suspend call. Use that context to program an entry
+ * into the TSP to allow it to do any remaining book keeping
+ ******************************************************************************/
+static void tspd_cpu_suspend_finish_handler(uint64_t suspend_level)
+{
+	int32_t rc = 0;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
+
+	assert(tsp_vectors);
+	assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_SUSPEND);
+
+	/* Program the entry point, suspend_level and enter the SP */
+	write_ctx_reg(get_gpregs_ctx(&tsp_ctx->cpu_ctx),
+		      CTX_GPREG_X0,
+		      suspend_level);
+	cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_resume_entry);
+	rc = tspd_synchronous_sp_entry(tsp_ctx);
+
+	/*
+	 * Read the response from the TSP. A non-zero return means that
+	 * something went wrong while communicating with the TSP.
+	 */
+	if (rc != 0)
+		panic();
+
+	/* Update its context to reflect the state the SP is in */
+	set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON);
+}
+
+/*******************************************************************************
+ * Return the type of TSP the TSPD is dealing with. Report the current resident
+ * cpu (mpidr format) if it is a UP/UP migratable TSP.
+ ******************************************************************************/
+static int32_t tspd_cpu_migrate_info(uint64_t *resident_cpu)
+{
+	return TSP_MIGRATE_INFO;
+}
+
+/*******************************************************************************
+ * System is about to be switched off. Allow the TSPD/TSP to perform
+ * any actions needed.
+ ******************************************************************************/
+static void tspd_system_off(void)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
+
+	assert(tsp_vectors);
+	assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON);
+
+	/* Program the entry point */
+	cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->system_off_entry);
+
+	/* Enter the TSP. We do not care about the return value because we
+	 * must continue the shutdown anyway */
+	tspd_synchronous_sp_entry(tsp_ctx);
+}
+
+/*******************************************************************************
+ * System is about to be reset. Allow the TSPD/TSP to perform
+ * any actions needed.
+ ******************************************************************************/
+static void tspd_system_reset(void)
+{
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = platform_get_core_pos(mpidr);
+	tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
+
+	assert(tsp_vectors);
+	assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON);
+
+	/* Program the entry point */
+	cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->system_reset_entry);
+
+	/* Enter the TSP. We do not care about the return value because we
+	 * must continue the reset anyway */
+	tspd_synchronous_sp_entry(tsp_ctx);
+}
+
+/*******************************************************************************
+ * Structure populated by the TSP Dispatcher to be given a chance to perform any
+ * TSP bookkeeping before PSCI executes a power mgmt.  operation.
+ ******************************************************************************/
+const spd_pm_ops_t tspd_pm = {
+	.svc_on = tspd_cpu_on_handler,
+	.svc_off = tspd_cpu_off_handler,
+	.svc_suspend = tspd_cpu_suspend_handler,
+	.svc_on_finish = tspd_cpu_on_finish_handler,
+	.svc_suspend_finish = tspd_cpu_suspend_finish_handler,
+	.svc_migrate = NULL,
+	.svc_migrate_info = tspd_cpu_migrate_info,
+	.svc_system_off = tspd_system_off,
+	.svc_system_reset = tspd_system_reset
+};
diff --git a/uefi/arm-trusted-firmware/services/spd/tspd/tspd_private.h b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_private.h
new file mode 100644
index 0000000..5f6fb2b
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/spd/tspd/tspd_private.h
@@ -0,0 +1,250 @@
+/*
+ * 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 __TSPD_PRIVATE_H__
+#define __TSPD_PRIVATE_H__
+
+#include <arch.h>
+#include <context.h>
+#include <interrupt_mgmt.h>
+#include <platform_def.h>
+#include <psci.h>
+
+/*******************************************************************************
+ * Secure Payload PM state information e.g. SP is suspended, uninitialised etc
+ * and macros to access the state information in the per-cpu 'state' flags
+ ******************************************************************************/
+#define TSP_PSTATE_OFF		0
+#define TSP_PSTATE_ON		1
+#define TSP_PSTATE_SUSPEND	2
+#define TSP_PSTATE_SHIFT	0
+#define TSP_PSTATE_MASK	0x3
+#define get_tsp_pstate(state)	((state >> TSP_PSTATE_SHIFT) & TSP_PSTATE_MASK)
+#define clr_tsp_pstate(state)	(state &= ~(TSP_PSTATE_MASK \
+					    << TSP_PSTATE_SHIFT))
+#define set_tsp_pstate(st, pst)	do {					       \
+					clr_tsp_pstate(st);		       \
+					st |= (pst & TSP_PSTATE_MASK) <<       \
+						TSP_PSTATE_SHIFT;	       \
+				} while (0);
+
+
+/*
+ * This flag is used by the TSPD to determine if the TSP is servicing a standard
+ * SMC request prior to programming the next entry into the TSP e.g. if TSP
+ * execution is preempted by a non-secure interrupt and handed control to the
+ * normal world. If another request which is distinct from what the TSP was
+ * previously doing arrives, then this flag will be help the TSPD to either
+ * reject the new request or service it while ensuring that the previous context
+ * is not corrupted.
+ */
+#define STD_SMC_ACTIVE_FLAG_SHIFT	2
+#define STD_SMC_ACTIVE_FLAG_MASK	1
+#define get_std_smc_active_flag(state)	((state >> STD_SMC_ACTIVE_FLAG_SHIFT) \
+					 & STD_SMC_ACTIVE_FLAG_MASK)
+#define set_std_smc_active_flag(state)	(state |=                             \
+					 1 << STD_SMC_ACTIVE_FLAG_SHIFT)
+#define clr_std_smc_active_flag(state)	(state &=                             \
+					 ~(STD_SMC_ACTIVE_FLAG_MASK           \
+					   << STD_SMC_ACTIVE_FLAG_SHIFT))
+
+/*******************************************************************************
+ * Secure Payload execution state information i.e. aarch32 or aarch64
+ ******************************************************************************/
+#define TSP_AARCH32		MODE_RW_32
+#define TSP_AARCH64		MODE_RW_64
+
+/*******************************************************************************
+ * The SPD should know the type of Secure Payload.
+ ******************************************************************************/
+#define TSP_TYPE_UP		PSCI_TOS_NOT_UP_MIG_CAP
+#define TSP_TYPE_UPM		PSCI_TOS_UP_MIG_CAP
+#define TSP_TYPE_MP		PSCI_TOS_NOT_PRESENT_MP
+
+/*******************************************************************************
+ * Secure Payload migrate type information as known to the SPD. We assume that
+ * the SPD is dealing with an MP Secure Payload.
+ ******************************************************************************/
+#define TSP_MIGRATE_INFO		TSP_TYPE_MP
+
+/*******************************************************************************
+ * Number of cpus that the present on this platform. TODO: Rely on a topology
+ * tree to determine this in the future to avoid assumptions about mpidr
+ * allocation
+ ******************************************************************************/
+#define TSPD_CORE_COUNT		PLATFORM_CORE_COUNT
+
+/*******************************************************************************
+ * Constants that allow assembler code to preserve callee-saved registers of the
+ * C runtime context while performing a security state switch.
+ ******************************************************************************/
+#define TSPD_C_RT_CTX_X19		0x0
+#define TSPD_C_RT_CTX_X20		0x8
+#define TSPD_C_RT_CTX_X21		0x10
+#define TSPD_C_RT_CTX_X22		0x18
+#define TSPD_C_RT_CTX_X23		0x20
+#define TSPD_C_RT_CTX_X24		0x28
+#define TSPD_C_RT_CTX_X25		0x30
+#define TSPD_C_RT_CTX_X26		0x38
+#define TSPD_C_RT_CTX_X27		0x40
+#define TSPD_C_RT_CTX_X28		0x48
+#define TSPD_C_RT_CTX_X29		0x50
+#define TSPD_C_RT_CTX_X30		0x58
+#define TSPD_C_RT_CTX_SIZE		0x60
+#define TSPD_C_RT_CTX_ENTRIES		(TSPD_C_RT_CTX_SIZE >> DWORD_SHIFT)
+
+/*******************************************************************************
+ * Constants that allow assembler code to preserve caller-saved registers of the
+ * SP context while performing a TSP preemption.
+ * Note: These offsets have to match with the offsets for the corresponding
+ * registers in cpu_context as we are using memcpy to copy the values from
+ * cpu_context to sp_ctx.
+ ******************************************************************************/
+#define TSPD_SP_CTX_X0		0x0
+#define TSPD_SP_CTX_X1		0x8
+#define TSPD_SP_CTX_X2		0x10
+#define TSPD_SP_CTX_X3		0x18
+#define TSPD_SP_CTX_X4		0x20
+#define TSPD_SP_CTX_X5		0x28
+#define TSPD_SP_CTX_X6		0x30
+#define TSPD_SP_CTX_X7		0x38
+#define TSPD_SP_CTX_X8		0x40
+#define TSPD_SP_CTX_X9		0x48
+#define TSPD_SP_CTX_X10		0x50
+#define TSPD_SP_CTX_X11		0x58
+#define TSPD_SP_CTX_X12		0x60
+#define TSPD_SP_CTX_X13		0x68
+#define TSPD_SP_CTX_X14		0x70
+#define TSPD_SP_CTX_X15		0x78
+#define TSPD_SP_CTX_X16		0x80
+#define TSPD_SP_CTX_X17		0x88
+#define TSPD_SP_CTX_SIZE	0x90
+#define TSPD_SP_CTX_ENTRIES		(TSPD_SP_CTX_SIZE >> DWORD_SHIFT)
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <stdint.h>
+
+/*
+ * The number of arguments to save during a SMC call for TSP.
+ * Currently only x1 and x2 are used by TSP.
+ */
+#define TSP_NUM_ARGS	0x2
+
+/* AArch64 callee saved general purpose register context structure. */
+DEFINE_REG_STRUCT(c_rt_regs, TSPD_C_RT_CTX_ENTRIES);
+
+/*
+ * Compile time assertion to ensure that both the compiler and linker
+ * have the same double word aligned view of the size of the C runtime
+ * register context.
+ */
+CASSERT(TSPD_C_RT_CTX_SIZE == sizeof(c_rt_regs_t),	\
+	assert_spd_c_rt_regs_size_mismatch);
+
+/* SEL1 Secure payload (SP) caller saved register context structure. */
+DEFINE_REG_STRUCT(sp_ctx_regs, TSPD_SP_CTX_ENTRIES);
+
+/*
+ * Compile time assertion to ensure that both the compiler and linker
+ * have the same double word aligned view of the size of the C runtime
+ * register context.
+ */
+CASSERT(TSPD_SP_CTX_SIZE == sizeof(sp_ctx_regs_t),	\
+	assert_spd_sp_regs_size_mismatch);
+
+/*******************************************************************************
+ * Structure which helps the SPD to maintain the per-cpu state of the SP.
+ * 'saved_spsr_el3' - temporary copy to allow FIQ handling when the TSP has been
+ *                    preempted.
+ * 'saved_elr_el3'  - temporary copy to allow FIQ handling when the TSP has been
+ *                    preempted.
+ * 'state'          - collection of flags to track SP state e.g. on/off
+ * 'mpidr'          - mpidr to associate a context with a cpu
+ * 'c_rt_ctx'       - stack address to restore C runtime context from after
+ *                    returning from a synchronous entry into the SP.
+ * 'cpu_ctx'        - space to maintain SP architectural state
+ * 'saved_tsp_args' - space to store arguments for TSP arithmetic operations
+ *                    which will queried using the TSP_GET_ARGS SMC by TSP.
+ * 'sp_ctx'         - space to save the SEL1 Secure Payload(SP) caller saved
+ *                    register context after it has been preempted by an EL3
+ *                    routed NS interrupt and when a Secure Interrupt is taken
+ *                    to SP.
+ ******************************************************************************/
+typedef struct tsp_context {
+	uint64_t saved_elr_el3;
+	uint32_t saved_spsr_el3;
+	uint32_t state;
+	uint64_t mpidr;
+	uint64_t c_rt_ctx;
+	cpu_context_t cpu_ctx;
+	uint64_t saved_tsp_args[TSP_NUM_ARGS];
+#if TSPD_ROUTE_IRQ_TO_EL3
+	sp_ctx_regs_t sp_ctx;
+#endif
+} tsp_context_t;
+
+/* Helper macros to store and retrieve tsp args from tsp_context */
+#define store_tsp_args(tsp_ctx, x1, x2)		do {\
+				tsp_ctx->saved_tsp_args[0] = x1;\
+				tsp_ctx->saved_tsp_args[1] = x2;\
+			} while (0)
+
+#define get_tsp_args(tsp_ctx, x1, x2)	do {\
+				x1 = tsp_ctx->saved_tsp_args[0];\
+				x2 = tsp_ctx->saved_tsp_args[1];\
+			} while (0)
+
+/* TSPD power management handlers */
+extern const spd_pm_ops_t tspd_pm;
+
+/*******************************************************************************
+ * Forward declarations
+ ******************************************************************************/
+struct tsp_vectors;
+
+/*******************************************************************************
+ * Function & Data prototypes
+ ******************************************************************************/
+uint64_t tspd_enter_sp(uint64_t *c_rt_ctx);
+void __dead2 tspd_exit_sp(uint64_t c_rt_ctx, uint64_t ret);
+uint64_t tspd_synchronous_sp_entry(tsp_context_t *tsp_ctx);
+void __dead2 tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret);
+void tspd_init_tsp_ep_state(struct entry_point_info *tsp_ep,
+				uint32_t rw,
+				uint64_t pc,
+				tsp_context_t *tsp_ctx);
+
+extern tsp_context_t tspd_sp_context[TSPD_CORE_COUNT];
+extern struct tsp_vectors *tsp_vectors;
+#endif /*__ASSEMBLY__*/
+
+#endif /* __TSPD_PRIVATE_H__ */
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_afflvl_off.c b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_afflvl_off.c
new file mode 100644
index 0000000..7eb9688
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_afflvl_off.c
@@ -0,0 +1,248 @@
+/*
+ * 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 <debug.h>
+#include <string.h>
+#include "psci_private.h"
+
+typedef void (*afflvl_off_handler_t)(aff_map_node_t *node);
+
+/*******************************************************************************
+ * The next three functions implement a handler for each supported affinity
+ * level which is called when that affinity level is turned off.
+ ******************************************************************************/
+static void psci_afflvl0_off(aff_map_node_t *cpu_node)
+{
+	assert(cpu_node->level == MPIDR_AFFLVL0);
+
+	/*
+	 * Arch. management. Perform the necessary steps to flush all
+	 * cpu caches.
+	 */
+	psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
+
+	/*
+	 * Plat. management: Perform platform specific actions to turn this
+	 * cpu off e.g. exit cpu coherency, program the power controller etc.
+	 */
+	psci_plat_pm_ops->affinst_off(cpu_node->level,
+				     psci_get_phys_state(cpu_node));
+}
+
+static void psci_afflvl1_off(aff_map_node_t *cluster_node)
+{
+	/* Sanity check the cluster level */
+	assert(cluster_node->level == MPIDR_AFFLVL1);
+
+	/*
+	 * Arch. Management. Flush all levels of caches to PoC if
+	 * the cluster is to be shutdown.
+	 */
+	psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL1);
+
+	/*
+	 * Plat. Management. Allow the platform to do its cluster
+	 * specific bookeeping e.g. turn off interconnect coherency,
+	 * program the power controller etc.
+	 */
+	psci_plat_pm_ops->affinst_off(cluster_node->level,
+					     psci_get_phys_state(cluster_node));
+}
+
+static void psci_afflvl2_off(aff_map_node_t *system_node)
+{
+	/* Cannot go beyond this level */
+	assert(system_node->level == MPIDR_AFFLVL2);
+
+	/*
+	 * Keep the physical state of the system handy to decide what
+	 * action needs to be taken
+	 */
+
+	/*
+	 * Arch. Management. Flush all levels of caches to PoC if
+	 * the system is to be shutdown.
+	 */
+	psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL2);
+
+	/*
+	 * Plat. Management : Allow the platform to do its bookeeping
+	 * at this affinity level
+	 */
+	psci_plat_pm_ops->affinst_off(system_node->level,
+					     psci_get_phys_state(system_node));
+}
+
+static const afflvl_off_handler_t psci_afflvl_off_handlers[] = {
+	psci_afflvl0_off,
+	psci_afflvl1_off,
+	psci_afflvl2_off,
+};
+
+/*******************************************************************************
+ * This function takes an array of pointers to affinity instance nodes in the
+ * topology tree and calls the off handler for the corresponding affinity
+ * levels
+ ******************************************************************************/
+static void psci_call_off_handlers(aff_map_node_t *mpidr_nodes[],
+				  int start_afflvl,
+				  int end_afflvl)
+{
+	int level;
+	aff_map_node_t *node;
+
+	for (level = start_afflvl; level <= end_afflvl; level++) {
+		node = mpidr_nodes[level];
+		if (node == NULL)
+			continue;
+
+		psci_afflvl_off_handlers[level](node);
+	}
+}
+
+/*******************************************************************************
+ * Top level handler which is called when a cpu wants to power itself down.
+ * It's assumed that along with turning the cpu off, higher affinity levels will
+ * be turned off as far as possible. It traverses through all the affinity
+ * levels performing generic, architectural, platform setup and state management
+ * e.g. for a cluster that's to be powered off, it will call the platform
+ * specific code which will disable coherency at the interconnect level if the
+ * cpu is the last in the cluster. For a cpu it could mean programming the power
+ * the power controller etc.
+ *
+ * The state of all the relevant affinity levels is changed prior to calling the
+ * affinity level specific handlers as their actions would depend upon the state
+ * the affinity level is about to enter.
+ *
+ * The affinity level specific handlers are called in ascending order i.e. from
+ * the lowest to the highest affinity level implemented by the platform because
+ * to turn off affinity level X it is neccesary to turn off affinity level X - 1
+ * first.
+ ******************************************************************************/
+int psci_afflvl_off(int start_afflvl,
+		    int end_afflvl)
+{
+	int rc;
+	mpidr_aff_map_nodes_t mpidr_nodes;
+	unsigned int max_phys_off_afflvl;
+
+	/*
+	 * This function must only be called on platforms where the
+	 * CPU_OFF platform hooks have been implemented.
+	 */
+	assert(psci_plat_pm_ops->affinst_off);
+
+	/*
+	 * Collect the pointers to the nodes in the topology tree for
+	 * each affinity instance in the mpidr. If this function does
+	 * not return successfully then either the mpidr or the affinity
+	 * levels are incorrect. Either way, this an internal TF error
+	 * therefore assert.
+	 */
+	rc = psci_get_aff_map_nodes(read_mpidr_el1() & MPIDR_AFFINITY_MASK,
+				    start_afflvl,
+				    end_afflvl,
+				    mpidr_nodes);
+	assert(rc == PSCI_E_SUCCESS);
+
+	/*
+	 * This function acquires the lock corresponding to each affinity
+	 * level so that by the time all locks are taken, the system topology
+	 * is snapshot and state management can be done safely.
+	 */
+	psci_acquire_afflvl_locks(start_afflvl,
+				  end_afflvl,
+				  mpidr_nodes);
+
+
+	/*
+	 * Call the cpu off handler registered by the Secure Payload Dispatcher
+	 * to let it do any bookkeeping. Assume that the SPD always reports an
+	 * E_DENIED error if SP refuse to power down
+	 */
+	if (psci_spd_pm && psci_spd_pm->svc_off) {
+		rc = psci_spd_pm->svc_off(0);
+		if (rc)
+			goto exit;
+	}
+
+	/*
+	 * This function updates the state of each affinity instance
+	 * corresponding to the mpidr in the range of affinity levels
+	 * specified.
+	 */
+	psci_do_afflvl_state_mgmt(start_afflvl,
+				  end_afflvl,
+				  mpidr_nodes,
+				  PSCI_STATE_OFF);
+
+	max_phys_off_afflvl = psci_find_max_phys_off_afflvl(start_afflvl,
+							   end_afflvl,
+							   mpidr_nodes);
+	assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
+
+	/* Stash the highest affinity level that will enter the OFF state. */
+	psci_set_max_phys_off_afflvl(max_phys_off_afflvl);
+
+	/* Perform generic, architecture and platform specific handling */
+	psci_call_off_handlers(mpidr_nodes,
+				    start_afflvl,
+				    end_afflvl);
+
+	/*
+	 * Invalidate the entry for the highest affinity level stashed earlier.
+	 * This ensures that any reads of this variable outside the power
+	 * up/down sequences return PSCI_INVALID_DATA.
+	 *
+	 */
+	psci_set_max_phys_off_afflvl(PSCI_INVALID_DATA);
+
+exit:
+	/*
+	 * Release the locks corresponding to each affinity level in the
+	 * reverse order to which they were acquired.
+	 */
+	psci_release_afflvl_locks(start_afflvl,
+				  end_afflvl,
+				  mpidr_nodes);
+
+	/*
+	 * Check if all actions needed to safely power down this cpu have
+	 * successfully completed. Enter a wfi loop which will allow the
+	 * power controller to physically power down this cpu.
+	 */
+	if (rc == PSCI_E_SUCCESS)
+		psci_power_down_wfi();
+
+	return rc;
+}
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_afflvl_on.c b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_afflvl_on.c
new file mode 100644
index 0000000..0ee03cb
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_afflvl_on.c
@@ -0,0 +1,403 @@
+/*
+ * 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 <debug.h>
+#include <context_mgmt.h>
+#include <platform.h>
+#include <runtime_svc.h>
+#include <stddef.h>
+#include "psci_private.h"
+
+typedef int (*afflvl_on_handler_t)(unsigned long target_cpu,
+				 aff_map_node_t *node);
+
+/*******************************************************************************
+ * This function checks whether a cpu which has been requested to be turned on
+ * is OFF to begin with.
+ ******************************************************************************/
+static int cpu_on_validate_state(unsigned int psci_state)
+{
+	if (psci_state == PSCI_STATE_ON || psci_state == PSCI_STATE_SUSPEND)
+		return PSCI_E_ALREADY_ON;
+
+	if (psci_state == PSCI_STATE_ON_PENDING)
+		return PSCI_E_ON_PENDING;
+
+	assert(psci_state == PSCI_STATE_OFF);
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Handler routine to turn a cpu on. It takes care of any generic, architectural
+ * or platform specific setup required.
+ * TODO: Split this code across separate handlers for each type of setup?
+ ******************************************************************************/
+static int psci_afflvl0_on(unsigned long target_cpu,
+			   aff_map_node_t *cpu_node)
+{
+	unsigned long psci_entrypoint;
+
+	/* Sanity check to safeguard against data corruption */
+	assert(cpu_node->level == MPIDR_AFFLVL0);
+
+	/* Set the secure world (EL3) re-entry point after BL1 */
+	psci_entrypoint = (unsigned long) psci_aff_on_finish_entry;
+
+	/*
+	 * Plat. management: Give the platform the current state
+	 * of the target cpu to allow it to perform the necessary
+	 * steps to power on.
+	 */
+	return psci_plat_pm_ops->affinst_on(target_cpu,
+					    psci_entrypoint,
+					    cpu_node->level,
+					    psci_get_phys_state(cpu_node));
+}
+
+/*******************************************************************************
+ * Handler routine to turn a cluster on. It takes care or any generic, arch.
+ * or platform specific setup required.
+ * TODO: Split this code across separate handlers for each type of setup?
+ ******************************************************************************/
+static int psci_afflvl1_on(unsigned long target_cpu,
+			   aff_map_node_t *cluster_node)
+{
+	unsigned long psci_entrypoint;
+
+	assert(cluster_node->level == MPIDR_AFFLVL1);
+
+	/*
+	 * There is no generic and arch. specific cluster
+	 * management required
+	 */
+
+	/* State management: Is not required while turning a cluster on */
+
+	/*
+	 * Plat. management: Give the platform the current state
+	 * of the target cpu to allow it to perform the necessary
+	 * steps to power on.
+	 */
+	psci_entrypoint = (unsigned long) psci_aff_on_finish_entry;
+	return psci_plat_pm_ops->affinst_on(target_cpu,
+					    psci_entrypoint,
+					    cluster_node->level,
+					    psci_get_phys_state(cluster_node));
+}
+
+/*******************************************************************************
+ * Handler routine to turn a cluster of clusters on. It takes care or any
+ * generic, arch. or platform specific setup required.
+ * TODO: Split this code across separate handlers for each type of setup?
+ ******************************************************************************/
+static int psci_afflvl2_on(unsigned long target_cpu,
+			   aff_map_node_t *system_node)
+{
+	unsigned long psci_entrypoint;
+
+	/* Cannot go beyond affinity level 2 in this psci imp. */
+	assert(system_node->level == MPIDR_AFFLVL2);
+
+	/*
+	 * There is no generic and arch. specific system management
+	 * required
+	 */
+
+	/* State management: Is not required while turning a system on */
+
+	/*
+	 * Plat. management: Give the platform the current state
+	 * of the target cpu to allow it to perform the necessary
+	 * steps to power on.
+	 */
+	psci_entrypoint = (unsigned long) psci_aff_on_finish_entry;
+	return psci_plat_pm_ops->affinst_on(target_cpu,
+					    psci_entrypoint,
+					    system_node->level,
+					    psci_get_phys_state(system_node));
+}
+
+/* Private data structure to make this handlers accessible through indexing */
+static const afflvl_on_handler_t psci_afflvl_on_handlers[] = {
+	psci_afflvl0_on,
+	psci_afflvl1_on,
+	psci_afflvl2_on,
+};
+
+/*******************************************************************************
+ * This function takes an array of pointers to affinity instance nodes in the
+ * topology tree and calls the on handler for the corresponding affinity
+ * levels
+ ******************************************************************************/
+static int psci_call_on_handlers(aff_map_node_t *target_cpu_nodes[],
+				 int start_afflvl,
+				 int end_afflvl,
+				 unsigned long target_cpu)
+{
+	int rc = PSCI_E_INVALID_PARAMS, level;
+	aff_map_node_t *node;
+
+	for (level = end_afflvl; level >= start_afflvl; level--) {
+		node = target_cpu_nodes[level];
+		if (node == NULL)
+			continue;
+
+		/*
+		 * TODO: In case of an error should there be a way
+		 * of undoing what we might have setup at higher
+		 * affinity levels.
+		 */
+		rc = psci_afflvl_on_handlers[level](target_cpu,
+						    node);
+		if (rc != PSCI_E_SUCCESS)
+			break;
+	}
+
+	return rc;
+}
+
+/*******************************************************************************
+ * Generic handler which is called to physically power on a cpu identified by
+ * its mpidr. It traverses through all the affinity levels performing generic,
+ * architectural, platform setup and state management e.g. for a cpu that is
+ * to be powered on, it will ensure that enough information is stashed for it
+ * to resume execution in the non-secure security state.
+ *
+ * The state of all the relevant affinity levels is changed after calling the
+ * affinity level specific handlers as their actions would depend upon the state
+ * the affinity level is currently in.
+ *
+ * The affinity level specific handlers are called in descending order i.e. from
+ * the highest to the lowest affinity level implemented by the platform because
+ * to turn on affinity level X it is necessary to turn on affinity level X + 1
+ * first.
+ ******************************************************************************/
+int psci_afflvl_on(unsigned long target_cpu,
+		   entry_point_info_t *ep,
+		   int start_afflvl,
+		   int end_afflvl)
+{
+	int rc;
+	mpidr_aff_map_nodes_t target_cpu_nodes;
+
+	/*
+	 * This function must only be called on platforms where the
+	 * CPU_ON platform hooks have been implemented.
+	 */
+	assert(psci_plat_pm_ops->affinst_on &&
+			psci_plat_pm_ops->affinst_on_finish);
+
+	/*
+	 * Collect the pointers to the nodes in the topology tree for
+	 * each affinity instance in the mpidr. If this function does
+	 * not return successfully then either the mpidr or the affinity
+	 * levels are incorrect.
+	 */
+	rc = psci_get_aff_map_nodes(target_cpu,
+				    start_afflvl,
+				    end_afflvl,
+				    target_cpu_nodes);
+	assert(rc == PSCI_E_SUCCESS);
+
+	/*
+	 * This function acquires the lock corresponding to each affinity
+	 * level so that by the time all locks are taken, the system topology
+	 * is snapshot and state management can be done safely.
+	 */
+	psci_acquire_afflvl_locks(start_afflvl,
+				  end_afflvl,
+				  target_cpu_nodes);
+
+	/*
+	 * Generic management: Ensure that the cpu is off to be
+	 * turned on.
+	 */
+	rc = cpu_on_validate_state(psci_get_state(
+				    target_cpu_nodes[MPIDR_AFFLVL0]));
+	if (rc != PSCI_E_SUCCESS)
+		goto exit;
+
+	/*
+	 * Call the cpu on handler registered by the Secure Payload Dispatcher
+	 * to let it do any bookeeping. If the handler encounters an error, it's
+	 * expected to assert within
+	 */
+	if (psci_spd_pm && psci_spd_pm->svc_on)
+		psci_spd_pm->svc_on(target_cpu);
+
+	/* Perform generic, architecture and platform specific handling. */
+	rc = psci_call_on_handlers(target_cpu_nodes,
+				   start_afflvl,
+				   end_afflvl,
+				   target_cpu);
+
+	assert(rc == PSCI_E_SUCCESS || rc == PSCI_E_INTERN_FAIL);
+
+	/*
+	 * This function updates the state of each affinity instance
+	 * corresponding to the mpidr in the range of affinity levels
+	 * specified.
+	 */
+	if (rc == PSCI_E_SUCCESS) {
+		psci_do_afflvl_state_mgmt(start_afflvl,
+					  end_afflvl,
+					  target_cpu_nodes,
+					  PSCI_STATE_ON_PENDING);
+
+		/*
+		 * Store the re-entry information for the non-secure world.
+		 */
+		cm_init_context(target_cpu, ep);
+	}
+
+exit:
+	/*
+	 * This loop releases the lock corresponding to each affinity level
+	 * in the reverse order to which they were acquired.
+	 */
+	psci_release_afflvl_locks(start_afflvl,
+				  end_afflvl,
+				  target_cpu_nodes);
+
+	return rc;
+}
+
+/*******************************************************************************
+ * The following functions finish an earlier affinity power on request. They
+ * are called by the common finisher routine in psci_common.c.
+ ******************************************************************************/
+static void psci_afflvl0_on_finish(aff_map_node_t *cpu_node)
+{
+	unsigned int plat_state, state;
+
+	assert(cpu_node->level == MPIDR_AFFLVL0);
+
+	/* Ensure we have been explicitly woken up by another cpu */
+	state = psci_get_state(cpu_node);
+	assert(state == PSCI_STATE_ON_PENDING);
+
+	/*
+	 * Plat. management: Perform the platform specific actions
+	 * for this cpu e.g. enabling the gic or zeroing the mailbox
+	 * register. The actual state of this cpu has already been
+	 * changed.
+	 */
+
+	/* Get the physical state of this cpu */
+	plat_state = get_phys_state(state);
+	psci_plat_pm_ops->affinst_on_finish(cpu_node->level,
+							 plat_state);
+
+	/*
+	 * Arch. management: Enable data cache and manage stack memory
+	 */
+	psci_do_pwrup_cache_maintenance();
+
+	/*
+	 * All the platform specific actions for turning this cpu
+	 * on have completed. Perform enough arch.initialization
+	 * to run in the non-secure address space.
+	 */
+	bl31_arch_setup();
+
+	/*
+	 * Call the cpu on finish handler registered by the Secure Payload
+	 * Dispatcher to let it do any bookeeping. If the handler encounters an
+	 * error, it's expected to assert within
+	 */
+	if (psci_spd_pm && psci_spd_pm->svc_on_finish)
+		psci_spd_pm->svc_on_finish(0);
+
+	/*
+	 * Generic management: Now we just need to retrieve the
+	 * information that we had stashed away during the cpu_on
+	 * call to set this cpu on its way.
+	 */
+	cm_prepare_el3_exit(NON_SECURE);
+
+	/* Clean caches before re-entering normal world */
+	dcsw_op_louis(DCCSW);
+}
+
+static void psci_afflvl1_on_finish(aff_map_node_t *cluster_node)
+{
+	unsigned int plat_state;
+
+	assert(cluster_node->level == MPIDR_AFFLVL1);
+
+	/*
+	 * Plat. management: Perform the platform specific actions
+	 * as per the old state of the cluster e.g. enabling
+	 * coherency at the interconnect depends upon the state with
+	 * which this cluster was powered up. If anything goes wrong
+	 * then assert as there is no way to recover from this
+	 * situation.
+	 */
+	plat_state = psci_get_phys_state(cluster_node);
+	psci_plat_pm_ops->affinst_on_finish(cluster_node->level,
+						 plat_state);
+}
+
+
+static void psci_afflvl2_on_finish(aff_map_node_t *system_node)
+{
+	unsigned int plat_state;
+
+	/* Cannot go beyond this affinity level */
+	assert(system_node->level == MPIDR_AFFLVL2);
+
+	/*
+	 * Currently, there are no architectural actions to perform
+	 * at the system level.
+	 */
+
+	/*
+	 * Plat. management: Perform the platform specific actions
+	 * as per the old state of the cluster e.g. enabling
+	 * coherency at the interconnect depends upon the state with
+	 * which this cluster was powered up. If anything goes wrong
+	 * then assert as there is no way to recover from this
+	 * situation.
+	 */
+	plat_state = psci_get_phys_state(system_node);
+	psci_plat_pm_ops->affinst_on_finish(system_node->level,
+						   plat_state);
+}
+
+const afflvl_power_on_finisher_t psci_afflvl_on_finishers[] = {
+	psci_afflvl0_on_finish,
+	psci_afflvl1_on_finish,
+	psci_afflvl2_on_finish,
+};
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_afflvl_suspend.c b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_afflvl_suspend.c
new file mode 100644
index 0000000..dad0cef
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_afflvl_suspend.c
@@ -0,0 +1,469 @@
+/*
+ * 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 <assert.h>
+#include <bl_common.h>
+#include <arch.h>
+#include <arch_helpers.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <cpu_data.h>
+#include <debug.h>
+#include <platform.h>
+#include <runtime_svc.h>
+#include <stddef.h>
+#include "psci_private.h"
+
+typedef void (*afflvl_suspend_handler_t)(aff_map_node_t *node);
+
+/*******************************************************************************
+ * This function saves the power state parameter passed in the current PSCI
+ * cpu_suspend call in the per-cpu data array.
+ ******************************************************************************/
+void psci_set_suspend_power_state(unsigned int power_state)
+{
+	set_cpu_data(psci_svc_cpu_data.power_state, power_state);
+	flush_cpu_data(psci_svc_cpu_data.power_state);
+}
+
+/*******************************************************************************
+ * This function gets the affinity level till which the current cpu could be
+ * powered down during a cpu_suspend call. Returns PSCI_INVALID_DATA if the
+ * power state is invalid.
+ ******************************************************************************/
+int psci_get_suspend_afflvl()
+{
+	unsigned int power_state;
+
+	power_state = get_cpu_data(psci_svc_cpu_data.power_state);
+
+	return ((power_state == PSCI_INVALID_DATA) ?
+		power_state : psci_get_pstate_afflvl(power_state));
+}
+
+/*******************************************************************************
+ * This function gets the state id of the current cpu from the power state
+ * parameter saved in the per-cpu data array. Returns PSCI_INVALID_DATA if the
+ * power state saved is invalid.
+ ******************************************************************************/
+int psci_get_suspend_stateid()
+{
+	unsigned int power_state;
+
+	power_state = get_cpu_data(psci_svc_cpu_data.power_state);
+
+	return ((power_state == PSCI_INVALID_DATA) ?
+		power_state : psci_get_pstate_id(power_state));
+}
+
+/*******************************************************************************
+ * This function gets the state id of the cpu specified by the 'mpidr' parameter
+ * from the power state parameter saved in the per-cpu data array. Returns
+ * PSCI_INVALID_DATA if the power state saved is invalid.
+ ******************************************************************************/
+int psci_get_suspend_stateid_by_mpidr(unsigned long mpidr)
+{
+	unsigned int power_state;
+
+	power_state = get_cpu_data_by_mpidr(mpidr,
+					    psci_svc_cpu_data.power_state);
+
+	return ((power_state == PSCI_INVALID_DATA) ?
+		power_state : psci_get_pstate_id(power_state));
+}
+
+/*******************************************************************************
+ * The next three functions implement a handler for each supported affinity
+ * level which is called when that affinity level is about to be suspended.
+ ******************************************************************************/
+static void psci_afflvl0_suspend(aff_map_node_t *cpu_node)
+{
+	unsigned long psci_entrypoint;
+
+	/* Sanity check to safeguard against data corruption */
+	assert(cpu_node->level == MPIDR_AFFLVL0);
+
+	/* Set the secure world (EL3) re-entry point after BL1 */
+	psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
+
+	/*
+	 * Arch. management. Perform the necessary steps to flush all
+	 * cpu caches.
+	 */
+	psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
+
+	/*
+	 * Plat. management: Allow the platform to perform the
+	 * necessary actions to turn off this cpu e.g. set the
+	 * platform defined mailbox with the psci entrypoint,
+	 * program the power controller etc.
+	 */
+	psci_plat_pm_ops->affinst_suspend(psci_entrypoint,
+						 cpu_node->level,
+						 psci_get_phys_state(cpu_node));
+}
+
+static void psci_afflvl1_suspend(aff_map_node_t *cluster_node)
+{
+	unsigned int plat_state;
+	unsigned long psci_entrypoint;
+
+	/* Sanity check the cluster level */
+	assert(cluster_node->level == MPIDR_AFFLVL1);
+
+	/*
+	 * Arch. management: Flush all levels of caches to PoC if the
+	 * cluster is to be shutdown.
+	 */
+	psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL1);
+
+	/*
+	 * Plat. Management. Allow the platform to do its cluster specific
+	 * bookeeping e.g. turn off interconnect coherency, program the power
+	 * controller etc. Sending the psci entrypoint is currently redundant
+	 * beyond affinity level 0 but one never knows what a platform might
+	 * do. Also it allows us to keep the platform handler prototype the
+	 * same.
+	 */
+	plat_state = psci_get_phys_state(cluster_node);
+	psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
+	psci_plat_pm_ops->affinst_suspend(psci_entrypoint,
+						 cluster_node->level,
+						 plat_state);
+}
+
+
+static void psci_afflvl2_suspend(aff_map_node_t *system_node)
+{
+	unsigned int plat_state;
+	unsigned long psci_entrypoint;
+
+	/* Cannot go beyond this */
+	assert(system_node->level == MPIDR_AFFLVL2);
+
+	/*
+	 * Keep the physical state of the system handy to decide what
+	 * action needs to be taken
+	 */
+	plat_state = psci_get_phys_state(system_node);
+
+	/*
+	 * Arch. management: Flush all levels of caches to PoC if the
+	 * system is to be shutdown.
+	 */
+	psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL2);
+
+	/*
+	 * Plat. Management : Allow the platform to do its bookeeping
+	 * at this affinity level
+	 */
+
+	/*
+	 * Sending the psci entrypoint is currently redundant
+	 * beyond affinity level 0 but one never knows what a
+	 * platform might do. Also it allows us to keep the
+	 * platform handler prototype the same.
+	 */
+	plat_state = psci_get_phys_state(system_node);
+	psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
+	psci_plat_pm_ops->affinst_suspend(psci_entrypoint,
+						 system_node->level,
+						 plat_state);
+}
+
+static const afflvl_suspend_handler_t psci_afflvl_suspend_handlers[] = {
+	psci_afflvl0_suspend,
+	psci_afflvl1_suspend,
+	psci_afflvl2_suspend,
+};
+
+/*******************************************************************************
+ * This function takes an array of pointers to affinity instance nodes in the
+ * topology tree and calls the suspend handler for the corresponding affinity
+ * levels
+ ******************************************************************************/
+static void psci_call_suspend_handlers(aff_map_node_t *mpidr_nodes[],
+				      int start_afflvl,
+				      int end_afflvl)
+{
+	int level;
+	aff_map_node_t *node;
+
+	for (level = start_afflvl; level <= end_afflvl; level++) {
+		node = mpidr_nodes[level];
+		if (node == NULL)
+			continue;
+
+		psci_afflvl_suspend_handlers[level](node);
+	}
+}
+
+/*******************************************************************************
+ * Top level handler which is called when a cpu wants to suspend its execution.
+ * It is assumed that along with turning the cpu off, higher affinity levels
+ * until the target affinity level will be turned off as well. It traverses
+ * through all the affinity levels performing generic, architectural, platform
+ * setup and state management e.g. for a cluster that's to be suspended, it will
+ * call the platform specific code which will disable coherency at the
+ * interconnect level if the cpu is the last in the cluster. For a cpu it could
+ * mean programming the power controller etc.
+ *
+ * The state of all the relevant affinity levels is changed prior to calling the
+ * affinity level specific handlers as their actions would depend upon the state
+ * the affinity level is about to enter.
+ *
+ * The affinity level specific handlers are called in ascending order i.e. from
+ * the lowest to the highest affinity level implemented by the platform because
+ * to turn off affinity level X it is neccesary to turn off affinity level X - 1
+ * first.
+ *
+ * All the required parameter checks are performed at the beginning and after
+ * the state transition has been done, no further error is expected and it
+ * is not possible to undo any of the actions taken beyond that point.
+ ******************************************************************************/
+void psci_afflvl_suspend(entry_point_info_t *ep,
+			int start_afflvl,
+			int end_afflvl)
+{
+	int skip_wfi = 0;
+	mpidr_aff_map_nodes_t mpidr_nodes;
+	unsigned int max_phys_off_afflvl;
+
+	/*
+	 * This function must only be called on platforms where the
+	 * CPU_SUSPEND platform hooks have been implemented.
+	 */
+	assert(psci_plat_pm_ops->affinst_suspend &&
+			psci_plat_pm_ops->affinst_suspend_finish);
+
+	/*
+	 * Collect the pointers to the nodes in the topology tree for
+	 * each affinity instance in the mpidr. If this function does
+	 * not return successfully then either the mpidr or the affinity
+	 * levels are incorrect. Either way, this an internal TF error
+	 * therefore assert.
+	 */
+	if (psci_get_aff_map_nodes(read_mpidr_el1() & MPIDR_AFFINITY_MASK,
+		   start_afflvl, end_afflvl, mpidr_nodes) != PSCI_E_SUCCESS)
+		assert(0);
+
+	/*
+	 * This function acquires the lock corresponding to each affinity
+	 * level so that by the time all locks are taken, the system topology
+	 * is snapshot and state management can be done safely.
+	 */
+	psci_acquire_afflvl_locks(start_afflvl,
+				  end_afflvl,
+				  mpidr_nodes);
+
+	/*
+	 * We check if there are any pending interrupts after the delay
+	 * introduced by lock contention to increase the chances of early
+	 * detection that a wake-up interrupt has fired.
+	 */
+	if (read_isr_el1()) {
+		skip_wfi = 1;
+		goto exit;
+	}
+
+	/*
+	 * Call the cpu suspend handler registered by the Secure Payload
+	 * Dispatcher to let it do any bookeeping. If the handler encounters an
+	 * error, it's expected to assert within
+	 */
+	if (psci_spd_pm && psci_spd_pm->svc_suspend)
+		psci_spd_pm->svc_suspend(0);
+
+	/*
+	 * This function updates the state of each affinity instance
+	 * corresponding to the mpidr in the range of affinity levels
+	 * specified.
+	 */
+	psci_do_afflvl_state_mgmt(start_afflvl,
+				  end_afflvl,
+				  mpidr_nodes,
+				  PSCI_STATE_SUSPEND);
+
+	max_phys_off_afflvl = psci_find_max_phys_off_afflvl(start_afflvl,
+							    end_afflvl,
+							    mpidr_nodes);
+	assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
+
+	/* Stash the highest affinity level that will be turned off */
+	psci_set_max_phys_off_afflvl(max_phys_off_afflvl);
+
+	/*
+	 * Store the re-entry information for the non-secure world.
+	 */
+	cm_init_context(read_mpidr_el1(), ep);
+
+	/* Perform generic, architecture and platform specific handling */
+	psci_call_suspend_handlers(mpidr_nodes,
+					start_afflvl,
+					end_afflvl);
+
+	/*
+	 * Invalidate the entry for the highest affinity level stashed earlier.
+	 * This ensures that any reads of this variable outside the power
+	 * up/down sequences return PSCI_INVALID_DATA.
+	 */
+	psci_set_max_phys_off_afflvl(PSCI_INVALID_DATA);
+
+exit:
+	/*
+	 * Release the locks corresponding to each affinity level in the
+	 * reverse order to which they were acquired.
+	 */
+	psci_release_afflvl_locks(start_afflvl,
+				  end_afflvl,
+				  mpidr_nodes);
+	if (!skip_wfi)
+		psci_power_down_wfi();
+}
+
+/*******************************************************************************
+ * The following functions finish an earlier affinity suspend request. They
+ * are called by the common finisher routine in psci_common.c.
+ ******************************************************************************/
+static void psci_afflvl0_suspend_finish(aff_map_node_t *cpu_node)
+{
+	unsigned int plat_state, state;
+	int32_t suspend_level;
+	uint64_t counter_freq;
+
+	assert(cpu_node->level == MPIDR_AFFLVL0);
+
+	/* Ensure we have been woken up from a suspended state */
+	state = psci_get_state(cpu_node);
+	assert(state == PSCI_STATE_SUSPEND);
+
+	/*
+	 * Plat. management: Perform the platform specific actions
+	 * before we change the state of the cpu e.g. enabling the
+	 * gic or zeroing the mailbox register. If anything goes
+	 * wrong then assert as there is no way to recover from this
+	 * situation.
+	 */
+
+	/* Get the physical state of this cpu */
+	plat_state = get_phys_state(state);
+	psci_plat_pm_ops->affinst_suspend_finish(cpu_node->level,
+							      plat_state);
+
+	/*
+	 * Arch. management: Enable the data cache, manage stack memory and
+	 * restore the stashed EL3 architectural context from the 'cpu_context'
+	 * structure for this cpu.
+	 */
+	psci_do_pwrup_cache_maintenance();
+
+	/* Re-init the cntfrq_el0 register */
+	counter_freq = plat_get_syscnt_freq();
+	write_cntfrq_el0(counter_freq);
+
+	/*
+	 * Call the cpu suspend finish handler registered by the Secure Payload
+	 * Dispatcher to let it do any bookeeping. If the handler encounters an
+	 * error, it's expected to assert within
+	 */
+	if (psci_spd_pm && psci_spd_pm->svc_suspend) {
+		suspend_level = psci_get_suspend_afflvl();
+		assert (suspend_level != PSCI_INVALID_DATA);
+		psci_spd_pm->svc_suspend_finish(suspend_level);
+	}
+
+	/* Invalidate the suspend context for the node */
+	psci_set_suspend_power_state(PSCI_INVALID_DATA);
+
+	/*
+	 * Generic management: Now we just need to retrieve the
+	 * information that we had stashed away during the suspend
+	 * call to set this cpu on its way.
+	 */
+	cm_prepare_el3_exit(NON_SECURE);
+
+	/* Clean caches before re-entering normal world */
+	dcsw_op_louis(DCCSW);
+}
+
+static void psci_afflvl1_suspend_finish(aff_map_node_t *cluster_node)
+{
+	unsigned int plat_state;
+
+	assert(cluster_node->level == MPIDR_AFFLVL1);
+
+	/*
+	 * Plat. management: Perform the platform specific actions
+	 * as per the old state of the cluster e.g. enabling
+	 * coherency at the interconnect depends upon the state with
+	 * which this cluster was powered up. If anything goes wrong
+	 * then assert as there is no way to recover from this
+	 * situation.
+	 */
+
+	/* Get the physical state of this cpu */
+	plat_state = psci_get_phys_state(cluster_node);
+	psci_plat_pm_ops->affinst_suspend_finish(cluster_node->level,
+						      plat_state);
+}
+
+
+static void psci_afflvl2_suspend_finish(aff_map_node_t *system_node)
+{
+	unsigned int plat_state;
+
+	/* Cannot go beyond this affinity level */
+	assert(system_node->level == MPIDR_AFFLVL2);
+
+	/*
+	 * Currently, there are no architectural actions to perform
+	 * at the system level.
+	 */
+
+	/*
+	 * Plat. management: Perform the platform specific actions
+	 * as per the old state of the cluster e.g. enabling
+	 * coherency at the interconnect depends upon the state with
+	 * which this cluster was powered up. If anything goes wrong
+	 * then assert as there is no way to recover from this
+	 * situation.
+	 */
+
+	/* Get the physical state of the system */
+	plat_state = psci_get_phys_state(system_node);
+	psci_plat_pm_ops->affinst_suspend_finish(system_node->level,
+						      plat_state);
+}
+
+const afflvl_power_on_finisher_t psci_afflvl_suspend_finishers[] = {
+	psci_afflvl0_suspend_finish,
+	psci_afflvl1_suspend_finish,
+	psci_afflvl2_suspend_finish,
+};
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_common.c b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_common.c
new file mode 100644
index 0000000..ad163ba
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_common.c
@@ -0,0 +1,655 @@
+/*
+ * 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 <context.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <platform.h>
+#include <string.h>
+#include "psci_private.h"
+
+/*
+ * SPD power management operations, expected to be supplied by the registered
+ * SPD on successful SP initialization
+ */
+const spd_pm_ops_t *psci_spd_pm;
+
+/*******************************************************************************
+ * Grand array that holds the platform's topology information for state
+ * management of affinity instances. Each node (aff_map_node) in the array
+ * corresponds to an affinity instance e.g. cluster, cpu within an mpidr
+ ******************************************************************************/
+aff_map_node_t psci_aff_map[PSCI_NUM_AFFS]
+#if USE_COHERENT_MEM
+__attribute__ ((section("tzfw_coherent_mem")))
+#endif
+;
+
+/*******************************************************************************
+ * Pointer to functions exported by the platform to complete power mgmt. ops
+ ******************************************************************************/
+const plat_pm_ops_t *psci_plat_pm_ops;
+
+/*******************************************************************************
+ * This function is passed an array of pointers to affinity level nodes in the
+ * topology tree for an mpidr. It iterates through the nodes to find the highest
+ * affinity level which is marked as physically powered off.
+ ******************************************************************************/
+uint32_t psci_find_max_phys_off_afflvl(uint32_t start_afflvl,
+				       uint32_t end_afflvl,
+				       aff_map_node_t *mpidr_nodes[])
+{
+	uint32_t max_afflvl = PSCI_INVALID_DATA;
+
+	for (; start_afflvl <= end_afflvl; start_afflvl++) {
+		if (mpidr_nodes[start_afflvl] == NULL)
+			continue;
+
+		if (psci_get_phys_state(mpidr_nodes[start_afflvl]) ==
+		    PSCI_STATE_OFF)
+			max_afflvl = start_afflvl;
+	}
+
+	return max_afflvl;
+}
+
+/*******************************************************************************
+ * This function verifies that the all the other cores in the system have been
+ * turned OFF and the current CPU is the last running CPU in the system.
+ * Returns 1 (true) if the current CPU is the last ON CPU or 0 (false)
+ * otherwise.
+ ******************************************************************************/
+unsigned int psci_is_last_on_cpu(void)
+{
+	unsigned long mpidr = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
+	unsigned int i;
+
+	for (i = psci_aff_limits[MPIDR_AFFLVL0].min;
+			i <= psci_aff_limits[MPIDR_AFFLVL0].max; i++) {
+
+		assert(psci_aff_map[i].level == MPIDR_AFFLVL0);
+
+		if (!(psci_aff_map[i].state & PSCI_AFF_PRESENT))
+			continue;
+
+		if (psci_aff_map[i].mpidr == mpidr) {
+			assert(psci_get_state(&psci_aff_map[i])
+					== PSCI_STATE_ON);
+			continue;
+		}
+
+		if (psci_get_state(&psci_aff_map[i]) != PSCI_STATE_OFF)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*******************************************************************************
+ * This function saves the highest affinity level which is in OFF state. The
+ * affinity instance with which the level is associated is determined by the
+ * caller.
+ ******************************************************************************/
+void psci_set_max_phys_off_afflvl(uint32_t afflvl)
+{
+	set_cpu_data(psci_svc_cpu_data.max_phys_off_afflvl, afflvl);
+
+	/*
+	 * Ensure that the saved value is flushed to main memory and any
+	 * speculatively pre-fetched stale copies are invalidated from the
+	 * caches of other cpus in the same coherency domain. This ensures that
+	 * the value can be safely read irrespective of the state of the data
+	 * cache.
+	 */
+	flush_cpu_data(psci_svc_cpu_data.max_phys_off_afflvl);
+}
+
+/*******************************************************************************
+ * This function reads the saved highest affinity level which is in OFF
+ * state. The affinity instance with which the level is associated is determined
+ * by the caller.
+ ******************************************************************************/
+uint32_t psci_get_max_phys_off_afflvl(void)
+{
+	/*
+	 * Ensure that the last update of this value in this cpu's cache is
+	 * flushed to main memory and any speculatively pre-fetched stale copies
+	 * are invalidated from the caches of other cpus in the same coherency
+	 * domain. This ensures that the value is always read from the main
+	 * memory when it was written before the data cache was enabled.
+	 */
+	flush_cpu_data(psci_svc_cpu_data.max_phys_off_afflvl);
+	return get_cpu_data(psci_svc_cpu_data.max_phys_off_afflvl);
+}
+
+/*******************************************************************************
+ * Routine to return the maximum affinity level to traverse to after a cpu has
+ * been physically powered up. It is expected to be called immediately after
+ * reset from assembler code.
+ ******************************************************************************/
+int get_power_on_target_afflvl()
+{
+	int afflvl;
+
+#if DEBUG
+	unsigned int state;
+	aff_map_node_t *node;
+
+	/* Retrieve our node from the topology tree */
+	node = psci_get_aff_map_node(read_mpidr_el1() & MPIDR_AFFINITY_MASK,
+				     MPIDR_AFFLVL0);
+	assert(node);
+
+	/*
+	 * Sanity check the state of the cpu. It should be either suspend or "on
+	 * pending"
+	 */
+	state = psci_get_state(node);
+	assert(state == PSCI_STATE_SUSPEND || state == PSCI_STATE_ON_PENDING);
+#endif
+
+	/*
+	 * Assume that this cpu was suspended and retrieve its target affinity
+	 * level. If it is invalid then it could only have been turned off
+	 * earlier. get_max_afflvl() will return the highest affinity level a
+	 * cpu can be turned off to.
+	 */
+	afflvl = psci_get_suspend_afflvl();
+	if (afflvl == PSCI_INVALID_DATA)
+		afflvl = get_max_afflvl();
+	return afflvl;
+}
+
+/*******************************************************************************
+ * Simple routine to retrieve the maximum affinity level supported by the
+ * platform and check that it makes sense.
+ ******************************************************************************/
+int get_max_afflvl(void)
+{
+	int aff_lvl;
+
+	aff_lvl = plat_get_max_afflvl();
+	assert(aff_lvl <= MPIDR_MAX_AFFLVL && aff_lvl >= MPIDR_AFFLVL0);
+
+	return aff_lvl;
+}
+
+/*******************************************************************************
+ * Simple routine to set the id of an affinity instance at a given level in the
+ * mpidr.
+ ******************************************************************************/
+unsigned long mpidr_set_aff_inst(unsigned long mpidr,
+				 unsigned char aff_inst,
+				 int aff_lvl)
+{
+	unsigned long aff_shift;
+
+	assert(aff_lvl <= MPIDR_AFFLVL3);
+
+	/*
+	 * Decide the number of bits to shift by depending upon
+	 * the affinity level
+	 */
+	aff_shift = get_afflvl_shift(aff_lvl);
+
+	/* Clear the existing affinity instance & set the new one*/
+	mpidr &= ~(MPIDR_AFFLVL_MASK << aff_shift);
+	mpidr |= aff_inst << aff_shift;
+
+	return mpidr;
+}
+
+/*******************************************************************************
+ * This function sanity checks a range of affinity levels.
+ ******************************************************************************/
+int psci_check_afflvl_range(int start_afflvl, int end_afflvl)
+{
+	/* Sanity check the parameters passed */
+	if (end_afflvl > get_max_afflvl())
+		return PSCI_E_INVALID_PARAMS;
+
+	if (start_afflvl < MPIDR_AFFLVL0)
+		return PSCI_E_INVALID_PARAMS;
+
+	if (end_afflvl < start_afflvl)
+		return PSCI_E_INVALID_PARAMS;
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * This function is passed an array of pointers to affinity level nodes in the
+ * topology tree for an mpidr and the state which each node should transition
+ * to. It updates the state of each node between the specified affinity levels.
+ ******************************************************************************/
+void psci_do_afflvl_state_mgmt(uint32_t start_afflvl,
+			       uint32_t end_afflvl,
+			       aff_map_node_t *mpidr_nodes[],
+			       uint32_t state)
+{
+	uint32_t level;
+
+	for (level = start_afflvl; level <= end_afflvl; level++) {
+		if (mpidr_nodes[level] == NULL)
+			continue;
+		psci_set_state(mpidr_nodes[level], state);
+	}
+}
+
+/*******************************************************************************
+ * This function is passed an array of pointers to affinity level nodes in the
+ * topology tree for an mpidr. It picks up locks for each affinity level bottom
+ * up in the range specified.
+ ******************************************************************************/
+void psci_acquire_afflvl_locks(int start_afflvl,
+			       int end_afflvl,
+			       aff_map_node_t *mpidr_nodes[])
+{
+	int level;
+
+	for (level = start_afflvl; level <= end_afflvl; level++) {
+		if (mpidr_nodes[level] == NULL)
+			continue;
+
+		psci_lock_get(mpidr_nodes[level]);
+	}
+}
+
+/*******************************************************************************
+ * This function is passed an array of pointers to affinity level nodes in the
+ * topology tree for an mpidr. It releases the lock for each affinity level top
+ * down in the range specified.
+ ******************************************************************************/
+void psci_release_afflvl_locks(int start_afflvl,
+			       int end_afflvl,
+			       aff_map_node_t *mpidr_nodes[])
+{
+	int level;
+
+	for (level = end_afflvl; level >= start_afflvl; level--) {
+		if (mpidr_nodes[level] == NULL)
+			continue;
+
+		psci_lock_release(mpidr_nodes[level]);
+	}
+}
+
+/*******************************************************************************
+ * Simple routine to determine whether an affinity instance at a given level
+ * in an mpidr exists or not.
+ ******************************************************************************/
+int psci_validate_mpidr(unsigned long mpidr, int level)
+{
+	aff_map_node_t *node;
+
+	node = psci_get_aff_map_node(mpidr, level);
+	if (node && (node->state & PSCI_AFF_PRESENT))
+		return PSCI_E_SUCCESS;
+	else
+		return PSCI_E_INVALID_PARAMS;
+}
+
+/*******************************************************************************
+ * This function determines the full entrypoint information for the requested
+ * PSCI entrypoint on power on/resume and returns it.
+ ******************************************************************************/
+int psci_get_ns_ep_info(entry_point_info_t *ep,
+		       uint64_t entrypoint, uint64_t context_id)
+{
+	uint32_t ep_attr, mode, sctlr, daif, ee;
+	uint32_t ns_scr_el3 = read_scr_el3();
+	uint32_t ns_sctlr_el1 = read_sctlr_el1();
+
+	sctlr = ns_scr_el3 & SCR_HCE_BIT ? read_sctlr_el2() : ns_sctlr_el1;
+	ee = 0;
+
+	ep_attr = NON_SECURE | EP_ST_DISABLE;
+	if (sctlr & SCTLR_EE_BIT) {
+		ep_attr |= EP_EE_BIG;
+		ee = 1;
+	}
+	SET_PARAM_HEAD(ep, PARAM_EP, VERSION_1, ep_attr);
+
+	ep->pc = entrypoint;
+	memset(&ep->args, 0, sizeof(ep->args));
+	ep->args.arg0 = context_id;
+
+	/*
+	 * Figure out whether the cpu enters the non-secure address space
+	 * in aarch32 or aarch64
+	 */
+	if (ns_scr_el3 & SCR_RW_BIT) {
+
+		/*
+		 * Check whether a Thumb entry point has been provided for an
+		 * aarch64 EL
+		 */
+		if (entrypoint & 0x1)
+			return PSCI_E_INVALID_PARAMS;
+
+		mode = ns_scr_el3 & SCR_HCE_BIT ? MODE_EL2 : MODE_EL1;
+
+		ep->spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	} else {
+
+		mode = ns_scr_el3 & SCR_HCE_BIT ? MODE32_hyp : MODE32_svc;
+
+		/*
+		 * TODO: Choose async. exception bits if HYP mode is not
+		 * implemented according to the values of SCR.{AW, FW} bits
+		 */
+		daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
+
+		ep->spsr = SPSR_MODE32(mode, entrypoint & 0x1, ee, daif);
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * This function takes a pointer to an affinity node in the topology tree and
+ * returns its state. State of a non-leaf node needs to be calculated.
+ ******************************************************************************/
+unsigned short psci_get_state(aff_map_node_t *node)
+{
+#if !USE_COHERENT_MEM
+	flush_dcache_range((uint64_t) node, sizeof(*node));
+#endif
+
+	assert(node->level >= MPIDR_AFFLVL0 && node->level <= MPIDR_MAX_AFFLVL);
+
+	/* A cpu node just contains the state which can be directly returned */
+	if (node->level == MPIDR_AFFLVL0)
+		return (node->state >> PSCI_STATE_SHIFT) & PSCI_STATE_MASK;
+
+	/*
+	 * For an affinity level higher than a cpu, the state has to be
+	 * calculated. It depends upon the value of the reference count
+	 * which is managed by each node at the next lower affinity level
+	 * e.g. for a cluster, each cpu increments/decrements the reference
+	 * count. If the reference count is 0 then the affinity level is
+	 * OFF else ON.
+	 */
+	if (node->ref_count)
+		return PSCI_STATE_ON;
+	else
+		return PSCI_STATE_OFF;
+}
+
+/*******************************************************************************
+ * This function takes a pointer to an affinity node in the topology tree and
+ * a target state. State of a non-leaf node needs to be converted to a reference
+ * count. State of a leaf node can be set directly.
+ ******************************************************************************/
+void psci_set_state(aff_map_node_t *node, unsigned short state)
+{
+	assert(node->level >= MPIDR_AFFLVL0 && node->level <= MPIDR_MAX_AFFLVL);
+
+	/*
+	 * For an affinity level higher than a cpu, the state is used
+	 * to decide whether the reference count is incremented or
+	 * decremented. Entry into the ON_PENDING state does not have
+	 * effect.
+	 */
+	if (node->level > MPIDR_AFFLVL0) {
+		switch (state) {
+		case PSCI_STATE_ON:
+			node->ref_count++;
+			break;
+		case PSCI_STATE_OFF:
+		case PSCI_STATE_SUSPEND:
+			node->ref_count--;
+			break;
+		case PSCI_STATE_ON_PENDING:
+			/*
+			 * An affinity level higher than a cpu will not undergo
+			 * a state change when it is about to be turned on
+			 */
+			return;
+		default:
+			assert(0);
+		}
+	} else {
+		node->state &= ~(PSCI_STATE_MASK << PSCI_STATE_SHIFT);
+		node->state |= (state & PSCI_STATE_MASK) << PSCI_STATE_SHIFT;
+	}
+
+#if !USE_COHERENT_MEM
+	flush_dcache_range((uint64_t) node, sizeof(*node));
+#endif
+}
+
+/*******************************************************************************
+ * An affinity level could be on, on_pending, suspended or off. These are the
+ * logical states it can be in. Physically either it is off or on. When it is in
+ * the state on_pending then it is about to be turned on. It is not possible to
+ * tell whether that's actually happenned or not. So we err on the side of
+ * caution & treat the affinity level as being turned off.
+ ******************************************************************************/
+unsigned short psci_get_phys_state(aff_map_node_t *node)
+{
+	unsigned int state;
+
+	state = psci_get_state(node);
+	return get_phys_state(state);
+}
+
+/*******************************************************************************
+ * This function takes an array of pointers to affinity instance nodes in the
+ * topology tree and calls the physical power on handler for the corresponding
+ * affinity levels
+ ******************************************************************************/
+static void psci_call_power_on_handlers(aff_map_node_t *mpidr_nodes[],
+				       int start_afflvl,
+				       int end_afflvl,
+				       afflvl_power_on_finisher_t *pon_handlers)
+{
+	int level;
+	aff_map_node_t *node;
+
+	for (level = end_afflvl; level >= start_afflvl; level--) {
+		node = mpidr_nodes[level];
+		if (node == NULL)
+			continue;
+
+		/*
+		 * If we run into any trouble while powering up an
+		 * affinity instance, then there is no recovery path
+		 * so simply return an error and let the caller take
+		 * care of the situation.
+		 */
+		pon_handlers[level](node);
+	}
+}
+
+/*******************************************************************************
+ * Generic handler which is called when a cpu is physically powered on. It
+ * traverses through all the affinity levels performing generic, architectural,
+ * platform setup and state management e.g. for a cluster that's been powered
+ * on, it will call the platform specific code which will enable coherency at
+ * the interconnect level. For a cpu it could mean turning on the MMU etc.
+ *
+ * The state of all the relevant affinity levels is changed after calling the
+ * affinity level specific handlers as their actions would depend upon the state
+ * the affinity level is exiting from.
+ *
+ * The affinity level specific handlers are called in descending order i.e. from
+ * the highest to the lowest affinity level implemented by the platform because
+ * to turn on affinity level X it is neccesary to turn on affinity level X + 1
+ * first.
+ ******************************************************************************/
+void psci_afflvl_power_on_finish(int start_afflvl,
+				 int end_afflvl,
+				 afflvl_power_on_finisher_t *pon_handlers)
+{
+	mpidr_aff_map_nodes_t mpidr_nodes;
+	int rc;
+	unsigned int max_phys_off_afflvl;
+
+
+	/*
+	 * Collect the pointers to the nodes in the topology tree for
+	 * each affinity instance in the mpidr. If this function does
+	 * not return successfully then either the mpidr or the affinity
+	 * levels are incorrect. Either case is an irrecoverable error.
+	 */
+	rc = psci_get_aff_map_nodes(read_mpidr_el1() & MPIDR_AFFINITY_MASK,
+				    start_afflvl,
+				    end_afflvl,
+				    mpidr_nodes);
+	if (rc != PSCI_E_SUCCESS)
+		panic();
+
+	/*
+	 * This function acquires the lock corresponding to each affinity
+	 * level so that by the time all locks are taken, the system topology
+	 * is snapshot and state management can be done safely.
+	 */
+	psci_acquire_afflvl_locks(start_afflvl,
+				  end_afflvl,
+				  mpidr_nodes);
+
+	max_phys_off_afflvl = psci_find_max_phys_off_afflvl(start_afflvl,
+							    end_afflvl,
+							    mpidr_nodes);
+	assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
+
+	/*
+	 * Stash the highest affinity level that will come out of the OFF or
+	 * SUSPEND states.
+	 */
+	psci_set_max_phys_off_afflvl(max_phys_off_afflvl);
+
+	/* Perform generic, architecture and platform specific handling */
+	psci_call_power_on_handlers(mpidr_nodes,
+					 start_afflvl,
+					 end_afflvl,
+					 pon_handlers);
+
+	/*
+	 * This function updates the state of each affinity instance
+	 * corresponding to the mpidr in the range of affinity levels
+	 * specified.
+	 */
+	psci_do_afflvl_state_mgmt(start_afflvl,
+				  end_afflvl,
+				  mpidr_nodes,
+				  PSCI_STATE_ON);
+
+	/*
+	 * Invalidate the entry for the highest affinity level stashed earlier.
+	 * This ensures that any reads of this variable outside the power
+	 * up/down sequences return PSCI_INVALID_DATA
+	 */
+	psci_set_max_phys_off_afflvl(PSCI_INVALID_DATA);
+
+	/*
+	 * This loop releases the lock corresponding to each affinity level
+	 * in the reverse order to which they were acquired.
+	 */
+	psci_release_afflvl_locks(start_afflvl,
+				  end_afflvl,
+				  mpidr_nodes);
+}
+
+/*******************************************************************************
+ * This function initializes the set of hooks that PSCI invokes as part of power
+ * management operation. The power management hooks are expected to be provided
+ * by the SPD, after it finishes all its initialization
+ ******************************************************************************/
+void psci_register_spd_pm_hook(const spd_pm_ops_t *pm)
+{
+	assert(pm);
+	psci_spd_pm = pm;
+
+	if (pm->svc_migrate)
+		psci_caps |= define_psci_cap(PSCI_MIG_AARCH64);
+
+	if (pm->svc_migrate_info)
+		psci_caps |= define_psci_cap(PSCI_MIG_INFO_UP_CPU_AARCH64)
+				| define_psci_cap(PSCI_MIG_INFO_TYPE);
+}
+
+/*******************************************************************************
+ * This function invokes the migrate info hook in the spd_pm_ops. It performs
+ * the necessary return value validation. If the Secure Payload is UP and
+ * migrate capable, it returns the mpidr of the CPU on which the Secure payload
+ * is resident through the mpidr parameter. Else the value of the parameter on
+ * return is undefined.
+ ******************************************************************************/
+int psci_spd_migrate_info(uint64_t *mpidr)
+{
+	int rc;
+
+	if (!psci_spd_pm || !psci_spd_pm->svc_migrate_info)
+		return PSCI_E_NOT_SUPPORTED;
+
+	rc = psci_spd_pm->svc_migrate_info(mpidr);
+
+	assert(rc == PSCI_TOS_UP_MIG_CAP || rc == PSCI_TOS_NOT_UP_MIG_CAP \
+		|| rc == PSCI_TOS_NOT_PRESENT_MP || rc == PSCI_E_NOT_SUPPORTED);
+
+	return rc;
+}
+
+
+/*******************************************************************************
+ * This function prints the state of all affinity instances present in the
+ * system
+ ******************************************************************************/
+void psci_print_affinity_map(void)
+{
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+	aff_map_node_t *node;
+	unsigned int idx;
+	/* This array maps to the PSCI_STATE_X definitions in psci.h */
+	static const char *psci_state_str[] = {
+		"ON",
+		"OFF",
+		"ON_PENDING",
+		"SUSPEND"
+	};
+
+	INFO("PSCI Affinity Map:\n");
+	for (idx = 0; idx < PSCI_NUM_AFFS ; idx++) {
+		node = &psci_aff_map[idx];
+		if (!(node->state & PSCI_AFF_PRESENT)) {
+			continue;
+		}
+		INFO("  AffInst: Level %u, MPID 0x%lx, State %s\n",
+				node->level, node->mpidr,
+				psci_state_str[psci_get_state(node)]);
+	}
+#endif
+}
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_entry.S b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_entry.S
new file mode 100644
index 0000000..3e67d34
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_entry.S
@@ -0,0 +1,172 @@
+/*
+ * 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 <psci.h>
+#include <xlat_tables.h>
+
+	.globl	psci_aff_on_finish_entry
+	.globl	psci_aff_suspend_finish_entry
+	.globl	psci_power_down_wfi
+
+	/* -----------------------------------------------------
+	 * This cpu has been physically powered up. Depending
+	 * upon whether it was resumed from suspend or simply
+	 * turned on, call the common power on finisher with
+	 * the handlers (chosen depending upon original state).
+	 * -----------------------------------------------------
+	 */
+func psci_aff_on_finish_entry
+	adr	x23, psci_afflvl_on_finishers
+	b	psci_aff_common_finish_entry
+
+psci_aff_suspend_finish_entry:
+	adr	x23, psci_afflvl_suspend_finishers
+
+psci_aff_common_finish_entry:
+#if !RESET_TO_BL31
+	/* ---------------------------------------------
+	 * Perform any processor specific actions which
+	 * undo or are in addition to the actions
+	 * performed by the reset handler in the BootROM
+	 * (BL1) e.g. cache, tlb invalidations, errata
+	 * workarounds etc.
+	 * ---------------------------------------------
+	 */
+	bl      reset_handler
+
+	/* ---------------------------------------------
+	 * Enable the instruction cache, stack pointer
+	 * and data access alignment checks.
+	 * It can be assumed that BL3-1 entrypoint code
+	 * will do this when RESET_TO_BL31 is set. The
+	 * same  assumption cannot be made when another
+	 * boot loader executes before BL3-1 in the warm
+	 * boot path e.g. BL1.
+	 * ---------------------------------------------
+	 */
+	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	mrs	x0, sctlr_el3
+	orr	x0, x0, x1
+	msr	sctlr_el3, x0
+	isb
+#endif
+
+	/* ---------------------------------------------
+	 * Initialise the pcpu cache pointer for the CPU
+	 * ---------------------------------------------
+	 */
+	bl	init_cpu_data_ptr
+
+	/* ---------------------------------------------
+	 * Initialize the cpu_ops pointer.
+	 * ---------------------------------------------
+	 */
+	bl	init_cpu_ops
+
+	/* ---------------------------------------------
+	 * Set the exception vectors
+	 * ---------------------------------------------
+	 */
+	adr	x0, runtime_exceptions
+	msr	vbar_el3, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Enable the SError interrupt now that the
+	 * exception vectors have been setup.
+	 * ---------------------------------------------
+	 */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	/* ---------------------------------------------
+	 * Use SP_EL0 for the C runtime stack.
+	 * ---------------------------------------------
+	 */
+	msr	spsel, #0
+
+	/* --------------------------------------------
+	 * 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	bl31_plat_enable_mmu
+
+	/* ---------------------------------------------
+	 * Call the finishers starting from affinity
+	 * level 0.
+	 * ---------------------------------------------
+	 */
+	bl	get_power_on_target_afflvl
+	mov	x2, x23
+	mov	x1, x0
+	mov	x0, #MPIDR_AFFLVL0
+	bl	psci_afflvl_power_on_finish
+
+	b	el3_exit
+
+	/* --------------------------------------------
+	 * This function is called to indicate to the
+	 * power controller that it is safe to power
+	 * down this cpu. It should not exit the wfi
+	 * and will be released from reset upon power
+	 * up. 'wfi_spill' is used to catch erroneous
+	 * exits from wfi.
+	 * --------------------------------------------
+	 */
+func psci_power_down_wfi
+	dsb	sy		// ensure write buffer empty
+	wfi
+wfi_spill:
+	b	wfi_spill
+
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_helpers.S b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_helpers.S
new file mode 100644
index 0000000..9a51d5c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_helpers.S
@@ -0,0 +1,166 @@
+/*
+ * 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 <assert_macros.S>
+#include <platform_def.h>
+#include <psci.h>
+
+	.globl	psci_do_pwrdown_cache_maintenance
+	.globl	psci_do_pwrup_cache_maintenance
+
+/* -----------------------------------------------------------------------
+ * void psci_do_pwrdown_cache_maintenance(uint32_t affinity level);
+ *
+ * This function performs cache maintenance if the specified affinity
+ * level is the equal to the level of the highest affinity instance which
+ * will be/is physically powered off. The levels of cache affected are
+ * determined by the affinity level which is passed as the argument i.e.
+ * level 0 results in a flush of the L1 cache. Both the L1 and L2 caches
+ * are flushed for a higher affinity level.
+ *
+ * Additionally, this function also ensures that stack memory is correctly
+ * flushed out to avoid coherency issues due to a change in its memory
+ * attributes after the data cache is disabled.
+ * -----------------------------------------------------------------------
+ */
+func psci_do_pwrdown_cache_maintenance
+	stp     x29, x30, [sp,#-16]!
+	stp     x19, x20, [sp,#-16]!
+
+	mov	x19, x0
+	bl	psci_get_max_phys_off_afflvl
+#if ASM_ASSERTION
+	cmp	x0, #PSCI_INVALID_DATA
+	ASM_ASSERT(ne)
+#endif
+	cmp	x0, x19
+	b.ne	1f
+
+	/* ---------------------------------------------
+	 * Determine to how many levels of cache will be
+	 * subject to cache maintenance. Affinity level
+	 * 0 implies that only the cpu is being powered
+	 * down. Only the L1 data cache needs to be
+	 * flushed to the PoU in this case. For a higher
+	 * affinity level we are assuming that a flush
+	 * of L1 data and L2 unified cache is enough.
+	 * This information should be provided by the
+	 * platform.
+	 * ---------------------------------------------
+	 */
+	cmp	x0, #MPIDR_AFFLVL0
+	b.eq	do_core_pwr_dwn
+	bl	prepare_cluster_pwr_dwn
+	b	do_stack_maintenance
+
+do_core_pwr_dwn:
+	bl	prepare_core_pwr_dwn
+
+	/* ---------------------------------------------
+	 * Do stack maintenance by flushing the used
+	 * stack to the main memory and invalidating the
+	 * remainder.
+	 * ---------------------------------------------
+	 */
+do_stack_maintenance:
+	mrs	x0, mpidr_el1
+	bl	platform_get_stack
+
+	/* ---------------------------------------------
+	 * Calculate and store the size of the used
+	 * stack memory in x1.
+	 * ---------------------------------------------
+	 */
+	mov	x19, x0
+	mov	x1, sp
+	sub	x1, x0, x1
+	mov	x0, sp
+	bl	flush_dcache_range
+
+	/* ---------------------------------------------
+	 * Calculate and store the size of the unused
+	 * stack memory in x1. Calculate and store the
+	 * stack base address in x0.
+	 * ---------------------------------------------
+	 */
+	sub	x0, x19, #PLATFORM_STACK_SIZE
+	sub	x1, sp, x0
+	bl	inv_dcache_range
+
+1:
+	ldp	x19, x20, [sp], #16
+	ldp	x29, x30, [sp], #16
+	ret
+
+
+/* -----------------------------------------------------------------------
+ * void psci_do_pwrup_cache_maintenance(void);
+ *
+ * This function performs cache maintenance after this cpu is powered up.
+ * Currently, this involves managing the used stack memory before turning
+ * on the data cache.
+ * -----------------------------------------------------------------------
+ */
+func psci_do_pwrup_cache_maintenance
+	stp	x29, x30, [sp,#-16]!
+
+	/* ---------------------------------------------
+	 * Ensure any inflight stack writes have made it
+	 * to main memory.
+	 * ---------------------------------------------
+	 */
+	dmb	st
+
+	/* ---------------------------------------------
+	 * Calculate and store the size of the used
+	 * stack memory in x1. Calculate and store the
+	 * stack base address in x0.
+	 * ---------------------------------------------
+	 */
+	mrs	x0, mpidr_el1
+	bl	platform_get_stack
+	mov	x1, sp
+	sub	x1, x0, x1
+	mov	x0, sp
+	bl	inv_dcache_range
+
+	/* ---------------------------------------------
+	 * Enable the data cache.
+	 * ---------------------------------------------
+	 */
+	mrs	x0, sctlr_el3
+	orr	x0, x0, #SCTLR_C_BIT
+	msr	sctlr_el3, x0
+	isb
+
+	ldp	x29, x30, [sp], #16
+	ret
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_main.c b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_main.c
new file mode 100644
index 0000000..52d252c
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_main.c
@@ -0,0 +1,463 @@
+/*
+ * 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 <debug.h>
+#include <platform.h>
+#include <runtime_svc.h>
+#include <std_svc.h>
+#include "psci_private.h"
+
+/*******************************************************************************
+ * PSCI frontend api for servicing SMCs. Described in the PSCI spec.
+ ******************************************************************************/
+int psci_cpu_on(unsigned long target_cpu,
+		unsigned long entrypoint,
+		unsigned long context_id)
+
+{
+	int rc;
+	unsigned int start_afflvl, end_afflvl;
+	entry_point_info_t ep;
+
+	/* Determine if the cpu exists of not */
+	rc = psci_validate_mpidr(target_cpu, MPIDR_AFFLVL0);
+	if (rc != PSCI_E_SUCCESS) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	/* Validate the entrypoint using platform pm_ops */
+	if (psci_plat_pm_ops->validate_ns_entrypoint) {
+		rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
+		if (rc != PSCI_E_SUCCESS) {
+			assert(rc == PSCI_E_INVALID_PARAMS);
+			return PSCI_E_INVALID_PARAMS;
+		}
+	}
+
+	/*
+	 * Verify and derive the re-entry information for
+	 * the non-secure world from the non-secure state from
+	 * where this call originated.
+	 */
+	rc = psci_get_ns_ep_info(&ep, entrypoint, context_id);
+	if (rc != PSCI_E_SUCCESS)
+		return rc;
+
+
+	/*
+	 * To turn this cpu on, specify which affinity
+	 * levels need to be turned on
+	 */
+	start_afflvl = MPIDR_AFFLVL0;
+	end_afflvl = get_max_afflvl();
+	rc = psci_afflvl_on(target_cpu,
+			    &ep,
+			    start_afflvl,
+			    end_afflvl);
+
+	return rc;
+}
+
+unsigned int psci_version(void)
+{
+	return PSCI_MAJOR_VER | PSCI_MINOR_VER;
+}
+
+int psci_cpu_suspend(unsigned int power_state,
+		     unsigned long entrypoint,
+		     unsigned long context_id)
+{
+	int rc;
+	unsigned int target_afflvl, pstate_type;
+	entry_point_info_t ep;
+
+	/* Check SBZ bits in power state are zero */
+	if (psci_validate_power_state(power_state))
+		return PSCI_E_INVALID_PARAMS;
+
+	/* Sanity check the requested state */
+	target_afflvl = psci_get_pstate_afflvl(power_state);
+	if (target_afflvl > get_max_afflvl())
+		return PSCI_E_INVALID_PARAMS;
+
+	/* Validate the power_state using platform pm_ops */
+	if (psci_plat_pm_ops->validate_power_state) {
+		rc = psci_plat_pm_ops->validate_power_state(power_state);
+		if (rc != PSCI_E_SUCCESS) {
+			assert(rc == PSCI_E_INVALID_PARAMS);
+			return PSCI_E_INVALID_PARAMS;
+		}
+	}
+
+	/* Validate the entrypoint using platform pm_ops */
+	if (psci_plat_pm_ops->validate_ns_entrypoint) {
+		rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
+		if (rc != PSCI_E_SUCCESS) {
+			assert(rc == PSCI_E_INVALID_PARAMS);
+			return PSCI_E_INVALID_PARAMS;
+		}
+	}
+
+	/* Determine the 'state type' in the 'power_state' parameter */
+	pstate_type = psci_get_pstate_type(power_state);
+
+	/*
+	 * Ensure that we have a platform specific handler for entering
+	 * a standby state.
+	 */
+	if (pstate_type == PSTATE_TYPE_STANDBY) {
+		if  (!psci_plat_pm_ops->affinst_standby)
+			return PSCI_E_INVALID_PARAMS;
+
+		psci_plat_pm_ops->affinst_standby(power_state);
+		return PSCI_E_SUCCESS;
+	}
+
+	/*
+	 * Verify and derive the re-entry information for
+	 * the non-secure world from the non-secure state from
+	 * where this call originated.
+	 */
+	rc = psci_get_ns_ep_info(&ep, entrypoint, context_id);
+	if (rc != PSCI_E_SUCCESS)
+		return rc;
+
+	/* Save PSCI power state parameter for the core in suspend context */
+	psci_set_suspend_power_state(power_state);
+
+	/*
+	 * Do what is needed to enter the power down state. Upon success,
+	 * enter the final wfi which will power down this CPU.
+	 */
+	psci_afflvl_suspend(&ep,
+			    MPIDR_AFFLVL0,
+			    target_afflvl);
+
+	/* Reset PSCI power state parameter for the core. */
+	psci_set_suspend_power_state(PSCI_INVALID_DATA);
+	return PSCI_E_SUCCESS;
+}
+
+int psci_system_suspend(unsigned long entrypoint,
+			unsigned long context_id)
+{
+	int rc;
+	unsigned int power_state;
+	entry_point_info_t ep;
+
+	/* Validate the entrypoint using platform pm_ops */
+	if (psci_plat_pm_ops->validate_ns_entrypoint) {
+		rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
+		if (rc != PSCI_E_SUCCESS) {
+			assert(rc == PSCI_E_INVALID_PARAMS);
+			return PSCI_E_INVALID_PARAMS;
+		}
+	}
+
+	/* Check if the current CPU is the last ON CPU in the system */
+	if (!psci_is_last_on_cpu())
+		return PSCI_E_DENIED;
+
+	/*
+	 * Verify and derive the re-entry information for
+	 * the non-secure world from the non-secure state from
+	 * where this call originated.
+	 */
+	rc = psci_get_ns_ep_info(&ep, entrypoint, context_id);
+	if (rc != PSCI_E_SUCCESS)
+		return rc;
+
+	/*
+	 * Assert that the required pm_ops hook is implemented to ensure that
+	 * the capability detected during psci_setup() is valid.
+	 */
+	assert(psci_plat_pm_ops->get_sys_suspend_power_state);
+
+	/*
+	 * Query the platform for the power_state required for system suspend
+	 */
+	power_state = psci_plat_pm_ops->get_sys_suspend_power_state();
+
+	/* Save PSCI power state parameter for the core in suspend context */
+	psci_set_suspend_power_state(power_state);
+
+	/*
+	 * Do what is needed to enter the power down state. Upon success,
+	 * enter the final wfi which will power down this cpu.
+	 */
+	psci_afflvl_suspend(&ep,
+			    MPIDR_AFFLVL0,
+			    PLATFORM_MAX_AFFLVL);
+
+	/* Reset PSCI power state parameter for the core. */
+	psci_set_suspend_power_state(PSCI_INVALID_DATA);
+	return PSCI_E_SUCCESS;
+}
+
+int psci_cpu_off(void)
+{
+	int rc;
+	int target_afflvl = get_max_afflvl();
+
+	/*
+	 * Traverse from the highest to the lowest affinity level. When the
+	 * lowest affinity level is hit, all the locks are acquired. State
+	 * management is done immediately followed by cpu, cluster ...
+	 * ..target_afflvl specific actions as this function unwinds back.
+	 */
+	rc = psci_afflvl_off(MPIDR_AFFLVL0, target_afflvl);
+
+	/*
+	 * The only error cpu_off can return is E_DENIED. So check if that's
+	 * indeed the case.
+	 */
+	assert (rc == PSCI_E_DENIED);
+
+	return rc;
+}
+
+int psci_affinity_info(unsigned long target_affinity,
+		       unsigned int lowest_affinity_level)
+{
+	int rc = PSCI_E_INVALID_PARAMS;
+	unsigned int aff_state;
+	aff_map_node_t *node;
+
+	if (lowest_affinity_level > get_max_afflvl())
+		return rc;
+
+	node = psci_get_aff_map_node(target_affinity, lowest_affinity_level);
+	if (node && (node->state & PSCI_AFF_PRESENT)) {
+
+		/*
+		 * TODO: For affinity levels higher than 0 i.e. cpu, the
+		 * state will always be either ON or OFF. Need to investigate
+		 * how critical is it to support ON_PENDING here.
+		 */
+		aff_state = psci_get_state(node);
+
+		/* A suspended cpu is available & on for the OS */
+		if (aff_state == PSCI_STATE_SUSPEND) {
+			aff_state = PSCI_STATE_ON;
+		}
+
+		rc = aff_state;
+	}
+
+	return rc;
+}
+
+int psci_migrate(unsigned long target_cpu)
+{
+	int rc;
+	unsigned long resident_cpu_mpidr;
+
+	rc = psci_spd_migrate_info(&resident_cpu_mpidr);
+	if (rc != PSCI_TOS_UP_MIG_CAP)
+		return (rc == PSCI_TOS_NOT_UP_MIG_CAP) ?
+			  PSCI_E_DENIED : PSCI_E_NOT_SUPPORTED;
+
+	/*
+	 * Migrate should only be invoked on the CPU where
+	 * the Secure OS is resident.
+	 */
+	if (resident_cpu_mpidr != read_mpidr_el1())
+		return PSCI_E_NOT_PRESENT;
+
+	/* Check the validity of the specified target cpu */
+	rc = psci_validate_mpidr(target_cpu, MPIDR_AFFLVL0);
+	if (rc != PSCI_E_SUCCESS)
+		return PSCI_E_INVALID_PARAMS;
+
+	assert(psci_spd_pm && psci_spd_pm->svc_migrate);
+
+	rc = psci_spd_pm->svc_migrate(read_mpidr_el1(), target_cpu);
+	assert(rc == PSCI_E_SUCCESS || rc == PSCI_E_INTERN_FAIL);
+
+	return rc;
+}
+
+int psci_migrate_info_type(void)
+{
+	unsigned long resident_cpu_mpidr;
+
+	return psci_spd_migrate_info(&resident_cpu_mpidr);
+}
+
+long psci_migrate_info_up_cpu(void)
+{
+	unsigned long resident_cpu_mpidr;
+	int rc;
+
+	/*
+	 * Return value of this depends upon what
+	 * psci_spd_migrate_info() returns.
+	 */
+	rc = psci_spd_migrate_info(&resident_cpu_mpidr);
+	if (rc != PSCI_TOS_NOT_UP_MIG_CAP && rc != PSCI_TOS_UP_MIG_CAP)
+		return PSCI_E_INVALID_PARAMS;
+
+	return resident_cpu_mpidr;
+}
+
+int psci_features(unsigned int psci_fid)
+{
+	uint32_t local_caps = psci_caps;
+
+	/* Check if it is a 64 bit function */
+	if (((psci_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_64)
+		local_caps &= PSCI_CAP_64BIT_MASK;
+
+	/* Check for invalid fid */
+	if (!(is_std_svc_call(psci_fid) && is_valid_fast_smc(psci_fid)
+			&& is_psci_fid(psci_fid)))
+		return PSCI_E_NOT_SUPPORTED;
+
+
+	/* Check if the psci fid is supported or not */
+	if (!(local_caps & define_psci_cap(psci_fid)))
+		return PSCI_E_NOT_SUPPORTED;
+
+	/* Format the feature flags */
+	if (psci_fid == PSCI_CPU_SUSPEND_AARCH32 ||
+			psci_fid == PSCI_CPU_SUSPEND_AARCH64) {
+		/*
+		 * The trusted firmware uses the original power state format
+		 * and does not support OS Initiated Mode.
+		 */
+		return (FF_PSTATE_ORIG << FF_PSTATE_SHIFT) |
+			((!FF_SUPPORTS_OS_INIT_MODE) << FF_MODE_SUPPORT_SHIFT);
+	}
+
+	/* Return 0 for all other fid's */
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * PSCI top level handler for servicing SMCs.
+ ******************************************************************************/
+uint64_t psci_smc_handler(uint32_t smc_fid,
+			  uint64_t x1,
+			  uint64_t x2,
+			  uint64_t x3,
+			  uint64_t x4,
+			  void *cookie,
+			  void *handle,
+			  uint64_t flags)
+{
+	if (is_caller_secure(flags))
+		SMC_RET1(handle, SMC_UNK);
+
+	/* Check the fid against the capabilities */
+	if (!(psci_caps & define_psci_cap(smc_fid)))
+		SMC_RET1(handle, SMC_UNK);
+
+	if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) {
+		/* 32-bit PSCI function, clear top parameter bits */
+
+		x1 = (uint32_t)x1;
+		x2 = (uint32_t)x2;
+		x3 = (uint32_t)x3;
+
+		switch (smc_fid) {
+		case PSCI_VERSION:
+			SMC_RET1(handle, psci_version());
+
+		case PSCI_CPU_OFF:
+			SMC_RET1(handle, psci_cpu_off());
+
+		case PSCI_CPU_SUSPEND_AARCH32:
+			SMC_RET1(handle, psci_cpu_suspend(x1, x2, x3));
+
+		case PSCI_CPU_ON_AARCH32:
+			SMC_RET1(handle, psci_cpu_on(x1, x2, x3));
+
+		case PSCI_AFFINITY_INFO_AARCH32:
+			SMC_RET1(handle, psci_affinity_info(x1, x2));
+
+		case PSCI_MIG_AARCH32:
+			SMC_RET1(handle, psci_migrate(x1));
+
+		case PSCI_MIG_INFO_TYPE:
+			SMC_RET1(handle, psci_migrate_info_type());
+
+		case PSCI_MIG_INFO_UP_CPU_AARCH32:
+			SMC_RET1(handle, psci_migrate_info_up_cpu());
+
+		case PSCI_SYSTEM_SUSPEND_AARCH32:
+			SMC_RET1(handle, psci_system_suspend(x1, x2));
+
+		case PSCI_SYSTEM_OFF:
+			psci_system_off();
+			/* We should never return from psci_system_off() */
+
+		case PSCI_SYSTEM_RESET:
+			psci_system_reset();
+			/* We should never return from psci_system_reset() */
+
+		case PSCI_FEATURES:
+			SMC_RET1(handle, psci_features(x1));
+
+		default:
+			break;
+		}
+	} else {
+		/* 64-bit PSCI function */
+
+		switch (smc_fid) {
+		case PSCI_CPU_SUSPEND_AARCH64:
+			SMC_RET1(handle, psci_cpu_suspend(x1, x2, x3));
+
+		case PSCI_CPU_ON_AARCH64:
+			SMC_RET1(handle, psci_cpu_on(x1, x2, x3));
+
+		case PSCI_AFFINITY_INFO_AARCH64:
+			SMC_RET1(handle, psci_affinity_info(x1, x2));
+
+		case PSCI_MIG_AARCH64:
+			SMC_RET1(handle, psci_migrate(x1));
+
+		case PSCI_MIG_INFO_UP_CPU_AARCH64:
+			SMC_RET1(handle, psci_migrate_info_up_cpu());
+
+		case PSCI_SYSTEM_SUSPEND_AARCH64:
+			SMC_RET1(handle, psci_system_suspend(x1, x2));
+
+		default:
+			break;
+		}
+	}
+
+	WARN("Unimplemented PSCI Call: 0x%x \n", smc_fid);
+	SMC_RET1(handle, SMC_UNK);
+}
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_private.h b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_private.h
new file mode 100644
index 0000000..f23ed8a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_private.h
@@ -0,0 +1,181 @@
+/*
+ * 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 __PSCI_PRIVATE_H__
+#define __PSCI_PRIVATE_H__
+
+#include <arch.h>
+#include <bakery_lock.h>
+#include <bl_common.h>
+#include <psci.h>
+
+/*
+ * The following helper macros abstract the interface to the Bakery
+ * Lock API.
+ */
+#if USE_COHERENT_MEM
+#define psci_lock_init(aff_map, idx)	bakery_lock_init(&(aff_map)[(idx)].lock)
+#define psci_lock_get(node)		bakery_lock_get(&((node)->lock))
+#define psci_lock_release(node)		bakery_lock_release(&((node)->lock))
+#else
+#define psci_lock_init(aff_map, idx)	((aff_map)[(idx)].aff_map_index = (idx))
+#define psci_lock_get(node)		bakery_lock_get((node)->aff_map_index,	  \
+						CPU_DATA_PSCI_LOCK_OFFSET)
+#define psci_lock_release(node)		bakery_lock_release((node)->aff_map_index,\
+						CPU_DATA_PSCI_LOCK_OFFSET)
+#endif
+
+/*
+ * The PSCI capability which are provided by the generic code but does not
+ * depend on the platform or spd capabilities.
+ */
+#define PSCI_GENERIC_CAP	\
+			(define_psci_cap(PSCI_VERSION) |		\
+			define_psci_cap(PSCI_AFFINITY_INFO_AARCH64) |	\
+			define_psci_cap(PSCI_FEATURES))
+
+/*
+ * The PSCI capabilities mask for 64 bit functions.
+ */
+#define PSCI_CAP_64BIT_MASK	\
+			(define_psci_cap(PSCI_CPU_SUSPEND_AARCH64) |	\
+			define_psci_cap(PSCI_CPU_ON_AARCH64) |		\
+			define_psci_cap(PSCI_AFFINITY_INFO_AARCH64) |	\
+			define_psci_cap(PSCI_MIG_AARCH64) |		\
+			define_psci_cap(PSCI_MIG_INFO_UP_CPU_AARCH64) |	\
+			define_psci_cap(PSCI_SYSTEM_SUSPEND_AARCH64))
+
+
+/*******************************************************************************
+ * The following two data structures hold the topology tree which in turn tracks
+ * the state of the all the affinity instances supported by the platform.
+ ******************************************************************************/
+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
+	/* For indexing the bakery_info array in per CPU data */
+	unsigned char aff_map_index;
+#endif
+} aff_map_node_t;
+
+typedef struct aff_limits_node {
+	int min;
+	int max;
+} aff_limits_node_t;
+
+typedef aff_map_node_t (*mpidr_aff_map_nodes_t[MPIDR_MAX_AFFLVL + 1]);
+typedef void (*afflvl_power_on_finisher_t)(aff_map_node_t *);
+
+/*******************************************************************************
+ * Data prototypes
+ ******************************************************************************/
+extern const plat_pm_ops_t *psci_plat_pm_ops;
+extern aff_map_node_t psci_aff_map[PSCI_NUM_AFFS];
+extern aff_limits_node_t psci_aff_limits[MPIDR_MAX_AFFLVL + 1];
+extern uint32_t psci_caps;
+
+/*******************************************************************************
+ * SPD's power management hooks registered with PSCI
+ ******************************************************************************/
+extern const spd_pm_ops_t *psci_spd_pm;
+
+/*******************************************************************************
+ * Function prototypes
+ ******************************************************************************/
+/* Private exported functions from psci_common.c */
+int get_max_afflvl(void);
+unsigned short psci_get_state(aff_map_node_t *node);
+unsigned short psci_get_phys_state(aff_map_node_t *node);
+void psci_set_state(aff_map_node_t *node, unsigned short state);
+unsigned long mpidr_set_aff_inst(unsigned long, unsigned char, int);
+int psci_validate_mpidr(unsigned long, int);
+int get_power_on_target_afflvl(void);
+void psci_afflvl_power_on_finish(int,
+				int,
+				afflvl_power_on_finisher_t *);
+int psci_get_ns_ep_info(entry_point_info_t *ep,
+		       uint64_t entrypoint, uint64_t context_id);
+int psci_check_afflvl_range(int start_afflvl, int end_afflvl);
+void psci_do_afflvl_state_mgmt(uint32_t start_afflvl,
+			       uint32_t end_afflvl,
+			       aff_map_node_t *mpidr_nodes[],
+			       uint32_t state);
+void psci_acquire_afflvl_locks(int start_afflvl,
+			       int end_afflvl,
+			       aff_map_node_t *mpidr_nodes[]);
+void psci_release_afflvl_locks(int start_afflvl,
+				int end_afflvl,
+				mpidr_aff_map_nodes_t mpidr_nodes);
+void psci_print_affinity_map(void);
+void psci_set_max_phys_off_afflvl(uint32_t afflvl);
+uint32_t psci_find_max_phys_off_afflvl(uint32_t start_afflvl,
+				       uint32_t end_afflvl,
+				       aff_map_node_t *mpidr_nodes[]);
+unsigned int psci_is_last_on_cpu(void);
+int psci_spd_migrate_info(uint64_t *mpidr);
+
+/* Private exported functions from psci_setup.c */
+int psci_get_aff_map_nodes(unsigned long mpidr,
+				int start_afflvl,
+				int end_afflvl,
+				aff_map_node_t *mpidr_nodes[]);
+aff_map_node_t *psci_get_aff_map_node(unsigned long, int);
+
+/* Private exported functions from psci_affinity_on.c */
+int psci_afflvl_on(unsigned long target_cpu,
+		   entry_point_info_t *ep,
+		   int start_afflvl,
+		   int end_afflvl);
+
+/* Private exported functions from psci_affinity_off.c */
+int psci_afflvl_off(int, int);
+
+/* Private exported functions from psci_affinity_suspend.c */
+void psci_afflvl_suspend(entry_point_info_t *ep,
+			int start_afflvl,
+			int end_afflvl);
+
+unsigned int psci_afflvl_suspend_finish(int, int);
+void psci_set_suspend_power_state(unsigned int power_state);
+
+/* Private exported functions from psci_helpers.S */
+void psci_do_pwrdown_cache_maintenance(uint32_t affinity_level);
+void psci_do_pwrup_cache_maintenance(void);
+
+/* Private exported functions from psci_system_off.c */
+void __dead2 psci_system_off(void);
+void __dead2 psci_system_reset(void);
+
+#endif /* __PSCI_PRIVATE_H__ */
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_setup.c b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_setup.c
new file mode 100644
index 0000000..fbd76d0
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_setup.c
@@ -0,0 +1,400 @@
+/*
+ * 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 <context.h>
+#include <context_mgmt.h>
+#include <platform.h>
+#include <stddef.h>
+#include "psci_private.h"
+
+/*******************************************************************************
+ * Per cpu non-secure contexts used to program the architectural state prior
+ * return to the normal world.
+ * TODO: Use the memory allocator to set aside memory for the contexts instead
+ * of relying on platform defined constants. Using PSCI_NUM_AFFS will be an
+ * overkill.
+ ******************************************************************************/
+static cpu_context_t psci_ns_context[PLATFORM_CORE_COUNT];
+
+/*******************************************************************************
+ * In a system, a certain number of affinity instances are present at an
+ * affinity level. The cumulative number of instances across all levels are
+ * stored in 'psci_aff_map'. The topology tree has been flattenned into this
+ * array. To retrieve nodes, information about the extents of each affinity
+ * level i.e. start index and end index needs to be present. 'psci_aff_limits'
+ * stores this information.
+ ******************************************************************************/
+aff_limits_node_t psci_aff_limits[MPIDR_MAX_AFFLVL + 1];
+
+/******************************************************************************
+ * Define the psci capability variable.
+ *****************************************************************************/
+uint32_t psci_caps;
+
+
+/*******************************************************************************
+ * Routines for retrieving the node corresponding to an affinity level instance
+ * in the mpidr. The first one uses binary search to find the node corresponding
+ * to the mpidr (key) at a particular affinity level. The second routine decides
+ * extents of the binary search at each affinity level.
+ ******************************************************************************/
+static int psci_aff_map_get_idx(unsigned long key,
+				int min_idx,
+				int max_idx)
+{
+	int mid;
+
+	/*
+	 * Terminating condition: If the max and min indices have crossed paths
+	 * during the binary search then the key has not been found.
+	 */
+	if (max_idx < min_idx)
+		return PSCI_E_INVALID_PARAMS;
+
+	/*
+	 * Make sure we are within array limits.
+	 */
+	assert(min_idx >= 0 && max_idx < PSCI_NUM_AFFS);
+
+	/*
+	 * Bisect the array around 'mid' and then recurse into the array chunk
+	 * where the key is likely to be found. The mpidrs in each node in the
+	 * 'psci_aff_map' for a given affinity level are stored in an ascending
+	 * order which makes the binary search possible.
+	 */
+	mid = min_idx + ((max_idx - min_idx) >> 1);	/* Divide by 2 */
+
+	if (psci_aff_map[mid].mpidr > key)
+		return psci_aff_map_get_idx(key, min_idx, mid - 1);
+	else if (psci_aff_map[mid].mpidr < key)
+		return psci_aff_map_get_idx(key, mid + 1, max_idx);
+	else
+		return mid;
+}
+
+aff_map_node_t *psci_get_aff_map_node(unsigned long mpidr, int aff_lvl)
+{
+	int rc;
+
+	if (aff_lvl > get_max_afflvl())
+		return NULL;
+
+	/* Right shift the mpidr to the required affinity level */
+	mpidr = mpidr_mask_lower_afflvls(mpidr, aff_lvl);
+
+	rc = psci_aff_map_get_idx(mpidr,
+				  psci_aff_limits[aff_lvl].min,
+				  psci_aff_limits[aff_lvl].max);
+	if (rc >= 0)
+		return &psci_aff_map[rc];
+	else
+		return NULL;
+}
+
+/*******************************************************************************
+ * This function populates an array with nodes corresponding to a given range of
+ * affinity levels in an mpidr. It returns successfully only when the affinity
+ * levels are correct, the mpidr is valid i.e. no affinity level is absent from
+ * the topology tree & the affinity instance at level 0 is not absent.
+ ******************************************************************************/
+int psci_get_aff_map_nodes(unsigned long mpidr,
+			   int start_afflvl,
+			   int end_afflvl,
+			   aff_map_node_t *mpidr_nodes[])
+{
+	int rc = PSCI_E_INVALID_PARAMS, level;
+	aff_map_node_t *node;
+
+	rc = psci_check_afflvl_range(start_afflvl, end_afflvl);
+	if (rc != PSCI_E_SUCCESS)
+		return rc;
+
+	for (level = start_afflvl; level <= end_afflvl; level++) {
+
+		/*
+		 * Grab the node for each affinity level. No affinity level
+		 * can be missing as that would mean that the topology tree
+		 * is corrupted.
+		 */
+		node = psci_get_aff_map_node(mpidr, level);
+		if (node == NULL) {
+			rc = PSCI_E_INVALID_PARAMS;
+			break;
+		}
+
+		/*
+		 * Skip absent affinity levels unless it's afffinity level 0.
+		 * An absent cpu means that the mpidr is invalid. Save the
+		 * pointer to the node for the present affinity level
+		 */
+		if (!(node->state & PSCI_AFF_PRESENT)) {
+			if (level == MPIDR_AFFLVL0) {
+				rc = PSCI_E_INVALID_PARAMS;
+				break;
+			}
+
+			mpidr_nodes[level] = NULL;
+		} else
+			mpidr_nodes[level] = node;
+	}
+
+	return rc;
+}
+
+/*******************************************************************************
+ * Function which initializes the 'aff_map_node' corresponding to an affinity
+ * level instance. Each node has a unique mpidr, level and bakery lock. The data
+ * field is opaque and holds affinity level specific data e.g. for affinity
+ * level 0 it contains the index into arrays that hold the secure/non-secure
+ * state for a cpu that's been turned on/off
+ ******************************************************************************/
+static void psci_init_aff_map_node(unsigned long mpidr,
+				   int level,
+				   unsigned int idx)
+{
+	unsigned char state;
+	uint32_t linear_id;
+	psci_aff_map[idx].mpidr = mpidr;
+	psci_aff_map[idx].level = level;
+	psci_lock_init(psci_aff_map, idx);
+
+	/*
+	 * If an affinity instance is present then mark it as OFF to begin with.
+	 */
+	state = plat_get_aff_state(level, mpidr);
+	psci_aff_map[idx].state = state;
+
+	if (level == MPIDR_AFFLVL0) {
+
+		/*
+		 * Mark the cpu as OFF. Higher affinity level reference counts
+		 * have already been memset to 0
+		 */
+		if (state & PSCI_AFF_PRESENT)
+			psci_set_state(&psci_aff_map[idx], PSCI_STATE_OFF);
+
+		/*
+		 * Associate a non-secure context with this affinity
+		 * instance through the context management library.
+		 */
+		linear_id = platform_get_core_pos(mpidr);
+		assert(linear_id < PLATFORM_CORE_COUNT);
+
+		/* Invalidate the suspend context for the node */
+		set_cpu_data_by_index(linear_id,
+				      psci_svc_cpu_data.power_state,
+				      PSCI_INVALID_DATA);
+
+		/*
+		 * There is no state associated with the current execution
+		 * context so ensure that any reads of the highest affinity
+		 * level in a powered down state return PSCI_INVALID_DATA.
+		 */
+		set_cpu_data_by_index(linear_id,
+				      psci_svc_cpu_data.max_phys_off_afflvl,
+				      PSCI_INVALID_DATA);
+
+		flush_cpu_data_by_index(linear_id, psci_svc_cpu_data);
+
+		cm_set_context_by_mpidr(mpidr,
+					(void *) &psci_ns_context[linear_id],
+					NON_SECURE);
+	}
+
+	return;
+}
+
+/*******************************************************************************
+ * Core routine used by the Breadth-First-Search algorithm to populate the
+ * affinity tree. Each level in the tree corresponds to an affinity level. This
+ * routine's aim is to traverse to the target affinity level and populate nodes
+ * in the 'psci_aff_map' for all the siblings at that level. It uses the current
+ * affinity level to keep track of how many levels from the root of the tree
+ * have been traversed. If the current affinity level != target affinity level,
+ * then the platform is asked to return the number of children that each
+ * affinity instance has at the current affinity level. Traversal is then done
+ * for each child at the next lower level i.e. current affinity level - 1.
+ *
+ * CAUTION: This routine assumes that affinity instance ids are allocated in a
+ * monotonically increasing manner at each affinity level in a mpidr starting
+ * from 0. If the platform breaks this assumption then this code will have to
+ * be reworked accordingly.
+ ******************************************************************************/
+static unsigned int psci_init_aff_map(unsigned long mpidr,
+				      unsigned int affmap_idx,
+				      int cur_afflvl,
+				      int tgt_afflvl)
+{
+	unsigned int ctr, aff_count;
+
+	assert(cur_afflvl >= tgt_afflvl);
+
+	/*
+	 * Find the number of siblings at the current affinity level &
+	 * assert if there are none 'cause then we have been invoked with
+	 * an invalid mpidr.
+	 */
+	aff_count = plat_get_aff_count(cur_afflvl, mpidr);
+	assert(aff_count);
+
+	if (tgt_afflvl < cur_afflvl) {
+		for (ctr = 0; ctr < aff_count; ctr++) {
+			mpidr = mpidr_set_aff_inst(mpidr, ctr, cur_afflvl);
+			affmap_idx = psci_init_aff_map(mpidr,
+						       affmap_idx,
+						       cur_afflvl - 1,
+						       tgt_afflvl);
+		}
+	} else {
+		for (ctr = 0; ctr < aff_count; ctr++, affmap_idx++) {
+			mpidr = mpidr_set_aff_inst(mpidr, ctr, cur_afflvl);
+			psci_init_aff_map_node(mpidr, cur_afflvl, affmap_idx);
+		}
+
+		/* affmap_idx is 1 greater than the max index of cur_afflvl */
+		psci_aff_limits[cur_afflvl].max = affmap_idx - 1;
+	}
+
+	return affmap_idx;
+}
+
+/*******************************************************************************
+ * This function initializes the topology tree by querying the platform. To do
+ * so, it's helper routines implement a Breadth-First-Search. At each affinity
+ * level the platform conveys the number of affinity instances that exist i.e.
+ * the affinity count. The algorithm populates the psci_aff_map recursively
+ * using this information. On a platform that implements two clusters of 4 cpus
+ * each, the populated aff_map_array would look like this:
+ *
+ *            <- cpus cluster0 -><- cpus cluster1 ->
+ * ---------------------------------------------------
+ * | 0  | 1  | 0  | 1  | 2  | 3  | 0  | 1  | 2  | 3  |
+ * ---------------------------------------------------
+ *           ^                                       ^
+ * cluster __|                                 cpu __|
+ * limit                                      limit
+ *
+ * The first 2 entries are of the cluster nodes. The next 4 entries are of cpus
+ * within cluster 0. The last 4 entries are of cpus within cluster 1.
+ * The 'psci_aff_limits' array contains the max & min index of each affinity
+ * level within the 'psci_aff_map' array. This allows restricting search of a
+ * node at an affinity level between the indices in the limits array.
+ ******************************************************************************/
+int32_t psci_setup(void)
+{
+	unsigned long mpidr = read_mpidr();
+	int afflvl, affmap_idx, max_afflvl;
+	aff_map_node_t *node;
+
+	psci_plat_pm_ops = NULL;
+
+	/* Find out the maximum affinity level that the platform implements */
+	max_afflvl = get_max_afflvl();
+	assert(max_afflvl <= MPIDR_MAX_AFFLVL);
+
+	/*
+	 * This call traverses the topology tree with help from the platform and
+	 * populates the affinity map using a breadth-first-search recursively.
+	 * We assume that the platform allocates affinity instance ids from 0
+	 * onwards at each affinity level in the mpidr. FIRST_MPIDR = 0.0.0.0
+	 */
+	affmap_idx = 0;
+	for (afflvl = max_afflvl; afflvl >= MPIDR_AFFLVL0; afflvl--) {
+		affmap_idx = psci_init_aff_map(FIRST_MPIDR,
+					       affmap_idx,
+					       max_afflvl,
+					       afflvl);
+	}
+
+#if !USE_COHERENT_MEM
+	/*
+	 * The psci_aff_map only needs flushing when it's not allocated in
+	 * coherent memory.
+	 */
+	flush_dcache_range((uint64_t) &psci_aff_map, sizeof(psci_aff_map));
+#endif
+
+	/*
+	 * Set the bounds for the affinity counts of each level in the map. Also
+	 * flush out the entire array so that it's visible to subsequent power
+	 * management operations. The 'psci_aff_limits' array is allocated in
+	 * normal memory. It will be accessed when the mmu is off e.g. after
+	 * reset. Hence it needs to be flushed.
+	 */
+	for (afflvl = MPIDR_AFFLVL0; afflvl < max_afflvl; afflvl++) {
+		psci_aff_limits[afflvl].min =
+			psci_aff_limits[afflvl + 1].max + 1;
+	}
+
+	flush_dcache_range((unsigned long) psci_aff_limits,
+			   sizeof(psci_aff_limits));
+
+	/*
+	 * Mark the affinity instances in our mpidr as ON. No need to lock as
+	 * this is the primary cpu.
+	 */
+	mpidr &= MPIDR_AFFINITY_MASK;
+	for (afflvl = MPIDR_AFFLVL0; afflvl <= max_afflvl; afflvl++) {
+
+		node = psci_get_aff_map_node(mpidr, afflvl);
+		assert(node);
+
+		/* Mark each present node as ON. */
+		if (node->state & PSCI_AFF_PRESENT)
+			psci_set_state(node, PSCI_STATE_ON);
+	}
+
+	platform_setup_pm(&psci_plat_pm_ops);
+	assert(psci_plat_pm_ops);
+
+	/* Initialize the psci capability */
+	psci_caps = PSCI_GENERIC_CAP;
+
+	if (psci_plat_pm_ops->affinst_off)
+		psci_caps |=  define_psci_cap(PSCI_CPU_OFF);
+	if (psci_plat_pm_ops->affinst_on && psci_plat_pm_ops->affinst_on_finish)
+		psci_caps |=  define_psci_cap(PSCI_CPU_ON_AARCH64);
+	if (psci_plat_pm_ops->affinst_suspend &&
+			psci_plat_pm_ops->affinst_suspend_finish) {
+		psci_caps |=  define_psci_cap(PSCI_CPU_SUSPEND_AARCH64);
+		if (psci_plat_pm_ops->get_sys_suspend_power_state)
+			psci_caps |=  define_psci_cap(PSCI_SYSTEM_SUSPEND_AARCH64);
+	}
+	if (psci_plat_pm_ops->system_off)
+		psci_caps |=  define_psci_cap(PSCI_SYSTEM_OFF);
+	if (psci_plat_pm_ops->system_reset)
+		psci_caps |=  define_psci_cap(PSCI_SYSTEM_RESET);
+
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/services/std_svc/psci/psci_system_off.c b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_system_off.c
new file mode 100644
index 0000000..970d4bb
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/psci/psci_system_off.c
@@ -0,0 +1,70 @@
+/*
+ * 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 <stddef.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <platform.h>
+#include "psci_private.h"
+
+void psci_system_off(void)
+{
+	psci_print_affinity_map();
+
+	assert(psci_plat_pm_ops->system_off);
+
+	/* Notify the Secure Payload Dispatcher */
+	if (psci_spd_pm && psci_spd_pm->svc_system_off) {
+		psci_spd_pm->svc_system_off();
+	}
+
+	/* Call the platform specific hook */
+	psci_plat_pm_ops->system_off();
+
+	/* This function does not return. We should never get here */
+}
+
+void psci_system_reset(void)
+{
+	psci_print_affinity_map();
+
+	assert(psci_plat_pm_ops->system_reset);
+
+	/* Notify the Secure Payload Dispatcher */
+	if (psci_spd_pm && psci_spd_pm->svc_system_reset) {
+		psci_spd_pm->svc_system_reset();
+	}
+
+	/* Call the platform specific hook */
+	psci_plat_pm_ops->system_reset();
+
+	/* This function does not return. We should never get here */
+}
diff --git a/uefi/arm-trusted-firmware/services/std_svc/std_svc_setup.c b/uefi/arm-trusted-firmware/services/std_svc/std_svc_setup.c
new file mode 100644
index 0000000..6cb0319
--- /dev/null
+++ b/uefi/arm-trusted-firmware/services/std_svc/std_svc_setup.c
@@ -0,0 +1,106 @@
+/*
+ * 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 <psci.h>
+#include <runtime_svc.h>
+#include <std_svc.h>
+#include <stdint.h>
+#include <uuid.h>
+
+/* Standard Service UUID */
+DEFINE_SVC_UUID(arm_svc_uid,
+		0x108d905b, 0xf863, 0x47e8, 0xae, 0x2d,
+		0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2);
+
+/* Setup Standard Services */
+static int32_t std_svc_setup(void)
+{
+	/*
+	 * PSCI is the only specification implemented as a Standard Service.
+	 * Invoke PSCI setup from here
+	 */
+	return psci_setup();
+}
+
+/*
+ * Top-level Standard Service SMC handler. This handler will in turn dispatch
+ * calls to PSCI SMC handler
+ */
+uint64_t std_svc_smc_handler(uint32_t smc_fid,
+			     uint64_t x1,
+			     uint64_t x2,
+			     uint64_t x3,
+			     uint64_t x4,
+			     void *cookie,
+			     void *handle,
+			     uint64_t flags)
+{
+	/*
+	 * Dispatch PSCI calls to PSCI SMC handler and return its return
+	 * value
+	 */
+	if (is_psci_fid(smc_fid)) {
+		return psci_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+				handle, flags);
+	}
+
+	switch (smc_fid) {
+	case ARM_STD_SVC_CALL_COUNT:
+		/*
+		 * Return the number of Standard Service Calls. PSCI is the only
+		 * standard service implemented; so return number of PSCI calls
+		 */
+		SMC_RET1(handle, PSCI_NUM_CALLS);
+
+	case ARM_STD_SVC_UID:
+		/* Return UID to the caller */
+		SMC_UUID_RET(handle, arm_svc_uid);
+
+	case ARM_STD_SVC_VERSION:
+		/* Return the version of current implementation */
+		SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR);
+
+	default:
+		WARN("Unimplemented Standard Service Call: 0x%x \n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+/* 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
+);
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/Makefile b/uefi/arm-trusted-firmware/tools/cert_create/Makefile
new file mode 100644
index 0000000..f1aa797
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/Makefile
@@ -0,0 +1,92 @@
+#
+# 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.
+#
+
+PROJECT		:= cert_create
+PLAT		:= none
+V		:= 0
+DEBUG		:= 0
+BINARY		:= ${PROJECT}
+
+OBJECTS := src/cert.o \
+           src/ext.o \
+           src/key.o \
+           src/main.o \
+           src/tbb_cert.o \
+           src/tbb_ext.o \
+           src/tbb_key.o \
+           src/sha.o
+
+CFLAGS := -Wall -std=c99
+
+# Check the platform
+ifeq (${PLAT},none)
+  $(error Error: No platform defined. Use PLAT=<platform>.)
+endif
+
+ifeq (${DEBUG},1)
+  CFLAGS += -g -O0 -DDEBUG -DLOG_LEVEL=40
+else
+  CFLAGS += -O2 -DLOG_LEVEL=20
+endif
+ifeq (${V},0)
+	Q := @
+else
+	Q :=
+endif
+
+# Make soft links and include from local directory otherwise wrong headers
+# could get pulled in from firmware tree.
+INC_DIR := -I ./include -I ../../plat/${PLAT}/include
+LIB_DIR :=
+LIB := -lssl -lcrypto
+
+CC := gcc
+RM := rm -rf
+
+.PHONY: all clean
+
+all: clean ${BINARY}
+
+${BINARY}: ${OBJECTS} Makefile
+	@echo "  LD      $@"
+	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
+                const char platform_msg[] = "${PLAT}";' | \
+                ${CC} -c ${CFLAGS} -xc - -o src/build_msg.o
+	${Q}${CC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+
+%.o: %.c
+	@echo "  CC      $<"
+	${Q}${CC} -c ${CFLAGS} ${INC_DIR} $< -o $@
+
+clean:
+	${Q}${RM} -f src/build_msg.o ${OBJECTS}
+
+realclean: clean
+	${Q}${RM} -f ${BINARY}
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/include/cert.h b/uefi/arm-trusted-firmware/tools/cert_create/include/cert.h
new file mode 100644
index 0000000..48a4146
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/include/cert.h
@@ -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.
+ */
+
+#ifndef CERT_H_
+#define CERT_H_
+
+#include <openssl/ossl_typ.h>
+#include <openssl/x509.h>
+#include "key.h"
+
+/*
+ * This structure contains information related to the generation of the
+ * certificates. All these fields must be known and specified at build time
+ * except for the file name, which is picked up from the command line at
+ * run time.
+ *
+ * One instance of this structure must be created for each of the certificates
+ * present in the chain of trust.
+ *
+ * If the issuer points to this same instance, the generated certificate will
+ * be self-signed.
+ */
+typedef struct cert_s cert_t;
+struct cert_s {
+	int id;			/* Unique identifier */
+
+	const char *fn;		/* Filename to save the certificate */
+	const char *bin;	/* Image associated to this certificate */
+
+	const char *cn;		/* Subject CN (Company Name) */
+
+	X509 *x;		/* X509 certificate container */
+	key_t *key;		/* Key to be signed */
+
+	cert_t *issuer;		/* Issuer certificate */
+};
+
+int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value);
+
+int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk);
+
+#endif /* CERT_H_ */
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/include/debug.h b/uefi/arm-trusted-firmware/tools/cert_create/include/debug.h
new file mode 100644
index 0000000..dd0510a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/include/debug.h
@@ -0,0 +1,83 @@
+/*
+ * 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 __DEBUG_H__
+#define __DEBUG_H__
+
+#include <stdio.h>
+
+/* The log output macros print output to the console. These macros produce
+ * compiled log output only if the LOG_LEVEL defined in the makefile (or the
+ * make command line) is greater or equal than the level required for that
+ * type of log output.
+ * The format expected is the same as for printf(). For example:
+ * INFO("Info %s.\n", "message")    -> INFO:    Info message.
+ * WARN("Warning %s.\n", "message") -> WARNING: Warning message.
+ */
+
+#define LOG_LEVEL_NONE			0
+#define LOG_LEVEL_ERROR			10
+#define LOG_LEVEL_NOTICE		20
+#define LOG_LEVEL_WARNING		30
+#define LOG_LEVEL_INFO			40
+#define LOG_LEVEL_VERBOSE		50
+
+
+#if LOG_LEVEL >= LOG_LEVEL_NOTICE
+# define NOTICE(...)	printf("NOTICE:  " __VA_ARGS__)
+#else
+# define NOTICE(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_ERROR
+# define ERROR(...)	printf("ERROR:   " __VA_ARGS__)
+#else
+# define ERROR(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_WARNING
+# define WARN(...)	printf("WARNING: " __VA_ARGS__)
+#else
+# define WARN(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+# define INFO(...)	printf("INFO:    " __VA_ARGS__)
+#else
+# define INFO(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+# define VERBOSE(...)	printf("VERBOSE: " __VA_ARGS__)
+#else
+# define VERBOSE(...)
+#endif
+
+#endif /* __DEBUG_H__ */
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/include/ext.h b/uefi/arm-trusted-firmware/tools/cert_create/include/ext.h
new file mode 100644
index 0000000..d73f573
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/include/ext.h
@@ -0,0 +1,70 @@
+/*
+ * 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 EXT_H_
+#define EXT_H_
+
+#include <openssl/x509v3.h>
+
+/*
+ * This structure contains the relevant information to create the extensions
+ * to be included in the certificates. This extensions will be used to
+ * establish the chain of trust.
+ */
+typedef struct ext_s {
+	const char *oid;	/* OID of the extension */
+	const char *sn;		/* Short name */
+	const char *ln;		/* Long description */
+	int type;		/* OpenSSL ASN1 type of the extension data.
+				 * Supported types are:
+				 *   - V_ASN1_INTEGER
+				 *   - V_ASN1_OCTET_STRING
+				 */
+	int alias;		/* In case OpenSSL provides an standard
+				 * extension of the same type, add the new
+				 * extension as an alias of this one
+				 */
+
+	X509V3_EXT_METHOD method; /* This field may be used to define a custom
+				   * function to print the contents of the
+				   * extension */
+} ext_t;
+
+enum {
+	EXT_NON_CRIT = 0,
+	EXT_CRIT = !EXT_NON_CRIT,
+};
+
+int ext_init(ext_t *tbb_ext);
+X509_EXTENSION *ext_new_hash(int nid, int crit, unsigned char *buf, size_t len);
+X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value);
+X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k);
+
+#endif /* EXT_H_ */
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/include/key.h b/uefi/arm-trusted-firmware/tools/cert_create/include/key.h
new file mode 100644
index 0000000..8819750
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/include/key.h
@@ -0,0 +1,57 @@
+/*
+ * 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 KEY_H_
+#define KEY_H_
+
+#include <openssl/ossl_typ.h>
+
+#define RSA_KEY_BITS		2048
+
+/*
+ * This structure contains the relevant information to create the keys
+ * required to sign the certificates.
+ *
+ * One instance of this structure must be created for each key, usually in an
+ * array fashion. The filename is obtained at run time from the command line
+ * parameters
+ */
+typedef struct key_s {
+	int id;			/* Key id */
+	const char *desc;	/* Key description (debug purposes) */
+	char *fn;		/* Filename to load/store the key */
+	EVP_PKEY *key;		/* Key container */
+} key_t;
+
+int key_new(key_t *key);
+int key_load(key_t *key);
+int key_store(key_t *key);
+
+#endif /* KEY_H_ */
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/include/sha.h b/uefi/arm-trusted-firmware/tools/cert_create/include/sha.h
new file mode 100644
index 0000000..466d668
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/include/sha.h
@@ -0,0 +1,36 @@
+/*
+ * 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 SHA_H_
+#define SHA_H_
+
+int sha_file(const char *filename, unsigned char *md);
+
+#endif /* SHA_H_ */
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/include/tbb_cert.h b/uefi/arm-trusted-firmware/tools/cert_create/include/tbb_cert.h
new file mode 100644
index 0000000..4e48125
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/include/tbb_cert.h
@@ -0,0 +1,58 @@
+/*
+ * 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 TBB_CERT_H_
+#define TBB_CERT_H_
+
+#include "cert.h"
+
+/*
+ * Enumerate the certificates that are used to establish the chain of trust
+ */
+enum {
+	BL2_CERT,
+	TRUSTED_KEY_CERT,
+	BL30_KEY_CERT,
+	BL30_CERT,
+	BL31_KEY_CERT,
+	BL31_CERT,
+	BL32_KEY_CERT,
+	BL32_CERT,
+	BL33_KEY_CERT,
+	BL33_CERT,
+	NUM_CERTIFICATES,
+};
+
+/*
+ * Array containing the certificate instances
+ */
+extern cert_t certs[NUM_CERTIFICATES];
+
+#endif /* TBB_CERT_H_ */
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/include/tbb_ext.h b/uefi/arm-trusted-firmware/tools/cert_create/include/tbb_ext.h
new file mode 100644
index 0000000..155d3cb
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/include/tbb_ext.h
@@ -0,0 +1,38 @@
+/*
+ * 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 TBB_EXT_H_
+#define TBB_EXT_H_
+
+#include "ext.h"
+
+/* Array containing the extensions used in the chain of trust */
+extern ext_t tbb_ext[];
+
+#endif /* TBB_EXT_H_ */
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/include/tbb_key.h b/uefi/arm-trusted-firmware/tools/cert_create/include/tbb_key.h
new file mode 100644
index 0000000..cc927d1
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/include/tbb_key.h
@@ -0,0 +1,55 @@
+/*
+ * 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 TBB_KEY_H_
+#define TBB_KEY_H_
+
+#include "key.h"
+
+/*
+ * Enumerate the keys that are used to establish the chain of trust
+ */
+enum {
+	ROT_KEY,
+	TRUSTED_WORLD_KEY,
+	NON_TRUSTED_WORLD_KEY,
+	BL30_KEY,
+	BL31_KEY,
+	BL32_KEY,
+	BL33_KEY,
+	NUM_KEYS
+};
+
+/*
+ * Array containing the key instances
+ */
+extern key_t keys[];
+
+#endif /* TBB_KEY_H_ */
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/src/cert.c b/uefi/arm-trusted-firmware/tools/cert_create/src/cert.c
new file mode 100644
index 0000000..9705643
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/src/cert.c
@@ -0,0 +1,180 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/sha.h>
+#include <openssl/x509v3.h>
+
+#include "cert.h"
+#include "debug.h"
+#include "key.h"
+#include "platform_oid.h"
+#include "sha.h"
+
+#define SERIAL_RAND_BITS	64
+
+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
+{
+	BIGNUM *btmp;
+	int ret = 0;
+	if (b)
+		btmp = b;
+	else
+		btmp = BN_new();
+
+	if (!btmp)
+		return 0;
+
+	if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
+		goto error;
+	if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
+		goto error;
+
+	ret = 1;
+
+error:
+
+	if (!b)
+		BN_free(btmp);
+
+	return ret;
+}
+
+int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value)
+{
+	X509_EXTENSION *ex;
+	X509V3_CTX ctx;
+
+	/* No configuration database */
+	X509V3_set_ctx_nodb(&ctx);
+
+	/* Set issuer and subject certificates in the context */
+	X509V3_set_ctx(&ctx, issuer, subject, NULL, NULL, 0);
+	ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
+	if (!ex) {
+		ERR_print_errors_fp(stdout);
+		return 0;
+	}
+
+	X509_add_ext(subject, ex, -1);
+	X509_EXTENSION_free(ex);
+
+	return 1;
+}
+
+
+int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk)
+{
+	EVP_PKEY *pkey = cert->key->key;
+	EVP_PKEY *ikey = cert->issuer->key->key;
+	X509 *issuer = cert->issuer->x;
+	X509 *x = NULL;
+	X509_EXTENSION *ex = NULL;
+	X509_NAME *name = NULL;
+	ASN1_INTEGER *sno = NULL;
+	int i, num;
+
+	/* Create the certificate structure */
+	x = X509_new();
+	if (!x) {
+		return 0;
+	}
+
+	/* If we do not have a key, use the issuer key (the certificate will
+	 * become self signed). This happens in content certificates. */
+	if (!pkey) {
+		pkey = ikey;
+	}
+
+	/* If we do not have an issuer certificate, use our own (the certificate
+	 * will become self signed) */
+	if (!issuer) {
+		issuer = x;
+	}
+
+	/* x509.v3 */
+	X509_set_version(x, 2);
+
+	/* Random serial number */
+	sno = ASN1_INTEGER_new();
+	rand_serial(NULL, sno);
+	X509_set_serialNumber(x, sno);
+	ASN1_INTEGER_free(sno);
+
+	X509_gmtime_adj(X509_get_notBefore(x), 0);
+	X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*days);
+	X509_set_pubkey(x, pkey);
+
+	/* Subject name */
+	name = X509_get_subject_name(x);
+	X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
+			(const unsigned char *)cert->cn, -1, -1, 0);
+	X509_set_subject_name(x, name);
+
+	/* Issuer name */
+	name = X509_get_issuer_name(x);
+	X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
+			(const unsigned char *)cert->issuer->cn, -1, -1, 0);
+	X509_set_issuer_name(x, name);
+
+	/* Add various extensions: standard extensions */
+	cert_add_ext(issuer, x, NID_subject_key_identifier, "hash");
+	cert_add_ext(issuer, x, NID_authority_key_identifier, "keyid:always");
+	if (ca) {
+		cert_add_ext(issuer, x, NID_basic_constraints, "CA:TRUE");
+		cert_add_ext(issuer, x, NID_key_usage, "keyCertSign");
+	} else {
+		cert_add_ext(issuer, x, NID_basic_constraints, "CA:FALSE");
+	}
+
+	/* Add custom extensions */
+	if (sk != NULL) {
+		num = sk_X509_EXTENSION_num(sk);
+		for (i = 0; i < num; i++) {
+			ex = sk_X509_EXTENSION_value(sk, i);
+			X509_add_ext(x, ex, -1);
+		}
+	}
+
+	/* Sign the certificate with the issuer key */
+	if (!X509_sign(x, ikey, EVP_sha1())) {
+		ERR_print_errors_fp(stdout);
+		return 0;
+	}
+
+	cert->x = x;
+	return 1;
+}
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/src/ext.c b/uefi/arm-trusted-firmware/tools/cert_create/src/ext.c
new file mode 100644
index 0000000..31f84a8
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/src/ext.c
@@ -0,0 +1,233 @@
+/*
+ * 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 <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "ext.h"
+
+DECLARE_ASN1_ITEM(ASN1_INTEGER)
+DECLARE_ASN1_ITEM(ASN1_OCTET_STRING)
+
+/*
+ * This function adds the TBB extensions to the internal extension list
+ * maintained by OpenSSL so they can be used later.
+ *
+ * It also initializes the methods to print the contents of the extension. If an
+ * alias is specified in the TBB extension, we reuse the methods of the alias.
+ * Otherwise, only methods for V_ASN1_INTEGER and V_ASN1_OCTET_STRING are
+ * provided. Any other type will be printed as a raw ascii string.
+ *
+ * Return: 0 = success, Otherwise: error
+ */
+int ext_init(ext_t *tbb_ext)
+{
+	ext_t *ext;
+	X509V3_EXT_METHOD *m;
+	int i = 0, nid, ret;
+
+	while ((ext = &tbb_ext[i++]) && ext->oid) {
+		nid = OBJ_create(ext->oid, ext->sn, ext->ln);
+		if (ext->alias) {
+			X509V3_EXT_add_alias(nid, ext->alias);
+		} else {
+			m = &ext->method;
+			memset(m, 0x0, sizeof(X509V3_EXT_METHOD));
+			switch (ext->type) {
+			case V_ASN1_INTEGER:
+				m->it = ASN1_ITEM_ref(ASN1_INTEGER);
+				m->i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER;
+				m->s2i = (X509V3_EXT_S2I)s2i_ASN1_INTEGER;
+				break;
+			case V_ASN1_OCTET_STRING:
+				m->it = ASN1_ITEM_ref(ASN1_OCTET_STRING);
+				m->i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING;
+				m->s2i = (X509V3_EXT_S2I)s2i_ASN1_OCTET_STRING;
+				break;
+			default:
+				continue;
+			}
+			m->ext_nid = nid;
+			ret = X509V3_EXT_add(m);
+			if (!ret) {
+				ERR_print_errors_fp(stdout);
+				return 1;
+			}
+		}
+	}
+	return 0;
+}
+
+/*
+ * Create a new extension
+ *
+ * Extension  ::=  SEQUENCE  {
+ *      id          OBJECT IDENTIFIER,
+ *      critical    BOOLEAN DEFAULT FALSE,
+ *      value       OCTET STRING  }
+ *
+ * Parameters:
+ *   pex: OpenSSL extension pointer (output parameter)
+ *   nid: extension identifier
+ *   crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
+ *   data: extension data. This data will be encapsulated in an Octet String
+ *
+ * Return: Extension address, NULL if error
+ */
+static
+X509_EXTENSION *ext_new(int nid, int crit, unsigned char *data, int len)
+{
+	X509_EXTENSION *ex;
+	ASN1_OCTET_STRING *ext_data;
+
+	/* Octet string containing the extension data */
+	ext_data = ASN1_OCTET_STRING_new();
+	ASN1_OCTET_STRING_set(ext_data, data, len);
+
+	/* Create the extension */
+	ex = X509_EXTENSION_create_by_NID(NULL, nid, crit, ext_data);
+
+	/* The extension makes a copy of the data, so we can free this object */
+	ASN1_OCTET_STRING_free(ext_data);
+
+	return ex;
+}
+
+/*
+ * Creates a x509v3 extension containing a hash encapsulated in an ASN1 Octet
+ * String
+ *
+ * Parameters:
+ *   pex: OpenSSL extension pointer (output parameter)
+ *   nid: extension identifier
+ *   crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
+ *   buf: pointer to the buffer that contains the hash
+ *   len: size of the hash in bytes
+ *
+ * Return: Extension address, NULL if error
+ */
+X509_EXTENSION *ext_new_hash(int nid, int crit, unsigned char *buf, size_t len)
+{
+	X509_EXTENSION *ex = NULL;
+	ASN1_OCTET_STRING *hash = NULL;
+	unsigned char *p = NULL;
+	int sz = -1;
+
+	/* Encode Hash */
+	hash = ASN1_OCTET_STRING_new();
+	ASN1_OCTET_STRING_set(hash, buf, len);
+	sz = i2d_ASN1_OCTET_STRING(hash, NULL);
+	i2d_ASN1_OCTET_STRING(hash, &p);
+
+	/* Create the extension */
+	ex = ext_new(nid, crit, p, sz);
+
+	/* Clean up */
+	OPENSSL_free(p);
+	ASN1_OCTET_STRING_free(hash);
+
+	return ex;
+}
+
+/*
+ * Creates a x509v3 extension containing a nvcounter encapsulated in an ASN1
+ * Integer
+ *
+ * Parameters:
+ *   pex: OpenSSL extension pointer (output parameter)
+ *   nid: extension identifier
+ *   crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
+ *   value: nvcounter value
+ *
+ * Return: Extension address, NULL if error
+ */
+X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value)
+{
+	X509_EXTENSION *ex = NULL;
+	ASN1_INTEGER *counter = NULL;
+	unsigned char *p = NULL;
+	int sz = -1;
+
+	/* Encode counter */
+	counter = ASN1_INTEGER_new();
+	ASN1_INTEGER_set(counter, value);
+	sz = i2d_ASN1_INTEGER(counter, NULL);
+	i2d_ASN1_INTEGER(counter, &p);
+
+	/* Create the extension */
+	ex = ext_new(nid, crit, p, sz);
+
+	/* Free objects */
+	OPENSSL_free(p);
+	ASN1_INTEGER_free(counter);
+
+	return ex;
+}
+
+/*
+ * Creates a x509v3 extension containing a public key in DER format:
+ *
+ *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
+ *       algorithm            AlgorithmIdentifier,
+ *       subjectPublicKey     BIT STRING }
+ *
+ * Parameters:
+ *   pex: OpenSSL extension pointer (output parameter)
+ *   nid: extension identifier
+ *   crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
+ *   k: key
+ *
+ * Return: Extension address, NULL if error
+ */
+X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k)
+{
+	X509_EXTENSION *ex = NULL;
+	unsigned char *p = NULL;
+	int sz = -1;
+
+	/* Encode key */
+	BIO *mem = BIO_new(BIO_s_mem());
+	if (i2d_PUBKEY_bio(mem, k) <= 0) {
+		ERR_print_errors_fp(stderr);
+		return NULL;
+	}
+	p = (unsigned char *)OPENSSL_malloc(4096);
+	sz = BIO_read(mem, p, 4096);
+
+	/* Create the extension */
+	ex = ext_new(nid, crit, p, sz);
+
+	/* Clean up */
+	OPENSSL_free(p);
+
+	return ex;
+}
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/src/key.c b/uefi/arm-trusted-firmware/tools/cert_create/src/key.c
new file mode 100644
index 0000000..b5737d9
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/src/key.c
@@ -0,0 +1,131 @@
+/*
+ * 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 <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+
+#include "cert.h"
+#include "debug.h"
+#include "key.h"
+#include "platform_oid.h"
+#include "sha.h"
+
+#define MAX_FILENAME_LEN		1024
+
+/*
+ * Create a new key
+ */
+int key_new(key_t *key)
+{
+	RSA *rsa = NULL;
+	EVP_PKEY *k = NULL;
+
+	/* Create key pair container */
+	k = EVP_PKEY_new();
+	if (k == NULL) {
+		return 0;
+	}
+
+	/* Generate a new RSA key */
+	rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL);
+	if (EVP_PKEY_assign_RSA(k, rsa)) {
+		key->key = k;
+		return 1;
+	} else {
+		printf("Cannot assign RSA key\n");
+	}
+
+	if (k)
+		EVP_PKEY_free(k);
+	return 0;
+}
+
+int key_load(key_t *key)
+{
+	FILE *fp = NULL;
+	EVP_PKEY *k = NULL;
+
+	/* Create key pair container */
+	k = EVP_PKEY_new();
+	if (k == NULL) {
+		return 0;
+	}
+
+	if (key->fn) {
+		/* Load key from file */
+		fp = fopen(key->fn, "r");
+		if (fp) {
+			k = PEM_read_PrivateKey(fp, &k, NULL, NULL);
+			fclose(fp);
+			if (k) {
+				key->key = k;
+				return 1;
+			} else {
+				ERROR("Cannot read key from %s\n", key->fn);
+			}
+		} else {
+			ERROR("Cannot open file %s\n", key->fn);
+		}
+	} else {
+		ERROR("Key filename not specified\n");
+	}
+
+	if (k)
+		EVP_PKEY_free(k);
+
+	return 0;
+}
+
+int key_store(key_t *key)
+{
+	FILE *fp = NULL;
+
+	if (key->fn) {
+		fp = fopen(key->fn, "w");
+		if (fp) {
+			PEM_write_PrivateKey(fp, key->key,
+					NULL, NULL, 0, NULL, NULL);
+			fclose(fp);
+			return 1;
+		} else {
+			ERROR("Cannot create file %s\n", key->fn);
+		}
+	} else {
+		ERROR("Key filename not specified\n");
+	}
+
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/src/main.c b/uefi/arm-trusted-firmware/tools/cert_create/src/main.c
new file mode 100644
index 0000000..6df367a
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/src/main.c
@@ -0,0 +1,719 @@
+/*
+ * 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 <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/sha.h>
+#include <openssl/x509v3.h>
+
+#include "cert.h"
+#include "debug.h"
+#include "ext.h"
+#include "key.h"
+#include "platform_oid.h"
+#include "sha.h"
+#include "tbb_ext.h"
+#include "tbb_cert.h"
+#include "tbb_key.h"
+
+/*
+ * Helper macros to simplify the code. This macro assigns the return value of
+ * the 'fn' function to 'v' and exits if the value is NULL.
+ */
+#define CHECK_NULL(v, fn) \
+	do { \
+		v = fn; \
+		if (v == NULL) { \
+			ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \
+			exit(1); \
+		} \
+	} while (0)
+
+/*
+ * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the
+ * NID is undefined.
+ */
+#define CHECK_OID(v, oid) \
+	do { \
+		v = OBJ_txt2nid(oid); \
+		if (v == NID_undef) { \
+			ERROR("Cannot find TBB extension %s\n", oid); \
+			exit(1); \
+		} \
+	} while (0)
+
+#define MAX_FILENAME_LEN		1024
+#define VAL_DAYS			7300
+#define ID_TO_BIT_MASK(id)		(1 << id)
+#define NVCOUNTER_VALUE			0
+
+/* Files */
+enum {
+	/* Image file names (inputs) */
+	BL2_ID = 0,
+	BL30_ID,
+	BL31_ID,
+	BL32_ID,
+	BL33_ID,
+	/* Certificate file names (outputs) */
+	BL2_CERT_ID,
+	TRUSTED_KEY_CERT_ID,
+	BL30_KEY_CERT_ID,
+	BL30_CERT_ID,
+	BL31_KEY_CERT_ID,
+	BL31_CERT_ID,
+	BL32_KEY_CERT_ID,
+	BL32_CERT_ID,
+	BL33_KEY_CERT_ID,
+	BL33_CERT_ID,
+	/* Key file names (input/output) */
+	ROT_KEY_ID,
+	TRUSTED_WORLD_KEY_ID,
+	NON_TRUSTED_WORLD_KEY_ID,
+	BL30_KEY_ID,
+	BL31_KEY_ID,
+	BL32_KEY_ID,
+	BL33_KEY_ID,
+	NUM_OPTS
+};
+
+/* Global options */
+static int new_keys;
+static int save_keys;
+static int print_cert;
+static int bl30_present;
+static int bl32_present;
+
+/* We are not checking nvcounters in TF. Include them in the certificates but
+ * the value will be set to 0 */
+static int tf_nvcounter;
+static int non_tf_nvcounter;
+
+/* Info messages created in the Makefile */
+extern const char build_msg[];
+extern const char platform_msg[];
+
+
+static char *strdup(const char *str)
+{
+	int n = strlen(str) + 1;
+	char *dup = malloc(n);
+	if (dup) {
+		strcpy(dup, str);
+	}
+	return dup;
+}
+
+/* Command line options */
+static const struct option long_opt[] = {
+	/* Binary images */
+	{"bl2", required_argument, 0, BL2_ID},
+	{"bl30", required_argument, 0, BL30_ID},
+	{"bl31", required_argument, 0, BL31_ID},
+	{"bl32", required_argument, 0, BL32_ID},
+	{"bl33", required_argument, 0, BL33_ID},
+	/* Certificate files */
+	{"bl2-cert", required_argument, 0, BL2_CERT_ID},
+	{"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID},
+	{"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID},
+	{"bl30-cert", required_argument, 0, BL30_CERT_ID},
+	{"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID},
+	{"bl31-cert", required_argument, 0, BL31_CERT_ID},
+	{"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID},
+	{"bl32-cert", required_argument, 0, BL32_CERT_ID},
+	{"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID},
+	{"bl33-cert", required_argument, 0, BL33_CERT_ID},
+	/* Private key files */
+	{"rot-key", required_argument, 0, ROT_KEY_ID},
+	{"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID},
+	{"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID},
+	{"bl30-key", required_argument, 0, BL30_KEY_ID},
+	{"bl31-key", required_argument, 0, BL31_KEY_ID},
+	{"bl32-key", required_argument, 0, BL32_KEY_ID},
+	{"bl33-key", required_argument, 0, BL33_KEY_ID},
+	/* Common options */
+	{"help", no_argument, 0, 'h'},
+	{"save-keys", no_argument, 0, 'k'},
+	{"new-chain", no_argument, 0, 'n'},
+	{"print-cert", no_argument, 0, 'p'},
+	{0, 0, 0, 0}
+};
+
+static void print_help(const char *cmd)
+{
+	int i = 0;
+	printf("\n\n");
+	printf("The certificate generation tool loads the binary images and\n"
+	       "optionally the RSA keys, and outputs the key and content\n"
+	       "certificates properly signed to implement the chain of trust.\n"
+	       "If keys are provided, they must be in PEM format.\n"
+	       "Certificates are generated in DER format.\n");
+	printf("\n");
+	printf("Usage:\n\n");
+	printf("    %s [-hknp] \\\n", cmd);
+	for (i = 0; i < NUM_OPTS; i++) {
+		printf("        --%s <file>  \\\n", long_opt[i].name);
+	}
+	printf("\n");
+	printf("-h    Print help and exit\n");
+	printf("-k    Save key pairs into files. Filenames must be provided\n");
+	printf("-n    Generate new key pairs if no key files are provided\n");
+	printf("-p    Print the certificates in the standard output\n");
+	printf("\n");
+
+	exit(0);
+}
+
+static void check_cmd_params(void)
+{
+	/* BL2, BL31 and BL33 are mandatory */
+	if (certs[BL2_CERT].bin == NULL) {
+		ERROR("BL2 image not specified\n");
+		exit(1);
+	}
+
+	if (certs[BL31_CERT].bin == NULL) {
+		ERROR("BL31 image not specified\n");
+		exit(1);
+	}
+
+	if (certs[BL33_CERT].bin == NULL) {
+		ERROR("BL33 image not specified\n");
+		exit(1);
+	}
+
+	/* BL30 and BL32 are optional */
+	if (certs[BL30_CERT].bin != NULL) {
+		bl30_present = 1;
+	}
+
+	if (certs[BL32_CERT].bin != NULL) {
+		bl32_present = 1;
+	}
+
+	/* TODO: Certificate filenames */
+
+	/* Filenames to store keys must be specified */
+	if (save_keys || !new_keys) {
+		if (keys[ROT_KEY].fn == NULL) {
+			ERROR("ROT key not specified\n");
+			exit(1);
+		}
+
+		if (keys[TRUSTED_WORLD_KEY].fn == NULL) {
+			ERROR("Trusted World key not specified\n");
+			exit(1);
+		}
+
+		if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) {
+			ERROR("Non-trusted World key not specified\n");
+			exit(1);
+		}
+
+		if (keys[BL31_KEY].fn == NULL) {
+			ERROR("BL31 key not specified\n");
+			exit(1);
+		}
+
+		if (keys[BL33_KEY].fn == NULL) {
+			ERROR("BL33 key not specified\n");
+			exit(1);
+		}
+
+		if (bl30_present && (keys[BL30_KEY].fn == NULL)) {
+			ERROR("BL30 key not specified\n");
+			exit(1);
+		}
+
+		if (bl32_present && (keys[BL32_KEY].fn == NULL)) {
+			ERROR("BL32 key not specified\n");
+			exit(1);
+		}
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	STACK_OF(X509_EXTENSION) * sk = NULL;
+	X509_EXTENSION *hash_ext = NULL;
+	X509_EXTENSION *nvctr_ext = NULL;
+	X509_EXTENSION *trusted_key_ext = NULL;
+	X509_EXTENSION *non_trusted_key_ext = NULL;
+	FILE *file = NULL;
+	int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid;
+	int c, opt_idx = 0;
+	unsigned char md[SHA256_DIGEST_LENGTH];
+
+	NOTICE("CoT Generation Tool: %s\n", build_msg);
+	NOTICE("Target platform: %s\n", platform_msg);
+
+	while (1) {
+		/* getopt_long stores the option index here. */
+		c = getopt_long(argc, argv, "hknp", long_opt, &opt_idx);
+
+		/* Detect the end of the options. */
+		if (c == -1) {
+			break;
+		}
+
+		switch (c) {
+		case 'h':
+			print_help(argv[0]);
+			break;
+		case 'k':
+			save_keys = 1;
+			break;
+		case 'n':
+			new_keys = 1;
+			break;
+		case 'p':
+			print_cert = 1;
+			break;
+		case BL2_ID:
+			certs[BL2_CERT].bin = strdup(optarg);
+			break;
+		case BL30_ID:
+			certs[BL30_CERT].bin = strdup(optarg);
+			break;
+		case BL31_ID:
+			certs[BL31_CERT].bin = strdup(optarg);
+			break;
+		case BL32_ID:
+			certs[BL32_CERT].bin = strdup(optarg);
+			break;
+		case BL33_ID:
+			certs[BL33_CERT].bin = strdup(optarg);
+			break;
+		case BL2_CERT_ID:
+			certs[BL2_CERT].fn = strdup(optarg);
+			break;
+		case TRUSTED_KEY_CERT_ID:
+			certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
+			break;
+		case BL30_KEY_CERT_ID:
+			certs[BL30_KEY_CERT].fn = strdup(optarg);
+			break;
+		case BL30_CERT_ID:
+			certs[BL30_CERT].fn = strdup(optarg);
+			break;
+		case BL31_KEY_CERT_ID:
+			certs[BL31_KEY_CERT].fn = strdup(optarg);
+			break;
+		case BL31_CERT_ID:
+			certs[BL31_CERT].fn = strdup(optarg);
+			break;
+		case BL32_KEY_CERT_ID:
+			certs[BL32_KEY_CERT].fn = strdup(optarg);
+			break;
+		case BL32_CERT_ID:
+			certs[BL32_CERT].fn = strdup(optarg);
+			break;
+		case BL33_KEY_CERT_ID:
+			certs[BL33_KEY_CERT].fn = strdup(optarg);
+			break;
+		case BL33_CERT_ID:
+			certs[BL33_CERT].fn = strdup(optarg);
+			break;
+		case ROT_KEY_ID:
+			keys[ROT_KEY].fn = strdup(optarg);
+			break;
+		case TRUSTED_WORLD_KEY_ID:
+			keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
+			break;
+		case NON_TRUSTED_WORLD_KEY_ID:
+			keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
+			break;
+		case BL30_KEY_ID:
+			keys[BL30_KEY].fn = strdup(optarg);
+			break;
+		case BL31_KEY_ID:
+			keys[BL31_KEY].fn = strdup(optarg);
+			break;
+		case BL32_KEY_ID:
+			keys[BL32_KEY].fn = strdup(optarg);
+			break;
+		case BL33_KEY_ID:
+			keys[BL33_KEY].fn = strdup(optarg);
+			break;
+		case '?':
+		default:
+			printf("%s\n", optarg);
+			exit(1);
+		}
+	}
+
+	/* Set the value of the NVCounters */
+	tf_nvcounter = NVCOUNTER_VALUE;
+	non_tf_nvcounter = NVCOUNTER_VALUE;
+
+	/* Check command line arguments */
+	check_cmd_params();
+
+	/* Register the new types and OIDs for the extensions */
+	if (ext_init(tbb_ext) != 0) {
+		ERROR("Cannot initialize TBB extensions\n");
+		exit(1);
+	}
+
+	/* Get non-volatile counters NIDs */
+	CHECK_OID(tz_nvctr_nid, TZ_FW_NVCOUNTER_OID);
+	CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID);
+
+	/* Load private keys from files (or generate new ones) */
+	if (new_keys) {
+		for (i = 0 ; i < NUM_KEYS ; i++) {
+			if (!key_new(&keys[i])) {
+				ERROR("Error creating %s\n", keys[i].desc);
+				exit(1);
+			}
+		}
+	} else {
+		for (i = 0 ; i < NUM_KEYS ; i++) {
+			if (!key_load(&keys[i])) {
+				ERROR("Error loading %s\n", keys[i].desc);
+				exit(1);
+			}
+		}
+	}
+
+	/* *********************************************************************
+	 * BL2 certificate (Trusted Boot Firmware certificate):
+	 *     - Self-signed with OEM ROT private key
+	 *     - Extensions:
+	 *         - TrustedFirmwareNVCounter (TODO)
+	 *         - BL2 hash
+	 **********************************************************************/
+	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+
+	/* Add the NVCounter as a critical extension */
+	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+			tf_nvcounter));
+	sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+	/* Add hash of BL2 as an extension */
+	if (!sha_file(certs[BL2_CERT].bin, md)) {
+		ERROR("Cannot calculate the hash of %s\n", certs[BL2_CERT].bin);
+		exit(1);
+	}
+	CHECK_OID(hash_nid, BL2_HASH_OID);
+	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+			SHA256_DIGEST_LENGTH));
+	sk_X509_EXTENSION_push(sk, hash_ext);
+
+	/* Create certificate. Signed with ROT key */
+	if (!cert_new(&certs[BL2_CERT], VAL_DAYS, 0, sk)) {
+		ERROR("Cannot create %s\n", certs[BL2_CERT].cn);
+		exit(1);
+	}
+	sk_X509_EXTENSION_free(sk);
+
+	/* *********************************************************************
+	 * Trusted Key certificate:
+	 *     - Self-signed with OEM ROT private key
+	 *     - Extensions:
+	 *         - TrustedFirmwareNVCounter (TODO)
+	 *         - TrustedWorldPK
+	 *         - NonTrustedWorldPK
+	 **********************************************************************/
+	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+			tf_nvcounter));
+	sk_X509_EXTENSION_push(sk, nvctr_ext);
+	CHECK_OID(pk_nid, TZ_WORLD_PK_OID);
+	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+			keys[TRUSTED_WORLD_KEY].key));
+	sk_X509_EXTENSION_push(sk, trusted_key_ext);
+	CHECK_OID(pk_nid, NTZ_WORLD_PK_OID);
+	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+			keys[NON_TRUSTED_WORLD_KEY].key));
+	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
+	if (!cert_new(&certs[TRUSTED_KEY_CERT], VAL_DAYS, 0, sk)) {
+		ERROR("Cannot create %s\n", certs[TRUSTED_KEY_CERT].cn);
+		exit(1);
+	}
+	sk_X509_EXTENSION_free(sk);
+
+	/* *********************************************************************
+	 * BL30 Key certificate (Trusted SCP Firmware Key certificate):
+	 *     - Self-signed with Trusted World key
+	 *     - Extensions:
+	 *         - TrustedFirmwareNVCounter (TODO)
+	 *         - SCPFirmwareContentCertPK
+	 **********************************************************************/
+	if (bl30_present) {
+		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+				tf_nvcounter));
+		sk_X509_EXTENSION_push(sk, nvctr_ext);
+		CHECK_OID(pk_nid, BL30_CONTENT_CERT_PK_OID);
+		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+				keys[BL30_KEY].key));
+		sk_X509_EXTENSION_push(sk, trusted_key_ext);
+		if (!cert_new(&certs[BL30_KEY_CERT], VAL_DAYS, 0, sk)) {
+			ERROR("Cannot create %s\n", certs[BL30_KEY_CERT].cn);
+			exit(1);
+		}
+		sk_X509_EXTENSION_free(sk);
+	}
+
+	/* *********************************************************************
+	 * BL30 certificate (SCP Firmware Content certificate):
+	 *     - Signed with Trusted World Key
+	 *     - Extensions:
+	 *         - TrustedFirmwareNVCounter (TODO)
+	 *         - SCPFirmwareHash
+	 **********************************************************************/
+	if (bl30_present) {
+		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+				tf_nvcounter));
+		sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+		if (!sha_file(certs[BL30_CERT].bin, md)) {
+			ERROR("Cannot calculate the hash of %s\n",
+					certs[BL30_CERT].bin);
+			exit(1);
+		}
+		CHECK_OID(hash_nid, BL30_HASH_OID);
+		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+				SHA256_DIGEST_LENGTH));
+		sk_X509_EXTENSION_push(sk, hash_ext);
+
+		if (!cert_new(&certs[BL30_CERT], VAL_DAYS, 0, sk)) {
+			ERROR("Cannot create %s\n", certs[BL30_CERT].cn);
+			exit(1);
+		}
+
+		sk_X509_EXTENSION_free(sk);
+	}
+
+	/* *********************************************************************
+	 * BL31 Key certificate (Trusted SoC Firmware Key certificate):
+	 *     - Self-signed with Trusted World key
+	 *     - Extensions:
+	 *         - TrustedFirmwareNVCounter (TODO)
+	 *         - SoCFirmwareContentCertPK
+	 **********************************************************************/
+	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+			tf_nvcounter));
+	sk_X509_EXTENSION_push(sk, nvctr_ext);
+	CHECK_OID(pk_nid, BL31_CONTENT_CERT_PK_OID);
+	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+			keys[BL31_KEY].key));
+	sk_X509_EXTENSION_push(sk, trusted_key_ext);
+	if (!cert_new(&certs[BL31_KEY_CERT], VAL_DAYS, 0, sk)) {
+		ERROR("Cannot create %s\n", certs[BL31_KEY_CERT].cn);
+		exit(1);
+	}
+	sk_X509_EXTENSION_free(sk);
+
+	/* *********************************************************************
+	 * BL31 certificate (SOC Firmware Content certificate):
+	 *     - Signed with Trusted World Key
+	 *     - Extensions:
+	 *         - TrustedFirmwareNVCounter (TODO)
+	 *         - BL31 hash
+	 **********************************************************************/
+	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+			tf_nvcounter));
+	sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+	if (!sha_file(certs[BL31_CERT].bin, md)) {
+		ERROR("Cannot calculate the hash of %s\n", certs[BL31_CERT].bin);
+		exit(1);
+	}
+	CHECK_OID(hash_nid, BL31_HASH_OID);
+	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+			SHA256_DIGEST_LENGTH));
+	sk_X509_EXTENSION_push(sk, hash_ext);
+
+	if (!cert_new(&certs[BL31_CERT], VAL_DAYS, 0, sk)) {
+		ERROR("Cannot create %s\n", certs[BL31_CERT].cn);
+		exit(1);
+	}
+
+	sk_X509_EXTENSION_free(sk);
+
+	/* *********************************************************************
+	 * BL32 Key certificate (Trusted OS Firmware Key certificate):
+	 *     - Self-signed with Trusted World key
+	 *     - Extensions:
+	 *         - TrustedFirmwareNVCounter (TODO)
+	 *         - TrustedOSFirmwareContentCertPK
+	 **********************************************************************/
+	if (bl32_present) {
+		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+				tf_nvcounter));
+		sk_X509_EXTENSION_push(sk, nvctr_ext);
+		CHECK_OID(pk_nid, BL32_CONTENT_CERT_PK_OID);
+		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+				keys[BL32_KEY].key));
+		sk_X509_EXTENSION_push(sk, trusted_key_ext);
+		if (!cert_new(&certs[BL32_KEY_CERT], VAL_DAYS, 0, sk)) {
+			ERROR("Cannot create %s\n", certs[BL32_KEY_CERT].cn);
+			exit(1);
+		}
+		sk_X509_EXTENSION_free(sk);
+	}
+
+	/* *********************************************************************
+	 * BL32 certificate (TrustedOS Firmware Content certificate):
+	 *     - Signed with Trusted World Key
+	 *     - Extensions:
+	 *         - TrustedFirmwareNVCounter (TODO)
+	 *         - BL32 hash
+	 **********************************************************************/
+	if (bl32_present) {
+		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+				tf_nvcounter));
+		sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+		if (!sha_file(certs[BL32_CERT].bin, md)) {
+			ERROR("Cannot calculate the hash of %s\n",
+					certs[BL32_CERT].bin);
+			exit(1);
+		}
+		CHECK_OID(hash_nid, BL32_HASH_OID);
+		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+				SHA256_DIGEST_LENGTH));
+		sk_X509_EXTENSION_push(sk, hash_ext);
+
+		if (!cert_new(&certs[BL32_CERT], VAL_DAYS, 0, sk)) {
+			ERROR("Cannot create %s\n", certs[BL32_CERT].cn);
+			exit(1);
+		}
+
+		sk_X509_EXTENSION_free(sk);
+	}
+
+	/* *********************************************************************
+	 * BL33 Key certificate (Non Trusted Firmware Key certificate):
+	 *     - Self-signed with Non Trusted World key
+	 *     - Extensions:
+	 *         - NonTrustedFirmwareNVCounter (TODO)
+	 *         - NonTrustedFirmwareContentCertPK
+	 **********************************************************************/
+	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
+			non_tf_nvcounter));
+	sk_X509_EXTENSION_push(sk, nvctr_ext);
+	CHECK_OID(pk_nid, BL33_CONTENT_CERT_PK_OID);
+	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+			keys[BL33_KEY].key));
+	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
+	if (!cert_new(&certs[BL33_KEY_CERT], VAL_DAYS, 0, sk)) {
+		ERROR("Cannot create %s\n", certs[BL33_KEY_CERT].cn);
+		exit(1);
+	}
+	sk_X509_EXTENSION_free(sk);
+
+	/* *********************************************************************
+	 * BL33 certificate (Non-Trusted World Content certificate):
+	 *     - Signed with Non-Trusted World Key
+	 *     - Extensions:
+	 *         - NonTrustedFirmwareNVCounter (TODO)
+	 *         - BL33 hash
+	 **********************************************************************/
+	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
+			non_tf_nvcounter));
+	sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+	if (!sha_file(certs[BL33_CERT].bin, md)) {
+		ERROR("Cannot calculate the hash of %s\n", certs[BL33_CERT].bin);
+		exit(1);
+	}
+	CHECK_OID(hash_nid, BL33_HASH_OID);
+	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+			SHA256_DIGEST_LENGTH));
+	sk_X509_EXTENSION_push(sk, hash_ext);
+
+	if (!cert_new(&certs[BL33_CERT], VAL_DAYS, 0, sk)) {
+		ERROR("Cannot create %s\n", certs[BL33_CERT].cn);
+		exit(1);
+	}
+	sk_X509_EXTENSION_free(sk);
+
+	/* Print the certificates */
+	if (print_cert) {
+		for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
+			if (!certs[i].x) {
+				continue;
+			}
+			printf("\n\n=====================================\n\n");
+			X509_print_fp(stdout, certs[i].x);
+		}
+	}
+
+	/* Save created certificates to files */
+	for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
+		if (certs[i].x && certs[i].fn) {
+			file = fopen(certs[i].fn, "w");
+			if (file != NULL) {
+				i2d_X509_fp(file, certs[i].x);
+				fclose(file);
+			} else {
+				ERROR("Cannot create file %s\n", certs[i].fn);
+			}
+		}
+	}
+
+	/* Save keys */
+	if (save_keys) {
+		for (i = 0 ; i < NUM_KEYS ; i++) {
+			if (!key_store(&keys[i])) {
+				ERROR("Cannot save %s\n", keys[i].desc);
+			}
+		}
+	}
+
+	X509_EXTENSION_free(hash_ext);
+	X509_EXTENSION_free(nvctr_ext);
+	X509_EXTENSION_free(trusted_key_ext);
+	X509_EXTENSION_free(non_trusted_key_ext);
+
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE_cleanup();
+#endif
+	CRYPTO_cleanup_all_ex_data();
+
+	return 0;
+}
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/src/sha.c b/uefi/arm-trusted-firmware/tools/cert_create/src/sha.c
new file mode 100644
index 0000000..57026b5
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/src/sha.c
@@ -0,0 +1,64 @@
+/*
+ * 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 <stdio.h>
+#include <openssl/sha.h>
+
+#include "debug.h"
+
+#define BUFFER_SIZE	256
+
+int sha_file(const char *filename, unsigned char *md)
+{
+	FILE *inFile;
+	SHA256_CTX shaContext;
+	int bytes;
+	unsigned char data[BUFFER_SIZE];
+
+	if ((filename == NULL) || (md == NULL)) {
+		ERROR("%s(): NULL argument\n", __FUNCTION__);
+		return 0;
+	}
+
+	inFile = fopen(filename, "rb");
+	if (inFile == NULL) {
+		ERROR("Cannot read %s\n", filename);
+		return 0;
+	}
+
+	SHA256_Init(&shaContext);
+	while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+		SHA256_Update(&shaContext, data, bytes);
+	}
+	SHA256_Final(md, &shaContext);
+
+	fclose(inFile);
+	return 1;
+}
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/src/tbb_cert.c b/uefi/arm-trusted-firmware/tools/cert_create/src/tbb_cert.c
new file mode 100644
index 0000000..8dfda60
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/src/tbb_cert.c
@@ -0,0 +1,111 @@
+/*
+ * 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 "tbb_cert.h"
+#include "tbb_key.h"
+
+/*
+ * Certificates used in the chain of trust
+ *
+ * The order of the certificates must follow the enumeration specified in
+ * tbb_cert.h. All certificates are self-signed.
+ */
+cert_t certs[NUM_CERTIFICATES] = {
+	{
+		.id = BL2_CERT,
+		.fn = NULL,
+		.cn = "BL2 Certificate",
+		.key = &keys[ROT_KEY],
+		.issuer = &certs[BL2_CERT],
+	},
+	{
+		.id = TRUSTED_KEY_CERT,
+		.fn = NULL,
+		.cn = "Trusted Key Certificate",
+		.key = &keys[ROT_KEY],
+		.issuer = &certs[TRUSTED_KEY_CERT],
+	},
+	{
+		.id = BL30_KEY_CERT,
+		.fn = NULL,
+		.cn = "BL3-0 Key Certificate",
+		.key = &keys[TRUSTED_WORLD_KEY],
+		.issuer = &certs[BL30_KEY_CERT],
+	},
+	{
+		.id = BL30_CERT,
+		.fn = NULL,
+		.cn = "BL3-0 Content Certificate",
+		.key = &keys[BL30_KEY],
+		.issuer = &certs[BL30_CERT],
+	},
+	{
+		.id = BL31_KEY_CERT,
+		.fn = NULL,
+		.cn = "BL3-1 Key Certificate",
+		.key = &keys[TRUSTED_WORLD_KEY],
+		.issuer = &certs[BL31_KEY_CERT],
+	},
+	{
+		.id = BL31_CERT,
+		.fn = NULL,
+		.cn = "BL3-1 Content Certificate",
+		.key = &keys[BL31_KEY],
+		.issuer = &certs[BL31_CERT],
+	},
+	{
+		.id = BL32_KEY_CERT,
+		.fn = NULL,
+		.cn = "BL3-2 Key Certificate",
+		.key = &keys[TRUSTED_WORLD_KEY],
+		.issuer = &certs[BL32_KEY_CERT],
+	},
+	{
+		.id = BL32_CERT,
+		.fn = NULL,
+		.cn = "BL3-2 Content Certificate",
+		.key = &keys[BL32_KEY],
+		.issuer = &certs[BL32_CERT],
+	},
+	{
+		.id = BL33_KEY_CERT,
+		.fn = NULL,
+		.cn = "BL3-3 Key Certificate",
+		.key = &keys[NON_TRUSTED_WORLD_KEY],
+		.issuer = &certs[BL33_KEY_CERT],
+	},
+	{
+		.id = BL33_CERT,
+		.fn = NULL,
+		.cn = "BL3-3 Content Certificate",
+		.key = &keys[BL33_KEY],
+		.issuer = &certs[BL33_CERT],
+	}
+};
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/src/tbb_ext.c b/uefi/arm-trusted-firmware/tools/cert_create/src/tbb_ext.c
new file mode 100644
index 0000000..0022611
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/src/tbb_ext.c
@@ -0,0 +1,118 @@
+/*
+ * 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 <stdio.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "ext.h"
+#include "platform_oid.h"
+
+ext_t tbb_ext[] = {
+	{
+		.oid = TZ_FW_NVCOUNTER_OID,
+		.sn = "TrustedNvCounter",
+		.ln = "Non-volatile trusted counter",
+		.type = V_ASN1_INTEGER
+	},
+	{
+		.oid = NTZ_FW_NVCOUNTER_OID,
+		.sn = "NonTrustedNvCounter",
+		.ln = "Non-volatile non-trusted counter",
+		.type = V_ASN1_INTEGER
+	},
+	{
+		.oid = BL2_HASH_OID,
+		.sn = "TrustedBootFirmwareHash",
+		.ln = "Trusted Boot Firmware (BL2) hash (SHA256)",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = TZ_WORLD_PK_OID,
+		.sn = "TrustedWorldPublicKey",
+		.ln = "Trusted World Public Key",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = NTZ_WORLD_PK_OID,
+		.sn = "NonTrustedWorldPublicKey",
+		.ln = "Non-Trusted World Public Key",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = BL31_CONTENT_CERT_PK_OID,
+		.sn = "SoCFirmwareContentCertPK",
+		.ln = "SoC Firmware content certificate public key",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = BL31_HASH_OID,
+		.sn = "APROMPatchHash",
+		.ln = "AP ROM patch hash",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = BL30_CONTENT_CERT_PK_OID,
+		.sn = "SCPFirmwareContentCertPK",
+		.ln = "SCP Firmware content certificate public key",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = BL30_HASH_OID,
+		.sn = "SCPFirmwareHash",
+		.ln = "SCP Firmware (BL30) hash (SHA256)",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = BL32_CONTENT_CERT_PK_OID,
+		.sn = "TrustedOSFirmwareContentCertPK",
+		.ln = "Trusted OS Firmware content certificate public key",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = BL32_HASH_OID,
+		.sn = "TrustedOSHash",
+		.ln = "Trusted OS (BL32) hash (SHA256)",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = BL33_CONTENT_CERT_PK_OID,
+		.sn = "NonTrustedFirmwareContentCertPK",
+		.ln = "Non-Trusted Firmware content certificate public key",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{
+		.oid = BL33_HASH_OID,
+		.sn = "NonTrustedWorldBootloaderHash",
+		.ln = "Non-Trusted World (BL33) hash (SHA256)",
+		.type = V_ASN1_OCTET_STRING
+	},
+	{ 0, 0, 0, 0 }
+};
diff --git a/uefi/arm-trusted-firmware/tools/cert_create/src/tbb_key.c b/uefi/arm-trusted-firmware/tools/cert_create/src/tbb_key.c
new file mode 100644
index 0000000..140aeda
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/cert_create/src/tbb_key.c
@@ -0,0 +1,67 @@
+/*
+ * 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 "tbb_key.h"
+
+/*
+ * Keys used to establish the chain of trust
+ *
+ * The order of the keys must follow the enumeration specified in tbb_key.h
+ */
+key_t keys[NUM_KEYS] = {
+	{
+		.id = ROT_KEY,
+		.desc = "Root Of Trust key"
+	},
+	{
+		.id = TRUSTED_WORLD_KEY,
+		.desc = "Trusted World key"
+	},
+	{
+		.id = NON_TRUSTED_WORLD_KEY,
+		.desc = "Non Trusted World key"
+	},
+	{
+		.id = BL30_KEY,
+		.desc = "BL30 key"
+	},
+	{
+		.id = BL31_KEY,
+		.desc = "BL31 key"
+	},
+	{
+		.id = BL32_KEY,
+		.desc = "BL32 key"
+	},
+	{
+		.id = BL33_KEY,
+		.desc = "BL33 key"
+	}
+};
diff --git a/uefi/arm-trusted-firmware/tools/fip_create/Makefile b/uefi/arm-trusted-firmware/tools/fip_create/Makefile
new file mode 100644
index 0000000..c72bae5
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/fip_create/Makefile
@@ -0,0 +1,65 @@
+#
+# 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.
+#
+
+PROJECT = fip_create
+OBJECTS = fip_create.o
+
+CFLAGS = -Wall -Werror -pedantic -std=c99
+ifeq (${DEBUG},1)
+  CFLAGS += -g -O0 -DDEBUG
+else
+  CFLAGS += -O2
+endif
+
+# Make soft links and include from local directory otherwise wrong headers
+# could get pulled in from firmware tree.
+INCLUDE_PATHS = -I.
+
+CC := gcc
+RM := rm -rf
+
+.PHONY: all clean
+
+all: ${PROJECT}
+
+${PROJECT}: ${OBJECTS} Makefile
+	@echo "  LD      $@"
+	${Q}${CC} ${OBJECTS} -o $@
+	@echo
+	@echo "Built $@ successfully"
+	@echo
+
+%.o: %.c %.h Makefile
+	@echo "  CC      $<"
+	${Q}${CC} -c ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
+
+clean:
+	${Q}${RM} ${PROJECT}
+	${Q}${RM} ${OBJECTS}
diff --git a/uefi/arm-trusted-firmware/tools/fip_create/fip_create.c b/uefi/arm-trusted-firmware/tools/fip_create/fip_create.c
new file mode 100644
index 0000000..c6869f9
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/fip_create/fip_create.c
@@ -0,0 +1,695 @@
+/*
+ * 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 <errno.h>
+#include <getopt.h> /* getopt_long() is a GNU extention */
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "fip_create.h"
+#include "firmware_image_package.h"
+
+/* Values returned by getopt() as part of the command line parsing */
+#define OPT_TOC_ENTRY 0
+#define OPT_DUMP 1
+#define OPT_HELP 2
+
+file_info_t files[MAX_FILES];
+unsigned file_info_count = 0;
+uuid_t uuid_null = {0};
+
+/*
+ * TODO: Add ability to specify and flag different file types.
+ * Add flags to the toc_entry?
+ * const char* format_type_str[] = { "RAW", "ELF", "PIC" };
+ */
+
+/* The images used depends on the platform. */
+static entry_lookup_list_t toc_entry_lookup_list[] = {
+	{ "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+	  "bl2", NULL, FLAG_FILENAME },
+	{ "SCP Firmware BL3-0", UUID_SCP_FIRMWARE_BL30,
+	  "bl30", NULL, FLAG_FILENAME},
+	{ "EL3 Runtime Firmware BL3-1", UUID_EL3_RUNTIME_FIRMWARE_BL31,
+	  "bl31", NULL, FLAG_FILENAME},
+	{ "Secure Payload BL3-2 (Trusted OS)", UUID_SECURE_PAYLOAD_BL32,
+	  "bl32", NULL, FLAG_FILENAME},
+	{ "Non-Trusted Firmware BL3-3", UUID_NON_TRUSTED_FIRMWARE_BL33,
+	  "bl33", NULL, FLAG_FILENAME},
+	/* Key Certificates */
+	{ "Root Of Trust key certificate", UUID_ROT_KEY_CERT,
+	  "rot-cert", NULL, FLAG_FILENAME },
+	{ "Trusted key certificate", UUID_TRUSTED_KEY_CERT,
+	  "trusted-key-cert", NULL, FLAG_FILENAME},
+	{ "SCP Firmware BL3-0 key certificate", UUID_SCP_FIRMWARE_BL30_KEY_CERT,
+	  "bl30-key-cert", NULL, FLAG_FILENAME},
+	{ "EL3 Runtime Firmware BL3-1 key certificate", UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT,
+	  "bl31-key-cert", NULL, FLAG_FILENAME},
+	{ "Secure Payload BL3-2 (Trusted OS) key certificate", UUID_SECURE_PAYLOAD_BL32_KEY_CERT,
+	  "bl32-key-cert", NULL, FLAG_FILENAME},
+	{ "Non-Trusted Firmware BL3-3 key certificate", UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT,
+	  "bl33-key-cert", NULL, FLAG_FILENAME},
+	/* Content certificates */
+	{ "Trusted Boot Firmware BL2 certificate", UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT,
+	  "bl2-cert", NULL, FLAG_FILENAME },
+	{ "SCP Firmware BL3-0 certificate", UUID_SCP_FIRMWARE_BL30_CERT,
+	  "bl30-cert", NULL, FLAG_FILENAME},
+	{ "EL3 Runtime Firmware BL3-1 certificate", UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT,
+	  "bl31-cert", NULL, FLAG_FILENAME},
+	{ "Secure Payload BL3-2 (Trusted OS) certificate", UUID_SECURE_PAYLOAD_BL32_CERT,
+	  "bl32-cert", NULL, FLAG_FILENAME},
+	{ "Non-Trusted Firmware BL3-3 certificate", UUID_NON_TRUSTED_FIRMWARE_BL33_CERT,
+	  "bl33-cert", NULL, FLAG_FILENAME},
+	{ NULL, {0}, 0 }
+};
+
+
+/* Return 0 for equal uuids */
+static inline int compare_uuids(const uuid_t *uuid1, const uuid_t *uuid2)
+{
+	return memcmp(uuid1, uuid2, sizeof(uuid_t));
+}
+
+
+static inline void copy_uuid(uuid_t *to_uuid, const uuid_t *from_uuid)
+{
+	memcpy(to_uuid, from_uuid, sizeof(uuid_t));
+}
+
+
+static void print_usage(void)
+{
+	entry_lookup_list_t *entry = toc_entry_lookup_list;
+
+	printf("Usage: fip_create [options] FIP_FILENAME\n\n");
+	printf("\tThis tool is used to create a Firmware Image Package.\n\n");
+	printf("Options:\n");
+	printf("\t--help: Print this help message and exit\n");
+	printf("\t--dump: Print contents of FIP\n\n");
+	printf("\tComponents that can be added/updated:\n");
+	for (; entry->command_line_name != NULL; entry++) {
+		printf("\t--%s%s\t\t%s",
+		       entry->command_line_name,
+		       (entry->flags & FLAG_FILENAME) ? " FILENAME" : "",
+		       entry->name);
+		printf("\n");
+	}
+}
+
+
+static entry_lookup_list_t *get_entry_lookup_from_uuid(const uuid_t *uuid)
+{
+	unsigned int lookup_index = 0;
+
+	while (toc_entry_lookup_list[lookup_index].command_line_name != NULL) {
+		if (compare_uuids(&toc_entry_lookup_list[lookup_index].name_uuid,
+		    uuid) == 0) {
+			return &toc_entry_lookup_list[lookup_index];
+		}
+		lookup_index++;
+	}
+	return NULL;
+}
+
+
+static file_info_t *find_file_info_from_uuid(const uuid_t *uuid)
+{
+	int index;
+
+	for (index = 0; index < file_info_count; index++) {
+		if (compare_uuids(&files[index].name_uuid, uuid) == 0) {
+			return &files[index];
+		}
+	}
+	return NULL;
+}
+
+
+static int add_file_info_entry(entry_lookup_list_t *lookup_entry, char *filename)
+{
+	file_info_t *file_info_entry;
+	int error;
+	struct stat file_status;
+	bool is_new_entry = false;
+
+	/* Check if the file already exists in the array */
+	file_info_entry = find_file_info_from_uuid(&lookup_entry->name_uuid);
+	if (file_info_entry == NULL) {
+		/* The file does not exist in the current list; take the next
+		 * one available in the file_info list. 'file_info_count' is
+		 * incremented in case of successful update at the end of the
+		 * function.
+		 */
+		file_info_entry = &files[file_info_count];
+		is_new_entry = true;
+
+		/* Copy the uuid for the new entry */
+		copy_uuid(&file_info_entry->name_uuid,
+			  &lookup_entry->name_uuid);
+	}
+
+	/* Get the file information for entry */
+	error = stat(filename, &file_status);
+	if (error != 0) {
+		printf("Error: Cannot get information for file \"%s\": %s\n",
+			filename, strerror(errno));
+		return errno;
+	}
+	file_info_entry->filename = filename;
+	file_info_entry->size = (unsigned int)file_status.st_size;
+	file_info_entry->entry = lookup_entry;
+
+	/* Increment the file_info counter on success if it is new file entry */
+	if (is_new_entry) {
+		file_info_count++;
+
+		/* Ensure we do not overflow */
+		if (file_info_count > MAX_FILES) {
+			printf("ERROR: Too many files in Package\n");
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+
+static int write_memory_to_file(const uint8_t *start, const char *filename,
+		unsigned int size)
+{
+	FILE *stream;
+	unsigned int bytes_written;
+
+	/* Write the packed file out to the filesystem */
+	stream = fopen(filename, "r+");
+	if (stream == NULL) {
+		stream = fopen(filename, "w");
+		if (stream == NULL) {
+			printf("Error: Cannot create output file \"%s\": %s\n",
+			       filename, strerror(errno));
+			return errno;
+		} else {
+			printf("Creating \"%s\"\n", filename);
+		}
+	} else {
+		printf("Updating \"%s\"\n", filename);
+	}
+
+	bytes_written = fwrite(start, sizeof(uint8_t), size, stream);
+	fclose(stream);
+
+	if (bytes_written != size) {
+		printf("Error: Incorrect write for file \"%s\": Size=%u,"
+			"Written=%u bytes.\n", filename, size, bytes_written);
+		return EIO;
+	}
+
+	return 0;
+}
+
+
+static int read_file_to_memory(void *memory, const file_info_t *info)
+{
+	FILE *stream;
+	unsigned int bytes_read;
+
+	/* If the file_info is defined by its filename we need to load it */
+	if (info->filename) {
+		/* Read image from filesystem */
+		stream = fopen(info->filename, "r");
+		if (stream == NULL) {
+			printf("Error: Cannot open file \"%s\": %s\n",
+				info->filename, strerror(errno));
+			return errno;
+		}
+
+		bytes_read = (unsigned int)fread(memory, sizeof(uint8_t),
+						 info->size, stream);
+		fclose(stream);
+		if (bytes_read != info->size) {
+			printf("Error: Incomplete read for file \"%s\":"
+				"Size=%u, Read=%u bytes.\n", info->filename,
+				info->size, bytes_read);
+			return EIO;
+		}
+	} else {
+		if (info->image_buffer == NULL) {
+			printf("ERROR: info->image_buffer = NULL\n");
+			return EIO;
+		}
+		/* Copy the file_info buffer (extracted from the existing
+		 * image package) into the new buffer.
+		 */
+		memcpy(memory, info->image_buffer, info->size);
+	}
+
+	return 0;
+}
+
+
+/* Create the image package file */
+static int pack_images(const char *fip_filename)
+{
+	int status;
+	uint8_t *fip_base_address;
+	void *entry_address;
+	fip_toc_header_t *toc_header;
+	fip_toc_entry_t *toc_entry;
+	unsigned int entry_index;
+	unsigned int toc_size;
+	unsigned int fip_size;
+	unsigned int entry_offset_address;
+	unsigned int payload_size = 0;
+
+	/* Validate filename */
+	if ((fip_filename == NULL) || (strcmp(fip_filename, "") == 0)) {
+		return EINVAL;
+	}
+
+	/* Payload size calculation */
+	for (entry_index = 0; entry_index < file_info_count; entry_index++) {
+		payload_size += files[entry_index].size;
+	}
+
+	/* Allocate memory for entire package, including the final null entry */
+	toc_size = (sizeof(fip_toc_header_t) +
+		    (sizeof(fip_toc_entry_t) * (file_info_count + 1)));
+	fip_size = toc_size + payload_size;
+	fip_base_address = malloc(fip_size);
+	if (fip_base_address == NULL) {
+		printf("Error: Can't allocate enough memory to create package."
+		       "Process aborted.\n");
+		return ENOMEM;
+	}
+	memset(fip_base_address, 0, fip_size);
+
+	/* Create ToC Header */
+	toc_header = (fip_toc_header_t *)fip_base_address;
+	toc_header->name = TOC_HEADER_NAME;
+	toc_header->serial_number = TOC_HEADER_SERIAL_NUMBER;
+	toc_header->flags = 0;
+
+	toc_entry = (fip_toc_entry_t *)(fip_base_address +
+				      sizeof(fip_toc_header_t));
+
+	/* Calculate the starting address of the first image, right after the
+	 * toc header.
+	 */
+	entry_offset_address = toc_size;
+	entry_index = 0;
+
+	/* Create the package in memory. */
+	for (entry_index = 0; entry_index < file_info_count; entry_index++) {
+		entry_address = (fip_base_address + entry_offset_address);
+		status = read_file_to_memory(entry_address,
+					     &files[entry_index]);
+		if (status != 0) {
+			printf("Error: While reading \"%s\" from filesystem.\n",
+				files[entry_index].filename);
+			return status;
+		}
+
+		copy_uuid(&toc_entry->uuid, &files[entry_index].name_uuid);
+		toc_entry->offset_address = entry_offset_address;
+		toc_entry->size = files[entry_index].size;
+		toc_entry->flags = 0;
+		entry_offset_address += toc_entry->size;
+		toc_entry++;
+	}
+
+	/* Add a null uuid entry to mark the end of toc entries */
+	copy_uuid(&toc_entry->uuid, &uuid_null);
+	toc_entry->offset_address = entry_offset_address;
+	toc_entry->size = 0;
+	toc_entry->flags = 0;
+
+	/* Save the package to file */
+	status = write_memory_to_file(fip_base_address, fip_filename, fip_size);
+	if (status != 0) {
+		printf("Error: Failed while writing package to file \"%s\" "
+			"with status=%d.\n", fip_filename, status);
+		return status;
+	}
+	return 0;
+}
+
+
+static void dump_toc(void)
+{
+	unsigned int index = 0;
+	unsigned int image_offset;
+	unsigned int image_size = 0;
+
+	image_offset = sizeof(fip_toc_header_t) +
+		(sizeof(fip_toc_entry_t) * (file_info_count + 1));
+
+	printf("Firmware Image Package ToC:\n");
+	printf("---------------------------\n");
+	for (index = 0; index < file_info_count; index++) {
+		if (files[index].entry) {
+			printf("- %s: ", files[index].entry->name);
+		} else {
+			printf("- Unknown entry: ");
+		}
+		image_size = files[index].size;
+
+		printf("offset=0x%X, size=0x%X\n", image_offset, image_size);
+		image_offset += image_size;
+
+		if (files[index].filename) {
+			printf("  file: '%s'\n", files[index].filename);
+		}
+	}
+	printf("---------------------------\n");
+}
+
+
+/* Read and load existing package into memory. */
+static int parse_fip(const char *fip_filename)
+{
+	FILE *fip;
+	char *fip_buffer;
+	char *fip_buffer_end;
+	int fip_size, read_fip_size;
+	fip_toc_header_t *toc_header;
+	fip_toc_entry_t *toc_entry;
+	bool found_last_toc_entry = false;
+	file_info_t *file_info_entry;
+	int status = -1;
+	struct stat st;
+
+	fip = fopen(fip_filename, "r");
+	if (fip == NULL) {
+		/* If the fip does not exist just return, it should not be
+		 * considered as an error. The package will be created later
+		 */
+		status = 0;
+		goto parse_fip_return;
+	}
+
+	if (stat(fip_filename, &st) != 0) {
+		status = errno;
+		goto parse_fip_fclose;
+	} else {
+		fip_size = (int)st.st_size;
+	}
+
+	/* Allocate a buffer to read the package */
+	fip_buffer = (char *)malloc(fip_size);
+	if (fip_buffer == NULL) {
+		printf("ERROR: Cannot allocate %d bytes.\n", fip_size);
+		status = errno;
+		goto parse_fip_fclose;
+	}
+	fip_buffer_end = fip_buffer + fip_size;
+
+	/* Read the file */
+	read_fip_size = fread(fip_buffer, sizeof(char), fip_size, fip);
+	if (read_fip_size != fip_size) {
+		printf("ERROR: Cannot read the FIP.\n");
+		status = EIO;
+		goto parse_fip_free;
+	}
+	fclose(fip);
+	fip = NULL;
+
+	/* The package must at least contain the ToC Header */
+	if (fip_size < sizeof(fip_toc_header_t)) {
+		printf("ERROR: Given FIP is smaller than the ToC header.\n");
+		status = EINVAL;
+		goto parse_fip_free;
+	}
+	/* Set the ToC Header at the base of the buffer */
+	toc_header = (fip_toc_header_t *)fip_buffer;
+	/* The first toc entry should be just after the ToC header */
+	toc_entry = (fip_toc_entry_t *)(toc_header + 1);
+
+	/* While the ToC entry is contained into the buffer */
+	int cnt = 0;
+	while (((char *)toc_entry + sizeof(fip_toc_entry_t)) < fip_buffer_end) {
+		cnt++;
+		/* Check if the ToC Entry is the last one */
+		if (compare_uuids(&toc_entry->uuid, &uuid_null) == 0) {
+			found_last_toc_entry = true;
+			status = 0;
+			break;
+		}
+
+		/* Add the entry into file_info */
+
+		/* Get the new entry in the array and clear it */
+		file_info_entry = &files[file_info_count++];
+		memset(file_info_entry, 0, sizeof(file_info_t));
+
+		/* Copy the info from the ToC entry */
+		copy_uuid(&file_info_entry->name_uuid, &toc_entry->uuid);
+		file_info_entry->image_buffer = fip_buffer +
+		  toc_entry->offset_address;
+		file_info_entry->size = toc_entry->size;
+
+		/* Check if there is a corresponding entry in lookup table */
+		file_info_entry->entry =
+		  get_entry_lookup_from_uuid(&toc_entry->uuid);
+
+		/* Go to the next ToC entry */
+		toc_entry++;
+	}
+
+	if (!found_last_toc_entry) {
+		printf("ERROR: Given FIP does not have an end ToC entry.\n");
+		status = EINVAL;
+		goto parse_fip_free;
+	} else {
+		/* All is well, we should not free any of the loaded images */
+		goto parse_fip_fclose;
+	}
+
+ parse_fip_free:
+	if (fip_buffer != NULL) {
+		free(fip_buffer);
+		fip_buffer = NULL;
+	}
+
+ parse_fip_fclose:
+	if (fip != NULL) {
+		fclose(fip);
+	}
+
+ parse_fip_return:
+	return status;
+}
+
+
+/* Parse all command-line options and return the FIP name if present. */
+static char *get_filename(int argc, char **argv, struct option *options)
+{
+	int c;
+	char *filename = NULL;
+
+	/* Reset option pointer so we parse all args. starts at 1.
+	 * The filename is the only argument that does not have an option flag.
+	 */
+	optind = 1;
+	while (1) {
+		c = getopt_long(argc, argv, "", options, NULL);
+		if (c == -1)
+			break;
+
+		if (c == '?') {
+			/* Failed to parse an option. Fail. */
+			return NULL;
+		}
+	}
+
+	/* Only one argument left then it is the filename.
+	 * We dont expect any other options
+	 */
+	if (optind + 1 == argc)
+		filename = argv[optind];
+
+	return filename;
+}
+
+
+/* Work through command-line options */
+static int parse_cmdline(int argc, char **argv, struct option *options,
+			 int *do_pack)
+{
+	int c;
+	int status = 0;
+	int option_index = 0;
+	entry_lookup_list_t *lookup_entry;
+	int do_dump = 0;
+
+	/* restart parse to process all options. starts at 1. */
+	optind = 1;
+	while (1) {
+		c = getopt_long(argc, argv, "", options, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case OPT_TOC_ENTRY:
+			if (optarg) {
+				/* Does the option expect a filename. */
+				lookup_entry = &toc_entry_lookup_list[option_index];
+				if (lookup_entry->flags & FLAG_FILENAME) {
+					status = add_file_info_entry(lookup_entry, optarg);
+					if (status != 0) {
+						printf("Failed to process %s\n",
+						       options[option_index].name);
+						return status;
+					} else {
+						/* Update package */
+						*do_pack = 1;
+					}
+				}
+			}
+			break;
+
+		case OPT_DUMP:
+			do_dump = 1;
+			continue;
+
+		case OPT_HELP:
+			print_usage();
+			exit(0);
+
+		default:
+			/* Unrecognised options are caught in get_filename() */
+			break;
+		}
+	}
+
+
+	/* Do not dump toc if we have an error as it could hide the error */
+	if ((status == 0) && (do_dump)) {
+		dump_toc();
+	}
+
+	return status;
+
+}
+
+int main(int argc, char **argv)
+{
+	int i;
+	int status;
+	char *fip_filename;
+	int do_pack = 0;
+
+	/* Clear file list table. */
+	memset(files, 0, sizeof(files));
+
+	/* Initialise for getopt_long().
+	 * Use image table as defined at top of file to get options.
+	 * Add 'dump' option, 'help' option and end marker.
+	 */
+	static struct option long_options[(sizeof(toc_entry_lookup_list)/
+					   sizeof(entry_lookup_list_t)) + 2];
+
+	for (i = 0;
+	     /* -1 because we dont want to process end marker in toc table */
+	     i < sizeof(toc_entry_lookup_list)/sizeof(entry_lookup_list_t) - 1;
+	     i++) {
+		long_options[i].name = toc_entry_lookup_list[i].command_line_name;
+		/* The only flag defined at the moment is for a FILENAME */
+		long_options[i].has_arg = toc_entry_lookup_list[i].flags ? 1 : 0;
+		long_options[i].flag = 0;
+		long_options[i].val = OPT_TOC_ENTRY;
+	}
+
+	/* Add '--dump' option */
+	long_options[i].name = "dump";
+	long_options[i].has_arg = 0;
+	long_options[i].flag = 0;
+	long_options[i].val = OPT_DUMP;
+
+	/* Add '--help' option */
+	long_options[++i].name = "help";
+	long_options[i].has_arg = 0;
+	long_options[i].flag = 0;
+	long_options[i].val = OPT_HELP;
+
+	/* Zero the last entry (required) */
+	long_options[++i].name = 0;
+	long_options[i].has_arg = 0;
+	long_options[i].flag = 0;
+	long_options[i].val = 0;
+
+#ifdef DEBUG
+	/* Print all supported options */
+	for (i = 0; i < sizeof(long_options)/sizeof(struct option); i++) {
+		printf("long opt (%d) : name = %s\n", i, long_options[i].name);
+	}
+#endif /* DEBUG */
+
+	/* As the package may already exist and is to be updated we need to get
+	 * the filename from the arguments and load from it.
+	 * NOTE: As this is the first function to look at the program arguments
+	 * it causes a failure if bad options were provided.
+	 */
+	fip_filename = get_filename(argc, argv, long_options);
+
+	/* Try to open the file and load it into memory */
+	if (fip_filename != NULL) {
+		status = parse_fip(fip_filename);
+		if (status != 0) {
+			return status;
+		}
+	}
+
+	/* Work through provided program arguments and perform actions */
+	status = parse_cmdline(argc, argv, long_options, &do_pack);
+	if (status != 0) {
+		return status;
+	};
+
+	if (fip_filename == NULL) {
+		printf("ERROR: Missing FIP filename\n");
+		print_usage();
+		return 0;
+	}
+
+	/* Processed all command line options. Create/update the package if
+	 * required.
+	 */
+	if (do_pack) {
+		status = pack_images(fip_filename);
+		if (status != 0) {
+			printf("Failed to create package (status = %d).\n",
+			       status);
+		}
+	}
+
+	return status;
+}
diff --git a/uefi/arm-trusted-firmware/tools/fip_create/fip_create.h b/uefi/arm-trusted-firmware/tools/fip_create/fip_create.h
new file mode 100644
index 0000000..3258335
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/fip_create/fip_create.h
@@ -0,0 +1,60 @@
+/*
+ * 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 __FIP_CREATE_H__
+#define __FIP_CREATE_H__
+
+#include <stdint.h>
+#include <uuid.h>
+
+#define MAX_FILES			20
+
+/* TODO: Update this number as required */
+#define TOC_HEADER_SERIAL_NUMBER	0x12345678
+
+#define FLAG_FILENAME			(1 << 0)
+
+typedef struct entry_lookup_list {
+	const char		*name;
+	uuid_t			 name_uuid;
+	const char		*command_line_name;
+	struct file_info	*info;
+	unsigned int		 flags;
+} entry_lookup_list_t;
+
+typedef struct file_info {
+	uuid_t			 name_uuid;
+	const char		*filename;
+	unsigned int		 size;
+	void			*image_buffer;
+	entry_lookup_list_t	*entry;
+} file_info_t;
+
+#endif /* __FIP_CREATE_H__ */
diff --git a/uefi/arm-trusted-firmware/tools/fip_create/firmware_image_package.h b/uefi/arm-trusted-firmware/tools/fip_create/firmware_image_package.h
new file mode 120000
index 0000000..cc61903
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/fip_create/firmware_image_package.h
@@ -0,0 +1 @@
+../../include/common/firmware_image_package.h
\ No newline at end of file
diff --git a/uefi/arm-trusted-firmware/tools/fip_create/uuid.h b/uefi/arm-trusted-firmware/tools/fip_create/uuid.h
new file mode 120000
index 0000000..c77762f
--- /dev/null
+++ b/uefi/arm-trusted-firmware/tools/fip_create/uuid.h
@@ -0,0 +1 @@
+../../include/stdlib/sys/uuid.h
\ No newline at end of file