/[qemu]/qemu/target-i386/helper.c
ViewVC logotype

Diff of /qemu/target-i386/helper.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by bellard, Tue Sep 30 20:33:28 2003 UTC revision 1.2 by bellard, Mon Oct 27 21:22:23 2003 UTC
# Line 153  static inline void get_ss_esp_from_tss(u Line 153  static inline void get_ss_esp_from_tss(u
153      if (index + (4 << shift) - 1 > env->tr.limit)      if (index + (4 << shift) - 1 > env->tr.limit)
154          raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);          raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);
155      if (shift == 0) {      if (shift == 0) {
156          *esp_ptr = lduw(env->tr.base + index);          *esp_ptr = lduw_kernel(env->tr.base + index);
157          *ss_ptr = lduw(env->tr.base + index + 2);          *ss_ptr = lduw_kernel(env->tr.base + index + 2);
158      } else {      } else {
159          *esp_ptr = ldl(env->tr.base + index);          *esp_ptr = ldl_kernel(env->tr.base + index);
160          *ss_ptr = lduw(env->tr.base + index + 4);          *ss_ptr = lduw_kernel(env->tr.base + index + 4);
161      }      }
162  }  }
163    
# Line 177  static inline int load_segment(uint32_t Line 177  static inline int load_segment(uint32_t
177      if ((index + 7) > dt->limit)      if ((index + 7) > dt->limit)
178          return -1;          return -1;
179      ptr = dt->base + index;      ptr = dt->base + index;
180      *e1_ptr = ldl(ptr);      *e1_ptr = ldl_kernel(ptr);
181      *e2_ptr = ldl(ptr + 4);      *e2_ptr = ldl_kernel(ptr + 4);
182      return 0;      return 0;
183  }  }
184                                                                            
# Line 226  static void do_interrupt_protected(int i Line 226  static void do_interrupt_protected(int i
226      if (intno * 8 + 7 > dt->limit)      if (intno * 8 + 7 > dt->limit)
227          raise_exception_err(EXCP0D_GPF, intno * 8 + 2);          raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
228      ptr = dt->base + intno * 8;      ptr = dt->base + intno * 8;
229      e1 = ldl(ptr);      e1 = ldl_kernel(ptr);
230      e2 = ldl(ptr + 4);      e2 = ldl_kernel(ptr + 4);
231      /* check gate type */      /* check gate type */
232      type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;      type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
233      switch(type) {      switch(type) {
# Line 344  static void do_interrupt_protected(int i Line 344  static void do_interrupt_protected(int i
344          int old_eflags;          int old_eflags;
345          if (env->eflags & VM_MASK) {          if (env->eflags & VM_MASK) {
346              ssp -= 4;              ssp -= 4;
347              stl(ssp, env->segs[R_GS].selector);              stl_kernel(ssp, env->segs[R_GS].selector);
348              ssp -= 4;              ssp -= 4;
349              stl(ssp, env->segs[R_FS].selector);              stl_kernel(ssp, env->segs[R_FS].selector);
350              ssp -= 4;              ssp -= 4;
351              stl(ssp, env->segs[R_DS].selector);              stl_kernel(ssp, env->segs[R_DS].selector);
352              ssp -= 4;              ssp -= 4;
353              stl(ssp, env->segs[R_ES].selector);              stl_kernel(ssp, env->segs[R_ES].selector);
354          }          }
355          if (new_stack) {          if (new_stack) {
356              ssp -= 4;              ssp -= 4;
357              stl(ssp, old_ss);              stl_kernel(ssp, old_ss);
358              ssp -= 4;              ssp -= 4;
359              stl(ssp, old_esp);              stl_kernel(ssp, old_esp);
360          }          }
361          ssp -= 4;          ssp -= 4;
362          old_eflags = compute_eflags();          old_eflags = compute_eflags();
363          stl(ssp, old_eflags);          stl_kernel(ssp, old_eflags);
364          ssp -= 4;          ssp -= 4;
365          stl(ssp, old_cs);          stl_kernel(ssp, old_cs);
366          ssp -= 4;          ssp -= 4;
367          stl(ssp, old_eip);          stl_kernel(ssp, old_eip);
368          if (has_error_code) {          if (has_error_code) {
369              ssp -= 4;              ssp -= 4;
370              stl(ssp, error_code);              stl_kernel(ssp, error_code);
371          }          }
372      } else {      } else {
373          if (new_stack) {          if (new_stack) {
374              ssp -= 2;              ssp -= 2;
375              stw(ssp, old_ss);              stw_kernel(ssp, old_ss);
376              ssp -= 2;              ssp -= 2;
377              stw(ssp, old_esp);              stw_kernel(ssp, old_esp);
378          }          }
379          ssp -= 2;          ssp -= 2;
380          stw(ssp, compute_eflags());          stw_kernel(ssp, compute_eflags());
381          ssp -= 2;          ssp -= 2;
382          stw(ssp, old_cs);          stw_kernel(ssp, old_cs);
383          ssp -= 2;          ssp -= 2;
384          stw(ssp, old_eip);          stw_kernel(ssp, old_eip);
385          if (has_error_code) {          if (has_error_code) {
386              ssp -= 2;              ssp -= 2;
387              stw(ssp, error_code);              stw_kernel(ssp, error_code);
388          }          }
389      }      }
390            
# Line 410  static void do_interrupt_real(int intno, Line 410  static void do_interrupt_real(int intno,
410      if (intno * 4 + 3 > dt->limit)      if (intno * 4 + 3 > dt->limit)
411          raise_exception_err(EXCP0D_GPF, intno * 8 + 2);          raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
412      ptr = dt->base + intno * 4;      ptr = dt->base + intno * 4;
413      offset = lduw(ptr);      offset = lduw_kernel(ptr);
414      selector = lduw(ptr + 2);      selector = lduw_kernel(ptr + 2);
415      esp = ESP;      esp = ESP;
416      ssp = env->segs[R_SS].base;      ssp = env->segs[R_SS].base;
417      if (is_int)      if (is_int)
# Line 420  static void do_interrupt_real(int intno, Line 420  static void do_interrupt_real(int intno,
420          old_eip = env->eip;          old_eip = env->eip;
421      old_cs = env->segs[R_CS].selector;      old_cs = env->segs[R_CS].selector;
422      esp -= 2;      esp -= 2;
423      stw(ssp + (esp & 0xffff), compute_eflags());      stw_kernel(ssp + (esp & 0xffff), compute_eflags());
424      esp -= 2;      esp -= 2;
425      stw(ssp + (esp & 0xffff), old_cs);      stw_kernel(ssp + (esp & 0xffff), old_cs);
426      esp -= 2;      esp -= 2;
427      stw(ssp + (esp & 0xffff), old_eip);      stw_kernel(ssp + (esp & 0xffff), old_eip);
428            
429      /* update processor state */      /* update processor state */
430      ESP = (ESP & ~0xffff) | (esp & 0xffff);      ESP = (ESP & ~0xffff) | (esp & 0xffff);
# Line 445  void do_interrupt_user(int intno, int is Line 445  void do_interrupt_user(int intno, int is
445    
446      dt = &env->idt;      dt = &env->idt;
447      ptr = dt->base + (intno * 8);      ptr = dt->base + (intno * 8);
448      e2 = ldl(ptr + 4);      e2 = ldl_kernel(ptr + 4);
449            
450      dpl = (e2 >> DESC_DPL_SHIFT) & 3;      dpl = (e2 >> DESC_DPL_SHIFT) & 3;
451      cpl = env->hflags & HF_CPL_MASK;      cpl = env->hflags & HF_CPL_MASK;
# Line 651  void helper_lldt_T0(void) Line 651  void helper_lldt_T0(void)
651          if ((index + 7) > dt->limit)          if ((index + 7) > dt->limit)
652              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
653          ptr = dt->base + index;          ptr = dt->base + index;
654          e1 = ldl(ptr);          e1 = ldl_kernel(ptr);
655          e2 = ldl(ptr + 4);          e2 = ldl_kernel(ptr + 4);
656          if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2)          if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2)
657              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
658          if (!(e2 & DESC_P_MASK))          if (!(e2 & DESC_P_MASK))
# Line 684  void helper_ltr_T0(void) Line 684  void helper_ltr_T0(void)
684          if ((index + 7) > dt->limit)          if ((index + 7) > dt->limit)
685              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
686          ptr = dt->base + index;          ptr = dt->base + index;
687          e1 = ldl(ptr);          e1 = ldl_kernel(ptr);
688          e2 = ldl(ptr + 4);          e2 = ldl_kernel(ptr + 4);
689          type = (e2 >> DESC_TYPE_SHIFT) & 0xf;          type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
690          if ((e2 & DESC_S_MASK) ||          if ((e2 & DESC_S_MASK) ||
691              (type != 2 && type != 9))              (type != 2 && type != 9))
# Line 694  void helper_ltr_T0(void) Line 694  void helper_ltr_T0(void)
694              raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);              raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
695          load_seg_cache_raw_dt(&env->tr, e1, e2);          load_seg_cache_raw_dt(&env->tr, e1, e2);
696          e2 |= 0x00000200; /* set the busy bit */          e2 |= 0x00000200; /* set the busy bit */
697          stl(ptr + 4, e2);          stl_kernel(ptr + 4, e2);
698      }      }
699      env->tr.selector = selector;      env->tr.selector = selector;
700  }  }
# Line 813  void helper_lcall_real_T0_T1(int shift, Line 813  void helper_lcall_real_T0_T1(int shift,
813      ssp = env->segs[R_SS].base;      ssp = env->segs[R_SS].base;
814      if (shift) {      if (shift) {
815          esp -= 4;          esp -= 4;
816          stl(ssp + (esp & esp_mask), env->segs[R_CS].selector);          stl_kernel(ssp + (esp & esp_mask), env->segs[R_CS].selector);
817          esp -= 4;          esp -= 4;
818          stl(ssp + (esp & esp_mask), next_eip);          stl_kernel(ssp + (esp & esp_mask), next_eip);
819      } else {      } else {
820          esp -= 2;          esp -= 2;
821          stw(ssp + (esp & esp_mask), env->segs[R_CS].selector);          stw_kernel(ssp + (esp & esp_mask), env->segs[R_CS].selector);
822          esp -= 2;          esp -= 2;
823          stw(ssp + (esp & esp_mask), next_eip);          stw_kernel(ssp + (esp & esp_mask), next_eip);
824      }      }
825    
826      if (!(env->segs[R_SS].flags & DESC_B_MASK))      if (!(env->segs[R_SS].flags & DESC_B_MASK))
# Line 873  void helper_lcall_protected_T0_T1(int sh Line 873  void helper_lcall_protected_T0_T1(int sh
873          ssp = env->segs[R_SS].base + sp;          ssp = env->segs[R_SS].base + sp;
874          if (shift) {          if (shift) {
875              ssp -= 4;              ssp -= 4;
876              stl(ssp, env->segs[R_CS].selector);              stl_kernel(ssp, env->segs[R_CS].selector);
877              ssp -= 4;              ssp -= 4;
878              stl(ssp, next_eip);              stl_kernel(ssp, next_eip);
879          } else {          } else {
880              ssp -= 2;              ssp -= 2;
881              stw(ssp, env->segs[R_CS].selector);              stw_kernel(ssp, env->segs[R_CS].selector);
882              ssp -= 2;              ssp -= 2;
883              stw(ssp, next_eip);              stw_kernel(ssp, next_eip);
884          }          }
885          sp -= (4 << shift);          sp -= (4 << shift);
886                    
# Line 975  void helper_lcall_protected_T0_T1(int sh Line 975  void helper_lcall_protected_T0_T1(int sh
975              ssp = env->segs[R_SS].base + sp;              ssp = env->segs[R_SS].base + sp;
976              if (shift) {              if (shift) {
977                  ssp -= 4;                  ssp -= 4;
978                  stl(ssp, old_ss);                  stl_kernel(ssp, old_ss);
979                  ssp -= 4;                  ssp -= 4;
980                  stl(ssp, old_esp);                  stl_kernel(ssp, old_esp);
981                  ssp -= 4 * param_count;                  ssp -= 4 * param_count;
982                  for(i = 0; i < param_count; i++) {                  for(i = 0; i < param_count; i++) {
983                      val = ldl(old_ssp + i * 4);                      val = ldl_kernel(old_ssp + i * 4);
984                      stl(ssp + i * 4, val);                      stl_kernel(ssp + i * 4, val);
985                  }                  }
986              } else {              } else {
987                  ssp -= 2;                  ssp -= 2;
988                  stw(ssp, old_ss);                  stw_kernel(ssp, old_ss);
989                  ssp -= 2;                  ssp -= 2;
990                  stw(ssp, old_esp);                  stw_kernel(ssp, old_esp);
991                  ssp -= 2 * param_count;                  ssp -= 2 * param_count;
992                  for(i = 0; i < param_count; i++) {                  for(i = 0; i < param_count; i++) {
993                      val = lduw(old_ssp + i * 2);                      val = lduw_kernel(old_ssp + i * 2);
994                      stw(ssp + i * 2, val);                      stw_kernel(ssp + i * 2, val);
995                  }                  }
996              }              }
997          } else {          } else {
# Line 1004  void helper_lcall_protected_T0_T1(int sh Line 1004  void helper_lcall_protected_T0_T1(int sh
1004    
1005          if (shift) {          if (shift) {
1006              ssp -= 4;              ssp -= 4;
1007              stl(ssp, env->segs[R_CS].selector);              stl_kernel(ssp, env->segs[R_CS].selector);
1008              ssp -= 4;              ssp -= 4;
1009              stl(ssp, next_eip);              stl_kernel(ssp, next_eip);
1010          } else {          } else {
1011              ssp -= 2;              ssp -= 2;
1012              stw(ssp, env->segs[R_CS].selector);              stw_kernel(ssp, env->segs[R_CS].selector);
1013              ssp -= 2;              ssp -= 2;
1014              stw(ssp, next_eip);              stw_kernel(ssp, next_eip);
1015          }          }
1016    
1017          sp -= push_size;          sp -= push_size;
# Line 1042  void helper_iret_real(int shift) Line 1042  void helper_iret_real(int shift)
1042      ssp = env->segs[R_SS].base + sp;      ssp = env->segs[R_SS].base + sp;
1043      if (shift == 1) {      if (shift == 1) {
1044          /* 32 bits */          /* 32 bits */
1045          new_eflags = ldl(ssp + 8);          new_eflags = ldl_kernel(ssp + 8);
1046          new_cs = ldl(ssp + 4) & 0xffff;          new_cs = ldl_kernel(ssp + 4) & 0xffff;
1047          new_eip = ldl(ssp) & 0xffff;          new_eip = ldl_kernel(ssp) & 0xffff;
1048      } else {      } else {
1049          /* 16 bits */          /* 16 bits */
1050          new_eflags = lduw(ssp + 4);          new_eflags = lduw_kernel(ssp + 4);
1051          new_cs = lduw(ssp + 2);          new_cs = lduw_kernel(ssp + 2);
1052          new_eip = lduw(ssp);          new_eip = lduw_kernel(ssp);
1053      }      }
1054      new_esp = sp + (6 << shift);      new_esp = sp + (6 << shift);
1055      ESP = (ESP & 0xffff0000) |      ESP = (ESP & 0xffff0000) |
# Line 1078  static inline void helper_ret_protected( Line 1078  static inline void helper_ret_protected(
1078      if (shift == 1) {      if (shift == 1) {
1079          /* 32 bits */          /* 32 bits */
1080          if (is_iret)          if (is_iret)
1081              new_eflags = ldl(ssp + 8);              new_eflags = ldl_kernel(ssp + 8);
1082          new_cs = ldl(ssp + 4) & 0xffff;          new_cs = ldl_kernel(ssp + 4) & 0xffff;
1083          new_eip = ldl(ssp);          new_eip = ldl_kernel(ssp);
1084          if (is_iret && (new_eflags & VM_MASK))          if (is_iret && (new_eflags & VM_MASK))
1085              goto return_to_vm86;              goto return_to_vm86;
1086      } else {      } else {
1087          /* 16 bits */          /* 16 bits */
1088          if (is_iret)          if (is_iret)
1089              new_eflags = lduw(ssp + 4);              new_eflags = lduw_kernel(ssp + 4);
1090          new_cs = lduw(ssp + 2);          new_cs = lduw_kernel(ssp + 2);
1091          new_eip = lduw(ssp);          new_eip = lduw_kernel(ssp);
1092      }      }
1093      if ((new_cs & 0xfffc) == 0)      if ((new_cs & 0xfffc) == 0)
1094          raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);          raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
# Line 1124  static inline void helper_ret_protected( Line 1124  static inline void helper_ret_protected(
1124          ssp += (4 << shift) + ((2 * is_iret) << shift) + addend;          ssp += (4 << shift) + ((2 * is_iret) << shift) + addend;
1125          if (shift == 1) {          if (shift == 1) {
1126              /* 32 bits */              /* 32 bits */
1127              new_esp = ldl(ssp);              new_esp = ldl_kernel(ssp);
1128              new_ss = ldl(ssp + 4) & 0xffff;              new_ss = ldl_kernel(ssp + 4) & 0xffff;
1129          } else {          } else {
1130              /* 16 bits */              /* 16 bits */
1131              new_esp = lduw(ssp);              new_esp = lduw_kernel(ssp);
1132              new_ss = lduw(ssp + 2);              new_ss = lduw_kernel(ssp + 2);
1133          }          }
1134                    
1135          if ((new_ss & 3) != rpl)          if ((new_ss & 3) != rpl)
# Line 1175  static inline void helper_ret_protected( Line 1175  static inline void helper_ret_protected(
1175      return;      return;
1176    
1177   return_to_vm86:   return_to_vm86:
1178      new_esp = ldl(ssp + 12);      new_esp = ldl_kernel(ssp + 12);
1179      new_ss = ldl(ssp + 16);      new_ss = ldl_kernel(ssp + 16);
1180      new_es = ldl(ssp + 20);      new_es = ldl_kernel(ssp + 20);
1181      new_ds = ldl(ssp + 24);      new_ds = ldl_kernel(ssp + 24);
1182      new_fs = ldl(ssp + 28);      new_fs = ldl_kernel(ssp + 28);
1183      new_gs = ldl(ssp + 32);      new_gs = ldl_kernel(ssp + 32);
1184            
1185      /* modify processor state */      /* modify processor state */
1186      load_eflags(new_eflags, FL_UPDATE_CPL0_MASK | VM_MASK | VIF_MASK | VIP_MASK);      load_eflags(new_eflags, FL_UPDATE_CPL0_MASK | VM_MASK | VIF_MASK | VIP_MASK);
# Line 1770  void helper_frstor(uint8_t *ptr, int dat Line 1770  void helper_frstor(uint8_t *ptr, int dat
1770      }      }
1771  }  }
1772    
1773    #if !defined(CONFIG_USER_ONLY)
1774    
1775    #define MMUSUFFIX _mmu
1776    #define GETPC() (__builtin_return_address(0))
1777    
1778  #define SHIFT 0  #define SHIFT 0
1779  #include "softmmu_template.h"  #include "softmmu_template.h"
1780    
# Line 1782  void helper_frstor(uint8_t *ptr, int dat Line 1787  void helper_frstor(uint8_t *ptr, int dat
1787  #define SHIFT 3  #define SHIFT 3
1788  #include "softmmu_template.h"  #include "softmmu_template.h"
1789    
1790  /* try to fill the TLB and return an exception if error */  #endif
1791  void tlb_fill(unsigned long addr, int is_write, void *retaddr)  
1792    /* try to fill the TLB and return an exception if error. If retaddr is
1793       NULL, it means that the function was called in C code (i.e. not
1794       from generated code or from helper.c) */
1795    /* XXX: fix it to restore all registers */
1796    void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr)
1797  {  {
1798      TranslationBlock *tb;      TranslationBlock *tb;
1799      int ret;      int ret;
1800      unsigned long pc;      unsigned long pc;
1801      ret = cpu_x86_handle_mmu_fault(env, addr, is_write);      CPUX86State *saved_env;
1802    
1803        /* XXX: hack to restore env in all cases, even if not called from
1804           generated code */
1805        saved_env = env;
1806        env = cpu_single_env;
1807        if (is_write && page_unprotect(addr)) {
1808            /* nothing more to do: the page was write protected because
1809               there was code in it. page_unprotect() flushed the code. */
1810        }
1811    
1812        ret = cpu_x86_handle_mmu_fault(env, addr, is_write, is_user, 1);
1813      if (ret) {      if (ret) {
1814          /* now we have a real cpu fault */          if (retaddr) {
1815          pc = (unsigned long)retaddr;              /* now we have a real cpu fault */
1816          tb = tb_find_pc(pc);              pc = (unsigned long)retaddr;
1817          if (tb) {              tb = tb_find_pc(pc);
1818              /* the PC is inside the translated code. It means that we have              if (tb) {
1819                 a virtual CPU fault */                  /* the PC is inside the translated code. It means that we have
1820              cpu_restore_state(tb, env, pc);                     a virtual CPU fault */
1821                    cpu_restore_state(tb, env, pc);
1822                }
1823          }          }
1824          raise_exception_err(EXCP0E_PAGE, env->error_code);          raise_exception_err(EXCP0E_PAGE, env->error_code);
1825      }      }
1826        env = saved_env;
1827  }  }

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

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26