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 | ... | ... |