0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/string.h>
0009 #include <linux/perf_event.h>
0010 #include <asm/reg.h>
0011 #include <asm/cputable.h>
0012
0013
0014
0015
0016
0017 static int e500_generic_events[] = {
0018 [PERF_COUNT_HW_CPU_CYCLES] = 1,
0019 [PERF_COUNT_HW_INSTRUCTIONS] = 2,
0020 [PERF_COUNT_HW_CACHE_MISSES] = 41,
0021 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 12,
0022 [PERF_COUNT_HW_BRANCH_MISSES] = 15,
0023 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 18,
0024 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 19,
0025 };
0026
0027 #define C(x) PERF_COUNT_HW_CACHE_##x
0028
0029
0030
0031
0032
0033
0034 static int e500_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
0035
0036
0037
0038
0039 [C(L1D)] = {
0040 [C(OP_READ)] = { 27, 0 },
0041 [C(OP_WRITE)] = { 28, 0 },
0042 [C(OP_PREFETCH)] = { 29, 0 },
0043 },
0044 [C(L1I)] = {
0045 [C(OP_READ)] = { 2, 60 },
0046 [C(OP_WRITE)] = { -1, -1 },
0047 [C(OP_PREFETCH)] = { 0, 0 },
0048 },
0049
0050
0051
0052
0053
0054
0055 [C(LL)] = {
0056 [C(OP_READ)] = { 0, 0 },
0057 [C(OP_WRITE)] = { 0, 0 },
0058 [C(OP_PREFETCH)] = { 0, 0 },
0059 },
0060
0061
0062
0063
0064
0065
0066 [C(DTLB)] = {
0067 [C(OP_READ)] = { 26, 66 },
0068 [C(OP_WRITE)] = { -1, -1 },
0069 [C(OP_PREFETCH)] = { -1, -1 },
0070 },
0071 [C(BPU)] = {
0072 [C(OP_READ)] = { 12, 15 },
0073 [C(OP_WRITE)] = { -1, -1 },
0074 [C(OP_PREFETCH)] = { -1, -1 },
0075 },
0076 [C(NODE)] = {
0077 [C(OP_READ)] = { -1, -1 },
0078 [C(OP_WRITE)] = { -1, -1 },
0079 [C(OP_PREFETCH)] = { -1, -1 },
0080 },
0081 };
0082
0083 static int num_events = 128;
0084
0085
0086 static u64 e500_xlate_event(u64 event_id)
0087 {
0088 u32 event_low = (u32)event_id;
0089 u64 ret;
0090
0091 if (event_low >= num_events)
0092 return 0;
0093
0094 ret = FSL_EMB_EVENT_VALID;
0095
0096 if (event_low >= 76 && event_low <= 81) {
0097 ret |= FSL_EMB_EVENT_RESTRICTED;
0098 ret |= event_id &
0099 (FSL_EMB_EVENT_THRESHMUL | FSL_EMB_EVENT_THRESH);
0100 } else if (event_id &
0101 (FSL_EMB_EVENT_THRESHMUL | FSL_EMB_EVENT_THRESH)) {
0102
0103 return 0;
0104 }
0105
0106 return ret;
0107 }
0108
0109 static struct fsl_emb_pmu e500_pmu = {
0110 .name = "e500 family",
0111 .n_counter = 4,
0112 .n_restricted = 2,
0113 .xlate_event = e500_xlate_event,
0114 .n_generic = ARRAY_SIZE(e500_generic_events),
0115 .generic_events = e500_generic_events,
0116 .cache_events = &e500_cache_events,
0117 };
0118
0119 static int init_e500_pmu(void)
0120 {
0121 unsigned int pvr = mfspr(SPRN_PVR);
0122
0123
0124 if (PVR_VER(pvr) == PVR_VER_E500MC || PVR_VER(pvr) == PVR_VER_E5500)
0125 num_events = 256;
0126
0127 else if (PVR_VER(pvr) != PVR_VER_E500V1 && PVR_VER(pvr) != PVR_VER_E500V2)
0128 return -ENODEV;
0129
0130 return register_fsl_emb_pmu(&e500_pmu);
0131 }
0132
0133 early_initcall(init_e500_pmu);