1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2022, Athira Rajeev, IBM Corp.
4  */
5 
6 #include <stdio.h>
7 #include "../event.h"
8 #include "../sampling_tests/misc.h"
9 
10 #define PM_RUN_CYC_ALT 0x200f4
11 #define PM_INST_DISP 0x200f2
12 #define PM_BR_2PATH 0x20036
13 #define PM_LD_MISS_L1 0x3e054
14 #define PM_RUN_INST_CMPL_ALT 0x400fa
15 
16 #define EventCode_1 0x200fa
17 #define EventCode_2 0x200fc
18 #define EventCode_3 0x300fc
19 #define EventCode_4 0x400fc
20 
21 /*
22  * Check for event alternatives.
23  */
24 
25 static int event_alternatives_tests_p9(void)
26 {
27 	struct event event, leader;
28 
29 	/* Check for platform support for the test */
30 	SKIP_IF(platform_check_for_tests());
31 
32 	/*
33 	 * PVR check is used here since PMU specific data like
34 	 * alternative events is handled by respective PMU driver
35 	 * code and using PVR will work correctly for all cases
36 	 * including generic compat mode.
37 	 */
38 	SKIP_IF(PVR_VER(mfspr(SPRN_PVR)) != POWER9);
39 
40 	/* Skip for generic compat PMU */
41 	SKIP_IF(check_for_generic_compat_pmu());
42 
43 	/* Init the event for PM_RUN_CYC_ALT */
44 	event_init(&leader, PM_RUN_CYC_ALT);
45 	FAIL_IF(event_open(&leader));
46 
47 	event_init(&event, EventCode_1);
48 
49 	/*
50 	 * Expected to pass since PM_RUN_CYC_ALT in PMC2 has alternative event
51 	 * 0x600f4. So it can go in with EventCode_1 which is using PMC2
52 	 */
53 	FAIL_IF(event_open_with_group(&event, leader.fd));
54 
55 	event_close(&leader);
56 	event_close(&event);
57 
58 	event_init(&leader, PM_INST_DISP);
59 	FAIL_IF(event_open(&leader));
60 
61 	event_init(&event, EventCode_2);
62 	/*
63 	 * Expected to pass since PM_INST_DISP in PMC2 has alternative event
64 	 * 0x300f2 in PMC3. So it can go in with EventCode_2 which is using PMC2
65 	 */
66 	FAIL_IF(event_open_with_group(&event, leader.fd));
67 
68 	event_close(&leader);
69 	event_close(&event);
70 
71 	event_init(&leader, PM_BR_2PATH);
72 	FAIL_IF(event_open(&leader));
73 
74 	event_init(&event, EventCode_2);
75 	/*
76 	 * Expected to pass since PM_BR_2PATH in PMC2 has alternative event
77 	 * 0x40036 in PMC4. So it can go in with EventCode_2 which is using PMC2
78 	 */
79 	FAIL_IF(event_open_with_group(&event, leader.fd));
80 
81 	event_close(&leader);
82 	event_close(&event);
83 
84 	event_init(&leader, PM_LD_MISS_L1);
85 	FAIL_IF(event_open(&leader));
86 
87 	event_init(&event, EventCode_3);
88 	/*
89 	 * Expected to pass since PM_LD_MISS_L1 in PMC3 has alternative event
90 	 * 0x400f0 in PMC4. So it can go in with EventCode_3 which is using PMC3
91 	 */
92 	FAIL_IF(event_open_with_group(&event, leader.fd));
93 
94 	event_close(&leader);
95 	event_close(&event);
96 
97 	event_init(&leader, PM_RUN_INST_CMPL_ALT);
98 	FAIL_IF(event_open(&leader));
99 
100 	event_init(&event, EventCode_4);
101 	/*
102 	 * Expected to pass since PM_RUN_INST_CMPL_ALT in PMC4 has alternative event
103 	 * 0x500fa in PMC5. So it can go in with EventCode_4 which is using PMC4
104 	 */
105 	FAIL_IF(event_open_with_group(&event, leader.fd));
106 
107 	event_close(&leader);
108 	event_close(&event);
109 
110 	return 0;
111 }
112 
113 int main(void)
114 {
115 	return test_harness(event_alternatives_tests_p9, "event_alternatives_tests_p9");
116 }
117