Diff for /np2/i386c/ia32/ctrlxfer.c between versions 1.1 and 1.2

version 1.1, 2003/12/08 00:55:31 version 1.2, 2004/01/13 16:37:42
Line 41  JMPfar_pm(WORD selector, DWORD new_ip) Line 41  JMPfar_pm(WORD selector, DWORD new_ip)
         selector_t sel2;          selector_t sel2;
         int rv;          int rv;
   
         VERBOSE(("JMPfar_pm: selector = 0x%04x, new_ip = 0x%08x", selector, new_ip));          VERBOSE(("JMPfar_pm: EIP = 0x%08x, selector = 0x%04x, new_ip = 0x%08x", CPU_PREV_EIP, selector, new_ip));
   
         /*          /*
          * IF effective address in the CS, DS, ES, FS, GS, or SS segment is illegal           * IF effective address in the CS, DS, ES, FS, GS, or SS segment is illegal
Line 53  JMPfar_pm(WORD selector, DWORD new_ip) Line 53  JMPfar_pm(WORD selector, DWORD new_ip)
   
         rv = parse_selector(&jmp_sel, selector);          rv = parse_selector(&jmp_sel, selector);
         if (rv < 0) {          if (rv < 0) {
                   VERBOSE(("JMPfar_pm: parse_selector (selector = %04x, rv = %d)", selector, rv));
                 EXCEPTION(GP_EXCEPTION, jmp_sel.idx);                  EXCEPTION(GP_EXCEPTION, jmp_sel.idx);
         }          }
   
         if (jmp_sel.desc.s) {          if (jmp_sel.desc.s) {
                 /* code segment descriptor */                  /* code segment descriptor */
                   VERBOSE(("JMPfar_pm: code or data segment descriptor"));
   
                 if (!jmp_sel.desc.u.seg.c) {                  if (!jmp_sel.desc.u.seg.c) {
                         /* data segment */                          /* data segment */
                           VERBOSE(("JMPfar_pm: data segment"));
                         EXCEPTION(GP_EXCEPTION, jmp_sel.idx);                          EXCEPTION(GP_EXCEPTION, jmp_sel.idx);
                 }                  }
   
Line 69  JMPfar_pm(WORD selector, DWORD new_ip) Line 73  JMPfar_pm(WORD selector, DWORD new_ip)
                         /* 布船 p.119 4.8.1.1. */                          /* 布船 p.119 4.8.1.1. */
                         if ((jmp_sel.rpl > CPU_STAT_CPL)                          if ((jmp_sel.rpl > CPU_STAT_CPL)
                          || (jmp_sel.desc.dpl != CPU_STAT_CPL)) {                           || (jmp_sel.desc.dpl != CPU_STAT_CPL)) {
                                   VERBOSE(("JMPfar_pm: RPL(%d) > CPL(%d) or DPL(%d) != CPL(%d)", jmp_sel.rpl, CPU_STAT_CPL, jmp_sel.desc.dpl, CPU_STAT_CPL));
                                 EXCEPTION(GP_EXCEPTION, jmp_sel.idx);                                  EXCEPTION(GP_EXCEPTION, jmp_sel.idx);
                         }                          }
                 } else {                  } else {
                         VERBOSE(("CONFORMING-CODE-SEGMENT"));                          VERBOSE(("CONFORMING-CODE-SEGMENT"));
                         /* 布船 p.120 4.8.1.2. */                          /* 布船 p.120 4.8.1.2. */
                         if (jmp_sel.desc.dpl > CPU_STAT_CPL) {                          if (jmp_sel.desc.dpl > CPU_STAT_CPL) {
                                   VERBOSE(("JMPfar_pm: DPL(%d) > CPL(%d)", jmp_sel.desc.dpl, CPU_STAT_CPL));
                                 EXCEPTION(GP_EXCEPTION, jmp_sel.idx);                                  EXCEPTION(GP_EXCEPTION, jmp_sel.idx);
                         }                          }
                 }                  }
   
                 /* not present */                  /* not present */
                 if (selector_is_not_present(&jmp_sel)) {                  if (selector_is_not_present(&jmp_sel)) {
                           VERBOSE(("JMPfar_pm: selector is not present"));
                         EXCEPTION(NP_EXCEPTION, jmp_sel.idx);                          EXCEPTION(NP_EXCEPTION, jmp_sel.idx);
                 }                  }
   
Line 90  JMPfar_pm(WORD selector, DWORD new_ip) Line 97  JMPfar_pm(WORD selector, DWORD new_ip)
   
                 /* out of range */                  /* out of range */
                 if (new_ip > jmp_sel.desc.u.seg.limit) {                  if (new_ip > jmp_sel.desc.u.seg.limit) {
                           VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, jmp_sel.desc.u.seg.limit));
                         EXCEPTION(GP_EXCEPTION, 0);                          EXCEPTION(GP_EXCEPTION, 0);
                 }                  }
   
                   VERBOSE(("JMPfar_pm: new CS = %04x, EIP = %08x", jmp_sel.selector, new_ip));
                 load_cs(jmp_sel.selector, &jmp_sel.desc, CPU_STAT_CPL);                  load_cs(jmp_sel.selector, &jmp_sel.desc, CPU_STAT_CPL);
                 SET_EIP(new_ip);                  SET_EIP(new_ip);
         } else {          } else {
                 /* system descriptor */                  /* system descriptor */
                   VERBOSE(("JMPfar_pm: system descriptor"));
   
                 switch (jmp_sel.desc.type) {                  switch (jmp_sel.desc.type) {
                 case CPU_SYSDESC_TYPE_CALL_16:                  case CPU_SYSDESC_TYPE_CALL_16:
                 case CPU_SYSDESC_TYPE_CALL_32:                  case CPU_SYSDESC_TYPE_CALL_32:
Line 105  JMPfar_pm(WORD selector, DWORD new_ip) Line 116  JMPfar_pm(WORD selector, DWORD new_ip)
                         /* check privilege level */                          /* check privilege level */
                         if ((jmp_sel.desc.dpl < CPU_STAT_CPL)                          if ((jmp_sel.desc.dpl < CPU_STAT_CPL)
                          || (jmp_sel.desc.dpl < jmp_sel.rpl)) {                           || (jmp_sel.desc.dpl < jmp_sel.rpl)) {
                                   VERBOSE(("JMPfar_pm: DPL(%d) < CPL(%d) or DPL(%d) < RPL(%d)", jmp_sel.desc.dpl, CPU_STAT_CPL, jmp_sel.desc.dpl, jmp_sel.rpl));
                                 EXCEPTION(GP_EXCEPTION, jmp_sel.idx);                                  EXCEPTION(GP_EXCEPTION, jmp_sel.idx);
                         }                          }
   
                         /* not present */                          /* not present */
                         if (selector_is_not_present(&jmp_sel)) {                          if (selector_is_not_present(&jmp_sel)) {
                                   VERBOSE(("JMPfar_pm: selector is not present"));
                                 EXCEPTION(NP_EXCEPTION, jmp_sel.idx);                                  EXCEPTION(NP_EXCEPTION, jmp_sel.idx);
                         }                          }
   
                         /* parse call gate selector */                          /* parse call gate selector */
                         rv = parse_selector(&sel2, jmp_sel.desc.u.gate.selector);                          rv = parse_selector(&sel2, jmp_sel.desc.u.gate.selector);
                         if (rv < 0) {                          if (rv < 0) {
                                   VERBOSE(("JMPfar_pm: parse_selector (selector = %04x, rv = %d)", jmp_sel.desc.u.gate.selector, rv));
                                 EXCEPTION(GP_EXCEPTION, sel2.idx);                                  EXCEPTION(GP_EXCEPTION, sel2.idx);
                         }                          }
   
                         /* check code segment descriptor */                          /* check code segment descriptor */
                         if (!sel2.desc.s || !sel2.desc.u.seg.c) {                          if (!sel2.desc.s || !sel2.desc.u.seg.c) {
                                   VERBOSE(("JMPfar_pm: not code segment (%s, %s)", sel2.desc.s ? "code/data" : "system", sel2.desc.u.seg.c ? "code" : "data"));
                                 EXCEPTION(GP_EXCEPTION, sel2.idx);                                  EXCEPTION(GP_EXCEPTION, sel2.idx);
                         }                          }
   
Line 129  JMPfar_pm(WORD selector, DWORD new_ip) Line 144  JMPfar_pm(WORD selector, DWORD new_ip)
                                 /* 布船 p.119 4.8.1.1. */                                  /* 布船 p.119 4.8.1.1. */
                                 if ((sel2.rpl > CPU_STAT_CPL)                                  if ((sel2.rpl > CPU_STAT_CPL)
                                  || (sel2.desc.dpl != CPU_STAT_CPL)) {                                   || (sel2.desc.dpl != CPU_STAT_CPL)) {
                                           VERBOSE(("JMPfar_pm: RPL(%d) > CPL(%d) or DPL(%d) != CPL(%d)", sel2.rpl, CPU_STAT_CPL, sel2.desc.dpl, CPU_STAT_CPL));
                                         EXCEPTION(GP_EXCEPTION, sel2.idx);                                          EXCEPTION(GP_EXCEPTION, sel2.idx);
                                 }                                  }
                         } else {                          } else {
                                 /* 布船 p.120 4.8.1.2. */                                  /* 布船 p.120 4.8.1.2. */
                                 if (sel2.desc.dpl > CPU_STAT_CPL) {                                  if (sel2.desc.dpl > CPU_STAT_CPL) {
                                           VERBOSE(("JMPfar_pm: DPL(%d) > CPL(%d)", sel2.desc.dpl, CPU_STAT_CPL));
                                         EXCEPTION(GP_EXCEPTION, sel2.idx);                                          EXCEPTION(GP_EXCEPTION, sel2.idx);
                                 }                                  }
                         }                          }
   
                         /* not present */                          /* not present */
                         if (selector_is_not_present(&sel2)) {                          if (selector_is_not_present(&sel2)) {
                                   VERBOSE(("JMPfar_pm: selector is not present"));
                                 EXCEPTION(NP_EXCEPTION, sel2.idx);                                  EXCEPTION(NP_EXCEPTION, sel2.idx);
                         }                          }
   
Line 150  JMPfar_pm(WORD selector, DWORD new_ip) Line 168  JMPfar_pm(WORD selector, DWORD new_ip)
   
                         /* out of range */                          /* out of range */
                         if (new_ip > sel2.desc.u.seg.limit) {                          if (new_ip > sel2.desc.u.seg.limit) {
                                   VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, sel2.desc.u.seg.limit));
                                 EXCEPTION(GP_EXCEPTION, 0);                                  EXCEPTION(GP_EXCEPTION, 0);
                         }                          }
   
                           VERBOSE(("JMPfar_pm: new CS = %04x, EIP = %08x", sel2.selector, new_ip));
                         load_cs(sel2.selector, &sel2.desc, CPU_STAT_CPL);                          load_cs(sel2.selector, &sel2.desc, CPU_STAT_CPL);
                         SET_EIP(new_ip);                          SET_EIP(new_ip);
                         break;                          break;
Line 176  JMPfar_pm(WORD selector, DWORD new_ip) Line 196  JMPfar_pm(WORD selector, DWORD new_ip)
                         /* check privilege level */                          /* check privilege level */
                         if ((jmp_sel.desc.dpl < CPU_STAT_CPL)                          if ((jmp_sel.desc.dpl < CPU_STAT_CPL)
                          || (jmp_sel.desc.dpl < jmp_sel.rpl)) {                           || (jmp_sel.desc.dpl < jmp_sel.rpl)) {
                                   VERBOSE(("JMPfar_pm: DPL(%d) < CPL(%d) or DPL(%d) < RPL(%d)", jmp_sel.desc.dpl, CPU_STAT_CPL, jmp_sel.desc.dpl, jmp_sel.rpl));
                                 EXCEPTION(GP_EXCEPTION, jmp_sel.idx);                                  EXCEPTION(GP_EXCEPTION, jmp_sel.idx);
                         }                          }
   
                         /* not present */                          /* not present */
                         if (selector_is_not_present(&jmp_sel)) {                          if (selector_is_not_present(&jmp_sel)) {
                                   VERBOSE(("JMPfar_pm: selector is not present"));
                                 EXCEPTION(NP_EXCEPTION, jmp_sel.idx);                                  EXCEPTION(NP_EXCEPTION, jmp_sel.idx);
                         }                          }
   
                         /* parse call tss selector */                          /* parse call tss selector */
                         rv = parse_selector(&sel2, jmp_sel.desc.u.gate.selector);                          rv = parse_selector(&sel2, jmp_sel.desc.u.gate.selector);
                         if (rv < 0 || sel2.ldt) {                          if (rv < 0 || sel2.ldt) {
                                   VERBOSE(("JMPfar_pm: parse_selector (selector = %04x, rv = %d, %s)", jmp_sel.desc.u.gate.selector, rv, sel2.ldt ? "LDT" : "GDT"));
                                 EXCEPTION(GP_EXCEPTION, sel2.idx);                                  EXCEPTION(GP_EXCEPTION, sel2.idx);
                         }                          }
   
Line 197  JMPfar_pm(WORD selector, DWORD new_ip) Line 220  JMPfar_pm(WORD selector, DWORD new_ip)
                                 break;                                  break;
   
                         default:                          default:
                                   VERBOSE(("JMPfar_pm: invalid descriptor type (type = %d)", sel2.desc.type));
                                 EXCEPTION(GP_EXCEPTION, sel2.idx);                                  EXCEPTION(GP_EXCEPTION, sel2.idx);
                                 break;                                  break;
                         }                          }
   
                         /* not present */                          /* not present */
                         if (selector_is_not_present(&sel2)) {                          if (selector_is_not_present(&sel2)) {
                                   VERBOSE(("JMPfar_pm: selector is not present"));
                                 EXCEPTION(NP_EXCEPTION, sel2.idx);                                  EXCEPTION(NP_EXCEPTION, sel2.idx);
                         }                          }
   
Line 210  JMPfar_pm(WORD selector, DWORD new_ip) Line 235  JMPfar_pm(WORD selector, DWORD new_ip)
   
                         /* out of range */                          /* out of range */
                         if (CPU_EIP > CPU_STAT_CS_LIMIT) {                          if (CPU_EIP > CPU_STAT_CS_LIMIT) {
                                   VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT));
                                 EXCEPTION(GP_EXCEPTION, 0);                                  EXCEPTION(GP_EXCEPTION, 0);
                         }                          }
                         break;                          break;
Line 221  JMPfar_pm(WORD selector, DWORD new_ip) Line 247  JMPfar_pm(WORD selector, DWORD new_ip)
                         /* check privilege level */                          /* check privilege level */
                         if ((jmp_sel.desc.dpl < CPU_STAT_CPL)                          if ((jmp_sel.desc.dpl < CPU_STAT_CPL)
                          || (jmp_sel.desc.dpl < jmp_sel.rpl)) {                           || (jmp_sel.desc.dpl < jmp_sel.rpl)) {
                                   VERBOSE(("JMPfar_pm: DPL(%d) < CPL(%d) or DPL(%d) < RPL(%d)", jmp_sel.desc.dpl, CPU_STAT_CPL, jmp_sel.desc.dpl, jmp_sel.rpl));
                                 EXCEPTION(TS_EXCEPTION, jmp_sel.idx);                                  EXCEPTION(TS_EXCEPTION, jmp_sel.idx);
                         }                          }
   
                         /* not present */                          /* not present */
                         if (selector_is_not_present(&jmp_sel)) {                          if (selector_is_not_present(&jmp_sel)) {
                                   VERBOSE(("JMPfar_pm: selector is not present"));
                                 EXCEPTION(NP_EXCEPTION, jmp_sel.idx);                                  EXCEPTION(NP_EXCEPTION, jmp_sel.idx);
                         }                          }
   
Line 233  JMPfar_pm(WORD selector, DWORD new_ip) Line 261  JMPfar_pm(WORD selector, DWORD new_ip)
   
                         /* out of range */                          /* out of range */
                         if (CPU_EIP > CPU_STAT_CS_LIMIT) {                          if (CPU_EIP > CPU_STAT_CS_LIMIT) {
                                   VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT));
                                 EXCEPTION(GP_EXCEPTION, 0);                                  EXCEPTION(GP_EXCEPTION, 0);
                         }                          }
                         break;                          break;
Line 242  JMPfar_pm(WORD selector, DWORD new_ip) Line 271  JMPfar_pm(WORD selector, DWORD new_ip)
                         VERBOSE(("JMPfar_pm: task is busy"));                          VERBOSE(("JMPfar_pm: task is busy"));
                         /*FALLTHROUGH*/                          /*FALLTHROUGH*/
                 default:                  default:
                           VERBOSE(("JMPfar_pm: invalid descriptor type (type = %d)", sel2.desc.type));
                         EXCEPTION(GP_EXCEPTION, jmp_sel.idx);                          EXCEPTION(GP_EXCEPTION, jmp_sel.idx);
                         break;                          break;
                 }                  }
Line 274  CALLfar_pm(WORD selector, DWORD new_ip) Line 304  CALLfar_pm(WORD selector, DWORD new_ip)
         selector_t sel2;          selector_t sel2;
         int rv;          int rv;
   
         VERBOSE(("CALLfar_pm: selector = 0x%04x, new_ip = 0x%08x", selector, new_ip));          VERBOSE(("CALLfar_pm: EIP = 0x%08x, selector = 0x%04x, new_ip = 0x%08x", CPU_PREV_EIP, selector, new_ip));
   
         rv = parse_selector(&call_sel, selector);          rv = parse_selector(&call_sel, selector);
         if (rv < 0) {          if (rv < 0) {
Line 329  CALLfar_pm(WORD selector, DWORD new_ip) Line 359  CALLfar_pm(WORD selector, DWORD new_ip)
   
                         PUSH0_16(CPU_CS);                          PUSH0_16(CPU_CS);
                         PUSH0_16(CPU_IP);                          PUSH0_16(CPU_IP);
                   }
   
                   if (!call_sel.desc.d) {
                         new_ip &= 0xffff;                          new_ip &= 0xffff;
                 }                  }
   
                 load_cs(call_sel.selector, &call_sel.desc, CPU_STAT_CPL);                  load_cs(call_sel.selector, &call_sel.desc, CPU_STAT_CPL);
                 SET_EIP(new_ip);                  SET_EIP(new_ip);
         } else {          } else {
Line 603  RETfar_pm(DWORD nbytes) Line 637  RETfar_pm(DWORD nbytes)
         DWORD new_ip;          DWORD new_ip;
         WORD selector;          WORD selector;
   
         VERBOSE(("RETfar_pm: nbytes = %d", nbytes));          VERBOSE(("RETfar_pm: EIP = 0x%08x, nbytes = %d", CPU_PREV_EIP, nbytes));
   
         if (CPU_INST_OP32) {          if (CPU_INST_OP32) {
                 CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 8 + nbytes);                  CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 8 + nbytes);
Line 759  IRET_pm() Line 793  IRET_pm()
         DWORD new_ip, new_flags;          DWORD new_ip, new_flags;
         WORD new_cs;          WORD new_cs;
   
         VERBOSE(("IRET_pm"));          VERBOSE(("IRET_pm: EIP = 0x%08x", CPU_PREV_EIP));
   
         if (CPU_STAT_VM86) {          if (CPU_STAT_VM86) {
                 /* RETURN-FROM-VIRTUAL-8086-MODE */                  /* RETURN-FROM-VIRTUAL-8086-MODE */

Removed from v.1.1  
changed lines
  Added in v.1.2


RetroPC.NET-CVS <cvs@retropc.net>