aboutsummaryrefslogtreecommitdiff
path: root/target-sh4
diff options
context:
space:
mode:
Diffstat (limited to 'target-sh4')
-rw-r--r--target-sh4/cpu.h8
-rw-r--r--target-sh4/helper.c74
2 files changed, 82 insertions, 0 deletions
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 9eccb0cf8c..789d1880b7 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -201,12 +201,20 @@ 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);
+uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSH4State *s,
+ target_phys_addr_t addr);
void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr,
uint32_t mem_value);
+uint32_t cpu_sh4_read_mmaped_itlb_data(CPUSH4State *s,
+ target_phys_addr_t addr);
void cpu_sh4_write_mmaped_itlb_data(CPUSH4State *s, target_phys_addr_t addr,
uint32_t mem_value);
+uint32_t cpu_sh4_read_mmaped_utlb_addr(CPUSH4State *s,
+ target_phys_addr_t addr);
void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
uint32_t mem_value);
+uint32_t cpu_sh4_read_mmaped_utlb_data(CPUSH4State *s,
+ target_phys_addr_t addr);
void cpu_sh4_write_mmaped_utlb_data(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 4cd42b51cb..785e9e54e7 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -567,6 +567,17 @@ void cpu_load_tlb(CPUSH4State * env)
tlb_flush(s, 1);
}
+uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSH4State *s,
+ target_phys_addr_t addr)
+{
+ int index = (addr & 0x00000300) >> 8;
+ tlb_t * entry = &s->itlb[index];
+
+ return (entry->vpn << 10) |
+ (entry->v << 8) |
+ (entry->asid);
+}
+
void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr,
uint32_t mem_value)
{
@@ -586,6 +597,29 @@ void cpu_sh4_write_mmaped_itlb_addr(CPUSH4State *s, target_phys_addr_t addr,
entry->v = v;
}
+uint32_t cpu_sh4_read_mmaped_itlb_data(CPUSH4State *s,
+ target_phys_addr_t addr)
+{
+ int array = (addr & 0x00800000) >> 23;
+ int index = (addr & 0x00000300) >> 8;
+ tlb_t * entry = &s->itlb[index];
+
+ if (array == 0) {
+ /* ITLB Data Array 1 */
+ return (entry->ppn << 10) |
+ (entry->v << 8) |
+ (entry->pr << 5) |
+ ((entry->sz & 1) << 6) |
+ ((entry->sz & 2) << 4) |
+ (entry->c << 3) |
+ (entry->sh << 1);
+ } else {
+ /* ITLB Data Array 2 */
+ return (entry->tc << 1) |
+ (entry->sa);
+ }
+}
+
void cpu_sh4_write_mmaped_itlb_data(CPUSH4State *s, target_phys_addr_t addr,
uint32_t mem_value)
{
@@ -614,6 +648,19 @@ void cpu_sh4_write_mmaped_itlb_data(CPUSH4State *s, target_phys_addr_t addr,
}
}
+uint32_t cpu_sh4_read_mmaped_utlb_addr(CPUSH4State *s,
+ target_phys_addr_t addr)
+{
+ int index = (addr & 0x00003f00) >> 8;
+ tlb_t * entry = &s->utlb[index];
+
+ increment_urc(s); /* per utlb access */
+
+ return (entry->vpn << 10) |
+ (entry->v << 8) |
+ (entry->asid);
+}
+
void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
uint32_t mem_value)
{
@@ -686,6 +733,33 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
}
}
+uint32_t cpu_sh4_read_mmaped_utlb_data(CPUSH4State *s,
+ target_phys_addr_t addr)
+{
+ int array = (addr & 0x00800000) >> 23;
+ int index = (addr & 0x00003f00) >> 8;
+ tlb_t * entry = &s->utlb[index];
+
+ increment_urc(s); /* per utlb access */
+
+ if (array == 0) {
+ /* ITLB Data Array 1 */
+ return (entry->ppn << 10) |
+ (entry->v << 8) |
+ (entry->pr << 5) |
+ ((entry->sz & 1) << 6) |
+ ((entry->sz & 2) << 4) |
+ (entry->c << 3) |
+ (entry->d << 2) |
+ (entry->sh << 1) |
+ (entry->wt);
+ } else {
+ /* ITLB Data Array 2 */
+ return (entry->tc << 1) |
+ (entry->sa);
+ }
+}
+
void cpu_sh4_write_mmaped_utlb_data(CPUSH4State *s, target_phys_addr_t addr,
uint32_t mem_value)
{