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