📄 mips_mts.c
字号:
/* 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){ struct insn_block *block; m_uint32_t phys_page;#if DEBUG_CACHE cpu_log(cpu,"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 DEBUG_CACHE cpu_log(cpu,"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 {#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 } } } } 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_mips_t *cpu){ MTS_PROTO(invalidate_cache)(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); cpu->mts_rebuild = MTS_PROTO(api_rebuild); /* 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); /* Show statistics */ cpu->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_PROTO#undef MTS_PROTO_UP#undef MTS_ENTRY#undef MTS_CHUNK
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -