On Thu, Feb 7, 2013 at 10:10 PM, Vince Weaver <vincent.weaver@maine.edu> wrote:

This patch adds support for the ARM 1176 armv6 processor found in the
Raspberry Pi.

I've tested that libpfm4 with this patch works on a Raspberry Pi, but the
kernel installed on the board has broken perf_event support so I haven't
actually measured any performance events yet.

Patch applied. Added a couple of encoding tests in validate_arm.c
Thanks.
 
---
 config.mk                    |    3 +
 include/perfmon/pfmlib.h     |    2 +
 lib/Makefile                 |    2 +-
 lib/events/arm_1176_events.h |  136 ++++++++++++++++++++++++++++++++++++++++++
 lib/pfmlib_arm_armv6.c       |   77 ++++++++++++++++++++++++
 lib/pfmlib_common.c          |    1 +
 lib/pfmlib_priv.h            |    1 +
 7 files changed, 221 insertions(+), 1 deletion(-)
 create mode 100644 lib/events/arm_1176_events.h
 create mode 100644 lib/pfmlib_arm_armv6.c

diff --git a/config.mk b/config.mk
index 5f6adf2..b5cefc3 100644
--- a/config.mk
+++ b/config.mk
@@ -57,6 +57,9 @@ endif
 ifeq (sparc64,$(findstring sparc64,$(ARCH)))
 override ARCH=sparc
 endif
+ifeq (armv6,$(findstring armv6,$(ARCH)))
+override ARCH=arm
+endif
 ifeq (armv7,$(findstring armv7,$(ARCH)))
 override ARCH=arm
 endif
diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h
index b122ca5..ac8f31e 100644
--- a/include/perfmon/pfmlib.h
+++ b/include/perfmon/pfmlib.h
@@ -180,6 +180,8 @@ typedef enum {

        PFM_PMU_S390X_CPUM_CF,          /* s390x: CPU-M counter facility */

+       PFM_PMU_ARM_1176,               /* ARM 1176 */
+
        /* MUST ADD NEW PMU MODELS HERE */

        PFM_PMU_MAX                     /* end marker */
diff --git a/lib/Makefile b/lib/Makefile
index d2f00a9..0c288d3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -127,7 +127,7 @@ SRCS += pfmlib_arm_perf_event.c
 endif

 INCARCH = $(INC_ARM)
-SRCS   += pfmlib_arm.c pfmlib_arm_armv7_pmuv1.c
+SRCS   += pfmlib_arm.c pfmlib_arm_armv7_pmuv1.c pfmlib_arm_armv6.c
 CFLAGS += -DCONFIG_PFMLIB_ARCH_ARM
 endif

diff --git a/lib/events/arm_1176_events.h b/lib/events/arm_1176_events.h
new file mode 100644
index 0000000..35a43fa
--- /dev/null
+++ b/lib/events/arm_1176_events.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013 by Vince Weaver <vincent.weaver@maine.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of libpfm, a performance monitoring support library for
+ * applications on Linux.
+ */
+
+/*
+ * the various event names are the same as those given in the
+ * file linux-2.6/arch/arm/kernel/perf_event_v6.c
+ */
+
+/*
+ * ARM1176 Event Table
+ */
+static const arm_entry_t arm_1176_pe []={
+       {.name = "ICACHE_MISS",
+        .code = 0x00,
+        .desc = "Instruction cache miss (includes speculative accesses)"
+       },
+       {.name = "IBUF_STALL",
+        .code = 0x01,
+        .desc = "Stall because instruction buffer cannot deliver an instruction"
+       },
+       {.name = "DDEP_STALL",
+        .code = 0x02,
+        .desc = "Stall because of data dependency"
+       },
+       {.name = "ITLB_MISS",
+        .code = 0x03,
+        .desc = "Instruction MicroTLB miss"
+       },
+       {.name = "DTLB_MISS",
+        .code = 0x04,
+        .desc = "Data MicroTLB miss"
+       },
+       {.name = "BR_EXEC",
+        .code = 0x05,
+        .desc = "Branch instruction executed"
+       },
+       {.name = "BR_MISPREDICT",
+        .code = 0x06,
+        .desc = "Branch mispredicted"
+       },
+       {.name = "INSTR_EXEC",
+        .code = 0x07,
+        .desc = "Instruction executed"
+       },
+       {.name = "DCACHE_HIT",
+        .code = 0x09,
+        .desc = "Data cache hit"
+       },
+       {.name = "DCACHE_ACCESS",
+        .code = 0x0a,
+        .desc = "Data cache access"
+       },
+       {.name = "DCACHE_MISS",
+        .code = 0x0b,
+        .desc = "Data cache miss"
+       },
+       {.name = "DCACHE_WBACK",
+        .code = 0x0c,
+        .desc = "Data cache writeback"
+       },
+       {.name = "SW_PC_CHANGE",
+        .code = 0x0d,
+        .desc = "Software changed the PC."
+       },
+       {.name = "MAIN_TLB_MISS",
+        .code = 0x0f,
+        .desc = "Main TLB miss"
+       },
+       {.name = "EXPL_D_ACCESS",
+        .code = 0x10,
+        .desc = "Explicit external data cache access "
+       },
+       {.name = "LSU_FULL_STALL",
+        .code = 0x11,
+        .desc = "Stall because of a full Load Store Unit request queue."
+       },
+       {.name = "WBUF_DRAINED",
+        .code = 0x12,
+        .desc = "Write buffer drained due to data synchronization barrier or strongly ordered operation"
+       },
+       {.name = "ETMEXTOUT_0",
+        .code = 0x20,
+        .desc = "ETMEXTOUT[0] was asserted"
+       },
+       {.name = "ETMEXTOUT_1",
+        .code = 0x21,
+        .desc = "ETMEXTOUT[1] was asserted"
+       },
+       {.name = "ETMEXTOUT",
+        .code = 0x22,
+        .desc = "Increment once for each of ETMEXTOUT[0] or ETMEXTOUT[1]"
+       },
+       {.name = "PROC_CALL_EXEC",
+        .code = 0x23,
+        .desc = "Procedure call instruction executed"
+       },
+       {.name = "PROC_RET_EXEC",
+        .code = 0x24,
+        .desc = "Procedure return instruction executed"
+       },
+       {.name = "PROC_RET_EXEC_PRED",
+        .code = 0x25,
+        .desc = "Proceudre return instruction executed and address predicted"
+       },
+       {.name = "PROC_RET_EXEC_PRED_INCORRECT",
+        .code = 0x26,
+        .desc = "Procedure return instruction executed and address predicted incorrectly"
+       },
+       {.name = "CPU_CYCLES",
+        .code = 0xff,
+        .desc = "CPU cycles"
+       },
+};
+
+#define ARM_1176_EVENT_COUNT   (sizeof(arm_1176_pe)/sizeof(arm_entry_t))
diff --git a/lib/pfmlib_arm_armv6.c b/lib/pfmlib_arm_armv6.c
new file mode 100644
index 0000000..d59b402
--- /dev/null
+++ b/lib/pfmlib_arm_armv6.c
@@ -0,0 +1,77 @@
+/*
+ * pfmlib_arm_armv6.c :        support for ARMv6 chips
+ *
+ * Copyright (c) 2013 by Vince Weaver <vincent.weaver@maine.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+/* private headers */
+#include "pfmlib_priv.h"                       /* library private */
+#include "pfmlib_arm_priv.h"
+
+#include "events/arm_1176_events.h"        /* event tables */
+
+static int
+pfm_arm_detect_1176(void *this)
+{
+
+       int ret;
+
+       ret = pfm_arm_detect(this);
+       if (ret != PFM_SUCCESS)
+               return PFM_ERR_NOTSUPP;
+
+       if ((pfm_arm_cfg.implementer == 0x41) && /* ARM */
+                       (pfm_arm_cfg.part==0xb76)) { /* 1176 */
+               return PFM_SUCCESS;
+       }
+       return PFM_ERR_NOTSUPP;
+}
+
+/* ARM1176 support */
+pfmlib_pmu_t arm_1176_support={
+       .desc                   = "ARM1176",
+       .name                   = "arm_1176",
+       .pmu                    = PFM_PMU_ARM_1176,
+       .pme_count              = LIBPFM_ARRAY_SIZE(arm_1176_pe),
+       .type                   = PFM_PMU_TYPE_CORE,
+       .pe                     = arm_1176_pe,
+
+       .pmu_detect             = pfm_arm_detect_1176,
+       .max_encoding           = 1,
+       .num_cntrs              = 2,
+
+       .get_event_encoding[PFM_OS_NONE] = pfm_arm_get_encoding,
+        PFMLIB_ENCODE_PERF(pfm_arm_get_perf_encoding),
+       .get_event_first        = pfm_arm_get_event_first,
+       .get_event_next         = pfm_arm_get_event_next,
+       .event_is_valid         = pfm_arm_event_is_valid,
+       .validate_table         = pfm_arm_validate_table,
+       .get_event_info         = pfm_arm_get_event_info,
+       .get_event_attr_info    = pfm_arm_get_event_attr_info,
+        PFMLIB_VALID_PERF_PATTRS(pfm_arm_perf_validate_pattrs),
+       .get_event_nattrs       = pfm_arm_get_event_nattrs,
+};
diff --git a/lib/pfmlib_common.c b/lib/pfmlib_common.c
index c29a325..87f6a01 100644
--- a/lib/pfmlib_common.c
+++ b/lib/pfmlib_common.c
@@ -152,6 +152,7 @@ static pfmlib_pmu_t *pfmlib_pmus[]=
        &arm_cortex_a8_support,
        &arm_cortex_a9_support,
        &arm_cortex_a15_support,
+       &arm_1176_support,
 #endif
 #ifdef CONFIG_PFMLIB_ARCH_S390X
        &s390x_cpum_cf_support,
diff --git a/lib/pfmlib_priv.h b/lib/pfmlib_priv.h
index 8d3353d..b57aa10 100644
--- a/lib/pfmlib_priv.h
+++ b/lib/pfmlib_priv.h
@@ -274,6 +274,7 @@ extern pfmlib_pmu_t intel_wsm_unc_support;
 extern pfmlib_pmu_t arm_cortex_a8_support;
 extern pfmlib_pmu_t arm_cortex_a9_support;
 extern pfmlib_pmu_t arm_cortex_a15_support;
+extern pfmlib_pmu_t arm_1176_support;
 extern pfmlib_pmu_t mips_74k_support;
 extern pfmlib_pmu_t s390x_cpum_cf_support;

--
1.7.10.4