Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/powerpc: Add cycles test with MMCR2 handling

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Michael Ellerman and committed by
Benjamin Herrenschmidt
985ac68e c418a678

+93 -1
+2 -1
tools/testing/selftests/powerpc/pmu/ebb/Makefile
··· 13 13 close_clears_pmcc_test instruction_count_test \ 14 14 fork_cleanup_test ebb_on_child_test \ 15 15 ebb_on_willing_child_test back_to_back_ebbs_test \ 16 - lost_exception_test no_handler_test 16 + lost_exception_test no_handler_test \ 17 + cycles_with_mmcr2_test 17 18 18 19 all: $(PROGS) 19 20
+91
tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + #include <stdbool.h> 9 + 10 + #include "ebb.h" 11 + 12 + 13 + /* 14 + * Test of counting cycles while manipulating the user accessible bits in MMCR2. 15 + */ 16 + 17 + /* We use two values because the first freezes PMC1 and so we would get no EBBs */ 18 + #define MMCR2_EXPECTED_1 0x4020100804020000UL /* (FC1P|FC2P|FC3P|FC4P|FC5P|FC6P) */ 19 + #define MMCR2_EXPECTED_2 0x0020100804020000UL /* ( FC2P|FC3P|FC4P|FC5P|FC6P) */ 20 + 21 + 22 + int cycles_with_mmcr2(void) 23 + { 24 + struct event event; 25 + uint64_t val, expected[2], actual; 26 + int i; 27 + bool bad_mmcr2; 28 + 29 + event_init_named(&event, 0x1001e, "cycles"); 30 + event_leader_ebb_init(&event); 31 + 32 + event.attr.exclude_kernel = 1; 33 + event.attr.exclude_hv = 1; 34 + event.attr.exclude_idle = 1; 35 + 36 + FAIL_IF(event_open(&event)); 37 + 38 + ebb_enable_pmc_counting(1); 39 + setup_ebb_handler(standard_ebb_callee); 40 + ebb_global_enable(); 41 + 42 + FAIL_IF(ebb_event_enable(&event)); 43 + 44 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 45 + 46 + /* XXX Set of MMCR2 must be after enable */ 47 + expected[0] = MMCR2_EXPECTED_1; 48 + expected[1] = MMCR2_EXPECTED_2; 49 + i = 0; 50 + bad_mmcr2 = false; 51 + 52 + /* Make sure we loop until we take at least one EBB */ 53 + while ((ebb_state.stats.ebb_count < 20 && !bad_mmcr2) || 54 + ebb_state.stats.ebb_count < 1) 55 + { 56 + mtspr(SPRN_MMCR2, expected[i % 2]); 57 + 58 + FAIL_IF(core_busy_loop()); 59 + 60 + val = mfspr(SPRN_MMCR2); 61 + if (val != expected[i % 2]) { 62 + bad_mmcr2 = true; 63 + actual = val; 64 + } 65 + 66 + i++; 67 + } 68 + 69 + ebb_global_disable(); 70 + ebb_freeze_pmcs(); 71 + 72 + count_pmc(1, sample_period); 73 + 74 + dump_ebb_state(); 75 + 76 + event_close(&event); 77 + 78 + FAIL_IF(ebb_state.stats.ebb_count == 0); 79 + 80 + if (bad_mmcr2) 81 + printf("Bad MMCR2 value seen is 0x%lx\n", actual); 82 + 83 + FAIL_IF(bad_mmcr2); 84 + 85 + return 0; 86 + } 87 + 88 + int main(void) 89 + { 90 + return test_harness(cycles_with_mmcr2, "cycles_with_mmcr2"); 91 + }