diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-10 17:31:51 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-10 17:31:51 +0000 |
commit | eeda67786ccfb1016d8bd5977821bc5175ae862a (patch) | |
tree | 491fb3380e9687ce8075f5c2d3af783f45d99540 /target-sh4 | |
parent | target-sh4: check FD bit for FP instructions (diff) | |
download | qemu-kvm-eeda67786ccfb1016d8bd5977821bc5175ae862a.tar.gz qemu-kvm-eeda67786ccfb1016d8bd5977821bc5175ae862a.tar.bz2 qemu-kvm-eeda67786ccfb1016d8bd5977821bc5175ae862a.zip |
target-sh4: Add SH bit handling to TLB
This patch adds SH bit handling to sh4's TLB, which is a part of MMU
functionality that had not been implemented in qemu.
Additionally, increment_urc() call in cpu_load_tlb() is deleted, because
the specification explicitly says that URC is not incremented by an LDTLB
instruction (at Section 3 of SH7751 Hardware manual(REJ09B0370-0400)).
Even though URC is not needed to be strictly same as HW because it is a
random number, this condition is not negligible.
Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5971 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sh4')
-rw-r--r-- | target-sh4/helper.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/target-sh4/helper.c b/target-sh4/helper.c index c2cc4325e..882bc9c54 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -255,7 +255,7 @@ static int find_tlb_entry(CPUState * env, target_ulong address, for (i = 0; i < nbtlb; i++) { if (!entries[i].v) continue; /* Invalid entry */ - if (use_asid && entries[i].asid != asid) + if (!entries[i].sh && use_asid && entries[i].asid != asid) continue; /* Bad ASID */ #if 0 switch (entries[i].sz) { @@ -538,9 +538,6 @@ void cpu_load_tlb(CPUState * env) } } - /* per utlb access cannot implemented. */ - increment_urc(env); - /* Take values into cpu status from registers. */ entry->asid = (uint8_t)cpu_pteh_asid(env->pteh); entry->vpn = cpu_pteh_vpn(env->pteh); @@ -581,6 +578,7 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, uint8_t d = (uint8_t)((mem_value & 0x00000200) >> 9); uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8); uint8_t asid = (uint8_t)(mem_value & 0x000000ff); + int use_asid = (s->mmucr & MMUCR_SV) == 0 || (s->sr & SR_MD) == 0; if (associate) { int i; @@ -593,7 +591,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, if (!entry->v) continue; - if (entry->vpn == vpn && entry->asid == asid) { + if (entry->vpn == vpn + && (!use_asid || entry->asid == asid || entry->sh)) { if (utlb_match_entry) { /* Multiple TLB Exception */ s->exception_index = 0x140; @@ -612,7 +611,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, /* search ITLB */ for (i = 0; i < ITLB_SIZE; i++) { tlb_t * entry = &s->itlb[i]; - if (entry->vpn == vpn && entry->asid == asid) { + if (entry->vpn == vpn + && (!use_asid || entry->asid == asid || entry->sh)) { if (entry->v && !v) needs_tlb_flush = 1; if (utlb_match_entry) |