1 .globl sparc64_of_client_interface, client_tba
5 * SAVE_WINDOW_STATE and RESTORE_WINDOW_STATE are used to ensure
6 * that the CPU window state is preserved across CIF calls. This is
7 * to workaround a *BSD restriction that window fill/spill traps must
8 * be minimised during trap table takeover, and likely emulates the
12 #define SAVE_WINDOW_STATE(type) \
13 setx client_window, %g6, %g1; \
17 stx %g7, [%g1 + 0x8]; \
18 rdpr %canrestore, %g7; \
19 stx %g7, [%g1 + 0x10]; \
20 rdpr %otherwin, %g7; \
21 stx %g7, [%g1 + 0x18]; \
23 stx %g7, [%g1 + 0x20]; \
24 rdpr %cleanwin, %g7; \
25 stx %g7, [%g1 + 0x28]; \
27 stx %o0, [%g1 + 0x30]; \
28 stx %o1, [%g1 + 0x38]; \
29 stx %o2, [%g1 + 0x40]; \
30 stx %o3, [%g1 + 0x48]; \
31 stx %o4, [%g1 + 0x50]; \
32 stx %o5, [%g1 + 0x58]; \
33 stx %o6, [%g1 + 0x60]; \
34 stx %o7, [%g1 + 0x68]; \
37 stx %g7, [%g1 + 0x70]; \
39 stx %g7, [%g1 + 0x78]; \
41 stx %g7, [%g1 + 0x80]; \
43 /* Now iterate through all of the windows saving all l and i registers */ \
46 /* Get the number of windows in %g6 */ \
51 save_cpu_window_##type: \
55 stx %l1, [%g5 + 0x8]; \
56 stx %l2, [%g5 + 0x10]; \
57 stx %l3, [%g5 + 0x18]; \
58 stx %l4, [%g5 + 0x20]; \
59 stx %l5, [%g5 + 0x28]; \
60 stx %l6, [%g5 + 0x30]; \
61 stx %l7, [%g5 + 0x38]; \
62 stx %i0, [%g5 + 0x40]; \
63 stx %i1, [%g5 + 0x48]; \
64 stx %i2, [%g5 + 0x50]; \
65 stx %i3, [%g5 + 0x58]; \
66 stx %i4, [%g5 + 0x60]; \
67 stx %i5, [%g5 + 0x68]; \
68 stx %i6, [%g5 + 0x70]; \
69 stx %i7, [%g5 + 0x78]; \
70 bne save_cpu_window_##type; \
73 /* For 8 windows with 16 registers to save in the window, memory required \
74 is 16*8*8 = 0x400 bytes */ \
76 /* Now we should be in window 0 so update the other window registers */ \
82 wrpr %g0, %cleanwin; \
83 wrpr %g0, %canrestore; \
87 #define RESTORE_WINDOW_STATE(type) \
88 setx client_window, %g6, %g1; \
90 /* Get the number of windows in %g6 */ \
95 /* Now iterate through all of the windows restoring all l and i registers */ \
98 restore_cpu_window_##type: \
102 ldx [%g5 + 0x8], %l1; \
103 ldx [%g5 + 0x10], %l2; \
104 ldx [%g5 + 0x18], %l3; \
105 ldx [%g5 + 0x20], %l4; \
106 ldx [%g5 + 0x28], %l5; \
107 ldx [%g5 + 0x30], %l6; \
108 ldx [%g5 + 0x38], %l7; \
109 ldx [%g5 + 0x40], %i0; \
110 ldx [%g5 + 0x48], %i1; \
111 ldx [%g5 + 0x50], %i2; \
112 ldx [%g5 + 0x58], %i3; \
113 ldx [%g5 + 0x60], %i4; \
114 ldx [%g5 + 0x68], %i5; \
115 ldx [%g5 + 0x70], %i6; \
116 ldx [%g5 + 0x78], %i7; \
117 bne restore_cpu_window_##type; \
118 add %g5, 0x80, %g5; \
120 /* Restore the window registers to their original value */ \
123 ldx [%g1 + 0x8], %g7; \
124 wrpr %g7, %cansave; \
125 ldx [%g1 + 0x10], %g7; \
126 wrpr %g7, %canrestore; \
127 ldx [%g1 + 0x18], %g7; \
128 wrpr %g7, %otherwin; \
129 ldx [%g1 + 0x20], %g7; \
131 ldx [%g1 + 0x28], %g7; \
132 wrpr %g7, %cleanwin; \
134 ldx [%g1 + 0x30], %o0; \
135 ldx [%g1 + 0x38], %o1; \
136 ldx [%g1 + 0x40], %o2; \
137 ldx [%g1 + 0x48], %o3; \
138 ldx [%g1 + 0x50], %o4; \
139 ldx [%g1 + 0x58], %o5; \
140 ldx [%g1 + 0x60], %o6; \
141 ldx [%g1 + 0x68], %o7; \
143 ldx [%g1 + 0x70], %g7; \
145 ldx [%g1 + 0x78], %g7; \
147 ldx [%g1 + 0x80], %g7; \
167 .register %g2, #scratch
168 .register %g3, #scratch
169 .register %g6, #scratch
170 .register %g7, #scratch
172 make some more space on stack since linux kernel only provides 128 bytes
173 without memory to spill registers (used by gcc in -O0 mode)
176 sparc64_of_client_interface:
178 /* Save globals on callers stack */
181 stx %g1, [%sp + 2047 + 0]
182 stx %g2, [%sp + 2047 + 8]
183 stx %g3, [%sp + 2047 + 16]
184 stx %g4, [%sp + 2047 + 24]
185 stx %g5, [%sp + 2047 + 32]
186 stx %g6, [%sp + 2047 + 40]
187 stx %g7, [%sp + 2047 + 48]
189 /* Save client trap table */
190 setx client_tba, %g6, %g7
194 /* Save existing stack */
195 setx client_stack, %g6, %g7
199 SAVE_WINDOW_STATE(cif)
201 /* Move to OpenBIOS stack */
202 setx openbios_stack - 2047 - 192, %g6, %g7
205 /* Call client inteface */
206 call of_client_interface
207 ldx [%g1 + 0x30], %o0
209 setx client_window, %g6, %g1
210 stx %o0, [%g1 + 0x30]
212 /* Restore windows */
213 RESTORE_WINDOW_STATE(cif)
216 setx client_stack, %g6, %g7
219 /* Restore client trap table */
220 setx client_tba, %g6, %g7
224 /* Restore globals */
225 ldx [%sp + 2047 + 0], %g1
226 ldx [%sp + 2047 + 8], %g2
227 ldx [%sp + 2047 + 16], %g3
228 ldx [%sp + 2047 + 24], %g4
229 ldx [%sp + 2047 + 32], %g5
230 ldx [%sp + 2047 + 40], %g6
231 ldx [%sp + 2047 + 48], %g7