0001
0002
0003
0004
0005
0006
0007
0008 #include <unistd.h>
0009 #include <sys/syscall.h>
0010 #include <string.h>
0011 #include <stdio.h>
0012 #include <sys/ioctl.h>
0013 #include <sys/mman.h>
0014 #include <stdlib.h>
0015 #include <ctype.h>
0016
0017 #include "misc.h"
0018
0019 #define PAGE_SIZE sysconf(_SC_PAGESIZE)
0020
0021
0022 int pvr;
0023 u64 platform_extended_mask;
0024
0025
0026 int ev_mask_pmcxsel, ev_shift_pmcxsel;
0027 int ev_mask_marked, ev_shift_marked;
0028 int ev_mask_comb, ev_shift_comb;
0029 int ev_mask_unit, ev_shift_unit;
0030 int ev_mask_pmc, ev_shift_pmc;
0031 int ev_mask_cache, ev_shift_cache;
0032 int ev_mask_sample, ev_shift_sample;
0033 int ev_mask_thd_sel, ev_shift_thd_sel;
0034 int ev_mask_thd_start, ev_shift_thd_start;
0035 int ev_mask_thd_stop, ev_shift_thd_stop;
0036 int ev_mask_thd_cmp, ev_shift_thd_cmp;
0037 int ev_mask_sm, ev_shift_sm;
0038 int ev_mask_rsq, ev_shift_rsq;
0039 int ev_mask_l2l3, ev_shift_l2l3;
0040 int ev_mask_mmcr3_src, ev_shift_mmcr3_src;
0041
0042 static void init_ev_encodes(void)
0043 {
0044 ev_mask_pmcxsel = 0xff;
0045 ev_shift_pmcxsel = 0;
0046 ev_mask_marked = 1;
0047 ev_shift_marked = 8;
0048 ev_mask_unit = 0xf;
0049 ev_shift_unit = 12;
0050 ev_mask_pmc = 0xf;
0051 ev_shift_pmc = 16;
0052 ev_mask_sample = 0x1f;
0053 ev_shift_sample = 24;
0054 ev_mask_thd_sel = 0x7;
0055 ev_shift_thd_sel = 29;
0056 ev_mask_thd_start = 0xf;
0057 ev_shift_thd_start = 36;
0058 ev_mask_thd_stop = 0xf;
0059 ev_shift_thd_stop = 32;
0060
0061 switch (pvr) {
0062 case POWER10:
0063 ev_mask_thd_cmp = 0x3ffff;
0064 ev_shift_thd_cmp = 0;
0065 ev_mask_rsq = 1;
0066 ev_shift_rsq = 9;
0067 ev_mask_comb = 3;
0068 ev_shift_comb = 10;
0069 ev_mask_cache = 3;
0070 ev_shift_cache = 20;
0071 ev_mask_sm = 0x3;
0072 ev_shift_sm = 22;
0073 ev_mask_l2l3 = 0x1f;
0074 ev_shift_l2l3 = 40;
0075 ev_mask_mmcr3_src = 0x7fff;
0076 ev_shift_mmcr3_src = 45;
0077 break;
0078 case POWER9:
0079 ev_mask_comb = 3;
0080 ev_shift_comb = 10;
0081 ev_mask_cache = 0xf;
0082 ev_shift_cache = 20;
0083 ev_mask_thd_cmp = 0x3ff;
0084 ev_shift_thd_cmp = 40;
0085 ev_mask_sm = 0x3;
0086 ev_shift_sm = 50;
0087 break;
0088 default:
0089 FAIL_IF_EXIT(1);
0090 }
0091 }
0092
0093
0094 static u64 perf_get_platform_reg_mask(void)
0095 {
0096 if (have_hwcap2(PPC_FEATURE2_ARCH_3_1))
0097 return PERF_POWER10_MASK;
0098 if (have_hwcap2(PPC_FEATURE2_ARCH_3_00))
0099 return PERF_POWER9_MASK;
0100
0101 return -1;
0102 }
0103
0104 int check_extended_regs_support(void)
0105 {
0106 int fd;
0107 struct event event;
0108
0109 event_init(&event, 0x1001e);
0110
0111 event.attr.type = 4;
0112 event.attr.sample_period = 1;
0113 event.attr.disabled = 1;
0114 event.attr.sample_type = PERF_SAMPLE_REGS_INTR;
0115 event.attr.sample_regs_intr = platform_extended_mask;
0116
0117 fd = event_open(&event);
0118 if (fd != -1)
0119 return 0;
0120
0121 return -1;
0122 }
0123
0124 int platform_check_for_tests(void)
0125 {
0126 pvr = PVR_VER(mfspr(SPRN_PVR));
0127
0128
0129
0130
0131
0132 if ((pvr != POWER10) && (pvr != POWER9))
0133 goto out;
0134
0135
0136
0137
0138
0139 if (!have_hwcap2(PPC_FEATURE2_EBB) || !have_hwcap2(PPC_FEATURE2_ARCH_3_00))
0140 goto out;
0141
0142 return 0;
0143
0144 out:
0145 printf("%s: Tests unsupported for this platform\n", __func__);
0146 return -1;
0147 }
0148
0149 int check_pvr_for_sampling_tests(void)
0150 {
0151 SKIP_IF(platform_check_for_tests());
0152
0153 platform_extended_mask = perf_get_platform_reg_mask();
0154
0155 if (check_extended_regs_support())
0156 goto out;
0157
0158 init_ev_encodes();
0159 return 0;
0160
0161 out:
0162 printf("%s: Sampling tests un-supported\n", __func__);
0163 return -1;
0164 }
0165
0166
0167
0168
0169
0170 void *event_sample_buf_mmap(int fd, int mmap_pages)
0171 {
0172 size_t page_size = sysconf(_SC_PAGESIZE);
0173 size_t mmap_size;
0174 void *buff;
0175
0176 if (mmap_pages <= 0)
0177 return NULL;
0178
0179 if (fd <= 0)
0180 return NULL;
0181
0182 mmap_size = page_size * (1 + mmap_pages);
0183 buff = mmap(NULL, mmap_size,
0184 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
0185
0186 if (buff == MAP_FAILED) {
0187 perror("mmap() failed.");
0188 return NULL;
0189 }
0190 return buff;
0191 }
0192
0193
0194
0195
0196
0197
0198
0199
0200 void *__event_read_samples(void *sample_buff, size_t *size, u64 *sample_count)
0201 {
0202 size_t page_size = sysconf(_SC_PAGESIZE);
0203 struct perf_event_header *header = sample_buff + page_size;
0204 struct perf_event_mmap_page *metadata_page = sample_buff;
0205 unsigned long data_head, data_tail;
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 data_head = metadata_page->data_head;
0216
0217 mb();
0218 data_tail = metadata_page->data_tail;
0219
0220
0221 if (sample_count)
0222 *sample_count = 0;
0223
0224 while (1) {
0225
0226
0227
0228
0229
0230
0231
0232 if (data_head - data_tail < sizeof(header))
0233 return NULL;
0234
0235 data_tail += sizeof(header);
0236 if (header->type == PERF_RECORD_SAMPLE) {
0237 *size = (header->size - sizeof(header));
0238 if (!sample_count)
0239 return sample_buff + page_size + data_tail;
0240 data_tail += *size;
0241 *sample_count += 1;
0242 } else {
0243 *size = (header->size - sizeof(header));
0244 if ((metadata_page->data_tail + *size) > metadata_page->data_head)
0245 data_tail = metadata_page->data_head;
0246 else
0247 data_tail += *size;
0248 }
0249 header = (struct perf_event_header *)((void *)header + header->size);
0250 }
0251 return NULL;
0252 }
0253
0254 int collect_samples(void *sample_buff)
0255 {
0256 u64 sample_count;
0257 size_t size = 0;
0258
0259 __event_read_samples(sample_buff, &size, &sample_count);
0260 return sample_count;
0261 }
0262
0263 static void *perf_read_first_sample(void *sample_buff, size_t *size)
0264 {
0265 return __event_read_samples(sample_buff, size, NULL);
0266 }
0267
0268 u64 *get_intr_regs(struct event *event, void *sample_buff)
0269 {
0270 u64 type = event->attr.sample_type;
0271 u64 *intr_regs;
0272 size_t size = 0;
0273
0274 if ((type ^ (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_BRANCH_STACK)) &&
0275 (type ^ PERF_SAMPLE_REGS_INTR))
0276 return NULL;
0277
0278 intr_regs = (u64 *)perf_read_first_sample(sample_buff, &size);
0279 if (!intr_regs)
0280 return NULL;
0281
0282 if (type & PERF_SAMPLE_BRANCH_STACK) {
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 intr_regs += ((*intr_regs) * 3) + 1;
0298 }
0299
0300
0301
0302
0303
0304
0305 ++intr_regs;
0306
0307 return intr_regs;
0308 }
0309
0310 static const int __perf_reg_mask(const char *register_name)
0311 {
0312 if (!strcmp(register_name, "R0"))
0313 return 0;
0314 else if (!strcmp(register_name, "R1"))
0315 return 1;
0316 else if (!strcmp(register_name, "R2"))
0317 return 2;
0318 else if (!strcmp(register_name, "R3"))
0319 return 3;
0320 else if (!strcmp(register_name, "R4"))
0321 return 4;
0322 else if (!strcmp(register_name, "R5"))
0323 return 5;
0324 else if (!strcmp(register_name, "R6"))
0325 return 6;
0326 else if (!strcmp(register_name, "R7"))
0327 return 7;
0328 else if (!strcmp(register_name, "R8"))
0329 return 8;
0330 else if (!strcmp(register_name, "R9"))
0331 return 9;
0332 else if (!strcmp(register_name, "R10"))
0333 return 10;
0334 else if (!strcmp(register_name, "R11"))
0335 return 11;
0336 else if (!strcmp(register_name, "R12"))
0337 return 12;
0338 else if (!strcmp(register_name, "R13"))
0339 return 13;
0340 else if (!strcmp(register_name, "R14"))
0341 return 14;
0342 else if (!strcmp(register_name, "R15"))
0343 return 15;
0344 else if (!strcmp(register_name, "R16"))
0345 return 16;
0346 else if (!strcmp(register_name, "R17"))
0347 return 17;
0348 else if (!strcmp(register_name, "R18"))
0349 return 18;
0350 else if (!strcmp(register_name, "R19"))
0351 return 19;
0352 else if (!strcmp(register_name, "R20"))
0353 return 20;
0354 else if (!strcmp(register_name, "R21"))
0355 return 21;
0356 else if (!strcmp(register_name, "R22"))
0357 return 22;
0358 else if (!strcmp(register_name, "R23"))
0359 return 23;
0360 else if (!strcmp(register_name, "R24"))
0361 return 24;
0362 else if (!strcmp(register_name, "R25"))
0363 return 25;
0364 else if (!strcmp(register_name, "R26"))
0365 return 26;
0366 else if (!strcmp(register_name, "R27"))
0367 return 27;
0368 else if (!strcmp(register_name, "R28"))
0369 return 28;
0370 else if (!strcmp(register_name, "R29"))
0371 return 29;
0372 else if (!strcmp(register_name, "R30"))
0373 return 30;
0374 else if (!strcmp(register_name, "R31"))
0375 return 31;
0376 else if (!strcmp(register_name, "NIP"))
0377 return 32;
0378 else if (!strcmp(register_name, "MSR"))
0379 return 33;
0380 else if (!strcmp(register_name, "ORIG_R3"))
0381 return 34;
0382 else if (!strcmp(register_name, "CTR"))
0383 return 35;
0384 else if (!strcmp(register_name, "LINK"))
0385 return 36;
0386 else if (!strcmp(register_name, "XER"))
0387 return 37;
0388 else if (!strcmp(register_name, "CCR"))
0389 return 38;
0390 else if (!strcmp(register_name, "SOFTE"))
0391 return 39;
0392 else if (!strcmp(register_name, "TRAP"))
0393 return 40;
0394 else if (!strcmp(register_name, "DAR"))
0395 return 41;
0396 else if (!strcmp(register_name, "DSISR"))
0397 return 42;
0398 else if (!strcmp(register_name, "SIER"))
0399 return 43;
0400 else if (!strcmp(register_name, "MMCRA"))
0401 return 44;
0402 else if (!strcmp(register_name, "MMCR0"))
0403 return 45;
0404 else if (!strcmp(register_name, "MMCR1"))
0405 return 46;
0406 else if (!strcmp(register_name, "MMCR2"))
0407 return 47;
0408 else if (!strcmp(register_name, "MMCR3"))
0409 return 48;
0410 else if (!strcmp(register_name, "SIER2"))
0411 return 49;
0412 else if (!strcmp(register_name, "SIER3"))
0413 return 50;
0414 else if (!strcmp(register_name, "PMC1"))
0415 return 51;
0416 else if (!strcmp(register_name, "PMC2"))
0417 return 52;
0418 else if (!strcmp(register_name, "PMC3"))
0419 return 53;
0420 else if (!strcmp(register_name, "PMC4"))
0421 return 54;
0422 else if (!strcmp(register_name, "PMC5"))
0423 return 55;
0424 else if (!strcmp(register_name, "PMC6"))
0425 return 56;
0426 else if (!strcmp(register_name, "SDAR"))
0427 return 57;
0428 else if (!strcmp(register_name, "SIAR"))
0429 return 58;
0430 else
0431 return -1;
0432 }
0433
0434 u64 get_reg_value(u64 *intr_regs, char *register_name)
0435 {
0436 int register_bit_position;
0437
0438 register_bit_position = __perf_reg_mask(register_name);
0439
0440 if (register_bit_position < 0 || (!((platform_extended_mask >>
0441 (register_bit_position - 1)) & 1)))
0442 return -1;
0443
0444 return *(intr_regs + register_bit_position);
0445 }
0446
0447 int get_thresh_cmp_val(struct event event)
0448 {
0449 int exp = 0;
0450 u64 result = 0;
0451 u64 value;
0452
0453 if (!have_hwcap2(PPC_FEATURE2_ARCH_3_1))
0454 return EV_CODE_EXTRACT(event.attr.config, thd_cmp);
0455
0456 value = EV_CODE_EXTRACT(event.attr.config1, thd_cmp);
0457
0458 if (!value)
0459 return value;
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 if (value > 261120)
0471 value = 261120;
0472 while ((64 - __builtin_clzl(value)) > 8) {
0473 exp++;
0474 value >>= 2;
0475 }
0476
0477
0478
0479
0480
0481
0482 if (!(value & 0xC0) && exp)
0483 result = -1;
0484 else
0485 result = (exp << 8) | value;
0486 return result;
0487 }
0488
0489
0490
0491
0492
0493
0494 static bool auxv_generic_compat_pmu(void)
0495 {
0496 int base_pvr = 0;
0497
0498 if (!strcmp(auxv_base_platform(), "power9"))
0499 base_pvr = POWER9;
0500 else if (!strcmp(auxv_base_platform(), "power10"))
0501 base_pvr = POWER10;
0502
0503 return (!base_pvr);
0504 }
0505
0506
0507
0508
0509
0510
0511
0512
0513 bool check_for_generic_compat_pmu(void)
0514 {
0515 char pmu_name[256];
0516
0517 memset(pmu_name, 0, sizeof(pmu_name));
0518 if (read_sysfs_file("bus/event_source/devices/cpu/caps/pmu_name",
0519 pmu_name, sizeof(pmu_name)) < 0)
0520 return auxv_generic_compat_pmu();
0521
0522 if (!strcmp(pmu_name, "ISAv3"))
0523 return true;
0524 else
0525 return false;
0526 }
0527
0528
0529
0530
0531 bool check_for_compat_mode(void)
0532 {
0533 char *platform = auxv_platform();
0534 char *base_platform = auxv_base_platform();
0535
0536 return strcmp(platform, base_platform);
0537 }