Commit a4bb6c3e87b8bfa5db94a4e231e211696e05b4f5
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
Showing
4 changed files
with
110 additions
and
175 deletions
target-ppc/op.c
... | ... | @@ -2365,51 +2365,27 @@ void OPPROTO op_wrte (void) |
2365 | 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 | 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 | 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 | 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 | 2389 | RETURN(); |
2414 | 2390 | } |
2415 | 2391 | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -2607,95 +2607,79 @@ void do_4xx_tlbwe_lo (void) |
2607 | 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 | 2613 | ppcemb_tlb_t *tlb; |
2614 | - target_ulong EPN, size; | |
2614 | + target_ulong EPN, RPN, size; | |
2615 | 2615 | int do_flush_tlbs; |
2616 | 2616 | |
2617 | 2617 | #if defined (DEBUG_SOFTWARE_TLB) |
2618 | 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 | 2622 | #endif |
2622 | 2623 | do_flush_tlbs = 0; |
2623 | 2624 | T0 &= 0x3F; |
2624 | 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 | 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 | 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 | 2684 | int tmp = xer_so; |
2701 | 2685 | |
... | ... | @@ -2705,52 +2689,47 @@ void do_booke_tlbsx_ (void) |
2705 | 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 | 2694 | ppcemb_tlb_t *tlb; |
2711 | 2695 | int size; |
2712 | 2696 | |
2713 | 2697 | T0 &= 0x3F; |
2714 | 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 | 2735 | #endif /* !CONFIG_USER_ONLY */ | ... | ... |
target-ppc/op_helper.h
... | ... | @@ -156,16 +156,12 @@ void do_POWER_rfsvc (void); |
156 | 156 | void do_op_602_mfrom (void); |
157 | 157 | #endif |
158 | 158 | |
159 | -/* PowerPC BookE specific helpers */ | |
159 | +/* PowerPC 440 specific helpers */ | |
160 | 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 | 165 | #endif |
170 | 166 | |
171 | 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 | 4695 | #endif |
4696 | 4696 | } |
4697 | 4697 | |
4698 | -/* TLB management - PowerPC BookE implementation */ | |
4698 | +/* TLB management - PowerPC 440 implementation */ | |
4699 | 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 | 4702 | #if defined(CONFIG_USER_ONLY) |
4703 | 4703 | RET_PRIVOPC(ctx); |
... | ... | @@ -4708,18 +4708,10 @@ GEN_HANDLER(tlbre_booke, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) |
4708 | 4708 | } |
4709 | 4709 | switch (rB(ctx->opcode)) { |
4710 | 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 | 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 | 4712 | case 2: |
4721 | 4713 | gen_op_load_gpr_T0(rA(ctx->opcode)); |
4722 | - gen_op_booke_tlbre2(); | |
4714 | + gen_op_440_tlbre(rB(ctx->opcode)); | |
4723 | 4715 | gen_op_store_T0_gpr(rD(ctx->opcode)); |
4724 | 4716 | break; |
4725 | 4717 | default: |
... | ... | @@ -4730,7 +4722,7 @@ GEN_HANDLER(tlbre_booke, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) |
4730 | 4722 | } |
4731 | 4723 | |
4732 | 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 | 4727 | #if defined(CONFIG_USER_ONLY) |
4736 | 4728 | RET_PRIVOPC(ctx); |
... | ... | @@ -4741,15 +4733,15 @@ GEN_HANDLER(tlbsx_booke, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE) |
4741 | 4733 | } |
4742 | 4734 | gen_addr_reg_index(ctx); |
4743 | 4735 | if (Rc(ctx->opcode)) |
4744 | - gen_op_booke_tlbsx_(); | |
4736 | + gen_op_440_tlbsx_(); | |
4745 | 4737 | else |
4746 | - gen_op_booke_tlbsx(); | |
4738 | + gen_op_440_tlbsx(); | |
4747 | 4739 | gen_op_store_T0_gpr(rD(ctx->opcode)); |
4748 | 4740 | #endif |
4749 | 4741 | } |
4750 | 4742 | |
4751 | 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 | 4746 | #if defined(CONFIG_USER_ONLY) |
4755 | 4747 | RET_PRIVOPC(ctx); |
... | ... | @@ -4760,19 +4752,11 @@ GEN_HANDLER(tlbwe_booke, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE) |
4760 | 4752 | } |
4761 | 4753 | switch (rB(ctx->opcode)) { |
4762 | 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 | 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 | 4756 | case 2: |
4773 | 4757 | gen_op_load_gpr_T0(rA(ctx->opcode)); |
4774 | 4758 | gen_op_load_gpr_T1(rS(ctx->opcode)); |
4775 | - gen_op_booke_tlbwe2(); | |
4759 | + gen_op_440_tlbwe(rB(ctx->opcode)); | |
4776 | 4760 | break; |
4777 | 4761 | default: |
4778 | 4762 | RET_INVAL(ctx); | ... | ... |