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
25static 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
113int main(void)
114{
115	return test_harness(event_alternatives_tests_p9, "event_alternatives_tests_p9");
116}
117