1 | /* |
---|
2 | * Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com> |
---|
3 | * Parts taken from FreeBSD. |
---|
4 | * |
---|
5 | *************************************************************************** |
---|
6 | * |
---|
7 | * Redistribution and use in source and binary forms, with or without |
---|
8 | * modification, are permitted provided that the following conditions |
---|
9 | * are met: |
---|
10 | * 1. Redistributions of source code must retain the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer. |
---|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
13 | * notice, this list of conditions and the following disclaimer in the |
---|
14 | * documentation and/or other materials provided with the distribution. |
---|
15 | * |
---|
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
---|
17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
---|
20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
26 | * SUCH DAMAGE. |
---|
27 | * |
---|
28 | */ |
---|
29 | |
---|
30 | |
---|
31 | #include "asm.h" |
---|
32 | #include "page.h" |
---|
33 | #include "ia64_cpu.h" |
---|
34 | #include "ia64_fpu.h" |
---|
35 | #include "offsets.h" |
---|
36 | #include "xen/xen.h" |
---|
37 | |
---|
38 | |
---|
39 | /* |
---|
40 | * ia64_change_mode: change mode to/from physical mode |
---|
41 | * |
---|
42 | * Arguments: |
---|
43 | * r14 psr for desired mode |
---|
44 | * |
---|
45 | * Modifies: |
---|
46 | * r15-r20 scratch |
---|
47 | * ar.bsp translated to new mode |
---|
48 | * sp translated to new mode |
---|
49 | * iip translated to new mode |
---|
50 | */ |
---|
51 | ENTRY(ia64_change_mode) |
---|
52 | rsm psr.i | psr.ic |
---|
53 | mov r19=ar.rsc // save rsc while we change mode |
---|
54 | tbit.nz p8,p9=r14,17 // Uses psr.dt-physical or virtual ? |
---|
55 | // p8 == true: switch to virtual |
---|
56 | // p9 == true: switch to physical |
---|
57 | ;; |
---|
58 | mov ar.rsc=IA64_RSE_LAZY // turn off RSE |
---|
59 | mov r16=rp |
---|
60 | ;; |
---|
61 | flushrs // clean the rse |
---|
62 | srlz.i |
---|
63 | ;; |
---|
64 | 1: mov r15=ip |
---|
65 | mov r17=ar.bsp |
---|
66 | mov r18=ar.rnat |
---|
67 | ;; |
---|
68 | add r15=2f-1b,r15 // address to rfi to |
---|
69 | /* !!! must be the same like in minios-ia64.lds */ |
---|
70 | (p8) movl r20=(KERNEL_START - (1<<KERNEL_PHYS_START_SHIFT)) |
---|
71 | ;; |
---|
72 | // (p8): switch to virtual |
---|
73 | // (p9): switch to physical |
---|
74 | |
---|
75 | // from virtual to physical |
---|
76 | (p9) tpa r15=r15 // ip |
---|
77 | (p9) tpa r16=r16 // rp |
---|
78 | (p9) tpa r17=r17 // ar.bsp |
---|
79 | (p9) tpa sp=sp // sp |
---|
80 | ;; /* Needed only for assembler violate ... warnings. */ |
---|
81 | // from physical to virtual |
---|
82 | (p8) add r15=r20,r15 // ip |
---|
83 | (p8) add r16=r20,r16 // rp |
---|
84 | (p8) add r17=r20,r17 // ar.bsp |
---|
85 | (p8) add sp=r20,sp // sp |
---|
86 | ;; |
---|
87 | mov ar.bspstore=r17 |
---|
88 | mov rp=r16 |
---|
89 | ;; |
---|
90 | mov ar.rnat=r18 |
---|
91 | mov cr.iip=r15 |
---|
92 | mov cr.ipsr=r14 // psr for new mode |
---|
93 | mov cr.ifs=r0 |
---|
94 | ;; |
---|
95 | rfi |
---|
96 | ;; |
---|
97 | 2: mov ar.rsc=r19 // restore ar.rsc |
---|
98 | ;; |
---|
99 | br.ret.sptk.few rp // now in new mode |
---|
100 | END(ia64_change_mode) |
---|
101 | |
---|
102 | /* |
---|
103 | * ia64_physical_mode: change mode to physical mode |
---|
104 | * |
---|
105 | * Return: |
---|
106 | * ret0 psr to restore |
---|
107 | * |
---|
108 | * Modifies: |
---|
109 | * r15-r18 scratch |
---|
110 | * ar.bsp tranlated to physical mode |
---|
111 | * psr.i cleared |
---|
112 | */ |
---|
113 | ENTRY(ia64_physical_mode) |
---|
114 | mov r14=psr |
---|
115 | movl r15=(IA64_PSR_I|IA64_PSR_IT|IA64_PSR_DT| \ |
---|
116 | IA64_PSR_RT|IA64_PSR_DFL|IA64_PSR_DFH) |
---|
117 | ;; |
---|
118 | mov ret0=r14 |
---|
119 | movl r16=IA64_PSR_BN |
---|
120 | ;; |
---|
121 | andcm r14=r14,r15 // clear various xT bits |
---|
122 | ;; |
---|
123 | or r14=r14,r16 // make sure BN=1 |
---|
124 | or ret0=ret0,r16 // make sure BN=1 |
---|
125 | ;; |
---|
126 | br.cond.sptk.many ia64_change_mode |
---|
127 | END(ia64_physical_mode) |
---|
128 | |
---|
129 | /* |
---|
130 | * ia64_call_efi_physical: call an EFI procedure in physical mode |
---|
131 | * |
---|
132 | * Arguments: |
---|
133 | * in0 Address of EFI procedure descriptor |
---|
134 | * in1-in5 Arguments to EFI procedure |
---|
135 | * |
---|
136 | * Return: |
---|
137 | * ret0-ret3 return values from EFI |
---|
138 | * |
---|
139 | */ |
---|
140 | ENTRY(ia64_call_efi_physical) |
---|
141 | .prologue |
---|
142 | .regstk 6,4,5,0 |
---|
143 | .save ar.pfs,loc0 |
---|
144 | alloc loc0=ar.pfs,6,4,5,0 |
---|
145 | ;; |
---|
146 | .save rp,loc1 |
---|
147 | mov loc1=rp |
---|
148 | ;; |
---|
149 | .body |
---|
150 | br.call.sptk.many rp=ia64_physical_mode |
---|
151 | ;; |
---|
152 | |
---|
153 | mov loc2=r8 // psr to restore mode |
---|
154 | mov loc3=gp // save kernel gp |
---|
155 | ld8 r14=[in0],8 // function address |
---|
156 | ;; |
---|
157 | ld8 gp=[in0] // function gp value |
---|
158 | #if defined(BIG_ENDIAN) |
---|
159 | mux1 r14=r14,@rev // swap because mini-os is in BE |
---|
160 | mov ar.rsc=3 |
---|
161 | ;; |
---|
162 | #endif |
---|
163 | mov out0=in1 |
---|
164 | mov out1=in2 |
---|
165 | mov out2=in3 |
---|
166 | mov out3=in4 |
---|
167 | mov out4=in5 |
---|
168 | mov b6=r14 |
---|
169 | ;; |
---|
170 | #if defined(BIG_ENDIAN) |
---|
171 | mux1 gp=gp,@rev // swap because mini-os is in BE |
---|
172 | rum IA64_PSR_BE |
---|
173 | ;; |
---|
174 | #endif |
---|
175 | |
---|
176 | br.call.sptk.many rp=b6 // call EFI procedure |
---|
177 | |
---|
178 | #if defined(BIG_ENDIAN) |
---|
179 | ;; |
---|
180 | sum IA64_PSR_BE |
---|
181 | mov ar.rsc=IA64_RSE_EAGER |
---|
182 | #endif |
---|
183 | mov gp=loc3 // restore kernel gp |
---|
184 | mov r14=loc2 // psr to restore mode |
---|
185 | ;; |
---|
186 | br.call.sptk.many rp=ia64_change_mode |
---|
187 | ;; |
---|
188 | mov rp=loc1 |
---|
189 | mov ar.pfs=loc0 |
---|
190 | ;; |
---|
191 | br.ret.sptk.many rp |
---|
192 | END(ia64_call_efi_physical) |
---|
193 | |
---|
194 | |
---|
195 | /* |
---|
196 | * struct ia64_pal_result ia64_call_pal_static(uint64_t proc, |
---|
197 | * uint64_t arg1, uint64_t arg2, uint64_t arg3) |
---|
198 | */ |
---|
199 | ENTRY(ia64_call_pal_static) |
---|
200 | |
---|
201 | .regstk 4,5,0,0 |
---|
202 | palret = loc0 |
---|
203 | entry = loc1 |
---|
204 | rpsave = loc2 |
---|
205 | pfssave = loc3 |
---|
206 | psrsave = loc4 |
---|
207 | |
---|
208 | alloc pfssave=ar.pfs,4,5,0,0 |
---|
209 | ;; |
---|
210 | mov rpsave=rp |
---|
211 | |
---|
212 | movl entry=@gprel(ia64_pal_entry) |
---|
213 | 1: mov palret=ip // for return address |
---|
214 | ;; |
---|
215 | add entry=entry,gp |
---|
216 | mov psrsave=psr |
---|
217 | mov r28=in0 // procedure number |
---|
218 | ;; |
---|
219 | ld8 entry=[entry] // read entry point |
---|
220 | mov r29=in1 // copy arguments |
---|
221 | mov r30=in2 |
---|
222 | mov r31=in3 |
---|
223 | ;; |
---|
224 | mov b6=entry |
---|
225 | add palret=2f-1b,palret // calculate return address |
---|
226 | ;; |
---|
227 | mov b0=palret |
---|
228 | rsm psr.i // disable interrupts |
---|
229 | ;; |
---|
230 | #if defined(BIG_ENDIAN) |
---|
231 | rum IA64_PSR_BE // set psr.be==0 |
---|
232 | ;; |
---|
233 | #endif |
---|
234 | br.cond.sptk b6 // call into firmware |
---|
235 | ;; |
---|
236 | #if defined(BIG_ENDIAN) |
---|
237 | sum IA64_PSR_BE // set psr.be==1 |
---|
238 | ;; |
---|
239 | #endif |
---|
240 | ssm psr.i // enable interrupts |
---|
241 | ;; |
---|
242 | 2: mov psr.l=psrsave |
---|
243 | mov rp=rpsave |
---|
244 | mov ar.pfs=pfssave |
---|
245 | ;; |
---|
246 | srlz.d |
---|
247 | br.ret.sptk rp |
---|
248 | |
---|
249 | END(ia64_call_pal_static) |
---|
250 | |
---|
251 | /* |
---|
252 | * Call a efi function. |
---|
253 | * in0: func descriptor |
---|
254 | * in1: param1 |
---|
255 | * ... |
---|
256 | * in5: param5 |
---|
257 | */ |
---|
258 | ENTRY(ia64_call_efi_func) |
---|
259 | alloc loc0=ar.pfs,6,3,5,0 |
---|
260 | |
---|
261 | mov loc1=gp |
---|
262 | mov loc2=rp |
---|
263 | |
---|
264 | mov out0=in1 |
---|
265 | mov out1=in2 |
---|
266 | mov out2=in3 |
---|
267 | mov out3=in4 |
---|
268 | mov out4=in5 |
---|
269 | |
---|
270 | ld8 r14=[in0],8 // get function address |
---|
271 | ;; |
---|
272 | ld8 gp=[in0] // function gp value |
---|
273 | ;; |
---|
274 | #if defined(BIG_ENDIAN) |
---|
275 | mux1 r14=r14,@rev // swap if mini-os is in BE |
---|
276 | mux1 gp=gp,@rev // swap if mini-os is in BE |
---|
277 | #endif |
---|
278 | ;; |
---|
279 | mov b6=r14 |
---|
280 | |
---|
281 | #if defined(BIG_ENDIAN) |
---|
282 | rum IA64_PSR_BE |
---|
283 | ;; |
---|
284 | #endif |
---|
285 | |
---|
286 | br.call.sptk.many rp=b6 // call EFI procedure |
---|
287 | |
---|
288 | #if defined(BIG_ENDIAN) |
---|
289 | sum IA64_PSR_BE |
---|
290 | ;; |
---|
291 | #endif |
---|
292 | |
---|
293 | mov ar.pfs=loc0 |
---|
294 | mov gp=loc1 |
---|
295 | mov rp=loc2 |
---|
296 | br.ret.sptk rp |
---|
297 | |
---|
298 | END(ia64_call_efi_func) |
---|
299 | |
---|
300 | |
---|
301 | /* Restore the context from the thread context. |
---|
302 | */ |
---|
303 | ENTRY(restore_context) |
---|
304 | { .mmi |
---|
305 | invala |
---|
306 | mov ar.rsc=IA64_RSE_LAZY |
---|
307 | add r29=SW_SP,in0 |
---|
308 | } |
---|
309 | add r30=SW_RP,in0 |
---|
310 | add r31=SW_PR,in0 |
---|
311 | ;; |
---|
312 | ld8 r12=[r29],SW_LC-SW_SP // load sp |
---|
313 | ld8 r16=[r30],SW_BSP-SW_RP // load rp |
---|
314 | ;; |
---|
315 | ld8 r17=[r31],SW_RNAT-SW_PR // load pr |
---|
316 | ld8 r18=[r30],SW_PFS-SW_BSP // load bsp |
---|
317 | mov rp=r16 |
---|
318 | ;; |
---|
319 | ld8 r16=[r31],SW_R4-SW_RNAT // load rnat |
---|
320 | mov pr=r17,-1 // set pr |
---|
321 | mov ar.bspstore=r18 |
---|
322 | ;; |
---|
323 | ld8 r18=[r30],SW_UNATA-SW_PFS // load pfs |
---|
324 | ld8 r17=[r29],SW_UNATB-SW_LC // load lc |
---|
325 | mov ar.rnat=r16 |
---|
326 | ;; |
---|
327 | ld8 r16=[r30],SW_R5-SW_UNATA // load unat_a |
---|
328 | mov ar.pfs=r18 |
---|
329 | mov ar.lc=r17 |
---|
330 | ;; |
---|
331 | ld8.fill r4=[r31],SW_R6-SW_R4 // load r4 |
---|
332 | mov ar.unat=r16 |
---|
333 | ;; |
---|
334 | ld8.fill r5=[r30],SW_R7-SW_R5 // load r5 |
---|
335 | ld8 r16=[r29],SW_B3-SW_UNATB // load unat_b |
---|
336 | mov ar.rsc=IA64_RSE_EAGER |
---|
337 | ;; |
---|
338 | ld8.fill r6=[r31],SW_B1-SW_R6 // load r6 |
---|
339 | ld8.fill r7=[r30],SW_B2-SW_R7 // load r7 |
---|
340 | ;; |
---|
341 | ld8 r17=[r31],SW_B4-SW_B1 // load b1 |
---|
342 | ld8 r18=[r30],SW_B5-SW_B2 // load b2 |
---|
343 | mov ar.unat=r16 // unat_b |
---|
344 | ;; |
---|
345 | ld8 r16=[r29],SW_F2-SW_B3 // load b3 |
---|
346 | mov b1=r17 |
---|
347 | mov b2=r18 |
---|
348 | ;; |
---|
349 | ld8 r17=[r31],SW_F3-SW_B4 // load b4 |
---|
350 | ld8 r18=[r30],SW_F4-SW_B5 // load b5 |
---|
351 | mov b3=r16 |
---|
352 | ;; |
---|
353 | ldf.fill f2=[r29] // load f2 |
---|
354 | mov b4=r17 |
---|
355 | mov b5=r18 |
---|
356 | ;; |
---|
357 | ldf.fill f3=[r31],SW_F5-SW_F3 // load f3 |
---|
358 | ldf.fill f4=[r30],SW_F4-SW_F2 // load f4 |
---|
359 | ;; |
---|
360 | ldf.fill f5=[r31],SW_F5-SW_F3 // load f5 |
---|
361 | ldf.fill f16=[r30],SW_F4-SW_F2 // load f16 |
---|
362 | ;; |
---|
363 | ldf.fill f17=[r31],SW_F5-SW_F3 // load f17 |
---|
364 | ldf.fill f18=[r30],SW_F4-SW_F2 // load f18 |
---|
365 | ;; |
---|
366 | ldf.fill f19=[r31],SW_F5-SW_F3 // load f19 |
---|
367 | ldf.fill f20=[r30],SW_F4-SW_F2 // load f20 |
---|
368 | ;; |
---|
369 | ldf.fill f21=[r31],SW_F5-SW_F3 // load f21 |
---|
370 | ldf.fill f22=[r30],SW_F4-SW_F2 // load f22 |
---|
371 | ;; |
---|
372 | ldf.fill f23=[r31],SW_F5-SW_F3 // load f23 |
---|
373 | ldf.fill f24=[r30],SW_F4-SW_F2 // load f24 |
---|
374 | ;; |
---|
375 | ldf.fill f25=[r31],SW_F5-SW_F3 // load f25 |
---|
376 | ldf.fill f26=[r30],SW_F4-SW_F2 // load f26 |
---|
377 | ;; |
---|
378 | ldf.fill f27=[r31],SW_F5-SW_F3 // load f27 |
---|
379 | ldf.fill f28=[r30],SW_F4-SW_F2 // load f28 |
---|
380 | ;; |
---|
381 | ldf.fill f29=[r31],SW_F5-SW_F3 // load f29 |
---|
382 | ldf.fill f30=[r30],SW_F4-SW_F2 // load f30 |
---|
383 | ;; |
---|
384 | ldf.fill f31=[r30],SW_F4-SW_F2 // load f31 |
---|
385 | add r8=1,r0 |
---|
386 | br.ret.sptk rp |
---|
387 | ;; |
---|
388 | END(restore_context) |
---|
389 | |
---|
390 | /* |
---|
391 | * void switch_context(struct thread* old, struct thread* new) |
---|
392 | */ |
---|
393 | ENTRY(switch_context) |
---|
394 | |
---|
395 | mov ar.rsc=IA64_RSE_LAZY |
---|
396 | mov r16=ar.unat |
---|
397 | add r31=SW_UNATB,in0 |
---|
398 | add r30=SW_SP,in0 |
---|
399 | ;; |
---|
400 | { .mmi |
---|
401 | flushrs |
---|
402 | st8 [r30]=sp,SW_RP-SW_SP // sp |
---|
403 | mov r17=rp |
---|
404 | ;; |
---|
405 | } |
---|
406 | st8 [r31]=r16,SW_PR-SW_UNATB // unat (before) |
---|
407 | st8 [r30]=r17,SW_BSP-SW_RP // rp |
---|
408 | mov r16=pr |
---|
409 | ;; |
---|
410 | st8 [r31]=r16,SW_PFS-SW_PR // pr |
---|
411 | mov r17=ar.bsp |
---|
412 | mov r16=ar.pfs |
---|
413 | ;; |
---|
414 | st8 [r31]=r16,SW_RNAT-SW_PFS // save pfs |
---|
415 | st8 [r30]=r17,SW_R4-SW_BSP // save bsp |
---|
416 | mov r16=ar.rnat |
---|
417 | ;; |
---|
418 | st8 [r31]=r16,SW_R5-SW_RNAT // save rnat |
---|
419 | mov ar.rsc=IA64_RSE_EAGER |
---|
420 | ;; |
---|
421 | { .mmi |
---|
422 | .mem.offset 8,0 |
---|
423 | st8.spill [r30]=r4,SW_R6-SW_R4 // r4 |
---|
424 | .mem.offset 16,0 |
---|
425 | st8.spill [r31]=r5,SW_R7-SW_R5 // r5 |
---|
426 | mov r16=b1 |
---|
427 | ;; |
---|
428 | } |
---|
429 | { .mmi |
---|
430 | .mem.offset 8,0 |
---|
431 | st8.spill [r30]=r4,SW_B1-SW_R6 // r6 |
---|
432 | .mem.offset 16,0 |
---|
433 | st8.spill [r31]=r5,SW_B2-SW_R7 // r7 |
---|
434 | mov r17=b2 |
---|
435 | ;; |
---|
436 | } |
---|
437 | st8 [r30]=r16,SW_UNATA-SW_B1 // b1 |
---|
438 | st8 [r31]=r17,SW_B3-SW_B2 // b2 |
---|
439 | mov r18=ar.unat |
---|
440 | mov r19=b3 |
---|
441 | mov r20=b4 |
---|
442 | mov r21=b5 |
---|
443 | ;; |
---|
444 | st8 [r30]=r18,SW_B4-SW_UNATA // unat (after) |
---|
445 | st8 [r31]=r19,SW_B5-SW_B3 // b3 |
---|
446 | ;; |
---|
447 | st8 [r30]=r20,SW_LC-SW_B4 // b4 |
---|
448 | st8 [r31]=r21,SW_F2-SW_B5 // b5 |
---|
449 | mov r17=ar.lc |
---|
450 | ;; |
---|
451 | st8 [r30]=r17,SW_F3-SW_LC // ar.lc |
---|
452 | stf.spill [r31]=f2,SW_F4-SW_F2 |
---|
453 | ;; |
---|
454 | stf.spill [r30]=f3,SW_F5-SW_F3 |
---|
455 | stf.spill [r31]=f4,SW_F4-SW_F2 |
---|
456 | ;; |
---|
457 | stf.spill [r30]=f5,SW_F5-SW_F3 |
---|
458 | stf.spill [r31]=f16,SW_F4-SW_F2 |
---|
459 | ;; |
---|
460 | stf.spill [r30]=f17,SW_F5-SW_F3 |
---|
461 | stf.spill [r31]=f18,SW_F4-SW_F2 |
---|
462 | ;; |
---|
463 | stf.spill [r30]=f19,SW_F5-SW_F3 |
---|
464 | stf.spill [r31]=f20,SW_F4-SW_F2 |
---|
465 | ;; |
---|
466 | stf.spill [r30]=f21,SW_F5-SW_F3 |
---|
467 | stf.spill [r31]=f22,SW_F4-SW_F2 |
---|
468 | ;; |
---|
469 | stf.spill [r30]=f23,SW_F5-SW_F3 |
---|
470 | stf.spill [r31]=f24,SW_F4-SW_F2 |
---|
471 | ;; |
---|
472 | stf.spill [r30]=f25,SW_F5-SW_F3 |
---|
473 | stf.spill [r31]=f26,SW_F4-SW_F2 |
---|
474 | ;; |
---|
475 | stf.spill [r30]=f27,SW_F5-SW_F3 |
---|
476 | stf.spill [r31]=f28,SW_F4-SW_F2 |
---|
477 | ;; |
---|
478 | stf.spill [r30]=f29,SW_F4-SW_F2 |
---|
479 | stf.spill [r31]=f30 |
---|
480 | ;; |
---|
481 | stf.spill [r30]=f31 |
---|
482 | add r8=0,r0 |
---|
483 | mf |
---|
484 | // br.ret.sptk rp |
---|
485 | |
---|
486 | { .mfb |
---|
487 | mov r32=r33 |
---|
488 | nop 0 |
---|
489 | br.sptk restore_context |
---|
490 | ;; |
---|
491 | } |
---|
492 | |
---|
493 | END(switch_context) |
---|
494 | |
---|
495 | /* |
---|
496 | * The function is used to start a new thread. |
---|
497 | */ |
---|
498 | ENTRY(thread_starter) |
---|
499 | |
---|
500 | .prologue |
---|
501 | .save ar.pfs,loc0 |
---|
502 | alloc loc0=ar.pfs,0,1,1,0 |
---|
503 | ;; |
---|
504 | .body |
---|
505 | ;; |
---|
506 | mov b7=r4 // the function pointer |
---|
507 | mov out0=r6 // the argument |
---|
508 | ;; |
---|
509 | br.call.sptk.many rp=b7 // Call the thread function |
---|
510 | ;; |
---|
511 | br.call.sptk.many rp=exit_thread // call exit_thread |
---|
512 | ;; |
---|
513 | END(thread_starter) |
---|
514 | |
---|
515 | ENTRY(__hypercall) |
---|
516 | mov r2=r37 |
---|
517 | break 0x1000 |
---|
518 | br.ret.sptk.many b0 |
---|
519 | ;; |
---|
520 | END(__hypercall) |
---|
521 | |
---|
522 | /* |
---|
523 | * Stub for suspend. |
---|
524 | * Just force the stacked registers to be written in memory. |
---|
525 | */ |
---|
526 | ENTRY(xencomm_arch_hypercall_suspend) |
---|
527 | ;; |
---|
528 | alloc r20=ar.pfs,0,0,6,0 |
---|
529 | mov r2=__HYPERVISOR_sched_op |
---|
530 | ;; |
---|
531 | /* We don't want to deal with RSE. */ |
---|
532 | flushrs |
---|
533 | mov r33=r32 |
---|
534 | mov r32=2 // SCHEDOP_shutdown |
---|
535 | ;; |
---|
536 | break 0x1000 |
---|
537 | ;; |
---|
538 | br.ret.sptk.many b0 |
---|
539 | END(xencomm_arch_hypercall_suspend) |
---|
540 | |
---|