Add openPOWER version string support

See VERSION.readme for more info
diff --git a/.gitignore b/.gitignore
index 1377554..7fce548 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 *.swp
+customrc
diff --git a/op-build-env b/op-build-env
index 79299c8..9f2bfd2 100755
--- a/op-build-env
+++ b/op-build-env
@@ -1,6 +1,10 @@
 #!/bin/bash
 __PWD=`pwd`
 
+if [ -e ./customrc ]; then
+    source ./customrc
+fi
+
 export BR2_EXTERNAL=${__PWD}/openpower
 export BR2_DL_DIR=${__PWD}/dl
 
diff --git a/openpower/external.mk b/openpower/external.mk
index be628ba..8d7b578 100644
--- a/openpower/external.mk
+++ b/openpower/external.mk
@@ -1,5 +1,6 @@
+include $(sort $(wildcard $(BR2_EXTERNAL)/package/*.mk))
 include $(sort $(wildcard $(BR2_EXTERNAL)/package/*/*.mk))
 
 # Utilize user-defined custom directory.
 include $(sort $(wildcard $(BR2_EXTERNAL)/custom/*.mk))
-BR2_GLOBAL_PATCH_DIR += " $(BR2_EXTERNAL)/custom/patches "
+BR2_GLOBAL_PATCH_DIR += "$(BR2_EXTERNAL)/custom/patches"
diff --git a/openpower/package/VERSION.readme b/openpower/package/VERSION.readme
new file mode 100644
index 0000000..59fec86
--- /dev/null
+++ b/openpower/package/VERSION.readme
@@ -0,0 +1,119 @@
+#### Version String Readme ####
+
+    ## Customrc ##
+
+    Create a file at the top level of op-build called 'customrc'
+    to specify custom $(OPBUILD_VENDOR), $(OPBUILD_PLATFORM), and $(OPBUILD_VERSION).
+
+    Example:
+    #!/bin/sh
+    #export OPBUILD_VENDOR=IBM
+    #export OPBUILD_PLATFORM=plat-ibm
+    #export OPBUILD_VERSION=v-1.0.1
+
+    ## Op-build Commands ##
+
+    # Display package version
+    op-build $(package)-version
+
+    # Force a rebuild of a package version
+    op-build $(package)-build-version
+
+    ##  Version String (ASCII) ##
+
+    General:
+    $(op-build)\n
+    \t$(subpackage0)\n
+    \t$(subpackage1)\n
+    \0
+
+    ## Version String Details ##
+
+    $(op-build):
+    - Clean
+        + $(vendor)-$(platform)-$(op-version)
+    - Dirty.
+        + $(vendor)-$(platform)-$(gitcommit+dirty)
+    $(sub-package):
+    - Directly upstream, no patches, op-build clean.
+        + $(package)-$(version)
+    - Directly upstream, no patches, op-build dirty.
+        + $(package)-$(version)-$(op-dirty)
+    - Directly upstream, op-build patches, op-build clean
+        + $(package)-$(version)-$(patch-level)
+    - Directly upstream, op-build patches, op-build dirty.
+        + $(package)-$(version)-$(op-dirty)-$(patch-level)
+    - SITE=local
+        + $(package)-site_local-$(user)-$(gitcommit+dirty)
+
+    ## Variable Details ##
+
+    - $(vendor) = $(OPBUILD_VENDOR) or 'open-power'.
+    - $(platform) = $(OPBUILD_PLATFORM) or defconfig
+        + Order $(OPBUILD_PLATFORM), defconfig
+    - $(op-version) = git tag or first 7 characters of commit or $(OPBUILD_VERSION) or 'unknown'.
+        + Order $(OPBUILD_VERSION), tag, commit, unknown
+    - **$(gitcommit+dirty) = abcd123 or abcd123-dirty or 'unknown'
+    - $(version) = git tag or first 7 characters of commit
+    - $(user) = `whoami`
+    - **$(op-dirty) = opdirty or 'unknown'
+    - $(patch-level) = $(first 7 characters of 'sha512sum *.patch | sha512sum')
+        + the output of this gives us a quick way to check all the patches with one string
+
+    ** Indicates possible unknown case when source downloaded versus git clone due to git commands required
+
+    ## Sub Packages ##
+
+    Current sub packages included in openpower-pnor.mk $(OPENPOWER_VERSIONED_SUBPACKAGES)
+
+    - hostboot
+    - occ
+    - skiboot
+    - $(platform)-xml
+    - hostboot-binaries
+    - capp-ucode
+
+    ## PNOR section ##
+
+    - There is one version PNOR section per side
+    - Each is one page w/o ECC so 4K
+    - The data in the section will just be ASCII
+
+    ## Op-build Command Examples ##
+
+    cmd> op-build openpower-pnor-version
+    === OPENPOWER_PNOR_VERSION ===
+    IBM-plat-ibm-v-1.2.3-dirty
+        hostboot-3593853-99cca2b
+        occ-cc8376d
+        skiboot-9a3f68b-7c66ab4
+        hostboot-binaries-e3c9356
+        habanero-xml-4c1e936
+        capp-ucode-d4b2683
+
+    cmd> op-build hostboot-version
+    === HOSTBOOT_VERSION ===
+        hostboot-3593853-opdirty-99cca2b
+
+    If a version does not already exist, the commands to make one will be run.
+    Additionally you can force with op-build $(package)-build-version
+
+    cmd> op-build hostboot-version (or op-build hostboot-build-version)
+    === HOSTBOOT_VERSION ===
+            Searching for patches...
+    op-build/openpower/package/hostboot/hostboot-0001-Increase-uart-delay.patch
+    op-build/openpower/package/hostboot/hostboot-0002-Disable-centaur-memory-throttle.patch
+    op-build/openpower/package/hostboot/hostboot-0003-GCC-4.9-Make-compiler-use-ELFv1-ABI-and-use-O2.patch
+    op-build/openpower/package/hostboot/hostboot-0004-Revert-SW294127-INITPROC-FSP-Hostboot-fast-exit-powe.patch
+    op-build/openpower/package/hostboot/hostboot-0005-Disable-SPD-writes-workaround-for-DRAM-repairs-error.patch
+    op-build/openpower/package/hostboot/hostboot-0006-Runtime-fixes-for-IPMI.patch
+    op-build/openpower/package/hostboot/hostboot-0007-Update-DIMM_TEMP-Sensor-Enum.patch
+    op-build/openpower/package/hostboot/hostboot-0008-mss-thermal-init-SW297647.patch
+    op-build/openpower/package/hostboot/hostboot-0009-Sel-instead-of-eSel.patch
+    op-build/openpower/package/hostboot/hostboot-0010-Reset-occ-when-fails-to-activate.patch
+    op-build/openpower/package/hostboot/hostboot-0011-eRepair-MBVPD-size-check-for-CDIMM-and-ISDIMM.patch
+            End of patches...
+            Creating version string (various output may display)...
+    heads/pnor_version-dirty
+            End creating version string...
+            version: hostboot-3593853-99cca2b
diff --git a/openpower/package/hostboot/hostboot.mk b/openpower/package/hostboot/hostboot.mk
index d3b76fa..e388305 100644
--- a/openpower/package/hostboot/hostboot.mk
+++ b/openpower/package/hostboot/hostboot.mk
@@ -15,7 +15,8 @@
 
 HOSTBOOT_ENV_VARS=$(TARGET_MAKE_ENV) \
     CONFIG_FILE=$(BR2_EXTERNAL)/configs/hostboot/$(BR2_HOSTBOOT_CONFIG_FILE) \
-    OPENPOWER_BUILD=1 CROSS_PREFIX=$(TARGET_CROSS) HOST_PREFIX="" HOST_BINUTILS_DIR=$(HOST_BINUTILS_DIR)
+    OPENPOWER_BUILD=1 CROSS_PREFIX=$(TARGET_CROSS) HOST_PREFIX="" HOST_BINUTILS_DIR=$(HOST_BINUTILS_DIR) \
+    HOSTBOOT_VERSION=`cat $(HOSTBOOT_VERSION_FILE)`
 
 define HOSTBOOT_BUILD_CMDS
         $(HOSTBOOT_ENV_VARS) bash -c 'cd $(@D) && source ./env.bash && $(MAKE)'
diff --git a/openpower/package/openpower-pnor/openpower-pnor.mk b/openpower/package/openpower-pnor/openpower-pnor.mk
index 8854207..3639e9c 100644
--- a/openpower/package/openpower-pnor/openpower-pnor.mk
+++ b/openpower/package/openpower-pnor/openpower-pnor.mk
@@ -30,6 +30,11 @@
 HOSTBOOT_IMAGE_DIR=$(STAGING_DIR)/hostboot_build_images/
 HOSTBOOT_BINARY_DIR = $(STAGING_DIR)/hostboot_binaries/
 OPENPOWER_PNOR_SCRATCH_DIR = $(STAGING_DIR)/openpower_pnor_scratch/
+OPENPOWER_VERSION_DIR = $(STAGING_DIR)/openpower_version
+
+# Subpackages we want to include in the version info (do not include openpower-pnor)
+OPENPOWER_VERSIONED_SUBPACKAGES = hostboot occ skiboot hostboot-binaries $(XML_PACKAGE) capp-ucode
+OPENPOWER_PNOR = openpower-pnor
 
 define OPENPOWER_PNOR_INSTALL_IMAGES_CMDS
         mkdir -p $(OPENPOWER_PNOR_SCRATCH_DIR)
@@ -44,7 +49,8 @@
             -sbe_binary_filename $(BR2_HOSTBOOT_BINARY_SBE_FILENAME) \
             -sbec_binary_filename $(BR2_HOSTBOOT_BINARY_SBEC_FILENAME) \
             -occ_binary_filename $(OCC_STAGING_DIR)/$(BR2_OCC_BIN_FILENAME) \
-            -capp_binary_filename $(BINARIES_DIR)/$(BR2_CAPP_UCODE_BIN_FILENAME)
+            -capp_binary_filename $(BINARIES_DIR)/$(BR2_CAPP_UCODE_BIN_FILENAME) \
+            -openpower_version_filename $(OPENPOWER_PNOR_VERSION_FILE)
 
         mkdir -p $(STAGING_DIR)/pnor/
         $(TARGET_MAKE_ENV) $(@D)/create_pnor_image.pl \
@@ -58,9 +64,12 @@
             -sbe_binary_filename $(BR2_HOSTBOOT_BINARY_SBE_FILENAME) \
             -sbec_binary_filename $(BR2_HOSTBOOT_BINARY_SBEC_FILENAME) \
             -occ_binary_filename $(OCC_STAGING_DIR)/$(BR2_OCC_BIN_FILENAME) \
-            -targeting_binary_filename $(BR2_OPENPOWER_TARGETING_ECC_FILENAME)
+            -targeting_binary_filename $(BR2_OPENPOWER_TARGETING_ECC_FILENAME) \
+            -openpower_version_filename $(OPENPOWER_PNOR_VERSION_FILE)
 
         $(INSTALL) $(STAGING_DIR)/pnor/$(BR2_OPENPOWER_PNOR_FILENAME) $(BINARIES_DIR)
 endef
 
 $(eval $(generic-package))
+# Generate openPOWER pnor version string by combining subpackage version string files
+$(eval $(call OPENPOWER_VERSION,$(OPENPOWER_PNOR)))
diff --git a/openpower/package/pkg-versions.mk b/openpower/package/pkg-versions.mk
new file mode 100644
index 0000000..3ac8c9f
--- /dev/null
+++ b/openpower/package/pkg-versions.mk
@@ -0,0 +1,195 @@
+################################################################################
+#
+# pkg-versions
+#
+# Read VERSION.readme in the current directory to learn about the version
+# string structure
+#
+################################################################################
+
+define OPENPOWER_SUBPACKAGE_VERSION
+
+$(2)_VERSION_FILE = $$(OPENPOWER_VERSION_DIR)/$(1).version.txt
+ALL_SUBPACKAGE_VERSIONS += $$($(2)_VERSION_FILE)
+
+### Create subpackage patch file
+define $(2)_OPENPOWER_PATCH_FILE
+
+mkdir -p "$$(OPENPOWER_VERSION_DIR)";
+
+# Remove patch file to start off fresh
+if [ -f $$(OPENPOWER_VERSION_DIR)/$(1).patch.txt ]; then \
+		rm -rf $$(OPENPOWER_VERSION_DIR)/$(1).patch.txt; \
+fi
+
+# Check all global patch directories
+$$(foreach path, $$(BR2_GLOBAL_PATCH_DIR),if ls $$(path)/$(1)/*.patch 2>/dev/null; then \
+		sha512sum $$(path)/$(1)/*.patch | sha512sum | \
+		xargs echo >> $$(OPENPOWER_VERSION_DIR)/$(1).tmp_patch.txt; fi;)
+
+# Check the package patch dir, $$(PKGDIR) doesn't exist when running the version rules
+if [ -n "$$(PKGDIR)" ]; then \
+	if ls $$(PKGDIR)*.patch 2>/dev/null; then sha512sum $$(PKGDIR)*.patch | sha512sum | \
+		xargs echo >> $$(OPENPOWER_VERSION_DIR)/$(1).tmp_patch.txt; \
+	fi; \
+else \
+	if ls $$(BR2_EXTERNAL)/package/$(1)/*.patch 2>/dev/null; then sha512sum \
+		$$(BR2_EXTERNAL)/package/$(1)/*.patch | sha512sum | \
+		xargs echo >> $$(OPENPOWER_VERSION_DIR)/$(1).tmp_patch.txt; \
+	fi; \
+fi
+
+# Combine all the patches found in the package and global package directories
+if [ -f $$(OPENPOWER_VERSION_DIR)/$(1).tmp_patch.txt ]; then \
+		cat $$(OPENPOWER_VERSION_DIR)/$(1).tmp_patch.txt | sha512sum | cut -c 1-7 | \
+		xargs echo -n > $$(OPENPOWER_VERSION_DIR)/$(1).patch.txt; \
+fi
+
+# Remove the tmp_patch file
+if [ -f $$(OPENPOWER_VERSION_DIR)/$(1).tmp_patch.txt ]; then \
+	rm -rf $$(OPENPOWER_VERSION_DIR)/$(1).tmp_patch.txt; \
+fi
+
+endef ###
+
+### Create subpackage version file
+define $(2)_OPENPOWER_VERSION_FILE
+
+mkdir -p "$$(OPENPOWER_VERSION_DIR)"
+
+# Add package name
+echo -n "	$(1)-" > $$($(2)_VERSION_FILE)
+
+# If site local
+# Add site local and user, local commit, if local is dirty
+# Else not local
+# Add package version, op-build is dirty, op-build patches
+if [ "$$($(2)_SITE_METHOD)" == "local" ]; then \
+echo -n "site_local-" >> $$($(2)_VERSION_FILE); \
+whoami | xargs echo -n >> $$($(2)_VERSION_FILE); \
+echo -n "-" >> $$($(2)_VERSION_FILE); \
+\
+cd "$$($(2)_SITE)"; (git describe --tags || git log -n1 --pretty=format:'%h' || echo "unknown") \
+	| sed 's/\(.*\)-g\([0-9a-f]\{7\}\).*/\2/' | xargs echo -n \
+	>> $$($(2)_VERSION_FILE); \
+\
+cd "$$($(2)_SITE)"; git describe --all --dirty | grep -e "-dirty" | sed 's/.*\(-dirty\)/\1/' | \
+	xargs echo -n >> $$($(2)_VERSION_FILE); \
+else \
+\
+[ `echo -n $$($(2)_VERSION) | wc -c` == "40" ] && (echo -n $$($(2)_VERSION) | \
+	sed "s/^\([0-9a-f]\{7\}\).*/\1/" >> $$($(2)_VERSION_FILE)) \
+	|| echo -n $$($(2)_VERSION) >> $$($(2)_VERSION_FILE); \
+\
+cd "$$(BR2_EXTERNAL)"; git describe --all --dirty | \
+	if grep -e "-dirty"; then \
+	echo -n "-opdirty" >> $$($(2)_VERSION_FILE); \
+	fi; \
+\
+if [ -f $$(OPENPOWER_VERSION_DIR)/$(1).patch.txt ]; then \
+	echo -n "-" >> $$($(2)_VERSION_FILE); \
+	cat $$(OPENPOWER_VERSION_DIR)/$(1).patch.txt >> $$($(2)_VERSION_FILE); fi \
+fi
+
+# Add new line to version.txt
+echo "" >> $$($(2)_VERSION_FILE);
+
+endef ###
+
+# Add appropriate templates to hooks
+$(2)_POST_PATCH_HOOKS += $(2)_OPENPOWER_PATCH_FILE
+$(2)_PRE_BUILD_HOOKS += $(2)_OPENPOWER_VERSION_FILE
+
+# Top-level rule to print or generate a subpackage version
+$(1)-version: $$(if $$(wildcard $$($(2)_VERSION_FILE)),$(1)-print-version,$(1)-build-version)
+
+# Rule to print out subpackage version
+$(1)-print-version:
+		@echo "=== $(2)_VERSION ==="
+		@cat $$($(2)_VERSION_FILE) | xargs echo
+
+# Rule to generate subpackage version
+$(1)-build-version:
+		@echo "=== $(2)_VERSION ==="
+		@echo "	Searching for patches..."
+		@$$($(2)_OPENPOWER_PATCH_FILE)
+		@echo "	End of patches...";
+		@echo "	Creating version string (various output may display)..."
+		@$$($(2)_OPENPOWER_VERSION_FILE)
+		@echo "	End creating version string..."
+		@echo -n "	version: "; cat $$($(2)_VERSION_FILE) | xargs echo
+
+endef
+
+define OPENPOWER_VERSION
+
+UPPER_CASE_PKG = $(call UPPERCASE,$(1))
+$$(UPPER_CASE_PKG)_VERSION_FILE = $$(OPENPOWER_VERSION_DIR)/$(1).version.txt
+
+
+$$(eval $$(foreach pkg,$$(OPENPOWER_VERSIONED_SUBPACKAGES), \
+		$$(call OPENPOWER_SUBPACKAGE_VERSION,$$(pkg),$$(call UPPERCASE,$$(pkg)))))
+
+### Combine subpackage files into one version file
+define $$(UPPER_CASE_PKG)_OPENPOWER_VERSION_FILE
+
+mkdir -p "$$(OPENPOWER_VERSION_DIR)"
+
+# Add vendor or default open-power
+if [ "$$(OPBUILD_VENDOR)" != '' ]; then \
+echo -n "$$(OPBUILD_VENDOR)-" > $$($$(UPPER_CASE_PKG)_VERSION_FILE); \
+else \
+echo -n "open-power-" > $$($$(UPPER_CASE_PKG)_VERSION_FILE); \
+fi
+
+# Add platform or default from defconfig
+if [ "$$(OPBUILD_PLATFORM)" != '' ]; then \
+echo -n "$$(OPBUILD_PLATFORM)-" >> $$($$(UPPER_CASE_PKG)_VERSION_FILE); \
+else \
+echo -n "$$(BR2_OPENPOWER_CONFIG_NAME)-" >> $$($$(UPPER_CASE_PKG)_VERSION_FILE); \
+fi
+
+# Add op-build version
+# Order: OPBUILD_VERSION, tag, commit, unknown
+if [ "$$(OPBUILD_VERSION)" != '' ]; then \
+	echo -n "$$(OPBUILD_VERSION)" >> $$($$(UPPER_CASE_PKG)_VERSION_FILE); \
+else \
+cd "$$(BR2_EXTERNAL)"; (git describe --tags || git log -n1 --pretty=format:'%h' || echo "unknown") \
+	| sed 's/\(.*\)-g\([0-9a-f]\{7\}\).*/\2/' | xargs echo -n \
+	>> $$($$(UPPER_CASE_PKG)_VERSION_FILE); \
+fi
+
+# Check if op-build is dirty
+cd "$$(BR2_EXTERNAL)"; git describe --all --dirty | grep -e "-dirty" | sed 's/.*\(-dirty\)/\1/' | \
+	xargs echo -n >> $$($$(UPPER_CASE_PKG)_VERSION_FILE);
+
+# Add new line to $$($$(UPPER_CASE_PKG)_VERSION_FILE)
+echo "" >> $$($$(UPPER_CASE_PKG)_VERSION_FILE);
+
+# Combing subpackage version files into $$($$(UPPER_CASE_PKG)_VERSION_FILE)
+$$(foreach verFile,$$(ALL_SUBPACKAGE_VERSIONS),
+	if [ -f $$(verFile) ]; then cat $$(verFile) \
+	>> $$($$(UPPER_CASE_PKG)_VERSION_FILE); fi )
+
+endef ###
+
+$$(UPPER_CASE_PKG)_PRE_BUILD_HOOKS += $$(UPPER_CASE_PKG)_OPENPOWER_VERSION_FILE
+
+# Top-level rule to print or generate openpower-pnor version
+$(1)-version: $$(if $$(wildcard $$($$(UPPER_CASE_PKG)_VERSION_FILE)),$(1)-print-version,$(1)-build-version)
+
+# Rule to print out pnor version
+$(1)-print-version:
+		@echo "=== $$(UPPER_CASE_PKG)_VERSION ==="
+		@cat $$($$(UPPER_CASE_PKG)_VERSION_FILE)
+		@echo ""; echo "**See openpower/package/VERSION.readme for detailed info on package strings"; echo ""
+
+
+# Rule to generate pnor version
+$(1)-build-version: $$(foreach pkg,$$(OPENPOWER_VERSIONED_SUBPACKAGES), $$(pkg)-version)
+		@$$($$(UPPER_CASE_PKG)_OPENPOWER_VERSION_FILE)
+		@echo "=== $$(UPPER_CASE_PKG)_VERSION ==="
+		@cat $$($$(UPPER_CASE_PKG)_VERSION_FILE)
+		@echo ""; echo "**See openpower/package/VERSION.readme for detailed info on package strings"; echo ""
+
+endef