debuggers.hg

view extras/mini-os/arch/ia64/fw.S @ 0:7d21f7218375

Exact replica of unstable on 051908 + README-this
author Mukesh Rathor
date Mon May 19 15:34:57 2008 -0700 (2008-05-19)
parents
children 46f8fc57b1a4
line source
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 */
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"
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
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)
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)
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 ;;
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
176 br.call.sptk.many rp=b6 // call EFI procedure
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)
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)
201 .regstk 4,5,0,0
202 palret = loc0
203 entry = loc1
204 rpsave = loc2
205 pfssave = loc3
206 psrsave = loc4
208 alloc pfssave=ar.pfs,4,5,0,0
209 ;;
210 mov rpsave=rp
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
249 END(ia64_call_pal_static)
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
261 mov loc1=gp
262 mov loc2=rp
264 mov out0=in1
265 mov out1=in2
266 mov out2=in3
267 mov out3=in4
268 mov out4=in5
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
281 #if defined(BIG_ENDIAN)
282 rum IA64_PSR_BE
283 ;;
284 #endif
286 br.call.sptk.many rp=b6 // call EFI procedure
288 #if defined(BIG_ENDIAN)
289 sum IA64_PSR_BE
290 ;;
291 #endif
293 mov ar.pfs=loc0
294 mov gp=loc1
295 mov rp=loc2
296 br.ret.sptk rp
298 END(ia64_call_efi_func)
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)
390 /*
391 * void switch_context(struct thread* old, struct thread* new)
392 */
393 ENTRY(switch_context)
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
486 { .mfb
487 mov r32=r33
488 nop 0
489 br.sptk restore_context
490 ;;
491 }
493 END(switch_context)
495 /*
496 * The function is used to start a new thread.
497 */
498 ENTRY(thread_starter)
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)
515 ENTRY(__hypercall)
516 mov r2=r37
517 break 0x1000
518 br.ret.sptk.many b0
519 ;;
520 END(__hypercall)
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)