[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] ia64: Add fast reflection for most clock ticks
ChangeSet 1.1726.1.6, 2005/06/23 12:59:01-06:00, djm@xxxxxxxxxxxxxxx ia64: Add fast reflection for most clock ticks Also, some additional debug output for various situations. Signed-off-by: Dan Magenheimer <dan.magenheimer@xxxxxx> asm-offsets.c | 1 domain.c | 2 hypercall.c | 3 hyperprivop.S | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- ivt.S | 20 +++++ privop.c | 1 process.c | 8 +- 7 files changed, 220 insertions(+), 13 deletions(-) diff -Nru a/xen/arch/ia64/asm-offsets.c b/xen/arch/ia64/asm-offsets.c --- a/xen/arch/ia64/asm-offsets.c 2005-06-29 18:03:06 -04:00 +++ b/xen/arch/ia64/asm-offsets.c 2005-06-29 18:03:06 -04:00 @@ -88,6 +88,7 @@ BLANK(); DEFINE(IA64_CPUINFO_ITM_NEXT_OFFSET, offsetof (struct cpuinfo_ia64, itm_next)); + DEFINE(IA64_CPUINFO_PGD_QUICK_OFFSET, offsetof (struct cpuinfo_ia64, pgd_quick)); //DEFINE(IA64_SIGHAND_SIGLOCK_OFFSET,offsetof (struct sighand_struct, siglock)); diff -Nru a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c --- a/xen/arch/ia64/domain.c 2005-06-29 18:03:06 -04:00 +++ b/xen/arch/ia64/domain.c 2005-06-29 18:03:06 -04:00 @@ -50,7 +50,7 @@ //FIXME: alignment should be 256MB, lest Linux use a 256MB page size unsigned long dom0_align = 256*1024*1024; #else // CONFIG_VTI -unsigned long dom0_size = 256*1024*1024; //FIXME: Should be configurable +unsigned long dom0_size = 512*1024*1024; //FIXME: Should be configurable //FIXME: alignment should be 256MB, lest Linux use a 256MB page size unsigned long dom0_align = 64*1024*1024; #endif // CONFIG_VTI diff -Nru a/xen/arch/ia64/hypercall.c b/xen/arch/ia64/hypercall.c --- a/xen/arch/ia64/hypercall.c 2005-06-29 18:03:06 -04:00 +++ b/xen/arch/ia64/hypercall.c 2005-06-29 18:03:06 -04:00 @@ -43,7 +43,8 @@ #if 1 #define SPURIOUS_VECTOR 15 if (vcpu_check_pending_interrupts(v)!=SPURIOUS_VECTOR) { -//printf("Domain trying to go idle when interrupt pending!\n"); +// int pi = vcpu_check_pending_interrupts(v); +//printf("idle w/int#%d pending!\n",pi); //this shouldn't happen, but it apparently does quite a bit! so don't //allow it to happen... i.e. if a domain has an interrupt pending and //it tries to halt itself because it thinks it is idle, just return here diff -Nru a/xen/arch/ia64/hyperprivop.S b/xen/arch/ia64/hyperprivop.S --- a/xen/arch/ia64/hyperprivop.S 2005-06-29 18:03:06 -04:00 +++ b/xen/arch/ia64/hyperprivop.S 2005-06-29 18:03:06 -04:00 @@ -17,6 +17,10 @@ #define FAST_HYPERPRIVOP_CNT #define FAST_REFLECT_CNT +// FIXME: This is defined in include/asm-ia64/hw_irq.h but this +// doesn't appear to be include'able from assembly? +#define IA64_TIMER_VECTOR 0xef + // Should be included from common header file (also in process.c) // NO PSR_CLR IS DIFFERENT! (CPL) #define IA64_PSR_CPL1 (__IA64_UL(1) << IA64_PSR_CPL1_BIT) @@ -241,14 +245,23 @@ adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18; adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;; bsw.1;; - st8 [r2]=r16,16; st8 [r3]=r17,16 ;; - st8 [r2]=r18,16; st8 [r3]=r19,16 ;; - st8 [r2]=r20,16; st8 [r3]=r21,16 ;; - st8 [r2]=r22,16; st8 [r3]=r23,16 ;; - st8 [r2]=r24,16; st8 [r3]=r25,16 ;; - st8 [r2]=r26,16; st8 [r3]=r27,16 ;; - st8 [r2]=r28,16; st8 [r3]=r29,16 ;; - st8 [r2]=r30,16; st8 [r3]=r31,16 ;; + // FIXME: need to handle ar.unat! + .mem.offset 0,0; st8.spill [r2]=r16,16; + .mem.offset 8,0; st8.spill [r3]=r17,16 ;; + .mem.offset 0,0; st8.spill [r2]=r18,16; + .mem.offset 8,0; st8.spill [r3]=r19,16 ;; + .mem.offset 0,0; st8.spill [r2]=r20,16; + .mem.offset 8,0; st8.spill [r3]=r21,16 ;; + .mem.offset 0,0; st8.spill [r2]=r22,16; + .mem.offset 8,0; st8.spill [r3]=r23,16 ;; + .mem.offset 0,0; st8.spill [r2]=r24,16; + .mem.offset 8,0; st8.spill [r3]=r25,16 ;; + .mem.offset 0,0; st8.spill [r2]=r26,16; + .mem.offset 8,0; st8.spill [r3]=r27,16 ;; + .mem.offset 0,0; st8.spill [r2]=r28,16; + .mem.offset 8,0; st8.spill [r3]=r29,16 ;; + .mem.offset 0,0; st8.spill [r2]=r30,16; + .mem.offset 8,0; st8.spill [r3]=r31,16 ;; movl r31=XSI_IPSR;; bsw.0 ;; mov r2=r30; mov r3=r29;; @@ -257,6 +270,175 @@ mov pr=r31,-1 ;; rfi ;; + +// reflect domain clock interrupt +// r31 == pr +// r30 == cr.ivr +// r29 == rp +GLOBAL_ENTRY(fast_tick_reflect) +#define FAST_TICK +#ifndef FAST_TICK + br.cond.sptk.many rp;; +#endif + mov r28=IA64_TIMER_VECTOR;; + cmp.ne p6,p0=r28,r30 +(p6) br.cond.sptk.many rp;; + movl r20=(PERCPU_ADDR)+IA64_CPUINFO_ITM_NEXT_OFFSET;; + ld8 r21=[r20];; + mov r27=ar.itc;; + cmp.ltu p6,p0=r21,r27 +(p6) br.cond.sptk.many rp;; + mov r17=cr.ipsr;; + // slow path if: ipsr.be==1, ipsr.pp==1 + extr.u r21=r17,IA64_PSR_BE_BIT,1 ;; + cmp.ne p6,p0=r21,r0 +(p6) br.cond.sptk.many rp;; + extr.u r21=r17,IA64_PSR_PP_BIT,1 ;; + cmp.ne p6,p0=r21,r0 +(p6) br.cond.sptk.many rp;; +#ifdef FAST_REFLECT_CNT + movl r20=fast_reflect_count+((0x3000>>8)*8);; + ld8 r21=[r20];; + adds r21=1,r21;; + st8 [r20]=r21;; +#endif + mov cr.eoi=r0;; + mov rp=r29;; + // vcpu_pend_timer(current) + movl r18=XSI_PSR_IC;; + adds r20=XSI_ITV_OFS-XSI_PSR_IC_OFS,r18 ;; + ld8 r20=[r20];; + cmp.eq p6,p0=r20,r0 // if cr.itv==0 done +(p6) br.cond.sptk.many fast_tick_reflect_done;; + tbit.nz p6,p0=r20,16;; // check itv.m (discard) bit +(p6) br.cond.sptk.many fast_tick_reflect_done;; + extr.u r27=r20,0,6 // r27 has low 6 bits of itv.vector + extr.u r26=r20,6,2;; // r26 has irr index of itv.vector + mov r19=IA64_KR(CURRENT);; + adds r22=IA64_VCPU_DOMAIN_ITM_LAST_OFFSET,r19 + adds r23=IA64_VCPU_DOMAIN_ITM_OFFSET,r19;; + ld8 r24=[r22];; + ld8 r23=[r23];; + cmp.eq p6,p0=r23,r24 // skip if this tick already delivered +(p6) br.cond.sptk.many fast_tick_reflect_done;; + // set irr bit + adds r21=IA64_VCPU_IRR0_OFFSET,r19; + shl r26=r26,3;; + add r21=r21,r26;; + mov r25=1;; + shl r22=r25,r27;; + ld8 r23=[r21];; + or r22=r22,r23;; + st8 [r21]=r22;; + // set PSCB(pending_interruption)! + adds r20=XSI_PEND_OFS-XSI_PSR_IC_OFS,r18 ;; + st4 [r20]=r25;; + + // if interrupted at pl0, we're done + extr.u r16=r17,IA64_PSR_CPL0_BIT,2;; + cmp.eq p6,p0=r16,r0;; +(p6) br.cond.sptk.many fast_tick_reflect_done;; + // now deliver to iva+0x3000 + // r17 == cr.ipsr + // r18 == XSI_PSR_IC + // r19 == IA64_KR(CURRENT) + // r31 == pr + + // if guest vpsr.i is off, we're done + adds r21=XSI_PSR_I_OFS-XSI_PSR_IC_OFS,r18 ;; + ld4 r21=[r21];; + cmp.eq p6,p0=r21,r0 +(p6) br.cond.sptk.many fast_tick_reflect_done;; + + // OK, we have a clock tick to deliver to the active domain! + mov r16=cr.isr;; + mov r29=cr.iip;; + adds r21=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;; + st8 [r21]=r29 ;; + // set shared_mem isr + extr.u r16=r16,38,1;; // grab cr.isr.ir bit + dep r16=r16,r0,38,1 ;; // insert into cr.isr (rest of bits zero) + extr.u r20=r17,41,2 ;; // get ipsr.ri + dep r16=r20,r16,41,2 ;; // deposit cr.isr.ei + adds r21=XSI_ISR_OFS-XSI_PSR_IC_OFS,r18 ;; + st8 [r21]=r16 ;; + // set cr.ipsr (make sure cpl==2!) + mov r29=r17 ;; + movl r28=DELIVER_PSR_SET;; + movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);; + or r29=r29,r28;; + and r29=r29,r27;; + mov cr.ipsr=r29;; + // set shared_mem ipsr (from ipsr in r17 with ipsr.ri already set) + extr.u r29=r17,IA64_PSR_CPL0_BIT,2;; + cmp.eq p6,p7=3,r29;; +(p6) dep r17=-1,r17,IA64_PSR_CPL0_BIT,2 +(p7) dep r17=0,r17,IA64_PSR_CPL0_BIT,2 + ;; + movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT);; + movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN|IA64_PSR_I|IA64_PSR_IC);; + dep r21=-1,r21,IA64_PSR_CPL1_BIT,1 ;; + or r17=r17,r28;; + and r17=r17,r27;; + ld4 r16=[r18],4;; + cmp.ne p6,p0=r16,r0;; +(p6) dep r17=-1,r17,IA64_PSR_IC_BIT,1 ;; + ld4 r16=[r18],-4;; + cmp.ne p6,p0=r16,r0;; +(p6) dep r17=-1,r17,IA64_PSR_I_BIT,1 ;; + adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;; + st8 [r21]=r17 ;; + // set shared_mem interrupt_delivery_enabled to 0 + // set shared_mem interrupt_collection_enabled to 0 + st8 [r18]=r0;; + // cover and set shared_mem precover_ifs to cr.ifs + // set shared_mem ifs and incomplete_regframe to 0 + cover ;; + mov r20=cr.ifs;; + adds r21=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;; + st4 [r21]=r0 ;; + adds r21=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;; + st8 [r21]=r0 ;; + adds r21=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;; + st8 [r21]=r20 ;; + // leave cr.ifs alone for later rfi + // set iip to go to domain IVA break instruction vector + adds r22=IA64_VCPU_IVA_OFFSET,r19;; + ld8 r23=[r22];; + movl r24=0x3000;; + add r24=r24,r23;; + mov cr.iip=r24;; + // OK, now all set to go except for switch to virtual bank0 + mov r30=r2; mov r29=r3;; + adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18; + adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;; + bsw.1;; + // FIXME: need to handle ar.unat! + .mem.offset 0,0; st8.spill [r2]=r16,16; + .mem.offset 8,0; st8.spill [r3]=r17,16 ;; + .mem.offset 0,0; st8.spill [r2]=r18,16; + .mem.offset 8,0; st8.spill [r3]=r19,16 ;; + .mem.offset 0,0; st8.spill [r2]=r20,16; + .mem.offset 8,0; st8.spill [r3]=r21,16 ;; + .mem.offset 0,0; st8.spill [r2]=r22,16; + .mem.offset 8,0; st8.spill [r3]=r23,16 ;; + .mem.offset 0,0; st8.spill [r2]=r24,16; + .mem.offset 8,0; st8.spill [r3]=r25,16 ;; + .mem.offset 0,0; st8.spill [r2]=r26,16; + .mem.offset 8,0; st8.spill [r3]=r27,16 ;; + .mem.offset 0,0; st8.spill [r2]=r28,16; + .mem.offset 8,0; st8.spill [r3]=r29,16 ;; + .mem.offset 0,0; st8.spill [r2]=r30,16; + .mem.offset 8,0; st8.spill [r3]=r31,16 ;; + movl r31=XSI_IPSR;; + bsw.0 ;; + mov r2=r30; mov r3=r29;; + adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;; + st4 [r20]=r0 ;; +fast_tick_reflect_done: + mov pr=r31,-1 ;; + rfi +END(fast_tick_reflect) // reflect domain breaks directly to domain // FIXME: DOES NOT WORK YET diff -Nru a/xen/arch/ia64/ivt.S b/xen/arch/ia64/ivt.S --- a/xen/arch/ia64/ivt.S 2005-06-29 18:03:06 -04:00 +++ b/xen/arch/ia64/ivt.S 2005-06-29 18:03:06 -04:00 @@ -919,6 +919,21 @@ DBG_FAULT(12) mov r31=pr // prepare to save predicates ;; +#ifdef XEN + mov r30=cr.ivr // pass cr.ivr as first arg + // FIXME: this is a hack... use cpuinfo.pgd_quick because its + // not used anywhere else and we need a place to stash ivr and + // there's no registers available unused by SAVE_MIN/REST + movl r29=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;; + st8 [r29]=r30;; + movl r28=slow_interrupt;; + mov r29=rp;; + mov rp=r28;; + br.cond.sptk.many fast_tick_reflect + ;; +slow_interrupt: + mov rp=r29;; +#endif SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 ssm psr.ic | PSR_DEFAULT_BITS ;; @@ -928,7 +943,12 @@ SAVE_REST ;; alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group +#ifdef XEN + movl out0=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;; + ld8 out0=[out0];; +#else mov out0=cr.ivr // pass cr.ivr as first arg +#endif add out1=16,sp // pass pointer to pt_regs as second arg ;; srlz.d // make sure we see the effect of cr.ivr diff -Nru a/xen/arch/ia64/privop.c b/xen/arch/ia64/privop.c --- a/xen/arch/ia64/privop.c 2005-06-29 18:03:06 -04:00 +++ b/xen/arch/ia64/privop.c 2005-06-29 18:03:06 -04:00 @@ -781,6 +781,7 @@ // FIXME: Handle faults appropriately for these if (!iim || iim > HYPERPRIVOP_MAX) { printf("bad hyperprivop; ignored\n"); + printf("iim=%d, iip=%p\n",iim,regs->cr_iip); return 1; } slow_hyperpriv_cnt[iim]++; diff -Nru a/xen/arch/ia64/process.c b/xen/arch/ia64/process.c --- a/xen/arch/ia64/process.c 2005-06-29 18:03:06 -04:00 +++ b/xen/arch/ia64/process.c 2005-06-29 18:03:06 -04:00 @@ -191,8 +191,8 @@ if (vector != IA64_DATA_TLB_VECTOR && vector != IA64_ALT_DATA_TLB_VECTOR && vector != IA64_VHPT_TRANS_VECTOR) { -panic_domain(regs,"psr.ic off, delivering fault=%lx,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n", - vector,regs->cr_iip,ifa,isr,PSCB(v,iip)); +panic_domain(regs,"psr.ic off, delivering fault=%lx,ipsr=%p,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n", + vector,regs->cr_ipsr,regs->cr_iip,ifa,isr,PSCB(v,iip)); } //printf("Delivering NESTED DATA TLB fault\n"); @@ -754,7 +754,8 @@ vcpu_set_gr(current,8,-1L); break; default: - printf("ia64_handle_break: bad ssc code %lx, iip=%p, b0=%p\n",ssc,regs->cr_iip,regs->b0); + printf("ia64_handle_break: bad ssc code %lx, iip=%p, b0=%p... spinning\n",ssc,regs->cr_iip,regs->b0); + while(1); break; } vcpu_increment_iip(current); @@ -845,6 +846,7 @@ break; case 26: printf("*** NaT fault... attempting to handle as privop\n"); +printf("isr=%p, ifa=%p,iip=%p,ipsr=%p\n",isr,ifa,regs->cr_iip,psr); vector = priv_emulate(v,regs,isr); if (vector == IA64_NO_FAULT) { printf("*** Handled privop masquerading as NaT fault\n"); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |