1/* 2 * Copyright 2014, Michael Ellerman, IBM Corp. 3 * Licensed under GPLv2. 4 */ 5 6#include <stdio.h> 7#include <stdlib.h> 8 9#include "ebb.h" 10 11 12/* 13 * Test that PMC5 & 6 are frozen (ie. don't overflow) when they are not being 14 * used. Tests the MMCR0_FC56 logic in the kernel. 15 */ 16 17static int pmc56_overflowed; 18 19static void ebb_callee(void) 20{ 21 uint64_t val; 22 23 val = mfspr(SPRN_BESCR); 24 if (!(val & BESCR_PMEO)) { 25 ebb_state.stats.spurious++; 26 goto out; 27 } 28 29 ebb_state.stats.ebb_count++; 30 count_pmc(2, sample_period); 31 32 val = mfspr(SPRN_PMC5); 33 if (val >= COUNTER_OVERFLOW) 34 pmc56_overflowed++; 35 36 count_pmc(5, COUNTER_OVERFLOW); 37 38 val = mfspr(SPRN_PMC6); 39 if (val >= COUNTER_OVERFLOW) 40 pmc56_overflowed++; 41 42 count_pmc(6, COUNTER_OVERFLOW); 43 44out: 45 reset_ebb(); 46} 47 48int pmc56_overflow(void) 49{ 50 struct event event; 51 52 /* Use PMC2 so we set PMCjCE, which enables PMC5/6 */ 53 event_init(&event, 0x2001e); 54 event_leader_ebb_init(&event); 55 56 event.attr.exclude_kernel = 1; 57 event.attr.exclude_hv = 1; 58 event.attr.exclude_idle = 1; 59 60 FAIL_IF(event_open(&event)); 61 62 setup_ebb_handler(ebb_callee); 63 ebb_global_enable(); 64 65 FAIL_IF(ebb_event_enable(&event)); 66 67 mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 68 mtspr(SPRN_PMC5, 0); 69 mtspr(SPRN_PMC6, 0); 70 71 while (ebb_state.stats.ebb_count < 10) 72 FAIL_IF(core_busy_loop()); 73 74 ebb_global_disable(); 75 ebb_freeze_pmcs(); 76 77 count_pmc(2, sample_period); 78 79 dump_ebb_state(); 80 81 printf("PMC5/6 overflow %d\n", pmc56_overflowed); 82 83 event_close(&event); 84 85 FAIL_IF(ebb_state.stats.ebb_count == 0 || pmc56_overflowed != 0); 86 87 return 0; 88} 89 90int main(void) 91{ 92 return test_harness(pmc56_overflow, "pmc56_overflow"); 93} 94