---
 README                        |   1 +
 docs/Makefile                 |   6 +-
 docs/man3/libpfm_arm_xgene.3  |  39 ++++
 include/perfmon/pfmlib.h      |   1 +
 lib/events/arm_xgene_events.h | 515 ++++++++++++++++++++++++++++++++++++++++++
 lib/pfmlib_arm_armv8.c        |  42 ++++
 lib/pfmlib_common.c           |   2 +
 lib/pfmlib_priv.h             |   1 +
 tests/validate_arm64.c        |  28 +++
 9 files changed, 633 insertions(+), 2 deletions(-)
 create mode 100644 docs/man3/libpfm_arm_xgene.3
 create mode 100644 lib/events/arm_xgene_events.h

diff --git a/README b/README
index e74238f..f6f45c9 100644
--- a/README
+++ b/README
@@ -58,6 +58,7 @@ The library supports many PMUs. The current version can 
handle:
                ARMV7 Cortex A9
                ARMV7 Cortex A15
                ARMV8 Cortex A57, A53
+               Applied Micro X-Gene
                Qualcomm Krait
 
        - For SPARC
diff --git a/docs/Makefile b/docs/Makefile
index c7d797e..4ae4bae 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -76,7 +76,8 @@ endif
 endif
 
 ifeq ($(CONFIG_PFMLIB_ARCH_ARM),y)
-ARCH_MAN += libpfm_arm_ac57.3 \
+ARCH_MAN += libpfm_arm_xgene.3 \
+           libpfm_arm_ac57.3 \
            libpfm_arm_ac53.3 \
            libpfm_arm_ac15.3 \
            libpfm_arm_ac8.3 \
@@ -85,7 +86,8 @@ ARCH_MAN += libpfm_arm_ac57.3 \
 endif
 
 ifeq ($(CONFIG_PFMLIB_ARCH_ARM64),y)
-ARCH_MAN += libpfm_arm_ac57.3 \
+ARCH_MAN += libpfm_arm_xgene.3 \
+           libpfm_arm_ac57.3 \
            libpfm_arm_ac53.3
 endif
 
diff --git a/docs/man3/libpfm_arm_xgene.3 b/docs/man3/libpfm_arm_xgene.3
new file mode 100644
index 0000000..a0a84bc
--- /dev/null
+++ b/docs/man3/libpfm_arm_xgene.3
@@ -0,0 +1,39 @@
+.TH LIBPFM 4  "May, 2014" "" "Linux Programmer's Manual"
+.SH NAME
+libpfm_arm_ac57 - support for Applied Micro X-Gene PMU
+.SH SYNOPSIS
+.nf
+.B #include <perfmon/pfmlib.h>
+.sp
+.B PMU name: arm_xgene
+.B PMU desc: Applied Micro X-Gene
+.sp
+.SH DESCRIPTION
+The library supports the Applied Micro X-Gene PMU.
+
+This PMU supports 6 counters and privilege levels filtering.
+It can operate in both 32 and 64 bit modes.
+
+.SH MODIFIERS
+The following modifiers are supported on Applied Micro X-Gene:
+.TP
+.B u
+Measure at the user level. This corresponds to \fBPFM_PLM3\fR.
+This is a boolean modifier.
+.TP
+.B k
+Measure at the kernel level. This corresponds to \fBPFM_PLM0\fR.
+This is a boolean modifier.
+.TP
+.B hv
+Measure at the hypervisor level. This corresponds to \fBPFM_PLMH\fR.
+This is a boolean modifier.
+
+.SH AUTHORS
+.nf
+Stephane Eranian <eran...@gmail.com>
+.if
+.nf
+William Cohen <wco...@redhat.com>
+.if
+.PP
diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h
index a7ec026..b7b312e 100644
--- a/include/perfmon/pfmlib.h
+++ b/include/perfmon/pfmlib.h
@@ -239,6 +239,7 @@ typedef enum {
 
        PFM_PMU_ARM_CORTEX_A57,         /* ARM Cortex A57 (ARMv8) */
        PFM_PMU_ARM_CORTEX_A53,         /* ARM Cortex A53 (ARMv8) */
+       PFM_PMU_ARM_XGENE,              /* Applied Micro X-Gene (ARMv8) */
 
        /* MUST ADD NEW PMU MODELS HERE */
 
diff --git a/lib/events/arm_xgene_events.h b/lib/events/arm_xgene_events.h
new file mode 100644
index 0000000..856dac1
--- /dev/null
+++ b/lib/events/arm_xgene_events.h
@@ -0,0 +1,515 @@
+/*
+ * Copyright (c) 2014 Google Inc. All rights reserved
+ * Copyright (c) 2014 Red Hat Inc. All rights reserved
+ * Contributed by William Cohen <wco...@redhat.com>
+ *
+ * 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.
+ *
+ * Applied Micro X-Gene
+ * based on Mustang (X-Gene) Software User Guide 15.1.2 CPU PMU Event list
+ */
+
+static const arm_entry_t arm_xgene_pe[]={
+       {.name = "SW_INCR",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x00,
+        .desc = "Instruction architecturally executed (condition check pass) 
Software increment"
+       },
+       {.name = "L1I_CACHE_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x01,
+        .desc = "Level 1 instruction cache refill"
+       },
+       {.name = "L1I_TLB_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x02,
+        .desc = "Level 1 instruction TLB refill"
+       },
+       {.name = "L1D_CACHE_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x03,
+        .desc = "Level 1 data cache refill"
+       },
+       {.name = "L1D_CACHE_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x04,
+        .desc = "Level 1 data cache access"
+       },
+       {.name = "L1D_TLB_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x05,
+        .desc = "Level 1 data TLB refill"
+       },
+       {.name = "INST_RETIRED",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x08,
+        .desc = "Instruction architecturally executed"
+       },
+       {.name = "EXCEPTION_TAKEN",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x09,
+        .desc = "Exception taken"
+       },
+       {.name = "EXCEPTION_RETURN",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x0a,
+        .desc = "Instruction architecturally executed (condition check pass) 
Exception return"
+       },
+       {.name = "CID_WRITE_RETIRED",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x0b,
+        .desc = "Change to Context ID retired",
+       },
+       {.name = "BRANCH_MISPRED",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x10,
+        .desc = "Mispredicted or not predicted branch speculatively executed"
+       },
+       {.name = "CPU_CYCLES",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x11,
+        .desc = "Cycles"
+       },
+       {.name = "BRANCH_PRED",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x12,
+        .desc = "Predictable branch speculatively executed"
+       },
+       {.name = "DATA_MEM_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x13,
+        .desc = "Data memory access"
+       },
+       {.name = "L1I_CACHE_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x14,
+        .desc = "Level 1 instruction cache access"
+       },
+       {.name = "L2D_CACHE_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x16,
+        .desc = "Level 2 data cache access"
+       },
+       {.name = "L2D_CACHE_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x17,
+        .desc = "Level 2 data cache refill"
+       },
+       {.name = "L2D_CACHE_WB",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x18,
+        .desc = "Level 2 data cache WriteBack"
+       },
+       {.name = "BUS_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x19,
+        .desc = "Bus access"
+       },
+       {.name = "LOCAL_MEMORY_ERROR",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x1a,
+        .desc = "Local memory error"
+       },
+
+       {.name = "L1D_READ_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x40,
+        .desc = "Level 1 data cache read access"
+       },
+       {.name = "L1D_WRITE_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x41,
+        .desc = "Level 1 data cache write access"
+       },
+       {.name = "L1D_READ_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x42,
+        .desc = "Level 1 data cache read refill"
+       },
+       {.name = "L1D_INVALIDATE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x48,
+        .desc = "Level 1 data cache invalidate"
+       },
+       {.name = "L1D_TLB_READ_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x4c,
+        .desc = "Level 1 data TLB read refill"
+       },
+       {.name = "L1D_TLB_WRITE_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x4d,
+        .desc = "Level 1 data TLB write refill"
+       },
+       {.name = "L2D_READ_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x50,
+        .desc = "Level 2 data cache read access"
+       },
+       {.name = "L2D_WRITE_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x51,
+        .desc = "Level 2 data cache write access"
+       },
+       {.name = "L2D_READ_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x52,
+        .desc = "Level 2 data cache read refill"
+       },
+       {.name = "L2D_WRITE_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x53,
+        .desc = "Level 2 data cache write refill"
+       },
+       {.name = "L2D_WB_VICTIM",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x56,
+        .desc = "Level 2 data cache writeback victim"
+       },
+       {.name = "L2D_WB_CLEAN_COHERENCY",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x57,
+        .desc = "Level 2 data cache writeback cleaning and coherency"
+       },
+       {.name = "L2D_INVALIDATE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x58,
+        .desc = "Level 2 data cache invalidate"
+       },
+       {.name = "BUS_READ_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x60,
+        .desc = "Bus read access"
+       },
+       {.name = "BUS_WRITE_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x61,
+        .desc = "Bus write access"
+       },
+       {.name = "BUS_NORMAL_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x62,
+        .desc = "Bus normal access"
+       },
+       {.name = "BUS_NOT_NORMAL_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x63,
+        .desc = "Bus not normal access"
+       },
+       {.name = "BUS_NORMAL_ACCESS_2",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x64,
+        .desc = "Bus normal access"
+       },
+       {.name = "BUS_PERIPH_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x65,
+        .desc = "Bus peripheral access"
+       },
+       {.name = "DATA_MEM_READ_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x66,
+        .desc = "Data memory read access"
+       },
+       {.name = "DATA_MEM_WRITE_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x67,
+        .desc = "Data memory write access"
+       },
+       {.name = "UNALIGNED_READ_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x68,
+        .desc = "Unaligned read access"
+       },
+       {.name = "UNALIGNED_WRITE_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x69,
+        .desc = "Unaligned read access"
+       },
+       {.name = "UNALIGNED_ACCESS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x6a,
+        .desc = "Unaligned access"
+       },
+       {.name = "INST_SPEC_EXEC_LDREX",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x6c,
+        .desc = "LDREX exclusive instruction speculatively executed"
+       },
+       {.name = "INST_SPEC_EXEC_STREX_PASS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x6d,
+        .desc = "STREX pass exclusive instruction speculatively executed"
+       },
+       {.name = "INST_SPEC_EXEC_STREX_FAIL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x6e,
+        .desc = "STREX fail exclusive instruction speculatively executed"
+       },
+       {.name = "INST_SPEC_EXEC_LOAD",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x70,
+        .desc = "Load instruction speculatively executed"
+       },
+       {.name = "INST_SPEC_EXEC_STORE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x71,
+        .desc = "Store instruction speculatively executed"
+       },
+       {.name = "INST_SPEC_EXEC_LOAD_STORE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x72,
+        .desc = "Load or store instruction speculatively executed"
+       },
+       {.name = "INST_SPEC_EXEC_INTEGER_INST",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x73,
+        .desc = "Integer data processing instruction speculatively executed"
+       },
+       {.name = "INST_SPEC_EXEC_SIMD",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x74,
+        .desc = "Advanced SIMD instruction speculatively executed"
+       },
+       {.name = "INST_SPEC_EXEC_VFP",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x75,
+        .desc = "VFP instruction speculatively executed"
+       },
+       {.name = "INST_SPEC_EXEC_SOFT_PC",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x76,
+        .desc = "Software of the PC instruction speculatively executed"
+       },
+       {.name = "BRANCH_SPEC_EXEC_IMM_BRANCH",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x78,
+        .desc = "Immediate branch speculatively executed"
+       },
+       {.name = "BRANCH_SPEC_EXEC_RET",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x79,
+        .desc = "Return branch speculatively executed"
+       },
+       {.name = "BRANCH_SPEC_EXEC_IND",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x7a,
+        .desc = "Indirect branch speculatively executed"
+       },
+       {.name = "BARRIER_SPEC_EXEC_ISB",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x7c,
+        .desc = "ISB barrier speculatively executed"
+       },
+       {.name = "BARRIER_SPEC_EXEC_DSB",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x7d,
+        .desc = "DSB barrier speculatively executed"
+       },
+       {.name = "BARRIER_SPEC_EXEC_DMB",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x7e,
+        .desc = "DMB barrier speculatively executed"
+       },
+       {.name = "EXCEPTION_UNDEF",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x81,
+        .desc = "Exception taken, other synchronous"
+       },
+       {.name = "EXCEPTION_SVC",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x82,
+        .desc = "Exception taken, supervisor call"
+       },
+       {.name = "EXCEPTION_PABORT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x83,
+        .desc = "Exception taken, instruction abort"
+       },
+       {.name = "EXCEPTION_DABORT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x84,
+        .desc = "Exception taken, data abort or SError"
+       },
+       {.name = "EXCEPTION_IRQ",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x86,
+        .desc = "Exception taken, irq"
+       },
+       {.name = "EXCEPTION_FIQ",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x87,
+        .desc = "Exception taken, irq"
+       },
+       {.name = "EXCEPTION_HVC",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x8a,
+        .desc = "Exception taken, hypervisor call"
+       },
+       {.name = "EXCEPTION_TRAP_PABORT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x8b,
+        .desc = "Exception taken, instruction abort not taken locally"
+       },
+       {.name = "EXCEPTION_TRAP_DABORT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x8c,
+        .desc = "Exception taken, data abort or SError not taken locally"
+       },
+       {.name = "EXCEPTION_TRAP_OTHER",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x8d,
+        .desc = "Exception taken, other traps not taken locally"
+       },
+       {.name = "EXCEPTION_TRAP_IRQ",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x8e,
+        .desc = "Exception taken, irq not taken locally"
+       },
+       {.name = "EXCEPTION_TRAP_FIQ",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x8f,
+        .desc = "Exception taken, fiq not taken locally"
+       },
+       {.name = "RC_LD_SPEC",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x90,
+        .desc = "Release consistency instruction speculatively executed 
(load-acquire)",
+       },
+       {.name = "RC_ST_SPEC",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x91,
+        .desc = "Release consistency instruction speculatively executed 
(store-release)",
+       },
+       {.name = "INST_SPEC_EXEC_NOP",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x100,
+        .desc = "Operation speculatively executed - NOP",
+       },
+       {.name = "FSU_CLOCK_OFF",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x101,
+        .desc = "FSU clocking gated off cycle",
+       },
+       {.name = "BTB_MISPREDICT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x102,
+        .desc = "BTB misprediction",
+       },
+       {.name = "ITB_MISS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x103,
+        .desc = "ITB miss",
+       },
+       {.name = "DTB_MISS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x104,
+        .desc = "DTB miss",
+       },
+       {.name = "L1D_CACHE_LATE_MISS",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x105,
+        .desc = "L1 data cache late miss",
+       },
+       {.name = "L1D_CACHE_PREFETCH",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x106,
+        .desc = "L1 data cache prefetch request",
+       },
+       {.name = "L2_CACHE_PREFETCH",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x107,
+        .desc = "L2 data prefetch request",
+       },
+       {.name = "STALLED_CYCLES_FRONTEND",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x108,
+        .desc = "Decode starved for instruction cycle",
+       },
+       {.name = "STALLED_CYCLES_BACKEND",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x109,
+        .desc = "Op dispatch stalled cycle",
+       },
+       {.name = "IXA_NO_ISSUE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x10A,
+        .desc = "IXA Op non-issue",
+       },
+       {.name = "IXB_NO_ISSUE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x10B,
+        .desc = "IXB Op non-issue",
+       },
+       {.name = "BX_NO_ISSUE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x10C,
+        .desc = "BX Op non-issue",
+       },
+       {.name = "LX_NO_ISSUE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x10D,
+        .desc = "LX Op non-issue",
+       },
+       {.name = "SX_NO_ISSUE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x10E,
+        .desc = "SX Op non-issue",
+       },
+       {.name = "FX_NO_ISSUE",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x10F,
+        .desc = "FX Op non-issue",
+       },
+       {.name = "WAIT_CYCLES",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x110,
+        .desc = "Wait state cycle",
+       },
+       {.name = "L1_STAGE2_TLB_REFILL",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x111,
+        .desc = "L1 stage-2 TLB refill",
+       },
+       {.name = "PAGE_WALK_L0_STAGE1_HIT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x112,
+        .desc = "Page Walk Cache level-0 stage-1 hit",
+       },
+       {.name = "PAGE_WALK_L1_STAGE1_HIT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x113,
+        .desc = "Page Walk Cache level-1 stage-1 hit",
+       },
+       {.name = "PAGE_WALK_L2_STAGE1_HIT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x114,
+        .desc = "Page Walk Cache level-2 stage-1 hit",
+       },
+       {.name = "PAGE_WALK_L1_STAGE2_HIT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x115,
+        .desc = "Page Walk Cache level-1 stage-2 hit",
+       },
+       {.name = "PAGE_WALK_L2_STAGE2_HIT",
+        .modmsk = ARMV8_ATTRS,
+        .code = 0x116,
+        .desc = "Page Walk Cache level-2 stage-2 hit",
+       },
+       /* END Applied Micro X-Gene specific events */
+};
diff --git a/lib/pfmlib_arm_armv8.c b/lib/pfmlib_arm_armv8.c
index c38bd9b..3619508 100644
--- a/lib/pfmlib_arm_armv8.c
+++ b/lib/pfmlib_arm_armv8.c
@@ -32,6 +32,7 @@
 
 #include "events/arm_cortex_a57_events.h"    /* A57 event tables */
 #include "events/arm_cortex_a53_events.h"    /* A53 event tables */
+#include "events/arm_xgene_events.h"         /* Applied Micro X-Gene tables */
 
 static int
 pfm_arm_detect_cortex_a57(void *this)
@@ -65,6 +66,22 @@ pfm_arm_detect_cortex_a53(void *this)
        return PFM_ERR_NOTSUPP;
 }
 
+static int
+pfm_arm_detect_xgene(void *this)
+{
+       int ret;
+
+       ret = pfm_arm_detect(this);
+       if (ret != PFM_SUCCESS)
+               return PFM_ERR_NOTSUPP;
+
+       if ((pfm_arm_cfg.implementer == 0x50) && /* Applied Micro */
+               (pfm_arm_cfg.part == 0x000)) { /* Applied Micro X-Gene */
+                       return PFM_SUCCESS;
+       }
+       return PFM_ERR_NOTSUPP;
+}
+
 /* ARM Cortex A57 support */
 pfmlib_pmu_t arm_cortex_a57_support={
        .desc                   = "ARM Cortex A57",
@@ -114,3 +131,28 @@ pfmlib_pmu_t arm_cortex_a53_support={
         PFMLIB_VALID_PERF_PATTRS(pfm_arm_perf_validate_pattrs),
        .get_event_nattrs       = pfm_arm_get_event_nattrs,
 };
+
+/* Applied Micro X-Gene support */
+pfmlib_pmu_t arm_xgene_support={
+       .desc                   = "Applied Micro X-Gene",
+       .name                   = "arm_xgene",
+       .pmu                    = PFM_PMU_ARM_XGENE,
+       .pme_count              = LIBPFM_ARRAY_SIZE(arm_xgene_pe),
+       .type                   = PFM_PMU_TYPE_CORE,
+       .pe                     = arm_xgene_pe,
+
+       .pmu_detect             = pfm_arm_detect_xgene,
+       .max_encoding           = 1,
+       .num_cntrs              = 6,
+
+       .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 ebe20da..569ce85 100644
--- a/lib/pfmlib_common.c
+++ b/lib/pfmlib_common.c
@@ -201,10 +201,12 @@ static pfmlib_pmu_t *pfmlib_pmus[]=
        &arm_qcom_krait_support,
        &arm_cortex_a57_support,
        &arm_cortex_a53_support,
+       &arm_xgene_support,
 #endif
 #ifdef CONFIG_PFMLIB_ARCH_ARM64
        &arm_cortex_a57_support,
        &arm_cortex_a53_support,
+       &arm_xgene_support,
 #endif
 
 #ifdef CONFIG_PFMLIB_ARCH_S390X
diff --git a/lib/pfmlib_priv.h b/lib/pfmlib_priv.h
index 5678cc0..1666bcb 100644
--- a/lib/pfmlib_priv.h
+++ b/lib/pfmlib_priv.h
@@ -334,6 +334,7 @@ extern pfmlib_pmu_t arm_1176_support;
 extern pfmlib_pmu_t arm_qcom_krait_support;
 extern pfmlib_pmu_t arm_cortex_a57_support;
 extern pfmlib_pmu_t arm_cortex_a53_support;
+extern pfmlib_pmu_t arm_xgene_support;
 extern pfmlib_pmu_t mips_74k_support;
 extern pfmlib_pmu_t s390x_cpum_cf_support;
 extern pfmlib_pmu_t s390x_cpum_sf_support;
diff --git a/tests/validate_arm64.c b/tests/validate_arm64.c
index 61400ac..f4593de 100644
--- a/tests/validate_arm64.c
+++ b/tests/validate_arm64.c
@@ -114,6 +114,34 @@ static const test_event_t arm64_test_events[]={
          .codes[0] = 0x8000007,
          .fstr = "arm_ac53::ST_RETIRED:k=1:u=1:hv=0",
        },
+       { SRC_LINE,
+         .name = "arm_xgene::CPU_CYCLES",
+         .ret  = PFM_SUCCESS,
+         .count = 1,
+         .codes[0] = 0x8000011,
+         .fstr = "arm_xgene::CPU_CYCLES:k=1:u=1:hv=0",
+       },
+       { SRC_LINE,
+         .name = "arm_xgene::CPU_CYCLES:k",
+         .ret  = PFM_SUCCESS,
+         .count = 1,
+         .codes[0] = 0x88000011,
+         .fstr = "arm_xgene::CPU_CYCLES:k=1:u=0:hv=0",
+       },
+       { SRC_LINE,
+         .name = "arm_xgene::CPU_CYCLES:k:u",
+         .ret  = PFM_SUCCESS,
+         .count = 1,
+         .codes[0] = 0x8000011,
+         .fstr = "arm_xgene::CPU_CYCLES:k=1:u=1:hv=0",
+       },
+       { SRC_LINE,
+         .name = "arm_xgene::INST_RETIRED",
+         .ret  = PFM_SUCCESS,
+         .count = 1,
+         .codes[0] = 0x8000008,
+         .fstr = "arm_xgene::INST_RETIRED:k=1:u=1:hv=0",
+       },
 };
 #define NUM_TEST_EVENTS (int)(sizeof(arm64_test_events)/sizeof(test_event_t))
 
-- 
1.9.3


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their 
applications. Written by three acclaimed leaders in the field, 
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech
_______________________________________________
perfmon2-devel mailing list
perfmon2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel

Reply via email to