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

Diff of /qemu/helper-i386.c

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

revision 1.3 by bellard, Sun Jun 15 19:49:16 2003 UTC revision 1.4 by bellard, Sat Jun 21 13:10:39 2003 UTC
# Line 157  void raise_interrupt(int intno, int is_i Line 157  void raise_interrupt(int intno, int is_i
157          break;          break;
158      }      }
159      dpl = (e2 >> DESC_DPL_SHIFT) & 3;      dpl = (e2 >> DESC_DPL_SHIFT) & 3;
160      cpl = env->segs[R_CS] & 3;      cpl = env->segs[R_CS].selector & 3;
161      /* check privledge if software int */      /* check privledge if software int */
162      if (is_int && dpl < cpl)      if (is_int && dpl < cpl)
163          raise_exception_err(EXCP0D_GPF, intno * 8 + 2);          raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
# Line 176  void raise_interrupt(int intno, int is_i Line 176  void raise_interrupt(int intno, int is_i
176  void raise_interrupt(int intno, int is_int, int error_code,  void raise_interrupt(int intno, int is_int, int error_code,
177                       unsigned int next_eip)                       unsigned int next_eip)
178  {  {
179      SegmentDescriptorTable *dt;      SegmentCache *dt;
180      uint8_t *ptr;      uint8_t *ptr;
181      int dpl, cpl;      int dpl, cpl;
182      uint32_t e2;      uint32_t e2;
# Line 331  void helper_cpuid(void) Line 331  void helper_cpuid(void)
331      }      }
332  }  }
333    
334    static inline void load_seg_cache(SegmentCache *sc, uint32_t e1, uint32_t e2)
335    {
336        sc->base = (void *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
337        sc->limit = (e1 & 0xffff) | (e2 & 0x000f0000);
338        if (e2 & (1 << 23))
339            sc->limit = (sc->limit << 12) | 0xfff;
340        sc->seg_32bit = (e2 >> 22) & 1;
341    }
342    
343    void helper_lldt_T0(void)
344    {
345        int selector;
346        SegmentCache *dt;
347        uint32_t e1, e2;
348        int index;
349        uint8_t *ptr;
350        
351        selector = T0 & 0xffff;
352        if ((selector & 0xfffc) == 0) {
353            /* XXX: NULL selector case: invalid LDT */
354            env->ldt.base = NULL;
355            env->ldt.limit = 0;
356        } else {
357            if (selector & 0x4)
358                raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
359            dt = &env->gdt;
360            index = selector & ~7;
361            if ((index + 7) > dt->limit)
362                raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
363            ptr = dt->base + index;
364            e1 = ldl(ptr);
365            e2 = ldl(ptr + 4);
366            if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2)
367                raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
368            if (!(e2 & DESC_P_MASK))
369                raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
370            load_seg_cache(&env->ldt, e1, e2);
371        }
372        env->ldt.selector = selector;
373    }
374    
375    void helper_ltr_T0(void)
376    {
377        int selector;
378        SegmentCache *dt;
379        uint32_t e1, e2;
380        int index, type;
381        uint8_t *ptr;
382        
383        selector = T0 & 0xffff;
384        if ((selector & 0xfffc) == 0) {
385            /* XXX: NULL selector case: invalid LDT */
386            env->tr.base = NULL;
387            env->tr.limit = 0;
388        } else {
389            if (selector & 0x4)
390                raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
391            dt = &env->gdt;
392            index = selector & ~7;
393            if ((index + 7) > dt->limit)
394                raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
395            ptr = dt->base + index;
396            e1 = ldl(ptr);
397            e2 = ldl(ptr + 4);
398            type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
399            if ((e2 & DESC_S_MASK) ||
400                (type != 2 && type != 9))
401                raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
402            if (!(e2 & DESC_P_MASK))
403                raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
404            load_seg_cache(&env->tr, e1, e2);
405            e2 |= 0x00000200; /* set the busy bit */
406            stl(ptr + 4, e2);
407        }
408        env->tr.selector = selector;
409    }
410    
411  /* only works if protected mode and not VM86 */  /* only works if protected mode and not VM86 */
412  void load_seg(int seg_reg, int selector, unsigned cur_eip)  void load_seg(int seg_reg, int selector, unsigned int cur_eip)
413  {  {
414      SegmentCache *sc;      SegmentCache *sc;
415      SegmentDescriptorTable *dt;      SegmentCache *dt;
416      int index;      int index;
417      uint32_t e1, e2;      uint32_t e1, e2;
418      uint8_t *ptr;      uint8_t *ptr;
419        
420      sc = &env->seg_cache[seg_reg];      sc = &env->segs[seg_reg];
421      if ((selector & 0xfffc) == 0) {      if ((selector & 0xfffc) == 0) {
422          /* null selector case */          /* null selector case */
423          if (seg_reg == R_SS) {          if (seg_reg == R_SS) {
424              EIP = cur_eip;              EIP = cur_eip;
425              raise_exception_err(EXCP0D_GPF, selector & 0xfffc);              raise_exception_err(EXCP0D_GPF, 0);
426          } else {          } else {
427              /* XXX: each access should trigger an exception */              /* XXX: each access should trigger an exception */
428              sc->base = NULL;              sc->base = NULL;
# Line 390  void load_seg(int seg_reg, int selector, Line 467  void load_seg(int seg_reg, int selector,
467              else              else
468                  raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);                  raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
469          }          }
470                    load_seg_cache(sc, e1, e2);
         sc->base = (void *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));  
         sc->limit = (e1 & 0xffff) | (e2 & 0x000f0000);  
         if (e2 & (1 << 23))  
             sc->limit = (sc->limit << 12) | 0xfff;  
         sc->seg_32bit = (e2 >> 22) & 1;  
471  #if 0  #if 0
472          fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx seg_32bit=%d\n",          fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx seg_32bit=%d\n",
473                  selector, (unsigned long)sc->base, sc->limit, sc->seg_32bit);                  selector, (unsigned long)sc->base, sc->limit, sc->seg_32bit);
474  #endif  #endif
475      }      }
476      env->segs[seg_reg] = selector;      sc->selector = selector;
477    }
478    
479    /* protected mode jump */
480    void jmp_seg(int selector, unsigned int new_eip)
481    {
482        SegmentCache sc1;
483        SegmentCache *dt;
484        int index;
485        uint32_t e1, e2, cpl, dpl, rpl;
486        uint8_t *ptr;
487    
488        if ((selector & 0xfffc) == 0) {
489            raise_exception_err(EXCP0D_GPF, 0);
490        }
491    
492        if (selector & 0x4)
493          dt = &env->ldt;
494        else
495          dt = &env->gdt;
496        index = selector & ~7;
497        if ((index + 7) > dt->limit)
498            raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
499        ptr = dt->base + index;
500        e1 = ldl(ptr);
501        e2 = ldl(ptr + 4);
502        cpl = env->segs[R_CS].selector & 3;
503        if (e2 & DESC_S_MASK) {
504            if (!(e2 & DESC_CS_MASK))
505                raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
506            dpl = (e2 >> DESC_DPL_SHIFT) & 3;
507            if (e2 & DESC_CS_MASK) {
508                /* conforming code segment */
509                if (dpl > cpl)
510                    raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
511            } else {
512                /* non conforming code segment */
513                rpl = selector & 3;
514                if (rpl > cpl)
515                    raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
516                if (dpl != cpl)
517                    raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
518            }
519            if (!(e2 & DESC_P_MASK))
520                raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
521            load_seg_cache(&sc1, e1, e2);
522            if (new_eip > sc1.limit)
523                raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
524            env->segs[R_CS] = sc1;
525            env->segs[R_CS].selector = (selector & 0xfffc) | cpl;
526            EIP = new_eip;
527        } else {
528            cpu_abort(env, "jmp to call/task gate not supported 0x%04x:0x%08x",
529                      selector, new_eip);
530        }
531    }
532    
533    /* XXX: do more */
534    void helper_movl_crN_T0(int reg)
535    {
536        switch(reg) {
537        case 0:
538        default:
539            env->cr[0] = reg;
540            break;
541        case 2:
542            env->cr[2] = reg;
543            break;
544        case 3:
545            env->cr[3] = reg;
546            break;
547        case 4:
548            env->cr[4] = reg;
549            break;
550        }
551    }
552    
553    /* XXX: do more */
554    void helper_movl_drN_T0(int reg)
555    {
556        env->dr[reg] = T0;
557  }  }
558    
559  /* rdtsc */  /* rdtsc */
# Line 425  void helper_rdtsc(void) Line 577  void helper_rdtsc(void)
577  void helper_lsl(void)  void helper_lsl(void)
578  {  {
579      unsigned int selector, limit;      unsigned int selector, limit;
580      SegmentDescriptorTable *dt;      SegmentCache *dt;
581      int index;      int index;
582      uint32_t e1, e2;      uint32_t e1, e2;
583      uint8_t *ptr;      uint8_t *ptr;
# Line 452  void helper_lsl(void) Line 604  void helper_lsl(void)
604  void helper_lar(void)  void helper_lar(void)
605  {  {
606      unsigned int selector;      unsigned int selector;
607      SegmentDescriptorTable *dt;      SegmentCache *dt;
608      int index;      int index;
609      uint32_t e2;      uint32_t e2;
610      uint8_t *ptr;      uint8_t *ptr;

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

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