Merge pull request #78 from jeenuv:tf-issues-148
diff --git a/Makefile b/Makefile
index 511a64a..8ec8472 100644
--- a/Makefile
+++ b/Makefile
@@ -28,13 +28,26 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-# Decrease the verbosity of the make script
-# can be made verbose by passing V=1 at the make command line
-ifdef V
-  KBUILD_VERBOSE = ${V}
-else
-  KBUILD_VERBOSE = 0
-endif
+#
+# 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
+
 
 # Checkpatch ignores
 CHECK_IGNORE		=	--ignore COMPLEX_MACRO
@@ -42,17 +55,14 @@
 CHECKPATCH_ARGS		=	--no-tree --no-signoff ${CHECK_IGNORE}
 CHECKCODE_ARGS		=	--no-patch --no-tree --no-signoff ${CHECK_IGNORE}
 
-ifeq "${KBUILD_VERBOSE}" "0"
+ifeq (${V},0)
 	Q=@
 	CHECKCODE_ARGS	+=	--no-summary --terse
 else
 	Q=
 endif
-
 export Q
 
-DEBUG	?= 0
-
 ifneq (${DEBUG}, 0)
 	BUILD_TYPE	:=	debug
 else
@@ -69,14 +79,6 @@
 				lib/io_storage.c			\
 				plat/common/aarch64/platform_helpers.S
 
-ARCH 			?=	aarch64
-
-# By default, build fvp platform
-DEFAULT_PLAT		:=	fvp
-PLAT			?=	${DEFAULT_PLAT}
-# By default, build no SPD component
-SPD			?=	none
-
 BUILD_BASE		:=	./build
 BUILD_PLAT		:=	${BUILD_BASE}/${PLAT}/${BUILD_TYPE}
 
@@ -84,6 +86,19 @@
 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
@@ -132,7 +147,6 @@
 .PHONY:			all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool fip
 .SUFFIXES:
 
-
 INCLUDES		+=	-Iinclude/bl1			\
 				-Iinclude/bl2			\
 				-Iinclude/bl31			\
@@ -150,28 +164,32 @@
 				${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))
+
 ASFLAGS			+= 	-nostdinc -ffreestanding -Wa,--fatal-warnings	\
-				-mgeneral-regs-only -D__ASSEMBLY__ ${INCLUDES}	\
-				-DDEBUG=${DEBUG}
-CFLAGS			:= 	-nostdinc -pedantic -ffreestanding -Wall	\
+				-mgeneral-regs-only -D__ASSEMBLY__		\
+				${DEFINES} ${INCLUDES}
+CFLAGS			+= 	-nostdinc -pedantic -ffreestanding -Wall	\
 				-Werror -mgeneral-regs-only -std=c99 -c -Os	\
-				-DDEBUG=${DEBUG} ${INCLUDES} ${CFLAGS}
+				${DEFINES} ${INCLUDES}
 CFLAGS			+=	-ffunction-sections -fdata-sections
 
 LDFLAGS			+=	--fatal-warnings -O1
 LDFLAGS			+=	--gc-sections
 
 
-ifneq (${DEBUG}, 0)
-#CFLAGS			+= 	-g -O0
-CFLAGS			+= 	-g
-# -save-temps -fverbose-asm
-ASFLAGS			+= 	-g -Wa,--gdwarf-2
-else
-CFLAGS			+=	-DNDEBUG=1
-endif
-
-
 CC			:=	${CROSS_COMPILE}gcc
 CPP			:=	${CROSS_COMPILE}cpp
 AS			:=	${CROSS_COMPILE}gcc
@@ -182,8 +200,6 @@
 NM			:=	${CROSS_COMPILE}nm
 PP			:=	${CROSS_COMPILE}gcc -E ${CFLAGS}
 
-BASE_COMMIT		?=	origin/master
-
 # Variables for use with Firmware Image Package
 FIPTOOLPATH		?=	tools/fip_create
 FIPTOOL			?=	${FIPTOOLPATH}/fip_create
diff --git a/bl31/aarch64/context.S b/bl31/aarch64/context.S
index 45d4a22..d0bca64 100644
--- a/bl31/aarch64/context.S
+++ b/bl31/aarch64/context.S
@@ -172,6 +172,8 @@
 	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]
@@ -181,8 +183,11 @@
 	stp	x12, x13, [x0, #CTX_CNTV_CTL_EL0]
 
 	mrs	x14, cntkctl_el1
+	str	x14, [x0, #CTX_CNTKCTL_EL1]
+#endif
+
 	mrs	x15, fpexc32_el2
-	stp	x14, x15, [x0, #CTX_CNTKCTL_EL1]
+	str	x15, [x0, #CTX_FP_FPEXC32_EL2]
 
 	ret
 
@@ -253,6 +258,8 @@
 	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
@@ -261,8 +268,11 @@
 	msr	cntv_ctl_el0, x12
 	msr	cntv_cval_el0, x13
 
-	ldp	x14, x15, [x0, #CTX_CNTKCTL_EL1]
+	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 */
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 1bb0fe9..e7f0df5 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -83,6 +83,9 @@
         BL33=<path-to>/<bl33_image>                               \
         make PLAT=fvp all fip
 
+    See the "Summary of build options" for information on available build
+    options.
+
     By default this produces a release version of the build. To produce a debug
     version instead, refer to the "Debugging options" section below. UEFI can be
     used as the BL3-3 image, refer to the "Obtaining the normal world software"
@@ -120,6 +123,39 @@
 
         make realclean
 
+### 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.
+
+*   `BL33`: Path to BL33 image in the host file system. This is mandatory for
+    `fip` target
+
+*   `CROSS_COMPILE`: Prefix to tool chain 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
+
+*   `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 could 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
+    SPD source; the directory is expected to contain `spd.mk` makefile
+
+*   `V`: Verbose build. If assigned anything other than 0, the build commands
+    are printed. Default is 0
 
 ### Creating a Firmware Image Package
 
diff --git a/include/bl31/context.h b/include/bl31/context.h
index 59c61da..16cc744 100644
--- a/include/bl31/context.h
+++ b/include/bl31/context.h
@@ -127,6 +127,11 @@
 #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
@@ -134,6 +139,10 @@
 #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'