Commit | Line | Data |
---|---|---|
96d01610 S |
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 | ||
25 | #include <inttypes.h> | |
26 | #include <stdio.h> | |
27 | #include <stdlib.h> | |
28 | #include <assert.h> | |
29 | #include <asm/tm.h> | |
30 | ||
aa83f3d8 | 31 | #include "utils.h" |
b319ee84 | 32 | #include "tm.h" |
aa83f3d8 | 33 | |
96d01610 S |
34 | #define SPRN_DSCR 0x03 |
35 | ||
aa83f3d8 ME |
36 | int test_body(void) |
37 | { | |
96d01610 S |
38 | uint64_t rv, dscr1 = 1, dscr2, texasr; |
39 | ||
b319ee84 ME |
40 | SKIP_IF(!have_htm()); |
41 | ||
96d01610 S |
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 | ||
51 | /* start and suspend a transaction */ | |
da3ddc3b | 52 | "tbegin.;" |
96d01610 | 53 | "beq 1f;" |
da3ddc3b | 54 | "tsuspend.;" |
96d01610 S |
55 | |
56 | /* hard loop until the transaction becomes doomed */ | |
57 | "2: ;" | |
da3ddc3b | 58 | "tcheck 0;" |
96d01610 S |
59 | "bc 4, 0, 2b;" |
60 | ||
61 | /* record DSCR and TEXASR */ | |
62 | "mfspr 3, %[sprn_dscr];" | |
63 | "std 3, %[dscr2];" | |
64 | "mfspr 3, %[sprn_texasr];" | |
65 | "std 3, %[texasr];" | |
66 | ||
da3ddc3b RG |
67 | "tresume.;" |
68 | "tend.;" | |
96d01610 S |
69 | "li %[rv], 0;" |
70 | "1: ;" | |
71 | : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr) | |
72 | : [dscr1]"m"(dscr1) | |
73 | , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR) | |
74 | : "memory", "r3" | |
75 | ); | |
76 | assert(rv); /* make sure the transaction aborted */ | |
77 | if ((texasr >> 56) != TM_CAUSE_RESCHED) { | |
78 | putchar('.'); | |
79 | fflush(stdout); | |
80 | continue; | |
81 | } | |
82 | if (dscr2 != dscr1) { | |
83 | printf(" FAIL\n"); | |
aa83f3d8 | 84 | return 1; |
96d01610 S |
85 | } else { |
86 | printf(" OK\n"); | |
aa83f3d8 | 87 | return 0; |
96d01610 S |
88 | } |
89 | } | |
90 | } | |
aa83f3d8 ME |
91 | |
92 | int main(void) | |
93 | { | |
94 | return test_harness(test_body, "tm_resched_dscr"); | |
95 | } |