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>
12b9125c9aSBenjamin Gray #include <stdio.h>
1315ec3997SSimon Guo #include <stdbool.h>
14bdb07f35SBenjamin Gray #include <sys/signal.h>
1515ec3997SSimon Guo #include <linux/auxvec.h>
16d2bf7932SNaveen N. Rao #include <linux/perf_event.h>
17178282a0SMichael Ellerman #include <asm/cputable.h>
1815ec3997SSimon Guo #include "reg.h"
19b9125c9aSBenjamin Gray #include <unistd.h>
20b9125c9aSBenjamin Gray 
21b9125c9aSBenjamin Gray #ifndef ARRAY_SIZE
22b9125c9aSBenjamin Gray # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
23b9125c9aSBenjamin Gray #endif
2415ec3997SSimon Guo 
2515ec3997SSimon Guo /* Avoid headaches with PRI?64 - just use %ll? always */
2615ec3997SSimon Guo typedef unsigned long long u64;
2715ec3997SSimon Guo typedef   signed long long s64;
2815ec3997SSimon Guo 
2915ec3997SSimon Guo /* Just for familiarity */
3015ec3997SSimon Guo typedef uint32_t u32;
3115ec3997SSimon Guo typedef uint16_t u16;
3215ec3997SSimon Guo typedef uint8_t u8;
3315ec3997SSimon Guo 
3415ec3997SSimon Guo void test_harness_set_timeout(uint64_t time);
35*701ca365SNathan Lynch int test_harness(int (test_function)(void), const char *name);
36e3028437SMichael Ellerman 
37e3028437SMichael Ellerman int read_auxv(char *buf, ssize_t buf_size);
38e3028437SMichael Ellerman void *find_auxv_entry(int type, char *auxv);
39e3028437SMichael Ellerman void *get_auxv_entry(int type);
40e3028437SMichael Ellerman 
416ff4dc25SBenjamin Gray #define BIND_CPU_ANY	(-1)
426ff4dc25SBenjamin Gray 
4315ec3997SSimon Guo int pick_online_cpu(void);
44c97b2fc6SBenjamin Gray int bind_to_cpu(int cpu);
4515ec3997SSimon Guo 
46d1bc05b7SBenjamin Gray int parse_intmax(const char *buffer, size_t count, intmax_t *result, int base);
47d1bc05b7SBenjamin Gray int parse_uintmax(const char *buffer, size_t count, uintmax_t *result, int base);
48d1bc05b7SBenjamin Gray int parse_int(const char *buffer, size_t count, int *result, int base);
49d1bc05b7SBenjamin Gray int parse_uint(const char *buffer, size_t count, unsigned int *result, int base);
50d1bc05b7SBenjamin Gray int parse_long(const char *buffer, size_t count, long *result, int base);
51d1bc05b7SBenjamin Gray int parse_ulong(const char *buffer, size_t count, unsigned long *result, int base);
52d1bc05b7SBenjamin Gray 
53a974f0c1SBenjamin Gray int read_file(const char *path, char *buf, size_t count, size_t *len);
54a974f0c1SBenjamin Gray int write_file(const char *path, const char *buf, size_t count);
558d7253dcSBenjamin Gray int read_file_alloc(const char *path, char **buf, size_t *len);
565c20de57SBenjamin Gray int read_long(const char *path, long *result, int base);
575c20de57SBenjamin Gray int write_long(const char *path, long result, int base);
585c20de57SBenjamin Gray int read_ulong(const char *path, unsigned long *result, int base);
595c20de57SBenjamin Gray int write_ulong(const char *path, unsigned long result, int base);
60121d340bSBenjamin Gray int read_debugfs_file(const char *debugfs_file, char *buf, size_t count);
61121d340bSBenjamin Gray int write_debugfs_file(const char *debugfs_file, const char *buf, size_t count);
62121d340bSBenjamin Gray int read_debugfs_int(const char *debugfs_file, int *result);
63121d340bSBenjamin Gray int write_debugfs_int(const char *debugfs_file, int result);
64c790c3d2SMichael Ellerman int read_sysfs_file(char *debugfs_file, char *result, size_t result_size);
65d2bf7932SNaveen N. Rao int perf_event_open_counter(unsigned int type,
66d2bf7932SNaveen N. Rao 			    unsigned long config, int group_fd);
67d2bf7932SNaveen N. Rao int perf_event_enable(int fd);
68d2bf7932SNaveen N. Rao int perf_event_disable(int fd);
69d2bf7932SNaveen N. Rao int perf_event_reset(int fd);
70d2bf7932SNaveen N. Rao 
710d239f3bSDaniel Axtens struct perf_event_read {
720d239f3bSDaniel Axtens 	__u64 nr;
730d239f3bSDaniel Axtens 	__u64 l1d_misses;
740d239f3bSDaniel Axtens };
750d239f3bSDaniel Axtens 
76743f3544SSandipan Das #if !defined(__GLIBC_PREREQ) || !__GLIBC_PREREQ(2, 30)
77743f3544SSandipan Das #include <sys/syscall.h>
78743f3544SSandipan Das 
gettid(void)79743f3544SSandipan Das static inline pid_t gettid(void)
80743f3544SSandipan Das {
81743f3544SSandipan Das 	return syscall(SYS_gettid);
82743f3544SSandipan Das }
83743f3544SSandipan Das #endif
84743f3544SSandipan Das 
have_hwcap(unsigned long ftr)8515ec3997SSimon Guo static inline bool have_hwcap(unsigned long ftr)
8615ec3997SSimon Guo {
8715ec3997SSimon Guo 	return ((unsigned long)get_auxv_entry(AT_HWCAP) & ftr) == ftr;
8815ec3997SSimon Guo }
8915ec3997SSimon Guo 
9015ec3997SSimon Guo #ifdef AT_HWCAP2
have_hwcap2(unsigned long ftr2)9115ec3997SSimon Guo static inline bool have_hwcap2(unsigned long ftr2)
9215ec3997SSimon Guo {
9315ec3997SSimon Guo 	return ((unsigned long)get_auxv_entry(AT_HWCAP2) & ftr2) == ftr2;
9415ec3997SSimon Guo }
9515ec3997SSimon Guo #else
have_hwcap2(unsigned long ftr2)9615ec3997SSimon Guo static inline bool have_hwcap2(unsigned long ftr2)
9715ec3997SSimon Guo {
9815ec3997SSimon Guo 	return false;
9915ec3997SSimon Guo }
10015ec3997SSimon Guo #endif
10115ec3997SSimon Guo 
auxv_base_platform(void)102a069b5f9SAthira Rajeev static inline char *auxv_base_platform(void)
103a069b5f9SAthira Rajeev {
104a069b5f9SAthira Rajeev 	return ((char *)get_auxv_entry(AT_BASE_PLATFORM));
105a069b5f9SAthira Rajeev }
106a069b5f9SAthira Rajeev 
auxv_platform(void)107a069b5f9SAthira Rajeev static inline char *auxv_platform(void)
108a069b5f9SAthira Rajeev {
109a069b5f9SAthira Rajeev 	return ((char *)get_auxv_entry(AT_PLATFORM));
110a069b5f9SAthira Rajeev }
111a069b5f9SAthira Rajeev 
11295f9b3afSMichael Ellerman bool is_ppc64le(void);
113c405b738SSandipan Das int using_hash_mmu(bool *using_hash);
11495f9b3afSMichael Ellerman 
115bdb07f35SBenjamin Gray struct sigaction push_signal_handler(int sig, void (*fn)(int, siginfo_t *, void *));
116bdb07f35SBenjamin Gray struct sigaction pop_signal_handler(int sig, struct sigaction old_handler);
117bdb07f35SBenjamin Gray 
11815ec3997SSimon Guo /* Yes, this is evil */
11915ec3997SSimon Guo #define FAIL_IF(x)						\
12015ec3997SSimon Guo do {								\
12115ec3997SSimon Guo 	if ((x)) {						\
12215ec3997SSimon Guo 		fprintf(stderr,					\
12315ec3997SSimon Guo 		"[FAIL] Test FAILED on line %d\n", __LINE__);	\
12415ec3997SSimon Guo 		return 1;					\
12515ec3997SSimon Guo 	}							\
12615ec3997SSimon Guo } while (0)
12715ec3997SSimon Guo 
128b9125c9aSBenjamin Gray #define FAIL_IF_MSG(x, msg)					\
129b9125c9aSBenjamin Gray do {								\
130b9125c9aSBenjamin Gray 	if ((x)) {						\
131b9125c9aSBenjamin Gray 		fprintf(stderr,					\
132b9125c9aSBenjamin Gray 		"[FAIL] Test FAILED on line %d: %s\n", 		\
133b9125c9aSBenjamin Gray 		__LINE__, msg);					\
134b9125c9aSBenjamin Gray 		return 1;					\
135b9125c9aSBenjamin Gray 	}							\
136b9125c9aSBenjamin Gray } while (0)
137b9125c9aSBenjamin Gray 
138e3333c59SSandipan Das #define FAIL_IF_EXIT(x)						\
139e3333c59SSandipan Das do {								\
140e3333c59SSandipan Das 	if ((x)) {						\
141e3333c59SSandipan Das 		fprintf(stderr,					\
142e3333c59SSandipan Das 		"[FAIL] Test FAILED on line %d\n", __LINE__);	\
143e3333c59SSandipan Das 		_exit(1);					\
144e3333c59SSandipan Das 	}							\
145e3333c59SSandipan Das } while (0)
146e3333c59SSandipan Das 
147b9125c9aSBenjamin Gray #define FAIL_IF_EXIT_MSG(x, msg)				\
148b9125c9aSBenjamin Gray do {								\
149b9125c9aSBenjamin Gray 	if ((x)) {						\
150b9125c9aSBenjamin Gray 		fprintf(stderr,					\
151b9125c9aSBenjamin Gray 		"[FAIL] Test FAILED on line %d: %s\n", 		\
152b9125c9aSBenjamin Gray 		__LINE__, msg);					\
153b9125c9aSBenjamin Gray 		_exit(1);					\
154b9125c9aSBenjamin Gray 	}							\
155b9125c9aSBenjamin Gray } while (0)
156b9125c9aSBenjamin Gray 
15715ec3997SSimon Guo /* The test harness uses this, yes it's gross */
15815ec3997SSimon Guo #define MAGIC_SKIP_RETURN_VALUE	99
15915ec3997SSimon Guo 
16015ec3997SSimon Guo #define SKIP_IF(x)						\
16115ec3997SSimon Guo do {								\
16215ec3997SSimon Guo 	if ((x)) {						\
16315ec3997SSimon Guo 		fprintf(stderr,					\
16415ec3997SSimon Guo 		"[SKIP] Test skipped on line %d\n", __LINE__);	\
16515ec3997SSimon Guo 		return MAGIC_SKIP_RETURN_VALUE;			\
16615ec3997SSimon Guo 	}							\
16715ec3997SSimon Guo } while (0)
16815ec3997SSimon Guo 
169e653b656SBreno Leitao #define SKIP_IF_MSG(x, msg)					\
170e653b656SBreno Leitao do {								\
171e653b656SBreno Leitao 	if ((x)) {						\
172e653b656SBreno Leitao 		fprintf(stderr,					\
173e653b656SBreno Leitao 		"[SKIP] Test skipped on line %d: %s\n",		\
174e653b656SBreno Leitao 		 __LINE__, msg);				\
175e653b656SBreno Leitao 		return MAGIC_SKIP_RETURN_VALUE;			\
176e653b656SBreno Leitao 	}							\
177e653b656SBreno Leitao } while (0)
178e653b656SBreno Leitao 
17915ec3997SSimon Guo #define _str(s) #s
18015ec3997SSimon Guo #define str(s) _str(s)
18115ec3997SSimon Guo 
182128d3d02SSandipan Das #define sigsafe_err(msg)	({ \
183128d3d02SSandipan Das 		ssize_t nbytes __attribute__((unused)); \
184128d3d02SSandipan Das 		nbytes = write(STDERR_FILENO, msg, strlen(msg)); })
185128d3d02SSandipan Das 
18615ec3997SSimon Guo /* POWER9 feature */
18715ec3997SSimon Guo #ifndef PPC_FEATURE2_ARCH_3_00
18815ec3997SSimon Guo #define PPC_FEATURE2_ARCH_3_00 0x00800000
18915ec3997SSimon Guo #endif
19015ec3997SSimon Guo 
191620a6473SJordan Niethe /* POWER10 feature */
192620a6473SJordan Niethe #ifndef PPC_FEATURE2_ARCH_3_1
193620a6473SJordan Niethe #define PPC_FEATURE2_ARCH_3_1 0x00040000
194620a6473SJordan Niethe #endif
195620a6473SJordan Niethe 
1963527e1abSAlistair Popple /* POWER10 features */
1973527e1abSAlistair Popple #ifndef PPC_FEATURE2_MMA
1983527e1abSAlistair Popple #define PPC_FEATURE2_MMA 0x00020000
1993527e1abSAlistair Popple #endif
2003527e1abSAlistair Popple 
201db384851SNaveen N. Rao #if defined(__powerpc64__)
202db384851SNaveen N. Rao #define UCONTEXT_NIA(UC)	(UC)->uc_mcontext.gp_regs[PT_NIP]
203a65329aaSBreno Leitao #define UCONTEXT_MSR(UC)	(UC)->uc_mcontext.gp_regs[PT_MSR]
204db384851SNaveen N. Rao #elif defined(__powerpc__)
205db384851SNaveen N. Rao #define UCONTEXT_NIA(UC)	(UC)->uc_mcontext.uc_regs->gregs[PT_NIP]
206a65329aaSBreno Leitao #define UCONTEXT_MSR(UC)	(UC)->uc_mcontext.uc_regs->gregs[PT_MSR]
207db384851SNaveen N. Rao #else
208db384851SNaveen N. Rao #error implement UCONTEXT_NIA
209db384851SNaveen N. Rao #endif
210db384851SNaveen N. Rao 
21115ec3997SSimon Guo #endif /* _SELFTESTS_POWERPC_UTILS_H */
212