Add provision to extend CPU operations at more levels

Various CPU drivers in ARM Trusted Firmware register functions to handle
power-down operations. At present, separate functions are registered to
power down individual cores and clusters.

This scheme operates on the basis of core and cluster, and doesn't cater
for extending the hierarchy for power-down operations. For example,
future CPUs might support multiple threads which might need powering
down individually.

This patch therefore reworks the CPU operations framework to allow for
registering power down handlers on specific level basis. Henceforth:

  - Generic code invokes CPU power down operations by the level
    required.

  - CPU drivers explicitly mention CPU_NO_RESET_FUNC when the CPU has no
    reset function.

  - CPU drivers register power down handlers as a list: a mandatory
    handler for level 0, and optional handlers for higher levels.

All existing CPU drivers are adapted to the new CPU operations framework
without needing any functional changes within.

Also update firmware design guide.

Change-Id: I1826842d37a9e60a9e85fdcee7b4b8f6bc1ad043
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index f34f078..570ef88 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, 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:
@@ -35,6 +35,15 @@
 #define CPU_IMPL_PN_MASK	(MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
 				(MIDR_PN_MASK << MIDR_PN_SHIFT)
 
+/* The number of CPU operations allowed */
+#define CPU_MAX_PWR_DWN_OPS		2
+
+/* Special constant to specify that CPU has no reset function */
+#define CPU_NO_RESET_FUNC		0
+
+/* Word size for 64-bit CPUs */
+#define CPU_WORD_SIZE			8
+
 	/*
 	 * Define the offsets to the fields in cpu_ops structure.
 	 */
@@ -47,10 +56,8 @@
 	.space  8
 #endif
 #if IMAGE_BL31 /* The power down core and cluster is needed only in BL31 */
-CPU_PWR_DWN_CORE: /* cpu_ops core_pwr_dwn */
-	.space  8
-CPU_PWR_DWN_CLUSTER: /* cpu_ops cluster_pwr_dwn */
-	.space  8
+CPU_PWR_DWN_OPS: /* cpu_ops power down functions */
+	.space  (8 * CPU_MAX_PWR_DWN_OPS)
 #endif
 #if (IMAGE_BL31 && CRASH_REPORTING)
 CPU_REG_DUMP: /* cpu specific register dump for crash reporting */
@@ -59,24 +66,80 @@
 CPU_OPS_SIZE = .
 
 	/*
-	 * Convenience macro to declare cpu_ops structure.
-	 * Make sure the structure fields are as per the offsets
-	 * defined above.
+	 * Write given expressions as quad words
+	 *
+	 * _count:
+	 *	Write at least _count quad words. If the given number of
+	 *	expressions is less than _count, repeat the last expression to
+	 *	fill _count quad words in total
+	 * _rest:
+	 *	Optional list of expressions. _this is for parameter extraction
+	 *	only, and has no significance to the caller
+	 *
+	 * Invoked as:
+	 *	fill_constants 2, foo, bar, blah, ...
 	 */
-	.macro declare_cpu_ops _name:req, _midr:req, _noresetfunc = 0
-	.section cpu_ops, "a"; .align 3
+	.macro fill_constants _count:req, _this, _rest:vararg
+	  .ifgt \_count
+	    /* Write the current expression */
+	    .ifb \_this
+	      .error "Nothing to fill"
+	    .endif
+	    .quad \_this
+
+	    /* Invoke recursively for remaining expressions */
+	    .ifnb \_rest
+	      fill_constants \_count-1, \_rest
+	    .else
+	      fill_constants \_count-1, \_this
+	    .endif
+	  .endif
+	.endm
+
+	/*
+	 * Declare CPU operations
+	 *
+	 * _name:
+	 *	Name of the CPU for which operations are being specified
+	 * _midr:
+	 *	Numeric value expected to read from CPU's MIDR
+	 * _resetfunc:
+	 *	Reset function for the CPU. If there's no CPU reset function,
+	 *	specify CPU_NO_RESET_FUNC
+	 * _power_down_ops:
+	 *	Comma-separated list of functions to perform power-down
+	 *	operatios on the CPU. At least one, and up to
+	 *	CPU_MAX_PWR_DWN_OPS number of functions may be specified.
+	 *	Starting at power level 0, these functions shall handle power
+	 *	down at subsequent power levels. If there aren't exactly
+	 *	CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
+	 *	used to handle power down at subsequent levels
+	 */
+	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
+		_power_down_ops:vararg
+	.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
+	.quad \_resetfunc
 #endif
 #if IMAGE_BL31
-	.quad \_name\()_core_pwr_dwn
-	.quad \_name\()_cluster_pwr_dwn
+1:
+	/* Insert list of functions */
+	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
+2:
+	/*
+	 * Error if no or more than CPU_MAX_PWR_DWN_OPS were specified in the
+	 * list
+	 */
+	.ifeq 2b - 1b
+	  .error "At least one power down function must be specified"
+	.else
+	  .iflt 2b - 1b - (CPU_MAX_PWR_DWN_OPS * CPU_WORD_SIZE)
+	    .error "More than CPU_MAX_PWR_DWN_OPS functions specified"
+	  .endif
+	.endif
 #endif
 #if (IMAGE_BL31 && CRASH_REPORTING)
 	.quad \_name\()_cpu_reg_dump