|
|
| version 1.11, 2004/02/13 14:50:17 | 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 37 | Line 35 |
| /*------------------------------------------------------------------------------ | /*------------------------------------------------------------------------------ |
| * JMPfar_pm | * JMPfar_pm |
| */ | */ |
| static void JMPfar_pm_code_segment(selector_t *jmp_sel, DWORD new_ip); | static void JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip); |
| static void JMPfar_pm_call_gate(selector_t *jmp_sel); | static void JMPfar_pm_call_gate(const selector_t *callgate_sel); |
| static void JMPfar_pm_task_gate(selector_t *jmp_sel); | static void JMPfar_pm_task_gate(selector_t *taskgate_sel); |
| static void JMPfar_pm_tss(selector_t *jmp_sel); | static void JMPfar_pm_tss(selector_t *tss_sel); |
| void | void |
| JMPfar_pm(WORD selector, DWORD new_ip) | JMPfar_pm(UINT16 selector, UINT32 new_ip) |
| { | { |
| selector_t jmp_sel; | selector_t jmp_sel; |
| int rv; | int rv; |
| Line 106 JMPfar_pm(WORD selector, DWORD new_ip) | Line 104 JMPfar_pm(WORD selector, DWORD new_ip) |
| * JMPfar: code segment | * JMPfar: code segment |
| */ | */ |
| static void | static void |
| JMPfar_pm_code_segment(selector_t *cs_sel, DWORD new_ip) | JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip) |
| { | { |
| VERBOSE(("JMPfar_pm: CODE-SEGMENT")); | VERBOSE(("JMPfar_pm: CODE-SEGMENT")); |
| Line 152 JMPfar_pm_code_segment(selector_t *cs_se | Line 150 JMPfar_pm_code_segment(selector_t *cs_se |
| * JMPfar: call gate | * JMPfar: call gate |
| */ | */ |
| static void | static void |
| JMPfar_pm_call_gate(selector_t *callgate_sel) | JMPfar_pm_call_gate(const selector_t *callgate_sel) |
| { | { |
| selector_t cs_sel; | selector_t cs_sel; |
| int rv; | int rv; |
| Line 318 JMPfar_pm_tss(selector_t *tss_sel) | Line 316 JMPfar_pm_tss(selector_t *tss_sel) |
| /*------------------------------------------------------------------------------ | /*------------------------------------------------------------------------------ |
| * CALLfar_pm | * CALLfar_pm |
| */ | */ |
| static void CALLfar_pm_code_segment(selector_t *call_sel, DWORD new_ip); | static void CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip); |
| static void CALLfar_pm_call_gate(selector_t *call_sel); | static void CALLfar_pm_call_gate(const selector_t *callgate_sel); |
| static void CALLfar_pm_task_gate(selector_t *call_sel); | static void CALLfar_pm_task_gate(selector_t *taskgate_sel); |
| static void CALLfar_pm_tss(selector_t *call_sel); | static void CALLfar_pm_tss(selector_t *tss_sel); |
| void | void |
| CALLfar_pm(WORD selector, DWORD new_ip) | CALLfar_pm(UINT16 selector, UINT32 new_ip) |
| { | { |
| selector_t call_sel; | selector_t call_sel; |
| int rv; | int rv; |
| Line 387 CALLfar_pm(WORD selector, DWORD new_ip) | Line 385 CALLfar_pm(WORD selector, DWORD new_ip) |
| * CALLfar_pm: code segment | * CALLfar_pm: code segment |
| */ | */ |
| static void | static void |
| CALLfar_pm_code_segment(selector_t *cs_sel, DWORD new_ip) | CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip) |
| { | { |
| DWORD sp; | UINT32 sp; |
| VERBOSE(("CALLfar_pm: CODE-SEGMENT")); | VERBOSE(("CALLfar_pm: CODE-SEGMENT")); |
| Line 426 CALLfar_pm_code_segment(selector_t *cs_s | Line 424 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 435 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 456 CALLfar_pm_code_segment(selector_t *cs_s | Line 454 CALLfar_pm_code_segment(selector_t *cs_s |
| /*--- | /*--- |
| * CALLfar_pm: call gate | * CALLfar_pm: call gate |
| */ | */ |
| static void CALLfar_pm_call_gate_same_privilege(selector_t *call_sel, selector_t *cs_sel); | static void CALLfar_pm_call_gate_same_privilege(const selector_t *call_sel, selector_t *cs_sel); |
| static void CALLfar_pm_call_gate_more_privilege(selector_t *call_sel, selector_t *cs_sel); | static void CALLfar_pm_call_gate_more_privilege(const selector_t *call_sel, selector_t *cs_sel); |
| static void | static void |
| CALLfar_pm_call_gate(selector_t *callgate_sel) | CALLfar_pm_call_gate(const selector_t *callgate_sel) |
| { | { |
| selector_t cs_sel; | selector_t cs_sel; |
| int rv; | int rv; |
| Line 529 CALLfar_pm_call_gate(selector_t *callgat | Line 527 CALLfar_pm_call_gate(selector_t *callgat |
| * CALLfar_pm: call gate (SAME-PRIVILEGE) | * CALLfar_pm: call gate (SAME-PRIVILEGE) |
| */ | */ |
| static void | static void |
| CALLfar_pm_call_gate_same_privilege(selector_t *callgate_sel, selector_t *cs_sel) | CALLfar_pm_call_gate_same_privilege(const selector_t *callgate_sel, selector_t *cs_sel) |
| { | { |
| DWORD sp; | UINT32 sp; |
| VERBOSE(("CALLfar_pm: SAME-PRIVILEGE")); | VERBOSE(("CALLfar_pm: SAME-PRIVILEGE")); |
| Line 542 CALLfar_pm_call_gate_same_privilege(sele | Line 540 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 548 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 564 CALLfar_pm_call_gate_same_privilege(sele | Line 562 CALLfar_pm_call_gate_same_privilege(sele |
| * CALLfar_pm: call gate (MORE-PRIVILEGE) | * CALLfar_pm: call gate (MORE-PRIVILEGE) |
| */ | */ |
| static void | static void |
| CALLfar_pm_call_gate_more_privilege(selector_t *callgate_sel, selector_t *cs_sel) | CALLfar_pm_call_gate_more_privilege(const selector_t *callgate_sel, selector_t *cs_sel) |
| { | { |
| DWORD param[32]; /* copy param */ | UINT32 param[32]; /* copy param */ |
| selector_t ss_sel; | selector_t ss_sel; |
| DWORD old_eip, old_esp; | UINT32 old_eip, old_esp; |
| DWORD new_esp; | UINT32 new_esp; |
| WORD old_cs, old_ss; | UINT16 old_cs, old_ss; |
| WORD new_ss; | UINT16 new_ss; |
| int param_count; | int param_count; |
| int i; | int i; |
| int rv; | int rv; |
| Line 631 CALLfar_pm_call_gate_more_privilege(sele | Line 629 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 643 CALLfar_pm_call_gate_more_privilege(sele | Line 641 CALLfar_pm_call_gate_more_privilege(sele |
| if (CPU_STAT_SS32) { | if (CPU_STAT_SS32) { |
| CPU_ESP = new_esp; | CPU_ESP = new_esp; |
| } else { | } else { |
| CPU_SP = new_esp; | CPU_SP = (UINT16)new_esp; |
| } | } |
| load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl); | load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl); |
| Line 661 CALLfar_pm_call_gate_more_privilege(sele | Line 659 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 673 CALLfar_pm_call_gate_more_privilege(sele | Line 671 CALLfar_pm_call_gate_more_privilege(sele |
| if (CPU_STAT_SS32) { | if (CPU_STAT_SS32) { |
| CPU_ESP = new_esp; | CPU_ESP = new_esp; |
| } else { | } else { |
| CPU_SP = new_esp; | CPU_SP = (UINT16)new_esp; |
| } | } |
| load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl); | load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl); |
| Line 786 CALLfar_pm_tss(selector_t *tss_sel) | Line 784 CALLfar_pm_tss(selector_t *tss_sel) |
| */ | */ |
| void | void |
| RETfar_pm(DWORD nbytes) | RETfar_pm(UINT nbytes) |
| { | { |
| selector_t cs_sel, ss_sel, temp_sel; | selector_t cs_sel, ss_sel, temp_sel; |
| DWORD sp; | UINT32 sp; |
| DWORD new_ip, new_sp; | UINT32 new_ip, new_sp; |
| WORD new_cs, new_ss; | UINT16 new_cs, new_ss; |
| int rv; | int rv; |
| int i; | int i; |
| Line 803 RETfar_pm(DWORD nbytes) | Line 801 RETfar_pm(DWORD 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 863 RETfar_pm(DWORD nbytes) | Line 861 RETfar_pm(DWORD nbytes) |
| if (CPU_STAT_SS32) { | if (CPU_STAT_SS32) { |
| CPU_ESP += nbytes; | CPU_ESP += nbytes; |
| } else { | } else { |
| CPU_SP += nbytes; | CPU_SP += (UINT16)nbytes; |
| } | } |
| load_cs(cs_sel.selector, &cs_sel.desc, CPU_STAT_CPL); | load_cs(cs_sel.selector, &cs_sel.desc, CPU_STAT_CPL); |
| Line 872 RETfar_pm(DWORD nbytes) | Line 870 RETfar_pm(DWORD 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 933 RETfar_pm(DWORD nbytes) | Line 931 RETfar_pm(DWORD nbytes) |
| if (CPU_STAT_SS32) { | if (CPU_STAT_SS32) { |
| CPU_ESP = new_sp + nbytes; | CPU_ESP = new_sp + nbytes; |
| } else { | } else { |
| CPU_SP = new_sp + nbytes; | CPU_SP = (UINT16)(new_sp + nbytes); |
| } | } |
| /* check segment register */ | /* check segment register */ |
| Line 989 RETfar_pm(DWORD nbytes) | Line 987 RETfar_pm(DWORD nbytes) |
| * IRET_pm | * IRET_pm |
| */ | */ |
| static void IRET_pm_nested_task(void); | static void IRET_pm_nested_task(void); |
| static void IRET_pm_protected_mode_return(DWORD new_cs, DWORD new_ip, DWORD new_flags); | static void IRET_pm_protected_mode_return(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); |
| static void IRET_pm_protected_mode_return_same_privilege(selector_t *cs_sel, DWORD new_ip, DWORD new_flags); | static void IRET_pm_protected_mode_return_same_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags); |
| static void IRET_pm_protected_mode_return_outer_privilege(selector_t *cs_sel, DWORD new_ip, DWORD new_flags); | static void IRET_pm_protected_mode_return_outer_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags); |
| static void IRET_pm_return_to_vm86(DWORD new_cs, DWORD new_ip, DWORD new_flags); | static void IRET_pm_return_to_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); |
| static void IRET_pm_return_from_vm86(DWORD new_cs, DWORD new_ip, DWORD new_flags); | static void IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); |
| void | void |
| IRET_pm(void) | IRET_pm(void) |
| { | { |
| DWORD sp; | UINT32 sp; |
| DWORD new_ip, new_flags; | UINT32 new_ip, new_flags; |
| WORD new_cs; | UINT16 new_cs; |
| int rv; | |
| VERBOSE(("IRET_pm: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_PREV_EIP, CPU_SS, CPU_ESP)); | VERBOSE(("IRET_pm: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_PREV_EIP, CPU_SS, CPU_ESP)); |
| Line 1015 IRET_pm(void) | Line 1012 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 1050 static void | Line 1047 static void |
| IRET_pm_nested_task(void) | IRET_pm_nested_task(void) |
| { | { |
| selector_t tss_sel; | selector_t tss_sel; |
| UINT16 new_tss; | |
| int rv; | int rv; |
| WORD new_tss; | |
| VERBOSE(("IRET_pm: TASK-RETURN: PE=1, VM=0, NT=1")); | VERBOSE(("IRET_pm: TASK-RETURN: PE=1, VM=0, NT=1")); |
| Line 1065 IRET_pm_nested_task(void) | Line 1062 IRET_pm_nested_task(void) |
| /* check system segment */ | /* check system segment */ |
| if (tss_sel.desc.s) { | if (tss_sel.desc.s) { |
| VERBOSE(("IRET_pm: task segment is %d segment", tss_sel.desc.u.seg.c ? "code" : "data")); | VERBOSE(("IRET_pm: task segment is %s segment", tss_sel.desc.u.seg.c ? "code" : "data")); |
| EXCEPTION(GP_EXCEPTION, tss_sel.idx); | EXCEPTION(GP_EXCEPTION, tss_sel.idx); |
| } | } |
| Line 1097 IRET_pm_nested_task(void) | Line 1094 IRET_pm_nested_task(void) |
| * IRET_pm: PROTECTED-MODE-RETURN | * IRET_pm: PROTECTED-MODE-RETURN |
| */ | */ |
| static void | static void |
| IRET_pm_protected_mode_return(DWORD new_cs, DWORD new_ip, DWORD new_flags) | IRET_pm_protected_mode_return(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| selector_t cs_sel; | selector_t cs_sel; |
| int rv; | int rv; |
| Line 1148 IRET_pm_protected_mode_return(DWORD new_ | Line 1145 IRET_pm_protected_mode_return(DWORD new_ |
| * IRET_pm: SAME-PRIVILEGE | * IRET_pm: SAME-PRIVILEGE |
| */ | */ |
| static void | static void |
| IRET_pm_protected_mode_return_same_privilege(selector_t *cs_sel, DWORD new_ip, DWORD new_flags) | IRET_pm_protected_mode_return_same_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| DWORD mask; | UINT32 mask; |
| DWORD stacksize; | UINT stacksize; |
| VERBOSE(("IRET_pm: RETURN-TO-SAME-PRIVILEGE-LEVEL")); | VERBOSE(("IRET_pm: RETURN-TO-SAME-PRIVILEGE-LEVEL")); |
| Line 1172 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; |
| } | } |
| } | } |
| if (CPU_INST_OP32) { | if (CPU_INST_OP32) { |
| stacksize = 12; | stacksize = 12; |
| } else { | } else { |
| Line 1187 IRET_pm_protected_mode_return_same_privi | Line 1185 IRET_pm_protected_mode_return_same_privi |
| if (CPU_STAT_SS32) { | if (CPU_STAT_SS32) { |
| CPU_ESP += stacksize; | CPU_ESP += stacksize; |
| } else { | } else { |
| CPU_SP += stacksize; | CPU_SP += (UINT16)stacksize; |
| } | } |
| } | } |
| Line 1195 IRET_pm_protected_mode_return_same_privi | Line 1193 IRET_pm_protected_mode_return_same_privi |
| * IRET_pm: OUTER-PRIVILEGE | * IRET_pm: OUTER-PRIVILEGE |
| */ | */ |
| static void | static void |
| IRET_pm_protected_mode_return_outer_privilege(selector_t *cs_sel, DWORD new_ip, DWORD new_flags) | IRET_pm_protected_mode_return_outer_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| descriptor_t *dp; | descriptor_t *dp; |
| selector_t ss_sel; | selector_t ss_sel; |
| DWORD mask; | UINT32 mask; |
| DWORD sp; | UINT32 sp; |
| DWORD new_sp; | UINT32 new_sp; |
| WORD new_ss; | UINT16 new_ss; |
| int rv; | int rv; |
| int i; | int i; |
| Line 1214 IRET_pm_protected_mode_return_outer_priv | Line 1212 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 1288 IRET_pm_protected_mode_return_outer_priv | Line 1286 IRET_pm_protected_mode_return_outer_priv |
| if (CPU_STAT_SS32) { | if (CPU_STAT_SS32) { |
| CPU_ESP = new_sp; | CPU_ESP = new_sp; |
| } else { | } else { |
| CPU_SP = new_sp; | CPU_SP = (UINT16)new_sp; |
| } | } |
| /* check segment register */ | /* check segment register */ |
| Line 1300 IRET_pm_protected_mode_return_outer_priv | Line 1298 IRET_pm_protected_mode_return_outer_priv |
| /* segment register is invalid */ | /* segment register is invalid */ |
| CPU_REGS_SREG(i) = 0; | CPU_REGS_SREG(i) = 0; |
| CPU_STAT_SREG_CLEAR(i); | CPU_STAT_SREG_CLEAR(i); |
| continue; | |
| } | } |
| } | } |
| } | } |
| Line 1310 IRET_pm_protected_mode_return_outer_priv | Line 1307 IRET_pm_protected_mode_return_outer_priv |
| * IRET_pm: new_flags & VM_FLAG | * IRET_pm: new_flags & VM_FLAG |
| */ | */ |
| static void | static void |
| IRET_pm_return_to_vm86(DWORD new_cs, DWORD new_ip, DWORD new_flags) | IRET_pm_return_to_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| WORD segsel[CPU_SEGREG_NUM]; | UINT16 segsel[CPU_SEGREG_NUM]; |
| DWORD sp; | UINT32 sp; |
| DWORD new_sp; | UINT32 new_sp; |
| int i; | int i; |
| 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 1332 IRET_pm_return_to_vm86(DWORD new_cs, DWO | Line 1329 IRET_pm_return_to_vm86(DWORD new_cs, DWO |
| } 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); |
| segsel[CPU_DS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 24); | segsel[CPU_DS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 24); |
| segsel[CPU_FS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 28); | segsel[CPU_FS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 28); |
| segsel[CPU_GS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 32); | segsel[CPU_GS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 32); |
| segsel[CPU_CS_INDEX] = new_cs; | segsel[CPU_CS_INDEX] = (UINT16)new_cs; |
| for (i = 0; i < CPU_SEGREG_NUM; i++) { | for (i = 0; i < CPU_SEGREG_NUM; i++) { |
| CPU_REGS_SREG(i) = segsel[i]; | CPU_REGS_SREG(i) = segsel[i]; |
| Line 1360 IRET_pm_return_to_vm86(DWORD new_cs, DWO | Line 1357 IRET_pm_return_to_vm86(DWORD new_cs, DWO |
| * IRET_pm: VM_FLAG | * IRET_pm: VM_FLAG |
| */ | */ |
| static void | static void |
| IRET_pm_return_from_vm86(DWORD new_cs, DWORD new_ip, DWORD new_flags) | IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| DWORD stacksize; | UINT stacksize; |
| VERBOSE(("IRET_pm: virtual-8086 mode: VM=1")); | VERBOSE(("IRET_pm: virtual-8086 mode: VM=1")); |
| Line 1376 IRET_pm_return_from_vm86(DWORD new_cs, D | Line 1373 IRET_pm_return_from_vm86(DWORD new_cs, D |
| if (CPU_STAT_SS32) { | if (CPU_STAT_SS32) { |
| CPU_ESP += stacksize; | CPU_ESP += stacksize; |
| } else { | } else { |
| CPU_SP += stacksize; | CPU_SP += (UINT16)stacksize; |
| } | } |
| set_eflags(new_flags, I_FLAG|RF_FLAG); | set_eflags(new_flags, I_FLAG|RF_FLAG); |