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

« back to all changes in this revision

Viewing changes to cpu/smm.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: smm.cc,v 1.40 2008/05/26 21:46:39 sshwarts Exp $
 
2
// $Id: smm.cc,v 1.61 2009/04/07 16:12:19 sshwarts Exp $
3
3
/////////////////////////////////////////////////////////////////////////
4
4
//
5
5
//   Copyright (c) 2006 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
#define NEED_CPU_REG_SHORTCUTS 1
69
69
  /* If we are not in System Management Mode, then #UD should be generated */
70
70
  if (! BX_CPU_THIS_PTR smm_mode()) {
71
71
    BX_INFO(("RSM not in System Management Mode !"));
72
 
    UndefinedOpcode(i);
73
 
  }
 
72
    exception(BX_UD_EXCEPTION, 0, 0);
 
73
  }
 
74
 
 
75
#if BX_SUPPORT_VMX
 
76
  if (BX_CPU_THIS_PTR in_vmx_guest) {
 
77
    BX_ERROR(("VMEXIT: RSM in VMX non-root operation"));
 
78
    VMexit(i, VMX_VMEXIT_RSM, 0);
 
79
  }
 
80
#endif
74
81
 
75
82
  invalidate_prefetch_q();
76
83
 
77
84
  BX_INFO(("RSM: Resuming from System Management Mode"));
78
85
 
79
 
  BX_CPU_THIS_PTR nmi_disable = 0;
 
86
  BX_CPU_THIS_PTR disable_NMI = 0;
80
87
 
81
88
  Bit32u saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
82
89
  // reset reserved bits
86
93
  // could be optimized with reading of only non-reserved bytes
87
94
  for(n=0;n<SMM_SAVE_STATE_MAP_SIZE;n++) {
88
95
    base -= 4;
89
 
    BX_MEM(0)->readPhysicalPage(BX_CPU_THIS, base, 4, &saved_state[n]);
 
96
    access_read_physical(base, 4, &saved_state[n]);
90
97
    BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, base, 4, BX_READ, (Bit8u*)(&saved_state[n]));
91
98
  }
92
99
  BX_CPU_THIS_PTR in_smm = 0;
109
116
  // debug(BX_CPU_THIS_PTR prev_rip);
110
117
 
111
118
  BX_CPU_THIS_PTR in_smm = 1;
 
119
  BX_CPU_THIS_PTR disable_NMI = 1;
112
120
 
113
121
  Bit32u saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
114
122
  // reset reserved bits
120
128
  // could be optimized with reading of only non-reserved bytes
121
129
  for(n=0;n<SMM_SAVE_STATE_MAP_SIZE;n++) {
122
130
    base -= 4;
123
 
    BX_MEM(0)->writePhysicalPage(BX_CPU_THIS, base, 4, &saved_state[n]);
 
131
    access_write_physical(base, 4, &saved_state[n]);
124
132
    BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, base, 4, BX_WRITE, (Bit8u*)(&saved_state[n]));
125
133
  }
126
134
 
135
143
  BX_CPU_THIS_PTR cr0.set_PG(0); // paging disabled (bit 31)
136
144
 
137
145
  // paging mode was changed - flush TLB
138
 
  TLB_flush(1); // 1 = Flush Global entries also
 
146
  TLB_flush(); //  Flush Global entries also
139
147
 
140
148
#if BX_CPU_LEVEL >= 4
141
 
  BX_CPU_THIS_PTR cr4.setRegister(0);
 
149
  BX_CPU_THIS_PTR cr4.set32(0);
142
150
#endif
143
151
 
144
152
#if BX_SUPPORT_X86_64
145
 
  BX_CPU_THIS_PTR efer.setRegister(0);
 
153
  BX_CPU_THIS_PTR efer.set32(0);
146
154
#endif
147
155
 
148
156
  parse_selector(BX_CPU_THIS_PTR smbase >> 4,
149
157
               &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector);
150
158
 
151
 
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid    = 1;
 
159
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid    = SegValidCache | SegAccessROK | SegAccessWOK;
152
160
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p        = 1;
153
161
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl      = 0;
154
162
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment  = 1;  /* data/code segment */
155
163
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type     = BX_DATA_READ_WRITE_ACCESSED;
156
164
 
157
165
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base         = BX_CPU_THIS_PTR smbase;
158
 
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit        = 0xffff;
159
166
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xffffffff;
160
167
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
161
168
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g   = 1; /* page granular */
164
171
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l   = 0; /* 16bit default size */
165
172
#endif
166
173
 
167
 
#if BX_SUPPORT_ICACHE
168
 
  BX_CPU_THIS_PTR updateFetchModeMask();
169
 
#endif
170
 
 
171
174
  handleCpuModeChange();
172
175
 
173
176
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
178
181
  parse_selector(0x0000,
179
182
               &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector);
180
183
 
181
 
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid    = 1;
 
184
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid    = SegValidCache | SegAccessROK | SegAccessWOK;
182
185
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p        = 1;
183
186
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl      = 0;
184
187
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment  = 1; /* data/code segment */
185
188
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.type     = BX_DATA_READ_WRITE_ACCESSED;
186
189
 
187
190
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base         = 0x00000000;
188
 
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit        = 0xffff;
189
191
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xffffffff;
190
192
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0;
191
193
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g   = 1; /* byte granular */
202
204
}
203
205
 
204
206
#define SMRAM_TRANSLATE(addr)    (((0x8000 - (addr)) >> 2) - 1)
205
 
#define SMRAM_FIELD(state, addr) (state[SMRAM_TRANSLATE(addr)])
 
207
 
 
208
// SMRAM SMM_SAVE_STATE_MAP_SIZE is 128 elements, find the element for each field
 
209
static unsigned smram_map[SMRAM_FIELD_LAST];
 
210
 
 
211
#if BX_SUPPORT_X86_64
 
212
 
 
213
void BX_CPU_C::init_SMRAM(void)
 
214
{
 
215
  static bx_bool smram_map_ready = 0;
 
216
 
 
217
  if (smram_map_ready) return;
 
218
  smram_map_ready = 1;
 
219
 
 
220
  smram_map[SMRAM_FIELD_SMBASE_OFFSET] = SMRAM_TRANSLATE(0x7f00);
 
221
  smram_map[SMRAM_FIELD_SMM_REVISION_ID] = SMRAM_TRANSLATE(0x7efc);
 
222
  smram_map[SMRAM_FIELD_RAX_HI32] = SMRAM_TRANSLATE(0x7ffc);
 
223
  smram_map[SMRAM_FIELD_EAX] = SMRAM_TRANSLATE(0x7ff8);
 
224
  smram_map[SMRAM_FIELD_RCX_HI32] = SMRAM_TRANSLATE(0x7ff4);
 
225
  smram_map[SMRAM_FIELD_ECX] = SMRAM_TRANSLATE(0x7ff0);
 
226
  smram_map[SMRAM_FIELD_RDX_HI32] = SMRAM_TRANSLATE(0x7fec);
 
227
  smram_map[SMRAM_FIELD_EDX] = SMRAM_TRANSLATE(0x7fe8);
 
228
  smram_map[SMRAM_FIELD_RBX_HI32] = SMRAM_TRANSLATE(0x7fe4);
 
229
  smram_map[SMRAM_FIELD_EBX] = SMRAM_TRANSLATE(0x7fe0);
 
230
  smram_map[SMRAM_FIELD_RSP_HI32] = SMRAM_TRANSLATE(0x7fdc);
 
231
  smram_map[SMRAM_FIELD_ESP] = SMRAM_TRANSLATE(0x7fd8);
 
232
  smram_map[SMRAM_FIELD_RBP_HI32] = SMRAM_TRANSLATE(0x7fd4);
 
233
  smram_map[SMRAM_FIELD_EBP] = SMRAM_TRANSLATE(0x7fd0);
 
234
  smram_map[SMRAM_FIELD_RSI_HI32] = SMRAM_TRANSLATE(0x7fcc);
 
235
  smram_map[SMRAM_FIELD_ESI] = SMRAM_TRANSLATE(0x7fc8);
 
236
  smram_map[SMRAM_FIELD_RDI_HI32] = SMRAM_TRANSLATE(0x7fc4);
 
237
  smram_map[SMRAM_FIELD_EDI] = SMRAM_TRANSLATE(0x7fc0);
 
238
  smram_map[SMRAM_FIELD_R8_HI32]  = SMRAM_TRANSLATE(0x7fbc);
 
239
  smram_map[SMRAM_FIELD_R8]  = SMRAM_TRANSLATE(0x7fb8);
 
240
  smram_map[SMRAM_FIELD_R9_HI32]  = SMRAM_TRANSLATE(0x7fb4);
 
241
  smram_map[SMRAM_FIELD_R9]  = SMRAM_TRANSLATE(0x7fb0);
 
242
  smram_map[SMRAM_FIELD_R10_HI32] = SMRAM_TRANSLATE(0x7fac);
 
243
  smram_map[SMRAM_FIELD_R10] = SMRAM_TRANSLATE(0x7fa8);
 
244
  smram_map[SMRAM_FIELD_R11_HI32] = SMRAM_TRANSLATE(0x7fa4);
 
245
  smram_map[SMRAM_FIELD_R11] = SMRAM_TRANSLATE(0x7fa0);
 
246
  smram_map[SMRAM_FIELD_R12_HI32] = SMRAM_TRANSLATE(0x7f9c);
 
247
  smram_map[SMRAM_FIELD_R12] = SMRAM_TRANSLATE(0x7f98);
 
248
  smram_map[SMRAM_FIELD_R13_HI32] = SMRAM_TRANSLATE(0x7f94);
 
249
  smram_map[SMRAM_FIELD_R13] = SMRAM_TRANSLATE(0x7f90);
 
250
  smram_map[SMRAM_FIELD_R14_HI32] = SMRAM_TRANSLATE(0x7f8c);
 
251
  smram_map[SMRAM_FIELD_R14] = SMRAM_TRANSLATE(0x7f88);
 
252
  smram_map[SMRAM_FIELD_R15_HI32] = SMRAM_TRANSLATE(0x7f84);
 
253
  smram_map[SMRAM_FIELD_R15] = SMRAM_TRANSLATE(0x7f80);
 
254
  smram_map[SMRAM_FIELD_RIP_HI32] = SMRAM_TRANSLATE(0x7f7c);
 
255
  smram_map[SMRAM_FIELD_EIP] = SMRAM_TRANSLATE(0x7f78);
 
256
  smram_map[SMRAM_FIELD_RFLAGS_HI32] = SMRAM_TRANSLATE(0x7f74); // always zero
 
257
  smram_map[SMRAM_FIELD_EFLAGS] = SMRAM_TRANSLATE(0x7f70);
 
258
  smram_map[SMRAM_FIELD_DR6_HI32] = SMRAM_TRANSLATE(0x7f6c);    // always zero
 
259
  smram_map[SMRAM_FIELD_DR6] = SMRAM_TRANSLATE(0x7f68);
 
260
  smram_map[SMRAM_FIELD_DR7_HI32] = SMRAM_TRANSLATE(0x7f64);    // always zero
 
261
  smram_map[SMRAM_FIELD_DR7] = SMRAM_TRANSLATE(0x7f60);
 
262
  smram_map[SMRAM_FIELD_CR0_HI32] = SMRAM_TRANSLATE(0x7f5c);    // always zero
 
263
  smram_map[SMRAM_FIELD_CR0] = SMRAM_TRANSLATE(0x7f58);
 
264
  smram_map[SMRAM_FIELD_CR3_HI32] = SMRAM_TRANSLATE(0x7f54);    // zero when physical address size 32-bit
 
265
  smram_map[SMRAM_FIELD_CR3] = SMRAM_TRANSLATE(0x7f50);
 
266
  smram_map[SMRAM_FIELD_CR4_HI32] = SMRAM_TRANSLATE(0x7f4c);    // always zero
 
267
  smram_map[SMRAM_FIELD_CR4] = SMRAM_TRANSLATE(0x7f48);
 
268
  smram_map[SMRAM_FIELD_EFER_HI32] = SMRAM_TRANSLATE(0x7ed4);   // always zero
 
269
  smram_map[SMRAM_FIELD_EFER] = SMRAM_TRANSLATE(0x7ed0);
 
270
  smram_map[SMRAM_FIELD_IO_INSTRUCTION_RESTART] = SMRAM_TRANSLATE(0x7ec8);
 
271
  smram_map[SMRAM_FIELD_AUTOHALT_RESTART] = SMRAM_TRANSLATE(0x7ec8);
 
272
  smram_map[SMRAM_FIELD_NMI_MASK] = SMRAM_TRANSLATE(0x7ec8);
 
273
  smram_map[SMRAM_FIELD_TR_BASE_HI32] = SMRAM_TRANSLATE(0x7e9c);
 
274
  smram_map[SMRAM_FIELD_TR_BASE] = SMRAM_TRANSLATE(0x7e98);
 
275
  smram_map[SMRAM_FIELD_TR_LIMIT] = SMRAM_TRANSLATE(0x7e94);
 
276
  smram_map[SMRAM_FIELD_TR_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e90);
 
277
  smram_map[SMRAM_FIELD_IDTR_BASE_HI32] = SMRAM_TRANSLATE(0x7e8c);
 
278
  smram_map[SMRAM_FIELD_IDTR_BASE] = SMRAM_TRANSLATE(0x7e88);
 
279
  smram_map[SMRAM_FIELD_IDTR_LIMIT] = SMRAM_TRANSLATE(0x7e84);
 
280
  smram_map[SMRAM_FIELD_LDTR_BASE_HI32] = SMRAM_TRANSLATE(0x7e7c);
 
281
  smram_map[SMRAM_FIELD_LDTR_BASE] = SMRAM_TRANSLATE(0x7e78);
 
282
  smram_map[SMRAM_FIELD_LDTR_LIMIT] = SMRAM_TRANSLATE(0x7e74);
 
283
  smram_map[SMRAM_FIELD_LDTR_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e70);
 
284
  smram_map[SMRAM_FIELD_GDTR_BASE_HI32] = SMRAM_TRANSLATE(0x7e6c);
 
285
  smram_map[SMRAM_FIELD_GDTR_BASE] = SMRAM_TRANSLATE(0x7e68);
 
286
  smram_map[SMRAM_FIELD_GDTR_LIMIT] = SMRAM_TRANSLATE(0x7e64);
 
287
  smram_map[SMRAM_FIELD_ES_BASE_HI32] = SMRAM_TRANSLATE(0x7e0c);
 
288
  smram_map[SMRAM_FIELD_ES_BASE] = SMRAM_TRANSLATE(0x7e08);
 
289
  smram_map[SMRAM_FIELD_ES_LIMIT] = SMRAM_TRANSLATE(0x7e04);
 
290
  smram_map[SMRAM_FIELD_ES_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e00);
 
291
  smram_map[SMRAM_FIELD_CS_BASE_HI32] = SMRAM_TRANSLATE(0x7e1c);
 
292
  smram_map[SMRAM_FIELD_CS_BASE] = SMRAM_TRANSLATE(0x7e18);
 
293
  smram_map[SMRAM_FIELD_CS_LIMIT] = SMRAM_TRANSLATE(0x7e14);
 
294
  smram_map[SMRAM_FIELD_CS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e10);
 
295
  smram_map[SMRAM_FIELD_SS_BASE_HI32] = SMRAM_TRANSLATE(0x7e2c);
 
296
  smram_map[SMRAM_FIELD_SS_BASE] = SMRAM_TRANSLATE(0x7e28);
 
297
  smram_map[SMRAM_FIELD_SS_LIMIT] = SMRAM_TRANSLATE(0x7e24);
 
298
  smram_map[SMRAM_FIELD_SS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e20);
 
299
  smram_map[SMRAM_FIELD_DS_BASE_HI32] = SMRAM_TRANSLATE(0x7e3c);
 
300
  smram_map[SMRAM_FIELD_DS_BASE] = SMRAM_TRANSLATE(0x7e38);
 
301
  smram_map[SMRAM_FIELD_DS_LIMIT] = SMRAM_TRANSLATE(0x7e34);
 
302
  smram_map[SMRAM_FIELD_DS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e30);
 
303
  smram_map[SMRAM_FIELD_FS_BASE_HI32] = SMRAM_TRANSLATE(0x7e4c);
 
304
  smram_map[SMRAM_FIELD_FS_BASE] = SMRAM_TRANSLATE(0x7e48);
 
305
  smram_map[SMRAM_FIELD_FS_LIMIT] = SMRAM_TRANSLATE(0x7e44);
 
306
  smram_map[SMRAM_FIELD_FS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e40);
 
307
  smram_map[SMRAM_FIELD_GS_BASE_HI32] = SMRAM_TRANSLATE(0x7e5c);
 
308
  smram_map[SMRAM_FIELD_GS_BASE] = SMRAM_TRANSLATE(0x7e58);
 
309
  smram_map[SMRAM_FIELD_GS_LIMIT] = SMRAM_TRANSLATE(0x7e54);
 
310
  smram_map[SMRAM_FIELD_GS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e50);
 
311
 
 
312
  for (unsigned n=0; n<SMRAM_FIELD_LAST;n++) {
 
313
    if (smram_map[n] >= SMM_SAVE_STATE_MAP_SIZE) {
 
314
      BX_PANIC(("smram map[%d] = %d", n, smram_map[n]));
 
315
    }
 
316
  }
 
317
}
 
318
 
 
319
#else
 
320
 
 
321
// source for Intel P6 SMM save state map used: www.sandpile.org
 
322
 
 
323
void BX_CPU_C::init_SMRAM(void)
 
324
{
 
325
  smram_map[SMRAM_FIELD_SMBASE_OFFSET] = SMRAM_TRANSLATE(0x7ef8);
 
326
  smram_map[SMRAM_FIELD_SMM_REVISION_ID] = SMRAM_TRANSLATE(0x7efc);
 
327
  smram_map[SMRAM_FIELD_EAX] = SMRAM_TRANSLATE(0x7fd0);
 
328
  smram_map[SMRAM_FIELD_ECX] = SMRAM_TRANSLATE(0x7fd4);
 
329
  smram_map[SMRAM_FIELD_EDX] = SMRAM_TRANSLATE(0x7fd8);
 
330
  smram_map[SMRAM_FIELD_EBX] = SMRAM_TRANSLATE(0x7fdc);
 
331
  smram_map[SMRAM_FIELD_ESP] = SMRAM_TRANSLATE(0x7fe0);
 
332
  smram_map[SMRAM_FIELD_EBP] = SMRAM_TRANSLATE(0x7fe4);
 
333
  smram_map[SMRAM_FIELD_ESI] = SMRAM_TRANSLATE(0x7fe8);
 
334
  smram_map[SMRAM_FIELD_EDI] = SMRAM_TRANSLATE(0x7fec);
 
335
  smram_map[SMRAM_FIELD_EIP] = SMRAM_TRANSLATE(0x7ff0);
 
336
  smram_map[SMRAM_FIELD_EFLAGS] = SMRAM_TRANSLATE(0x7ff4);
 
337
  smram_map[SMRAM_FIELD_DR6] = SMRAM_TRANSLATE(0x7fcc);
 
338
  smram_map[SMRAM_FIELD_DR7] = SMRAM_TRANSLATE(0x7fc8);
 
339
  smram_map[SMRAM_FIELD_CR0] = SMRAM_TRANSLATE(0x7ffc);
 
340
  smram_map[SMRAM_FIELD_CR3] = SMRAM_TRANSLATE(0x7ff8);
 
341
  smram_map[SMRAM_FIELD_CR4] = SMRAM_TRANSLATE(0x7f14);
 
342
  smram_map[SMRAM_FIELD_IO_INSTRUCTION_RESTART] = SMRAM_TRANSLATE(0x7f00);
 
343
  smram_map[SMRAM_FIELD_AUTOHALT_RESTART] = SMRAM_TRANSLATE(0x7f00);
 
344
  smram_map[SMRAM_FIELD_NMI_MASK] = SMRAM_TRANSLATE(0x7f00);
 
345
  smram_map[SMRAM_FIELD_TR_SELECTOR] = SMRAM_TRANSLATE(0x7fc4);
 
346
  smram_map[SMRAM_FIELD_TR_BASE] = SMRAM_TRANSLATE(0x7f64);
 
347
  smram_map[SMRAM_FIELD_TR_LIMIT] = SMRAM_TRANSLATE(0x7f60);
 
348
  smram_map[SMRAM_FIELD_TR_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f5c);
 
349
  smram_map[SMRAM_FIELD_LDTR_SELECTOR] = SMRAM_TRANSLATE(0x7fc0);
 
350
  smram_map[SMRAM_FIELD_LDTR_BASE] = SMRAM_TRANSLATE(0x7f80);
 
351
  smram_map[SMRAM_FIELD_LDTR_LIMIT] = SMRAM_TRANSLATE(0x7f7c);
 
352
  smram_map[SMRAM_FIELD_LDTR_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f78);
 
353
  smram_map[SMRAM_FIELD_IDTR_BASE] = SMRAM_TRANSLATE(0x7f58);
 
354
  smram_map[SMRAM_FIELD_IDTR_LIMIT] = SMRAM_TRANSLATE(0x7f54);
 
355
  smram_map[SMRAM_FIELD_GDTR_BASE] = SMRAM_TRANSLATE(0x7f74);
 
356
  smram_map[SMRAM_FIELD_GDTR_LIMIT] = SMRAM_TRANSLATE(0x7f70);
 
357
  smram_map[SMRAM_FIELD_ES_SELECTOR] = SMRAM_TRANSLATE(0x7fa8);
 
358
  smram_map[SMRAM_FIELD_ES_BASE] = SMRAM_TRANSLATE(0x7f8c);
 
359
  smram_map[SMRAM_FIELD_ES_LIMIT] = SMRAM_TRANSLATE(0x7f88);
 
360
  smram_map[SMRAM_FIELD_ES_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f84);
 
361
  smram_map[SMRAM_FIELD_CS_SELECTOR] = SMRAM_TRANSLATE(0x7fac);
 
362
  smram_map[SMRAM_FIELD_CS_BASE] = SMRAM_TRANSLATE(0x7f98);
 
363
  smram_map[SMRAM_FIELD_CS_LIMIT] = SMRAM_TRANSLATE(0x7f94);
 
364
  smram_map[SMRAM_FIELD_CS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f90);
 
365
  smram_map[SMRAM_FIELD_SS_SELECTOR] = SMRAM_TRANSLATE(0x7fb0);
 
366
  smram_map[SMRAM_FIELD_SS_BASE] = SMRAM_TRANSLATE(0x7fa4);
 
367
  smram_map[SMRAM_FIELD_SS_LIMIT] = SMRAM_TRANSLATE(0x7fa0);
 
368
  smram_map[SMRAM_FIELD_SS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f9c);
 
369
  smram_map[SMRAM_FIELD_DS_SELECTOR] = SMRAM_TRANSLATE(0x7fb4);
 
370
  smram_map[SMRAM_FIELD_DS_BASE] = SMRAM_TRANSLATE(0x7f34);
 
371
  smram_map[SMRAM_FIELD_DS_LIMIT] = SMRAM_TRANSLATE(0x7f30);
 
372
  smram_map[SMRAM_FIELD_DS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f2c);
 
373
  smram_map[SMRAM_FIELD_FS_SELECTOR] = SMRAM_TRANSLATE(0x7fb8);
 
374
  smram_map[SMRAM_FIELD_FS_BASE] = SMRAM_TRANSLATE(0x7f40);
 
375
  smram_map[SMRAM_FIELD_FS_LIMIT] = SMRAM_TRANSLATE(0x7f3c);
 
376
  smram_map[SMRAM_FIELD_FS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f38);
 
377
  smram_map[SMRAM_FIELD_GS_SELECTOR] = SMRAM_TRANSLATE(0x7fbc);
 
378
  smram_map[SMRAM_FIELD_GS_BASE] = SMRAM_TRANSLATE(0x7f4c);
 
379
  smram_map[SMRAM_FIELD_GS_LIMIT] = SMRAM_TRANSLATE(0x7f48);
 
380
  smram_map[SMRAM_FIELD_GS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f44);
 
381
 
 
382
  for (unsigned n=0; n<SMRAM_FIELD_LAST;n++) {
 
383
    if (smram_map[n] >= SMM_SAVE_STATE_MAP_SIZE) {
 
384
      BX_PANIC(("smram map[%d] = %d", n, smram_map[n]));
 
385
    }
 
386
  }
 
387
}
 
388
 
 
389
#endif
 
390
 
 
391
#define SMRAM_FIELD(state, field) (state[smram_map[field]])
206
392
 
207
393
#if BX_SUPPORT_X86_64
208
394
 
216
402
void BX_CPU_C::smram_save_state(Bit32u *saved_state)
217
403
{
218
404
  // --- General Purpose Registers --- //
219
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RAX_HI32) = (Bit32u)(RAX >> 32);
220
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RAX_LO32) = EAX;
221
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RCX_HI32) = (Bit32u)(RCX >> 32);
222
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RCX_LO32) = ECX;
223
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDX_HI32) = (Bit32u)(RDX >> 32);
224
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDX_LO32) = EDX;
225
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBX_HI32) = (Bit32u)(RBX >> 32);
226
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBX_LO32) = EBX;
227
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSP_HI32) = (Bit32u)(RSP >> 32);
228
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSP_LO32) = ESP;
229
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBP_HI32) = (Bit32u)(RBP >> 32);
230
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBP_LO32) = EBP;
231
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSI_HI32) = (Bit32u)(RSI >> 32);
232
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSI_LO32) = ESI;
233
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDI_HI32) = (Bit32u)(RDI >> 32);
234
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDI_LO32) = EDI;
235
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R8_HI32)  = (Bit32u)(R8 >> 32);
236
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R8_LO32)  = (Bit32u)(R8 & 0xffffffff);
237
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R9_HI32)  = (Bit32u)(R9 >> 32);
238
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R9_LO32)  = (Bit32u)(R9 & 0xffffffff);
239
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R10_HI32) = (Bit32u)(R10 >> 32);
240
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R10_LO32) = (Bit32u)(R10 & 0xffffffff);
241
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R11_HI32) = (Bit32u)(R11 >> 32);
242
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R11_LO32) = (Bit32u)(R11 & 0xffffffff);
243
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R12_HI32) = (Bit32u)(R12 >> 32);
244
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R12_LO32) = (Bit32u)(R12 & 0xffffffff);
245
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R13_HI32) = (Bit32u)(R13 >> 32);
246
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R13_LO32) = (Bit32u)(R13 & 0xffffffff);
247
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R14_HI32) = (Bit32u)(R14 >> 32);
248
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R14_LO32) = (Bit32u)(R14 & 0xffffffff);
249
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R15_HI32) = (Bit32u)(R15 >> 32);
250
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_R15_LO32) = (Bit32u)(R15 & 0xffffffff);
251
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RIP_HI32) = (Bit32u)(RIP >> 32);
252
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RIP_LO32) = EIP;
253
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_RFLAGS32) = read_eflags();
 
405
  for (int n=0; n<BX_GENERAL_REGISTERS; n++) {
 
406
    Bit64u val_64 = BX_READ_64BIT_REG(n);
 
407
 
 
408
    SMRAM_FIELD(saved_state, SMRAM_FIELD_RAX_HI32 + 2*n) = GET32H(val_64);
 
409
    SMRAM_FIELD(saved_state, SMRAM_FIELD_EAX + 2*n) = GET32L(val_64);
 
410
  }
 
411
 
 
412
  SMRAM_FIELD(saved_state, SMRAM_FIELD_RIP_HI32) = GET32H(RIP);
 
413
  SMRAM_FIELD(saved_state, SMRAM_FIELD_EIP) = EIP;
 
414
  SMRAM_FIELD(saved_state, SMRAM_FIELD_EFLAGS) = read_eflags();
254
415
 
255
416
  // --- Debug and Control Registers --- //
256
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6) = BX_CPU_THIS_PTR dr6;
257
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7) = BX_CPU_THIS_PTR dr7;
258
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0) = BX_CPU_THIS_PTR cr0.getRegister();
259
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3) = BX_CPU_THIS_PTR cr3;
260
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4) = BX_CPU_THIS_PTR cr4.getRegister();
261
 
  /* base+0x7f44 to base+0x7f04 is reserved */
262
 
  SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET)   = BX_CPU_THIS_PTR smbase;
263
 
  SMRAM_FIELD(saved_state, SMRAM_SMM_REVISION_ID) = SMM_REVISION_ID;
264
 
  /* base+0x7ef8 to base+0x7ed8 is reserved */
265
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFER) = BX_CPU_THIS_PTR efer.getRegister();
266
 
  /* base+0x7ecc is reserved */
267
 
  /* base+0x7ec8 is I/O Instruction Restart, Auto-Halt Restart and NMI Mask */
268
 
  /* base+0x7ec4 is reserved */
269
 
  /* base+0x7ec0 is SMM I/O Trap */
270
 
  /* base+0x7ebc to base+0x7ea0 is reserved */
 
417
  SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6) = BX_CPU_THIS_PTR dr6;
 
418
  SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7) = BX_CPU_THIS_PTR dr7;
 
419
  SMRAM_FIELD(saved_state, SMRAM_FIELD_CR0) = BX_CPU_THIS_PTR cr0.get32();
 
420
  SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3_HI32) = GET32H(BX_CPU_THIS_PTR cr3);
 
421
  SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3) = GET32L(BX_CPU_THIS_PTR cr3);
 
422
  SMRAM_FIELD(saved_state, SMRAM_FIELD_CR4) = BX_CPU_THIS_PTR cr4.get32();
 
423
  SMRAM_FIELD(saved_state, SMRAM_FIELD_EFER) = BX_CPU_THIS_PTR efer.get32();
 
424
 
 
425
  SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET)   = BX_CPU_THIS_PTR smbase;
 
426
  SMRAM_FIELD(saved_state, SMRAM_FIELD_SMM_REVISION_ID) = SMM_REVISION_ID;
271
427
 
272
428
  // --- Task Register --- //
273
 
  SMRAM_FIELD(saved_state, SMRAM_TR_BASE_HI32) = (Bit32u)(BX_CPU_THIS_PTR tr.cache.u.system.base >> 32);
274
 
  SMRAM_FIELD(saved_state, SMRAM_TR_BASE_LO32) = (Bit32u)(BX_CPU_THIS_PTR tr.cache.u.system.base & 0xffffffff);
275
 
  SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.system.limit;
276
 
  SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value |
277
 
    (((Bit32u) get_segment_ar_data(&BX_CPU_THIS_PTR tr.cache)) << 16);
 
429
  SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_BASE_HI32) = GET32H(BX_CPU_THIS_PTR tr.cache.u.segment.base);
 
430
  SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_BASE) = GET32L(BX_CPU_THIS_PTR tr.cache.u.segment.base);
 
431
  SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.segment.limit_scaled;
 
432
  Bit32u tr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR tr.cache) >> 8) & 0xf0ff) | (BX_CPU_THIS_PTR tr.cache.valid << 8);
 
433
  SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value | (tr_ar << 16);
 
434
 
 
435
  // --- LDTR --- //
 
436
  SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_BASE_HI32) = GET32H(BX_CPU_THIS_PTR ldtr.cache.u.segment.base);
 
437
  SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_BASE) = GET32L(BX_CPU_THIS_PTR ldtr.cache.u.segment.base);
 
438
  SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.segment.limit_scaled;
 
439
  Bit32u ldtr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache) >> 8) & 0xf0ff) | (BX_CPU_THIS_PTR ldtr.cache.valid << 8);
 
440
  SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value | (ldtr_ar << 16);
278
441
 
279
442
  // --- IDTR --- //
280
 
  SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE_HI32) = (Bit32u)(BX_CPU_THIS_PTR idtr.base >> 32);
281
 
  SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE_LO32) = (Bit32u)(BX_CPU_THIS_PTR idtr.base & 0xffffffff);
282
 
  SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
283
 
  // --- LDTR --- //
284
 
  SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE_HI32) = (Bit32u)(BX_CPU_THIS_PTR ldtr.cache.u.system.base >> 32);
285
 
  SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE_LO32) = (Bit32u)(BX_CPU_THIS_PTR ldtr.cache.u.system.base & 0xffffffff);
286
 
  SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.system.limit;
287
 
  SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value |
288
 
    (((Bit32u) get_segment_ar_data(&BX_CPU_THIS_PTR ldtr.cache)) << 16);
 
443
  SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_BASE_HI32) = GET32H(BX_CPU_THIS_PTR idtr.base);
 
444
  SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_BASE) = GET32L(BX_CPU_THIS_PTR idtr.base);
 
445
  SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
 
446
 
289
447
  // --- GDTR --- //
290
 
  SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE_HI32) = (Bit32u)(BX_CPU_THIS_PTR gdtr.base >> 32);
291
 
  SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE_LO32) = (Bit32u)(BX_CPU_THIS_PTR gdtr.base & 0xffffffff);
292
 
  SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
293
 
  // --- GS selector --- //
294
 
  bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS]);
295
 
  SMRAM_FIELD(saved_state, SMRAM_GS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
296
 
  SMRAM_FIELD(saved_state, SMRAM_GS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
297
 
  SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT) = seg->cache.u.segment.limit;
298
 
  SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) = seg->selector.value |
299
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
300
 
  // --- FS selector --- //
301
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS]);
302
 
  SMRAM_FIELD(saved_state, SMRAM_FS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
303
 
  SMRAM_FIELD(saved_state, SMRAM_FS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
304
 
  SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT) = seg->cache.u.segment.limit;
305
 
  SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) = seg->selector.value |
306
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
307
 
  // --- DS selector --- //
308
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]);
309
 
  SMRAM_FIELD(saved_state, SMRAM_DS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
310
 
  SMRAM_FIELD(saved_state, SMRAM_DS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
311
 
  SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT) = seg->cache.u.segment.limit;
312
 
  SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) = seg->selector.value |
313
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
314
 
  // --- SS selector --- //
315
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]);
316
 
  SMRAM_FIELD(saved_state, SMRAM_SS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
317
 
  SMRAM_FIELD(saved_state, SMRAM_SS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
318
 
  SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT) = seg->cache.u.segment.limit;
319
 
  SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) = seg->selector.value |
320
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
321
 
  // --- CS selector --- //
322
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]);
323
 
  SMRAM_FIELD(saved_state, SMRAM_CS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
324
 
  SMRAM_FIELD(saved_state, SMRAM_CS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
325
 
  SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT) = seg->cache.u.segment.limit;
326
 
  SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) = seg->selector.value |
327
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
328
 
  // --- ES selector --- //
329
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES]);
330
 
  SMRAM_FIELD(saved_state, SMRAM_ES_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
331
 
  SMRAM_FIELD(saved_state, SMRAM_ES_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
332
 
  SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT) = seg->cache.u.segment.limit;
333
 
  SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) = seg->selector.value |
334
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
 
448
  SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_BASE_HI32) = GET32H(BX_CPU_THIS_PTR gdtr.base);
 
449
  SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_BASE) = GET32L(BX_CPU_THIS_PTR gdtr.base);
 
450
  SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
 
451
 
 
452
  for (int segreg = 0; segreg < 6; segreg++) {
 
453
    bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[segreg]);
 
454
    SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_BASE_HI32 + 4*segreg) = GET32H(seg->cache.u.segment.base);
 
455
    SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_BASE + 4*segreg) = GET32L(seg->cache.u.segment.base);
 
456
    SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_LIMIT + 4*segreg) = seg->cache.u.segment.limit_scaled;
 
457
    Bit32u seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xf0ff) | (seg->cache.valid << 8);
 
458
    SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) = seg->selector.value | (seg_ar << 16);
 
459
  }
335
460
}
336
461
 
337
462
bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
338
463
{
339
 
  Bit32u temp_cr0    = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0);
340
 
  Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_OFFSET_RFLAGS32);
341
 
  Bit32u temp_efer   = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFER);
 
464
  Bit32u temp_cr0    = SMRAM_FIELD(saved_state, SMRAM_FIELD_CR0);
 
465
  Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_FIELD_EFLAGS);
 
466
  Bit32u temp_efer   = SMRAM_FIELD(saved_state, SMRAM_FIELD_EFER);
342
467
 
343
 
  bx_bool pe = (temp_cr0 & 0x01);
344
 
  bx_bool nw = (temp_cr0 >> 29) & 0x01;
345
 
  bx_bool cd = (temp_cr0 >> 30) & 0x01;
346
 
  bx_bool pg = (temp_cr0 >> 31) & 0x01;
 
468
  bx_bool pe = (temp_cr0 & 0x1);
 
469
  bx_bool nw = (temp_cr0 >> 29) & 0x1;
 
470
  bx_bool cd = (temp_cr0 >> 30) & 0x1;
 
471
  bx_bool pg = (temp_cr0 >> 31) & 0x1;
347
472
 
348
473
  // check CR0 conditions for entering to shutdown state
349
474
  if (pg && !pe) {
357
482
  }
358
483
 
359
484
  // shutdown if write to reserved CR4 bits
360
 
  if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4))) {
 
485
  if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_FIELD_CR4))) {
361
486
    BX_PANIC(("SMM restore: incorrect CR4 state !"));
362
487
    return 0;
363
488
  }
367
492
    return 0;
368
493
  }
369
494
 
370
 
  BX_CPU_THIS_PTR efer.setRegister(temp_efer & BX_EFER_SUPPORTED_BITS);
 
495
  BX_CPU_THIS_PTR efer.set32(temp_efer & BX_EFER_SUPPORTED_BITS);
371
496
 
372
497
  if (BX_CPU_THIS_PTR efer.get_LMA()) {
373
498
    if (temp_eflags & EFlagsVMMask) {
391
516
  // hack CR0 to be able to back to long mode correctly
392
517
  BX_CPU_THIS_PTR cr0.set_PE(0); // real mode (bit 0)
393
518
  BX_CPU_THIS_PTR cr0.set_PG(0); // paging disabled (bit 31)
394
 
  SetCR0(temp_cr0);
 
519
  if (! SetCR0(temp_cr0)) {
 
520
    BX_PANIC(("SMM restore: failed to restore CR0 !"));
 
521
    return 0;
 
522
  }
395
523
  setEFlags(temp_eflags);
396
524
 
397
 
  bx_phy_address temp_cr3 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3);
 
525
  bx_phy_address temp_cr3 = (bx_phy_address) SMRAM_FIELD64(saved_state, SMRAM_FIELD_CR3_HI32, SMRAM_FIELD_CR3);
398
526
  SetCR3(temp_cr3);
399
527
 
400
 
  RAX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RAX_HI32, SMRAM_OFFSET_RAX_LO32);
401
 
  RBX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RBX_HI32, SMRAM_OFFSET_RBX_LO32);
402
 
  RCX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RCX_HI32, SMRAM_OFFSET_RCX_LO32);
403
 
  RDX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RDX_HI32, SMRAM_OFFSET_RDX_LO32);
404
 
  RSP = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RSP_HI32, SMRAM_OFFSET_RSP_LO32);
405
 
  RBP = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RBP_HI32, SMRAM_OFFSET_RBP_LO32);
406
 
  RSI = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RSI_HI32, SMRAM_OFFSET_RSI_LO32);
407
 
  RDI = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RDI_HI32, SMRAM_OFFSET_RDI_LO32);
408
 
  R8  = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R8_HI32,  SMRAM_OFFSET_R8_LO32);
409
 
  R9  = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R9_HI32,  SMRAM_OFFSET_R9_LO32);
410
 
  R10 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R10_HI32, SMRAM_OFFSET_R10_LO32);
411
 
  R11 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R11_HI32, SMRAM_OFFSET_R11_LO32);
412
 
  R12 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R12_HI32, SMRAM_OFFSET_R12_LO32);
413
 
  R13 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R13_HI32, SMRAM_OFFSET_R13_LO32);
414
 
  R14 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R14_HI32, SMRAM_OFFSET_R14_LO32);
415
 
  R15 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R15_HI32, SMRAM_OFFSET_R15_LO32);
416
 
  RIP = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RIP_HI32, SMRAM_OFFSET_RIP_LO32);
417
 
 
418
 
  BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6);
419
 
  BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7);
420
 
 
421
 
  BX_CPU_THIS_PTR gdtr.base  = SMRAM_FIELD64(saved_state, SMRAM_GDTR_BASE_HI32, SMRAM_GDTR_BASE_LO32);
422
 
  BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT);
423
 
  BX_CPU_THIS_PTR idtr.base  = SMRAM_FIELD64(saved_state, SMRAM_IDTR_BASE_HI32, SMRAM_IDTR_BASE_LO32);
424
 
  BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT);
425
 
 
426
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS],
427
 
          SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) & 0xffff,
428
 
          SMRAM_FIELD64(saved_state, SMRAM_CS_BASE_HI32, SMRAM_CS_BASE_LO32),
429
 
          SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT),
430
 
          SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) >> 16))
431
 
  {
432
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment) {
433
 
        BX_PANIC(("SMM restore: restored valid non segment CS !"));
434
 
        return 0;
435
 
     }
 
528
  for (int n=0; n<BX_GENERAL_REGISTERS; n++) {
 
529
    Bit64u val_64 = SMRAM_FIELD64(saved_state,
 
530
           SMRAM_FIELD_RAX_HI32 + 2*n, SMRAM_FIELD_EAX + 2*n);
 
531
 
 
532
    BX_WRITE_64BIT_REG(n, val_64);
 
533
  }
 
534
 
 
535
  RIP = SMRAM_FIELD64(saved_state, SMRAM_FIELD_RIP_HI32, SMRAM_FIELD_EIP);
 
536
 
 
537
  BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6);
 
538
  BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7);
 
539
 
 
540
  BX_CPU_THIS_PTR gdtr.base  = SMRAM_FIELD64(saved_state, SMRAM_FIELD_GDTR_BASE_HI32, SMRAM_FIELD_GDTR_BASE);
 
541
  BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT);
 
542
  BX_CPU_THIS_PTR idtr.base  = SMRAM_FIELD64(saved_state, SMRAM_FIELD_IDTR_BASE_HI32, SMRAM_FIELD_IDTR_BASE);
 
543
  BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_LIMIT);
 
544
 
 
545
  for (int segreg = 0; segreg < 6; segreg++) {
 
546
    Bit16u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) >> 16;
 
547
    if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[segreg],
 
548
          (ar_data >> 8) & 1,
 
549
          SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) & 0xf0ff,
 
550
          SMRAM_FIELD64(saved_state, SMRAM_FIELD_ES_BASE_HI32 + 4*segreg, SMRAM_FIELD_ES_BASE + 4*segreg),
 
551
          SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_LIMIT + 4*segreg), ar_data))
 
552
    {
 
553
       if (! BX_CPU_THIS_PTR sregs[segreg].cache.segment) {
 
554
         BX_PANIC(("SMM restore: restored valid non segment %d !", segreg));
 
555
         return 0;
 
556
       }
 
557
    }
436
558
  }
437
559
 
438
560
  handleCpuModeChange();
439
561
 
440
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS],
441
 
          SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) & 0xffff,
442
 
          SMRAM_FIELD64(saved_state, SMRAM_DS_BASE_HI32, SMRAM_DS_BASE_LO32),
443
 
          SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT),
444
 
          SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) >> 16))
445
 
  {
446
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment) {
447
 
        BX_PANIC(("SMM restore: restored valid non segment DS !"));
448
 
        return 0;
449
 
     }
450
 
  }
451
 
 
452
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS],
453
 
          SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) & 0xffff,
454
 
          SMRAM_FIELD64(saved_state, SMRAM_SS_BASE_HI32, SMRAM_SS_BASE_LO32),
455
 
          SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT),
456
 
          SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) >> 16))
457
 
  {
458
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment) {
459
 
        BX_PANIC(("SMM restore: restored valid non segment SS !"));
460
 
        return 0;
461
 
     }
462
 
  }
463
 
 
464
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES],
465
 
          SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) & 0xffff,
466
 
          SMRAM_FIELD64(saved_state, SMRAM_ES_BASE_HI32, SMRAM_ES_BASE_LO32),
467
 
          SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT),
468
 
          SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) >> 16))
469
 
  {
470
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment) {
471
 
        BX_PANIC(("SMM restore: restored valid non segment ES !"));
472
 
        return 0;
473
 
     }
474
 
  }
475
 
 
476
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS],
477
 
          SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) & 0xffff,
478
 
          SMRAM_FIELD64(saved_state, SMRAM_FS_BASE_HI32, SMRAM_FS_BASE_LO32),
479
 
          SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT),
480
 
          SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) >> 16))
481
 
  {
482
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment) {
483
 
        BX_PANIC(("SMM restore: restored valid non segment FS !"));
484
 
        return 0;
485
 
     }
486
 
  }
487
 
 
488
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS],
489
 
          SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) & 0xffff,
490
 
          SMRAM_FIELD64(saved_state, SMRAM_GS_BASE_HI32, SMRAM_GS_BASE_LO32),
491
 
          SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT),
492
 
          SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) >> 16))
493
 
  {
494
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment) {
495
 
        BX_PANIC(("SMM restore: restored valid non segment GS !"));
496
 
        return 0;
497
 
     }
498
 
  }
499
 
 
 
562
  Bit16u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) >> 16;
500
563
  if (set_segment_ar_data(&BX_CPU_THIS_PTR ldtr,
501
 
          SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) & 0xffff,
502
 
          SMRAM_FIELD64(saved_state, SMRAM_LDTR_BASE_HI32, SMRAM_LDTR_BASE_LO32),
503
 
          SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT),
504
 
          SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) >> 16))
 
564
          (ar_data >> 8) & 1,
 
565
          SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) & 0xf0ff,
 
566
          SMRAM_FIELD64(saved_state, SMRAM_FIELD_LDTR_BASE_HI32, SMRAM_FIELD_LDTR_BASE),
 
567
          SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_LIMIT), ar_data))
505
568
  {
506
569
     if (BX_CPU_THIS_PTR ldtr.cache.type != BX_SYS_SEGMENT_LDT) {
507
570
        BX_PANIC(("SMM restore: LDTR is not LDT descriptor type !"));
509
572
     }
510
573
  }
511
574
 
 
575
  ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) >> 16;
512
576
  if (set_segment_ar_data(&BX_CPU_THIS_PTR tr,
513
 
          SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) & 0xffff,
514
 
          SMRAM_FIELD64(saved_state, SMRAM_TR_BASE_HI32, SMRAM_TR_BASE_LO32),
515
 
          SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT),
516
 
          SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) >> 16))
 
577
          (ar_data >> 8) & 1,
 
578
          SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) & 0xf0ff,
 
579
          SMRAM_FIELD64(saved_state, SMRAM_FIELD_TR_BASE_HI32, SMRAM_FIELD_TR_BASE),
 
580
          SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_LIMIT), ar_data))
517
581
  {
518
582
     if (BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_286_TSS &&
519
583
         BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_286_TSS &&
526
590
  }
527
591
 
528
592
  if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
529
 
     BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET);
 
593
     BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET);
530
594
 
531
595
  return 1;
532
596
}
535
599
 
536
600
void BX_CPU_C::smram_save_state(Bit32u *saved_state)
537
601
{
538
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0) = BX_CPU_THIS_PTR cr0.getRegister();
539
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3) = BX_CPU_THIS_PTR cr3;
540
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFLAGS) = read_eflags();
541
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_EIP) = EIP;
542
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDI) = EDI;
543
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESI) = ESI;
544
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBP) = EBP;
545
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESP) = ESP;
546
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBX) = EBX;
547
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDX) = EDX;
548
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_ECX) = ECX;
549
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_EAX) = EAX;
550
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6) = BX_CPU_THIS_PTR dr6;
551
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7) = BX_CPU_THIS_PTR dr7;
552
 
  SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR)   = BX_CPU_THIS_PTR   tr.selector.value;
553
 
  SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR) = BX_CPU_THIS_PTR ldtr.selector.value;
554
 
 
555
 
  SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR) =
556
 
    BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
557
 
  SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR) =
558
 
    BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
559
 
  SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR) =
560
 
    BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
561
 
  SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR) =
562
 
    BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
563
 
  SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR) =
564
 
    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
565
 
  SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR) =
566
 
    BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
567
 
 
568
 
  // --- SS selector --- //
569
 
  bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]);
570
 
  SMRAM_FIELD(saved_state, SMRAM_SS_BASE) = seg->cache.u.segment.base;
571
 
  SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT) = seg->cache.u.segment.limit;
572
 
  SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) = seg->selector.value |
573
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
574
 
  // --- CS selector --- //
575
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]);
576
 
  SMRAM_FIELD(saved_state, SMRAM_CS_BASE) = seg->cache.u.segment.base;
577
 
  SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT) = seg->cache.u.segment.limit;
578
 
  SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) = seg->selector.value |
579
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
580
 
  // --- ES selector --- //
581
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES]);
582
 
  SMRAM_FIELD(saved_state, SMRAM_ES_BASE) = seg->cache.u.segment.base;
583
 
  SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT) = seg->cache.u.segment.limit;
584
 
  SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) = seg->selector.value |
585
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
 
602
  SMRAM_FIELD(saved_state, SMRAM_FIELD_SMM_REVISION_ID) = SMM_REVISION_ID;
 
603
  SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET)   = BX_CPU_THIS_PTR smbase;
 
604
 
 
605
  for (int n=0; n<BX_GENERAL_REGISTERS; n++) {
 
606
    Bit32u val_32 = BX_READ_32BIT_REG(n);
 
607
    SMRAM_FIELD(saved_state, SMRAM_FIELD_EAX + n) = val_32;
 
608
  }
 
609
 
 
610
  SMRAM_FIELD(saved_state, SMRAM_FIELD_EIP) = EIP;
 
611
  SMRAM_FIELD(saved_state, SMRAM_FIELD_EFLAGS) = read_eflags();
 
612
 
 
613
  SMRAM_FIELD(saved_state, SMRAM_FIELD_CR0) = BX_CPU_THIS_PTR cr0.get32();
 
614
  SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3) = BX_CPU_THIS_PTR cr3;
 
615
#if BX_CPU_LEVEL >= 4
 
616
  SMRAM_FIELD(saved_state, SMRAM_FIELD_CR4) = BX_CPU_THIS_PTR cr4.get32();
 
617
#endif
 
618
  SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6) = BX_CPU_THIS_PTR dr6;
 
619
  SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7) = BX_CPU_THIS_PTR dr7;
 
620
 
 
621
  // --- Task Register --- //
 
622
  SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR) = BX_CPU_THIS_PTR tr.selector.value;
 
623
  SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_BASE) = BX_CPU_THIS_PTR tr.cache.u.segment.base;
 
624
  SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.segment.limit_scaled;
 
625
  Bit32u tr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR tr.cache) >> 8) & 0xf0ff) | (BX_CPU_THIS_PTR tr.cache.valid << 8);
 
626
  SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value | (tr_ar << 16);
 
627
 
586
628
  // --- LDTR --- //
587
 
  SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE) = BX_CPU_THIS_PTR ldtr.cache.u.system.base;
588
 
  SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.system.limit;
589
 
  SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value |
590
 
    (((Bit32u) get_segment_ar_data(&BX_CPU_THIS_PTR ldtr.cache)) << 16);
 
629
  SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR) = BX_CPU_THIS_PTR ldtr.selector.value;
 
630
  SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_BASE) = BX_CPU_THIS_PTR ldtr.cache.u.segment.base;
 
631
  SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.segment.limit_scaled;
 
632
  Bit32u ldtr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache) >> 8) & 0xf0ff) | (BX_CPU_THIS_PTR ldtr.cache.valid << 8);
 
633
  SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value | (ldtr_ar << 16);
 
634
 
 
635
  // --- IDTR --- //
 
636
  SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_BASE) = BX_CPU_THIS_PTR idtr.base;
 
637
  SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
 
638
 
591
639
  // --- GDTR --- //
592
 
  SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE) = BX_CPU_THIS_PTR gdtr.base;
593
 
  SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
594
 
  /* base+0x7f6c is reserved */
595
 
  /* base+0x7f68 is reserved */
596
 
 
597
 
  // --- Task Register --- //
598
 
  SMRAM_FIELD(saved_state, SMRAM_TR_BASE) = BX_CPU_THIS_PTR tr.cache.u.system.base;
599
 
  SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.system.limit;
600
 
  SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value |
601
 
    (((Bit32u) get_segment_ar_data(&BX_CPU_THIS_PTR tr.cache)) << 16);
602
 
 
603
 
  // --- IDTR --- //
604
 
  SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE) = BX_CPU_THIS_PTR idtr.base;
605
 
  SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
606
 
  /* base+0x7f50 is reserved */
607
 
  // --- GS selector --- //
608
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS]);
609
 
  SMRAM_FIELD(saved_state, SMRAM_GS_BASE) = seg->cache.u.segment.base;
610
 
  SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT) = seg->cache.u.segment.limit;
611
 
  SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) = seg->selector.value |
612
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
613
 
  // --- FS selector --- //
614
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS]);
615
 
  SMRAM_FIELD(saved_state, SMRAM_FS_BASE) = seg->cache.u.segment.base;
616
 
  SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT) = seg->cache.u.segment.limit;
617
 
  SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) = seg->selector.value |
618
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
619
 
  // --- DS selector --- //
620
 
  seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]);
621
 
  SMRAM_FIELD(saved_state, SMRAM_DS_BASE) = seg->cache.u.segment.base;
622
 
  SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT) = seg->cache.u.segment.limit;
623
 
  SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) = seg->selector.value |
624
 
    (((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
625
 
 
626
 
  /* base+0x7f28 to base+7f18 is reserved */
627
 
#if BX_CPU_LEVEL >= 4
628
 
  SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4) = BX_CPU_THIS_PTR cr4.getRegister();
629
 
#endif
630
 
 
631
 
  /* base+0x7f02 is Auto HALT restart field (2 byte) */
632
 
  /* base+0x7f00 is I/O restart field (2 byte) */
633
 
  SMRAM_FIELD(saved_state, SMRAM_SMM_REVISION_ID) = SMM_REVISION_ID;
634
 
  SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET)   = BX_CPU_THIS_PTR smbase;
635
 
  /* base+0x7ef4 to base+0x7e00 is reserved */
 
640
  SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_BASE) = BX_CPU_THIS_PTR gdtr.base;
 
641
  SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
 
642
 
 
643
  for (int segreg = 0; segreg < 6; segreg++) {
 
644
    bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[segreg]);
 
645
    SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR + 4*segreg) = seg->selector.value;
 
646
    SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_BASE + 4*segreg) = seg->cache.u.segment.base;
 
647
    SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_LIMIT + 4*segreg) = seg->cache.u.segment.limit_scaled;
 
648
    Bit32u seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xf0ff) | (seg->cache.valid << 8);
 
649
    SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) = seg->selector.value | (seg_ar << 16);
 
650
  }
636
651
}
637
652
 
638
653
bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
639
654
{
640
 
  Bit32u temp_cr0    = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0);
641
 
  Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFLAGS);
642
 
  Bit32u temp_cr3    = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3);
 
655
  Bit32u temp_cr0    = SMRAM_FIELD(saved_state, SMRAM_FIELD_CR0);
 
656
  Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_FIELD_EFLAGS);
 
657
  Bit32u temp_cr3    = SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3);
643
658
 
644
659
  bx_bool pe = (temp_cr0 & 0x01);
645
660
  bx_bool nw = (temp_cr0 >> 29) & 0x01;
657
672
    return 0;
658
673
  }
659
674
 
660
 
  SetCR0(temp_cr0);
 
675
  if (!SetCR0(temp_cr0)) {
 
676
    BX_PANIC(("SMM restore: failed to restore CR0 !"));
 
677
    return 0;
 
678
  }
661
679
  SetCR3(temp_cr3);
662
680
  setEFlags(temp_eflags);
663
681
 
664
682
#if BX_CPU_LEVEL >= 4
665
 
  if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4))) {
 
683
  if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_FIELD_CR4))) {
666
684
    BX_PANIC(("SMM restore: incorrect CR4 state !"));
667
685
    return 0;
668
686
  }
669
687
#endif
670
688
 
671
 
  EIP = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EIP);
672
 
  EDI = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDI);
673
 
  ESI = SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESI);
674
 
  EBP = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBP);
675
 
  ESP = SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESP);
676
 
  EBX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBX);
677
 
  EDX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDX);
678
 
  ECX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_ECX);
679
 
  EAX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EAX);
680
 
 
681
 
  BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6);
682
 
  BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7);
683
 
 
684
 
  BX_CPU_THIS_PTR gdtr.base  = SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE);
685
 
  BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT);
686
 
  BX_CPU_THIS_PTR idtr.base  = SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE);
687
 
  BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT);
688
 
 
689
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS],
690
 
          SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) & 0xffff,
691
 
          SMRAM_FIELD(saved_state, SMRAM_CS_BASE),
692
 
          SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT),
693
 
          SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) >> 16))
694
 
  {
695
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment) {
696
 
        BX_PANIC(("SMM restore: restored valid non segment CS !"));
697
 
        return 0;
698
 
     }
699
 
  }
700
 
 
701
 
  handleCpuModeChange();
702
 
 
703
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS],
704
 
          SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) & 0xffff,
705
 
          SMRAM_FIELD(saved_state, SMRAM_DS_BASE),
706
 
          SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT),
707
 
          SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) >> 16))
708
 
  {
709
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment) {
710
 
        BX_PANIC(("SMM restore: restored valid non segment DS !"));
711
 
        return 0;
712
 
     }
713
 
  }
714
 
 
715
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS],
716
 
          SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) & 0xffff,
717
 
          SMRAM_FIELD(saved_state, SMRAM_SS_BASE),
718
 
          SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT),
719
 
          SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) >> 16))
720
 
  {
721
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment) {
722
 
        BX_PANIC(("SMM restore: restored valid non segment SS !"));
723
 
        return 0;
724
 
     }
725
 
  }
726
 
 
727
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES],
728
 
          SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) & 0xffff,
729
 
          SMRAM_FIELD(saved_state, SMRAM_ES_BASE),
730
 
          SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT),
731
 
          SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) >> 16))
732
 
  {
733
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment) {
734
 
        BX_PANIC(("SMM restore: restored valid non segment ES !"));
735
 
        return 0;
736
 
     }
737
 
  }
738
 
 
739
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS],
740
 
          SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) & 0xffff,
741
 
          SMRAM_FIELD(saved_state, SMRAM_FS_BASE),
742
 
          SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT),
743
 
          SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) >> 16))
744
 
  {
745
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment) {
746
 
        BX_PANIC(("SMM restore: restored valid non segment FS !"));
747
 
        return 0;
748
 
     }
749
 
  }
750
 
 
751
 
  if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS],
752
 
          SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) & 0xffff,
753
 
          SMRAM_FIELD(saved_state, SMRAM_GS_BASE),
754
 
          SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT),
755
 
          SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) >> 16))
756
 
  {
757
 
     if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment) {
758
 
        BX_PANIC(("SMM restore: restored valid non segment GS !"));
759
 
        return 0;
760
 
     }
761
 
  }
762
 
 
 
689
  for (int n=0; n<BX_GENERAL_REGISTERS; n++) {
 
690
    Bit32u val_32 = SMRAM_FIELD(saved_state, SMRAM_FIELD_EAX + n);
 
691
    BX_WRITE_32BIT_REGZ(n, val_32);
 
692
  }
 
693
 
 
694
  EIP = SMRAM_FIELD(saved_state, SMRAM_FIELD_EIP);
 
695
 
 
696
  BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6);
 
697
  BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7);
 
698
 
 
699
  BX_CPU_THIS_PTR gdtr.base  = SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_BASE);
 
700
  BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT);
 
701
 
 
702
  BX_CPU_THIS_PTR idtr.base  = SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_BASE);
 
703
  BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_LIMIT);
 
704
 
 
705
  for (int segreg = 0; segreg < 6; segreg++) {
 
706
    Bit32u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) >> 16;
 
707
    if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[segreg],
 
708
          (ar_data >> 8) & 1,
 
709
          SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) & 0xf0ff,
 
710
          SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_BASE + 4*segreg),
 
711
          SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_LIMIT + 4*segreg), ar_data))
 
712
    {
 
713
       if (! BX_CPU_THIS_PTR sregs[segreg].cache.segment) {
 
714
         BX_PANIC(("SMM restore: restored valid non segment %d !", segreg));
 
715
         return 0;
 
716
       }
 
717
    }
 
718
  }
 
719
 
 
720
  Bit32u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) >> 16;
763
721
  if (set_segment_ar_data(&BX_CPU_THIS_PTR ldtr,
764
 
          SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) & 0xffff,
765
 
          SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE),
766
 
          SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT),
767
 
          SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) >> 16))
 
722
          (ar_data >> 8) & 1,
 
723
          SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) & 0xf0ff,
 
724
          SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_BASE),
 
725
          SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_LIMIT), ar_data))
768
726
  {
769
727
     if (BX_CPU_THIS_PTR ldtr.cache.type != BX_SYS_SEGMENT_LDT) {
770
728
        BX_PANIC(("SMM restore: LDTR is not LDT descriptor type !"));
772
730
     }
773
731
  }
774
732
 
 
733
  ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) >> 16;
775
734
  if (set_segment_ar_data(&BX_CPU_THIS_PTR tr,
776
 
          SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) & 0xffff,
777
 
          SMRAM_FIELD(saved_state, SMRAM_TR_BASE),
778
 
          SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT),
779
 
          SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) >> 16))
 
735
          (ar_data >> 8) & 1,
 
736
          SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) & 0xf0ff,
 
737
          SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_BASE),
 
738
          SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_LIMIT), ar_data))
780
739
  {
781
740
     if (BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_286_TSS &&
782
741
         BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_286_TSS &&
789
748
  }
790
749
 
791
750
  if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) {
792
 
     BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET);
 
751
     BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET);
793
752
#if BX_CPU_LEVEL < 6
794
753
     if (BX_CPU_THIS_PTR smbase & 0x7fff) {
795
754
        BX_PANIC(("SMM restore: SMBASE must be aligned to 32K !"));