/[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 41 by dpavlin, Mon Oct 8 16:22:11 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu.c,v 1.376 2007/04/19 15:18:15 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 39  Line 39 
39  #include "cpu.h"  #include "cpu.h"
40  #include "machine.h"  #include "machine.h"
41  #include "memory.h"  #include "memory.h"
 #include "misc.h"  
42  #include "settings.h"  #include "settings.h"
43    #include "timer.h"
44    
45    
46  extern size_t dyntrans_cache_size;  extern size_t dyntrans_cache_size;
# Line 71  struct cpu *cpu_new(struct memory *mem, Line 71  struct cpu *cpu_new(struct memory *mem,
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->path = malloc(strlen(machine->path) + 15);          CHECK_ALLOCATION(cpu->path = malloc(strlen(machine->path) + 15));
         if (cpu->path == NULL) {  
                 fprintf(stderr, "cpu_new(): out of memory\n");  
                 exit(1);  
         }  
79          snprintf(cpu->path, strlen(machine->path) + 15,          snprintf(cpu->path, strlen(machine->path) + 15,
80              "%s.cpu[%i]", machine->path, cpu_id);              "%s.cpu[%i]", machine->path, cpu_id);
81    
# Line 95  struct cpu *cpu_new(struct memory *mem, Line 87  struct cpu *cpu_new(struct memory *mem,
87          cpu->byte_order = EMUL_UNDEFINED_ENDIAN;          cpu->byte_order = EMUL_UNDEFINED_ENDIAN;
88          cpu->running    = 0;          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:  */          /*  Create settings, and attach to the machine:  */
93          cpu->settings = settings_new();          cpu->settings = settings_new();
94          snprintf(tmpstr, sizeof(tmpstr), "cpu[%i]", cpu_id);          snprintf(tmpstr, sizeof(tmpstr), "cpu[%i]", cpu_id);
# Line 103  struct cpu *cpu_new(struct memory *mem, Line 97  struct cpu *cpu_new(struct memory *mem,
97    
98          settings_add(cpu->settings, "name", 0, SETTINGS_TYPE_STRING,          settings_add(cpu->settings, "name", 0, SETTINGS_TYPE_STRING,
99              SETTINGS_FORMAT_STRING, (void *) &cpu->name);              SETTINGS_FORMAT_STRING, (void *) &cpu->name);
100          settings_add(cpu->settings, "running", 0, SETTINGS_TYPE_INT,          settings_add(cpu->settings, "running", 0, SETTINGS_TYPE_UINT8,
101              SETTINGS_FORMAT_YESNO, (void *) &cpu->running);              SETTINGS_FORMAT_YESNO, (void *) &cpu->running);
102    
103          cpu_create_or_reset_tc(cpu);          cpu_create_or_reset_tc(cpu);
# Line 150  struct cpu *cpu_new(struct memory *mem, Line 144  struct cpu *cpu_new(struct memory *mem,
144   */   */
145  void cpu_destroy(struct cpu *cpu)  void cpu_destroy(struct cpu *cpu)
146  {  {
147            if (cpu->sampling_timer != NULL)
148                    timer_remove(cpu->sampling_timer);
149    
150          settings_remove(cpu->settings, "name");          settings_remove(cpu->settings, "name");
151          settings_remove(cpu->settings, "running");          settings_remove(cpu->settings, "running");
152    
# Line 229  void cpu_register_dump(struct machine *m Line 226  void cpu_register_dump(struct machine *m
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)
# Line 297  void cpu_create_or_reset_tc(struct cpu * Line 301  void cpu_create_or_reset_tc(struct cpu *
301          if (cpu->translation_cache == NULL) {          if (cpu->translation_cache == NULL) {
302                  cpu->translation_cache = zeroed_alloc(s);                  cpu->translation_cache = zeroed_alloc(s);
303    
 #ifdef NATIVE_CODE_GENERATION  
304                  if (native_code_translation_enabled) {                  if (native_code_translation_enabled) {
305                          mprotect(cpu->translation_cache, s,                          mprotect(cpu->translation_cache, s,
306                              PROT_READ | PROT_WRITE | PROT_EXEC);                              PROT_READ | PROT_WRITE | PROT_EXEC);
307                  }                  }
 #endif  
308          }          }
309    
 #ifdef NATIVE_CODE_GENERATION  
         if (native_code_translation_enabled && cpu->inr.inr_entries == NULL)  
                 cpu->inr.inr_entries = zeroed_alloc(  
                     sizeof(struct inr_entry) * INR_MAX_ENTRIES);  
   
         cpu->inr.nr_inr_entries_used = 0;  
 #endif  
   
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)
312              * N_BASE_TABLE_ENTRIES);              * N_BASE_TABLE_ENTRIES);
# Line 396  void cpu_run_deinit(struct machine *mach Line 390  void cpu_run_deinit(struct machine *mach
390           *  TODO: This should be refactored when redesigning the mainbus           *  TODO: This should be refactored when redesigning the mainbus
391           *        concepts!           *        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          if (machine->show_nr_of_instructions)          if (machine->show_nr_of_instructions)
# Line 430  void cpu_show_cycles(struct machine *mac Line 424  void cpu_show_cycles(struct machine *mac
424          pc = cpu->pc;          pc = 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 439  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->ninstrs_since_gettimeofday;          ninstrs = cpu->ninstrs_since_gettimeofday;
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("[ %"PRIi64" instrs", (int64_t)machine->ninstrs);          printf("[ %"PRIi64" instrs", (int64_t) cpu->ninstrs);
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 470  void cpu_show_cycles(struct machine *mac Line 464  void cpu_show_cycles(struct machine *mac
464                          printf("; pc=0x%016"PRIx64, (uint64_t) 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 488  do_return: Line 487  do_return:
487   */   */
488  void cpu_run_init(struct machine *machine)  void cpu_run_init(struct machine *machine)
489  {  {
490          machine->ninstrs_flush = 0;          int i;
491          machine->ninstrs = 0;          for (i=0; i<machine->ncpus; i++) {
492          machine->ninstrs_show = 0;                  struct cpu *cpu = machine->cpus[i];
493    
494          /*  For performance measurement:  */                  cpu->ninstrs_flush = 0;
495          gettimeofday(&machine->starttime, NULL);                  cpu->ninstrs = 0;
496          machine->ninstrs_since_gettimeofday = 0;                  cpu->ninstrs_show = 0;
497    
498                    /*  For performance measurement:  */
499                    gettimeofday(&cpu->starttime, NULL);
500                    cpu->ninstrs_since_gettimeofday = 0;
501            }
502  }  }
503    
504    
# Line 509  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 568  struct cpu_family *cpu_family_ptr_by_num Line 568  struct cpu_family *cpu_family_ptr_by_num
568   *   *
569   *  Should be called before any other cpu_*() function.   *  Should be called before any other cpu_*() function.
570   *   *
571   *  TODO: Make this nicer by moving out the conditional stuff to   *  This function calls add_cpu_family() for each processor architecture.
572   *  an automagically generated file? Or a define in config.h?   *  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_M88K  
         add_cpu_family(m88k_cpu_family_init, ARCH_M88K);  
 #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  
578  }  }
579    

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

  ViewVC Help
Powered by ViewVC 1.1.26