/* * 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, u_int *exc); 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;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_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 - dev->phys_addr; alt_entry->gvpa = map->vaddr; alt_entry->gppa = map->paddr; 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; u_int exc; return(MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LOOKUP,4,MTS_READ, &data,&exc)); } /* === MIPS Memory Operations ============================================= */ /* LB: Load Byte */ fastcall u_int 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); if (likely(haddr != NULL)) data = *(m_uint8_t *)haddr; if (likely(!exc)) cpu->gpr[reg] = sign_extend(data,8); return(exc); } /* LBU: Load Byte Unsigned */ fastcall u_int 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); if (likely(haddr != NULL)) data = *(m_uint8_t *)haddr; if (likely(!exc)) cpu->gpr[reg] = data & 0xff; return(exc); } /* LH: Load Half-Word */ fastcall u_int 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); if (likely(haddr != NULL)) data = vmtoh16(*(m_uint16_t *)haddr); if (likely(!exc)) cpu->gpr[reg] = sign_extend(data,16); return(exc); } /* LHU: Load Half-Word Unsigned */ fastcall u_int 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); if (likely(haddr != NULL)) data = vmtoh16(*(m_uint16_t *)haddr); if (likely(!exc)) cpu->gpr[reg] = data & 0xffff; return(exc); } /* LW: Load Word */ fastcall u_int 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); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); if (likely(!exc)) cpu->gpr[reg] = sign_extend(data,32); return(exc); } /* LWU: Load Word Unsigned */ fastcall u_int 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); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); if (likely(!exc)) cpu->gpr[reg] = data & 0xffffffff; return(exc); } /* LD: Load Double-Word */ fastcall u_int 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); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); if (likely(!exc)) cpu->gpr[reg] = data; return(exc); } /* SB: Store Byte */ fastcall u_int 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); 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) { 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); 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) { 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); 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) { 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); 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) { m_uint64_t data; void *haddr; u_int exc; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LDC1,8,MTS_READ,&data,&exc); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); if (likely(!exc)) cpu->fpu.reg[reg] = data; return(exc); } /* LWL: Load Word Left */ fastcall u_int 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); 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); } /* LWR: Load Word Right */ fastcall u_int 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); 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; 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); } /* LDL: Load Double-Word Left */ fastcall u_int 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); 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; cpu->gpr[reg] &= r_mask; cpu->gpr[reg] |= data; } return(exc); } /* LDR: Load Double-Word Right */ fastcall u_int 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); 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); } /* SWL: Store Word Left */ fastcall u_int 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); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); r_shift = (vaddr & 0x03) << 3; d_mask = 0xffffffff >> r_shift; data &= ~d_mask; data |= (cpu->gpr[reg] & 0xffffffff) >> r_shift; haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWL,4,MTS_WRITE,&data,&exc); 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) { 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); if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr); r_shift = ((vaddr & 0x03) + 1) << 3; d_mask = 0xffffffff >> r_shift; 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); 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) { 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); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); r_shift = (vaddr & 0x07) << 3; d_mask = 0xffffffffffffffffULL >> r_shift; data &= ~d_mask; data |= cpu->gpr[reg] >> r_shift; haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDL,8,MTS_WRITE,&data,&exc); 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) { 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); if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr); r_shift = ((vaddr & 0x07) + 1) << 3; d_mask = 0xffffffffffffffffULL >> r_shift; data &= d_mask; data |= cpu->gpr[reg] << (64 - r_shift); haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDR,8,MTS_WRITE,&data,&exc); 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) { m_uint64_t data; void *haddr; u_int exc; haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LL,4,MTS_READ,&data,&exc); 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); } /* SC: Store Conditional */ fastcall u_int 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); if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data); } if (likely(!exc)) cpu->gpr[reg] = cpu->ll_bit; return(exc); } /* SDC1: Store Double-Word from Coprocessor 1 */ fastcall u_int 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); 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) { mips64_jit_tcb_t *block; m_uint32_t pc_hash; #if DEBUG_CACHE 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->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->gen,"MTS", "CACHE: removing compiled page at 0x%llx, pc=0x%llx\n", block->start_pc,cpu->pc); #endif cpu->exec_blk_map[pc_hash] = NULL; mips64_jit_tcb_free(cpu,block,TRUE); } else { #if DEBUG_CACHE 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 ============================================= */ /* MTS map/unmap/rebuild "API" functions */ void MTS_PROTO(api_map)(cpu_mips_t *cpu,m_uint64_t vaddr,m_uint64_t paddr, m_uint32_t len,int cache_access,int tlb_index) { /* nothing to do, the cache will be filled on-the-fly */ } void MTS_PROTO(api_unmap)(cpu_mips_t *cpu,m_uint64_t vaddr,m_uint32_t len, m_uint32_t val,int tlb_index) { /* Invalidate the TLB entry or the full cache if no index is specified */ if (tlb_index != -1) MTS_PROTO(invalidate_tlb_entry)(cpu,tlb_index); else MTS_PROTO(invalidate_cache)(cpu); } void MTS_PROTO(api_rebuild)(cpu_gen_t *cpu) { MTS_PROTO(invalidate_cache)(CPU_MIPS64(cpu)); } /* ======================================================================== */ /* Initialize memory access vectors */ void MTS_PROTO(init_memop_vectors)(cpu_mips_t *cpu) { /* XXX TODO: * - LD/SD forbidden in Supervisor/User modes with 32-bit addresses. */ cpu->addr_mode = MTS_ADDR_SIZE; /* API vectors */ cpu->mts_map = MTS_PROTO(api_map); cpu->mts_unmap = MTS_PROTO(api_unmap); /* Memory lookup operation */ cpu->mem_op_lookup = MTS_PROTO(lookup); /* Translation operation */ cpu->translate = MTS_PROTO(translate); /* Shutdown operation */ cpu->mts_shutdown = MTS_PROTO(shutdown); /* Rebuild MTS data structures */ cpu->gen->mts_rebuild = MTS_PROTO(api_rebuild); /* Show statistics */ cpu->gen->mts_show_stats = MTS_PROTO(show_stats); /* Load Operations */ cpu->mem_op_fn[MIPS_MEMOP_LB] = MTS_PROTO(lb); cpu->mem_op_fn[MIPS_MEMOP_LBU] = MTS_PROTO(lbu); cpu->mem_op_fn[MIPS_MEMOP_LH] = MTS_PROTO(lh); cpu->mem_op_fn[MIPS_MEMOP_LHU] = MTS_PROTO(lhu); cpu->mem_op_fn[MIPS_MEMOP_LW] = MTS_PROTO(lw); cpu->mem_op_fn[MIPS_MEMOP_LWU] = MTS_PROTO(lwu); cpu->mem_op_fn[MIPS_MEMOP_LD] = MTS_PROTO(ld); cpu->mem_op_fn[MIPS_MEMOP_LDL] = MTS_PROTO(ldl); cpu->mem_op_fn[MIPS_MEMOP_LDR] = MTS_PROTO(ldr); /* Store Operations */ cpu->mem_op_fn[MIPS_MEMOP_SB] = MTS_PROTO(sb); cpu->mem_op_fn[MIPS_MEMOP_SH] = MTS_PROTO(sh); cpu->mem_op_fn[MIPS_MEMOP_SW] = MTS_PROTO(sw); cpu->mem_op_fn[MIPS_MEMOP_SD] = MTS_PROTO(sd); /* Load Left/Right operations */ cpu->mem_op_fn[MIPS_MEMOP_LWL] = MTS_PROTO(lwl); cpu->mem_op_fn[MIPS_MEMOP_LWR] = MTS_PROTO(lwr); cpu->mem_op_fn[MIPS_MEMOP_LDL] = MTS_PROTO(ldl); cpu->mem_op_fn[MIPS_MEMOP_LDR] = MTS_PROTO(ldr); /* Store Left/Right operations */ cpu->mem_op_fn[MIPS_MEMOP_SWL] = MTS_PROTO(swl); cpu->mem_op_fn[MIPS_MEMOP_SWR] = MTS_PROTO(swr); cpu->mem_op_fn[MIPS_MEMOP_SDL] = MTS_PROTO(sdl); cpu->mem_op_fn[MIPS_MEMOP_SDR] = MTS_PROTO(sdr); /* LL/SC - Load Linked / Store Conditional */ cpu->mem_op_fn[MIPS_MEMOP_LL] = MTS_PROTO(ll); cpu->mem_op_fn[MIPS_MEMOP_SC] = MTS_PROTO(sc); /* Coprocessor 1 memory access functions */ cpu->mem_op_fn[MIPS_MEMOP_LDC1] = MTS_PROTO(ldc1); cpu->mem_op_fn[MIPS_MEMOP_SDC1] = MTS_PROTO(sdc1); /* Cache Operation */ cpu->mem_op_fn[MIPS_MEMOP_CACHE] = MTS_PROTO(cache); } #undef MTS_ADDR_SIZE #undef MTS_NAME #undef MTS_NAME_UP #undef MTS_PROTO #undef MTS_PROTO_UP #undef MTS_ENTRY #undef MTS_CHUNK