1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Test the powerpc alignment handler on POWER8/POWER9 4 * 5 * Copyright (C) 2017 IBM Corporation (Michael Neuling, Andrew Donnellan) 6 */ 7 8 /* 9 * This selftest exercises the powerpc alignment fault handler. 10 * 11 * We create two sets of source and destination buffers, one in regular memory, 12 * the other cache-inhibited (by default we use /dev/fb0 for this, but an 13 * alterative path for cache-inhibited memory may be provided, e.g. memtrace). 14 * 15 * We initialise the source buffers, then use whichever set of load/store 16 * instructions is under test to copy bytes from the source buffers to the 17 * destination buffers. For the regular buffers, these instructions will 18 * execute normally. For the cache-inhibited buffers, these instructions 19 * will trap and cause an alignment fault, and the alignment fault handler 20 * will emulate the particular instruction under test. We then compare the 21 * destination buffers to ensure that the native and emulated cases give the 22 * same result. 23 * 24 * TODO: 25 * - Any FIXMEs below 26 * - Test VSX regs < 32 and > 32 27 * - Test all loads and stores 28 * - Check update forms do update register 29 * - Test alignment faults over page boundary 30 * 31 * Some old binutils may not support all the instructions. 32 */ 33 34 35 #include <sys/mman.h> 36 #include <sys/types.h> 37 #include <sys/stat.h> 38 #include <fcntl.h> 39 #include <unistd.h> 40 #include <stdbool.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <assert.h> 45 #include <getopt.h> 46 #include <setjmp.h> 47 #include <signal.h> 48 49 #include "utils.h" 50 #include "instructions.h" 51 52 int bufsize; 53 int debug; 54 int testing; 55 volatile int gotsig; 56 bool prefixes_enabled; 57 char *cipath = "/dev/fb0"; 58 long cioffset; 59 60 void sighandler(int sig, siginfo_t *info, void *ctx) 61 { 62 ucontext_t *ucp = ctx; 63 64 if (!testing) { 65 signal(sig, SIG_DFL); 66 kill(0, sig); 67 } 68 gotsig = sig; 69 #ifdef __powerpc64__ 70 if (prefixes_enabled) { 71 u32 inst = *(u32 *)ucp->uc_mcontext.gp_regs[PT_NIP]; 72 ucp->uc_mcontext.gp_regs[PT_NIP] += ((inst >> 26 == 1) ? 8 : 4); 73 } else { 74 ucp->uc_mcontext.gp_regs[PT_NIP] += 4; 75 } 76 #else 77 ucp->uc_mcontext.uc_regs->gregs[PT_NIP] += 4; 78 #endif 79 } 80 81 #define XFORM(reg, n) " " #reg " ,%"#n",%2 ;" 82 #define DFORM(reg, n) " " #reg " ,0(%"#n") ;" 83 84 #define TEST(name, ld_op, st_op, form, ld_reg, st_reg) \ 85 void test_##name(char *s, char *d) \ 86 { \ 87 asm volatile( \ 88 #ld_op form(ld_reg, 0) \ 89 #st_op form(st_reg, 1) \ 90 :: "r"(s), "r"(d), "r"(0) \ 91 : "memory", "vs0", "vs32", "r31"); \ 92 } \ 93 rc |= do_test(#name, test_##name) 94 95 #define TESTP(name, ld_op, st_op, ld_reg, st_reg) \ 96 void test_##name(char *s, char *d) \ 97 { \ 98 asm volatile( \ 99 ld_op(ld_reg, %0, 0, 0) \ 100 st_op(st_reg, %1, 0, 0) \ 101 :: "r"(s), "r"(d), "r"(0) \ 102 : "memory", "vs0", "vs32", "r31"); \ 103 } \ 104 rc |= do_test(#name, test_##name) 105 106 #define LOAD_VSX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 32, 32) 107 #define STORE_VSX_XFORM_TEST(op) TEST(op, lxvd2x, op, XFORM, 32, 32) 108 #define LOAD_VSX_DFORM_TEST(op) TEST(op, op, stxv, DFORM, 32, 32) 109 #define STORE_VSX_DFORM_TEST(op) TEST(op, lxv, op, DFORM, 32, 32) 110 #define LOAD_VMX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 0, 32) 111 #define STORE_VMX_XFORM_TEST(op) TEST(op, lxvd2x, op, XFORM, 32, 0) 112 #define LOAD_VMX_DFORM_TEST(op) TEST(op, op, stxv, DFORM, 0, 32) 113 #define STORE_VMX_DFORM_TEST(op) TEST(op, lxv, op, DFORM, 32, 0) 114 115 #define LOAD_XFORM_TEST(op) TEST(op, op, stdx, XFORM, 31, 31) 116 #define STORE_XFORM_TEST(op) TEST(op, ldx, op, XFORM, 31, 31) 117 #define LOAD_DFORM_TEST(op) TEST(op, op, std, DFORM, 31, 31) 118 #define STORE_DFORM_TEST(op) TEST(op, ld, op, DFORM, 31, 31) 119 120 #define LOAD_FLOAT_DFORM_TEST(op) TEST(op, op, stfd, DFORM, 0, 0) 121 #define STORE_FLOAT_DFORM_TEST(op) TEST(op, lfd, op, DFORM, 0, 0) 122 #define LOAD_FLOAT_XFORM_TEST(op) TEST(op, op, stfdx, XFORM, 0, 0) 123 #define STORE_FLOAT_XFORM_TEST(op) TEST(op, lfdx, op, XFORM, 0, 0) 124 125 #define LOAD_MLS_PREFIX_TEST(op) TESTP(op, op, PSTD, 31, 31) 126 #define STORE_MLS_PREFIX_TEST(op) TESTP(op, PLD, op, 31, 31) 127 128 #define LOAD_8LS_PREFIX_TEST(op) TESTP(op, op, PSTD, 31, 31) 129 #define STORE_8LS_PREFIX_TEST(op) TESTP(op, PLD, op, 31, 31) 130 131 #define LOAD_FLOAT_MLS_PREFIX_TEST(op) TESTP(op, op, PSTFD, 0, 0) 132 #define STORE_FLOAT_MLS_PREFIX_TEST(op) TESTP(op, PLFD, op, 0, 0) 133 134 #define LOAD_VSX_8LS_PREFIX_TEST(op, tail) TESTP(op, op, PSTXV ## tail, 0, 32) 135 #define STORE_VSX_8LS_PREFIX_TEST(op, tail) TESTP(op, PLXV ## tail, op, 32, 0) 136 137 /* FIXME: Unimplemented tests: */ 138 // STORE_DFORM_TEST(stq) /* FIXME: need two registers for quad */ 139 // STORE_DFORM_TEST(stswi) /* FIXME: string instruction */ 140 141 // STORE_XFORM_TEST(stwat) /* AMO can't emulate or run on CI */ 142 // STORE_XFORM_TEST(stdat) /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ 143 144 145 /* preload byte by byte */ 146 void preload_data(void *dst, int offset, int width) 147 { 148 char *c = dst; 149 int i; 150 151 c += offset; 152 153 for (i = 0 ; i < width ; i++) 154 c[i] = i; 155 } 156 157 int test_memcpy(void *dst, void *src, int size, int offset, 158 void (*test_func)(char *, char *)) 159 { 160 char *s, *d; 161 162 s = src; 163 s += offset; 164 d = dst; 165 d += offset; 166 167 assert(size == 16); 168 gotsig = 0; 169 testing = 1; 170 171 test_func(s, d); /* run the actual test */ 172 173 testing = 0; 174 if (gotsig) { 175 if (debug) 176 printf(" Got signal %i\n", gotsig); 177 return 1; 178 } 179 return 0; 180 } 181 182 void dumpdata(char *s1, char *s2, int n, char *test_name) 183 { 184 int i; 185 186 printf(" %s: unexpected result:\n", test_name); 187 printf(" mem:"); 188 for (i = 0; i < n; i++) 189 printf(" %02x", s1[i]); 190 printf("\n"); 191 printf(" ci: "); 192 for (i = 0; i < n; i++) 193 printf(" %02x", s2[i]); 194 printf("\n"); 195 } 196 197 int test_memcmp(void *s1, void *s2, int n, int offset, char *test_name) 198 { 199 char *s1c, *s2c; 200 201 s1c = s1; 202 s1c += offset; 203 s2c = s2; 204 s2c += offset; 205 206 if (memcmp(s1c, s2c, n)) { 207 if (debug) { 208 printf("\n Compare failed. Offset:%i length:%i\n", 209 offset, n); 210 dumpdata(s1c, s2c, n, test_name); 211 } 212 return 1; 213 } 214 return 0; 215 } 216 217 /* 218 * Do two memcpy tests using the same instructions. One cachable 219 * memory and the other doesn't. 220 */ 221 int do_test(char *test_name, void (*test_func)(char *, char *)) 222 { 223 int offset, width, fd, rc, r; 224 void *mem0, *mem1, *ci0, *ci1; 225 226 printf("\tDoing %s:\t", test_name); 227 228 fd = open(cipath, O_RDWR); 229 if (fd < 0) { 230 printf("\n"); 231 perror("Can't open ci file now?"); 232 return 1; 233 } 234 235 ci0 = mmap(NULL, bufsize, PROT_WRITE | PROT_READ, MAP_SHARED, 236 fd, cioffset); 237 ci1 = mmap(NULL, bufsize, PROT_WRITE | PROT_READ, MAP_SHARED, 238 fd, cioffset + bufsize); 239 240 if ((ci0 == MAP_FAILED) || (ci1 == MAP_FAILED)) { 241 printf("\n"); 242 perror("mmap failed"); 243 SKIP_IF(1); 244 } 245 246 rc = posix_memalign(&mem0, bufsize, bufsize); 247 if (rc) { 248 printf("\n"); 249 return rc; 250 } 251 252 rc = posix_memalign(&mem1, bufsize, bufsize); 253 if (rc) { 254 printf("\n"); 255 free(mem0); 256 return rc; 257 } 258 259 rc = 0; 260 /* 261 * offset = 0 is aligned but tests the workaround for the P9N 262 * DD2.1 vector CI load issue (see 5080332c2c89 "powerpc/64s: 263 * Add workaround for P9 vector CI load issue") 264 */ 265 for (offset = 0; offset < 16; offset++) { 266 width = 16; /* vsx == 16 bytes */ 267 r = 0; 268 269 /* load pattern into memory byte by byte */ 270 preload_data(ci0, offset, width); 271 preload_data(mem0, offset, width); // FIXME: remove?? 272 memcpy(ci0, mem0, bufsize); 273 memcpy(ci1, mem1, bufsize); /* initialise output to the same */ 274 275 /* sanity check */ 276 test_memcmp(mem0, ci0, width, offset, test_name); 277 278 r |= test_memcpy(ci1, ci0, width, offset, test_func); 279 r |= test_memcpy(mem1, mem0, width, offset, test_func); 280 if (r && !debug) { 281 printf("FAILED: Got signal"); 282 rc = 1; 283 break; 284 } 285 286 r |= test_memcmp(mem1, ci1, width, offset, test_name); 287 if (r && !debug) { 288 printf("FAILED: Wrong Data"); 289 rc = 1; 290 break; 291 } 292 } 293 294 if (rc == 0) 295 printf("PASSED"); 296 297 printf("\n"); 298 299 munmap(ci0, bufsize); 300 munmap(ci1, bufsize); 301 free(mem0); 302 free(mem1); 303 close(fd); 304 305 return rc; 306 } 307 308 static bool can_open_cifile(void) 309 { 310 int fd; 311 312 fd = open(cipath, O_RDWR); 313 if (fd < 0) 314 return false; 315 316 close(fd); 317 return true; 318 } 319 320 int test_alignment_handler_vsx_206(void) 321 { 322 int rc = 0; 323 324 SKIP_IF(!can_open_cifile()); 325 SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06)); 326 327 printf("VSX: 2.06B\n"); 328 LOAD_VSX_XFORM_TEST(lxvd2x); 329 LOAD_VSX_XFORM_TEST(lxvw4x); 330 LOAD_VSX_XFORM_TEST(lxsdx); 331 LOAD_VSX_XFORM_TEST(lxvdsx); 332 STORE_VSX_XFORM_TEST(stxvd2x); 333 STORE_VSX_XFORM_TEST(stxvw4x); 334 STORE_VSX_XFORM_TEST(stxsdx); 335 return rc; 336 } 337 338 int test_alignment_handler_vsx_207(void) 339 { 340 int rc = 0; 341 342 SKIP_IF(!can_open_cifile()); 343 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07)); 344 345 printf("VSX: 2.07B\n"); 346 LOAD_VSX_XFORM_TEST(lxsspx); 347 LOAD_VSX_XFORM_TEST(lxsiwax); 348 LOAD_VSX_XFORM_TEST(lxsiwzx); 349 STORE_VSX_XFORM_TEST(stxsspx); 350 STORE_VSX_XFORM_TEST(stxsiwx); 351 return rc; 352 } 353 354 int test_alignment_handler_vsx_300(void) 355 { 356 int rc = 0; 357 358 SKIP_IF(!can_open_cifile()); 359 360 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00)); 361 printf("VSX: 3.00B\n"); 362 LOAD_VMX_DFORM_TEST(lxsd); 363 LOAD_VSX_XFORM_TEST(lxsibzx); 364 LOAD_VSX_XFORM_TEST(lxsihzx); 365 LOAD_VMX_DFORM_TEST(lxssp); 366 LOAD_VSX_DFORM_TEST(lxv); 367 LOAD_VSX_XFORM_TEST(lxvb16x); 368 LOAD_VSX_XFORM_TEST(lxvh8x); 369 LOAD_VSX_XFORM_TEST(lxvx); 370 LOAD_VSX_XFORM_TEST(lxvwsx); 371 LOAD_VSX_XFORM_TEST(lxvl); 372 LOAD_VSX_XFORM_TEST(lxvll); 373 STORE_VMX_DFORM_TEST(stxsd); 374 STORE_VSX_XFORM_TEST(stxsibx); 375 STORE_VSX_XFORM_TEST(stxsihx); 376 STORE_VMX_DFORM_TEST(stxssp); 377 STORE_VSX_DFORM_TEST(stxv); 378 STORE_VSX_XFORM_TEST(stxvb16x); 379 STORE_VSX_XFORM_TEST(stxvh8x); 380 STORE_VSX_XFORM_TEST(stxvx); 381 STORE_VSX_XFORM_TEST(stxvl); 382 STORE_VSX_XFORM_TEST(stxvll); 383 return rc; 384 } 385 386 int test_alignment_handler_vsx_prefix(void) 387 { 388 int rc = 0; 389 390 SKIP_IF(!can_open_cifile()); 391 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 392 393 printf("VSX: PREFIX\n"); 394 LOAD_VSX_8LS_PREFIX_TEST(PLXSD, 0); 395 LOAD_VSX_8LS_PREFIX_TEST(PLXSSP, 0); 396 LOAD_VSX_8LS_PREFIX_TEST(PLXV0, 0); 397 LOAD_VSX_8LS_PREFIX_TEST(PLXV1, 1); 398 STORE_VSX_8LS_PREFIX_TEST(PSTXSD, 0); 399 STORE_VSX_8LS_PREFIX_TEST(PSTXSSP, 0); 400 STORE_VSX_8LS_PREFIX_TEST(PSTXV0, 0); 401 STORE_VSX_8LS_PREFIX_TEST(PSTXV1, 1); 402 return rc; 403 } 404 405 int test_alignment_handler_integer(void) 406 { 407 int rc = 0; 408 409 SKIP_IF(!can_open_cifile()); 410 411 printf("Integer\n"); 412 LOAD_DFORM_TEST(lbz); 413 LOAD_DFORM_TEST(lbzu); 414 LOAD_XFORM_TEST(lbzx); 415 LOAD_XFORM_TEST(lbzux); 416 LOAD_DFORM_TEST(lhz); 417 LOAD_DFORM_TEST(lhzu); 418 LOAD_XFORM_TEST(lhzx); 419 LOAD_XFORM_TEST(lhzux); 420 LOAD_DFORM_TEST(lha); 421 LOAD_DFORM_TEST(lhau); 422 LOAD_XFORM_TEST(lhax); 423 LOAD_XFORM_TEST(lhaux); 424 LOAD_XFORM_TEST(lhbrx); 425 LOAD_DFORM_TEST(lwz); 426 LOAD_DFORM_TEST(lwzu); 427 LOAD_XFORM_TEST(lwzx); 428 LOAD_XFORM_TEST(lwzux); 429 LOAD_DFORM_TEST(lwa); 430 LOAD_XFORM_TEST(lwax); 431 LOAD_XFORM_TEST(lwaux); 432 LOAD_XFORM_TEST(lwbrx); 433 LOAD_DFORM_TEST(ld); 434 LOAD_DFORM_TEST(ldu); 435 LOAD_XFORM_TEST(ldx); 436 LOAD_XFORM_TEST(ldux); 437 STORE_DFORM_TEST(stb); 438 STORE_XFORM_TEST(stbx); 439 STORE_DFORM_TEST(stbu); 440 STORE_XFORM_TEST(stbux); 441 STORE_DFORM_TEST(sth); 442 STORE_XFORM_TEST(sthx); 443 STORE_DFORM_TEST(sthu); 444 STORE_XFORM_TEST(sthux); 445 STORE_XFORM_TEST(sthbrx); 446 STORE_DFORM_TEST(stw); 447 STORE_XFORM_TEST(stwx); 448 STORE_DFORM_TEST(stwu); 449 STORE_XFORM_TEST(stwux); 450 STORE_XFORM_TEST(stwbrx); 451 STORE_DFORM_TEST(std); 452 STORE_XFORM_TEST(stdx); 453 STORE_DFORM_TEST(stdu); 454 STORE_XFORM_TEST(stdux); 455 456 #ifdef __BIG_ENDIAN__ 457 LOAD_DFORM_TEST(lmw); 458 STORE_DFORM_TEST(stmw); 459 #endif 460 461 return rc; 462 } 463 464 int test_alignment_handler_integer_206(void) 465 { 466 int rc = 0; 467 468 SKIP_IF(!can_open_cifile()); 469 SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06)); 470 471 printf("Integer: 2.06\n"); 472 473 LOAD_XFORM_TEST(ldbrx); 474 STORE_XFORM_TEST(stdbrx); 475 476 return rc; 477 } 478 479 int test_alignment_handler_integer_prefix(void) 480 { 481 int rc = 0; 482 483 SKIP_IF(!can_open_cifile()); 484 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 485 486 printf("Integer: PREFIX\n"); 487 LOAD_MLS_PREFIX_TEST(PLBZ); 488 LOAD_MLS_PREFIX_TEST(PLHZ); 489 LOAD_MLS_PREFIX_TEST(PLHA); 490 LOAD_MLS_PREFIX_TEST(PLWZ); 491 LOAD_8LS_PREFIX_TEST(PLWA); 492 LOAD_8LS_PREFIX_TEST(PLD); 493 STORE_MLS_PREFIX_TEST(PSTB); 494 STORE_MLS_PREFIX_TEST(PSTH); 495 STORE_MLS_PREFIX_TEST(PSTW); 496 STORE_8LS_PREFIX_TEST(PSTD); 497 return rc; 498 } 499 500 int test_alignment_handler_vmx(void) 501 { 502 int rc = 0; 503 504 SKIP_IF(!can_open_cifile()); 505 SKIP_IF(!have_hwcap(PPC_FEATURE_HAS_ALTIVEC)); 506 507 printf("VMX\n"); 508 LOAD_VMX_XFORM_TEST(lvx); 509 510 /* 511 * FIXME: These loads only load part of the register, so our 512 * testing method doesn't work. Also they don't take alignment 513 * faults, so it's kinda pointless anyway 514 * 515 LOAD_VMX_XFORM_TEST(lvebx) 516 LOAD_VMX_XFORM_TEST(lvehx) 517 LOAD_VMX_XFORM_TEST(lvewx) 518 LOAD_VMX_XFORM_TEST(lvxl) 519 */ 520 STORE_VMX_XFORM_TEST(stvx); 521 STORE_VMX_XFORM_TEST(stvebx); 522 STORE_VMX_XFORM_TEST(stvehx); 523 STORE_VMX_XFORM_TEST(stvewx); 524 STORE_VMX_XFORM_TEST(stvxl); 525 return rc; 526 } 527 528 int test_alignment_handler_fp(void) 529 { 530 int rc = 0; 531 532 SKIP_IF(!can_open_cifile()); 533 534 printf("Floating point\n"); 535 LOAD_FLOAT_DFORM_TEST(lfd); 536 LOAD_FLOAT_XFORM_TEST(lfdx); 537 LOAD_FLOAT_DFORM_TEST(lfdu); 538 LOAD_FLOAT_XFORM_TEST(lfdux); 539 LOAD_FLOAT_DFORM_TEST(lfs); 540 LOAD_FLOAT_XFORM_TEST(lfsx); 541 LOAD_FLOAT_DFORM_TEST(lfsu); 542 LOAD_FLOAT_XFORM_TEST(lfsux); 543 STORE_FLOAT_DFORM_TEST(stfd); 544 STORE_FLOAT_XFORM_TEST(stfdx); 545 STORE_FLOAT_DFORM_TEST(stfdu); 546 STORE_FLOAT_XFORM_TEST(stfdux); 547 STORE_FLOAT_DFORM_TEST(stfs); 548 STORE_FLOAT_XFORM_TEST(stfsx); 549 STORE_FLOAT_DFORM_TEST(stfsu); 550 STORE_FLOAT_XFORM_TEST(stfsux); 551 STORE_FLOAT_XFORM_TEST(stfiwx); 552 553 return rc; 554 } 555 556 int test_alignment_handler_fp_205(void) 557 { 558 int rc = 0; 559 560 SKIP_IF(!can_open_cifile()); 561 SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_05)); 562 563 printf("Floating point: 2.05\n"); 564 565 LOAD_FLOAT_DFORM_TEST(lfdp); 566 LOAD_FLOAT_XFORM_TEST(lfdpx); 567 LOAD_FLOAT_XFORM_TEST(lfiwax); 568 STORE_FLOAT_DFORM_TEST(stfdp); 569 STORE_FLOAT_XFORM_TEST(stfdpx); 570 571 return rc; 572 } 573 574 int test_alignment_handler_fp_206(void) 575 { 576 int rc = 0; 577 578 SKIP_IF(!can_open_cifile()); 579 SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06)); 580 581 printf("Floating point: 2.06\n"); 582 583 LOAD_FLOAT_XFORM_TEST(lfiwzx); 584 585 return rc; 586 } 587 588 589 int test_alignment_handler_fp_prefix(void) 590 { 591 int rc = 0; 592 593 SKIP_IF(!can_open_cifile()); 594 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 595 596 printf("Floating point: PREFIX\n"); 597 LOAD_FLOAT_DFORM_TEST(lfs); 598 LOAD_FLOAT_MLS_PREFIX_TEST(PLFS); 599 LOAD_FLOAT_MLS_PREFIX_TEST(PLFD); 600 STORE_FLOAT_MLS_PREFIX_TEST(PSTFS); 601 STORE_FLOAT_MLS_PREFIX_TEST(PSTFD); 602 return rc; 603 } 604 605 void usage(char *prog) 606 { 607 printf("Usage: %s [options] [path [offset]]\n", prog); 608 printf(" -d Enable debug error output\n"); 609 printf("\n"); 610 printf("This test requires a POWER8, POWER9 or POWER10 CPU "); 611 printf("and either a usable framebuffer at /dev/fb0 or "); 612 printf("the path to usable cache inhibited memory and optional "); 613 printf("offset to be provided\n"); 614 } 615 616 int main(int argc, char *argv[]) 617 { 618 619 struct sigaction sa; 620 int rc = 0; 621 int option = 0; 622 623 while ((option = getopt(argc, argv, "d")) != -1) { 624 switch (option) { 625 case 'd': 626 debug++; 627 break; 628 default: 629 usage(argv[0]); 630 exit(1); 631 } 632 } 633 argc -= optind; 634 argv += optind; 635 636 if (argc > 0) 637 cipath = argv[0]; 638 if (argc > 1) 639 cioffset = strtol(argv[1], 0, 0x10); 640 641 bufsize = getpagesize(); 642 643 sa.sa_sigaction = sighandler; 644 sigemptyset(&sa.sa_mask); 645 sa.sa_flags = SA_SIGINFO; 646 if (sigaction(SIGSEGV, &sa, NULL) == -1 647 || sigaction(SIGBUS, &sa, NULL) == -1 648 || sigaction(SIGILL, &sa, NULL) == -1) { 649 perror("sigaction"); 650 exit(1); 651 } 652 653 prefixes_enabled = have_hwcap2(PPC_FEATURE2_ARCH_3_1); 654 655 rc |= test_harness(test_alignment_handler_vsx_206, 656 "test_alignment_handler_vsx_206"); 657 rc |= test_harness(test_alignment_handler_vsx_207, 658 "test_alignment_handler_vsx_207"); 659 rc |= test_harness(test_alignment_handler_vsx_300, 660 "test_alignment_handler_vsx_300"); 661 rc |= test_harness(test_alignment_handler_vsx_prefix, 662 "test_alignment_handler_vsx_prefix"); 663 rc |= test_harness(test_alignment_handler_integer, 664 "test_alignment_handler_integer"); 665 rc |= test_harness(test_alignment_handler_integer_206, 666 "test_alignment_handler_integer_206"); 667 rc |= test_harness(test_alignment_handler_integer_prefix, 668 "test_alignment_handler_integer_prefix"); 669 rc |= test_harness(test_alignment_handler_vmx, 670 "test_alignment_handler_vmx"); 671 rc |= test_harness(test_alignment_handler_fp, 672 "test_alignment_handler_fp"); 673 rc |= test_harness(test_alignment_handler_fp_205, 674 "test_alignment_handler_fp_205"); 675 rc |= test_harness(test_alignment_handler_fp_206, 676 "test_alignment_handler_fp_206"); 677 rc |= test_harness(test_alignment_handler_fp_prefix, 678 "test_alignment_handler_fp_prefix"); 679 return rc; 680 } 681