| version 1.5, 2004/01/26 15:23:55 | version 1.7, 2004/02/04 13:24:35 | 
| Line 103  exception(int num, int error_code) | Line 103  exception(int num, int error_code) | 
 | error_code = 0; | error_code = 0; | 
 | break; | break; | 
 |  |  | 
 |  | #if CPU_FAMILY >= 4 | 
 | case AC_EXCEPTION:      /* (F) アラインメントチェック (errcode: 0) */ | case AC_EXCEPTION:      /* (F) アラインメントチェック (errcode: 0) */ | 
 | error_code = 0; | error_code = 0; | 
 | /*FALLTHROUGH*/ | /*FALLTHROUGH*/ | 
 |  | #endif | 
 | case TS_EXCEPTION:      /* (F) 無効 TSS (errcode) */ | case TS_EXCEPTION:      /* (F) 無効 TSS (errcode) */ | 
 | case NP_EXCEPTION:      /* (F) セグメント不在 (errcode) */ | case NP_EXCEPTION:      /* (F) セグメント不在 (errcode) */ | 
 | case SS_EXCEPTION:      /* (F) スタックセグメントフォルト (errcode) */ | case SS_EXCEPTION:      /* (F) スタックセグメントフォルト (errcode) */ | 
| Line 120  exception(int num, int error_code) | Line 122  exception(int num, int error_code) | 
 | errorp = 0; | errorp = 0; | 
 | break; | break; | 
 |  |  | 
 |  | #if CPU_FAMILY >= 5 | 
 | case MC_EXCEPTION:      /* (A) マシンチェック */ | case MC_EXCEPTION:      /* (A) マシンチェック */ | 
 | CPU_EIP = CPU_PREV_EIP; | CPU_EIP = CPU_PREV_EIP; | 
 | errorp = 0; | errorp = 0; | 
 | break; | break; | 
 |  | #endif | 
 |  |  | 
 |  | #if CPU_FAMILY >= 6 | 
 | case XF_EXCEPTION:      /* (F) ストリーミング SIMD 拡張命令 */ | case XF_EXCEPTION:      /* (F) ストリーミング SIMD 拡張命令 */ | 
 | CPU_EIP = CPU_PREV_EIP; | CPU_EIP = CPU_PREV_EIP; | 
 | errorp = 0; | errorp = 0; | 
 | break; | break; | 
 |  | #endif | 
 |  |  | 
 | default: | default: | 
 | ia32_panic("exception: unknown exception (%d)", num); | ia32_panic("exception: unknown exception (%d)", num); | 
| Line 258  interrupt(int num, int softintp, int err | Line 264  interrupt(int num, int softintp, int err | 
 | } | } | 
 |  |  | 
 | memset(&gd, 0, sizeof(gd)); | memset(&gd, 0, sizeof(gd)); | 
| CPU_SET_GATEDESC(&gd, CPU_IDTR_BASE + idt_idx); | CPU_SET_GATEDESC(&gd, CPU_IDTR_BASE + idt_idx, CPU_MODE_SUPERVISER); | 
 | if (!gd.valid || !gd.p) { | if (!gd.valid || !gd.p) { | 
 | VERBOSE(("interrupt: gate descripter is invalid.")); | VERBOSE(("interrupt: gate descripter is invalid.")); | 
 | EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp); | EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp); | 
| Line 313  interrupt_task(descriptor_t *gdp, int so | Line 319  interrupt_task(descriptor_t *gdp, int so | 
 |  |  | 
 | (void)softintp; | (void)softintp; | 
 |  |  | 
| rv = parse_selector(&task_sel, gdp->u.gate.selector); | rv = parse_selector_sv(&task_sel, gdp->u.gate.selector); | 
 | if (rv < 0 || task_sel.ldt) { | if (rv < 0 || task_sel.ldt) { | 
 | VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d, %cDT)", gdp->u.gate.selector, rv, task_sel.ldt ? 'L' : 'G')); | VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d, %cDT)", gdp->u.gate.selector, rv, task_sel.ldt ? 'L' : 'G')); | 
 | EXCEPTION(TS_EXCEPTION, task_sel.idx); | EXCEPTION(TS_EXCEPTION, task_sel.idx); | 
| Line 352  static void | Line 358  static void | 
 | interrupt_intr_or_trap(descriptor_t *gdp, int softintp, int errorp, int error_code) | interrupt_intr_or_trap(descriptor_t *gdp, int softintp, int errorp, int error_code) | 
 | { | { | 
 | selector_t intr_sel, ss_sel; | selector_t intr_sel, ss_sel; | 
 |  | DWORD old_flags = REAL_EFLAGREG; | 
 | DWORD flags = REAL_EFLAGREG; | DWORD flags = REAL_EFLAGREG; | 
 | DWORD mask = 0; | DWORD mask = 0; | 
 | DWORD stacksize; | DWORD stacksize; | 
| Line 360  interrupt_intr_or_trap(descriptor_t *gdp | Line 367  interrupt_intr_or_trap(descriptor_t *gdp | 
 | WORD old_cs, old_ss, new_ss; | WORD old_cs, old_ss, new_ss; | 
 | int rv; | int rv; | 
 |  |  | 
 |  | VERBOSE(("interrupt: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_PREV_EIP, CPU_SS, CPU_ESP)); | 
 |  |  | 
 |  | new_ip = gdp->u.gate.offset; | 
 |  | old_ss = CPU_SS; | 
 |  | old_cs = CPU_CS; | 
 |  | old_ip = CPU_EIP; | 
 |  | old_sp = CPU_ESP; | 
 |  |  | 
 | switch (gdp->type) { | switch (gdp->type) { | 
 | case CPU_SYSDESC_TYPE_INTR_16: | case CPU_SYSDESC_TYPE_INTR_16: | 
 |  | old_ip &= 0xffff; | 
 |  | old_sp &= 0xffff; | 
 |  | /*FALLTHROUGH*/ | 
 | case CPU_SYSDESC_TYPE_INTR_32: | case CPU_SYSDESC_TYPE_INTR_32: | 
 | VERBOSE(("interrupt: INTERRUPT-GATE")); | VERBOSE(("interrupt: INTERRUPT-GATE")); | 
 | flags &= ~I_FLAG; | flags &= ~I_FLAG; | 
| Line 369  interrupt_intr_or_trap(descriptor_t *gdp | Line 387  interrupt_intr_or_trap(descriptor_t *gdp | 
 | break; | break; | 
 |  |  | 
 | case CPU_SYSDESC_TYPE_TRAP_16: | case CPU_SYSDESC_TYPE_TRAP_16: | 
 |  | old_ip &= 0xffff; | 
 |  | old_sp &= 0xffff; | 
 |  | /*FALLTHROUGH*/ | 
 | case CPU_SYSDESC_TYPE_TRAP_32: | case CPU_SYSDESC_TYPE_TRAP_32: | 
 | VERBOSE(("interrupt: TRAP-GATE")); | VERBOSE(("interrupt: TRAP-GATE")); | 
 | break; | break; | 
 | } | } | 
 |  |  | 
 | flags &= ~(T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG); | flags &= ~(T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG); | 
 | mask |= T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG; | mask |= T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG; | 
 |  |  | 
| new_ip = gdp->u.gate.offset; | rv = parse_selector_sv(&intr_sel, gdp->u.gate.selector); | 
| old_ss = CPU_SS; |  | 
| old_cs = CPU_CS; |  | 
| old_ip = CPU_EIP; |  | 
| old_sp = CPU_ESP; |  | 
| switch (gdp->type) { |  | 
| case CPU_SYSDESC_TYPE_INTR_16: |  | 
| case CPU_SYSDESC_TYPE_TRAP_16: |  | 
| old_ip &= 0xffff; |  | 
| old_sp &= 0xffff; |  | 
| break; |  | 
| } |  | 
| VERBOSE(("interrupt: old EIP = %04x:%08x, ESP = %04x:%08x", old_cs, old_ip, old_ss, old_sp)); |  | 
|  |  | 
| rv = parse_selector(&intr_sel, gdp->u.gate.selector); |  | 
 | if (rv < 0) { | if (rv < 0) { | 
 | VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", gdp->u.gate.selector, rv)); | VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", gdp->u.gate.selector, rv)); | 
 | EXCEPTION(GP_EXCEPTION, intr_sel.idx | !softintp); | EXCEPTION(GP_EXCEPTION, intr_sel.idx | !softintp); | 
| Line 443  interrupt_intr_or_trap(descriptor_t *gdp | Line 449  interrupt_intr_or_trap(descriptor_t *gdp | 
 |  |  | 
 | get_stack_from_tss(intr_sel.desc.dpl, &new_ss, &new_sp); | get_stack_from_tss(intr_sel.desc.dpl, &new_ss, &new_sp); | 
 |  |  | 
| rv = parse_selector(&ss_sel, new_ss); | rv = parse_selector_sv(&ss_sel, new_ss); | 
 | if (rv < 0) { | if (rv < 0) { | 
 | VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", new_ss, rv)); | VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", new_ss, rv)); | 
 | EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp); | EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp); | 
| Line 488  interrupt_intr_or_trap(descriptor_t *gdp | Line 494  interrupt_intr_or_trap(descriptor_t *gdp | 
 | EXCEPTION(GP_EXCEPTION, 0); | EXCEPTION(GP_EXCEPTION, 0); | 
 | } | } | 
 |  |  | 
| load_ss(new_ss, &ss_sel.desc, intr_sel.desc.dpl); | load_ss(ss_sel.selector, &ss_sel.desc, intr_sel.desc.dpl); | 
 | CPU_ESP = new_sp; | CPU_ESP = new_sp; | 
 |  |  | 
 | load_cs(intr_sel.selector, &intr_sel.desc, intr_sel.desc.dpl); | load_cs(intr_sel.selector, &intr_sel.desc, intr_sel.desc.dpl); | 
| Line 521  interrupt_intr_or_trap(descriptor_t *gdp | Line 527  interrupt_intr_or_trap(descriptor_t *gdp | 
 | case CPU_SYSDESC_TYPE_TRAP_32: | case CPU_SYSDESC_TYPE_TRAP_32: | 
 | PUSH0_32(old_ss); | PUSH0_32(old_ss); | 
 | PUSH0_32(old_sp); | PUSH0_32(old_sp); | 
| PUSH0_32(REAL_EFLAGREG); | PUSH0_32(old_flags); | 
 | PUSH0_32(old_cs); | PUSH0_32(old_cs); | 
 | PUSH0_32(old_ip); | PUSH0_32(old_ip); | 
 | if (errorp) { | if (errorp) { | 
| Line 533  interrupt_intr_or_trap(descriptor_t *gdp | Line 539  interrupt_intr_or_trap(descriptor_t *gdp | 
 | case CPU_SYSDESC_TYPE_TRAP_16: | case CPU_SYSDESC_TYPE_TRAP_16: | 
 | PUSH0_16(old_ss); | PUSH0_16(old_ss); | 
 | PUSH0_16(old_sp); | PUSH0_16(old_sp); | 
| PUSH0_16(REAL_FLAGREG); | PUSH0_16(old_flags); | 
 | PUSH0_16(old_cs); | PUSH0_16(old_cs); | 
 | PUSH0_16(old_ip); | PUSH0_16(old_ip); | 
 | if (errorp) { | if (errorp) { |