# HG changeset patch # User tristan.gingold@xxxxxxxx # Node ID 79450354e4840e08c387620521598a5db0c2069c # Parent 8acef8c0ff82f4e44550cf113eadff00bcd5696a mmio.c: handle more instructions (stf8, stf.spill, lfetch). vcpu_get_fpreg added. Signed-off-by: Tristan Gingold diff -r 8acef8c0ff82 -r 79450354e484 xen/arch/ia64/linux-xen/unaligned.c --- a/xen/arch/ia64/linux-xen/unaligned.c Thu Apr 13 08:05:23 2006 +++ b/xen/arch/ia64/linux-xen/unaligned.c Thu Apr 13 08:18:24 2006 @@ -216,7 +216,6 @@ RPT(r28), RPT(r29), RPT(r30), RPT(r31) }; -#ifndef XEN static u16 fr_info[32]={ 0, /* constant : WE SHOULD NEVER GET THIS */ 0, /* constant : WE SHOULD NEVER GET THIS */ @@ -233,6 +232,7 @@ RSW(f30), RSW(f31) }; +#ifndef XEN /* Invalidate ALAT entry for integer register REGNO. */ static void invala_gr (int regno) @@ -700,8 +700,11 @@ ia64_stf_spill(final, 1); } -#ifndef XEN +#ifdef XEN +void +#else static void +#endif getfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs) { struct switch_stack *sw = (struct switch_stack *) regs - 1; @@ -750,8 +753,6 @@ } } } -#endif /* XEN */ - #ifdef XEN void diff -r 8acef8c0ff82 -r 79450354e484 xen/arch/ia64/vmx/mmio.c --- a/xen/arch/ia64/vmx/mmio.c Thu Apr 13 08:05:23 2006 +++ b/xen/arch/ia64/vmx/mmio.c Thu Apr 13 08:18:24 2006 @@ -473,14 +473,64 @@ } } - // Floating-point Load/Store + // Floating-point spill + Imm update + else if(inst.M10.major==7&&inst.M10.x6==0x3B){ + struct ia64_fpreg v; + inst_type=SL_FLOATING; + dir=IOREQ_WRITE; + vcpu_get_fpreg(vcpu,inst.M10.f2,&v); + vcpu_get_gr_nat(vcpu,inst.M10.r3,&temp); + post_update = (inst.M10.i<<7)+inst.M10.imm7; + if(inst.M10.s) + temp -= post_update; + else + temp += post_update; + vcpu_set_gr(vcpu,inst.M10.r3,temp,0); + + /* Write high word. + FIXME: this is a kludge! */ + v.u.bits[1] &= 0x3ffff; + mmio_access(vcpu, padr + 8, &v.u.bits[1], 8, ma, IOREQ_WRITE); + data = v.u.bits[0]; + size = 3; + } + // Floating-point stf8 + Imm update + else if(inst.M10.major==7&&inst.M10.x6==0x31){ + struct ia64_fpreg v; + inst_type=SL_FLOATING; + dir=IOREQ_WRITE; + size=3; + vcpu_get_fpreg(vcpu,inst.M10.f2,&v); + data = v.u.bits[0]; /* Significand. */ + vcpu_get_gr_nat(vcpu,inst.M10.r3,&temp); + post_update = (inst.M10.i<<7)+inst.M10.imm7; + if(inst.M10.s) + temp -= post_update; + else + temp += post_update; + vcpu_set_gr(vcpu,inst.M10.r3,temp,0); + } // else if(inst.M6.major==6&&inst.M6.m==0&&inst.M6.x==0&&inst.M6.x6==3){ // inst_type=SL_FLOATING; //fp // dir=IOREQ_READ; // size=3; //ldfd // } + // lfetch - do not perform accesses. + else if(inst.M15.major==7&&inst.M15.x6>=0x2c&&inst.M15.x6<=0x2f){ + vcpu_get_gr_nat(vcpu,inst.M15.r3,&temp); + post_update = (inst.M15.i<<7)+inst.M15.imm7; + if(inst.M15.s) + temp -= post_update; + else + temp += post_update; + vcpu_set_gr(vcpu,inst.M15.r3,temp,0); + + vmx_vcpu_increment_iip(vcpu); + return; + } else{ - printf("This memory access instruction can't be emulated two: %lx\n ",inst.inst); + printf("This memory access instr can't be emulated: %lx pc=%lx\n ", + inst.inst, regs->cr_iip); while(1); } diff -r 8acef8c0ff82 -r 79450354e484 xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Thu Apr 13 08:05:23 2006 +++ b/xen/arch/ia64/xen/vcpu.c Thu Apr 13 08:18:24 2006 @@ -22,6 +22,8 @@ /* FIXME: where these declarations should be there ? */ extern void getreg(unsigned long regnum, unsigned long *val, int *nat, struct pt_regs *regs); extern void setreg(unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs); +extern void getfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs); + extern void panic_domain(struct pt_regs *, const char *, ...); extern unsigned long translate_domain_pte(UINT64,UINT64,UINT64); extern unsigned long translate_domain_mpaddr(unsigned long); @@ -104,6 +106,15 @@ setreg(reg,value,nat,regs); // FIXME: handle NATs later return IA64_NO_FAULT; } + +IA64FAULT +vcpu_get_fpreg(VCPU *vcpu, unsigned long reg, struct ia64_fpreg *val) +{ + REGS *regs = vcpu_regs(vcpu); + getfpreg(reg,val,regs); // FIXME: handle NATs later + return 0; +} + #else // returns: // IA64_ILLOP_FAULT if the register would cause an Illegal Operation fault diff -r 8acef8c0ff82 -r 79450354e484 xen/include/asm-ia64/privop.h --- a/xen/include/asm-ia64/privop.h Thu Apr 13 08:05:23 2006 +++ b/xen/include/asm-ia64/privop.h Thu Apr 13 08:18:24 2006 @@ -169,6 +169,21 @@ IA64_INST inst; struct { unsigned long qp:6, f1:7, un7:7, r3:7, x:1, hint:2, x6:6, m:1, major:4; }; } INST64_M6; + +typedef union U_INST64_M9 { + IA64_INST inst; + struct { unsigned long qp:6, :7, f2:7, r3:7, x:1, hint:2, x6:6, m:1, major:4; }; +} INST64_M9; + +typedef union U_INST64_M10 { + IA64_INST inst; + struct { unsigned long qp:6, imm7:7, f2:7, r3:7, i:1, hint:2, x6:6, s:1, major:4; }; +} INST64_M10; + +typedef union U_INST64_M15 { + IA64_INST inst; + struct { unsigned long qp:6, :7, imm7:7, r3:7, i:1, hint:2, x6:6, s:1, major:4; }; +} INST64_M15; typedef union U_INST64 { IA64_INST inst; @@ -187,6 +202,9 @@ INST64_M4 M4; // st integer INST64_M5 M5; INST64_M6 M6; // ldfd floating pointer + INST64_M9 M9; // stfd floating pointer + INST64_M10 M10; // stfd floating pointer + INST64_M15 M15; // lfetch + imm update INST64_M28 M28; // purge translation cache entry INST64_M29 M29; // mov register to ar (M unit) INST64_M30 M30; // mov immediate to ar (M unit) diff -r 8acef8c0ff82 -r 79450354e484 xen/include/asm-ia64/vcpu.h --- a/xen/include/asm-ia64/vcpu.h Thu Apr 13 08:05:23 2006 +++ b/xen/include/asm-ia64/vcpu.h Thu Apr 13 08:18:24 2006 @@ -40,6 +40,8 @@ extern UINT64 vcpu_get_gr(VCPU *vcpu, unsigned long reg); extern IA64FAULT vcpu_get_gr_nat(VCPU *vcpu, unsigned long reg, UINT64 *val); extern IA64FAULT vcpu_set_gr(VCPU *vcpu, unsigned long reg, UINT64 value, int nat); +extern IA64FAULT vcpu_get_fpreg(VCPU *vcpu, unsigned long reg, struct ia64_fpreg *val); + /* application registers */ extern void vcpu_load_kernel_regs(VCPU *vcpu); extern IA64FAULT vcpu_set_ar(VCPU *vcpu, UINT64 reg, UINT64 val);