/[guss]/guss/guss/i386/i386-tdep.c
ViewVC logotype

Diff of /guss/guss/i386/i386-tdep.c

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

revision 1.3 by jrydberg, Sun Sep 7 15:40:06 2003 UTC revision 1.4 by jrydberg, Sun Sep 14 19:12:35 2003 UTC
# Line 63  struct i386_segment_desc Line 63  struct i386_segment_desc
63  #define ACC_DATA_EW       0x16          /* data, expand-down,  #define ACC_DATA_EW       0x16          /* data, expand-down,
64                                             writable */                                             writable */
65    
66    #define ACC_TYPE_SYSTEM   0x0f
67  #define ACC_LDT           0x02          /* LDT */  #define ACC_LDT           0x02          /* LDT */
68  #define ACC_CALL_GATE_16  0x04          /* 16-bit call gate */  #define ACC_CALL_GATE_16  0x04          /* 16-bit call gate */
69  #define ACC_TASK_GATE     0x05          /* task gate */  #define ACC_TASK_GATE     0x05          /* task gate */
70  #define ACC_INTR_GATE_16  0x06  #define ACC_INTR_GATE_16  0x06
71  #define ACC_TRAP_GATE_16  0x07  #define ACC_TRAP_GATE_16  0x07
72  #define ACC_TSS           0x09          /* task segment */  #define ACC_TSS           0x09          /* task segment */
73    #define ACC_TSS_16        0x01
74  #define ACC_CALL_GATE     0x0c          /* call gate */  #define ACC_CALL_GATE     0x0c          /* call gate */
75  #define ACC_INTR_GATE     0x0e          /* interrupt gate */  #define ACC_INTR_GATE     0x0e          /* interrupt gate */
76  #define ACC_TRAP_GATE     0x0f          /* trap gate */  #define ACC_TRAP_GATE     0x0f          /* trap gate */
# Line 177  unpack_segment (struct unpacked_segment Line 179  unpack_segment (struct unpacked_segment
179    us->limit = sd->limit_low | sd->limit_high << 16;    us->limit = sd->limit_low | sd->limit_high << 16;
180    if (sd->granularity & 8)    if (sd->granularity & 8)
181      us->limit = (us->limit << 12) | 0xfff;      us->limit = (us->limit << 12) | 0xfff;
   dprintf ("unpack segment: gran = %x\n", sd->granularity);  
182    us->is_32bit = (sd->granularity & 4 ? 1 : 0);    us->is_32bit = (sd->granularity & 4 ? 1 : 0);
183      us->flags = sd->access;
184  }  }
185    
186  /* Load segment with SELECTOR.  SEGNO is the segment that  /* Load segment with SELECTOR.  SEGNO is the segment that
# Line 256  i386_lldt (struct processor *current_cpu Line 258  i386_lldt (struct processor *current_cpu
258      {      {
259        CPU (ldt.base) = 0;        CPU (ldt.base) = 0;
260        CPU (ldt.limit) = 0;        CPU (ldt.limit) = 0;
261          CPU (ldt.flags) = 0;
262      }      }
263    else    else
264      {      {
# Line 282  i386_ltr (struct processor *current_cpu, Line 285  i386_ltr (struct processor *current_cpu,
285    
286    if ((selector & 0xfffc) == 0)    if ((selector & 0xfffc) == 0)
287      {      {
288        CPU (ldt.base) = 0;        CPU (tr.base) = 0;
289        CPU (ldt.limit) = 0;        CPU (tr.limit) = 0;
290          CPU (tr.flags) = 0;
291      }      }
292    else    else
293      {      {
# Line 298  i386_ltr (struct processor *current_cpu, Line 302  i386_ltr (struct processor *current_cpu,
302    CPU (tr.selector) = selector;    CPU (tr.selector) = selector;
303  }  }
304    
305    /* Get stack segment selector and stack pointer for DPL from
306       the TSS.  Returns nonzero if exception was raised.  */
307    
308    static int
309    get_sp_from_tss (struct processor *current_cpu, UWI *ssp,
310                     UWI *spp, int dpl)
311    {
312      struct unpacked_segment *tr = &CPU (tr);
313      ADDR index;
314    
315      if ((tr->flags & ACC_P) == 0
316          || (tr->flags & ACC_TYPE_USER) != 0
317          || ((tr->flags & ACC_TYPE_SYSTEM) != ACC_TSS
318              && (tr->flags & ACC_TYPE_SYSTEM) != ACC_TSS_16))
319        {
320          internal_error (__FILE__, __LINE__, "FIXME: invalid tss");
321        }
322      if ((tr->flags & ACC_TYPE_SYSTEM) == ACC_TSS)
323        {
324          index = tr->base + (dpl * 8 + 4);
325          if ((dpl * 8 + 4) + 8 - 1 > tr->limit)
326            {
327              i386_raise_exception (current_cpu, EXC_TS,
328                                    tr->selector & 0xfffc, 0, 0);
329              return 1;
330            }
331          *spp = GETMEMUSI (index);
332          *ssp = GETMEMUSI (index + 4) & 0xffff;
333        }
334      else /* 16-bit */
335        {
336          index = tr->base + (dpl * 4 + 2);
337          if ((dpl * 4 + 2) + 4 - 1 > tr->limit)
338            {
339              i386_raise_exception (current_cpu, EXC_TS,
340                                    tr->selector & 0xfffc, 0, 0);
341              return 1;
342            }
343          *spp = GETMEMUHI (index);
344          *ssp = GETMEMUHI (index + 2);
345        }
346      return 0;
347    }
348    
349    
350  /* Return full value of the EFLAGS register, for CURRENT_CPU. */  /* Return full value of the EFLAGS register, for CURRENT_CPU. */
351    
352  UWI  UWI
353  i386_compute_eflags (struct processor *current_cpu)  i386_compute_eflags (struct processor *current_cpu)
354  {  {
355    return (CPU (hw_eflags) | cctable[CPU (cc_op)].compute_all ()    return (CPU (hw_eflags)
356              | (cctable[CPU (cc_op)].compute_all () & EFL_CC)
357            | (CPU (hw_dflag) & EFL_DF));            | (CPU (hw_dflag) & EFL_DF));
358  }  }
359    
# Line 480  i386_load_cr3 (struct processor *current Line 530  i386_load_cr3 (struct processor *current
530    CPU (hw_cr[3]) = value;    CPU (hw_cr[3]) = value;
531    CPU (pgdir) = core_address_from_physical_address (CPU_NODE (current_cpu),    CPU (pgdir) = core_address_from_physical_address (CPU_NODE (current_cpu),
532                                                      value & ~0xfff);                                                      value & ~0xfff);
533      mtcache_flush_all (&mtcache_data_read);
534      mtcache_flush_all (&mtcache_data_write);
535  }  }
536    
537  void  void
# Line 606  void Line 658  void
658  i386_protected_mode_ret (struct processor *current_cpu,  i386_protected_mode_ret (struct processor *current_cpu,
659                           int dflag, int is_iret, int addend)                           int dflag, int is_iret, int addend)
660  {  {
661    struct i386_segment_desc sd;    struct i386_segment_desc sd, stackd;
662    UWI new_eflags = 0, new_cs;    UWI new_eflags = 0, new_cs, new_ss;
663    int cpl, rpl;    int cpl, rpl;
664    ADDR sp, stackp, new_sp = 0;    ADDR sp, stackp, new_sp = 0;
665    IADDR new_pc;    IADDR new_pc;
# Line 617  i386_protected_mode_ret (struct processo Line 669  i386_protected_mode_ret (struct processo
669      sp &= 0xffff;      sp &= 0xffff;
670    stackp = CPU (segs[ss_regno].base) + sp;    stackp = CPU (segs[ss_regno].base) + sp;
671    
   
672    if (dflag)    if (dflag)
673      {      {
674        if (is_iret)        if (is_iret)
# Line 635  i386_protected_mode_ret (struct processo Line 686  i386_protected_mode_ret (struct processo
686        new_pc = GETMEMUHI (stackp);        new_pc = GETMEMUHI (stackp);
687      }      }
688    
689      /* FIXME nt flag */
690    
691    if ((new_cs & 0xfffc) == 0    if ((new_cs & 0xfffc) == 0
692        || fetch_segment (current_cpu, NULL, new_cs, &sd)        || fetch_segment (current_cpu, NULL, new_cs, &sd)
693        || (sd.access & ACC_P) == 0        || (sd.access & ACC_P) == 0
# Line 654  i386_protected_mode_ret (struct processo Line 707  i386_protected_mode_ret (struct processo
707      }      }
708    else    else
709      {      {
710        ABORT ();        /* Return to a different priviledge level */
711    
712          if (dflag)
713            {
714              stackp += 8 + addend;
715              if (is_iret)
716                stackp += 4;
717            }
718          else
719            {
720              stackp += 4 + addend;
721              if (is_iret)
722                stackp += 2;
723            }
724          if (dflag)
725            {
726              new_ss = GETMEMUSI (stackp + 4) & 0xffff;
727              new_sp = GETMEMUSI (stackp);
728            }
729          else
730            {
731              new_ss = GETMEMUHI (stackp + 2);
732              new_sp = GETMEMUHI (stackp);
733            }
734    
735          if (new_ss == 0
736              /* If stack segment RPL isn't the same as RPL */
737              || ((new_ss & 3) != rpl)
738              /* If stack segment selector is not within limits */
739              || fetch_segment (current_cpu, NULL, new_ss, &stackd)
740              /* The stack segment must be present */
741              || ((stackd.access & ACC_P) == 0)
742              /* If stack segment DPL isn't the same as RPL */
743              || ((stackd.access >> 5) & 3) != rpl
744              /* If stack segment isn't a writeable data segment */
745              || ((stackd.access & ACC_TYPE) != ACC_DATA_W
746                  && (stackd.access & ACC_TYPE) != ACC_DATA_EW))
747            {
748              i386_raise_exception (current_cpu, EXC_GP, new_ss, 0, 0);
749              return;
750            }
751          unpack_segment (&CPU (segs[ss_regno]), &stackd);
752          CPU (segs[ss_regno].selector) = new_ss;
753          unpack_segment (&CPU (segs[cs_regno]), &sd);
754          CPU (segs[cs_regno].selector) = new_cs;
755    
756          /* Recalculate state since both the code and stack segment
757             has been changed.  */
758          CPU (state) = i386_get_state (current_cpu);
759      }      }
760        
761    if (CPU (segs[ss_regno].is_32bit))    if (CPU (segs[ss_regno].is_32bit))
# Line 693  i386_protected_mode_interrupt (struct pr Line 794  i386_protected_mode_interrupt (struct pr
794                                 IADDR next_pc, int is_hw_intr)                                 IADDR next_pc, int is_hw_intr)
795  {  {
796    struct i386_callgate_desc sd;    struct i386_callgate_desc sd;
797    struct i386_segment_desc seg;    struct i386_segment_desc seg, stackd;
798    int dpl, selector, cpl;    UWI save_ss, save_cs, new_cs, new_ss, save_sp, new_sp;
799    UWI save_pc, save_cs, save_eflags;    int with_error = 0, new_stack;
800    int has_error_code, new_stack, push_size, not_16bit;    ADDR stackp, save_pc;
801    ADDR stackp, sp;    int dpl, cpl;
802    
803      /* FIXME these are here to shut up the compiler */
804      save_ss = 0;
805      save_sp = 0;
806      new_stack = 0;
807    
808      /* Put the processor in pseudo-supervisor mode, since we need
809         to access supervisor-only available data structures such as
810         the TSS, GDT and LDT.  */
811    
812      CPU (pseudo_supervisor_p) = 1;
813    
814    /* If the number of unresolved exceptions equals three,    /* If the number of unresolved exceptions equals three,
815       take a trippe-fault.  FIXME.  */       take a trippe-fault.  FIXME.  */
   
816    if (CPU (unresolved_exceptions)++ == 3)    if (CPU (unresolved_exceptions)++ == 3)
817      {      {
818        ABORT ();        ABORT ();
819      }      }
820    
821      /* If (intno * 8) + 7 is not within the IDT limits, take
822         general protection fault with the IDT bit set.  */
823    if (fetch_callgate (current_cpu, & CPU (idt), intno*8, &sd))    if (fetch_callgate (current_cpu, & CPU (idt), intno*8, &sd))
824      {      {
825        take_gpf:
826        i386_raise_exception (current_cpu, EXC_GP, (intno * 8) + 2, 0, 0);        i386_raise_exception (current_cpu, EXC_GP, (intno * 8) + 2, 0, 0);
827        return;        return;
828      }      }
829    
830      /* If the selected IDT descriptor is not a interrupt-, trap-, or
831         task-gate take general protection fault.  */
832    
833    switch (sd.access & ACC_TYPE)    switch (sd.access & ACC_TYPE)
834      {      {
835      case ACC_TASK_GATE:      case ACC_TASK_GATE:
836          /* FIXME jrydberg: implement task gates */
837        internal_abort (__FILE__, __LINE__, "task gate not supported");        internal_abort (__FILE__, __LINE__, "task gate not supported");
838      case ACC_INTR_GATE_16:      case ACC_INTR_GATE_16:
839      case ACC_INTR_GATE:      case ACC_INTR_GATE:
# Line 722  i386_protected_mode_interrupt (struct pr Line 841  i386_protected_mode_interrupt (struct pr
841      case ACC_TRAP_GATE:      case ACC_TRAP_GATE:
842        break;        break;
843      default:      default:
844        i386_raise_exception (current_cpu, EXC_GP, (intno * 8) + 2, 0, 0);        goto take_gpf;
       return;  
845      }      }
846    
847      /* Values that should be saved in the interrupt frame.  */
848      save_cs = CPU (segs[cs_regno].selector);
849      save_pc = (is_intr ? next_pc : HW_PC_GET (current_cpu));
850      
851      /* ??? DPL */
852        
853    dpl = (sd.access >> 5) & 3;    dpl = (sd.access >> 5) & 3;
854    cpl = /* ??? */ CPU (segs[cs_regno].selector) & 3;    cpl = /* ??? */ CPU (segs[cs_regno].selector) & 3;
855    
856    if (is_intr && dpl < cpl              /* check priviledge */    /* If the interrupt is generated by a software action (int N, into, int 3)
857        || !(sd.access & 0x80))           /* present */       then take GP exception if DPL is less than CPL.  */
858      if (is_intr && is_hw_intr == 0 && dpl < cpl)
859      {      {
       printf ("sd.access = %x\n", sd.access);  
860        i386_raise_exception (current_cpu, EXC_GP, (intno * 8) + 2, 0, 0);        i386_raise_exception (current_cpu, EXC_GP, (intno * 8) + 2, 0, 0);
861        return;        return;
862      }      }
863    if ((sd.selector & 0xfffc) == 0)  
864      /* If gate is not present, take NP exception. */
865      if ((sd.access & ACC_P) == 0)
866      {      {
867        i386_raise_exception (current_cpu, EXC_GP, 0, 0, 0);        i386_raise_exception (current_cpu, EXC_NP, (intno * 8) + 2, 0, 0);
868        return;        return;
869      }      }
870    if (fetch_segment (current_cpu, NULL, sd.selector, &seg)    new_cs = sd.selector;
871  #if 0  
872        || !(seg.access & (1 << 12))    /* Read segment selector for trap or interrupt gate.
873        || !(seg.access & (1 << 11))       If segment selector for code segment is null, take GP */
874  #endif    if ((new_cs & 0xfffc) == 0)
       || (dpl = (seg.access >> 5) & 3) > cpl  
       || !(seg.access & ACC_P))  
875      {      {
876        i386_raise_exception (current_cpu, EXC_GP, sd.selector & 0xfffc, 0, 0);        i386_raise_exception (current_cpu, EXC_GP, 0, 0, 0);
877        return;        return;
878      }      }
879    if (dpl < cpl) /* to inner */  
880      {    /* If selector is outside limits, or if segment is not a code
881        new_stack = 0;       segment, take a general protectin fault.  */
882        /* get ss_esp from tss */    if (fetch_segment (current_cpu, NULL, new_cs, &seg)
883        ABORT ();        || ((seg.access & ACC_TYPE) != ACC_CODE
884      }            && (seg.access & ACC_TYPE) != ACC_CODE_R
885    else if (seg.access & (1 << 12) || dpl == cpl)            && (seg.access & ACC_TYPE) != ACC_CODE_C
886              && (seg.access & ACC_TYPE) != ACC_CODE_CR))
887      {      {
888        new_stack = 0;        /* FIXME is this the correct selector ? */
889          i386_raise_exception (current_cpu, EXC_GP, new_cs & 0xfffc, 0, 0);
890          return;
891      }      }
892    else    /* If segment is not present, take NP exception */
893      if ((seg.access & ACC_P) == 0)
894      {      {
895        i386_raise_exception (current_cpu, EXC_GP, sd.selector & 0xfffc, 0, 0);        /* FIXME is this the correct selector ? */
896          i386_raise_exception (current_cpu, EXC_NP, new_cs & 0xfffc, 0, 0);
897        return;        return;
898      }      }
899    
900    not_16bit = (sd.access & 0x1f) >> 3;    dpl = (seg.access >> 5) & 3;
901    
902      /* If the code segment is non-conforming and the DPL is
903         less than the CPL it can be a inter-priviledge level interrupt */
904    
905      if (((seg.access & ACC_TYPE) == ACC_CODE
906           || (seg.access & ACC_TYPE) == ACC_CODE_R)
907          && dpl < cpl)
908        {
909          if ((CPU (hw_eflags) & EFL_VM) == 0)
910            {
911              /* inter-privilege level interrupt */
912    
913              /* The call to get_sp_from_tss checks so that TSS stack
914                 address is within the TSS limits.  */        
915              if (get_sp_from_tss (current_cpu, &new_ss, &new_sp, dpl))
916                return;
917              if ((new_ss & 0xfffc) == 0)
918                {
919                  i386_raise_exception (current_cpu, EXC_TS, 0, 0, 0);
920                  return;
921                }
922              if ((new_ss & 3) != dpl
923                  /* Check that new_ss is within table limits */
924                  || fetch_segment (current_cpu, NULL, new_ss, &stackd)
925                  /* Stack segment DPL must be same as DPL of code segment */
926                  || (stackd.access >> 5) & 3 != dpl
927                  /* Stack segment must be present */
928                  || (stackd.access & ACC_P) == 0)
929                /* FIXME must also check that the segment has room for
930                   interrupt frame */
931                {
932                  i386_raise_exception (current_cpu, EXC_TS, new_ss & 0xfffc, 0, 0);
933                  return;
934                }
935    
936              /* Save the values of the stack pointer and stack selector
937                 on the new stack.  */
938              save_sp = CPU (hw_gpr[esp_regno]);
939              save_ss = CPU (segs[ss_regno].selector);
940              new_stack = 1;
941            }
942          else
943            {
944              if (dpl != 0)
945                {
946                  i386_raise_exception (current_cpu, EXC_GP,
947                                        new_cs & 0xfffc, 0, 0);
948                  return;
949                }
950              internal_error (__FILE__, __LINE__, "intr vm86 not supp");
951            }
952        }
953      else /* dpl >= cpl */
954        {
955          if (CPU (hw_eflags) & EFL_VM)
956            {
957              i386_raise_exception (current_cpu, EXC_GP,
958                                    new_cs & 0xfffc, 0, 0);
959              return;
960            }
961          if (((seg.access & ACC_TYPE) == ACC_CODE_C
962               || (seg.access & ACC_TYPE) == ACC_CODE_CR)
963              || dpl == cpl)
964            {
965              /* intra-privilege level interrupt */
966              new_sp = CPU (hw_gpr[esp_regno]);
967              new_stack = save_sp = save_ss = 0;
968            }
969          else
970            {
971              i386_raise_exception (current_cpu, EXC_GP,
972                                    new_cs & 0xfffc, 0, 0);
973              return;
974            }
975        }
976    
977    has_error_code = 0;    /* Pushing error code on the stack is only needed if the
978    if (!is_intr && !is_hw_intr)       interrupt is an exception (!is_intr) and the exception number
979         is one of 8, 10, 11, 12, 13, 14 or 17.  */
980      if (is_intr == 0)
981      {      {
982        switch(intno)        switch (intno)
983          {          {
984          case 8: case 10: case 11: case 12:          case 8:  case 10: case 11: case 12:
985          case 13: case 14: case 17:          case 13: case 14: case 17:
986            has_error_code = 1;            with_error = 1;
           break;  
987          }          }
988      }      }
   push_size = 6 + (new_stack ? 4 : 0) + (has_error_code ? 2 : 0);  
 #if 0  
   if (vm86-mode)  
     push_size += 8;  
 #endif  
   if (not_16bit)  
     push_size = push_size << 1;  
989    
990      /* It is important to preserve precise exceptions; Therefor the
991         stack and code segment is not updated until all the data is
992         saved on the stack (every access may case another exception).  */
993    if (new_stack)    if (new_stack)
994      {      {
995        sp = 0;        struct unpacked_segment bal;
996        ABORT ();        unpack_segment (&bal, &stackd);
997          stackp = bal.base + new_sp;
998      }      }
999    else    else
1000      {      {
1001        /* old_sp = old_ss = 0;  */        /* FIXME what if stack segment is 16-bit? */
1002        sp = CPU (hw_gpr[esp_regno]);        stackp = CPU (segs[ss_regno].base) + new_sp;
1003      }      }
   save_pc = (is_intr ? next_pc : HW_PC_GET (current_cpu));  
   save_cs = CPU (segs[cs_regno].selector);  
1004    
1005    selector = (sd.selector & ~3) | dpl;    if ((sd.access & 0x1f) >> 3)
   i386_load_segment (current_cpu, cs_regno, selector);  
   /* FIXME set cpl */  
   
   CPU (hw_pc) = (sd.offset_high << 16) | sd.offset_low;  
   
   stackp = CPU (segs[ss_regno].base) + sp;  
   
   if (not_16bit)  
1006      {      {
1007        save_eflags = i386_compute_eflags (current_cpu);        UWI save_eflags = i386_compute_eflags (current_cpu);
1008    
1009          /* The stack segment selector is just two bytes, but
1010             it is padded up to four.  */
1011        if (new_stack)        if (new_stack)
1012          {          {
1013            ABORT ();            stackp -= 4;
1014              SETMEMUSI (stackp, save_ss);
1015              stackp -= 4;
1016              SETMEMUSI (stackp, save_sp);
1017          }          }
1018        stackp -= 4;        stackp -= 4;
1019        SETMEMUSI (stackp, save_eflags);        SETMEMUSI (stackp, save_eflags);
# Line 823  i386_protected_mode_interrupt (struct pr Line 1021  i386_protected_mode_interrupt (struct pr
1021        SETMEMUSI (stackp, save_cs);        SETMEMUSI (stackp, save_cs);
1022        stackp -= 4;        stackp -= 4;
1023        SETMEMUSI (stackp, save_pc);        SETMEMUSI (stackp, save_pc);
1024        if (has_error_code)  
1025          if (with_error)
1026          {          {
1027            stackp -= 4;            stackp -= 4;
1028            SETMEMUSI (stackp, error_code);            SETMEMUSI (stackp, error_code);
1029          }          }
1030          /* Update the stack pointer so that the value is
1031             correct when the register is set.  */
1032          new_sp = new_sp - 12 - ((new_stack ? 8 : 0)
1033                                  + (with_error ? 4 : 0));
1034      }      }
1035    else    else
1036      {      {
# Line 835  i386_protected_mode_interrupt (struct pr Line 1038  i386_protected_mode_interrupt (struct pr
1038    
1039        if (new_stack)        if (new_stack)
1040          {          {
1041            ABORT ();            stackp -= 2;
1042              SETMEMUHI (stackp, save_ss);
1043              stackp -= 2;
1044              SETMEMUHI (stackp, save_sp);
1045          }          }
1046        stackp -= 2;        stackp -= 2;
1047        SETMEMUHI (stackp, save_eflags);        SETMEMUHI (stackp, save_eflags);
# Line 843  i386_protected_mode_interrupt (struct pr Line 1049  i386_protected_mode_interrupt (struct pr
1049        SETMEMUHI (stackp, save_cs);        SETMEMUHI (stackp, save_cs);
1050        stackp -= 2;        stackp -= 2;
1051        SETMEMUHI (stackp, save_pc);        SETMEMUHI (stackp, save_pc);
1052        if (has_error_code)  
1053          if (with_error)
1054          {          {
1055            stackp -= 2;            stackp -= 2;
1056            SETMEMUHI (stackp, error_code);            SETMEMUHI (stackp, error_code);
1057          }          }
1058          /* Update the stack pointer so that the value is
1059             correct when the register is set.  */
1060          new_sp = new_sp - 6 - ((new_stack ? 4 : 0)
1061                                  + (with_error ? 2 : 0));
1062      }      }
1063    
1064    /* FIXME what if 16-bit stack? */    if (new_stack)
1065    CPU (hw_gpr[esp_regno]) = (sp - push_size);      {
1066          unpack_segment (&CPU(segs[ss_regno]), &stackd);
1067          CPU (segs[ss_regno].selector) = new_ss;
1068        }
1069      CPU (hw_gpr[esp_regno]) = new_sp;
1070    
1071      /* Set new program counter.
1072         FIXME jrydberg: is this correct?  no difference between
1073         16-bit or 32-bit gate here.  */
1074      /* FIXME jrydberg: set CPL */
1075      CPU (hw_pc) = (sd.offset_high << 16) | sd.offset_low;
1076      
1077      unpack_segment (&CPU(segs[cs_regno]), &seg);
1078      CPU (segs[cs_regno].selector) = (new_cs & ~3) | dpl;
1079    
1080      /* FIXME jrydberg: it seems as there is no difference if the
1081         stack segment is 16 bits.  verify this */
1082      CPU (hw_gpr[esp_regno]) = new_sp;
1083    
1084    /* interrupt gate clear IF mask */    /* interrupt gate clear IF mask */
1085    if ((sd.access & 1) == 0)    if ((sd.access & 1) == 0)
1086      CPU (hw_eflags) &= ~EFL_IF;      CPU (hw_eflags) &= ~EFL_IF;
1087    CPU (hw_eflags) &= ~(EFL_TF|EFL_VM|EFL_RF|EFL_NT);    CPU (hw_eflags) &= ~(EFL_TF|EFL_VM|EFL_RF|EFL_NT);
1088    
1089      /* The code segment has changed (for sure), and maybe also
1090         the stack segment; there is need to re-calc the state.  */
1091      CPU (state) = i386_get_state (current_cpu);
1092    
1093    /* The exception was resolved.  No chance of a tripple-fault.  */    /* The exception was resolved.  No chance of a tripple-fault.  */
1094    CPU (unresolved_exceptions) = 0;    CPU (unresolved_exceptions) = 0;
1095      /* Put processor back in normal mode */
1096      CPU (pseudo_supervisor_p) = 0;
1097  }  }
1098    
1099    
# Line 1229  i386_dump_temps (struct processor *curre Line 1463  i386_dump_temps (struct processor *curre
1463    fprintf (stderr, "T0 = %#x, T1 = %#x, A0 = %#x\n", t0, t1, t2);    fprintf (stderr, "T0 = %#x, T1 = %#x, A0 = %#x\n", t0, t1, t2);
1464  }  }
1465    
1466    /* Read time stamp counter and store result in %eax:%edx */
1467    
1468    void
1469    i386_rdts (struct processor *current_cpu)
1470    {
1471      unsigned long long val = get_cpu_insn_count (current_cpu);
1472      CPU (hw_gpr[eax_regno]) = (val & 0xffffffff);
1473      CPU (hw_gpr[edx_regno]) = ((val >> 32) & 0xffffffff);
1474    }
1475    
1476  /* FIXME clean up this code */  /* FIXME clean up this code */
1477    
1478  #define CPUID_FP87 (1 << 0)  #define CPUID_FP87 (1 << 0)
# Line 1271  i386_cpuid (struct processor *current_cp Line 1515  i386_cpuid (struct processor *current_cp
1515        CPU (hw_gpr[ecx_regno]) = 0;        CPU (hw_gpr[ecx_regno]) = 0;
1516        CPU (hw_gpr[edx_regno])        CPU (hw_gpr[edx_regno])
1517          = (CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR          = (CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR
1518             | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV);             | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | CPUID_FP87);
1519      }      }
1520  }  }

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