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