- tftp_send_optack() was not 64-bit clean (patch from SF bug #1787500)
[bochs-mirror.git] / cpu / debugstuff.cc
blob1baf4f6666b35c08dddc06557dc89949c0a0ce66
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: debugstuff.cc,v 1.77 2006/10/02 17:40:19 vruppert Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2001 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define NEED_CPU_REG_SHORTCUTS 1
29 #include "bochs.h"
30 #include "cpu.h"
31 #define LOG_THIS BX_CPU_THIS_PTR
34 #if BX_DISASM
35 void BX_CPU_C::debug_disasm_instruction(bx_address offset)
37 bx_phy_address phy_addr;
38 Bit8u instr_buf[16];
39 char char_buf[512];
40 unsigned i=0;
42 static char letters[] = "0123456789ABCDEF";
43 static disassembler bx_disassemble;
44 unsigned remainsInPage = 0x1000 - (offset & 0xfff);
46 bx_bool valid = dbg_xlate_linear2phy(BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS) + offset, &phy_addr);
47 if (valid && BX_CPU_THIS_PTR mem!=NULL) {
48 BX_CPU_THIS_PTR mem->dbg_fetch_mem(BX_CPU_THIS, phy_addr, 16, instr_buf);
49 char_buf[i++] = '>';
50 char_buf[i++] = '>';
51 char_buf[i++] = ' ';
52 unsigned isize = bx_disassemble.disasm(
53 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b,
54 BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64,
55 BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS), offset,
56 instr_buf, char_buf+i);
57 if (isize <= remainsInPage) {
58 i=strlen(char_buf);
59 char_buf[i++] = ' ';
60 char_buf[i++] = ':';
61 char_buf[i++] = ' ';
62 for (unsigned j=0; j<isize; j++) {
63 char_buf[i++] = letters[(instr_buf[j] >> 4) & 0xf];
64 char_buf[i++] = letters[(instr_buf[j] >> 0) & 0xf];
66 char_buf[i] = 0;
67 BX_INFO(("%s", char_buf));
69 else {
70 BX_INFO(("(instruction unavailable) page split instruction"));
73 else {
74 BX_INFO(("(instruction unavailable) page not present"));
77 #endif // #if BX_DISASM
79 const char* cpu_mode_string(unsigned cpu_mode)
81 static const char *cpu_mode_name[] = {
82 "real mode",
83 "v8086 mode",
84 "protected mode",
85 "compatibility mode",
86 "long mode",
87 "unknown mode"
90 if(cpu_mode >= 5) cpu_mode = 5;
91 return cpu_mode_name[cpu_mode];
94 void BX_CPU_C::debug(bx_address offset)
96 BX_INFO(("%s", cpu_mode_string(BX_CPU_THIS_PTR cpu_mode)));
97 BX_INFO(("CS.d_b = %u bit",
98 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b ? 32 : 16));
99 BX_INFO(("SS.d_b = %u bit",
100 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b ? 32 : 16));
101 #if BX_SUPPORT_X86_64
102 BX_INFO(("EFER = 0x%08x", BX_CPU_THIS_PTR get_EFER()));
103 BX_INFO(("| RAX=%08x%08x RBX=%08x%08x",
104 (unsigned) (RAX >> 32), (unsigned) EAX,
105 (unsigned) (RBX >> 32), (unsigned) EBX));
106 BX_INFO(("| RCX=%08x%08x RDX=%08x%08x",
107 (unsigned) (RCX >> 32), (unsigned) ECX,
108 (unsigned) (RDX >> 32), (unsigned) EDX));
109 BX_INFO(("| RSP=%08x%08x RBP=%08x%08x",
110 (unsigned) (RSP >> 32), (unsigned) ESP,
111 (unsigned) (RBP >> 32), (unsigned) EBP));
112 BX_INFO(("| RSI=%08x%08x RDI=%08x%08x",
113 (unsigned) (RSI >> 32), (unsigned) ESI,
114 (unsigned) (RDI >> 32), (unsigned) EDI));
115 BX_INFO(("| R8=%08x%08x R9=%08x%08x",
116 (unsigned) (R8 >> 32), (unsigned) (R8 & 0xFFFFFFFF),
117 (unsigned) (R9 >> 32), (unsigned) (R9 & 0xFFFFFFFF)));
118 BX_INFO(("| R10=%08x%08x R11=%08x%08x",
119 (unsigned) (R10 >> 32), (unsigned) (R10 & 0xFFFFFFFF),
120 (unsigned) (R11 >> 32), (unsigned) (R11 & 0xFFFFFFFF)));
121 BX_INFO(("| R12=%08x%08x R13=%08x%08x",
122 (unsigned) (R12 >> 32), (unsigned) (R12 & 0xFFFFFFFF),
123 (unsigned) (R13 >> 32), (unsigned) (R13 & 0xFFFFFFFF)));
124 BX_INFO(("| R14=%08x%08x R15=%08x%08x",
125 (unsigned) (R14 >> 32), (unsigned) (R14 & 0xFFFFFFFF),
126 (unsigned) (R15 >> 32), (unsigned) (R15 & 0xFFFFFFFF)));
127 #else
128 BX_INFO(("| EAX=%08x EBX=%08x ECX=%08x EDX=%08x",
129 (unsigned) EAX, (unsigned) EBX, (unsigned) ECX, (unsigned) EDX));
130 BX_INFO(("| ESP=%08x EBP=%08x ESI=%08x EDI=%08x",
131 (unsigned) ESP, (unsigned) EBP, (unsigned) ESI, (unsigned) EDI));
132 #endif
133 BX_INFO(("| IOPL=%1u %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
134 BX_CPU_THIS_PTR get_IOPL(),
135 BX_CPU_THIS_PTR get_ID() ? "ID" : "id",
136 BX_CPU_THIS_PTR get_VIP() ? "VIP" : "vip",
137 BX_CPU_THIS_PTR get_VIF() ? "VIF" : "vif",
138 BX_CPU_THIS_PTR get_AC() ? "AC" : "ac",
139 BX_CPU_THIS_PTR get_VM() ? "VM" : "vm",
140 BX_CPU_THIS_PTR get_RF() ? "RF" : "rf",
141 BX_CPU_THIS_PTR get_NT() ? "NT" : "nt",
142 BX_CPU_THIS_PTR get_OF() ? "OF" : "of",
143 BX_CPU_THIS_PTR get_DF() ? "DF" : "df",
144 BX_CPU_THIS_PTR get_IF() ? "IF" : "if",
145 BX_CPU_THIS_PTR get_TF() ? "TF" : "tf",
146 BX_CPU_THIS_PTR get_SF() ? "SF" : "sf",
147 BX_CPU_THIS_PTR get_ZF() ? "ZF" : "zf",
148 BX_CPU_THIS_PTR get_AF() ? "AF" : "af",
149 BX_CPU_THIS_PTR get_PF() ? "PF" : "pf",
150 BX_CPU_THIS_PTR get_CF() ? "CF" : "cf"));
152 BX_INFO(("| SEG selector base limit G D"));
153 BX_INFO(("| SEG sltr(index|ti|rpl) base limit G D"));
154 BX_INFO(("| CS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u",
155 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
156 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index,
157 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti,
158 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl,
159 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base,
160 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit,
161 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g,
162 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b));
163 BX_INFO(("| DS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u",
164 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value,
165 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index,
166 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti,
167 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl,
168 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base,
169 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit,
170 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g,
171 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b));
172 BX_INFO(("| SS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u",
173 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value,
174 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index,
175 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti,
176 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl,
177 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base,
178 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit,
179 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g,
180 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b));
181 BX_INFO(("| ES:%04x( %04x| %01u| %1u) %08x %08x %1u %1u",
182 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value,
183 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index,
184 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti,
185 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl,
186 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base,
187 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit,
188 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g,
189 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b));
190 BX_INFO(("| FS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u",
191 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value,
192 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index,
193 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti,
194 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl,
195 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base,
196 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit,
197 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g,
198 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b));
199 BX_INFO(("| GS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u",
200 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value,
201 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index,
202 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti,
203 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl,
204 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base,
205 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit,
206 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g,
207 (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b));
208 #if BX_SUPPORT_X86_64
209 BX_INFO(("| MSR_FS_BASE:%08x%08x",
210 (unsigned) (MSR_FSBASE >> 32), (unsigned) (MSR_FSBASE & 0xFFFFFFFF)));
211 BX_INFO(("| MSR_GS_BASE:%08x%08x",
212 (unsigned) (MSR_GSBASE >> 32), (unsigned) (MSR_GSBASE & 0xFFFFFFFF)));
213 #endif
215 #if BX_SUPPORT_X86_64
216 BX_INFO(("| RIP=%08x%08x (%08x%08x)",
217 (unsigned) BX_CPU_THIS_PTR dword.rip_upper, (unsigned) EIP,
218 (unsigned) (BX_CPU_THIS_PTR prev_eip >> 32),
219 (unsigned) (BX_CPU_THIS_PTR prev_eip & 0xffffffff)));
220 BX_INFO(("| CR0=0x%08x CR1=0x%x CR2=0x%08x%08x",
221 (unsigned) (BX_CPU_THIS_PTR cr0.val32), 0,
222 (unsigned) (BX_CPU_THIS_PTR cr2 >> 32),
223 (unsigned) (BX_CPU_THIS_PTR cr2 & 0xffffffff)));
224 BX_INFO(("| CR3=0x%08x CR4=0x%08x",
225 (unsigned) BX_CPU_THIS_PTR cr3, BX_CPU_THIS_PTR cr4.getRegister()));
226 #else
227 BX_INFO(("| EIP=%08x (%08x)", (unsigned) EIP,
228 (unsigned) BX_CPU_THIS_PTR prev_eip));
230 #if BX_CPU_LEVEL >= 2 && BX_CPU_LEVEL < 4
231 BX_INFO(("| CR0=0x%08x CR1=%x CR2=0x%08x CR3=0x%08x",
232 BX_CPU_THIS_PTR cr0.val32, 0,
233 BX_CPU_THIS_PTR cr2,
234 BX_CPU_THIS_PTR cr3));
235 #elif BX_CPU_LEVEL >= 4
236 BX_INFO(("| CR0=0x%08x CR1=%x CR2=0x%08x",
237 BX_CPU_THIS_PTR cr0.val32, 0,
238 BX_CPU_THIS_PTR cr2));
239 BX_INFO(("| CR3=0x%08x CR4=0x%08x",
240 BX_CPU_THIS_PTR cr3,
241 BX_CPU_THIS_PTR cr4.getRegister()));
242 #endif
244 #endif // BX_SUPPORT_X86_64
247 #if BX_DISASM
248 debug_disasm_instruction(offset);
249 #endif // #if BX_DISASM
253 #if BX_DEBUGGER
254 Bit32u BX_CPU_C::dbg_get_reg(unsigned reg)
256 Bit32u return_val32;
258 switch (reg) {
259 case BX_DBG_REG_EIP: return(EIP);
260 case BX_DBG_REG_EFLAGS:
261 return_val32 = BX_CPU_THIS_PTR read_eflags();
262 return(return_val32);
263 case BX_DBG_REG_CS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
264 case BX_DBG_REG_SS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
265 case BX_DBG_REG_DS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
266 case BX_DBG_REG_ES: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
267 case BX_DBG_REG_FS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
268 case BX_DBG_REG_GS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
269 case BX_DBG_REG_CR0:
270 return BX_CPU_THIS_PTR cr0.val32;
271 case BX_DBG_REG_CR2:
272 return BX_CPU_THIS_PTR cr2;
273 case BX_DBG_REG_CR3:
274 return BX_CPU_THIS_PTR cr3;
275 #if BX_CPU_LEVEL >= 4
276 case BX_DBG_REG_CR4:
277 return BX_CPU_THIS_PTR cr4.getRegister();
278 #endif
279 default:
280 BX_PANIC(("get_reg: request for unknown register"));
281 return(0);
285 bx_bool BX_CPU_C::dbg_set_reg(unsigned reg, Bit32u val)
287 // returns 1=OK, 0=can't change
288 bx_segment_reg_t *seg;
289 Bit32u current_sys_bits;
291 switch (reg) {
292 case BX_DBG_REG_EIP: EIP = val; return(1);
293 case BX_DBG_REG_EFLAGS:
294 BX_INFO(("dbg_set_reg: can not handle eflags yet."));
295 if (val & 0xffff0000) {
296 BX_INFO(("dbg_set_reg: can not set upper 16 bits of eflags."));
297 return(0);
299 // make sure none of the system bits are being changed
300 current_sys_bits = ((BX_CPU_THIS_PTR getB_NT()) << 14) |
301 (BX_CPU_THIS_PTR get_IOPL () << 12) |
302 ((BX_CPU_THIS_PTR getB_TF()) << 8);
303 if (current_sys_bits != (val & 0x0000f100)) {
304 BX_INFO(("dbg_set_reg: can not modify NT, IOPL, or TF."));
305 return(0);
307 BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
308 BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
309 BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
310 BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
311 BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 2;
312 BX_CPU_THIS_PTR set_IF(val & 0x01); val >>= 1;
313 BX_CPU_THIS_PTR set_DF(val & 0x01); val >>= 1;
314 BX_CPU_THIS_PTR set_OF(val & 0x01);
315 if (BX_CPU_THIS_PTR get_IF())
316 BX_CPU_THIS_PTR async_event = 1;
317 return(1);
318 case BX_DBG_REG_CS:
319 seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
320 break;
321 case BX_DBG_REG_SS:
322 seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
323 break;
324 case BX_DBG_REG_DS:
325 seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
326 break;
327 case BX_DBG_REG_ES:
328 seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES];
329 break;
330 case BX_DBG_REG_FS:
331 seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS];
332 break;
333 case BX_DBG_REG_GS:
334 seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS];
335 break;
336 default:
337 BX_PANIC(("dbg_set_reg: unrecognized register ID (%u)", reg));
338 return(0);
341 if (real_mode()) {
342 seg->selector.value = val;
343 seg->cache.valid = 1;
344 seg->cache.p = 1;
345 seg->cache.dpl = 0;
346 seg->cache.segment = 1; // regular segment
347 if (reg == BX_DBG_REG_CS)
348 seg->cache.type = BX_CODE_EXEC_READ_ACCESSED;
349 else
350 seg->cache.type = BX_DATA_READ_WRITE_ACCESSED;
351 seg->cache.u.segment.base = val << 4;
352 seg->cache.u.segment.limit = 0xffff;
353 seg->cache.u.segment.limit_scaled = 0xffff;
354 seg->cache.u.segment.g = 0; // byte granular
355 seg->cache.u.segment.d_b = 0; // default 16bit size
356 seg->cache.u.segment.avl = 0;
357 return(1); // ok
360 return(0); // can't change when not in real mode
363 unsigned BX_CPU_C::dbg_query_pending(void)
365 unsigned ret = 0;
367 if (BX_HRQ) { // DMA Hold Request
368 ret |= BX_DBG_PENDING_DMA;
371 if (BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR get_IF()) {
372 ret |= BX_DBG_PENDING_IRQ;
375 return(ret);
378 bx_bool BX_CPU_C::dbg_get_sreg(bx_dbg_sreg_t *sreg, unsigned sreg_no)
380 if (sreg_no > 5)
381 return(0);
382 sreg->sel = BX_CPU_THIS_PTR sregs[sreg_no].selector.value;
383 sreg->des_l = get_descriptor_l(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
384 sreg->des_h = get_descriptor_h(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
385 sreg->valid = BX_CPU_THIS_PTR sregs[sreg_no].cache.valid;
386 return(1);
389 void BX_CPU_C::dbg_get_tr(bx_dbg_sreg_t *sreg)
391 sreg->sel = BX_CPU_THIS_PTR tr.selector.value;
392 sreg->des_l = get_descriptor_l(&BX_CPU_THIS_PTR tr.cache);
393 sreg->des_h = get_descriptor_h(&BX_CPU_THIS_PTR tr.cache);
394 sreg->valid = BX_CPU_THIS_PTR tr.cache.valid;
397 void BX_CPU_C::dbg_get_ldtr(bx_dbg_sreg_t *sreg)
399 sreg->sel = BX_CPU_THIS_PTR ldtr.selector.value;
400 sreg->des_l = get_descriptor_l(&BX_CPU_THIS_PTR ldtr.cache);
401 sreg->des_h = get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache);
402 sreg->valid = BX_CPU_THIS_PTR ldtr.cache.valid;
405 void BX_CPU_C::dbg_get_gdtr(bx_dbg_global_sreg_t *sreg)
407 sreg->base = BX_CPU_THIS_PTR gdtr.base;
408 sreg->limit = BX_CPU_THIS_PTR gdtr.limit;
411 void BX_CPU_C::dbg_get_idtr(bx_dbg_global_sreg_t *sreg)
413 sreg->base = BX_CPU_THIS_PTR idtr.base;
414 sreg->limit = BX_CPU_THIS_PTR idtr.limit;
417 bx_bool BX_CPU_C::dbg_get_cpu(bx_dbg_cpu_t *cpu)
419 cpu->eax = EAX;
420 cpu->ebx = EBX;
421 cpu->ecx = ECX;
422 cpu->edx = EDX;
423 cpu->ebp = EBP;
424 cpu->esi = ESI;
425 cpu->edi = EDI;
426 cpu->esp = ESP;
427 cpu->eip = EIP;
429 cpu->eflags = BX_CPU_THIS_PTR read_eflags();
431 cpu->cs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
432 cpu->cs.des_l = get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
433 cpu->cs.des_h = get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
434 cpu->cs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid;
436 cpu->ss.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
437 cpu->ss.des_l = get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
438 cpu->ss.des_h = get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
439 cpu->ss.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid;
441 cpu->ds.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
442 cpu->ds.des_l = get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
443 cpu->ds.des_h = get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
444 cpu->ds.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid;
446 cpu->es.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
447 cpu->es.des_l = get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
448 cpu->es.des_h = get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
449 cpu->es.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid;
451 cpu->fs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
452 cpu->fs.des_l = get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
453 cpu->fs.des_h = get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
454 cpu->fs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid;
456 cpu->gs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
457 cpu->gs.des_l = get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
458 cpu->gs.des_h = get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
459 cpu->gs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid;
461 cpu->ldtr.sel = BX_CPU_THIS_PTR ldtr.selector.value;
462 cpu->ldtr.des_l = get_descriptor_l(&BX_CPU_THIS_PTR ldtr.cache);
463 cpu->ldtr.des_h = get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache);
464 cpu->ldtr.valid = BX_CPU_THIS_PTR ldtr.cache.valid;
466 cpu->tr.sel = BX_CPU_THIS_PTR tr.selector.value;
467 cpu->tr.des_l = get_descriptor_l(&BX_CPU_THIS_PTR tr.cache);
468 cpu->tr.des_h = get_descriptor_h(&BX_CPU_THIS_PTR tr.cache);
469 cpu->tr.valid = BX_CPU_THIS_PTR tr.cache.valid;
471 cpu->gdtr.base = BX_CPU_THIS_PTR gdtr.base;
472 cpu->gdtr.limit = BX_CPU_THIS_PTR gdtr.limit;
474 cpu->idtr.base = BX_CPU_THIS_PTR idtr.base;
475 cpu->idtr.limit = BX_CPU_THIS_PTR idtr.limit;
477 cpu->dr0 = BX_CPU_THIS_PTR dr0;
478 cpu->dr1 = BX_CPU_THIS_PTR dr1;
479 cpu->dr2 = BX_CPU_THIS_PTR dr2;
480 cpu->dr3 = BX_CPU_THIS_PTR dr3;
481 cpu->dr6 = BX_CPU_THIS_PTR dr6;
482 cpu->dr7 = BX_CPU_THIS_PTR dr7;
484 #if BX_CPU_LEVEL >= 2
485 cpu->cr0 = BX_CPU_THIS_PTR cr0.val32;
486 cpu->cr1 = 0;
487 cpu->cr2 = BX_CPU_THIS_PTR cr2;
488 cpu->cr3 = BX_CPU_THIS_PTR cr3;
489 #endif
490 #if BX_CPU_LEVEL >= 4
491 cpu->cr4 = BX_CPU_THIS_PTR cr4.getRegister();
492 #endif
494 cpu->inhibit_mask = BX_CPU_THIS_PTR inhibit_mask;
496 return(1);
499 bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
501 // returns 1=OK, 0=Error
502 Bit32u type;
504 // =================================================
505 // Do checks first, before setting any CPU registers
506 // =================================================
508 // CS, SS, DS, ES, FS, GS descriptor checks
509 if (!cpu->cs.valid) {
510 BX_ERROR(("Error: CS not valid"));
511 return(0); // error
513 if ((cpu->cs.des_h & 0x1000) == 0) {
514 BX_ERROR(("Error: CS not application type"));
515 return(0); // error
517 if ((cpu->cs.des_h & 0x0800) == 0) {
518 BX_ERROR(("Error: CS not executable"));
519 return(0); // error
522 if (!cpu->ss.valid) {
523 BX_ERROR(("Error: SS not valid"));
524 return(0); // error
526 if ((cpu->ss.des_h & 0x1000) == 0) {
527 BX_ERROR(("Error: SS not application type"));
528 return(0); // error
531 if (cpu->ds.valid) {
532 if ((cpu->ds.des_h & 0x1000) == 0) {
533 BX_ERROR(("Error: DS not application type"));
534 return(0); // error
538 if (cpu->es.valid) {
539 if ((cpu->es.des_h & 0x1000) == 0) {
540 BX_ERROR(("Error: ES not application type"));
541 return(0); // error
545 if (cpu->fs.valid) {
546 if ((cpu->fs.des_h & 0x1000) == 0) {
547 BX_ERROR(("Error: FS not application type"));
548 return(0); // error
552 if (cpu->gs.valid) {
553 if ((cpu->gs.des_h & 0x1000) == 0) {
554 BX_ERROR(("Error: GS not application type"));
555 return(0); // error
559 if (cpu->ldtr.valid) {
560 if (cpu->ldtr.des_h & 0x1000) {
561 BX_ERROR(("Error: LDTR not system type"));
562 return(0); // error
564 if (((cpu->ldtr.des_h >> 8) & 0x0f) != BX_SYS_SEGMENT_LDT) {
565 BX_ERROR(("Error: LDTR descriptor type not LDT"));
566 return(0); // error
570 if (cpu->tr.valid) {
571 if (cpu->tr.des_h & 0x1000) {
572 BX_ERROR(("Error: TR not system type"));
573 return(0); // error
575 type = (cpu->tr.des_h >> 8) & 0x0f;
577 if ((type != 1) && (type != 9)) {
578 BX_ERROR(("Error: TR descriptor type not TSS"));
579 return(0); // error
583 // =============
584 // end of checks
585 // =============
587 EAX = cpu->eax;
588 EBX = cpu->ebx;
589 ECX = cpu->ecx;
590 EDX = cpu->edx;
591 EBP = cpu->ebp;
592 ESI = cpu->esi;
593 EDI = cpu->edi;
594 ESP = cpu->esp;
595 EIP = cpu->eip;
597 setEFlags(cpu->eflags);
599 // CS:
600 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cpu->cs.sel;
601 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cpu->cs.sel >> 3;
602 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = (cpu->cs.sel >> 2) & 0x01;
603 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = cpu->cs.sel & 0x03;
605 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = cpu->cs.valid;
606 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = (cpu->cs.des_h >> 15) & 0x01;
607 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = (cpu->cs.des_h >> 13) & 0x03;
608 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = (cpu->cs.des_h >> 12) & 0x01;
609 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = (cpu->cs.des_h >> 8) & 0x0f;
610 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = (cpu->cs.des_l >> 16);
611 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base |= (cpu->cs.des_h & 0xff) << 16;
612 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base |= (cpu->cs.des_h & 0xff000000);
613 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = (cpu->cs.des_l & 0xffff);
614 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit |= (cpu->cs.des_h & 0x000f0000);
615 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = (cpu->cs.des_h >> 23) & 0x01;
616 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = (cpu->cs.des_h >> 22) & 0x01;
617 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = (cpu->cs.des_h >> 20) & 0x01;
618 if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g)
619 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
620 (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit << 12) | 0x0fff;
621 else
622 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
623 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
625 #if BX_SUPPORT_ICACHE
626 BX_CPU_THIS_PTR updateFetchModeMask();
627 #endif
629 // SS:
630 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = cpu->ss.sel;
631 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = cpu->ss.sel >> 3;
632 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = (cpu->ss.sel >> 2) & 0x01;
633 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = cpu->ss.sel & 0x03;
635 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = cpu->ss.valid;
636 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = (cpu->ss.des_h >> 15) & 0x01;
637 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = (cpu->ss.des_h >> 13) & 0x03;
638 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = (cpu->ss.des_h >> 12) & 0x01;
639 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type = (cpu->ss.des_h >> 8) & 0x0f;
640 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base = (cpu->ss.des_l >> 16);
641 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base |= (cpu->ss.des_h & 0xff) << 16;
642 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base |= (cpu->ss.des_h & 0xff000000);
643 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = (cpu->ss.des_l & 0xffff);
644 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit |= (cpu->ss.des_h & 0x000f0000);
645 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g = (cpu->ss.des_h >> 23) & 0x01;
646 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b = (cpu->ss.des_h >> 22) & 0x01;
647 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = (cpu->ss.des_h >> 20) & 0x01;
648 if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g)
649 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
650 (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit << 12) | 0x0fff;
651 else
652 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
653 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit;
655 // DS:
656 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = cpu->ds.sel;
657 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = cpu->ds.sel >> 3;
658 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti = (cpu->ds.sel >> 2) & 0x01;
659 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = cpu->ds.sel & 0x03;
661 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = cpu->ds.valid;
662 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = (cpu->ds.des_h >> 15) & 0x01;
663 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = (cpu->ds.des_h >> 13) & 0x03;
664 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment = (cpu->ds.des_h >> 12) & 0x01;
665 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.type = (cpu->ds.des_h >> 8) & 0x0f;
666 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base = (cpu->ds.des_l >> 16);
667 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base |= (cpu->ds.des_h & 0xff) << 16;
668 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base |= (cpu->ds.des_h & 0xff000000);
669 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = (cpu->ds.des_l & 0xffff);
670 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit |= (cpu->ds.des_h & 0x000f0000);
671 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g = (cpu->ds.des_h >> 23) & 0x01;
672 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b = (cpu->ds.des_h >> 22) & 0x01;
673 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl = (cpu->ds.des_h >> 20) & 0x01;
674 if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g)
675 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
676 (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit << 12) | 0x0fff;
677 else
678 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
679 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit;
681 // ES:
682 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = cpu->es.sel;
683 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = cpu->es.sel >> 3;
684 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti = (cpu->es.sel >> 2) & 0x01;
685 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl = cpu->es.sel & 0x03;
687 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = cpu->es.valid;
688 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p = (cpu->es.des_h >> 15) & 0x01;
689 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl = (cpu->es.des_h >> 13) & 0x03;
690 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment = (cpu->es.des_h >> 12) & 0x01;
691 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.type = (cpu->es.des_h >> 8) & 0x0f;
692 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base = (cpu->es.des_l >> 16);
693 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base |= (cpu->es.des_h & 0xff) << 16;
694 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base |= (cpu->es.des_h & 0xff000000);
695 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit = (cpu->es.des_l & 0xffff);
696 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit |= (cpu->es.des_h & 0x000f0000);
697 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g = (cpu->es.des_h >> 23) & 0x01;
698 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b = (cpu->es.des_h >> 22) & 0x01;
699 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.avl = (cpu->es.des_h >> 20) & 0x01;
700 if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g)
701 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
702 (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit << 12) | 0x0fff;
703 else
704 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
705 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit;
707 // FS:
708 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = cpu->fs.sel;
709 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index = cpu->fs.sel >> 3;
710 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti = (cpu->fs.sel >> 2) & 0x01;
711 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl = cpu->fs.sel & 0x03;
713 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = cpu->fs.valid;
714 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.p = (cpu->fs.des_h >> 15) & 0x01;
715 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl = (cpu->fs.des_h >> 13) & 0x03;
716 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment = (cpu->fs.des_h >> 12) & 0x01;
717 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.type = (cpu->fs.des_h >> 8) & 0x0f;
718 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base = (cpu->fs.des_l >> 16);
719 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base |= (cpu->fs.des_h & 0xff) << 16;
720 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base |= (cpu->fs.des_h & 0xff000000);
721 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit = (cpu->fs.des_l & 0xffff);
722 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit |= (cpu->fs.des_h & 0x000f0000);
723 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g = (cpu->fs.des_h >> 23) & 0x01;
724 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b = (cpu->fs.des_h >> 22) & 0x01;
725 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.avl = (cpu->fs.des_h >> 20) & 0x01;
726 if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g)
727 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
728 (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit << 12) | 0x0fff;
729 else
730 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
731 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit;
733 // GS:
734 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = cpu->gs.sel;
735 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index = cpu->gs.sel >> 3;
736 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti = (cpu->gs.sel >> 2) & 0x01;
737 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl = cpu->gs.sel & 0x03;
739 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = cpu->gs.valid;
740 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.p = (cpu->gs.des_h >> 15) & 0x01;
741 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl = (cpu->gs.des_h >> 13) & 0x03;
742 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment = (cpu->gs.des_h >> 12) & 0x01;
743 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.type = (cpu->gs.des_h >> 8) & 0x0f;
744 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base = (cpu->gs.des_l >> 16);
745 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base |= (cpu->gs.des_h & 0xff) << 16;
746 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base |= (cpu->gs.des_h & 0xff000000);
747 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit = (cpu->gs.des_l & 0xffff);
748 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit |= (cpu->gs.des_h & 0x000f0000);
749 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g = (cpu->gs.des_h >> 23) & 0x01;
750 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b = (cpu->gs.des_h >> 22) & 0x01;
751 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.avl = (cpu->gs.des_h >> 20) & 0x01;
752 if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g)
753 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
754 (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit << 12) | 0x0fff;
755 else
756 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
757 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit;
759 // LDTR
760 BX_CPU_THIS_PTR ldtr.selector.value = cpu->ldtr.sel;
761 BX_CPU_THIS_PTR ldtr.selector.index = cpu->ldtr.sel >> 3;
762 BX_CPU_THIS_PTR ldtr.selector.ti = (cpu->ldtr.sel >> 2) & 0x01;
763 BX_CPU_THIS_PTR ldtr.selector.rpl = cpu->ldtr.sel & 0x03;
765 BX_CPU_THIS_PTR ldtr.cache.valid = cpu->ldtr.valid;
766 BX_CPU_THIS_PTR ldtr.cache.p = (cpu->ldtr.des_h >> 15) & 0x01;
767 BX_CPU_THIS_PTR ldtr.cache.dpl = (cpu->ldtr.des_h >> 13) & 0x03;
768 BX_CPU_THIS_PTR ldtr.cache.segment = (cpu->ldtr.des_h >> 12) & 0x01;
769 BX_CPU_THIS_PTR ldtr.cache.type = (cpu->ldtr.des_h >> 8) & 0x0f;
770 BX_CPU_THIS_PTR ldtr.cache.u.system.base = (cpu->ldtr.des_l >> 16);
771 BX_CPU_THIS_PTR ldtr.cache.u.system.base |= (cpu->ldtr.des_h & 0xff) << 16;
772 BX_CPU_THIS_PTR ldtr.cache.u.system.base |= (cpu->ldtr.des_h & 0xff000000);
773 BX_CPU_THIS_PTR ldtr.cache.u.system.limit = (cpu->ldtr.des_l & 0xffff);
774 BX_CPU_THIS_PTR ldtr.cache.u.system.limit |= (cpu->ldtr.des_h & 0x000f0000);
775 BX_CPU_THIS_PTR ldtr.cache.u.system.g = (cpu->ldtr.des_h >> 23) & 0x01;
776 BX_CPU_THIS_PTR ldtr.cache.u.system.avl = (cpu->ldtr.des_h >> 20) & 0x01;
778 if (BX_CPU_THIS_PTR ldtr.cache.u.system.g)
779 BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled =
780 (BX_CPU_THIS_PTR ldtr.cache.u.system.limit << 12) | 0x0fff;
781 else
782 BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled =
783 (BX_CPU_THIS_PTR ldtr.cache.u.system.limit);
785 // TR
786 type = (cpu->tr.des_h >> 8) & 0x0f;
787 type &= ~2; // never allow busy bit in tr.cache.type
788 BX_CPU_THIS_PTR tr.selector.value = cpu->tr.sel;
789 BX_CPU_THIS_PTR tr.selector.index = cpu->tr.sel >> 3;
790 BX_CPU_THIS_PTR tr.selector.ti = (cpu->tr.sel >> 2) & 0x01;
791 BX_CPU_THIS_PTR tr.selector.rpl = cpu->tr.sel & 0x03;
793 BX_CPU_THIS_PTR tr.cache.valid = cpu->tr.valid;
794 BX_CPU_THIS_PTR tr.cache.p = (cpu->tr.des_h >> 15) & 0x01;
795 BX_CPU_THIS_PTR tr.cache.dpl = (cpu->tr.des_h >> 13) & 0x03;
796 BX_CPU_THIS_PTR tr.cache.segment = (cpu->tr.des_h >> 12) & 0x01;
797 BX_CPU_THIS_PTR tr.cache.type = type;
798 if (type == BX_SYS_SEGMENT_AVAIL_286_TSS) {
799 BX_CPU_THIS_PTR tr.cache.u.system.base = (cpu->tr.des_l >> 16);
800 BX_CPU_THIS_PTR tr.cache.u.system.base |= (cpu->tr.des_h & 0xff) << 16;
801 BX_CPU_THIS_PTR tr.cache.u.system.limit = (cpu->tr.des_l & 0xffff);
802 BX_CPU_THIS_PTR tr.cache.u.system.g = 0;
803 BX_CPU_THIS_PTR tr.cache.u.system.avl = 0;
805 else { // type == BX_SYS_SEGMENT_AVAIL_386_TSS
806 BX_CPU_THIS_PTR tr.cache.u.system.base = (cpu->tr.des_l >> 16);
807 BX_CPU_THIS_PTR tr.cache.u.system.base |= (cpu->tr.des_h & 0xff) << 16;
808 BX_CPU_THIS_PTR tr.cache.u.system.base |= (cpu->tr.des_h & 0xff000000);
809 BX_CPU_THIS_PTR tr.cache.u.system.limit = (cpu->tr.des_l & 0xffff);
810 BX_CPU_THIS_PTR tr.cache.u.system.limit |= (cpu->tr.des_h & 0x000f0000);
811 BX_CPU_THIS_PTR tr.cache.u.system.g = (cpu->tr.des_h >> 23) & 0x01;
812 BX_CPU_THIS_PTR tr.cache.u.system.avl = (cpu->tr.des_h >> 20) & 0x01;
815 if (BX_CPU_THIS_PTR tr.cache.u.system.g)
816 BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled =
817 (BX_CPU_THIS_PTR tr.cache.u.system.limit << 12) | 0x0fff;
818 else
819 BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled =
820 (BX_CPU_THIS_PTR tr.cache.u.system.limit);
822 // GDTR
823 BX_CPU_THIS_PTR gdtr.base = cpu->gdtr.base;
824 BX_CPU_THIS_PTR gdtr.limit = cpu->gdtr.limit;
826 // IDTR
827 BX_CPU_THIS_PTR idtr.base = cpu->idtr.base;
828 BX_CPU_THIS_PTR idtr.limit = cpu->idtr.limit;
831 BX_CPU_THIS_PTR dr0 = cpu->dr0;
832 BX_CPU_THIS_PTR dr1 = cpu->dr1;
833 BX_CPU_THIS_PTR dr2 = cpu->dr2;
834 BX_CPU_THIS_PTR dr3 = cpu->dr3;
835 BX_CPU_THIS_PTR dr6 = cpu->dr6;
836 BX_CPU_THIS_PTR dr7 = cpu->dr7;
838 #if BX_CPU_LEVEL >= 2
839 // Control registers
840 SetCR0(cpu->cr0);
841 BX_CPU_THIS_PTR cr2 = cpu->cr2;
842 CR3_change(cpu->cr3);
843 #if BX_CPU_LEVEL >= 4
844 BX_CPU_THIS_PTR cr4.setRegister(cpu->cr4);
845 #endif
846 #endif
848 BX_CPU_THIS_PTR inhibit_mask = cpu->inhibit_mask;
851 // flush cached items, prefetch, paging, etc
853 BX_CPU_THIS_PTR invalidate_prefetch_q();
854 BX_CPU_THIS_PTR async_event = 1;
856 return(1);
859 #endif // #if BX_DEBUGGER
861 void BX_CPU_C::atexit(void)
863 debug(BX_CPU_THIS_PTR prev_eip);