diff options
| -rw-r--r-- | arch/mips/Kconfig | 2 | ||||
| -rw-r--r-- | arch/mips/kernel/perf_event_mipsxx.c | 147 |
2 files changed, 148 insertions, 1 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 90877154f298..a92648438240 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -2101,7 +2101,7 @@ config NODES_SHIFT | |||
| 2101 | 2101 | ||
| 2102 | config HW_PERF_EVENTS | 2102 | config HW_PERF_EVENTS |
| 2103 | bool "Enable hardware performance counter support for perf events" | 2103 | bool "Enable hardware performance counter support for perf events" |
| 2104 | depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1) | 2104 | depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON) |
| 2105 | default y | 2105 | default y |
| 2106 | help | 2106 | help |
| 2107 | Enable hardware performance counter support for perf events. If | 2107 | Enable hardware performance counter support for perf events. If |
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 0c9549480c42..4f2971bcf8e5 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
| @@ -841,6 +841,16 @@ static const struct mips_perf_event mipsxx74Kcore_event_map | |||
| 841 | [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID }, | 841 | [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID }, |
| 842 | }; | 842 | }; |
| 843 | 843 | ||
| 844 | static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = { | ||
| 845 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL }, | ||
| 846 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x03, CNTR_ALL }, | ||
| 847 | [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x2b, CNTR_ALL }, | ||
| 848 | [PERF_COUNT_HW_CACHE_MISSES] = { 0x2e, CNTR_ALL }, | ||
| 849 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x08, CNTR_ALL }, | ||
| 850 | [PERF_COUNT_HW_BRANCH_MISSES] = { 0x09, CNTR_ALL }, | ||
| 851 | [PERF_COUNT_HW_BUS_CYCLES] = { 0x25, CNTR_ALL }, | ||
| 852 | }; | ||
| 853 | |||
| 844 | /* 24K/34K/1004K cores can share the same cache event map. */ | 854 | /* 24K/34K/1004K cores can share the same cache event map. */ |
| 845 | static const struct mips_perf_event mipsxxcore_cache_map | 855 | static const struct mips_perf_event mipsxxcore_cache_map |
| 846 | [PERF_COUNT_HW_CACHE_MAX] | 856 | [PERF_COUNT_HW_CACHE_MAX] |
| @@ -1074,6 +1084,102 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map | |||
| 1074 | }, | 1084 | }, |
| 1075 | }; | 1085 | }; |
| 1076 | 1086 | ||
| 1087 | |||
| 1088 | static const struct mips_perf_event octeon_cache_map | ||
| 1089 | [PERF_COUNT_HW_CACHE_MAX] | ||
| 1090 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
| 1091 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
| 1092 | [C(L1D)] = { | ||
| 1093 | [C(OP_READ)] = { | ||
| 1094 | [C(RESULT_ACCESS)] = { 0x2b, CNTR_ALL }, | ||
| 1095 | [C(RESULT_MISS)] = { 0x2e, CNTR_ALL }, | ||
| 1096 | }, | ||
| 1097 | [C(OP_WRITE)] = { | ||
| 1098 | [C(RESULT_ACCESS)] = { 0x30, CNTR_ALL }, | ||
| 1099 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1100 | }, | ||
| 1101 | [C(OP_PREFETCH)] = { | ||
| 1102 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1103 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1104 | }, | ||
| 1105 | }, | ||
| 1106 | [C(L1I)] = { | ||
| 1107 | [C(OP_READ)] = { | ||
| 1108 | [C(RESULT_ACCESS)] = { 0x18, CNTR_ALL }, | ||
| 1109 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1110 | }, | ||
| 1111 | [C(OP_WRITE)] = { | ||
| 1112 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1113 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1114 | }, | ||
| 1115 | [C(OP_PREFETCH)] = { | ||
| 1116 | [C(RESULT_ACCESS)] = { 0x19, CNTR_ALL }, | ||
| 1117 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1118 | }, | ||
| 1119 | }, | ||
| 1120 | [C(LL)] = { | ||
| 1121 | [C(OP_READ)] = { | ||
| 1122 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1123 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1124 | }, | ||
| 1125 | [C(OP_WRITE)] = { | ||
| 1126 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1127 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1128 | }, | ||
| 1129 | [C(OP_PREFETCH)] = { | ||
| 1130 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1131 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1132 | }, | ||
| 1133 | }, | ||
| 1134 | [C(DTLB)] = { | ||
| 1135 | /* | ||
| 1136 | * Only general DTLB misses are counted use the same event for | ||
| 1137 | * read and write. | ||
| 1138 | */ | ||
| 1139 | [C(OP_READ)] = { | ||
| 1140 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1141 | [C(RESULT_MISS)] = { 0x35, CNTR_ALL }, | ||
| 1142 | }, | ||
| 1143 | [C(OP_WRITE)] = { | ||
| 1144 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1145 | [C(RESULT_MISS)] = { 0x35, CNTR_ALL }, | ||
| 1146 | }, | ||
| 1147 | [C(OP_PREFETCH)] = { | ||
| 1148 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1149 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1150 | }, | ||
| 1151 | }, | ||
| 1152 | [C(ITLB)] = { | ||
| 1153 | [C(OP_READ)] = { | ||
| 1154 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1155 | [C(RESULT_MISS)] = { 0x37, CNTR_ALL }, | ||
| 1156 | }, | ||
| 1157 | [C(OP_WRITE)] = { | ||
| 1158 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1159 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1160 | }, | ||
| 1161 | [C(OP_PREFETCH)] = { | ||
| 1162 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1163 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1164 | }, | ||
| 1165 | }, | ||
| 1166 | [C(BPU)] = { | ||
| 1167 | /* Using the same code for *HW_BRANCH* */ | ||
| 1168 | [C(OP_READ)] = { | ||
| 1169 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1170 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1171 | }, | ||
| 1172 | [C(OP_WRITE)] = { | ||
| 1173 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1174 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1175 | }, | ||
| 1176 | [C(OP_PREFETCH)] = { | ||
| 1177 | [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1178 | [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, | ||
| 1179 | }, | ||
| 1180 | }, | ||
| 1181 | }; | ||
| 1182 | |||
| 1077 | #ifdef CONFIG_MIPS_MT_SMP | 1183 | #ifdef CONFIG_MIPS_MT_SMP |
| 1078 | static void check_and_calc_range(struct perf_event *event, | 1184 | static void check_and_calc_range(struct perf_event *event, |
| 1079 | const struct mips_perf_event *pev) | 1185 | const struct mips_perf_event *pev) |
| @@ -1411,6 +1517,39 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) | |||
| 1411 | return &raw_event; | 1517 | return &raw_event; |
| 1412 | } | 1518 | } |
| 1413 | 1519 | ||
| 1520 | static const struct mips_perf_event *octeon_pmu_map_raw_event(u64 config) | ||
| 1521 | { | ||
| 1522 | unsigned int raw_id = config & 0xff; | ||
| 1523 | unsigned int base_id = raw_id & 0x7f; | ||
| 1524 | |||
| 1525 | |||
| 1526 | raw_event.cntr_mask = CNTR_ALL; | ||
| 1527 | raw_event.event_id = base_id; | ||
| 1528 | |||
| 1529 | if (current_cpu_type() == CPU_CAVIUM_OCTEON2) { | ||
| 1530 | if (base_id > 0x42) | ||
| 1531 | return ERR_PTR(-EOPNOTSUPP); | ||
| 1532 | } else { | ||
| 1533 | if (base_id > 0x3a) | ||
| 1534 | return ERR_PTR(-EOPNOTSUPP); | ||
| 1535 | } | ||
| 1536 | |||
| 1537 | switch (base_id) { | ||
| 1538 | case 0x00: | ||
| 1539 | case 0x0f: | ||
| 1540 | case 0x1e: | ||
| 1541 | case 0x1f: | ||
| 1542 | case 0x2f: | ||
| 1543 | case 0x34: | ||
| 1544 | case 0x3b ... 0x3f: | ||
| 1545 | return ERR_PTR(-EOPNOTSUPP); | ||
| 1546 | default: | ||
| 1547 | break; | ||
| 1548 | } | ||
| 1549 | |||
| 1550 | return &raw_event; | ||
| 1551 | } | ||
| 1552 | |||
| 1414 | static int __init | 1553 | static int __init |
| 1415 | init_hw_perf_events(void) | 1554 | init_hw_perf_events(void) |
| 1416 | { | 1555 | { |
| @@ -1470,6 +1609,14 @@ init_hw_perf_events(void) | |||
| 1470 | mipspmu.general_event_map = &mipsxxcore_event_map; | 1609 | mipspmu.general_event_map = &mipsxxcore_event_map; |
| 1471 | mipspmu.cache_event_map = &mipsxxcore_cache_map; | 1610 | mipspmu.cache_event_map = &mipsxxcore_cache_map; |
| 1472 | break; | 1611 | break; |
| 1612 | case CPU_CAVIUM_OCTEON: | ||
| 1613 | case CPU_CAVIUM_OCTEON_PLUS: | ||
| 1614 | case CPU_CAVIUM_OCTEON2: | ||
| 1615 | mipspmu.name = "octeon"; | ||
| 1616 | mipspmu.general_event_map = &octeon_event_map; | ||
| 1617 | mipspmu.cache_event_map = &octeon_cache_map; | ||
| 1618 | mipspmu.map_raw_event = octeon_pmu_map_raw_event; | ||
| 1619 | break; | ||
| 1473 | default: | 1620 | default: |
| 1474 | pr_cont("Either hardware does not support performance " | 1621 | pr_cont("Either hardware does not support performance " |
| 1475 | "counters, or not yet implemented.\n"); | 1622 | "counters, or not yet implemented.\n"); |
