Commit 98c1b82b6cf96d650bf07a6a2bf0414907924ffe

Authored by pbrook
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
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  
... ...