--- upstream/dynamips-0.2.7/mips64_mem.c 2007/10/06 16:29:14 10 +++ upstream/dynamips-0.2.8-RC1/mips64_mem.c 2007/10/06 16:33:40 11 @@ -24,10 +24,19 @@ /* MTS access with special access mask */ void mips64_access_special(cpu_mips_t *cpu,m_uint64_t vaddr,m_uint32_t mask, u_int op_code,u_int op_type,u_int op_size, - m_uint64_t *data,u_int *exc) + m_uint64_t *data) { switch(mask) { case MTS_ACC_U: + if (op_type == MTS_READ) + *data = 0; + + if (cpu->gen->undef_mem_handler != NULL) { + if (cpu->gen->undef_mem_handler(cpu->gen,vaddr,op_size,op_type, + data)) + return; + } + #if DEBUG_MTS_ACC_U if (op_type == MTS_READ) cpu_log(cpu->gen, @@ -39,8 +48,6 @@ "pc=0x%llx, value=0x%8.8llx (size=%u)\n", vaddr,cpu->pc,*data,op_size); #endif - if (op_type == MTS_READ) - *data = 0; break; case MTS_ACC_T: @@ -56,15 +63,16 @@ memlog_dump(cpu->gen); #endif #endif + cpu->cp0.reg[MIPS_CP0_BADVADDR] = vaddr; if (op_type == MTS_READ) mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_TLB_LOAD,0); else mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_TLB_SAVE,0); + + cpu_exec_loop_enter(cpu->gen); } - - *exc = 1; break; case MTS_ACC_AE: @@ -81,9 +89,9 @@ mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_ADDR_LOAD,0); else mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_ADDR_SAVE,0); - } - *exc = 1; + cpu_exec_loop_enter(cpu->gen); + } break; } } @@ -113,7 +121,7 @@ mips64_mts64_slow_lookup(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,mts64_entry_t *alt_entry) + mts64_entry_t *alt_entry) { m_uint32_t hash_bucket,zone,sub_zone,cca; mts64_entry_t *entry; @@ -148,6 +156,7 @@ case 0x7fc: /* ckseg0 */ map.vaddr = vaddr & MIPS_MIN_PAGE_MASK; map.paddr = map.vaddr - 0xFFFFFFFF80000000ULL; + map.offset = vaddr & MIPS_MIN_PAGE_IMASK; map.cached = TRUE; if (!(entry = mips64_mts64_map(cpu,op_type,&map, @@ -159,6 +168,7 @@ case 0x7fd: /* ckseg1 */ map.vaddr = vaddr & MIPS_MIN_PAGE_MASK; map.paddr = map.vaddr - 0xFFFFFFFFA0000000ULL; + map.offset = vaddr & MIPS_MIN_PAGE_IMASK; map.cached = FALSE; if (!(entry = mips64_mts64_map(cpu,op_type,&map, @@ -199,6 +209,7 @@ map.vaddr = vaddr & MIPS_MIN_PAGE_MASK; map.paddr = (vaddr & MIPS64_XKPHYS_PHYS_MASK); map.paddr &= MIPS_MIN_PAGE_MASK; + map.offset = vaddr & MIPS_MIN_PAGE_IMASK; if (!(entry = mips64_mts64_map(cpu,op_type,&map,entry,alt_entry))) goto err_undef; @@ -211,14 +222,13 @@ } err_undef: - mips64_access_special(cpu,vaddr,MTS_ACC_U,op_code,op_type,op_size,data,exc); + mips64_access_special(cpu,vaddr,MTS_ACC_U,op_code,op_type,op_size,data); return NULL; err_address: - mips64_access_special(cpu,vaddr,MTS_ACC_AE,op_code,op_type,op_size, - data,exc); + mips64_access_special(cpu,vaddr,MTS_ACC_AE,op_code,op_type,op_size,data); return NULL; err_tlb: - mips64_access_special(cpu,vaddr,MTS_ACC_T,op_code,op_type,op_size,data,exc); + mips64_access_special(cpu,vaddr,MTS_ACC_T,op_code,op_type,op_size,data); return NULL; } @@ -226,8 +236,7 @@ static forced_inline void *mips64_mts64_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) { mts64_entry_t *entry,alt_entry; m_uint32_t hash_bucket; @@ -240,7 +249,6 @@ memlog_rec_access(cpu->gen,vaddr,*data,op_size,op_type); #endif - *exc = 0; hash_bucket = MTS64_HASH(vaddr); entry = &cpu->mts_u.mts64_cache[hash_bucket]; @@ -254,14 +262,13 @@ /* Slow lookup if nothing found in cache */ if (unlikely(((vaddr & MIPS_MIN_PAGE_MASK) != entry->gvpa) || cow)) { entry = mips64_mts64_slow_lookup(cpu,vaddr,op_code,op_size,op_type, - data,exc,&alt_entry); + data,&alt_entry); if (!entry) return NULL; if (entry->flags & MTS_FLAG_DEV) { dev_id = (entry->hpa & MTS_DEVID_MASK) >> MTS_DEVID_SHIFT; haddr = entry->hpa & MTS_DEVOFF_MASK; - haddr += vaddr - entry->gvpa; return(dev_access_fast(cpu->gen,dev_id,haddr,op_size,op_type,data)); } } @@ -281,7 +288,6 @@ mts64_entry_t *entry,alt_entry; m_uint32_t hash_bucket; m_uint64_t data = 0; - u_int exc = 0; hash_bucket = MTS64_HASH(vaddr); entry = &cpu->mts_u.mts64_cache[hash_bucket]; @@ -289,7 +295,7 @@ /* Slow lookup if nothing found in cache */ if (unlikely((vaddr & MIPS_MIN_PAGE_MASK) != entry->gvpa)) { entry = mips64_mts64_slow_lookup(cpu,vaddr,MIPS_MEMOP_LOOKUP,4,MTS_READ, - &data,&exc,&alt_entry); + &data,&alt_entry); if (!entry) return(-1); } @@ -305,7 +311,7 @@ mips64_mts32_slow_lookup(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,mts32_entry_t *alt_entry) + mts32_entry_t *alt_entry) { m_uint32_t hash_bucket,zone; mts32_entry_t *entry; @@ -334,6 +340,7 @@ case 0x04: /* kseg0 */ map.vaddr = vaddr & MIPS_MIN_PAGE_MASK; map.paddr = map.vaddr - 0xFFFFFFFF80000000ULL; + map.offset = vaddr & MIPS_MIN_PAGE_IMASK; map.cached = TRUE; if (!(entry = mips64_mts32_map(cpu,op_type,&map,entry,alt_entry))) @@ -344,6 +351,7 @@ case 0x05: /* kseg1 */ map.vaddr = vaddr & MIPS_MIN_PAGE_MASK; map.paddr = map.vaddr - 0xFFFFFFFFA0000000ULL; + map.offset = vaddr & MIPS_MIN_PAGE_IMASK; map.cached = FALSE; if (!(entry = mips64_mts32_map(cpu,op_type,&map,entry,alt_entry))) @@ -364,14 +372,13 @@ } err_undef: - mips64_access_special(cpu,vaddr,MTS_ACC_U,op_code,op_type,op_size,data,exc); + mips64_access_special(cpu,vaddr,MTS_ACC_U,op_code,op_type,op_size,data); return NULL; err_address: - mips64_access_special(cpu,vaddr,MTS_ACC_AE,op_code,op_type,op_size, - data,exc); + mips64_access_special(cpu,vaddr,MTS_ACC_AE,op_code,op_type,op_size,data); return NULL; err_tlb: - mips64_access_special(cpu,vaddr,MTS_ACC_T,op_code,op_type,op_size,data,exc); + mips64_access_special(cpu,vaddr,MTS_ACC_T,op_code,op_type,op_size,data); return NULL; } @@ -379,8 +386,7 @@ static forced_inline void *mips64_mts32_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) { mts32_entry_t *entry,alt_entry; m_uint32_t hash_bucket; @@ -393,7 +399,6 @@ memlog_rec_access(cpu->gen,vaddr,*data,op_size,op_type); #endif - *exc = 0; hash_bucket = MTS32_HASH(vaddr); entry = &cpu->mts_u.mts32_cache[hash_bucket]; @@ -409,14 +414,13 @@ cow)) { entry = mips64_mts32_slow_lookup(cpu,vaddr,op_code,op_size,op_type, - data,exc,&alt_entry); + data,&alt_entry); if (!entry) return NULL; if (entry->flags & MTS_FLAG_DEV) { dev_id = (entry->hpa & MTS_DEVID_MASK) >> MTS_DEVID_SHIFT; haddr = entry->hpa & MTS_DEVOFF_MASK; - haddr += vaddr - entry->gvpa; return(dev_access_fast(cpu->gen,dev_id,haddr,op_size,op_type,data)); } } @@ -436,7 +440,6 @@ mts32_entry_t *entry,alt_entry; m_uint32_t hash_bucket; m_uint64_t data = 0; - u_int exc = 0; hash_bucket = MTS32_HASH(vaddr); entry = &cpu->mts_u.mts32_cache[hash_bucket]; @@ -444,7 +447,7 @@ /* Slow lookup if nothing found in cache */ if (unlikely(((m_uint32_t)vaddr & MIPS_MIN_PAGE_MASK) != entry->gvpa)) { entry = mips64_mts32_slow_lookup(cpu,vaddr,MIPS_MEMOP_LOOKUP,4,MTS_READ, - &data,&exc,&alt_entry); + &data,&alt_entry); if (!entry) return(-1); }