ia64/xen-unstable

changeset 9764:2d2ef3f4c747

[IA64] emulate ldfp8 in mmio

1. emulate ldpf8 in mmio
2. handle floating point register rotation in functions setfpreg and getfpreg

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author awilliam@localhost
date Tue Apr 25 17:05:16 2006 -0600 (2006-04-25)
parents af32ca486466
children 7c7bcf173f8b
files xen/arch/ia64/linux-xen/unaligned.c xen/arch/ia64/vmx/mmio.c xen/arch/ia64/xen/vcpu.c xen/include/asm-ia64/privop.h xen/include/asm-ia64/vcpu.h
line diff
     1.1 --- a/xen/arch/ia64/linux-xen/unaligned.c	Tue Apr 25 16:55:09 2006 -0600
     1.2 +++ b/xen/arch/ia64/linux-xen/unaligned.c	Tue Apr 25 17:05:16 2006 -0600
     1.3 @@ -754,6 +754,9 @@ getfpreg (unsigned long regnum, struct i
     1.4  void
     1.5  getfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
     1.6  {
     1.7 +	// Take floating register rotation into consideration
     1.8 +	if(regnum >= IA64_FIRST_ROTATING_FR)
     1.9 +		regnum = IA64_FIRST_ROTATING_FR + fph_index(regs, regnum); 
    1.10  #define CASE_FIXED_FP(reg)			\
    1.11  	case reg:				\
    1.12  		ia64_stf_spill(fpval,reg);	\
    1.13 @@ -898,6 +901,161 @@ getfpreg (unsigned long regnum, struct i
    1.14  #undef CASE_FIXED_FP
    1.15  #undef CASE_SAVED_FP
    1.16  }
    1.17 +
    1.18 +
    1.19 +void
    1.20 +setfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
    1.21 +{
    1.22 +	// Take floating register rotation into consideration
    1.23 +	ia64_fph_enable();
    1.24 +	if(regnum >= IA64_FIRST_ROTATING_FR)
    1.25 +		regnum = IA64_FIRST_ROTATING_FR + fph_index(regs, regnum); 
    1.26 +
    1.27 +#define CASE_FIXED_FP(reg)			\
    1.28 +	case reg:				\
    1.29 +		ia64_ldf_fill(reg,fpval);	\
    1.30 +		break
    1.31 +#define CASE_RESTORED_FP(reg)					\
    1.32 +	case reg:						\
    1.33 +		regs->f##reg.u.bits[0] = fpval->u.bits[0]; 	\
    1.34 +		regs->f##reg.u.bits[1] = fpval->u.bits[1] ;	\
    1.35 +		break
    1.36 +	switch(regnum) {
    1.37 +		CASE_FIXED_FP(0);
    1.38 +		CASE_FIXED_FP(1);
    1.39 +		CASE_FIXED_FP(2);
    1.40 +		CASE_FIXED_FP(3);
    1.41 +		CASE_FIXED_FP(4);
    1.42 +		CASE_FIXED_FP(5);
    1.43 +
    1.44 +		CASE_RESTORED_FP(6);
    1.45 +		CASE_RESTORED_FP(7);
    1.46 +		CASE_RESTORED_FP(8);
    1.47 +		CASE_RESTORED_FP(9);
    1.48 +		CASE_RESTORED_FP(10);
    1.49 +		CASE_RESTORED_FP(11);
    1.50 +
    1.51 +		CASE_FIXED_FP(12);
    1.52 +		CASE_FIXED_FP(13);
    1.53 +		CASE_FIXED_FP(14);
    1.54 +		CASE_FIXED_FP(15);
    1.55 +		CASE_FIXED_FP(16);
    1.56 +		CASE_FIXED_FP(17);
    1.57 +		CASE_FIXED_FP(18);
    1.58 +		CASE_FIXED_FP(19);
    1.59 +		CASE_FIXED_FP(20);
    1.60 +		CASE_FIXED_FP(21);
    1.61 +		CASE_FIXED_FP(22);
    1.62 +		CASE_FIXED_FP(23);
    1.63 +		CASE_FIXED_FP(24);
    1.64 +		CASE_FIXED_FP(25);
    1.65 +		CASE_FIXED_FP(26);
    1.66 +		CASE_FIXED_FP(27);
    1.67 +		CASE_FIXED_FP(28);
    1.68 +		CASE_FIXED_FP(29);
    1.69 +		CASE_FIXED_FP(30);
    1.70 +		CASE_FIXED_FP(31);
    1.71 +		CASE_FIXED_FP(32);
    1.72 +		CASE_FIXED_FP(33);
    1.73 +		CASE_FIXED_FP(34);
    1.74 +		CASE_FIXED_FP(35);
    1.75 +		CASE_FIXED_FP(36);
    1.76 +		CASE_FIXED_FP(37);
    1.77 +		CASE_FIXED_FP(38);
    1.78 +		CASE_FIXED_FP(39);
    1.79 +		CASE_FIXED_FP(40);
    1.80 +		CASE_FIXED_FP(41);
    1.81 +		CASE_FIXED_FP(42);
    1.82 +		CASE_FIXED_FP(43);
    1.83 +		CASE_FIXED_FP(44);
    1.84 +		CASE_FIXED_FP(45);
    1.85 +		CASE_FIXED_FP(46);
    1.86 +		CASE_FIXED_FP(47);
    1.87 +		CASE_FIXED_FP(48);
    1.88 +		CASE_FIXED_FP(49);
    1.89 +		CASE_FIXED_FP(50);
    1.90 +		CASE_FIXED_FP(51);
    1.91 +		CASE_FIXED_FP(52);
    1.92 +		CASE_FIXED_FP(53);
    1.93 +		CASE_FIXED_FP(54);
    1.94 +		CASE_FIXED_FP(55);
    1.95 +		CASE_FIXED_FP(56);
    1.96 +		CASE_FIXED_FP(57);
    1.97 +		CASE_FIXED_FP(58);
    1.98 +		CASE_FIXED_FP(59);
    1.99 +		CASE_FIXED_FP(60);
   1.100 +		CASE_FIXED_FP(61);
   1.101 +		CASE_FIXED_FP(62);
   1.102 +		CASE_FIXED_FP(63);
   1.103 +		CASE_FIXED_FP(64);
   1.104 +		CASE_FIXED_FP(65);
   1.105 +		CASE_FIXED_FP(66);
   1.106 +		CASE_FIXED_FP(67);
   1.107 +		CASE_FIXED_FP(68);
   1.108 +		CASE_FIXED_FP(69);
   1.109 +		CASE_FIXED_FP(70);
   1.110 +		CASE_FIXED_FP(71);
   1.111 +		CASE_FIXED_FP(72);
   1.112 +		CASE_FIXED_FP(73);
   1.113 +		CASE_FIXED_FP(74);
   1.114 +		CASE_FIXED_FP(75);
   1.115 +		CASE_FIXED_FP(76);
   1.116 +		CASE_FIXED_FP(77);
   1.117 +		CASE_FIXED_FP(78);
   1.118 +		CASE_FIXED_FP(79);
   1.119 +		CASE_FIXED_FP(80);
   1.120 +		CASE_FIXED_FP(81);
   1.121 +		CASE_FIXED_FP(82);
   1.122 +		CASE_FIXED_FP(83);
   1.123 +		CASE_FIXED_FP(84);
   1.124 +		CASE_FIXED_FP(85);
   1.125 +		CASE_FIXED_FP(86);
   1.126 +		CASE_FIXED_FP(87);
   1.127 +		CASE_FIXED_FP(88);
   1.128 +		CASE_FIXED_FP(89);
   1.129 +		CASE_FIXED_FP(90);
   1.130 +		CASE_FIXED_FP(91);
   1.131 +		CASE_FIXED_FP(92);
   1.132 +		CASE_FIXED_FP(93);
   1.133 +		CASE_FIXED_FP(94);
   1.134 +		CASE_FIXED_FP(95);
   1.135 +		CASE_FIXED_FP(96);
   1.136 +		CASE_FIXED_FP(97);
   1.137 +		CASE_FIXED_FP(98);
   1.138 +		CASE_FIXED_FP(99);
   1.139 +		CASE_FIXED_FP(100);
   1.140 +		CASE_FIXED_FP(101);
   1.141 +		CASE_FIXED_FP(102);
   1.142 +		CASE_FIXED_FP(103);
   1.143 +		CASE_FIXED_FP(104);
   1.144 +		CASE_FIXED_FP(105);
   1.145 +		CASE_FIXED_FP(106);
   1.146 +		CASE_FIXED_FP(107);
   1.147 +		CASE_FIXED_FP(108);
   1.148 +		CASE_FIXED_FP(109);
   1.149 +		CASE_FIXED_FP(110);
   1.150 +		CASE_FIXED_FP(111);
   1.151 +		CASE_FIXED_FP(112);
   1.152 +		CASE_FIXED_FP(113);
   1.153 +		CASE_FIXED_FP(114);
   1.154 +		CASE_FIXED_FP(115);
   1.155 +		CASE_FIXED_FP(116);
   1.156 +		CASE_FIXED_FP(117);
   1.157 +		CASE_FIXED_FP(118);
   1.158 +		CASE_FIXED_FP(119);
   1.159 +		CASE_FIXED_FP(120);
   1.160 +		CASE_FIXED_FP(121);
   1.161 +		CASE_FIXED_FP(122);
   1.162 +		CASE_FIXED_FP(123);
   1.163 +		CASE_FIXED_FP(124);
   1.164 +		CASE_FIXED_FP(125);
   1.165 +		CASE_FIXED_FP(126);
   1.166 +		CASE_FIXED_FP(127);
   1.167 +	}
   1.168 +#undef CASE_FIXED_FP
   1.169 +#undef CASE_RESTORED_FP
   1.170 +}
   1.171 +
   1.172  #endif /* XEN */
   1.173  
   1.174  
     2.1 --- a/xen/arch/ia64/vmx/mmio.c	Tue Apr 25 16:55:09 2006 -0600
     2.2 +++ b/xen/arch/ia64/vmx/mmio.c	Tue Apr 25 17:05:16 2006 -0600
     2.3 @@ -529,6 +529,26 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
     2.4  	vmx_vcpu_increment_iip(vcpu);
     2.5  	return;
     2.6      }
     2.7 +    // Floating-point Load Pair + Imm ldfp8 M12
     2.8 +    else if(inst.M12.major==6&&inst.M12.m==1&&inst.M12.x==1&&inst.M12.x6==1){
     2.9 +        struct ia64_fpreg v;
    2.10 +        inst_type=SL_FLOATING;
    2.11 +        dir = IOREQ_READ;
    2.12 +        size = 8;     //ldfd
    2.13 +        mmio_access(vcpu, padr, &data, size, ma, dir);
    2.14 +        v.u.bits[0]=data;
    2.15 +        v.u.bits[1]=0x1003E;
    2.16 +        vcpu_set_fpreg(vcpu,inst.M12.f1,&v);
    2.17 +        padr += 8;
    2.18 +        mmio_access(vcpu, padr, &data, size, ma, dir);
    2.19 +        v.u.bits[0]=data;
    2.20 +        v.u.bits[1]=0x1003E;
    2.21 +        vcpu_set_fpreg(vcpu,inst.M12.f2,&v);
    2.22 +        padr += 8;
    2.23 +        vcpu_set_gr(vcpu,inst.M12.r3,padr,0);
    2.24 +        vmx_vcpu_increment_iip(vcpu);
    2.25 +        return;
    2.26 +    }					
    2.27      else{
    2.28          panic_domain
    2.29  	  (NULL,"This memory access instr can't be emulated: %lx pc=%lx\n ",
     3.1 --- a/xen/arch/ia64/xen/vcpu.c	Tue Apr 25 16:55:09 2006 -0600
     3.2 +++ b/xen/arch/ia64/xen/vcpu.c	Tue Apr 25 17:05:16 2006 -0600
     3.3 @@ -24,6 +24,8 @@ extern void getreg(unsigned long regnum,
     3.4  extern void setreg(unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs);
     3.5  extern void getfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs);
     3.6  
     3.7 +extern void setfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs);
     3.8 +
     3.9  extern void panic_domain(struct pt_regs *, const char *, ...);
    3.10  extern unsigned long translate_domain_mpaddr(unsigned long);
    3.11  extern void ia64_global_tlb_purge(UINT64 start, UINT64 end, UINT64 nbits);
    3.12 @@ -111,7 +113,16 @@ vcpu_get_fpreg(VCPU *vcpu, unsigned long
    3.13  {
    3.14  	REGS *regs = vcpu_regs(vcpu);
    3.15  	getfpreg(reg,val,regs);	// FIXME: handle NATs later
    3.16 -	return 0;
    3.17 +	return IA64_NO_FAULT;
    3.18 +}
    3.19 +
    3.20 +IA64FAULT
    3.21 +vcpu_set_fpreg(VCPU *vcpu, unsigned long reg, struct ia64_fpreg *val)
    3.22 +{
    3.23 +	REGS *regs = vcpu_regs(vcpu);
    3.24 +	if(reg > 1)
    3.25 +		setfpreg(reg,val,regs);	// FIXME: handle NATs later
    3.26 +	return IA64_NO_FAULT;
    3.27  }
    3.28  
    3.29  #else
     4.1 --- a/xen/include/asm-ia64/privop.h	Tue Apr 25 16:55:09 2006 -0600
     4.2 +++ b/xen/include/asm-ia64/privop.h	Tue Apr 25 17:05:16 2006 -0600
     4.3 @@ -180,6 +180,11 @@ typedef union U_INST64_M10 {
     4.4      struct { unsigned long qp:6, imm7:7, f2:7, r3:7, i:1, hint:2, x6:6, s:1, major:4; };
     4.5  } INST64_M10;
     4.6  
     4.7 +typedef union U_INST64_M12 {
     4.8 +    IA64_INST inst;
     4.9 +    struct { unsigned long qp:6, f1:7, f2:7, r3:7, x:1, hint:2, x6:6, m:1, major:4; };
    4.10 +} INST64_M12;
    4.11 +			 
    4.12  typedef union U_INST64_M15 {
    4.13      IA64_INST inst;
    4.14      struct { unsigned long qp:6, :7, imm7:7, r3:7, i:1, hint:2, x6:6, s:1, major:4; };
    4.15 @@ -204,6 +209,7 @@ typedef union U_INST64 {
    4.16      INST64_M6  M6;	// ldfd floating pointer
    4.17      INST64_M9  M9;	// stfd floating pointer
    4.18      INST64_M10 M10;	// stfd floating pointer
    4.19 +    INST64_M12 M12;    // ldfd pair floating pointer
    4.20      INST64_M15 M15;	// lfetch + imm update
    4.21      INST64_M28 M28;	// purge translation cache entry
    4.22      INST64_M29 M29;	// mov register to ar (M unit)
     5.1 --- a/xen/include/asm-ia64/vcpu.h	Tue Apr 25 16:55:09 2006 -0600
     5.2 +++ b/xen/include/asm-ia64/vcpu.h	Tue Apr 25 17:05:16 2006 -0600
     5.3 @@ -42,6 +42,8 @@ extern IA64FAULT vcpu_get_gr_nat(VCPU *v
     5.4  extern IA64FAULT vcpu_set_gr(VCPU *vcpu, unsigned long reg, UINT64 value, int nat);
     5.5  extern IA64FAULT vcpu_get_fpreg(VCPU *vcpu, unsigned long reg, struct ia64_fpreg *val);
     5.6  
     5.7 +extern IA64FAULT vcpu_set_fpreg(VCPU *vcpu, unsigned long reg, struct ia64_fpreg *val);
     5.8 +
     5.9  /* application registers */
    5.10  extern void vcpu_load_kernel_regs(VCPU *vcpu);
    5.11  extern IA64FAULT vcpu_set_ar(VCPU *vcpu, UINT64 reg, UINT64 val);