|
|
| version 1.15, 2004/02/20 16:09:04 | version 1.16, 2004/03/12 13:34:08 |
|---|---|
| Line 426 CALLfar_pm_code_segment(selector_t *cs_s | Line 426 CALLfar_pm_code_segment(selector_t *cs_s |
| sp = CPU_SP; | sp = CPU_SP; |
| } | } |
| if (CPU_INST_OP32) { | if (CPU_INST_OP32) { |
| CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 8); | STACK_PUSH_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 8); |
| /* out of range */ | /* out of range */ |
| if (new_ip > cs_sel->desc.u.seg.limit) { | if (new_ip > cs_sel->desc.u.seg.limit) { |
| Line 437 CALLfar_pm_code_segment(selector_t *cs_s | Line 437 CALLfar_pm_code_segment(selector_t *cs_s |
| PUSH0_32(CPU_CS); | PUSH0_32(CPU_CS); |
| PUSH0_32(CPU_EIP); | PUSH0_32(CPU_EIP); |
| } else { | } else { |
| CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 4); | STACK_PUSH_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 4); |
| /* out of range */ | /* out of range */ |
| if (new_ip > cs_sel->desc.u.seg.limit) { | if (new_ip > cs_sel->desc.u.seg.limit) { |
| Line 542 CALLfar_pm_call_gate_same_privilege(sele | Line 542 CALLfar_pm_call_gate_same_privilege(sele |
| } | } |
| if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) { | if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) { |
| CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 8); | STACK_PUSH_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 8); |
| PUSH0_32(CPU_CS); | PUSH0_32(CPU_CS); |
| PUSH0_32(CPU_EIP); | PUSH0_32(CPU_EIP); |
| Line 550 CALLfar_pm_call_gate_same_privilege(sele | Line 550 CALLfar_pm_call_gate_same_privilege(sele |
| load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL); | load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL); |
| SET_EIP(callgate_sel->desc.u.gate.offset); | SET_EIP(callgate_sel->desc.u.gate.offset); |
| } else { | } else { |
| CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 4); | STACK_PUSH_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 4); |
| PUSH0_16(CPU_CS); | PUSH0_16(CPU_CS); |
| PUSH0_16(CPU_IP); | PUSH0_16(CPU_IP); |
| Line 631 CALLfar_pm_call_gate_more_privilege(sele | Line 631 CALLfar_pm_call_gate_more_privilege(sele |
| VERBOSE(("CALLfar_pm: param_count = %d", param_count)); | VERBOSE(("CALLfar_pm: param_count = %d", param_count)); |
| if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) { | if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) { |
| CHECK_STACK_PUSH(&ss_sel.desc, new_esp, 16 + param_count * 4); | STACK_PUSH_CHECK(ss_sel.idx, &ss_sel.desc, new_esp, 16 + param_count * 4); |
| /* dump param */ | /* dump param */ |
| for (i = 0; i < param_count; i++) { | for (i = 0; i < param_count; i++) { |
| Line 661 CALLfar_pm_call_gate_more_privilege(sele | Line 661 CALLfar_pm_call_gate_more_privilege(sele |
| PUSH0_32(old_cs); | PUSH0_32(old_cs); |
| PUSH0_32(old_eip); | PUSH0_32(old_eip); |
| } else { | } else { |
| CHECK_STACK_PUSH(&ss_sel.desc, new_esp, 8 + param_count * 2); | STACK_PUSH_CHECK(ss_sel.idx, &ss_sel.desc, new_esp, 8 + param_count * 2); |
| /* dump param */ | /* dump param */ |
| for (i = 0; i < param_count; i++) { | for (i = 0; i < param_count; i++) { |
| Line 803 RETfar_pm(UINT nbytes) | Line 803 RETfar_pm(UINT nbytes) |
| sp = CPU_SP; | sp = CPU_SP; |
| } | } |
| if (CPU_INST_OP32) { | if (CPU_INST_OP32) { |
| CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, nbytes + 8); | STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, nbytes + 8); |
| new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp); | new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp); |
| new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4); | new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4); |
| } else { | } else { |
| CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, nbytes + 4); | STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, nbytes + 4); |
| new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp); | new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp); |
| new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2); | new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2); |
| } | } |
| Line 872 RETfar_pm(UINT nbytes) | Line 872 RETfar_pm(UINT nbytes) |
| VERBOSE(("RETfar_pm: RETURN-OUTER-PRIVILEGE-LEVEL")); | VERBOSE(("RETfar_pm: RETURN-OUTER-PRIVILEGE-LEVEL")); |
| if (CPU_INST_OP32) { | if (CPU_INST_OP32) { |
| CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 8 + 8 + nbytes); | STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 8 + 8 + nbytes); |
| new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8 + nbytes); | new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8 + nbytes); |
| new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8 + nbytes + 4); | new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8 + nbytes + 4); |
| } else { | } else { |
| CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 4 + 4 + nbytes); | STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 4 + 4 + nbytes); |
| new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes); | new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes); |
| new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes + 2); | new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes + 2); |
| } | } |
| Line 1014 IRET_pm(void) | Line 1014 IRET_pm(void) |
| sp = CPU_SP; | sp = CPU_SP; |
| } | } |
| if (CPU_INST_OP32) { | if (CPU_INST_OP32) { |
| CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 12); | STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 12); |
| new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp); | new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp); |
| new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4); | new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4); |
| new_flags = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8); | new_flags = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8); |
| } else { | } else { |
| CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 6); | STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 6); |
| new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp); | new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp); |
| new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2); | new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2); |
| new_flags = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4); | new_flags = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4); |
| Line 1151 IRET_pm_protected_mode_return_same_privi | Line 1151 IRET_pm_protected_mode_return_same_privi |
| { | { |
| UINT32 mask; | UINT32 mask; |
| UINT stacksize; | UINT stacksize; |
| #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) | |
| UINT32 old_flags = CPU_EFLAG; | |
| #endif | |
| VERBOSE(("IRET_pm: RETURN-TO-SAME-PRIVILEGE-LEVEL")); | VERBOSE(("IRET_pm: RETURN-TO-SAME-PRIVILEGE-LEVEL")); |
| Line 1160 IRET_pm_protected_mode_return_same_privi | Line 1163 IRET_pm_protected_mode_return_same_privi |
| EXCEPTION(GP_EXCEPTION, 0); | EXCEPTION(GP_EXCEPTION, 0); |
| } | } |
| #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) | |
| mask = ALL_EFLAG; | |
| if (CPU_STAT_CPL > CPU_STAT_IOPL) | |
| mask &= ~I_FLAG; | |
| if (CPU_STAT_CPL > 0) { | |
| mask &= ~IOPL_FLAG; | |
| if (CPU_INST_OP32) { | |
| mask &= ~(VM_FLAG|VIF_FLAG|VIP_FLAG); | |
| } | |
| } | |
| #else | |
| mask = 0; | mask = 0; |
| if (CPU_INST_OP32) | if (CPU_INST_OP32) |
| mask |= RF_FLAG; | mask |= RF_FLAG; |
| Line 1171 IRET_pm_protected_mode_return_same_privi | Line 1185 IRET_pm_protected_mode_return_same_privi |
| mask |= VM_FLAG|VIF_FLAG|VIP_FLAG; | mask |= VM_FLAG|VIF_FLAG|VIP_FLAG; |
| } | } |
| } | } |
| #endif | |
| if (CPU_INST_OP32) { | if (CPU_INST_OP32) { |
| stacksize = 12; | stacksize = 12; |
| } else { | } else { |
| Line 1181 IRET_pm_protected_mode_return_same_privi | Line 1197 IRET_pm_protected_mode_return_same_privi |
| load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL); | load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL); |
| SET_EIP(new_ip); | SET_EIP(new_ip); |
| #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) | |
| CPU_EFLAG = (new_flags & mask) | (CPU_EFLAG & ~mask); | |
| CPU_OV = CPU_FLAG & O_FLAG; | |
| CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); | |
| if ((old_flags ^ CPU_EFLAG) & VM_FLAG) { | |
| if (CPU_EFLAG & VM_FLAG) { | |
| change_vm(1); | |
| } else { | |
| change_vm(0); | |
| } | |
| } | |
| #else | |
| set_eflags(new_flags, mask); | set_eflags(new_flags, mask); |
| #endif | |
| if (CPU_STAT_SS32) { | if (CPU_STAT_SS32) { |
| CPU_ESP += stacksize; | CPU_ESP += stacksize; |
| Line 1204 IRET_pm_protected_mode_return_outer_priv | Line 1233 IRET_pm_protected_mode_return_outer_priv |
| UINT16 new_ss; | UINT16 new_ss; |
| int rv; | int rv; |
| int i; | int i; |
| #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) | |
| UINT32 old_flags = CPU_EFLAG; | |
| #endif | |
| VERBOSE(("IRET_pm: RETURN-OUTER-PRIVILEGE-LEVEL")); | VERBOSE(("IRET_pm: RETURN-OUTER-PRIVILEGE-LEVEL")); |
| Line 1213 IRET_pm_protected_mode_return_outer_priv | Line 1245 IRET_pm_protected_mode_return_outer_priv |
| sp = CPU_SP; | sp = CPU_SP; |
| } | } |
| if (CPU_INST_OP32) { | if (CPU_INST_OP32) { |
| CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 20); | STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 20); |
| new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12); | new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12); |
| new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16); | new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16); |
| } else { | } else { |
| CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 10); | STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 10); |
| new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 6); | new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 6); |
| new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8); | new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8); |
| } | } |
| Line 1265 IRET_pm_protected_mode_return_outer_priv | Line 1297 IRET_pm_protected_mode_return_outer_priv |
| EXCEPTION(GP_EXCEPTION, 0); | EXCEPTION(GP_EXCEPTION, 0); |
| } | } |
| #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) | |
| mask = ALL_EFLAG; | |
| if (CPU_STAT_CPL > CPU_STAT_IOPL) | |
| mask &= ~I_FLAG; | |
| if (CPU_STAT_CPL > 0) { | |
| mask &= ~IOPL_FLAG; | |
| if (CPU_INST_OP32) { | |
| mask &= ~(VM_FLAG|VIF_FLAG|VIP_FLAG); | |
| } | |
| } | |
| #else | |
| mask = 0; | mask = 0; |
| if (CPU_INST_OP32) | if (CPU_INST_OP32) |
| mask |= RF_FLAG; | mask |= RF_FLAG; |
| Line 1276 IRET_pm_protected_mode_return_outer_priv | Line 1319 IRET_pm_protected_mode_return_outer_priv |
| mask |= VM_FLAG|VIF_FLAG|VIP_FLAG; | mask |= VM_FLAG|VIF_FLAG|VIP_FLAG; |
| } | } |
| } | } |
| #endif | |
| /* set new register */ | /* set new register */ |
| load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->rpl); | load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->rpl); |
| SET_EIP(new_ip); | SET_EIP(new_ip); |
| #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) | |
| CPU_EFLAG = (new_flags & mask) | (CPU_EFLAG & ~mask); | |
| CPU_OV = CPU_FLAG & O_FLAG; | |
| CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); | |
| if ((old_flags ^ CPU_EFLAG) & VM_FLAG) { | |
| if (CPU_EFLAG & VM_FLAG) { | |
| change_vm(1); | |
| } else { | |
| change_vm(0); | |
| } | |
| } | |
| #else | |
| set_eflags(new_flags, mask); | set_eflags(new_flags, mask); |
| #endif | |
| load_ss(ss_sel.selector, &ss_sel.desc, cs_sel->rpl); | load_ss(ss_sel.selector, &ss_sel.desc, cs_sel->rpl); |
| if (CPU_STAT_SS32) { | if (CPU_STAT_SS32) { |
| Line 1314 IRET_pm_return_to_vm86(UINT16 new_cs, UI | Line 1371 IRET_pm_return_to_vm86(UINT16 new_cs, UI |
| UINT32 sp; | UINT32 sp; |
| UINT32 new_sp; | UINT32 new_sp; |
| int i; | int i; |
| #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) | |
| UINT32 old_flags = CPU_EFLAG; | |
| #endif | |
| VERBOSE(("IRET_pm: Interrupt procedure was in virtual-8086 mode: PE=1, VM=1 in flags image")); | VERBOSE(("IRET_pm: Interrupt procedure was in virtual-8086 mode: PE=1, VM=1 in flags image")); |
| Line 1330 IRET_pm_return_to_vm86(UINT16 new_cs, UI | Line 1390 IRET_pm_return_to_vm86(UINT16 new_cs, UI |
| } else { | } else { |
| sp = CPU_SP; | sp = CPU_SP; |
| } | } |
| CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, 36); | STACK_POP_CHECK(CPU_REGS_SREG(CPU_SS_INDEX), &CPU_STAT_SREG(CPU_SS_INDEX), sp, 36); |
| new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12); | new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12); |
| segsel[CPU_SS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16); | segsel[CPU_SS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16); |
| segsel[CPU_ES_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 20); | segsel[CPU_ES_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 20); |
| Line 1345 IRET_pm_return_to_vm86(UINT16 new_cs, UI | Line 1405 IRET_pm_return_to_vm86(UINT16 new_cs, UI |
| } | } |
| /* to VM86 mode */ | /* to VM86 mode */ |
| #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) | |
| CPU_EFLAG = new_flags; | |
| CPU_OV = CPU_FLAG & O_FLAG; | |
| CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); | |
| if ((old_flags ^ CPU_EFLAG) & VM_FLAG) { | |
| if (CPU_EFLAG & VM_FLAG) { | |
| change_vm(1); | |
| } else { | |
| change_vm(0); | |
| } | |
| } | |
| #else | |
| set_eflags(new_flags, IOPL_FLAG|I_FLAG|VM_FLAG|RF_FLAG); | set_eflags(new_flags, IOPL_FLAG|I_FLAG|VM_FLAG|RF_FLAG); |
| #endif | |
| new_sp &= 0xffff; | new_sp &= 0xffff; |
| new_ip &= 0xffff; | new_ip &= 0xffff; |
| Line 1377 IRET_pm_return_from_vm86(UINT16 new_cs, | Line 1450 IRET_pm_return_from_vm86(UINT16 new_cs, |
| CPU_SP += (UINT16)stacksize; | CPU_SP += (UINT16)stacksize; |
| } | } |
| #if defined(IA32_DONT_USE_SET_EFLAGS_FUNCTION) | |
| CPU_EFLAG = (new_flags & ~(IOPL_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG)) | (CPU_EFLAG & (IOPL_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG)); | |
| CPU_OV = CPU_FLAG & O_FLAG; | |
| CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); | |
| #else | |
| set_eflags(new_flags, I_FLAG|RF_FLAG); | set_eflags(new_flags, I_FLAG|RF_FLAG); |
| #endif | |
| CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); | CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); |
| SET_EIP(new_ip); | SET_EIP(new_ip); |