Revision 12de9a39

b/target-ppc/cpu.h
105 105
    /* BookE FSL MMU model                                     */
106 106
    POWERPC_MMU_BOOKE_FSL,
107 107
#if defined(TARGET_PPC64)
108
    /* Standard 64 bits PowerPC MMU                            */
108
    /* 64 bits PowerPC MMU                                     */
109 109
    POWERPC_MMU_64B,
110
    /* 64 bits "bridge" PowerPC MMU                            */
111
    POWERPC_MMU_64BRIDGE,
112 110
#endif /* defined(TARGET_PPC64) */
113 111
};
114 112

  
......
514 512
    ppc_tlb_t *tlb;  /* TLB is optional. Allocate them only if needed        */
515 513
    /* 403 dedicated access protection registers */
516 514
    target_ulong pb[4];
515
    /* PowerPC 64 SLB area */
516
    int slb_nr;
517 517

  
518 518
    int dcache_line_size;
519 519
    int icache_line_size;
......
606 606
#if defined(TARGET_PPC64)
607 607
target_ulong ppc_load_asr (CPUPPCState *env);
608 608
void ppc_store_asr (CPUPPCState *env, target_ulong value);
609
#endif
609
target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr);
610
void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs);
611
#endif /* defined(TARGET_PPC64) */
612
#if 0 // Unused
610 613
target_ulong do_load_sr (CPUPPCState *env, int srnum);
611
void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
612 614
#endif
615
void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
616
#endif /* !defined(CONFIG_USER_ONLY) */
613 617
target_ulong ppc_load_xer (CPUPPCState *env);
614 618
void ppc_store_xer (CPUPPCState *env, target_ulong value);
615 619
target_ulong do_load_msr (CPUPPCState *env);
b/target-ppc/helper.c
501 501
            pte0 = ldq_phys(base + (i * 16));
502 502
            pte1 =  ldq_phys(base + (i * 16) + 8);
503 503
            r = pte64_check(ctx, pte0, pte1, h, rw);
504
#if defined (DEBUG_MMU)
505
            if (loglevel != 0) {
506
                fprintf(logfile, "Load pte from 0x" ADDRX " => 0x" ADDRX
507
                        " 0x" ADDRX " %d %d %d 0x" ADDRX "\n",
508
                        base + (i * 16), pte0, pte1,
509
                        (int)(pte0 & 1), h, (int)((pte0 >> 1) & 1),
510
                        ctx->ptem);
511
            }
512
#endif
504 513
        } else
505 514
#endif
506 515
        {
507 516
            pte0 = ldl_phys(base + (i * 8));
508 517
            pte1 =  ldl_phys(base + (i * 8) + 4);
509 518
            r = pte32_check(ctx, pte0, pte1, h, rw);
510
        }
511 519
#if defined (DEBUG_MMU)
512
        if (loglevel != 0) {
513
            fprintf(logfile, "Load pte from 0x" ADDRX " => 0x" ADDRX
514
                    " 0x" ADDRX " %d %d %d 0x" ADDRX "\n",
515
                    base + (i * 8), pte0, pte1,
516
                    (int)(pte0 >> 31), h, (int)((pte0 >> 6) & 1), ctx->ptem);
517
        }
520
            if (loglevel != 0) {
521
                fprintf(logfile, "Load pte from 0x" ADDRX " => 0x" ADDRX
522
                        " 0x" ADDRX " %d %d %d 0x" ADDRX "\n",
523
                        base + (i * 8), pte0, pte1,
524
                        (int)(pte0 >> 31), h, (int)((pte0 >> 6) & 1),
525
                        ctx->ptem);
526
            }
518 527
#endif
528
        }
519 529
        switch (r) {
520 530
        case -3:
521 531
            /* PTE inconsistency */
......
581 591
static inline int find_pte (CPUState *env, mmu_ctx_t *ctx, int h, int rw)
582 592
{
583 593
#if defined(TARGET_PPC64)
584
    if (env->mmu_model == POWERPC_MMU_64B ||
585
        env->mmu_model == POWERPC_MMU_64BRIDGE)
594
    if (env->mmu_model == POWERPC_MMU_64B)
586 595
        return find_pte64(ctx, h, rw);
587 596
#endif
588 597

  
589 598
    return find_pte32(ctx, h, rw);
590 599
}
591 600

  
592
static inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1,
593
                                             int sdr_sh,
594
                                             target_phys_addr_t hash,
595
                                             target_phys_addr_t mask)
596
{
597
    return (sdr1 & ((target_ulong)(-1ULL) << sdr_sh)) | (hash & mask);
598
}
599

  
600 601
#if defined(TARGET_PPC64)
601
static int slb_lookup (CPUState *env, target_ulong eaddr,
602
static int slb_lookup (CPUPPCState *env, target_ulong eaddr,
602 603
                       target_ulong *vsid, target_ulong *page_mask, int *attr)
603 604
{
604 605
    target_phys_addr_t sr_base;
......
610 611

  
611 612
    ret = -5;
612 613
    sr_base = env->spr[SPR_ASR];
614
#if defined(DEBUG_SLB)
615
    if (loglevel != 0) {
616
        fprintf(logfile, "%s: eaddr " ADDRX " base " PADDRX "\n",
617
                __func__, eaddr, sr_base);
618
    }
619
#endif
613 620
    mask = 0x0000000000000000ULL; /* Avoid gcc warning */
614
#if 0 /* XXX: Fix this */
615 621
    slb_nr = env->slb_nr;
616
#else
617
    slb_nr = 32;
618
#endif
619 622
    for (n = 0; n < slb_nr; n++) {
620 623
        tmp64 = ldq_phys(sr_base);
624
        tmp = ldl_phys(sr_base + 8);
625
#if defined(DEBUG_SLB)
626
        if (loglevel != 0) {
627
        fprintf(logfile, "%s: seg %d " PADDRX " %016" PRIx64 " %08" PRIx32 "\n",
628
                __func__, n, sr_base, tmp64, tmp);
629
        }
630
#endif
621 631
        if (tmp64 & 0x0000000008000000ULL) {
622 632
            /* SLB entry is valid */
623 633
            switch (tmp64 & 0x0000000006000000ULL) {
......
636 646
            }
637 647
            if ((eaddr & mask) == (tmp64 & mask)) {
638 648
                /* SLB match */
639
                tmp = ldl_phys(sr_base + 8);
640 649
                *vsid = ((tmp64 << 24) | (tmp >> 8)) & 0x0003FFFFFFFFFFFFULL;
641 650
                *page_mask = ~mask;
642 651
                *attr = tmp & 0xFF;
......
649 658

  
650 659
    return ret;
651 660
}
661

  
662
target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr)
663
{
664
    target_phys_addr_t sr_base;
665
    target_ulong rt;
666
    uint64_t tmp64;
667
    uint32_t tmp;
668

  
669
    sr_base = env->spr[SPR_ASR];
670
    sr_base += 12 * slb_nr;
671
    tmp64 = ldq_phys(sr_base);
672
    tmp = ldl_phys(sr_base + 8);
673
    if (tmp64 & 0x0000000008000000ULL) {
674
        /* SLB entry is valid */
675
        /* Copy SLB bits 62:88 to Rt 37:63 (VSID 23:49) */
676
        rt = tmp >> 8;             /* 65:88 => 40:63 */
677
        rt |= (tmp64 & 0x7) << 24; /* 62:64 => 37:39 */
678
        /* Copy SLB bits 89:92 to Rt 33:36 (KsKpNL) */
679
        rt |= ((tmp >> 4) & 0xF) << 27;
680
    } else {
681
        rt = 0;
682
    }
683
#if defined(DEBUG_SLB)
684
    if (loglevel != 0) {
685
        fprintf(logfile, "%s: " PADDRX " %016" PRIx64 " %08" PRIx32 " => %d "
686
                ADDRX "\n", __func__, sr_base, tmp64, tmp, slb_nr, rt);
687
    }
688
#endif
689

  
690
    return rt;
691
}
692

  
693
void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs)
694
{
695
    target_phys_addr_t sr_base;
696
    uint64_t tmp64;
697
    uint32_t tmp;
698

  
699
    sr_base = env->spr[SPR_ASR];
700
    sr_base += 12 * slb_nr;
701
    /* Copy Rs bits 37:63 to SLB 62:88 */
702
    tmp = rs << 8;
703
    tmp64 = (rs >> 24) & 0x7;
704
    /* Copy Rs bits 33:36 to SLB 89:92 */
705
    tmp |= ((rs >> 27) & 0xF) << 4;
706
    /* Set the valid bit */
707
    tmp64 |= 1 << 27;
708
    /* Set ESID */
709
    tmp64 |= (uint32_t)slb_nr << 28;
710
#if defined(DEBUG_SLB)
711
    if (loglevel != 0) {
712
        fprintf(logfile, "%s: %d " ADDRX " => " PADDRX " %016" PRIx64 " %08"
713
                PRIx32 "\n", __func__, slb_nr, rs, sr_base, tmp64, tmp);
714
    }
715
#endif
716
    /* Write SLB entry to memory */
717
    stq_phys(sr_base, tmp64);
718
    stl_phys(sr_base + 8, tmp);
719
}
652 720
#endif /* defined(TARGET_PPC64) */
653 721

  
654 722
/* Perform segment based translation */
723
static inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1,
724
                                             int sdr_sh,
725
                                             target_phys_addr_t hash,
726
                                             target_phys_addr_t mask)
727
{
728
    return (sdr1 & ((target_ulong)(-1ULL) << sdr_sh)) | (hash & mask);
729
}
730

  
655 731
static int get_segment (CPUState *env, mmu_ctx_t *ctx,
656 732
                        target_ulong eaddr, int rw, int type)
657 733
{
658
    target_phys_addr_t sdr, hash, mask, sdr_mask;
734
    target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
659 735
    target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
660 736
#if defined(TARGET_PPC64)
661 737
    int attr;
......
664 740
    int ret, ret2;
665 741

  
666 742
#if defined(TARGET_PPC64)
667
    if (env->mmu_model == POWERPC_MMU_64B ||
668
        env->mmu_model == POWERPC_MMU_64BRIDGE) {
743
    if (env->mmu_model == POWERPC_MMU_64B) {
744
#if defined (DEBUG_MMU)
745
        if (loglevel != 0) {
746
            fprintf(logfile, "Check SLBs\n");
747
        }
748
#endif
669 749
        ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr);
670 750
        if (ret < 0)
671 751
            return ret;
......
699 779
                    eaddr, (int)(eaddr >> 28), sr, env->nip,
700 780
                    env->lr, msr_ir, msr_dr, msr_pr, rw, type);
701 781
        }
702
        if (!ds && loglevel != 0) {
703
            fprintf(logfile, "pte segment: key=%d n=0x" ADDRX "\n",
704
                    ctx->key, sr & 0x10000000);
705
        }
706 782
#endif
707 783
    }
784
#if defined (DEBUG_MMU)
785
    if (loglevel != 0) {
786
        fprintf(logfile, "pte segment: key=%d ds %d nx %d vsid " ADDRX "\n",
787
                ctx->key, ds, nx, vsid);
788
    }
789
#endif
708 790
    ret = -1;
709 791
    if (!ds) {
710 792
        /* Check if instruction fetch is allowed, if needed */
711 793
        if (type != ACCESS_CODE || nx == 0) {
712 794
            /* Page address translation */
713
            pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS;
714
            hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
715 795
            /* Primary table address */
716 796
            sdr = env->sdr1;
717
            mask = ((sdr & 0x000001FF) << sdr_sh) | sdr_mask;
797
            pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS;
798
#if defined(TARGET_PPC64)
799
            if (env->mmu_model == POWERPC_MMU_64B) {
800
                htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
801
                /* XXX: this is false for 1 TB segments */
802
                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
803
            } else
804
#endif
805
            {
806
                htab_mask = sdr & 0x000001FF;
807
                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
808
            }
809
            mask = (htab_mask << sdr_sh) | sdr_mask;
810
#if defined (DEBUG_MMU)
811
            if (loglevel != 0) {
812
                fprintf(logfile, "sdr " PADDRX " sh %d hash " PADDRX " mask "
813
                        PADDRX " " ADDRX "\n", sdr, sdr_sh, hash, mask,
814
                        page_mask);
815
            }
816
#endif
718 817
            ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask);
719 818
            /* Secondary table address */
720 819
            hash = (~hash) & vsid_mask;
820
#if defined (DEBUG_MMU)
821
            if (loglevel != 0) {
822
                fprintf(logfile, "sdr " PADDRX " sh %d hash " PADDRX " mask "
823
                        PADDRX "\n", sdr, sdr_sh, hash, mask);
824
            }
825
#endif
721 826
            ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
722 827
#if defined(TARGET_PPC64)
723
            if (env->mmu_model == POWERPC_MMU_64B ||
724
                env->mmu_model == POWERPC_MMU_64BRIDGE) {
828
            if (env->mmu_model == POWERPC_MMU_64B) {
725 829
                /* Only 5 bits of the page index are used in the AVPN */
726 830
                ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
727 831
            } else
......
762 866
                        ret = ret2;
763 867
                }
764 868
            }
869
#if defined (DEBUG_MMU)
870
                    if (loglevel != 0) {
871
                        target_phys_addr_t curaddr;
872
                        uint32_t a0, a1, a2, a3;
873
                        fprintf(logfile,
874
                                "Page table: " PADDRX " len " PADDRX "\n",
875
                                sdr, mask + 0x80);
876
                        for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
877
                             curaddr += 16) {
878
                            a0 = ldl_phys(curaddr);
879
                            a1 = ldl_phys(curaddr + 4);
880
                            a2 = ldl_phys(curaddr + 8);
881
                            a3 = ldl_phys(curaddr + 12);
882
                            if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
883
                                fprintf(logfile,
884
                                        PADDRX ": %08x %08x %08x %08x\n",
885
                                        curaddr, a0, a1, a2, a3);
886
                            }
887
                        }
888
                    }
889
#endif
765 890
        } else {
766 891
#if defined (DEBUG_MMU)
767 892
            if (loglevel != 0)
......
1103 1228
        break;
1104 1229
#if defined(TARGET_PPC64)
1105 1230
    case POWERPC_MMU_64B:
1106
    case POWERPC_MMU_64BRIDGE:
1107 1231
        /* Real address are 60 bits long */
1108 1232
        ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
1109 1233
        ctx->prot |= PAGE_WRITE;
......
1170 1294
            /* No break here */
1171 1295
#if defined(TARGET_PPC64)
1172 1296
        case POWERPC_MMU_64B:
1173
        case POWERPC_MMU_64BRIDGE:
1174 1297
#endif
1175 1298
            if (ret < 0) {
1176 1299
                /* We didn't match any BAT entry or don't have BATs */
......
1275 1398
                case POWERPC_MMU_32B:
1276 1399
#if defined(TARGET_PPC64)
1277 1400
                case POWERPC_MMU_64B:
1278
                case POWERPC_MMU_64BRIDGE:
1279 1401
#endif
1280 1402
                    env->exception_index = POWERPC_EXCP_ISI;
1281 1403
                    env->error_code = 0x40000000;
......
1371 1493
                case POWERPC_MMU_32B:
1372 1494
#if defined(TARGET_PPC64)
1373 1495
                case POWERPC_MMU_64B:
1374
                case POWERPC_MMU_64BRIDGE:
1375 1496
#endif
1376 1497
                    env->exception_index = POWERPC_EXCP_DSI;
1377 1498
                    env->error_code = 0;
......
1622 1743
    case POWERPC_MMU_32B:
1623 1744
#if defined(TARGET_PPC64)
1624 1745
    case POWERPC_MMU_64B:
1625
    case POWERPC_MMU_64BRIDGE:
1626 1746
#endif /* defined(TARGET_PPC64) */
1627 1747
        tlb_flush(env, 1);
1628 1748
        break;
1629 1749
    default:
1630 1750
        /* XXX: TODO */
1631
        cpu_abort(env, "Unknown MMU model %d\n", env->mmu_model);
1751
        cpu_abort(env, "Unknown MMU model\n");
1632 1752
        break;
1633 1753
    }
1634 1754
}
......
1688 1808
        break;
1689 1809
#if defined(TARGET_PPC64)
1690 1810
    case POWERPC_MMU_64B:
1691
    case POWERPC_MMU_64BRIDGE:
1692 1811
        /* tlbie invalidate TLBs for all segments */
1693 1812
        /* XXX: given the fact that there are too many segments to invalidate,
1694 1813
         *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
......
1699 1818
#endif /* defined(TARGET_PPC64) */
1700 1819
    default:
1701 1820
        /* XXX: TODO */
1702
        cpu_abort(env, "Unknown MMU model 2\n");
1821
        cpu_abort(env, "Unknown MMU model\n");
1703 1822
        break;
1704 1823
    }
1705 1824
#else
......
1752 1871
    }
1753 1872
#endif
1754 1873
    if (env->sdr1 != value) {
1874
        /* XXX: for PowerPC 64, should check that the HTABSIZE value
1875
         *      is <= 28
1876
         */
1755 1877
        env->sdr1 = value;
1756 1878
        tlb_flush(env, 1);
1757 1879
    }
1758 1880
}
1759 1881

  
1882
#if 0 // Unused
1760 1883
target_ulong do_load_sr (CPUPPCState *env, int srnum)
1761 1884
{
1762 1885
    return env->sr[srnum];
1763 1886
}
1887
#endif
1764 1888

  
1765 1889
void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
1766 1890
{
b/target-ppc/op.c
317 317
    RETURN();
318 318
}
319 319

  
320
#if defined(TARGET_PPC64)
321
void OPPROTO op_load_slb (void)
322
{
323
    T0 = ppc_load_slb(env, T1);
324
    RETURN();
325
}
326

  
327
void OPPROTO op_store_slb (void)
328
{
329
    ppc_store_slb(env, T1, T0);
330
    RETURN();
331
}
332
#endif /* defined(TARGET_PPC64) */
333

  
320 334
void OPPROTO op_load_sdr1 (void)
321 335
{
322 336
    T0 = env->sdr1;
b/target-ppc/translate.c
385 385
/* PowerPC Instructions types definitions                                    */
386 386
enum {
387 387
    PPC_NONE          = 0x0000000000000000ULL,
388
    /* integer operations instructions                  */
389
    /* flow control instructions                        */
390
    /* virtual memory instructions                      */
391
    /* ld/st with reservation instructions              */
392
    /* cache control instructions                       */
393
    /* spr/msr access instructions                      */
388
    /* PowerPC base instructions set                                         */
394 389
    PPC_INSNS_BASE    = 0x0000000000000001ULL,
390
    /* integer operations instructions                                       */
395 391
#define PPC_INTEGER PPC_INSNS_BASE
392
    /* flow control instructions                                             */
396 393
#define PPC_FLOW    PPC_INSNS_BASE
394
    /* virtual memory instructions                                           */
397 395
#define PPC_MEM     PPC_INSNS_BASE
396
    /* ld/st with reservation instructions                                   */
398 397
#define PPC_RES     PPC_INSNS_BASE
398
    /* cache control instructions                                            */
399 399
#define PPC_CACHE   PPC_INSNS_BASE
400
    /* spr/msr access instructions                                           */
400 401
#define PPC_MISC    PPC_INSNS_BASE
401
    /* Optional floating point instructions             */
402
    /* Optional floating point instructions                                  */
402 403
    PPC_FLOAT         = 0x0000000000000002ULL,
403 404
    PPC_FLOAT_FSQRT   = 0x0000000000000004ULL,
404 405
    PPC_FLOAT_FRES    = 0x0000000000000008ULL,
405 406
    PPC_FLOAT_FRSQRTE = 0x0000000000000010ULL,
406 407
    PPC_FLOAT_FSEL    = 0x0000000000000020ULL,
407 408
    PPC_FLOAT_STFIWX  = 0x0000000000000040ULL,
408
    /* external control instructions                    */
409
    /* external control instructions                                         */
409 410
    PPC_EXTERN        = 0x0000000000000080ULL,
410
    /* segment register access instructions             */
411
    /* segment register access instructions                                  */
411 412
    PPC_SEGMENT       = 0x0000000000000100ULL,
412
    /* Optional cache control instruction               */
413
    /* Optional cache control instruction                                    */
413 414
    PPC_CACHE_DCBA    = 0x0000000000000200ULL,
414
    /* Optional memory control instructions             */
415
    /* Optional memory control instructions                                  */
415 416
    PPC_MEM_TLBIA     = 0x0000000000000400ULL,
416 417
    PPC_MEM_TLBIE     = 0x0000000000000800ULL,
417 418
    PPC_MEM_TLBSYNC   = 0x0000000000001000ULL,
418
    /* eieio & sync                                     */
419
    /* eieio & sync                                                          */
419 420
    PPC_MEM_SYNC      = 0x0000000000002000ULL,
420
    /* PowerPC 6xx TLB management instructions          */
421
    /* PowerPC 6xx TLB management instructions                               */
421 422
    PPC_6xx_TLB       = 0x0000000000004000ULL,
422
    /* Altivec support                                  */
423
    /* Altivec support                                                       */
423 424
    PPC_ALTIVEC       = 0x0000000000008000ULL,
424
    /* Time base mftb instruction                       */
425
    /* Time base mftb instruction                                            */
425 426
    PPC_MFTB          = 0x0000000000010000ULL,
426
    /* Embedded PowerPC dedicated instructions          */
427
    /* Embedded PowerPC dedicated instructions                               */
427 428
    PPC_EMB_COMMON    = 0x0000000000020000ULL,
428
    /* PowerPC 40x exception model                      */
429
    /* PowerPC 40x exception model                                           */
429 430
    PPC_40x_EXCP      = 0x0000000000040000ULL,
430
    /* PowerPC 40x TLB management instructions          */
431
    /* PowerPC 40x TLB management instructions                               */
431 432
    PPC_40x_TLB       = 0x0000000000080000ULL,
432
    /* PowerPC 405 Mac instructions                     */
433
    /* PowerPC 405 Mac instructions                                          */
433 434
    PPC_405_MAC       = 0x0000000000100000ULL,
434
    /* PowerPC 440 specific instructions                */
435
    /* PowerPC 440 specific instructions                                     */
435 436
    PPC_440_SPEC      = 0x0000000000200000ULL,
436
    /* Power-to-PowerPC bridge (601)                    */
437
    /* Power-to-PowerPC bridge (601)                                         */
437 438
    PPC_POWER_BR      = 0x0000000000400000ULL,
438
    /* PowerPC 602 specific */
439
    /* PowerPC 602 specific                                                  */
439 440
    PPC_602_SPEC      = 0x0000000000800000ULL,
440
    /* Deprecated instructions                          */
441
    /* Original POWER instruction set                   */
441
    /* Deprecated instructions                                               */
442
    /* Original POWER instruction set                                        */
442 443
    PPC_POWER         = 0x0000000001000000ULL,
443
    /* POWER2 instruction set extension                 */
444
    /* POWER2 instruction set extension                                      */
444 445
    PPC_POWER2        = 0x0000000002000000ULL,
445
    /* Power RTC support */
446
    /* Power RTC support                                                     */
446 447
    PPC_POWER_RTC     = 0x0000000004000000ULL,
447
    /* 64 bits PowerPC instructions                     */
448
    /* 64 bits PowerPC instruction set                  */
448
    /* 64 bits PowerPC instruction set                                       */
449 449
    PPC_64B           = 0x0000000008000000ULL,
450
    /* 64 bits hypervisor extensions                    */
450
    /* 64 bits hypervisor extensions                                         */
451 451
    PPC_64H           = 0x0000000010000000ULL,
452
    /* 64 bits PowerPC "bridge" features                */
453
    PPC_64_BRIDGE     = 0x0000000020000000ULL,
454
    /* BookE (embedded) PowerPC specification           */
452
    /* segment register access instructions for PowerPC 64 "bridge"          */
453
    PPC_SEGMENT_64B   = 0x0000000020000000ULL,
454
    /* BookE (embedded) PowerPC specification                                */
455 455
    PPC_BOOKE         = 0x0000000040000000ULL,
456
    /* eieio                                            */
456
    /* eieio                                                                 */
457 457
    PPC_MEM_EIEIO     = 0x0000000080000000ULL,
458
    /* e500 vector instructions                         */
458
    /* e500 vector instructions                                              */
459 459
    PPC_E500_VECTOR   = 0x0000000100000000ULL,
460
    /* PowerPC 4xx dedicated instructions               */
460
    /* PowerPC 4xx dedicated instructions                                    */
461 461
    PPC_4xx_COMMON    = 0x0000000200000000ULL,
462
    /* PowerPC 2.03 specification extensions            */
462
    /* PowerPC 2.03 specification extensions                                 */
463 463
    PPC_203           = 0x0000000400000000ULL,
464
    /* PowerPC 2.03 SPE extension                       */
464
    /* PowerPC 2.03 SPE extension                                            */
465 465
    PPC_SPE           = 0x0000000800000000ULL,
466
    /* PowerPC 2.03 SPE floating-point extension        */
466
    /* PowerPC 2.03 SPE floating-point extension                             */
467 467
    PPC_SPEFPU        = 0x0000001000000000ULL,
468
    /* SLB management                                   */
468
    /* SLB management                                                        */
469 469
    PPC_SLBI          = 0x0000002000000000ULL,
470
    /* PowerPC 40x ibct instructions                    */
470
    /* PowerPC 40x ibct instructions                                         */
471 471
    PPC_40x_ICBT      = 0x0000004000000000ULL,
472
    /* PowerPC 74xx TLB management instructions         */
472
    /* PowerPC 74xx TLB management instructions                              */
473 473
    PPC_74xx_TLB      = 0x0000008000000000ULL,
474
    /* More BookE (embedded) instructions...            */
474
    /* More BookE (embedded) instructions...                                 */
475 475
    PPC_BOOKE_EXT     = 0x0000010000000000ULL,
476
    /* rfmci is not implemented in all BookE PowerPC    */
476
    /* rfmci is not implemented in all BookE PowerPC                         */
477 477
    PPC_RFMCI         = 0x0000020000000000ULL,
478
    /* user-mode DCR access, implemented in PowerPC 460 */
478
    /* user-mode DCR access, implemented in PowerPC 460                      */
479 479
    PPC_DCRUX         = 0x0000040000000000ULL,
480
    /* New floating-point extensions (PowerPC 2.0x)     */
480
    /* New floating-point extensions (PowerPC 2.0x)                          */
481 481
    PPC_FLOAT_EXT     = 0x0000080000000000ULL,
482
    /* New wait instruction (PowerPC 2.0x)              */
482
    /* New wait instruction (PowerPC 2.0x)                                   */
483 483
    PPC_WAIT          = 0x0000100000000000ULL,
484
    /* New 64 bits extensions (PowerPC 2.0x)            */
484
    /* New 64 bits extensions (PowerPC 2.0x)                                 */
485 485
    PPC_64BX          = 0x0000200000000000ULL,
486
    /* dcbz instruction with fixed cache line size      */
486
    /* dcbz instruction with fixed cache line size                           */
487 487
    PPC_CACHE_DCBZ    = 0x0000400000000000ULL,
488
    /* dcbz instruction with tunable cache line size    */
488
    /* dcbz instruction with tunable cache line size                         */
489 489
    PPC_CACHE_DCBZT   = 0x0000800000000000ULL,
490 490
};
491 491

  
......
3931 3931
#endif
3932 3932
}
3933 3933

  
3934
#if defined(TARGET_PPC64)
3935
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
3936
/* mfsr */
3937
GEN_HANDLER(mfsr_64b, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
3938
{
3939
#if defined(CONFIG_USER_ONLY)
3940
    GEN_EXCP_PRIVREG(ctx);
3941
#else
3942
    if (unlikely(!ctx->supervisor)) {
3943
        GEN_EXCP_PRIVREG(ctx);
3944
        return;
3945
    }
3946
    gen_op_set_T1(SR(ctx->opcode));
3947
    gen_op_load_slb();
3948
    gen_op_store_T0_gpr(rD(ctx->opcode));
3949
#endif
3950
}
3951

  
3952
/* mfsrin */
3953
GEN_HANDLER(mfsrin_64b, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT_64B)
3954
{
3955
#if defined(CONFIG_USER_ONLY)
3956
    GEN_EXCP_PRIVREG(ctx);
3957
#else
3958
    if (unlikely(!ctx->supervisor)) {
3959
        GEN_EXCP_PRIVREG(ctx);
3960
        return;
3961
    }
3962
    gen_op_load_gpr_T1(rB(ctx->opcode));
3963
    gen_op_srli_T1(28);
3964
    gen_op_load_slb();
3965
    gen_op_store_T0_gpr(rD(ctx->opcode));
3966
#endif
3967
}
3968

  
3969
/* mtsr */
3970
GEN_HANDLER(mtsr_64b, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
3971
{
3972
#if defined(CONFIG_USER_ONLY)
3973
    GEN_EXCP_PRIVREG(ctx);
3974
#else
3975
    if (unlikely(!ctx->supervisor)) {
3976
        GEN_EXCP_PRIVREG(ctx);
3977
        return;
3978
    }
3979
    gen_op_load_gpr_T0(rS(ctx->opcode));
3980
    gen_op_set_T1(SR(ctx->opcode));
3981
    gen_op_store_slb();
3982
#endif
3983
}
3984

  
3985
/* mtsrin */
3986
GEN_HANDLER(mtsrin_64b, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT_64B)
3987
{
3988
#if defined(CONFIG_USER_ONLY)
3989
    GEN_EXCP_PRIVREG(ctx);
3990
#else
3991
    if (unlikely(!ctx->supervisor)) {
3992
        GEN_EXCP_PRIVREG(ctx);
3993
        return;
3994
    }
3995
    gen_op_load_gpr_T0(rS(ctx->opcode));
3996
    gen_op_load_gpr_T1(rB(ctx->opcode));
3997
    gen_op_srli_T1(28);
3998
    gen_op_store_slb();
3999
#endif
4000
}
4001
#endif /* defined(TARGET_PPC64) */
4002

  
3934 4003
/***                      Lookaside buffer management                      ***/
3935 4004
/* Optional & supervisor only: */
3936 4005
/* tlbia */
b/target-ppc/translate_init.c
3095 3095
/* Non-embedded PowerPC                                                      */
3096 3096
/* Base instructions set for all 6xx/7xx/74xx/970 PowerPC                    */
3097 3097
#define POWERPC_INSNS_6xx    (PPC_INSNS_BASE | PPC_FLOAT | PPC_MEM_SYNC |     \
3098
                              PPC_MEM_EIEIO | PPC_SEGMENT | PPC_MEM_TLBIE)
3098
                              PPC_MEM_EIEIO | PPC_MEM_TLBIE)
3099 3099
/* Instructions common to all 6xx/7xx/74xx/970 PowerPC except 601 & 602      */
3100 3100
#define POWERPC_INSNS_WORKS  (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT |           \
3101 3101
                              PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \
3102 3102
                              PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \
3103
                              PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ | PPC_MFTB)
3103
                              PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ | PPC_MFTB |   \
3104
                              PPC_SEGMENT)
3104 3105

  
3105 3106
/* POWER : same as 601, without mfmsr, mfsr                                  */
3106 3107
#if defined(TODO)
......
3111 3112

  
3112 3113
/* PowerPC 601                                                               */
3113 3114
#define POWERPC_INSNS_601    (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ |            \
3114
                              PPC_EXTERN | PPC_POWER_BR)
3115
                              PPC_SEGMENT | PPC_EXTERN | PPC_POWER_BR)
3115 3116
#define POWERPC_MSRM_601     (0x000000000000FE70ULL)
3116 3117
//#define POWERPC_MMU_601      (POWERPC_MMU_601)
3117 3118
//#define POWERPC_EXCP_601     (POWERPC_EXCP_601)
......
3164 3165
                              PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \
3165 3166
                              PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \
3166 3167
                              PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ |\
3167
                              PPC_602_SPEC)
3168
                              PPC_SEGMENT | PPC_602_SPEC)
3168 3169
#define POWERPC_MSRM_602     (0x000000000033FF73ULL)
3169 3170
#define POWERPC_MMU_602      (POWERPC_MMU_SOFT_6xx)
3170 3171
//#define POWERPC_EXCP_602     (POWERPC_EXCP_602)
......
3942 3943

  
3943 3944
#if defined (TARGET_PPC64)
3944 3945
#define POWERPC_INSNS_WORK64  (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT |          \
3945
                              PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \
3946
                              PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \
3947
                              PPC_MEM_TLBSYNC | PPC_CACHE_DCBZT | PPC_MFTB)
3946
                               PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |           \
3947
                               PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |            \
3948
                               PPC_MEM_TLBSYNC | PPC_CACHE_DCBZT | PPC_MFTB)
3948 3949
/* PowerPC 970                                                               */
3949 3950
#define POWERPC_INSNS_970    (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT |        \
3950 3951
                              PPC_64B | PPC_ALTIVEC |                         \
3951
                              PPC_64_BRIDGE | PPC_SLBI)
3952
                              PPC_SEGMENT_64B | PPC_SLBI)
3952 3953
#define POWERPC_MSRM_970     (0x900000000204FF36ULL)
3953
#define POWERPC_MMU_970      (POWERPC_MMU_64BRIDGE)
3954
#define POWERPC_MMU_970      (POWERPC_MMU_64B)
3954 3955
//#define POWERPC_EXCP_970     (POWERPC_EXCP_970)
3955 3956
#define POWERPC_INPUT_970    (PPC_FLAGS_INPUT_970)
3956 3957
#define POWERPC_BFDM_970     (bfd_mach_ppc64)
......
3990 3991
    /* Memory management */
3991 3992
    /* XXX: not correct */
3992 3993
    gen_low_BATs(env);
3993
#if 0 // TODO
3994
    env->slb_nr = 32;
3994
    /* XXX : not implemented */
3995
    spr_register(env, SPR_MMUCFG, "MMUCFG",
3996
                 SPR_NOACCESS, SPR_NOACCESS,
3997
                 &spr_read_generic, SPR_NOACCESS,
3998
                 0x00000000); /* TOFIX */
3999
    /* XXX : not implemented */
4000
    spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4001
                 SPR_NOACCESS, SPR_NOACCESS,
4002
                 &spr_read_generic, &spr_write_generic,
4003
                 0x00000000); /* TOFIX */
4004
    spr_register(env, SPR_HIOR, "SPR_HIOR",
4005
                 SPR_NOACCESS, SPR_NOACCESS,
4006
                 &spr_read_generic, &spr_write_generic,
4007
                 0xFFF00000); /* XXX: This is a hack */
4008
#if !defined(CONFIG_USER_ONLY)
4009
    env->excp_prefix = 0xFFF00000;
3995 4010
#endif
4011
    env->slb_nr = 32;
3996 4012
    init_excp_970(env);
3997 4013
    env->dcache_line_size = 128;
3998 4014
    env->icache_line_size = 128;
......
4003 4019
/* PowerPC 970FX (aka G5)                                                    */
4004 4020
#define POWERPC_INSNS_970FX  (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT |        \
4005 4021
                              PPC_64B | PPC_ALTIVEC |                         \
4006
                              PPC_64_BRIDGE | PPC_SLBI)
4022
                              PPC_SEGMENT_64B | PPC_SLBI)
4007 4023
#define POWERPC_MSRM_970FX   (0x800000000204FF36ULL)
4008
#define POWERPC_MMU_970FX    (POWERPC_MMU_64BRIDGE)
4024
#define POWERPC_MMU_970FX    (POWERPC_MMU_64B)
4009 4025
#define POWERPC_EXCP_970FX   (POWERPC_EXCP_970)
4010 4026
#define POWERPC_INPUT_970FX  (PPC_FLAGS_INPUT_970)
4011 4027
#define POWERPC_BFDM_970FX   (bfd_mach_ppc64)
......
4045 4061
    /* Memory management */
4046 4062
    /* XXX: not correct */
4047 4063
    gen_low_BATs(env);
4048
#if 0 // TODO
4049
    env->slb_nr = 32;
4064
    /* XXX : not implemented */
4065
    spr_register(env, SPR_MMUCFG, "MMUCFG",
4066
                 SPR_NOACCESS, SPR_NOACCESS,
4067
                 &spr_read_generic, SPR_NOACCESS,
4068
                 0x00000000); /* TOFIX */
4069
    /* XXX : not implemented */
4070
    spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4071
                 SPR_NOACCESS, SPR_NOACCESS,
4072
                 &spr_read_generic, &spr_write_generic,
4073
                 0x00000000); /* TOFIX */
4074
    spr_register(env, SPR_HIOR, "SPR_HIOR",
4075
                 SPR_NOACCESS, SPR_NOACCESS,
4076
                 &spr_read_generic, &spr_write_generic,
4077
                 0xFFF00000); /* XXX: This is a hack */
4078
#if !defined(CONFIG_USER_ONLY)
4079
    env->excp_prefix = 0xFFF00000;
4050 4080
#endif
4081
    env->slb_nr = 32;
4051 4082
    init_excp_970(env);
4052 4083
    env->dcache_line_size = 128;
4053 4084
    env->icache_line_size = 128;
......
4058 4089
/* PowerPC 970 GX                                                            */
4059 4090
#define POWERPC_INSNS_970GX  (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT |        \
4060 4091
                              PPC_64B | PPC_ALTIVEC |                         \
4061
                              PPC_64_BRIDGE | PPC_SLBI)
4092
                              PPC_SEGMENT_64B | PPC_SLBI)
4062 4093
#define POWERPC_MSRM_970GX   (0x800000000204FF36ULL)
4063
#define POWERPC_MMU_970GX    (POWERPC_MMU_64BRIDGE)
4094
#define POWERPC_MMU_970GX    (POWERPC_MMU_64B)
4064 4095
#define POWERPC_EXCP_970GX   (POWERPC_EXCP_970)
4065 4096
#define POWERPC_INPUT_970GX  (PPC_FLAGS_INPUT_970)
4066 4097
#define POWERPC_BFDM_970GX   (bfd_mach_ppc64)
......
4100 4131
    /* Memory management */
4101 4132
    /* XXX: not correct */
4102 4133
    gen_low_BATs(env);
4103
#if 0 // TODO
4104
    env->slb_nr = 32;
4134
    /* XXX : not implemented */
4135
    spr_register(env, SPR_MMUCFG, "MMUCFG",
4136
                 SPR_NOACCESS, SPR_NOACCESS,
4137
                 &spr_read_generic, SPR_NOACCESS,
4138
                 0x00000000); /* TOFIX */
4139
    /* XXX : not implemented */
4140
    spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4141
                 SPR_NOACCESS, SPR_NOACCESS,
4142
                 &spr_read_generic, &spr_write_generic,
4143
                 0x00000000); /* TOFIX */
4144
    spr_register(env, SPR_HIOR, "SPR_HIOR",
4145
                 SPR_NOACCESS, SPR_NOACCESS,
4146
                 &spr_read_generic, &spr_write_generic,
4147
                 0xFFF00000); /* XXX: This is a hack */
4148
#if !defined(CONFIG_USER_ONLY)
4149
    env->excp_prefix = 0xFFF00000;
4105 4150
#endif
4151
    env->slb_nr = 32;
4106 4152
    init_excp_970(env);
4107 4153
    env->dcache_line_size = 128;
4108 4154
    env->icache_line_size = 128;
......
6010 6056
        case POWERPC_MMU_64B:
6011 6057
            mmu_model = "PowerPC 64";
6012 6058
            break;
6013
        case POWERPC_MMU_64BRIDGE:
6014
            mmu_model = "PowerPC 64 bridge";
6015
            break;
6016 6059
#endif
6017 6060
        default:
6018 6061
            mmu_model = "Unknown or invalid";

Also available in: Unified diff