Revision eacc3249

b/target-ppc/helper.c
601 601
}
602 602

  
603 603
#if defined(TARGET_PPC64)
604
static inline int slb_is_valid (uint64_t slb64)
605
{
606
    return slb64 & 0x0000000008000000ULL ? 1 : 0;
607
}
608

  
609
static inline void slb_invalidate (uint64_t *slb64)
610
{
611
    *slb64 &= ~0x0000000008000000ULL;
612
}
613

  
604 614
static int slb_lookup (CPUPPCState *env, target_ulong eaddr,
605 615
                       target_ulong *vsid, target_ulong *page_mask, int *attr)
606 616
{
......
609 619
    uint64_t tmp64;
610 620
    uint32_t tmp;
611 621
    int n, ret;
612
    int slb_nr;
613 622

  
614 623
    ret = -5;
615 624
    sr_base = env->spr[SPR_ASR];
......
620 629
    }
621 630
#endif
622 631
    mask = 0x0000000000000000ULL; /* Avoid gcc warning */
623
    slb_nr = env->slb_nr;
624
    for (n = 0; n < slb_nr; n++) {
632
    for (n = 0; n < env->slb_nr; n++) {
625 633
        tmp64 = ldq_phys(sr_base);
626 634
        tmp = ldl_phys(sr_base + 8);
627 635
#if defined(DEBUG_SLB)
......
630 638
                    PRIx32 "\n", __func__, n, sr_base, tmp64, tmp);
631 639
        }
632 640
#endif
633
        if (tmp64 & 0x0000000008000000ULL) {
641
        if (slb_is_valid(tmp64)) {
634 642
            /* SLB entry is valid */
635 643
            switch (tmp64 & 0x0000000006000000ULL) {
636 644
            case 0x0000000000000000ULL:
......
651 659
                *vsid = ((tmp64 << 24) | (tmp >> 8)) & 0x0003FFFFFFFFFFFFULL;
652 660
                *page_mask = ~mask;
653 661
                *attr = tmp & 0xFF;
654
                ret = 0;
662
                ret = n;
655 663
                break;
656 664
            }
657 665
        }
......
661 669
    return ret;
662 670
}
663 671

  
672
void ppc_slb_invalidate_all (CPUPPCState *env)
673
{
674
    target_phys_addr_t sr_base;
675
    uint64_t tmp64;
676
    int n, do_invalidate;
677

  
678
    do_invalidate = 0;
679
    sr_base = env->spr[SPR_ASR];
680
    for (n = 0; n < env->slb_nr; n++) {
681
        tmp64 = ldq_phys(sr_base);
682
        if (slb_is_valid(tmp64)) {
683
            slb_invalidate(&tmp64);
684
            stq_phys(sr_base, tmp64);
685
            /* XXX: given the fact that segment size is 256 MB or 1TB,
686
             *      and we still don't have a tlb_flush_mask(env, n, mask)
687
             *      in Qemu, we just invalidate all TLBs
688
             */
689
            do_invalidate = 1;
690
        }
691
        sr_base += 12;
692
    }
693
    if (do_invalidate)
694
        tlb_flush(env, 1);
695
}
696

  
697
void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
698
{
699
    target_phys_addr_t sr_base;
700
    target_ulong vsid, page_mask;
701
    uint64_t tmp64;
702
    int attr;
703
    int n;
704

  
705
    n = slb_lookup(env, T0, &vsid, &page_mask, &attr);
706
    if (n >= 0) {
707
        sr_base = env->spr[SPR_ASR];
708
        sr_base += 12 * n;
709
        tmp64 = ldq_phys(sr_base);
710
        if (slb_is_valid(tmp64)) {
711
            slb_invalidate(&tmp64);
712
            stq_phys(sr_base, tmp64);
713
            /* XXX: given the fact that segment size is 256 MB or 1TB,
714
             *      and we still don't have a tlb_flush_mask(env, n, mask)
715
             *      in Qemu, we just invalidate all TLBs
716
             */
717
            tlb_flush(env, 1);
718
        }
719
    }
720
}
721

  
664 722
target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr)
665 723
{
666 724
    target_phys_addr_t sr_base;
......
1828 1886
#endif
1829 1887
}
1830 1888

  
1831
#if defined(TARGET_PPC64)
1832
void ppc_slb_invalidate_all (CPUPPCState *env)
1833
{
1834
    /* XXX: TODO */
1835
    tlb_flush(env, 1);
1836
}
1837

  
1838
void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
1839
{
1840
    /* XXX: TODO */
1841
    tlb_flush(env, 1);
1842
}
1843
#endif
1844

  
1845 1889
/*****************************************************************************/
1846 1890
/* Special registers manipulation */
1847 1891
#if defined(TARGET_PPC64)

Also available in: Unified diff