1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2014, Michael Ellerman, IBM Corp. 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 17 static int pmc56_overflowed; 18 19 static 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 44 out: 45 reset_ebb(); 46 } 47 48 int pmc56_overflow(void) 49 { 50 struct event event; 51 52 SKIP_IF(!ebb_is_supported()); 53 54 /* Use PMC2 so we set PMCjCE, which enables PMC5/6 */ 55 event_init(&event, 0x2001e); 56 event_leader_ebb_init(&event); 57 58 event.attr.exclude_kernel = 1; 59 event.attr.exclude_hv = 1; 60 event.attr.exclude_idle = 1; 61 62 FAIL_IF(event_open(&event)); 63 64 setup_ebb_handler(ebb_callee); 65 ebb_global_enable(); 66 67 FAIL_IF(ebb_event_enable(&event)); 68 69 mtspr(SPRN_PMC2, pmc_sample_period(sample_period)); 70 mtspr(SPRN_PMC5, 0); 71 mtspr(SPRN_PMC6, 0); 72 73 while (ebb_state.stats.ebb_count < 10) 74 FAIL_IF(core_busy_loop()); 75 76 ebb_global_disable(); 77 ebb_freeze_pmcs(); 78 79 count_pmc(2, sample_period); 80 81 dump_ebb_state(); 82 83 printf("PMC5/6 overflow %d\n", pmc56_overflowed); 84 85 event_close(&event); 86 87 FAIL_IF(ebb_state.stats.ebb_count == 0 || pmc56_overflowed != 0); 88 89 return 0; 90 } 91 92 int main(void) 93 { 94 return test_harness(pmc56_overflow, "pmc56_overflow"); 95 } 96