diff --git a/hw/sh7750.c b/hw/sh7750.c index 9e54ad1904..36b702f628 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -670,6 +670,8 @@ static void sh7750_mmct_writel(void *opaque, target_phys_addr_t addr, /* do nothing */ break; case MM_ITLB_ADDR: + cpu_sh4_write_mmaped_itlb_addr(s->cpu, addr, mem_value); + break; case MM_ITLB_DATA: /* XXXXX */ abort(); diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index e19776643b..8ccf25cafb 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -172,6 +172,8 @@ void do_interrupt(CPUSH4State * env); void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf); #if !defined(CONFIG_USER_ONLY) void cpu_sh4_invalidate_tlb(CPUSH4State *s); +void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr, + uint32_t mem_value); void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, uint32_t mem_value); #endif diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 9e70352311..863886b89e 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -544,6 +544,25 @@ void cpu_load_tlb(CPUSH4State * env) tlb_flush(s, 1); } +void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr, + uint32_t mem_value) +{ + uint32_t vpn = (mem_value & 0xfffffc00) >> 10; + uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8); + uint8_t asid = (uint8_t)(mem_value & 0x000000ff); + + int index = (addr & 0x00003f00) >> 8; + tlb_t * entry = &s->itlb[index]; + if (entry->v) { + /* Overwriting valid entry in itlb. */ + target_ulong address = entry->vpn << 10; + tlb_flush_page(s, address); + } + entry->asid = asid; + entry->vpn = vpn; + entry->v = v; +} + void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, uint32_t mem_value) {