Merge "hikey: uefi-tools: Update UEFI tools to match updated UEFI sources"
diff --git a/uefi-tools/atf-build.sh b/uefi-tools/atf-build.sh
index 0c4c09c..65d4dbc 100755
--- a/uefi-tools/atf-build.sh
+++ b/uefi-tools/atf-build.sh
@@ -8,7 +8,6 @@
 # parse-platforms.py and platforms.config.
 #
 
-TOOLS_DIR="`dirname $0`"
 . "$TOOLS_DIR"/common-functions
 OUTPUT_DIR="$PWD"/uefi-build
 
@@ -72,10 +71,10 @@
 	BL30="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o scp_bin`"
 	if [ $ATF_BUILDVER -gt 1 ]; then
 		unset SCP_BL2
-		SCP_BL2="$EDK2_DIR/$BL30"
+		SCP_BL2=`search_packages_path "$BL30"`
 	fi
 	BL31="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o el3_bin`"
-	BL33="$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o uefi_bin`"
+	BL33="$WORKSPACE/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o uefi_bin`"
 
 	#
 	# Set up cross compilation variables (if applicable)
@@ -86,10 +85,10 @@
 	echo "CROSS_COMPILE=\"$TEMP_CROSS_COMPILE\""
 
 	if [ X"$BL30" != X"" ]; then
-		BL30="${EDK2_DIR}"/"${BL30}"
+		BL30=`search_packages_path "$BL30"`
 	fi
 	if [ X"$BL31" != X"" ]; then
-		BL31="${EDK2_DIR}"/"${BL31}"
+		BL31=`search_packages_path "$BL31"`
 	fi
 
 	#
@@ -102,7 +101,7 @@
 
 		TOS_BIN="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o tos_bin`"
 		if [ X"$TOS_BIN" != X"" ]; then
-			BL32=$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/$TOS_BIN
+			BL32=$WORKSPACE/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/$TOS_BIN
 		fi
 
 		if [ X"$SPD" != X"" ] && [ X"$BL32" != X"" ]; then
@@ -116,8 +115,26 @@
 			echo "		Please specify both ATF_SPD and TOS_BIN"
 			echo "		if you wish to use a Trusted OS!"
 		fi
+	else
+	#
+	# Since TOS_DIR is not set, user does not want a Trusted OS
+	# even if the source directory and/or binary for it exists.
+	# Next, Check whether user wants secure partition image.
+	# If SPM_BIN is set then include pre-built secure partition image as a
+	# BL32 Image and implicitly set SPM=1.
+	#
+		SPM_BIN="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o spm_bin`"
+
+		if [ X"$SPM_BIN" != X"" ]; then
+			BL32=$WORKSPACE/Build/StandaloneSmmPkg/$BUILD_PROFILE/FV/$SPM_BIN
+			PLATFORM_BUILDFLAGS="$PLATFORM_BUILDFLAGS SPM=1"
+		fi
+	# We assume that user does not want secure partition either.
+	# Todo: Revisit if either one of Trusted OS or Secure Partition Image is Mandatory.
 	fi
 
+
+
 	#
 	# Debug extraction handling
 	#
@@ -135,7 +152,7 @@
 	export BL30 BL31 BL32 BL33
 
 	echo "BL30=$BL30"
-	if [ $ATF_BUILDVER -gt 1 ]; then
+	if [ $ATF_BUILDVER -gt 1 ] && [ X"$BL30" != X"" ]; then
 		export SCP_BL2
 		echo "SCP_BL2=$BL30"
 	fi
@@ -165,9 +182,9 @@
 		# Copy resulting images to UEFI image dir
 		#
 		if [ $VERBOSE -eq 1 ]; then
-			echo "Copying bl1.bin and fip.bin to "$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/""
+			echo "Copying bl1.bin and fip.bin to "$WORKSPACE/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/""
 		fi
-		cp -a build/"$ATF_PLATFORM/$BUILD_TYPE"/{bl1,fip}.bin "$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/"
+		cp -a build/"$ATF_PLATFORM/$BUILD_TYPE"/{bl1,fip}.bin "$WORKSPACE/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/"
 	else
 		return 1
 	fi
diff --git a/uefi-tools/common-functions b/uefi-tools/common-functions
index 08f4fbf..9d01ae1 100644
--- a/uefi-tools/common-functions
+++ b/uefi-tools/common-functions
@@ -4,8 +4,6 @@
 RESULT_PASS_COUNT=0
 RESULT_FAIL_COUNT=0
 
-TOOLS_DIR="`dirname $0`"
-
 function result_log
 {
 	if [ $1 -eq 0 ]; then
@@ -34,6 +32,10 @@
 	        BUILD_ARCH=ARM;;
 	    aarch64*)
 	        BUILD_ARCH=AARCH64;;
+	    i?86*)
+		BUILD_ARCH=IA32;;
+	    x86_64*)
+		BUILD_ARCH=X64;;
 	    *)
 	        BUILD_ARCH=other;;
 	esac
@@ -45,42 +47,168 @@
 
 	echo "Target: $PLATFORM_ARCH"
 	echo "Build: $BUILD_ARCH"
-	if [ "$PLATFORM_ARCH" = "$BUILD_ARCH" ]; then
+ 	if [ "$PLATFORM_ARCH" = "$BUILD_ARCH" ]; then
 	    TEMP_CROSS_COMPILE=
-	elif [ "$PLATFORM_ARCH" == "AARCH64" ]; then
-	    if [ X"$CROSS_COMPILE_64" != X"" ]; then
-	        TEMP_CROSS_COMPILE="$CROSS_COMPILE_64"
-	    else
-	        TEMP_CROSS_COMPILE=aarch64-linux-gnu-
-	    fi
-	elif [ "$PLATFORM_ARCH" == "ARM" ]; then
-	    if [ X"$CROSS_COMPILE_32" != X"" ]; then
-	        TEMP_CROSS_COMPILE="$CROSS_COMPILE_32"
-	    else
-	        TEMP_CROSS_COMPILE=arm-linux-gnueabihf-
-	    fi
 	else
-	    echo "Unsupported target architecture '$PLATFORM_ARCH'!" >&2
+	    case "$PLATFORM_ARCH" in
+		AARCH64)
+                    if [ X"$CROSS_COMPILE_64" != X"" ]; then
+                        TEMP_CROSS_COMPILE="$CROSS_COMPILE_64"
+                    else
+                        TEMP_CROSS_COMPILE=aarch64-linux-gnu-
+                    fi
+                ;;
+		ARM)
+		    TEMP_CROSS_COMPILE=arm-linux-gnueabihf- ;;
+		IA32)
+		    TEMP_CROSS_COMPILE=x86_64-linux-gnu-
+		    for family in 6 5 4 3; do
+		        if i$family86-linux-gnu-as -version >/dev/null 2>&1;then
+		            TEMP_CROSS_COMPILE=i$family86-linux-gnu-
+		            break
+		        fi
+		    done
+		;;
+		X64)
+		    TEMP_CROSS_COMPILE=x86_64-linux-gnu- ;;
+		*)
+	            echo "Unsupported target architecture '$PLATFORM_ARCH'!" >&2
+		;;
+	    esac
 	fi
 }
 
 function get_gcc_version
 {
+	$1 -v >/dev/null 2>&1 || return 1
 	gcc_version=$($1 -dumpversion)
+	MAJVER=`echo $gcc_version | cut -d. -f1`
+
 	case $gcc_version in
-		4.6*|4.7*|4.8*|4.9*)
+		4*)
 			echo GCC$(echo ${gcc_version} | awk -F. '{print $1$2}')
 			;;
 		*)
-			echo "Unknown toolchain version '$gcc_version'" >&2
-			echo "Attempting to build using GCC49 profile." >&2
-			echo GCC49
+			if [ "$MAJVER" -ge 5 ]; then
+			    # We only have a GCC5 build profile for now, so...
+			    # echo GCC$MAJVER
+			    echo GCC5
+			else
+			    echo "Unknown toolchain version '$gcc_version'" >&2
+			    echo "Attempting to build using GCC49 profile." >&2
+			    echo GCC49
+			fi
 			;;
 	esac
+
+	return 0
 }
 
 function get_clang_version
 {
 	clang_version=`$1 --version | head -1 | sed 's/^.*version\s*\([0-9]*\).\([0-9]*\).*/\1\2/g'`
-	echo "CLANG$clang_version"
+	case $clang_version in
+		35*)
+			echo "CLANG$clang_version"
+			;;
+		*)
+			echo "Unknown toolchain version '$clang_version'" >&2
+			echo "Attempting to build using CLANG35 profile." >&2
+			echo CLANG35
+			;;
+	esac
+}
+
+function download_patch_openssl
+{
+    OPENSSL_VER=`ls EDKII_openssl-*.patch | sed 's/^.*-\([0-9.a-z]*\).patch/\1/'`
+    OPENSSL_TAR=openssl-${OPENSSL_VER}.tar.gz
+    OPENSSL_URL=http://www.openssl.org/source/${OPENSSL_TAR}
+    OPENSSL_DIR=openssl-${OPENSSL_VER}
+    OPENSSL_PATCH=EDKII_openssl-${OPENSSL_VER}.patch
+
+    if [ -e "$WORKSPACE"/CryptoPkg/Include/openssl/opensslconf.h ]; then
+        echo "OpenSSL already imported!"
+        return 0
+    fi
+
+    # Use cached copy if available
+    if [ -f "$WORKSPACE"/LinaroPkg/"$OPENSSL_TAR" ]; then
+	tar xzf "$WORKSPACE"/LinaroPkg/"$OPENSSL_TAR"
+    else
+	wget -O - -q ${OPENSSL_URL} | tar xzf -
+    fi
+
+    echo "Importing OpenSSL $OPENSSL_VER"
+    ( cd ${OPENSSL_DIR}; patch -p1 -i ../${OPENSSL_PATCH} )
+    ./Install.sh
+
+    if [ $? -eq 0 ]; then
+	OPENSSL_CONFIGURED=TRUE
+    else
+	echo "OpenSSL $OPENSSL_VER import failed!" >&2
+	rm -rf $OPENSSL_TAR $OPENSSL_DIR
+	return 1
+    fi
+}
+
+function clone_process_openssl
+{
+    if [ -e openssl/include/openssl/opensslconf.h ]; then
+        echo "OpenSSL already imported!"
+        return 0
+    fi
+
+    OPENSSL_VER=`git ls-remote --tags git://github.com/openssl/openssl.git | awk '{print $2;}' | sed 's-^refs/tags/--g' | grep -v '\^{}$' | grep '^OpenSSL' | grep -v '^OpenSSL_FIPS' | tail -1 | sed -n 's/^OpenSSL_\([0-9]*\)_\([0-9]*\)_\([0-9.a-z]*\)$/openssl-\1.\2.\3\n/p'`
+    OPENSSL_TAR="$OPENSSL_VER.tar.gz"
+    if [ -z "$OPENSSL_TAR" ]; then
+        return 1
+    fi
+    OPENSSL_URL=http://www.openssl.org/source/${OPENSSL_TAR}
+    if [ ! -f "$OPENSSL_TAR" ]; then
+        wget -q ${OPENSSL_URL}
+    else
+        rm -rf openssl
+    fi
+    tar xzf "$OPENSSL_TAR"
+    mv "$OPENSSL_VER" openssl
+    # perl process_files.pl # not needed and not currently working
+    return $?
+}
+
+function import_openssl
+{
+    # Don't re-import if already done
+    if [ "$OPENSSL_CONFIGURED" = "TRUE" ]; then
+	echo "Using existing OpenSSL $OPENSSL_VER"
+	return 0
+    fi
+
+    cd CryptoPkg/Library/OpensslLib/
+    if [ -f EDKII_openssl-*.patch ]; then
+        download_patch_openssl
+    else
+        clone_process_openssl
+    fi
+    RET=$?
+    cd - >/dev/null
+    return $RET
+}
+
+function search_packages_path
+{
+    file="$1"
+
+    IFS=:
+    for dir in $PACKAGES_PATH; do
+	if [ -e "$dir/$file" ]; then
+	    echo "$dir/$file"
+	    unset IFS
+	    return 0
+	fi
+    done
+
+    echo "$file not found in any directory on PACKAGES_PATH!" >&2
+    unset IFS
+    return 1
 }
diff --git a/uefi-tools/edk2-build.sh b/uefi-tools/edk2-build.sh
new file mode 100755
index 0000000..3e218b3
--- /dev/null
+++ b/uefi-tools/edk2-build.sh
@@ -0,0 +1,401 @@
+#!/bin/bash
+
+#
+# edk2-build.sh: evolution of uefi-build.sh for edk2-platforms
+#
+
+unset MAKEFLAGS  # BaseTools not safe to build parallel, prevent env overrides
+
+TOOLS_DIR="`dirname $0`"
+TOOLS_DIR="`readlink -f \"$TOOLS_DIR\"`"
+export TOOLS_DIR
+. "$TOOLS_DIR"/common-functions
+PLATFORM_CONFIG="-c $TOOLS_DIR/edk2-platforms.config"
+ARCH=
+VERBOSE=0                  # Override with -v
+ATF_DIR=
+TOS_DIR=
+TOOLCHAIN="gcc"            # Override with -T
+WORKSPACE=
+EDK2_DIR=
+PLATFORMS_DIR=
+NON_OSI_DIR=
+IMPORT_OPENSSL=TRUE
+OPENSSL_CONFIGURED=FALSE
+
+# Number of threads to use for build
+export NUM_THREADS=$((`getconf _NPROCESSORS_ONLN` + `getconf _NPROCESSORS_ONLN`))
+
+function do_build
+{
+	PLATFORM_ARCH=`echo $board | cut -s -d: -f2`
+	if [ -n "$PLATFORM_ARCH" ]; then
+		board=`echo $board | cut -d: -f1`
+	else
+		PLATFORM_ARCH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o arch`"
+	fi
+	PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname` ($PLATFORM_ARCH)"
+	if [ -z "$PLATFORM_ARCH" ]; then
+		echo "Unknown target architecture - aborting!" >&2
+		return 1
+	fi
+	PLATFORM_PREBUILD_CMDS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o prebuild_cmds`"
+	PLATFORM_BUILDFLAGS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildflags`"
+	PLATFORM_BUILDFLAGS="$PLATFORM_BUILDFLAGS ${EXTRA_OPTIONS[@]}"
+	PLATFORM_BUILDCMD="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildcmd`"
+	PLATFORM_DSC="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o dsc`"
+	PLATFORM_PACKAGES_PATH=""
+	COMPONENT_INF="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o inf`"
+
+	TEMP_PACKAGES_PATH="$GLOBAL_PACKAGES_PATH:`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o packages_path`"
+	IFS=:
+	for path in "$TEMP_PACKAGES_PATH"; do
+		case "$path" in
+			/*)
+				PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$path"
+			;;
+			*)
+				PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$PWD/$path"
+			;;
+	        esac
+	done
+	unset IFS
+
+	if [ $VERBOSE -eq 1 ]; then
+		echo "Setting build parallellism to $NUM_THREADS processes"
+		echo "PLATFORM_NAME=$PLATFORM_NAME"
+		echo "PLATFORM_PREBUILD_CMDS=$PLATFORM_PREBUILD_CMDS"
+		echo "PLATFORM_BUILDFLAGS=$PLATFORM_BUILDFLAGS"
+		echo "PLATFORM_BUILDCMD=$PLATFORM_BUILDCMD"
+		echo "PLATFORM_DSC=$PLATFORM_DSC"
+		echo "PLATFORM_ARCH=$PLATFORM_ARCH"
+		echo "PLATFORM_PACKAGES_PATH=$PLATFORM_PACKAGES_PATH"
+	fi
+
+	set_cross_compile
+	CROSS_COMPILE="$TEMP_CROSS_COMPILE"
+
+	echo "Building $PLATFORM_NAME - $PLATFORM_ARCH"
+	echo "CROSS_COMPILE=\"$TEMP_CROSS_COMPILE\""
+	echo "$board"_BUILDFLAGS="'$PLATFORM_BUILDFLAGS'"
+
+	if [ "$TARGETS" == "" ]; then
+		TARGETS=( RELEASE )
+	fi
+
+	case $TOOLCHAIN in
+		"gcc")
+			PLATFORM_TOOLCHAIN=`get_gcc_version "$CROSS_COMPILE"gcc`
+			;;
+		"clang")
+			PLATFORM_TOOLCHAIN=`get_clang_version clang`
+			;;
+		*)
+			# Use command-line specified profile directly
+			PLATFORM_TOOLCHAIN=$TOOLCHAIN
+			;;
+	esac
+	echo "PLATFORM_TOOLCHAIN is ${PLATFORM_TOOLCHAIN}"
+
+	export ${PLATFORM_TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE
+	echo "Toolchain prefix: ${PLATFORM_TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE"
+
+	export PACKAGES_PATH="$PLATFORM_PACKAGES_PATH"
+	for target in "${TARGETS[@]}" ; do
+		if [ X"$PLATFORM_PREBUILD_CMDS" != X"" ]; then
+			echo "Run pre-build commands:"
+			if [ $VERBOSE -eq 1 ]; then
+				echo "  ${PLATFORM_PREBUILD_CMDS}"
+			fi
+			eval ${PLATFORM_PREBUILD_CMDS}
+		fi
+
+		if [ -n "$COMPONENT_INF" ]; then
+			# Build a standalone component
+			if [ $VERBOSE -eq 1 ]; then
+				echo "build -n $NUM_THREADS -a \"$PLATFORM_ARCH\" -t ${PLATFORM_TOOLCHAIN} -p \"$PLATFORM_DSC\"" \
+					"-m \"$COMPONENT_INF\" -b "$target" ${PLATFORM_BUILDFLAGS}"
+			fi
+			build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${PLATFORM_TOOLCHAIN} -p "$PLATFORM_DSC" \
+				-m "$COMPONENT_INF" -b "$target" ${PLATFORM_BUILDFLAGS}
+		else
+			# Build a platform
+			if [ $VERBOSE -eq 1 ]; then
+				echo "build -n $NUM_THREADS -a \"$PLATFORM_ARCH\" -t ${PLATFORM_TOOLCHAIN} -p \"$PLATFORM_DSC\"" \
+					"-b "$target" ${PLATFORM_BUILDFLAGS}"
+			fi
+			build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${PLATFORM_TOOLCHAIN} -p "$PLATFORM_DSC" \
+				-b "$target" ${PLATFORM_BUILDFLAGS}
+		fi
+
+		RESULT=$?
+		if [ $RESULT -eq 0 ]; then
+			if [ X"$TOS_DIR" != X"" ]; then
+				pushd $TOS_DIR >/dev/null
+				if [ $VERBOSE -eq 1 ]; then
+					echo "$TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board"
+				fi
+				$TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board
+				RESULT=$?
+				popd >/dev/null
+			fi
+		fi
+		if [ $RESULT -eq 0 ]; then
+			if [ X"$ATF_DIR" != X"" ]; then
+				pushd $ATF_DIR >/dev/null
+				if [ $VERBOSE -eq 1 ]; then
+					echo "$TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board"
+				fi
+				$TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board
+				RESULT=$?
+				popd >/dev/null
+			fi
+		fi
+		result_log $RESULT "$PLATFORM_NAME $target"
+	done
+	unset PACKAGES_PATH
+}
+
+
+function configure_paths
+{
+	WORKSPACE="$PWD"
+
+	# Check to see if we are in a UEFI repository
+	# refuse to continue if we aren't
+	if [ ! -d "$EDK2_DIR"/BaseTools ]
+	then
+		if [ -d "$PWD"/edk2/BaseTools ]; then
+			EDK2_DIR="$PWD"/edk2
+		else
+			echo "ERROR: can't locate the edk2 directory" >&2
+			echo "       please specify -e/--edk2-dir" >&2
+			exit 1
+		fi
+	fi
+
+	GLOBAL_PACKAGES_PATH="$EDK2_DIR"
+
+	# locate edk2-platforms
+	if [ -z "$PLATFORMS_DIR" -a -d "$PWD"/edk2-platforms ]; then
+		PLATFORMS_DIR="$PWD"/edk2-platforms
+	fi
+	if [ -n "$PLATFORMS_DIR" ]; then
+		GLOBAL_PACKAGES_PATH="$GLOBAL_PACKAGES_PATH:$PLATFORMS_DIR"
+	fi
+
+	# locate edk2-non-osi
+	if [ -z "$NON_OSI_DIR" -a -d "$PWD"/edk2-non-osi ]; then
+		NON_OSI_DIR="$PWD"/edk2-non-osi
+	fi
+	if [ -n "$NON_OSI_DIR" ]; then
+		GLOBAL_PACKAGES_PATH="$GLOBAL_PACKAGES_PATH:$NON_OSI_DIR"
+	fi
+
+	# locate arm-trusted-firmware
+	if [ -z "$ATF_DIR" -a -d "$PWD"/arm-trusted-firmware ]; then
+		ATF_DIR="$PWD"/arm-trusted-firmware
+	fi
+
+	export WORKSPACE
+}
+
+
+function prepare_build
+{
+	get_build_arch
+	export ARCH=$BUILD_ARCH
+
+	export ARCH
+	cd $EDK2_DIR
+	PACKAGES_PATH=$GLOBAL_PACKAGES_PATH . edksetup.sh --reconfig
+	if [ $? -ne 0 ]; then
+		echo "Sourcing edksetup.sh failed!" >&2
+		exit 1
+	fi
+	if [ $VERBOSE -eq 1 ]; then
+		echo "Building BaseTools"
+	fi
+	make -C BaseTools
+	RET=$?
+	cd -
+	if [ $RET -ne 0 ]; then
+		echo " !!! BaseTools failed to build !!! " >&2
+		exit 1
+	fi
+
+	if [ "$IMPORT_OPENSSL" = "TRUE" ]; then
+		cd $EDK2_DIR
+		import_openssl
+		if [ $? -ne 0 ]; then
+			echo "Importing OpenSSL failed - aborting!" >&2
+			echo "  specify --no-openssl to attempt build anyway." >&2
+			exit 1
+		fi
+		cd $WORKSPACE
+	fi
+}
+
+
+function usage
+{
+	echo "usage:"
+	echo -n "uefi-build.sh [-b DEBUG | RELEASE] [ all "
+	for board in "${boards[@]}" ; do
+	    echo -n "| $board "
+	done
+	echo "]"
+	printf "%8s\tbuild %s\n" "all" "all supported platforms"
+	for board in "${boards[@]}" ; do
+		PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname`"
+		printf "%8s\tbuild %s\n" "$board" "${PLATFORM_NAME}"
+	done
+}
+
+#
+# Since we do a command line validation on whether specified platforms exist or
+# not, do a first pass of command line to see if there is an explicit config
+# file there to read valid platforms from.
+#
+commandline=( "$@" )
+i=0
+for arg;
+do
+	if [ $arg == "-c" ]; then
+		FILE_ARG=${commandline[i + 1]}
+		if [ ! -f "$FILE_ARG" ]; then
+			echo "ERROR: configuration file '$FILE_ARG' not found" >&2
+			exit 1
+		fi
+		case "$FILE_ARG" in
+			/*)
+				PLATFORM_CONFIG="-c $FILE_ARG"
+			;;
+			*)
+				PLATFORM_CONFIG="-c `readlink -f \"$FILE_ARG\"`"
+			;;
+		esac
+		echo "Platform config file: '$FILE_ARG'"
+	fi
+	i=$(($i + 1))
+done
+
+export PLATFORM_CONFIG
+
+builds=()
+boards=()
+boardlist="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG shortlist`"
+for board in $boardlist; do
+    boards=(${boards[@]} $board)
+done
+
+NUM_TARGETS=0
+
+while [ "$1" != "" ]; do
+	case $1 in
+		-1)     # Disable build parallellism
+			NUM_THREADS=1
+			;;
+		-a | --arm-tf-dir)
+			shift
+			ATF_DIR="`readlink -f $1`"
+			;;
+		-c)     # Already parsed above - skip this + option
+			shift
+			;;
+		-b | --build-target)
+			shift
+			echo "Adding Build target: $1"
+			TARGETS=(${TARGETS[@]} $1)
+			;;
+		-D)     # Pass through as -D option to 'build'
+			shift
+			echo "Adding Macro: -D $1"
+			EXTRA_OPTIONS=(${EXTRA_OPTIONS[@]} "-D" $1)
+			;;
+		-e | --edk2-dir)
+			shift
+			export EDK2_DIR="`readlink -f $1`"
+			;;
+		-h | --help)
+			usage
+			exit
+			;;
+		--no-openssl)
+			IMPORT_OPENSSL=FALSE
+			;;
+		-n | --non-osi-dir)
+			shift
+			NON_OSI_DIR="`readlink -f $1`"
+			;;
+		-p | --platforms-dir)
+			shift
+			PLATFORMS_DIR="`readlink -f $1`"
+			;;
+		-s | --tos-dir)
+			shift
+			export TOS_DIR="`readlink -f $1`"
+			;;
+		-T)     # Set specific toolchain tag, or clang/gcc for autoselection
+			shift
+			echo "Setting toolchain tag to '$1'"
+			TOOLCHAIN="$1"
+			;;
+		-v)
+			VERBOSE=1
+			;;
+		all)    # Add all targets in configuration file to list
+			builds=(${boards[@]})
+			NUM_TARGETS=$(($NUM_TARGETS + 1))
+			;;
+		*)      # Try to match target in configuration file, add to list
+			MATCH=0
+			for board in "${boards[@]}" ; do
+				if [ "`echo $1 | cut -d: -f1`" == $board ]; then
+					MATCH=1
+					builds=(${builds[@]} "$1")
+					break
+				fi
+			done
+
+			if [ $MATCH -eq 0 ]; then
+				echo "unknown arg $1"
+				usage
+				exit 1
+			fi
+			NUM_TARGETS=$(($NUM_TARGETS + 1))
+			;;
+	esac
+	shift
+done
+
+if [ $NUM_TARGETS -le  0 ]; then
+	echo "No targets specified - exiting!" >&2
+	exit 0
+fi
+
+export VERBOSE
+
+configure_paths
+
+prepare_build
+
+if [[ "${EXTRA_OPTIONS[@]}" != *"FIRMWARE_VER"* ]]; then
+	if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
+		FIRMWARE_VER=`git rev-parse --short HEAD`
+		if ! git diff-index --quiet HEAD --; then
+			FIRMWARE_VER="${FIRMWARE_VER}-dirty"
+		fi
+		EXTRA_OPTIONS=( ${EXTRA_OPTIONS[@]} "-D" FIRMWARE_VER=$FIRMWARE_VER )
+		if [ $VERBOSE -eq 1 ]; then
+			echo "FIRMWARE_VER=$FIRMWARE_VER"
+			echo "EXTRA_OPTIONS=$EXTRA_OPTIONS"
+		fi
+	fi
+fi
+
+for board in "${builds[@]}" ; do
+	do_build
+done
+
+result_print
diff --git a/uefi-tools/edk2-platforms.config b/uefi-tools/edk2-platforms.config
new file mode 100644
index 0000000..be74327
--- /dev/null
+++ b/uefi-tools/edk2-platforms.config
@@ -0,0 +1,138 @@
+# Platform build configurations for Linaro EDK2 builds
+# ====================================================
+# The configuration file format is extremely simplistic:
+# - Each platform has a short name.
+# - A platform entry starts by the short name held in square brackets, '[]'
+# - Within each entry, all options are described in a NAME=VALUE scheme,
+#   with the name being whatever comes before the first '=' on the line,
+#   and the value being everything that comes after it.
+#
+# Mandatory options:
+# - LONGNAME		A more descriptive name of the platform.
+# - DSC			Pointer to the EDK2 build description file. (The
+#			pandaboard is excused, all other ports must have this.)
+# - ARCH		String describing the architecture to build for.
+#			Currently supported are AARCH32 and AARCH64.
+# - UEFI_BIN		Name of executable image produced.
+# - UEFI_IMAGE_DIR	Build output directory name, relative to 'Build'.
+#
+# Options for Trusted OS
+# Note that OP-TEE (https://github.com/OP-TEE/optee_os) is the only currently
+# supported Trusted OS
+# - BUILD_TOS		Set to "yes" if the build should automatically build
+#   			Trusted OS, mainly for ARM Trusted Firmware.
+#			If this is set, you must also set ATF_SPD!
+#			Else we will not know which specific Trusted OS to
+#			build.
+#			Set to "debug" to create a debug build.
+# - TOS_PLATFORM	Platform name for Trusted OS build, if
+#   			different from ARM Trusted Firmware platform
+#			or UEFI platform name.
+# - TOS_PLATFORM_FLAVOR	If a core platform has multiple flavors, specify which
+#			flavor here.
+#
+# Options for ARM Trusted Firmware platforms
+# - BUILD_ATF		Set to "yes" if the build should automatically build
+#   			ARM Trusted Firmware and a fip containing UEFI image.
+#			Set to "debug" to create a debug build.
+# - ATF_PLATFORM	Platform name for ARM Trusted Firmware build, if
+#   			different from UEFI platform name.
+# - SCP_BIN		SCP image to pass to ARM Trusted Firmware.
+# - TOS_BIN		Trusted OS image to pass to ARM Trusted Firmware.
+#			The path is relative to
+#			$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/.
+#			To actually build the Trusted OS, you must also set
+#			ATF_SPD.
+# - ATF_SPD		Name of Secure Payload Dispatcher
+#			To actually build the Trusted OS, you must also set
+#			TOS_BIN.
+#
+# Optional options:
+# - BUILDFLAGS		Any special flags you want to pass to the build command.
+# - ATF_BUILDFLAGS	Any special flags you want to pass to the ARM Trusted
+#			Firmware build command.
+# - TOS_BUILDFLAGS	Any special flags you want to pass to the Trusted OS
+#			build command.
+# - EXTRA_FILES		Any additional files to be copied to output dir.
+# - PREBUILD_CMDS	Any commands you want to execute before the build step.
+# - POSTBUILD_CMDS	Any commands you want to execute after the build step.
+# - PACKAGES_PATH	Additional directories to search for packages under.
+# - INF                 Point to a .inf (in addition to a .dsc) in order to
+#                       build a single component (standalone driver/app).
+#
+
+[juno]
+LONGNAME=aarch64 Juno
+DSC=Platform/ARM/JunoPkg/ArmJuno.dsc
+BUILDFLAGS=
+ARCH=AARCH64
+BUILD_ATF=yes
+SCP_BIN=Platform/ARM/Juno/bl30.bin
+UEFI_BIN=BL33_AP_UEFI.fd
+UEFI_IMAGE_DIR=ArmJuno
+
+# ARM FVP BASE AEMv8-A model
+[fvp]
+LONGNAME=aarch64 FVP RTSM
+DSC=Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc
+BUILDFLAGS=-D EDK2_ENABLE_SMSC_91X=1 -D EDK2_ENABLE_PL111=1
+ARCH=AARCH64
+BUILD_ATF=yes
+UEFI_BIN=FVP_AARCH64_EFI.fd
+UEFI_IMAGE_DIR=ArmVExpress-FVP-AArch64
+
+[tc2]
+LONGNAME=Versatile Express TC2
+BUILDFLAGS=-D ARM_BIGLITTLE_TC2=1
+DSC=Platform/ARM/VExpressPkg/ArmVExpress-CTA15-A7.dsc
+ARCH=ARM
+
+[overdrive]
+LONGNAME=AMD Overdrive
+DSC=Platform/AMD/OverdriveBoard/OverdriveBoard.dsc
+ARCH=AARCH64
+
+[overdrive1000]
+LONGNAME=SoftIron Overdrive 1000
+DSC=Platform/SoftIron/Overdrive1000Board/Overdrive1000Board.dsc
+ARCH=AARCH64
+
+[cello]
+LONGNAME=LeMaker Cello
+DSC=Platform/LeMaker/CelloBoard/CelloBoard.dsc
+ARCH=AARCH64
+
+[hikey]
+LONGNAME=HiKey
+DSC=Platform/Hisilicon/HiKey/HiKey.dsc
+ARCH=AARCH64
+
+[d02]
+LONGNAME=Hisilicon D02
+DSC=Platform/Hisilicon/D02/Pv660D02.dsc
+ARCH=AARCH64
+
+[d03]
+LONGNAME=Hisilicon D03
+DSC=Platform/Hisilicon/D03/D03.dsc
+ARCH=AARCH64
+
+[d05]
+LONGNAME=HiSilicon D05
+DSC=Platform/Hisilicon/D05/D05.dsc
+ARCH=AARCH64
+
+[armada70x0]
+LONGNAME=Marvell Armada 70x0
+DSC=Platform/Marvell/Armada/Armada70x0.dsc
+ARCH=AARCH64
+
+[chaoskey]
+LONGNAME=Altus Metrum ChaosKey RNG
+DSC=Silicon/Openmoko/Openmoko.dsc
+ARCH=AARCH64
+
+[beagle]
+LONGNAME=Beagleboard (original)
+DSC=BeagleBoardPkg/BeagleBoardPkg.dsc
+ARCH=ARM
diff --git a/uefi-tools/edk2-to-git-am.sh b/uefi-tools/edk2-to-git-am.sh
new file mode 100755
index 0000000..d3f8a27
--- /dev/null
+++ b/uefi-tools/edk2-to-git-am.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# Convert one or more git patches that have had it's CR:s stripped out by SMTP
+# into something th
+
+if [ $# -lt 1 ]; then
+  echo "usage: `basename $0` <filename>" >&2
+  exit 1
+fi
+
+convert_file()
+{
+  sed -i "s/$/\r/g" "$1"
+  sed -i "s:^\(---\|+++ \)\(.*\)\r$:\1\2:g" "$1"
+}
+
+while [ $# -gt 0 ]; do
+  convert_file "$1"
+  shift
+done
diff --git a/uefi-tools/handy-snippets.sh b/uefi-tools/handy-snippets.sh
new file mode 100644
index 0000000..834ca74
--- /dev/null
+++ b/uefi-tools/handy-snippets.sh
@@ -0,0 +1,8 @@
+#
+# First step in looking for duplicate file GUIDs
+#
+# find . -name "*.inf" | \
+#   xargs grep -H FILE_GUID | \
+#   sed 's/^\(.*\):[ \t]*FILE_GUID[ \t]*=[ \t]*\([a-f.A-F.0-9.-]*\).*\r$/\2 \1/' | \
+#   sort
+#
diff --git a/uefi-tools/opteed-build.sh b/uefi-tools/opteed-build.sh
index 3c759eb..702860e 100755
--- a/uefi-tools/opteed-build.sh
+++ b/uefi-tools/opteed-build.sh
@@ -7,7 +7,6 @@
 # parse-platforms.py and platforms.config.
 #
 
-TOOLS_DIR="`dirname $0`"
 . "$TOOLS_DIR"/common-functions
 
 export CFG_TEE_CORE_LOG_LEVEL=2  # 0=none 1=err 2=info 3=debug 4=flow
@@ -100,10 +99,11 @@
 		#
 		# Copy resulting images to UEFI image dir
 		#
+		TOS_BIN="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o tos_bin`"
 		if [ $VERBOSE -eq 1 ]; then
-			echo "Copying tee.bin to "$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/""
+			echo "Copying '$TOS_BIN' to '$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/'"
 		fi
-		cp -a out/arm-plat-"$TOS_PLATFORM"/core/tee.bin "$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/"
+		cp -a out/arm-plat-"$TOS_PLATFORM"/core/"$TOS_BIN" "$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/"
 	else
 		return 1
 	fi
diff --git a/uefi-tools/parse-platforms.py b/uefi-tools/parse-platforms.py
index 5aa4283..af44038 100755
--- a/uefi-tools/parse-platforms.py
+++ b/uefi-tools/parse-platforms.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python
 
 import sys, os, argparse, ConfigParser
 
diff --git a/uefi-tools/platforms.config b/uefi-tools/platforms.config
index adaf6c0..deb02f4 100644
--- a/uefi-tools/platforms.config
+++ b/uefi-tools/platforms.config
@@ -46,6 +46,9 @@
 # - ATF_SPD		Name of Secure Payload Dispatcher
 #			To actually build the Trusted OS, you must also set
 #			TOS_BIN.
+# - SPM_BIN		Prebuilt Secure Partition image to pass to ARM Trusted Firmware.
+#			The path is relative to
+#			$EDK2_DIR/Build/StandaloneSmmPkg/$BUILD_PROFILE/FV/.
 #
 # Optional options:
 # - BUILDFLAGS		Any special flags you want to pass to the build command.
@@ -57,10 +60,8 @@
 # - PREBUILD_CMDS	Any commands you want to execute before the build step.
 # - POSTBUILD_CMDS	Any commands you want to execute after the build step.
 # - PACKAGES_PATH	Additional directories to search for packages under.
-#
-# Special options:
-# - BUILDCMD		Command to call instead of the normal build command.
-#			Only for pandaboard, not to be used for new ports.
+# - INF                 Point to a .inf (in addition to a .dsc) in order to
+#                       build a single component (standalone driver/app).
 #
 
 [juno]
@@ -92,6 +93,26 @@
 UEFI_BIN=FVP_AARCH64_EFI.fd
 UEFI_IMAGE_DIR=ArmVExpress-FVP-AArch64
 
+# ARM FVP BASE AEMv8-A model
+[fvp_mm_standalone]
+LONGNAME=FVP Base for MM Standalone image in secure world
+DSC=StandaloneSmmPkg/StandaloneSmmPkg.dsc
+ARCH=AARCH64
+UEFI_BIN=FVP_AARCH64_EFI_MM_STANDALONE.fd
+UEFI_IMAGE_DIR=ArmVExpress-FVP-AArch64-MM-Standalone
+
+[fvp_mm_normal]
+LONGNAME=FVP Base for UEFI image with MM support in normal world
+DSC=OpenPlatformPkg/Platforms/ARM/VExpress/ArmVExpress-FVP-AArch64.dsc
+BUILDFLAGS=-D EDK2_OUT_DIR=Build/ArmVExpress-FVP-AArch64-MM-Normal -D ARM_STANDALONE_MM_ENABLE=TRUE
+ARCH=AARCH64
+BUILD_ATF=debug
+UEFI_BIN=FVP_AARCH64_EFI.fd
+UEFI_IMAGE_DIR=ArmVExpress-FVP-AArch64-MM-Normal
+ATF_PLATFORM=fvp
+SPM_BIN=STANDALONESMM.fd
+ATF_BUILDFLAGS=ARM_BL31_IN_DRAM=1
+
 [tc2]
 LONGNAME=Versatile Express TC2
 BUILDFLAGS=-D ARM_BIGLITTLE_TC2=1
@@ -100,14 +121,6 @@
 UEFI_BIN=ARM_VEXPRESS_CTA15A7_EFI.fd
 UEFI_IMAGE_DIR=ArmVExpress-CTA15-A7
 
-[panda]
-LONGNAME=TI Pandaboard
-BUILDCMD=./PandaBoardPkg/build.sh
-BUILDFLAGS=
-ARCH=ARM
-UEFI_BIN=MLO
-UEFI_IMAGE_DIR=PandaBoard
-
 [beagle]
 LONGNAME=BeagleBoard
 BUILDFLAGS=
@@ -130,14 +143,6 @@
 UEFI_BIN=D01.fd
 UEFI_IMAGE_DIR=D01
 
-[bbb]
-LONGNAME=Texas Instruments BeagleBone Black
-BUILDFLAGS=
-DSC=TexasInstrumentsPkg/BeagleBoneBlackPkg/BeagleBoneBlackPkg.dsc
-ARCH=ARM
-UEFI_BIN=BEAGLEBONEBLACK_EFI.fd
-UEFI_IMAGE_DIR=BeagleBoneBlack
-
 [qemu]
 LONGNAME=QEMU ARM Emulator
 BUILDFLAGS=-D INTEL_BDS
@@ -171,6 +176,15 @@
 UEFI_BIN=STYX_ROM.fd
 UEFI_IMAGE_DIR=Overdrive
 
+[overdrive1000]
+LONGNAME=SoftIron Overdrive 1000
+BUILDFLAGS=-D INTEL_BDS
+DSC=OpenPlatformPkg/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc
+ARCH=AARCH64
+PACKAGES_PATH=OpenPlatformPkg/Platforms/AMD/Styx/Binary
+UEFI_BIN=OVERDRIVE1000_ROM.fd
+UEFI_IMAGE_DIR=Overdrive1000Board
+
 [cello]
 LONGNAME=LeMaker Cello
 BUILDFLAGS=-D INTEL_BDS
@@ -180,6 +194,9 @@
 UEFI_BIN=STYX_ROM.fd
 UEFI_IMAGE_DIR=Cello
 
+# NOTE: If using upstream ATF, i.e.
+# https://github.com/ARM-software/arm-trusted-firmware
+# please set TOS_BIN=tee-pager.bin
 [hikey]
 LONGNAME=CircuitCo HiKey
 DSC=OpenPlatformPkg/Platforms/Hisilicon/HiKey/HiKey.dsc
@@ -189,6 +206,7 @@
 BUILD_ATF=yes
 ATF_SPD=opteed
 TOS_BIN=tee.bin
+TOS_PLATFORM_FLAVOR=hikey
 BUILD_TOS=yes
 SCP_BIN=OpenPlatformPkg/Platforms/Hisilicon/HiKey/Binary/mcuimage.bin
 # Uncomment this to use UART0 as the EDK2 console
@@ -198,13 +216,29 @@
 # Uncomment this to use UART0 as the OP-TEE Trusted OS console
 #TOS_BUILDFLAGS=CFG_CONSOLE_UART=0
 
+[hikey960]
+LONGNAME=Hikey960
+DSC=OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960.dsc
+ARCH=AARCH64
+UEFI_BIN=BL33_AP_UEFI.fd
+UEFI_IMAGE_DIR=HiKey960
+BUILD_ATF=yes
+ATF_SPD=opteed
+TOS_BIN=tee-pager.bin
+TOS_PLATFORM=hikey
+TOS_PLATFORM_FLAVOR=hikey960
+BUILD_TOS=yes
+SCP_BIN=OpenPlatformPkg/Platforms/Hisilicon/HiKey960/Binary/lpm3.img
+# Uncomment this to use UART5 as the EDK2 console for v1 hardware
+#BUILDFLAGS=-DSERIAL_BASE=0xFDF05000
+
 [xen64]
 LONGNAME=AArch64 Xen guest
 BUILDFLAGS=
-DSC=ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc
+DSC=ArmVirtPkg/ArmVirtXen.dsc
 ARCH=AARCH64
 UEFI_BIN=XEN_EFI.fd
-UEFI_IMAGE_DIR=ArmVirtualizationXen-AARCH64
+UEFI_IMAGE_DIR=ArmVirtXen-AARCH64
 
 [aarch64-shell]
 LONGNAME=AArch64 EFI Shell
@@ -243,3 +277,30 @@
 ARCH=AARCH64
 UEFI_BIN=D03.fd
 UEFI_IMAGE_DIR=D03
+
+[d05]
+LONGNAME=HiSilicon D05
+DSC=OpenPlatformPkg/Platforms/Hisilicon/D05/D05.dsc
+ARCH=AARCH64
+UEFI_BIN=D05.fd
+UEFI_IMAGE_DIR=D05
+
+[armada70x0]
+LONGNAME=Marvell Armada 70x0
+DSC=OpenPlatformPkg/Platforms/Marvell/Armada/Armada70x0.dsc
+ARCH=AARCH64
+
+[ovmfx64]
+LONGNAME=OVMF Qemu X64
+DSC=OvmfPkg/OvmfPkgX64.dsc
+ARCH=X64
+
+[hello]
+LONGNAME=EDK2 Hello World Example
+DSC=MdeModulePkg/MdeModulePkg.dsc
+INF=MdeModulePkg/Application/HelloWorld/HelloWorld.inf
+
+[chaoskey]
+LONGNAME=Altus Metrum ChaosKey Driver
+DSC=OptionRomPkg/OptionRomPkg.dsc
+INF=OpenPlatformPkg/Drivers/Usb/Misc/ChaosKeyDxe/ChaosKeyDxe.inf
diff --git a/uefi-tools/tos-build.sh b/uefi-tools/tos-build.sh
index 9dc4b2d..a3bf421 100755
--- a/uefi-tools/tos-build.sh
+++ b/uefi-tools/tos-build.sh
@@ -8,7 +8,6 @@
 # parse-platforms.py and platforms.config.
 #
 
-TOOLS_DIR="`dirname $0`"
 . "$TOOLS_DIR"/common-functions
 
 function usage
diff --git a/uefi-tools/uefi-build.sh b/uefi-tools/uefi-build.sh
index 0fa50ed..7fec3d0 100755
--- a/uefi-tools/uefi-build.sh
+++ b/uefi-tools/uefi-build.sh
@@ -12,6 +12,7 @@
 unset WORKSPACE EDK_TOOLS_DIR MAKEFLAGS
 
 TOOLS_DIR="`dirname $0`"
+export TOOLS_DIR
 . "$TOOLS_DIR"/common-functions
 PLATFORM_CONFIG=""
 VERBOSE=0
@@ -23,7 +24,7 @@
 # Number of threads to use for build
 export NUM_THREADS=$((`getconf _NPROCESSORS_ONLN` + 1))
 
-function build_platform
+function do_build
 {
 	PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname`"
 	PLATFORM_PREBUILD_CMDS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o prebuild_cmds`"
@@ -31,9 +32,23 @@
 	PLATFORM_BUILDFLAGS="$PLATFORM_BUILDFLAGS ${EXTRA_OPTIONS[@]}"
 	PLATFORM_BUILDCMD="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildcmd`"
 	PLATFORM_DSC="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o dsc`"
-	PLATFORM_ARCH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o arch`"
 	PLATFORM_PACKAGES_PATH="$PWD"
+	COMPONENT_INF="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o inf`"
 
+	PLATFORM_ARCH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o arch`"
+	if [ -n "$PLATFORM_ARCH" ]; then
+		if [ -n "$DEFAULT_PLATFORM_ARCH" -a "$DEFAULT_PLATFORM_ARCH" != "$PLATFORM_ARCH" ]; then
+			echo "Command line specified architecture '$DEFAULT_PLATFORM_ARCH'" >&2
+			echo "differs from config file specified '$PLATFORM_ARCH'" >&2
+			return 1
+		fi
+	else
+		if [ ! -n "$DEFAULT_PLATFORM_ARCH" ]; then
+			echo "Unknown target architecture - aborting!" >&2
+			return 1
+		fi
+		PLATFORM_ARCH="$DEFAULT_PLATFORM_ARCH"
+	fi
 	TEMP_PACKAGES_PATH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o packages_path`"
 	if [ -n "$TEMP_PACKAGES_PATH" ]; then
 		IFS=:
@@ -60,7 +75,18 @@
 		echo "PLATFORM_PACKAGES_PATH=$PLATFORM_PACKAGES_PATH"
 	fi
 
-	set_cross_compile
+	if [[ "${PLATFORM_BUILDFLAGS}" =~ "SECURE_BOOT_ENABLE=TRUE" ]]; then
+	    import_openssl
+	fi
+
+	if [ -n "$CROSS_COMPILE_64" -a "$PLATFORM_ARCH" == "AARCH64" ]; then
+		TEMP_CROSS_COMPILE="$CROSS_COMPILE_64"
+	elif [ -n "$CROSS_COMPILE_32" -a "$PLATFORM_ARCH" == "ARM" ]; then
+		TEMP_CROSS_COMPILE="$CROSS_COMPILE_32"
+	else
+		set_cross_compile
+	fi
+
 	CROSS_COMPILE="$TEMP_CROSS_COMPILE"
 
 	echo "Building $PLATFORM_NAME - $PLATFORM_ARCH"
@@ -73,12 +99,20 @@
 
 	case $TOOLCHAIN in
 		"gcc")
-			export TOOLCHAIN=`get_gcc_version "$CROSS_COMPILE"gcc`
+			TOOLCHAIN=`get_gcc_version "$CROSS_COMPILE"gcc`
+			if [ $? -ne 0 ]; then
+				echo "${CROSS_COMPILE}gcc not found!" >&2
+				return 1
+			fi
 			;;
 		"clang")
-			export TOOLCHAIN=`get_clang_version clang`
+			TOOLCHAIN=`get_clang_version clang`
+			if [ $? -ne 0 ]; then
+				return 1
+			fi
 			;;
 	esac
+	export TOOLCHAIN
 	echo "TOOLCHAIN is ${TOOLCHAIN}"
 
 	export ${TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE
@@ -90,14 +124,17 @@
 			echo "Run pre build commands"
 			eval ${PLATFORM_PREBUILD_CMDS}
 		fi
-		if [ X"$PLATFORM_BUILDCMD" == X"" ]; then
-			echo  ${TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${TOOLCHAIN} -p "$PLATFORM_DSC" -b "$target" \
-				${PLATFORM_BUILDFLAGS}
-			build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${TOOLCHAIN} -p "$PLATFORM_DSC" -b "$target" \
-				${PLATFORM_BUILDFLAGS}
+
+		if [ -n "$COMPONENT_INF" ]; then
+			# Build a standalone component
+			build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${TOOLCHAIN} -p "$PLATFORM_DSC" \
+				-m "$COMPONENT_INF" -b "$target" ${PLATFORM_BUILDFLAGS}
 		else
-			${PLATFORM_BUILDCMD} -b "$target" ${PLATFORM_BUILDFLAGS}
+			# Build a platform
+			build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${TOOLCHAIN} -p "$PLATFORM_DSC" \
+				-b "$target" ${PLATFORM_BUILDFLAGS}
 		fi
+
 		RESULT=$?
 		if [ $RESULT -eq 0 ]; then
 			if [ X"$TOS_DIR" != X"" ]; then
@@ -127,6 +164,31 @@
 }
 
 
+function clearcache
+{
+  CONF_FILES="build_rule target tools_def"
+  if [ -z "$EDK_TOOLS_PATH" ]
+  then
+    TEMPLATE_PATH=./BaseTools/Conf/
+  else
+    TEMPLATE_PATH="$EDK_TOOLS_PATH/Conf/"
+  fi
+
+  for File in $CONF_FILES
+  do
+    TEMPLATE_FILE="$TEMPLATE_PATH/$File.template"
+    CACHE_FILE="Conf/$File.txt"
+    if [ -e "$CACHE_FILE" -a "$TEMPLATE_FILE" -nt "$CACHE_FILE" ]
+    then
+      echo "Removing outdated '$CACHE_FILE'."
+      rm "$CACHE_FILE"
+    fi
+  done
+
+  unset TEMPLATE_PATH TEMPLATE_FILE CACHE_FILE
+}
+
+
 function uefishell
 {
 	BUILD_ARCH=`uname -m`
@@ -142,11 +204,12 @@
 			;;
 	esac
 	export ARCH
+	export EDK_TOOLS_PATH=`pwd`/BaseTools
+	clearcache
+	. edksetup.sh BaseTools
 	if [ $VERBOSE -eq 1 ]; then
 		echo "Building BaseTools"
 	fi
-	export EDK_TOOLS_PATH=`pwd`/BaseTools
-	. edksetup.sh BaseTools
 	make -C $EDK_TOOLS_PATH
 	if [ $? -ne 0 ]; then
 		echo " !!! UEFI BaseTools failed to build !!! " >&2
@@ -187,7 +250,7 @@
 		fi
 		case "$FILE_ARG" in
 			/*)
-				PLATFORM_CONFIG="-c \"$FILE_ARG\""
+				PLATFORM_CONFIG="-c $FILE_ARG"
 			;;
 			*)
 				PLATFORM_CONFIG="-c `readlink -f \"$FILE_ARG\"`"
@@ -225,6 +288,10 @@
 			shift
 			ATF_DIR="$1"
 			;;
+		"-A" )
+			shift
+			DEFAULT_PLATFORM_ARCH="$1"
+			;;
 		"-c" )
 			# Already parsed above - skip this + option
 			shift
@@ -325,7 +392,7 @@
 fi
 
 for board in "${builds[@]}" ; do
-	build_platform
+	do_build
 done
 
 result_print