Revision 8145122b target-i386/helper.c
b/target-i386/helper.c | ||
---|---|---|
21 | 21 |
|
22 | 22 |
//#define DEBUG_PCALL |
23 | 23 |
|
24 |
#if 0 |
|
25 |
#define raise_exception_err(a, b)\ |
|
26 |
do {\ |
|
27 |
printf("raise_exception line=%d\n", __LINE__);\ |
|
28 |
(raise_exception_err)(a, b);\ |
|
29 |
} while (0) |
|
30 |
#endif |
|
31 |
|
|
24 | 32 |
const uint8_t parity_table[256] = { |
25 | 33 |
CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
26 | 34 |
0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
... | ... | |
424 | 432 |
possible exception */ |
425 | 433 |
env->eip = new_eip; |
426 | 434 |
eflags_mask = TF_MASK | AC_MASK | ID_MASK | |
427 |
IF_MASK | IOPL_MASK | VM_MASK | RF_MASK; |
|
435 |
IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK;
|
|
428 | 436 |
if (!(type & 8)) |
429 | 437 |
eflags_mask &= 0xffff; |
430 | 438 |
load_eflags(new_eflags, eflags_mask); |
... | ... | |
452 | 460 |
if (new_ldt & 4) |
453 | 461 |
raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); |
454 | 462 |
|
455 |
dt = &env->gdt; |
|
456 |
index = new_ldt & ~7; |
|
457 |
if ((index + 7) > dt->limit) |
|
458 |
raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); |
|
459 |
ptr = dt->base + index; |
|
460 |
e1 = ldl_kernel(ptr); |
|
461 |
e2 = ldl_kernel(ptr + 4); |
|
462 |
if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) |
|
463 |
raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); |
|
464 |
if (!(e2 & DESC_P_MASK)) |
|
465 |
raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); |
|
466 |
load_seg_cache_raw_dt(&env->ldt, e1, e2); |
|
463 |
if ((new_ldt & 0xfffc) != 0) { |
|
464 |
dt = &env->gdt; |
|
465 |
index = new_ldt & ~7; |
|
466 |
if ((index + 7) > dt->limit) |
|
467 |
raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); |
|
468 |
ptr = dt->base + index; |
|
469 |
e1 = ldl_kernel(ptr); |
|
470 |
e2 = ldl_kernel(ptr + 4); |
|
471 |
if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) |
|
472 |
raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); |
|
473 |
if (!(e2 & DESC_P_MASK)) |
|
474 |
raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); |
|
475 |
load_seg_cache_raw_dt(&env->ldt, e1, e2); |
|
476 |
} |
|
467 | 477 |
|
468 | 478 |
/* load the segments */ |
469 | 479 |
if (!(new_eflags & VM_MASK)) { |
... | ... | |
748 | 758 |
if (env->eflags & VM_MASK) { |
749 | 759 |
/* XXX: explain me why W2K hangs if the whole segment cache is |
750 | 760 |
reset ? */ |
761 |
#if 1 |
|
751 | 762 |
env->segs[R_ES].selector = 0; |
752 | 763 |
env->segs[R_ES].flags = 0; |
753 | 764 |
env->segs[R_DS].selector = 0; |
... | ... | |
756 | 767 |
env->segs[R_FS].flags = 0; |
757 | 768 |
env->segs[R_GS].selector = 0; |
758 | 769 |
env->segs[R_GS].flags = 0; |
770 |
#else |
|
771 |
cpu_x86_load_seg_cache(env, R_ES, 0, NULL, 0, 0); |
|
772 |
cpu_x86_load_seg_cache(env, R_DS, 0, NULL, 0, 0); |
|
773 |
cpu_x86_load_seg_cache(env, R_FS, 0, NULL, 0, 0); |
|
774 |
cpu_x86_load_seg_cache(env, R_GS, 0, NULL, 0, 0); |
|
775 |
#endif |
|
759 | 776 |
} |
760 | 777 |
ss = (ss & ~3) | dpl; |
761 | 778 |
cpu_x86_load_seg_cache(env, R_SS, ss, |
... | ... | |
853 | 870 |
{ |
854 | 871 |
extern FILE *stdout; |
855 | 872 |
static int count; |
856 |
if ((env->cr[0] && CR0_PE_MASK)) {
|
|
857 |
fprintf(stdout, "%d: interrupt: vector=%02x error_code=%04x int=%d CPL=%d CS:EIP=%04x:%08x SS:ESP=%04x:%08x EAX=%08x\n",
|
|
873 |
if (env->cr[0] & CR0_PE_MASK) {
|
|
874 |
fprintf(stdout, "%d: v=%02x e=%04x i=%d CPL=%d CS:EIP=%04x:%08x SS:ESP=%04x:%08x",
|
|
858 | 875 |
count, intno, error_code, is_int, |
859 | 876 |
env->hflags & HF_CPL_MASK, |
860 | 877 |
env->segs[R_CS].selector, EIP, |
861 |
env->segs[R_SS].selector, ESP, |
|
862 |
EAX); |
|
878 |
env->segs[R_SS].selector, ESP); |
|
879 |
if (intno == 0x0e) { |
|
880 |
fprintf(stdout, " CR2=%08x", env->cr[2]); |
|
881 |
} else { |
|
882 |
fprintf(stdout, " EAX=%08x", env->regs[R_EAX]); |
|
883 |
} |
|
884 |
fprintf(stdout, "\n"); |
|
885 |
|
|
863 | 886 |
if (0) { |
864 | 887 |
cpu_x86_dump_state(env, stdout, X86_DUMP_CCOP); |
865 | 888 |
#if 0 |
... | ... | |
879 | 902 |
} |
880 | 903 |
} |
881 | 904 |
#endif |
882 |
|
|
883 | 905 |
#ifdef DEBUG_PCALL |
884 | 906 |
if (loglevel) { |
885 | 907 |
static int count; |
... | ... | |
925 | 947 |
} |
926 | 948 |
|
927 | 949 |
/* shortcuts to generate exceptions */ |
928 |
void raise_exception_err(int exception_index, int error_code) |
|
950 |
|
|
951 |
void (raise_exception_err)(int exception_index, int error_code) |
|
929 | 952 |
{ |
930 | 953 |
raise_interrupt(exception_index, 0, error_code, 0); |
931 | 954 |
} |
... | ... | |
1409 | 1432 |
if (dpl < cpl || dpl < rpl) |
1410 | 1433 |
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); |
1411 | 1434 |
switch_tss(new_cs, e1, e2, SWITCH_TSS_CALL); |
1412 |
break;
|
|
1435 |
return;
|
|
1413 | 1436 |
case 4: /* 286 call gate */ |
1414 | 1437 |
case 12: /* 386 call gate */ |
1415 | 1438 |
break; |
... | ... | |
1551 | 1574 |
load_seg_vm(R_CS, new_cs); |
1552 | 1575 |
env->eip = new_eip; |
1553 | 1576 |
if (env->eflags & VM_MASK) |
1554 |
eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK; |
|
1577 |
eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK | NT_MASK;
|
|
1555 | 1578 |
else |
1556 |
eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | RF_MASK; |
|
1579 |
eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | RF_MASK | NT_MASK;
|
|
1557 | 1580 |
if (shift == 0) |
1558 | 1581 |
eflags_mask &= 0xffff; |
1559 | 1582 |
load_eflags(new_eflags, eflags_mask); |
... | ... | |
1688 | 1711 |
env->eip = new_eip; |
1689 | 1712 |
if (is_iret) { |
1690 | 1713 |
/* NOTE: 'cpl' is the _old_ CPL */ |
1691 |
eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK; |
|
1714 |
eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK | NT_MASK;
|
|
1692 | 1715 |
if (cpl == 0) |
1693 | 1716 |
eflags_mask |= IOPL_MASK; |
1694 | 1717 |
iopl = (env->eflags >> IOPL_SHIFT) & 3; |
... | ... | |
1710 | 1733 |
|
1711 | 1734 |
/* modify processor state */ |
1712 | 1735 |
load_eflags(new_eflags, TF_MASK | AC_MASK | ID_MASK | |
1713 |
IF_MASK | IOPL_MASK | VM_MASK | VIF_MASK | VIP_MASK); |
|
1736 |
IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | VIP_MASK);
|
|
1714 | 1737 |
load_seg_vm(R_CS, new_cs & 0xffff); |
1715 | 1738 |
cpu_x86_set_cpl(env, 3); |
1716 | 1739 |
load_seg_vm(R_SS, new_ss & 0xffff); |
Also available in: Unified diff