📄 mips_mts.c
字号:
/* * Cisco router simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * Template code for MTS. */#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);static fastcall int MTS_PROTO(translate)(cpu_mips_t *cpu,m_uint64_t vaddr, m_uint32_t *phys_page);/* Initialize the MTS subsystem for the specified CPU */int MTS_PROTO(init)(cpu_mips_t *cpu){ size_t len; /* Initialize the cache entries to 0 (empty) */ len = MTS_NAME_UP(HASH_SIZE) * sizeof(MTS_ENTRY); if (!(MTS_CACHE(cpu) = malloc(len))) return(-1); memset(MTS_CACHE(cpu),0xFF,len); cpu->mts_lookups = 0; cpu->mts_misses = 0; return(0);}/* Free memory used by MTS */void MTS_PROTO(shutdown)(cpu_mips_t *cpu){ /* Free the cache itself */ free(MTS_CACHE(cpu)); MTS_CACHE(cpu) = NULL;}/* Show MTS detailed information (debugging only!) */void MTS_PROTO(show_stats)(cpu_gen_t *gen_cpu){ cpu_mips_t *cpu = CPU_MIPS64(gen_cpu);#if DEBUG_MTS_MAP_VIRT MTS_ENTRY *entry; u_int i,count;#endif 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;i<MTS_NAME_UP(HASH_SIZE);i++) { entry = &(MTS_CACHE(cpu)[i]); if (!(entry->gvpa & 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_NAME_UP(HASH_SIZE));#endif 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){ size_t len; 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_PROTO(invalidate_cache)(cpu);} /* * MTS mapping. * * It is NOT inlined since it triggers a GCC bug on my config (x86, GCC 3.3.5) */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_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->host_addr || (dev->flags & VDEVICE_FLAG_NO_MTS_MMAP)) { offset = (map->paddr + map->offset) - dev->phys_addr; /* 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; } entry->gvpa = map->vaddr; entry->gppa = map->paddr; entry->hpa = dev->host_addr + (map->paddr - dev->phys_addr); entry->flags = 0; return entry;}/* MTS lookup */static void *MTS_PROTO(lookup)(cpu_mips_t *cpu,m_uint64_t vaddr){ m_uint64_t data; return(MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LOOKUP,4,MTS_READ,&data));}/* === MIPS Memory Operations ============================================= *//* LB: Load Byte */fastcall void MTS_PROTO(lb)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LB,1,MTS_READ,&data); if (likely(haddr != NULL)) data = *(m_uint8_t *)haddr; cpu->gpr[reg] = sign_extend(data,8);}/* LBU: Load Byte Unsigned */fastcall void MTS_PROTO(lbu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LBU,1,MTS_READ,&data); if (likely(haddr != NULL)) data = *(m_uint8_t *)haddr; cpu->gpr[reg] = data & 0xff;}/* LH: Load Half-Word */fastcall void MTS_PROTO(lh)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LH,2,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh16(*(m_uint16_t *)haddr); cpu->gpr[reg] = sign_extend(data,16);}/* LHU: Load Half-Word Unsigned */fastcall void MTS_PROTO(lhu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LHU,2,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh16(*(m_uint16_t *)haddr); cpu->gpr[reg] = data & 0xffff;}/* LW: Load Word */fastcall void MTS_PROTO(lw)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LW,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); cpu->gpr[reg] = sign_extend(data,32);}/* LWU: Load Word Unsigned */fastcall void MTS_PROTO(lwu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LWU,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); cpu->gpr[reg] = data & 0xffffffff;}/* LD: Load Double-Word */fastcall void MTS_PROTO(ld)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LD,8,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); cpu->gpr[reg] = data;}/* SB: Store Byte */fastcall void MTS_PROTO(sb)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; data = cpu->gpr[reg] & 0xff; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SB,1,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint8_t *)haddr = data;}/* SH: Store Half-Word */fastcall void MTS_PROTO(sh)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; data = cpu->gpr[reg] & 0xffff; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SH,2,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint16_t *)haddr = htovm16(data);}/* SW: Store Word */fastcall void MTS_PROTO(sw)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; data = cpu->gpr[reg] & 0xffffffff; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SW,4,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data);}/* SD: Store Double-Word */fastcall void MTS_PROTO(sd)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; data = cpu->gpr[reg]; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SD,8,MTS_WRITE,&data); if (likely(haddr != NULL)) *(m_uint64_t *)haddr = htovm64(data);}/* LDC1: Load Double-Word To Coprocessor 1 */fastcall void MTS_PROTO(ldc1)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg){ m_uint64_t data; void *haddr; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LDC1,8,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); cpu->fpu.reg[reg] = data;}/* LWL: Load Word Left */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; naddr = vaddr & ~(0x03); haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LWL,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); 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 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; naddr = vaddr & ~(0x03); haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LWR,4,MTS_READ,&data); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); 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); cpu->gpr[reg] &= ~r_mask; cpu->gpr[reg] |= data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -