tm-resched-dscr.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. #define TBEGIN ".long 0x7C00051D ;"
  31. #define TEND ".long 0x7C00055D ;"
  32. #define TCHECK ".long 0x7C00059C ;"
  33. #define TSUSPEND ".long 0x7C0005DD ;"
  34. #define TRESUME ".long 0x7C2005DD ;"
  35. #define SPRN_TEXASR 0x82
  36. #define SPRN_DSCR 0x03
  37. int test_body(void)
  38. {
  39. uint64_t rv, dscr1 = 1, dscr2, texasr;
  40. printf("Check DSCR TM context switch: ");
  41. fflush(stdout);
  42. for (;;) {
  43. rv = 1;
  44. asm __volatile__ (
  45. /* set a known value into the DSCR */
  46. "ld 3, %[dscr1];"
  47. "mtspr %[sprn_dscr], 3;"
  48. /* start and suspend a transaction */
  49. TBEGIN
  50. "beq 1f;"
  51. TSUSPEND
  52. /* hard loop until the transaction becomes doomed */
  53. "2: ;"
  54. TCHECK
  55. "bc 4, 0, 2b;"
  56. /* record DSCR and TEXASR */
  57. "mfspr 3, %[sprn_dscr];"
  58. "std 3, %[dscr2];"
  59. "mfspr 3, %[sprn_texasr];"
  60. "std 3, %[texasr];"
  61. TRESUME
  62. TEND
  63. "li %[rv], 0;"
  64. "1: ;"
  65. : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr)
  66. : [dscr1]"m"(dscr1)
  67. , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR)
  68. : "memory", "r3"
  69. );
  70. assert(rv); /* make sure the transaction aborted */
  71. if ((texasr >> 56) != TM_CAUSE_RESCHED) {
  72. putchar('.');
  73. fflush(stdout);
  74. continue;
  75. }
  76. if (dscr2 != dscr1) {
  77. printf(" FAIL\n");
  78. return 1;
  79. } else {
  80. printf(" OK\n");
  81. return 0;
  82. }
  83. }
  84. }
  85. int main(void)
  86. {
  87. return test_harness(test_body, "tm_resched_dscr");
  88. }