/[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 31 by dpavlin, Mon Oct 8 16:20:40 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu.c,v 1.349 2006/07/26 23:21:47 debug Exp $   *  $Id: cpu.c,v 1.361 2006/10/25 09:24:05 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 40  Line 40 
40  #include "machine.h"  #include "machine.h"
41  #include "memory.h"  #include "memory.h"
42  #include "misc.h"  #include "misc.h"
43    #include "settings.h"
44    
45    
46  static struct cpu_family *first_cpu_family = NULL;  static struct cpu_family *first_cpu_family = NULL;
# Line 50  static struct cpu_family *first_cpu_fami Line 51  static struct cpu_family *first_cpu_fami
51   *   *
52   *  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
53   *  CPU family recognizes the cpu_type_name.   *  CPU family recognizes the cpu_type_name.
54     *
55     *  If there was no match, NULL is returned. Otherwise, a pointer to an
56     *  initialized cpu struct is returned.
57   */   */
58  struct cpu *cpu_new(struct memory *mem, struct machine *machine,  struct cpu *cpu_new(struct memory *mem, struct machine *machine,
59          int cpu_id, char *name)          int cpu_id, char *name)
# Line 57  struct cpu *cpu_new(struct memory *mem, Line 61  struct cpu *cpu_new(struct memory *mem,
61          struct cpu *cpu;          struct cpu *cpu;
62          struct cpu_family *fp;          struct cpu_family *fp;
63          char *cpu_type_name;          char *cpu_type_name;
64            char tmpstr[30];
65    
66          if (name == NULL) {          if (name == NULL) {
67                  fprintf(stderr, "cpu_new(): cpu name = NULL?\n");                  fprintf(stderr, "cpu_new(): cpu name = NULL?\n");
# Line 71  struct cpu *cpu_new(struct memory *mem, Line 76  struct cpu *cpu_new(struct memory *mem,
76    
77          cpu = zeroed_alloc(sizeof(struct cpu));          cpu = zeroed_alloc(sizeof(struct cpu));
78    
79          cpu->memory_rw          = NULL;          cpu->memory_rw  = NULL;
80          cpu->name               = cpu_type_name;          cpu->name       = cpu_type_name;
81          cpu->mem                = mem;          cpu->mem        = mem;
82          cpu->machine            = machine;          cpu->machine    = machine;
83          cpu->cpu_id             = cpu_id;          cpu->cpu_id     = cpu_id;
84          cpu->byte_order         = EMUL_LITTLE_ENDIAN;          cpu->byte_order = EMUL_UNDEFINED_ENDIAN;
85          cpu->running            = 0;          cpu->running    = 0;
86    
87            /*  Create settings, and attach to the machine:  */
88            cpu->settings = settings_new();
89            snprintf(tmpstr, sizeof(tmpstr), "cpu[%i]", cpu_id);
90            settings_add(machine->settings, tmpstr, 1,
91                SETTINGS_TYPE_SUBSETTINGS, 0, cpu->settings);
92    
93            settings_add(cpu->settings, "name", 0, SETTINGS_TYPE_STRING,
94                SETTINGS_FORMAT_STRING, (void *) &cpu->name);
95            settings_add(cpu->settings, "running", 0, SETTINGS_TYPE_INT,
96                SETTINGS_FORMAT_YESNO, (void *) &cpu->running);
97    
98          cpu_create_or_reset_tc(cpu);          cpu_create_or_reset_tc(cpu);
99    
# Line 107  struct cpu *cpu_new(struct memory *mem, Line 123  struct cpu *cpu_new(struct memory *mem,
123    
124          fp->init_tables(cpu);          fp->init_tables(cpu);
125    
126            if (cpu->byte_order == EMUL_UNDEFINED_ENDIAN) {
127                    fatal("\ncpu_new(): Internal bug: Endianness not set.\n");
128                    exit(1);
129            }
130    
131          return cpu;          return cpu;
132  }  }
133    
134    
135  /*  /*
136     *  cpu_destroy():
137     *
138     *  Destroy a cpu object.
139     */
140    void cpu_destroy(struct cpu *cpu)
141    {
142            settings_remove(cpu->settings, "name");
143            settings_remove(cpu->settings, "running");
144    
145            /*  Remove any remaining level-1 settings:  */
146            settings_remove_all(cpu->settings);
147    
148            settings_destroy(cpu->settings);
149    
150            /*  TODO: This assumes that zeroed_alloc() actually succeeded
151                with using mmap(), and not malloc()!  */
152            munmap((void *)cpu, sizeof(struct cpu));
153    }
154    
155    
156    /*
157   *  cpu_tlbdump():   *  cpu_tlbdump():
158   *   *
159   *  Called from the debugger to dump the TLB in a readable format.   *  Called from the debugger to dump the TLB in a readable format.
# Line 130  void cpu_tlbdump(struct machine *m, int Line 172  void cpu_tlbdump(struct machine *m, int
172    
173    
174  /*  /*
  *  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);  
 }  
   
   
 /*  
175   *  cpu_disassemble_instr():   *  cpu_disassemble_instr():
176   *   *
177   *  Convert an instruction word into human readable format, for instruction   *  Convert an instruction word into human readable format, for instruction
# Line 409  void cpu_run_deinit(struct machine *mach Line 435  void cpu_run_deinit(struct machine *mach
435  /*  /*
436   *  cpu_show_cycles():   *  cpu_show_cycles():
437   *   *
438   *  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
439   *  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.  
440   */   */
441  void cpu_show_cycles(struct machine *machine, int forced)  void cpu_show_cycles(struct machine *machine, int forced)
442  {  {
# Line 420  void cpu_show_cycles(struct machine *mac Line 444  void cpu_show_cycles(struct machine *mac
444          char *symbol;          char *symbol;
445          int64_t mseconds, ninstrs, is, avg;          int64_t mseconds, ninstrs, is, avg;
446          struct timeval tv;          struct timeval tv;
447          int h, m, s, ms, d;          struct cpu *cpu = machine->cpus[machine->bootstrap_cpu];
448    
449          static int64_t mseconds_last = 0;          static int64_t mseconds_last = 0;
450          static int64_t ninstrs_last = -1;          static int64_t ninstrs_last = -1;
451    
452          pc = machine->cpus[machine->bootstrap_cpu]->pc;          pc = cpu->pc;
453    
454          gettimeofday(&tv, NULL);          gettimeofday(&tv, NULL);
455          mseconds = (tv.tv_sec - machine->starttime.tv_sec) * 1000          mseconds = (tv.tv_sec - machine->starttime.tv_sec) * 1000
# Line 439  void cpu_show_cycles(struct machine *mac Line 463  void cpu_show_cycles(struct machine *mac
463    
464          ninstrs = machine->ninstrs_since_gettimeofday;          ninstrs = machine->ninstrs_since_gettimeofday;
465    
         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);  
   
                 /*  fatal("[ CYCLES PER SECOND = %"PRIi64" ]\n",  
                     cur_cycles_per_second);  */  
   
                 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;  
                 }  
   
                 /*  fatal("[ updating emulated_hz to %"PRIi64" Hz ]\n",  
                     machine->emulated_hz);  */  
         }  
   
   
466          /*  RETURN here, unless show_nr_of_instructions (-N) is turned on:  */          /*  RETURN here, unless show_nr_of_instructions (-N) is turned on:  */
467          if (!machine->show_nr_of_instructions && !forced)          if (!machine->show_nr_of_instructions && !forced)
468                  goto do_return;                  goto do_return;
469    
470          printf("[ %"PRIi64" instrs", (int64_t)machine->ninstrs);          printf("[ %"PRIi64" instrs", (int64_t)machine->ninstrs);
471    
         if (!machine->automatic_clock_adjustment) {  
                 d = machine->emulated_hz / 1000;  
                 if (d < 1)  
                         d = 1;  
                 ms = machine->ninstrs / 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);  
         }  
   
472          /*  Instructions per second, and average so far:  */          /*  Instructions per second, and average so far:  */
473          is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last);          is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last);
474          avg = (long long)1000 * ninstrs / mseconds;          avg = (long long)1000 * ninstrs / mseconds;
# Line 493  void cpu_show_cycles(struct machine *mac Line 476  void cpu_show_cycles(struct machine *mac
476                  is = 0;                  is = 0;
477          if (avg < 0)          if (avg < 0)
478                  avg = 0;                  avg = 0;
479          printf("; i/s=%"PRIi64" avg=%"PRIi64, is, avg);  
480            if (cpu->has_been_idling) {
481                    printf("; idling");
482                    cpu->has_been_idling = 0;
483            } else
484                    printf("; i/s=%"PRIi64" avg=%"PRIi64, is, avg);
485    
486          symbol = get_symbol_name(&machine->symbol_context, pc, &offset);          symbol = get_symbol_name(&machine->symbol_context, pc, &offset);
487    
488          if (machine->ncpus == 1) {          if (machine->ncpus == 1) {
489                  if (machine->cpus[machine->bootstrap_cpu]->is_32bit)                  if (cpu->is_32bit)
490                          printf("; pc=0x%08"PRIx32, (uint32_t) pc);                          printf("; pc=0x%08"PRIx32, (uint32_t) pc);
491                  else                  else
492                          printf("; pc=0x%016"PRIx64, (uint64_t) pc);                          printf("; pc=0x%016"PRIx64, (uint64_t) pc);
# Line 601  struct cpu_family *cpu_family_ptr_by_num Line 589  struct cpu_family *cpu_family_ptr_by_num
589   *  cpu_init():   *  cpu_init():
590   *   *
591   *  Should be called before any other cpu_*() function.   *  Should be called before any other cpu_*() function.
592     *
593     *  TODO: Make this nicer by moving out the conditional stuff to
594     *  an automagically generated file? Or a define in config.h?
595   */   */
596  void cpu_init(void)  void cpu_init(void)
597  {  {
# Line 618  void cpu_init(void) Line 609  void cpu_init(void)
609          add_cpu_family(avr_cpu_family_init, ARCH_AVR);          add_cpu_family(avr_cpu_family_init, ARCH_AVR);
610  #endif  #endif
611    
612    #ifdef ENABLE_AVR32
613            add_cpu_family(avr32_cpu_family_init, ARCH_AVR32);
614    #endif
615    
616    #ifdef ENABLE_RCA180X
617            add_cpu_family(rca180x_cpu_family_init, ARCH_RCA180X);
618    #endif
619    
620  #ifdef ENABLE_HPPA  #ifdef ENABLE_HPPA
621          add_cpu_family(hppa_cpu_family_init, ARCH_HPPA);          add_cpu_family(hppa_cpu_family_init, ARCH_HPPA);
622  #endif  #endif

Legend:
Removed from v.31  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26