Commit | Line | Data |
---|---|---|
6eda3a75 DM |
1 | .align 32 |
2 | .globl __flushw_user | |
3 | .type __flushw_user,#function | |
4 | __flushw_user: | |
5 | rdpr %otherwin, %g1 | |
6 | brz,pn %g1, 2f | |
7 | clr %g2 | |
8 | 1: save %sp, -128, %sp | |
9 | rdpr %otherwin, %g1 | |
10 | brnz,pt %g1, 1b | |
11 | add %g2, 1, %g2 | |
12 | 1: sub %g2, 1, %g2 | |
13 | brnz,pt %g2, 1b | |
14 | restore %g0, %g0, %g0 | |
15 | 2: retl | |
16 | nop | |
17 | .size __flushw_user,.-__flushw_user | |
18 | ||
19 | /* Flush %fp and %i7 to the stack for all register | |
20 | * windows active inside of the cpu. This allows | |
21 | * show_stack_trace() to avoid using an expensive | |
22 | * 'flushw'. | |
23 | */ | |
24 | .globl stack_trace_flush | |
25 | .type stack_trace_flush,#function | |
26 | stack_trace_flush: | |
27 | rdpr %pstate, %o0 | |
28 | wrpr %o0, PSTATE_IE, %pstate | |
29 | ||
30 | rdpr %cwp, %g1 | |
31 | rdpr %canrestore, %g2 | |
32 | sub %g1, 1, %g3 | |
33 | ||
34 | 1: brz,pn %g2, 2f | |
35 | sub %g2, 1, %g2 | |
36 | wrpr %g3, %cwp | |
37 | stx %fp, [%sp + STACK_BIAS + RW_V9_I6] | |
38 | stx %i7, [%sp + STACK_BIAS + RW_V9_I7] | |
39 | ba,pt %xcc, 1b | |
40 | sub %g3, 1, %g3 | |
41 | ||
42 | 2: wrpr %g1, %cwp | |
43 | wrpr %o0, %pstate | |
44 | ||
45 | retl | |
46 | nop | |
47 | .size stack_trace_flush,.-stack_trace_flush | |
48 | ||
954fbc89 DM |
49 | #ifdef CONFIG_PERF_EVENTS |
50 | .globl perf_arch_fetch_caller_regs | |
51 | .type perf_arch_fetch_caller_regs,#function | |
52 | perf_arch_fetch_caller_regs: | |
53 | /* We always read the %pstate into %o5 since we will use | |
54 | * that to construct a fake %tstate to store into the regs. | |
55 | */ | |
56 | rdpr %pstate, %o5 | |
57 | brz,pn %o2, 50f | |
58 | mov %o2, %g7 | |
59 | ||
60 | /* Turn off interrupts while we walk around the register | |
61 | * window by hand. | |
62 | */ | |
63 | wrpr %o5, PSTATE_IE, %pstate | |
64 | ||
65 | /* The %canrestore tells us how many register windows are | |
66 | * still live in the chip above us, past that we have to | |
67 | * walk the frame as saved on the stack. We stash away | |
68 | * the %cwp in %g1 so we can return back to the original | |
69 | * register window. | |
70 | */ | |
71 | rdpr %cwp, %g1 | |
72 | rdpr %canrestore, %g2 | |
73 | sub %g1, 1, %g3 | |
74 | ||
75 | /* We have the skip count in %g7, if it hits zero then | |
76 | * %fp/%i7 are the registers we need. Otherwise if our | |
77 | * %canrestore count maintained in %g2 hits zero we have | |
78 | * to start traversing the stack. | |
79 | */ | |
80 | 10: brz,pn %g2, 4f | |
81 | sub %g2, 1, %g2 | |
82 | wrpr %g3, %cwp | |
83 | subcc %g7, 1, %g7 | |
84 | bne,pt %xcc, 10b | |
85 | sub %g3, 1, %g3 | |
86 | ||
87 | /* We found the values we need in the cpu's register | |
88 | * windows. | |
89 | */ | |
90 | mov %fp, %g3 | |
91 | ba,pt %xcc, 3f | |
92 | mov %i7, %g2 | |
93 | ||
94 | 50: mov %fp, %g3 | |
95 | ba,pt %xcc, 2f | |
96 | mov %i7, %g2 | |
97 | ||
98 | /* We hit the end of the valid register windows in the | |
99 | * cpu, start traversing the stack frame. | |
100 | */ | |
101 | 4: mov %fp, %g3 | |
102 | ||
103 | 20: ldx [%g3 + STACK_BIAS + RW_V9_I7], %g2 | |
104 | subcc %g7, 1, %g7 | |
105 | bne,pn %xcc, 20b | |
106 | ldx [%g3 + STACK_BIAS + RW_V9_I6], %g3 | |
107 | ||
108 | /* Restore the current register window position and | |
109 | * re-enable interrupts. | |
110 | */ | |
111 | 3: wrpr %g1, %cwp | |
112 | wrpr %o5, %pstate | |
113 | ||
114 | 2: stx %g3, [%o0 + PT_V9_FP] | |
115 | sllx %o5, 8, %o5 | |
116 | stx %o5, [%o0 + PT_V9_TSTATE] | |
117 | stx %g2, [%o0 + PT_V9_TPC] | |
118 | add %g2, 4, %g2 | |
119 | retl | |
120 | stx %g2, [%o0 + PT_V9_TNPC] | |
121 | .size perf_arch_fetch_caller_regs,.-perf_arch_fetch_caller_regs | |
122 | #endif /* CONFIG_PERF_EVENTS */ | |
123 | ||
6eda3a75 DM |
124 | #ifdef CONFIG_SMP |
125 | .globl hard_smp_processor_id | |
126 | .type hard_smp_processor_id,#function | |
127 | hard_smp_processor_id: | |
128 | #endif | |
129 | .globl real_hard_smp_processor_id | |
130 | .type real_hard_smp_processor_id,#function | |
131 | real_hard_smp_processor_id: | |
132 | __GET_CPUID(%o0) | |
133 | retl | |
134 | nop | |
135 | #ifdef CONFIG_SMP | |
136 | .size hard_smp_processor_id,.-hard_smp_processor_id | |
137 | #endif | |
138 | .size real_hard_smp_processor_id,.-real_hard_smp_processor_id |