Revision faadf50e target-ppc/helper.c

b/target-ppc/helper.c
448 448
}
449 449

  
450 450
/* Perform BAT hit & translation */
451
static always_inline void bat_size_prot (CPUState *env, target_ulong *blp,
452
                                         int *validp, int *protp,
453
                                         target_ulong *BATu, target_ulong *BATl)
454
{
455
    target_ulong bl;
456
    int pp, valid, prot;
457

  
458
    bl = (*BATu & 0x00001FFC) << 15;
459
    valid = 0;
460
    prot = 0;
461
    if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
462
        ((msr_pr != 0) && (*BATu & 0x00000001))) {
463
        valid = 1;
464
        pp = *BATl & 0x00000003;
465
        if (pp != 0) {
466
            prot = PAGE_READ | PAGE_EXEC;
467
            if (pp == 0x2)
468
                prot |= PAGE_WRITE;
469
        }
470
    }
471
    *blp = bl;
472
    *validp = valid;
473
    *protp = prot;
474
}
475

  
476
static always_inline void bat_601_size_prot (CPUState *env,target_ulong *blp,
477
                                             int *validp, int *protp,
478
                                             target_ulong *BATu,
479
                                             target_ulong *BATl)
480
{
481
    target_ulong bl;
482
    int key, pp, valid, prot;
483

  
484
    bl = (*BATl & 0x0000003F) << 17;
485
    if (loglevel != 0) {
486
        fprintf(logfile, "b %02x ==> bl %08x msk %08x\n",
487
                *BATl & 0x0000003F, bl, ~bl);
488
    }
489
    prot = 0;
490
    valid = (*BATl >> 6) & 1;
491
    if (valid) {
492
        pp = *BATu & 0x00000003;
493
        if (msr_pr == 0)
494
            key = (*BATu >> 3) & 1;
495
        else
496
            key = (*BATu >> 2) & 1;
497
        prot = pp_check(key, pp, 0);
498
    }
499
    *blp = bl;
500
    *validp = valid;
501
    *protp = prot;
502
}
503

  
451 504
static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
452 505
                                  target_ulong virtual, int rw, int type)
453 506
{
454 507
    target_ulong *BATlt, *BATut, *BATu, *BATl;
455 508
    target_ulong base, BEPIl, BEPIu, bl;
456
    int i, pp, pr;
509
    int i, valid, prot;
457 510
    int ret = -1;
458 511

  
459 512
#if defined (DEBUG_BATS)
......
462 515
                type == ACCESS_CODE ? 'I' : 'D', virtual);
463 516
    }
464 517
#endif
465
    pr = msr_pr;
466 518
    switch (type) {
467 519
    case ACCESS_CODE:
468 520
        BATlt = env->IBAT[1];
......
480 532
    }
481 533
#endif
482 534
    base = virtual & 0xFFFC0000;
483
    for (i = 0; i < 4; i++) {
535
    for (i = 0; i < env->nb_BATs; i++) {
484 536
        BATu = &BATut[i];
485 537
        BATl = &BATlt[i];
486 538
        BEPIu = *BATu & 0xF0000000;
487 539
        BEPIl = *BATu & 0x0FFE0000;
488
        bl = (*BATu & 0x00001FFC) << 15;
540
        if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
541
            bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
542
        } else {
543
            bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
544
        }
489 545
#if defined (DEBUG_BATS)
490 546
        if (loglevel != 0) {
491 547
            fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX
......
497 553
        if ((virtual & 0xF0000000) == BEPIu &&
498 554
            ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
499 555
            /* BAT matches */
500
            if (((pr == 0) && (*BATu & 0x00000002)) ||
501
                ((pr != 0) && (*BATu & 0x00000001))) {
556
            if (valid != 0) {
502 557
                /* Get physical address */
503 558
                ctx->raddr = (*BATl & 0xF0000000) |
504 559
                    ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
505 560
                    (virtual & 0x0001F000);
506 561
                /* Compute access rights */
507
                pp = *BATl & 0x00000003;
508
                ctx->prot = 0;
509
                if (pp != 0) {
510
                    ctx->prot = PAGE_READ | PAGE_EXEC;
511
                    if (pp == 0x2)
512
                        ctx->prot |= PAGE_WRITE;
513
                }
562
                ctx->prot = prot;
514 563
                ret = check_prot(ctx->prot, rw, type);
515 564
#if defined (DEBUG_BATS)
516 565
                if (ret == 0 && loglevel != 0) {
......
1302 1351
    ret = 0;
1303 1352
    switch (env->mmu_model) {
1304 1353
    case POWERPC_MMU_32B:
1354
    case POWERPC_MMU_601:
1305 1355
    case POWERPC_MMU_SOFT_6xx:
1306 1356
    case POWERPC_MMU_SOFT_74xx:
1307 1357
    case POWERPC_MMU_SOFT_4xx:
......
1353 1403
}
1354 1404

  
1355 1405
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1356
                          int rw, int access_type, int check_BATs)
1406
                          int rw, int access_type)
1357 1407
{
1358 1408
    int ret;
1359 1409

  
......
1370 1420
        ret = -1;
1371 1421
        switch (env->mmu_model) {
1372 1422
        case POWERPC_MMU_32B:
1423
        case POWERPC_MMU_601:
1373 1424
        case POWERPC_MMU_SOFT_6xx:
1374 1425
        case POWERPC_MMU_SOFT_74xx:
1375
            /* Try to find a BAT */
1376
            if (check_BATs)
1377
                ret = get_bat(env, ctx, eaddr, rw, access_type);
1378
            /* No break here */
1379 1426
#if defined(TARGET_PPC64)
1380 1427
        case POWERPC_MMU_64B:
1381 1428
#endif
1429
            /* Try to find a BAT */
1430
            if (env->nb_BATs != 0)
1431
                ret = get_bat(env, ctx, eaddr, rw, access_type);
1382 1432
            if (ret < 0) {
1383 1433
                /* We didn't match any BAT entry or don't have BATs */
1384 1434
                ret = get_segment(env, ctx, eaddr, rw, access_type);
......
1419 1469
{
1420 1470
    mmu_ctx_t ctx;
1421 1471

  
1422
    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT, 1) != 0))
1472
    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
1423 1473
        return -1;
1424 1474

  
1425 1475
    return ctx.raddr & TARGET_PAGE_MASK;
......
1444 1494
        access_type = ACCESS_INT;
1445 1495
        //        access_type = env->access_type;
1446 1496
    }
1447
    ret = get_physical_address(env, &ctx, address, rw, access_type, 1);
1497
    ret = get_physical_address(env, &ctx, address, rw, access_type);
1448 1498
    if (ret == 0) {
1449 1499
        ret = tlb_set_page_exec(env, address & TARGET_PAGE_MASK,
1450 1500
                                ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
......
1476 1526
                    env->spr[SPR_40x_ESR] = 0x00000000;
1477 1527
                    break;
1478 1528
                case POWERPC_MMU_32B:
1529
                case POWERPC_MMU_601:
1479 1530
#if defined(TARGET_PPC64)
1480 1531
                case POWERPC_MMU_64B:
1481 1532
#endif
......
1567 1618
                        env->spr[SPR_40x_ESR] = 0x00000000;
1568 1619
                    break;
1569 1620
                case POWERPC_MMU_32B:
1621
                case POWERPC_MMU_601:
1570 1622
#if defined(TARGET_PPC64)
1571 1623
                case POWERPC_MMU_64B:
1572 1624
#endif
......
1809 1861
        cpu_abort(env, "MMU model not implemented\n");
1810 1862
        break;
1811 1863
    case POWERPC_MMU_32B:
1864
    case POWERPC_MMU_601:
1812 1865
#if defined(TARGET_PPC64)
1813 1866
    case POWERPC_MMU_64B:
1814 1867
#endif /* defined(TARGET_PPC64) */
......
1848 1901
        cpu_abort(env, "MMU model not implemented\n");
1849 1902
        break;
1850 1903
    case POWERPC_MMU_32B:
1904
    case POWERPC_MMU_601:
1851 1905
        /* tlbie invalidate TLBs for all segments */
1852 1906
        addr &= ~((target_ulong)-1 << 28);
1853 1907
        /* XXX: this case should be optimized,

Also available in: Unified diff