Revision 7dbe11ac

b/target-ppc/helper.c
664 664
    int ret, ret2;
665 665

  
666 666
#if defined(TARGET_PPC64)
667
    if (env->mmu_model == POWERPC_MMU_64B) {
667
    if (env->mmu_model == POWERPC_MMU_64B ||
668
        env->mmu_model == POWERPC_MMU_64BRIDGE) {
668 669
        ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr);
669 670
        if (ret < 0)
670 671
            return ret;
......
730 731
            }
731 732
            /* Initialize real address with an invalid value */
732 733
            ctx->raddr = (target_ulong)-1;
733
            if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
734
            if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
735
                         env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
734 736
                /* Software TLB search */
735 737
                ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
736 738
            } else {
......
1092 1094
    switch (env->mmu_model) {
1093 1095
    case POWERPC_MMU_32B:
1094 1096
    case POWERPC_MMU_SOFT_6xx:
1097
    case POWERPC_MMU_SOFT_74xx:
1095 1098
    case POWERPC_MMU_601:
1096 1099
    case POWERPC_MMU_SOFT_4xx:
1097 1100
    case POWERPC_MMU_REAL_4xx:
1101
    case POWERPC_MMU_BOOKE:
1098 1102
        ctx->prot |= PAGE_WRITE;
1099 1103
        break;
1100 1104
#if defined(TARGET_PPC64)
......
1129 1133
            }
1130 1134
        }
1131 1135
        break;
1132
    case POWERPC_MMU_BOOKE:
1133
        ctx->prot |= PAGE_WRITE;
1134
        break;
1135 1136
    case POWERPC_MMU_BOOKE_FSL:
1136 1137
        /* XXX: TODO */
1137 1138
        cpu_abort(env, "BookE FSL MMU model not implemented\n");
......
1162 1163
        switch (env->mmu_model) {
1163 1164
        case POWERPC_MMU_32B:
1164 1165
        case POWERPC_MMU_SOFT_6xx:
1166
        case POWERPC_MMU_SOFT_74xx:
1165 1167
            /* Try to find a BAT */
1166 1168
            if (check_BATs)
1167 1169
                ret = get_bat(env, ctx, eaddr, rw, access_type);
......
1262 1264
                    env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1263 1265
                    error_code = 1 << 18;
1264 1266
                    goto tlb_miss;
1267
                case POWERPC_MMU_SOFT_74xx:
1268
                    exception = POWERPC_EXCP_IFTLB;
1269
                    goto tlb_miss_74xx;
1265 1270
                case POWERPC_MMU_SOFT_4xx:
1266 1271
                case POWERPC_MMU_SOFT_4xx_Z:
1267 1272
                    exception = POWERPC_EXCP_ITLB;
......
1346 1351
                    env->spr[SPR_HASH2] = ctx.pg_addr[1];
1347 1352
                    /* Do not alter DAR nor DSISR */
1348 1353
                    goto out;
1354
                case POWERPC_MMU_SOFT_74xx:
1355
                    if (rw == 1) {
1356
                        exception = POWERPC_EXCP_DSTLB;
1357
                    } else {
1358
                        exception = POWERPC_EXCP_DLTLB;
1359
                    }
1360
                tlb_miss_74xx:
1361
                    /* Implement LRU algorithm */
1362
                    env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |
1363
                        ((env->last_way + 1) & (env->nb_ways - 1));
1364
                    env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
1365
                    error_code = ctx.key << 19;
1366
                    break;
1349 1367
                case POWERPC_MMU_SOFT_4xx:
1350 1368
                case POWERPC_MMU_SOFT_4xx_Z:
1351 1369
                    exception = POWERPC_EXCP_DTLB;
......
1571 1589
{
1572 1590
    switch (env->mmu_model) {
1573 1591
    case POWERPC_MMU_SOFT_6xx:
1592
    case POWERPC_MMU_SOFT_74xx:
1574 1593
        ppc6xx_tlb_invalidate_all(env);
1575 1594
        break;
1576 1595
    case POWERPC_MMU_SOFT_4xx:
1577 1596
    case POWERPC_MMU_SOFT_4xx_Z:
1578 1597
        ppc4xx_tlb_invalidate_all(env);
1579 1598
        break;
1580
    default:
1599
    case POWERPC_MMU_REAL_4xx:
1600
        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1601
        break;
1602
    case POWERPC_MMU_BOOKE:
1603
        /* XXX: TODO */
1604
        cpu_abort(env, "MMU model not implemented\n");
1605
        break;
1606
    case POWERPC_MMU_BOOKE_FSL:
1607
        /* XXX: TODO */
1608
        cpu_abort(env, "MMU model not implemented\n");
1609
        break;
1610
    case POWERPC_MMU_601:
1611
        /* XXX: TODO */
1612
        cpu_abort(env, "MMU model not implemented\n");
1613
        break;
1614
    case POWERPC_MMU_32B:
1615
    case POWERPC_MMU_64B:
1616
    case POWERPC_MMU_64BRIDGE:
1581 1617
        tlb_flush(env, 1);
1582 1618
        break;
1583 1619
    }
......
1589 1625
    addr &= TARGET_PAGE_MASK;
1590 1626
    switch (env->mmu_model) {
1591 1627
    case POWERPC_MMU_SOFT_6xx:
1628
    case POWERPC_MMU_SOFT_74xx:
1592 1629
        ppc6xx_tlb_invalidate_virt(env, addr, 0);
1593 1630
        if (env->id_tlbs == 1)
1594 1631
            ppc6xx_tlb_invalidate_virt(env, addr, 1);
......
1597 1634
    case POWERPC_MMU_SOFT_4xx_Z:
1598 1635
        ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
1599 1636
        break;
1600
    default:
1637
    case POWERPC_MMU_REAL_4xx:
1638
        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1639
        break;
1640
    case POWERPC_MMU_BOOKE:
1641
        /* XXX: TODO */
1642
        cpu_abort(env, "MMU model not implemented\n");
1643
        break;
1644
    case POWERPC_MMU_BOOKE_FSL:
1645
        /* XXX: TODO */
1646
        cpu_abort(env, "MMU model not implemented\n");
1647
        break;
1648
    case POWERPC_MMU_601:
1649
        /* XXX: TODO */
1650
        cpu_abort(env, "MMU model not implemented\n");
1651
        break;
1652
    case POWERPC_MMU_32B:
1601 1653
        /* tlbie invalidate TLBs for all segments */
1602 1654
        addr &= ~((target_ulong)-1 << 28);
1603 1655
        /* XXX: this case should be optimized,
......
1619 1671
        tlb_flush_page(env, addr | (0xD << 28));
1620 1672
        tlb_flush_page(env, addr | (0xE << 28));
1621 1673
        tlb_flush_page(env, addr | (0xF << 28));
1674
        break;
1675
    case POWERPC_MMU_64B:
1676
    case POWERPC_MMU_64BRIDGE:
1677
        /* tlbie invalidate TLBs for all segments */
1678
        /* XXX: given the fact that there are too many segments to invalidate,
1679
         *      we just invalidate all TLBs
1680
         */
1681
        tlb_flush(env, 1);
1682
        break;
1622 1683
    }
1623 1684
#else
1624 1685
    ppc_tlb_invalidate_all(env);
......
2317 2378
            goto tlb_miss_tgpr;
2318 2379
        case POWERPC_EXCP_7x5:
2319 2380
            goto tlb_miss;
2381
        case POWERPC_EXCP_74xx:
2382
            goto tlb_miss_74xx;
2320 2383
        default:
2321 2384
            cpu_abort(env, "Invalid instruction TLB miss exception\n");
2322 2385
            break;
......
2336 2399
            goto tlb_miss_tgpr;
2337 2400
        case POWERPC_EXCP_7x5:
2338 2401
            goto tlb_miss;
2402
        case POWERPC_EXCP_74xx:
2403
            goto tlb_miss_74xx;
2339 2404
        default:
2340 2405
            cpu_abort(env, "Invalid data load TLB miss exception\n");
2341 2406
            break;
......
2390 2455
            /* Set way using a LRU mechanism */
2391 2456
            msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2392 2457
            break;
2458
        case POWERPC_EXCP_74xx:
2459
        tlb_miss_74xx:
2460
#if defined (DEBUG_SOFTWARE_TLB)
2461
            if (loglevel != 0) {
2462
                const unsigned char *es;
2463
                target_ulong *miss, *cmp;
2464
                int en;
2465
                if (excp == POWERPC_EXCP_IFTLB) {
2466
                    es = "I";
2467
                    en = 'I';
2468
                    miss = &env->spr[SPR_IMISS];
2469
                    cmp = &env->spr[SPR_ICMP];
2470
                } else {
2471
                    if (excp == POWERPC_EXCP_DLTLB)
2472
                        es = "DL";
2473
                    else
2474
                        es = "DS";
2475
                    en = 'D';
2476
                    miss = &env->spr[SPR_TLBMISS];
2477
                    cmp = &env->spr[SPR_PTEHI];
2478
                }
2479
                fprintf(logfile, "74xx %sTLB miss: %cM " ADDRX " %cC " ADDRX
2480
                        " %08x\n",
2481
                        es, en, *miss, en, *cmp, env->error_code);
2482
            }
2483
#endif
2484
            msr |= env->error_code; /* key bit */
2485
            break;
2393 2486
        default:
2394 2487
            cpu_abort(env, "Invalid data store TLB miss exception\n");
2395 2488
            break;
b/target-ppc/op.c
2025 2025
#endif
2026 2026
#endif
2027 2027

  
2028
/* PowerPC 602/603/755 software TLB load instructions */
2029 2028
#if !defined(CONFIG_USER_ONLY)
2029
/* PowerPC 602/603/755 software TLB load instructions */
2030 2030
void OPPROTO op_6xx_tlbld (void)
2031 2031
{
2032 2032
    do_load_6xx_tlb(0);
......
2038 2038
    do_load_6xx_tlb(1);
2039 2039
    RETURN();
2040 2040
}
2041

  
2042
/* PowerPC 74xx software TLB load instructions */
2043
void OPPROTO op_74xx_tlbld (void)
2044
{
2045
    do_load_74xx_tlb(0);
2046
    RETURN();
2047
}
2048

  
2049
void OPPROTO op_74xx_tlbli (void)
2050
{
2051
    do_load_74xx_tlb(1);
2052
    RETURN();
2053
}
2041 2054
#endif
2042 2055

  
2043 2056
/* 601 specific */
b/target-ppc/op_helper.c
2363 2363
                     way, is_code, CMP, RPN);
2364 2364
}
2365 2365

  
2366
void do_load_74xx_tlb (int is_code)
2367
{
2368
    target_ulong RPN, CMP, EPN;
2369
    int way;
2370

  
2371
    RPN = env->spr[SPR_PTELO];
2372
    CMP = env->spr[SPR_PTEHI];
2373
    EPN = env->spr[SPR_TLBMISS] & ~0x3;
2374
    way = env->spr[SPR_TLBMISS] & 0x3;
2375
#if defined (DEBUG_SOFTWARE_TLB)
2376
    if (loglevel != 0) {
2377
        fprintf(logfile, "%s: EPN %08lx %08lx PTE0 %08lx PTE1 %08lx way %d\n",
2378
                __func__, (unsigned long)T0, (unsigned long)EPN,
2379
                (unsigned long)CMP, (unsigned long)RPN, way);
2380
    }
2381
#endif
2382
    /* Store this TLB */
2383
    ppc6xx_tlb_store(env, (uint32_t)(T0 & TARGET_PAGE_MASK),
2384
                     way, is_code, CMP, RPN);
2385
}
2386

  
2366 2387
static target_ulong booke_tlb_to_page_size (int size)
2367 2388
{
2368 2389
    return 1024 << (2 * size);
b/target-ppc/op_helper.h
135 135
void do_hrfid (void);
136 136
#endif
137 137
void do_load_6xx_tlb (int is_code);
138
void do_load_74xx_tlb (int is_code);
138 139
#endif
139 140

  
140 141
/* POWER / PowerPC 601 specific helpers */
b/target-ppc/translate.c
4299 4299

  
4300 4300
/* 602 - 603 - G2 TLB management */
4301 4301
/* tlbld */
4302
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4302
GEN_HANDLER(tlbld_6xx, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4303 4303
{
4304 4304
#if defined(CONFIG_USER_ONLY)
4305 4305
    GEN_EXCP_PRIVOPC(ctx);
......
4314 4314
}
4315 4315

  
4316 4316
/* tlbli */
4317
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4317
GEN_HANDLER(tlbli_6xx, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4318 4318
{
4319 4319
#if defined(CONFIG_USER_ONLY)
4320 4320
    GEN_EXCP_PRIVOPC(ctx);
......
4328 4328
#endif
4329 4329
}
4330 4330

  
4331
/* 74xx TLB management */
4332
/* tlbld */
4333
GEN_HANDLER(tlbld_74xx, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4334
{
4335
#if defined(CONFIG_USER_ONLY)
4336
    GEN_EXCP_PRIVOPC(ctx);
4337
#else
4338
    if (unlikely(!ctx->supervisor)) {
4339
        GEN_EXCP_PRIVOPC(ctx);
4340
        return;
4341
    }
4342
    gen_op_load_gpr_T0(rB(ctx->opcode));
4343
    gen_op_74xx_tlbld();
4344
#endif
4345
}
4346

  
4347
/* tlbli */
4348
GEN_HANDLER(tlbli_74xx, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4349
{
4350
#if defined(CONFIG_USER_ONLY)
4351
    GEN_EXCP_PRIVOPC(ctx);
4352
#else
4353
    if (unlikely(!ctx->supervisor)) {
4354
        GEN_EXCP_PRIVOPC(ctx);
4355
        return;
4356
    }
4357
    gen_op_load_gpr_T0(rB(ctx->opcode));
4358
    gen_op_74xx_tlbli();
4359
#endif
4360
}
4361

  
4331 4362
/* POWER instructions not in PowerPC 601 */
4332 4363
/* clf */
4333 4364
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)

Also available in: Unified diff