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

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

revision 11 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_mips_coproc.c,v 1.23 2005/06/26 11:36:27 debug Exp $   *  $Id: cpu_mips_coproc.c,v 1.27 2005/08/14 15:47:36 debug Exp $
29   *   *
30   *  Emulation of MIPS coprocessors.   *  Emulation of MIPS coprocessors.
31   */   */
# Line 88  static void initialize_cop0_config(struc Line 88  static void initialize_cop0_config(struc
88  #else  #else
89          const int m16 = 0;          const int m16 = 0;
90  #endif  #endif
91          int cpu_type, IB, DB, SB, IC, DC, SC;          int cpu_type, IB, DB, SB, IC, DC, SC, IA, DA;
92    
93          /*  Default values:  */          /*  Default values:  */
94          c->reg[COP0_CONFIG] =          c->reg[COP0_CONFIG] =
# Line 319  static void initialize_cop0_config(struc Line 319  static void initialize_cop0_config(struc
319                      | (   1 <<  7)      /*  MMU type: 1=TLB, 3=FMT  */                      | (   1 <<  7)      /*  MMU type: 1=TLB, 3=FMT  */
320                      | (   2 <<  0)      /*  kseg0 cache coherency algorithm  */                      | (   2 <<  0)      /*  kseg0 cache coherency algorithm  */
321                      ;                      ;
322                  /*  Config select 1: caches etc. TODO: Associativity?  */                  /*  Config select 1: caches etc. TODO: Don't use
323                            cpu->machine for this stuff!  */
324                  IB = cpu->machine->cache_picache_linesize - 1;                  IB = cpu->machine->cache_picache_linesize - 1;
325                  IB = IB < 0? 0 : (IB > 7? 7 : IB);                  IB = IB < 0? 0 : (IB > 7? 7 : IB);
326                  DB = cpu->machine->cache_pdcache_linesize - 1;                  DB = cpu->machine->cache_pdcache_linesize - 1;
# Line 328  static void initialize_cop0_config(struc Line 329  static void initialize_cop0_config(struc
329                      cpu->machine->cache_picache_linesize - 7;                      cpu->machine->cache_picache_linesize - 7;
330                  DC = cpu->machine->cache_pdcache -                  DC = cpu->machine->cache_pdcache -
331                      cpu->machine->cache_pdcache_linesize - 7;                      cpu->machine->cache_pdcache_linesize - 7;
332                    IA = cpu->cd.mips.cpu_type.piways - 1;
333                    DA = cpu->cd.mips.cpu_type.pdways - 1;
334                  cpu->cd.mips.cop0_config_select1 =                  cpu->cd.mips.cop0_config_select1 =
335                      ((cpu->cd.mips.cpu_type.nr_of_tlb_entries - 1) << 25)                      ((cpu->cd.mips.cpu_type.nr_of_tlb_entries - 1) << 25)
336                      | (IC << 22)        /*  IS: I-cache sets per way  */                      | (IC << 22)        /*  IS: I-cache sets per way  */
337                      | (IB << 19)        /*  IL: I-cache line-size  */                      | (IB << 19)        /*  IL: I-cache line-size  */
338                      | (1 << 16)         /*  IA: I-cache assoc. (ways-1)  */                      | (IA << 16)        /*  IA: I-cache assoc. (ways-1)  */
339                      | (DC << 13)        /*  DS: D-cache sets per way  */                      | (DC << 13)        /*  DS: D-cache sets per way  */
340                      | (DB << 10)        /*  DL: D-cache line-size  */                      | (DB << 10)        /*  DL: D-cache line-size  */
341                      | (1 <<  7)         /*  DA: D-cache assoc. (ways-1)  */                      | (DA <<  7)        /*  DA: D-cache assoc. (ways-1)  */
342                      | (16 * 0)          /*  Existance of PerformanceCounters  */                      | (16 * 0)          /*  Existance of PerformanceCounters  */
343                      | ( 8 * 0)          /*  Existance of Watch Registers  */                      | ( 8 * 0)          /*  Existance of Watch Registers  */
344                      | ( 4 * m16)        /*  Existance of MIPS16  */                      | ( 4 * m16)        /*  Existance of MIPS16  */
# Line 532  void mips_coproc_tlb_set_entry(struct cp Line 535  void mips_coproc_tlb_set_entry(struct cp
535  }  }
536    
537    
 #ifdef BINTRANS  
538  /*  /*
539   *  old_update_translation_table():   *  old_update_translation_table():
540   */   */
541  static void old_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,  static void old_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
542          unsigned char *host_page, int writeflag, uint64_t paddr_page)          unsigned char *host_page, int writeflag, uint64_t paddr_page)
543  {  {
544          int a, b;          int a, b, index;
545          struct vth32_table *tbl1;          struct vth32_table *tbl1;
546          void *p_r, *p_w;          void *p_r, *p_w;
547          uint32_t p_paddr;          uint32_t p_paddr;
# Line 555  static void old_update_translation_table Line 557  static void old_update_translation_table
557    
558          a = (vaddr_page >> 22) & 0x3ff;          a = (vaddr_page >> 22) & 0x3ff;
559          b = (vaddr_page >> 12) & 0x3ff;          b = (vaddr_page >> 12) & 0x3ff;
560            index = (vaddr_page >> 12) & 0xfffff;
561    
562          /*  printf("vaddr = %08x, a = %03x, b = %03x\n",          /*  printf("vaddr = %08x, a = %03x, b = %03x\n",
563              (int)vaddr_page,a, b);  */              (int)vaddr_page,a, b);  */
564    
565          tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];          tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];
566          /*  printf("tbl1 = %p\n", tbl1);  */          /*  printf("tbl1 = %p\n", tbl1);  */
567          if (tbl1 == cpu->cd.mips.vaddr_to_hostaddr_nulltable) {          if (tbl1 == cpu->cd.mips.vaddr_to_hostaddr_nulltable) {
# Line 572  static void old_update_translation_table Line 577  static void old_update_translation_table
577                          memset(tbl1, 0, sizeof(struct vth32_table));                          memset(tbl1, 0, sizeof(struct vth32_table));
578                  } else {                  } else {
579                          tbl1 = cpu->cd.mips.next_free_vth_table;                          tbl1 = cpu->cd.mips.next_free_vth_table;
580                          cpu->cd.mips.next_free_vth_table =                          cpu->cd.mips.next_free_vth_table = tbl1->next_free;
                             tbl1->next_free;  
581                          tbl1->next_free = NULL;                          tbl1->next_free = NULL;
582                  }                  }
583                  cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a] = tbl1;                  cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a] = tbl1;
# Line 596  static void old_update_translation_table Line 600  static void old_update_translation_table
600          if (writeflag == -1) {          if (writeflag == -1) {
601                  /*  Forced downgrade to read-only:  */                  /*  Forced downgrade to read-only:  */
602                  tbl1->haddr_entry[b*2 + 1] = NULL;                  tbl1->haddr_entry[b*2 + 1] = NULL;
603                    if (cpu->cd.mips.host_store ==
604                        cpu->cd.mips.host_store_orig)
605                            cpu->cd.mips.host_store[index] = NULL;
606          } else if (writeflag==0 && p_w != NULL && host_page != NULL) {          } else if (writeflag==0 && p_w != NULL && host_page != NULL) {
607                  /*  Don't degrade a page from writable to readonly.  */                  /*  Don't degrade a page from writable to readonly.  */
608          } else {          } else {
609                  if (host_page != NULL) {                  if (host_page != NULL) {
610                          tbl1->haddr_entry[b*2] = host_page;                          tbl1->haddr_entry[b*2] = host_page;
611                          if (writeflag)                          if (cpu->cd.mips.host_load ==
612                                cpu->cd.mips.host_load_orig)
613                                    cpu->cd.mips.host_load[index] = host_page;
614                            if (writeflag) {
615                                  tbl1->haddr_entry[b*2+1] = host_page;                                  tbl1->haddr_entry[b*2+1] = host_page;
616                          else                                  if (cpu->cd.mips.host_store ==
617                                        cpu->cd.mips.host_store_orig)
618                                            cpu->cd.mips.host_store[index] =
619                                                host_page;
620                            } else {
621                                  tbl1->haddr_entry[b*2+1] = NULL;                                  tbl1->haddr_entry[b*2+1] = NULL;
622                                    if (cpu->cd.mips.host_store ==
623                                        cpu->cd.mips.host_store_orig)
624                                            cpu->cd.mips.host_store[index] = NULL;
625                            }
626                  } else {                  } else {
627                          tbl1->haddr_entry[b*2] = NULL;                          tbl1->haddr_entry[b*2] = NULL;
628                          tbl1->haddr_entry[b*2+1] = NULL;                          tbl1->haddr_entry[b*2+1] = NULL;
629                            if (cpu->cd.mips.host_store ==
630                                cpu->cd.mips.host_store_orig) {
631                                    cpu->cd.mips.host_load[index] = NULL;
632                                    cpu->cd.mips.host_store[index] = NULL;
633                            }
634                  }                  }
635                  tbl1->paddr_entry[b] = paddr_page;                  tbl1->paddr_entry[b] = paddr_page;
636          }          }
637          tbl1->bintrans_chunks[b] = NULL;          tbl1->bintrans_chunks[b] = NULL;
638  }  }
 #endif  
639    
640    
641  /*  /*
642   *  update_translation_table():   *  mips_update_translation_table():
643   */   */
644  void update_translation_table(struct cpu *cpu, uint64_t vaddr_page,  void mips_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
645          unsigned char *host_page, int writeflag, uint64_t paddr_page)          unsigned char *host_page, int writeflag, uint64_t paddr_page)
646  {  {
 #ifdef BINTRANS  
647          if (!cpu->machine->bintrans_enable)          if (!cpu->machine->bintrans_enable)
648                  return;                  return;
649    
# Line 637  void update_translation_table(struct cpu Line 658  void update_translation_table(struct cpu
658    
659          /*  TODO  */          /*  TODO  */
660          /*  printf("update_translation_table(): TODO\n");  */          /*  printf("update_translation_table(): TODO\n");  */
 #endif  
661  }  }
662    
663    
 #ifdef BINTRANS  
664  /*  /*
665   *  invalidate_table_entry():   *  invalidate_table_entry():
666   */   */
667  static void invalidate_table_entry(struct cpu *cpu, uint64_t vaddr)  static void invalidate_table_entry(struct cpu *cpu, uint64_t vaddr)
668  {  {
669          int a, b;          int a, b, index;
670          struct vth32_table *tbl1;          struct vth32_table *tbl1;
671          void *p_r, *p_w;          void *p_r, *p_w;
672          uint32_t p_paddr;          uint32_t p_paddr;
# Line 674  static void invalidate_table_entry(struc Line 693  static void invalidate_table_entry(struc
693    
694          a = (vaddr >> 22) & 0x3ff;          a = (vaddr >> 22) & 0x3ff;
695          b = (vaddr >> 12) & 0x3ff;          b = (vaddr >> 12) & 0x3ff;
696            index = (vaddr >> 12) & 0xfffff;
697    
698          /*  printf("vaddr = %08x, a = %03x, b = %03x\n", (int)vaddr,a, b);  */          /*  printf("vaddr = %08x, a = %03x, b = %03x\n", (int)vaddr,a, b);  */
699    
# Line 684  static void invalidate_table_entry(struc Line 704  static void invalidate_table_entry(struc
704          p_paddr = tbl1->paddr_entry[b];          p_paddr = tbl1->paddr_entry[b];
705          tbl1->bintrans_chunks[b] = NULL;          tbl1->bintrans_chunks[b] = NULL;
706          /*  printf("B:  p_r=%p p_w=%p\n", p_r,p_w);  */          /*  printf("B:  p_r=%p p_w=%p\n", p_r,p_w);  */
707            cpu->cd.mips.host_load_orig[index] = NULL;
708            cpu->cd.mips.host_store_orig[index] = NULL;
709          if (p_r != NULL || p_paddr != 0) {          if (p_r != NULL || p_paddr != 0) {
710                  /*  printf("Found a mapping, "                  /*  printf("Found a mapping, "
711                      "vaddr = %08x, a = %03x, b = %03x\n", (int)vaddr,a, b);  */                      "vaddr = %08x, a = %03x, b = %03x\n", (int)vaddr,a, b);  */
# Line 719  void clear_all_chunks_from_all_tables(st Line 741  void clear_all_chunks_from_all_tables(st
741                  tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];                  tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];
742                  if (tbl1 != cpu->cd.mips.vaddr_to_hostaddr_nulltable) {                  if (tbl1 != cpu->cd.mips.vaddr_to_hostaddr_nulltable) {
743                          for (b=0; b<0x400; b++) {                          for (b=0; b<0x400; b++) {
744                                    int index;
745    
746                                  tbl1->haddr_entry[b*2] = NULL;                                  tbl1->haddr_entry[b*2] = NULL;
747                                  tbl1->haddr_entry[b*2+1] = NULL;                                  tbl1->haddr_entry[b*2+1] = NULL;
748                                  tbl1->paddr_entry[b] = 0;                                  tbl1->paddr_entry[b] = 0;
749                                  tbl1->bintrans_chunks[b] = NULL;                                  tbl1->bintrans_chunks[b] = NULL;
750    
751                                    if (cpu->cd.mips.host_store ==
752                                        cpu->cd.mips.host_store_orig) {
753                                            index = (a << 10) + b;
754                                            cpu->cd.mips.host_load[index] = NULL;
755                                            cpu->cd.mips.host_store[index] = NULL;
756                                    }
757                          }                          }
758                  }                  }
759          }          }
760  }  }
 #endif  
761    
762    
763  /*  /*
# Line 737  void clear_all_chunks_from_all_tables(st Line 767  void clear_all_chunks_from_all_tables(st
767   */   */
768  void mips_invalidate_translation_caches_paddr(struct cpu *cpu, uint64_t paddr)  void mips_invalidate_translation_caches_paddr(struct cpu *cpu, uint64_t paddr)
769  {  {
 #ifdef BINTRANS  
770          paddr &= ~0xfff;          paddr &= ~0xfff;
771    
772          if (cpu->machine->bintrans_enable) {          if (cpu->machine->bintrans_enable) {
# Line 842  void mips_invalidate_translation_caches_ Line 871  void mips_invalidate_translation_caches_
871                  cpu->bintrans_data_hostpage[i] = NULL;                  cpu->bintrans_data_hostpage[i] = NULL;
872  }  }
873  #endif  #endif
   
 #endif  
874  }  }
875    
876    
# Line 862  static void invalidate_translation_cache Line 889  static void invalidate_translation_cache
889          /*  printf("inval(all=%i, kernel=%i, addr=%016llx)\n",          /*  printf("inval(all=%i, kernel=%i, addr=%016llx)\n",
890              all, kernelspace, (long long)vaddr);  */              all, kernelspace, (long long)vaddr);  */
891    
 #ifdef BINTRANS  
892          if (!cpu->machine->bintrans_enable)          if (!cpu->machine->bintrans_enable)
893                  goto nobintrans;                  goto nobintrans;
894    
# Line 943  nobintrans: Line 969  nobintrans:
969          /*  TODO: Don't invalidate everything.  */          /*  TODO: Don't invalidate everything.  */
970          for (i=0; i<N_BINTRANS_VADDR_TO_HOST; i++)          for (i=0; i<N_BINTRANS_VADDR_TO_HOST; i++)
971                  cpu->cd.mips.bintrans_data_hostpage[i] = NULL;                  cpu->cd.mips.bintrans_data_hostpage[i] = NULL;
 #endif  
972    
973          if (kernelspace)          if (kernelspace)
974                  all = 1;                  all = 1;
# Line 1276  void coproc_register_write(struct cpu *c Line 1301  void coproc_register_write(struct cpu *c
1301                          }                          }
1302  #endif  #endif
1303    
 #ifdef BINTRANS  
1304                          if (cpu->cd.mips.cpu_type.mmu_model == MMU3K &&                          if (cpu->cd.mips.cpu_type.mmu_model == MMU3K &&
1305                              (oldmode & MIPS1_ISOL_CACHES) !=                              (oldmode & MIPS1_ISOL_CACHES) !=
1306                              (tmp & MIPS1_ISOL_CACHES)) {                              (tmp & MIPS1_ISOL_CACHES)) {
# Line 1284  void coproc_register_write(struct cpu *c Line 1308  void coproc_register_write(struct cpu *c
1308                                      treated in bintrans mode by changing                                      treated in bintrans mode by changing
1309                                      the vaddr_to_hostaddr_table0 pointer:  */                                      the vaddr_to_hostaddr_table0 pointer:  */
1310                                  if (tmp & MIPS1_ISOL_CACHES) {                                  if (tmp & MIPS1_ISOL_CACHES) {
1311                                          /*  cpu->cd.mips.                                          /*  2-level table:  */
                                             dont_run_next_bintrans = 1;  */  
1312                                          cpu->cd.mips.vaddr_to_hostaddr_table0 =                                          cpu->cd.mips.vaddr_to_hostaddr_table0 =
1313                                            tmp & MIPS1_SWAP_CACHES?                                            tmp & MIPS1_SWAP_CACHES?
1314                                            cpu->cd.mips.                                            cpu->cd.mips.
1315                                            vaddr_to_hostaddr_table0_cacheisol_i                                            vaddr_to_hostaddr_table0_cacheisol_i
1316                                            : cpu->cd.mips.                                            : cpu->cd.mips.
1317                                            vaddr_to_hostaddr_table0_cacheisol_d;                                            vaddr_to_hostaddr_table0_cacheisol_d;
1318    
1319                                            /*  1M-entry table:  */
1320                                            cpu->cd.mips.host_load =
1321                                                cpu->cd.mips.host_store =
1322                                                cpu->cd.mips.huge_r2k3k_cache_table;
1323                                  } else {                                  } else {
1324                                            /*  2-level table:  */
1325                                          cpu->cd.mips.vaddr_to_hostaddr_table0 =                                          cpu->cd.mips.vaddr_to_hostaddr_table0 =
1326                                              cpu->cd.mips.                                              cpu->cd.mips.
1327                                                  vaddr_to_hostaddr_table0_kernel;                                                  vaddr_to_hostaddr_table0_kernel;
1328    
1329                                          /*  TODO: cpu->cd.mips.                                          /*  TODO: cpu->cd.mips.
1330                                              vaddr_to_hostaddr_table0_user;  */                                              vaddr_to_hostaddr_table0_user;  */
1331    
1332                                            /*  1M-entry table:  */
1333                                            cpu->cd.mips.host_load =
1334                                                cpu->cd.mips.host_load_orig;
1335                                            cpu->cd.mips.host_store =
1336                                                cpu->cd.mips.host_store_orig;
1337                                  }                                  }
1338                          }                          }
 #endif  
1339                          unimpl = 0;                          unimpl = 0;
1340                          break;                          break;
1341                  case COP0_CAUSE:                  case COP0_CAUSE:
# Line 2422  void coproc_tlbwri(struct cpu *cpu, int Line 2456  void coproc_tlbwri(struct cpu *cpu, int
2456  /*                      if (vaddr < 0x10000000)  */  /*                      if (vaddr < 0x10000000)  */
2457                                  wf = 0;                                  wf = 0;
2458    
2459                          update_translation_table(cpu, vaddr, memblock,                          cpu->update_translation_table(cpu, vaddr, memblock,
2460                              wf, paddr);                              wf, paddr);
2461                  }                  }
2462          } else {          } else {

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

  ViewVC Help
Powered by ViewVC 1.1.26