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