Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/powerpc: Add prefixed loads/stores to alignment_handler test

Extend the alignment handler selftest to exercise prefixed load store
instructions. Add tests for prefixed VSX, floating point and integer
instructions.

Skip prefix tests if ISA version does not support prefixed instructions.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
Tested-by: Alistair Popple <alistair@popple.id.au>
[mpe: Fixup PPC_FEATURE2_ARCH_3_1 naming as noted by Alistair]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200520021103.19798-2-jniethe5@gmail.com

authored by

Jordan Niethe and committed by
Michael Ellerman
620a6473 01bd2946

+172 -3
+90 -3
tools/testing/selftests/powerpc/alignment/alignment_handler.c
··· 58 58 #include <asm/cputable.h> 59 59 60 60 #include "utils.h" 61 + #include "instructions.h" 61 62 62 63 int bufsize; 63 64 int debug; ··· 97 96 } \ 98 97 rc |= do_test(#name, test_##name) 99 98 99 + #define TESTP(name, ld_op, st_op, ld_reg, st_reg) \ 100 + void test_##name(char *s, char *d) \ 101 + { \ 102 + asm volatile( \ 103 + ld_op(ld_reg, %0, 0, 0) \ 104 + st_op(st_reg, %1, 0, 0) \ 105 + :: "r"(s), "r"(d), "r"(0) \ 106 + : "memory", "vs0", "vs32", "r31"); \ 107 + } \ 108 + rc |= do_test(#name, test_##name) 109 + 100 110 #define LOAD_VSX_XFORM_TEST(op) TEST(op, op, stxvd2x, XFORM, 32, 32) 101 111 #define STORE_VSX_XFORM_TEST(op) TEST(op, lxvd2x, op, XFORM, 32, 32) 102 112 #define LOAD_VSX_DFORM_TEST(op) TEST(op, op, stxv, DFORM, 32, 32) ··· 127 115 #define LOAD_FLOAT_XFORM_TEST(op) TEST(op, op, stfdx, XFORM, 0, 0) 128 116 #define STORE_FLOAT_XFORM_TEST(op) TEST(op, lfdx, op, XFORM, 0, 0) 129 117 118 + #define LOAD_MLS_PREFIX_TEST(op) TESTP(op, op, PSTD, 31, 31) 119 + #define STORE_MLS_PREFIX_TEST(op) TESTP(op, PLD, op, 31, 31) 120 + 121 + #define LOAD_8LS_PREFIX_TEST(op) TESTP(op, op, PSTD, 31, 31) 122 + #define STORE_8LS_PREFIX_TEST(op) TESTP(op, PLD, op, 31, 31) 123 + 124 + #define LOAD_FLOAT_MLS_PREFIX_TEST(op) TESTP(op, op, PSTFD, 0, 0) 125 + #define STORE_FLOAT_MLS_PREFIX_TEST(op) TESTP(op, PLFD, op, 0, 0) 126 + 127 + #define LOAD_VSX_8LS_PREFIX_TEST(op, tail) TESTP(op, op, PSTXV ## tail, 0, 32) 128 + #define STORE_VSX_8LS_PREFIX_TEST(op, tail) TESTP(op, PLXV ## tail, op, 32, 0) 130 129 131 130 /* FIXME: Unimplemented tests: */ 132 131 // STORE_DFORM_TEST(stq) /* FIXME: need two registers for quad */ ··· 384 361 return rc; 385 362 } 386 363 364 + int test_alignment_handler_vsx_prefix(void) 365 + { 366 + int rc = 0; 367 + 368 + SKIP_IF(!can_open_cifile()); 369 + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 370 + 371 + printf("VSX: PREFIX\n"); 372 + LOAD_VSX_8LS_PREFIX_TEST(PLXSD, 0); 373 + LOAD_VSX_8LS_PREFIX_TEST(PLXSSP, 0); 374 + LOAD_VSX_8LS_PREFIX_TEST(PLXV0, 0); 375 + LOAD_VSX_8LS_PREFIX_TEST(PLXV1, 1); 376 + STORE_VSX_8LS_PREFIX_TEST(PSTXSD, 0); 377 + STORE_VSX_8LS_PREFIX_TEST(PSTXSSP, 0); 378 + STORE_VSX_8LS_PREFIX_TEST(PSTXV0, 0); 379 + STORE_VSX_8LS_PREFIX_TEST(PSTXV1, 1); 380 + return rc; 381 + } 382 + 387 383 int test_alignment_handler_integer(void) 388 384 { 389 385 int rc = 0; ··· 471 429 LOAD_XFORM_TEST(ldbrx); 472 430 STORE_XFORM_TEST(stdbrx); 473 431 432 + return rc; 433 + } 434 + 435 + int test_alignment_handler_integer_prefix(void) 436 + { 437 + int rc = 0; 438 + 439 + SKIP_IF(!can_open_cifile()); 440 + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 441 + 442 + printf("Integer: PREFIX\n"); 443 + LOAD_MLS_PREFIX_TEST(PLBZ); 444 + LOAD_MLS_PREFIX_TEST(PLHZ); 445 + LOAD_MLS_PREFIX_TEST(PLHA); 446 + LOAD_MLS_PREFIX_TEST(PLWZ); 447 + LOAD_8LS_PREFIX_TEST(PLWA); 448 + LOAD_8LS_PREFIX_TEST(PLD); 449 + STORE_MLS_PREFIX_TEST(PSTB); 450 + STORE_MLS_PREFIX_TEST(PSTH); 451 + STORE_MLS_PREFIX_TEST(PSTW); 452 + STORE_8LS_PREFIX_TEST(PSTD); 474 453 return rc; 475 454 } 476 455 ··· 583 520 return rc; 584 521 } 585 522 523 + 524 + int test_alignment_handler_fp_prefix(void) 525 + { 526 + int rc = 0; 527 + 528 + SKIP_IF(!can_open_cifile()); 529 + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); 530 + 531 + printf("Floating point: PREFIX\n"); 532 + LOAD_FLOAT_DFORM_TEST(lfs); 533 + LOAD_FLOAT_MLS_PREFIX_TEST(PLFS); 534 + LOAD_FLOAT_MLS_PREFIX_TEST(PLFD); 535 + STORE_FLOAT_MLS_PREFIX_TEST(PSTFS); 536 + STORE_FLOAT_MLS_PREFIX_TEST(PSTFD); 537 + return rc; 538 + } 539 + 586 540 void usage(char *prog) 587 541 { 588 542 printf("Usage: %s [options] [path [offset]]\n", prog); 589 543 printf(" -d Enable debug error output\n"); 590 544 printf("\n"); 591 - printf("This test requires a POWER8 or POWER9 CPU and either a "); 592 - printf("usable framebuffer at /dev/fb0 or the path to usable "); 593 - printf("cache-inhibited memory and optional offset to be provided\n"); 545 + printf("This test requires a POWER8, POWER9 or POWER10 CPU "); 546 + printf("and either a usable framebuffer at /dev/fb0 or "); 547 + printf("the path to usable cache inhibited memory and optional "); 548 + printf("offset to be provided\n"); 594 549 } 595 550 596 551 int main(int argc, char *argv[]) ··· 654 573 "test_alignment_handler_vsx_207"); 655 574 rc |= test_harness(test_alignment_handler_vsx_300, 656 575 "test_alignment_handler_vsx_300"); 576 + rc |= test_harness(test_alignment_handler_vsx_prefix, 577 + "test_alignment_handler_vsx_prefix"); 657 578 rc |= test_harness(test_alignment_handler_integer, 658 579 "test_alignment_handler_integer"); 659 580 rc |= test_harness(test_alignment_handler_integer_206, 660 581 "test_alignment_handler_integer_206"); 582 + rc |= test_harness(test_alignment_handler_integer_prefix, 583 + "test_alignment_handler_integer_prefix"); 661 584 rc |= test_harness(test_alignment_handler_vmx, 662 585 "test_alignment_handler_vmx"); 663 586 rc |= test_harness(test_alignment_handler_fp, ··· 670 585 "test_alignment_handler_fp_205"); 671 586 rc |= test_harness(test_alignment_handler_fp_206, 672 587 "test_alignment_handler_fp_206"); 588 + rc |= test_harness(test_alignment_handler_fp_prefix, 589 + "test_alignment_handler_fp_prefix"); 673 590 return rc; 674 591 }
+77
tools/testing/selftests/powerpc/include/instructions.h
··· 66 66 #define PPC_INST_PASTE __PASTE(0, 0, 0, 0) 67 67 #define PPC_INST_PASTE_LAST __PASTE(0, 0, 1, 1) 68 68 69 + /* This defines the prefixed load/store instructions */ 70 + #ifdef __ASSEMBLY__ 71 + # define stringify_in_c(...) __VA_ARGS__ 72 + #else 73 + # define __stringify_in_c(...) #__VA_ARGS__ 74 + # define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " " 75 + #endif 76 + 77 + #define __PPC_RA(a) (((a) & 0x1f) << 16) 78 + #define __PPC_RS(s) (((s) & 0x1f) << 21) 79 + #define __PPC_RT(t) __PPC_RS(t) 80 + #define __PPC_PREFIX_R(r) (((r) & 0x1) << 20) 81 + 82 + #define PPC_PREFIX_MLS 0x06000000 83 + #define PPC_PREFIX_8LS 0x04000000 84 + 85 + #define PPC_INST_LBZ 0x88000000 86 + #define PPC_INST_LHZ 0xa0000000 87 + #define PPC_INST_LHA 0xa8000000 88 + #define PPC_INST_LWZ 0x80000000 89 + #define PPC_INST_STB 0x98000000 90 + #define PPC_INST_STH 0xb0000000 91 + #define PPC_INST_STW 0x90000000 92 + #define PPC_INST_STD 0xf8000000 93 + #define PPC_INST_LFS 0xc0000000 94 + #define PPC_INST_LFD 0xc8000000 95 + #define PPC_INST_STFS 0xd0000000 96 + #define PPC_INST_STFD 0xd8000000 97 + 98 + #define PREFIX_MLS(instr, t, a, r, d) stringify_in_c(.balign 64, , 4;) \ 99 + stringify_in_c(.long PPC_PREFIX_MLS | \ 100 + __PPC_PREFIX_R(r) | \ 101 + (((d) >> 16) & 0x3ffff);) \ 102 + stringify_in_c(.long (instr) | \ 103 + __PPC_RT(t) | \ 104 + __PPC_RA(a) | \ 105 + ((d) & 0xffff);\n) 106 + 107 + #define PREFIX_8LS(instr, t, a, r, d) stringify_in_c(.balign 64, , 4;) \ 108 + stringify_in_c(.long PPC_PREFIX_8LS | \ 109 + __PPC_PREFIX_R(r) | \ 110 + (((d) >> 16) & 0x3ffff);) \ 111 + stringify_in_c(.long (instr) | \ 112 + __PPC_RT(t) | \ 113 + __PPC_RA(a) | \ 114 + ((d) & 0xffff);\n) 115 + 116 + /* Prefixed Integer Load/Store instructions */ 117 + #define PLBZ(t, a, r, d) PREFIX_MLS(PPC_INST_LBZ, t, a, r, d) 118 + #define PLHZ(t, a, r, d) PREFIX_MLS(PPC_INST_LHZ, t, a, r, d) 119 + #define PLHA(t, a, r, d) PREFIX_MLS(PPC_INST_LHA, t, a, r, d) 120 + #define PLWZ(t, a, r, d) PREFIX_MLS(PPC_INST_LWZ, t, a, r, d) 121 + #define PLWA(t, a, r, d) PREFIX_8LS(0xa4000000, t, a, r, d) 122 + #define PLD(t, a, r, d) PREFIX_8LS(0xe4000000, t, a, r, d) 123 + #define PLQ(t, a, r, d) PREFIX_8LS(0xe0000000, t, a, r, d) 124 + #define PSTB(s, a, r, d) PREFIX_MLS(PPC_INST_STB, s, a, r, d) 125 + #define PSTH(s, a, r, d) PREFIX_MLS(PPC_INST_STH, s, a, r, d) 126 + #define PSTW(s, a, r, d) PREFIX_MLS(PPC_INST_STW, s, a, r, d) 127 + #define PSTD(s, a, r, d) PREFIX_8LS(0xf4000000, s, a, r, d) 128 + #define PSTQ(s, a, r, d) PREFIX_8LS(0xf0000000, s, a, r, d) 129 + 130 + /* Prefixed Floating-Point Load/Store Instructions */ 131 + #define PLFS(frt, a, r, d) PREFIX_MLS(PPC_INST_LFS, frt, a, r, d) 132 + #define PLFD(frt, a, r, d) PREFIX_MLS(PPC_INST_LFD, frt, a, r, d) 133 + #define PSTFS(frs, a, r, d) PREFIX_MLS(PPC_INST_STFS, frs, a, r, d) 134 + #define PSTFD(frs, a, r, d) PREFIX_MLS(PPC_INST_STFD, frs, a, r, d) 135 + 136 + /* Prefixed VSX Load/Store Instructions */ 137 + #define PLXSD(vrt, a, r, d) PREFIX_8LS(0xa8000000, vrt, a, r, d) 138 + #define PLXSSP(vrt, a, r, d) PREFIX_8LS(0xac000000, vrt, a, r, d) 139 + #define PLXV0(s, a, r, d) PREFIX_8LS(0xc8000000, s, a, r, d) 140 + #define PLXV1(s, a, r, d) PREFIX_8LS(0xcc000000, s, a, r, d) 141 + #define PSTXSD(vrs, a, r, d) PREFIX_8LS(0xb8000000, vrs, a, r, d) 142 + #define PSTXSSP(vrs, a, r, d) PREFIX_8LS(0xbc000000, vrs, a, r, d) 143 + #define PSTXV0(s, a, r, d) PREFIX_8LS(0xd8000000, s, a, r, d) 144 + #define PSTXV1(s, a, r, d) PREFIX_8LS(0xdc000000, s, a, r, d) 145 + 69 146 #endif /* _SELFTESTS_POWERPC_INSTRUCTIONS_H */
+5
tools/testing/selftests/powerpc/include/utils.h
··· 101 101 #define PPC_FEATURE2_ARCH_3_00 0x00800000 102 102 #endif 103 103 104 + /* POWER10 feature */ 105 + #ifndef PPC_FEATURE2_ARCH_3_1 106 + #define PPC_FEATURE2_ARCH_3_1 0x00040000 107 + #endif 108 + 104 109 #if defined(__powerpc64__) 105 110 #define UCONTEXT_NIA(UC) (UC)->uc_mcontext.gp_regs[PT_NIP] 106 111 #define UCONTEXT_MSR(UC) (UC)->uc_mcontext.gp_regs[PT_MSR]