direct-io.hg

changeset 5566:dca57ff5d1c1

bitkeeper revision 1.1726.1.6 (42bb0675eG3PXvB-XpEs0EYcdos-EA)

ia64: Add fast reflection for most clock ticks
Also, some additional debug output for various situations.
Signed-off-by: Dan Magenheimer <dan.magenheimer@hp.com>
author djm@kirby.fc.hp.com
date Thu Jun 23 18:59:01 2005 +0000 (2005-06-23)
parents 78b0596ef957
children cef83293394d
files xen/arch/ia64/asm-offsets.c xen/arch/ia64/domain.c xen/arch/ia64/hypercall.c xen/arch/ia64/hyperprivop.S xen/arch/ia64/ivt.S xen/arch/ia64/privop.c xen/arch/ia64/process.c
line diff
     1.1 --- a/xen/arch/ia64/asm-offsets.c	Wed Jun 22 17:46:00 2005 +0000
     1.2 +++ b/xen/arch/ia64/asm-offsets.c	Thu Jun 23 18:59:01 2005 +0000
     1.3 @@ -88,6 +88,7 @@ void foo(void)
     1.4  
     1.5  	BLANK();
     1.6  	DEFINE(IA64_CPUINFO_ITM_NEXT_OFFSET, offsetof (struct cpuinfo_ia64, itm_next));
     1.7 +	DEFINE(IA64_CPUINFO_PGD_QUICK_OFFSET, offsetof (struct cpuinfo_ia64, pgd_quick));
     1.8  
     1.9  	//DEFINE(IA64_SIGHAND_SIGLOCK_OFFSET,offsetof (struct sighand_struct, siglock));
    1.10  
     2.1 --- a/xen/arch/ia64/domain.c	Wed Jun 22 17:46:00 2005 +0000
     2.2 +++ b/xen/arch/ia64/domain.c	Thu Jun 23 18:59:01 2005 +0000
     2.3 @@ -50,7 +50,7 @@ unsigned long dom0_size = 512*1024*1024;
     2.4  //FIXME: alignment should be 256MB, lest Linux use a 256MB page size
     2.5  unsigned long dom0_align = 256*1024*1024;
     2.6  #else // CONFIG_VTI
     2.7 -unsigned long dom0_size = 256*1024*1024; //FIXME: Should be configurable
     2.8 +unsigned long dom0_size = 512*1024*1024; //FIXME: Should be configurable
     2.9  //FIXME: alignment should be 256MB, lest Linux use a 256MB page size
    2.10  unsigned long dom0_align = 64*1024*1024;
    2.11  #endif // CONFIG_VTI
     3.1 --- a/xen/arch/ia64/hypercall.c	Wed Jun 22 17:46:00 2005 +0000
     3.2 +++ b/xen/arch/ia64/hypercall.c	Thu Jun 23 18:59:01 2005 +0000
     3.3 @@ -43,7 +43,8 @@ ia64_hypercall (struct pt_regs *regs)
     3.4  #if 1
     3.5  #define SPURIOUS_VECTOR 15
     3.6  			if (vcpu_check_pending_interrupts(v)!=SPURIOUS_VECTOR) {
     3.7 -//printf("Domain trying to go idle when interrupt pending!\n");
     3.8 +//				int pi = vcpu_check_pending_interrupts(v);
     3.9 +//printf("idle w/int#%d pending!\n",pi);
    3.10  //this shouldn't happen, but it apparently does quite a bit!  so don't
    3.11  //allow it to happen... i.e. if a domain has an interrupt pending and
    3.12  //it tries to halt itself because it thinks it is idle, just return here
     4.1 --- a/xen/arch/ia64/hyperprivop.S	Wed Jun 22 17:46:00 2005 +0000
     4.2 +++ b/xen/arch/ia64/hyperprivop.S	Thu Jun 23 18:59:01 2005 +0000
     4.3 @@ -17,6 +17,10 @@
     4.4  #define FAST_HYPERPRIVOP_CNT
     4.5  #define FAST_REFLECT_CNT
     4.6  
     4.7 +// FIXME: This is defined in include/asm-ia64/hw_irq.h but this
     4.8 +// doesn't appear to be include'able from assembly?
     4.9 +#define IA64_TIMER_VECTOR 0xef
    4.10 +
    4.11  // Should be included from common header file (also in process.c)
    4.12  //  NO PSR_CLR IS DIFFERENT! (CPL)
    4.13  #define IA64_PSR_CPL1	(__IA64_UL(1) << IA64_PSR_CPL1_BIT)
    4.14 @@ -241,14 +245,23 @@ ENTRY(hyper_ssm_i)
    4.15  	adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
    4.16  	adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
    4.17  	bsw.1;;
    4.18 -	st8 [r2]=r16,16; st8 [r3]=r17,16 ;;
    4.19 -	st8 [r2]=r18,16; st8 [r3]=r19,16 ;;
    4.20 -	st8 [r2]=r20,16; st8 [r3]=r21,16 ;;
    4.21 -	st8 [r2]=r22,16; st8 [r3]=r23,16 ;;
    4.22 -	st8 [r2]=r24,16; st8 [r3]=r25,16 ;;
    4.23 -	st8 [r2]=r26,16; st8 [r3]=r27,16 ;;
    4.24 -	st8 [r2]=r28,16; st8 [r3]=r29,16 ;;
    4.25 -	st8 [r2]=r30,16; st8 [r3]=r31,16 ;;
    4.26 +	// FIXME: need to handle ar.unat!
    4.27 +	.mem.offset 0,0; st8.spill [r2]=r16,16;
    4.28 +	.mem.offset 8,0; st8.spill [r3]=r17,16 ;;
    4.29 +	.mem.offset 0,0; st8.spill [r2]=r18,16;
    4.30 +	.mem.offset 8,0; st8.spill [r3]=r19,16 ;;
    4.31 +	.mem.offset 0,0; st8.spill [r2]=r20,16;
    4.32 +	.mem.offset 8,0; st8.spill [r3]=r21,16 ;;
    4.33 +	.mem.offset 0,0; st8.spill [r2]=r22,16;
    4.34 +	.mem.offset 8,0; st8.spill [r3]=r23,16 ;;
    4.35 +	.mem.offset 0,0; st8.spill [r2]=r24,16;
    4.36 +	.mem.offset 8,0; st8.spill [r3]=r25,16 ;;
    4.37 +	.mem.offset 0,0; st8.spill [r2]=r26,16;
    4.38 +	.mem.offset 8,0; st8.spill [r3]=r27,16 ;;
    4.39 +	.mem.offset 0,0; st8.spill [r2]=r28,16;
    4.40 +	.mem.offset 8,0; st8.spill [r3]=r29,16 ;;
    4.41 +	.mem.offset 0,0; st8.spill [r2]=r30,16;
    4.42 +	.mem.offset 8,0; st8.spill [r3]=r31,16 ;;
    4.43  	movl r31=XSI_IPSR;;
    4.44  	bsw.0 ;;
    4.45  	mov r2=r30; mov r3=r29;;
    4.46 @@ -258,6 +271,175 @@ ENTRY(hyper_ssm_i)
    4.47  	rfi
    4.48  	;;
    4.49  
    4.50 +// reflect domain clock interrupt
    4.51 +//	r31 == pr
    4.52 +//	r30 == cr.ivr
    4.53 +//	r29 == rp
    4.54 +GLOBAL_ENTRY(fast_tick_reflect)
    4.55 +#define FAST_TICK
    4.56 +#ifndef FAST_TICK
    4.57 +	br.cond.sptk.many rp;;
    4.58 +#endif
    4.59 +	mov r28=IA64_TIMER_VECTOR;;
    4.60 +	cmp.ne p6,p0=r28,r30
    4.61 +(p6)	br.cond.sptk.many rp;;
    4.62 +	movl r20=(PERCPU_ADDR)+IA64_CPUINFO_ITM_NEXT_OFFSET;;
    4.63 +	ld8 r21=[r20];;
    4.64 +	mov r27=ar.itc;;
    4.65 +	cmp.ltu p6,p0=r21,r27
    4.66 +(p6)	br.cond.sptk.many rp;;
    4.67 +	mov r17=cr.ipsr;;
    4.68 +	// slow path if: ipsr.be==1, ipsr.pp==1
    4.69 +	extr.u r21=r17,IA64_PSR_BE_BIT,1 ;;
    4.70 +	cmp.ne p6,p0=r21,r0
    4.71 +(p6)	br.cond.sptk.many rp;;
    4.72 +	extr.u r21=r17,IA64_PSR_PP_BIT,1 ;;
    4.73 +	cmp.ne p6,p0=r21,r0
    4.74 +(p6)	br.cond.sptk.many rp;;
    4.75 +#ifdef FAST_REFLECT_CNT
    4.76 +	movl r20=fast_reflect_count+((0x3000>>8)*8);;
    4.77 +	ld8 r21=[r20];;
    4.78 +	adds r21=1,r21;;
    4.79 +	st8 [r20]=r21;;
    4.80 +#endif
    4.81 +	mov cr.eoi=r0;;
    4.82 +	mov rp=r29;;
    4.83 +	// vcpu_pend_timer(current)
    4.84 +	movl r18=XSI_PSR_IC;;
    4.85 +	adds r20=XSI_ITV_OFS-XSI_PSR_IC_OFS,r18 ;;
    4.86 +	ld8 r20=[r20];;
    4.87 +	cmp.eq p6,p0=r20,r0	// if cr.itv==0 done
    4.88 +(p6)	br.cond.sptk.many fast_tick_reflect_done;;
    4.89 +	tbit.nz p6,p0=r20,16;;	// check itv.m (discard) bit
    4.90 +(p6)	br.cond.sptk.many fast_tick_reflect_done;;
    4.91 +	extr.u r27=r20,0,6	// r27 has low 6 bits of itv.vector
    4.92 +	extr.u r26=r20,6,2;;	// r26 has irr index of itv.vector
    4.93 +	mov r19=IA64_KR(CURRENT);;
    4.94 +	adds r22=IA64_VCPU_DOMAIN_ITM_LAST_OFFSET,r19
    4.95 +	adds r23=IA64_VCPU_DOMAIN_ITM_OFFSET,r19;;
    4.96 +	ld8 r24=[r22];;
    4.97 +	ld8 r23=[r23];;
    4.98 +	cmp.eq p6,p0=r23,r24	// skip if this tick already delivered
    4.99 +(p6)	br.cond.sptk.many fast_tick_reflect_done;;
   4.100 +	// set irr bit
   4.101 +	adds r21=IA64_VCPU_IRR0_OFFSET,r19;
   4.102 +	shl r26=r26,3;;
   4.103 +	add r21=r21,r26;;
   4.104 +	mov r25=1;;
   4.105 +	shl r22=r25,r27;;
   4.106 +	ld8 r23=[r21];;
   4.107 +	or r22=r22,r23;;
   4.108 +	st8 [r21]=r22;;
   4.109 +	// set PSCB(pending_interruption)!
   4.110 +	adds r20=XSI_PEND_OFS-XSI_PSR_IC_OFS,r18 ;;
   4.111 +	st4 [r20]=r25;;
   4.112 +	
   4.113 +	// if interrupted at pl0, we're done
   4.114 +	extr.u r16=r17,IA64_PSR_CPL0_BIT,2;;
   4.115 +	cmp.eq p6,p0=r16,r0;;
   4.116 +(p6)	br.cond.sptk.many fast_tick_reflect_done;;
   4.117 +	// now deliver to iva+0x3000
   4.118 +	//	r17 == cr.ipsr
   4.119 +	//	r18 == XSI_PSR_IC
   4.120 +	//	r19 == IA64_KR(CURRENT)
   4.121 +	//	r31 == pr
   4.122 +
   4.123 +	// if guest vpsr.i is off, we're done
   4.124 +	adds r21=XSI_PSR_I_OFS-XSI_PSR_IC_OFS,r18 ;;
   4.125 +	ld4 r21=[r21];;
   4.126 +	cmp.eq p6,p0=r21,r0
   4.127 +(p6)	br.cond.sptk.many fast_tick_reflect_done;;
   4.128 +
   4.129 +	// OK, we have a clock tick to deliver to the active domain!
   4.130 +	mov r16=cr.isr;;
   4.131 +	mov r29=cr.iip;;
   4.132 +	adds r21=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;;
   4.133 +	st8 [r21]=r29 ;;
   4.134 +	// set shared_mem isr
   4.135 +	extr.u r16=r16,38,1;;	// grab cr.isr.ir bit
   4.136 +	dep r16=r16,r0,38,1 ;;	// insert into cr.isr (rest of bits zero)
   4.137 +	extr.u r20=r17,41,2 ;;	// get ipsr.ri
   4.138 +	dep r16=r20,r16,41,2 ;; // deposit cr.isr.ei
   4.139 +	adds r21=XSI_ISR_OFS-XSI_PSR_IC_OFS,r18 ;; 
   4.140 +	st8 [r21]=r16 ;;
   4.141 +	// set cr.ipsr (make sure cpl==2!)
   4.142 +	mov r29=r17 ;;
   4.143 +	movl r28=DELIVER_PSR_SET;;
   4.144 +	movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);;
   4.145 +	or r29=r29,r28;;
   4.146 +	and r29=r29,r27;;
   4.147 +	mov cr.ipsr=r29;;
   4.148 +	// set shared_mem ipsr (from ipsr in r17 with ipsr.ri already set)
   4.149 +	extr.u r29=r17,IA64_PSR_CPL0_BIT,2;;
   4.150 +	cmp.eq p6,p7=3,r29;;
   4.151 +(p6)	dep r17=-1,r17,IA64_PSR_CPL0_BIT,2
   4.152 +(p7)	dep r17=0,r17,IA64_PSR_CPL0_BIT,2
   4.153 +	;;
   4.154 +	movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT);;
   4.155 +	movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN|IA64_PSR_I|IA64_PSR_IC);;
   4.156 +	dep r21=-1,r21,IA64_PSR_CPL1_BIT,1 ;;
   4.157 +	or r17=r17,r28;;
   4.158 +	and r17=r17,r27;;
   4.159 +	ld4 r16=[r18],4;;
   4.160 +	cmp.ne p6,p0=r16,r0;;
   4.161 +(p6)	dep r17=-1,r17,IA64_PSR_IC_BIT,1 ;;
   4.162 +	ld4 r16=[r18],-4;;
   4.163 +	cmp.ne p6,p0=r16,r0;;
   4.164 +(p6)	dep r17=-1,r17,IA64_PSR_I_BIT,1 ;;
   4.165 +	adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
   4.166 +	st8 [r21]=r17 ;;
   4.167 +	// set shared_mem interrupt_delivery_enabled to 0
   4.168 +	// set shared_mem interrupt_collection_enabled to 0
   4.169 +	st8 [r18]=r0;;
   4.170 +	// cover and set shared_mem precover_ifs to cr.ifs
   4.171 +	// set shared_mem ifs and incomplete_regframe to 0
   4.172 +	cover ;;
   4.173 +	mov r20=cr.ifs;;
   4.174 +	adds r21=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
   4.175 +	st4 [r21]=r0 ;;
   4.176 +	adds r21=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   4.177 +	st8 [r21]=r0 ;;
   4.178 +	adds r21=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   4.179 +	st8 [r21]=r20 ;;
   4.180 +	// leave cr.ifs alone for later rfi
   4.181 +	// set iip to go to domain IVA break instruction vector
   4.182 +	adds r22=IA64_VCPU_IVA_OFFSET,r19;;
   4.183 +	ld8 r23=[r22];;
   4.184 +	movl r24=0x3000;;
   4.185 +	add r24=r24,r23;;
   4.186 +	mov cr.iip=r24;;
   4.187 +	// OK, now all set to go except for switch to virtual bank0
   4.188 +	mov r30=r2; mov r29=r3;;
   4.189 +	adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
   4.190 +	adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
   4.191 +	bsw.1;;
   4.192 +	// FIXME: need to handle ar.unat!
   4.193 +	.mem.offset 0,0; st8.spill [r2]=r16,16;
   4.194 +	.mem.offset 8,0; st8.spill [r3]=r17,16 ;;
   4.195 +	.mem.offset 0,0; st8.spill [r2]=r18,16;
   4.196 +	.mem.offset 8,0; st8.spill [r3]=r19,16 ;;
   4.197 +	.mem.offset 0,0; st8.spill [r2]=r20,16;
   4.198 +	.mem.offset 8,0; st8.spill [r3]=r21,16 ;;
   4.199 +	.mem.offset 0,0; st8.spill [r2]=r22,16;
   4.200 +	.mem.offset 8,0; st8.spill [r3]=r23,16 ;;
   4.201 +	.mem.offset 0,0; st8.spill [r2]=r24,16;
   4.202 +	.mem.offset 8,0; st8.spill [r3]=r25,16 ;;
   4.203 +	.mem.offset 0,0; st8.spill [r2]=r26,16;
   4.204 +	.mem.offset 8,0; st8.spill [r3]=r27,16 ;;
   4.205 +	.mem.offset 0,0; st8.spill [r2]=r28,16;
   4.206 +	.mem.offset 8,0; st8.spill [r3]=r29,16 ;;
   4.207 +	.mem.offset 0,0; st8.spill [r2]=r30,16;
   4.208 +	.mem.offset 8,0; st8.spill [r3]=r31,16 ;;
   4.209 +	movl r31=XSI_IPSR;;
   4.210 +	bsw.0 ;;
   4.211 +	mov r2=r30; mov r3=r29;;
   4.212 +	adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
   4.213 +	st4 [r20]=r0 ;;
   4.214 +fast_tick_reflect_done:
   4.215 +	mov pr=r31,-1 ;;
   4.216 +	rfi
   4.217 +END(fast_tick_reflect)
   4.218 +
   4.219  // reflect domain breaks directly to domain
   4.220  // FIXME: DOES NOT WORK YET
   4.221  //	r16 == cr.isr
     5.1 --- a/xen/arch/ia64/ivt.S	Wed Jun 22 17:46:00 2005 +0000
     5.2 +++ b/xen/arch/ia64/ivt.S	Thu Jun 23 18:59:01 2005 +0000
     5.3 @@ -919,6 +919,21 @@ ENTRY(interrupt)
     5.4  	DBG_FAULT(12)
     5.5  	mov r31=pr		// prepare to save predicates
     5.6  	;;
     5.7 +#ifdef XEN
     5.8 +	mov r30=cr.ivr		// pass cr.ivr as first arg
     5.9 +	// FIXME: this is a hack... use cpuinfo.pgd_quick because its
    5.10 +	// not used anywhere else and we need a place to stash ivr and
    5.11 +	// there's no registers available unused by SAVE_MIN/REST
    5.12 +	movl r29=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;;
    5.13 +	st8 [r29]=r30;;
    5.14 +	movl r28=slow_interrupt;;
    5.15 +	mov r29=rp;;
    5.16 +	mov rp=r28;;
    5.17 +	br.cond.sptk.many fast_tick_reflect
    5.18 +	;;
    5.19 +slow_interrupt:
    5.20 +	mov rp=r29;;
    5.21 +#endif
    5.22  	SAVE_MIN_WITH_COVER	// uses r31; defines r2 and r3
    5.23  	ssm psr.ic | PSR_DEFAULT_BITS
    5.24  	;;
    5.25 @@ -928,7 +943,12 @@ ENTRY(interrupt)
    5.26  	SAVE_REST
    5.27  	;;
    5.28  	alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
    5.29 +#ifdef XEN
    5.30 +	movl out0=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;;
    5.31 +	ld8 out0=[out0];;
    5.32 +#else
    5.33  	mov out0=cr.ivr		// pass cr.ivr as first arg
    5.34 +#endif
    5.35  	add out1=16,sp		// pass pointer to pt_regs as second arg
    5.36  	;;
    5.37  	srlz.d			// make sure we see the effect of cr.ivr
     6.1 --- a/xen/arch/ia64/privop.c	Wed Jun 22 17:46:00 2005 +0000
     6.2 +++ b/xen/arch/ia64/privop.c	Thu Jun 23 18:59:01 2005 +0000
     6.3 @@ -781,6 +781,7 @@ ia64_hyperprivop(unsigned long iim, REGS
     6.4  // FIXME: Handle faults appropriately for these
     6.5  	if (!iim || iim > HYPERPRIVOP_MAX) {
     6.6  		printf("bad hyperprivop; ignored\n");
     6.7 +		printf("iim=%d, iip=%p\n",iim,regs->cr_iip);
     6.8  		return 1;
     6.9  	}
    6.10  	slow_hyperpriv_cnt[iim]++;
     7.1 --- a/xen/arch/ia64/process.c	Wed Jun 22 17:46:00 2005 +0000
     7.2 +++ b/xen/arch/ia64/process.c	Thu Jun 23 18:59:01 2005 +0000
     7.3 @@ -191,8 +191,8 @@ void reflect_interruption(unsigned long 
     7.4  		if (vector != IA64_DATA_TLB_VECTOR &&
     7.5  		    vector != IA64_ALT_DATA_TLB_VECTOR &&
     7.6  		    vector != IA64_VHPT_TRANS_VECTOR) {
     7.7 -panic_domain(regs,"psr.ic off, delivering fault=%lx,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n",
     7.8 -	vector,regs->cr_iip,ifa,isr,PSCB(v,iip));
     7.9 +panic_domain(regs,"psr.ic off, delivering fault=%lx,ipsr=%p,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n",
    7.10 +	vector,regs->cr_ipsr,regs->cr_iip,ifa,isr,PSCB(v,iip));
    7.11  			
    7.12  		}
    7.13  //printf("Delivering NESTED DATA TLB fault\n");
    7.14 @@ -754,7 +754,8 @@ if (!running_on_sim) { printf("SSC_OPEN,
    7.15  		vcpu_set_gr(current,8,-1L);
    7.16  		break;
    7.17  	    default:
    7.18 -		printf("ia64_handle_break: bad ssc code %lx, iip=%p, b0=%p\n",ssc,regs->cr_iip,regs->b0);
    7.19 +		printf("ia64_handle_break: bad ssc code %lx, iip=%p, b0=%p... spinning\n",ssc,regs->cr_iip,regs->b0);
    7.20 +		while(1);
    7.21  		break;
    7.22  	}
    7.23  	vcpu_increment_iip(current);
    7.24 @@ -845,6 +846,7 @@ ia64_handle_reflection (unsigned long if
    7.25  		break;
    7.26  	    case 26:
    7.27  printf("*** NaT fault... attempting to handle as privop\n");
    7.28 +printf("isr=%p, ifa=%p,iip=%p,ipsr=%p\n",isr,ifa,regs->cr_iip,psr);
    7.29  		vector = priv_emulate(v,regs,isr);
    7.30  		if (vector == IA64_NO_FAULT) {
    7.31  printf("*** Handled privop masquerading as NaT fault\n");