Commit 12de9a396acbc95e25c5d60ed097cc55777eaaed

Authored by j_mayer
1 parent 5bfb56b2

Full implementation of PowerPC 64 MMU, just missing support for 1 TB

memory segments.
Remove the PowerPC 64 "bridge" MMU model and implement segment registers
  emulation using SLB entries instead.
Make SLB area size implementation dependant.
Improve TLB & SLB search debug traces.
Temporary hack to make PowerPC 970 boot from ROM instead of RAM.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3335 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/cpu.h
@@ -105,10 +105,8 @@ enum { @@ -105,10 +105,8 @@ enum {
105 /* BookE FSL MMU model */ 105 /* BookE FSL MMU model */
106 POWERPC_MMU_BOOKE_FSL, 106 POWERPC_MMU_BOOKE_FSL,
107 #if defined(TARGET_PPC64) 107 #if defined(TARGET_PPC64)
108 - /* Standard 64 bits PowerPC MMU */ 108 + /* 64 bits PowerPC MMU */
109 POWERPC_MMU_64B, 109 POWERPC_MMU_64B,
110 - /* 64 bits "bridge" PowerPC MMU */  
111 - POWERPC_MMU_64BRIDGE,  
112 #endif /* defined(TARGET_PPC64) */ 110 #endif /* defined(TARGET_PPC64) */
113 }; 111 };
114 112
@@ -514,6 +512,8 @@ struct CPUPPCState { @@ -514,6 +512,8 @@ struct CPUPPCState {
514 ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */ 512 ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */
515 /* 403 dedicated access protection registers */ 513 /* 403 dedicated access protection registers */
516 target_ulong pb[4]; 514 target_ulong pb[4];
  515 + /* PowerPC 64 SLB area */
  516 + int slb_nr;
517 517
518 int dcache_line_size; 518 int dcache_line_size;
519 int icache_line_size; 519 int icache_line_size;
@@ -606,10 +606,14 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value); @@ -606,10 +606,14 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value);
606 #if defined(TARGET_PPC64) 606 #if defined(TARGET_PPC64)
607 target_ulong ppc_load_asr (CPUPPCState *env); 607 target_ulong ppc_load_asr (CPUPPCState *env);
608 void ppc_store_asr (CPUPPCState *env, target_ulong value); 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 target_ulong do_load_sr (CPUPPCState *env, int srnum); 613 target_ulong do_load_sr (CPUPPCState *env, int srnum);
611 -void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);  
612 #endif 614 #endif
  615 +void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
  616 +#endif /* !defined(CONFIG_USER_ONLY) */
613 target_ulong ppc_load_xer (CPUPPCState *env); 617 target_ulong ppc_load_xer (CPUPPCState *env);
614 void ppc_store_xer (CPUPPCState *env, target_ulong value); 618 void ppc_store_xer (CPUPPCState *env, target_ulong value);
615 target_ulong do_load_msr (CPUPPCState *env); 619 target_ulong do_load_msr (CPUPPCState *env);
target-ppc/helper.c
@@ -501,21 +501,31 @@ static inline int _find_pte (mmu_ctx_t *ctx, int is_64b, int h, int rw) @@ -501,21 +501,31 @@ static inline int _find_pte (mmu_ctx_t *ctx, int is_64b, int h, int rw)
501 pte0 = ldq_phys(base + (i * 16)); 501 pte0 = ldq_phys(base + (i * 16));
502 pte1 = ldq_phys(base + (i * 16) + 8); 502 pte1 = ldq_phys(base + (i * 16) + 8);
503 r = pte64_check(ctx, pte0, pte1, h, rw); 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 } else 513 } else
505 #endif 514 #endif
506 { 515 {
507 pte0 = ldl_phys(base + (i * 8)); 516 pte0 = ldl_phys(base + (i * 8));
508 pte1 = ldl_phys(base + (i * 8) + 4); 517 pte1 = ldl_phys(base + (i * 8) + 4);
509 r = pte32_check(ctx, pte0, pte1, h, rw); 518 r = pte32_check(ctx, pte0, pte1, h, rw);
510 - }  
511 #if defined (DEBUG_MMU) 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 #endif 527 #endif
  528 + }
519 switch (r) { 529 switch (r) {
520 case -3: 530 case -3:
521 /* PTE inconsistency */ 531 /* PTE inconsistency */
@@ -581,24 +591,15 @@ static int find_pte64 (mmu_ctx_t *ctx, int h, int rw) @@ -581,24 +591,15 @@ static int find_pte64 (mmu_ctx_t *ctx, int h, int rw)
581 static inline int find_pte (CPUState *env, mmu_ctx_t *ctx, int h, int rw) 591 static inline int find_pte (CPUState *env, mmu_ctx_t *ctx, int h, int rw)
582 { 592 {
583 #if defined(TARGET_PPC64) 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 return find_pte64(ctx, h, rw); 595 return find_pte64(ctx, h, rw);
587 #endif 596 #endif
588 597
589 return find_pte32(ctx, h, rw); 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 #if defined(TARGET_PPC64) 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 target_ulong *vsid, target_ulong *page_mask, int *attr) 603 target_ulong *vsid, target_ulong *page_mask, int *attr)
603 { 604 {
604 target_phys_addr_t sr_base; 605 target_phys_addr_t sr_base;
@@ -610,14 +611,23 @@ static int slb_lookup (CPUState *env, target_ulong eaddr, @@ -610,14 +611,23 @@ static int slb_lookup (CPUState *env, target_ulong eaddr,
610 611
611 ret = -5; 612 ret = -5;
612 sr_base = env->spr[SPR_ASR]; 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 mask = 0x0000000000000000ULL; /* Avoid gcc warning */ 620 mask = 0x0000000000000000ULL; /* Avoid gcc warning */
614 -#if 0 /* XXX: Fix this */  
615 slb_nr = env->slb_nr; 621 slb_nr = env->slb_nr;
616 -#else  
617 - slb_nr = 32;  
618 -#endif  
619 for (n = 0; n < slb_nr; n++) { 622 for (n = 0; n < slb_nr; n++) {
620 tmp64 = ldq_phys(sr_base); 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 if (tmp64 & 0x0000000008000000ULL) { 631 if (tmp64 & 0x0000000008000000ULL) {
622 /* SLB entry is valid */ 632 /* SLB entry is valid */
623 switch (tmp64 & 0x0000000006000000ULL) { 633 switch (tmp64 & 0x0000000006000000ULL) {
@@ -636,7 +646,6 @@ static int slb_lookup (CPUState *env, target_ulong eaddr, @@ -636,7 +646,6 @@ static int slb_lookup (CPUState *env, target_ulong eaddr,
636 } 646 }
637 if ((eaddr & mask) == (tmp64 & mask)) { 647 if ((eaddr & mask) == (tmp64 & mask)) {
638 /* SLB match */ 648 /* SLB match */
639 - tmp = ldl_phys(sr_base + 8);  
640 *vsid = ((tmp64 << 24) | (tmp >> 8)) & 0x0003FFFFFFFFFFFFULL; 649 *vsid = ((tmp64 << 24) | (tmp >> 8)) & 0x0003FFFFFFFFFFFFULL;
641 *page_mask = ~mask; 650 *page_mask = ~mask;
642 *attr = tmp & 0xFF; 651 *attr = tmp & 0xFF;
@@ -649,13 +658,80 @@ static int slb_lookup (CPUState *env, target_ulong eaddr, @@ -649,13 +658,80 @@ static int slb_lookup (CPUState *env, target_ulong eaddr,
649 658
650 return ret; 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 #endif /* defined(TARGET_PPC64) */ 720 #endif /* defined(TARGET_PPC64) */
653 721
654 /* Perform segment based translation */ 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 static int get_segment (CPUState *env, mmu_ctx_t *ctx, 731 static int get_segment (CPUState *env, mmu_ctx_t *ctx,
656 target_ulong eaddr, int rw, int type) 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 target_ulong sr, vsid, vsid_mask, pgidx, page_mask; 735 target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
660 #if defined(TARGET_PPC64) 736 #if defined(TARGET_PPC64)
661 int attr; 737 int attr;
@@ -664,8 +740,12 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, @@ -664,8 +740,12 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
664 int ret, ret2; 740 int ret, ret2;
665 741
666 #if defined(TARGET_PPC64) 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 ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr); 749 ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr);
670 if (ret < 0) 750 if (ret < 0)
671 return ret; 751 return ret;
@@ -699,29 +779,53 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, @@ -699,29 +779,53 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
699 eaddr, (int)(eaddr >> 28), sr, env->nip, 779 eaddr, (int)(eaddr >> 28), sr, env->nip,
700 env->lr, msr_ir, msr_dr, msr_pr, rw, type); 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 #endif 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 ret = -1; 790 ret = -1;
709 if (!ds) { 791 if (!ds) {
710 /* Check if instruction fetch is allowed, if needed */ 792 /* Check if instruction fetch is allowed, if needed */
711 if (type != ACCESS_CODE || nx == 0) { 793 if (type != ACCESS_CODE || nx == 0) {
712 /* Page address translation */ 794 /* Page address translation */
713 - pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS;  
714 - hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;  
715 /* Primary table address */ 795 /* Primary table address */
716 sdr = env->sdr1; 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 ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask); 817 ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask);
719 /* Secondary table address */ 818 /* Secondary table address */
720 hash = (~hash) & vsid_mask; 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 ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask); 826 ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
722 #if defined(TARGET_PPC64) 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 /* Only 5 bits of the page index are used in the AVPN */ 829 /* Only 5 bits of the page index are used in the AVPN */
726 ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80); 830 ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
727 } else 831 } else
@@ -762,6 +866,27 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, @@ -762,6 +866,27 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
762 ret = ret2; 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 } else { 890 } else {
766 #if defined (DEBUG_MMU) 891 #if defined (DEBUG_MMU)
767 if (loglevel != 0) 892 if (loglevel != 0)
@@ -1103,7 +1228,6 @@ static int check_physical (CPUState *env, mmu_ctx_t *ctx, @@ -1103,7 +1228,6 @@ static int check_physical (CPUState *env, mmu_ctx_t *ctx,
1103 break; 1228 break;
1104 #if defined(TARGET_PPC64) 1229 #if defined(TARGET_PPC64)
1105 case POWERPC_MMU_64B: 1230 case POWERPC_MMU_64B:
1106 - case POWERPC_MMU_64BRIDGE:  
1107 /* Real address are 60 bits long */ 1231 /* Real address are 60 bits long */
1108 ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL; 1232 ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
1109 ctx->prot |= PAGE_WRITE; 1233 ctx->prot |= PAGE_WRITE;
@@ -1170,7 +1294,6 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, @@ -1170,7 +1294,6 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1170 /* No break here */ 1294 /* No break here */
1171 #if defined(TARGET_PPC64) 1295 #if defined(TARGET_PPC64)
1172 case POWERPC_MMU_64B: 1296 case POWERPC_MMU_64B:
1173 - case POWERPC_MMU_64BRIDGE:  
1174 #endif 1297 #endif
1175 if (ret < 0) { 1298 if (ret < 0) {
1176 /* We didn't match any BAT entry or don't have BATs */ 1299 /* We didn't match any BAT entry or don't have BATs */
@@ -1275,7 +1398,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -1275,7 +1398,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1275 case POWERPC_MMU_32B: 1398 case POWERPC_MMU_32B:
1276 #if defined(TARGET_PPC64) 1399 #if defined(TARGET_PPC64)
1277 case POWERPC_MMU_64B: 1400 case POWERPC_MMU_64B:
1278 - case POWERPC_MMU_64BRIDGE:  
1279 #endif 1401 #endif
1280 env->exception_index = POWERPC_EXCP_ISI; 1402 env->exception_index = POWERPC_EXCP_ISI;
1281 env->error_code = 0x40000000; 1403 env->error_code = 0x40000000;
@@ -1371,7 +1493,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -1371,7 +1493,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1371 case POWERPC_MMU_32B: 1493 case POWERPC_MMU_32B:
1372 #if defined(TARGET_PPC64) 1494 #if defined(TARGET_PPC64)
1373 case POWERPC_MMU_64B: 1495 case POWERPC_MMU_64B:
1374 - case POWERPC_MMU_64BRIDGE:  
1375 #endif 1496 #endif
1376 env->exception_index = POWERPC_EXCP_DSI; 1497 env->exception_index = POWERPC_EXCP_DSI;
1377 env->error_code = 0; 1498 env->error_code = 0;
@@ -1622,13 +1743,12 @@ void ppc_tlb_invalidate_all (CPUPPCState *env) @@ -1622,13 +1743,12 @@ void ppc_tlb_invalidate_all (CPUPPCState *env)
1622 case POWERPC_MMU_32B: 1743 case POWERPC_MMU_32B:
1623 #if defined(TARGET_PPC64) 1744 #if defined(TARGET_PPC64)
1624 case POWERPC_MMU_64B: 1745 case POWERPC_MMU_64B:
1625 - case POWERPC_MMU_64BRIDGE:  
1626 #endif /* defined(TARGET_PPC64) */ 1746 #endif /* defined(TARGET_PPC64) */
1627 tlb_flush(env, 1); 1747 tlb_flush(env, 1);
1628 break; 1748 break;
1629 default: 1749 default:
1630 /* XXX: TODO */ 1750 /* XXX: TODO */
1631 - cpu_abort(env, "Unknown MMU model %d\n", env->mmu_model); 1751 + cpu_abort(env, "Unknown MMU model\n");
1632 break; 1752 break;
1633 } 1753 }
1634 } 1754 }
@@ -1688,7 +1808,6 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) @@ -1688,7 +1808,6 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
1688 break; 1808 break;
1689 #if defined(TARGET_PPC64) 1809 #if defined(TARGET_PPC64)
1690 case POWERPC_MMU_64B: 1810 case POWERPC_MMU_64B:
1691 - case POWERPC_MMU_64BRIDGE:  
1692 /* tlbie invalidate TLBs for all segments */ 1811 /* tlbie invalidate TLBs for all segments */
1693 /* XXX: given the fact that there are too many segments to invalidate, 1812 /* XXX: given the fact that there are too many segments to invalidate,
1694 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu, 1813 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
@@ -1699,7 +1818,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) @@ -1699,7 +1818,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
1699 #endif /* defined(TARGET_PPC64) */ 1818 #endif /* defined(TARGET_PPC64) */
1700 default: 1819 default:
1701 /* XXX: TODO */ 1820 /* XXX: TODO */
1702 - cpu_abort(env, "Unknown MMU model 2\n"); 1821 + cpu_abort(env, "Unknown MMU model\n");
1703 break; 1822 break;
1704 } 1823 }
1705 #else 1824 #else
@@ -1752,15 +1871,20 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value) @@ -1752,15 +1871,20 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value)
1752 } 1871 }
1753 #endif 1872 #endif
1754 if (env->sdr1 != value) { 1873 if (env->sdr1 != value) {
  1874 + /* XXX: for PowerPC 64, should check that the HTABSIZE value
  1875 + * is <= 28
  1876 + */
1755 env->sdr1 = value; 1877 env->sdr1 = value;
1756 tlb_flush(env, 1); 1878 tlb_flush(env, 1);
1757 } 1879 }
1758 } 1880 }
1759 1881
  1882 +#if 0 // Unused
1760 target_ulong do_load_sr (CPUPPCState *env, int srnum) 1883 target_ulong do_load_sr (CPUPPCState *env, int srnum)
1761 { 1884 {
1762 return env->sr[srnum]; 1885 return env->sr[srnum];
1763 } 1886 }
  1887 +#endif
1764 1888
1765 void do_store_sr (CPUPPCState *env, int srnum, target_ulong value) 1889 void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
1766 { 1890 {
target-ppc/op.c
@@ -317,6 +317,20 @@ void OPPROTO op_store_sr (void) @@ -317,6 +317,20 @@ void OPPROTO op_store_sr (void)
317 RETURN(); 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 void OPPROTO op_load_sdr1 (void) 334 void OPPROTO op_load_sdr1 (void)
321 { 335 {
322 T0 = env->sdr1; 336 T0 = env->sdr1;
target-ppc/translate.c
@@ -385,107 +385,107 @@ static inline target_ulong MASK (uint32_t start, uint32_t end) @@ -385,107 +385,107 @@ static inline target_ulong MASK (uint32_t start, uint32_t end)
385 /* PowerPC Instructions types definitions */ 385 /* PowerPC Instructions types definitions */
386 enum { 386 enum {
387 PPC_NONE = 0x0000000000000000ULL, 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 PPC_INSNS_BASE = 0x0000000000000001ULL, 389 PPC_INSNS_BASE = 0x0000000000000001ULL,
  390 + /* integer operations instructions */
395 #define PPC_INTEGER PPC_INSNS_BASE 391 #define PPC_INTEGER PPC_INSNS_BASE
  392 + /* flow control instructions */
396 #define PPC_FLOW PPC_INSNS_BASE 393 #define PPC_FLOW PPC_INSNS_BASE
  394 + /* virtual memory instructions */
397 #define PPC_MEM PPC_INSNS_BASE 395 #define PPC_MEM PPC_INSNS_BASE
  396 + /* ld/st with reservation instructions */
398 #define PPC_RES PPC_INSNS_BASE 397 #define PPC_RES PPC_INSNS_BASE
  398 + /* cache control instructions */
399 #define PPC_CACHE PPC_INSNS_BASE 399 #define PPC_CACHE PPC_INSNS_BASE
  400 + /* spr/msr access instructions */
400 #define PPC_MISC PPC_INSNS_BASE 401 #define PPC_MISC PPC_INSNS_BASE
401 - /* Optional floating point instructions */ 402 + /* Optional floating point instructions */
402 PPC_FLOAT = 0x0000000000000002ULL, 403 PPC_FLOAT = 0x0000000000000002ULL,
403 PPC_FLOAT_FSQRT = 0x0000000000000004ULL, 404 PPC_FLOAT_FSQRT = 0x0000000000000004ULL,
404 PPC_FLOAT_FRES = 0x0000000000000008ULL, 405 PPC_FLOAT_FRES = 0x0000000000000008ULL,
405 PPC_FLOAT_FRSQRTE = 0x0000000000000010ULL, 406 PPC_FLOAT_FRSQRTE = 0x0000000000000010ULL,
406 PPC_FLOAT_FSEL = 0x0000000000000020ULL, 407 PPC_FLOAT_FSEL = 0x0000000000000020ULL,
407 PPC_FLOAT_STFIWX = 0x0000000000000040ULL, 408 PPC_FLOAT_STFIWX = 0x0000000000000040ULL,
408 - /* external control instructions */ 409 + /* external control instructions */
409 PPC_EXTERN = 0x0000000000000080ULL, 410 PPC_EXTERN = 0x0000000000000080ULL,
410 - /* segment register access instructions */ 411 + /* segment register access instructions */
411 PPC_SEGMENT = 0x0000000000000100ULL, 412 PPC_SEGMENT = 0x0000000000000100ULL,
412 - /* Optional cache control instruction */ 413 + /* Optional cache control instruction */
413 PPC_CACHE_DCBA = 0x0000000000000200ULL, 414 PPC_CACHE_DCBA = 0x0000000000000200ULL,
414 - /* Optional memory control instructions */ 415 + /* Optional memory control instructions */
415 PPC_MEM_TLBIA = 0x0000000000000400ULL, 416 PPC_MEM_TLBIA = 0x0000000000000400ULL,
416 PPC_MEM_TLBIE = 0x0000000000000800ULL, 417 PPC_MEM_TLBIE = 0x0000000000000800ULL,
417 PPC_MEM_TLBSYNC = 0x0000000000001000ULL, 418 PPC_MEM_TLBSYNC = 0x0000000000001000ULL,
418 - /* eieio & sync */ 419 + /* eieio & sync */
419 PPC_MEM_SYNC = 0x0000000000002000ULL, 420 PPC_MEM_SYNC = 0x0000000000002000ULL,
420 - /* PowerPC 6xx TLB management instructions */ 421 + /* PowerPC 6xx TLB management instructions */
421 PPC_6xx_TLB = 0x0000000000004000ULL, 422 PPC_6xx_TLB = 0x0000000000004000ULL,
422 - /* Altivec support */ 423 + /* Altivec support */
423 PPC_ALTIVEC = 0x0000000000008000ULL, 424 PPC_ALTIVEC = 0x0000000000008000ULL,
424 - /* Time base mftb instruction */ 425 + /* Time base mftb instruction */
425 PPC_MFTB = 0x0000000000010000ULL, 426 PPC_MFTB = 0x0000000000010000ULL,
426 - /* Embedded PowerPC dedicated instructions */ 427 + /* Embedded PowerPC dedicated instructions */
427 PPC_EMB_COMMON = 0x0000000000020000ULL, 428 PPC_EMB_COMMON = 0x0000000000020000ULL,
428 - /* PowerPC 40x exception model */ 429 + /* PowerPC 40x exception model */
429 PPC_40x_EXCP = 0x0000000000040000ULL, 430 PPC_40x_EXCP = 0x0000000000040000ULL,
430 - /* PowerPC 40x TLB management instructions */ 431 + /* PowerPC 40x TLB management instructions */
431 PPC_40x_TLB = 0x0000000000080000ULL, 432 PPC_40x_TLB = 0x0000000000080000ULL,
432 - /* PowerPC 405 Mac instructions */ 433 + /* PowerPC 405 Mac instructions */
433 PPC_405_MAC = 0x0000000000100000ULL, 434 PPC_405_MAC = 0x0000000000100000ULL,
434 - /* PowerPC 440 specific instructions */ 435 + /* PowerPC 440 specific instructions */
435 PPC_440_SPEC = 0x0000000000200000ULL, 436 PPC_440_SPEC = 0x0000000000200000ULL,
436 - /* Power-to-PowerPC bridge (601) */ 437 + /* Power-to-PowerPC bridge (601) */
437 PPC_POWER_BR = 0x0000000000400000ULL, 438 PPC_POWER_BR = 0x0000000000400000ULL,
438 - /* PowerPC 602 specific */ 439 + /* PowerPC 602 specific */
439 PPC_602_SPEC = 0x0000000000800000ULL, 440 PPC_602_SPEC = 0x0000000000800000ULL,
440 - /* Deprecated instructions */  
441 - /* Original POWER instruction set */ 441 + /* Deprecated instructions */
  442 + /* Original POWER instruction set */
442 PPC_POWER = 0x0000000001000000ULL, 443 PPC_POWER = 0x0000000001000000ULL,
443 - /* POWER2 instruction set extension */ 444 + /* POWER2 instruction set extension */
444 PPC_POWER2 = 0x0000000002000000ULL, 445 PPC_POWER2 = 0x0000000002000000ULL,
445 - /* Power RTC support */ 446 + /* Power RTC support */
446 PPC_POWER_RTC = 0x0000000004000000ULL, 447 PPC_POWER_RTC = 0x0000000004000000ULL,
447 - /* 64 bits PowerPC instructions */  
448 - /* 64 bits PowerPC instruction set */ 448 + /* 64 bits PowerPC instruction set */
449 PPC_64B = 0x0000000008000000ULL, 449 PPC_64B = 0x0000000008000000ULL,
450 - /* 64 bits hypervisor extensions */ 450 + /* 64 bits hypervisor extensions */
451 PPC_64H = 0x0000000010000000ULL, 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 PPC_BOOKE = 0x0000000040000000ULL, 455 PPC_BOOKE = 0x0000000040000000ULL,
456 - /* eieio */ 456 + /* eieio */
457 PPC_MEM_EIEIO = 0x0000000080000000ULL, 457 PPC_MEM_EIEIO = 0x0000000080000000ULL,
458 - /* e500 vector instructions */ 458 + /* e500 vector instructions */
459 PPC_E500_VECTOR = 0x0000000100000000ULL, 459 PPC_E500_VECTOR = 0x0000000100000000ULL,
460 - /* PowerPC 4xx dedicated instructions */ 460 + /* PowerPC 4xx dedicated instructions */
461 PPC_4xx_COMMON = 0x0000000200000000ULL, 461 PPC_4xx_COMMON = 0x0000000200000000ULL,
462 - /* PowerPC 2.03 specification extensions */ 462 + /* PowerPC 2.03 specification extensions */
463 PPC_203 = 0x0000000400000000ULL, 463 PPC_203 = 0x0000000400000000ULL,
464 - /* PowerPC 2.03 SPE extension */ 464 + /* PowerPC 2.03 SPE extension */
465 PPC_SPE = 0x0000000800000000ULL, 465 PPC_SPE = 0x0000000800000000ULL,
466 - /* PowerPC 2.03 SPE floating-point extension */ 466 + /* PowerPC 2.03 SPE floating-point extension */
467 PPC_SPEFPU = 0x0000001000000000ULL, 467 PPC_SPEFPU = 0x0000001000000000ULL,
468 - /* SLB management */ 468 + /* SLB management */
469 PPC_SLBI = 0x0000002000000000ULL, 469 PPC_SLBI = 0x0000002000000000ULL,
470 - /* PowerPC 40x ibct instructions */ 470 + /* PowerPC 40x ibct instructions */
471 PPC_40x_ICBT = 0x0000004000000000ULL, 471 PPC_40x_ICBT = 0x0000004000000000ULL,
472 - /* PowerPC 74xx TLB management instructions */ 472 + /* PowerPC 74xx TLB management instructions */
473 PPC_74xx_TLB = 0x0000008000000000ULL, 473 PPC_74xx_TLB = 0x0000008000000000ULL,
474 - /* More BookE (embedded) instructions... */ 474 + /* More BookE (embedded) instructions... */
475 PPC_BOOKE_EXT = 0x0000010000000000ULL, 475 PPC_BOOKE_EXT = 0x0000010000000000ULL,
476 - /* rfmci is not implemented in all BookE PowerPC */ 476 + /* rfmci is not implemented in all BookE PowerPC */
477 PPC_RFMCI = 0x0000020000000000ULL, 477 PPC_RFMCI = 0x0000020000000000ULL,
478 - /* user-mode DCR access, implemented in PowerPC 460 */ 478 + /* user-mode DCR access, implemented in PowerPC 460 */
479 PPC_DCRUX = 0x0000040000000000ULL, 479 PPC_DCRUX = 0x0000040000000000ULL,
480 - /* New floating-point extensions (PowerPC 2.0x) */ 480 + /* New floating-point extensions (PowerPC 2.0x) */
481 PPC_FLOAT_EXT = 0x0000080000000000ULL, 481 PPC_FLOAT_EXT = 0x0000080000000000ULL,
482 - /* New wait instruction (PowerPC 2.0x) */ 482 + /* New wait instruction (PowerPC 2.0x) */
483 PPC_WAIT = 0x0000100000000000ULL, 483 PPC_WAIT = 0x0000100000000000ULL,
484 - /* New 64 bits extensions (PowerPC 2.0x) */ 484 + /* New 64 bits extensions (PowerPC 2.0x) */
485 PPC_64BX = 0x0000200000000000ULL, 485 PPC_64BX = 0x0000200000000000ULL,
486 - /* dcbz instruction with fixed cache line size */ 486 + /* dcbz instruction with fixed cache line size */
487 PPC_CACHE_DCBZ = 0x0000400000000000ULL, 487 PPC_CACHE_DCBZ = 0x0000400000000000ULL,
488 - /* dcbz instruction with tunable cache line size */ 488 + /* dcbz instruction with tunable cache line size */
489 PPC_CACHE_DCBZT = 0x0000800000000000ULL, 489 PPC_CACHE_DCBZT = 0x0000800000000000ULL,
490 }; 490 };
491 491
@@ -3931,6 +3931,75 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) @@ -3931,6 +3931,75 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3931 #endif 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 /*** Lookaside buffer management ***/ 4003 /*** Lookaside buffer management ***/
3935 /* Optional & supervisor only: */ 4004 /* Optional & supervisor only: */
3936 /* tlbia */ 4005 /* tlbia */
target-ppc/translate_init.c
@@ -3095,12 +3095,13 @@ static void init_proc_e500 (CPUPPCState *env) @@ -3095,12 +3095,13 @@ static void init_proc_e500 (CPUPPCState *env)
3095 /* Non-embedded PowerPC */ 3095 /* Non-embedded PowerPC */
3096 /* Base instructions set for all 6xx/7xx/74xx/970 PowerPC */ 3096 /* Base instructions set for all 6xx/7xx/74xx/970 PowerPC */
3097 #define POWERPC_INSNS_6xx (PPC_INSNS_BASE | PPC_FLOAT | PPC_MEM_SYNC | \ 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 /* Instructions common to all 6xx/7xx/74xx/970 PowerPC except 601 & 602 */ 3099 /* Instructions common to all 6xx/7xx/74xx/970 PowerPC except 601 & 602 */
3100 #define POWERPC_INSNS_WORKS (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT | \ 3100 #define POWERPC_INSNS_WORKS (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT | \
3101 PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | \ 3101 PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | \
3102 PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX | \ 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 /* POWER : same as 601, without mfmsr, mfsr */ 3106 /* POWER : same as 601, without mfmsr, mfsr */
3106 #if defined(TODO) 3107 #if defined(TODO)
@@ -3111,7 +3112,7 @@ static void init_proc_e500 (CPUPPCState *env) @@ -3111,7 +3112,7 @@ static void init_proc_e500 (CPUPPCState *env)
3111 3112
3112 /* PowerPC 601 */ 3113 /* PowerPC 601 */
3113 #define POWERPC_INSNS_601 (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ | \ 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 #define POWERPC_MSRM_601 (0x000000000000FE70ULL) 3116 #define POWERPC_MSRM_601 (0x000000000000FE70ULL)
3116 //#define POWERPC_MMU_601 (POWERPC_MMU_601) 3117 //#define POWERPC_MMU_601 (POWERPC_MMU_601)
3117 //#define POWERPC_EXCP_601 (POWERPC_EXCP_601) 3118 //#define POWERPC_EXCP_601 (POWERPC_EXCP_601)
@@ -3164,7 +3165,7 @@ static void init_proc_601 (CPUPPCState *env) @@ -3164,7 +3165,7 @@ static void init_proc_601 (CPUPPCState *env)
3164 PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | \ 3165 PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | \
3165 PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX | \ 3166 PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX | \
3166 PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ |\ 3167 PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ |\
3167 - PPC_602_SPEC) 3168 + PPC_SEGMENT | PPC_602_SPEC)
3168 #define POWERPC_MSRM_602 (0x000000000033FF73ULL) 3169 #define POWERPC_MSRM_602 (0x000000000033FF73ULL)
3169 #define POWERPC_MMU_602 (POWERPC_MMU_SOFT_6xx) 3170 #define POWERPC_MMU_602 (POWERPC_MMU_SOFT_6xx)
3170 //#define POWERPC_EXCP_602 (POWERPC_EXCP_602) 3171 //#define POWERPC_EXCP_602 (POWERPC_EXCP_602)
@@ -3942,15 +3943,15 @@ static void init_proc_7455 (CPUPPCState *env) @@ -3942,15 +3943,15 @@ static void init_proc_7455 (CPUPPCState *env)
3942 3943
3943 #if defined (TARGET_PPC64) 3944 #if defined (TARGET_PPC64)
3944 #define POWERPC_INSNS_WORK64 (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT | \ 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 /* PowerPC 970 */ 3949 /* PowerPC 970 */
3949 #define POWERPC_INSNS_970 (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \ 3950 #define POWERPC_INSNS_970 (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \
3950 PPC_64B | PPC_ALTIVEC | \ 3951 PPC_64B | PPC_ALTIVEC | \
3951 - PPC_64_BRIDGE | PPC_SLBI) 3952 + PPC_SEGMENT_64B | PPC_SLBI)
3952 #define POWERPC_MSRM_970 (0x900000000204FF36ULL) 3953 #define POWERPC_MSRM_970 (0x900000000204FF36ULL)
3953 -#define POWERPC_MMU_970 (POWERPC_MMU_64BRIDGE) 3954 +#define POWERPC_MMU_970 (POWERPC_MMU_64B)
3954 //#define POWERPC_EXCP_970 (POWERPC_EXCP_970) 3955 //#define POWERPC_EXCP_970 (POWERPC_EXCP_970)
3955 #define POWERPC_INPUT_970 (PPC_FLAGS_INPUT_970) 3956 #define POWERPC_INPUT_970 (PPC_FLAGS_INPUT_970)
3956 #define POWERPC_BFDM_970 (bfd_mach_ppc64) 3957 #define POWERPC_BFDM_970 (bfd_mach_ppc64)
@@ -3990,9 +3991,24 @@ static void init_proc_970 (CPUPPCState *env) @@ -3990,9 +3991,24 @@ static void init_proc_970 (CPUPPCState *env)
3990 /* Memory management */ 3991 /* Memory management */
3991 /* XXX: not correct */ 3992 /* XXX: not correct */
3992 gen_low_BATs(env); 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 #endif 4010 #endif
  4011 + env->slb_nr = 32;
3996 init_excp_970(env); 4012 init_excp_970(env);
3997 env->dcache_line_size = 128; 4013 env->dcache_line_size = 128;
3998 env->icache_line_size = 128; 4014 env->icache_line_size = 128;
@@ -4003,9 +4019,9 @@ static void init_proc_970 (CPUPPCState *env) @@ -4003,9 +4019,9 @@ static void init_proc_970 (CPUPPCState *env)
4003 /* PowerPC 970FX (aka G5) */ 4019 /* PowerPC 970FX (aka G5) */
4004 #define POWERPC_INSNS_970FX (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \ 4020 #define POWERPC_INSNS_970FX (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \
4005 PPC_64B | PPC_ALTIVEC | \ 4021 PPC_64B | PPC_ALTIVEC | \
4006 - PPC_64_BRIDGE | PPC_SLBI) 4022 + PPC_SEGMENT_64B | PPC_SLBI)
4007 #define POWERPC_MSRM_970FX (0x800000000204FF36ULL) 4023 #define POWERPC_MSRM_970FX (0x800000000204FF36ULL)
4008 -#define POWERPC_MMU_970FX (POWERPC_MMU_64BRIDGE) 4024 +#define POWERPC_MMU_970FX (POWERPC_MMU_64B)
4009 #define POWERPC_EXCP_970FX (POWERPC_EXCP_970) 4025 #define POWERPC_EXCP_970FX (POWERPC_EXCP_970)
4010 #define POWERPC_INPUT_970FX (PPC_FLAGS_INPUT_970) 4026 #define POWERPC_INPUT_970FX (PPC_FLAGS_INPUT_970)
4011 #define POWERPC_BFDM_970FX (bfd_mach_ppc64) 4027 #define POWERPC_BFDM_970FX (bfd_mach_ppc64)
@@ -4045,9 +4061,24 @@ static void init_proc_970FX (CPUPPCState *env) @@ -4045,9 +4061,24 @@ static void init_proc_970FX (CPUPPCState *env)
4045 /* Memory management */ 4061 /* Memory management */
4046 /* XXX: not correct */ 4062 /* XXX: not correct */
4047 gen_low_BATs(env); 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 #endif 4080 #endif
  4081 + env->slb_nr = 32;
4051 init_excp_970(env); 4082 init_excp_970(env);
4052 env->dcache_line_size = 128; 4083 env->dcache_line_size = 128;
4053 env->icache_line_size = 128; 4084 env->icache_line_size = 128;
@@ -4058,9 +4089,9 @@ static void init_proc_970FX (CPUPPCState *env) @@ -4058,9 +4089,9 @@ static void init_proc_970FX (CPUPPCState *env)
4058 /* PowerPC 970 GX */ 4089 /* PowerPC 970 GX */
4059 #define POWERPC_INSNS_970GX (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \ 4090 #define POWERPC_INSNS_970GX (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \
4060 PPC_64B | PPC_ALTIVEC | \ 4091 PPC_64B | PPC_ALTIVEC | \
4061 - PPC_64_BRIDGE | PPC_SLBI) 4092 + PPC_SEGMENT_64B | PPC_SLBI)
4062 #define POWERPC_MSRM_970GX (0x800000000204FF36ULL) 4093 #define POWERPC_MSRM_970GX (0x800000000204FF36ULL)
4063 -#define POWERPC_MMU_970GX (POWERPC_MMU_64BRIDGE) 4094 +#define POWERPC_MMU_970GX (POWERPC_MMU_64B)
4064 #define POWERPC_EXCP_970GX (POWERPC_EXCP_970) 4095 #define POWERPC_EXCP_970GX (POWERPC_EXCP_970)
4065 #define POWERPC_INPUT_970GX (PPC_FLAGS_INPUT_970) 4096 #define POWERPC_INPUT_970GX (PPC_FLAGS_INPUT_970)
4066 #define POWERPC_BFDM_970GX (bfd_mach_ppc64) 4097 #define POWERPC_BFDM_970GX (bfd_mach_ppc64)
@@ -4100,9 +4131,24 @@ static void init_proc_970GX (CPUPPCState *env) @@ -4100,9 +4131,24 @@ static void init_proc_970GX (CPUPPCState *env)
4100 /* Memory management */ 4131 /* Memory management */
4101 /* XXX: not correct */ 4132 /* XXX: not correct */
4102 gen_low_BATs(env); 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 #endif 4150 #endif
  4151 + env->slb_nr = 32;
4106 init_excp_970(env); 4152 init_excp_970(env);
4107 env->dcache_line_size = 128; 4153 env->dcache_line_size = 128;
4108 env->icache_line_size = 128; 4154 env->icache_line_size = 128;
@@ -6010,9 +6056,6 @@ int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def) @@ -6010,9 +6056,6 @@ int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def)
6010 case POWERPC_MMU_64B: 6056 case POWERPC_MMU_64B:
6011 mmu_model = "PowerPC 64"; 6057 mmu_model = "PowerPC 64";
6012 break; 6058 break;
6013 - case POWERPC_MMU_64BRIDGE:  
6014 - mmu_model = "PowerPC 64 bridge";  
6015 - break;  
6016 #endif 6059 #endif
6017 default: 6060 default:
6018 mmu_model = "Unknown or invalid"; 6061 mmu_model = "Unknown or invalid";