Commit 98c1b82b6cf96d650bf07a6a2bf0414907924ffe
1 parent
6d6f7c28
e bitfields in mips TLB structures (Thiemo Seufer).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1774 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
35 additions
and
41 deletions
target-mips/cpu.h
| @@ -21,11 +21,14 @@ struct tlb_t { | @@ -21,11 +21,14 @@ struct tlb_t { | ||
| 21 | target_ulong VPN; | 21 | target_ulong VPN; |
| 22 | target_ulong end; | 22 | target_ulong end; |
| 23 | target_ulong end2; | 23 | target_ulong end2; |
| 24 | - uint8_t ASID; | ||
| 25 | - uint8_t G; | ||
| 26 | - uint8_t C[2]; | ||
| 27 | - uint8_t V[2]; | ||
| 28 | - uint8_t D[2]; | 24 | + uint_fast8_t ASID; |
| 25 | + uint_fast16_t G:1; | ||
| 26 | + uint_fast16_t C0:3; | ||
| 27 | + uint_fast16_t C1:3; | ||
| 28 | + uint_fast16_t V0:1; | ||
| 29 | + uint_fast16_t V1:1; | ||
| 30 | + uint_fast16_t D0:1; | ||
| 31 | + uint_fast16_t D1:1; | ||
| 29 | target_ulong PFN[2]; | 32 | target_ulong PFN[2]; |
| 30 | }; | 33 | }; |
| 31 | #endif | 34 | #endif |
target-mips/helper.c
| @@ -50,17 +50,16 @@ static int map_address (CPUState *env, target_ulong *physical, int *prot, | @@ -50,17 +50,16 @@ static int map_address (CPUState *env, target_ulong *physical, int *prot, | ||
| 50 | /* TLB match */ | 50 | /* TLB match */ |
| 51 | n = (address >> 12) & 1; | 51 | n = (address >> 12) & 1; |
| 52 | /* Check access rights */ | 52 | /* Check access rights */ |
| 53 | - if ((tlb->V[n] & 2) && (rw == 0 || (tlb->D[n] & 4))) { | 53 | + if (!(n ? tlb->V1 : tlb->V0)) |
| 54 | + return -3; | ||
| 55 | + if (rw == 0 || (n ? tlb->D1 : tlb->D0)) { | ||
| 54 | *physical = tlb->PFN[n] | (address & 0xFFF); | 56 | *physical = tlb->PFN[n] | (address & 0xFFF); |
| 55 | *prot = PAGE_READ; | 57 | *prot = PAGE_READ; |
| 56 | - if (tlb->D[n]) | 58 | + if (n ? tlb->D1 : tlb->D0) |
| 57 | *prot |= PAGE_WRITE; | 59 | *prot |= PAGE_WRITE; |
| 58 | return 0; | 60 | return 0; |
| 59 | - } else if (!(tlb->V[n] & 2)) { | ||
| 60 | - return -3; | ||
| 61 | - } else { | ||
| 62 | - return -4; | ||
| 63 | } | 61 | } |
| 62 | + return -4; | ||
| 64 | } | 63 | } |
| 65 | } | 64 | } |
| 66 | 65 |
target-mips/op_helper.c
| @@ -535,30 +535,22 @@ void do_mtc0 (int reg, int sel) | @@ -535,30 +535,22 @@ void do_mtc0 (int reg, int sel) | ||
| 535 | 535 | ||
| 536 | /* TLB management */ | 536 | /* TLB management */ |
| 537 | #if defined(MIPS_USES_R4K_TLB) | 537 | #if defined(MIPS_USES_R4K_TLB) |
| 538 | -static void invalidate_tb (int idx) | 538 | +static void invalidate_tlb (int idx) |
| 539 | { | 539 | { |
| 540 | tlb_t *tlb; | 540 | tlb_t *tlb; |
| 541 | - target_ulong addr, end; | 541 | + target_ulong addr; |
| 542 | 542 | ||
| 543 | tlb = &env->tlb[idx]; | 543 | tlb = &env->tlb[idx]; |
| 544 | - if (tlb->V[0]) { | ||
| 545 | - addr = tlb->PFN[0]; | ||
| 546 | - end = addr + (tlb->end - tlb->VPN); | ||
| 547 | - tb_invalidate_page_range(addr, end); | ||
| 548 | - /* FIXME: Might be faster to just invalidate the whole "tlb" here | ||
| 549 | - and refill it on demand from our simulated TLB. */ | 544 | + if (tlb->V0) { |
| 545 | + tb_invalidate_page_range(tlb->PFN[0], tlb->end - tlb->VPN); | ||
| 550 | addr = tlb->VPN; | 546 | addr = tlb->VPN; |
| 551 | while (addr < tlb->end) { | 547 | while (addr < tlb->end) { |
| 552 | tlb_flush_page (env, addr); | 548 | tlb_flush_page (env, addr); |
| 553 | addr += TARGET_PAGE_SIZE; | 549 | addr += TARGET_PAGE_SIZE; |
| 554 | } | 550 | } |
| 555 | } | 551 | } |
| 556 | - if (tlb->V[1]) { | ||
| 557 | - addr = tlb->PFN[1]; | ||
| 558 | - end = addr + (tlb->end - tlb->VPN); | ||
| 559 | - tb_invalidate_page_range(addr, end); | ||
| 560 | - /* FIXME: Might be faster to just invalidate the whole "tlb" here | ||
| 561 | - and refill it on demand from our simulated TLB. */ | 552 | + if (tlb->V1) { |
| 553 | + tb_invalidate_page_range(tlb->PFN[1], tlb->end2 - tlb->end); | ||
| 562 | addr = tlb->end; | 554 | addr = tlb->end; |
| 563 | while (addr < tlb->end2) { | 555 | while (addr < tlb->end2) { |
| 564 | tlb_flush_page (env, addr); | 556 | tlb_flush_page (env, addr); |
| @@ -567,7 +559,7 @@ static void invalidate_tb (int idx) | @@ -567,7 +559,7 @@ static void invalidate_tb (int idx) | ||
| 567 | } | 559 | } |
| 568 | } | 560 | } |
| 569 | 561 | ||
| 570 | -static void fill_tb (int idx) | 562 | +static void fill_tlb (int idx) |
| 571 | { | 563 | { |
| 572 | tlb_t *tlb; | 564 | tlb_t *tlb; |
| 573 | int size; | 565 | int size; |
| @@ -575,19 +567,19 @@ static void fill_tb (int idx) | @@ -575,19 +567,19 @@ static void fill_tb (int idx) | ||
| 575 | /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */ | 567 | /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */ |
| 576 | tlb = &env->tlb[idx]; | 568 | tlb = &env->tlb[idx]; |
| 577 | tlb->VPN = env->CP0_EntryHi & 0xFFFFE000; | 569 | tlb->VPN = env->CP0_EntryHi & 0xFFFFE000; |
| 578 | - tlb->ASID = env->CP0_EntryHi & 0x000000FF; | 570 | + tlb->ASID = env->CP0_EntryHi & 0xFF; |
| 579 | size = env->CP0_PageMask >> 13; | 571 | size = env->CP0_PageMask >> 13; |
| 580 | size = 4 * (size + 1); | 572 | size = 4 * (size + 1); |
| 581 | tlb->end = tlb->VPN + (1 << (8 + size)); | 573 | tlb->end = tlb->VPN + (1 << (8 + size)); |
| 582 | tlb->end2 = tlb->end + (1 << (8 + size)); | 574 | tlb->end2 = tlb->end + (1 << (8 + size)); |
| 583 | tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1; | 575 | tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1; |
| 584 | - tlb->V[0] = env->CP0_EntryLo0 & 2; | ||
| 585 | - tlb->D[0] = env->CP0_EntryLo0 & 4; | ||
| 586 | - tlb->C[0] = (env->CP0_EntryLo0 >> 3) & 0x7; | 576 | + tlb->V0 = (env->CP0_EntryLo0 & 2) != 0; |
| 577 | + tlb->D0 = (env->CP0_EntryLo0 & 4) != 0; | ||
| 578 | + tlb->C0 = (env->CP0_EntryLo0 >> 3) & 0x7; | ||
| 587 | tlb->PFN[0] = (env->CP0_EntryLo0 >> 6) << 12; | 579 | tlb->PFN[0] = (env->CP0_EntryLo0 >> 6) << 12; |
| 588 | - tlb->V[1] = env->CP0_EntryLo1 & 2; | ||
| 589 | - tlb->D[1] = env->CP0_EntryLo1 & 4; | ||
| 590 | - tlb->C[1] = (env->CP0_EntryLo1 >> 3) & 0x7; | 580 | + tlb->V1 = (env->CP0_EntryLo1 & 2) != 0; |
| 581 | + tlb->D1 = (env->CP0_EntryLo1 & 4) != 0; | ||
| 582 | + tlb->C1 = (env->CP0_EntryLo1 >> 3) & 0x7; | ||
| 591 | tlb->PFN[1] = (env->CP0_EntryLo1 >> 6) << 12; | 583 | tlb->PFN[1] = (env->CP0_EntryLo1 >> 6) << 12; |
| 592 | } | 584 | } |
| 593 | 585 | ||
| @@ -595,16 +587,16 @@ void do_tlbwi (void) | @@ -595,16 +587,16 @@ void do_tlbwi (void) | ||
| 595 | { | 587 | { |
| 596 | /* Wildly undefined effects for CP0_index containing a too high value and | 588 | /* Wildly undefined effects for CP0_index containing a too high value and |
| 597 | MIPS_TLB_NB not being a power of two. But so does real silicon. */ | 589 | MIPS_TLB_NB not being a power of two. But so does real silicon. */ |
| 598 | - invalidate_tb(env->CP0_index & (MIPS_TLB_NB - 1)); | ||
| 599 | - fill_tb(env->CP0_index & (MIPS_TLB_NB - 1)); | 590 | + invalidate_tlb(env->CP0_index & (MIPS_TLB_NB - 1)); |
| 591 | + fill_tlb(env->CP0_index & (MIPS_TLB_NB - 1)); | ||
| 600 | } | 592 | } |
| 601 | 593 | ||
| 602 | void do_tlbwr (void) | 594 | void do_tlbwr (void) |
| 603 | { | 595 | { |
| 604 | int r = cpu_mips_get_random(env); | 596 | int r = cpu_mips_get_random(env); |
| 605 | 597 | ||
| 606 | - invalidate_tb(r); | ||
| 607 | - fill_tb(r); | 598 | + invalidate_tlb(r); |
| 599 | + fill_tlb(r); | ||
| 608 | } | 600 | } |
| 609 | 601 | ||
| 610 | void do_tlbp (void) | 602 | void do_tlbp (void) |
| @@ -645,10 +637,10 @@ void do_tlbr (void) | @@ -645,10 +637,10 @@ void do_tlbr (void) | ||
| 645 | env->CP0_EntryHi = tlb->VPN | tlb->ASID; | 637 | env->CP0_EntryHi = tlb->VPN | tlb->ASID; |
| 646 | size = (tlb->end - tlb->VPN) >> 12; | 638 | size = (tlb->end - tlb->VPN) >> 12; |
| 647 | env->CP0_PageMask = (size - 1) << 13; | 639 | env->CP0_PageMask = (size - 1) << 13; |
| 648 | - env->CP0_EntryLo0 = tlb->V[0] | tlb->D[0] | (tlb->C[0] << 3) | | ||
| 649 | - (tlb->PFN[0] >> 6); | ||
| 650 | - env->CP0_EntryLo1 = tlb->V[1] | tlb->D[1] | (tlb->C[1] << 3) | | ||
| 651 | - (tlb->PFN[1] >> 6); | 640 | + env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) |
| 641 | + | (tlb->C0 << 3) | (tlb->PFN[0] >> 6); | ||
| 642 | + env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) | ||
| 643 | + | (tlb->C1 << 3) | (tlb->PFN[1] >> 6); | ||
| 652 | } | 644 | } |
| 653 | #endif | 645 | #endif |
| 654 | 646 |