/[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 10 by dpavlin, Mon Oct 8 16:18:27 2007 UTC revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu.c,v 1.298 2005/06/27 10:43:16 debug Exp $   *  $Id: cpu.c,v 1.316 2005/08/16 05:37:09 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 37  Line 37 
37    
38  #include "cpu.h"  #include "cpu.h"
39  #include "machine.h"  #include "machine.h"
40    #include "memory.h"
41  #include "misc.h"  #include "misc.h"
42    
43    
# Line 71  struct cpu *cpu_new(struct memory *mem, Line 72  struct cpu *cpu_new(struct memory *mem,
72                  exit(1);                  exit(1);
73          }          }
74    
75          cpu = malloc(sizeof(struct cpu));          cpu = zeroed_alloc(sizeof(struct cpu));
         if (cpu == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
76    
         memset(cpu, 0, sizeof(struct cpu));  
77          cpu->memory_rw          = NULL;          cpu->memory_rw          = NULL;
78          cpu->name               = cpu_type_name;          cpu->name               = cpu_type_name;
79          cpu->mem                = mem;          cpu->mem                = mem;
# Line 87  struct cpu *cpu_new(struct memory *mem, Line 83  struct cpu *cpu_new(struct memory *mem,
83          cpu->bootstrap_cpu_flag = 0;          cpu->bootstrap_cpu_flag = 0;
84          cpu->running            = 0;          cpu->running            = 0;
85    
86            cpu_create_or_reset_tc(cpu);
87    
88          fp = first_cpu_family;          fp = first_cpu_family;
89    
90          while (fp != NULL) {          while (fp != NULL) {
# Line 231  int cpu_interrupt_ack(struct cpu *cpu, u Line 229  int cpu_interrupt_ack(struct cpu *cpu, u
229    
230    
231  /*  /*
232     *  cpu_functioncall_trace():
233     *
234     *  This function should be called if machine->show_trace_tree is enabled, and
235     *  a function call is being made. f contains the address of the function.
236     */
237    void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
238    {
239            int i, n_args = -1;
240            char *symbol;
241            uint64_t offset;
242    
243            if (cpu->machine->ncpus > 1)
244                    fatal("cpu%i:\t", cpu->cpu_id);
245    
246            cpu->trace_tree_depth ++;
247            for (i=0; i<cpu->trace_tree_depth; i++)
248                    fatal("  ");
249    
250            fatal("<");
251            symbol = get_symbol_name_and_n_args(&cpu->machine->symbol_context,
252                f, &offset, &n_args);
253            if (symbol != NULL)
254                    fatal("%s", symbol);
255            else {
256                    if (cpu->is_32bit)
257                            fatal("0x%08x", (int)f);
258                    else
259                            fatal("0x%llx", (long long)f);
260            }
261            fatal("(");
262    
263            if (cpu->machine->cpu_family->functioncall_trace != NULL)
264                    cpu->machine->cpu_family->functioncall_trace(cpu, f, n_args);
265    
266            fatal(")>\n");
267    }
268    
269    
270    /*
271     *  cpu_functioncall_trace_return():
272     *
273     *  This function should be called if machine->show_trace_tree is enabled, and
274     *  a function is being returned from.
275     *
276     *  TODO: Print return value? This could be implemented similar to the
277     *  cpu->functioncall_trace function call above.
278     */
279    void cpu_functioncall_trace_return(struct cpu *cpu)
280    {
281            cpu->trace_tree_depth --;
282            if (cpu->trace_tree_depth < 0)
283                    cpu->trace_tree_depth = 0;
284    }
285    
286    
287    /*
288     *  cpu_create_or_reset_tc():
289     *
290     *  Create the translation cache in memory (ie allocate memory for it), if
291     *  necessary, and then reset it to an initial state.
292     */
293    void cpu_create_or_reset_tc(struct cpu *cpu)
294    {
295            if (cpu->translation_cache == NULL)
296                    cpu->translation_cache = zeroed_alloc(DYNTRANS_CACHE_SIZE +
297                        DYNTRANS_CACHE_MARGIN);
298    
299            /*  Create an empty table at the beginning of the translation cache:  */
300            memset(cpu->translation_cache, 0, sizeof(uint32_t)
301                * N_BASE_TABLE_ENTRIES);
302    
303            cpu->translation_cache_cur_ofs =
304                N_BASE_TABLE_ENTRIES * sizeof(uint32_t);
305    
306            /*
307             *  There might be other translation pointers that still point to
308             *  within the translation_cache region. Let's invalidate those too:
309             */
310            if (cpu->invalidate_code_translation_caches != NULL)
311                    cpu->invalidate_code_translation_caches(cpu);
312    }
313    
314    
315    /*
316   *  cpu_run():   *  cpu_run():
317   *   *
318   *  Run instructions on all CPUs in this machine, for a "medium duration"   *  Run instructions on all CPUs in this machine, for a "medium duration"
# Line 304  void cpu_list_available_types(void) Line 386  void cpu_list_available_types(void)
386   *  Shuts down all CPUs in a machine when ending a simulation. (This function   *  Shuts down all CPUs in a machine when ending a simulation. (This function
387   *  should only need to be called once for each machine.)   *  should only need to be called once for each machine.)
388   */   */
389  void cpu_run_deinit(struct emul *emul, struct machine *machine)  void cpu_run_deinit(struct machine *machine)
390  {  {
391          int te;          int te;
392    
# Line 343  void cpu_run_deinit(struct emul *emul, s Line 425  void cpu_run_deinit(struct emul *emul, s
425  void cpu_show_cycles(struct machine *machine, int forced)  void cpu_show_cycles(struct machine *machine, int forced)
426  {  {
427          uint64_t offset, pc;          uint64_t offset, pc;
         int is_32bit = 0, instrs_per_cycle = 1;  
428          char *symbol;          char *symbol;
429          int64_t mseconds, ninstrs;          int64_t mseconds, ninstrs, is, avg;
430          struct timeval tv;          struct timeval tv;
431          int h, m, s, ms, d;          int h, m, s, ms, d, instrs_per_cycle = 1;
432    
433          static int64_t mseconds_last = 0;          static int64_t mseconds_last = 0;
434          static int64_t ninstrs_last = -1;          static int64_t ninstrs_last = -1;
435    
436          switch (machine->arch) {          switch (machine->arch) {
437          case ARCH_MIPS:          case ARCH_MIPS:
                 if (machine->cpus[machine->bootstrap_cpu]->cd.mips.  
                     cpu_type.isa_level < 3 || machine->cpus[machine->  
                     bootstrap_cpu]->cd.mips.cpu_type.isa_level == 32)  
                         is_32bit = 1;  
438                  instrs_per_cycle = machine->cpus[machine->bootstrap_cpu]->                  instrs_per_cycle = machine->cpus[machine->bootstrap_cpu]->
439                      cd.mips.cpu_type.instrs_per_cycle;                      cd.mips.cpu_type.instrs_per_cycle;
440                  break;                  break;
         case ARCH_ARM:  
                 is_32bit = 1;  
                 break;  
441          }          }
442    
443          pc = machine->cpus[machine->bootstrap_cpu]->pc;          pc = machine->cpus[machine->bootstrap_cpu]->pc;
# Line 399  void cpu_show_cycles(struct machine *mac Line 473  void cpu_show_cycles(struct machine *mac
473                              cur_cycles_per_second) / 16;                              cur_cycles_per_second) / 16;
474                  }                  }
475    
476                  debug("[ updating emulated_hz to %lli Hz ]\n",                  /*  debug("[ updating emulated_hz to %lli Hz ]\n",
477                      (long long)machine->emulated_hz);                      (long long)machine->emulated_hz);  */
478          }          }
479    
480    
# Line 427  void cpu_show_cycles(struct machine *mac Line 501  void cpu_show_cycles(struct machine *mac
501          }          }
502    
503          /*  Instructions per second, and average so far:  */          /*  Instructions per second, and average so far:  */
504          printf("; i/s=%lli avg=%lli; ",          is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last);
505              (long long) ((long long)1000 * (ninstrs-ninstrs_last)          avg = (long long)1000 * ninstrs / mseconds;
506                  / (mseconds-mseconds_last)),          if (is < 0)
507              (long long) ((long long)1000 * ninstrs / mseconds));                  is = 0;
508            if (avg < 0)
509                    avg = 0;
510            printf("; i/s=%lli avg=%lli", (long long)is, (long long)avg);
511    
512          symbol = get_symbol_name(&machine->symbol_context, pc, &offset);          symbol = get_symbol_name(&machine->symbol_context, pc, &offset);
513    
514          if (is_32bit)          if (machine->ncpus == 1) {
515                  printf("pc=0x%08x", (int)pc);                  if (machine->cpus[machine->bootstrap_cpu]->is_32bit)
516          else                          printf("; pc=0x%08x", (int)pc);
517                  printf("pc=0x%016llx", (long long)pc);                  else
518                            printf("; pc=0x%016llx", (long long)pc);
519            }
520    
521          if (symbol != NULL)          if (symbol != NULL)
522                  printf(" <%s>", symbol);                  printf(" <%s>", symbol);
# Line 455  do_return: Line 534  do_return:
534   *  Prepare to run instructions on all CPUs in this machine. (This function   *  Prepare to run instructions on all CPUs in this machine. (This function
535   *  should only need to be called once for each machine.)   *  should only need to be called once for each machine.)
536   */   */
537  void cpu_run_init(struct emul *emul, struct machine *machine)  void cpu_run_init(struct machine *machine)
538  {  {
539          int ncpus = machine->ncpus;          int ncpus = machine->ncpus;
540          int te;          int te;
# Line 565  struct cpu_family *cpu_family_ptr_by_num Line 644  struct cpu_family *cpu_family_ptr_by_num
644  void cpu_init(void)  void cpu_init(void)
645  {  {
646          /*  Note: These are registered in alphabetic order.  */          /*  Note: These are registered in alphabetic order.  */
647    
648    #ifdef ENABLE_ALPHA
649            add_cpu_family(alpha_cpu_family_init, ARCH_ALPHA);
650    #endif
651    
652    #ifdef ENABLE_ARM
653          add_cpu_family(arm_cpu_family_init, ARCH_ARM);          add_cpu_family(arm_cpu_family_init, ARCH_ARM);
654    #endif
655    
656    #ifdef ENABLE_IA64
657            add_cpu_family(ia64_cpu_family_init, ARCH_IA64);
658    #endif
659    
660    #ifdef ENABLE_M68K
661            add_cpu_family(m68k_cpu_family_init, ARCH_M68K);
662    #endif
663    
664    #ifdef ENABLE_MIPS
665          add_cpu_family(mips_cpu_family_init, ARCH_MIPS);          add_cpu_family(mips_cpu_family_init, ARCH_MIPS);
666    #endif
667    
668    #ifdef ENABLE_PPC
669          add_cpu_family(ppc_cpu_family_init, ARCH_PPC);          add_cpu_family(ppc_cpu_family_init, ARCH_PPC);
670          add_cpu_family(urisc_cpu_family_init, ARCH_URISC);  #endif
671    
672    #ifdef ENABLE_SPARC
673            add_cpu_family(sparc_cpu_family_init, ARCH_SPARC);
674    #endif
675    
676    #ifdef ENABLE_X86
677          add_cpu_family(x86_cpu_family_init, ARCH_X86);          add_cpu_family(x86_cpu_family_init, ARCH_X86);
678    #endif
679  }  }
680    

Legend:
Removed from v.10  
changed lines
  Added in v.12

  ViewVC Help
Powered by ViewVC 1.1.26