summaryrefslogtreecommitdiff
path: root/powerpc/pmu
diff options
context:
space:
mode:
authorMilosz Wasilewski <milosz.wasilewski@hackbox.linaro.org>2014-10-02 10:16:18 +0100
committerMilosz Wasilewski <milosz.wasilewski@hackbox.linaro.org>2014-10-02 10:16:18 +0100
commit8b27a74bc734d860958941b1a331aa7b38bc2af4 (patch)
tree90f368cfd48a916aa52ddbd3356a7ef2224384a8 /powerpc/pmu
parente14eb051ff73ab8692770762adf44045ba092398 (diff)
Diffstat (limited to 'powerpc/pmu')
-rw-r--r--powerpc/pmu/Makefile38
-rw-r--r--powerpc/pmu/count_instructions.c147
-rw-r--r--powerpc/pmu/ebb/Makefile33
-rw-r--r--powerpc/pmu/ebb/back_to_back_ebbs_test.c106
-rw-r--r--powerpc/pmu/ebb/busy_loop.S271
-rw-r--r--powerpc/pmu/ebb/close_clears_pmcc_test.c59
-rw-r--r--powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c93
-rw-r--r--powerpc/pmu/ebb/cpu_event_vs_ebb_test.c89
-rw-r--r--powerpc/pmu/ebb/cycles_test.c58
-rw-r--r--powerpc/pmu/ebb/cycles_with_freeze_test.c117
-rw-r--r--powerpc/pmu/ebb/cycles_with_mmcr2_test.c91
-rw-r--r--powerpc/pmu/ebb/ebb.c478
-rw-r--r--powerpc/pmu/ebb/ebb.h77
-rw-r--r--powerpc/pmu/ebb/ebb_handler.S365
-rw-r--r--powerpc/pmu/ebb/ebb_on_child_test.c86
-rw-r--r--powerpc/pmu/ebb/ebb_on_willing_child_test.c92
-rw-r--r--powerpc/pmu/ebb/ebb_vs_cpu_event_test.c86
-rw-r--r--powerpc/pmu/ebb/event_attributes_test.c131
-rw-r--r--powerpc/pmu/ebb/fixed_instruction_loop.S43
-rw-r--r--powerpc/pmu/ebb/fork_cleanup_test.c79
-rw-r--r--powerpc/pmu/ebb/instruction_count_test.c164
-rw-r--r--powerpc/pmu/ebb/lost_exception_test.c100
-rw-r--r--powerpc/pmu/ebb/multi_counter_test.c91
-rw-r--r--powerpc/pmu/ebb/multi_ebb_procs_test.c109
-rw-r--r--powerpc/pmu/ebb/no_handler_test.c61
-rw-r--r--powerpc/pmu/ebb/pmae_handling_test.c106
-rw-r--r--powerpc/pmu/ebb/pmc56_overflow_test.c93
-rw-r--r--powerpc/pmu/ebb/reg.h49
-rw-r--r--powerpc/pmu/ebb/reg_access_test.c39
-rw-r--r--powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c91
-rw-r--r--powerpc/pmu/ebb/task_event_vs_ebb_test.c83
-rw-r--r--powerpc/pmu/ebb/trace.c300
-rw-r--r--powerpc/pmu/ebb/trace.h41
-rw-r--r--powerpc/pmu/event.c131
-rw-r--r--powerpc/pmu/event.h43
-rw-r--r--powerpc/pmu/l3_bank_test.c48
-rw-r--r--powerpc/pmu/lib.c300
-rw-r--r--powerpc/pmu/lib.h42
-rw-r--r--powerpc/pmu/loop.S43
-rw-r--r--powerpc/pmu/per_event_excludes.c114
40 files changed, 0 insertions, 4587 deletions
diff --git a/powerpc/pmu/Makefile b/powerpc/pmu/Makefile
deleted file mode 100644
index c9f4263..0000000
--- a/powerpc/pmu/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-noarg:
- $(MAKE) -C ../
-
-PROGS := count_instructions l3_bank_test per_event_excludes
-EXTRA_SOURCES := ../harness.c event.c lib.c
-
-SUB_TARGETS = ebb
-
-all: $(PROGS) $(SUB_TARGETS)
-
-$(PROGS): $(EXTRA_SOURCES)
-
-# loop.S can only be built 64-bit
-count_instructions: loop.S count_instructions.c $(EXTRA_SOURCES)
- $(CC) $(CFLAGS) -m64 -o $@ $^
-
-run_tests: all sub_run_tests
- @-for PROG in $(PROGS); do \
- ./$$PROG; \
- done;
-
-clean: sub_clean
- rm -f $(PROGS) loop.o
-
-$(SUB_TARGETS):
- $(MAKE) -k -C $@ all
-
-sub_run_tests: all
- @for TARGET in $(SUB_TARGETS); do \
- $(MAKE) -C $$TARGET run_tests; \
- done;
-
-sub_clean:
- @for TARGET in $(SUB_TARGETS); do \
- $(MAKE) -C $$TARGET clean; \
- done;
-
-.PHONY: all run_tests clean sub_run_tests sub_clean $(SUB_TARGETS)
diff --git a/powerpc/pmu/count_instructions.c b/powerpc/pmu/count_instructions.c
deleted file mode 100644
index 4622117..0000000
--- a/powerpc/pmu/count_instructions.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2013, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-#include <sys/prctl.h>
-
-#include "event.h"
-#include "utils.h"
-#include "lib.h"
-
-extern void thirty_two_instruction_loop(u64 loops);
-
-static void setup_event(struct event *e, u64 config, char *name)
-{
- event_init_opts(e, config, PERF_TYPE_HARDWARE, name);
-
- e->attr.disabled = 1;
- e->attr.exclude_kernel = 1;
- e->attr.exclude_hv = 1;
- e->attr.exclude_idle = 1;
-}
-
-static int do_count_loop(struct event *events, u64 instructions,
- u64 overhead, bool report)
-{
- s64 difference, expected;
- double percentage;
-
- prctl(PR_TASK_PERF_EVENTS_ENABLE);
-
- /* Run for 1M instructions */
- thirty_two_instruction_loop(instructions >> 5);
-
- prctl(PR_TASK_PERF_EVENTS_DISABLE);
-
- event_read(&events[0]);
- event_read(&events[1]);
-
- expected = instructions + overhead;
- difference = events[0].result.value - expected;
- percentage = (double)difference / events[0].result.value * 100;
-
- if (report) {
- event_report(&events[0]);
- event_report(&events[1]);
-
- printf("Looped for %llu instructions, overhead %llu\n", instructions, overhead);
- printf("Expected %llu\n", expected);
- printf("Actual %llu\n", events[0].result.value);
- printf("Delta %lld, %f%%\n", difference, percentage);
- }
-
- event_reset(&events[0]);
- event_reset(&events[1]);
-
- if (difference < 0)
- difference = -difference;
-
- /* Tolerate a difference below 0.0001 % */
- difference *= 10000 * 100;
- if (difference / events[0].result.value)
- return -1;
-
- return 0;
-}
-
-/* Count how many instructions it takes to do a null loop */
-static u64 determine_overhead(struct event *events)
-{
- u64 current, overhead;
- int i;
-
- do_count_loop(events, 0, 0, false);
- overhead = events[0].result.value;
-
- for (i = 0; i < 100; i++) {
- do_count_loop(events, 0, 0, false);
- current = events[0].result.value;
- if (current < overhead) {
- printf("Replacing overhead %llu with %llu\n", overhead, current);
- overhead = current;
- }
- }
-
- return overhead;
-}
-
-static int test_body(void)
-{
- struct event events[2];
- u64 overhead;
-
- setup_event(&events[0], PERF_COUNT_HW_INSTRUCTIONS, "instructions");
- setup_event(&events[1], PERF_COUNT_HW_CPU_CYCLES, "cycles");
-
- if (event_open(&events[0])) {
- perror("perf_event_open");
- return -1;
- }
-
- if (event_open_with_group(&events[1], events[0].fd)) {
- perror("perf_event_open");
- return -1;
- }
-
- overhead = determine_overhead(events);
- printf("Overhead of null loop: %llu instructions\n", overhead);
-
- /* Run for 1Mi instructions */
- FAIL_IF(do_count_loop(events, 1000000, overhead, true));
-
- /* Run for 10Mi instructions */
- FAIL_IF(do_count_loop(events, 10000000, overhead, true));
-
- /* Run for 100Mi instructions */
- FAIL_IF(do_count_loop(events, 100000000, overhead, true));
-
- /* Run for 1Bi instructions */
- FAIL_IF(do_count_loop(events, 1000000000, overhead, true));
-
- /* Run for 16Bi instructions */
- FAIL_IF(do_count_loop(events, 16000000000, overhead, true));
-
- /* Run for 64Bi instructions */
- FAIL_IF(do_count_loop(events, 64000000000, overhead, true));
-
- event_close(&events[0]);
- event_close(&events[1]);
-
- return 0;
-}
-
-static int count_instructions(void)
-{
- return eat_cpu(test_body);
-}
-
-int main(void)
-{
- return test_harness(count_instructions, "count_instructions");
-}
diff --git a/powerpc/pmu/ebb/Makefile b/powerpc/pmu/ebb/Makefile
deleted file mode 100644
index 3dc4332..0000000
--- a/powerpc/pmu/ebb/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-noarg:
- $(MAKE) -C ../../
-
-# The EBB handler is 64-bit code and everything links against it
-CFLAGS += -m64
-
-PROGS := reg_access_test event_attributes_test cycles_test \
- cycles_with_freeze_test pmc56_overflow_test \
- ebb_vs_cpu_event_test cpu_event_vs_ebb_test \
- cpu_event_pinned_vs_ebb_test task_event_vs_ebb_test \
- task_event_pinned_vs_ebb_test multi_ebb_procs_test \
- multi_counter_test pmae_handling_test \
- close_clears_pmcc_test instruction_count_test \
- fork_cleanup_test ebb_on_child_test \
- ebb_on_willing_child_test back_to_back_ebbs_test \
- lost_exception_test no_handler_test \
- cycles_with_mmcr2_test
-
-all: $(PROGS)
-
-$(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S
-
-instruction_count_test: ../loop.S
-
-lost_exception_test: ../lib.c
-
-run_tests: all
- @-for PROG in $(PROGS); do \
- ./$$PROG; \
- done;
-
-clean:
- rm -f $(PROGS)
diff --git a/powerpc/pmu/ebb/back_to_back_ebbs_test.c b/powerpc/pmu/ebb/back_to_back_ebbs_test.c
deleted file mode 100644
index 66ea765..0000000
--- a/powerpc/pmu/ebb/back_to_back_ebbs_test.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#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");
-}
diff --git a/powerpc/pmu/ebb/busy_loop.S b/powerpc/pmu/ebb/busy_loop.S
deleted file mode 100644
index c7e4093..0000000
--- a/powerpc/pmu/ebb/busy_loop.S
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <ppc-asm.h>
-
- .text
-
-FUNC_START(core_busy_loop)
- stdu %r1, -168(%r1)
- std r14, 160(%r1)
- std r15, 152(%r1)
- std r16, 144(%r1)
- std r17, 136(%r1)
- std r18, 128(%r1)
- std r19, 120(%r1)
- std r20, 112(%r1)
- std r21, 104(%r1)
- std r22, 96(%r1)
- std r23, 88(%r1)
- std r24, 80(%r1)
- std r25, 72(%r1)
- std r26, 64(%r1)
- std r27, 56(%r1)
- std r28, 48(%r1)
- std r29, 40(%r1)
- std r30, 32(%r1)
- std r31, 24(%r1)
-
- li r3, 0x3030
- std r3, -96(%r1)
- li r4, 0x4040
- std r4, -104(%r1)
- li r5, 0x5050
- std r5, -112(%r1)
- li r6, 0x6060
- std r6, -120(%r1)
- li r7, 0x7070
- std r7, -128(%r1)
- li r8, 0x0808
- std r8, -136(%r1)
- li r9, 0x0909
- std r9, -144(%r1)
- li r10, 0x1010
- std r10, -152(%r1)
- li r11, 0x1111
- std r11, -160(%r1)
- li r14, 0x1414
- std r14, -168(%r1)
- li r15, 0x1515
- std r15, -176(%r1)
- li r16, 0x1616
- std r16, -184(%r1)
- li r17, 0x1717
- std r17, -192(%r1)
- li r18, 0x1818
- std r18, -200(%r1)
- li r19, 0x1919
- std r19, -208(%r1)
- li r20, 0x2020
- std r20, -216(%r1)
- li r21, 0x2121
- std r21, -224(%r1)
- li r22, 0x2222
- std r22, -232(%r1)
- li r23, 0x2323
- std r23, -240(%r1)
- li r24, 0x2424
- std r24, -248(%r1)
- li r25, 0x2525
- std r25, -256(%r1)
- li r26, 0x2626
- std r26, -264(%r1)
- li r27, 0x2727
- std r27, -272(%r1)
- li r28, 0x2828
- std r28, -280(%r1)
- li r29, 0x2929
- std r29, -288(%r1)
- li r30, 0x3030
- li r31, 0x3131
-
- li r3, 0
-0: addi r3, r3, 1
- cmpwi r3, 100
- blt 0b
-
- /* Return 1 (fail) unless we get through all the checks */
- li r3, 1
-
- /* Check none of our registers have been corrupted */
- cmpwi r4, 0x4040
- bne 1f
- cmpwi r5, 0x5050
- bne 1f
- cmpwi r6, 0x6060
- bne 1f
- cmpwi r7, 0x7070
- bne 1f
- cmpwi r8, 0x0808
- bne 1f
- cmpwi r9, 0x0909
- bne 1f
- cmpwi r10, 0x1010
- bne 1f
- cmpwi r11, 0x1111
- bne 1f
- cmpwi r14, 0x1414
- bne 1f
- cmpwi r15, 0x1515
- bne 1f
- cmpwi r16, 0x1616
- bne 1f
- cmpwi r17, 0x1717
- bne 1f
- cmpwi r18, 0x1818
- bne 1f
- cmpwi r19, 0x1919
- bne 1f
- cmpwi r20, 0x2020
- bne 1f
- cmpwi r21, 0x2121
- bne 1f
- cmpwi r22, 0x2222
- bne 1f
- cmpwi r23, 0x2323
- bne 1f
- cmpwi r24, 0x2424
- bne 1f
- cmpwi r25, 0x2525
- bne 1f
- cmpwi r26, 0x2626
- bne 1f
- cmpwi r27, 0x2727
- bne 1f
- cmpwi r28, 0x2828
- bne 1f
- cmpwi r29, 0x2929
- bne 1f
- cmpwi r30, 0x3030
- bne 1f
- cmpwi r31, 0x3131
- bne 1f
-
- /* Load junk into all our registers before we reload them from the stack. */
- li r3, 0xde
- li r4, 0xad
- li r5, 0xbe
- li r6, 0xef
- li r7, 0xde
- li r8, 0xad
- li r9, 0xbe
- li r10, 0xef
- li r11, 0xde
- li r14, 0xad
- li r15, 0xbe
- li r16, 0xef
- li r17, 0xde
- li r18, 0xad
- li r19, 0xbe
- li r20, 0xef
- li r21, 0xde
- li r22, 0xad
- li r23, 0xbe
- li r24, 0xef
- li r25, 0xde
- li r26, 0xad
- li r27, 0xbe
- li r28, 0xef
- li r29, 0xdd
-
- ld r3, -96(%r1)
- cmpwi r3, 0x3030
- bne 1f
- ld r4, -104(%r1)
- cmpwi r4, 0x4040
- bne 1f
- ld r5, -112(%r1)
- cmpwi r5, 0x5050
- bne 1f
- ld r6, -120(%r1)
- cmpwi r6, 0x6060
- bne 1f
- ld r7, -128(%r1)
- cmpwi r7, 0x7070
- bne 1f
- ld r8, -136(%r1)
- cmpwi r8, 0x0808
- bne 1f
- ld r9, -144(%r1)
- cmpwi r9, 0x0909
- bne 1f
- ld r10, -152(%r1)
- cmpwi r10, 0x1010
- bne 1f
- ld r11, -160(%r1)
- cmpwi r11, 0x1111
- bne 1f
- ld r14, -168(%r1)
- cmpwi r14, 0x1414
- bne 1f
- ld r15, -176(%r1)
- cmpwi r15, 0x1515
- bne 1f
- ld r16, -184(%r1)
- cmpwi r16, 0x1616
- bne 1f
- ld r17, -192(%r1)
- cmpwi r17, 0x1717
- bne 1f
- ld r18, -200(%r1)
- cmpwi r18, 0x1818
- bne 1f
- ld r19, -208(%r1)
- cmpwi r19, 0x1919
- bne 1f
- ld r20, -216(%r1)
- cmpwi r20, 0x2020
- bne 1f
- ld r21, -224(%r1)
- cmpwi r21, 0x2121
- bne 1f
- ld r22, -232(%r1)
- cmpwi r22, 0x2222
- bne 1f
- ld r23, -240(%r1)
- cmpwi r23, 0x2323
- bne 1f
- ld r24, -248(%r1)
- cmpwi r24, 0x2424
- bne 1f
- ld r25, -256(%r1)
- cmpwi r25, 0x2525
- bne 1f
- ld r26, -264(%r1)
- cmpwi r26, 0x2626
- bne 1f
- ld r27, -272(%r1)
- cmpwi r27, 0x2727
- bne 1f
- ld r28, -280(%r1)
- cmpwi r28, 0x2828
- bne 1f
- ld r29, -288(%r1)
- cmpwi r29, 0x2929
- bne 1f
-
- /* Load 0 (success) to return */
- li r3, 0
-
-1: ld r14, 160(%r1)
- ld r15, 152(%r1)
- ld r16, 144(%r1)
- ld r17, 136(%r1)
- ld r18, 128(%r1)
- ld r19, 120(%r1)
- ld r20, 112(%r1)
- ld r21, 104(%r1)
- ld r22, 96(%r1)
- ld r23, 88(%r1)
- ld r24, 80(%r1)
- ld r25, 72(%r1)
- ld r26, 64(%r1)
- ld r27, 56(%r1)
- ld r28, 48(%r1)
- ld r29, 40(%r1)
- ld r30, 32(%r1)
- ld r31, 24(%r1)
- addi %r1, %r1, 168
- blr
diff --git a/powerpc/pmu/ebb/close_clears_pmcc_test.c b/powerpc/pmu/ebb/close_clears_pmcc_test.c
deleted file mode 100644
index 0f0423d..0000000
--- a/powerpc/pmu/ebb/close_clears_pmcc_test.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#include "ebb.h"
-
-
-/*
- * Test that closing the EBB event clears MMCR0_PMCC, preventing further access
- * by userspace to the PMU hardware.
- */
-
-int close_clears_pmcc(void)
-{
- struct event event;
-
- event_init_named(&event, 0x1001e, "cycles");
- event_leader_ebb_init(&event);
-
- FAIL_IF(event_open(&event));
-
- ebb_enable_pmc_counting(1);
- setup_ebb_handler(standard_ebb_callee);
- ebb_global_enable();
- FAIL_IF(ebb_event_enable(&event));
-
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
-
- while (ebb_state.stats.ebb_count < 1)
- FAIL_IF(core_busy_loop());
-
- ebb_global_disable();
- event_close(&event);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
-
- /* The real test is here, do we take a SIGILL when writing PMU regs now
- * that we have closed the event. We expect that we will. */
-
- FAIL_IF(catch_sigill(write_pmc1));
-
- /* We should still be able to read EBB regs though */
- mfspr(SPRN_EBBHR);
- mfspr(SPRN_EBBRR);
- mfspr(SPRN_BESCR);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(close_clears_pmcc, "close_clears_pmcc");
-}
diff --git a/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c b/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c
deleted file mode 100644
index d3ed64d..0000000
--- a/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "ebb.h"
-
-
-/*
- * Tests a pinned cpu event vs an EBB - in that order. The pinned cpu event
- * should remain and the EBB event should fail to enable.
- */
-
-static int setup_cpu_event(struct event *event, int cpu)
-{
- event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL");
-
- event->attr.pinned = 1;
-
- event->attr.exclude_kernel = 1;
- event->attr.exclude_hv = 1;
- event->attr.exclude_idle = 1;
-
- SKIP_IF(require_paranoia_below(1));
- FAIL_IF(event_open_with_cpu(event, cpu));
- FAIL_IF(event_enable(event));
-
- return 0;
-}
-
-int cpu_event_pinned_vs_ebb(void)
-{
- union pipe read_pipe, write_pipe;
- struct event event;
- int cpu, rc;
- pid_t pid;
-
- cpu = pick_online_cpu();
- FAIL_IF(cpu < 0);
- FAIL_IF(bind_to_cpu(cpu));
-
- FAIL_IF(pipe(read_pipe.fds) == -1);
- FAIL_IF(pipe(write_pipe.fds) == -1);
-
- pid = fork();
- if (pid == 0) {
- /* NB order of pipes looks reversed */
- exit(ebb_child(write_pipe, read_pipe));
- }
-
- /* We setup the cpu event first */
- rc = setup_cpu_event(&event, cpu);
- if (rc) {
- kill_child_and_wait(pid);
- return rc;
- }
-
- /* Signal the child to install its EBB event and wait */
- if (sync_with_child(read_pipe, write_pipe))
- /* If it fails, wait for it to exit */
- goto wait;
-
- /* Signal the child to run */
- FAIL_IF(sync_with_child(read_pipe, write_pipe));
-
-wait:
- /* We expect it to fail to read the event */
- FAIL_IF(wait_for_child(pid) != 2);
-
- FAIL_IF(event_disable(&event));
- FAIL_IF(event_read(&event));
-
- event_report(&event);
-
- /* The cpu event should have run */
- FAIL_IF(event.result.value == 0);
- FAIL_IF(event.result.enabled != event.result.running);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(cpu_event_pinned_vs_ebb, "cpu_event_pinned_vs_ebb");
-}
diff --git a/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c b/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c
deleted file mode 100644
index 8b972c2..0000000
--- a/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "ebb.h"
-
-
-/*
- * Tests a cpu event vs an EBB - in that order. The EBB should force the cpu
- * event off the PMU.
- */
-
-static int setup_cpu_event(struct event *event, int cpu)
-{
- event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL");
-
- event->attr.exclude_kernel = 1;
- event->attr.exclude_hv = 1;
- event->attr.exclude_idle = 1;
-
- SKIP_IF(require_paranoia_below(1));
- FAIL_IF(event_open_with_cpu(event, cpu));
- FAIL_IF(event_enable(event));
-
- return 0;
-}
-
-int cpu_event_vs_ebb(void)
-{
- union pipe read_pipe, write_pipe;
- struct event event;
- int cpu, rc;
- pid_t pid;
-
- cpu = pick_online_cpu();
- FAIL_IF(cpu < 0);
- FAIL_IF(bind_to_cpu(cpu));
-
- FAIL_IF(pipe(read_pipe.fds) == -1);
- FAIL_IF(pipe(write_pipe.fds) == -1);
-
- pid = fork();
- if (pid == 0) {
- /* NB order of pipes looks reversed */
- exit(ebb_child(write_pipe, read_pipe));
- }
-
- /* We setup the cpu event first */
- rc = setup_cpu_event(&event, cpu);
- if (rc) {
- kill_child_and_wait(pid);
- return rc;
- }
-
- /* Signal the child to install its EBB event and wait */
- if (sync_with_child(read_pipe, write_pipe))
- /* If it fails, wait for it to exit */
- goto wait;
-
- /* Signal the child to run */
- FAIL_IF(sync_with_child(read_pipe, write_pipe));
-
-wait:
- /* We expect the child to succeed */
- FAIL_IF(wait_for_child(pid));
-
- FAIL_IF(event_disable(&event));
- FAIL_IF(event_read(&event));
-
- event_report(&event);
-
- /* The cpu event may have run */
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(cpu_event_vs_ebb, "cpu_event_vs_ebb");
-}
diff --git a/powerpc/pmu/ebb/cycles_test.c b/powerpc/pmu/ebb/cycles_test.c
deleted file mode 100644
index 8590fc1..0000000
--- a/powerpc/pmu/ebb/cycles_test.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "ebb.h"
-
-
-/*
- * Basic test that counts user cycles and takes EBBs.
- */
-int cycles(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));
-
- ebb_enable_pmc_counting(1);
- setup_ebb_handler(standard_ebb_callee);
- ebb_global_enable();
- FAIL_IF(ebb_event_enable(&event));
-
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
-
- while (ebb_state.stats.ebb_count < 10) {
- FAIL_IF(core_busy_loop());
- FAIL_IF(ebb_check_mmcr0());
- }
-
- ebb_global_disable();
- ebb_freeze_pmcs();
-
- count_pmc(1, sample_period);
-
- dump_ebb_state();
-
- event_close(&event);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
- FAIL_IF(!ebb_check_count(1, sample_period, 100));
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(cycles, "cycles");
-}
diff --git a/powerpc/pmu/ebb/cycles_with_freeze_test.c b/powerpc/pmu/ebb/cycles_with_freeze_test.c
deleted file mode 100644
index 754b3f2..0000000
--- a/powerpc/pmu/ebb/cycles_with_freeze_test.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-
-#include "ebb.h"
-
-
-/*
- * Test of counting cycles while using MMCR0_FC (freeze counters) to only count
- * parts of the code. This is complicated by the fact that FC is set by the
- * hardware when the event overflows. We may take the EBB after we have set FC,
- * so we have to be careful about whether we clear FC at the end of the EBB
- * handler or not.
- */
-
-static bool counters_frozen = false;
-static int ebbs_while_frozen = 0;
-
-static void ebb_callee(void)
-{
- uint64_t mask, val;
-
- mask = MMCR0_PMAO | MMCR0_FC;
-
- 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);
-
- val = mfspr(SPRN_MMCR0);
- trace_log_reg(ebb_state.trace, SPRN_MMCR0, val);
-
- if (counters_frozen) {
- trace_log_string(ebb_state.trace, "frozen");
- ebbs_while_frozen++;
- mask &= ~MMCR0_FC;
- }
-
- count_pmc(1, sample_period);
-out:
- reset_ebb_with_clear_mask(mask);
-}
-
-int cycles_with_freeze(void)
-{
- struct event event;
- uint64_t val;
- bool fc_cleared;
-
- 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);
- ebb_global_enable();
- FAIL_IF(ebb_event_enable(&event));
-
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
-
- fc_cleared = false;
-
- /* Make sure we loop until we take at least one EBB */
- while ((ebb_state.stats.ebb_count < 20 && !fc_cleared) ||
- ebb_state.stats.ebb_count < 1)
- {
- counters_frozen = false;
- mb();
- mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC);
-
- FAIL_IF(core_busy_loop());
-
- counters_frozen = true;
- mb();
- mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC);
-
- val = mfspr(SPRN_MMCR0);
- if (! (val & MMCR0_FC)) {
- printf("Outside of loop, FC NOT set MMCR0 0x%lx\n", val);
- fc_cleared = true;
- }
- }
-
- ebb_global_disable();
- ebb_freeze_pmcs();
-
- count_pmc(1, sample_period);
-
- dump_ebb_state();
-
- printf("EBBs while frozen %d\n", ebbs_while_frozen);
-
- event_close(&event);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
- FAIL_IF(fc_cleared);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(cycles_with_freeze, "cycles_with_freeze");
-}
diff --git a/powerpc/pmu/ebb/cycles_with_mmcr2_test.c b/powerpc/pmu/ebb/cycles_with_mmcr2_test.c
deleted file mode 100644
index d43029b..0000000
--- a/powerpc/pmu/ebb/cycles_with_mmcr2_test.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-
-#include "ebb.h"
-
-
-/*
- * Test of counting cycles while manipulating the user accessible bits in MMCR2.
- */
-
-/* We use two values because the first freezes PMC1 and so we would get no EBBs */
-#define MMCR2_EXPECTED_1 0x4020100804020000UL /* (FC1P|FC2P|FC3P|FC4P|FC5P|FC6P) */
-#define MMCR2_EXPECTED_2 0x0020100804020000UL /* ( FC2P|FC3P|FC4P|FC5P|FC6P) */
-
-
-int cycles_with_mmcr2(void)
-{
- struct event event;
- uint64_t val, expected[2], actual;
- int i;
- bool bad_mmcr2;
-
- 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));
-
- ebb_enable_pmc_counting(1);
- setup_ebb_handler(standard_ebb_callee);
- ebb_global_enable();
-
- FAIL_IF(ebb_event_enable(&event));
-
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
-
- /* XXX Set of MMCR2 must be after enable */
- expected[0] = MMCR2_EXPECTED_1;
- expected[1] = MMCR2_EXPECTED_2;
- i = 0;
- bad_mmcr2 = false;
-
- /* Make sure we loop until we take at least one EBB */
- while ((ebb_state.stats.ebb_count < 20 && !bad_mmcr2) ||
- ebb_state.stats.ebb_count < 1)
- {
- mtspr(SPRN_MMCR2, expected[i % 2]);
-
- FAIL_IF(core_busy_loop());
-
- val = mfspr(SPRN_MMCR2);
- if (val != expected[i % 2]) {
- bad_mmcr2 = true;
- actual = val;
- }
-
- i++;
- }
-
- ebb_global_disable();
- ebb_freeze_pmcs();
-
- count_pmc(1, sample_period);
-
- dump_ebb_state();
-
- event_close(&event);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
-
- if (bad_mmcr2)
- printf("Bad MMCR2 value seen is 0x%lx\n", actual);
-
- FAIL_IF(bad_mmcr2);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(cycles_with_mmcr2, "cycles_with_mmcr2");
-}
diff --git a/powerpc/pmu/ebb/ebb.c b/powerpc/pmu/ebb/ebb.c
deleted file mode 100644
index d7a72ce..0000000
--- a/powerpc/pmu/ebb/ebb.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#define _GNU_SOURCE /* For CPU_ZERO etc. */
-
-#include <sched.h>
-#include <sys/wait.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-
-#include "trace.h"
-#include "reg.h"
-#include "ebb.h"
-
-
-void (*ebb_user_func)(void);
-
-void ebb_hook(void)
-{
- if (ebb_user_func)
- ebb_user_func();
-}
-
-struct ebb_state ebb_state;
-
-u64 sample_period = 0x40000000ull;
-
-void reset_ebb_with_clear_mask(unsigned long mmcr0_clear_mask)
-{
- u64 val;
-
- /* 2) clear MMCR0[PMAO] - docs say BESCR[PMEO] should do this */
- /* 3) set MMCR0[PMAE] - docs say BESCR[PME] should do this */
- val = mfspr(SPRN_MMCR0);
- mtspr(SPRN_MMCR0, (val & ~mmcr0_clear_mask) | MMCR0_PMAE);
-
- /* 4) clear BESCR[PMEO] */
- mtspr(SPRN_BESCRR, BESCR_PMEO);
-
- /* 5) set BESCR[PME] */
- mtspr(SPRN_BESCRS, BESCR_PME);
-
- /* 6) rfebb 1 - done in our caller */
-}
-
-void reset_ebb(void)
-{
- reset_ebb_with_clear_mask(MMCR0_PMAO | MMCR0_FC);
-}
-
-/* Called outside of the EBB handler to check MMCR0 is sane */
-int ebb_check_mmcr0(void)
-{
- u64 val;
-
- val = mfspr(SPRN_MMCR0);
- if ((val & (MMCR0_FC | MMCR0_PMAO)) == MMCR0_FC) {
- /* It's OK if we see FC & PMAO, but not FC by itself */
- printf("Outside of loop, only FC set 0x%llx\n", val);
- return 1;
- }
-
- return 0;
-}
-
-bool ebb_check_count(int pmc, u64 sample_period, int fudge)
-{
- u64 count, upper, lower;
-
- count = ebb_state.stats.pmc_count[PMC_INDEX(pmc)];
-
- lower = ebb_state.stats.ebb_count * (sample_period - fudge);
-
- if (count < lower) {
- printf("PMC%d count (0x%llx) below lower limit 0x%llx (-0x%llx)\n",
- pmc, count, lower, lower - count);
- return false;
- }
-
- upper = ebb_state.stats.ebb_count * (sample_period + fudge);
-
- if (count > upper) {
- printf("PMC%d count (0x%llx) above upper limit 0x%llx (+0x%llx)\n",
- pmc, count, upper, count - upper);
- return false;
- }
-
- printf("PMC%d count (0x%llx) is between 0x%llx and 0x%llx delta +0x%llx/-0x%llx\n",
- pmc, count, lower, upper, count - lower, upper - count);
-
- return true;
-}
-
-void standard_ebb_callee(void)
-{
- int found, i;
- u64 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);
-
- val = mfspr(SPRN_MMCR0);
- trace_log_reg(ebb_state.trace, SPRN_MMCR0, val);
-
- found = 0;
- for (i = 1; i <= 6; i++) {
- if (ebb_state.pmc_enable[PMC_INDEX(i)])
- found += count_pmc(i, sample_period);
- }
-
- if (!found)
- ebb_state.stats.no_overflow++;
-
-out:
- reset_ebb();
-}
-
-extern void ebb_handler(void);
-
-void setup_ebb_handler(void (*callee)(void))
-{
- u64 entry;
-
-#if defined(_CALL_ELF) && _CALL_ELF == 2
- entry = (u64)ebb_handler;
-#else
- struct opd
- {
- u64 entry;
- u64 toc;
- } *opd;
-
- opd = (struct opd *)ebb_handler;
- entry = opd->entry;
-#endif
- printf("EBB Handler is at %#llx\n", entry);
-
- ebb_user_func = callee;
-
- /* Ensure ebb_user_func is set before we set the handler */
- mb();
- mtspr(SPRN_EBBHR, entry);
-
- /* Make sure the handler is set before we return */
- mb();
-}
-
-void clear_ebb_stats(void)
-{
- memset(&ebb_state.stats, 0, sizeof(ebb_state.stats));
-}
-
-void dump_summary_ebb_state(void)
-{
- printf("ebb_state:\n" \
- " ebb_count = %d\n" \
- " spurious = %d\n" \
- " negative = %d\n" \
- " no_overflow = %d\n" \
- " pmc[1] count = 0x%llx\n" \
- " pmc[2] count = 0x%llx\n" \
- " pmc[3] count = 0x%llx\n" \
- " pmc[4] count = 0x%llx\n" \
- " pmc[5] count = 0x%llx\n" \
- " pmc[6] count = 0x%llx\n",
- ebb_state.stats.ebb_count, ebb_state.stats.spurious,
- ebb_state.stats.negative, ebb_state.stats.no_overflow,
- ebb_state.stats.pmc_count[0], ebb_state.stats.pmc_count[1],
- ebb_state.stats.pmc_count[2], ebb_state.stats.pmc_count[3],
- ebb_state.stats.pmc_count[4], ebb_state.stats.pmc_count[5]);
-}
-
-static char *decode_mmcr0(u32 value)
-{
- static char buf[16];
-
- buf[0] = '\0';
-
- if (value & (1 << 31))
- strcat(buf, "FC ");
- if (value & (1 << 26))
- strcat(buf, "PMAE ");
- if (value & (1 << 7))
- strcat(buf, "PMAO ");
-
- return buf;
-}
-
-static char *decode_bescr(u64 value)
-{
- static char buf[16];
-
- buf[0] = '\0';
-
- if (value & (1ull << 63))
- strcat(buf, "GE ");
- if (value & (1ull << 32))
- strcat(buf, "PMAE ");
- if (value & 1)
- strcat(buf, "PMAO ");
-
- return buf;
-}
-
-void dump_ebb_hw_state(void)
-{
- u64 bescr;
- u32 mmcr0;
-
- mmcr0 = mfspr(SPRN_MMCR0);
- bescr = mfspr(SPRN_BESCR);
-
- printf("HW state:\n" \
- "MMCR0 0x%016x %s\n" \
- "MMCR2 0x%016lx\n" \
- "EBBHR 0x%016lx\n" \
- "BESCR 0x%016llx %s\n" \
- "PMC1 0x%016lx\n" \
- "PMC2 0x%016lx\n" \
- "PMC3 0x%016lx\n" \
- "PMC4 0x%016lx\n" \
- "PMC5 0x%016lx\n" \
- "PMC6 0x%016lx\n" \
- "SIAR 0x%016lx\n",
- mmcr0, decode_mmcr0(mmcr0), mfspr(SPRN_MMCR2),
- mfspr(SPRN_EBBHR), bescr, decode_bescr(bescr),
- mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), mfspr(SPRN_PMC3),
- mfspr(SPRN_PMC4), mfspr(SPRN_PMC5), mfspr(SPRN_PMC6),
- mfspr(SPRN_SIAR));
-}
-
-void dump_ebb_state(void)
-{
- dump_summary_ebb_state();
-
- dump_ebb_hw_state();
-
- trace_buffer_print(ebb_state.trace);
-}
-
-int count_pmc(int pmc, uint32_t sample_period)
-{
- uint32_t start_value;
- u64 val;
-
- /* 0) Read PMC */
- start_value = pmc_sample_period(sample_period);
-
- val = read_pmc(pmc);
- if (val < start_value)
- ebb_state.stats.negative++;
- else
- ebb_state.stats.pmc_count[PMC_INDEX(pmc)] += val - start_value;
-
- trace_log_reg(ebb_state.trace, SPRN_PMC1 + pmc - 1, val);
-
- /* 1) Reset PMC */
- write_pmc(pmc, start_value);
-
- /* Report if we overflowed */
- return val >= COUNTER_OVERFLOW;
-}
-
-int ebb_event_enable(struct event *e)
-{
- int rc;
-
- /* Ensure any SPR writes are ordered vs us */
- mb();
-
- rc = ioctl(e->fd, PERF_EVENT_IOC_ENABLE);
- if (rc)
- return rc;
-
- rc = event_read(e);
-
- /* Ditto */
- mb();
-
- return rc;
-}
-
-void ebb_freeze_pmcs(void)
-{
- mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC);
- mb();
-}
-
-void ebb_unfreeze_pmcs(void)
-{
- /* Unfreeze counters */
- mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC);
- mb();
-}
-
-void ebb_global_enable(void)
-{
- /* Enable EBBs globally and PMU EBBs */
- mtspr(SPRN_BESCR, 0x8000000100000000ull);
- mb();
-}
-
-void ebb_global_disable(void)
-{
- /* Disable EBBs & freeze counters, events are still scheduled */
- mtspr(SPRN_BESCRR, BESCR_PME);
- mb();
-}
-
-void event_ebb_init(struct event *e)
-{
- e->attr.config |= (1ull << 63);
-}
-
-void event_bhrb_init(struct event *e, unsigned ifm)
-{
- e->attr.config |= (1ull << 62) | ((u64)ifm << 60);
-}
-
-void event_leader_ebb_init(struct event *e)
-{
- event_ebb_init(e);
-
- e->attr.exclusive = 1;
- e->attr.pinned = 1;
-}
-
-int ebb_child(union pipe read_pipe, union pipe write_pipe)
-{
- struct event event;
- uint64_t val;
-
- FAIL_IF(wait_for_parent(read_pipe));
-
- 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));
-
- ebb_enable_pmc_counting(1);
- setup_ebb_handler(standard_ebb_callee);
- ebb_global_enable();
-
- FAIL_IF(event_enable(&event));
-
- if (event_read(&event)) {
- /*
- * Some tests expect to fail here, so don't report an error on
- * this line, and return a distinguisable error code. Tell the
- * parent an error happened.
- */
- notify_parent_of_error(write_pipe);
- return 2;
- }
-
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
-
- FAIL_IF(notify_parent(write_pipe));
- FAIL_IF(wait_for_parent(read_pipe));
- FAIL_IF(notify_parent(write_pipe));
-
- while (ebb_state.stats.ebb_count < 20) {
- FAIL_IF(core_busy_loop());
-
- /* To try and hit SIGILL case */
- val = mfspr(SPRN_MMCRA);
- val |= mfspr(SPRN_MMCR2);
- val |= mfspr(SPRN_MMCR0);
- }
-
- ebb_global_disable();
- ebb_freeze_pmcs();
-
- count_pmc(1, sample_period);
-
- dump_ebb_state();
-
- event_close(&event);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
-
- return 0;
-}
-
-static jmp_buf setjmp_env;
-
-static void sigill_handler(int signal)
-{
- printf("Took sigill\n");
- longjmp(setjmp_env, 1);
-}
-
-static struct sigaction sigill_action = {
- .sa_handler = sigill_handler,
-};
-
-int catch_sigill(void (*func)(void))
-{
- if (sigaction(SIGILL, &sigill_action, NULL)) {
- perror("sigaction");
- return 1;
- }
-
- if (setjmp(setjmp_env) == 0) {
- func();
- return 1;
- }
-
- return 0;
-}
-
-void write_pmc1(void)
-{
- mtspr(SPRN_PMC1, 0);
-}
-
-void write_pmc(int pmc, u64 value)
-{
- switch (pmc) {
- case 1: mtspr(SPRN_PMC1, value); break;
- case 2: mtspr(SPRN_PMC2, value); break;
- case 3: mtspr(SPRN_PMC3, value); break;
- case 4: mtspr(SPRN_PMC4, value); break;
- case 5: mtspr(SPRN_PMC5, value); break;
- case 6: mtspr(SPRN_PMC6, value); break;
- }
-}
-
-u64 read_pmc(int pmc)
-{
- switch (pmc) {
- case 1: return mfspr(SPRN_PMC1);
- case 2: return mfspr(SPRN_PMC2);
- case 3: return mfspr(SPRN_PMC3);
- case 4: return mfspr(SPRN_PMC4);
- case 5: return mfspr(SPRN_PMC5);
- case 6: return mfspr(SPRN_PMC6);
- }
-
- return 0;
-}
-
-static void term_handler(int signal)
-{
- dump_summary_ebb_state();
- dump_ebb_hw_state();
- abort();
-}
-
-struct sigaction term_action = {
- .sa_handler = term_handler,
-};
-
-static void __attribute__((constructor)) ebb_init(void)
-{
- clear_ebb_stats();
-
- if (sigaction(SIGTERM, &term_action, NULL))
- perror("sigaction");
-
- ebb_state.trace = trace_buffer_allocate(1 * 1024 * 1024);
-}
diff --git a/powerpc/pmu/ebb/ebb.h b/powerpc/pmu/ebb/ebb.h
deleted file mode 100644
index e44eee5..0000000
--- a/powerpc/pmu/ebb/ebb.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#ifndef _SELFTESTS_POWERPC_PMU_EBB_EBB_H
-#define _SELFTESTS_POWERPC_PMU_EBB_EBB_H
-
-#include "../event.h"
-#include "../lib.h"
-#include "trace.h"
-#include "reg.h"
-
-#define PMC_INDEX(pmc) ((pmc)-1)
-
-#define NUM_PMC_VALUES 128
-
-struct ebb_state
-{
- struct {
- u64 pmc_count[6];
- volatile int ebb_count;
- int spurious;
- int negative;
- int no_overflow;
- } stats;
-
- bool pmc_enable[6];
- struct trace_buffer *trace;
-};
-
-extern struct ebb_state ebb_state;
-
-#define COUNTER_OVERFLOW 0x80000000ull
-
-static inline uint32_t pmc_sample_period(uint32_t value)
-{
- return COUNTER_OVERFLOW - value;
-}
-
-static inline void ebb_enable_pmc_counting(int pmc)
-{
- ebb_state.pmc_enable[PMC_INDEX(pmc)] = true;
-}
-
-bool ebb_check_count(int pmc, u64 sample_period, int fudge);
-void event_leader_ebb_init(struct event *e);
-void event_ebb_init(struct event *e);
-void event_bhrb_init(struct event *e, unsigned ifm);
-void setup_ebb_handler(void (*callee)(void));
-void standard_ebb_callee(void);
-int ebb_event_enable(struct event *e);
-void ebb_global_enable(void);
-void ebb_global_disable(void);
-void ebb_freeze_pmcs(void);
-void ebb_unfreeze_pmcs(void);
-void event_ebb_init(struct event *e);
-void event_leader_ebb_init(struct event *e);
-int count_pmc(int pmc, uint32_t sample_period);
-void dump_ebb_state(void);
-void dump_summary_ebb_state(void);
-void dump_ebb_hw_state(void);
-void clear_ebb_stats(void);
-void write_pmc(int pmc, u64 value);
-u64 read_pmc(int pmc);
-void reset_ebb_with_clear_mask(unsigned long mmcr0_clear_mask);
-void reset_ebb(void);
-int ebb_check_mmcr0(void);
-
-extern u64 sample_period;
-
-int core_busy_loop(void);
-int ebb_child(union pipe read_pipe, union pipe write_pipe);
-int catch_sigill(void (*func)(void));
-void write_pmc1(void);
-
-#endif /* _SELFTESTS_POWERPC_PMU_EBB_EBB_H */
diff --git a/powerpc/pmu/ebb/ebb_handler.S b/powerpc/pmu/ebb/ebb_handler.S
deleted file mode 100644
index 14274ea..0000000
--- a/powerpc/pmu/ebb/ebb_handler.S
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <ppc-asm.h>
-#include "reg.h"
-
-
-/* ppc-asm.h defines most of the reg aliases, but not r1/r2. */
-#define r1 1
-#define r2 2
-
-#define RFEBB .long 0x4c000924
-
-/* Stack layout:
- *
- * ^
- * User stack |
- * Back chain ------+ <- r1 <-------+
- * ... |
- * Red zone / ABI Gap |
- * ... |
- * vr63 <+ |
- * vr0 | |
- * VSCR | |
- * FSCR | |
- * r31 | Save area |
- * r0 | |
- * XER | |
- * CTR | |
- * LR | |
- * CCR <+ |
- * ... <+ |
- * LR | Caller frame |
- * CCR | |
- * Back chain <+ <- updated r1 --------+
- *
- */
-
-#if defined(_CALL_ELF) && _CALL_ELF == 2
-#define ABIGAP 512
-#else
-#define ABIGAP 288
-#endif
-
-#define NR_GPR 32
-#define NR_SPR 6
-#define NR_VSR 64
-
-#define SAVE_AREA ((NR_GPR + NR_SPR) * 8 + (NR_VSR * 16))
-#define CALLER_FRAME 112
-
-#define STACK_FRAME (ABIGAP + SAVE_AREA + CALLER_FRAME)
-
-#define CCR_SAVE (CALLER_FRAME)
-#define LR_SAVE (CCR_SAVE + 8)
-#define CTR_SAVE (LR_SAVE + 8)
-#define XER_SAVE (CTR_SAVE + 8)
-#define GPR_SAVE(n) (XER_SAVE + 8 + (8 * n))
-#define FSCR_SAVE (GPR_SAVE(31) + 8)
-#define VSCR_SAVE (FSCR_SAVE + 8)
-#define VSR_SAVE(n) (VSCR_SAVE + 8 + (16 * n))
-
-#define SAVE_GPR(n) std n,GPR_SAVE(n)(r1)
-#define REST_GPR(n) ld n,GPR_SAVE(n)(r1)
-#define TRASH_GPR(n) lis n,0xaaaa
-
-#define SAVE_VSR(n, b) li b, VSR_SAVE(n); stxvd2x n,b,r1
-#define LOAD_VSR(n, b) li b, VSR_SAVE(n); lxvd2x n,b,r1
-
-#define LOAD_REG_IMMEDIATE(reg,expr) \
- lis reg,(expr)@highest; \
- ori reg,reg,(expr)@higher; \
- rldicr reg,reg,32,31; \
- oris reg,reg,(expr)@h; \
- ori reg,reg,(expr)@l;
-
-
-#if defined(_CALL_ELF) && _CALL_ELF == 2
-#define ENTRY_POINT(name) \
- .type FUNC_NAME(name),@function; \
- .globl FUNC_NAME(name); \
- FUNC_NAME(name):
-
-#define RESTORE_TOC(name) \
- /* Restore our TOC pointer using our entry point */ \
- LOAD_REG_IMMEDIATE(r12, name) \
-0: addis r2,r12,(.TOC.-0b)@ha; \
- addi r2,r2,(.TOC.-0b)@l;
-
-#else
-#define ENTRY_POINT(name) FUNC_START(name)
-#define RESTORE_TOC(name) \
- /* Restore our TOC pointer via our opd entry */ \
- LOAD_REG_IMMEDIATE(r2, name) \
- ld r2,8(r2);
-#endif
-
- .text
-
-ENTRY_POINT(ebb_handler)
- stdu r1,-STACK_FRAME(r1)
- SAVE_GPR(0)
- mflr r0
- std r0,LR_SAVE(r1)
- mfcr r0
- std r0,CCR_SAVE(r1)
- mfctr r0
- std r0,CTR_SAVE(r1)
- mfxer r0
- std r0,XER_SAVE(r1)
- SAVE_GPR(2)
- SAVE_GPR(3)
- SAVE_GPR(4)
- SAVE_GPR(5)
- SAVE_GPR(6)
- SAVE_GPR(7)
- SAVE_GPR(8)
- SAVE_GPR(9)
- SAVE_GPR(10)
- SAVE_GPR(11)
- SAVE_GPR(12)
- SAVE_GPR(13)
- SAVE_GPR(14)
- SAVE_GPR(15)
- SAVE_GPR(16)
- SAVE_GPR(17)
- SAVE_GPR(18)
- SAVE_GPR(19)
- SAVE_GPR(20)
- SAVE_GPR(21)
- SAVE_GPR(22)
- SAVE_GPR(23)
- SAVE_GPR(24)
- SAVE_GPR(25)
- SAVE_GPR(26)
- SAVE_GPR(27)
- SAVE_GPR(28)
- SAVE_GPR(29)
- SAVE_GPR(30)
- SAVE_GPR(31)
- SAVE_VSR(0, r3)
- mffs f0
- stfd f0, FSCR_SAVE(r1)
- mfvscr f0
- stfd f0, VSCR_SAVE(r1)
- SAVE_VSR(1, r3)
- SAVE_VSR(2, r3)
- SAVE_VSR(3, r3)
- SAVE_VSR(4, r3)
- SAVE_VSR(5, r3)
- SAVE_VSR(6, r3)
- SAVE_VSR(7, r3)
- SAVE_VSR(8, r3)
- SAVE_VSR(9, r3)
- SAVE_VSR(10, r3)
- SAVE_VSR(11, r3)
- SAVE_VSR(12, r3)
- SAVE_VSR(13, r3)
- SAVE_VSR(14, r3)
- SAVE_VSR(15, r3)
- SAVE_VSR(16, r3)
- SAVE_VSR(17, r3)
- SAVE_VSR(18, r3)
- SAVE_VSR(19, r3)
- SAVE_VSR(20, r3)
- SAVE_VSR(21, r3)
- SAVE_VSR(22, r3)
- SAVE_VSR(23, r3)
- SAVE_VSR(24, r3)
- SAVE_VSR(25, r3)
- SAVE_VSR(26, r3)
- SAVE_VSR(27, r3)
- SAVE_VSR(28, r3)
- SAVE_VSR(29, r3)
- SAVE_VSR(30, r3)
- SAVE_VSR(31, r3)
- SAVE_VSR(32, r3)
- SAVE_VSR(33, r3)
- SAVE_VSR(34, r3)
- SAVE_VSR(35, r3)
- SAVE_VSR(36, r3)
- SAVE_VSR(37, r3)
- SAVE_VSR(38, r3)
- SAVE_VSR(39, r3)
- SAVE_VSR(40, r3)
- SAVE_VSR(41, r3)
- SAVE_VSR(42, r3)
- SAVE_VSR(43, r3)
- SAVE_VSR(44, r3)
- SAVE_VSR(45, r3)
- SAVE_VSR(46, r3)
- SAVE_VSR(47, r3)
- SAVE_VSR(48, r3)
- SAVE_VSR(49, r3)
- SAVE_VSR(50, r3)
- SAVE_VSR(51, r3)
- SAVE_VSR(52, r3)
- SAVE_VSR(53, r3)
- SAVE_VSR(54, r3)
- SAVE_VSR(55, r3)
- SAVE_VSR(56, r3)
- SAVE_VSR(57, r3)
- SAVE_VSR(58, r3)
- SAVE_VSR(59, r3)
- SAVE_VSR(60, r3)
- SAVE_VSR(61, r3)
- SAVE_VSR(62, r3)
- SAVE_VSR(63, r3)
-
- TRASH_GPR(2)
- TRASH_GPR(3)
- TRASH_GPR(4)
- TRASH_GPR(5)
- TRASH_GPR(6)
- TRASH_GPR(7)
- TRASH_GPR(8)
- TRASH_GPR(9)
- TRASH_GPR(10)
- TRASH_GPR(11)
- TRASH_GPR(12)
- TRASH_GPR(14)
- TRASH_GPR(15)
- TRASH_GPR(16)
- TRASH_GPR(17)
- TRASH_GPR(18)
- TRASH_GPR(19)
- TRASH_GPR(20)
- TRASH_GPR(21)
- TRASH_GPR(22)
- TRASH_GPR(23)
- TRASH_GPR(24)
- TRASH_GPR(25)
- TRASH_GPR(26)
- TRASH_GPR(27)
- TRASH_GPR(28)
- TRASH_GPR(29)
- TRASH_GPR(30)
- TRASH_GPR(31)
-
- RESTORE_TOC(ebb_handler)
-
- /*
- * r13 is our TLS pointer. We leave whatever value was in there when the
- * EBB fired. That seems to be OK because once set the TLS pointer is not
- * changed - but presumably that could change in future.
- */
-
- bl ebb_hook
- nop
-
- /* r2 may be changed here but we don't care */
-
- lfd f0, FSCR_SAVE(r1)
- mtfsf 0xff,f0
- lfd f0, VSCR_SAVE(r1)
- mtvscr f0
- LOAD_VSR(0, r3)
- LOAD_VSR(1, r3)
- LOAD_VSR(2, r3)
- LOAD_VSR(3, r3)
- LOAD_VSR(4, r3)
- LOAD_VSR(5, r3)
- LOAD_VSR(6, r3)
- LOAD_VSR(7, r3)
- LOAD_VSR(8, r3)
- LOAD_VSR(9, r3)
- LOAD_VSR(10, r3)
- LOAD_VSR(11, r3)
- LOAD_VSR(12, r3)
- LOAD_VSR(13, r3)
- LOAD_VSR(14, r3)
- LOAD_VSR(15, r3)
- LOAD_VSR(16, r3)
- LOAD_VSR(17, r3)
- LOAD_VSR(18, r3)
- LOAD_VSR(19, r3)
- LOAD_VSR(20, r3)
- LOAD_VSR(21, r3)
- LOAD_VSR(22, r3)
- LOAD_VSR(23, r3)
- LOAD_VSR(24, r3)
- LOAD_VSR(25, r3)
- LOAD_VSR(26, r3)
- LOAD_VSR(27, r3)
- LOAD_VSR(28, r3)
- LOAD_VSR(29, r3)
- LOAD_VSR(30, r3)
- LOAD_VSR(31, r3)
- LOAD_VSR(32, r3)
- LOAD_VSR(33, r3)
- LOAD_VSR(34, r3)
- LOAD_VSR(35, r3)
- LOAD_VSR(36, r3)
- LOAD_VSR(37, r3)
- LOAD_VSR(38, r3)
- LOAD_VSR(39, r3)
- LOAD_VSR(40, r3)
- LOAD_VSR(41, r3)
- LOAD_VSR(42, r3)
- LOAD_VSR(43, r3)
- LOAD_VSR(44, r3)
- LOAD_VSR(45, r3)
- LOAD_VSR(46, r3)
- LOAD_VSR(47, r3)
- LOAD_VSR(48, r3)
- LOAD_VSR(49, r3)
- LOAD_VSR(50, r3)
- LOAD_VSR(51, r3)
- LOAD_VSR(52, r3)
- LOAD_VSR(53, r3)
- LOAD_VSR(54, r3)
- LOAD_VSR(55, r3)
- LOAD_VSR(56, r3)
- LOAD_VSR(57, r3)
- LOAD_VSR(58, r3)
- LOAD_VSR(59, r3)
- LOAD_VSR(60, r3)
- LOAD_VSR(61, r3)
- LOAD_VSR(62, r3)
- LOAD_VSR(63, r3)
-
- ld r0,XER_SAVE(r1)
- mtxer r0
- ld r0,CTR_SAVE(r1)
- mtctr r0
- ld r0,LR_SAVE(r1)
- mtlr r0
- ld r0,CCR_SAVE(r1)
- mtcr r0
- REST_GPR(0)
- REST_GPR(2)
- REST_GPR(3)
- REST_GPR(4)
- REST_GPR(5)
- REST_GPR(6)
- REST_GPR(7)
- REST_GPR(8)
- REST_GPR(9)
- REST_GPR(10)
- REST_GPR(11)
- REST_GPR(12)
- REST_GPR(13)
- REST_GPR(14)
- REST_GPR(15)
- REST_GPR(16)
- REST_GPR(17)
- REST_GPR(18)
- REST_GPR(19)
- REST_GPR(20)
- REST_GPR(21)
- REST_GPR(22)
- REST_GPR(23)
- REST_GPR(24)
- REST_GPR(25)
- REST_GPR(26)
- REST_GPR(27)
- REST_GPR(28)
- REST_GPR(29)
- REST_GPR(30)
- REST_GPR(31)
- addi r1,r1,STACK_FRAME
- RFEBB
-FUNC_END(ebb_handler)
diff --git a/powerpc/pmu/ebb/ebb_on_child_test.c b/powerpc/pmu/ebb/ebb_on_child_test.c
deleted file mode 100644
index c45f948..0000000
--- a/powerpc/pmu/ebb/ebb_on_child_test.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "ebb.h"
-
-
-/*
- * Tests we can setup an EBB on our child. Nothing interesting happens, because
- * even though the event is enabled and running the child hasn't enabled the
- * actual delivery of the EBBs.
- */
-
-static int victim_child(union pipe read_pipe, union pipe write_pipe)
-{
- int i;
-
- FAIL_IF(wait_for_parent(read_pipe));
- FAIL_IF(notify_parent(write_pipe));
-
- /* Parent creates EBB event */
-
- FAIL_IF(wait_for_parent(read_pipe));
- FAIL_IF(notify_parent(write_pipe));
-
- /* Check the EBB is enabled by writing PMC1 */
- write_pmc1();
-
- /* EBB event is enabled here */
- for (i = 0; i < 1000000; i++) ;
-
- return 0;
-}
-
-int ebb_on_child(void)
-{
- union pipe read_pipe, write_pipe;
- struct event event;
- pid_t pid;
-
- FAIL_IF(pipe(read_pipe.fds) == -1);
- FAIL_IF(pipe(write_pipe.fds) == -1);
-
- pid = fork();
- if (pid == 0) {
- /* NB order of pipes looks reversed */
- exit(victim_child(write_pipe, read_pipe));
- }
-
- FAIL_IF(sync_with_child(read_pipe, write_pipe));
-
- /* Child is running now */
-
- 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_with_pid(&event, pid));
- FAIL_IF(ebb_event_enable(&event));
-
- FAIL_IF(sync_with_child(read_pipe, write_pipe));
-
- /* Child should just exit happily */
- FAIL_IF(wait_for_child(pid));
-
- event_close(&event);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(ebb_on_child, "ebb_on_child");
-}
diff --git a/powerpc/pmu/ebb/ebb_on_willing_child_test.c b/powerpc/pmu/ebb/ebb_on_willing_child_test.c
deleted file mode 100644
index 11acf1d..0000000
--- a/powerpc/pmu/ebb/ebb_on_willing_child_test.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "ebb.h"
-
-
-/*
- * Tests we can setup an EBB on our child. The child expects this and enables
- * EBBs, which are then delivered to the child, even though the event is
- * created by the parent.
- */
-
-static int victim_child(union pipe read_pipe, union pipe write_pipe)
-{
- FAIL_IF(wait_for_parent(read_pipe));
-
- /* Setup our EBB handler, before the EBB event is created */
- ebb_enable_pmc_counting(1);
- setup_ebb_handler(standard_ebb_callee);
- ebb_global_enable();
-
- FAIL_IF(notify_parent(write_pipe));
-
- while (ebb_state.stats.ebb_count < 20) {
- FAIL_IF(core_busy_loop());
- }
-
- ebb_global_disable();
- ebb_freeze_pmcs();
-
- count_pmc(1, sample_period);
-
- dump_ebb_state();
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
-
- return 0;
-}
-
-/* Tests we can setup an EBB on our child - if it's expecting it */
-int ebb_on_willing_child(void)
-{
- union pipe read_pipe, write_pipe;
- struct event event;
- pid_t pid;
-
- FAIL_IF(pipe(read_pipe.fds) == -1);
- FAIL_IF(pipe(write_pipe.fds) == -1);
-
- pid = fork();
- if (pid == 0) {
- /* NB order of pipes looks reversed */
- exit(victim_child(write_pipe, read_pipe));
- }
-
- /* Signal the child to setup its EBB handler */
- FAIL_IF(sync_with_child(read_pipe, write_pipe));
-
- /* Child is running now */
-
- 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_with_pid(&event, pid));
- FAIL_IF(ebb_event_enable(&event));
-
- /* Child show now take EBBs and then exit */
- FAIL_IF(wait_for_child(pid));
-
- event_close(&event);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(ebb_on_willing_child, "ebb_on_willing_child");
-}
diff --git a/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c b/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c
deleted file mode 100644
index be4dd5a..0000000
--- a/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "ebb.h"
-
-
-/*
- * Tests an EBB vs a cpu event - in that order. The EBB should force the cpu
- * event off the PMU.
- */
-
-static int setup_cpu_event(struct event *event, int cpu)
-{
- event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL");
-
- event->attr.exclude_kernel = 1;
- event->attr.exclude_hv = 1;
- event->attr.exclude_idle = 1;
-
- SKIP_IF(require_paranoia_below(1));
- FAIL_IF(event_open_with_cpu(event, cpu));
- FAIL_IF(event_enable(event));
-
- return 0;
-}
-
-int ebb_vs_cpu_event(void)
-{
- union pipe read_pipe, write_pipe;
- struct event event;
- int cpu, rc;
- pid_t pid;
-
- cpu = pick_online_cpu();
- FAIL_IF(cpu < 0);
- FAIL_IF(bind_to_cpu(cpu));
-
- FAIL_IF(pipe(read_pipe.fds) == -1);
- FAIL_IF(pipe(write_pipe.fds) == -1);
-
- pid = fork();
- if (pid == 0) {
- /* NB order of pipes looks reversed */
- exit(ebb_child(write_pipe, read_pipe));
- }
-
- /* Signal the child to install its EBB event and wait */
- FAIL_IF(sync_with_child(read_pipe, write_pipe));
-
- /* Now try to install our CPU event */
- rc = setup_cpu_event(&event, cpu);
- if (rc) {
- kill_child_and_wait(pid);
- return rc;
- }
-
- /* Signal the child to run */
- FAIL_IF(sync_with_child(read_pipe, write_pipe));
-
- /* .. and wait for it to complete */
- FAIL_IF(wait_for_child(pid));
- FAIL_IF(event_disable(&event));
- FAIL_IF(event_read(&event));
-
- event_report(&event);
-
- /* The cpu event may have run, but we don't expect 100% */
- FAIL_IF(event.result.enabled >= event.result.running);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(ebb_vs_cpu_event, "ebb_vs_cpu_event");
-}
diff --git a/powerpc/pmu/ebb/event_attributes_test.c b/powerpc/pmu/ebb/event_attributes_test.c
deleted file mode 100644
index 7e78153..0000000
--- a/powerpc/pmu/ebb/event_attributes_test.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "ebb.h"
-
-
-/*
- * Test various attributes of the EBB event are enforced.
- */
-int event_attributes(void)
-{
- struct event event, leader;
-
- event_init(&event, 0x1001e);
- event_leader_ebb_init(&event);
- /* Expected to succeed */
- FAIL_IF(event_open(&event));
- event_close(&event);
-
-
- event_init(&event, 0x001e); /* CYCLES - no PMC specified */
- event_leader_ebb_init(&event);
- /* Expected to fail, no PMC specified */
- FAIL_IF(event_open(&event) == 0);
-
-
- event_init(&event, 0x2001e);
- event_leader_ebb_init(&event);
- event.attr.exclusive = 0;
- /* Expected to fail, not exclusive */
- FAIL_IF(event_open(&event) == 0);
-
-
- event_init(&event, 0x3001e);
- event_leader_ebb_init(&event);
- event.attr.freq = 1;
- /* Expected to fail, sets freq */
- FAIL_IF(event_open(&event) == 0);
-
-
- event_init(&event, 0x4001e);
- event_leader_ebb_init(&event);
- event.attr.sample_period = 1;
- /* Expected to fail, sets sample_period */
- FAIL_IF(event_open(&event) == 0);
-
-
- event_init(&event, 0x1001e);
- event_leader_ebb_init(&event);
- event.attr.enable_on_exec = 1;
- /* Expected to fail, sets enable_on_exec */
- FAIL_IF(event_open(&event) == 0);
-
-
- event_init(&event, 0x1001e);
- event_leader_ebb_init(&event);
- event.attr.inherit = 1;
- /* Expected to fail, sets inherit */
- FAIL_IF(event_open(&event) == 0);
-
-
- event_init(&leader, 0x1001e);
- event_leader_ebb_init(&leader);
- FAIL_IF(event_open(&leader));
-
- event_init(&event, 0x20002);
- event_ebb_init(&event);
-
- /* Expected to succeed */
- FAIL_IF(event_open_with_group(&event, leader.fd));
- event_close(&leader);
- event_close(&event);
-
-
- event_init(&leader, 0x1001e);
- event_leader_ebb_init(&leader);
- FAIL_IF(event_open(&leader));
-
- event_init(&event, 0x20002);
-
- /* Expected to fail, event doesn't request EBB, leader does */
- FAIL_IF(event_open_with_group(&event, leader.fd) == 0);
- event_close(&leader);
-
-
- event_init(&leader, 0x1001e);
- event_leader_ebb_init(&leader);
- /* Clear the EBB flag */
- leader.attr.config &= ~(1ull << 63);
-
- FAIL_IF(event_open(&leader));
-
- event_init(&event, 0x20002);
- event_ebb_init(&event);
-
- /* Expected to fail, leader doesn't request EBB */
- FAIL_IF(event_open_with_group(&event, leader.fd) == 0);
- event_close(&leader);
-
-
- event_init(&leader, 0x1001e);
- event_leader_ebb_init(&leader);
- leader.attr.exclusive = 0;
- /* Expected to fail, leader isn't exclusive */
- FAIL_IF(event_open(&leader) == 0);
-
-
- event_init(&leader, 0x1001e);
- event_leader_ebb_init(&leader);
- leader.attr.pinned = 0;
- /* Expected to fail, leader isn't pinned */
- FAIL_IF(event_open(&leader) == 0);
-
- event_init(&event, 0x1001e);
- event_leader_ebb_init(&event);
- /* Expected to fail, not a task event */
- SKIP_IF(require_paranoia_below(1));
- FAIL_IF(event_open_with_cpu(&event, 0) == 0);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(event_attributes, "event_attributes");
-}
diff --git a/powerpc/pmu/ebb/fixed_instruction_loop.S b/powerpc/pmu/ebb/fixed_instruction_loop.S
deleted file mode 100644
index b866a05..0000000
--- a/powerpc/pmu/ebb/fixed_instruction_loop.S
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <ppc-asm.h>
-
- .text
-
-FUNC_START(thirty_two_instruction_loop)
- cmpwi r3,0
- beqlr
- addi r4,r3,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1 # 28 addi's
- subi r3,r3,1
- b FUNC_NAME(thirty_two_instruction_loop)
-FUNC_END(thirty_two_instruction_loop)
diff --git a/powerpc/pmu/ebb/fork_cleanup_test.c b/powerpc/pmu/ebb/fork_cleanup_test.c
deleted file mode 100644
index 9e7af6e..0000000
--- a/powerpc/pmu/ebb/fork_cleanup_test.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#include "ebb.h"
-
-
-/*
- * Test that a fork clears the PMU state of the child. eg. BESCR/EBBHR/EBBRR
- * are cleared, and MMCR0_PMCC is reset, preventing the child from accessing
- * the PMU.
- */
-
-static struct event event;
-
-static int child(void)
-{
- /* Even though we have EBE=0 we can still see the EBB regs */
- FAIL_IF(mfspr(SPRN_BESCR) != 0);
- FAIL_IF(mfspr(SPRN_EBBHR) != 0);
- FAIL_IF(mfspr(SPRN_EBBRR) != 0);
-
- FAIL_IF(catch_sigill(write_pmc1));
-
- /* We can still read from the event, though it is on our parent */
- FAIL_IF(event_read(&event));
-
- return 0;
-}
-
-/* Tests that fork clears EBB state */
-int fork_cleanup(void)
-{
- pid_t pid;
-
- event_init_named(&event, 0x1001e, "cycles");
- event_leader_ebb_init(&event);
-
- FAIL_IF(event_open(&event));
-
- ebb_enable_pmc_counting(1);
- setup_ebb_handler(standard_ebb_callee);
- ebb_global_enable();
-
- FAIL_IF(ebb_event_enable(&event));
-
- mtspr(SPRN_MMCR0, MMCR0_FC);
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
-
- /* Don't need to actually take any EBBs */
-
- pid = fork();
- if (pid == 0)
- exit(child());
-
- /* Child does the actual testing */
- FAIL_IF(wait_for_child(pid));
-
- /* After fork */
- event_close(&event);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(fork_cleanup, "fork_cleanup");
-}
diff --git a/powerpc/pmu/ebb/instruction_count_test.c b/powerpc/pmu/ebb/instruction_count_test.c
deleted file mode 100644
index f8190fa..0000000
--- a/powerpc/pmu/ebb/instruction_count_test.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-#include <sys/prctl.h>
-
-#include "ebb.h"
-
-
-/*
- * Run a calibrated instruction loop and count instructions executed using
- * EBBs. Make sure the counts look right.
- */
-
-extern void thirty_two_instruction_loop(uint64_t loops);
-
-static bool counters_frozen = true;
-
-static int do_count_loop(struct event *event, uint64_t instructions,
- uint64_t overhead, bool report)
-{
- int64_t difference, expected;
- double percentage;
-
- clear_ebb_stats();
-
- counters_frozen = false;
- mb();
- mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC);
-
- thirty_two_instruction_loop(instructions >> 5);
-
- counters_frozen = true;
- mb();
- mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC);
-
- count_pmc(4, sample_period);
-
- event->result.value = ebb_state.stats.pmc_count[4-1];
- expected = instructions + overhead;
- difference = event->result.value - expected;
- percentage = (double)difference / event->result.value * 100;
-
- if (report) {
- printf("Looped for %lu instructions, overhead %lu\n", instructions, overhead);
- printf("Expected %lu\n", expected);
- printf("Actual %llu\n", event->result.value);
- printf("Error %ld, %f%%\n", difference, percentage);
- printf("Took %d EBBs\n", ebb_state.stats.ebb_count);
- }
-
- if (difference < 0)
- difference = -difference;
-
- /* Tolerate a difference of up to 0.0001 % */
- difference *= 10000 * 100;
- if (difference / event->result.value)
- return -1;
-
- return 0;
-}
-
-/* Count how many instructions it takes to do a null loop */
-static uint64_t determine_overhead(struct event *event)
-{
- uint64_t current, overhead;
- int i;
-
- do_count_loop(event, 0, 0, false);
- overhead = event->result.value;
-
- for (i = 0; i < 100; i++) {
- do_count_loop(event, 0, 0, false);
- current = event->result.value;
- if (current < overhead) {
- printf("Replacing overhead %lu with %lu\n", overhead, current);
- overhead = current;
- }
- }
-
- return overhead;
-}
-
-static void pmc4_ebb_callee(void)
-{
- uint64_t val;
-
- val = mfspr(SPRN_BESCR);
- if (!(val & BESCR_PMEO)) {
- ebb_state.stats.spurious++;
- goto out;
- }
-
- ebb_state.stats.ebb_count++;
- count_pmc(4, sample_period);
-out:
- if (counters_frozen)
- reset_ebb_with_clear_mask(MMCR0_PMAO);
- else
- reset_ebb();
-}
-
-int instruction_count(void)
-{
- struct event event;
- uint64_t overhead;
-
- event_init_named(&event, 0x400FA, "PM_RUN_INST_CMPL");
- 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));
- FAIL_IF(ebb_event_enable(&event));
-
- sample_period = COUNTER_OVERFLOW;
-
- setup_ebb_handler(pmc4_ebb_callee);
- mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC);
- ebb_global_enable();
-
- overhead = determine_overhead(&event);
- printf("Overhead of null loop: %lu instructions\n", overhead);
-
- /* Run for 1M instructions */
- FAIL_IF(do_count_loop(&event, 0x100000, overhead, true));
-
- /* Run for 10M instructions */
- FAIL_IF(do_count_loop(&event, 0xa00000, overhead, true));
-
- /* Run for 100M instructions */
- FAIL_IF(do_count_loop(&event, 0x6400000, overhead, true));
-
- /* Run for 1G instructions */
- FAIL_IF(do_count_loop(&event, 0x40000000, overhead, true));
-
- /* Run for 16G instructions */
- FAIL_IF(do_count_loop(&event, 0x400000000, overhead, true));
-
- /* Run for 64G instructions */
- FAIL_IF(do_count_loop(&event, 0x1000000000, overhead, true));
-
- /* Run for 128G instructions */
- FAIL_IF(do_count_loop(&event, 0x2000000000, overhead, true));
-
- ebb_global_disable();
- event_close(&event);
-
- printf("Finished OK\n");
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(instruction_count, "instruction_count");
-}
diff --git a/powerpc/pmu/ebb/lost_exception_test.c b/powerpc/pmu/ebb/lost_exception_test.c
deleted file mode 100644
index 0c9dd9b..0000000
--- a/powerpc/pmu/ebb/lost_exception_test.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <sched.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-#include "ebb.h"
-
-
-/*
- * Test that tries to trigger CPU_FTR_PMAO_BUG. Which is a hardware defect
- * where an exception triggers but we context switch before it is delivered and
- * lose the exception.
- */
-
-static int test_body(void)
-{
- int i, orig_period, max_period;
- struct event event;
-
- /* We use PMC4 to make sure the kernel switches all counters correctly */
- event_init_named(&event, 0x40002, "instructions");
- 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));
-
- ebb_enable_pmc_counting(4);
- setup_ebb_handler(standard_ebb_callee);
- ebb_global_enable();
- FAIL_IF(ebb_event_enable(&event));
-
- /*
- * We want a low sample period, but we also want to get out of the EBB
- * handler without tripping up again.
- *
- * This value picked after much experimentation.
- */
- orig_period = max_period = sample_period = 400;
-
- mtspr(SPRN_PMC4, pmc_sample_period(sample_period));
-
- while (ebb_state.stats.ebb_count < 1000000) {
- /*
- * We are trying to get the EBB exception to race exactly with
- * us entering the kernel to do the syscall. We then need the
- * kernel to decide our timeslice is up and context switch to
- * the other thread. When we come back our EBB will have been
- * lost and we'll spin in this while loop forever.
- */
-
- for (i = 0; i < 100000; i++)
- sched_yield();
-
- /* Change the sample period slightly to try and hit the race */
- if (sample_period >= (orig_period + 200))
- sample_period = orig_period;
- else
- sample_period++;
-
- if (sample_period > max_period)
- max_period = sample_period;
- }
-
- ebb_freeze_pmcs();
- ebb_global_disable();
-
- count_pmc(4, sample_period);
- mtspr(SPRN_PMC4, 0xdead);
-
- dump_summary_ebb_state();
- dump_ebb_hw_state();
-
- event_close(&event);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
-
- /* We vary our sample period so we need extra fudge here */
- FAIL_IF(!ebb_check_count(4, orig_period, 2 * (max_period - orig_period)));
-
- return 0;
-}
-
-static int lost_exception(void)
-{
- return eat_cpu(test_body);
-}
-
-int main(void)
-{
- return test_harness(lost_exception, "lost_exception");
-}
diff --git a/powerpc/pmu/ebb/multi_counter_test.c b/powerpc/pmu/ebb/multi_counter_test.c
deleted file mode 100644
index 67d78af..0000000
--- a/powerpc/pmu/ebb/multi_counter_test.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-
-#include "ebb.h"
-
-
-/*
- * Test counting multiple events using EBBs.
- */
-int multi_counter(void)
-{
- struct event events[6];
- int i, group_fd;
-
- event_init_named(&events[0], 0x1001C, "PM_CMPLU_STALL_THRD");
- event_init_named(&events[1], 0x2D016, "PM_CMPLU_STALL_FXU");
- event_init_named(&events[2], 0x30006, "PM_CMPLU_STALL_OTHER_CMPL");
- event_init_named(&events[3], 0x4000A, "PM_CMPLU_STALL");
- event_init_named(&events[4], 0x600f4, "PM_RUN_CYC");
- event_init_named(&events[5], 0x500fa, "PM_RUN_INST_CMPL");
-
- event_leader_ebb_init(&events[0]);
- for (i = 1; i < 6; i++)
- event_ebb_init(&events[i]);
-
- group_fd = -1;
- for (i = 0; i < 6; i++) {
- events[i].attr.exclude_kernel = 1;
- events[i].attr.exclude_hv = 1;
- events[i].attr.exclude_idle = 1;
-
- FAIL_IF(event_open_with_group(&events[i], group_fd));
- if (group_fd == -1)
- group_fd = events[0].fd;
- }
-
- ebb_enable_pmc_counting(1);
- ebb_enable_pmc_counting(2);
- ebb_enable_pmc_counting(3);
- ebb_enable_pmc_counting(4);
- ebb_enable_pmc_counting(5);
- ebb_enable_pmc_counting(6);
- setup_ebb_handler(standard_ebb_callee);
-
- FAIL_IF(ioctl(events[0].fd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP));
- FAIL_IF(event_read(&events[0]));
-
- ebb_global_enable();
-
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
- mtspr(SPRN_PMC2, pmc_sample_period(sample_period));
- mtspr(SPRN_PMC3, pmc_sample_period(sample_period));
- mtspr(SPRN_PMC4, pmc_sample_period(sample_period));
- mtspr(SPRN_PMC5, pmc_sample_period(sample_period));
- mtspr(SPRN_PMC6, pmc_sample_period(sample_period));
-
- while (ebb_state.stats.ebb_count < 50) {
- FAIL_IF(core_busy_loop());
- FAIL_IF(ebb_check_mmcr0());
- }
-
- ebb_global_disable();
- ebb_freeze_pmcs();
-
- count_pmc(1, sample_period);
- count_pmc(2, sample_period);
- count_pmc(3, sample_period);
- count_pmc(4, sample_period);
- count_pmc(5, sample_period);
- count_pmc(6, sample_period);
-
- dump_ebb_state();
-
- for (i = 0; i < 6; i++)
- event_close(&events[i]);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(multi_counter, "multi_counter");
-}
diff --git a/powerpc/pmu/ebb/multi_ebb_procs_test.c b/powerpc/pmu/ebb/multi_ebb_procs_test.c
deleted file mode 100644
index b8dc371..0000000
--- a/powerpc/pmu/ebb/multi_ebb_procs_test.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-
-#include "ebb.h"
-
-
-/*
- * Test running multiple EBB using processes at once on a single CPU. They
- * should all run happily without interfering with each other.
- */
-
-static bool child_should_exit;
-
-static void sigint_handler(int signal)
-{
- child_should_exit = true;
-}
-
-struct sigaction sigint_action = {
- .sa_handler = sigint_handler,
-};
-
-static int cycles_child(void)
-{
- struct event event;
-
- if (sigaction(SIGINT, &sigint_action, NULL)) {
- perror("sigaction");
- return 1;
- }
-
- 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));
-
- ebb_enable_pmc_counting(1);
- setup_ebb_handler(standard_ebb_callee);
- ebb_global_enable();
-
- FAIL_IF(ebb_event_enable(&event));
-
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
-
- while (!child_should_exit) {
- FAIL_IF(core_busy_loop());
- FAIL_IF(ebb_check_mmcr0());
- }
-
- ebb_global_disable();
- ebb_freeze_pmcs();
-
- count_pmc(1, sample_period);
-
- dump_summary_ebb_state();
-
- event_close(&event);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
-
- return 0;
-}
-
-#define NR_CHILDREN 4
-
-int multi_ebb_procs(void)
-{
- pid_t pids[NR_CHILDREN];
- int cpu, rc, i;
-
- cpu = pick_online_cpu();
- FAIL_IF(cpu < 0);
- FAIL_IF(bind_to_cpu(cpu));
-
- for (i = 0; i < NR_CHILDREN; i++) {
- pids[i] = fork();
- if (pids[i] == 0)
- exit(cycles_child());
- }
-
- /* Have them all run for "a while" */
- sleep(10);
-
- rc = 0;
- for (i = 0; i < NR_CHILDREN; i++) {
- /* Tell them to stop */
- kill(pids[i], SIGINT);
- /* And wait */
- rc |= wait_for_child(pids[i]);
- }
-
- return rc;
-}
-
-int main(void)
-{
- return test_harness(multi_ebb_procs, "multi_ebb_procs");
-}
diff --git a/powerpc/pmu/ebb/no_handler_test.c b/powerpc/pmu/ebb/no_handler_test.c
deleted file mode 100644
index 2f9bf8e..0000000
--- a/powerpc/pmu/ebb/no_handler_test.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#include "ebb.h"
-
-
-/* Test that things work sanely if we have no handler */
-
-static int no_handler_test(void)
-{
- struct event event;
- u64 val;
- int i;
-
- 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));
- FAIL_IF(ebb_event_enable(&event));
-
- val = mfspr(SPRN_EBBHR);
- FAIL_IF(val != 0);
-
- /* Make sure it overflows quickly */
- sample_period = 1000;
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
-
- /* Spin to make sure the event has time to overflow */
- for (i = 0; i < 1000; i++)
- mb();
-
- dump_ebb_state();
-
- /* We expect to see the PMU frozen & PMAO set */
- val = mfspr(SPRN_MMCR0);
- FAIL_IF(val != 0x0000000080000080);
-
- event_close(&event);
-
- dump_ebb_state();
-
- /* The real test is that we never took an EBB at 0x0 */
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(no_handler_test,"no_handler_test");
-}
diff --git a/powerpc/pmu/ebb/pmae_handling_test.c b/powerpc/pmu/ebb/pmae_handling_test.c
deleted file mode 100644
index 986500f..0000000
--- a/powerpc/pmu/ebb/pmae_handling_test.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <sched.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "ebb.h"
-
-
-/*
- * Test that the kernel properly handles PMAE across context switches.
- *
- * We test this by calling into the kernel inside our EBB handler, where PMAE
- * is clear. A cpu eater companion thread is running on the same CPU as us to
- * encourage the scheduler to switch us.
- *
- * The kernel must make sure that when it context switches us back in, it
- * honours the fact that we had PMAE clear.
- *
- * Observed to hit the failing case on the first EBB with a broken kernel.
- */
-
-static bool mmcr0_mismatch;
-static uint64_t before, after;
-
-static void syscall_ebb_callee(void)
-{
- uint64_t val;
-
- val = mfspr(SPRN_BESCR);
- if (!(val & BESCR_PMEO)) {
- ebb_state.stats.spurious++;
- goto out;
- }
-
- ebb_state.stats.ebb_count++;
- count_pmc(1, sample_period);
-
- before = mfspr(SPRN_MMCR0);
-
- /* Try and get ourselves scheduled, to force a PMU context switch */
- sched_yield();
-
- after = mfspr(SPRN_MMCR0);
- if (before != after)
- mmcr0_mismatch = true;
-
-out:
- reset_ebb();
-}
-
-static int test_body(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(syscall_ebb_callee);
- ebb_global_enable();
-
- FAIL_IF(ebb_event_enable(&event));
-
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
-
- while (ebb_state.stats.ebb_count < 20 && !mmcr0_mismatch)
- FAIL_IF(core_busy_loop());
-
- ebb_global_disable();
- ebb_freeze_pmcs();
-
- count_pmc(1, sample_period);
-
- dump_ebb_state();
-
- if (mmcr0_mismatch)
- printf("Saw MMCR0 before 0x%lx after 0x%lx\n", before, after);
-
- event_close(&event);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0);
- FAIL_IF(mmcr0_mismatch);
-
- return 0;
-}
-
-int pmae_handling(void)
-{
- return eat_cpu(test_body);
-}
-
-int main(void)
-{
- return test_harness(pmae_handling, "pmae_handling");
-}
diff --git a/powerpc/pmu/ebb/pmc56_overflow_test.c b/powerpc/pmu/ebb/pmc56_overflow_test.c
deleted file mode 100644
index a503fa7..0000000
--- a/powerpc/pmu/ebb/pmc56_overflow_test.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "ebb.h"
-
-
-/*
- * Test that PMC5 & 6 are frozen (ie. don't overflow) when they are not being
- * used. Tests the MMCR0_FC56 logic in the kernel.
- */
-
-static int pmc56_overflowed;
-
-static void ebb_callee(void)
-{
- uint64_t val;
-
- val = mfspr(SPRN_BESCR);
- if (!(val & BESCR_PMEO)) {
- ebb_state.stats.spurious++;
- goto out;
- }
-
- ebb_state.stats.ebb_count++;
- count_pmc(2, sample_period);
-
- val = mfspr(SPRN_PMC5);
- if (val >= COUNTER_OVERFLOW)
- pmc56_overflowed++;
-
- count_pmc(5, COUNTER_OVERFLOW);
-
- val = mfspr(SPRN_PMC6);
- if (val >= COUNTER_OVERFLOW)
- pmc56_overflowed++;
-
- count_pmc(6, COUNTER_OVERFLOW);
-
-out:
- reset_ebb();
-}
-
-int pmc56_overflow(void)
-{
- struct event event;
-
- /* Use PMC2 so we set PMCjCE, which enables PMC5/6 */
- event_init(&event, 0x2001e);
- 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);
- ebb_global_enable();
-
- FAIL_IF(ebb_event_enable(&event));
-
- mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
- mtspr(SPRN_PMC5, 0);
- mtspr(SPRN_PMC6, 0);
-
- while (ebb_state.stats.ebb_count < 10)
- FAIL_IF(core_busy_loop());
-
- ebb_global_disable();
- ebb_freeze_pmcs();
-
- count_pmc(2, sample_period);
-
- dump_ebb_state();
-
- printf("PMC5/6 overflow %d\n", pmc56_overflowed);
-
- event_close(&event);
-
- FAIL_IF(ebb_state.stats.ebb_count == 0 || pmc56_overflowed != 0);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(pmc56_overflow, "pmc56_overflow");
-}
diff --git a/powerpc/pmu/ebb/reg.h b/powerpc/pmu/ebb/reg.h
deleted file mode 100644
index 5921b0d..0000000
--- a/powerpc/pmu/ebb/reg.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#ifndef _SELFTESTS_POWERPC_REG_H
-#define _SELFTESTS_POWERPC_REG_H
-
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
-
-#define mfspr(rn) ({unsigned long rval; \
- asm volatile("mfspr %0," __stringify(rn) \
- : "=r" (rval)); rval; })
-#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \
- : "r" ((unsigned long)(v)) \
- : "memory")
-
-#define mb() asm volatile("sync" : : : "memory");
-
-#define SPRN_MMCR2 769
-#define SPRN_MMCRA 770
-#define SPRN_MMCR0 779
-#define MMCR0_PMAO 0x00000080
-#define MMCR0_PMAE 0x04000000
-#define MMCR0_FC 0x80000000
-#define SPRN_EBBHR 804
-#define SPRN_EBBRR 805
-#define SPRN_BESCR 806 /* Branch event status & control register */
-#define SPRN_BESCRS 800 /* Branch event status & control set (1 bits set to 1) */
-#define SPRN_BESCRSU 801 /* Branch event status & control set upper */
-#define SPRN_BESCRR 802 /* Branch event status & control REset (1 bits set to 0) */
-#define SPRN_BESCRRU 803 /* Branch event status & control REset upper */
-
-#define BESCR_PMEO 0x1 /* PMU Event-based exception Occurred */
-#define BESCR_PME (0x1ul << 32) /* PMU Event-based exception Enable */
-
-#define SPRN_PMC1 771
-#define SPRN_PMC2 772
-#define SPRN_PMC3 773
-#define SPRN_PMC4 774
-#define SPRN_PMC5 775
-#define SPRN_PMC6 776
-
-#define SPRN_SIAR 780
-#define SPRN_SDAR 781
-#define SPRN_SIER 768
-
-#endif /* _SELFTESTS_POWERPC_REG_H */
diff --git a/powerpc/pmu/ebb/reg_access_test.c b/powerpc/pmu/ebb/reg_access_test.c
deleted file mode 100644
index 0cae66f..0000000
--- a/powerpc/pmu/ebb/reg_access_test.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "ebb.h"
-#include "reg.h"
-
-
-/*
- * Test basic access to the EBB regs, they should be user accessible with no
- * kernel interaction required.
- */
-int reg_access(void)
-{
- uint64_t val, expected;
-
- expected = 0x8000000100000000ull;
- mtspr(SPRN_BESCR, expected);
- val = mfspr(SPRN_BESCR);
-
- FAIL_IF(val != expected);
-
- expected = 0x0000000001000000ull;
- mtspr(SPRN_EBBHR, expected);
- val = mfspr(SPRN_EBBHR);
-
- FAIL_IF(val != expected);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(reg_access, "reg_access");
-}
diff --git a/powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c b/powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c
deleted file mode 100644
index d56607e..0000000
--- a/powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "ebb.h"
-
-
-/*
- * Tests a pinned per-task event vs an EBB - in that order. The pinned per-task
- * event should prevent the EBB event from being enabled.
- */
-
-static int setup_child_event(struct event *event, pid_t child_pid)
-{
- event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL");
-
- event->attr.pinned = 1;
-
- event->attr.exclude_kernel = 1;
- event->attr.exclude_hv = 1;
- event->attr.exclude_idle = 1;
-
- FAIL_IF(event_open_with_pid(event, child_pid));
- FAIL_IF(event_enable(event));
-
- return 0;
-}
-
-int task_event_pinned_vs_ebb(void)
-{
- union pipe read_pipe, write_pipe;
- struct event event;
- pid_t pid;
- int rc;
-
- FAIL_IF(pipe(read_pipe.fds) == -1);
- FAIL_IF(pipe(write_pipe.fds) == -1);
-
- pid = fork();
- if (pid == 0) {
- /* NB order of pipes looks reversed */
- exit(ebb_child(write_pipe, read_pipe));
- }
-
- /* We setup the task event first */
- rc = setup_child_event(&event, pid);
- if (rc) {
- kill_child_and_wait(pid);
- return rc;
- }
-
- /* Signal the child to install its EBB event and wait */
- if (sync_with_child(read_pipe, write_pipe))
- /* If it fails, wait for it to exit */
- goto wait;
-
- /* Signal the child to run */
- FAIL_IF(sync_with_child(read_pipe, write_pipe));
-
-wait:
- /* We expect it to fail to read the event */
- FAIL_IF(wait_for_child(pid) != 2);
- FAIL_IF(event_disable(&event));
- FAIL_IF(event_read(&event));
-
- event_report(&event);
-
- FAIL_IF(event.result.value == 0);
- /*
- * For reasons I don't understand enabled is usually just slightly
- * lower than running. Would be good to confirm why.
- */
- FAIL_IF(event.result.enabled == 0);
- FAIL_IF(event.result.running == 0);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(task_event_pinned_vs_ebb, "task_event_pinned_vs_ebb");
-}
diff --git a/powerpc/pmu/ebb/task_event_vs_ebb_test.c b/powerpc/pmu/ebb/task_event_vs_ebb_test.c
deleted file mode 100644
index eba3219..0000000
--- a/powerpc/pmu/ebb/task_event_vs_ebb_test.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "ebb.h"
-
-
-/*
- * Tests a per-task event vs an EBB - in that order. The EBB should push the
- * per-task event off the PMU.
- */
-
-static int setup_child_event(struct event *event, pid_t child_pid)
-{
- event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL");
-
- event->attr.exclude_kernel = 1;
- event->attr.exclude_hv = 1;
- event->attr.exclude_idle = 1;
-
- FAIL_IF(event_open_with_pid(event, child_pid));
- FAIL_IF(event_enable(event));
-
- return 0;
-}
-
-int task_event_vs_ebb(void)
-{
- union pipe read_pipe, write_pipe;
- struct event event;
- pid_t pid;
- int rc;
-
- FAIL_IF(pipe(read_pipe.fds) == -1);
- FAIL_IF(pipe(write_pipe.fds) == -1);
-
- pid = fork();
- if (pid == 0) {
- /* NB order of pipes looks reversed */
- exit(ebb_child(write_pipe, read_pipe));
- }
-
- /* We setup the task event first */
- rc = setup_child_event(&event, pid);
- if (rc) {
- kill_child_and_wait(pid);
- return rc;
- }
-
- /* Signal the child to install its EBB event and wait */
- if (sync_with_child(read_pipe, write_pipe))
- /* If it fails, wait for it to exit */
- goto wait;
-
- /* Signal the child to run */
- FAIL_IF(sync_with_child(read_pipe, write_pipe));
-
-wait:
- /* The EBB event should push the task event off so the child should succeed */
- FAIL_IF(wait_for_child(pid));
- FAIL_IF(event_disable(&event));
- FAIL_IF(event_read(&event));
-
- event_report(&event);
-
- /* The task event may have run, or not so we can't assert anything about it */
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(task_event_vs_ebb, "task_event_vs_ebb");
-}
diff --git a/powerpc/pmu/ebb/trace.c b/powerpc/pmu/ebb/trace.c
deleted file mode 100644
index 251e66a..0000000
--- a/powerpc/pmu/ebb/trace.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-
-#include "trace.h"
-
-
-struct trace_buffer *trace_buffer_allocate(u64 size)
-{
- struct trace_buffer *tb;
-
- if (size < sizeof(*tb)) {
- fprintf(stderr, "Error: trace buffer too small\n");
- return NULL;
- }
-
- tb = mmap(NULL, size, PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- if (tb == MAP_FAILED) {
- perror("mmap");
- return NULL;
- }
-
- tb->size = size;
- tb->tail = tb->data;
- tb->overflow = false;
-
- return tb;
-}
-
-static bool trace_check_bounds(struct trace_buffer *tb, void *p)
-{
- return p < ((void *)tb + tb->size);
-}
-
-static bool trace_check_alloc(struct trace_buffer *tb, void *p)
-{
- /*
- * If we ever overflowed don't allow any more input. This prevents us
- * from dropping a large item and then later logging a small one. The
- * buffer should just stop when overflow happened, not be patchy. If
- * you're overflowing, make your buffer bigger.
- */
- if (tb->overflow)
- return false;
-
- if (!trace_check_bounds(tb, p)) {
- tb->overflow = true;
- return false;
- }
-
- return true;
-}
-
-static void *trace_alloc(struct trace_buffer *tb, int bytes)
-{
- void *p, *newtail;
-
- p = tb->tail;
- newtail = tb->tail + bytes;
- if (!trace_check_alloc(tb, newtail))
- return NULL;
-
- tb->tail = newtail;
-
- return p;
-}
-
-static struct trace_entry *trace_alloc_entry(struct trace_buffer *tb, int payload_size)
-{
- struct trace_entry *e;
-
- e = trace_alloc(tb, sizeof(*e) + payload_size);
- if (e)
- e->length = payload_size;
-
- return e;
-}
-
-int trace_log_reg(struct trace_buffer *tb, u64 reg, u64 value)
-{
- struct trace_entry *e;
- u64 *p;
-
- e = trace_alloc_entry(tb, sizeof(reg) + sizeof(value));
- if (!e)
- return -ENOSPC;
-
- e->type = TRACE_TYPE_REG;
- p = (u64 *)e->data;
- *p++ = reg;
- *p++ = value;
-
- return 0;
-}
-
-int trace_log_counter(struct trace_buffer *tb, u64 value)
-{
- struct trace_entry *e;
- u64 *p;
-
- e = trace_alloc_entry(tb, sizeof(value));
- if (!e)
- return -ENOSPC;
-
- e->type = TRACE_TYPE_COUNTER;
- p = (u64 *)e->data;
- *p++ = value;
-
- return 0;
-}
-
-int trace_log_string(struct trace_buffer *tb, char *str)
-{
- struct trace_entry *e;
- char *p;
- int len;
-
- len = strlen(str);
-
- /* We NULL terminate to make printing easier */
- e = trace_alloc_entry(tb, len + 1);
- if (!e)
- return -ENOSPC;
-
- e->type = TRACE_TYPE_STRING;
- p = (char *)e->data;
- memcpy(p, str, len);
- p += len;
- *p = '\0';
-
- return 0;
-}
-
-int trace_log_indent(struct trace_buffer *tb)
-{
- struct trace_entry *e;
-
- e = trace_alloc_entry(tb, 0);
- if (!e)
- return -ENOSPC;
-
- e->type = TRACE_TYPE_INDENT;
-
- return 0;
-}
-
-int trace_log_outdent(struct trace_buffer *tb)
-{
- struct trace_entry *e;
-
- e = trace_alloc_entry(tb, 0);
- if (!e)
- return -ENOSPC;
-
- e->type = TRACE_TYPE_OUTDENT;
-
- return 0;
-}
-
-static void trace_print_header(int seq, int prefix)
-{
- printf("%*s[%d]: ", prefix, "", seq);
-}
-
-static char *trace_decode_reg(int reg)
-{
- switch (reg) {
- case 769: return "SPRN_MMCR2"; break;
- case 770: return "SPRN_MMCRA"; break;
- case 779: return "SPRN_MMCR0"; break;
- case 804: return "SPRN_EBBHR"; break;
- case 805: return "SPRN_EBBRR"; break;
- case 806: return "SPRN_BESCR"; break;
- case 800: return "SPRN_BESCRS"; break;
- case 801: return "SPRN_BESCRSU"; break;
- case 802: return "SPRN_BESCRR"; break;
- case 803: return "SPRN_BESCRRU"; break;
- case 771: return "SPRN_PMC1"; break;
- case 772: return "SPRN_PMC2"; break;
- case 773: return "SPRN_PMC3"; break;
- case 774: return "SPRN_PMC4"; break;
- case 775: return "SPRN_PMC5"; break;
- case 776: return "SPRN_PMC6"; break;
- case 780: return "SPRN_SIAR"; break;
- case 781: return "SPRN_SDAR"; break;
- case 768: return "SPRN_SIER"; break;
- }
-
- return NULL;
-}
-
-static void trace_print_reg(struct trace_entry *e)
-{
- u64 *p, *reg, *value;
- char *name;
-
- p = (u64 *)e->data;
- reg = p++;
- value = p;
-
- name = trace_decode_reg(*reg);
- if (name)
- printf("register %-10s = 0x%016llx\n", name, *value);
- else
- printf("register %lld = 0x%016llx\n", *reg, *value);
-}
-
-static void trace_print_counter(struct trace_entry *e)
-{
- u64 *value;
-
- value = (u64 *)e->data;
- printf("counter = %lld\n", *value);
-}
-
-static void trace_print_string(struct trace_entry *e)
-{
- char *str;
-
- str = (char *)e->data;
- puts(str);
-}
-
-#define BASE_PREFIX 2
-#define PREFIX_DELTA 8
-
-static void trace_print_entry(struct trace_entry *e, int seq, int *prefix)
-{
- switch (e->type) {
- case TRACE_TYPE_REG:
- trace_print_header(seq, *prefix);
- trace_print_reg(e);
- break;
- case TRACE_TYPE_COUNTER:
- trace_print_header(seq, *prefix);
- trace_print_counter(e);
- break;
- case TRACE_TYPE_STRING:
- trace_print_header(seq, *prefix);
- trace_print_string(e);
- break;
- case TRACE_TYPE_INDENT:
- trace_print_header(seq, *prefix);
- puts("{");
- *prefix += PREFIX_DELTA;
- break;
- case TRACE_TYPE_OUTDENT:
- *prefix -= PREFIX_DELTA;
- if (*prefix < BASE_PREFIX)
- *prefix = BASE_PREFIX;
- trace_print_header(seq, *prefix);
- puts("}");
- break;
- default:
- trace_print_header(seq, *prefix);
- printf("entry @ %p type %d\n", e, e->type);
- break;
- }
-}
-
-void trace_buffer_print(struct trace_buffer *tb)
-{
- struct trace_entry *e;
- int i, prefix;
- void *p;
-
- printf("Trace buffer dump:\n");
- printf(" address %p \n", tb);
- printf(" tail %p\n", tb->tail);
- printf(" size %llu\n", tb->size);
- printf(" overflow %s\n", tb->overflow ? "TRUE" : "false");
- printf(" Content:\n");
-
- p = tb->data;
-
- i = 0;
- prefix = BASE_PREFIX;
-
- while (trace_check_bounds(tb, p) && p < tb->tail) {
- e = p;
-
- trace_print_entry(e, i, &prefix);
-
- i++;
- p = (void *)e + sizeof(*e) + e->length;
- }
-}
-
-void trace_print_location(struct trace_buffer *tb)
-{
- printf("Trace buffer 0x%llx bytes @ %p\n", tb->size, tb);
-}
diff --git a/powerpc/pmu/ebb/trace.h b/powerpc/pmu/ebb/trace.h
deleted file mode 100644
index 926458e..0000000
--- a/powerpc/pmu/ebb/trace.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#ifndef _SELFTESTS_POWERPC_PMU_EBB_TRACE_H
-#define _SELFTESTS_POWERPC_PMU_EBB_TRACE_H
-
-#include "utils.h"
-
-#define TRACE_TYPE_REG 1
-#define TRACE_TYPE_COUNTER 2
-#define TRACE_TYPE_STRING 3
-#define TRACE_TYPE_INDENT 4
-#define TRACE_TYPE_OUTDENT 5
-
-struct trace_entry
-{
- u8 type;
- u8 length;
- u8 data[0];
-};
-
-struct trace_buffer
-{
- u64 size;
- bool overflow;
- void *tail;
- u8 data[0];
-};
-
-struct trace_buffer *trace_buffer_allocate(u64 size);
-int trace_log_reg(struct trace_buffer *tb, u64 reg, u64 value);
-int trace_log_counter(struct trace_buffer *tb, u64 value);
-int trace_log_string(struct trace_buffer *tb, char *str);
-int trace_log_indent(struct trace_buffer *tb);
-int trace_log_outdent(struct trace_buffer *tb);
-void trace_buffer_print(struct trace_buffer *tb);
-void trace_print_location(struct trace_buffer *tb);
-
-#endif /* _SELFTESTS_POWERPC_PMU_EBB_TRACE_H */
diff --git a/powerpc/pmu/event.c b/powerpc/pmu/event.c
deleted file mode 100644
index 184b368..0000000
--- a/powerpc/pmu/event.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2013, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#define _GNU_SOURCE
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-
-#include "event.h"
-
-
-int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
- int group_fd, unsigned long flags)
-{
- return syscall(__NR_perf_event_open, attr, pid, cpu,
- group_fd, flags);
-}
-
-void event_init_opts(struct event *e, u64 config, int type, char *name)
-{
- memset(e, 0, sizeof(*e));
-
- e->name = name;
-
- e->attr.type = type;
- e->attr.config = config;
- e->attr.size = sizeof(e->attr);
- /* This has to match the structure layout in the header */
- e->attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | \
- PERF_FORMAT_TOTAL_TIME_RUNNING;
-}
-
-void event_init_named(struct event *e, u64 config, char *name)
-{
- event_init_opts(e, config, PERF_TYPE_RAW, name);
-}
-
-void event_init(struct event *e, u64 config)
-{
- event_init_opts(e, config, PERF_TYPE_RAW, "event");
-}
-
-#define PERF_CURRENT_PID 0
-#define PERF_NO_PID -1
-#define PERF_NO_CPU -1
-#define PERF_NO_GROUP -1
-
-int event_open_with_options(struct event *e, pid_t pid, int cpu, int group_fd)
-{
- e->fd = perf_event_open(&e->attr, pid, cpu, group_fd, 0);
- if (e->fd == -1) {
- perror("perf_event_open");
- return -1;
- }
-
- return 0;
-}
-
-int event_open_with_group(struct event *e, int group_fd)
-{
- return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, group_fd);
-}
-
-int event_open_with_pid(struct event *e, pid_t pid)
-{
- return event_open_with_options(e, pid, PERF_NO_CPU, PERF_NO_GROUP);
-}
-
-int event_open_with_cpu(struct event *e, int cpu)
-{
- return event_open_with_options(e, PERF_NO_PID, cpu, PERF_NO_GROUP);
-}
-
-int event_open(struct event *e)
-{
- return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, PERF_NO_GROUP);
-}
-
-void event_close(struct event *e)
-{
- close(e->fd);
-}
-
-int event_enable(struct event *e)
-{
- return ioctl(e->fd, PERF_EVENT_IOC_ENABLE);
-}
-
-int event_disable(struct event *e)
-{
- return ioctl(e->fd, PERF_EVENT_IOC_DISABLE);
-}
-
-int event_reset(struct event *e)
-{
- return ioctl(e->fd, PERF_EVENT_IOC_RESET);
-}
-
-int event_read(struct event *e)
-{
- int rc;
-
- rc = read(e->fd, &e->result, sizeof(e->result));
- if (rc != sizeof(e->result)) {
- fprintf(stderr, "read error on event %p!\n", e);
- return -1;
- }
-
- return 0;
-}
-
-void event_report_justified(struct event *e, int name_width, int result_width)
-{
- printf("%*s: result %*llu ", name_width, e->name, result_width,
- e->result.value);
-
- if (e->result.running == e->result.enabled)
- printf("running/enabled %llu\n", e->result.running);
- else
- printf("running %llu enabled %llu\n", e->result.running,
- e->result.enabled);
-}
-
-void event_report(struct event *e)
-{
- event_report_justified(e, 0, 0);
-}
diff --git a/powerpc/pmu/event.h b/powerpc/pmu/event.h
deleted file mode 100644
index a0ea6b1..0000000
--- a/powerpc/pmu/event.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2013, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#ifndef _SELFTESTS_POWERPC_PMU_EVENT_H
-#define _SELFTESTS_POWERPC_PMU_EVENT_H
-
-#include <unistd.h>
-#include <linux/perf_event.h>
-
-#include "utils.h"
-
-
-struct event {
- struct perf_event_attr attr;
- char *name;
- int fd;
- /* This must match the read_format we use */
- struct {
- u64 value;
- u64 running;
- u64 enabled;
- } result;
-};
-
-void event_init(struct event *e, u64 config);
-void event_init_named(struct event *e, u64 config, char *name);
-void event_init_opts(struct event *e, u64 config, int type, char *name);
-int event_open_with_options(struct event *e, pid_t pid, int cpu, int group_fd);
-int event_open_with_group(struct event *e, int group_fd);
-int event_open_with_pid(struct event *e, pid_t pid);
-int event_open_with_cpu(struct event *e, int cpu);
-int event_open(struct event *e);
-void event_close(struct event *e);
-int event_enable(struct event *e);
-int event_disable(struct event *e);
-int event_reset(struct event *e);
-int event_read(struct event *e);
-void event_report_justified(struct event *e, int name_width, int result_width);
-void event_report(struct event *e);
-
-#endif /* _SELFTESTS_POWERPC_PMU_EVENT_H */
diff --git a/powerpc/pmu/l3_bank_test.c b/powerpc/pmu/l3_bank_test.c
deleted file mode 100644
index 77472f3..0000000
--- a/powerpc/pmu/l3_bank_test.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "event.h"
-#include "utils.h"
-
-#define MALLOC_SIZE (0x10000 * 10) /* Ought to be enough .. */
-
-/*
- * Tests that the L3 bank handling is correct. We fixed it in commit e9aaac1.
- */
-static int l3_bank_test(void)
-{
- struct event event;
- char *p;
- int i;
-
- p = malloc(MALLOC_SIZE);
- FAIL_IF(!p);
-
- event_init(&event, 0x84918F);
-
- FAIL_IF(event_open(&event));
-
- for (i = 0; i < MALLOC_SIZE; i += 0x10000)
- p[i] = i;
-
- event_read(&event);
- event_report(&event);
-
- FAIL_IF(event.result.running == 0);
- FAIL_IF(event.result.enabled == 0);
-
- event_close(&event);
- free(p);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(l3_bank_test, "l3_bank_test");
-}
diff --git a/powerpc/pmu/lib.c b/powerpc/pmu/lib.c
deleted file mode 100644
index 9768dea..0000000
--- a/powerpc/pmu/lib.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#define _GNU_SOURCE /* For CPU_ZERO etc. */
-
-#include <elf.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <link.h>
-#include <sched.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include "utils.h"
-#include "lib.h"
-
-
-int pick_online_cpu(void)
-{
- cpu_set_t mask;
- int cpu;
-
- CPU_ZERO(&mask);
-
- if (sched_getaffinity(0, sizeof(mask), &mask)) {
- perror("sched_getaffinity");
- return -1;
- }
-
- /* We prefer a primary thread, but skip 0 */
- for (cpu = 8; cpu < CPU_SETSIZE; cpu += 8)
- if (CPU_ISSET(cpu, &mask))
- return cpu;
-
- /* Search for anything, but in reverse */
- for (cpu = CPU_SETSIZE - 1; cpu >= 0; cpu--)
- if (CPU_ISSET(cpu, &mask))
- return cpu;
-
- printf("No cpus in affinity mask?!\n");
- return -1;
-}
-
-int bind_to_cpu(int cpu)
-{
- cpu_set_t mask;
-
- printf("Binding to cpu %d\n", cpu);
-
- CPU_ZERO(&mask);
- CPU_SET(cpu, &mask);
-
- return sched_setaffinity(0, sizeof(mask), &mask);
-}
-
-#define PARENT_TOKEN 0xAA
-#define CHILD_TOKEN 0x55
-
-int sync_with_child(union pipe read_pipe, union pipe write_pipe)
-{
- char c = PARENT_TOKEN;
-
- FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
- FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
- if (c != CHILD_TOKEN) /* sometimes expected */
- return 1;
-
- return 0;
-}
-
-int wait_for_parent(union pipe read_pipe)
-{
- char c;
-
- FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1);
- FAIL_IF(c != PARENT_TOKEN);
-
- return 0;
-}
-
-int notify_parent(union pipe write_pipe)
-{
- char c = CHILD_TOKEN;
-
- FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
-
- return 0;
-}
-
-int notify_parent_of_error(union pipe write_pipe)
-{
- char c = ~CHILD_TOKEN;
-
- FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1);
-
- return 0;
-}
-
-int wait_for_child(pid_t child_pid)
-{
- int rc;
-
- if (waitpid(child_pid, &rc, 0) == -1) {
- perror("waitpid");
- return 1;
- }
-
- if (WIFEXITED(rc))
- rc = WEXITSTATUS(rc);
- else
- rc = 1; /* Signal or other */
-
- return rc;
-}
-
-int kill_child_and_wait(pid_t child_pid)
-{
- kill(child_pid, SIGTERM);
-
- return wait_for_child(child_pid);
-}
-
-static int eat_cpu_child(union pipe read_pipe, union pipe write_pipe)
-{
- volatile int i = 0;
-
- /*
- * We are just here to eat cpu and die. So make sure we can be killed,
- * and also don't do any custom SIGTERM handling.
- */
- signal(SIGTERM, SIG_DFL);
-
- notify_parent(write_pipe);
- wait_for_parent(read_pipe);
-
- /* Soak up cpu forever */
- while (1) i++;
-
- return 0;
-}
-
-pid_t eat_cpu(int (test_function)(void))
-{
- union pipe read_pipe, write_pipe;
- int cpu, rc;
- pid_t pid;
-
- cpu = pick_online_cpu();
- FAIL_IF(cpu < 0);
- FAIL_IF(bind_to_cpu(cpu));
-
- if (pipe(read_pipe.fds) == -1)
- return -1;
-
- if (pipe(write_pipe.fds) == -1)
- return -1;
-
- pid = fork();
- if (pid == 0)
- exit(eat_cpu_child(write_pipe, read_pipe));
-
- if (sync_with_child(read_pipe, write_pipe)) {
- rc = -1;
- goto out;
- }
-
- printf("main test running as pid %d\n", getpid());
-
- rc = test_function();
-out:
- kill(pid, SIGKILL);
-
- return rc;
-}
-
-struct addr_range libc, vdso;
-
-int parse_proc_maps(void)
-{
- unsigned long start, end;
- char execute, name[128];
- FILE *f;
- int rc;
-
- f = fopen("/proc/self/maps", "r");
- if (!f) {
- perror("fopen");
- return -1;
- }
-
- do {
- /* This skips line with no executable which is what we want */
- rc = fscanf(f, "%lx-%lx %*c%*c%c%*c %*x %*d:%*d %*d %127s\n",
- &start, &end, &execute, name);
- if (rc <= 0)
- break;
-
- if (execute != 'x')
- continue;
-
- if (strstr(name, "libc")) {
- libc.first = start;
- libc.last = end - 1;
- } else if (strstr(name, "[vdso]")) {
- vdso.first = start;
- vdso.last = end - 1;
- }
- } while(1);
-
- fclose(f);
-
- return 0;
-}
-
-#define PARANOID_PATH "/proc/sys/kernel/perf_event_paranoid"
-
-bool require_paranoia_below(int level)
-{
- unsigned long current;
- char *end, buf[16];
- FILE *f;
- int rc;
-
- rc = -1;
-
- f = fopen(PARANOID_PATH, "r");
- if (!f) {
- perror("fopen");
- goto out;
- }
-
- if (!fgets(buf, sizeof(buf), f)) {
- printf("Couldn't read " PARANOID_PATH "?\n");
- goto out_close;
- }
-
- current = strtoul(buf, &end, 10);
-
- if (end == buf) {
- printf("Couldn't parse " PARANOID_PATH "?\n");
- goto out_close;
- }
-
- if (current >= level)
- goto out;
-
- rc = 0;
-out_close:
- fclose(f);
-out:
- return rc;
-}
-
-static char auxv[4096];
-
-void *get_auxv_entry(int type)
-{
- ElfW(auxv_t) *p;
- void *result;
- ssize_t num;
- int fd;
-
- fd = open("/proc/self/auxv", O_RDONLY);
- if (fd == -1) {
- perror("open");
- return NULL;
- }
-
- result = NULL;
-
- num = read(fd, auxv, sizeof(auxv));
- if (num < 0) {
- perror("read");
- goto out;
- }
-
- if (num > sizeof(auxv)) {
- printf("Overflowed auxv buffer\n");
- goto out;
- }
-
- p = (ElfW(auxv_t) *)auxv;
-
- while (p->a_type != AT_NULL) {
- if (p->a_type == type) {
- result = (void *)p->a_un.a_val;
- break;
- }
-
- p++;
- }
-out:
- close(fd);
- return result;
-}
diff --git a/powerpc/pmu/lib.h b/powerpc/pmu/lib.h
deleted file mode 100644
index 0f0339c..0000000
--- a/powerpc/pmu/lib.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#ifndef __SELFTESTS_POWERPC_PMU_LIB_H
-#define __SELFTESTS_POWERPC_PMU_LIB_H
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-union pipe {
- struct {
- int read_fd;
- int write_fd;
- };
- int fds[2];
-};
-
-extern int pick_online_cpu(void);
-extern int bind_to_cpu(int cpu);
-extern int kill_child_and_wait(pid_t child_pid);
-extern int wait_for_child(pid_t child_pid);
-extern int sync_with_child(union pipe read_pipe, union pipe write_pipe);
-extern int wait_for_parent(union pipe read_pipe);
-extern int notify_parent(union pipe write_pipe);
-extern int notify_parent_of_error(union pipe write_pipe);
-extern pid_t eat_cpu(int (test_function)(void));
-extern bool require_paranoia_below(int level);
-extern void *get_auxv_entry(int type);
-
-struct addr_range {
- uint64_t first, last;
-};
-
-extern struct addr_range libc, vdso;
-
-int parse_proc_maps(void);
-
-#endif /* __SELFTESTS_POWERPC_PMU_LIB_H */
diff --git a/powerpc/pmu/loop.S b/powerpc/pmu/loop.S
deleted file mode 100644
index 20c1f08..0000000
--- a/powerpc/pmu/loop.S
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2013, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#include <ppc-asm.h>
-
- .text
-
-FUNC_START(thirty_two_instruction_loop)
- cmpdi r3,0
- beqlr
- addi r4,r3,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1
- addi r4,r4,1 # 28 addi's
- subi r3,r3,1
- b FUNC_NAME(thirty_two_instruction_loop)
-FUNC_END(thirty_two_instruction_loop)
diff --git a/powerpc/pmu/per_event_excludes.c b/powerpc/pmu/per_event_excludes.c
deleted file mode 100644
index fddbbc9..0000000
--- a/powerpc/pmu/per_event_excludes.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#define _GNU_SOURCE
-
-#include <elf.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-#include <sys/prctl.h>
-
-#include "event.h"
-#include "lib.h"
-#include "utils.h"
-
-/*
- * Test that per-event excludes work.
- */
-
-static int per_event_excludes(void)
-{
- struct event *e, events[4];
- char *platform;
- int i;
-
- platform = (char *)get_auxv_entry(AT_BASE_PLATFORM);
- FAIL_IF(!platform);
- SKIP_IF(strcmp(platform, "power8") != 0);
-
- /*
- * We need to create the events disabled, otherwise the running/enabled
- * counts don't match up.
- */
- e = &events[0];
- event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
- PERF_TYPE_HARDWARE, "instructions");
- e->attr.disabled = 1;
-
- e = &events[1];
- event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
- PERF_TYPE_HARDWARE, "instructions(k)");
- e->attr.disabled = 1;
- e->attr.exclude_user = 1;
- e->attr.exclude_hv = 1;
-
- e = &events[2];
- event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
- PERF_TYPE_HARDWARE, "instructions(h)");
- e->attr.disabled = 1;
- e->attr.exclude_user = 1;
- e->attr.exclude_kernel = 1;
-
- e = &events[3];
- event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
- PERF_TYPE_HARDWARE, "instructions(u)");
- e->attr.disabled = 1;
- e->attr.exclude_hv = 1;
- e->attr.exclude_kernel = 1;
-
- FAIL_IF(event_open(&events[0]));
-
- /*
- * The open here will fail if we don't have per event exclude support,
- * because the second event has an incompatible set of exclude settings
- * and we're asking for the events to be in a group.
- */
- for (i = 1; i < 4; i++)
- FAIL_IF(event_open_with_group(&events[i], events[0].fd));
-
- /*
- * Even though the above will fail without per-event excludes we keep
- * testing in order to be thorough.
- */
- prctl(PR_TASK_PERF_EVENTS_ENABLE);
-
- /* Spin for a while */
- for (i = 0; i < INT_MAX; i++)
- asm volatile("" : : : "memory");
-
- prctl(PR_TASK_PERF_EVENTS_DISABLE);
-
- for (i = 0; i < 4; i++) {
- FAIL_IF(event_read(&events[i]));
- event_report(&events[i]);
- }
-
- /*
- * We should see that all events have enabled == running. That
- * shows that they were all on the PMU at once.
- */
- for (i = 0; i < 4; i++)
- FAIL_IF(events[i].result.running != events[i].result.enabled);
-
- /*
- * We can also check that the result for instructions is >= all the
- * other counts. That's because it is counting all instructions while
- * the others are counting a subset.
- */
- for (i = 1; i < 4; i++)
- FAIL_IF(events[0].result.value < events[i].result.value);
-
- for (i = 0; i < 4; i++)
- event_close(&events[i]);
-
- return 0;
-}
-
-int main(void)
-{
- return test_harness(per_event_excludes, "per_event_excludes");
-}