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