Implement {spe,sve}_supported() helpers and refactor code

Implement helpers to test if the core supports SPE/SVE.  We have a
similar helper for AMU and this patch makes all extensions consistent
in their implementation.

Change-Id: I3e6f7522535ca358259ad142550b19fcb883ca67
Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index 3b297f2..716cd64 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,71 +14,72 @@
  */
 #define psb_csync()	asm volatile("hint #17")
 
-void spe_enable(int el2_unused)
+int spe_supported(void)
 {
 	uint64_t features;
 
 	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
-	if ((features & ID_AA64DFR0_PMS_MASK) == 1) {
-		uint64_t v;
+	return (features & ID_AA64DFR0_PMS_MASK) == 1;
+}
 
-		if (el2_unused) {
-			/*
-			 * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
-			 * profiling controls to EL2.
-			 *
-			 * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in Non-secure
-			 * state. Accesses to profiling buffer controls at
-			 * Non-secure EL1 are not trapped to EL2.
-			 */
-			v = read_mdcr_el2();
-			v &= ~MDCR_EL2_TPMS;
-			v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
-			write_mdcr_el2(v);
-		}
+void spe_enable(int el2_unused)
+{
+	uint64_t v;
 
+	if (!spe_supported())
+		return;
+
+	if (el2_unused) {
 		/*
-		 * MDCR_EL2.NSPB (ARM v8.2): SPE enabled in Non-secure state
-		 * and disabled in secure state. Accesses to SPE registers at
-		 * S-EL1 generate trap exceptions to EL3.
+		 * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
+		 * profiling controls to EL2.
+		 *
+		 * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in Non-secure
+		 * state. Accesses to profiling buffer controls at
+		 * Non-secure EL1 are not trapped to EL2.
 		 */
-		v = read_mdcr_el3();
-		v |= MDCR_NSPB(MDCR_NSPB_EL1);
-		write_mdcr_el3(v);
+		v = read_mdcr_el2();
+		v &= ~MDCR_EL2_TPMS;
+		v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
+		write_mdcr_el2(v);
 	}
+
+	/*
+	 * MDCR_EL2.NSPB (ARM v8.2): SPE enabled in Non-secure state
+	 * and disabled in secure state. Accesses to SPE registers at
+	 * S-EL1 generate trap exceptions to EL3.
+	 */
+	v = read_mdcr_el3();
+	v |= MDCR_NSPB(MDCR_NSPB_EL1);
+	write_mdcr_el3(v);
 }
 
 void spe_disable(void)
 {
-	uint64_t features;
+	uint64_t v;
 
-	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
-	if ((features & ID_AA64DFR0_PMS_MASK) == 1) {
-		uint64_t v;
+	if (!spe_supported())
+		return;
 
-		/* Drain buffered data */
-		psb_csync();
-		dsbnsh();
+	/* Drain buffered data */
+	psb_csync();
+	dsbnsh();
 
-		/* Disable profiling buffer */
-		v = read_pmblimitr_el1();
-		v &= ~(1ULL << 0);
-		write_pmblimitr_el1(v);
-		isb();
-	}
+	/* Disable profiling buffer */
+	v = read_pmblimitr_el1();
+	v &= ~(1ULL << 0);
+	write_pmblimitr_el1(v);
+	isb();
 }
 
 static void *spe_drain_buffers_hook(const void *arg)
 {
-	uint64_t features;
-
-	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
-	if ((features & ID_AA64DFR0_PMS_MASK) == 1) {
-		/* Drain buffered data */
-		psb_csync();
-		dsbnsh();
-	}
+	if (!spe_supported())
+		return (void *)-1;
 
+	/* Drain buffered data */
+	psb_csync();
+	dsbnsh();
 	return 0;
 }