Index: kernel/arch/arm32/include/asm.h
===================================================================
--- kernel/arch/arm32/include/asm.h	(revision 4b28c709536aac5f2730fb19ac4f4032e8edaf11)
+++ kernel/arch/arm32/include/asm.h	(revision 3fa509b7d6b019645af8ba968895d2b30ec8eab9)
@@ -43,5 +43,5 @@
 #include <trace.h>
 
-/** No such instruction on old ARM to sleep CPU.
+/** CPU specific way to sleep cpu.
  *
  * ARMv7 introduced wait for event and wait for interrupt (wfe/wfi).
Index: kernel/arch/arm32/include/cp15.h
===================================================================
--- kernel/arch/arm32/include/cp15.h	(revision 4b28c709536aac5f2730fb19ac4f4032e8edaf11)
+++ kernel/arch/arm32/include/cp15.h	(revision 3fa509b7d6b019645af8ba968895d2b30ec8eab9)
@@ -416,5 +416,30 @@
 CONTROL_REG_GEN_WRITE(TLBIALLNSNHS, c8, 4, c7, 4);
 
-/* c9 are reserved */
+/* c9 are performance monitoring resgisters */
+enum {
+	PMCR_IMP_MASK = 0xff,
+	PMCR_IMP_SHIFT = 24,
+	PMCR_IDCODE_MASK = 0xff,
+	PMCR_IDCODE_SHIFT = 16,
+	PMCR_EVENT_NUM_MASK = 0x1f,
+	PMCR_EVENT_NUM_SHIFT = 11,
+	PMCR_DP_FLAG = 1 << 5,
+	PMCR_X_FLAG = 1 << 4,
+	PMCR_D_FLAG = 1 << 3,
+	PMCR_C_FLAG = 1 << 2,
+	PMCR_P_FLAG = 1 << 1,
+	PMCR_E_FLAG = 1 << 0,
+};
+CONTROL_REG_GEN_READ(PMCR, c9, 0, c12, 0);
+CONTROL_REG_GEN_WRITE(PMCR, c9, 0, c12, 0);
+enum {
+	PMCNTENSET_CYCLE_COUNTER_EN_FLAG = 1 << 31,
+#define PMCNTENSET_COUNTER_EN_FLAG(c)   (1 << c)
+};
+CONTROL_REG_GEN_READ(PMCNTENSET, c9, 0, c12, 1);
+CONTROL_REG_GEN_WRITE(PMCNTENSET, c9, 0, c12, 1);
+CONTROL_REG_GEN_READ(PMCCNTR, c9, 0, c13, 0);
+CONTROL_REG_GEN_WRITE(PMCCNTR, c9, 0, c13, 0);
+
 
 /*c10 has tons of reserved too */
Index: kernel/arch/arm32/include/cycle.h
===================================================================
--- kernel/arch/arm32/include/cycle.h	(revision 4b28c709536aac5f2730fb19ac4f4032e8edaf11)
+++ kernel/arch/arm32/include/cycle.h	(revision 3fa509b7d6b019645af8ba968895d2b30ec8eab9)
@@ -38,4 +38,5 @@
 
 #include <trace.h>
+#include <arch/cp15.h>
 
 /** Return count of CPU cycles.
@@ -48,4 +49,14 @@
 NO_TRACE static inline uint64_t get_cycle(void)
 {
+#ifdef PROCESSOR_ARCH_armv7_a
+	if ((ID_PFR1_read() & ID_PFR1_GEN_TIMER_EXT_MASK) ==
+	    ID_PFR1_GEN_TIMER_EXT) {
+	    uint32_t low = 0, high = 0;
+	    asm volatile( "MRRC p15, 0, %[low], %[high], c14": [low]"=r"(low), [high]"=r"(high));
+	   return ((uint64_t)high << 32) | low;
+	} else {
+		return PMCCNTR_read();
+	}
+#endif
 	return 0;
 }
Index: kernel/arch/arm32/src/cpu/cpu.c
===================================================================
--- kernel/arch/arm32/src/cpu/cpu.c	(revision 4b28c709536aac5f2730fb19ac4f4032e8edaf11)
+++ kernel/arch/arm32/src/cpu/cpu.c	(revision 3fa509b7d6b019645af8ba968895d2b30ec8eab9)
@@ -168,4 +168,9 @@
 	fpu_setup();
 #endif
+
+#ifdef PROCESSOR_ARCH_armv7_a
+	PMCR_write(PMCR_read() | PMCR_E_FLAG);
+	PMCNTENSET_write(PMCNTENSET_CYCLE_COUNTER_EN_FLAG);
+#endif
 }
 
