From 57f0f512b273f60d52568b8c6b77e17f5636edc0 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Wed, 5 Aug 2015 17:04:01 -0300 Subject: Initial import --- .../powerpc/pmu/ebb/back_to_back_ebbs_test.c | 106 +++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c (limited to 'tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c') diff --git a/tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c b/tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c new file mode 100644 index 000000000..66ea765c0 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c @@ -0,0 +1,106 @@ +/* + * Copyright 2014, Michael Ellerman, IBM Corp. + * Licensed under GPLv2. + */ + +#include +#include +#include + +#include "ebb.h" + + +#define NUMBER_OF_EBBS 50 + +/* + * Test that if we overflow the counter while in the EBB handler, we take + * another EBB on exiting from the handler. + * + * We do this by counting with a stupidly low sample period, causing us to + * overflow the PMU while we're still in the EBB handler, leading to another + * EBB. + * + * We get out of what would otherwise be an infinite loop by leaving the + * counter frozen once we've taken enough EBBs. + */ + +static void ebb_callee(void) +{ + uint64_t siar, val; + + val = mfspr(SPRN_BESCR); + if (!(val & BESCR_PMEO)) { + ebb_state.stats.spurious++; + goto out; + } + + ebb_state.stats.ebb_count++; + trace_log_counter(ebb_state.trace, ebb_state.stats.ebb_count); + + /* Resets the PMC */ + count_pmc(1, sample_period); + +out: + if (ebb_state.stats.ebb_count == NUMBER_OF_EBBS) + /* Reset but leave counters frozen */ + reset_ebb_with_clear_mask(MMCR0_PMAO); + else + /* Unfreezes */ + reset_ebb(); + + /* Do some stuff to chew some cycles and pop the counter */ + siar = mfspr(SPRN_SIAR); + trace_log_reg(ebb_state.trace, SPRN_SIAR, siar); + + val = mfspr(SPRN_PMC1); + trace_log_reg(ebb_state.trace, SPRN_PMC1, val); + + val = mfspr(SPRN_MMCR0); + trace_log_reg(ebb_state.trace, SPRN_MMCR0, val); +} + +int back_to_back_ebbs(void) +{ + struct event event; + + event_init_named(&event, 0x1001e, "cycles"); + event_leader_ebb_init(&event); + + event.attr.exclude_kernel = 1; + event.attr.exclude_hv = 1; + event.attr.exclude_idle = 1; + + FAIL_IF(event_open(&event)); + + setup_ebb_handler(ebb_callee); + + FAIL_IF(ebb_event_enable(&event)); + + sample_period = 5; + + ebb_freeze_pmcs(); + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); + ebb_global_enable(); + ebb_unfreeze_pmcs(); + + while (ebb_state.stats.ebb_count < NUMBER_OF_EBBS) + FAIL_IF(core_busy_loop()); + + ebb_global_disable(); + ebb_freeze_pmcs(); + + count_pmc(1, sample_period); + + dump_ebb_state(); + + event_close(&event); + + FAIL_IF(ebb_state.stats.ebb_count != NUMBER_OF_EBBS); + + return 0; +} + +int main(void) +{ + return test_harness(back_to_back_ebbs, "back_to_back_ebbs"); +} -- cgit v1.2.3-54-g00ecf