# HG changeset patch # User tristan.gingold@xxxxxxxx # Node ID 0771620083f2a53354b8ed4146938a9349a825f5 # Parent ff9552fc3bcfb46da5e6cde2d16e1ec85c951e56 getfpregs rewritten for Xen. mmio.c: handle more instructions, panic replaced by panic_domain. Signed-off-by: Tristan Gingold diff -r ff9552fc3bcf -r 0771620083f2 xen/arch/ia64/Rules.mk --- a/xen/arch/ia64/Rules.mk Fri Apr 14 05:25:28 2006 +++ b/xen/arch/ia64/Rules.mk Fri Apr 14 07:14:22 2006 @@ -28,7 +28,7 @@ -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen #CFLAGS += -Wno-pointer-arith -Wredundant-decls CFLAGS += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY -CFLAGS += -ffixed-r13 -mfixed-range=f12-f15,f32-f127 +CFLAGS += -ffixed-r13 -mfixed-range=f2-f5,f12-f127 CFLAGS += -g #CFLAGS += -DVTI_DEBUG ifeq ($(VALIDATE_VT),y) diff -r ff9552fc3bcf -r 0771620083f2 xen/arch/ia64/linux-xen/unaligned.c --- a/xen/arch/ia64/linux-xen/unaligned.c Fri Apr 14 05:25:28 2006 +++ b/xen/arch/ia64/linux-xen/unaligned.c Fri Apr 14 07:14:22 2006 @@ -750,6 +750,154 @@ } } } +#else +void +getfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs) +{ +#define CASE_FIXED_FP(reg) \ + case reg: \ + ia64_stf_spill(fpval,reg); \ + break +#define CASE_SAVED_FP(reg) \ + case reg: \ + fpval->u.bits[0] = regs->f##reg.u.bits[0]; \ + fpval->u.bits[1] = regs->f##reg.u.bits[1]; \ + break + switch(regnum) { + CASE_FIXED_FP(0); + CASE_FIXED_FP(1); + CASE_FIXED_FP(2); + CASE_FIXED_FP(3); + CASE_FIXED_FP(4); + CASE_FIXED_FP(5); + + CASE_SAVED_FP(6); + CASE_SAVED_FP(7); + CASE_SAVED_FP(8); + CASE_SAVED_FP(9); + CASE_SAVED_FP(10); + CASE_SAVED_FP(11); + + CASE_FIXED_FP(12); + CASE_FIXED_FP(13); + CASE_FIXED_FP(14); + CASE_FIXED_FP(15); + CASE_FIXED_FP(16); + CASE_FIXED_FP(17); + CASE_FIXED_FP(18); + CASE_FIXED_FP(19); + CASE_FIXED_FP(20); + CASE_FIXED_FP(21); + CASE_FIXED_FP(22); + CASE_FIXED_FP(23); + CASE_FIXED_FP(24); + CASE_FIXED_FP(25); + CASE_FIXED_FP(26); + CASE_FIXED_FP(27); + CASE_FIXED_FP(28); + CASE_FIXED_FP(29); + CASE_FIXED_FP(30); + CASE_FIXED_FP(31); + CASE_FIXED_FP(32); + CASE_FIXED_FP(33); + CASE_FIXED_FP(34); + CASE_FIXED_FP(35); + CASE_FIXED_FP(36); + CASE_FIXED_FP(37); + CASE_FIXED_FP(38); + CASE_FIXED_FP(39); + CASE_FIXED_FP(40); + CASE_FIXED_FP(41); + CASE_FIXED_FP(42); + CASE_FIXED_FP(43); + CASE_FIXED_FP(44); + CASE_FIXED_FP(45); + CASE_FIXED_FP(46); + CASE_FIXED_FP(47); + CASE_FIXED_FP(48); + CASE_FIXED_FP(49); + CASE_FIXED_FP(50); + CASE_FIXED_FP(51); + CASE_FIXED_FP(52); + CASE_FIXED_FP(53); + CASE_FIXED_FP(54); + CASE_FIXED_FP(55); + CASE_FIXED_FP(56); + CASE_FIXED_FP(57); + CASE_FIXED_FP(58); + CASE_FIXED_FP(59); + CASE_FIXED_FP(60); + CASE_FIXED_FP(61); + CASE_FIXED_FP(62); + CASE_FIXED_FP(63); + CASE_FIXED_FP(64); + CASE_FIXED_FP(65); + CASE_FIXED_FP(66); + CASE_FIXED_FP(67); + CASE_FIXED_FP(68); + CASE_FIXED_FP(69); + CASE_FIXED_FP(70); + CASE_FIXED_FP(71); + CASE_FIXED_FP(72); + CASE_FIXED_FP(73); + CASE_FIXED_FP(74); + CASE_FIXED_FP(75); + CASE_FIXED_FP(76); + CASE_FIXED_FP(77); + CASE_FIXED_FP(78); + CASE_FIXED_FP(79); + CASE_FIXED_FP(80); + CASE_FIXED_FP(81); + CASE_FIXED_FP(82); + CASE_FIXED_FP(83); + CASE_FIXED_FP(84); + CASE_FIXED_FP(85); + CASE_FIXED_FP(86); + CASE_FIXED_FP(87); + CASE_FIXED_FP(88); + CASE_FIXED_FP(89); + CASE_FIXED_FP(90); + CASE_FIXED_FP(91); + CASE_FIXED_FP(92); + CASE_FIXED_FP(93); + CASE_FIXED_FP(94); + CASE_FIXED_FP(95); + CASE_FIXED_FP(96); + CASE_FIXED_FP(97); + CASE_FIXED_FP(98); + CASE_FIXED_FP(99); + CASE_FIXED_FP(100); + CASE_FIXED_FP(101); + CASE_FIXED_FP(102); + CASE_FIXED_FP(103); + CASE_FIXED_FP(104); + CASE_FIXED_FP(105); + CASE_FIXED_FP(106); + CASE_FIXED_FP(107); + CASE_FIXED_FP(108); + CASE_FIXED_FP(109); + CASE_FIXED_FP(110); + CASE_FIXED_FP(111); + CASE_FIXED_FP(112); + CASE_FIXED_FP(113); + CASE_FIXED_FP(114); + CASE_FIXED_FP(115); + CASE_FIXED_FP(116); + CASE_FIXED_FP(117); + CASE_FIXED_FP(118); + CASE_FIXED_FP(119); + CASE_FIXED_FP(120); + CASE_FIXED_FP(121); + CASE_FIXED_FP(122); + CASE_FIXED_FP(123); + CASE_FIXED_FP(124); + CASE_FIXED_FP(125); + CASE_FIXED_FP(126); + CASE_FIXED_FP(127); + } +#undef CASE_FIXED_FP +#undef CASE_SAVED_FP +} #endif /* XEN */ diff -r ff9552fc3bcf -r 0771620083f2 xen/arch/ia64/vmx/mmio.c --- a/xen/arch/ia64/vmx/mmio.c Fri Apr 14 05:25:28 2006 +++ b/xen/arch/ia64/vmx/mmio.c Fri Apr 14 07:14:22 2006 @@ -57,20 +57,21 @@ { switch (pib_off) { case PIB_OFST_INTA: - panic("Undefined write on PIB INTA\n"); + panic_domain(NULL,"Undefined write on PIB INTA\n"); break; case PIB_OFST_XTP: if ( s == 1 && ma == 4 /* UC */) { vmx_vcpu_get_plat(vcpu)->xtp = *(uint8_t *)src; } else { - panic("Undefined write on PIB XTP\n"); + panic_domain(NULL,"Undefined write on PIB XTP\n"); } break; default: if ( PIB_LOW_HALF(pib_off) ) { // lower half if ( s != 8 || ma != 0x4 /* UC */ ) { - panic("Undefined IPI-LHF write with s %ld, ma %d!\n", s, ma); + panic_domain + (NULL,"Undefined IPI-LHF write with s %ld, ma %d!\n", s, ma); } else { write_ipi(vcpu, pib_off, *(uint64_t *)src); @@ -79,7 +80,7 @@ } else { // upper half printf("IPI-UHF write %lx\n",pib_off); - panic("Not support yet for SM-VP\n"); + panic_domain(NULL,"Not support yet for SM-VP\n"); } break; } @@ -94,7 +95,7 @@ // TODO: INTA read from IOSAPIC } else { - panic("Undefined read on PIB INTA\n"); + panic_domain(NULL,"Undefined read on PIB INTA\n"); } break; case PIB_OFST_XTP: @@ -102,13 +103,13 @@ *((uint8_t*)dest) = vmx_vcpu_get_plat(vcpu)->xtp; } else { - panic("Undefined read on PIB XTP\n"); + panic_domain(NULL,"Undefined read on PIB XTP\n"); } break; default: if ( PIB_LOW_HALF(pib_off) ) { // lower half if ( s != 8 || ma != 4 ) { - panic("Undefined IPI-LHF read!\n"); + panic_domain(NULL,"Undefined IPI-LHF read!\n"); } else { #ifdef IPI_DEBUG @@ -119,7 +120,7 @@ } else { // upper half if ( s != 1 || ma != 4 ) { - panic("Undefined PIB-UHF read!\n"); + panic_domain(NULL,"Undefined PIB-UHF read!\n"); } else { #ifdef IPI_DEBUG @@ -140,7 +141,7 @@ vio = get_vio(v->domain, v->vcpu_id); if (vio == 0) { - panic("bad shared page: %lx", (unsigned long)vio); + panic_domain(NULL,"bad shared page: %lx", (unsigned long)vio); } p = &vio->vp_ioreq; p->addr = pa; @@ -172,7 +173,7 @@ vio = get_vio(v->domain, v->vcpu_id); if (vio == 0) { - panic("bad shared page\n"); + panic_domain(NULL,"bad shared page\n"); } p = &vio->vp_ioreq; p->addr = TO_LEGACY_IO(pa&0x3ffffffUL); @@ -237,7 +238,7 @@ legacy_io_access(vcpu, src_pa, dest, s, dir); break; default: - panic("Bad I/O access\n"); + panic_domain(NULL,"Bad I/O access\n"); break; } return; @@ -285,7 +286,7 @@ uint64_t pa; if (!vtlb->nomap) - panic("Normal memory write shouldn't go to this point!"); + panic_domain(NULL,"Normal memory write shouldn't go to this point!"); pa = PPN_2_PA(vtlb->ppn); pa += POFFSET((u64)src, vtlb->ps); @@ -329,14 +330,14 @@ break; case 2: // PMI // TODO -- inject guest PMI - panic ("Inject guest PMI!\n"); + panic_domain (NULL, "Inject guest PMI!\n"); break; case 4: // NMI vmx_vcpu_pend_interrupt (vcpu, 2); break; case 5: // INIT // TODO -- inject guest INIT - panic ("Inject guest INIT!\n"); + panic_domain (NULL, "Inject guest INIT!\n"); break; case 7: // ExtINT vmx_vcpu_pend_interrupt (vcpu, 0); @@ -345,7 +346,7 @@ case 3: case 6: default: - panic ("Deliver reserved IPI!\n"); + panic_domain (NULL, "Deliver reserved IPI!\n"); break; } } @@ -379,7 +380,7 @@ target_cpu = lid_2_vcpu(vcpu->domain, ((ipi_a_t)addr).id, ((ipi_a_t)addr).eid); - if ( target_cpu == NULL ) panic("Unknown IPI cpu\n"); + if ( target_cpu == NULL ) panic_domain (NULL,"Unknown IPI cpu\n"); if ( target_cpu == vcpu ) { // IPI to self deliver_ipi (vcpu, ((ipi_d_t)value).dm, @@ -388,7 +389,7 @@ } else { // TODO: send Host IPI to inject guest SMP IPI interruption - panic ("No SM-VP supported!\n"); + panic_domain (NULL, "No SM-VP supported!\n"); return 0; } } @@ -473,15 +474,65 @@ } } - // 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); - while(1); + panic_domain + (NULL,"This memory access instr can't be emulated: %lx pc=%lx\n ", + inst.inst, regs->cr_iip); } size = 1 << size; @@ -499,7 +550,7 @@ if(inst_type==SL_INTEGER){ //gp vcpu_set_gr(vcpu,inst.M1.r1,data,0); }else{ - panic("Don't support ldfd now !"); + panic_domain(NULL, "Don't support ldfd now !"); /* switch(inst.M6.f1){ case 6: diff -r ff9552fc3bcf -r 0771620083f2 xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Fri Apr 14 05:25:28 2006 +++ b/xen/arch/ia64/xen/vcpu.c Fri Apr 14 07:14:22 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 ff9552fc3bcf -r 0771620083f2 xen/include/asm-ia64/privop.h --- a/xen/include/asm-ia64/privop.h Fri Apr 14 05:25:28 2006 +++ b/xen/include/asm-ia64/privop.h Fri Apr 14 07:14:22 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 ff9552fc3bcf -r 0771620083f2 xen/include/asm-ia64/vcpu.h --- a/xen/include/asm-ia64/vcpu.h Fri Apr 14 05:25:28 2006 +++ b/xen/include/asm-ia64/vcpu.h Fri Apr 14 07:14:22 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);