Revision daf4f96e target-ppc/helper.c

b/target-ppc/helper.c
237 237
    return nr;
238 238
}
239 239

  
240
void ppc6xx_tlb_invalidate_all (CPUState *env)
240
static void ppc6xx_tlb_invalidate_all (CPUState *env)
241 241
{
242 242
    ppc6xx_tlb_t *tlb;
243 243
    int nr, max;
......
253 253
        max *= 2;
254 254
    for (nr = 0; nr < max; nr++) {
255 255
        tlb = &env->tlb[nr].tlb6;
256
#if !defined(FLUSH_ALL_TLBS)
257
        tlb_flush_page(env, tlb->EPN);
258
#endif
259 256
        pte_invalidate(&tlb->pte0);
260 257
    }
261
#if defined(FLUSH_ALL_TLBS)
262 258
    tlb_flush(env, 1);
263
#endif
264 259
}
265 260

  
266 261
static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
......
292 287
#endif
293 288
}
294 289

  
295
void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
296
                                 int is_code)
290
static void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
291
                                        int is_code)
297 292
{
298 293
    __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
299 294
}
......
834 829
        return -1;
835 830
    }
836 831
    mask = ~(tlb->size - 1);
832
#if defined (DEBUG_SOFTWARE_TLB)
837 833
    if (loglevel != 0) {
838 834
        fprintf(logfile, "%s: TLB %d address " ADDRX " PID %d <=> "
839 835
                ADDRX " " ADDRX " %d\n",
840 836
                __func__, i, address, pid, tlb->EPN, mask, (int)tlb->PID);
841 837
    }
838
#endif
842 839
    /* Check PID */
843 840
    if (tlb->PID != 0 && tlb->PID != pid)
844 841
        return -1;
......
876 873
    return ret;
877 874
}
878 875

  
879
void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
880
                                 uint32_t pid)
876
/* Helpers specific to PowerPC 40x implementations */
877
static void ppc4xx_tlb_invalidate_all (CPUState *env)
881 878
{
882 879
    ppcemb_tlb_t *tlb;
883
    target_phys_addr_t raddr;
884
    target_ulong page, end;
885 880
    int i;
886 881

  
887 882
    for (i = 0; i < env->nb_tlb; i++) {
888 883
        tlb = &env->tlb[i].tlbe;
889
        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
890
            end = tlb->EPN + tlb->size;
891
            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
892
                tlb_flush_page(env, page);
893
            tlb->prot &= ~PAGE_VALID;
894
            break;
895
        }
884
        tlb->prot &= ~PAGE_VALID;
896 885
    }
886
    tlb_flush(env, 1);
897 887
}
898 888

  
899
/* Helpers specific to PowerPC 40x implementations */
900
void ppc4xx_tlb_invalidate_all (CPUState *env)
889
static void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
890
                                        uint32_t pid)
901 891
{
892
#if !defined(FLUSH_ALL_TLBS)
902 893
    ppcemb_tlb_t *tlb;
894
    target_phys_addr_t raddr;
895
    target_ulong page, end;
903 896
    int i;
904 897

  
905 898
    for (i = 0; i < env->nb_tlb; i++) {
906 899
        tlb = &env->tlb[i].tlbe;
907
        if (tlb->prot & PAGE_VALID) {
908
#if 0 // XXX: TLB have variable sizes then we flush all Qemu TLB.
900
        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
909 901
            end = tlb->EPN + tlb->size;
910 902
            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
911 903
                tlb_flush_page(env, page);
912
#endif
913 904
            tlb->prot &= ~PAGE_VALID;
905
            break;
914 906
        }
915 907
    }
916
    tlb_flush(env, 1);
908
#else
909
    ppc4xx_tlb_invalidate_all(env);
910
#endif
917 911
}
918 912

  
919 913
int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
......
932 926
            continue;
933 927
        zsel = (tlb->attr >> 4) & 0xF;
934 928
        zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
929
#if defined (DEBUG_SOFTWARE_TLB)
935 930
        if (loglevel != 0) {
936 931
            fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
937 932
                    __func__, i, zsel, zpr, rw, tlb->attr);
938 933
        }
934
#endif
939 935
        if (access_type == ACCESS_CODE) {
940 936
            /* Check execute enable bit */
941 937
            switch (zpr) {
......
1009 1005
        }
1010 1006
        if (ret >= 0) {
1011 1007
            ctx->raddr = raddr;
1008
#if defined (DEBUG_SOFTWARE_TLB)
1012 1009
            if (loglevel != 0) {
1013 1010
                fprintf(logfile, "%s: access granted " ADDRX " => " REGX
1014 1011
                        " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1015 1012
                        ret);
1016 1013
            }
1014
#endif
1017 1015
            return 0;
1018 1016
        }
1019 1017
    }
1018
#if defined (DEBUG_SOFTWARE_TLB)
1020 1019
    if (loglevel != 0) {
1021 1020
        fprintf(logfile, "%s: access refused " ADDRX " => " REGX
1022 1021
                " %d %d\n", __func__, address, raddr, ctx->prot,
1023 1022
                ret);
1024 1023
    }
1024
#endif
1025 1025

  
1026 1026
    return ret;
1027 1027
}
......
1569 1569
/* TLB management */
1570 1570
void ppc_tlb_invalidate_all (CPUPPCState *env)
1571 1571
{
1572
    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
1572
    switch (env->mmu_model) {
1573
    case POWERPC_MMU_SOFT_6xx:
1573 1574
        ppc6xx_tlb_invalidate_all(env);
1574
    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
1575
        break;
1576
    case POWERPC_MMU_SOFT_4xx:
1577
    case POWERPC_MMU_SOFT_4xx_Z:
1575 1578
        ppc4xx_tlb_invalidate_all(env);
1576
    } else {
1579
        break;
1580
    default:
1577 1581
        tlb_flush(env, 1);
1582
        break;
1583
    }
1584
}
1585

  
1586
void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
1587
{
1588
#if !defined(FLUSH_ALL_TLBS)
1589
    addr &= TARGET_PAGE_MASK;
1590
    switch (env->mmu_model) {
1591
    case POWERPC_MMU_SOFT_6xx:
1592
        ppc6xx_tlb_invalidate_virt(env, addr, 0);
1593
        if (env->id_tlbs == 1)
1594
            ppc6xx_tlb_invalidate_virt(env, addr, 1);
1595
        break;
1596
    case POWERPC_MMU_SOFT_4xx:
1597
    case POWERPC_MMU_SOFT_4xx_Z:
1598
        ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
1599
        break;
1600
    default:
1601
        /* tlbie invalidate TLBs for all segments */
1602
        addr &= ~((target_ulong)-1 << 28);
1603
        /* XXX: this case should be optimized,
1604
         * giving a mask to tlb_flush_page
1605
         */
1606
        tlb_flush_page(env, addr | (0x0 << 28));
1607
        tlb_flush_page(env, addr | (0x1 << 28));
1608
        tlb_flush_page(env, addr | (0x2 << 28));
1609
        tlb_flush_page(env, addr | (0x3 << 28));
1610
        tlb_flush_page(env, addr | (0x4 << 28));
1611
        tlb_flush_page(env, addr | (0x5 << 28));
1612
        tlb_flush_page(env, addr | (0x6 << 28));
1613
        tlb_flush_page(env, addr | (0x7 << 28));
1614
        tlb_flush_page(env, addr | (0x8 << 28));
1615
        tlb_flush_page(env, addr | (0x9 << 28));
1616
        tlb_flush_page(env, addr | (0xA << 28));
1617
        tlb_flush_page(env, addr | (0xB << 28));
1618
        tlb_flush_page(env, addr | (0xC << 28));
1619
        tlb_flush_page(env, addr | (0xD << 28));
1620
        tlb_flush_page(env, addr | (0xE << 28));
1621
        tlb_flush_page(env, addr | (0xF << 28));
1578 1622
    }
1623
#else
1624
    ppc_tlb_invalidate_all(env);
1625
#endif
1579 1626
}
1580 1627

  
1628
#if defined(TARGET_PPC64)
1629
void ppc_slb_invalidate_all (CPUPPCState *env)
1630
{
1631
    /* XXX: TODO */
1632
    tlb_flush(env, 1);
1633
}
1634

  
1635
void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
1636
{
1637
    /* XXX: TODO */
1638
    tlb_flush(env, 1);
1639
}
1640
#endif
1641

  
1642

  
1581 1643
/*****************************************************************************/
1582 1644
/* Special registers manipulation */
1583 1645
#if defined(TARGET_PPC64)

Also available in: Unified diff