rework general purpose registers save and restore

The runtime exception handling assembler code used magic numbers for
saving and restoring the general purpose register context on stack
memory. The memory is interpreted as a 'gp_regs' structure and the
magic numbers are offsets to members of this structure. This patch
replaces the magic number offsets with constants. It also adds compile
time assertions to prevent an incorrect assembler view of this
structure.

Change-Id: Ibf125bfdd62ba3a33e58c5f1d71f8c229720781c
diff --git a/include/runtime_svc.h b/include/runtime_svc.h
index 3ccbe88..61c2d27 100644
--- a/include/runtime_svc.h
+++ b/include/runtime_svc.h
@@ -31,6 +31,7 @@
 #ifndef __RUNTIME_SVC_H__
 #define __RUNTIME_SVC_H__
 #include <psci.h>
+#include <bl_common.h>
 
 /*******************************************************************************
  * Bit definitions inside the function id as per the SMC calling convention
@@ -72,6 +73,45 @@
 #define FIQ_AARCH32			0xe
 #define SERROR_AARCH32			0xf
 
+/*******************************************************************************
+ * Constants that allow assembler code to access members of the 'gp_regs'
+ * structure at their correct offsets.
+ ******************************************************************************/
+#define SIZEOF_GPREGS		0x110
+#define GPREGS_X0_OFF		0x0
+#define GPREGS_X1_OFF		0x8
+#define GPREGS_X2_OFF		0x10
+#define GPREGS_X3_OFF		0x18
+#define GPREGS_X4_OFF		0x20
+#define GPREGS_X5_OFF		0x28
+#define GPREGS_X6_OFF		0x30
+#define GPREGS_X7_OFF		0x38
+#define GPREGS_X8_OFF		0x40
+#define GPREGS_X9_OFF		0x48
+#define GPREGS_X10_OFF		0x50
+#define GPREGS_X11_OFF		0x58
+#define GPREGS_X12_OFF		0x60
+#define GPREGS_X13_OFF		0x68
+#define GPREGS_X14_OFF		0x70
+#define GPREGS_X15_OFF		0x78
+#define GPREGS_X16_OFF		0x80
+#define GPREGS_X17_OFF		0x88
+#define GPREGS_X18_OFF		0x90
+#define GPREGS_X19_OFF		0x98
+#define GPREGS_X20_OFF		0xA0
+#define GPREGS_X21_OFF		0xA8
+#define GPREGS_X22_OFF		0xB0
+#define GPREGS_X23_OFF		0xB8
+#define GPREGS_X24_OFF		0xC0
+#define GPREGS_X25_OFF		0xC8
+#define GPREGS_X26_OFF		0xD0
+#define GPREGS_X27_OFF		0xD8
+#define GPREGS_X28_OFF		0xE0
+#define GPREGS_SP_EL0_OFF	0xE8
+#define GPREGS_SPSR_OFF		0xF0
+#define GPREGS_FP_OFF		0x100
+#define GPREGS_LR_OFF		0x108
+
 #ifndef __ASSEMBLY__
 
 typedef struct {
@@ -106,10 +146,24 @@
 	unsigned long x28;
 	unsigned long sp_el0;
 	unsigned long spsr;
-	unsigned long fp;
+	/*
+	 * Alignment constraint which allows save & restore of fp & lr on the
+	 * stack during exception handling
+	 */
+	unsigned long fp  __attribute__((__aligned__(16)));
 	unsigned long lr;
-} gp_regs;
+} __attribute__((__aligned__(16))) gp_regs;
 
+/*******************************************************************************
+ * Compile time assertions to ensure that:
+ * 1)  the assembler code's view of the size of the 'gp_regs' data structure is
+ *     the same as the actual size of this data structure.
+ * 2)  the assembler code's view of the offset of the frame pointer member of
+ *     the 'gp_regs' structure is the same as the actual offset of this member.
+ ******************************************************************************/
+CASSERT((sizeof(gp_regs) == SIZEOF_GPREGS), assert_sizeof_gpregs_mismatch);
+CASSERT(GPREGS_FP_OFF == __builtin_offsetof(gp_regs, fp), \
+	assert_gpregs_fp_offset_mismatch);
 
 /*******************************************************************************
  * Function & variable prototypes