aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/sh7750.c2
-rw-r--r--target-sh4/cpu.h2
-rw-r--r--target-sh4/helper.c19
3 files changed, 23 insertions, 0 deletions
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)
{