Use my patch to bochs 2.5.1, it will help you tracking down the bug.
It suppresses the first debugger prompt if called with -q, otherwise it will show you helpful messages, also in debugger you'll be able to see dpls for gdt and idt. Also note that if you enable trace, it will show you whenever an interrupt is called.
Code: Select all
diff -r bochs-2.5.1/bx_debug/dbg_main.cc bochs-2.5.1new/bx_debug/dbg_main.cc
300a301
> int firstcommand=1;
327a329,333
> if (firstcommand && SIM->get_param_enum(BXPN_BOCHS_START)->get()==BX_QUICK_START) {
> firstcommand=0;
> strcat(tmp_buf, "c\n");
> charptr_ret = &tmp_buf[0];
> } else {
336a343
> }
2855c2862
< dbg_printf("Code segment, base=0x%08x, limit=0x%08x, %s%s%s, %d-bit\n",
---
> dbg_printf("Code segment, base=0x%08x, limit=0x%08x, %s%s%s, %d-bit, dpl=%d\n",
2860c2867
< d_b ? 32 : 16);
---
> d_b ? 32 : 16, dpl);
2862c2869
< dbg_printf("Data segment, base=0x%08x, limit=0x%08x, %s%s%s\n",
---
> dbg_printf("Data segment, base=0x%08x, limit=0x%08x, %s%s%s, dpl=%d\n",
2866c2873
< (type&1)? ", Accessed" : "");
---
> (type&1)? ", Accessed" : "", dpl);
2892c2899
< dbg_printf("descriptor hi=0x%08x, lo=0x%08x", hi, lo);
---
> dbg_printf("descriptor hi=0x%08x, lo=0x%08x, dpl=%d", hi, lo, dpl);
diff -r bochs-2.5.1/cpu/access.cc bochs-2.5.1new/cpu/access.cc
43c43
< BX_DEBUG(("write_virtual_checks(): segment descriptor not valid"));
---
> BX_DEBUG(("write_virtual_checks(): segment %d descriptor not valid", seg->selector.index));
48c48
< BX_ERROR(("write_virtual_checks(): segment not present"));
---
> BX_ERROR(("write_virtual_checks(): segment %d not present", seg->selector.index));
59c59
< BX_ERROR(("write_virtual_checks(): no write access to seg"));
---
> BX_ERROR(("write_virtual_checks(): no write access to seg %d", seg->selector.index));
66c66
< BX_ERROR(("write_virtual_checks(): write beyond limit, r/w"));
---
> BX_ERROR(("write_virtual_checks(): write beyond limit, r/w, seg %d", seg->selector.index));
89c89
< BX_ERROR(("write_virtual_checks(): write beyond limit, r/w ED"));
---
> BX_ERROR(("write_virtual_checks(): write beyond limit, r/w ED, seg %d", seg->selector.index));
95c95
< BX_PANIC(("write_virtual_checks(): unknown descriptor type=%d", seg->cache.type));
---
> BX_PANIC(("write_virtual_checks(): unknown descriptor type=%d seg %d", seg->cache.type, seg->selector.index));
107c107
< BX_DEBUG(("read_virtual_checks(): segment descriptor not valid"));
---
> BX_DEBUG(("read_virtual_checks(): segment %d descriptor not valid", seg->selector.index));
112c112
< BX_ERROR(("read_virtual_checks(): segment not present"));
---
> BX_ERROR(("read_virtual_checks(): segment %d not present", seg->selector.index));
124c124
< BX_ERROR(("read_virtual_checks(): read beyond limit"));
---
> BX_ERROR(("read_virtual_checks(): read beyond limit seg %d", seg->selector.index));
143c143
< BX_ERROR(("read_virtual_checks(): read beyond limit ED"));
---
> BX_ERROR(("read_virtual_checks(): read beyond limit ED seg %d", seg->selector.index));
155c155
< BX_PANIC(("read_virtual_checks(): unknown descriptor type=%d", seg->cache.type));
---
> BX_PANIC(("read_virtual_checks(): unknown descriptor type=%d seg %d", seg->cache.type, seg->selector.index));
167c167
< BX_DEBUG(("execute_virtual_checks(): segment descriptor not valid"));
---
> BX_DEBUG(("execute_virtual_checks(): segment %d descriptor not valid", seg->selector.index));
172c172
< BX_ERROR(("execute_virtual_checks(): segment not present"));
---
> BX_ERROR(("execute_virtual_checks(): segment %d not present", seg->selector.index));
184c184
< BX_ERROR(("execute_virtual_checks(): read beyond limit"));
---
> BX_ERROR(("execute_virtual_checks(): read beyond limit seg %d", seg->selector.index));
199c199
< BX_ERROR(("execute_virtual_checks(): read beyond limit execute only"));
---
> BX_ERROR(("execute_virtual_checks(): read beyond limit execute only seg %d", seg->selector.index));
213c213
< BX_ERROR(("execute_virtual_checks(): read beyond limit ED"));
---
> BX_ERROR(("execute_virtual_checks(): read beyond limit ED seg %d", seg->selector.index));
219c219
< BX_PANIC(("execute_virtual_checks(): unknown descriptor type=%d", seg->cache.type));
---
> BX_PANIC(("execute_virtual_checks(): unknown descriptor type=%d seg %d", seg->cache.type, seg->selector.index));
234c234
< BX_PANIC(("undefined segment passed to strseg()!"));
---
> BX_PANIC(("undefined segment %d passed to strseg()!", seg->selector.index));
268c268
< BX_ERROR(("system_read_byte(): canonical failure"));
---
> BX_ERROR(("system_read_byte(): canonical failure %lx", laddr));
298c298
< BX_ERROR(("system_read_word(): canonical failure"));
---
> BX_ERROR(("system_read_word(): canonical failure %lx", laddr));
328c328
< BX_ERROR(("system_read_dword(): canonical failure"));
---
> BX_ERROR(("system_read_dword(): canonical failure %lx", laddr));
358c358
< BX_ERROR(("system_read_qword(): canonical failure"));
---
> BX_ERROR(("system_read_qword(): canonical failure %lx", laddr));
391c391
< BX_ERROR(("system_write_byte(): canonical failure"));
---
> BX_ERROR(("system_write_byte(): canonical failure %lx", laddr));
423c423
< BX_ERROR(("system_write_word(): canonical failure"));
---
> BX_ERROR(("system_write_word(): canonical failure %lx", laddr));
455c455
< BX_ERROR(("system_write_dword(): canonical failure"));
---
> BX_ERROR(("system_write_dword(): canonical failure %lx", laddr));
diff -r bochs-2.5.1/cpu/ctrl_xfer_pro.cc bochs-2.5.1new/cpu/ctrl_xfer_pro.cc
138c138
< BX_ERROR(("branch_far64: canonical RIP violation"));
---
> BX_ERROR(("branch_far64: canonical RIP violation %lx", rip));
149c149
< BX_ERROR(("branch_far64: RIP > limit"));
---
> BX_ERROR(("branch_far64: RIP(%lx) > limit(%lx)", rip, descriptor->u.segment.limit_scaled));
diff -r bochs-2.5.1/cpu/exception.cc bochs-2.5.1new/cpu/exception.cc
46c46
< BX_ERROR(("interrupt(long mode): vector must be within IDT table limits, IDT.limit = 0x%x", BX_CPU_THIS_PTR idtr.limit));
---
> BX_ERROR(("interrupt(long mode): vector %d must be within IDT table limits, IDT.limit = 0x%x", vector, BX_CPU_THIS_PTR idtr.limit));
54c54
< BX_ERROR(("interrupt(long mode): IDT entry extended attributes DWORD4 TYPE != 0"));
---
> BX_ERROR(("interrupt(long mode): IDT entry %d extended attributes DWORD4 TYPE != 0", vector));
66c66
< BX_ERROR(("interrupt(long mode): gate descriptor is not valid sys seg"));
---
> BX_ERROR(("interrupt(long mode): gate descriptor %d is not valid sys seg", vector));
75,76c75,76
< BX_ERROR(("interrupt(long mode): unsupported gate type %u",
< (unsigned) gate_descriptor.type));
---
> BX_ERROR(("interrupt(long mode): unsupported gate type %u vector %d",
> (unsigned) gate_descriptor.type, vector));
84c84
< BX_ERROR(("interrupt(long mode): soft_int && gate.dpl < CPL"));
---
> BX_ERROR(("interrupt(long mode): soft_int(%d) && gate.dpl(%d) < CPL(%d)", vector, gate_descriptor.dpl, CPL));
103c103
< BX_ERROR(("int_trap_gate(long mode): selector null"));
---
> BX_ERROR(("int_trap_gate(long mode): selector null vector %d",vector));
120c120
< BX_ERROR(("interrupt(long mode): not accessible or not code segment"));
---
> BX_ERROR(("interrupt(long mode): not accessible or not code segment vector %d", vector));
127c127
< BX_ERROR(("interrupt(long mode): must be 64 bit segment"));
---
> BX_ERROR(("interrupt(long mode): must be 64 bit segment vector %d", vector));
133c133
< BX_ERROR(("interrupt(long mode): segment not present"));
---
> BX_ERROR(("interrupt(long mode): segment not present vector %d", vector));
253c253
< BX_ERROR(("interrupt(): vector must be within IDT table limits, IDT.limit = 0x%x", BX_CPU_THIS_PTR idtr.limit));
---
> BX_ERROR(("interrupt(): vector %d must be within IDT table limits, IDT.limit = 0x%x", vector, BX_CPU_THIS_PTR idtr.limit));
279,280c279,280
< BX_ERROR(("interrupt(): gate.type(%u) != {5,6,7,14,15}",
< (unsigned) gate_descriptor.type));
---
> BX_ERROR(("interrupt(): gate.type(%u) != {5,6,7,14,15} vector %d",
> (unsigned) gate_descriptor.type, vector));
287c287
< BX_ERROR(("interrupt(): soft_int && (gate.dpl < CPL)"));
---
> BX_ERROR(("interrupt(): soft_int(%d) && (gate.dpl(%d) < CPL(%d))", vector, gate_descriptor.dpl, CPL));
293c293
< BX_ERROR(("interrupt(): gate not present"));
---
> BX_ERROR(("interrupt(): gate not present vector %d", vector));
306c306
< BX_ERROR(("interrupt(): tss_selector.ti=1 from gate descriptor - #GP(tss_selector)"));
---
> BX_ERROR(("interrupt(): tss_selector.ti=1 from gate descriptor - #GP(tss_selector) vector %d",vector));
318c318
< BX_ERROR(("interrupt(): TSS selector points to invalid or bad TSS - #GP(tss_selector)"));
---
> BX_ERROR(("interrupt(): TSS selector points to invalid or bad TSS - #GP(tss_selector) vector %d seg %d", vector, tss_selector.index));
325c325
< BX_ERROR(("interrupt(): TSS selector points to bad TSS - #GP(tss_selector)"));
---
> BX_ERROR(("interrupt(): TSS selector points to bad TSS - #GP(tss_selector) vector %d seg %d", vector, tss_selector.index));
331c331
< BX_ERROR(("interrupt(): TSS descriptor.p == 0"));
---
> BX_ERROR(("interrupt(): TSS descriptor.p == 0 vector %d seg", vector, tss_selector.index));
354c354
< BX_ERROR(("interrupt(): EIP > CS.limit"));
---
> BX_ERROR(("interrupt(): EIP(%x) > CS.limit(%x)",EIP,BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled));
437c437
< BX_ERROR(("interrupt(): SS.rpl != CS.dpl"));
---
> BX_ERROR(("interrupt(): SS.rpl(%d) != CS.dpl(%d)", ss_selector.rpl, cs_descriptor.dpl));
444c444
< BX_ERROR(("interrupt(): SS.dpl != CS.dpl"));
---
> BX_ERROR(("interrupt(): SS.dpl(%d) != CS.dpl(%d)", ss_descriptor.dpl, cs_descriptor.dpl));
diff -r bochs-2.5.1/cpu/segment_ctrl_pro.cc bochs-2.5.1new/cpu/segment_ctrl_pro.cc
56c56
< BX_ERROR(("load_seg_reg(SS): rpl != CPL"));
---
> BX_ERROR(("load_seg_reg(SS): rpl(%d) != CPL(%d)", ss_selector.rpl, CPL));
77c77
< BX_ERROR(("load_seg_reg(SS): dpl != CPL"));
---
> BX_ERROR(("load_seg_reg(SS): dpl(%d) != CPL(%d)", descriptor.dpl, CPL));
134c134
< BX_ERROR(("load_seg_reg(%s, 0x%04x): RPL & CPL must be <= DPL", strseg(seg), new_value));
---
> BX_ERROR(("load_seg_reg(%s, 0x%04x): RPL(%d) & CPL(%d) must be <= DPL(%d)", strseg(seg), new_value, selector.rpl, CPL, descriptor.dpl));