tm-resched-dscr.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* Test context switching to see if the DSCR SPR is correctly preserved
  2. * when within a transaction.
  3. *
  4. * Note: We assume that the DSCR has been left at the default value (0)
  5. * for all CPUs.
  6. *
  7. * Method:
  8. *
  9. * Set a value into the DSCR.
  10. *
  11. * Start a transaction, and suspend it (*).
  12. *
  13. * Hard loop checking to see if the transaction has become doomed.
  14. *
  15. * Now that we *may* have been preempted, record the DSCR and TEXASR SPRS.
  16. *
  17. * If the abort was because of a context switch, check the DSCR value.
  18. * Otherwise, try again.
  19. *
  20. * (*) If the transaction is not suspended we can't see the problem because
  21. * the transaction abort handler will restore the DSCR to it's checkpointed
  22. * value before we regain control.
  23. */
  24. #include <inttypes.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <assert.h>
  28. #include <asm/tm.h>
  29. #include "utils.h"
  30. #include "tm.h"
  31. #define TBEGIN ".long 0x7C00051D ;"
  32. #define TEND ".long 0x7C00055D ;"
  33. #define TCHECK ".long 0x7C00059C ;"
  34. #define TSUSPEND ".long 0x7C0005DD ;"
  35. #define TRESUME ".long 0x7C2005DD ;"
  36. #define SPRN_TEXASR 0x82
  37. #define SPRN_DSCR 0x03
  38. int test_body(void)
  39. {
  40. uint64_t rv, dscr1 = 1, dscr2, texasr;
  41. SKIP_IF(!have_htm());
  42. printf("Check DSCR TM context switch: ");
  43. fflush(stdout);
  44. for (;;) {
  45. rv = 1;
  46. asm __volatile__ (
  47. /* set a known value into the DSCR */
  48. "ld 3, %[dscr1];"
  49. "mtspr %[sprn_dscr], 3;"
  50. /* start and suspend a transaction */
  51. TBEGIN
  52. "beq 1f;"
  53. TSUSPEND
  54. /* hard loop until the transaction becomes doomed */
  55. "2: ;"
  56. TCHECK
  57. "bc 4, 0, 2b;"
  58. /* record DSCR and TEXASR */
  59. "mfspr 3, %[sprn_dscr];"
  60. "std 3, %[dscr2];"
  61. "mfspr 3, %[sprn_texasr];"
  62. "std 3, %[texasr];"
  63. TRESUME
  64. TEND
  65. "li %[rv], 0;"
  66. "1: ;"
  67. : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr)
  68. : [dscr1]"m"(dscr1)
  69. , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR)
  70. : "memory", "r3"
  71. );
  72. assert(rv); /* make sure the transaction aborted */
  73. if ((texasr >> 56) != TM_CAUSE_RESCHED) {
  74. putchar('.');
  75. fflush(stdout);
  76. continue;
  77. }
  78. if (dscr2 != dscr1) {
  79. printf(" FAIL\n");
  80. return 1;
  81. } else {
  82. printf(" OK\n");
  83. return 0;
  84. }
  85. }
  86. }
  87. int main(void)
  88. {
  89. return test_harness(test_body, "tm_resched_dscr");
  90. }