|
|
| version 1.22, 2011/12/20 09:03:28 | version 1.27, 2012/06/18 14:30:27 |
|---|---|
| Line 33 | Line 33 |
| /*------------------------------------------------------------------------------ | /*------------------------------------------------------------------------------ |
| * JMPfar_pm | * JMPfar_pm |
| */ | */ |
| static void JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip); | static void CPUCALL JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip); |
| static void JMPfar_pm_call_gate(const selector_t *callgate_sel); | static void CPUCALL JMPfar_pm_call_gate(const selector_t *callgate_sel); |
| static void JMPfar_pm_task_gate(selector_t *taskgate_sel); | static void CPUCALL JMPfar_pm_task_gate(selector_t *taskgate_sel); |
| static void JMPfar_pm_tss(selector_t *tss_sel); | static void CPUCALL JMPfar_pm_tss(selector_t *tss_sel); |
| void | void CPUCALL |
| JMPfar_pm(UINT16 selector, UINT32 new_ip) | JMPfar_pm(UINT16 selector, UINT32 new_ip) |
| { | { |
| selector_t jmp_sel; | selector_t jmp_sel; |
| Line 101 JMPfar_pm(UINT16 selector, UINT32 new_ip | Line 101 JMPfar_pm(UINT16 selector, UINT32 new_ip |
| /*--- | /*--- |
| * JMPfar: code segment | * JMPfar: code segment |
| */ | */ |
| static void | static void CPUCALL |
| JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip) | JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip) |
| { | { |
| Line 110 JMPfar_pm_code_segment(const selector_t | Line 110 JMPfar_pm_code_segment(const selector_t |
| /* check privilege level */ | /* check privilege level */ |
| if (!SEG_IS_CONFORMING_CODE(&cs_sel->desc)) { | if (!SEG_IS_CONFORMING_CODE(&cs_sel->desc)) { |
| VERBOSE(("JMPfar_pm: NON-CONFORMING-CODE-SEGMENT")); | VERBOSE(("JMPfar_pm: NON-CONFORMING-CODE-SEGMENT")); |
| /* イシエャ p.119 4.8.1.1. */ | /* 荳句キサ p.119 4.8.1.1. */ |
| if (cs_sel->rpl > CPU_STAT_CPL) { | if (cs_sel->rpl > CPU_STAT_CPL) { |
| VERBOSE(("JMPfar_pm: RPL(%d) > CPL(%d)", cs_sel->rpl, CPU_STAT_CPL)); | VERBOSE(("JMPfar_pm: RPL(%d) > CPL(%d)", cs_sel->rpl, CPU_STAT_CPL)); |
| EXCEPTION(GP_EXCEPTION, cs_sel->idx); | EXCEPTION(GP_EXCEPTION, cs_sel->idx); |
| Line 121 JMPfar_pm_code_segment(const selector_t | Line 121 JMPfar_pm_code_segment(const selector_t |
| } | } |
| } else { | } else { |
| VERBOSE(("JMPfar_pm: CONFORMING-CODE-SEGMENT")); | VERBOSE(("JMPfar_pm: CONFORMING-CODE-SEGMENT")); |
| /* イシエャ p.120 4.8.1.2. */ | /* 荳句キサ p.120 4.8.1.2. */ |
| if (cs_sel->desc.dpl > CPU_STAT_CPL) { | if (cs_sel->desc.dpl > CPU_STAT_CPL) { |
| VERBOSE(("JMPfar_pm: DPL(%d) > CPL(%d)", cs_sel->desc.dpl, CPU_STAT_CPL)); | VERBOSE(("JMPfar_pm: DPL(%d) > CPL(%d)", cs_sel->desc.dpl, CPU_STAT_CPL)); |
| EXCEPTION(GP_EXCEPTION, cs_sel->idx); | EXCEPTION(GP_EXCEPTION, cs_sel->idx); |
| Line 147 JMPfar_pm_code_segment(const selector_t | Line 147 JMPfar_pm_code_segment(const selector_t |
| /*--- | /*--- |
| * JMPfar: call gate | * JMPfar: call gate |
| */ | */ |
| static void | static void CPUCALL |
| JMPfar_pm_call_gate(const selector_t *callgate_sel) | JMPfar_pm_call_gate(const selector_t *callgate_sel) |
| { | { |
| selector_t cs_sel; | selector_t cs_sel; |
| Line 190 JMPfar_pm_call_gate(const selector_t *ca | Line 190 JMPfar_pm_call_gate(const selector_t *ca |
| /* check privilege level */ | /* check privilege level */ |
| if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc)) { | if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc)) { |
| /* イシエャ p.119 4.8.1.1. */ | /* 荳句キサ p.119 4.8.1.1. */ |
| if (cs_sel.rpl > CPU_STAT_CPL) { | if (cs_sel.rpl > CPU_STAT_CPL) { |
| VERBOSE(("JMPfar_pm: RPL(%d) > CPL(%d)", cs_sel.rpl, CPU_STAT_CPL)); | VERBOSE(("JMPfar_pm: RPL(%d) > CPL(%d)", cs_sel.rpl, CPU_STAT_CPL)); |
| EXCEPTION(GP_EXCEPTION, cs_sel.idx); | EXCEPTION(GP_EXCEPTION, cs_sel.idx); |
| Line 200 JMPfar_pm_call_gate(const selector_t *ca | Line 200 JMPfar_pm_call_gate(const selector_t *ca |
| EXCEPTION(GP_EXCEPTION, cs_sel.idx); | EXCEPTION(GP_EXCEPTION, cs_sel.idx); |
| } | } |
| } else { | } else { |
| /* イシエャ p.120 4.8.1.2. */ | /* 荳句キサ p.120 4.8.1.2. */ |
| if (cs_sel.desc.dpl > CPU_STAT_CPL) { | if (cs_sel.desc.dpl > CPU_STAT_CPL) { |
| VERBOSE(("JMPfar_pm: DPL(%d) > CPL(%d)", cs_sel.desc.dpl, CPU_STAT_CPL)); | VERBOSE(("JMPfar_pm: DPL(%d) > CPL(%d)", cs_sel.desc.dpl, CPU_STAT_CPL)); |
| EXCEPTION(GP_EXCEPTION, cs_sel.idx); | EXCEPTION(GP_EXCEPTION, cs_sel.idx); |
| Line 226 JMPfar_pm_call_gate(const selector_t *ca | Line 226 JMPfar_pm_call_gate(const selector_t *ca |
| /*--- | /*--- |
| * JMPfar: task gate | * JMPfar: task gate |
| */ | */ |
| static void | static void CPUCALL |
| JMPfar_pm_task_gate(selector_t *taskgate_sel) | JMPfar_pm_task_gate(selector_t *taskgate_sel) |
| { | { |
| selector_t tss_sel; | selector_t tss_sel; |
| Line 291 JMPfar_pm_task_gate(selector_t *taskgate | Line 291 JMPfar_pm_task_gate(selector_t *taskgate |
| /*--- | /*--- |
| * JMPfar: TSS | * JMPfar: TSS |
| */ | */ |
| static void | static void CPUCALL |
| JMPfar_pm_tss(selector_t *tss_sel) | JMPfar_pm_tss(selector_t *tss_sel) |
| { | { |
| Line 326 JMPfar_pm_tss(selector_t *tss_sel) | Line 326 JMPfar_pm_tss(selector_t *tss_sel) |
| /*------------------------------------------------------------------------------ | /*------------------------------------------------------------------------------ |
| * CALLfar_pm | * CALLfar_pm |
| */ | */ |
| static void CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip); | static void CPUCALL CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip); |
| static void CALLfar_pm_call_gate(const selector_t *callgate_sel); | static void CPUCALL CALLfar_pm_call_gate(const selector_t *callgate_sel); |
| static void CALLfar_pm_task_gate(selector_t *taskgate_sel); | static void CPUCALL CALLfar_pm_task_gate(selector_t *taskgate_sel); |
| static void CALLfar_pm_tss(selector_t *tss_sel); | static void CPUCALL CALLfar_pm_tss(selector_t *tss_sel); |
| void | void CPUCALL |
| CALLfar_pm(UINT16 selector, UINT32 new_ip) | CALLfar_pm(UINT16 selector, UINT32 new_ip) |
| { | { |
| selector_t call_sel; | selector_t call_sel; |
| Line 394 CALLfar_pm(UINT16 selector, UINT32 new_i | Line 394 CALLfar_pm(UINT16 selector, UINT32 new_i |
| /*--- | /*--- |
| * CALLfar_pm: code segment | * CALLfar_pm: code segment |
| */ | */ |
| static void | static void CPUCALL |
| CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip) | CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip) |
| { | { |
| UINT32 sp; | UINT32 sp; |
| Line 404 CALLfar_pm_code_segment(const selector_t | Line 404 CALLfar_pm_code_segment(const selector_t |
| /* check privilege level */ | /* check privilege level */ |
| if (!SEG_IS_CONFORMING_CODE(&cs_sel->desc)) { | if (!SEG_IS_CONFORMING_CODE(&cs_sel->desc)) { |
| VERBOSE(("CALLfar_pm: NON-CONFORMING-CODE-SEGMENT")); | VERBOSE(("CALLfar_pm: NON-CONFORMING-CODE-SEGMENT")); |
| /* イシエャ p.119 4.8.1.1. */ | /* 荳句キサ p.119 4.8.1.1. */ |
| if (cs_sel->rpl > CPU_STAT_CPL) { | if (cs_sel->rpl > CPU_STAT_CPL) { |
| VERBOSE(("CALLfar_pm: RPL(%d) > CPL(%d)", cs_sel->rpl, CPU_STAT_CPL)); | VERBOSE(("CALLfar_pm: RPL(%d) > CPL(%d)", cs_sel->rpl, CPU_STAT_CPL)); |
| EXCEPTION(GP_EXCEPTION, cs_sel->idx); | EXCEPTION(GP_EXCEPTION, cs_sel->idx); |
| Line 415 CALLfar_pm_code_segment(const selector_t | Line 415 CALLfar_pm_code_segment(const selector_t |
| } | } |
| } else { | } else { |
| VERBOSE(("CALLfar_pm: CONFORMING-CODE-SEGMENT")); | VERBOSE(("CALLfar_pm: CONFORMING-CODE-SEGMENT")); |
| /* イシエャ p.120 4.8.1.2. */ | /* 荳句キサ p.120 4.8.1.2. */ |
| if (cs_sel->desc.dpl > CPU_STAT_CPL) { | if (cs_sel->desc.dpl > CPU_STAT_CPL) { |
| VERBOSE(("CALLfar_pm: DPL(%d) > CPL(%d)", cs_sel->desc.dpl, CPU_STAT_CPL)); | VERBOSE(("CALLfar_pm: DPL(%d) > CPL(%d)", cs_sel->desc.dpl, CPU_STAT_CPL)); |
| EXCEPTION(GP_EXCEPTION, cs_sel->idx); | EXCEPTION(GP_EXCEPTION, cs_sel->idx); |
| Line 464 CALLfar_pm_code_segment(const selector_t | Line 464 CALLfar_pm_code_segment(const selector_t |
| /*--- | /*--- |
| * CALLfar_pm: call gate | * CALLfar_pm: call gate |
| */ | */ |
| static void CALLfar_pm_call_gate_same_privilege(const selector_t *call_sel, selector_t *cs_sel); | static void CPUCALL CALLfar_pm_call_gate_same_privilege(const 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 CPUCALL CALLfar_pm_call_gate_more_privilege(const selector_t *call_sel, selector_t *cs_sel); |
| static void | static void CPUCALL |
| CALLfar_pm_call_gate(const selector_t *callgate_sel) | CALLfar_pm_call_gate(const selector_t *callgate_sel) |
| { | { |
| selector_t cs_sel; | selector_t cs_sel; |
| Line 536 CALLfar_pm_call_gate(const selector_t *c | Line 536 CALLfar_pm_call_gate(const selector_t *c |
| /*--- | /*--- |
| * CALLfar_pm: call gate (SAME-PRIVILEGE) | * CALLfar_pm: call gate (SAME-PRIVILEGE) |
| */ | */ |
| static void | static void CPUCALL |
| CALLfar_pm_call_gate_same_privilege(const selector_t *callgate_sel, selector_t *cs_sel) | CALLfar_pm_call_gate_same_privilege(const selector_t *callgate_sel, selector_t *cs_sel) |
| { | { |
| UINT32 sp; | UINT32 sp; |
| Line 567 CALLfar_pm_call_gate_same_privilege(cons | Line 567 CALLfar_pm_call_gate_same_privilege(cons |
| /*--- | /*--- |
| * CALLfar_pm: call gate (MORE-PRIVILEGE) | * CALLfar_pm: call gate (MORE-PRIVILEGE) |
| */ | */ |
| static void | static void CPUCALL |
| CALLfar_pm_call_gate_more_privilege(const selector_t *callgate_sel, selector_t *cs_sel) | CALLfar_pm_call_gate_more_privilege(const selector_t *callgate_sel, selector_t *cs_sel) |
| { | { |
| UINT32 param[32]; /* copy param */ | UINT32 param[32]; /* copy param */ |
| Line 646 CALLfar_pm_call_gate_more_privilege(cons | Line 646 CALLfar_pm_call_gate_more_privilege(cons |
| } else { | } else { |
| stacksize += param_count * 2; | stacksize += param_count * 2; |
| } | } |
| cpu_stack_push_check(ss_sel.idx, &ss_sel.desc, new_esp, stacksize); | cpu_stack_push_check(ss_sel.idx, &ss_sel.desc, new_esp, stacksize, ss_sel.desc.d); |
| if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) { | if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) { |
| /* dump param */ | /* dump param */ |
| Line 710 CALLfar_pm_call_gate_more_privilege(cons | Line 710 CALLfar_pm_call_gate_more_privilege(cons |
| /*--- | /*--- |
| * CALLfar_pm: task gate | * CALLfar_pm: task gate |
| */ | */ |
| static void | static void CPUCALL |
| CALLfar_pm_task_gate(selector_t *taskgate_sel) | CALLfar_pm_task_gate(selector_t *taskgate_sel) |
| { | { |
| selector_t tss_sel; | selector_t tss_sel; |
| Line 775 CALLfar_pm_task_gate(selector_t *taskgat | Line 775 CALLfar_pm_task_gate(selector_t *taskgat |
| /*--- | /*--- |
| * CALLfar_pm: TSS | * CALLfar_pm: TSS |
| */ | */ |
| static void | static void CPUCALL |
| CALLfar_pm_tss(selector_t *tss_sel) | CALLfar_pm_tss(selector_t *tss_sel) |
| { | { |
| Line 811 CALLfar_pm_tss(selector_t *tss_sel) | Line 811 CALLfar_pm_tss(selector_t *tss_sel) |
| * RETfar_pm | * RETfar_pm |
| */ | */ |
| void | void CPUCALL |
| RETfar_pm(UINT nbytes) | RETfar_pm(UINT nbytes) |
| { | { |
| selector_t cs_sel, ss_sel, temp_sel; | selector_t cs_sel, ss_sel, temp_sel; |
| Line 973 RETfar_pm(UINT nbytes) | Line 973 RETfar_pm(UINT nbytes) |
| && (CPU_STAT_CPL > sdp->dpl)) { | && (CPU_STAT_CPL > sdp->dpl)) { |
| /* current segment descriptor is invalid */ | /* current segment descriptor is invalid */ |
| CPU_REGS_SREG(i) = 0; | CPU_REGS_SREG(i) = 0; |
| segdesc_clear(sdp); | memset(sdp, 0, sizeof(*sdp)); |
| continue; | continue; |
| } | } |
| Line 982 RETfar_pm(UINT nbytes) | Line 982 RETfar_pm(UINT nbytes) |
| if (rv < 0) { | if (rv < 0) { |
| /* segment register is invalid */ | /* segment register is invalid */ |
| CPU_REGS_SREG(i) = 0; | CPU_REGS_SREG(i) = 0; |
| segdesc_clear(sdp); | memset(sdp, 0, sizeof(*sdp)); |
| continue; | continue; |
| } | } |
| Line 999 RETfar_pm(UINT nbytes) | Line 999 RETfar_pm(UINT nbytes) |
| && (CPU_STAT_CPL > temp_sel.desc.dpl))) { | && (CPU_STAT_CPL > temp_sel.desc.dpl))) { |
| /* segment descriptor is invalid */ | /* segment descriptor is invalid */ |
| CPU_REGS_SREG(i) = 0; | CPU_REGS_SREG(i) = 0; |
| segdesc_clear(sdp); | memset(sdp, 0, sizeof(*sdp)); |
| } | } |
| } | } |
| } | } |
| Line 1012 RETfar_pm(UINT nbytes) | Line 1012 RETfar_pm(UINT 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(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); | static void CPUCALL IRET_pm_protected_mode_return(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); |
| static void IRET_pm_protected_mode_return_same_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags); | static void CPUCALL 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(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags); | static void CPUCALL 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(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); | static void CPUCALL IRET_pm_return_to_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); |
| static void IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); | static void CPUCALL IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); |
| void | void |
| IRET_pm(void) | IRET_pm(void) |
| Line 1124 IRET_pm_nested_task(void) | Line 1124 IRET_pm_nested_task(void) |
| /*--- | /*--- |
| * IRET_pm: PROTECTED-MODE-RETURN | * IRET_pm: PROTECTED-MODE-RETURN |
| */ | */ |
| static void | static void CPUCALL |
| IRET_pm_protected_mode_return(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) | IRET_pm_protected_mode_return(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| selector_t cs_sel; | selector_t cs_sel; |
| Line 1175 IRET_pm_protected_mode_return(UINT16 new | Line 1175 IRET_pm_protected_mode_return(UINT16 new |
| /*--- | /*--- |
| * IRET_pm: SAME-PRIVILEGE | * IRET_pm: SAME-PRIVILEGE |
| */ | */ |
| static void | static void CPUCALL |
| IRET_pm_protected_mode_return_same_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags) | IRET_pm_protected_mode_return_same_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| UINT32 mask; | UINT32 mask; |
| Line 1223 IRET_pm_protected_mode_return_same_privi | Line 1223 IRET_pm_protected_mode_return_same_privi |
| /*--- | /*--- |
| * IRET_pm: OUTER-PRIVILEGE | * IRET_pm: OUTER-PRIVILEGE |
| */ | */ |
| static void | static void CPUCALL |
| IRET_pm_protected_mode_return_outer_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags) | IRET_pm_protected_mode_return_outer_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| descriptor_t *sdp; | descriptor_t *sdp; |
| Line 1334 IRET_pm_protected_mode_return_outer_priv | Line 1334 IRET_pm_protected_mode_return_outer_priv |
| && (sdp->dpl < CPU_STAT_CPL)) { | && (sdp->dpl < CPU_STAT_CPL)) { |
| /* segment register is invalid */ | /* segment register is invalid */ |
| CPU_REGS_SREG(i) = 0; | CPU_REGS_SREG(i) = 0; |
| segdesc_clear(sdp); | memset(sdp, 0, sizeof(*sdp)); |
| } | } |
| } | } |
| } | } |
| Line 1343 IRET_pm_protected_mode_return_outer_priv | Line 1343 IRET_pm_protected_mode_return_outer_priv |
| /*--- | /*--- |
| * IRET_pm: new_flags & VM_FLAG | * IRET_pm: new_flags & VM_FLAG |
| */ | */ |
| static void | static void CPUCALL |
| IRET_pm_return_to_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) | IRET_pm_return_to_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| UINT16 segsel[CPU_SEGREG_NUM]; | UINT16 segsel[CPU_SEGREG_NUM]; |
| Line 1364 IRET_pm_return_to_vm86(UINT16 new_cs, UI | Line 1364 IRET_pm_return_to_vm86(UINT16 new_cs, UI |
| } | } |
| SS_POP_CHECK(sp, 36); | SS_POP_CHECK(sp, 36); |
| if (new_ip > 0xffff) { | |
| EXCEPTION(GP_EXCEPTION, 0); | |
| } | |
| 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 1381 IRET_pm_return_to_vm86(UINT16 new_cs, UI | Line 1377 IRET_pm_return_to_vm86(UINT16 new_cs, UI |
| } | } |
| CPU_ESP = new_sp; | CPU_ESP = new_sp; |
| CPU_EIP = new_ip; | CPU_EIP = new_ip & 0xffff; |
| /* to VM86 mode */ | /* to VM86 mode */ |
| set_eflags(new_flags, IOPL_FLAG|I_FLAG|VM_FLAG|RF_FLAG); | set_eflags(new_flags, IOPL_FLAG|I_FLAG|VM_FLAG|RF_FLAG); |
| Line 1390 IRET_pm_return_to_vm86(UINT16 new_cs, UI | Line 1386 IRET_pm_return_to_vm86(UINT16 new_cs, UI |
| /*--- | /*--- |
| * IRET_pm: VM_FLAG | * IRET_pm: VM_FLAG |
| */ | */ |
| static void | static void CPUCALL |
| IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) | IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) |
| { | { |
| UINT stacksize; | UINT stacksize; |