/[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 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 24 by dpavlin, Mon Oct 8 16:19:56 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.5 2005/11/13 00:14:07 debug Exp $   *  $Id: cpu_x86.c,v 1.15 2006/06/16 18:31:26 debug Exp $
29   *   *
30   *  x86 (and amd64) CPU emulation.   *  x86 (and amd64) CPU emulation.
31   *   *
# Line 142  int x86_cpu_new(struct cpu *cpu, struct Line 142  int x86_cpu_new(struct cpu *cpu, struct
142                  debug("%s", cpu->name);                  debug("%s", cpu->name);
143          }          }
144    
145            x86_init_64bit_dummy_tables(cpu);
146    
147          return 1;          return 1;
148  }  }
149    
# Line 168  void x86_cpu_list_available_types(void) Line 170  void x86_cpu_list_available_types(void)
170          while (models[i].model_number != 0) {          while (models[i].model_number != 0) {
171                  debug("%s", models[i].name);                  debug("%s", models[i].name);
172    
173                  for (j=0; j<10-strlen(models[i].name); j++)                  for (j=0; j<10-(int)strlen(models[i].name); j++)
174                          debug(" ");                          debug(" ");
175                  i++;                  i++;
176                  if ((i % 6) == 0 || models[i].name == NULL)                  if ((i % 6) == 0 || models[i].name == NULL)
# Line 189  void x86_cpu_register_dump(struct cpu *c Line 191  void x86_cpu_register_dump(struct cpu *c
191          uint64_t offset;          uint64_t offset;
192          int i, x = cpu->cpu_id;          int i, x = cpu->cpu_id;
193    
194          if (REAL_MODE) {          if (LONG_MODE) {
195                  /*  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  */  
196                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
197                      cpu->pc, &offset);                      cpu->pc, &offset);
198    
199                  debug("cpu%i:  rip = 0x", x);                  debug("cpu%i:  rip = 0x%016"PRIx64, x, cpu->pc);
                 debug("%016llx", (long long)cpu->pc);  
200                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
201    
202                  for (i=0; i<N_X86_REGS; i++) {                  for (i=0; i<N_X86_REGS; i++) {
203                          if ((i & 1) == 0)                          if ((i & 1) == 0)
204                                  debug("cpu%i:", x);                                  debug("cpu%i:", x);
205                          debug("  r%s = 0x%016llx", reg_names[i],                          debug("  r%s = 0x%016"PRIx64, reg_names[i],
206                              (long long)cpu->cd.x86.r[i]);                              (uint64_t)cpu->cd.x86.r[i]);
207                          if ((i & 1) == 1)                          if ((i & 1) == 1)
208                                  debug("\n");                                  debug("\n");
209                  }                  }
210  #endif          } else if (REAL_MODE) {
211                    /*  16-bit real-mode:  */
212                    debug("cpu%i:  cs:ip = 0x%04"PRIx16":0x%04"PRIx16"\n", x,
213                        cpu->cd.x86.s[X86_S_CS], (uint16_t)cpu->pc);
214    
215                    debug("cpu%i:  ax = 0x%04"PRIx16"  bx = 0x%04"PRIx16
216                        "  cx = 0x%04"PRIx16"  dx = 0x%04"PRIx16"\n", x,
217                        (uint16_t)cpu->cd.x86.r[X86_R_AX],
218                        (uint16_t)cpu->cd.x86.r[X86_R_BX],
219                        (uint16_t)cpu->cd.x86.r[X86_R_CX],
220                        (uint16_t)cpu->cd.x86.r[X86_R_DX]);
221                    debug("cpu%i:  si = 0x%04"PRIx16"  di = 0x%04"PRIx16
222                        "  bp = 0x%04"PRIx16"  sp = 0x%04"PRIx16"\n", x,
223                        (uint16_t)cpu->cd.x86.r[X86_R_SI],
224                        (uint16_t)cpu->cd.x86.r[X86_R_DI],
225                        (uint16_t)cpu->cd.x86.r[X86_R_BP],
226                        (uint16_t)cpu->cd.x86.r[X86_R_SP]);
227                    debug("cpu%i:  ds = 0x%04"PRIx16"  es = 0x%04"PRIx16
228                        "  ss = 0x%04"PRIx16"  flags = 0x%04"PRIx16"\n", x,
229                        (uint16_t)cpu->cd.x86.s[X86_S_DS],
230                        (uint16_t)cpu->cd.x86.s[X86_S_ES],
231                        (uint16_t)cpu->cd.x86.s[X86_S_SS],
232                        (uint16_t)cpu->cd.x86.rflags);
233            } else {
234                    /*  32-bit protected mode:  */
235                    symbol = get_symbol_name(&cpu->machine->symbol_context,
236                        cpu->pc, &offset);
237    
238                    debug("cpu%i:  eip=0x%08"PRIx32, x, (uint32_t)cpu->pc);
239                    debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
240    
241                    debug("cpu%i:  eax=0x%08"PRIx32"  ebx=0x%08"PRIx32
242                        "  ecx=0x%08"PRIx32"  edx=0x%08"PRIx32"\n", x,
243                        (uint32_t)cpu->cd.x86.r[X86_R_AX],
244                        (uint32_t)cpu->cd.x86.r[X86_R_BX],
245                        (uint32_t)cpu->cd.x86.r[X86_R_CX],
246                        (uint32_t)cpu->cd.x86.r[X86_R_DX]);
247                    debug("cpu%i:  esi=0x%08"PRIx32"  edi=0x%08"PRIx32
248                        "  ebp=0x%08"PRIx32"  esp=0x%08"PRIx32"\n", x,
249                        (uint32_t)cpu->cd.x86.r[X86_R_SI],
250                        (uint32_t)cpu->cd.x86.r[X86_R_DI],
251                        (uint32_t)cpu->cd.x86.r[X86_R_BP],
252                        (uint32_t)cpu->cd.x86.r[X86_R_SP]);
253          }          }
254    
255          if (coprocs != 0) {          if (coprocs != 0) {
# Line 280  void x86_cpu_register_dump(struct cpu *c Line 288  void x86_cpu_register_dump(struct cpu *c
288                      cpu->machine->isa_pic_data.pic2->irq_base);                      cpu->machine->isa_pic_data.pic2->irq_base);
289          } else if (PROTECTED_MODE) {          } else if (PROTECTED_MODE) {
290                  /*  Protected mode:  */                  /*  Protected mode:  */
291                  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"
292                      "fs=0x%04x  gs=0x%04x  ss=0x%04x\n", x,                      PRIx16"  fs=0x%04"PRIx16"  gs=0x%04"PRIx16"  ss=0x%04"
293                      (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],
294                      (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],
295                      (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],
296                        (uint16_t)cpu->cd.x86.s[X86_S_FS],
297                        (uint16_t)cpu->cd.x86.s[X86_S_GS],
298                        (uint16_t)cpu->cd.x86.s[X86_S_SS]);
299          }          }
300    
301          if (PROTECTED_MODE) {          if (PROTECTED_MODE) {
302                  /*  Protected mode:  */                  /*  Protected mode:  */
303                  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"
304                      "0x%08x\n", x, (int)cpu->cd.x86.cr[0],                      PRIx32"  eflags=0x%08"PRIx32"\n", x,
305                      (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],
306                      (int)cpu->cd.x86.rflags);                      (uint32_t)cpu->cd.x86.cr[3], (uint32_t)cpu->cd.x86.rflags);
307                  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"
308                      x, (int)cpu->cd.x86.tr, (long long)cpu->cd.x86.tr_base,                      PRIx32")\n", x, (uint16_t)cpu->cd.x86.tr, (uint64_t)
309                      (int)cpu->cd.x86.tr_limit);                      cpu->cd.x86.tr_base, (uint32_t)cpu->cd.x86.tr_limit);
310          }          }
311  }  }
312    
# Line 508  static uint32_t read_imm_and_print(unsig Line 519  static uint32_t read_imm_and_print(unsig
519  }  }
520    
521    
522  static uint32_t read_imm(unsigned char **instrp, uint64_t *newpcp,  uint32_t read_imm(unsigned char **instrp, uint64_t *newpcp,
523          int mode)          int mode)
524  {  {
525          return read_imm_common(instrp, newpcp, mode, 0);          return read_imm_common(instrp, newpcp, mode, 0);
526  }  }
527    
528    
529  static void print_csip(struct cpu *cpu)  void print_csip(struct cpu *cpu)
530  {  {
531          fatal("0x%04x:", cpu->cd.x86.s[X86_S_CS]);          fatal("0x%04x:", cpu->cd.x86.s[X86_S_CS]);
532          if (PROTECTED_MODE)          if (PROTECTED_MODE)
# Line 526  static void print_csip(struct cpu *cpu) Line 537  static void print_csip(struct cpu *cpu)
537    
538    
539  /*  /*
540     *  x86_cpu_tlbdump():
541     *
542     *  Called from the debugger to dump the TLB in a readable format.
543     *  x is the cpu number to dump, or -1 to dump all CPUs.
544     *
545     *  If rawflag is nonzero, then the TLB contents isn't formated nicely,
546     *  just dumped.
547     */
548    void x86_cpu_tlbdump(struct machine *m, int x, int rawflag)
549    {
550    }
551    
552    
553    /*
554     *  x86_cpu_gdb_stub():
555     *
556     *  Execute a "remote GDB" command. Returns a newly allocated response string
557     *  on success, NULL on failure.
558     */
559    char *x86_cpu_gdb_stub(struct cpu *cpu, char *cmd)
560    {
561            fatal("x86_cpu_gdb_stub(): TODO\n");
562            return NULL;
563    }
564    
565    
566    /*
567   *  x86_cpu_interrupt():   *  x86_cpu_interrupt():
568   *   *
569   *  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 655  void x86_task_switch(struct cpu *cpu, in Line 693  void x86_task_switch(struct cpu *cpu, in
693          reload_segment_descriptor(cpu, RELOAD_TR, new_tr, NULL);          reload_segment_descriptor(cpu, RELOAD_TR, new_tr, NULL);
694    
695          if (cpu->cd.x86.tr_limit < 0x67)          if (cpu->cd.x86.tr_limit < 0x67)
696                  fatal("WARNING: tr_limit = 0x%x, must be at least 0x67!\n",                  fatal("WARNING: tr_limit = 0x%"PRIx16", must be at least "
697                      (int)cpu->cd.x86.tr_limit);                      "0x67!\n", (uint16_t)cpu->cd.x86.tr_limit);
698    
699          /*  Read new registers:  */          /*  Read new registers:  */
700  #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 713  void reload_segment_descriptor(struct cp Line 751  void reload_segment_descriptor(struct cp
751          int segment = 1, rpl, orig_selector = selector;          int segment = 1, rpl, orig_selector = selector;
752          unsigned char descr[8];          unsigned char descr[8];
753          char *table_name = "GDT";          char *table_name = "GDT";
754          uint64_t base, limit, table_base, table_limit;          uint64_t base, limit, table_base;
755            int64_t table_limit;
756    
757          if (segnr > 0x100)      /*  arbitrary, larger than N_X86_SEGS  */          if (segnr > 0x100)      /*  arbitrary, larger than N_X86_SEGS  */
758                  segment = 0;                  segment = 0;
# Line 1492  static int modrm(struct cpu *cpu, int wr Line 1531  static int modrm(struct cpu *cpu, int wr
1531   *  The rest of running tells us the default (code) operand size.   *  The rest of running tells us the default (code) operand size.
1532   */   */
1533  int x86_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,  int x86_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
1534          int running, uint64_t dumpaddr, int bintrans)          int running, uint64_t dumpaddr)
1535  {  {
1536          int op, rep = 0, lock = 0, n_prefix_bytes = 0;          int op, rep = 0, lock = 0, n_prefix_bytes = 0;
1537          uint64_t ilen = 0, offset;          uint64_t ilen = 0, offset;
# Line 2428  int x86_cpu_disassemble_instr(struct cpu Line 2467  int x86_cpu_disassemble_instr(struct cpu
2467   *   *
2468   *  TODO: Level 1 and 2 info.   *  TODO: Level 1 and 2 info.
2469   */   */
2470  static void x86_cpuid(struct cpu *cpu)  void x86_cpuid(struct cpu *cpu)
2471  {  {
2472          switch (cpu->cd.x86.r[X86_R_AX]) {          switch (cpu->cd.x86.r[X86_R_AX]) {
2473          /*  Normal CPU id:  */          /*  Normal CPU id:  */
# Line 2596  int x86_interrupt(struct cpu *cpu, int n Line 2635  int x86_interrupt(struct cpu *cpu, int n
2635          if (PROTECTED_MODE) {          if (PROTECTED_MODE) {
2636                  int i, int_type = 0;                  int i, int_type = 0;
2637    
2638                  if (nr * 8 > cpu->cd.x86.idtr_limit) {                  if (nr * 8 > (int)cpu->cd.x86.idtr_limit) {
2639                          fatal("TODO: protected mode int 0x%02x outside idtr"                          fatal("TODO: protected mode int 0x%02x outside idtr"
2640                              " limit (%i)?\n", nr, (int)cpu->cd.x86.idtr_limit);                              " limit (%i)?\n", nr, (int)cpu->cd.x86.idtr_limit);
2641                          cpu->running = 0;                          cpu->running = 0;
# Line 2738  int x86_interrupt(struct cpu *cpu, int n Line 2777  int x86_interrupt(struct cpu *cpu, int n
2777          /*          /*
2778           *  Real mode:           *  Real mode:
2779           */           */
2780          if (nr * 4 > cpu->cd.x86.idtr_limit) {          if (nr * 4 > (int)cpu->cd.x86.idtr_limit) {
2781                  fatal("TODO: real mode int 0x%02x outside idtr limit ("                  fatal("TODO: real mode int 0x%02x outside idtr limit ("
2782                      "%i)?\n", nr, (int)cpu->cd.x86.idtr_limit);                      "%i)?\n", nr, (int)cpu->cd.x86.idtr_limit);
2783                  cpu->running = 0;                  cpu->running = 0;

Legend:
Removed from v.20  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26