1f50a7f3dSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
215ec3997SSimon Guo /*
315ec3997SSimon Guo  * Copyright 2013, Michael Ellerman, IBM Corp.
415ec3997SSimon Guo  */
515ec3997SSimon Guo 
615ec3997SSimon Guo #ifndef _SELFTESTS_POWERPC_UTILS_H
715ec3997SSimon Guo #define _SELFTESTS_POWERPC_UTILS_H
815ec3997SSimon Guo 
915ec3997SSimon Guo #define __cacheline_aligned __attribute__((aligned(128)))
1015ec3997SSimon Guo 
1115ec3997SSimon Guo #include <stdint.h>
1215ec3997SSimon Guo #include <stdbool.h>
1315ec3997SSimon Guo #include <linux/auxvec.h>
14d2bf7932SNaveen N. Rao #include <linux/perf_event.h>
15178282a0SMichael Ellerman #include <asm/cputable.h>
1615ec3997SSimon Guo #include "reg.h"
1715ec3997SSimon Guo 
1815ec3997SSimon Guo /* Avoid headaches with PRI?64 - just use %ll? always */
1915ec3997SSimon Guo typedef unsigned long long u64;
2015ec3997SSimon Guo typedef   signed long long s64;
2115ec3997SSimon Guo 
2215ec3997SSimon Guo /* Just for familiarity */
2315ec3997SSimon Guo typedef uint32_t u32;
2415ec3997SSimon Guo typedef uint16_t u16;
2515ec3997SSimon Guo typedef uint8_t u8;
2615ec3997SSimon Guo 
2715ec3997SSimon Guo void test_harness_set_timeout(uint64_t time);
2815ec3997SSimon Guo int test_harness(int (test_function)(void), char *name);
29e3028437SMichael Ellerman 
30e3028437SMichael Ellerman int read_auxv(char *buf, ssize_t buf_size);
31e3028437SMichael Ellerman void *find_auxv_entry(int type, char *auxv);
32e3028437SMichael Ellerman void *get_auxv_entry(int type);
33e3028437SMichael Ellerman 
3415ec3997SSimon Guo int pick_online_cpu(void);
3515ec3997SSimon Guo 
36a974f0c1SBenjamin Gray int read_file(const char *path, char *buf, size_t count, size_t *len);
37a974f0c1SBenjamin Gray int write_file(const char *path, const char *buf, size_t count);
38*121d340bSBenjamin Gray int read_debugfs_file(const char *debugfs_file, char *buf, size_t count);
39*121d340bSBenjamin Gray int write_debugfs_file(const char *debugfs_file, const char *buf, size_t count);
40*121d340bSBenjamin Gray int read_debugfs_int(const char *debugfs_file, int *result);
41*121d340bSBenjamin Gray int write_debugfs_int(const char *debugfs_file, int result);
42c790c3d2SMichael Ellerman int read_sysfs_file(char *debugfs_file, char *result, size_t result_size);
43d2bf7932SNaveen N. Rao int perf_event_open_counter(unsigned int type,
44d2bf7932SNaveen N. Rao 			    unsigned long config, int group_fd);
45d2bf7932SNaveen N. Rao int perf_event_enable(int fd);
46d2bf7932SNaveen N. Rao int perf_event_disable(int fd);
47d2bf7932SNaveen N. Rao int perf_event_reset(int fd);
48d2bf7932SNaveen N. Rao 
490d239f3bSDaniel Axtens struct perf_event_read {
500d239f3bSDaniel Axtens 	__u64 nr;
510d239f3bSDaniel Axtens 	__u64 l1d_misses;
520d239f3bSDaniel Axtens };
530d239f3bSDaniel Axtens 
54743f3544SSandipan Das #if !defined(__GLIBC_PREREQ) || !__GLIBC_PREREQ(2, 30)
55743f3544SSandipan Das #include <unistd.h>
56743f3544SSandipan Das #include <sys/syscall.h>
57743f3544SSandipan Das 
58743f3544SSandipan Das static inline pid_t gettid(void)
59743f3544SSandipan Das {
60743f3544SSandipan Das 	return syscall(SYS_gettid);
61743f3544SSandipan Das }
62743f3544SSandipan Das #endif
63743f3544SSandipan Das 
6415ec3997SSimon Guo static inline bool have_hwcap(unsigned long ftr)
6515ec3997SSimon Guo {
6615ec3997SSimon Guo 	return ((unsigned long)get_auxv_entry(AT_HWCAP) & ftr) == ftr;
6715ec3997SSimon Guo }
6815ec3997SSimon Guo 
6915ec3997SSimon Guo #ifdef AT_HWCAP2
7015ec3997SSimon Guo static inline bool have_hwcap2(unsigned long ftr2)
7115ec3997SSimon Guo {
7215ec3997SSimon Guo 	return ((unsigned long)get_auxv_entry(AT_HWCAP2) & ftr2) == ftr2;
7315ec3997SSimon Guo }
7415ec3997SSimon Guo #else
7515ec3997SSimon Guo static inline bool have_hwcap2(unsigned long ftr2)
7615ec3997SSimon Guo {
7715ec3997SSimon Guo 	return false;
7815ec3997SSimon Guo }
7915ec3997SSimon Guo #endif
8015ec3997SSimon Guo 
81a069b5f9SAthira Rajeev static inline char *auxv_base_platform(void)
82a069b5f9SAthira Rajeev {
83a069b5f9SAthira Rajeev 	return ((char *)get_auxv_entry(AT_BASE_PLATFORM));
84a069b5f9SAthira Rajeev }
85a069b5f9SAthira Rajeev 
86a069b5f9SAthira Rajeev static inline char *auxv_platform(void)
87a069b5f9SAthira Rajeev {
88a069b5f9SAthira Rajeev 	return ((char *)get_auxv_entry(AT_PLATFORM));
89a069b5f9SAthira Rajeev }
90a069b5f9SAthira Rajeev 
9195f9b3afSMichael Ellerman bool is_ppc64le(void);
92c405b738SSandipan Das int using_hash_mmu(bool *using_hash);
9395f9b3afSMichael Ellerman 
9415ec3997SSimon Guo /* Yes, this is evil */
9515ec3997SSimon Guo #define FAIL_IF(x)						\
9615ec3997SSimon Guo do {								\
9715ec3997SSimon Guo 	if ((x)) {						\
9815ec3997SSimon Guo 		fprintf(stderr,					\
9915ec3997SSimon Guo 		"[FAIL] Test FAILED on line %d\n", __LINE__);	\
10015ec3997SSimon Guo 		return 1;					\
10115ec3997SSimon Guo 	}							\
10215ec3997SSimon Guo } while (0)
10315ec3997SSimon Guo 
104e3333c59SSandipan Das #define FAIL_IF_EXIT(x)						\
105e3333c59SSandipan Das do {								\
106e3333c59SSandipan Das 	if ((x)) {						\
107e3333c59SSandipan Das 		fprintf(stderr,					\
108e3333c59SSandipan Das 		"[FAIL] Test FAILED on line %d\n", __LINE__);	\
109e3333c59SSandipan Das 		_exit(1);					\
110e3333c59SSandipan Das 	}							\
111e3333c59SSandipan Das } while (0)
112e3333c59SSandipan Das 
11315ec3997SSimon Guo /* The test harness uses this, yes it's gross */
11415ec3997SSimon Guo #define MAGIC_SKIP_RETURN_VALUE	99
11515ec3997SSimon Guo 
11615ec3997SSimon Guo #define SKIP_IF(x)						\
11715ec3997SSimon Guo do {								\
11815ec3997SSimon Guo 	if ((x)) {						\
11915ec3997SSimon Guo 		fprintf(stderr,					\
12015ec3997SSimon Guo 		"[SKIP] Test skipped on line %d\n", __LINE__);	\
12115ec3997SSimon Guo 		return MAGIC_SKIP_RETURN_VALUE;			\
12215ec3997SSimon Guo 	}							\
12315ec3997SSimon Guo } while (0)
12415ec3997SSimon Guo 
125e653b656SBreno Leitao #define SKIP_IF_MSG(x, msg)					\
126e653b656SBreno Leitao do {								\
127e653b656SBreno Leitao 	if ((x)) {						\
128e653b656SBreno Leitao 		fprintf(stderr,					\
129e653b656SBreno Leitao 		"[SKIP] Test skipped on line %d: %s\n",		\
130e653b656SBreno Leitao 		 __LINE__, msg);				\
131e653b656SBreno Leitao 		return MAGIC_SKIP_RETURN_VALUE;			\
132e653b656SBreno Leitao 	}							\
133e653b656SBreno Leitao } while (0)
134e653b656SBreno Leitao 
13515ec3997SSimon Guo #define _str(s) #s
13615ec3997SSimon Guo #define str(s) _str(s)
13715ec3997SSimon Guo 
138128d3d02SSandipan Das #define sigsafe_err(msg)	({ \
139128d3d02SSandipan Das 		ssize_t nbytes __attribute__((unused)); \
140128d3d02SSandipan Das 		nbytes = write(STDERR_FILENO, msg, strlen(msg)); })
141128d3d02SSandipan Das 
14215ec3997SSimon Guo /* POWER9 feature */
14315ec3997SSimon Guo #ifndef PPC_FEATURE2_ARCH_3_00
14415ec3997SSimon Guo #define PPC_FEATURE2_ARCH_3_00 0x00800000
14515ec3997SSimon Guo #endif
14615ec3997SSimon Guo 
147620a6473SJordan Niethe /* POWER10 feature */
148620a6473SJordan Niethe #ifndef PPC_FEATURE2_ARCH_3_1
149620a6473SJordan Niethe #define PPC_FEATURE2_ARCH_3_1 0x00040000
150620a6473SJordan Niethe #endif
151620a6473SJordan Niethe 
1523527e1abSAlistair Popple /* POWER10 features */
1533527e1abSAlistair Popple #ifndef PPC_FEATURE2_MMA
1543527e1abSAlistair Popple #define PPC_FEATURE2_MMA 0x00020000
1553527e1abSAlistair Popple #endif
1563527e1abSAlistair Popple 
157db384851SNaveen N. Rao #if defined(__powerpc64__)
158db384851SNaveen N. Rao #define UCONTEXT_NIA(UC)	(UC)->uc_mcontext.gp_regs[PT_NIP]
159a65329aaSBreno Leitao #define UCONTEXT_MSR(UC)	(UC)->uc_mcontext.gp_regs[PT_MSR]
160db384851SNaveen N. Rao #elif defined(__powerpc__)
161db384851SNaveen N. Rao #define UCONTEXT_NIA(UC)	(UC)->uc_mcontext.uc_regs->gregs[PT_NIP]
162a65329aaSBreno Leitao #define UCONTEXT_MSR(UC)	(UC)->uc_mcontext.uc_regs->gregs[PT_MSR]
163db384851SNaveen N. Rao #else
164db384851SNaveen N. Rao #error implement UCONTEXT_NIA
165db384851SNaveen N. Rao #endif
166db384851SNaveen N. Rao 
16715ec3997SSimon Guo #endif /* _SELFTESTS_POWERPC_UTILS_H */
168