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