/[gxemul]/trunk/src/cpus/cpu_mips.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/cpus/cpu_mips.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 21 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-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_mips.c,v 1.8 2005/11/13 00:14:07 debug Exp $   *  $Id: cpu_mips.c,v 1.17 2006/02/17 20:27:21 debug Exp $
29   *   *
30   *  MIPS core CPU emulation.   *  MIPS core CPU emulation.
31   */   */
# Line 98  static char *cop0_names[] = COP0_NAMES; Line 98  static char *cop0_names[] = COP0_NAMES;
98  #include "cpu_mips16.c"  #include "cpu_mips16.c"
99    
100    
101    #ifdef EXPERIMENTAL_NEWMIPS
102    #define DYNTRANS_DUALMODE_32
103    #define DYNTRANS_DELAYSLOT
104    #include "tmp_mips_head.c"
105    #endif
106    
107    
108  /*  /*
109   *  regname():   *  regname():
110   *   *
# Line 157  int mips_cpu_new(struct cpu *cpu, struct Line 164  int mips_cpu_new(struct cpu *cpu, struct
164          cpu->name               = cpu->cd.mips.cpu_type.name;          cpu->name               = cpu->cd.mips.cpu_type.name;
165          cpu->byte_order         = EMUL_LITTLE_ENDIAN;          cpu->byte_order         = EMUL_LITTLE_ENDIAN;
166          cpu->cd.mips.gpr[MIPS_GPR_SP] = INITIAL_STACK_POINTER;          cpu->cd.mips.gpr[MIPS_GPR_SP] = INITIAL_STACK_POINTER;
167          cpu->update_translation_table = mips_update_translation_table;          cpu->update_translation_table = mips_OLD_update_translation_table;
168          cpu->invalidate_translation_caches =          cpu->invalidate_translation_caches =
169              mips_invalidate_translation_caches_paddr;              mips_invalidate_translation_caches_paddr;
170    
# Line 335  int mips_cpu_new(struct cpu *cpu, struct Line 342  int mips_cpu_new(struct cpu *cpu, struct
342                          cpu->translate_address = translate_address_generic;                          cpu->translate_address = translate_address_generic;
343          }          }
344    
345  /*  Testing:  */          /*  Testing:  */
346          cpu->cd.mips.host_load = zeroed_alloc(1048576 *          cpu->cd.mips.host_OLD_load = zeroed_alloc(1048576 *
347              sizeof(unsigned char *));              sizeof(unsigned char *));
348          cpu->cd.mips.host_store = zeroed_alloc(1048576 *          cpu->cd.mips.host_OLD_store = zeroed_alloc(1048576 *
349              sizeof(unsigned char *));              sizeof(unsigned char *));
350          cpu->cd.mips.host_load_orig = cpu->cd.mips.host_load;          cpu->cd.mips.host_load_orig = cpu->cd.mips.host_OLD_load;
351          cpu->cd.mips.host_store_orig = cpu->cd.mips.host_store;          cpu->cd.mips.host_store_orig = cpu->cd.mips.host_OLD_store;
352    
353          return 1;          return 1;
354  }  }
355    
356    
357  /*  /*
358     *  mips_cpu_dumpinfo():
359     *
360     *  Debug dump of MIPS-specific CPU data for specific CPU.
361     */
362    void mips_cpu_dumpinfo(struct cpu *cpu)
363    {
364            int iadd = DEBUG_INDENTATION;
365            struct mips_cpu_type_def *ct = &cpu->cd.mips.cpu_type;
366    
367            debug_indentation(iadd);
368    
369            debug("\n%i-bit %s (MIPS",
370                cpu->is_32bit? 32 : 64,
371                cpu->byte_order == EMUL_BIG_ENDIAN? "BE" : "LE");
372    
373            switch (ct->isa_level) {
374            case 1: debug(" ISA I"); break;
375            case 2: debug(" ISA II"); break;
376            case 3: debug(" ISA III"); break;
377            case 4: debug(" ISA IV"); break;
378            case 5: debug(" ISA V"); break;
379            case 32:
380            case 64:debug("%i", ct->isa_level); break;
381            default:debug(" ISA level %i", ct->isa_level);
382            }
383    
384            debug("), ");
385            if (ct->nr_of_tlb_entries)
386                    debug("%i TLB entries", ct->nr_of_tlb_entries);
387            else
388                    debug("no TLB");
389            debug("\n");
390    
391            if (ct->picache) {
392                    debug("L1 I-cache: %i KB", (1 << ct->picache) / 1024);
393                    if (ct->pilinesize)
394                            debug(", %i bytes per line", 1 << ct->pilinesize);
395                    if (ct->piways > 1)
396                            debug(", %i-way", ct->piways);
397                    else
398                            debug(", direct-mapped");
399                    debug("\n");
400            }
401    
402            if (ct->pdcache) {
403                    debug("L1 D-cache: %i KB", (1 << ct->pdcache) / 1024);
404                    if (ct->pdlinesize)
405                            debug(", %i bytes per line", 1 << ct->pdlinesize);
406                    if (ct->pdways > 1)
407                            debug(", %i-way", ct->pdways);
408                    else
409                            debug(", direct-mapped");
410                    debug("\n");
411            }
412    
413            if (ct->scache) {
414                    int kb = (1 << ct->scache) / 1024;
415                    debug("L2 cache: %i %s",
416                        kb >= 1024? kb / 1024 : kb, kb >= 1024? "MB":"KB");
417                    if (ct->slinesize)
418                            debug(", %i bytes per line", 1 << ct->slinesize);
419                    if (ct->sways > 1)
420                            debug(", %i-way", ct->sways);
421                    else
422                            debug(", direct-mapped");
423                    debug("\n");
424            }
425    
426            debug_indentation(-iadd);
427    }
428    
429    
430    /*
431     *  mips_cpu_list_available_types():
432     *
433     *  Print a list of available MIPS CPU types.
434     */
435    void mips_cpu_list_available_types(void)
436    {
437            int i, j;
438            struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;
439    
440            i = 0;
441            while (cpu_type_defs[i].name != NULL) {
442                    debug("%s", cpu_type_defs[i].name);
443                    for (j=10 - strlen(cpu_type_defs[i].name); j>0; j--)
444                            debug(" ");
445                    i++;
446                    if ((i % 6) == 0 || cpu_type_defs[i].name == NULL)
447                            debug("\n");
448            }
449    }
450    
451    
452    /*
453   *  mips_cpu_show_full_statistics():   *  mips_cpu_show_full_statistics():
454   *   *
455   *  Show detailed statistics on opcode usage on each cpu.   *  Show detailed statistics on opcode usage on each cpu.
456   */   */
457  void mips_cpu_show_full_statistics(struct machine *m)  void mips_cpu_show_full_statistics(struct machine *m)
458  {  {
459          int i, s1, s2, iadd = 4;          int i, s1, s2, iadd = DEBUG_INDENTATION;
460    
461          if (m->bintrans_enable)          if (m->bintrans_enable)
462                  fatal("NOTE: Dynamic binary translation is used; this list"                  fatal("NOTE: Dynamic binary translation is used; this list"
# Line 418  void mips_cpu_tlbdump(struct machine *m, Line 520  void mips_cpu_tlbdump(struct machine *m,
520  {  {
521          int i, j;          int i, j;
522    
523          /*  Nicely formatted output:  */          /*  Raw output:  */
524          if (!rawflag) {          if (rawflag) {
525                  for (i=0; i<m->ncpus; i++) {                  for (i=0; i<m->ncpus; i++) {
                         int pageshift = 12;  
   
526                          if (x >= 0 && i != x)                          if (x >= 0 && i != x)
527                                  continue;                                  continue;
528    
                         if (m->cpus[i]->cd.mips.cpu_type.rev == MIPS_R4100)  
                                 pageshift = 10;  
   
529                          /*  Print index, random, and wired:  */                          /*  Print index, random, and wired:  */
530                          printf("cpu%i: (", i);                          printf("cpu%i: (", i);
531                          switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {  
532                          case 1:                          if (m->cpus[i]->is_32bit)
533                          case 2:                                  printf("index=0x%08x random=0x%08x", (int)m->
534                                  printf("index=0x%x random=0x%x",                                      cpus[i]->cd.mips.coproc[0]->reg[COP0_INDEX],
535                                      (int) ((m->cpus[i]->cd.mips.coproc[0]->                                      (int)m->cpus[i]->cd.mips.coproc[0]->reg
536                                      reg[COP0_INDEX] & R2K3K_INDEX_MASK)                                      [COP0_RANDOM]);
537                                      >> R2K3K_INDEX_SHIFT),                          else
538                                      (int) ((m->cpus[i]->cd.mips.coproc[0]->                                  printf("index=0x%016llx random=0x%016llx",
539                                      reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)                                      (long long)m->cpus[i]->cd.mips.coproc[0]->
540                                      >> R2K3K_RANDOM_SHIFT));                                      reg[COP0_INDEX], (long long)m->cpus[i]->
541                                  break;                                      cd.mips.coproc[0]->reg[COP0_RANDOM]);
542                          default:  
543                                  printf("index=0x%x random=0x%x",                          if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)
544                                      (int) (m->cpus[i]->cd.mips.coproc[0]->                                  printf(" wired=0x%llx", (long long) m->cpus
545                                      reg[COP0_INDEX] & INDEX_MASK),                                      [i]->cd.mips.coproc[0]->reg[COP0_WIRED]);
                                     (int) (m->cpus[i]->cd.mips.coproc[0]->  
                                     reg[COP0_RANDOM] & RANDOM_MASK));  
                                 printf(" wired=0x%llx", (long long)  
                                     m->cpus[i]->cd.mips.coproc[0]->  
                                     reg[COP0_WIRED]);  
                         }  
546    
547                          printf(")\n");                          printf(")\n");
548    
549                          for (j=0; j<m->cpus[i]->cd.mips.cpu_type.                          for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
550                              nr_of_tlb_entries; j++) {                              nr_of_tlb_entries; j++) {
551                                  uint64_t hi,lo0,lo1,mask;                                  if (m->cpus[i]->cd.mips.cpu_type.mmu_model ==
552                                  hi = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi;                                      MMU3K)
553                                  lo0 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0;                                          printf("%3i: hi=0x%08x lo=0x%08x\n", j,
554                                  lo1 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1;                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,
555                                  mask = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask;                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0);
556                                    else if (m->cpus[i]->is_32bit)
557                                  printf("%3i: ", j);                                          printf("%3i: hi=0x%08x mask=0x%08x "
558                                  switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {                                              "lo0=0x%08x lo1=0x%08x\n", j,
559                                  case MMU3K:                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,
560                                          if (!(lo0 & R2K3K_ENTRYLO_V)) {                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,
561                                                  printf("(invalid)\n");                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,
562                                                  continue;                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);
563                                          }                                  else
564                                          printf("vaddr=0x%08x ",                                          printf("%3i: hi=0x%016llx mask=0x%016llx "
565                                              (int) (hi&R2K3K_ENTRYHI_VPN_MASK));                                              "lo0=0x%016llx lo1=0x%016llx\n", j,
566                                          if (lo0 & R2K3K_ENTRYLO_G)                                              (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,
567                                                  printf("(global), ");                                              (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,
568                                          else                                              (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,
569                                                  printf("(asid %02x),",                                              (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);
                                                     (int) ((hi & R2K3K_ENTRYHI_ASID_MASK)  
                                                     >> R2K3K_ENTRYHI_ASID_SHIFT));  
                                         printf(" paddr=0x%08x ",  
                                             (int) (lo0&R2K3K_ENTRYLO_PFN_MASK));  
                                         if (lo0 & R2K3K_ENTRYLO_N)  
                                                 printf("N");  
                                         if (lo0 & R2K3K_ENTRYLO_D)  
                                                 printf("D");  
                                         printf("\n");  
                                         break;  
                                 default:  
                                         switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {  
                                         case MMU10K:  
                                                 printf("vaddr=0x%1x..%011llx ",  
                                                     (int) (hi >> 60),  
                                                     (long long) (hi&ENTRYHI_VPN2_MASK_R10K));  
                                                 break;  
                                         case MMU32:  
                                                 printf("vaddr=0x%08x ", (int)(hi&ENTRYHI_VPN2_MASK));  
                                                 break;  
                                         default:/*  R4000 etc.  */  
                                                 printf("vaddr=0x%1x..%010llx ",  
                                                     (int) (hi >> 60),  
                                                     (long long) (hi&ENTRYHI_VPN2_MASK));  
                                         }  
                                         if (hi & TLB_G)  
                                                 printf("(global): ");  
                                         else  
                                                 printf("(asid %02x):",  
                                                     (int) (hi & ENTRYHI_ASID));  
   
                                         /*  TODO: Coherency bits  */  
   
                                         if (!(lo0 & ENTRYLO_V))  
                                                 printf(" p0=(invalid)   ");  
                                         else  
                                                 printf(" p0=0x%09llx ", (long long)  
                                                     (((lo0&ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) << pageshift));  
                                         printf(lo0 & ENTRYLO_D? "D" : " ");  
   
                                         if (!(lo1 & ENTRYLO_V))  
                                                 printf(" p1=(invalid)   ");  
                                         else  
                                                 printf(" p1=0x%09llx ", (long long)  
                                                     (((lo1&ENTRYLO_PFN_MASK) >> ENTRYLO_PFN_SHIFT) << pageshift));  
                                         printf(lo1 & ENTRYLO_D? "D" : " ");  
                                         mask |= (1 << (pageshift+1)) - 1;  
                                         switch (mask) {  
                                         case 0x7ff:     printf(" (1KB)"); break;  
                                         case 0x1fff:    printf(" (4KB)"); break;  
                                         case 0x7fff:    printf(" (16KB)"); break;  
                                         case 0x1ffff:   printf(" (64KB)"); break;  
                                         case 0x7ffff:   printf(" (256KB)"); break;  
                                         case 0x1fffff:  printf(" (1MB)"); break;  
                                         case 0x7fffff:  printf(" (4MB)"); break;  
                                         case 0x1ffffff: printf(" (16MB)"); break;  
                                         case 0x7ffffff: printf(" (64MB)"); break;  
                                         default:  
                                                 printf(" (mask=%08x?)", (int)mask);  
                                         }  
                                         printf("\n");  
                                 }  
570                          }                          }
571                  }                  }
   
572                  return;                  return;
573          }          }
574    
575          /*  Raw output:  */          /*  Nicely formatted output:  */
576          for (i=0; i<m->ncpus; i++) {          for (i=0; i<m->ncpus; i++) {
577                    int pageshift = 12;
578    
579                  if (x >= 0 && i != x)                  if (x >= 0 && i != x)
580                          continue;                          continue;
581    
582                    if (m->cpus[i]->cd.mips.cpu_type.rev == MIPS_R4100)
583                            pageshift = 10;
584    
585                  /*  Print index, random, and wired:  */                  /*  Print index, random, and wired:  */
586                  printf("cpu%i: (", i);                  printf("cpu%i: (", i);
587                    switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {
588                  if (m->cpus[i]->is_32bit)                  case 1:
589                          printf("index=0x%08x random=0x%08x",                  case 2: printf("index=0x%x random=0x%x",
590                              (int)m->cpus[i]->cd.mips.coproc[0]->reg[COP0_INDEX],                              (int) ((m->cpus[i]->cd.mips.coproc[0]->
591                              (int)m->cpus[i]->cd.mips.coproc[0]->reg[COP0_RANDOM]);                              reg[COP0_INDEX] & R2K3K_INDEX_MASK)
592                  else                              >> R2K3K_INDEX_SHIFT),
593                          printf("index=0x%016llx random=0x%016llx", (long long)                              (int) ((m->cpus[i]->cd.mips.coproc[0]->
594                              m->cpus[i]->cd.mips.coproc[0]->reg[COP0_INDEX],                              reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)
595                              (long long)m->cpus[i]->cd.mips.coproc[0]->reg                              >> R2K3K_RANDOM_SHIFT));
596                              [COP0_RANDOM]);                          break;
597                    default:printf("index=0x%x random=0x%x",
598                  if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)                              (int) (m->cpus[i]->cd.mips.coproc[0]->
599                                reg[COP0_INDEX] & INDEX_MASK),
600                                (int) (m->cpus[i]->cd.mips.coproc[0]->
601                                reg[COP0_RANDOM] & RANDOM_MASK));
602                          printf(" wired=0x%llx", (long long)                          printf(" wired=0x%llx", (long long)
603                              m->cpus[i]->cd.mips.coproc[0]->reg[COP0_WIRED]);                              m->cpus[i]->cd.mips.coproc[0]->
604                                reg[COP0_WIRED]);
605                    }
606    
607                  printf(")\n");                  printf(")\n");
608    
609                  for (j=0; j<m->cpus[i]->cd.mips.cpu_type.nr_of_tlb_entries; j++) {                  for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
610                          if (m->cpus[i]->cd.mips.cpu_type.mmu_model == MMU3K)                      nr_of_tlb_entries; j++) {
611                                  printf("%3i: hi=0x%08x lo=0x%08x\n",                          uint64_t hi,lo0,lo1,mask;
612                                      j,                          hi = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi;
613                                      (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,                          lo0 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0;
614                                      (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0);                          lo1 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1;
615                          else if (m->cpus[i]->is_32bit)                          mask = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask;
616                                  printf("%3i: hi=0x%08x mask=0x%08x "  
617                                      "lo0=0x%08x lo1=0x%08x\n", j,                          printf("%3i: ", j);
618                                      (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,                          switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {
619                                      (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,                          case MMU3K:
620                                      (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,                                  if (!(lo0 & R2K3K_ENTRYLO_V)) {
621                                      (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);                                          printf("(invalid)\n");
622                          else                                          continue;
623                                  printf("%3i: hi=0x%016llx mask=0x%016llx "                                  }
624                                      "lo0=0x%016llx lo1=0x%016llx\n", j,                                  printf("vaddr=0x%08x ",
625                                      (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,                                      (int) (hi&R2K3K_ENTRYHI_VPN_MASK));
626                                      (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,                                  if (lo0 & R2K3K_ENTRYLO_G)
627                                      (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,                                          printf("(global), ");
628                                      (long long)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);                                  else
629                                            printf("(asid %02x),", (int) ((hi &
630                                                R2K3K_ENTRYHI_ASID_MASK)
631                                                >> R2K3K_ENTRYHI_ASID_SHIFT));
632                                    printf(" paddr=0x%08x ",
633                                        (int) (lo0&R2K3K_ENTRYLO_PFN_MASK));
634                                    if (lo0 & R2K3K_ENTRYLO_N)
635                                            printf("N");
636                                    if (lo0 & R2K3K_ENTRYLO_D)
637                                            printf("D");
638                                    printf("\n");
639                                    break;
640                            default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){
641                                    case MMU10K:
642                                            printf("vaddr=0x%1x..%011llx ",
643                                                (int) (hi >> 60), (long long)
644                                                (hi&ENTRYHI_VPN2_MASK_R10K));
645                                            break;
646                                    case MMU32:
647                                            printf("vaddr=0x%08x ", (int)
648                                                (hi&ENTRYHI_VPN2_MASK));
649                                            break;
650                                    default:/*  R4000 etc.  */
651                                            printf("vaddr=0x%1x..%010llx ",
652                                                (int) (hi >> 60),
653                                                (long long) (hi&ENTRYHI_VPN2_MASK));
654                                    }
655                                    if (hi & TLB_G)
656                                            printf("(global): ");
657                                    else
658                                            printf("(asid %02x):",
659                                                (int) (hi & ENTRYHI_ASID));
660    
661                                    /*  TODO: Coherency bits  */
662    
663                                    if (!(lo0 & ENTRYLO_V))
664                                            printf(" p0=(invalid)   ");
665                                    else
666                                            printf(" p0=0x%09llx ", (long long)
667                                                (((lo0&ENTRYLO_PFN_MASK) >>
668                                                ENTRYLO_PFN_SHIFT) << pageshift));
669                                    printf(lo0 & ENTRYLO_D? "D" : " ");
670    
671                                    if (!(lo1 & ENTRYLO_V))
672                                            printf(" p1=(invalid)   ");
673                                    else
674                                            printf(" p1=0x%09llx ", (long long)
675                                                (((lo1&ENTRYLO_PFN_MASK) >>
676                                                ENTRYLO_PFN_SHIFT) << pageshift));
677                                    printf(lo1 & ENTRYLO_D? "D" : " ");
678                                    mask |= (1 << (pageshift+1)) - 1;
679                                    switch (mask) {
680                                    case 0x7ff:     printf(" (1KB)"); break;
681                                    case 0x1fff:    printf(" (4KB)"); break;
682                                    case 0x7fff:    printf(" (16KB)"); break;
683                                    case 0x1ffff:   printf(" (64KB)"); break;
684                                    case 0x7ffff:   printf(" (256KB)"); break;
685                                    case 0x1fffff:  printf(" (1MB)"); break;
686                                    case 0x7fffff:  printf(" (4MB)"); break;
687                                    case 0x1ffffff: printf(" (16MB)"); break;
688                                    case 0x7ffffff: printf(" (64MB)"); break;
689                                    default:printf(" (mask=%08x?)", (int)mask);
690                                    }
691                                    printf("\n");
692                            }
693                  }                  }
694          }          }
695  }  }
# Line 977  int mips_cpu_disassemble_instr(struct cp Line 1079  int mips_cpu_disassemble_instr(struct cp
1079                  if (imm >= 32768)                  if (imm >= 32768)
1080                          imm -= 65536;                          imm -= 65536;
1081                  addr = (dumpaddr + 4) + (imm << 2);                  addr = (dumpaddr + 4) + (imm << 2);
                 debug("%s\t", hi6_names[hi6]);  
1082    
1083                  switch (hi6) {                  if (hi6 == HI6_BEQ && rt == MIPS_GPR_ZERO &&
1084                  case HI6_BEQ:                      rs == MIPS_GPR_ZERO)
1085                  case HI6_BEQL:                          debug("b\t");
1086                  case HI6_BNE:                  else {
1087                  case HI6_BNEL:                          debug("%s\t", hi6_names[hi6]);
1088                          debug("%s,", regname(cpu->machine, rt));                          switch (hi6) {
1089                            case HI6_BEQ:
1090                            case HI6_BEQL:
1091                            case HI6_BNE:
1092                            case HI6_BNEL:
1093                                    debug("%s,", regname(cpu->machine, rt));
1094                            }
1095                            debug("%s,", regname(cpu->machine, rs));
1096                  }                  }
1097    
                 debug("%s,", regname(cpu->machine, rs));  
   
1098                  if (cpu->is_32bit)                  if (cpu->is_32bit)
1099                          debug("0x%08x", (int)addr);                          debug("0x%08x", (int)addr);
1100                  else                  else
# Line 1185  int mips_cpu_disassemble_instr(struct cp Line 1291  int mips_cpu_disassemble_instr(struct cp
1291                          debug(",%s", regname(cpu->machine, rs));                          debug(",%s", regname(cpu->machine, rs));
1292                          debug(",%s", regname(cpu->machine, rt));                          debug(",%s", regname(cpu->machine, rt));
1293                  } else if (special6 == SPECIAL2_MUL) {                  } else if (special6 == SPECIAL2_MUL) {
1294                          /*  TODO: this is just a guess, I don't have the                          /*  Apparently used both on R5900 and MIPS32:  */
                                 docs in front of me  */  
1295                          debug("mul\t%s", regname(cpu->machine, rd));                          debug("mul\t%s", regname(cpu->machine, rd));
1296                          debug(",%s", regname(cpu->machine, rs));                          debug(",%s", regname(cpu->machine, rs));
1297                          debug(",%s", regname(cpu->machine, rt));                          debug(",%s", regname(cpu->machine, rt));
# Line 1426  void mips_cpu_register_dump(struct cpu * Line 1531  void mips_cpu_register_dump(struct cpu *
1531  }  }
1532    
1533    
1534    #ifndef EXPERIMENTAL_NEWMIPS
1535    
1536  #define DYNTRANS_FUNCTION_TRACE mips_cpu_functioncall_trace  #define DYNTRANS_FUNCTION_TRACE mips_cpu_functioncall_trace
1537  #define DYNTRANS_MIPS  #define DYNTRANS_MIPS
1538  #define DYNTRANS_ARCH mips  #define DYNTRANS_ARCH mips
# Line 1434  void mips_cpu_register_dump(struct cpu * Line 1541  void mips_cpu_register_dump(struct cpu *
1541  #undef DYNTRANS_ARCH  #undef DYNTRANS_ARCH
1542  #undef DYNTRANS_FUNCTION_TRACE  #undef DYNTRANS_FUNCTION_TRACE
1543    
1544    #endif
1545    
1546    
1547  /*  /*
1548   *  mips_cpu_interrupt():   *  mips_cpu_interrupt():
# Line 1581  void mips_cpu_exception(struct cpu *cpu, Line 1690  void mips_cpu_exception(struct cpu *cpu,
1690                  else                  else
1691                          fatal("0x%016llx", (long long)cpu->cd.mips.pc_last);                          fatal("0x%016llx", (long long)cpu->cd.mips.pc_last);
1692                  fatal(" <%s> ]\n", symbol? symbol : "(no symbol)");                  fatal(" <%s> ]\n", symbol? symbol : "(no symbol)");
   
 #ifdef TRACE_NULL_CRASHES  
                 /*  This can be useful for debugging kernel bugs:  */  
                 {  
                         int i = cpu->trace_null_index;  
                         do {  
                                 fatal("TRACE: 0x%016llx\n",  
                                     cpu->trace_null_addr[i]);  
                                 i ++;  
                                 i %= TRACE_NULL_N_ENTRIES;  
                         } while (i != cpu->trace_null_index);  
                 }  
                 cpu->running = 0;  
                 cpu->dead = 1;  
 #endif  
1693          }          }
1694    
1695          /*  Clear the exception code bits of the cause register...  */          /*  Clear the exception code bits of the cause register...  */
# Line 1764  void mips_cpu_cause_simple_exception(str Line 1858  void mips_cpu_cause_simple_exception(str
1858  #include "memory_mips.c"  #include "memory_mips.c"
1859    
1860    
1861    #ifndef EXPERIMENTAL_NEWMIPS
1862  /*  /*
1863   *  mips_cpu_run_instr():   *  mips_OLD_cpu_run_instr():
1864   *   *
1865   *  Execute one instruction on a cpu.   *  Execute one instruction on a cpu.
1866   *   *
# Line 1775  void mips_cpu_cause_simple_exception(str Line 1870  void mips_cpu_cause_simple_exception(str
1870   *  Return value is the number of instructions executed during this call,   *  Return value is the number of instructions executed during this call,
1871   *  0 if no instruction was executed.   *  0 if no instruction was executed.
1872   */   */
1873  int mips_cpu_run_instr(struct emul *emul, struct cpu *cpu)  int mips_OLD_cpu_run_instr(struct emul *emul, struct cpu *cpu)
1874  {  {
1875          int quiet_mode_cached = quiet_mode;          int quiet_mode_cached = quiet_mode;
1876          int instruction_trace_cached = cpu->machine->instruction_trace;          int instruction_trace_cached = cpu->machine->instruction_trace;
# Line 1847  int mips_cpu_run_instr(struct emul *emul Line 1942  int mips_cpu_run_instr(struct emul *emul
1942          /*  Cache the program counter in a local variable:  */          /*  Cache the program counter in a local variable:  */
1943          cached_pc = cpu->pc;          cached_pc = cpu->pc;
1944    
 #ifdef TRACE_NULL_CRASHES  
         cpu->trace_null_addr[cpu->trace_null_index] = cached_pc;  
         cpu->trace_null_index ++;  
         cpu->trace_null_index %= TRACE_NULL_N_ENTRIES;  
 #endif  
   
1945          /*  Hardwire the zero register to 0:  */          /*  Hardwire the zero register to 0:  */
1946          cpu->cd.mips.gpr[MIPS_GPR_ZERO] = 0;          cpu->cd.mips.gpr[MIPS_GPR_ZERO] = 0;
1947    
# Line 1940  int mips_cpu_run_instr(struct emul *emul Line 2029  int mips_cpu_run_instr(struct emul *emul
2029              cpu->machine->prom_emulation) {              cpu->machine->prom_emulation) {
2030                  int rom_jal = 1, res = 1;                  int rom_jal = 1, res = 1;
2031                  switch (cpu->machine->machine_type) {                  switch (cpu->machine->machine_type) {
2032                  case MACHINE_DEC:                  case MACHINE_PMAX:
2033                          res = decstation_prom_emul(cpu);                          res = decstation_prom_emul(cpu);
2034                          break;                          break;
2035                  case MACHINE_PS2:                  case MACHINE_PS2:
# Line 2071  int mips_cpu_run_instr(struct emul *emul Line 2160  int mips_cpu_run_instr(struct emul *emul
2160          }          }
2161  #endif  #endif
2162    
         PREFETCH(cpu->cd.mips.pc_last_host_4k_page + (cached_pc & 0xfff));  
   
2163  #ifdef HALT_IF_PC_ZERO  #ifdef HALT_IF_PC_ZERO
2164          /*  Halt if PC = 0:  */          /*  Halt if PC = 0:  */
2165          if (cached_pc == 0) {          if (cached_pc == 0) {
# Line 3872  int mips_cpu_run_instr(struct emul *emul Line 3959  int mips_cpu_run_instr(struct emul *emul
3959                  which_cache = copz & 3;                  which_cache = copz & 3;
3960    
3961                  /*                  /*
3962                   *  TODO:  The cache instruction is implementation dependant.                   *  TODO:  The cache instruction is implementation dependent.
3963                   */                   */
3964    
3965                  /*                  /*
# Line 3974  int mips_cpu_run_instr(struct emul *emul Line 4061  int mips_cpu_run_instr(struct emul *emul
4061                              ((cpu->cd.mips.gpr[rs] & 0xffffffffULL) << 32)              /*  TODO: switch rt and rs?  */                              ((cpu->cd.mips.gpr[rs] & 0xffffffffULL) << 32)              /*  TODO: switch rt and rs?  */
4062                              | (cpu->cd.mips.gpr[rt] & 0xffffffffULL);                              | (cpu->cd.mips.gpr[rt] & 0xffffffffULL);
4063                  } else if (special6 == SPECIAL2_MUL) {                  } else if (special6 == SPECIAL2_MUL) {
4064                          cpu->cd.mips.gpr[rd] = (int64_t)cpu->cd.mips.gpr[rt] *                          /*  Apparently used both on R5900 MIPS32:  */
4065                              (int64_t)cpu->cd.mips.gpr[rs];                          cpu->cd.mips.gpr[rd] = (int64_t)(int32_t) (
4066                                (int32_t)cpu->cd.mips.gpr[rt] *
4067                                (int32_t)cpu->cd.mips.gpr[rs] );
4068                  } else if (special6 == SPECIAL2_CLZ) {                  } else if (special6 == SPECIAL2_CLZ) {
4069                          /*  clz: count leading zeroes  */                          /*  clz: count leading zeroes  */
4070                          int i, n=0;                          int i, n=0;
# Line 4041  int mips_cpu_run_instr(struct emul *emul Line 4130  int mips_cpu_run_instr(struct emul *emul
4130    
4131          /*  NOTREACHED  */          /*  NOTREACHED  */
4132  }  }
4133    #endif  /*  !EXPERIMENTAL_NEWMIPS  */
4134    
4135    
4136    
4137    #ifdef EXPERIMENTAL_NEWMIPS
4138    
4139  #define CPU_RUN         mips_cpu_run  #include "tmp_mips_tail.c"
4140    
4141    #else
4142    
4143    #define CPU_RUN         mips_OLD_cpu_run
4144  #define CPU_RUN_MIPS  #define CPU_RUN_MIPS
4145  #define CPU_RINSTR      mips_cpu_run_instr  #define CPU_RINSTR      mips_OLD_cpu_run_instr
4146  #include "cpu_run.c"  #include "cpu_run.c"
4147  #undef CPU_RINSTR  #undef CPU_RINSTR
4148  #undef CPU_RUN_MIPS  #undef CPU_RUN_MIPS
4149  #undef CPU_RUN  #undef CPU_RUN
   
   
 /*  
  *  mips_cpu_dumpinfo():  
  *  
  *  Debug dump of MIPS-specific CPU data for specific CPU.  
  */  
 void mips_cpu_dumpinfo(struct cpu *cpu)  
 {  
         int iadd = 4;  
         struct mips_cpu_type_def *ct = &cpu->cd.mips.cpu_type;  
   
         debug_indentation(iadd);  
   
         debug("\n%i-bit %s (MIPS",  
             cpu->is_32bit? 32 : 64,  
             cpu->byte_order == EMUL_BIG_ENDIAN? "BE" : "LE");  
   
         switch (ct->isa_level) {  
         case 1: debug(" ISA I"); break;  
         case 2: debug(" ISA II"); break;  
         case 3: debug(" ISA III"); break;  
         case 4: debug(" ISA IV"); break;  
         case 5: debug(" ISA V"); break;  
         case 32:  
         case 64:debug("%i", ct->isa_level); break;  
         default:debug(" ISA level %i", ct->isa_level);  
         }  
   
         debug("), ");  
         if (ct->nr_of_tlb_entries)  
                 debug("%i TLB entries", ct->nr_of_tlb_entries);  
         else  
                 debug("no TLB");  
         debug("\n");  
   
         if (ct->picache) {  
                 debug("L1 I-cache: %i KB", (1 << ct->picache) / 1024);  
                 if (ct->pilinesize)  
                         debug(", %i bytes per line", 1 << ct->pilinesize);  
                 if (ct->piways > 1)  
                         debug(", %i-way", ct->piways);  
                 else  
                         debug(", direct-mapped");  
                 debug("\n");  
         }  
   
         if (ct->pdcache) {  
                 debug("L1 D-cache: %i KB", (1 << ct->pdcache) / 1024);  
                 if (ct->pdlinesize)  
                         debug(", %i bytes per line", 1 << ct->pdlinesize);  
                 if (ct->pdways > 1)  
                         debug(", %i-way", ct->pdways);  
                 else  
                         debug(", direct-mapped");  
                 debug("\n");  
         }  
   
         if (ct->scache) {  
                 int kb = (1 << ct->scache) / 1024;  
                 debug("L2 cache: %i %s",  
                     kb >= 1024? kb / 1024 : kb, kb >= 1024? "MB":"KB");  
                 if (ct->slinesize)  
                         debug(", %i bytes per line", 1 << ct->slinesize);  
                 if (ct->sways > 1)  
                         debug(", %i-way", ct->sways);  
                 else  
                         debug(", direct-mapped");  
                 debug("\n");  
         }  
   
         debug_indentation(-iadd);  
 }  
   
   
 /*  
  *  mips_cpu_list_available_types():  
  *  
  *  Print a list of available MIPS CPU types.  
  */  
 void mips_cpu_list_available_types(void)  
 {  
         int i, j;  
         struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS;  
   
         i = 0;  
         while (cpu_type_defs[i].name != NULL) {  
                 debug("%s", cpu_type_defs[i].name);  
                 for (j=10 - strlen(cpu_type_defs[i].name); j>0; j--)  
                         debug(" ");  
                 i++;  
                 if ((i % 6) == 0 || cpu_type_defs[i].name == NULL)  
                         debug("\n");  
         }  
 }  
   
   
 /*  NOTE: _OLD_ family init. TODO: remove all this  */  
   
4150  CPU_OLD_FAMILY_INIT(mips,"MIPS")  CPU_OLD_FAMILY_INIT(mips,"MIPS")
4151    
4152    #endif
4153    
4154    
4155  #endif  /*  ENABLE_MIPS  */  #endif  /*  ENABLE_MIPS  */

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

  ViewVC Help
Powered by ViewVC 1.1.26