18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Test the powerpc alignment handler on POWER8/POWER9
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2017 IBM Corporation (Michael Neuling, Andrew Donnellan)
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci * This selftest exercises the powerpc alignment fault handler.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * We create two sets of source and destination buffers, one in regular memory,
128c2ecf20Sopenharmony_ci * the other cache-inhibited (by default we use /dev/fb0 for this, but an
138c2ecf20Sopenharmony_ci * alterative path for cache-inhibited memory may be provided).
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * One way to get cache-inhibited memory is to use the "mem" kernel parameter
168c2ecf20Sopenharmony_ci * to limit the kernel to less memory than actually exists.  Addresses above
178c2ecf20Sopenharmony_ci * the limit may still be accessed but will be treated as cache-inhibited. For
188c2ecf20Sopenharmony_ci * example, if there is actually 4GB of memory and the parameter "mem=3GB" is
198c2ecf20Sopenharmony_ci * used, memory from address 0xC0000000 onwards is treated as cache-inhibited.
208c2ecf20Sopenharmony_ci * To access this region /dev/mem is used. The kernel should be configured
218c2ecf20Sopenharmony_ci * without CONFIG_STRICT_DEVMEM. In this case use:
228c2ecf20Sopenharmony_ci *         ./alignment_handler /dev/mem 0xc0000000
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * We initialise the source buffers, then use whichever set of load/store
258c2ecf20Sopenharmony_ci * instructions is under test to copy bytes from the source buffers to the
268c2ecf20Sopenharmony_ci * destination buffers. For the regular buffers, these instructions will
278c2ecf20Sopenharmony_ci * execute normally. For the cache-inhibited buffers, these instructions
288c2ecf20Sopenharmony_ci * will trap and cause an alignment fault, and the alignment fault handler
298c2ecf20Sopenharmony_ci * will emulate the particular instruction under test. We then compare the
308c2ecf20Sopenharmony_ci * destination buffers to ensure that the native and emulated cases give the
318c2ecf20Sopenharmony_ci * same result.
328c2ecf20Sopenharmony_ci *
338c2ecf20Sopenharmony_ci * TODO:
348c2ecf20Sopenharmony_ci *   - Any FIXMEs below
358c2ecf20Sopenharmony_ci *   - Test VSX regs < 32 and > 32
368c2ecf20Sopenharmony_ci *   - Test all loads and stores
378c2ecf20Sopenharmony_ci *   - Check update forms do update register
388c2ecf20Sopenharmony_ci *   - Test alignment faults over page boundary
398c2ecf20Sopenharmony_ci *
408c2ecf20Sopenharmony_ci * Some old binutils may not support all the instructions.
418c2ecf20Sopenharmony_ci */
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#include <sys/mman.h>
458c2ecf20Sopenharmony_ci#include <sys/types.h>
468c2ecf20Sopenharmony_ci#include <sys/stat.h>
478c2ecf20Sopenharmony_ci#include <fcntl.h>
488c2ecf20Sopenharmony_ci#include <unistd.h>
498c2ecf20Sopenharmony_ci#include <stdbool.h>
508c2ecf20Sopenharmony_ci#include <stdio.h>
518c2ecf20Sopenharmony_ci#include <stdlib.h>
528c2ecf20Sopenharmony_ci#include <string.h>
538c2ecf20Sopenharmony_ci#include <assert.h>
548c2ecf20Sopenharmony_ci#include <getopt.h>
558c2ecf20Sopenharmony_ci#include <setjmp.h>
568c2ecf20Sopenharmony_ci#include <signal.h>
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci#include "utils.h"
598c2ecf20Sopenharmony_ci#include "instructions.h"
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ciint bufsize;
628c2ecf20Sopenharmony_ciint debug;
638c2ecf20Sopenharmony_ciint testing;
648c2ecf20Sopenharmony_civolatile int gotsig;
658c2ecf20Sopenharmony_cibool prefixes_enabled;
668c2ecf20Sopenharmony_cichar *cipath = "/dev/fb0";
678c2ecf20Sopenharmony_cilong cioffset;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_civoid sighandler(int sig, siginfo_t *info, void *ctx)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	ucontext_t *ucp = ctx;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	if (!testing) {
748c2ecf20Sopenharmony_ci		signal(sig, SIG_DFL);
758c2ecf20Sopenharmony_ci		kill(0, sig);
768c2ecf20Sopenharmony_ci	}
778c2ecf20Sopenharmony_ci	gotsig = sig;
788c2ecf20Sopenharmony_ci#ifdef __powerpc64__
798c2ecf20Sopenharmony_ci	if (prefixes_enabled) {
808c2ecf20Sopenharmony_ci		u32 inst = *(u32 *)ucp->uc_mcontext.gp_regs[PT_NIP];
818c2ecf20Sopenharmony_ci		ucp->uc_mcontext.gp_regs[PT_NIP] += ((inst >> 26 == 1) ? 8 : 4);
828c2ecf20Sopenharmony_ci	} else {
838c2ecf20Sopenharmony_ci		ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
848c2ecf20Sopenharmony_ci	}
858c2ecf20Sopenharmony_ci#else
868c2ecf20Sopenharmony_ci	ucp->uc_mcontext.uc_regs->gregs[PT_NIP] += 4;
878c2ecf20Sopenharmony_ci#endif
888c2ecf20Sopenharmony_ci}
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci#define XFORM(reg, n)  " " #reg " ,%"#n",%2 ;"
918c2ecf20Sopenharmony_ci#define DFORM(reg, n)  " " #reg " ,0(%"#n") ;"
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci#define TEST(name, ld_op, st_op, form, ld_reg, st_reg)		\
948c2ecf20Sopenharmony_ci	void test_##name(char *s, char *d)			\
958c2ecf20Sopenharmony_ci	{							\
968c2ecf20Sopenharmony_ci		asm volatile(					\
978c2ecf20Sopenharmony_ci			#ld_op form(ld_reg, 0)			\
988c2ecf20Sopenharmony_ci			#st_op form(st_reg, 1)			\
998c2ecf20Sopenharmony_ci			:: "r"(s), "r"(d), "r"(0)		\
1008c2ecf20Sopenharmony_ci			: "memory", "vs0", "vs32", "r31");	\
1018c2ecf20Sopenharmony_ci	}							\
1028c2ecf20Sopenharmony_ci	rc |= do_test(#name, test_##name)
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci#define TESTP(name, ld_op, st_op, ld_reg, st_reg)		\
1058c2ecf20Sopenharmony_ci	void test_##name(char *s, char *d)			\
1068c2ecf20Sopenharmony_ci	{							\
1078c2ecf20Sopenharmony_ci		asm volatile(					\
1088c2ecf20Sopenharmony_ci			ld_op(ld_reg, %0, 0, 0)			\
1098c2ecf20Sopenharmony_ci			st_op(st_reg, %1, 0, 0)			\
1108c2ecf20Sopenharmony_ci			:: "r"(s), "r"(d), "r"(0)		\
1118c2ecf20Sopenharmony_ci			: "memory", "vs0", "vs32", "r31");	\
1128c2ecf20Sopenharmony_ci	}							\
1138c2ecf20Sopenharmony_ci	rc |= do_test(#name, test_##name)
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci#define LOAD_VSX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 32, 32)
1168c2ecf20Sopenharmony_ci#define STORE_VSX_XFORM_TEST(op) TEST(op, lxvd2x, op, XFORM, 32, 32)
1178c2ecf20Sopenharmony_ci#define LOAD_VSX_DFORM_TEST(op) TEST(op, op, stxv, DFORM, 32, 32)
1188c2ecf20Sopenharmony_ci#define STORE_VSX_DFORM_TEST(op) TEST(op, lxv, op, DFORM, 32, 32)
1198c2ecf20Sopenharmony_ci#define LOAD_VMX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 0, 32)
1208c2ecf20Sopenharmony_ci#define STORE_VMX_XFORM_TEST(op) TEST(op, lxvd2x, op, XFORM, 32, 0)
1218c2ecf20Sopenharmony_ci#define LOAD_VMX_DFORM_TEST(op) TEST(op, op, stxv, DFORM, 0, 32)
1228c2ecf20Sopenharmony_ci#define STORE_VMX_DFORM_TEST(op) TEST(op, lxv, op, DFORM, 32, 0)
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci#define LOAD_XFORM_TEST(op) TEST(op, op, stdx, XFORM, 31, 31)
1258c2ecf20Sopenharmony_ci#define STORE_XFORM_TEST(op) TEST(op, ldx, op, XFORM, 31, 31)
1268c2ecf20Sopenharmony_ci#define LOAD_DFORM_TEST(op) TEST(op, op, std, DFORM, 31, 31)
1278c2ecf20Sopenharmony_ci#define STORE_DFORM_TEST(op) TEST(op, ld, op, DFORM, 31, 31)
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci#define LOAD_FLOAT_DFORM_TEST(op)  TEST(op, op, stfd, DFORM, 0, 0)
1308c2ecf20Sopenharmony_ci#define STORE_FLOAT_DFORM_TEST(op) TEST(op, lfd, op, DFORM, 0, 0)
1318c2ecf20Sopenharmony_ci#define LOAD_FLOAT_XFORM_TEST(op)  TEST(op, op, stfdx, XFORM, 0, 0)
1328c2ecf20Sopenharmony_ci#define STORE_FLOAT_XFORM_TEST(op) TEST(op, lfdx, op, XFORM, 0, 0)
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci#define LOAD_MLS_PREFIX_TEST(op) TESTP(op, op, PSTD, 31, 31)
1358c2ecf20Sopenharmony_ci#define STORE_MLS_PREFIX_TEST(op) TESTP(op, PLD, op, 31, 31)
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci#define LOAD_8LS_PREFIX_TEST(op) TESTP(op, op, PSTD, 31, 31)
1388c2ecf20Sopenharmony_ci#define STORE_8LS_PREFIX_TEST(op) TESTP(op, PLD, op, 31, 31)
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci#define LOAD_FLOAT_MLS_PREFIX_TEST(op) TESTP(op, op, PSTFD, 0, 0)
1418c2ecf20Sopenharmony_ci#define STORE_FLOAT_MLS_PREFIX_TEST(op) TESTP(op, PLFD, op, 0, 0)
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci#define LOAD_VSX_8LS_PREFIX_TEST(op, tail) TESTP(op, op, PSTXV ## tail, 0, 32)
1448c2ecf20Sopenharmony_ci#define STORE_VSX_8LS_PREFIX_TEST(op, tail) TESTP(op, PLXV ## tail, op, 32, 0)
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci/* FIXME: Unimplemented tests: */
1478c2ecf20Sopenharmony_ci// STORE_DFORM_TEST(stq)   /* FIXME: need two registers for quad */
1488c2ecf20Sopenharmony_ci// STORE_DFORM_TEST(stswi) /* FIXME: string instruction */
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci// STORE_XFORM_TEST(stwat) /* AMO can't emulate or run on CI */
1518c2ecf20Sopenharmony_ci// STORE_XFORM_TEST(stdat) /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci/* preload byte by byte */
1558c2ecf20Sopenharmony_civoid preload_data(void *dst, int offset, int width)
1568c2ecf20Sopenharmony_ci{
1578c2ecf20Sopenharmony_ci	char *c = dst;
1588c2ecf20Sopenharmony_ci	int i;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	c += offset;
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	for (i = 0 ; i < width ; i++)
1638c2ecf20Sopenharmony_ci		c[i] = i;
1648c2ecf20Sopenharmony_ci}
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ciint test_memcpy(void *dst, void *src, int size, int offset,
1678c2ecf20Sopenharmony_ci		void (*test_func)(char *, char *))
1688c2ecf20Sopenharmony_ci{
1698c2ecf20Sopenharmony_ci	char *s, *d;
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci	s = src;
1728c2ecf20Sopenharmony_ci	s += offset;
1738c2ecf20Sopenharmony_ci	d = dst;
1748c2ecf20Sopenharmony_ci	d += offset;
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	assert(size == 16);
1778c2ecf20Sopenharmony_ci	gotsig = 0;
1788c2ecf20Sopenharmony_ci	testing = 1;
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	test_func(s, d); /* run the actual test */
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	testing = 0;
1838c2ecf20Sopenharmony_ci	if (gotsig) {
1848c2ecf20Sopenharmony_ci		if (debug)
1858c2ecf20Sopenharmony_ci			printf("  Got signal %i\n", gotsig);
1868c2ecf20Sopenharmony_ci		return 1;
1878c2ecf20Sopenharmony_ci	}
1888c2ecf20Sopenharmony_ci	return 0;
1898c2ecf20Sopenharmony_ci}
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_civoid dumpdata(char *s1, char *s2, int n, char *test_name)
1928c2ecf20Sopenharmony_ci{
1938c2ecf20Sopenharmony_ci	int i;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	printf("  %s: unexpected result:\n", test_name);
1968c2ecf20Sopenharmony_ci	printf("    mem:");
1978c2ecf20Sopenharmony_ci	for (i = 0; i < n; i++)
1988c2ecf20Sopenharmony_ci		printf(" %02x", s1[i]);
1998c2ecf20Sopenharmony_ci	printf("\n");
2008c2ecf20Sopenharmony_ci	printf("    ci: ");
2018c2ecf20Sopenharmony_ci	for (i = 0; i < n; i++)
2028c2ecf20Sopenharmony_ci		printf(" %02x", s2[i]);
2038c2ecf20Sopenharmony_ci	printf("\n");
2048c2ecf20Sopenharmony_ci}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ciint test_memcmp(void *s1, void *s2, int n, int offset, char *test_name)
2078c2ecf20Sopenharmony_ci{
2088c2ecf20Sopenharmony_ci	char *s1c, *s2c;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci	s1c = s1;
2118c2ecf20Sopenharmony_ci	s1c += offset;
2128c2ecf20Sopenharmony_ci	s2c = s2;
2138c2ecf20Sopenharmony_ci	s2c += offset;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	if (memcmp(s1c, s2c, n)) {
2168c2ecf20Sopenharmony_ci		if (debug) {
2178c2ecf20Sopenharmony_ci			printf("\n  Compare failed. Offset:%i length:%i\n",
2188c2ecf20Sopenharmony_ci			       offset, n);
2198c2ecf20Sopenharmony_ci			dumpdata(s1c, s2c, n, test_name);
2208c2ecf20Sopenharmony_ci		}
2218c2ecf20Sopenharmony_ci		return 1;
2228c2ecf20Sopenharmony_ci	}
2238c2ecf20Sopenharmony_ci	return 0;
2248c2ecf20Sopenharmony_ci}
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci/*
2278c2ecf20Sopenharmony_ci * Do two memcpy tests using the same instructions. One cachable
2288c2ecf20Sopenharmony_ci * memory and the other doesn't.
2298c2ecf20Sopenharmony_ci */
2308c2ecf20Sopenharmony_ciint do_test(char *test_name, void (*test_func)(char *, char *))
2318c2ecf20Sopenharmony_ci{
2328c2ecf20Sopenharmony_ci	int offset, width, fd, rc, r;
2338c2ecf20Sopenharmony_ci	void *mem0, *mem1, *ci0, *ci1;
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	printf("\tDoing %s:\t", test_name);
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	fd = open(cipath, O_RDWR);
2388c2ecf20Sopenharmony_ci	if (fd < 0) {
2398c2ecf20Sopenharmony_ci		printf("\n");
2408c2ecf20Sopenharmony_ci		perror("Can't open ci file now?");
2418c2ecf20Sopenharmony_ci		return 1;
2428c2ecf20Sopenharmony_ci	}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	ci0 = mmap(NULL, bufsize, PROT_WRITE | PROT_READ, MAP_SHARED,
2458c2ecf20Sopenharmony_ci		   fd, cioffset);
2468c2ecf20Sopenharmony_ci	ci1 = mmap(NULL, bufsize, PROT_WRITE | PROT_READ, MAP_SHARED,
2478c2ecf20Sopenharmony_ci		   fd, cioffset + bufsize);
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	if ((ci0 == MAP_FAILED) || (ci1 == MAP_FAILED)) {
2508c2ecf20Sopenharmony_ci		printf("\n");
2518c2ecf20Sopenharmony_ci		perror("mmap failed");
2528c2ecf20Sopenharmony_ci		SKIP_IF(1);
2538c2ecf20Sopenharmony_ci	}
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	rc = posix_memalign(&mem0, bufsize, bufsize);
2568c2ecf20Sopenharmony_ci	if (rc) {
2578c2ecf20Sopenharmony_ci		printf("\n");
2588c2ecf20Sopenharmony_ci		return rc;
2598c2ecf20Sopenharmony_ci	}
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci	rc = posix_memalign(&mem1, bufsize, bufsize);
2628c2ecf20Sopenharmony_ci	if (rc) {
2638c2ecf20Sopenharmony_ci		printf("\n");
2648c2ecf20Sopenharmony_ci		free(mem0);
2658c2ecf20Sopenharmony_ci		return rc;
2668c2ecf20Sopenharmony_ci	}
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci	rc = 0;
2698c2ecf20Sopenharmony_ci	/*
2708c2ecf20Sopenharmony_ci	 * offset = 0 is aligned but tests the workaround for the P9N
2718c2ecf20Sopenharmony_ci	 * DD2.1 vector CI load issue (see 5080332c2c89 "powerpc/64s:
2728c2ecf20Sopenharmony_ci	 * Add workaround for P9 vector CI load issue")
2738c2ecf20Sopenharmony_ci	 */
2748c2ecf20Sopenharmony_ci	for (offset = 0; offset < 16; offset++) {
2758c2ecf20Sopenharmony_ci		width = 16; /* vsx == 16 bytes */
2768c2ecf20Sopenharmony_ci		r = 0;
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci		/* load pattern into memory byte by byte */
2798c2ecf20Sopenharmony_ci		preload_data(ci0, offset, width);
2808c2ecf20Sopenharmony_ci		preload_data(mem0, offset, width); // FIXME: remove??
2818c2ecf20Sopenharmony_ci		memcpy(ci0, mem0, bufsize);
2828c2ecf20Sopenharmony_ci		memcpy(ci1, mem1, bufsize); /* initialise output to the same */
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci		/* sanity check */
2858c2ecf20Sopenharmony_ci		test_memcmp(mem0, ci0, width, offset, test_name);
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci		r |= test_memcpy(ci1,  ci0,  width, offset, test_func);
2888c2ecf20Sopenharmony_ci		r |= test_memcpy(mem1, mem0, width, offset, test_func);
2898c2ecf20Sopenharmony_ci		if (r && !debug) {
2908c2ecf20Sopenharmony_ci			printf("FAILED: Got signal");
2918c2ecf20Sopenharmony_ci			rc = 1;
2928c2ecf20Sopenharmony_ci			break;
2938c2ecf20Sopenharmony_ci		}
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci		r |= test_memcmp(mem1, ci1, width, offset, test_name);
2968c2ecf20Sopenharmony_ci		if (r && !debug) {
2978c2ecf20Sopenharmony_ci			printf("FAILED: Wrong Data");
2988c2ecf20Sopenharmony_ci			rc = 1;
2998c2ecf20Sopenharmony_ci			break;
3008c2ecf20Sopenharmony_ci		}
3018c2ecf20Sopenharmony_ci	}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	if (rc == 0)
3048c2ecf20Sopenharmony_ci		printf("PASSED");
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	printf("\n");
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci	munmap(ci0, bufsize);
3098c2ecf20Sopenharmony_ci	munmap(ci1, bufsize);
3108c2ecf20Sopenharmony_ci	free(mem0);
3118c2ecf20Sopenharmony_ci	free(mem1);
3128c2ecf20Sopenharmony_ci	close(fd);
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci	return rc;
3158c2ecf20Sopenharmony_ci}
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_cistatic bool can_open_cifile(void)
3188c2ecf20Sopenharmony_ci{
3198c2ecf20Sopenharmony_ci	int fd;
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	fd = open(cipath, O_RDWR);
3228c2ecf20Sopenharmony_ci	if (fd < 0)
3238c2ecf20Sopenharmony_ci		return false;
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	close(fd);
3268c2ecf20Sopenharmony_ci	return true;
3278c2ecf20Sopenharmony_ci}
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ciint test_alignment_handler_vsx_206(void)
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci	int rc = 0;
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
3348c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	printf("VSX: 2.06B\n");
3378c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxvd2x);
3388c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxvw4x);
3398c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxsdx);
3408c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxvdsx);
3418c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxvd2x);
3428c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxvw4x);
3438c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxsdx);
3448c2ecf20Sopenharmony_ci	return rc;
3458c2ecf20Sopenharmony_ci}
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ciint test_alignment_handler_vsx_207(void)
3488c2ecf20Sopenharmony_ci{
3498c2ecf20Sopenharmony_ci	int rc = 0;
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
3528c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07));
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci	printf("VSX: 2.07B\n");
3558c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxsspx);
3568c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxsiwax);
3578c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxsiwzx);
3588c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxsspx);
3598c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxsiwx);
3608c2ecf20Sopenharmony_ci	return rc;
3618c2ecf20Sopenharmony_ci}
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ciint test_alignment_handler_vsx_300(void)
3648c2ecf20Sopenharmony_ci{
3658c2ecf20Sopenharmony_ci	int rc = 0;
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
3708c2ecf20Sopenharmony_ci	printf("VSX: 3.00B\n");
3718c2ecf20Sopenharmony_ci	LOAD_VMX_DFORM_TEST(lxsd);
3728c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxsibzx);
3738c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxsihzx);
3748c2ecf20Sopenharmony_ci	LOAD_VMX_DFORM_TEST(lxssp);
3758c2ecf20Sopenharmony_ci	LOAD_VSX_DFORM_TEST(lxv);
3768c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxvb16x);
3778c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxvh8x);
3788c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxvx);
3798c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxvwsx);
3808c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxvl);
3818c2ecf20Sopenharmony_ci	LOAD_VSX_XFORM_TEST(lxvll);
3828c2ecf20Sopenharmony_ci	STORE_VMX_DFORM_TEST(stxsd);
3838c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxsibx);
3848c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxsihx);
3858c2ecf20Sopenharmony_ci	STORE_VMX_DFORM_TEST(stxssp);
3868c2ecf20Sopenharmony_ci	STORE_VSX_DFORM_TEST(stxv);
3878c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxvb16x);
3888c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxvh8x);
3898c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxvx);
3908c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxvl);
3918c2ecf20Sopenharmony_ci	STORE_VSX_XFORM_TEST(stxvll);
3928c2ecf20Sopenharmony_ci	return rc;
3938c2ecf20Sopenharmony_ci}
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ciint test_alignment_handler_vsx_prefix(void)
3968c2ecf20Sopenharmony_ci{
3978c2ecf20Sopenharmony_ci	int rc = 0;
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
4008c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1));
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	printf("VSX: PREFIX\n");
4038c2ecf20Sopenharmony_ci	LOAD_VSX_8LS_PREFIX_TEST(PLXSD, 0);
4048c2ecf20Sopenharmony_ci	LOAD_VSX_8LS_PREFIX_TEST(PLXSSP, 0);
4058c2ecf20Sopenharmony_ci	LOAD_VSX_8LS_PREFIX_TEST(PLXV0, 0);
4068c2ecf20Sopenharmony_ci	LOAD_VSX_8LS_PREFIX_TEST(PLXV1, 1);
4078c2ecf20Sopenharmony_ci	STORE_VSX_8LS_PREFIX_TEST(PSTXSD, 0);
4088c2ecf20Sopenharmony_ci	STORE_VSX_8LS_PREFIX_TEST(PSTXSSP, 0);
4098c2ecf20Sopenharmony_ci	STORE_VSX_8LS_PREFIX_TEST(PSTXV0, 0);
4108c2ecf20Sopenharmony_ci	STORE_VSX_8LS_PREFIX_TEST(PSTXV1, 1);
4118c2ecf20Sopenharmony_ci	return rc;
4128c2ecf20Sopenharmony_ci}
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ciint test_alignment_handler_integer(void)
4158c2ecf20Sopenharmony_ci{
4168c2ecf20Sopenharmony_ci	int rc = 0;
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	printf("Integer\n");
4218c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lbz);
4228c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lbzu);
4238c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lbzx);
4248c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lbzux);
4258c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lhz);
4268c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lhzu);
4278c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lhzx);
4288c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lhzux);
4298c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lha);
4308c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lhau);
4318c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lhax);
4328c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lhaux);
4338c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lhbrx);
4348c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lwz);
4358c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lwzu);
4368c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lwzx);
4378c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lwzux);
4388c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lwa);
4398c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lwax);
4408c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lwaux);
4418c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(lwbrx);
4428c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(ld);
4438c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(ldu);
4448c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(ldx);
4458c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(ldux);
4468c2ecf20Sopenharmony_ci	STORE_DFORM_TEST(stb);
4478c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(stbx);
4488c2ecf20Sopenharmony_ci	STORE_DFORM_TEST(stbu);
4498c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(stbux);
4508c2ecf20Sopenharmony_ci	STORE_DFORM_TEST(sth);
4518c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(sthx);
4528c2ecf20Sopenharmony_ci	STORE_DFORM_TEST(sthu);
4538c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(sthux);
4548c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(sthbrx);
4558c2ecf20Sopenharmony_ci	STORE_DFORM_TEST(stw);
4568c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(stwx);
4578c2ecf20Sopenharmony_ci	STORE_DFORM_TEST(stwu);
4588c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(stwux);
4598c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(stwbrx);
4608c2ecf20Sopenharmony_ci	STORE_DFORM_TEST(std);
4618c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(stdx);
4628c2ecf20Sopenharmony_ci	STORE_DFORM_TEST(stdu);
4638c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(stdux);
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN__
4668c2ecf20Sopenharmony_ci	LOAD_DFORM_TEST(lmw);
4678c2ecf20Sopenharmony_ci	STORE_DFORM_TEST(stmw);
4688c2ecf20Sopenharmony_ci#endif
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	return rc;
4718c2ecf20Sopenharmony_ci}
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ciint test_alignment_handler_integer_206(void)
4748c2ecf20Sopenharmony_ci{
4758c2ecf20Sopenharmony_ci	int rc = 0;
4768c2ecf20Sopenharmony_ci
4778c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
4788c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci	printf("Integer: 2.06\n");
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_ci	LOAD_XFORM_TEST(ldbrx);
4838c2ecf20Sopenharmony_ci	STORE_XFORM_TEST(stdbrx);
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci	return rc;
4868c2ecf20Sopenharmony_ci}
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ciint test_alignment_handler_integer_prefix(void)
4898c2ecf20Sopenharmony_ci{
4908c2ecf20Sopenharmony_ci	int rc = 0;
4918c2ecf20Sopenharmony_ci
4928c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
4938c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1));
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	printf("Integer: PREFIX\n");
4968c2ecf20Sopenharmony_ci	LOAD_MLS_PREFIX_TEST(PLBZ);
4978c2ecf20Sopenharmony_ci	LOAD_MLS_PREFIX_TEST(PLHZ);
4988c2ecf20Sopenharmony_ci	LOAD_MLS_PREFIX_TEST(PLHA);
4998c2ecf20Sopenharmony_ci	LOAD_MLS_PREFIX_TEST(PLWZ);
5008c2ecf20Sopenharmony_ci	LOAD_8LS_PREFIX_TEST(PLWA);
5018c2ecf20Sopenharmony_ci	LOAD_8LS_PREFIX_TEST(PLD);
5028c2ecf20Sopenharmony_ci	STORE_MLS_PREFIX_TEST(PSTB);
5038c2ecf20Sopenharmony_ci	STORE_MLS_PREFIX_TEST(PSTH);
5048c2ecf20Sopenharmony_ci	STORE_MLS_PREFIX_TEST(PSTW);
5058c2ecf20Sopenharmony_ci	STORE_8LS_PREFIX_TEST(PSTD);
5068c2ecf20Sopenharmony_ci	return rc;
5078c2ecf20Sopenharmony_ci}
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ciint test_alignment_handler_vmx(void)
5108c2ecf20Sopenharmony_ci{
5118c2ecf20Sopenharmony_ci	int rc = 0;
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
5148c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap(PPC_FEATURE_HAS_ALTIVEC));
5158c2ecf20Sopenharmony_ci
5168c2ecf20Sopenharmony_ci	printf("VMX\n");
5178c2ecf20Sopenharmony_ci	LOAD_VMX_XFORM_TEST(lvx);
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_ci	/*
5208c2ecf20Sopenharmony_ci	 * FIXME: These loads only load part of the register, so our
5218c2ecf20Sopenharmony_ci	 * testing method doesn't work. Also they don't take alignment
5228c2ecf20Sopenharmony_ci	 * faults, so it's kinda pointless anyway
5238c2ecf20Sopenharmony_ci	 *
5248c2ecf20Sopenharmony_ci	 LOAD_VMX_XFORM_TEST(lvebx)
5258c2ecf20Sopenharmony_ci	 LOAD_VMX_XFORM_TEST(lvehx)
5268c2ecf20Sopenharmony_ci	 LOAD_VMX_XFORM_TEST(lvewx)
5278c2ecf20Sopenharmony_ci	 LOAD_VMX_XFORM_TEST(lvxl)
5288c2ecf20Sopenharmony_ci	*/
5298c2ecf20Sopenharmony_ci	STORE_VMX_XFORM_TEST(stvx);
5308c2ecf20Sopenharmony_ci	STORE_VMX_XFORM_TEST(stvebx);
5318c2ecf20Sopenharmony_ci	STORE_VMX_XFORM_TEST(stvehx);
5328c2ecf20Sopenharmony_ci	STORE_VMX_XFORM_TEST(stvewx);
5338c2ecf20Sopenharmony_ci	STORE_VMX_XFORM_TEST(stvxl);
5348c2ecf20Sopenharmony_ci	return rc;
5358c2ecf20Sopenharmony_ci}
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ciint test_alignment_handler_fp(void)
5388c2ecf20Sopenharmony_ci{
5398c2ecf20Sopenharmony_ci	int rc = 0;
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_ci	printf("Floating point\n");
5448c2ecf20Sopenharmony_ci	LOAD_FLOAT_DFORM_TEST(lfd);
5458c2ecf20Sopenharmony_ci	LOAD_FLOAT_XFORM_TEST(lfdx);
5468c2ecf20Sopenharmony_ci	LOAD_FLOAT_DFORM_TEST(lfdu);
5478c2ecf20Sopenharmony_ci	LOAD_FLOAT_XFORM_TEST(lfdux);
5488c2ecf20Sopenharmony_ci	LOAD_FLOAT_DFORM_TEST(lfs);
5498c2ecf20Sopenharmony_ci	LOAD_FLOAT_XFORM_TEST(lfsx);
5508c2ecf20Sopenharmony_ci	LOAD_FLOAT_DFORM_TEST(lfsu);
5518c2ecf20Sopenharmony_ci	LOAD_FLOAT_XFORM_TEST(lfsux);
5528c2ecf20Sopenharmony_ci	STORE_FLOAT_DFORM_TEST(stfd);
5538c2ecf20Sopenharmony_ci	STORE_FLOAT_XFORM_TEST(stfdx);
5548c2ecf20Sopenharmony_ci	STORE_FLOAT_DFORM_TEST(stfdu);
5558c2ecf20Sopenharmony_ci	STORE_FLOAT_XFORM_TEST(stfdux);
5568c2ecf20Sopenharmony_ci	STORE_FLOAT_DFORM_TEST(stfs);
5578c2ecf20Sopenharmony_ci	STORE_FLOAT_XFORM_TEST(stfsx);
5588c2ecf20Sopenharmony_ci	STORE_FLOAT_DFORM_TEST(stfsu);
5598c2ecf20Sopenharmony_ci	STORE_FLOAT_XFORM_TEST(stfsux);
5608c2ecf20Sopenharmony_ci	STORE_FLOAT_XFORM_TEST(stfiwx);
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci	return rc;
5638c2ecf20Sopenharmony_ci}
5648c2ecf20Sopenharmony_ci
5658c2ecf20Sopenharmony_ciint test_alignment_handler_fp_205(void)
5668c2ecf20Sopenharmony_ci{
5678c2ecf20Sopenharmony_ci	int rc = 0;
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
5708c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_05));
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ci	printf("Floating point: 2.05\n");
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci	LOAD_FLOAT_DFORM_TEST(lfdp);
5758c2ecf20Sopenharmony_ci	LOAD_FLOAT_XFORM_TEST(lfdpx);
5768c2ecf20Sopenharmony_ci	LOAD_FLOAT_XFORM_TEST(lfiwax);
5778c2ecf20Sopenharmony_ci	STORE_FLOAT_DFORM_TEST(stfdp);
5788c2ecf20Sopenharmony_ci	STORE_FLOAT_XFORM_TEST(stfdpx);
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_ci	return rc;
5818c2ecf20Sopenharmony_ci}
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ciint test_alignment_handler_fp_206(void)
5848c2ecf20Sopenharmony_ci{
5858c2ecf20Sopenharmony_ci	int rc = 0;
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
5888c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_ci	printf("Floating point: 2.06\n");
5918c2ecf20Sopenharmony_ci
5928c2ecf20Sopenharmony_ci	LOAD_FLOAT_XFORM_TEST(lfiwzx);
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_ci	return rc;
5958c2ecf20Sopenharmony_ci}
5968c2ecf20Sopenharmony_ci
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_ciint test_alignment_handler_fp_prefix(void)
5998c2ecf20Sopenharmony_ci{
6008c2ecf20Sopenharmony_ci	int rc = 0;
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_ci	SKIP_IF(!can_open_cifile());
6038c2ecf20Sopenharmony_ci	SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1));
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_ci	printf("Floating point: PREFIX\n");
6068c2ecf20Sopenharmony_ci	LOAD_FLOAT_DFORM_TEST(lfs);
6078c2ecf20Sopenharmony_ci	LOAD_FLOAT_MLS_PREFIX_TEST(PLFS);
6088c2ecf20Sopenharmony_ci	LOAD_FLOAT_MLS_PREFIX_TEST(PLFD);
6098c2ecf20Sopenharmony_ci	STORE_FLOAT_MLS_PREFIX_TEST(PSTFS);
6108c2ecf20Sopenharmony_ci	STORE_FLOAT_MLS_PREFIX_TEST(PSTFD);
6118c2ecf20Sopenharmony_ci	return rc;
6128c2ecf20Sopenharmony_ci}
6138c2ecf20Sopenharmony_ci
6148c2ecf20Sopenharmony_civoid usage(char *prog)
6158c2ecf20Sopenharmony_ci{
6168c2ecf20Sopenharmony_ci	printf("Usage: %s [options] [path [offset]]\n", prog);
6178c2ecf20Sopenharmony_ci	printf("  -d	Enable debug error output\n");
6188c2ecf20Sopenharmony_ci	printf("\n");
6198c2ecf20Sopenharmony_ci	printf("This test requires a POWER8, POWER9 or POWER10 CPU ");
6208c2ecf20Sopenharmony_ci	printf("and either a usable framebuffer at /dev/fb0 or ");
6218c2ecf20Sopenharmony_ci	printf("the path to usable cache inhibited memory and optional ");
6228c2ecf20Sopenharmony_ci	printf("offset to be provided\n");
6238c2ecf20Sopenharmony_ci}
6248c2ecf20Sopenharmony_ci
6258c2ecf20Sopenharmony_ciint main(int argc, char *argv[])
6268c2ecf20Sopenharmony_ci{
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_ci	struct sigaction sa;
6298c2ecf20Sopenharmony_ci	int rc = 0;
6308c2ecf20Sopenharmony_ci	int option = 0;
6318c2ecf20Sopenharmony_ci
6328c2ecf20Sopenharmony_ci	while ((option = getopt(argc, argv, "d")) != -1) {
6338c2ecf20Sopenharmony_ci		switch (option) {
6348c2ecf20Sopenharmony_ci		case 'd':
6358c2ecf20Sopenharmony_ci			debug++;
6368c2ecf20Sopenharmony_ci			break;
6378c2ecf20Sopenharmony_ci		default:
6388c2ecf20Sopenharmony_ci			usage(argv[0]);
6398c2ecf20Sopenharmony_ci			exit(1);
6408c2ecf20Sopenharmony_ci		}
6418c2ecf20Sopenharmony_ci	}
6428c2ecf20Sopenharmony_ci	argc -= optind;
6438c2ecf20Sopenharmony_ci	argv += optind;
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_ci	if (argc > 0)
6468c2ecf20Sopenharmony_ci		cipath = argv[0];
6478c2ecf20Sopenharmony_ci	if (argc > 1)
6488c2ecf20Sopenharmony_ci		cioffset = strtol(argv[1], 0, 0x10);
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_ci	bufsize = getpagesize();
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci	sa.sa_sigaction = sighandler;
6538c2ecf20Sopenharmony_ci	sigemptyset(&sa.sa_mask);
6548c2ecf20Sopenharmony_ci	sa.sa_flags = SA_SIGINFO;
6558c2ecf20Sopenharmony_ci	if (sigaction(SIGSEGV, &sa, NULL) == -1
6568c2ecf20Sopenharmony_ci	    || sigaction(SIGBUS, &sa, NULL) == -1
6578c2ecf20Sopenharmony_ci	    || sigaction(SIGILL, &sa, NULL) == -1) {
6588c2ecf20Sopenharmony_ci		perror("sigaction");
6598c2ecf20Sopenharmony_ci		exit(1);
6608c2ecf20Sopenharmony_ci	}
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	prefixes_enabled = have_hwcap2(PPC_FEATURE2_ARCH_3_1);
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_vsx_206,
6658c2ecf20Sopenharmony_ci			   "test_alignment_handler_vsx_206");
6668c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_vsx_207,
6678c2ecf20Sopenharmony_ci			   "test_alignment_handler_vsx_207");
6688c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_vsx_300,
6698c2ecf20Sopenharmony_ci			   "test_alignment_handler_vsx_300");
6708c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_vsx_prefix,
6718c2ecf20Sopenharmony_ci			   "test_alignment_handler_vsx_prefix");
6728c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_integer,
6738c2ecf20Sopenharmony_ci			   "test_alignment_handler_integer");
6748c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_integer_206,
6758c2ecf20Sopenharmony_ci			   "test_alignment_handler_integer_206");
6768c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_integer_prefix,
6778c2ecf20Sopenharmony_ci			   "test_alignment_handler_integer_prefix");
6788c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_vmx,
6798c2ecf20Sopenharmony_ci			   "test_alignment_handler_vmx");
6808c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_fp,
6818c2ecf20Sopenharmony_ci			   "test_alignment_handler_fp");
6828c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_fp_205,
6838c2ecf20Sopenharmony_ci			   "test_alignment_handler_fp_205");
6848c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_fp_206,
6858c2ecf20Sopenharmony_ci			   "test_alignment_handler_fp_206");
6868c2ecf20Sopenharmony_ci	rc |= test_harness(test_alignment_handler_fp_prefix,
6878c2ecf20Sopenharmony_ci			   "test_alignment_handler_fp_prefix");
6888c2ecf20Sopenharmony_ci	return rc;
6898c2ecf20Sopenharmony_ci}
690