|
|
| version 1.1, 2003/12/08 00:55:31 | version 1.2, 2004/01/13 16:37:42 |
|---|---|
| Line 74 load_tr(WORD selector) | Line 74 load_tr(WORD selector) |
| } | } |
| void | void |
| get_stack_from_tss(BYTE pl, WORD* new_ss, DWORD* new_esp) | get_stack_from_tss(DWORD pl, WORD* new_ss, DWORD* new_esp) |
| { | { |
| DWORD tss_stack_addr; | DWORD tss_stack_addr; |
| Line 91 get_stack_from_tss(BYTE pl, WORD* new_ss | Line 91 get_stack_from_tss(BYTE pl, WORD* new_ss |
| case CPU_SYSDESC_TYPE_TSS_BUSY_16: | case CPU_SYSDESC_TYPE_TSS_BUSY_16: |
| tss_stack_addr = pl * 4 + 2; | tss_stack_addr = pl * 4 + 2; |
| if (tss_stack_addr + 4 > CPU_TR_DESC.u.seg.limit) { | if (tss_stack_addr + 3 > CPU_TR_DESC.u.seg.limit) { |
| EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); | EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); |
| } | } |
| tss_stack_addr += CPU_TR_DESC.u.seg.segbase; | tss_stack_addr += CPU_TR_DESC.u.seg.segbase; |
| Line 150 task_switch(selector_t* task_sel, int ty | Line 150 task_switch(selector_t* task_sel, int ty |
| cur_base = CPU_TR_DESC.u.seg.segbase; | cur_base = CPU_TR_DESC.u.seg.segbase; |
| task_base = task_sel->desc.u.seg.segbase; | task_base = task_sel->desc.u.seg.segbase; |
| VERBOSE(("task_switch: current task base address = 0x%08x", cur_base)); | |
| VERBOSE(("task_switch: new task base address = 0x%08x", task_base)); | |
| /* limit check */ | /* limit check */ |
| switch (task_sel->desc.type) { | switch (task_sel->desc.type) { |
| case CPU_SYSDESC_TYPE_TSS_32: | case CPU_SYSDESC_TYPE_TSS_32: |
| case CPU_SYSDESC_TYPE_TSS_BUSY_32: | case CPU_SYSDESC_TYPE_TSS_BUSY_32: |
| if (task_sel->desc.u.seg.limit < 103) { | if (task_sel->desc.u.seg.limit < 0x67) { |
| EXCEPTION(TS_EXCEPTION, task_sel->idx); | EXCEPTION(TS_EXCEPTION, task_sel->idx); |
| } | } |
| task16 = FALSE; | task16 = FALSE; |
| Line 164 task_switch(selector_t* task_sel, int ty | Line 166 task_switch(selector_t* task_sel, int ty |
| case CPU_SYSDESC_TYPE_TSS_16: | case CPU_SYSDESC_TYPE_TSS_16: |
| case CPU_SYSDESC_TYPE_TSS_BUSY_16: | case CPU_SYSDESC_TYPE_TSS_BUSY_16: |
| if (task_sel->desc.u.seg.limit < 43) { | if (task_sel->desc.u.seg.limit < 0x2b) { |
| EXCEPTION(TS_EXCEPTION, task_sel->idx); | EXCEPTION(TS_EXCEPTION, task_sel->idx); |
| } | } |
| task16 = TRUE; | task16 = TRUE; |
| Line 196 task_switch(selector_t* task_sel, int ty | Line 198 task_switch(selector_t* task_sel, int ty |
| regs[i] = cpu_lmemoryread_d(task_base + 40 + i * 4); | regs[i] = cpu_lmemoryread_d(task_base + 40 + i * 4); |
| } | } |
| for (i = 0; i < nsreg; i++) { | for (i = 0; i < nsreg; i++) { |
| sreg[i] = (WORD)cpu_lmemoryread_d(task_base + 72 + i * 4); | sreg[i] = cpu_lmemoryread_w(task_base + 72 + i * 4); |
| } | } |
| ldtr = (WORD)cpu_lmemoryread_d(task_base + 96); | ldtr = cpu_lmemoryread_w(task_base + 96); |
| t = cpu_lmemoryread_w(task_base + 100); | t = cpu_lmemoryread_w(task_base + 100); |
| t &= 1; | |
| iobase = cpu_lmemoryread_w(task_base + 102); | iobase = cpu_lmemoryread_w(task_base + 102); |
| } else { | } else { |
| eip = cpu_lmemoryread_w(task_base + 14); | eip = cpu_lmemoryread_w(task_base + 14); |
| Line 211 task_switch(selector_t* task_sel, int ty | Line 214 task_switch(selector_t* task_sel, int ty |
| sreg[i] = cpu_lmemoryread_w(task_base + 34 + i * 2); | sreg[i] = cpu_lmemoryread_w(task_base + 34 + i * 2); |
| } | } |
| ldtr = cpu_lmemoryread_w(task_base + 42); | ldtr = cpu_lmemoryread_w(task_base + 42); |
| t = 0; | |
| iobase = 0; | iobase = 0; |
| } | } |
| #ifdef VERBOSE | |
| VERBOSE(("task_switch: %dbit task", task16 ? 16 : 32)); | |
| VERBOSE(("task_switch: CR3 = 0x%08x", cr3)); | |
| VERBOSE(("task_switch: eip = 0x%08x", eip)); | |
| VERBOSE(("task_switch: eflags = 0x%08x", new_flags)); | |
| for (i = 0; i < CPU_REG_NUM; i++) { | |
| VERBOSE(("task_switch: regs[%d] = 0x%08x", i, regs[i])); | |
| } | |
| VERBOSE(("task_switch: nsreg = %d", nsreg)); | |
| for (i = 0; i < nsreg; i++) { | |
| VERBOSE(("task_switch: sreg[%d] = 0x%04x", i, sreg[i])); | |
| } | |
| VERBOSE(("task_switch: ldtr = 0x%04x", ldtr)); | |
| VERBOSE(("task_switch: t = 0x%04x", t)); | |
| VERBOSE(("task_switch: iobase = 0x%04x", iobase)); | |
| #endif | |
| /* if IRET or JMP, clear busy flag in this task: need */ | /* if IRET or JMP, clear busy flag in this task: need */ |
| /* if IRET, clear NT_FLAG in current EFLAG: need */ | /* if IRET, clear NT_FLAG in current EFLAG: need */ |
| Line 326 task_switch(selector_t* task_sel, int ty | Line 346 task_switch(selector_t* task_sel, int ty |
| CPU_REGS_SREG(i) = sreg[i]; | CPU_REGS_SREG(i) = sreg[i]; |
| CPU_STAT_SREG_CLEAR(i); | CPU_STAT_SREG_CLEAR(i); |
| } | } |
| CPU_LDTR = ldtr; | |
| CPU_LDTR_DESC.valid = 0; | |
| /* load LDTR */ | /* load LDTR */ |
| load_ldtr(ldtr, TS_EXCEPTION); | load_ldtr(ldtr, TS_EXCEPTION); |
| Line 335 task_switch(selector_t* task_sel, int ty | Line 353 task_switch(selector_t* task_sel, int ty |
| /* load CS */ | /* load CS */ |
| rv = parse_selector(&cs_sel, sreg[CPU_CS_INDEX]); | rv = parse_selector(&cs_sel, sreg[CPU_CS_INDEX]); |
| if (rv < 0) { | if (rv < 0) { |
| VERBOSE(("task_switch: load CS failure (sel = 0x%04x, rv = %d)", sreg[CPU_CS_INDEX], rv)); | |
| EXCEPTION(TS_EXCEPTION, cs_sel.idx); | EXCEPTION(TS_EXCEPTION, cs_sel.idx); |
| } | } |