/[gxemul]/trunk/src/cpus/cpu_x86.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/cpus/cpu_x86.c

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

revision 14 by dpavlin, Mon Oct 8 16:18:51 2007 UTC revision 26 by dpavlin, Mon Oct 8 16:20:10 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_x86.c,v 1.3 2005/09/30 14:17:03 debug Exp $   *  $Id: cpu_x86.c,v 1.16 2006/06/24 21:47:23 debug Exp $
29   *   *
30   *  x86 (and amd64) CPU emulation.   *  x86 (and amd64) CPU emulation.
31   *   *
# Line 95  int x86_cpu_new(struct cpu *cpu, struct Line 95  int x86_cpu_new(struct cpu *cpu, struct
95    
96          cpu->cd.x86.model = models[i];          cpu->cd.x86.model = models[i];
97    
98            cpu->translate_v2p = x86_translate_v2p;
99    
100          /*  Initial startup is in 16-bit real mode:  */          /*  Initial startup is in 16-bit real mode:  */
101          cpu->pc = 0xfff0;          cpu->pc = 0xfff0;
102    
# Line 109  int x86_cpu_new(struct cpu *cpu, struct Line 111  int x86_cpu_new(struct cpu *cpu, struct
111          cpu->cd.x86.descr_cache[X86_S_CS].writable = 1;          cpu->cd.x86.descr_cache[X86_S_CS].writable = 1;
112          cpu->cd.x86.descr_cache[X86_S_CS].granularity = 0;          cpu->cd.x86.descr_cache[X86_S_CS].granularity = 0;
113          cpu->cd.x86.s[X86_S_CS] = 0xf000;          cpu->cd.x86.s[X86_S_CS] = 0xf000;
114            cpu->cd.x86.cursegment = X86_S_CS;
115    
116          cpu->cd.x86.idtr = 0;          cpu->cd.x86.idtr = 0;
117          cpu->cd.x86.idtr_limit = 0x3ff;          cpu->cd.x86.idtr_limit = 0x3ff;
118    
         cpu->translate_address = x86_translate_address;  
   
119          cpu->cd.x86.rflags = 0x0002;          cpu->cd.x86.rflags = 0x0002;
120          if (cpu->cd.x86.model.model_number == X86_MODEL_8086)          if (cpu->cd.x86.model.model_number == X86_MODEL_8086)
121                  cpu->cd.x86.rflags |= 0xf000;                  cpu->cd.x86.rflags |= 0xf000;
122    
123            cpu->is_32bit = (cpu->cd.x86.model.model_number < X86_MODEL_AMD64)?
124                1 : 0;
125    
126            if (cpu->is_32bit) {
127                    cpu->update_translation_table = x8632_update_translation_table;
128                    cpu->invalidate_translation_caches =
129                        x8632_invalidate_translation_caches;
130                    cpu->invalidate_code_translation =
131                        x8632_invalidate_code_translation;
132            } else {
133                    cpu->update_translation_table = x86_update_translation_table;
134                    cpu->invalidate_translation_caches =
135                        x86_invalidate_translation_caches;
136                    cpu->invalidate_code_translation =
137                        x86_invalidate_code_translation;
138            }
139    
140          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */
141          if (cpu_id == 0) {          if (cpu_id == 0) {
142                  debug("%s", cpu->name);                  debug("%s", cpu->name);
# Line 150  void x86_cpu_list_available_types(void) Line 168  void x86_cpu_list_available_types(void)
168          while (models[i].model_number != 0) {          while (models[i].model_number != 0) {
169                  debug("%s", models[i].name);                  debug("%s", models[i].name);
170    
171                  for (j=0; j<10-strlen(models[i].name); j++)                  for (j=0; j<10-(int)strlen(models[i].name); j++)
172                          debug(" ");                          debug(" ");
173                  i++;                  i++;
174                  if ((i % 6) == 0 || models[i].name == NULL)                  if ((i % 6) == 0 || models[i].name == NULL)
# Line 171  void x86_cpu_register_dump(struct cpu *c Line 189  void x86_cpu_register_dump(struct cpu *c
189          uint64_t offset;          uint64_t offset;
190          int i, x = cpu->cpu_id;          int i, x = cpu->cpu_id;
191    
192          if (REAL_MODE) {          if (LONG_MODE) {
193                  /*  Real-mode:  */                  /*  64-bit long mode:  */
                 debug("cpu%i:  cs:ip = 0x%04x:0x%04x\n", x,  
                     cpu->cd.x86.s[X86_S_CS], (int)cpu->pc);  
   
                 debug("cpu%i:  ax = 0x%04x  bx = 0x%04x  cx = 0x%04x  dx = "  
                     "0x%04x\n", x,  
                     (int)cpu->cd.x86.r[X86_R_AX], (int)cpu->cd.x86.r[X86_R_BX],  
                     (int)cpu->cd.x86.r[X86_R_CX], (int)cpu->cd.x86.r[X86_R_DX]);  
                 debug("cpu%i:  si = 0x%04x  di = 0x%04x  bp = 0x%04x  sp = "  
                     "0x%04x\n", x,  
                     (int)cpu->cd.x86.r[X86_R_SI], (int)cpu->cd.x86.r[X86_R_DI],  
                     (int)cpu->cd.x86.r[X86_R_BP], (int)cpu->cd.x86.r[X86_R_SP]);  
   
                 debug("cpu%i:  ds = 0x%04x  es = 0x%04x  ss = 0x%04x  flags "  
                     "= 0x%04x\n", x,  
                     (int)cpu->cd.x86.s[X86_S_DS], (int)cpu->cd.x86.s[X86_S_ES],  
                     (int)cpu->cd.x86.s[X86_S_SS], (int)cpu->cd.x86.rflags);  
         } else {  
                 symbol = get_symbol_name(&cpu->machine->symbol_context,  
                     cpu->pc, &offset);  
   
                 debug("cpu%i:  eip=0x", x);  
                 debug("%08x", (int)cpu->pc);  
                 debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");  
   
                 debug("cpu%i:  eax=0x%08x  ebx=0x%08x  ecx=0x%08x  edx="  
                     "0x%08x\n", x,  
                     (int)cpu->cd.x86.r[X86_R_AX], (int)cpu->cd.x86.r[X86_R_BX],  
                     (int)cpu->cd.x86.r[X86_R_CX], (int)cpu->cd.x86.r[X86_R_DX]);  
                 debug("cpu%i:  esi=0x%08x  edi=0x%08x  ebp=0x%08x  esp="  
                     "0x%08x\n", x,  
                     (int)cpu->cd.x86.r[X86_R_SI], (int)cpu->cd.x86.r[X86_R_DI],  
                     (int)cpu->cd.x86.r[X86_R_BP], (int)cpu->cd.x86.r[X86_R_SP]);  
 #if 0  
         } else {  
                 /*  64-bit  */  
194                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
195                      cpu->pc, &offset);                      cpu->pc, &offset);
196    
197                  debug("cpu%i:  rip = 0x", x);                  debug("cpu%i:  rip = 0x%016"PRIx64, x, cpu->pc);
                 debug("%016llx", (long long)cpu->pc);  
198                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
199    
200                  for (i=0; i<N_X86_REGS; i++) {                  for (i=0; i<N_X86_REGS; i++) {
201                          if ((i & 1) == 0)                          if ((i & 1) == 0)
202                                  debug("cpu%i:", x);                                  debug("cpu%i:", x);
203                          debug("  r%s = 0x%016llx", reg_names[i],                          debug("  r%s = 0x%016"PRIx64, reg_names[i],
204                              (long long)cpu->cd.x86.r[i]);                              (uint64_t)cpu->cd.x86.r[i]);
205                          if ((i & 1) == 1)                          if ((i & 1) == 1)
206                                  debug("\n");                                  debug("\n");
207                  }                  }
208  #endif          } else if (REAL_MODE) {
209                    /*  16-bit real-mode:  */
210                    debug("cpu%i:  cs:ip = 0x%04"PRIx16":0x%04"PRIx16"\n", x,
211                        cpu->cd.x86.s[X86_S_CS], (uint16_t)cpu->pc);
212    
213                    debug("cpu%i:  ax = 0x%04"PRIx16"  bx = 0x%04"PRIx16
214                        "  cx = 0x%04"PRIx16"  dx = 0x%04"PRIx16"\n", x,
215                        (uint16_t)cpu->cd.x86.r[X86_R_AX],
216                        (uint16_t)cpu->cd.x86.r[X86_R_BX],
217                        (uint16_t)cpu->cd.x86.r[X86_R_CX],
218                        (uint16_t)cpu->cd.x86.r[X86_R_DX]);
219                    debug("cpu%i:  si = 0x%04"PRIx16"  di = 0x%04"PRIx16
220                        "  bp = 0x%04"PRIx16"  sp = 0x%04"PRIx16"\n", x,
221                        (uint16_t)cpu->cd.x86.r[X86_R_SI],
222                        (uint16_t)cpu->cd.x86.r[X86_R_DI],
223                        (uint16_t)cpu->cd.x86.r[X86_R_BP],
224                        (uint16_t)cpu->cd.x86.r[X86_R_SP]);
225                    debug("cpu%i:  ds = 0x%04"PRIx16"  es = 0x%04"PRIx16
226                        "  ss = 0x%04"PRIx16"  flags = 0x%04"PRIx16"\n", x,
227                        (uint16_t)cpu->cd.x86.s[X86_S_DS],
228                        (uint16_t)cpu->cd.x86.s[X86_S_ES],
229                        (uint16_t)cpu->cd.x86.s[X86_S_SS],
230                        (uint16_t)cpu->cd.x86.rflags);
231            } else {
232                    /*  32-bit protected mode:  */
233                    symbol = get_symbol_name(&cpu->machine->symbol_context,
234                        cpu->pc, &offset);
235    
236                    debug("cpu%i:  eip=0x%08"PRIx32, x, (uint32_t)cpu->pc);
237                    debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
238    
239                    debug("cpu%i:  eax=0x%08"PRIx32"  ebx=0x%08"PRIx32
240                        "  ecx=0x%08"PRIx32"  edx=0x%08"PRIx32"\n", x,
241                        (uint32_t)cpu->cd.x86.r[X86_R_AX],
242                        (uint32_t)cpu->cd.x86.r[X86_R_BX],
243                        (uint32_t)cpu->cd.x86.r[X86_R_CX],
244                        (uint32_t)cpu->cd.x86.r[X86_R_DX]);
245                    debug("cpu%i:  esi=0x%08"PRIx32"  edi=0x%08"PRIx32
246                        "  ebp=0x%08"PRIx32"  esp=0x%08"PRIx32"\n", x,
247                        (uint32_t)cpu->cd.x86.r[X86_R_SI],
248                        (uint32_t)cpu->cd.x86.r[X86_R_DI],
249                        (uint32_t)cpu->cd.x86.r[X86_R_BP],
250                        (uint32_t)cpu->cd.x86.r[X86_R_SP]);
251          }          }
252    
253          if (coprocs != 0) {          if (coprocs != 0) {
# Line 262  void x86_cpu_register_dump(struct cpu *c Line 286  void x86_cpu_register_dump(struct cpu *c
286                      cpu->machine->isa_pic_data.pic2->irq_base);                      cpu->machine->isa_pic_data.pic2->irq_base);
287          } else if (PROTECTED_MODE) {          } else if (PROTECTED_MODE) {
288                  /*  Protected mode:  */                  /*  Protected mode:  */
289                  debug("cpu%i:  cs=0x%04x  ds=0x%04x  es=0x%04x  "                  debug("cpu%i:  cs=0x%04"PRIx16"  ds=0x%04"PRIx16"  es=0x%04"
290                      "fs=0x%04x  gs=0x%04x  ss=0x%04x\n", x,                      PRIx16"  fs=0x%04"PRIx16"  gs=0x%04"PRIx16"  ss=0x%04"
291                      (int)cpu->cd.x86.s[X86_S_CS], (int)cpu->cd.x86.s[X86_S_DS],                      PRIx16"\n", x, (uint16_t)cpu->cd.x86.s[X86_S_CS],
292                      (int)cpu->cd.x86.s[X86_S_ES], (int)cpu->cd.x86.s[X86_S_FS],                      (uint16_t)cpu->cd.x86.s[X86_S_DS],
293                      (int)cpu->cd.x86.s[X86_S_GS], (int)cpu->cd.x86.s[X86_S_SS]);                      (uint16_t)cpu->cd.x86.s[X86_S_ES],
294                        (uint16_t)cpu->cd.x86.s[X86_S_FS],
295                        (uint16_t)cpu->cd.x86.s[X86_S_GS],
296                        (uint16_t)cpu->cd.x86.s[X86_S_SS]);
297          }          }
298    
299          if (PROTECTED_MODE) {          if (PROTECTED_MODE) {
300                  /*  Protected mode:  */                  /*  Protected mode:  */
301                  debug("cpu%i:  cr0=0x%08x  cr2=0x%08x  cr3=0x%08x  eflags="                  debug("cpu%i:  cr0=0x%08"PRIx32"  cr2=0x%08"PRIx32"  cr3=0x%08"
302                      "0x%08x\n", x, (int)cpu->cd.x86.cr[0],                      PRIx32"  eflags=0x%08"PRIx32"\n", x,
303                      (int)cpu->cd.x86.cr[2], (int)cpu->cd.x86.cr[3],                      (uint32_t)cpu->cd.x86.cr[0], (uint32_t)cpu->cd.x86.cr[2],
304                      (int)cpu->cd.x86.rflags);                      (uint32_t)cpu->cd.x86.cr[3], (uint32_t)cpu->cd.x86.rflags);
305                  debug("cpu%i:  tr = 0x%04x (base=0x%llx, limit=0x%x)\n",                  debug("cpu%i:  tr = 0x%04"PRIx16" (base=0x%"PRIx64", limit=0x"
306                      x, (int)cpu->cd.x86.tr, (long long)cpu->cd.x86.tr_base,                      PRIx32")\n", x, (uint16_t)cpu->cd.x86.tr, (uint64_t)
307                      (int)cpu->cd.x86.tr_limit);                      cpu->cd.x86.tr_base, (uint32_t)cpu->cd.x86.tr_limit);
308          }          }
309  }  }
310    
# Line 443  void x86_cpu_register_match(struct machi Line 470  void x86_cpu_register_match(struct machi
470  }  }
471    
472    
 /*  
  *  x86_cpu_show_full_statistics():  
  *  
  *  Show detailed statistics on opcode usage on each cpu.  
  */  
 void x86_cpu_show_full_statistics(struct machine *m)  
 {  
         fatal("x86_cpu_show_full_statistics(): TODO\n");  
 }  
   
   
 /*  
  *  x86_cpu_tlbdump():  
  *  
  *  Called from the debugger to dump the TLB in a readable format.  
  *  x is the cpu number to dump, or -1 to dump all CPUs.  
  *  
  *  If rawflag is nonzero, then the TLB contents isn't formated nicely,  
  *  just dumped.  
  */  
 void x86_cpu_tlbdump(struct machine *m, int x, int rawflag)  
 {  
         fatal("ppc_cpu_tlbdump(): TODO\n");  
 }  
   
   
473  /*  Macro which modifies the lower part of a value, or the entire value,  /*  Macro which modifies the lower part of a value, or the entire value,
474      depending on 'mode':  */      depending on 'mode':  */
475  #define modify(old,new) (                                       \  #define modify(old,new) (                                       \
# Line 516  static uint32_t read_imm_and_print(unsig Line 517  static uint32_t read_imm_and_print(unsig
517  }  }
518    
519    
520  static uint32_t read_imm(unsigned char **instrp, uint64_t *newpcp,  uint32_t read_imm(unsigned char **instrp, uint64_t *newpcp,
521          int mode)          int mode)
522  {  {
523          return read_imm_common(instrp, newpcp, mode, 0);          return read_imm_common(instrp, newpcp, mode, 0);
524  }  }
525    
526    
527  static void print_csip(struct cpu *cpu)  void print_csip(struct cpu *cpu)
528  {  {
529          fatal("0x%04x:", cpu->cd.x86.s[X86_S_CS]);          fatal("0x%04x:", cpu->cd.x86.s[X86_S_CS]);
530          if (PROTECTED_MODE)          if (PROTECTED_MODE)
# Line 534  static void print_csip(struct cpu *cpu) Line 535  static void print_csip(struct cpu *cpu)
535    
536    
537  /*  /*
538     *  x86_cpu_tlbdump():
539     *
540     *  Called from the debugger to dump the TLB in a readable format.
541     *  x is the cpu number to dump, or -1 to dump all CPUs.
542     *
543     *  If rawflag is nonzero, then the TLB contents isn't formated nicely,
544     *  just dumped.
545     */
546    void x86_cpu_tlbdump(struct machine *m, int x, int rawflag)
547    {
548    }
549    
550    
551    /*
552     *  x86_cpu_gdb_stub():
553     *
554     *  Execute a "remote GDB" command. Returns a newly allocated response string
555     *  on success, NULL on failure.
556     */
557    char *x86_cpu_gdb_stub(struct cpu *cpu, char *cmd)
558    {
559            fatal("x86_cpu_gdb_stub(): TODO\n");
560            return NULL;
561    }
562    
563    
564    /*
565   *  x86_cpu_interrupt():   *  x86_cpu_interrupt():
566   *   *
567   *  NOTE: Interacting with the 8259 PIC is done in src/machine.c.   *  NOTE: Interacting with the 8259 PIC is done in src/machine.c.
# Line 663  void x86_task_switch(struct cpu *cpu, in Line 691  void x86_task_switch(struct cpu *cpu, in
691          reload_segment_descriptor(cpu, RELOAD_TR, new_tr, NULL);          reload_segment_descriptor(cpu, RELOAD_TR, new_tr, NULL);
692    
693          if (cpu->cd.x86.tr_limit < 0x67)          if (cpu->cd.x86.tr_limit < 0x67)
694                  fatal("WARNING: tr_limit = 0x%x, must be at least 0x67!\n",                  fatal("WARNING: tr_limit = 0x%"PRIx16", must be at least "
695                      (int)cpu->cd.x86.tr_limit);                      "0x67!\n", (uint16_t)cpu->cd.x86.tr_limit);
696    
697          /*  Read new registers:  */          /*  Read new registers:  */
698  #define READ_VALUE { cpu->memory_rw(cpu, cpu->mem, cpu->cd.x86.tr_base + \  #define READ_VALUE { cpu->memory_rw(cpu, cpu->mem, cpu->cd.x86.tr_base + \
# Line 721  void reload_segment_descriptor(struct cp Line 749  void reload_segment_descriptor(struct cp
749          int segment = 1, rpl, orig_selector = selector;          int segment = 1, rpl, orig_selector = selector;
750          unsigned char descr[8];          unsigned char descr[8];
751          char *table_name = "GDT";          char *table_name = "GDT";
752          uint64_t base, limit, table_base, table_limit;          uint64_t base, limit, table_base;
753            int64_t table_limit;
754    
755          if (segnr > 0x100)      /*  arbitrary, larger than N_X86_SEGS  */          if (segnr > 0x100)      /*  arbitrary, larger than N_X86_SEGS  */
756                  segment = 0;                  segment = 0;
# Line 1500  static int modrm(struct cpu *cpu, int wr Line 1529  static int modrm(struct cpu *cpu, int wr
1529   *  The rest of running tells us the default (code) operand size.   *  The rest of running tells us the default (code) operand size.
1530   */   */
1531  int x86_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,  int x86_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
1532          int running, uint64_t dumpaddr, int bintrans)          int running, uint64_t dumpaddr)
1533  {  {
1534          int op, rep = 0, lock = 0, n_prefix_bytes = 0;          int op, rep = 0, lock = 0, n_prefix_bytes = 0;
1535          uint64_t ilen = 0, offset;          uint64_t ilen = 0, offset;
# Line 2436  int x86_cpu_disassemble_instr(struct cpu Line 2465  int x86_cpu_disassemble_instr(struct cpu
2465   *   *
2466   *  TODO: Level 1 and 2 info.   *  TODO: Level 1 and 2 info.
2467   */   */
2468  static void x86_cpuid(struct cpu *cpu)  void x86_cpuid(struct cpu *cpu)
2469  {  {
2470          switch (cpu->cd.x86.r[X86_R_AX]) {          switch (cpu->cd.x86.r[X86_R_AX]) {
2471          /*  Normal CPU id:  */          /*  Normal CPU id:  */
# Line 2604  int x86_interrupt(struct cpu *cpu, int n Line 2633  int x86_interrupt(struct cpu *cpu, int n
2633          if (PROTECTED_MODE) {          if (PROTECTED_MODE) {
2634                  int i, int_type = 0;                  int i, int_type = 0;
2635    
2636                  if (nr * 8 > cpu->cd.x86.idtr_limit) {                  if (nr * 8 > (int)cpu->cd.x86.idtr_limit) {
2637                          fatal("TODO: protected mode int 0x%02x outside idtr"                          fatal("TODO: protected mode int 0x%02x outside idtr"
2638                              " limit (%i)?\n", nr, (int)cpu->cd.x86.idtr_limit);                              " limit (%i)?\n", nr, (int)cpu->cd.x86.idtr_limit);
2639                          cpu->running = 0;                          cpu->running = 0;
# Line 2746  int x86_interrupt(struct cpu *cpu, int n Line 2775  int x86_interrupt(struct cpu *cpu, int n
2775          /*          /*
2776           *  Real mode:           *  Real mode:
2777           */           */
2778          if (nr * 4 > cpu->cd.x86.idtr_limit) {          if (nr * 4 > (int)cpu->cd.x86.idtr_limit) {
2779                  fatal("TODO: real mode int 0x%02x outside idtr limit ("                  fatal("TODO: real mode int 0x%02x outside idtr limit ("
2780                      "%i)?\n", nr, (int)cpu->cd.x86.idtr_limit);                      "%i)?\n", nr, (int)cpu->cd.x86.idtr_limit);
2781                  cpu->running = 0;                  cpu->running = 0;
# Line 3133  cpu->machine->isa_pic_data.pic2->irr, cp Line 3162  cpu->machine->isa_pic_data.pic2->irr, cp
3162  }  }
3163    
3164    
3165  #define TRANSLATE_ADDRESS       x86_translate_address  #define TRANSLATE_ADDRESS       x86_translate_v2p
3166  #include "memory_x86.c"  #include "memory_x86.c"
3167  #undef TRANSLATE_ADDRESS  #undef TRANSLATE_ADDRESS
3168    

Legend:
Removed from v.14  
changed lines
  Added in v.26

  ViewVC Help
Powered by ViewVC 1.1.26