Diff for /np2/i386c/ia32/exception.c between versions 1.6 and 1.8

version 1.6, 2004/01/27 15:56:57 version 1.8, 2004/02/05 16:43:44
Line 72  exception(int num, int error_code) Line 72  exception(int num, int error_code)
   
         __ASSERT((unsigned int)num < EXCEPTION_NUM);          __ASSERT((unsigned int)num < EXCEPTION_NUM);
   
           VERBOSE(("exception: -------------------------------------------------------------- start"));
         VERBOSE(("exception: %s, error_code = %x at %04x:%08x", exception_str[num], error_code, CPU_CS, CPU_PREV_EIP));          VERBOSE(("exception: %s, error_code = %x at %04x:%08x", exception_str[num], error_code, CPU_CS, CPU_PREV_EIP));
         VERBOSE(("exception:------------------------------------------------"));  
         VERBOSE(("%s", cpu_reg2str()));          VERBOSE(("%s", cpu_reg2str()));
         VERBOSE(("exception:------------------------------------------------"));  
   
         CPU_STAT_NERROR++;          CPU_STAT_NERROR++;
         if ((CPU_STAT_NERROR >= 3)           if ((CPU_STAT_NERROR >= 3) 
Line 103  exception(int num, int error_code) Line 102  exception(int num, int error_code)
                 error_code = 0;                  error_code = 0;
                 break;                  break;
   
   #if CPU_FAMILY >= 4
         case AC_EXCEPTION:      /* (F) アラインメントチェック (errcode: 0) */          case AC_EXCEPTION:      /* (F) アラインメントチェック (errcode: 0) */
                 error_code = 0;                  error_code = 0;
                 /*FALLTHROUGH*/                  /*FALLTHROUGH*/
   #endif
         case TS_EXCEPTION:      /* (F) 無効 TSS (errcode) */          case TS_EXCEPTION:      /* (F) 無効 TSS (errcode) */
         case NP_EXCEPTION:      /* (F) セグメント不在 (errcode) */          case NP_EXCEPTION:      /* (F) セグメント不在 (errcode) */
         case SS_EXCEPTION:      /* (F) スタックセグメントフォルト (errcode) */          case SS_EXCEPTION:      /* (F) スタックセグメントフォルト (errcode) */
Line 120  exception(int num, int error_code) Line 121  exception(int num, int error_code)
                 errorp = 0;                  errorp = 0;
                 break;                  break;
   
   #if CPU_FAMILY >= 5
         case MC_EXCEPTION:      /* (A) マシンチェック */          case MC_EXCEPTION:      /* (A) マシンチェック */
                 CPU_EIP = CPU_PREV_EIP;                  CPU_EIP = CPU_PREV_EIP;
                 errorp = 0;                  errorp = 0;
                 break;                  break;
   #endif
   
   #if CPU_FAMILY >= 6
         case XF_EXCEPTION:      /* (F) ストリーミング SIMD 拡張命令 */          case XF_EXCEPTION:      /* (F) ストリーミング SIMD 拡張命令 */
                 CPU_EIP = CPU_PREV_EIP;                  CPU_EIP = CPU_PREV_EIP;
                 errorp = 0;                  errorp = 0;
                 break;                  break;
   #endif
   
         default:          default:
                 ia32_panic("exception: unknown exception (%d)", num);                  ia32_panic("exception: unknown exception (%d)", num);
Line 142  exception(int num, int error_code) Line 147  exception(int num, int error_code)
         }          }
         CPU_STAT_PREV_EXCEPTION = num;          CPU_STAT_PREV_EXCEPTION = num;
   
         INTERRUPT(num, FALSE, errorp, error_code);          VERBOSE(("exception: ---------------------------------------------------------------- end"));
   
           INTERRUPT(num, 0, errorp, error_code);
         siglongjmp(exec_1step_jmpbuf, 1);          siglongjmp(exec_1step_jmpbuf, 1);
 }  }
   
Line 213  interrupt(int num, int softintp, int err Line 220  interrupt(int num, int softintp, int err
         DWORD new_ip;          DWORD new_ip;
         WORD new_cs;          WORD new_cs;
   
         VERBOSE(("interrupt: num = 0x%02x, softintp = %s, errorp = %s, error_code = %02x", num, softintp ? "on" : "off", errorp ? "on" : "off", error_code));          VERBOSE(("interrupt: num = 0x%02x, softintp = %s, errorp = %s, error_code = %08x", num, softintp ? "on" : "off", errorp ? "on" : "off", error_code));
   
         if (!CPU_STAT_PM) {          if (!CPU_STAT_PM) {
                 /* real mode */                  /* real mode */
                 idt_idx = num * 4;                  idt_idx = num * 4;
                 if (idt_idx + 3 > CPU_IDTR_LIMIT) {                  if (idt_idx + 3 > CPU_IDTR_LIMIT) {
                         VERBOSE(("interrupt: real-mode IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT));                          VERBOSE(("interrupt: real-mode IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT));
                         EXCEPTION(GP_EXCEPTION, num * 4 | 2);                          EXCEPTION(GP_EXCEPTION, idt_idx + 2);
                 }                  }
   
                 if (!softintp) {                  if (!softintp) {
Line 237  interrupt(int num, int softintp, int err Line 244  interrupt(int num, int softintp, int err
                 CPU_EFLAG &= ~(T_FLAG | I_FLAG | AC_FLAG | RF_FLAG);                  CPU_EFLAG &= ~(T_FLAG | I_FLAG | AC_FLAG | RF_FLAG);
                 CPU_TRAP = 0;                  CPU_TRAP = 0;
   
                 new_ip = cpu_memoryread_w(CPU_IDTR_BASE + num * 4);                  new_ip = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx);
                 new_cs = cpu_memoryread_w(CPU_IDTR_BASE + num * 4 + 2);                  new_cs = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx + 2);
                 CPU_SET_SEGREG(CPU_CS_INDEX, new_cs);                  CPU_SET_SEGREG(CPU_CS_INDEX, new_cs);
                 SET_EIP(new_ip);                  SET_EIP(new_ip);
                 CPU_WORKCLOCK(20);                  CPU_WORKCLOCK(20);
         } else {          } else {
                 /* protected mode */                  /* protected mode */
                   VERBOSE(("interrupt: -------------------------------------------------------------- start"));
   
                 /* VM86 && IOPL < 3 && interrupt cause == INTn */                  /* VM86 && IOPL < 3 && interrupt cause == INTn */
                 if (CPU_STAT_VM86 && (CPU_STAT_IOPL < CPU_IOPL3) && (softintp == -1)) {                  if (CPU_STAT_VM86 && (CPU_STAT_IOPL < CPU_IOPL3) && (softintp == -1)) {
Line 254  interrupt(int num, int softintp, int err Line 262  interrupt(int num, int softintp, int err
                 idt_idx = num * 8;                  idt_idx = num * 8;
                 if (idt_idx + 7 > CPU_IDTR_LIMIT) {                  if (idt_idx + 7 > CPU_IDTR_LIMIT) {
                         VERBOSE(("interrupt: IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT));                          VERBOSE(("interrupt: IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT));
                         EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp);                          EXCEPTION(GP_EXCEPTION, idt_idx + 2 + !softintp);
                 }                  }
   
                 memset(&gd, 0, sizeof(gd));                  memset(&gd, 0, sizeof(gd));
                 CPU_SET_GATEDESC(&gd, CPU_IDTR_BASE + idt_idx);                  load_descriptor(&gd, CPU_IDTR_BASE + idt_idx);
                 if (!gd.valid || !gd.p) {                  if (!gd.valid || !gd.p) {
                         VERBOSE(("interrupt: gate descripter is invalid."));                          VERBOSE(("interrupt: gate descripter is invalid."));
                         EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp);                          EXCEPTION(GP_EXCEPTION, idt_idx + 2 + !softintp);
                 }                  }
   
                 switch (gd.type) {                  switch (gd.type) {
Line 274  interrupt(int num, int softintp, int err Line 282  interrupt(int num, int softintp, int err
   
                 default:                  default:
                         VERBOSE(("interrupt: invalid gate type (%d)", gd.type));                          VERBOSE(("interrupt: invalid gate type (%d)", gd.type));
                         EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp);                          EXCEPTION(GP_EXCEPTION, idt_idx + 2 + !softintp);
                         break;                          break;
                 }                  }
   
                 /* 5.10.1.1. 例外/割り込みハンドラ・プロシージャの保護 */                  /* 5.10.1.1. 例外/割り込みハンドラ・プロシージャの保護 */
                 if (softintp && (gd.dpl < CPU_STAT_CPL)) {                  if (softintp && (gd.dpl < CPU_STAT_CPL)) {
                         VERBOSE(("interrupt: softintp && DPL(%d) < CPL(%d)", gd.dpl, CPU_STAT_CPL));                          VERBOSE(("interrupt: softintp && DPL(%d) < CPL(%d)", gd.dpl, CPU_STAT_CPL));
                         EXCEPTION(GP_EXCEPTION, num * 8 | 2);                          EXCEPTION(GP_EXCEPTION, idt_idx + 2);
                 }                  }
   
                 switch (gd.type) {                  switch (gd.type) {
Line 297  interrupt(int num, int softintp, int err Line 305  interrupt(int num, int softintp, int err
                         break;                          break;
   
                 default:                  default:
                         EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp);                          EXCEPTION(GP_EXCEPTION, idt_idx + 2 + !softintp);
                         break;                          break;
                 }                  }
   
                   VERBOSE(("interrupt: ---------------------------------------------------------------- end"));
         }          }
 }  }
   
Line 394  interrupt_intr_or_trap(descriptor_t *gdp Line 404  interrupt_intr_or_trap(descriptor_t *gdp
         rv = parse_selector(&intr_sel, gdp->u.gate.selector);          rv = parse_selector(&intr_sel, gdp->u.gate.selector);
         if (rv < 0) {          if (rv < 0) {
                 VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", gdp->u.gate.selector, rv));                  VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", gdp->u.gate.selector, rv));
                 EXCEPTION(GP_EXCEPTION, intr_sel.idx | !softintp);                  EXCEPTION(GP_EXCEPTION, intr_sel.idx + !softintp);
         }          }
   
         /* check segment type */          /* check segment type */
         if (!intr_sel.desc.s) {          if (!intr_sel.desc.s) {
                 VERBOSE(("interrupt: code segment is system segment"));                  VERBOSE(("interrupt: code segment is system segment"));
                 EXCEPTION(GP_EXCEPTION, intr_sel.idx | !softintp);                  EXCEPTION(GP_EXCEPTION, intr_sel.idx + !softintp);
         }          }
         if (!intr_sel.desc.u.seg.c) {          if (!intr_sel.desc.u.seg.c) {
                 VERBOSE(("interrupt: code segment is data segment"));                  VERBOSE(("interrupt: code segment is data segment"));
                 EXCEPTION(GP_EXCEPTION, intr_sel.idx | !softintp);                  EXCEPTION(GP_EXCEPTION, intr_sel.idx + !softintp);
         }          }
   
         /* check privilege level */          /* check privilege level */
         if (intr_sel.desc.dpl > CPU_STAT_CPL) {          if (intr_sel.desc.dpl > CPU_STAT_CPL) {
                 VERBOSE(("interrupt: DPL(%d) > CPL(%d)", intr_sel.desc.dpl, CPU_STAT_CPL));                  VERBOSE(("interrupt: DPL(%d) > CPL(%d)", intr_sel.desc.dpl, CPU_STAT_CPL));
                 EXCEPTION(GP_EXCEPTION, intr_sel.idx | !softintp);                  EXCEPTION(GP_EXCEPTION, intr_sel.idx + !softintp);
         }          }
   
         /* not present */          /* not present */
         if (selector_is_not_present(&intr_sel)) {          if (selector_is_not_present(&intr_sel)) {
                 VERBOSE(("interrupt: selector is not present"));                  VERBOSE(("interrupt: selector is not present"));
                 EXCEPTION(NP_EXCEPTION, intr_sel.idx | !softintp);                  EXCEPTION(NP_EXCEPTION, intr_sel.idx + !softintp);
         }          }
   
         if (!intr_sel.desc.u.seg.ec          if (!intr_sel.desc.u.seg.ec
Line 446  interrupt_intr_or_trap(descriptor_t *gdp Line 456  interrupt_intr_or_trap(descriptor_t *gdp
                 rv = parse_selector(&ss_sel, new_ss);                  rv = parse_selector(&ss_sel, new_ss);
                 if (rv < 0) {                  if (rv < 0) {
                         VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", new_ss, rv));                          VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", new_ss, rv));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp);                          EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);
                 }                  }
   
                 /* check privilege level */                  /* check privilege level */
                 if (ss_sel.rpl != intr_sel.desc.dpl) {                  if (ss_sel.rpl != intr_sel.desc.dpl) {
                         VERBOSE(("interrupt: RPL[SS](%d) != DPL[CS](%d)", ss_sel.rpl, intr_sel.desc.dpl));                          VERBOSE(("interrupt: RPL[SS](%d) != DPL[CS](%d)", ss_sel.rpl, intr_sel.desc.dpl));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp);                          EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);
                 }                  }
                 if (ss_sel.desc.dpl != intr_sel.desc.dpl) {                  if (ss_sel.desc.dpl != intr_sel.desc.dpl) {
                         VERBOSE(("interrupt: DPL[SS](%d) != DPL[CS](%d)", ss_sel.desc.dpl, intr_sel.desc.dpl));                          VERBOSE(("interrupt: DPL[SS](%d) != DPL[CS](%d)", ss_sel.desc.dpl, intr_sel.desc.dpl));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp);                          EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);
                 }                  }
   
                 /* check segment type */                  /* check segment type */
                 if (!ss_sel.desc.s) {                  if (!ss_sel.desc.s) {
                         VERBOSE(("interrupt: stack segment is system segment"));                          VERBOSE(("interrupt: stack segment is system segment"));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp);                          EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);
                 }                  }
                 if (ss_sel.desc.u.seg.c) {                  if (ss_sel.desc.u.seg.c) {
                         VERBOSE(("interrupt: stack segment is code segment"));                          VERBOSE(("interrupt: stack segment is code segment"));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp);                          EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);
                 }                  }
                 if (!ss_sel.desc.u.seg.wr) {                  if (!ss_sel.desc.u.seg.wr) {
                         VERBOSE(("interrupt: stack segment is read-only data segment"));                          VERBOSE(("interrupt: stack segment is read-only data segment"));
                         EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp);                          EXCEPTION(TS_EXCEPTION, ss_sel.idx + !softintp);
                 }                  }
   
                 /* not present */                  /* not present */
                 if (selector_is_not_present(&ss_sel)) {                  if (selector_is_not_present(&ss_sel)) {
                         VERBOSE(("interrupt: selector is not present"));                          VERBOSE(("interrupt: selector is not present"));
                         EXCEPTION(SS_EXCEPTION, ss_sel.idx | !softintp);                          EXCEPTION(SS_EXCEPTION, ss_sel.idx + !softintp);
                 }                  }
   
                 /* check stack room size */                  /* check stack room size */
Line 546  interrupt_intr_or_trap(descriptor_t *gdp Line 556  interrupt_intr_or_trap(descriptor_t *gdp
         } else {          } else {
                 if (CPU_STAT_VM86) {                  if (CPU_STAT_VM86) {
                         VERBOSE(("interrupt: VM86"));                          VERBOSE(("interrupt: VM86"));
                         EXCEPTION(GP_EXCEPTION, intr_sel.idx);                          EXCEPTION(GP_EXCEPTION, intr_sel.idx + !softintp);
                 }                  }
                 if (!intr_sel.desc.u.seg.ec && (intr_sel.desc.dpl != CPU_STAT_CPL)) {                  if (!intr_sel.desc.u.seg.ec && (intr_sel.desc.dpl != CPU_STAT_CPL)) {
                         VERBOSE(("interrupt: NON-CONFORMING-CODE-SEGMENT(%s) and DPL[CS](%d) != CPL", intr_sel.desc.u.seg.ec ? "false" : "true", intr_sel.desc.dpl, CPU_STAT_CPL));                          VERBOSE(("interrupt: NON-CONFORMING-CODE-SEGMENT(%s) and DPL[CS](%d) != CPL", intr_sel.desc.u.seg.ec ? "false" : "true", intr_sel.desc.dpl, CPU_STAT_CPL));
                         EXCEPTION(GP_EXCEPTION, intr_sel.idx);                          EXCEPTION(GP_EXCEPTION, intr_sel.idx + !softintp);
                 }                  }
                 VERBOSE(("interrupt: INTRA-PRIVILEGE-LEVEL-INTERRUPT"));                  VERBOSE(("interrupt: INTRA-PRIVILEGE-LEVEL-INTERRUPT"));
   

Removed from v.1.6  
changed lines
  Added in v.1.8


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