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 | 255 | for (i = 0; i < nbtlb; i++) { |
256 | 256 | if (!entries[i].v) |
257 | 257 | continue; /* Invalid entry */ |
258 | - if (use_asid && entries[i].asid != asid) | |
258 | + if (!entries[i].sh && use_asid && entries[i].asid != asid) | |
259 | 259 | continue; /* Bad ASID */ |
260 | 260 | #if 0 |
261 | 261 | switch (entries[i].sz) { |
... | ... | @@ -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 | 541 | /* Take values into cpu status from registers. */ |
545 | 542 | entry->asid = (uint8_t)cpu_pteh_asid(env->pteh); |
546 | 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 | 578 | uint8_t d = (uint8_t)((mem_value & 0x00000200) >> 9); |
582 | 579 | uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8); |
583 | 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 | 583 | if (associate) { |
586 | 584 | int i; |
... | ... | @@ -593,7 +591,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, |
593 | 591 | if (!entry->v) |
594 | 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 | 596 | if (utlb_match_entry) { |
598 | 597 | /* Multiple TLB Exception */ |
599 | 598 | s->exception_index = 0x140; |
... | ... | @@ -612,7 +611,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, |
612 | 611 | /* search ITLB */ |
613 | 612 | for (i = 0; i < ITLB_SIZE; i++) { |
614 | 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 | 616 | if (entry->v && !v) |
617 | 617 | needs_tlb_flush = 1; |
618 | 618 | if (utlb_match_entry) | ... | ... |