Commit 12de9a396acbc95e25c5d60ed097cc55777eaaed
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
Showing
5 changed files
with
373 additions
and
119 deletions
target-ppc/cpu.h
... | ... | @@ -105,10 +105,8 @@ enum { |
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,6 +512,8 @@ struct CPUPPCState { |
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,10 +606,14 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value); |
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); | ... | ... |
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 | 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,24 +591,15 @@ static int find_pte64 (mmu_ctx_t *ctx, int h, int rw) |
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,14 +611,23 @@ static int slb_lookup (CPUState *env, target_ulong eaddr, |
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,7 +646,6 @@ static int slb_lookup (CPUState *env, target_ulong eaddr, |
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,13 +658,80 @@ static int slb_lookup (CPUState *env, target_ulong eaddr, |
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,8 +740,12 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, |
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,29 +779,53 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, |
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,6 +866,27 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, |
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,7 +1228,6 @@ static int check_physical (CPUState *env, mmu_ctx_t *ctx, |
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,7 +1294,6 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, |
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,7 +1398,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
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,7 +1493,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
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,13 +1743,12 @@ void ppc_tlb_invalidate_all (CPUPPCState *env) |
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,7 +1808,6 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) |
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,7 +1818,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) |
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,15 +1871,20 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value) |
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 | { | ... | ... |
target-ppc/op.c
... | ... | @@ -317,6 +317,20 @@ void OPPROTO op_store_sr (void) |
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; | ... | ... |
target-ppc/translate.c
... | ... | @@ -385,107 +385,107 @@ static inline target_ulong MASK (uint32_t start, uint32_t end) |
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,6 +3931,75 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) |
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 */ | ... | ... |
target-ppc/translate_init.c
... | ... | @@ -3095,12 +3095,13 @@ static void init_proc_e500 (CPUPPCState *env) |
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,7 +3112,7 @@ static void init_proc_e500 (CPUPPCState *env) |
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,7 +3165,7 @@ static void init_proc_601 (CPUPPCState *env) |
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,15 +3943,15 @@ static void init_proc_7455 (CPUPPCState *env) |
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,9 +3991,24 @@ static void init_proc_970 (CPUPPCState *env) |
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,9 +4019,9 @@ static void init_proc_970 (CPUPPCState *env) |
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,9 +4061,24 @@ static void init_proc_970FX (CPUPPCState *env) |
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,9 +4089,9 @@ static void init_proc_970FX (CPUPPCState *env) |
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,9 +4131,24 @@ static void init_proc_970GX (CPUPPCState *env) |
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,9 +6056,6 @@ int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def) |
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"; | ... | ... |