/[gxemul]/trunk/src/cpu.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/cpu.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 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2007  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.c,v 1.321 2005/10/03 01:07:40 debug Exp $   *  $Id: cpu.c,v 1.389 2007/06/15 17:02:37 debug Exp $
29   *   *
30   *  Common routines for CPU emulation. (Not specific to any CPU type.)   *  Common routines for CPU emulation. (Not specific to any CPU type.)
31   */   */
# Line 33  Line 33 
33  #include <stdio.h>  #include <stdio.h>
34  #include <stdlib.h>  #include <stdlib.h>
35  #include <sys/types.h>  #include <sys/types.h>
36    #include <sys/mman.h>
37  #include <string.h>  #include <string.h>
38    
39  #include "cpu.h"  #include "cpu.h"
40  #include "machine.h"  #include "machine.h"
41  #include "memory.h"  #include "memory.h"
42  #include "misc.h"  #include "settings.h"
43    #include "timer.h"
44    
45    
46  extern int quiet_mode;  extern size_t dyntrans_cache_size;
47  extern int show_opcode_statistics;  extern int native_code_translation_enabled;
   
48    
49  static struct cpu_family *first_cpu_family = NULL;  static struct cpu_family *first_cpu_family = NULL;
50    
# Line 53  static struct cpu_family *first_cpu_fami Line 54  static struct cpu_family *first_cpu_fami
54   *   *
55   *  Create a new cpu object.  Each family is tried in sequence until a   *  Create a new cpu object.  Each family is tried in sequence until a
56   *  CPU family recognizes the cpu_type_name.   *  CPU family recognizes the cpu_type_name.
57     *
58     *  If there was no match, NULL is returned. Otherwise, a pointer to an
59     *  initialized cpu struct is returned.
60   */   */
61  struct cpu *cpu_new(struct memory *mem, struct machine *machine,  struct cpu *cpu_new(struct memory *mem, struct machine *machine,
62          int cpu_id, char *name)          int cpu_id, char *name)
# Line 60  struct cpu *cpu_new(struct memory *mem, Line 64  struct cpu *cpu_new(struct memory *mem,
64          struct cpu *cpu;          struct cpu *cpu;
65          struct cpu_family *fp;          struct cpu_family *fp;
66          char *cpu_type_name;          char *cpu_type_name;
67            char tmpstr[30];
68    
69          if (name == NULL) {          if (name == NULL) {
70                  fprintf(stderr, "cpu_new(): cpu name = NULL?\n");                  fprintf(stderr, "cpu_new(): cpu name = NULL?\n");
71                  exit(1);                  exit(1);
72          }          }
73    
74          cpu_type_name = strdup(name);          CHECK_ALLOCATION(cpu_type_name = strdup(name));
         if (cpu_type_name == NULL) {  
                 fprintf(stderr, "cpu_new(): out of memory\n");  
                 exit(1);  
         }  
75    
76          cpu = zeroed_alloc(sizeof(struct cpu));          cpu = zeroed_alloc(sizeof(struct cpu));
77    
78          cpu->memory_rw          = NULL;          CHECK_ALLOCATION(cpu->path = malloc(strlen(machine->path) + 15));
79          cpu->name               = cpu_type_name;          snprintf(cpu->path, strlen(machine->path) + 15,
80          cpu->mem                = mem;              "%s.cpu[%i]", machine->path, cpu_id);
81          cpu->machine            = machine;  
82          cpu->cpu_id             = cpu_id;          cpu->memory_rw  = NULL;
83          cpu->byte_order         = EMUL_LITTLE_ENDIAN;          cpu->name       = cpu_type_name;
84          cpu->bootstrap_cpu_flag = 0;          cpu->mem        = mem;
85          cpu->running            = 0;          cpu->machine    = machine;
86            cpu->cpu_id     = cpu_id;
87            cpu->byte_order = EMUL_UNDEFINED_ENDIAN;
88            cpu->running    = 0;
89    
90            cpu->sampling_paddr = zeroed_alloc(N_PADDR_SAMPLES * sizeof(uint64_t));
91    
92            /*  Create settings, and attach to the machine:  */
93            cpu->settings = settings_new();
94            snprintf(tmpstr, sizeof(tmpstr), "cpu[%i]", cpu_id);
95            settings_add(machine->settings, tmpstr, 1,
96                SETTINGS_TYPE_SUBSETTINGS, 0, cpu->settings);
97    
98            settings_add(cpu->settings, "name", 0, SETTINGS_TYPE_STRING,
99                SETTINGS_FORMAT_STRING, (void *) &cpu->name);
100            settings_add(cpu->settings, "running", 0, SETTINGS_TYPE_UINT8,
101                SETTINGS_FORMAT_YESNO, (void *) &cpu->running);
102    
103          cpu_create_or_reset_tc(cpu);          cpu_create_or_reset_tc(cpu);
104    
# Line 97  struct cpu *cpu_new(struct memory *mem, Line 114  struct cpu *cpu_new(struct memory *mem,
114                                              "NULL\n");                                              "NULL\n");
115                                          exit(1);                                          exit(1);
116                                  }                                  }
117                                  return cpu;                                  break;
118                          }                          }
119                  }                  }
120    
121                  fp = fp->next;                  fp = fp->next;
122          }          }
123    
124          fatal("\ncpu_new(): unknown cpu type '%s'\n", cpu_type_name);          if (fp == NULL) {
125          exit(1);                  fatal("\ncpu_new(): unknown cpu type '%s'\n", cpu_type_name);
126                    return NULL;
127            }
128    
129            fp->init_tables(cpu);
130    
131            if (cpu->byte_order == EMUL_UNDEFINED_ENDIAN) {
132                    fatal("\ncpu_new(): Internal bug: Endianness not set.\n");
133                    exit(1);
134            }
135    
136            return cpu;
137  }  }
138    
139    
140  /*  /*
141   *  cpu_show_full_statistics():   *  cpu_destroy():
142   *   *
143   *  Show detailed statistics on opcode usage on each cpu.   *  Destroy a cpu object.
144   */   */
145  void cpu_show_full_statistics(struct machine *m)  void cpu_destroy(struct cpu *cpu)
146  {  {
147          if (m->cpu_family == NULL ||          if (cpu->sampling_timer != NULL)
148              m->cpu_family->show_full_statistics == NULL)                  timer_remove(cpu->sampling_timer);
149                  fatal("cpu_show_full_statistics(): NULL\n");  
150          else          settings_remove(cpu->settings, "name");
151                  m->cpu_family->show_full_statistics(m);          settings_remove(cpu->settings, "running");
152    
153            /*  Remove any remaining level-1 settings:  */
154            settings_remove_all(cpu->settings);
155    
156            settings_destroy(cpu->settings);
157    
158            if (cpu->path != NULL)
159                    free(cpu->path);
160    
161            /*  TODO: This assumes that zeroed_alloc() actually succeeded
162                with using mmap(), and not malloc()!  */
163            munmap((void *)cpu, sizeof(struct cpu));
164  }  }
165    
166    
# Line 143  void cpu_tlbdump(struct machine *m, int Line 183  void cpu_tlbdump(struct machine *m, int
183    
184    
185  /*  /*
  *  cpu_register_match():  
  *  
  *  Used by the debugger.  
  */  
 void cpu_register_match(struct machine *m, char *name,  
         int writeflag, uint64_t *valuep, int *match_register)  
 {  
         if (m->cpu_family == NULL || m->cpu_family->register_match == NULL)  
                 fatal("cpu_register_match(): NULL\n");  
         else  
                 m->cpu_family->register_match(m, name, writeflag,  
                     valuep, match_register);  
 }  
   
   
 /*  
186   *  cpu_disassemble_instr():   *  cpu_disassemble_instr():
187   *   *
188   *  Convert an instruction word into human readable format, for instruction   *  Convert an instruction word into human readable format, for instruction
189   *  tracing.   *  tracing.
190   */   */
191  int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,  int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,
192          unsigned char *instr, int running, uint64_t addr, int bintrans)          unsigned char *instr, int running, uint64_t addr)
193  {  {
194          if (m->cpu_family == NULL || m->cpu_family->disassemble_instr == NULL) {          if (m->cpu_family == NULL || m->cpu_family->disassemble_instr == NULL) {
195                  fatal("cpu_disassemble_instr(): NULL\n");                  fatal("cpu_disassemble_instr(): NULL\n");
196                  return 0;                  return 0;
197          } else          } else
198                  return m->cpu_family->disassemble_instr(cpu, instr,                  return m->cpu_family->disassemble_instr(cpu, instr,
199                      running, addr, bintrans);                      running, addr);
200  }  }
201    
202    
# Line 181  int cpu_disassemble_instr(struct machine Line 205  int cpu_disassemble_instr(struct machine
205   *   *
206   *  Dump cpu registers in a relatively readable format.   *  Dump cpu registers in a relatively readable format.
207   *   *
208   *  gprs: set to non-zero to dump GPRs. (CPU dependant.)   *  gprs: set to non-zero to dump GPRs. (CPU dependent.)
209   *  coprocs: set bit 0..x to dump registers in coproc 0..x. (CPU dependant.)   *  coprocs: set bit 0..x to dump registers in coproc 0..x. (CPU dependent.)
210   */   */
211  void cpu_register_dump(struct machine *m, struct cpu *cpu,  void cpu_register_dump(struct machine *m, struct cpu *cpu,
212          int gprs, int coprocs)          int gprs, int coprocs)
# Line 195  void cpu_register_dump(struct machine *m Line 219  void cpu_register_dump(struct machine *m
219    
220    
221  /*  /*
  *  cpu_interrupt():  
  *  
  *  Assert an interrupt.  
  *  Return value is 1 if the interrupt was asserted, 0 otherwise.  
  */  
 int cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  
 {  
         if (cpu->machine->cpu_family == NULL ||  
             cpu->machine->cpu_family->interrupt == NULL) {  
                 fatal("cpu_interrupt(): NULL\n");  
                 return 0;  
         } else  
                 return cpu->machine->cpu_family->interrupt(cpu, irq_nr);  
 }  
   
   
 /*  
  *  cpu_interrupt_ack():  
  *  
  *  Acknowledge an interrupt.  
  *  Return value is 1 if the interrupt was deasserted, 0 otherwise.  
  */  
 int cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  
 {  
         if (cpu->machine->cpu_family == NULL ||  
             cpu->machine->cpu_family->interrupt_ack == NULL) {  
                 /*  debug("cpu_interrupt_ack(): NULL\n");  */  
                 return 0;  
         } else  
                 return cpu->machine->cpu_family->interrupt_ack(cpu, irq_nr);  
 }  
   
   
 /*  
222   *  cpu_functioncall_trace():   *  cpu_functioncall_trace():
223   *   *
224   *  This function should be called if machine->show_trace_tree is enabled, and   *  This function should be called if machine->show_trace_tree is enabled, and
# Line 236  int cpu_interrupt_ack(struct cpu *cpu, u Line 226  int cpu_interrupt_ack(struct cpu *cpu, u
226   */   */
227  void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)  void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
228  {  {
229            int show_symbolic_function_name = 1;
230          int i, n_args = -1;          int i, n_args = -1;
231          char *symbol;          char *symbol;
232          uint64_t offset;          uint64_t offset;
233    
234            /*  Special hack for M88K userspace:  */
235            if (cpu->machine->arch == ARCH_M88K &&
236                !(cpu->cd.m88k.cr[M88K_CR_PSR] & M88K_PSR_MODE))
237                    show_symbolic_function_name = 0;
238    
239          if (cpu->machine->ncpus > 1)          if (cpu->machine->ncpus > 1)
240                  fatal("cpu%i:\t", cpu->cpu_id);                  fatal("cpu%i:\t", cpu->cpu_id);
241    
         cpu->trace_tree_depth ++;  
242          if (cpu->trace_tree_depth > 100)          if (cpu->trace_tree_depth > 100)
243                  cpu->trace_tree_depth = 100;                  cpu->trace_tree_depth = 100;
244          for (i=0; i<cpu->trace_tree_depth; i++)          for (i=0; i<cpu->trace_tree_depth; i++)
245                  fatal("  ");                  fatal("  ");
246    
247            cpu->trace_tree_depth ++;
248    
249          fatal("<");          fatal("<");
250          symbol = get_symbol_name_and_n_args(&cpu->machine->symbol_context,          symbol = get_symbol_name_and_n_args(&cpu->machine->symbol_context,
251              f, &offset, &n_args);              f, &offset, &n_args);
252          if (symbol != NULL)          if (symbol != NULL && show_symbolic_function_name)
253                  fatal("%s", symbol);                  fatal("%s", symbol);
254          else {          else {
255                  if (cpu->is_32bit)                  if (cpu->is_32bit)
256                          fatal("0x%08x", (int)f);                          fatal("0x%"PRIx32, (uint32_t) f);
257                  else                  else
258                          fatal("0x%llx", (long long)f);                          fatal("0x%"PRIx64, (uint64_t) f);
259          }          }
260          fatal("(");          fatal("(");
261    
# Line 266  void cpu_functioncall_trace(struct cpu * Line 263  void cpu_functioncall_trace(struct cpu *
263                  cpu->machine->cpu_family->functioncall_trace(cpu, f, n_args);                  cpu->machine->cpu_family->functioncall_trace(cpu, f, n_args);
264    
265          fatal(")>\n");          fatal(")>\n");
266    
267    #ifdef PRINT_MEMORY_CHECKSUM
268            /*  Temporary hack for finding bugs:  */
269            fatal("call chksum=%016"PRIx64"\n", memory_checksum(cpu->mem));
270    #endif
271  }  }
272    
273    
# Line 294  void cpu_functioncall_trace_return(struc Line 296  void cpu_functioncall_trace_return(struc
296   */   */
297  void cpu_create_or_reset_tc(struct cpu *cpu)  void cpu_create_or_reset_tc(struct cpu *cpu)
298  {  {
299          if (cpu->translation_cache == NULL)          size_t s = dyntrans_cache_size + DYNTRANS_CACHE_MARGIN;
300                  cpu->translation_cache = zeroed_alloc(DYNTRANS_CACHE_SIZE +  
301                      DYNTRANS_CACHE_MARGIN);          if (cpu->translation_cache == NULL) {
302                    cpu->translation_cache = zeroed_alloc(s);
303    
304                    if (native_code_translation_enabled) {
305                            mprotect(cpu->translation_cache, s,
306                                PROT_READ | PROT_WRITE | PROT_EXEC);
307                    }
308            }
309    
310          /*  Create an empty table at the beginning of the translation cache:  */          /*  Create an empty table at the beginning of the translation cache:  */
311          memset(cpu->translation_cache, 0, sizeof(uint32_t)          memset(cpu->translation_cache, 0, sizeof(uint32_t)
# Line 315  void cpu_create_or_reset_tc(struct cpu * Line 324  void cpu_create_or_reset_tc(struct cpu *
324    
325    
326  /*  /*
  *  cpu_run():  
  *  
  *  Run instructions on all CPUs in this machine, for a "medium duration"  
  *  (or until all CPUs have halted).  
  *  
  *  Return value is 1 if anything happened, 0 if all CPUs are stopped.  
  */  
 int cpu_run(struct emul *emul, struct machine *m)  
 {  
         if (m->cpu_family == NULL || m->cpu_family->run == NULL) {  
                 fatal("cpu_run(): NULL\n");  
                 return 0;  
         } else  
                 return m->cpu_family->run(emul, m);  
 }  
   
   
 /*  
327   *  cpu_dumpinfo():   *  cpu_dumpinfo():
328   *   *
329   *  Dumps info about a CPU using debug(). "cpu0: CPUNAME, running" (or similar)   *  Dumps info about a CPU using debug(). "cpu0: CPUNAME, running" (or similar)
330   *  is outputed, and it is up to CPU dependant code to complete the line.   *  is outputed, and it is up to CPU dependent code to complete the line.
331   */   */
332  void cpu_dumpinfo(struct machine *m, struct cpu *cpu)  void cpu_dumpinfo(struct machine *m, struct cpu *cpu)
333  {  {
# Line 358  void cpu_dumpinfo(struct machine *m, str Line 349  void cpu_dumpinfo(struct machine *m, str
349  void cpu_list_available_types(void)  void cpu_list_available_types(void)
350  {  {
351          struct cpu_family *fp;          struct cpu_family *fp;
352          int iadd = 4;          int iadd = DEBUG_INDENTATION;
353    
354          fp = first_cpu_family;          fp = first_cpu_family;
355    
# Line 393  void cpu_run_deinit(struct machine *mach Line 384  void cpu_run_deinit(struct machine *mach
384          int te;          int te;
385    
386          /*          /*
387           *  Two last ticks of every hardware device.  This will allow           *  Two last ticks of every hardware device.  This will allow e.g.
388           *  framebuffers to draw the last updates to the screen before           *  framebuffers to draw the last updates to the screen before halting.
389           *  halting.           *
390             *  TODO: This should be refactored when redesigning the mainbus
391             *        concepts!
392           */           */
393          for (te=0; te<machine->n_tick_entries; te++) {          for (te=0; te<machine->tick_functions.n_entries; te++) {
394                  machine->tick_func[te](machine->cpus[0],                  machine->tick_functions.f[te](machine->cpus[0],
395                      machine->tick_extra[te]);                      machine->tick_functions.extra[te]);
396                  machine->tick_func[te](machine->cpus[0],                  machine->tick_functions.f[te](machine->cpus[0],
397                      machine->tick_extra[te]);                      machine->tick_functions.extra[te]);
398          }          }
399    
400          debug("cpu_run_deinit(): All CPUs halted.\n");          if (machine->show_nr_of_instructions)
   
         if (machine->show_nr_of_instructions || !quiet_mode)  
401                  cpu_show_cycles(machine, 1);                  cpu_show_cycles(machine, 1);
402    
         if (show_opcode_statistics)  
                 cpu_show_full_statistics(machine);  
   
403          fflush(stdout);          fflush(stdout);
404  }  }
405    
# Line 419  void cpu_run_deinit(struct machine *mach Line 407  void cpu_run_deinit(struct machine *mach
407  /*  /*
408   *  cpu_show_cycles():   *  cpu_show_cycles():
409   *   *
410   *  If automatic adjustment of clock interrupts is turned on, then recalculate   *  If show_nr_of_instructions is on, then print a line to stdout about how
411   *  emulated_hz.  Also, if show_nr_of_instructions is on, then print a   *  many instructions/cycles have been executed so far.
  *  line to stdout about how many instructions/cycles have been executed so  
  *  far.  
412   */   */
413  void cpu_show_cycles(struct machine *machine, int forced)  void cpu_show_cycles(struct machine *machine, int forced)
414  {  {
# Line 430  void cpu_show_cycles(struct machine *mac Line 416  void cpu_show_cycles(struct machine *mac
416          char *symbol;          char *symbol;
417          int64_t mseconds, ninstrs, is, avg;          int64_t mseconds, ninstrs, is, avg;
418          struct timeval tv;          struct timeval tv;
419          int h, m, s, ms, d, instrs_per_cycle = 1;          struct cpu *cpu = machine->cpus[machine->bootstrap_cpu];
420    
421          static int64_t mseconds_last = 0;          static int64_t mseconds_last = 0;
422          static int64_t ninstrs_last = -1;          static int64_t ninstrs_last = -1;
423    
424          switch (machine->arch) {          pc = cpu->pc;
         case ARCH_MIPS:  
                 instrs_per_cycle = machine->cpus[machine->bootstrap_cpu]->  
                     cd.mips.cpu_type.instrs_per_cycle;  
                 break;  
         }  
   
         pc = machine->cpus[machine->bootstrap_cpu]->pc;  
425    
426          gettimeofday(&tv, NULL);          gettimeofday(&tv, NULL);
427          mseconds = (tv.tv_sec - machine->starttime.tv_sec) * 1000          mseconds = (tv.tv_sec - cpu->starttime.tv_sec) * 1000
428                   + (tv.tv_usec - machine->starttime.tv_usec) / 1000;                   + (tv.tv_usec - cpu->starttime.tv_usec) / 1000;
429    
430          if (mseconds == 0)          if (mseconds == 0)
431                  mseconds = 1;                  mseconds = 1;
# Line 454  void cpu_show_cycles(struct machine *mac Line 433  void cpu_show_cycles(struct machine *mac
433          if (mseconds - mseconds_last == 0)          if (mseconds - mseconds_last == 0)
434                  mseconds ++;                  mseconds ++;
435    
436          ninstrs = machine->ncycles_since_gettimeofday * instrs_per_cycle;          ninstrs = cpu->ninstrs_since_gettimeofday;
   
         if (machine->automatic_clock_adjustment) {  
                 static int first_adjustment = 1;  
   
                 /*  Current nr of cycles per second:  */  
                 int64_t cur_cycles_per_second = 1000 *  
                     (ninstrs-ninstrs_last) / (mseconds-mseconds_last)  
                     / instrs_per_cycle;  
   
                 if (cur_cycles_per_second < 1000000)  
                         cur_cycles_per_second = 1000000;  
   
                 if (first_adjustment) {  
                         machine->emulated_hz = cur_cycles_per_second;  
                         first_adjustment = 0;  
                 } else {  
                         machine->emulated_hz = (15 * machine->emulated_hz +  
                             cur_cycles_per_second) / 16;  
                 }  
   
                 /*  debug("[ updating emulated_hz to %lli Hz ]\n",  
                     (long long)machine->emulated_hz);  */  
         }  
   
437    
438          /*  RETURN here, unless show_nr_of_instructions (-N) is turned on:  */          /*  RETURN here, unless show_nr_of_instructions (-N) is turned on:  */
439          if (!machine->show_nr_of_instructions && !forced)          if (!machine->show_nr_of_instructions && !forced)
440                  goto do_return;                  goto do_return;
441    
442          printf("[ %lli instrs",          printf("[ %"PRIi64" instrs", (int64_t) cpu->ninstrs);
             (long long)(machine->ncycles * instrs_per_cycle));  
   
         if (!machine->automatic_clock_adjustment) {  
                 d = machine->emulated_hz / 1000;  
                 if (d < 1)  
                         d = 1;  
                 ms = machine->ncycles / d;  
                 h = ms / 3600000;  
                 ms -= 3600000 * h;  
                 m = ms / 60000;  
                 ms -= 60000 * m;  
                 s = ms / 1000;  
                 ms -= 1000 * s;  
   
                 printf("emulated time = %02i:%02i:%02i.%03i; ", h, m, s, ms);  
         }  
443    
444          /*  Instructions per second, and average so far:  */          /*  Instructions per second, and average so far:  */
445          is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last);          is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last);
# Line 509  void cpu_show_cycles(struct machine *mac Line 448  void cpu_show_cycles(struct machine *mac
448                  is = 0;                  is = 0;
449          if (avg < 0)          if (avg < 0)
450                  avg = 0;                  avg = 0;
451          printf("; i/s=%lli avg=%lli", (long long)is, (long long)avg);  
452            if (cpu->has_been_idling) {
453                    printf("; idling");
454                    cpu->has_been_idling = 0;
455            } else
456                    printf("; i/s=%"PRIi64" avg=%"PRIi64, is, avg);
457    
458          symbol = get_symbol_name(&machine->symbol_context, pc, &offset);          symbol = get_symbol_name(&machine->symbol_context, pc, &offset);
459    
460          if (machine->ncpus == 1) {          if (machine->ncpus == 1) {
461                  if (machine->cpus[machine->bootstrap_cpu]->is_32bit)                  if (cpu->is_32bit)
462                          printf("; pc=0x%08x", (int)pc);                          printf("; pc=0x%08"PRIx32, (uint32_t) pc);
463                  else                  else
464                          printf("; pc=0x%016llx", (long long)pc);                          printf("; pc=0x%016"PRIx64, (uint64_t) pc);
465          }          }
466    
467            /*  Special hack for M88K userland:  (Don't show symbols.)  */
468            if (cpu->machine->arch == ARCH_M88K &&
469                !(cpu->cd.m88k.cr[M88K_CR_PSR] & M88K_PSR_MODE))
470                    symbol = NULL;
471    
472          if (symbol != NULL)          if (symbol != NULL)
473                  printf(" <%s>", symbol);                  printf(" <%s>", symbol);
474          printf(" ]\n");          printf(" ]\n");
# Line 538  do_return: Line 487  do_return:
487   */   */
488  void cpu_run_init(struct machine *machine)  void cpu_run_init(struct machine *machine)
489  {  {
490          int ncpus = machine->ncpus;          int i;
491          int te;          for (i=0; i<machine->ncpus; i++) {
492                    struct cpu *cpu = machine->cpus[i];
493          machine->a_few_cycles = 1048576;  
494          machine->ncycles_flush = 0;                  cpu->ninstrs_flush = 0;
495          machine->ncycles = 0;                  cpu->ninstrs = 0;
496          machine->ncycles_show = 0;                  cpu->ninstrs_show = 0;
497    
498          /*                  /*  For performance measurement:  */
499           *  Instead of doing { one cycle, check hardware ticks }, we                  gettimeofday(&cpu->starttime, NULL);
500           *  can do { n cycles, check hardware ticks }, as long as                  cpu->ninstrs_since_gettimeofday = 0;
          *  n is at most as much as the lowest number of cycles/tick  
          *  for any hardware device.  
          */  
         for (te=0; te<machine->n_tick_entries; te++) {  
                 if (machine->ticks_reset_value[te] < machine->a_few_cycles)  
                         machine->a_few_cycles = machine->ticks_reset_value[te];  
501          }          }
   
         machine->a_few_cycles >>= 1;  
         if (machine->a_few_cycles < 1)  
                 machine->a_few_cycles = 1;  
   
         if (ncpus > 1 && machine->max_random_cycles_per_chunk == 0)  
                 machine->a_few_cycles = 1;  
   
         /*  debug("cpu_run_init(): a_few_cycles = %i\n",  
             machine->a_few_cycles);  */  
   
         /*  For performance measurement:  */  
         gettimeofday(&machine->starttime, NULL);  
         machine->ncycles_since_gettimeofday = 0;  
502  }  }
503    
504    
# Line 584  static void add_cpu_family(int (*family_ Line 513  static void add_cpu_family(int (*family_
513          struct cpu_family *fp, *tmp;          struct cpu_family *fp, *tmp;
514          int res;          int res;
515    
516          fp = malloc(sizeof(struct cpu_family));          CHECK_ALLOCATION(fp = malloc(sizeof(struct cpu_family)));
         if (fp == NULL) {  
                 fprintf(stderr, "add_cpu_family(): out of memory\n");  
                 exit(1);  
         }  
517          memset(fp, 0, sizeof(struct cpu_family));          memset(fp, 0, sizeof(struct cpu_family));
518    
519          /*          /*
# Line 642  struct cpu_family *cpu_family_ptr_by_num Line 567  struct cpu_family *cpu_family_ptr_by_num
567   *  cpu_init():   *  cpu_init():
568   *   *
569   *  Should be called before any other cpu_*() function.   *  Should be called before any other cpu_*() function.
570     *
571     *  This function calls add_cpu_family() for each processor architecture.
572     *  ADD_ALL_CPU_FAMILIES is defined in the config.h file generated by the
573     *  configure script.
574   */   */
575  void cpu_init(void)  void cpu_init(void)
576  {  {
577          /*  Note: These are registered in alphabetic order.  */          ADD_ALL_CPU_FAMILIES;
   
 #ifdef ENABLE_ALPHA  
         add_cpu_family(alpha_cpu_family_init, ARCH_ALPHA);  
 #endif  
   
 #ifdef ENABLE_ARM  
         add_cpu_family(arm_cpu_family_init, ARCH_ARM);  
 #endif  
   
 #ifdef ENABLE_AVR  
         add_cpu_family(avr_cpu_family_init, ARCH_AVR);  
 #endif  
   
 #ifdef ENABLE_HPPA  
         add_cpu_family(hppa_cpu_family_init, ARCH_HPPA);  
 #endif  
   
 #ifdef ENABLE_I960  
         add_cpu_family(i960_cpu_family_init, ARCH_I960);  
 #endif  
   
 #ifdef ENABLE_IA64  
         add_cpu_family(ia64_cpu_family_init, ARCH_IA64);  
 #endif  
   
 #ifdef ENABLE_M68K  
         add_cpu_family(m68k_cpu_family_init, ARCH_M68K);  
 #endif  
   
 #ifdef ENABLE_MIPS  
         add_cpu_family(mips_cpu_family_init, ARCH_MIPS);  
 #endif  
   
 #ifdef ENABLE_PPC  
         add_cpu_family(ppc_cpu_family_init, ARCH_PPC);  
 #endif  
   
 #ifdef ENABLE_SH  
         add_cpu_family(sh_cpu_family_init, ARCH_SH);  
 #endif  
   
 #ifdef ENABLE_SPARC  
         add_cpu_family(sparc_cpu_family_init, ARCH_SPARC);  
 #endif  
   
 #ifdef ENABLE_X86  
         add_cpu_family(x86_cpu_family_init, ARCH_X86);  
 #endif  
578  }  }
579    

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

  ViewVC Help
Powered by ViewVC 1.1.26