Revision 5eb7995e target-ppc/op_helper.c
b/target-ppc/op_helper.c | ||
---|---|---|
2605 | 2605 |
} |
2606 | 2606 |
#endif |
2607 | 2607 |
} |
2608 |
|
|
2609 |
/* BookE TLB management */ |
|
2610 |
void do_booke_tlbwe0 (void) |
|
2611 |
{ |
|
2612 |
ppcemb_tlb_t *tlb; |
|
2613 |
target_ulong EPN, size; |
|
2614 |
int do_flush_tlbs; |
|
2615 |
|
|
2616 |
#if defined (DEBUG_SOFTWARE_TLB) |
|
2617 |
if (loglevel != 0) { |
|
2618 |
fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); |
|
2619 |
} |
|
2620 |
#endif |
|
2621 |
do_flush_tlbs = 0; |
|
2622 |
T0 &= 0x3F; |
|
2623 |
tlb = &env->tlb[T0].tlbe; |
|
2624 |
EPN = T1 & 0xFFFFFC00; |
|
2625 |
if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN) |
|
2626 |
do_flush_tlbs = 1; |
|
2627 |
tlb->EPN = EPN; |
|
2628 |
size = booke_tlb_to_page_size((T1 >> 4) & 0xF); |
|
2629 |
if ((tlb->prot & PAGE_VALID) && tlb->size < size) |
|
2630 |
do_flush_tlbs = 1; |
|
2631 |
tlb->size = size; |
|
2632 |
tlb->attr &= ~0x1; |
|
2633 |
tlb->attr |= (T1 >> 8) & 1; |
|
2634 |
if (T1 & 0x200) { |
|
2635 |
tlb->prot |= PAGE_VALID; |
|
2636 |
} else { |
|
2637 |
if (tlb->prot & PAGE_VALID) { |
|
2638 |
tlb->prot &= ~PAGE_VALID; |
|
2639 |
do_flush_tlbs = 1; |
|
2640 |
} |
|
2641 |
} |
|
2642 |
tlb->PID = env->spr[SPR_BOOKE_PID]; |
|
2643 |
if (do_flush_tlbs) |
|
2644 |
tlb_flush(env, 1); |
|
2645 |
} |
|
2646 |
|
|
2647 |
void do_booke_tlbwe1 (void) |
|
2648 |
{ |
|
2649 |
ppcemb_tlb_t *tlb; |
|
2650 |
target_phys_addr_t RPN; |
|
2651 |
|
|
2652 |
#if defined (DEBUG_SOFTWARE_TLB) |
|
2653 |
if (loglevel != 0) { |
|
2654 |
fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); |
|
2655 |
} |
|
2656 |
#endif |
|
2657 |
T0 &= 0x3F; |
|
2658 |
tlb = &env->tlb[T0].tlbe; |
|
2659 |
RPN = T1 & 0xFFFFFC0F; |
|
2660 |
if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN) |
|
2661 |
tlb_flush(env, 1); |
|
2662 |
tlb->RPN = RPN; |
|
2663 |
} |
|
2664 |
|
|
2665 |
void do_booke_tlbwe2 (void) |
|
2666 |
{ |
|
2667 |
ppcemb_tlb_t *tlb; |
|
2668 |
|
|
2669 |
#if defined (DEBUG_SOFTWARE_TLB) |
|
2670 |
if (loglevel != 0) { |
|
2671 |
fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); |
|
2672 |
} |
|
2673 |
#endif |
|
2674 |
T0 &= 0x3F; |
|
2675 |
tlb = &env->tlb[T0].tlbe; |
|
2676 |
tlb->attr = (tlb->attr & 0x1) | (T1 & 0x0000FF00); |
|
2677 |
tlb->prot = tlb->prot & PAGE_VALID; |
|
2678 |
if (T1 & 0x1) |
|
2679 |
tlb->prot |= PAGE_READ << 4; |
|
2680 |
if (T1 & 0x2) |
|
2681 |
tlb->prot |= PAGE_WRITE << 4; |
|
2682 |
if (T1 & 0x4) |
|
2683 |
tlb->prot |= PAGE_EXEC << 4; |
|
2684 |
if (T1 & 0x8) |
|
2685 |
tlb->prot |= PAGE_READ; |
|
2686 |
if (T1 & 0x10) |
|
2687 |
tlb->prot |= PAGE_WRITE; |
|
2688 |
if (T1 & 0x20) |
|
2689 |
tlb->prot |= PAGE_EXEC; |
|
2690 |
} |
|
2691 |
|
|
2692 |
void do_booke_tlbsx (void) |
|
2693 |
{ |
|
2694 |
T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]); |
|
2695 |
} |
|
2696 |
|
|
2697 |
void do_booke_tlbsx_ (void) |
|
2698 |
{ |
|
2699 |
int tmp = xer_so; |
|
2700 |
|
|
2701 |
T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]); |
|
2702 |
if (T0 != -1) |
|
2703 |
tmp |= 0x02; |
|
2704 |
env->crf[0] = tmp; |
|
2705 |
} |
|
2706 |
|
|
2707 |
void do_booke_tlbre0 (void) |
|
2708 |
{ |
|
2709 |
ppcemb_tlb_t *tlb; |
|
2710 |
int size; |
|
2711 |
|
|
2712 |
T0 &= 0x3F; |
|
2713 |
tlb = &env->tlb[T0].tlbe; |
|
2714 |
T0 = tlb->EPN; |
|
2715 |
size = booke_page_size_to_tlb(tlb->size); |
|
2716 |
if (size < 0 || size > 0xF) |
|
2717 |
size = 1; |
|
2718 |
T0 |= size << 4; |
|
2719 |
if (tlb->attr & 0x1) |
|
2720 |
T0 |= 0x100; |
|
2721 |
if (tlb->prot & PAGE_VALID) |
|
2722 |
T0 |= 0x200; |
|
2723 |
env->spr[SPR_BOOKE_PID] = tlb->PID; |
|
2724 |
} |
|
2725 |
|
|
2726 |
void do_booke_tlbre1 (void) |
|
2727 |
{ |
|
2728 |
ppcemb_tlb_t *tlb; |
|
2729 |
|
|
2730 |
T0 &= 0x3F; |
|
2731 |
tlb = &env->tlb[T0].tlbe; |
|
2732 |
T0 = tlb->RPN; |
|
2733 |
} |
|
2734 |
|
|
2735 |
void do_booke_tlbre2 (void) |
|
2736 |
{ |
|
2737 |
ppcemb_tlb_t *tlb; |
|
2738 |
|
|
2739 |
T0 &= 0x3F; |
|
2740 |
tlb = &env->tlb[T0].tlbe; |
|
2741 |
T0 = tlb->attr & ~0x1; |
|
2742 |
if (tlb->prot & (PAGE_READ << 4)) |
|
2743 |
T0 |= 0x1; |
|
2744 |
if (tlb->prot & (PAGE_WRITE << 4)) |
|
2745 |
T0 |= 0x2; |
|
2746 |
if (tlb->prot & (PAGE_EXEC << 4)) |
|
2747 |
T0 |= 0x4; |
|
2748 |
if (tlb->prot & PAGE_READ) |
|
2749 |
T0 |= 0x8; |
|
2750 |
if (tlb->prot & PAGE_WRITE) |
|
2751 |
T0 |= 0x10; |
|
2752 |
if (tlb->prot & PAGE_EXEC) |
|
2753 |
T0 |= 0x20; |
|
2754 |
} |
|
2608 | 2755 |
#endif /* !CONFIG_USER_ONLY */ |
Also available in: Unified diff