/[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 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 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.c,v 1.316 2005/08/16 05:37:09 debug Exp $   *  $Id: cpu.c,v 1.329 2006/01/16 04:48:08 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"
# Line 43  Line 44 
44    
45  extern int quiet_mode;  extern int quiet_mode;
46  extern int show_opcode_statistics;  extern int show_opcode_statistics;
47    extern int dyntrans_backend_enable;
48    
49  static struct cpu_family *first_cpu_family = NULL;  static struct cpu_family *first_cpu_family = NULL;
50    
# Line 181  int cpu_disassemble_instr(struct machine Line 182  int cpu_disassemble_instr(struct machine
182   *   *
183   *  Dump cpu registers in a relatively readable format.   *  Dump cpu registers in a relatively readable format.
184   *   *
185   *  gprs: set to non-zero to dump GPRs. (CPU dependant.)   *  gprs: set to non-zero to dump GPRs. (CPU dependent.)
186   *  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.)
187   */   */
188  void cpu_register_dump(struct machine *m, struct cpu *cpu,  void cpu_register_dump(struct machine *m, struct cpu *cpu,
189          int gprs, int coprocs)          int gprs, int coprocs)
# Line 244  void cpu_functioncall_trace(struct cpu * Line 245  void cpu_functioncall_trace(struct cpu *
245                  fatal("cpu%i:\t", cpu->cpu_id);                  fatal("cpu%i:\t", cpu->cpu_id);
246    
247          cpu->trace_tree_depth ++;          cpu->trace_tree_depth ++;
248            if (cpu->trace_tree_depth > 100)
249                    cpu->trace_tree_depth = 100;
250          for (i=0; i<cpu->trace_tree_depth; i++)          for (i=0; i<cpu->trace_tree_depth; i++)
251                  fatal("  ");                  fatal("  ");
252    
# Line 292  void cpu_functioncall_trace_return(struc Line 295  void cpu_functioncall_trace_return(struc
295   */   */
296  void cpu_create_or_reset_tc(struct cpu *cpu)  void cpu_create_or_reset_tc(struct cpu *cpu)
297  {  {
298          if (cpu->translation_cache == NULL)          size_t s = DYNTRANS_CACHE_SIZE + DYNTRANS_CACHE_MARGIN;
299                  cpu->translation_cache = zeroed_alloc(DYNTRANS_CACHE_SIZE +  
300                      DYNTRANS_CACHE_MARGIN);          if (cpu->translation_cache == NULL) {
301    #ifdef DYNTRANS_BACKEND
302                    if (dyntrans_backend_enable) {
303                            cpu->translation_cache = (unsigned char *) mmap(NULL,
304                                s, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON |
305                                MAP_PRIVATE, -1, 0);
306                            if (cpu->translation_cache == NULL) {
307                                    dyntrans_backend_enable = 0;
308                                    fatal("%\n%  WARNING! Dyntrans backend disabled"
309                                        ", because mmap() failed.\n%\n");
310                            }
311                    }
312    #endif
313                    if (cpu->translation_cache == NULL)
314                            cpu->translation_cache = zeroed_alloc(s);
315            }
316    
317          /*  Create an empty table at the beginning of the translation cache:  */          /*  Create an empty table at the beginning of the translation cache:  */
318          memset(cpu->translation_cache, 0, sizeof(uint32_t)          memset(cpu->translation_cache, 0, sizeof(uint32_t)
# Line 307  void cpu_create_or_reset_tc(struct cpu * Line 325  void cpu_create_or_reset_tc(struct cpu *
325           *  There might be other translation pointers that still point to           *  There might be other translation pointers that still point to
326           *  within the translation_cache region. Let's invalidate those too:           *  within the translation_cache region. Let's invalidate those too:
327           */           */
328          if (cpu->invalidate_code_translation_caches != NULL)          if (cpu->invalidate_code_translation != NULL)
329                  cpu->invalidate_code_translation_caches(cpu);                  cpu->invalidate_code_translation(cpu, 0, INVALIDATE_ALL);
330  }  }
331    
332    
# Line 334  int cpu_run(struct emul *emul, struct ma Line 352  int cpu_run(struct emul *emul, struct ma
352   *  cpu_dumpinfo():   *  cpu_dumpinfo():
353   *   *
354   *  Dumps info about a CPU using debug(). "cpu0: CPUNAME, running" (or similar)   *  Dumps info about a CPU using debug(). "cpu0: CPUNAME, running" (or similar)
355   *  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.
356   */   */
357  void cpu_dumpinfo(struct machine *m, struct cpu *cpu)  void cpu_dumpinfo(struct machine *m, struct cpu *cpu)
358  {  {
# Line 356  void cpu_dumpinfo(struct machine *m, str Line 374  void cpu_dumpinfo(struct machine *m, str
374  void cpu_list_available_types(void)  void cpu_list_available_types(void)
375  {  {
376          struct cpu_family *fp;          struct cpu_family *fp;
377          int iadd = 4;          int iadd = DEBUG_INDENTATION;
378    
379          fp = first_cpu_family;          fp = first_cpu_family;
380    
# Line 497  void cpu_show_cycles(struct machine *mac Line 515  void cpu_show_cycles(struct machine *mac
515                  s = ms / 1000;                  s = ms / 1000;
516                  ms -= 1000 * s;                  ms -= 1000 * s;
517    
518                  printf("emulated time = %02i:%02i:%02i.%03i; ", h, m, s, ms);                  printf(", emulated time = %02i:%02i:%02i.%03i; ", h, m, s, ms);
519          }          }
520    
521          /*  Instructions per second, and average so far:  */          /*  Instructions per second, and average so far:  */
# Line 636  struct cpu_family *cpu_family_ptr_by_num Line 654  struct cpu_family *cpu_family_ptr_by_num
654  }  }
655    
656    
657    #ifdef DYNTRANS_BACKEND
658    /*
659     *  cpu_dtb_add_fixup():
660     *
661     *  Add a fixup entry to a currently ongoing dyntrans backend translation.
662     */
663    void cpu_dtb_add_fixup(struct cpu *cpu, int type, void *addr, size_t data)
664    {
665            struct dtb_fixup *fixup = malloc(sizeof (struct dtb_fixup));
666            if (fixup == NULL) {
667                    fprintf(stderr, "out of memory\n"),
668                    exit(1);
669            }
670    
671            /*  memset(fixup, 0, sizeof(struct dtb_fixup));  */
672    
673            fixup->next = cpu->translation_context.fixups;
674            cpu->translation_context.fixups = fixup;
675    
676            fixup->type = type;
677            fixup->addr = addr;
678            fixup->data = data;
679    
680            /*  printf("{ fixup added: host addr %p, data=%p }\n", addr,
681                (void *)data);  */
682    }
683    
684    
685    /*
686     *  cpu_dtb_do_fixups():
687     *
688     *  This function should be called when a chunk of code has been translated,
689     *  and post-fixup is to be applied (i.e. add data which for some reason was
690     *  not included in the generated code).
691     *
692     *  If no fixup is necessary for a specific host platform, then it still needs
693     *  an empty do_fixups routine here (just set done = 1).
694     */
695    void cpu_dtb_do_fixups(struct cpu *cpu)
696    {
697            for (;;) {
698                    int done = 0;
699                    size_t omit_addr;
700    
701                    struct dtb_fixup *fixup = cpu->translation_context.fixups;
702                    if (fixup == NULL)
703                            break;
704    
705                    cpu->translation_context.fixups = fixup->next;
706    
707    #ifdef DYNTRANS_BACKEND_ALPHA
708                    /*  Add the data at the end of the new translation:  */
709    /*printf("%p %p\n", fixup->addr, fixup->data);*/
710                    omit_addr = (size_t)cpu->translation_context.p -
711                        (size_t)cpu->translation_context.translation_buffer;
712    /*printf("omit_addr = %016llx\n", (long long)omit_addr);*/
713                    omit_addr = ((omit_addr - 1) | (sizeof(uint64_t) - 1)) + 1;
714    /*printf("omit_addr = %016llx\n", (long long)omit_addr);*/
715                    {
716                            uint64_t *x = (void *)(omit_addr + (size_t)cpu->
717                                translation_context.translation_buffer);
718                            uint32_t *fixup_instr = (void *)fixup->addr;
719                            size_t ofs = omit_addr;
720                            if (ofs > 0x7fff) {
721                                    fatal("Alpha fixup > 0x7fff!\n");
722                                    exit(1);
723                            }
724                            *x = fixup->data;
725    /*printf("orig instr = 0x%08x\n", *fixup_instr);*/
726                            (*fixup_instr) &= ~0xffff;
727                            (*fixup_instr) |= ofs;
728    /*printf("new instr = 0x%08x\n", *fixup_instr);*/
729                    }
730                    omit_addr += sizeof(uint64_t);
731                    cpu->translation_context.p = (void *)
732                        ((size_t)cpu->translation_context.translation_buffer
733                        + omit_addr);
734                    done = 1;
735    #endif  /*  DYNTRANS_BACKEND_ALPHA  */
736    
737                    if (!done)
738                            fatal("!!! cpu_dtb_do_fixups() not implemented yet"
739                                " for this host architecture!\n");
740            }
741    }
742    
743    #endif  /*  DYNTRANS_BACKEND  */
744    
745    
746  /*  /*
747   *  cpu_init():   *  cpu_init():
748   *   *
# Line 653  void cpu_init(void) Line 760  void cpu_init(void)
760          add_cpu_family(arm_cpu_family_init, ARCH_ARM);          add_cpu_family(arm_cpu_family_init, ARCH_ARM);
761  #endif  #endif
762    
763    #ifdef ENABLE_AVR
764            add_cpu_family(avr_cpu_family_init, ARCH_AVR);
765    #endif
766    
767    #ifdef ENABLE_HPPA
768            add_cpu_family(hppa_cpu_family_init, ARCH_HPPA);
769    #endif
770    
771    #ifdef ENABLE_I960
772            add_cpu_family(i960_cpu_family_init, ARCH_I960);
773    #endif
774    
775  #ifdef ENABLE_IA64  #ifdef ENABLE_IA64
776          add_cpu_family(ia64_cpu_family_init, ARCH_IA64);          add_cpu_family(ia64_cpu_family_init, ARCH_IA64);
777  #endif  #endif
# Line 669  void cpu_init(void) Line 788  void cpu_init(void)
788          add_cpu_family(ppc_cpu_family_init, ARCH_PPC);          add_cpu_family(ppc_cpu_family_init, ARCH_PPC);
789  #endif  #endif
790    
791    #ifdef ENABLE_SH
792            add_cpu_family(sh_cpu_family_init, ARCH_SH);
793    #endif
794    
795  #ifdef ENABLE_SPARC  #ifdef ENABLE_SPARC
796          add_cpu_family(sparc_cpu_family_init, ARCH_SPARC);          add_cpu_family(sparc_cpu_family_init, ARCH_SPARC);
797  #endif  #endif

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

  ViewVC Help
Powered by ViewVC 1.1.26