/[dynamips]/upstream/dynamips-0.2.6-RC3/cp0.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 /upstream/dynamips-0.2.6-RC3/cp0.c

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

upstream/dynamips-0.2.6-RC2/cp0.c revision 3 by dpavlin, Sat Oct 6 16:05:34 2007 UTC upstream/dynamips-0.2.6-RC3/cp0.c revision 4 by dpavlin, Sat Oct 6 16:06:49 2007 UTC
# Line 334  static char *get_page_size_str(char *buf Line 334  static char *get_page_size_str(char *buf
334     return buffer;     return buffer;
335  }  }
336    
337    /* Get the VPN2 mask */
338    static forced_inline m_uint64_t cp0_get_vpn2_mask(cpu_mips_t *cpu)
339    {
340       if (cpu->addr_mode == 64)
341          return(MIPS_TLB_VPN2_MASK_64);
342       else
343          return(MIPS_TLB_VPN2_MASK_32);
344    }
345    
346  /* TLB lookup */  /* TLB lookup */
347  int cp0_tlb_lookup(cpu_mips_t *cpu,m_uint64_t vaddr,mts_map_t *res)  int cp0_tlb_lookup(cpu_mips_t *cpu,m_uint64_t vaddr,mts_map_t *res)
348  {  {
349     mips_cp0_t *cp0 = &cpu->cp0;     mips_cp0_t *cp0 = &cpu->cp0;
350     m_uint64_t v0_addr,v1_addr;     m_uint64_t vpn_addr,vpn2_mask;
351       m_uint64_t page_mask,hi_addr;
352     m_uint32_t page_size,pca;     m_uint32_t page_size,pca;
353     tlb_entry_t *entry;     tlb_entry_t *entry;
354       u_int asid;
355     int i;     int i;
356    
357       vpn2_mask = cp0_get_vpn2_mask(cpu);
358       vpn_addr = vaddr & vpn2_mask;
359       asid = cp0->reg[MIPS_CP0_TLB_HI] & MIPS_TLB_ASID_MASK;
360    
361     for(i=0;i<cp0->tlb_entries;i++) {     for(i=0;i<cp0->tlb_entries;i++) {
362        entry = &cp0->tlb[i];        entry = &cp0->tlb[i];
363    
364        page_size = get_page_size(entry->mask);        page_mask = ~(entry->mask + 0x1FFF);
365        v0_addr = entry->hi & MIPS_TLB_VPN2_MASK;        hi_addr = entry->hi & vpn2_mask;
       v1_addr = v0_addr + page_size;  
   
       /* virtual address in entry 0 ? */  
       if ((entry->lo0 & MIPS_TLB_V_MASK) &&  
           (vaddr >= v0_addr) && (vaddr < v1_addr))  
       {  
          res->vaddr = v0_addr;  
          res->paddr = (entry->lo0 & MIPS_TLB_PFN_MASK) << 6;  
          res->paddr &= cpu->addr_bus_mask;  
          res->len   = page_size;  
   
          pca = (entry->lo0 & MIPS_TLB_C_MASK);  
          pca >>= MIPS_TLB_C_SHIFT;  
          res->cached = mips64_cca_cached(pca);  
   
          res->tlb_index = i;  
          return(TRUE);  
       }  
366    
367        /* virtual address in entry 1 ? */        if (((vpn_addr & page_mask) == hi_addr) &&
368        if ((entry->lo1 & MIPS_TLB_V_MASK) &&            ((entry->hi & MIPS_TLB_G_MASK) ||
369            (vaddr >= v1_addr) && ((vaddr - v1_addr) < page_size))             ((entry->hi & MIPS_TLB_ASID_MASK) == asid)))
370        {        {
371           res->vaddr = v1_addr;           page_size = get_page_size(entry->mask);
372           res->paddr = (entry->lo1 & MIPS_TLB_PFN_MASK) << 6;  
373           res->paddr &= cpu->addr_bus_mask;           if ((vaddr & page_size) == 0) {
374           res->len   = page_size;              /* Even Page */
375                if (entry->lo0 & MIPS_TLB_V_MASK) {
376           pca = (entry->lo1 & MIPS_TLB_C_MASK);                 res->vaddr = vaddr & page_mask;
377           pca >>= MIPS_TLB_C_SHIFT;                 res->paddr = (entry->lo0 & MIPS_TLB_PFN_MASK) << 6;
378           res->cached = mips64_cca_cached(pca);                 res->paddr &= cpu->addr_bus_mask;
379                   res->len   = page_size;
380    
381                   pca = (entry->lo0 & MIPS_TLB_C_MASK);
382                   pca >>= MIPS_TLB_C_SHIFT;
383                   res->cached = mips64_cca_cached(pca);
384                
385                   res->tlb_index = i;
386                   return(TRUE);
387                }
388             } else {
389                /* Odd Page */
390                if (entry->lo1 & MIPS_TLB_V_MASK) {
391                   res->vaddr = (vaddr & page_mask) + page_size;
392                   res->paddr = (entry->lo1 & MIPS_TLB_PFN_MASK) << 6;
393                   res->paddr &= cpu->addr_bus_mask;
394                   res->len   = page_size;
395    
396                   pca = (entry->lo1 & MIPS_TLB_C_MASK);
397                   pca >>= MIPS_TLB_C_SHIFT;
398                   res->cached = mips64_cca_cached(pca);
399                  
400                   res->tlb_index = i;
401                   return(TRUE);
402                }
403             }
404    
405           res->tlb_index = i;           /* Invalid entry */
406           return(TRUE);           return(FALSE);
407        }        }
408     }     }
409    
410       /* No matching entry */
411     return(FALSE);     return(FALSE);
412  }  }
413    
# Line 406  void cp0_map_tlb_to_mts(cpu_mips_t *cpu, Line 429  void cp0_map_tlb_to_mts(cpu_mips_t *cpu,
429     entry = &cpu->cp0.tlb[index];     entry = &cpu->cp0.tlb[index];
430    
431     page_size = get_page_size(entry->mask);     page_size = get_page_size(entry->mask);
432     v0_addr = entry->hi & MIPS_TLB_VPN2_MASK;     v0_addr = entry->hi & cp0_get_vpn2_mask(cpu);
433     v1_addr = v0_addr + page_size;     v1_addr = v0_addr + page_size;
434    
435     if (entry->lo0 & MIPS_TLB_V_MASK) {     if (entry->lo0 & MIPS_TLB_V_MASK) {
# Line 442  void cp0_unmap_tlb_to_mts(cpu_mips_t *cp Line 465  void cp0_unmap_tlb_to_mts(cpu_mips_t *cp
465     entry = &cpu->cp0.tlb[index];     entry = &cpu->cp0.tlb[index];
466    
467     page_size = get_page_size(entry->mask);     page_size = get_page_size(entry->mask);
468     v0_addr = entry->hi & MIPS_TLB_VPN2_MASK;     v0_addr = entry->hi & cp0_get_vpn2_mask(cpu);
469     v1_addr = v0_addr + page_size;     v1_addr = v0_addr + page_size;
470    
471     if (entry->lo0 & MIPS_TLB_V_MASK)     if (entry->lo0 & MIPS_TLB_V_MASK)
# Line 465  void cp0_map_all_tlb_to_mts(cpu_mips_t * Line 488  void cp0_map_all_tlb_to_mts(cpu_mips_t *
488  fastcall void cp0_exec_tlbp(cpu_mips_t *cpu)  fastcall void cp0_exec_tlbp(cpu_mips_t *cpu)
489  {  {
490     mips_cp0_t *cp0 = &cpu->cp0;     mips_cp0_t *cp0 = &cpu->cp0;
491     m_uint64_t hi_reg,asid,vpn2;     m_uint64_t hi_reg,asid;
492       m_uint64_t vpn2,vpn2_mask;
493     tlb_entry_t *entry;     tlb_entry_t *entry;
494     int i;     int i;
495        
496       vpn2_mask = cp0_get_vpn2_mask(cpu);
497     hi_reg = cp0->reg[MIPS_CP0_TLB_HI];     hi_reg = cp0->reg[MIPS_CP0_TLB_HI];
498     asid = hi_reg & MIPS_TLB_ASID_MASK;     asid = hi_reg & MIPS_TLB_ASID_MASK;
499     vpn2 = hi_reg & MIPS_TLB_VPN2_MASK;     vpn2 = hi_reg & vpn2_mask;
500    
501     cp0->reg[MIPS_CP0_INDEX] = 0xffffffff80000000ULL;     cp0->reg[MIPS_CP0_INDEX] = 0xffffffff80000000ULL;
502        
503     for(i=0;i<cp0->tlb_entries;i++) {     for(i=0;i<cp0->tlb_entries;i++) {
504        entry = &cp0->tlb[i];        entry = &cp0->tlb[i];
505    
506        if (((entry->hi & MIPS_TLB_VPN2_MASK) == vpn2) &&        if (((entry->hi & vpn2_mask) == vpn2) &&
507            ((entry->hi & MIPS_TLB_G_MASK) ||            ((entry->hi & MIPS_TLB_G_MASK) ||
508             ((entry->hi & MIPS_TLB_ASID_MASK) == asid)))             ((entry->hi & MIPS_TLB_ASID_MASK) == asid)))
509        {        {
# Line 607  void tlb_dump_entry(cpu_mips_t *cpu,u_in Line 632  void tlb_dump_entry(cpu_mips_t *cpu,u_in
632     entry = &cpu->cp0.tlb[index];     entry = &cpu->cp0.tlb[index];
633    
634     /* virtual Address */     /* virtual Address */
635     printf(" %2d: vaddr=0x%8.8llx ", index, entry->hi & MIPS_TLB_VPN2_MASK);     printf(" %2d: vaddr=0x%8.8llx ", index, entry->hi & cp0_get_vpn2_mask(cpu));
636    
637     /* global or ASID */     /* global or ASID */
638     if (entry->hi & MIPS_TLB_G_MASK)     if (entry->hi & MIPS_TLB_G_MASK)

Legend:
Removed from v.3  
changed lines
  Added in v.4

  ViewVC Help
Powered by ViewVC 1.1.26