Commit a4bb6c3e87b8bfa5db94a4e231e211696e05b4f5

Authored by j_mayer
1 parent 4296f459

Rework PowerPC 440 TLB management (thanks to Hollis Blanchard)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3200 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/op.c
@@ -2365,51 +2365,27 @@ void OPPROTO op_wrte (void) @@ -2365,51 +2365,27 @@ void OPPROTO op_wrte (void)
2365 RETURN(); 2365 RETURN();
2366 } 2366 }
2367 2367
2368 -void OPPROTO op_booke_tlbre0 (void) 2368 +void OPPROTO op_440_tlbre (void)
2369 { 2369 {
2370 - do_booke_tlbre0(); 2370 + do_440_tlbre(PARAM1);
2371 RETURN(); 2371 RETURN();
2372 } 2372 }
2373 2373
2374 -void OPPROTO op_booke_tlbre1 (void) 2374 +void OPPROTO op_440_tlbsx (void)
2375 { 2375 {
2376 - do_booke_tlbre1(); 2376 + do_440_tlbsx();
2377 RETURN(); 2377 RETURN();
2378 } 2378 }
2379 2379
2380 -void OPPROTO op_booke_tlbre2 (void) 2380 +void OPPROTO op_440_tlbsx_ (void)
2381 { 2381 {
2382 - do_booke_tlbre2(); 2382 + do_440_tlbsx_();
2383 RETURN(); 2383 RETURN();
2384 } 2384 }
2385 2385
2386 -void OPPROTO op_booke_tlbsx (void) 2386 +void OPPROTO op_440_tlbwe (void)
2387 { 2387 {
2388 - do_booke_tlbsx();  
2389 - RETURN();  
2390 -}  
2391 -  
2392 -void OPPROTO op_booke_tlbsx_ (void)  
2393 -{  
2394 - do_booke_tlbsx_();  
2395 - RETURN();  
2396 -}  
2397 -  
2398 -void OPPROTO op_booke_tlbwe0 (void)  
2399 -{  
2400 - do_booke_tlbwe0();  
2401 - RETURN();  
2402 -}  
2403 -  
2404 -void OPPROTO op_booke_tlbwe1 (void)  
2405 -{  
2406 - do_booke_tlbwe1();  
2407 - RETURN();  
2408 -}  
2409 -  
2410 -void OPPROTO op_booke_tlbwe2 (void)  
2411 -{  
2412 - do_booke_tlbwe2(); 2388 + do_440_tlbwe(PARAM1);
2413 RETURN(); 2389 RETURN();
2414 } 2390 }
2415 2391
target-ppc/op_helper.c
@@ -2607,95 +2607,79 @@ void do_4xx_tlbwe_lo (void) @@ -2607,95 +2607,79 @@ void do_4xx_tlbwe_lo (void)
2607 #endif 2607 #endif
2608 } 2608 }
2609 2609
2610 -/* BookE TLB management */  
2611 -void do_booke_tlbwe0 (void) 2610 +/* PowerPC 440 TLB management */
  2611 +void do_440_tlbwe (int word)
2612 { 2612 {
2613 ppcemb_tlb_t *tlb; 2613 ppcemb_tlb_t *tlb;
2614 - target_ulong EPN, size; 2614 + target_ulong EPN, RPN, size;
2615 int do_flush_tlbs; 2615 int do_flush_tlbs;
2616 2616
2617 #if defined (DEBUG_SOFTWARE_TLB) 2617 #if defined (DEBUG_SOFTWARE_TLB)
2618 if (loglevel != 0) { 2618 if (loglevel != 0) {
2619 - fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); 2619 + fprintf(logfile, "%s word %d T0 " REGX " T1 " REGX "\n",
  2620 + __func__, word, T0, T1);
2620 } 2621 }
2621 #endif 2622 #endif
2622 do_flush_tlbs = 0; 2623 do_flush_tlbs = 0;
2623 T0 &= 0x3F; 2624 T0 &= 0x3F;
2624 tlb = &env->tlb[T0].tlbe; 2625 tlb = &env->tlb[T0].tlbe;
2625 - EPN = T1 & 0xFFFFFC00;  
2626 - if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN)  
2627 - do_flush_tlbs = 1;  
2628 - tlb->EPN = EPN;  
2629 - size = booke_tlb_to_page_size((T1 >> 4) & 0xF);  
2630 - if ((tlb->prot & PAGE_VALID) && tlb->size < size)  
2631 - do_flush_tlbs = 1;  
2632 - tlb->size = size;  
2633 - tlb->attr &= ~0x1;  
2634 - tlb->attr |= (T1 >> 8) & 1;  
2635 - if (T1 & 0x200) {  
2636 - tlb->prot |= PAGE_VALID;  
2637 - } else {  
2638 - if (tlb->prot & PAGE_VALID) {  
2639 - tlb->prot &= ~PAGE_VALID; 2626 + switch (word) {
  2627 + default:
  2628 + /* Just here to please gcc */
  2629 + case 0:
  2630 + EPN = T1 & 0xFFFFFC00;
  2631 + if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN)
2640 do_flush_tlbs = 1; 2632 do_flush_tlbs = 1;
  2633 + tlb->EPN = EPN;
  2634 + size = booke_tlb_to_page_size((T1 >> 4) & 0xF);
  2635 + if ((tlb->prot & PAGE_VALID) && tlb->size < size)
  2636 + do_flush_tlbs = 1;
  2637 + tlb->size = size;
  2638 + tlb->attr &= ~0x1;
  2639 + tlb->attr |= (T1 >> 8) & 1;
  2640 + if (T1 & 0x200) {
  2641 + tlb->prot |= PAGE_VALID;
  2642 + } else {
  2643 + if (tlb->prot & PAGE_VALID) {
  2644 + tlb->prot &= ~PAGE_VALID;
  2645 + do_flush_tlbs = 1;
  2646 + }
2641 } 2647 }
  2648 + tlb->PID = env->spr[SPR_440_MMUCR] & 0x000000FF;
  2649 + if (do_flush_tlbs)
  2650 + tlb_flush(env, 1);
  2651 + break;
  2652 + case 1:
  2653 + RPN = T1 & 0xFFFFFC0F;
  2654 + if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN)
  2655 + tlb_flush(env, 1);
  2656 + tlb->RPN = RPN;
  2657 + break;
  2658 + case 2:
  2659 + tlb->attr = (tlb->attr & 0x1) | (T1 & 0x0000FF00);
  2660 + tlb->prot = tlb->prot & PAGE_VALID;
  2661 + if (T1 & 0x1)
  2662 + tlb->prot |= PAGE_READ << 4;
  2663 + if (T1 & 0x2)
  2664 + tlb->prot |= PAGE_WRITE << 4;
  2665 + if (T1 & 0x4)
  2666 + tlb->prot |= PAGE_EXEC << 4;
  2667 + if (T1 & 0x8)
  2668 + tlb->prot |= PAGE_READ;
  2669 + if (T1 & 0x10)
  2670 + tlb->prot |= PAGE_WRITE;
  2671 + if (T1 & 0x20)
  2672 + tlb->prot |= PAGE_EXEC;
  2673 + break;
2642 } 2674 }
2643 - tlb->PID = env->spr[SPR_BOOKE_PID];  
2644 - if (do_flush_tlbs)  
2645 - tlb_flush(env, 1);  
2646 -}  
2647 -  
2648 -void do_booke_tlbwe1 (void)  
2649 -{  
2650 - ppcemb_tlb_t *tlb;  
2651 - target_phys_addr_t RPN;  
2652 -  
2653 -#if defined (DEBUG_SOFTWARE_TLB)  
2654 - if (loglevel != 0) {  
2655 - fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1);  
2656 - }  
2657 -#endif  
2658 - T0 &= 0x3F;  
2659 - tlb = &env->tlb[T0].tlbe;  
2660 - RPN = T1 & 0xFFFFFC0F;  
2661 - if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN)  
2662 - tlb_flush(env, 1);  
2663 - tlb->RPN = RPN;  
2664 -}  
2665 -  
2666 -void do_booke_tlbwe2 (void)  
2667 -{  
2668 - ppcemb_tlb_t *tlb;  
2669 -  
2670 -#if defined (DEBUG_SOFTWARE_TLB)  
2671 - if (loglevel != 0) {  
2672 - fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1);  
2673 - }  
2674 -#endif  
2675 - T0 &= 0x3F;  
2676 - tlb = &env->tlb[T0].tlbe;  
2677 - tlb->attr = (tlb->attr & 0x1) | (T1 & 0x0000FF00);  
2678 - tlb->prot = tlb->prot & PAGE_VALID;  
2679 - if (T1 & 0x1)  
2680 - tlb->prot |= PAGE_READ << 4;  
2681 - if (T1 & 0x2)  
2682 - tlb->prot |= PAGE_WRITE << 4;  
2683 - if (T1 & 0x4)  
2684 - tlb->prot |= PAGE_EXEC << 4;  
2685 - if (T1 & 0x8)  
2686 - tlb->prot |= PAGE_READ;  
2687 - if (T1 & 0x10)  
2688 - tlb->prot |= PAGE_WRITE;  
2689 - if (T1 & 0x20)  
2690 - tlb->prot |= PAGE_EXEC;  
2691 } 2675 }
2692 2676
2693 -void do_booke_tlbsx (void) 2677 +void do_440_tlbsx (void)
2694 { 2678 {
2695 T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]); 2679 T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]);
2696 } 2680 }
2697 2681
2698 -void do_booke_tlbsx_ (void) 2682 +void do_440_tlbsx_ (void)
2699 { 2683 {
2700 int tmp = xer_so; 2684 int tmp = xer_so;
2701 2685
@@ -2705,52 +2689,47 @@ void do_booke_tlbsx_ (void) @@ -2705,52 +2689,47 @@ void do_booke_tlbsx_ (void)
2705 env->crf[0] = tmp; 2689 env->crf[0] = tmp;
2706 } 2690 }
2707 2691
2708 -void do_booke_tlbre0 (void) 2692 +void do_440_tlbre (int word)
2709 { 2693 {
2710 ppcemb_tlb_t *tlb; 2694 ppcemb_tlb_t *tlb;
2711 int size; 2695 int size;
2712 2696
2713 T0 &= 0x3F; 2697 T0 &= 0x3F;
2714 tlb = &env->tlb[T0].tlbe; 2698 tlb = &env->tlb[T0].tlbe;
2715 - T0 = tlb->EPN;  
2716 - size = booke_page_size_to_tlb(tlb->size);  
2717 - if (size < 0 || size > 0xF)  
2718 - size = 1;  
2719 - T0 |= size << 4;  
2720 - if (tlb->attr & 0x1)  
2721 - T0 |= 0x100;  
2722 - if (tlb->prot & PAGE_VALID)  
2723 - T0 |= 0x200;  
2724 - env->spr[SPR_BOOKE_PID] = tlb->PID;  
2725 -}  
2726 -  
2727 -void do_booke_tlbre1 (void)  
2728 -{  
2729 - ppcemb_tlb_t *tlb;  
2730 -  
2731 - T0 &= 0x3F;  
2732 - tlb = &env->tlb[T0].tlbe;  
2733 - T0 = tlb->RPN;  
2734 -}  
2735 -  
2736 -void do_booke_tlbre2 (void)  
2737 -{  
2738 - ppcemb_tlb_t *tlb;  
2739 -  
2740 - T0 &= 0x3F;  
2741 - tlb = &env->tlb[T0].tlbe;  
2742 - T0 = tlb->attr & ~0x1;  
2743 - if (tlb->prot & (PAGE_READ << 4))  
2744 - T0 |= 0x1;  
2745 - if (tlb->prot & (PAGE_WRITE << 4))  
2746 - T0 |= 0x2;  
2747 - if (tlb->prot & (PAGE_EXEC << 4))  
2748 - T0 |= 0x4;  
2749 - if (tlb->prot & PAGE_READ)  
2750 - T0 |= 0x8;  
2751 - if (tlb->prot & PAGE_WRITE)  
2752 - T0 |= 0x10;  
2753 - if (tlb->prot & PAGE_EXEC)  
2754 - T0 |= 0x20; 2699 + switch (word) {
  2700 + default:
  2701 + /* Just here to please gcc */
  2702 + case 0:
  2703 + T0 = tlb->EPN;
  2704 + size = booke_page_size_to_tlb(tlb->size);
  2705 + if (size < 0 || size > 0xF)
  2706 + size = 1;
  2707 + T0 |= size << 4;
  2708 + if (tlb->attr & 0x1)
  2709 + T0 |= 0x100;
  2710 + if (tlb->prot & PAGE_VALID)
  2711 + T0 |= 0x200;
  2712 + env->spr[SPR_440_MMUCR] &= ~0x000000FF;
  2713 + env->spr[SPR_440_MMUCR] |= tlb->PID;
  2714 + break;
  2715 + case 1:
  2716 + T0 = tlb->RPN;
  2717 + break;
  2718 + case 2:
  2719 + T0 = tlb->attr & ~0x1;
  2720 + if (tlb->prot & (PAGE_READ << 4))
  2721 + T0 |= 0x1;
  2722 + if (tlb->prot & (PAGE_WRITE << 4))
  2723 + T0 |= 0x2;
  2724 + if (tlb->prot & (PAGE_EXEC << 4))
  2725 + T0 |= 0x4;
  2726 + if (tlb->prot & PAGE_READ)
  2727 + T0 |= 0x8;
  2728 + if (tlb->prot & PAGE_WRITE)
  2729 + T0 |= 0x10;
  2730 + if (tlb->prot & PAGE_EXEC)
  2731 + T0 |= 0x20;
  2732 + break;
  2733 + }
2755 } 2734 }
2756 #endif /* !CONFIG_USER_ONLY */ 2735 #endif /* !CONFIG_USER_ONLY */
target-ppc/op_helper.h
@@ -156,16 +156,12 @@ void do_POWER_rfsvc (void); @@ -156,16 +156,12 @@ void do_POWER_rfsvc (void);
156 void do_op_602_mfrom (void); 156 void do_op_602_mfrom (void);
157 #endif 157 #endif
158 158
159 -/* PowerPC BookE specific helpers */ 159 +/* PowerPC 440 specific helpers */
160 #if !defined(CONFIG_USER_ONLY) 160 #if !defined(CONFIG_USER_ONLY)
161 -void do_booke_tlbre0 (void);  
162 -void do_booke_tlbre1 (void);  
163 -void do_booke_tlbre2 (void);  
164 -void do_booke_tlbsx (void);  
165 -void do_booke_tlbsx_ (void);  
166 -void do_booke_tlbwe0 (void);  
167 -void do_booke_tlbwe1 (void);  
168 -void do_booke_tlbwe2 (void); 161 +void do_440_tlbre (int word);
  162 +void do_440_tlbsx (void);
  163 +void do_440_tlbsx_ (void);
  164 +void do_440_tlbwe (int word);
169 #endif 165 #endif
170 166
171 /* PowerPC 4xx specific helpers */ 167 /* PowerPC 4xx specific helpers */
target-ppc/translate.c
@@ -4695,9 +4695,9 @@ GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC) @@ -4695,9 +4695,9 @@ GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC)
4695 #endif 4695 #endif
4696 } 4696 }
4697 4697
4698 -/* TLB management - PowerPC BookE implementation */ 4698 +/* TLB management - PowerPC 440 implementation */
4699 /* tlbre */ 4699 /* tlbre */
4700 -GEN_HANDLER(tlbre_booke, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) 4700 +GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4701 { 4701 {
4702 #if defined(CONFIG_USER_ONLY) 4702 #if defined(CONFIG_USER_ONLY)
4703 RET_PRIVOPC(ctx); 4703 RET_PRIVOPC(ctx);
@@ -4708,18 +4708,10 @@ GEN_HANDLER(tlbre_booke, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) @@ -4708,18 +4708,10 @@ GEN_HANDLER(tlbre_booke, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4708 } 4708 }
4709 switch (rB(ctx->opcode)) { 4709 switch (rB(ctx->opcode)) {
4710 case 0: 4710 case 0:
4711 - gen_op_load_gpr_T0(rA(ctx->opcode));  
4712 - gen_op_booke_tlbre0();  
4713 - gen_op_store_T0_gpr(rD(ctx->opcode));  
4714 - break;  
4715 case 1: 4711 case 1:
4716 - gen_op_load_gpr_T0(rA(ctx->opcode));  
4717 - gen_op_booke_tlbre1();  
4718 - gen_op_store_T0_gpr(rD(ctx->opcode));  
4719 - break;  
4720 case 2: 4712 case 2:
4721 gen_op_load_gpr_T0(rA(ctx->opcode)); 4713 gen_op_load_gpr_T0(rA(ctx->opcode));
4722 - gen_op_booke_tlbre2(); 4714 + gen_op_440_tlbre(rB(ctx->opcode));
4723 gen_op_store_T0_gpr(rD(ctx->opcode)); 4715 gen_op_store_T0_gpr(rD(ctx->opcode));
4724 break; 4716 break;
4725 default: 4717 default:
@@ -4730,7 +4722,7 @@ GEN_HANDLER(tlbre_booke, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) @@ -4730,7 +4722,7 @@ GEN_HANDLER(tlbre_booke, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4730 } 4722 }
4731 4723
4732 /* tlbsx - tlbsx. */ 4724 /* tlbsx - tlbsx. */
4733 -GEN_HANDLER(tlbsx_booke, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE) 4725 +GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
4734 { 4726 {
4735 #if defined(CONFIG_USER_ONLY) 4727 #if defined(CONFIG_USER_ONLY)
4736 RET_PRIVOPC(ctx); 4728 RET_PRIVOPC(ctx);
@@ -4741,15 +4733,15 @@ GEN_HANDLER(tlbsx_booke, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE) @@ -4741,15 +4733,15 @@ GEN_HANDLER(tlbsx_booke, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
4741 } 4733 }
4742 gen_addr_reg_index(ctx); 4734 gen_addr_reg_index(ctx);
4743 if (Rc(ctx->opcode)) 4735 if (Rc(ctx->opcode))
4744 - gen_op_booke_tlbsx_(); 4736 + gen_op_440_tlbsx_();
4745 else 4737 else
4746 - gen_op_booke_tlbsx(); 4738 + gen_op_440_tlbsx();
4747 gen_op_store_T0_gpr(rD(ctx->opcode)); 4739 gen_op_store_T0_gpr(rD(ctx->opcode));
4748 #endif 4740 #endif
4749 } 4741 }
4750 4742
4751 /* tlbwe */ 4743 /* tlbwe */
4752 -GEN_HANDLER(tlbwe_booke, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE) 4744 +GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
4753 { 4745 {
4754 #if defined(CONFIG_USER_ONLY) 4746 #if defined(CONFIG_USER_ONLY)
4755 RET_PRIVOPC(ctx); 4747 RET_PRIVOPC(ctx);
@@ -4760,19 +4752,11 @@ GEN_HANDLER(tlbwe_booke, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE) @@ -4760,19 +4752,11 @@ GEN_HANDLER(tlbwe_booke, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
4760 } 4752 }
4761 switch (rB(ctx->opcode)) { 4753 switch (rB(ctx->opcode)) {
4762 case 0: 4754 case 0:
4763 - gen_op_load_gpr_T0(rA(ctx->opcode));  
4764 - gen_op_load_gpr_T1(rS(ctx->opcode));  
4765 - gen_op_booke_tlbwe0();  
4766 - break;  
4767 case 1: 4755 case 1:
4768 - gen_op_load_gpr_T0(rA(ctx->opcode));  
4769 - gen_op_load_gpr_T1(rS(ctx->opcode));  
4770 - gen_op_booke_tlbwe1();  
4771 - break;  
4772 case 2: 4756 case 2:
4773 gen_op_load_gpr_T0(rA(ctx->opcode)); 4757 gen_op_load_gpr_T0(rA(ctx->opcode));
4774 gen_op_load_gpr_T1(rS(ctx->opcode)); 4758 gen_op_load_gpr_T1(rS(ctx->opcode));
4775 - gen_op_booke_tlbwe2(); 4759 + gen_op_440_tlbwe(rB(ctx->opcode));
4776 break; 4760 break;
4777 default: 4761 default:
4778 RET_INVAL(ctx); 4762 RET_INVAL(ctx);