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)¤t_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 *)¤t_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)¤t_file.entry,
+ sizeof(current_file.entry),
+ &bytes_read);
+ if (result == IO_SUCCESS) {
+ if (compare_uuids(¤t_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(¤t_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)¤t_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(¤t_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)¤t_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 *)¤t_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