~ubuntu-branches/ubuntu/saucy/bochs/saucy-proposed

« back to all changes in this revision

Viewing changes to cpu/xsave.cc

  • Committer: Bazaar Package Importer
  • Author(s): David Futcher
  • Date: 2009-04-30 07:46:11 UTC
  • mfrom: (1.1.11 upstream) (4.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090430074611-6dih80a5mk2uvxhk
Tags: 2.3.7+20090416-1ubuntu1
* Merge from debian unstable (LP: #370427), remaining changes:
  - debian/patches/12_no-ssp.patch: Build bios with -fno-stack-protector
  - Add Replaces/Conflicts for bochsbios-qemu (<< 2.3.6-2)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/////////////////////////////////////////////////////////////////////////
2
 
// $Id: xsave.cc,v 1.10 2008/05/10 13:34:47 sshwarts Exp $
 
2
// $Id: xsave.cc,v 1.16 2009/01/16 18:18:59 sshwarts Exp $
3
3
/////////////////////////////////////////////////////////////////////////
4
4
//
5
5
//   Copyright (c) 2008 Stanislav Shwartsman
17
17
//
18
18
//  You should have received a copy of the GNU Lesser General Public
19
19
//  License along with this library; if not, write to the Free Software
20
 
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
20
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
21
21
//
22
22
/////////////////////////////////////////////////////////////////////////
23
23
 
41
41
 
42
42
  BX_CPU_THIS_PTR prepareXSAVE();
43
43
 
44
 
  BX_DEBUG(("XSAVE: save processor state XCR0=0x%08x", BX_CPU_THIS_PTR xcr0.getRegister()));
45
 
 
46
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
47
 
 
48
 
  bx_address laddr = get_laddr(i->seg(), RMAddr(i));
 
44
  BX_DEBUG(("XSAVE: save processor state XCR0=0x%08x", BX_CPU_THIS_PTR xcr0.get32()));
 
45
 
 
46
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
47
 
 
48
  bx_address laddr = get_laddr(i->seg(), eaddr);
49
49
 
50
50
  if (laddr & 0x3f) {
51
51
    BX_ERROR(("XSAVE: access not aligned to 64-byte"));
84
84
    else
85
85
#endif
86
86
    {
87
 
      xmm.xmm32u(2) = (Bit32u)(BX_CPU_THIS_PTR the_i387.fip) & 0xffffffff;
 
87
      xmm.xmm32u(2) = (Bit32u)(BX_CPU_THIS_PTR the_i387.fip);
88
88
      xmm.xmm32u(3) =         (BX_CPU_THIS_PTR the_i387.fcs);
89
89
    }
90
90
 
91
 
    write_virtual_dqword(i->seg(), RMAddr(i), (Bit8u *) &xmm);
 
91
    write_virtual_dqword(i->seg(), eaddr, (Bit8u *) &xmm);
92
92
 
93
93
    /*
94
94
     * x87 FPU Instruction Operand (Data) Pointer Offset (32/64 bits)
102
102
     */
103
103
#if BX_SUPPORT_X86_64
104
104
    if (i->os64L()) {
105
 
      write_virtual_qword(i->seg(), RMAddr(i) + 16, BX_CPU_THIS_PTR the_i387.fdp);
 
105
      write_virtual_qword(i->seg(), eaddr + 16, BX_CPU_THIS_PTR the_i387.fdp);
106
106
    }
107
107
    else
108
108
#endif
109
109
    {
110
 
      write_virtual_dword(i->seg(), RMAddr(i) + 16, 
111
 
            (Bit32u)(BX_CPU_THIS_PTR the_i387.fdp & 0xffffffff));
112
 
      write_virtual_dword(i->seg(), RMAddr(i) + 20, 
113
 
            (Bit32u)(BX_CPU_THIS_PTR the_i387.fds));
 
110
      write_virtual_dword(i->seg(), eaddr + 16, (Bit32u) BX_CPU_THIS_PTR the_i387.fdp);
 
111
      write_virtual_dword(i->seg(), eaddr + 20, (Bit32u) BX_CPU_THIS_PTR the_i387.fds);
114
112
    }
115
113
    /* do not touch MXCSR state */
116
114
 
123
121
      xmm.xmm64u(1) = 0;
124
122
      xmm.xmm16u(4) = fp.exp;
125
123
 
126
 
      write_virtual_dqword(i->seg(), RMAddr(i)+index*16+32, (Bit8u *) &xmm);
 
124
      write_virtual_dqword(i->seg(), eaddr+index*16+32, (Bit8u *) &xmm);
127
125
    }
128
126
  }
129
127
 
130
128
  /////////////////////////////////////////////////////////////////////////////
131
129
  if (BX_CPU_THIS_PTR xcr0.get_SSE() && (EAX & BX_XCR0_SSE_MASK) != 0)
132
130
  {
133
 
    write_virtual_dword(i->seg(), RMAddr(i) + 24, BX_MXCSR_REGISTER);
134
 
    write_virtual_dword(i->seg(), RMAddr(i) + 28, MXCSR_MASK);
 
131
    write_virtual_dword(i->seg(), eaddr + 24, BX_MXCSR_REGISTER);
 
132
    write_virtual_dword(i->seg(), eaddr + 28, MXCSR_MASK);
135
133
 
136
134
    /* store XMM register file */
137
135
    for(index=0; index < BX_XMM_REGISTERS; index++)
139
137
      // save XMM8-XMM15 only in 64-bit mode
140
138
      if (index < 8 || Is64BitMode()) {
141
139
        write_virtual_dqword(i->seg(),
142
 
           RMAddr(i)+index*16+160, (Bit8u *) &(BX_CPU_THIS_PTR xmm[index]));
 
140
           eaddr+index*16+160, (Bit8u *) &(BX_CPU_THIS_PTR xmm[index]));
143
141
      }
144
142
    }
145
143
  }
147
145
  // skip header update for now, required to know if a CPU feature is in its initial state
148
146
#else
149
147
  BX_INFO(("XSAVE: required XSAVE support, use --enable-xsave option"));
150
 
  UndefinedOpcode(i);
 
148
  exception(BX_UD_EXCEPTION, 0, 0);
151
149
#endif
152
150
}
153
151
 
160
158
 
161
159
  BX_CPU_THIS_PTR prepareXSAVE();
162
160
 
163
 
  BX_DEBUG(("XRSTOR: restore processor state XCR0=0x%08x", BX_CPU_THIS_PTR xcr0.getRegister()));
164
 
 
165
 
  BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
166
 
 
167
 
  bx_address laddr = get_laddr(i->seg(), RMAddr(i));
 
161
  BX_DEBUG(("XRSTOR: restore processor state XCR0=0x%08x", BX_CPU_THIS_PTR xcr0.get32()));
 
162
 
 
163
  bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
 
164
  bx_address laddr = get_laddr(i->seg(), eaddr);
168
165
 
169
166
  if (laddr & 0x3f) {
170
167
    BX_ERROR(("XRSTOR: access not aligned to 64-byte"));
171
168
    exception(BX_GP_EXCEPTION, 0, 0);
172
169
  }
173
170
 
174
 
  Bit64u header1 = read_virtual_qword(i->seg(), RMAddr(i) + 512);
175
 
  Bit64u header2 = read_virtual_qword(i->seg(), RMAddr(i) + 520);
176
 
  Bit64u header3 = read_virtual_qword(i->seg(), RMAddr(i) + 528);
 
171
  Bit64u header1 = read_virtual_qword(i->seg(), eaddr + 512);
 
172
  Bit64u header2 = read_virtual_qword(i->seg(), eaddr + 520);
 
173
  Bit64u header3 = read_virtual_qword(i->seg(), eaddr + 528);
177
174
 
178
 
  if ((~BX_CPU_THIS_PTR xcr0.getRegister() & header1) != 0) {
 
175
  if ((~BX_CPU_THIS_PTR xcr0.get32() & header1) != 0) {
179
176
    BX_ERROR(("XRSTOR: Broken header state"));
180
177
    exception(BX_GP_EXCEPTION, 0, 0);
181
178
  }
194
191
  {
195
192
    if (header1 & BX_XCR0_FPU_MASK) {
196
193
      // load FPU state from XSAVE area
197
 
      read_virtual_dqword(i->seg(), RMAddr(i), (Bit8u *) &xmm);
 
194
      read_virtual_dqword(i->seg(), eaddr, (Bit8u *) &xmm);
198
195
 
199
196
      BX_CPU_THIS_PTR the_i387.cwd =  xmm.xmm16u(0);
200
197
      BX_CPU_THIS_PTR the_i387.swd =  xmm.xmm16u(1);
214
211
#endif
215
212
      {
216
213
        BX_CPU_THIS_PTR the_i387.fip = xmm.xmm32u(2);
217
 
        BX_CPU_THIS_PTR the_i387.fcs = xmm.xmm16u(5);
 
214
        BX_CPU_THIS_PTR the_i387.fcs = xmm.xmm16u(6);
218
215
      }
219
216
 
220
217
      Bit32u tag_byte = xmm.xmmubyte(4);
221
218
 
222
219
      /* Restore x87 FPU DP */
223
 
      read_virtual_dqword(i->seg(), RMAddr(i) + 16, (Bit8u *) &xmm);
 
220
      read_virtual_dqword(i->seg(), eaddr + 16, (Bit8u *) &xmm);
224
221
 
225
222
#if BX_SUPPORT_X86_64
226
223
      if (i->os64L()) {
237
234
      /* load i387 register file */
238
235
      for(index=0; index < 8; index++)
239
236
      {
240
 
        read_virtual_tword(i->seg(), RMAddr(i)+index*16+32, &(BX_FPU_REG(index)));
 
237
        floatx80 reg;
 
238
        reg.fraction = read_virtual_qword(i->seg(), eaddr+index*16+32);
 
239
        reg.exp      = read_virtual_word (i->seg(), eaddr+index*16+40);
 
240
        BX_FPU_REG(index) = reg;
241
241
      }
242
242
 
243
243
      /* Restore floating point tag word - see desription for FXRSTOR instruction */
244
244
      BX_CPU_THIS_PTR the_i387.twd = unpack_FPU_TW(tag_byte);
245
245
    }
246
246
    else {
247
 
       // initialize FPU with reset values
248
 
       BX_CPU_THIS_PTR the_i387.init();
 
247
      // initialize FPU with reset values
 
248
      BX_CPU_THIS_PTR the_i387.init();
249
249
 
250
 
       for (index=0;index<8;index++) {
251
 
         BX_CPU_THIS_PTR the_i387.st_space[index].exp      = 0;
252
 
         BX_CPU_THIS_PTR the_i387.st_space[index].fraction = 0;
253
 
       }
 
250
      for (index=0;index<8;index++) {
 
251
        floatx80 reg = { 0, 0 };
 
252
        BX_FPU_REG(index) = reg;
 
253
      }
254
254
    }
255
255
  }
256
256
 
257
257
  /////////////////////////////////////////////////////////////////////////////
258
258
  if (BX_CPU_THIS_PTR xcr0.get_SSE() && (EAX & BX_XCR0_SSE_MASK) != 0)
259
259
  {
260
 
    Bit32u new_mxcsr = read_virtual_dword(i->seg(), RMAddr(i) + 24);
 
260
    Bit32u new_mxcsr = read_virtual_dword(i->seg(), eaddr + 24);
261
261
    if(new_mxcsr & ~MXCSR_MASK)
262
262
       exception(BX_GP_EXCEPTION, 0, 0);
263
263
 
268
268
         // restore XMM8-XMM15 only in 64-bit mode
269
269
         if (index < 8 || Is64BitMode()) {
270
270
           read_virtual_dqword(i->seg(),
271
 
               RMAddr(i)+index*16+160, (Bit8u *) &(BX_CPU_THIS_PTR xmm[index]));
 
271
               eaddr+index*16+160, (Bit8u *) &(BX_CPU_THIS_PTR xmm[index]));
272
272
         }
273
273
      }
274
274
    }
285
285
  }
286
286
#else
287
287
  BX_INFO(("XRSTOR: required XSAVE support, use --enable-xsave option"));
288
 
  UndefinedOpcode(i);
 
288
  exception(BX_UD_EXCEPTION, 0, 0);
289
289
#endif
290
290
}
291
291
 
306
306
  }
307
307
 
308
308
  RDX = 0;
309
 
  RAX = BX_CPU_THIS_PTR xcr0.getRegister();
 
309
  RAX = BX_CPU_THIS_PTR xcr0.get32();
310
310
#else
311
311
  BX_INFO(("XGETBV: required XSAVE support, use --enable-xsave option"));
312
 
  UndefinedOpcode(i);
 
312
  exception(BX_UD_EXCEPTION, 0, 0);
313
313
#endif
314
314
}
315
315
 
344
344
    exception(BX_GP_EXCEPTION, 0, 0);
345
345
  }
346
346
 
347
 
  BX_CPU_THIS_PTR xcr0.setRegister(EAX);
 
347
  BX_CPU_THIS_PTR xcr0.set32(EAX);
348
348
#else
349
349
  BX_INFO(("XSETBV: required XSAVE support, use --enable-xsave option"));
350
 
  UndefinedOpcode(i);
 
350
  exception(BX_UD_EXCEPTION, 0, 0);
351
351
#endif
352
352
}