Commit eeda67786ccfb1016d8bd5977821bc5175ae862a
1 parent
f6198371
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
Showing
1 changed file
with
6 additions
and
6 deletions
target-sh4/helper.c
@@ -255,7 +255,7 @@ static int find_tlb_entry(CPUState * env, target_ulong address, | @@ -255,7 +255,7 @@ static int find_tlb_entry(CPUState * env, target_ulong address, | ||
255 | for (i = 0; i < nbtlb; i++) { | 255 | for (i = 0; i < nbtlb; i++) { |
256 | if (!entries[i].v) | 256 | if (!entries[i].v) |
257 | continue; /* Invalid entry */ | 257 | continue; /* Invalid entry */ |
258 | - if (use_asid && entries[i].asid != asid) | 258 | + if (!entries[i].sh && use_asid && entries[i].asid != asid) |
259 | continue; /* Bad ASID */ | 259 | continue; /* Bad ASID */ |
260 | #if 0 | 260 | #if 0 |
261 | switch (entries[i].sz) { | 261 | switch (entries[i].sz) { |
@@ -538,9 +538,6 @@ void cpu_load_tlb(CPUState * env) | @@ -538,9 +538,6 @@ void cpu_load_tlb(CPUState * env) | ||
538 | } | 538 | } |
539 | } | 539 | } |
540 | 540 | ||
541 | - /* per utlb access cannot implemented. */ | ||
542 | - increment_urc(env); | ||
543 | - | ||
544 | /* Take values into cpu status from registers. */ | 541 | /* Take values into cpu status from registers. */ |
545 | entry->asid = (uint8_t)cpu_pteh_asid(env->pteh); | 542 | entry->asid = (uint8_t)cpu_pteh_asid(env->pteh); |
546 | entry->vpn = cpu_pteh_vpn(env->pteh); | 543 | 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, | @@ -581,6 +578,7 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, | ||
581 | uint8_t d = (uint8_t)((mem_value & 0x00000200) >> 9); | 578 | uint8_t d = (uint8_t)((mem_value & 0x00000200) >> 9); |
582 | uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8); | 579 | uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8); |
583 | uint8_t asid = (uint8_t)(mem_value & 0x000000ff); | 580 | uint8_t asid = (uint8_t)(mem_value & 0x000000ff); |
581 | + int use_asid = (s->mmucr & MMUCR_SV) == 0 || (s->sr & SR_MD) == 0; | ||
584 | 582 | ||
585 | if (associate) { | 583 | if (associate) { |
586 | int i; | 584 | int i; |
@@ -593,7 +591,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, | @@ -593,7 +591,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, | ||
593 | if (!entry->v) | 591 | if (!entry->v) |
594 | continue; | 592 | continue; |
595 | 593 | ||
596 | - if (entry->vpn == vpn && entry->asid == asid) { | 594 | + if (entry->vpn == vpn |
595 | + && (!use_asid || entry->asid == asid || entry->sh)) { | ||
597 | if (utlb_match_entry) { | 596 | if (utlb_match_entry) { |
598 | /* Multiple TLB Exception */ | 597 | /* Multiple TLB Exception */ |
599 | s->exception_index = 0x140; | 598 | s->exception_index = 0x140; |
@@ -612,7 +611,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, | @@ -612,7 +611,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, | ||
612 | /* search ITLB */ | 611 | /* search ITLB */ |
613 | for (i = 0; i < ITLB_SIZE; i++) { | 612 | for (i = 0; i < ITLB_SIZE; i++) { |
614 | tlb_t * entry = &s->itlb[i]; | 613 | tlb_t * entry = &s->itlb[i]; |
615 | - if (entry->vpn == vpn && entry->asid == asid) { | 614 | + if (entry->vpn == vpn |
615 | + && (!use_asid || entry->asid == asid || entry->sh)) { | ||
616 | if (entry->v && !v) | 616 | if (entry->v && !v) |
617 | needs_tlb_flush = 1; | 617 | needs_tlb_flush = 1; |
618 | if (utlb_match_entry) | 618 | if (utlb_match_entry) |