ia64/xen-unstable

view xen/arch/ia64/xenasm.S @ 4534:195fcaf1958f

bitkeeper revision 1.1277.1.7 (425ef17azBqJhPFLmZEkDtoof0rTBA)

xenasm.S:
another shared page fix for paravirtualization
author djm@kirby.fc.hp.com
date Thu Apr 14 22:40:58 2005 +0000 (2005-04-14)
parents 1f457fed92df
children 58efb3448933
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 GLOBAL_ENTRY(ia64_new_rr7)
52 // not sure this unwind statement is correct...
53 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1)
54 alloc loc1 = ar.pfs, 2, 7, 0, 0
55 1: {
56 mov r28 = in0 // copy procedure index
57 mov r8 = ip // save ip to compute branch
58 mov loc0 = rp // save rp
59 };;
60 .body
61 movl loc2=PERCPU_ADDR
62 ;;
63 tpa loc2=loc2 // grab this BEFORE changing rr7
64 ;;
65 #if VHPT_ENABLED
66 movl loc6=VHPT_ADDR
67 ;;
68 tpa loc6=loc6 // grab this BEFORE changing rr7
69 ;;
70 #endif
71 mov loc5=in1
72 ;;
73 tpa loc5=loc5 // grab this BEFORE changing rr7
74 ;;
75 mov loc3 = psr // save psr
76 adds r8 = 1f-1b,r8 // calculate return address for call
77 ;;
78 tpa r8=r8 // convert rp to physical
79 ;;
80 mov loc4=ar.rsc // save RSE configuration
81 ;;
82 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
83 movl r16=PSR_BITS_TO_CLEAR
84 movl r17=PSR_BITS_TO_SET
85 ;;
86 or loc3=loc3,r17 // add in psr the bits to set
87 ;;
88 andcm r16=loc3,r16 // removes bits to clear from psr
89 br.call.sptk.many rp=ia64_switch_mode_phys
90 1:
91 // now in physical mode with psr.i/ic off so do rr7 switch
92 dep r16=-1,r0,61,3
93 ;;
94 mov rr[r16]=in0
95 srlz.d
96 ;;
98 // re-pin mappings for kernel text and data
99 mov r18=KERNEL_TR_PAGE_SHIFT<<2
100 movl r17=KERNEL_START
101 ;;
102 rsm psr.i | psr.ic
103 ;;
104 srlz.i
105 ;;
106 ptr.i r17,r18
107 ptr.d r17,r18
108 ;;
109 mov cr.itir=r18
110 mov cr.ifa=r17
111 mov r16=IA64_TR_KERNEL
112 //mov r3=ip
113 movl r18=PAGE_KERNEL
114 ;;
115 dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT
116 ;;
117 or r18=r2,r18
118 ;;
119 srlz.i
120 ;;
121 itr.i itr[r16]=r18
122 ;;
123 itr.d dtr[r16]=r18
124 ;;
126 // re-pin mappings for stack (current), per-cpu, vhpt, and shared info
128 // unless overlaps with KERNEL_TR
129 dep r18=0,r13,0,KERNEL_TR_PAGE_SHIFT
130 ;;
131 cmp.eq p7,p0=r17,r18
132 (p7) br.cond.sptk .stack_overlaps
133 ;;
134 movl r25=PAGE_KERNEL
135 dep r21=0,r13,60,4 // physical address of "current"
136 ;;
137 or r23=r25,r21 // construct PA | page properties
138 mov r25=IA64_GRANULE_SHIFT<<2
139 ;;
140 ptr.d r13,r25
141 ;;
142 mov cr.itir=r25
143 mov cr.ifa=r13 // VA of next task...
144 ;;
145 mov r25=IA64_TR_CURRENT_STACK
146 ;;
147 itr.d dtr[r25]=r23 // wire in new mapping...
148 ;;
149 .stack_overlaps:
151 movl r22=PERCPU_ADDR
152 ;;
153 movl r25=PAGE_KERNEL
154 ;;
155 mov r21=loc2 // saved percpu physical address
156 ;;
157 or r23=r25,r21 // construct PA | page properties
158 mov r24=PERCPU_PAGE_SHIFT<<2
159 ;;
160 ptr.d r22,r24
161 ;;
162 mov cr.itir=r24
163 mov cr.ifa=r22
164 ;;
165 mov r25=IA64_TR_PERCPU_DATA
166 ;;
167 itr.d dtr[r25]=r23 // wire in new mapping...
168 ;;
170 #if VHPT_ENABLED
171 movl r22=VHPT_ADDR
172 ;;
173 movl r25=PAGE_KERNEL
174 ;;
175 mov r21=loc6 // saved vhpt physical address
176 ;;
177 or r23=r25,r21 // construct PA | page properties
178 mov r24=VHPT_PAGE_SHIFT<<2
179 ;;
180 ptr.d r22,r24
181 ;;
182 mov cr.itir=r24
183 mov cr.ifa=r22
184 ;;
185 mov r25=IA64_TR_VHPT
186 ;;
187 itr.d dtr[r25]=r23 // wire in new mapping...
188 ;;
189 #endif
191 movl r22=SHAREDINFO_ADDR
192 ;;
193 movl r25=PAGE_SHARED
194 movl r25=__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RW)
195 ;;
196 mov r21=loc5 // saved sharedinfo physical address
197 ;;
198 or r23=r25,r21 // construct PA | page properties
199 mov r24=PAGE_SHIFT<<2
200 ;;
201 ptr.d r22,r24
202 ;;
203 mov cr.itir=r24
204 mov cr.ifa=r22
205 ;;
206 mov r25=IA64_TR_SHARED_INFO
207 ;;
208 itr.d dtr[r25]=r23 // wire in new mapping...
209 ;;
211 // done, switch back to virtual and return
212 mov r16=loc3 // r16= original psr
213 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
214 mov psr.l = loc3 // restore init PSR
216 mov ar.pfs = loc1
217 mov rp = loc0
218 ;;
219 mov ar.rsc=loc4 // restore RSE configuration
220 srlz.d // seralize restoration of psr.l
221 br.ret.sptk.many rp
222 END(ia64_new_rr7)
224 #include "minstate.h"
226 GLOBAL_ENTRY(ia64_prepare_handle_privop)
227 .prologue
228 /*
229 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
230 */
231 mov r16=r0
232 DO_SAVE_SWITCH_STACK
233 br.call.sptk.many rp=ia64_handle_privop // stack frame setup in ivt
234 .ret22: .body
235 DO_LOAD_SWITCH_STACK
236 br.cond.sptk.many rp // goes to ia64_leave_kernel
237 END(ia64_prepare_handle_privop)
239 GLOBAL_ENTRY(ia64_prepare_handle_break)
240 .prologue
241 /*
242 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
243 */
244 mov r16=r0
245 DO_SAVE_SWITCH_STACK
246 br.call.sptk.many rp=ia64_handle_break // stack frame setup in ivt
247 .ret23: .body
248 DO_LOAD_SWITCH_STACK
249 br.cond.sptk.many rp // goes to ia64_leave_kernel
250 END(ia64_prepare_handle_break)
252 GLOBAL_ENTRY(ia64_prepare_handle_reflection)
253 .prologue
254 /*
255 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
256 */
257 mov r16=r0
258 DO_SAVE_SWITCH_STACK
259 br.call.sptk.many rp=ia64_handle_reflection // stack frame setup in ivt
260 .ret24: .body
261 DO_LOAD_SWITCH_STACK
262 br.cond.sptk.many rp // goes to ia64_leave_kernel
263 END(ia64_prepare_handle_reflection)
265 GLOBAL_ENTRY(__get_domain_bundle)
266 EX(.failure_in_get_bundle,ld8 r8=[r32],8)
267 ;;
268 EX(.failure_in_get_bundle,ld8 r9=[r32])
269 ;;
270 br.ret.sptk.many rp
271 ;;
272 .failure_in_get_bundle:
273 mov r8=0
274 ;;
275 mov r9=0
276 ;;
277 br.ret.sptk.many rp
278 ;;
279 END(__get_domain_bundle)
281 GLOBAL_ENTRY(dorfirfi)
282 #define SI_CR_IIP_OFFSET 0x10
283 #define SI_CR_IPSR_OFFSET 0x08
284 #define SI_CR_IFS_OFFSET 0x18
285 movl r16 = SHAREDINFO_ADDR+SI_CR_IIP_OFFSET
286 movl r17 = SHAREDINFO_ADDR+SI_CR_IPSR_OFFSET
287 movl r18 = SHAREDINFO_ADDR+SI_CR_IFS_OFFSET
288 ;;
289 ld8 r16 = [r16]
290 ld8 r17 = [r17]
291 ld8 r18 = [r18]
292 ;;
293 mov cr.iip=r16
294 mov cr.ipsr=r17
295 mov cr.ifs=r18
296 ;;
297 // fall through
298 END(dorfirfi)
300 GLOBAL_ENTRY(dorfi)
301 rfi
302 ;;
303 END(dorfirfi)
305 //
306 // Long's Peak UART Offsets
307 //
308 #define COM_TOP 0xff5e0000
309 #define COM_BOT 0xff5e2000
311 // UART offsets
312 #define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
313 #define UART_INT_ENB 1 /* interrupt enable (DLAB=0) */
314 #define UART_INT_ID 2 /* Interrupt ID register */
315 #define UART_LINE_CTL 3 /* Line control register */
316 #define UART_MODEM_CTL 4 /* Modem Control Register */
317 #define UART_LSR 5 /* In: Line Status Register */
318 #define UART_MSR 6 /* Modem status register */
319 #define UART_DLATCH_LOW UART_TX
320 #define UART_DLATCH_HIGH UART_INT_ENB
321 #define COM1 0x3f8
322 #define COM2 0x2F8
323 #define COM3 0x3E8
325 /* interrupt enable bits (offset 1) */
326 #define DATA_AVAIL_INT 1
327 #define XMIT_HOLD_EMPTY_INT 2
328 #define LINE_STAT_INT 4
329 #define MODEM_STAT_INT 8
331 /* line status bits (offset 5) */
332 #define REC_DATA_READY 1
333 #define OVERRUN 2
334 #define PARITY_ERROR 4
335 #define FRAMING_ERROR 8
336 #define BREAK_INTERRUPT 0x10
337 #define XMIT_HOLD_EMPTY 0x20
338 #define XMIT_SHIFT_EMPTY 0x40
340 // Write a single character
341 // input: r32 = character to be written
342 // output: none
343 GLOBAL_ENTRY(longs_peak_putc)
344 rsm psr.dt
345 movl r16 = 0x8000000000000000 + COM_TOP + UART_LSR
346 ;;
347 srlz.i
348 ;;
350 .Chk_THRE_p:
351 ld1.acq r18=[r16]
352 ;;
354 and r18 = XMIT_HOLD_EMPTY, r18
355 ;;
356 cmp4.eq p6,p0=0,r18
357 ;;
359 (p6) br .Chk_THRE_p
360 ;;
361 movl r16 = 0x8000000000000000 + COM_TOP + UART_TX
362 ;;
363 st1.rel [r16]=r32
364 ;;
365 ssm psr.dt
366 ;;
367 srlz.i
368 ;;
369 br.ret.sptk.many b0
370 END(longs_peak_putc)
372 /* derived from linux/arch/ia64/hp/sim/boot/boot_head.S */
373 GLOBAL_ENTRY(pal_emulator_static)
374 mov r8=-1
375 mov r9=256
376 ;;
377 cmp.gtu p7,p8=r9,r32 /* r32 <= 255? */
378 (p7) br.cond.sptk.few static
379 ;;
380 mov r9=512
381 ;;
382 cmp.gtu p7,p8=r9,r32
383 (p7) br.cond.sptk.few stacked
384 ;;
385 static: cmp.eq p7,p8=6,r32 /* PAL_PTCE_INFO */
386 (p8) br.cond.sptk.few 1f
387 ;;
388 mov r8=0 /* status = 0 */
389 movl r9=0x100000000 /* tc.base */
390 movl r10=0x0000000200000003 /* count[0], count[1] */
391 movl r11=0x1000000000002000 /* stride[0], stride[1] */
392 br.ret.sptk.few rp
393 1: cmp.eq p7,p8=14,r32 /* PAL_FREQ_RATIOS */
394 (p8) br.cond.sptk.few 1f
395 mov r8=0 /* status = 0 */
396 movl r9 =0x900000002 /* proc_ratio (1/100) */
397 movl r10=0x100000100 /* bus_ratio<<32 (1/256) */
398 movl r11=0x900000002 /* itc_ratio<<32 (1/100) */
399 ;;
400 1: cmp.eq p7,p8=19,r32 /* PAL_RSE_INFO */
401 (p8) br.cond.sptk.few 1f
402 mov r8=0 /* status = 0 */
403 mov r9=96 /* num phys stacked */
404 mov r10=0 /* hints */
405 mov r11=0
406 br.ret.sptk.few rp
407 1: cmp.eq p7,p8=1,r32 /* PAL_CACHE_FLUSH */
408 (p8) br.cond.sptk.few 1f
409 #if 0
410 mov r9=ar.lc
411 movl r8=524288 /* flush 512k million cache lines (16MB) */
412 ;;
413 mov ar.lc=r8
414 movl r8=0xe000000000000000
415 ;;
416 .loop: fc r8
417 add r8=32,r8
418 br.cloop.sptk.few .loop
419 sync.i
420 ;;
421 srlz.i
422 ;;
423 mov ar.lc=r9
424 mov r8=r0
425 ;;
426 1: cmp.eq p7,p8=15,r32 /* PAL_PERF_MON_INFO */
427 (p8) br.cond.sptk.few 1f
428 mov r8=0 /* status = 0 */
429 movl r9 =0x08122f04 /* generic=4 width=47 retired=8 cycles=18 */
430 mov r10=0 /* reserved */
431 mov r11=0 /* reserved */
432 mov r16=0xffff /* implemented PMC */
433 mov r17=0x3ffff /* implemented PMD */
434 add r18=8,r29 /* second index */
435 ;;
436 st8 [r29]=r16,16 /* store implemented PMC */
437 st8 [r18]=r0,16 /* clear remaining bits */
438 ;;
439 st8 [r29]=r0,16 /* clear remaining bits */
440 st8 [r18]=r0,16 /* clear remaining bits */
441 ;;
442 st8 [r29]=r17,16 /* store implemented PMD */
443 st8 [r18]=r0,16 /* clear remaining bits */
444 mov r16=0xf0 /* cycles count capable PMC */
445 ;;
446 st8 [r29]=r0,16 /* clear remaining bits */
447 st8 [r18]=r0,16 /* clear remaining bits */
448 mov r17=0xf0 /* retired bundles capable PMC */
449 ;;
450 st8 [r29]=r16,16 /* store cycles capable */
451 st8 [r18]=r0,16 /* clear remaining bits */
452 ;;
453 st8 [r29]=r0,16 /* clear remaining bits */
454 st8 [r18]=r0,16 /* clear remaining bits */
455 ;;
456 st8 [r29]=r17,16 /* store retired bundle capable */
457 st8 [r18]=r0,16 /* clear remaining bits */
458 ;;
459 st8 [r29]=r0,16 /* clear remaining bits */
460 st8 [r18]=r0,16 /* clear remaining bits */
461 ;;
462 1: br.cond.sptk.few rp
463 #else
464 1:
465 #endif
466 stacked:
467 br.ret.sptk.few rp
468 END(pal_emulator_static)
470 GLOBAL_ENTRY(vhpt_insert)
471 // alloc loc0 = ar.pfs, 3, 1, 0, 0
472 mov r16=r32
473 mov r26=r33
474 mov r27=r34
475 ;;
476 VHPT_INSERT()
477 // VHPT_INSERT1() ... add collision chains later
478 // mov ar.pfs = loc0
479 br.ret.sptk.few rp
480 ;;
481 END(vhpt_insert)