From da11e1f9ee3c4d9df111c31b207f67aac824541c Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 12 Aug 2020 10:17:17 +0000 Subject: [PATCH] Add support for Cortex-A76/Neoverse-N1 to hwpmc This adds support for the Cortex-A76 and Neoverse-N1 PMU counters to pmc. While here add more PMCR_IDCODE values and check the implementers code is correct before setting the PMU type. Reviewed by: bz, emaste (looks reasonable to me) Sponsored by: Innovate UK Differential Revision: https://reviews.freebsd.org/D25959 --- lib/libpmc/libpmc.c | 22 +++++++++++++++++++ sys/arm64/include/armreg.h | 15 ++++++++++--- sys/dev/hwpmc/hwpmc_arm64.c | 24 +++++++++++++++------ sys/dev/hwpmc/pmc_events.h | 43 ++++++++++++++++++++++++++++++++----- sys/sys/pmc.h | 3 ++- 5 files changed, 92 insertions(+), 15 deletions(-) diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c index 6e39373c1cb4..7d435cab0ff0 100644 --- a/lib/libpmc/libpmc.c +++ b/lib/libpmc/libpmc.c @@ -176,6 +176,11 @@ static const struct pmc_event_descr cortex_a57_event_table[] = __PMC_EV_ALIAS_ARMV8_CORTEX_A57() }; +static const struct pmc_event_descr cortex_a76_event_table[] = +{ + __PMC_EV_ALIAS_ARMV8_CORTEX_A76() +}; + /* * PMC_MDEP_TABLE(NAME, PRIMARYCLASS, ADDITIONAL_CLASSES...) * @@ -193,6 +198,7 @@ PMC_MDEP_TABLE(cortex_a8, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7); PMC_MDEP_TABLE(cortex_a9, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7); PMC_MDEP_TABLE(cortex_a53, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8); PMC_MDEP_TABLE(cortex_a57, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8); +PMC_MDEP_TABLE(cortex_a76, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8); PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K); PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); @@ -235,6 +241,7 @@ PMC_CLASS_TABLE_DESC(cortex_a9, ARMV7, cortex_a9, armv7); #if defined(__aarch64__) PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64); PMC_CLASS_TABLE_DESC(cortex_a57, ARMV8, cortex_a57, arm64); +PMC_CLASS_TABLE_DESC(cortex_a76, ARMV8, cortex_a76, arm64); #endif #if defined(__mips__) PMC_CLASS_TABLE_DESC(beri, BERI, beri, mips); @@ -817,6 +824,9 @@ static struct pmc_event_alias cortex_a53_aliases[] = { static struct pmc_event_alias cortex_a57_aliases[] = { EV_ALIAS(NULL, NULL) }; +static struct pmc_event_alias cortex_a76_aliases[] = { + EV_ALIAS(NULL, NULL) +}; static int arm64_allocate_pmc(enum pmc_event pe, char *ctrspec __unused, struct pmc_op_pmcallocate *pmc_config __unused) @@ -1273,6 +1283,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames, ev = cortex_a57_event_table; count = PMC_EVENT_TABLE_SIZE(cortex_a57); break; + case PMC_CPU_ARMV8_CORTEX_A76: + ev = cortex_a76_event_table; + count = PMC_EVENT_TABLE_SIZE(cortex_a76); + break; } break; case PMC_CLASS_BERI: @@ -1518,6 +1532,10 @@ pmc_init(void) PMC_MDEP_INIT(cortex_a57); pmc_class_table[n] = &cortex_a57_class_table_descr; break; + case PMC_CPU_ARMV8_CORTEX_A76: + PMC_MDEP_INIT(cortex_a76); + pmc_class_table[n] = &cortex_a76_class_table_descr; + break; #endif #if defined(__mips__) case PMC_CPU_MIPS_BERI: @@ -1658,6 +1676,10 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu) ev = cortex_a57_event_table; evfence = cortex_a57_event_table + PMC_EVENT_TABLE_SIZE(cortex_a57); break; + case PMC_CPU_ARMV8_CORTEX_A76: + ev = cortex_a76_event_table; + evfence = cortex_a76_event_table + PMC_EVENT_TABLE_SIZE(cortex_a76); + break; default: /* Unknown CPU type. */ break; } diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index c5091e93efe2..9cac6fce439b 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -857,11 +857,20 @@ #define PMCR_LC (1 << 6) /* Long cycle count enable */ #define PMCR_IMP_SHIFT 24 /* Implementer code */ #define PMCR_IMP_MASK (0xff << PMCR_IMP_SHIFT) +#define PMCR_IMP_ARM 0x41 #define PMCR_IDCODE_SHIFT 16 /* Identification code */ #define PMCR_IDCODE_MASK (0xff << PMCR_IDCODE_SHIFT) -#define PMCR_IDCODE_CORTEX_A57 0x01 -#define PMCR_IDCODE_CORTEX_A72 0x02 -#define PMCR_IDCODE_CORTEX_A53 0x03 +#define PMCR_IDCODE_CORTEX_A57 0x01 +#define PMCR_IDCODE_CORTEX_A72 0x02 +#define PMCR_IDCODE_CORTEX_A53 0x03 +#define PMCR_IDCODE_CORTEX_A73 0x04 +#define PMCR_IDCODE_CORTEX_A35 0x0a +#define PMCR_IDCODE_CORTEX_A76 0x0b +#define PMCR_IDCODE_NEOVERSE_N1 0x0c +#define PMCR_IDCODE_CORTEX_A77 0x10 +#define PMCR_IDCODE_CORTEX_A55 0x45 +#define PMCR_IDCODE_NEOVERSE_E1 0x46 +#define PMCR_IDCODE_CORTEX_A75 0x4a #define PMCR_N_SHIFT 11 /* Number of counters implemented */ #define PMCR_N_MASK (0x1f << PMCR_N_SHIFT) diff --git a/sys/dev/hwpmc/hwpmc_arm64.c b/sys/dev/hwpmc/hwpmc_arm64.c index 2618a889e86f..4ae8645abaf6 100644 --- a/sys/dev/hwpmc/hwpmc_arm64.c +++ b/sys/dev/hwpmc/hwpmc_arm64.c @@ -479,11 +479,12 @@ pmc_arm64_initialize() { struct pmc_mdep *pmc_mdep; struct pmc_classdep *pcd; - int idcode; + int idcode, impcode; int reg; reg = arm64_pmcr_read(); arm64_npmcs = (reg & PMCR_N_MASK) >> PMCR_N_SHIFT; + impcode = (reg & PMCR_IMP_MASK) >> PMCR_IMP_SHIFT; idcode = (reg & PMCR_IDCODE_MASK) >> PMCR_IDCODE_SHIFT; PMCDBG1(MDP, INI, 1, "arm64-init npmcs=%d", arm64_npmcs); @@ -498,13 +499,24 @@ pmc_arm64_initialize() /* Just one class */ pmc_mdep = pmc_mdep_alloc(1); - switch (idcode) { - case PMCR_IDCODE_CORTEX_A57: - case PMCR_IDCODE_CORTEX_A72: - pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A57; + switch(impcode) { + case PMCR_IMP_ARM: + switch (idcode) { + case PMCR_IDCODE_CORTEX_A76: + case PMCR_IDCODE_NEOVERSE_N1: + pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A76; + break; + case PMCR_IDCODE_CORTEX_A57: + case PMCR_IDCODE_CORTEX_A72: + pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A57; + break; + default: + case PMCR_IDCODE_CORTEX_A53: + pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53; + break; + } break; default: - case PMCR_IDCODE_CORTEX_A53: pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53; break; } diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h index 6f7282f8ea55..cb3c299b3aab 100644 --- a/sys/dev/hwpmc/pmc_events.h +++ b/sys/dev/hwpmc/pmc_events.h @@ -955,7 +955,7 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC) __PMC_EV_ALIAS("BR_RETURN_RETIRED", ARMV8_EVENT_0EH) \ __PMC_EV_ALIAS("UNALIGNED_LDST_RETIRED",ARMV8_EVENT_0FH) -#define __PMC_EV_ALIAS_ARMV8_CORTEX_A57() \ +#define __PMC_EV_ALIAS_ARMV8_CORTEX_A57_A76() \ __PMC_EV_ALIAS_ARMV8_COMMON() \ __PMC_EV_ALIAS("INST_SPEC", ARMV8_EVENT_1BH) \ __PMC_EV_ALIAS("TTBR_WRITE_RETIRED", ARMV8_EVENT_1CH) \ @@ -975,10 +975,6 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC) __PMC_EV_ALIAS("L2D_CACHE_WB_VICTIM", ARMV8_EVENT_56H) \ __PMC_EV_ALIAS("L2D_CACHE_WB_CLEAN", ARMV8_EVENT_57H) \ __PMC_EV_ALIAS("L2D_CACHE_INVAL", ARMV8_EVENT_58H) \ - __PMC_EV_ALIAS("BUS_ACCESS_SHARED", ARMV8_EVENT_62H) \ - __PMC_EV_ALIAS("BUS_ACCESS_NOT_SHARED", ARMV8_EVENT_63H) \ - __PMC_EV_ALIAS("BUS_ACCESS_NORMAL", ARMV8_EVENT_64H) \ - __PMC_EV_ALIAS("BUS_ACCESS_PERIPH", ARMV8_EVENT_65H) \ __PMC_EV_ALIAS("MEM_ACCESS_LD", ARMV8_EVENT_66H) \ __PMC_EV_ALIAS("MEM_ACCESS_ST", ARMV8_EVENT_67H) \ __PMC_EV_ALIAS("UNALIGNED_LD_SPEC", ARMV8_EVENT_68H) \ @@ -1014,6 +1010,43 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC) __PMC_EV_ALIAS("RC_LD_SPEC", ARMV8_EVENT_90H) \ __PMC_EV_ALIAS("RC_ST_SPEC", ARMV8_EVENT_91H) +#define __PMC_EV_ALIAS_ARMV8_CORTEX_A57() \ + __PMC_EV_ALIAS_ARMV8_CORTEX_A57_A76() \ + __PMC_EV_ALIAS("BUS_ACCESS_SHARED", ARMV8_EVENT_62H) \ + __PMC_EV_ALIAS("BUS_ACCESS_NOT_SHARED", ARMV8_EVENT_63H) \ + __PMC_EV_ALIAS("BUS_ACCESS_NORMAL", ARMV8_EVENT_64H) \ + __PMC_EV_ALIAS("BUS_ACCESS_PERIPH", ARMV8_EVENT_65H) + +#define __PMC_EV_ALIAS_ARMV8_CORTEX_A76() \ + __PMC_EV_ALIAS_ARMV8_CORTEX_A57_A76() \ + __PMC_EV_ALIAS("L2D_CACHE_ALLOCATE", ARMV8_EVENT_20H) \ + __PMC_EV_ALIAS("BR_RETIRED", ARMV8_EVENT_21H) \ + __PMC_EV_ALIAS("BR_MIS_PRED_RETIRED", ARMV8_EVENT_22H) \ + __PMC_EV_ALIAS("STALL_FRONTEND", ARMV8_EVENT_23H) \ + __PMC_EV_ALIAS("STALL_BACKEND", ARMV8_EVENT_24H) \ + __PMC_EV_ALIAS("L1D_TLB", ARMV8_EVENT_25H) \ + __PMC_EV_ALIAS("L1I_TLB", ARMV8_EVENT_26H) \ + __PMC_EV_ALIAS("L3D_CACHE_ALLOCATE", ARMV8_EVENT_29H) \ + __PMC_EV_ALIAS("L3D_CACHE_REFILL", ARMV8_EVENT_2AH) \ + __PMC_EV_ALIAS("L3D_CACHE", ARMV8_EVENT_2BH) \ + __PMC_EV_ALIAS("L2D_TLB_REFILL", ARMV8_EVENT_2DH) \ + __PMC_EV_ALIAS("L2D_TLB", ARMV8_EVENT_2FH) \ + __PMC_EV_ALIAS("REMOTE_ACCESS", ARMV8_EVENT_31H) \ + __PMC_EV_ALIAS("DTLB_WALK", ARMV8_EVENT_34H) \ + __PMC_EV_ALIAS("ITLB_WALK", ARMV8_EVENT_35H) \ + __PMC_EV_ALIAS("LL_CACHE_RD", ARMV8_EVENT_36H) \ + __PMC_EV_ALIAS("LL_CACHE_MISS_RD", ARMV8_EVENT_37H) \ + __PMC_EV_ALIAS("L1D_CACHE_REFILL_INNER", ARMV8_EVENT_44H) \ + __PMC_EV_ALIAS("L1D_CACHE_REFILL_OUTER", ARMV8_EVENT_45H) \ + __PMC_EV_ALIAS("L1D_TLB_RD", ARMV8_EVENT_4EH) \ + __PMC_EV_ALIAS("L1D_TLB_WR", ARMV8_EVENT_4FH) \ + __PMC_EV_ALIAS("L2D_TLB_REFILL_RD", ARMV8_EVENT_5CH) \ + __PMC_EV_ALIAS("L2D_TLB_REFILL_WR", ARMV8_EVENT_5DH) \ + __PMC_EV_ALIAS("L2D_TLB_RD", ARMV8_EVENT_5EH) \ + __PMC_EV_ALIAS("L2D_TLB_WR", ARMV8_EVENT_5FH) \ + __PMC_EV_ALIAS("STREX_SPEC", ARMV8_EVENT_6FH) \ + __PMC_EV_ALIAS("L3_CACHE_RD", ARMV8_EVENT_A0H) + /* * MIPS Events from "Programming the MIPS32 24K Core Family", * Document Number: MD00355 Revision 04.63 December 19, 2008 diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h index 7e14df30bff8..224d84c484f4 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -127,7 +127,8 @@ extern char pmc_cpuid[PMC_CPUID_LEN]; __PMC_CPU(ARMV7_CORTEX_A15, 0x504, "ARMv7 Cortex A15") \ __PMC_CPU(ARMV7_CORTEX_A17, 0x505, "ARMv7 Cortex A17") \ __PMC_CPU(ARMV8_CORTEX_A53, 0x600, "ARMv8 Cortex A53") \ - __PMC_CPU(ARMV8_CORTEX_A57, 0x601, "ARMv8 Cortex A57") + __PMC_CPU(ARMV8_CORTEX_A57, 0x601, "ARMv8 Cortex A57") \ + __PMC_CPU(ARMV8_CORTEX_A76, 0x602, "ARMv8 Cortex A76") enum pmc_cputype { #undef __PMC_CPU