libpmc.c (6bb7ba4aa180f667c1b558de1fc364f41bab57ce) libpmc.c (e3572eb654733a94e1e765fe9e95e0579981d851)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2003-2008 Joseph Koshy
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 51 unchanged lines hidden (view full) ---

60#endif
61#if defined(__arm__)
62static int armv7_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
63 struct pmc_op_pmcallocate *_pmc_config);
64#endif
65#if defined(__aarch64__)
66static int arm64_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
67 struct pmc_op_pmcallocate *_pmc_config);
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2003-2008 Joseph Koshy
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 51 unchanged lines hidden (view full) ---

60#endif
61#if defined(__arm__)
62static int armv7_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
63 struct pmc_op_pmcallocate *_pmc_config);
64#endif
65#if defined(__aarch64__)
66static int arm64_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
67 struct pmc_op_pmcallocate *_pmc_config);
68static int cmn600_pmu_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
69 struct pmc_op_pmcallocate *_pmc_config);
70static int dmc620_pmu_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
71 struct pmc_op_pmcallocate *_pmc_config);
68#endif
69static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
70 struct pmc_op_pmcallocate *_pmc_config);
71
72#if defined(__powerpc__)
73static int powerpc_allocate_pmc(enum pmc_event _pe, char* ctrspec,
74 struct pmc_op_pmcallocate *_pmc_config);
75#endif /* __powerpc__ */

--- 53 unchanged lines hidden (view full) ---

129 { \
130 __PMC_EV_##C() \
131 }
132
133PMC_CLASSDEP_TABLE(iaf, IAF);
134PMC_CLASSDEP_TABLE(k8, K8);
135PMC_CLASSDEP_TABLE(armv7, ARMV7);
136PMC_CLASSDEP_TABLE(armv8, ARMV8);
72#endif
73static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
74 struct pmc_op_pmcallocate *_pmc_config);
75
76#if defined(__powerpc__)
77static int powerpc_allocate_pmc(enum pmc_event _pe, char* ctrspec,
78 struct pmc_op_pmcallocate *_pmc_config);
79#endif /* __powerpc__ */

--- 53 unchanged lines hidden (view full) ---

133 { \
134 __PMC_EV_##C() \
135 }
136
137PMC_CLASSDEP_TABLE(iaf, IAF);
138PMC_CLASSDEP_TABLE(k8, K8);
139PMC_CLASSDEP_TABLE(armv7, ARMV7);
140PMC_CLASSDEP_TABLE(armv8, ARMV8);
141PMC_CLASSDEP_TABLE(cmn600_pmu, CMN600_PMU);
142PMC_CLASSDEP_TABLE(dmc620_pmu_cd2, DMC620_PMU_CD2);
143PMC_CLASSDEP_TABLE(dmc620_pmu_c, DMC620_PMU_C);
137PMC_CLASSDEP_TABLE(ppc7450, PPC7450);
138PMC_CLASSDEP_TABLE(ppc970, PPC970);
139PMC_CLASSDEP_TABLE(e500, E500);
140
141static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT];
142
143#undef __PMC_EV_ALIAS
144#define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE },

--- 60 unchanged lines hidden (view full) ---

205#if defined(__arm__)
206PMC_CLASS_TABLE_DESC(cortex_a8, ARMV7, cortex_a8, armv7);
207PMC_CLASS_TABLE_DESC(cortex_a9, ARMV7, cortex_a9, armv7);
208#endif
209#if defined(__aarch64__)
210PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64);
211PMC_CLASS_TABLE_DESC(cortex_a57, ARMV8, cortex_a57, arm64);
212PMC_CLASS_TABLE_DESC(cortex_a76, ARMV8, cortex_a76, arm64);
144PMC_CLASSDEP_TABLE(ppc7450, PPC7450);
145PMC_CLASSDEP_TABLE(ppc970, PPC970);
146PMC_CLASSDEP_TABLE(e500, E500);
147
148static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT];
149
150#undef __PMC_EV_ALIAS
151#define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE },

--- 60 unchanged lines hidden (view full) ---

212#if defined(__arm__)
213PMC_CLASS_TABLE_DESC(cortex_a8, ARMV7, cortex_a8, armv7);
214PMC_CLASS_TABLE_DESC(cortex_a9, ARMV7, cortex_a9, armv7);
215#endif
216#if defined(__aarch64__)
217PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64);
218PMC_CLASS_TABLE_DESC(cortex_a57, ARMV8, cortex_a57, arm64);
219PMC_CLASS_TABLE_DESC(cortex_a76, ARMV8, cortex_a76, arm64);
220PMC_CLASS_TABLE_DESC(cmn600_pmu, CMN600_PMU, cmn600_pmu, cmn600_pmu);
221PMC_CLASS_TABLE_DESC(dmc620_pmu_cd2, DMC620_PMU_CD2, dmc620_pmu_cd2, dmc620_pmu);
222PMC_CLASS_TABLE_DESC(dmc620_pmu_c, DMC620_PMU_C, dmc620_pmu_c, dmc620_pmu);
213#endif
214#if defined(__powerpc__)
215PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, powerpc);
216PMC_CLASS_TABLE_DESC(ppc970, PPC970, ppc970, powerpc);
217PMC_CLASS_TABLE_DESC(e500, E500, e500, powerpc);
218#endif
219
220static struct pmc_class_descr soft_class_table_descr =

--- 555 unchanged lines hidden (view full) ---

776 else if (KWMATCH(p, "usr"))
777 pmc_config->pm_caps |= PMC_CAP_USER;
778 else
779 return (-1);
780 }
781
782 return (0);
783}
223#endif
224#if defined(__powerpc__)
225PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, powerpc);
226PMC_CLASS_TABLE_DESC(ppc970, PPC970, ppc970, powerpc);
227PMC_CLASS_TABLE_DESC(e500, E500, e500, powerpc);
228#endif
229
230static struct pmc_class_descr soft_class_table_descr =

--- 555 unchanged lines hidden (view full) ---

786 else if (KWMATCH(p, "usr"))
787 pmc_config->pm_caps |= PMC_CAP_USER;
788 else
789 return (-1);
790 }
791
792 return (0);
793}
794
795static int
796cmn600_pmu_allocate_pmc(enum pmc_event pe, char *ctrspec,
797 struct pmc_op_pmcallocate *pmc_config)
798{
799 uint32_t nodeid, occupancy, xpport, xpchannel;
800 char *e, *p, *q;
801 unsigned int i;
802 char *xpport_names[] = { "East", "West", "North", "South", "devport0",
803 "devport1" };
804 char *xpchannel_names[] = { "REQ", "RSP", "SNP", "DAT" };
805
806 pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
807 pmc_config->pm_caps |= PMC_CAP_SYSTEM;
808 pmc_config->pm_md.pm_cmn600.pma_cmn600_config = 0;
809 /*
810 * CMN600 extra fields:
811 * * nodeid - node coordinates x[2-3],y[2-3],p[1],s[2]
812 * width of x and y fields depend on matrix size.
813 * * occupancy - numeric value to select desired filter.
814 * * xpport - East, West, North, South, devport0, devport1 (or 0, 1, ..., 5)
815 * * xpchannel - REQ, RSP, SNP, DAT (or 0, 1, 2, 3)
816 */
817
818 while ((p = strsep(&ctrspec, ",")) != NULL) {
819 if (KWPREFIXMATCH(p, "nodeid=")) {
820 q = strchr(p, '=');
821 if (*++q == '\0') /* skip '=' */
822 return (-1);
823
824 nodeid = strtol(q, &e, 0);
825 if (e == q || *e != '\0')
826 return (-1);
827
828 pmc_config->pm_md.pm_cmn600.pma_cmn600_nodeid |= nodeid;
829
830 } else if (KWPREFIXMATCH(p, "occupancy=")) {
831 q = strchr(p, '=');
832 if (*++q == '\0') /* skip '=' */
833 return (-1);
834
835 occupancy = strtol(q, &e, 0);
836 if (e == q || *e != '\0')
837 return (-1);
838
839 pmc_config->pm_md.pm_cmn600.pma_cmn600_occupancy = occupancy;
840 } else if (KWPREFIXMATCH(p, "xpport=")) {
841 q = strchr(p, '=');
842 if (*++q == '\0') /* skip '=' */
843 return (-1);
844
845 xpport = strtol(q, &e, 0);
846 if (e == q || *e != '\0') {
847 for (i = 0; i < nitems(xpport_names); i++) {
848 if (strcasecmp(xpport_names[i], q) == 0) {
849 xpport = i;
850 break;
851 }
852 }
853 if (i == nitems(xpport_names))
854 return (-1);
855 }
856
857 pmc_config->pm_md.pm_cmn600.pma_cmn600_config |= xpport << 2;
858 } else if (KWPREFIXMATCH(p, "xpchannel=")) {
859 q = strchr(p, '=');
860 if (*++q == '\0') /* skip '=' */
861 return (-1);
862
863 xpchannel = strtol(q, &e, 0);
864 if (e == q || *e != '\0') {
865 for (i = 0; i < nitems(xpchannel_names); i++) {
866 if (strcasecmp(xpchannel_names[i], q) == 0) {
867 xpchannel = i;
868 break;
869 }
870 }
871 if (i == nitems(xpchannel_names))
872 return (-1);
873 }
874
875 pmc_config->pm_md.pm_cmn600.pma_cmn600_config |= xpchannel << 5;
876 } else
877 return (-1);
878 }
879
880 return (0);
881}
882
883static int
884dmc620_pmu_allocate_pmc(enum pmc_event pe, char *ctrspec,
885 struct pmc_op_pmcallocate *pmc_config)
886{
887 char *e, *p, *q;
888 uint64_t match, mask;
889 uint32_t count;
890
891 pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
892 pmc_config->pm_caps |= PMC_CAP_SYSTEM;
893 pmc_config->pm_md.pm_dmc620.pm_dmc620_config = 0;
894
895 while ((p = strsep(&ctrspec, ",")) != NULL) {
896 if (KWPREFIXMATCH(p, "count=")) {
897 q = strchr(p, '=');
898 if (*++q == '\0') /* skip '=' */
899 return (-1);
900
901 count = strtol(q, &e, 0);
902 if (e == q || *e != '\0')
903 return (-1);
904
905 pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
906 pmc_config->pm_md.pm_dmc620.pm_dmc620_config |= count;
907
908 } else if (KWMATCH(p, "inv")) {
909 pmc_config->pm_caps |= PMC_CAP_INVERT;
910 } else if (KWPREFIXMATCH(p, "match=")) {
911 match = strtol(q, &e, 0);
912 if (e == q || *e != '\0')
913 return (-1);
914
915 pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
916 pmc_config->pm_md.pm_dmc620.pm_dmc620_match = match;
917 } else if (KWPREFIXMATCH(p, "mask=")) {
918 q = strchr(p, '=');
919 if (*++q == '\0') /* skip '=' */
920 return (-1);
921
922 mask = strtol(q, &e, 0);
923 if (e == q || *e != '\0')
924 return (-1);
925
926 pmc_config->pm_md.pm_dmc620.pm_dmc620_mask = mask;
927 pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
928 } else
929 return (-1);
930 }
931
932 return (0);
933}
784#endif
785
786#if defined(__powerpc__)
787
788static struct pmc_event_alias ppc7450_aliases[] = {
789 EV_ALIAS("instructions", "INSTR_COMPLETED"),
790 EV_ALIAS("branches", "BRANCHES_COMPLETED"),
791 EV_ALIAS("branch-mispredicts", "MISPREDICTED_BRANCHES"),

--- 359 unchanged lines hidden (view full) ---

1151 count = PMC_EVENT_TABLE_SIZE(cortex_a57);
1152 break;
1153 case PMC_CPU_ARMV8_CORTEX_A76:
1154 ev = cortex_a76_event_table;
1155 count = PMC_EVENT_TABLE_SIZE(cortex_a76);
1156 break;
1157 }
1158 break;
934#endif
935
936#if defined(__powerpc__)
937
938static struct pmc_event_alias ppc7450_aliases[] = {
939 EV_ALIAS("instructions", "INSTR_COMPLETED"),
940 EV_ALIAS("branches", "BRANCHES_COMPLETED"),
941 EV_ALIAS("branch-mispredicts", "MISPREDICTED_BRANCHES"),

--- 359 unchanged lines hidden (view full) ---

1301 count = PMC_EVENT_TABLE_SIZE(cortex_a57);
1302 break;
1303 case PMC_CPU_ARMV8_CORTEX_A76:
1304 ev = cortex_a76_event_table;
1305 count = PMC_EVENT_TABLE_SIZE(cortex_a76);
1306 break;
1307 }
1308 break;
1309 case PMC_CLASS_CMN600_PMU:
1310 ev = cmn600_pmu_event_table;
1311 count = PMC_EVENT_TABLE_SIZE(cmn600_pmu);
1312 break;
1313 case PMC_CLASS_DMC620_PMU_CD2:
1314 ev = dmc620_pmu_cd2_event_table;
1315 count = PMC_EVENT_TABLE_SIZE(dmc620_pmu_cd2);
1316 break;
1317 case PMC_CLASS_DMC620_PMU_C:
1318 ev = dmc620_pmu_c_event_table;
1319 count = PMC_EVENT_TABLE_SIZE(dmc620_pmu_c);
1320 break;
1159 case PMC_CLASS_PPC7450:
1160 ev = ppc7450_event_table;
1161 count = PMC_EVENT_TABLE_SIZE(ppc7450);
1162 break;
1163 case PMC_CLASS_PPC970:
1164 ev = ppc970_event_table;
1165 count = PMC_EVENT_TABLE_SIZE(ppc970);
1166 break;

--- 141 unchanged lines hidden (view full) ---

1308
1309 /*
1310 * Fill in the class table.
1311 */
1312 n = 0;
1313
1314 /* Fill soft events information. */
1315 pmc_class_table[n++] = &soft_class_table_descr;
1321 case PMC_CLASS_PPC7450:
1322 ev = ppc7450_event_table;
1323 count = PMC_EVENT_TABLE_SIZE(ppc7450);
1324 break;
1325 case PMC_CLASS_PPC970:
1326 ev = ppc970_event_table;
1327 count = PMC_EVENT_TABLE_SIZE(ppc970);
1328 break;

--- 141 unchanged lines hidden (view full) ---

1470
1471 /*
1472 * Fill in the class table.
1473 */
1474 n = 0;
1475
1476 /* Fill soft events information. */
1477 pmc_class_table[n++] = &soft_class_table_descr;
1478
1479 pmc_class_table[n++] = &cmn600_pmu_class_table_descr;
1480 pmc_class_table[n++] = &dmc620_pmu_cd2_class_table_descr;
1481 pmc_class_table[n++] = &dmc620_pmu_c_class_table_descr;
1316#if defined(__amd64__) || defined(__i386__)
1317 if (cpu_info.pm_cputype != PMC_CPU_GENERIC)
1318 pmc_class_table[n++] = &tsc_class_table_descr;
1319#endif
1320
1321#define PMC_MDEP_INIT(C) pmc_mdep_event_aliases = C##_aliases
1322
1323 /* Configure the event name parser. */

--- 152 unchanged lines hidden (view full) ---

1476 break;
1477 case PMC_CPU_ARMV8_CORTEX_A76:
1478 ev = cortex_a76_event_table;
1479 evfence = cortex_a76_event_table + PMC_EVENT_TABLE_SIZE(cortex_a76);
1480 break;
1481 default: /* Unknown CPU type. */
1482 break;
1483 }
1482#if defined(__amd64__) || defined(__i386__)
1483 if (cpu_info.pm_cputype != PMC_CPU_GENERIC)
1484 pmc_class_table[n++] = &tsc_class_table_descr;
1485#endif
1486
1487#define PMC_MDEP_INIT(C) pmc_mdep_event_aliases = C##_aliases
1488
1489 /* Configure the event name parser. */

--- 152 unchanged lines hidden (view full) ---

1642 break;
1643 case PMC_CPU_ARMV8_CORTEX_A76:
1644 ev = cortex_a76_event_table;
1645 evfence = cortex_a76_event_table + PMC_EVENT_TABLE_SIZE(cortex_a76);
1646 break;
1647 default: /* Unknown CPU type. */
1648 break;
1649 }
1650 } else if (pe >= PMC_EV_CMN600_PMU_FIRST &&
1651 pe <= PMC_EV_CMN600_PMU_LAST) {
1652 ev = cmn600_pmu_event_table;
1653 evfence = cmn600_pmu_event_table +
1654 PMC_EVENT_TABLE_SIZE(cmn600_pmu);
1655 } else if (pe >= PMC_EV_DMC620_PMU_CD2_FIRST &&
1656 pe <= PMC_EV_DMC620_PMU_CD2_LAST) {
1657 ev = dmc620_pmu_cd2_event_table;
1658 evfence = dmc620_pmu_cd2_event_table +
1659 PMC_EVENT_TABLE_SIZE(dmc620_pmu_cd2);
1660 } else if (pe >= PMC_EV_DMC620_PMU_C_FIRST &&
1661 pe <= PMC_EV_DMC620_PMU_C_LAST) {
1662 ev = dmc620_pmu_c_event_table;
1663 evfence = dmc620_pmu_c_event_table +
1664 PMC_EVENT_TABLE_SIZE(dmc620_pmu_c);
1484 } else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) {
1485 ev = ppc7450_event_table;
1486 evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450);
1487 } else if (pe >= PMC_EV_PPC970_FIRST && pe <= PMC_EV_PPC970_LAST) {
1488 ev = ppc970_event_table;
1489 evfence = ppc970_event_table + PMC_EVENT_TABLE_SIZE(ppc970);
1490 } else if (pe >= PMC_EV_E500_FIRST && pe <= PMC_EV_E500_LAST) {
1491 ev = e500_event_table;

--- 211 unchanged lines hidden ---
1665 } else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) {
1666 ev = ppc7450_event_table;
1667 evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450);
1668 } else if (pe >= PMC_EV_PPC970_FIRST && pe <= PMC_EV_PPC970_LAST) {
1669 ev = ppc970_event_table;
1670 evfence = ppc970_event_table + PMC_EVENT_TABLE_SIZE(ppc970);
1671 } else if (pe >= PMC_EV_E500_FIRST && pe <= PMC_EV_E500_LAST) {
1672 ev = e500_event_table;

--- 211 unchanged lines hidden ---