ia64/xen-unstable

view xen/arch/ia64/xen/xenasm.S @ 9405:29dfadcc5029

[IA64] Followup to xen time cleanup

Clean up to xen time handler. Tristan #if 0 some code because it seems
redundant, which however is actually problematic logic as a reason for
an intermittent timer oops issue of dom0. So delete it now.

Also remove vcpu_wake, since wakeup current has nothing meaningful and
simply waste cpu cycle.

Signed-off-by: Kevin Tian <kevin.tian@intel.com>
author awilliam@xenbuild.aw
date Mon Mar 27 15:32:08 2006 -0700 (2006-03-27)
parents eae5812f33f1
children 2f86b84d0483
line source
1 /*
2 * Assembly support routines for Xen/ia64
3 *
4 * Copyright (C) 2004 Hewlett-Packard Co
5 * Dan Magenheimer <dan.magenheimer@hp.com>
6 */
8 #include <linux/config.h>
9 #include <asm/asmmacro.h>
10 #include <asm/processor.h>
11 #include <asm/pgtable.h>
12 #include <asm/vhpt.h>
14 #if 0
15 // FIXME: there's gotta be a better way...
16 // ski and spaski are different... moved to xenmisc.c
17 #define RunningOnHpSki(rx,ry,pn) \
18 addl rx = 2, r0; \
19 addl ry = 3, r0; \
20 ;; \
21 mov rx = cpuid[rx]; \
22 mov ry = cpuid[ry]; \
23 ;; \
24 cmp.eq pn,p0 = 0, rx; \
25 ;; \
26 (pn) movl rx = 0x7000004 ; \
27 ;; \
28 (pn) cmp.ge pn,p0 = ry, rx; \
29 ;;
31 //int platform_is_hp_ski(void)
32 GLOBAL_ENTRY(platform_is_hp_ski)
33 mov r8 = 0
34 RunningOnHpSki(r3,r9,p8)
35 (p8) mov r8 = 1
36 br.ret.sptk.many b0
37 END(platform_is_hp_ski)
38 #endif
40 // Change rr7 to the passed value while ensuring
41 // Xen is mapped into the new region.
42 // in0: new rr7 value
43 // in1: Xen virtual address of shared info (to be pinned)
44 #define PSR_BITS_TO_CLEAR \
45 (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT | \
46 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \
47 IA64_PSR_DFL | IA64_PSR_DFH)
48 // FIXME? Note that this turns off the DB bit (debug)
49 #define PSR_BITS_TO_SET IA64_PSR_BN
51 //extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_info, unsigned long p_vhpt, unsigned long v_pal);
52 GLOBAL_ENTRY(ia64_new_rr7)
53 // not sure this unwind statement is correct...
54 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1)
55 alloc loc1 = ar.pfs, 5, 9, 0, 0
56 1: {
57 mov r28 = in0 // copy procedure index
58 mov r8 = ip // save ip to compute branch
59 mov loc0 = rp // save rp
60 };;
61 .body
62 movl loc2=PERCPU_ADDR
63 ;;
64 tpa loc2=loc2 // grab this BEFORE changing rr7
65 ;;
66 dep loc8=0,in4,60,4
67 ;;
68 #if VHPT_ENABLED
69 mov loc6=in3
70 ;;
71 //tpa loc6=loc6 // grab this BEFORE changing rr7
72 ;;
73 #endif
74 mov loc5=in1
75 ;;
76 tpa loc5=loc5 // grab this BEFORE changing rr7
77 ;;
78 mov loc7=in2 // arch_vcpu_info_t
79 ;;
80 tpa loc7=loc7 // grab this BEFORE changing rr7
81 ;;
82 mov loc3 = psr // save psr
83 adds r8 = 1f-1b,r8 // calculate return address for call
84 ;;
85 tpa r8=r8 // convert rp to physical
86 ;;
87 mov loc4=ar.rsc // save RSE configuration
88 ;;
89 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
90 movl r16=PSR_BITS_TO_CLEAR
91 movl r17=PSR_BITS_TO_SET
92 ;;
93 or loc3=loc3,r17 // add in psr the bits to set
94 ;;
95 andcm r16=loc3,r16 // removes bits to clear from psr
96 br.call.sptk.many rp=ia64_switch_mode_phys
97 1:
98 // now in physical mode with psr.i/ic off so do rr7 switch
99 dep r16=-1,r0,61,3
100 ;;
101 mov rr[r16]=in0
102 srlz.d
103 ;;
105 // re-pin mappings for kernel text and data
106 mov r18=KERNEL_TR_PAGE_SHIFT<<2
107 movl r17=KERNEL_START
108 ;;
109 rsm psr.i | psr.ic
110 ;;
111 srlz.i
112 ;;
113 ptr.i r17,r18
114 ptr.d r17,r18
115 ;;
116 mov cr.itir=r18
117 mov cr.ifa=r17
118 mov r16=IA64_TR_KERNEL
119 //mov r3=ip
120 movl r18=PAGE_KERNEL
121 ;;
122 dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT
123 ;;
124 or r18=r2,r18
125 ;;
126 srlz.i
127 ;;
128 itr.i itr[r16]=r18
129 ;;
130 itr.d dtr[r16]=r18
131 ;;
133 // re-pin mappings for stack (current), per-cpu, vhpt, and shared info
135 // unless overlaps with KERNEL_TR
136 dep r18=0,r13,0,KERNEL_TR_PAGE_SHIFT
137 ;;
138 cmp.eq p7,p0=r17,r18
139 (p7) br.cond.sptk .stack_overlaps
140 ;;
141 movl r25=PAGE_KERNEL
142 dep r21=0,r13,60,4 // physical address of "current"
143 ;;
144 or r23=r25,r21 // construct PA | page properties
145 mov r25=IA64_GRANULE_SHIFT<<2
146 ;;
147 ptr.d r13,r25
148 ;;
149 mov cr.itir=r25
150 mov cr.ifa=r13 // VA of next task...
151 ;;
152 mov r25=IA64_TR_CURRENT_STACK
153 ;;
154 itr.d dtr[r25]=r23 // wire in new mapping...
155 ;;
156 .stack_overlaps:
158 movl r22=PERCPU_ADDR
159 ;;
160 movl r25=PAGE_KERNEL
161 ;;
162 mov r21=loc2 // saved percpu physical address
163 ;;
164 or r23=r25,r21 // construct PA | page properties
165 mov r24=PERCPU_PAGE_SHIFT<<2
166 ;;
167 ptr.d r22,r24
168 ;;
169 mov cr.itir=r24
170 mov cr.ifa=r22
171 ;;
172 mov r25=IA64_TR_PERCPU_DATA
173 ;;
174 itr.d dtr[r25]=r23 // wire in new mapping...
175 ;;
177 #if VHPT_ENABLED
178 movl r22=VHPT_ADDR
179 ;;
180 movl r25=PAGE_KERNEL
181 ;;
182 mov r21=loc6 // saved vhpt physical address
183 ;;
184 or r23=r25,r21 // construct PA | page properties
185 mov r24=VHPT_PAGE_SHIFT<<2
186 ;;
187 ptr.d r22,r24
188 ;;
189 mov cr.itir=r24
190 mov cr.ifa=r22
191 ;;
192 mov r25=IA64_TR_VHPT
193 ;;
194 itr.d dtr[r25]=r23 // wire in new mapping...
195 ;;
196 #endif
198 movl r22=SHAREDINFO_ADDR
199 ;;
200 movl r25=__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RW)
201 ;;
202 mov r21=loc5 // saved sharedinfo physical address
203 ;;
204 or r23=r25,r21 // construct PA | page properties
205 mov r24=PAGE_SHIFT<<2
206 ;;
207 ptr.d r22,r24
208 ;;
209 mov cr.itir=r24
210 mov cr.ifa=r22
211 ;;
212 mov r25=IA64_TR_SHARED_INFO
213 ;;
214 itr.d dtr[r25]=r23 // wire in new mapping...
215 ;;
216 // Map for arch_vcpu_info_t
217 movl r22=SHARED_ARCHINFO_ADDR
218 ;;
219 movl r25=__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RW)
220 ;;
221 mov r21=loc7 // saved sharedinfo physical address
222 ;;
223 or r23=r25,r21 // construct PA | page properties
224 mov r24=PAGE_SHIFT<<2
225 ;;
226 ptr.d r22,r24
227 ;;
228 mov cr.itir=r24
229 mov cr.ifa=r22
230 ;;
231 mov r25=IA64_TR_ARCH_INFO
232 ;;
233 itr.d dtr[r25]=r23 // wire in new mapping...
234 ;;
236 //Purge/insert PAL TR
237 mov r24=IA64_TR_PALCODE
238 movl r25=PAGE_KERNEL
239 ;;
240 or loc8=r25,loc8
241 mov r23=IA64_GRANULE_SHIFT<<2
242 ;;
243 ptr.i in4,r23
244 ;;
245 mov cr.itir=r23
246 mov cr.ifa=in4
247 ;;
248 itr.i itr[r24]=loc8
249 ;;
251 // done, switch back to virtual and return
252 mov r16=loc3 // r16= original psr
253 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
254 mov psr.l = loc3 // restore init PSR
256 mov ar.pfs = loc1
257 mov rp = loc0
258 ;;
259 mov ar.rsc=loc4 // restore RSE configuration
260 srlz.d // seralize restoration of psr.l
261 br.ret.sptk.many rp
262 END(ia64_new_rr7)
264 #include "minstate.h"
266 GLOBAL_ENTRY(ia64_prepare_handle_privop)
267 .prologue
268 /*
269 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
270 */
271 mov r16=r0
272 DO_SAVE_SWITCH_STACK
273 br.call.sptk.many rp=ia64_handle_privop // stack frame setup in ivt
274 .ret22: .body
275 DO_LOAD_SWITCH_STACK
276 br.cond.sptk.many rp // goes to ia64_leave_kernel
277 END(ia64_prepare_handle_privop)
279 GLOBAL_ENTRY(ia64_prepare_handle_break)
280 .prologue
281 /*
282 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
283 */
284 mov r16=r0
285 DO_SAVE_SWITCH_STACK
286 br.call.sptk.many rp=ia64_handle_break // stack frame setup in ivt
287 .ret23: .body
288 DO_LOAD_SWITCH_STACK
289 br.cond.sptk.many rp // goes to ia64_leave_kernel
290 END(ia64_prepare_handle_break)
292 GLOBAL_ENTRY(ia64_prepare_handle_reflection)
293 .prologue
294 /*
295 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
296 */
297 mov r16=r0
298 DO_SAVE_SWITCH_STACK
299 br.call.sptk.many rp=ia64_handle_reflection // stack frame setup in ivt
300 .ret24: .body
301 DO_LOAD_SWITCH_STACK
302 br.cond.sptk.many rp // goes to ia64_leave_kernel
303 END(ia64_prepare_handle_reflection)
305 GLOBAL_ENTRY(__get_domain_bundle)
306 EX(.failure_in_get_bundle,ld8 r8=[r32],8)
307 ;;
308 EX(.failure_in_get_bundle,ld8 r9=[r32])
309 ;;
310 br.ret.sptk.many rp
311 ;;
312 .failure_in_get_bundle:
313 mov r8=0
314 ;;
315 mov r9=0
316 ;;
317 br.ret.sptk.many rp
318 ;;
319 END(__get_domain_bundle)
321 GLOBAL_ENTRY(dorfirfi)
322 movl r16 = XSI_IIP
323 movl r17 = XSI_IPSR
324 movl r18 = XSI_IFS
325 ;;
326 ld8 r16 = [r16]
327 ld8 r17 = [r17]
328 ld8 r18 = [r18]
329 ;;
330 mov cr.iip=r16
331 mov cr.ipsr=r17
332 mov cr.ifs=r18
333 ;;
334 // fall through
335 END(dorfirfi)
337 GLOBAL_ENTRY(dorfi)
338 rfi
339 ;;
340 END(dorfirfi)
342 //
343 // Long's Peak UART Offsets
344 //
345 #define COM_TOP 0xff5e0000
346 #define COM_BOT 0xff5e2000
348 // UART offsets
349 #define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
350 #define UART_INT_ENB 1 /* interrupt enable (DLAB=0) */
351 #define UART_INT_ID 2 /* Interrupt ID register */
352 #define UART_LINE_CTL 3 /* Line control register */
353 #define UART_MODEM_CTL 4 /* Modem Control Register */
354 #define UART_LSR 5 /* In: Line Status Register */
355 #define UART_MSR 6 /* Modem status register */
356 #define UART_DLATCH_LOW UART_TX
357 #define UART_DLATCH_HIGH UART_INT_ENB
358 #define COM1 0x3f8
359 #define COM2 0x2F8
360 #define COM3 0x3E8
362 /* interrupt enable bits (offset 1) */
363 #define DATA_AVAIL_INT 1
364 #define XMIT_HOLD_EMPTY_INT 2
365 #define LINE_STAT_INT 4
366 #define MODEM_STAT_INT 8
368 /* line status bits (offset 5) */
369 #define REC_DATA_READY 1
370 #define OVERRUN 2
371 #define PARITY_ERROR 4
372 #define FRAMING_ERROR 8
373 #define BREAK_INTERRUPT 0x10
374 #define XMIT_HOLD_EMPTY 0x20
375 #define XMIT_SHIFT_EMPTY 0x40
377 // Write a single character
378 // input: r32 = character to be written
379 // output: none
380 GLOBAL_ENTRY(longs_peak_putc)
381 rsm psr.dt
382 movl r16 = 0x8000000000000000 + COM_TOP + UART_LSR
383 ;;
384 srlz.i
385 ;;
387 .Chk_THRE_p:
388 ld1.acq r18=[r16]
389 ;;
391 and r18 = XMIT_HOLD_EMPTY, r18
392 ;;
393 cmp4.eq p6,p0=0,r18
394 ;;
396 (p6) br .Chk_THRE_p
397 ;;
398 movl r16 = 0x8000000000000000 + COM_TOP + UART_TX
399 ;;
400 st1.rel [r16]=r32
401 ;;
402 ssm psr.dt
403 ;;
404 srlz.i
405 ;;
406 br.ret.sptk.many b0
407 END(longs_peak_putc)
409 /* derived from linux/arch/ia64/hp/sim/boot/boot_head.S */
410 GLOBAL_ENTRY(pal_emulator_static)
411 mov r8=-1
412 mov r9=256
413 ;;
414 cmp.gtu p7,p8=r9,r32 /* r32 <= 255? */
415 (p7) br.cond.sptk.few static
416 ;;
417 mov r9=512
418 ;;
419 cmp.gtu p7,p8=r9,r32
420 (p7) br.cond.sptk.few stacked
421 ;;
422 static: cmp.eq p7,p8=6,r32 /* PAL_PTCE_INFO */
423 (p8) br.cond.sptk.few 1f
424 ;;
425 mov r8=0 /* status = 0 */
426 movl r9=0x100000000 /* tc.base */
427 movl r10=0x0000000200000003 /* count[0], count[1] */
428 movl r11=0x1000000000002000 /* stride[0], stride[1] */
429 br.ret.sptk.few rp
430 1: cmp.eq p7,p8=14,r32 /* PAL_FREQ_RATIOS */
431 (p8) br.cond.sptk.few 1f
432 mov r8=0 /* status = 0 */
433 movl r9 =0x900000002 /* proc_ratio (1/100) */
434 movl r10=0x100000100 /* bus_ratio<<32 (1/256) */
435 movl r11=0x900000002 /* itc_ratio<<32 (1/100) */
436 ;;
437 1: cmp.eq p7,p8=19,r32 /* PAL_RSE_INFO */
438 (p8) br.cond.sptk.few 1f
439 mov r8=0 /* status = 0 */
440 mov r9=96 /* num phys stacked */
441 mov r10=0 /* hints */
442 mov r11=0
443 br.ret.sptk.few rp
444 1: cmp.eq p7,p8=1,r32 /* PAL_CACHE_FLUSH */
445 (p8) br.cond.sptk.few 1f
446 #if 0
447 mov r9=ar.lc
448 movl r8=524288 /* flush 512k million cache lines (16MB) */
449 ;;
450 mov ar.lc=r8
451 movl r8=0xe000000000000000
452 ;;
453 .loop: fc r8
454 add r8=32,r8
455 br.cloop.sptk.few .loop
456 sync.i
457 ;;
458 srlz.i
459 ;;
460 mov ar.lc=r9
461 mov r8=r0
462 ;;
463 1: cmp.eq p7,p8=15,r32 /* PAL_PERF_MON_INFO */
464 (p8) br.cond.sptk.few 1f
465 mov r8=0 /* status = 0 */
466 movl r9 =0x08122f04 /* generic=4 width=47 retired=8 cycles=18 */
467 mov r10=0 /* reserved */
468 mov r11=0 /* reserved */
469 mov r16=0xffff /* implemented PMC */
470 mov r17=0x3ffff /* implemented PMD */
471 add r18=8,r29 /* second index */
472 ;;
473 st8 [r29]=r16,16 /* store implemented PMC */
474 st8 [r18]=r0,16 /* clear remaining bits */
475 ;;
476 st8 [r29]=r0,16 /* clear remaining bits */
477 st8 [r18]=r0,16 /* clear remaining bits */
478 ;;
479 st8 [r29]=r17,16 /* store implemented PMD */
480 st8 [r18]=r0,16 /* clear remaining bits */
481 mov r16=0xf0 /* cycles count capable PMC */
482 ;;
483 st8 [r29]=r0,16 /* clear remaining bits */
484 st8 [r18]=r0,16 /* clear remaining bits */
485 mov r17=0xf0 /* retired bundles capable PMC */
486 ;;
487 st8 [r29]=r16,16 /* store cycles capable */
488 st8 [r18]=r0,16 /* clear remaining bits */
489 ;;
490 st8 [r29]=r0,16 /* clear remaining bits */
491 st8 [r18]=r0,16 /* clear remaining bits */
492 ;;
493 st8 [r29]=r17,16 /* store retired bundle capable */
494 st8 [r18]=r0,16 /* clear remaining bits */
495 ;;
496 st8 [r29]=r0,16 /* clear remaining bits */
497 st8 [r18]=r0,16 /* clear remaining bits */
498 ;;
499 1: br.cond.sptk.few rp
500 #else
501 1:
502 #endif
503 stacked:
504 br.ret.sptk.few rp
505 END(pal_emulator_static)
507 GLOBAL_ENTRY(vhpt_insert)
508 // alloc loc0 = ar.pfs, 3, 1, 0, 0
509 mov r16=r32
510 mov r26=r33
511 mov r27=r34
512 ;;
513 VHPT_INSERT()
514 // VHPT_INSERT1() ... add collision chains later
515 // mov ar.pfs = loc0
516 br.ret.sptk.few rp
517 ;;
518 END(vhpt_insert)
520 // These instructions are copied in the domains.
521 // This is the virtual PAL, which simply does an hypercall.
522 // The size is 2 bunldes (32 Bytes). It handles both static and stacked
523 // convention.
524 // If you modify this code, you have to modify dom_fw.h (for the size) and
525 // dom_fw_pal_hypercall_patch.
526 GLOBAL_ENTRY(pal_call_stub)
527 {
528 .mii
529 addl r2=0x1000,r0 // Hypercall number (Value is patched).
530 mov r9=256
531 ;;
532 cmp.gtu p7,p8=r9,r28 /* r32 <= 255? */
533 }
534 {
535 .mbb
536 break 0x1000 // Hypercall vector (Value is patched).
537 (p7) br.cond.sptk.few rp
538 (p8) br.ret.sptk.few rp
539 }
540 END(pal_call_stub)