Factor out CPU AMU helpers

This patch also fixes `cpuamu_write_cpuamcntenclr_el0()` to use an MSR
instruction instead of an MRS instruction.

Change-Id: Ia6531f64b5ebc60ba432124eaa8d8eaccba40ed0
Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
diff --git a/include/lib/cpus/aarch64/cpuamu.h b/include/lib/cpus/aarch64/cpuamu.h
new file mode 100644
index 0000000..3d52f14
--- /dev/null
+++ b/include/lib/cpus/aarch64/cpuamu.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CPUAMU_H__
+#define __CPUAMU_H__
+
+/*******************************************************************************
+ * CPU Activity Monitor Unit register specific definitions.
+ ******************************************************************************/
+#define CPUAMCNTENCLR_EL0	S3_3_C15_C9_7
+#define CPUAMCNTENSET_EL0	S3_3_C15_C9_6
+#define CPUAMCFGR_EL0		S3_3_C15_C10_6
+#define CPUAMUSERENR_EL0	S3_3_C15_C10_7
+
+/* Activity Monitor Event Counter Registers */
+#define CPUAMEVCNTR0_EL0	S3_3_C15_C9_0
+#define CPUAMEVCNTR1_EL0	S3_3_C15_C9_1
+#define CPUAMEVCNTR2_EL0	S3_3_C15_C9_2
+#define CPUAMEVCNTR3_EL0	S3_3_C15_C9_3
+#define CPUAMEVCNTR4_EL0	S3_3_C15_C9_4
+
+/* Activity Monitor Event Type Registers */
+#define CPUAMEVTYPER0_EL0	S3_3_C15_C10_0
+#define CPUAMEVTYPER1_EL0	S3_3_C15_C10_1
+#define CPUAMEVTYPER2_EL0	S3_3_C15_C10_2
+#define CPUAMEVTYPER3_EL0	S3_3_C15_C10_3
+#define CPUAMEVTYPER4_EL0	S3_3_C15_C10_4
+
+#ifndef __ASSEMBLY__
+#include <stdint.h>
+
+uint64_t cpuamu_cnt_read(int idx);
+void cpuamu_cnt_write(int idx, uint64_t val);
+unsigned int cpuamu_read_cpuamcntenset_el0(void);
+unsigned int cpuamu_read_cpuamcntenclr_el0(void);
+void cpuamu_write_cpuamcntenset_el0(unsigned int mask);
+void cpuamu_write_cpuamcntenclr_el0(unsigned int mask);
+#endif /* __ASSEMBLY__ */
+
+#endif /* __CPUAMU_H__ */
diff --git a/lib/cpus/aarch64/cpuamu_helpers.S b/lib/cpus/aarch64/cpuamu_helpers.S
new file mode 100644
index 0000000..8965d6d
--- /dev/null
+++ b/lib/cpus/aarch64/cpuamu_helpers.S
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpuamu.h>
+
+	.globl	cpuamu_cnt_read
+	.globl	cpuamu_cnt_write
+	.globl	cpuamu_read_cpuamcntenset_el0
+	.globl	cpuamu_read_cpuamcntenclr_el0
+	.globl	cpuamu_write_cpuamcntenset_el0
+	.globl	cpuamu_write_cpuamcntenclr_el0
+
+/*
+ * uint64_t cpuamu_cnt_read(int idx);
+ *
+ * Given `idx`, read the corresponding AMU counter
+ * and return it in `x0`.
+ */
+func cpuamu_cnt_read
+	adr	x1, 1f
+	lsl	x0, x0, #3
+	add	x1, x1, x0
+	br	x1
+
+1:
+	mrs	x0, CPUAMEVCNTR0_EL0
+	ret
+	mrs	x0, CPUAMEVCNTR1_EL0
+	ret
+	mrs	x0, CPUAMEVCNTR2_EL0
+	ret
+	mrs	x0, CPUAMEVCNTR3_EL0
+	ret
+	mrs	x0, CPUAMEVCNTR4_EL0
+	ret
+endfunc cpuamu_cnt_read
+
+/*
+ * void cpuamu_cnt_write(int idx, uint64_t val);
+ *
+ * Given `idx`, write `val` to the corresponding AMU counter.
+ */
+func cpuamu_cnt_write
+	adr	x2, 1f
+	lsl	x0, x0, #3
+	add	x2, x2, x0
+	br	x2
+
+1:
+	msr	CPUAMEVCNTR0_EL0, x0
+	ret
+	msr	CPUAMEVCNTR1_EL0, x0
+	ret
+	msr	CPUAMEVCNTR2_EL0, x0
+	ret
+	msr	CPUAMEVCNTR3_EL0, x0
+	ret
+	msr	CPUAMEVCNTR4_EL0, x0
+	ret
+endfunc cpuamu_cnt_write
+
+/*
+ * unsigned int cpuamu_read_cpuamcntenset_el0(void);
+ *
+ * Read the `CPUAMCNTENSET_EL0` CPU register and return
+ * it in `x0`.
+ */
+func cpuamu_read_cpuamcntenset_el0
+	mrs	x0, CPUAMCNTENSET_EL0
+	ret
+endfunc cpuamu_read_cpuamcntenset_el0
+
+/*
+ * unsigned int cpuamu_read_cpuamcntenclr_el0(void);
+ *
+ * Read the `CPUAMCNTENCLR_EL0` CPU register and return
+ * it in `x0`.
+ */
+func cpuamu_read_cpuamcntenclr_el0
+	mrs	x0, CPUAMCNTENCLR_EL0
+	ret
+endfunc cpuamu_read_cpuamcntenclr_el0
+
+/*
+ * void cpuamu_write_cpuamcntenset_el0(unsigned int mask);
+ *
+ * Write `mask` to the `CPUAMCNTENSET_EL0` CPU register.
+ */
+func cpuamu_write_cpuamcntenset_el0
+	msr	CPUAMCNTENSET_EL0, x0
+	ret
+endfunc cpuamu_write_cpuamcntenset_el0
+
+/*
+ * void cpuamu_write_cpuamcntenclr_el0(unsigned int mask);
+ *
+ * Write `mask` to the `CPUAMCNTENCLR_EL0` CPU register.
+ */
+func cpuamu_write_cpuamcntenclr_el0
+	msr	CPUAMCNTENCLR_EL0, x0
+	ret
+endfunc cpuamu_write_cpuamcntenclr_el0
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 4164242..07c4842 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -180,7 +180,8 @@
 ENABLE_AMU			:=	1
 
 ifeq (${ENABLE_AMU},1)
-BL31_SOURCES		+= lib/cpus/aarch64/cortex_a75_pubsub.c
+BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a75_pubsub.c			\
+				lib/cpus/aarch64/cpuamu_helpers.S
 endif
 
 ifneq (${ENABLE_STACK_PROTECTOR},0)