--- upstream/dynamips-0.2.6-RC5/mips_mts.c 2007/10/06 16:09:07 6 +++ trunk/mips_mts.c 2007/10/06 16:45:40 12 @@ -5,14 +5,13 @@ * Template code for MTS. */ -#define MTS_ENTRY MTS_PROTO(entry_t) -#define MTS_CHUNK MTS_PROTO(chunk_t) +#define MTS_ENTRY MTS_NAME(entry_t) +#define MTS_CACHE(cpu) ( cpu->mts_u. MTS_NAME(cache) ) /* Forward declarations */ static forced_inline void *MTS_PROTO(access)(cpu_mips_t *cpu,m_uint64_t vaddr, u_int op_code,u_int op_size, - u_int op_type,m_uint64_t *data, - u_int *exc); + u_int op_type,m_uint64_t *data); static fastcall int MTS_PROTO(translate)(cpu_mips_t *cpu,m_uint64_t vaddr, m_uint32_t *phys_page); @@ -23,182 +22,70 @@ size_t len; /* Initialize the cache entries to 0 (empty) */ - len = MTS_PROTO_UP(HASH_SIZE) * sizeof(MTS_ENTRY *); - if (!(cpu->mts_cache = malloc(len))) + len = MTS_NAME_UP(HASH_SIZE) * sizeof(MTS_ENTRY); + if (!(MTS_CACHE(cpu) = malloc(len))) return(-1); - memset(cpu->mts_cache,0,len); + memset(MTS_CACHE(cpu),0xFF,len); cpu->mts_lookups = 0; cpu->mts_misses = 0; - - /* Reset the TLB reverse map (used for selective invalidations) */ - memset(cpu->mts_rmap,0,(cpu->cp0.tlb_entries * sizeof(MTS_ENTRY *))); return(0); } /* Free memory used by MTS */ void MTS_PROTO(shutdown)(cpu_mips_t *cpu) { - MTS_CHUNK *chunk,*next; - int i; - - /* Reset the reverse map */ - for(i=0;icp0.tlb_entries;i++) - cpu->mts_rmap[i] = NULL; - /* Free the cache itself */ - free(cpu->mts_cache); - cpu->mts_cache = NULL; - - /* Free the chunks */ - for(chunk=cpu->mts_chunk_list;chunk;chunk=next) { - next = chunk->next; - free(chunk); - } - - for(chunk=cpu->mts_chunk_free_list;chunk;chunk=next) { - next = chunk->next; - free(chunk); - } - - cpu->mts_chunk_list = cpu->mts_chunk_free_list = NULL; - cpu->mts_entry_free_list = NULL; + free(MTS_CACHE(cpu)); + MTS_CACHE(cpu) = NULL; } /* Show MTS detailed information (debugging only!) */ -void MTS_PROTO(show_stats)(cpu_mips_t *cpu) +void MTS_PROTO(show_stats)(cpu_gen_t *gen_cpu) { - MTS_CHUNK *chunk; + cpu_mips_t *cpu = CPU_MIPS64(gen_cpu); #if DEBUG_MTS_MAP_VIRT MTS_ENTRY *entry; - u_int i; + u_int i,count; #endif - u_int count; - printf("\nCPU%u: MTS%d statistics:\n",cpu->id,MTS_ADDR_SIZE); - - printf(" Total lookups: %llu, misses: %llu, efficiency: %g%%\n", - cpu->mts_lookups, cpu->mts_misses, - 100 - ((double)(cpu->mts_misses*100)/ - (double)cpu->mts_lookups)); + printf("\nCPU%u: MTS%d statistics:\n",cpu->gen->id,MTS_ADDR_SIZE); #if DEBUG_MTS_MAP_VIRT /* Valid hash entries */ - for(count=0,i=0;imts_cache[i]) != NULL) { - printf(" %4u: entry=%p, start=0x%16.16llx, " - "len=0x%8.8x, action=0x%8.8llx\n", - i,entry,(m_uint64_t)entry->start,entry->mask, - (m_uint64_t)entry->action); + for(count=0,i=0;igvpa & MTS_INV_ENTRY_MASK)) { + printf(" %4u: vaddr=0x%8.8llx, paddr=0x%8.8llx, hpa=%p\n", + i,(m_uint64_t)entry->gvpa,(m_uint64_t)entry->gppa, + (void *)entry->hpa); count++; } } - printf(" %u/%u valid hash entries.\n",count,MTS_PROTO_UP(HASH_SIZE)); + printf(" %u/%u valid hash entries.\n",count,MTS_NAME_UP(HASH_SIZE)); #endif - /* Number of chunks */ - for(count=0,chunk=cpu->mts_chunk_list;chunk;chunk=chunk->next) - count++; - - printf(" Number of chunks: %u\n",count); - -#if DEBUG_MTS_MAP_VIRT - /* Reverse map */ - for(i=0;imts_rmap[i];entry;entry=entry->next) - count++; - - if (count > 0) - printf(" tlb_rmap[%u]: %u entries\n",i,count); - } -#endif -} - -/* Allocate a new chunk */ -static int MTS_PROTO(alloc_chunk)(cpu_mips_t *cpu) -{ - MTS_CHUNK *chunk; - - /* Try the free list first, then use standard allocation procedure */ - if ((chunk = cpu->mts_chunk_free_list) != NULL) { - cpu->mts_chunk_free_list = chunk->next; - } else { - if (!(chunk = malloc(sizeof(*chunk)))) - return(-1); - } - - chunk->count = 0; - chunk->next = cpu->mts_chunk_list; - cpu->mts_chunk_list = chunk; - return(0); -} - -/* Allocate a new entry */ -static MTS_ENTRY *MTS_PROTO(alloc_entry)(cpu_mips_t *cpu) -{ - MTS_CHUNK *chunk = cpu->mts_chunk_list; - MTS_ENTRY *entry; - - /* First, try to allocate the entry from the free list */ - if ((entry = cpu->mts_entry_free_list) != NULL) { - cpu->mts_entry_free_list = ((MTS_ENTRY *)cpu->mts_entry_free_list)->next; - return entry; - } - - /* A new chunk is required */ - if (!chunk || (chunk->count == MTS_PROTO_UP(CHUNK_SIZE))) { - if (MTS_PROTO(alloc_chunk)(cpu) == -1) - return NULL; - - chunk = cpu->mts_chunk_list; - } - - entry = &chunk->entry[chunk->count]; - chunk->count++; - return entry; + printf(" Total lookups: %llu, misses: %llu, efficiency: %g%%\n", + cpu->mts_lookups, cpu->mts_misses, + 100 - ((double)(cpu->mts_misses*100)/ + (double)cpu->mts_lookups)); } /* Invalidate the complete MTS cache */ void MTS_PROTO(invalidate_cache)(cpu_mips_t *cpu) { - MTS_CHUNK *chunk; size_t len; - u_int i; - - len = MTS_PROTO_UP(HASH_SIZE) * sizeof(MTS_ENTRY *); - memset(cpu->mts_cache,0,len); - - /* Move all chunks to the free list */ - while((chunk = cpu->mts_chunk_list) != NULL) { - cpu->mts_chunk_list = chunk->next; - chunk->next = cpu->mts_chunk_free_list; - cpu->mts_chunk_free_list = chunk; - } - /* Reset the free list of entries (since they are located in chunks) */ - cpu->mts_entry_free_list = NULL; - - /* Reset the reverse map */ - for(i=0;icp0.tlb_entries;i++) - cpu->mts_rmap[i] = NULL; + len = MTS_NAME_UP(HASH_SIZE) * sizeof(MTS_ENTRY); + memset(MTS_CACHE(cpu),0xFF,len); } /* Invalidate partially the MTS cache, given a TLB entry index */ void MTS_PROTO(invalidate_tlb_entry)(cpu_mips_t *cpu,u_int tlb_index) { - MTS_ENTRY *entry; - - for(entry=cpu->mts_rmap[tlb_index];entry;entry=entry->next) { - *(entry->pself) = NULL; - if (!entry->next) { - entry->next = cpu->mts_entry_free_list; - break; - } - } - - cpu->mts_entry_free_list = cpu->mts_rmap[tlb_index]; - cpu->mts_rmap[tlb_index] = NULL; + MTS_PROTO(invalidate_cache)(cpu); } /* @@ -206,326 +93,287 @@ * * It is NOT inlined since it triggers a GCC bug on my config (x86, GCC 3.3.5) */ -static no_inline int MTS_PROTO(map)(cpu_mips_t *cpu,m_uint64_t vaddr, - mts_map_t *map,MTS_ENTRY *entry) +static no_inline MTS_ENTRY * +MTS_PROTO(map)(cpu_mips_t *cpu,u_int op_type,mts_map_t *map, + MTS_ENTRY *entry,MTS_ENTRY *alt_entry) { struct vdevice *dev; - m_uint64_t lk_addr; - m_uint32_t poffset; - - lk_addr = map->paddr + (vaddr - map->vaddr); + m_uint32_t offset; + m_iptr_t host_ptr; + int cow; + + if (!(dev = dev_lookup(cpu->vm,map->paddr,map->cached))) + return NULL; + + if (dev->flags & VDEVICE_FLAG_SPARSE) { + host_ptr = dev_sparse_get_host_addr(cpu->vm,dev,map->paddr,op_type,&cow); + + entry->gvpa = map->vaddr; + entry->gppa = map->paddr; + entry->hpa = host_ptr; + entry->flags = (cow) ? MTS_FLAG_COW : 0; + return entry; + } - if (!(dev = dev_lookup(cpu->vm,lk_addr,map->cached))) - return(FALSE); + if (!dev->host_addr || (dev->flags & VDEVICE_FLAG_NO_MTS_MMAP)) { + offset = (map->paddr + map->offset) - dev->phys_addr; - if (map->paddr > dev->phys_addr) { - poffset = map->paddr - dev->phys_addr; - entry->start = map->vaddr; - entry->phys_page = map->paddr >> MIPS_MIN_PAGE_SHIFT; - entry->mask = ~((m_min(map->len,dev->phys_len - poffset)) - 1); - entry->action = poffset; - } else { - poffset = dev->phys_addr - map->paddr; - entry->start = map->vaddr + poffset; - entry->phys_page = (map->paddr + poffset) >> MIPS_MIN_PAGE_SHIFT; - entry->mask = ~((m_min(map->len - poffset,dev->phys_len)) - 1); - entry->action = 0; + /* device entries are never stored in virtual TLB */ + alt_entry->hpa = (dev->id << MTS_DEVID_SHIFT) + offset; + alt_entry->flags = MTS_FLAG_DEV; + return alt_entry; } - if (!dev->host_addr || (dev->flags & VDEVICE_FLAG_NO_MTS_MMAP)) - entry->action += (dev->id << MTS_DEVID_SHIFT) | MTS_DEV_MASK; - else - entry->action += dev->host_addr; + entry->gvpa = map->vaddr; + entry->gppa = map->paddr; + entry->hpa = dev->host_addr + (map->paddr - dev->phys_addr); + entry->flags = 0; - return(TRUE); + return entry; } /* MTS lookup */ static void *MTS_PROTO(lookup)(cpu_mips_t *cpu,m_uint64_t vaddr) { m_uint64_t data; - u_int exc; - return(MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LOOKUP,4,MTS_READ, - &data,&exc)); + return(MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LOOKUP,4,MTS_READ,&data)); } /* === MIPS Memory Operations ============================================= */ /* LB: Load Byte */ -fastcall u_int MTS_PROTO(lb)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(lb)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LB,1,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LB,1,MTS_READ,&data); if (likely(haddr != NULL)) data = *(m_uint8_t *)haddr; - if (likely(!exc)) cpu->gpr[reg] = sign_extend(data,8); - return(exc); + cpu->gpr[reg] = sign_extend(data,8); } /* LBU: Load Byte Unsigned */ -fastcall u_int MTS_PROTO(lbu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(lbu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LBU,1,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LBU,1,MTS_READ,&data); if (likely(haddr != NULL)) data = *(m_uint8_t *)haddr; - if (likely(!exc)) cpu->gpr[reg] = data & 0xff; - return(exc); + cpu->gpr[reg] = data & 0xff; } /* LH: Load Half-Word */ -fastcall u_int MTS_PROTO(lh)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(lh)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LH,2,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LH,2,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh16(*(m_uint16_t *)haddr); - if (likely(!exc)) cpu->gpr[reg] = sign_extend(data,16); - return(exc); + cpu->gpr[reg] = sign_extend(data,16); } /* LHU: Load Half-Word Unsigned */ -fastcall u_int MTS_PROTO(lhu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(lhu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LHU,2,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LHU,2,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh16(*(m_uint16_t *)haddr); - if (likely(!exc)) cpu->gpr[reg] = data & 0xffff; - return(exc); + cpu->gpr[reg] = data & 0xffff; } /* LW: Load Word */ -fastcall u_int MTS_PROTO(lw)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(lw)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LW,4,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LW,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); - if (likely(!exc)) cpu->gpr[reg] = sign_extend(data,32); - return(exc); + cpu->gpr[reg] = sign_extend(data,32); } /* LWU: Load Word Unsigned */ -fastcall u_int MTS_PROTO(lwu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(lwu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LWU,4,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LWU,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); - if (likely(!exc)) cpu->gpr[reg] = data & 0xffffffff; - return(exc); + cpu->gpr[reg] = data & 0xffffffff; } /* LD: Load Double-Word */ -fastcall u_int MTS_PROTO(ld)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(ld)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LD,8,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LD,8,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); - if (likely(!exc)) cpu->gpr[reg] = data; - return(exc); + cpu->gpr[reg] = data; } /* SB: Store Byte */ -fastcall u_int MTS_PROTO(sb)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(sb)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; data = cpu->gpr[reg] & 0xff; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SB,1,MTS_WRITE,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SB,1,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint8_t *)haddr = data; - return(exc); } /* SH: Store Half-Word */ -fastcall u_int MTS_PROTO(sh)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(sh)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; data = cpu->gpr[reg] & 0xffff; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SH,2,MTS_WRITE,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SH,2,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint16_t *)haddr = htovm16(data); - return(exc); } /* SW: Store Word */ -fastcall u_int MTS_PROTO(sw)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(sw)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; data = cpu->gpr[reg] & 0xffffffff; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SW,4,MTS_WRITE,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SW,4,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data); - return(exc); } /* SD: Store Double-Word */ -fastcall u_int MTS_PROTO(sd)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(sd)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; data = cpu->gpr[reg]; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SD,8,MTS_WRITE,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SD,8,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint64_t *)haddr = htovm64(data); - return(exc); } /* LDC1: Load Double-Word To Coprocessor 1 */ -fastcall u_int MTS_PROTO(ldc1)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(ldc1)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LDC1,8,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LDC1,8,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); - if (likely(!exc)) cpu->fpu.reg[reg] = data; - return(exc); + cpu->fpu.reg[reg] = data; } /* LWL: Load Word Left */ -fastcall u_int MTS_PROTO(lwl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(lwl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t r_mask,naddr; m_uint64_t data; u_int m_shift; void *haddr; - u_int exc; naddr = vaddr & ~(0x03); - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LWL,4,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LWL,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); - if (likely(!exc)) { - m_shift = (vaddr & 0x03) << 3; - r_mask = (1ULL << m_shift) - 1; - data <<= m_shift; - - cpu->gpr[reg] &= r_mask; - cpu->gpr[reg] |= data; - cpu->gpr[reg] = sign_extend(cpu->gpr[reg],32); - } - return(exc); + m_shift = (vaddr & 0x03) << 3; + r_mask = (1ULL << m_shift) - 1; + data <<= m_shift; + + cpu->gpr[reg] &= r_mask; + cpu->gpr[reg] |= data; + cpu->gpr[reg] = sign_extend(cpu->gpr[reg],32); } /* LWR: Load Word Right */ -fastcall u_int MTS_PROTO(lwr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(lwr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t r_mask,naddr; m_uint64_t data; u_int m_shift; void *haddr; - u_int exc; naddr = vaddr & ~(0x03); - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LWR,4,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LWR,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); - if (likely(!exc)) { - m_shift = ((vaddr & 0x03) + 1) << 3; - r_mask = (1ULL << m_shift) - 1; + m_shift = ((vaddr & 0x03) + 1) << 3; + r_mask = (1ULL << m_shift) - 1; - data = sign_extend(data >> (32 - m_shift),32); - r_mask = sign_extend(r_mask,32); + data = sign_extend(data >> (32 - m_shift),32); + r_mask = sign_extend(r_mask,32); - cpu->gpr[reg] &= ~r_mask; - cpu->gpr[reg] |= data; - } - return(exc); + cpu->gpr[reg] &= ~r_mask; + cpu->gpr[reg] |= data; } /* LDL: Load Double-Word Left */ -fastcall u_int MTS_PROTO(ldl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(ldl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t r_mask,naddr; m_uint64_t data; u_int m_shift; void *haddr; - u_int exc; naddr = vaddr & ~(0x07); - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LDL,8,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LDL,8,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); - if (likely(!exc)) { - m_shift = (vaddr & 0x07) << 3; - r_mask = (1ULL << m_shift) - 1; - data <<= m_shift; + m_shift = (vaddr & 0x07) << 3; + r_mask = (1ULL << m_shift) - 1; + data <<= m_shift; - cpu->gpr[reg] &= r_mask; - cpu->gpr[reg] |= data; - } - return(exc); + cpu->gpr[reg] &= r_mask; + cpu->gpr[reg] |= data; } /* LDR: Load Double-Word Right */ -fastcall u_int MTS_PROTO(ldr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(ldr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t r_mask,naddr; m_uint64_t data; u_int m_shift; void *haddr; - u_int exc; naddr = vaddr & ~(0x07); - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LDR,8,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LDR,8,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); - if (likely(!exc)) { - m_shift = ((vaddr & 0x07) + 1) << 3; - r_mask = (1ULL << m_shift) - 1; - data >>= (64 - m_shift); - - cpu->gpr[reg] &= ~r_mask; - cpu->gpr[reg] |= data; - } - return(exc); + m_shift = ((vaddr & 0x07) + 1) << 3; + r_mask = (1ULL << m_shift) - 1; + data >>= (64 - m_shift); + + cpu->gpr[reg] &= ~r_mask; + cpu->gpr[reg] |= data; } /* SWL: Store Word Left */ -fastcall u_int MTS_PROTO(swl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(swl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t d_mask,naddr; m_uint64_t data; u_int r_shift; void *haddr; - u_int exc; naddr = vaddr & ~(0x03ULL); - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWL,4,MTS_READ,&data,&exc); - if (unlikely(exc)) return(exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWL,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); @@ -536,23 +384,20 @@ data &= ~d_mask; data |= (cpu->gpr[reg] & 0xffffffff) >> r_shift; - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWL,4,MTS_WRITE,&data,&exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWL,4,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data); - return(exc); } /* SWR: Store Word Right */ -fastcall u_int MTS_PROTO(swr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(swr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t d_mask,naddr; m_uint64_t data; u_int r_shift; void *haddr; - u_int exc; naddr = vaddr & ~(0x03); - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWR,4,MTS_READ,&data,&exc); - if (unlikely(exc)) return(exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWR,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); @@ -563,23 +408,20 @@ data &= d_mask; data |= (cpu->gpr[reg] << (32 - r_shift)) & 0xffffffff; - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWR,4,MTS_WRITE,&data,&exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWR,4,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data); - return(exc); } /* SDL: Store Double-Word Left */ -fastcall u_int MTS_PROTO(sdl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(sdl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t d_mask,naddr; m_uint64_t data; u_int r_shift; void *haddr; - u_int exc; naddr = vaddr & ~(0x07); - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDL,8,MTS_READ,&data,&exc); - if (unlikely(exc)) return(exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDL,8,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); @@ -590,23 +432,20 @@ data &= ~d_mask; data |= cpu->gpr[reg] >> r_shift; - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDL,8,MTS_WRITE,&data,&exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDL,8,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint64_t *)haddr = htovm64(data); - return(exc); } /* SDR: Store Double-Word Right */ -fastcall u_int MTS_PROTO(sdr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(sdr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t d_mask,naddr; m_uint64_t data; u_int r_shift; void *haddr; - u_int exc; naddr = vaddr & ~(0x07); - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDR,8,MTS_READ,&data,&exc); - if (unlikely(exc)) return(exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDR,8,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); @@ -617,102 +456,83 @@ data &= d_mask; data |= cpu->gpr[reg] << (64 - r_shift); - haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDR,8,MTS_WRITE,&data,&exc); + haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDR,8,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint64_t *)haddr = htovm64(data); - return(exc); } /* LL: Load Linked */ -fastcall u_int MTS_PROTO(ll)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(ll)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LL,4,MTS_READ,&data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LL,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); - if (likely(!exc)) { - cpu->gpr[reg] = sign_extend(data,32); - cpu->ll_bit = 1; - } - - return(exc); + cpu->gpr[reg] = sign_extend(data,32); + cpu->ll_bit = 1; } /* SC: Store Conditional */ -fastcall u_int MTS_PROTO(sc)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(sc)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc = 0; if (cpu->ll_bit) { data = cpu->gpr[reg] & 0xffffffff; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SC,4,MTS_WRITE, - &data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SC,4,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data); } - if (likely(!exc)) - cpu->gpr[reg] = cpu->ll_bit; - return(exc); + cpu->gpr[reg] = cpu->ll_bit; } /* SDC1: Store Double-Word from Coprocessor 1 */ -fastcall u_int MTS_PROTO(sdc1)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) +fastcall void MTS_PROTO(sdc1)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg) { m_uint64_t data; void *haddr; - u_int exc; data = cpu->fpu.reg[reg]; - haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SDC1,8,MTS_WRITE, - &data,&exc); + haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SDC1,8,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint64_t *)haddr = htovm64(data); - return(exc); } /* CACHE: Cache operation */ -fastcall u_int MTS_PROTO(cache)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int op) +fastcall void MTS_PROTO(cache)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int op) { - struct insn_block *block; - m_uint32_t phys_page; + mips64_jit_tcb_t *block; + m_uint32_t pc_hash; #if DEBUG_CACHE - cpu_log(cpu,"MTS","CACHE: PC=0x%llx, vaddr=0x%llx, cache=%u, code=%u\n", + cpu_log(cpu->gen, + "MTS","CACHE: PC=0x%llx, vaddr=0x%llx, cache=%u, code=%u\n", cpu->pc, vaddr, op & 0x3, op >> 2); #endif - if (!cpu->translate(cpu,vaddr,&phys_page)) { - if ((phys_page < 1048576) && cpu->exec_phys_map) { - block = cpu->exec_phys_map[phys_page]; - - if (block) { - if ((cpu->pc < block->start_pc) || - ((cpu->pc - block->start_pc) >= MIPS_MIN_PAGE_SIZE)) - { + if (cpu->exec_blk_map) { + pc_hash = mips64_jit_get_pc_hash(vaddr); + block = cpu->exec_blk_map[pc_hash]; + + if (block && (block->start_pc == (vaddr & MIPS_MIN_PAGE_MASK))) { #if DEBUG_CACHE - cpu_log(cpu,"MTS", - "CACHE: removing compiled page at 0x%llx, pc=0x%llx\n", - block->start_pc,cpu->pc); + cpu_log(cpu->gen,"MTS", + "CACHE: removing compiled page at 0x%llx, pc=0x%llx\n", + block->start_pc,cpu->pc); #endif - cpu->exec_phys_map[phys_page] = NULL; - insn_block_free(cpu,block,TRUE); - } - else - { + cpu->exec_blk_map[pc_hash] = NULL; + mips64_jit_tcb_free(cpu,block,TRUE); + } + else + { #if DEBUG_CACHE - cpu_log(cpu,"MTS", - "CACHE: trying to remove page 0x%llx with pc=0x%llx\n", - block->start_pc,cpu->pc); -#endif - } - } + cpu_log(cpu->gen,"MTS", + "CACHE: trying to remove page 0x%llx with pc=0x%llx\n", + vaddr, cpu->pc); +#endif } } - - return(0); } /* === MTS Cache Management ============================================= */ @@ -734,9 +554,9 @@ MTS_PROTO(invalidate_cache)(cpu); } -void MTS_PROTO(api_rebuild)(cpu_mips_t *cpu) +void MTS_PROTO(api_rebuild)(cpu_gen_t *cpu) { - MTS_PROTO(invalidate_cache)(cpu); + MTS_PROTO(invalidate_cache)(CPU_MIPS64(cpu)); } /* ======================================================================== */ @@ -753,9 +573,8 @@ /* API vectors */ cpu->mts_map = MTS_PROTO(api_map); cpu->mts_unmap = MTS_PROTO(api_unmap); - cpu->mts_rebuild = MTS_PROTO(api_rebuild); - /* memory lookup operation */ + /* Memory lookup operation */ cpu->mem_op_lookup = MTS_PROTO(lookup); /* Translation operation */ @@ -764,8 +583,11 @@ /* Shutdown operation */ cpu->mts_shutdown = MTS_PROTO(shutdown); + /* Rebuild MTS data structures */ + cpu->gen->mts_rebuild = MTS_PROTO(api_rebuild); + /* Show statistics */ - cpu->mts_show_stats = MTS_PROTO(show_stats); + cpu->gen->mts_show_stats = MTS_PROTO(show_stats); /* Load Operations */ cpu->mem_op_fn[MIPS_MEMOP_LB] = MTS_PROTO(lb); @@ -809,6 +631,8 @@ } #undef MTS_ADDR_SIZE +#undef MTS_NAME +#undef MTS_NAME_UP #undef MTS_PROTO #undef MTS_PROTO_UP #undef MTS_ENTRY