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 | 21 | target_ulong VPN; |
| 22 | 22 | target_ulong end; |
| 23 | 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 | 32 | target_ulong PFN[2]; |
| 30 | 33 | }; |
| 31 | 34 | #endif | ... | ... |
target-mips/helper.c
| ... | ... | @@ -50,17 +50,16 @@ static int map_address (CPUState *env, target_ulong *physical, int *prot, |
| 50 | 50 | /* TLB match */ |
| 51 | 51 | n = (address >> 12) & 1; |
| 52 | 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 | 56 | *physical = tlb->PFN[n] | (address & 0xFFF); |
| 55 | 57 | *prot = PAGE_READ; |
| 56 | - if (tlb->D[n]) | |
| 58 | + if (n ? tlb->D1 : tlb->D0) | |
| 57 | 59 | *prot |= PAGE_WRITE; |
| 58 | 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 | 535 | |
| 536 | 536 | /* TLB management */ |
| 537 | 537 | #if defined(MIPS_USES_R4K_TLB) |
| 538 | -static void invalidate_tb (int idx) | |
| 538 | +static void invalidate_tlb (int idx) | |
| 539 | 539 | { |
| 540 | 540 | tlb_t *tlb; |
| 541 | - target_ulong addr, end; | |
| 541 | + target_ulong addr; | |
| 542 | 542 | |
| 543 | 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 | 546 | addr = tlb->VPN; |
| 551 | 547 | while (addr < tlb->end) { |
| 552 | 548 | tlb_flush_page (env, addr); |
| 553 | 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 | 554 | addr = tlb->end; |
| 563 | 555 | while (addr < tlb->end2) { |
| 564 | 556 | tlb_flush_page (env, addr); |
| ... | ... | @@ -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 | 564 | tlb_t *tlb; |
| 573 | 565 | int size; |
| ... | ... | @@ -575,19 +567,19 @@ static void fill_tb (int idx) |
| 575 | 567 | /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */ |
| 576 | 568 | tlb = &env->tlb[idx]; |
| 577 | 569 | tlb->VPN = env->CP0_EntryHi & 0xFFFFE000; |
| 578 | - tlb->ASID = env->CP0_EntryHi & 0x000000FF; | |
| 570 | + tlb->ASID = env->CP0_EntryHi & 0xFF; | |
| 579 | 571 | size = env->CP0_PageMask >> 13; |
| 580 | 572 | size = 4 * (size + 1); |
| 581 | 573 | tlb->end = tlb->VPN + (1 << (8 + size)); |
| 582 | 574 | tlb->end2 = tlb->end + (1 << (8 + size)); |
| 583 | 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 | 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 | 583 | tlb->PFN[1] = (env->CP0_EntryLo1 >> 6) << 12; |
| 592 | 584 | } |
| 593 | 585 | |
| ... | ... | @@ -595,16 +587,16 @@ void do_tlbwi (void) |
| 595 | 587 | { |
| 596 | 588 | /* Wildly undefined effects for CP0_index containing a too high value and |
| 597 | 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 | 594 | void do_tlbwr (void) |
| 603 | 595 | { |
| 604 | 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 | 602 | void do_tlbp (void) |
| ... | ... | @@ -645,10 +637,10 @@ void do_tlbr (void) |
| 645 | 637 | env->CP0_EntryHi = tlb->VPN | tlb->ASID; |
| 646 | 638 | size = (tlb->end - tlb->VPN) >> 12; |
| 647 | 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 | 645 | #endif |
| 654 | 646 | ... | ... |