| version 1.17, 2004/03/23 22:39:40 | version 1.19, 2008/01/25 17:49:46 | 
| Line 12 | Line 12 | 
 | * 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | 
 | *    notice, this list of conditions and the following disclaimer in the | *    notice, this list of conditions and the following disclaimer in the | 
 | *    documentation and/or other materials provided with the distribution. | *    documentation and/or other materials provided with the distribution. | 
 | * 3. The name of the author may not be used to endorse or promote products |  | 
 | *    derived from this software without specific prior written permission. |  | 
 | * | * | 
 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 
 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
| Line 1151  IRET_pm_protected_mode_return_same_privi | Line 1149  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 1163  IRET_pm_protected_mode_return_same_privi | Line 1158  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 1185  IRET_pm_protected_mode_return_same_privi | Line 1169  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; | 
| Line 1197  IRET_pm_protected_mode_return_same_privi | Line 1180  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 1233  IRET_pm_protected_mode_return_outer_priv | Line 1203  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 1297  IRET_pm_protected_mode_return_outer_priv | Line 1264  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 1319  IRET_pm_protected_mode_return_outer_priv | Line 1275  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 1371  IRET_pm_return_to_vm86(UINT16 new_cs, UI | Line 1313  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 1405  IRET_pm_return_to_vm86(UINT16 new_cs, UI | Line 1344  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 1450  IRET_pm_return_from_vm86(UINT16 new_cs, | Line 1376  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); |