Commit add78955b0451c6d14d325d66592a634b2e5d595

Authored by j_mayer
1 parent 5b8105fa

PowerPC 620 MMU do not have the same exact behavior as standard

64 bits PowerPC ones.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3706 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/cpu.h
... ... @@ -93,30 +93,33 @@ typedef uint32_t ppc_gpr_t;
93 93 /* MMU model */
94 94 typedef enum powerpc_mmu_t powerpc_mmu_t;
95 95 enum powerpc_mmu_t {
96   - POWERPC_MMU_UNKNOWN = 0,
  96 + POWERPC_MMU_UNKNOWN = 0x00000000,
97 97 /* Standard 32 bits PowerPC MMU */
98   - POWERPC_MMU_32B,
  98 + POWERPC_MMU_32B = 0x00000001,
99 99 /* PowerPC 6xx MMU with software TLB */
100   - POWERPC_MMU_SOFT_6xx,
  100 + POWERPC_MMU_SOFT_6xx = 0x00000002,
101 101 /* PowerPC 74xx MMU with software TLB */
102   - POWERPC_MMU_SOFT_74xx,
  102 + POWERPC_MMU_SOFT_74xx = 0x00000003,
103 103 /* PowerPC 4xx MMU with software TLB */
104   - POWERPC_MMU_SOFT_4xx,
  104 + POWERPC_MMU_SOFT_4xx = 0x00000004,
105 105 /* PowerPC 4xx MMU with software TLB and zones protections */
106   - POWERPC_MMU_SOFT_4xx_Z,
  106 + POWERPC_MMU_SOFT_4xx_Z = 0x00000005,
107 107 /* PowerPC MMU in real mode only */
108   - POWERPC_MMU_REAL,
  108 + POWERPC_MMU_REAL = 0x00000006,
109 109 /* Freescale MPC8xx MMU model */
110   - POWERPC_MMU_MPC8xx,
  110 + POWERPC_MMU_MPC8xx = 0x00000007,
111 111 /* BookE MMU model */
112   - POWERPC_MMU_BOOKE,
  112 + POWERPC_MMU_BOOKE = 0x00000008,
113 113 /* BookE FSL MMU model */
114   - POWERPC_MMU_BOOKE_FSL,
  114 + POWERPC_MMU_BOOKE_FSL = 0x00000009,
115 115 /* PowerPC 601 MMU model (specific BATs format) */
116   - POWERPC_MMU_601,
  116 + POWERPC_MMU_601 = 0x0000000A,
117 117 #if defined(TARGET_PPC64)
  118 +#define POWERPC_MMU_64 0x00010000
118 119 /* 64 bits PowerPC MMU */
119   - POWERPC_MMU_64B,
  120 + POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001,
  121 + /* 620 variant (no segment exceptions) */
  122 + POWERPC_MMU_620 = POWERPC_MMU_64 | 0x00000002,
120 123 #endif /* defined(TARGET_PPC64) */
121 124 };
122 125  
... ...
target-ppc/helper.c
... ... @@ -706,7 +706,7 @@ static always_inline int find_pte (CPUState *env, mmu_ctx_t *ctx,
706 706 int h, int rw, int type)
707 707 {
708 708 #if defined(TARGET_PPC64)
709   - if (env->mmu_model == POWERPC_MMU_64B)
  709 + if (env->mmu_model & POWERPC_MMU_64)
710 710 return find_pte64(ctx, h, rw, type);
711 711 #endif
712 712  
... ... @@ -916,7 +916,7 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
916 916  
917 917 pr = msr_pr;
918 918 #if defined(TARGET_PPC64)
919   - if (env->mmu_model == POWERPC_MMU_64B) {
  919 + if (env->mmu_model & POWERPC_MMU_64) {
920 920 #if defined (DEBUG_MMU)
921 921 if (loglevel != 0) {
922 922 fprintf(logfile, "Check SLBs\n");
... ... @@ -973,7 +973,7 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
973 973 sdr = env->sdr1;
974 974 pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS;
975 975 #if defined(TARGET_PPC64)
976   - if (env->mmu_model == POWERPC_MMU_64B) {
  976 + if (env->mmu_model & POWERPC_MMU_64) {
977 977 htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
978 978 /* XXX: this is false for 1 TB segments */
979 979 hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
... ... @@ -1002,7 +1002,7 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
1002 1002 #endif
1003 1003 ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
1004 1004 #if defined(TARGET_PPC64)
1005   - if (env->mmu_model == POWERPC_MMU_64B) {
  1005 + if (env->mmu_model & POWERPC_MMU_64) {
1006 1006 /* Only 5 bits of the page index are used in the AVPN */
1007 1007 ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
1008 1008 } else
... ... @@ -1362,6 +1362,7 @@ static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
1362 1362 ctx->prot |= PAGE_WRITE;
1363 1363 break;
1364 1364 #if defined(TARGET_PPC64)
  1365 + case POWERPC_MMU_620:
1365 1366 case POWERPC_MMU_64B:
1366 1367 /* Real address are 60 bits long */
1367 1368 ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
... ... @@ -1430,6 +1431,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1430 1431 case POWERPC_MMU_SOFT_6xx:
1431 1432 case POWERPC_MMU_SOFT_74xx:
1432 1433 #if defined(TARGET_PPC64)
  1434 + case POWERPC_MMU_620:
1433 1435 case POWERPC_MMU_64B:
1434 1436 #endif
1435 1437 /* Try to find a BAT */
... ... @@ -1538,6 +1540,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1538 1540 case POWERPC_MMU_32B:
1539 1541 case POWERPC_MMU_601:
1540 1542 #if defined(TARGET_PPC64)
  1543 + case POWERPC_MMU_620:
1541 1544 case POWERPC_MMU_64B:
1542 1545 #endif
1543 1546 env->exception_index = POWERPC_EXCP_ISI;
... ... @@ -1583,8 +1586,14 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1583 1586 #if defined(TARGET_PPC64)
1584 1587 case -5:
1585 1588 /* No match in segment table */
1586   - env->exception_index = POWERPC_EXCP_ISEG;
1587   - env->error_code = 0;
  1589 + if (env->mmu_model == POWERPC_MMU_620) {
  1590 + env->exception_index = POWERPC_EXCP_ISI;
  1591 + /* XXX: this might be incorrect */
  1592 + env->error_code = 0x40000000;
  1593 + } else {
  1594 + env->exception_index = POWERPC_EXCP_ISEG;
  1595 + env->error_code = 0;
  1596 + }
1588 1597 break;
1589 1598 #endif
1590 1599 }
... ... @@ -1634,6 +1643,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1634 1643 case POWERPC_MMU_32B:
1635 1644 case POWERPC_MMU_601:
1636 1645 #if defined(TARGET_PPC64)
  1646 + case POWERPC_MMU_620:
1637 1647 case POWERPC_MMU_64B:
1638 1648 #endif
1639 1649 env->exception_index = POWERPC_EXCP_DSI;
... ... @@ -1716,9 +1726,20 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1716 1726 #if defined(TARGET_PPC64)
1717 1727 case -5:
1718 1728 /* No match in segment table */
1719   - env->exception_index = POWERPC_EXCP_DSEG;
1720   - env->error_code = 0;
1721   - env->spr[SPR_DAR] = address;
  1729 + if (env->mmu_model == POWERPC_MMU_620) {
  1730 + env->exception_index = POWERPC_EXCP_DSI;
  1731 + env->error_code = 0;
  1732 + env->spr[SPR_DAR] = address;
  1733 + /* XXX: this might be incorrect */
  1734 + if (rw == 1)
  1735 + env->spr[SPR_DSISR] = 0x42000000;
  1736 + else
  1737 + env->spr[SPR_DSISR] = 0x40000000;
  1738 + } else {
  1739 + env->exception_index = POWERPC_EXCP_DSEG;
  1740 + env->error_code = 0;
  1741 + env->spr[SPR_DAR] = address;
  1742 + }
1722 1743 break;
1723 1744 #endif
1724 1745 }
... ... @@ -1955,6 +1976,7 @@ void ppc_tlb_invalidate_all (CPUPPCState *env)
1955 1976 case POWERPC_MMU_32B:
1956 1977 case POWERPC_MMU_601:
1957 1978 #if defined(TARGET_PPC64)
  1979 + case POWERPC_MMU_620:
1958 1980 case POWERPC_MMU_64B:
1959 1981 #endif /* defined(TARGET_PPC64) */
1960 1982 tlb_flush(env, 1);
... ... @@ -2021,6 +2043,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
2021 2043 tlb_flush_page(env, addr | (0xF << 28));
2022 2044 break;
2023 2045 #if defined(TARGET_PPC64)
  2046 + case POWERPC_MMU_620:
2024 2047 case POWERPC_MMU_64B:
2025 2048 /* tlbie invalidate TLBs for all segments */
2026 2049 /* XXX: given the fact that there are too many segments to invalidate,
... ...
target-ppc/translate_init.c
... ... @@ -5237,13 +5237,13 @@ static void init_proc_970MP (CPUPPCState *env)
5237 5237 /* PowerPC 620 */
5238 5238 #define POWERPC_INSNS_620 (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT | \
5239 5239 PPC_64B | PPC_SLBI)
5240   -#define POWERPC_MSRM_620 (0x800000000005FF73ULL)
5241   -#define POWERPC_MMU_620 (POWERPC_MMU_64B)
  5240 +#define POWERPC_MSRM_620 (0x800000000005FF77ULL)
  5241 +//#define POWERPC_MMU_620 (POWERPC_MMU_620)
5242 5242 #define POWERPC_EXCP_620 (POWERPC_EXCP_970)
5243 5243 #define POWERPC_INPUT_620 (PPC_FLAGS_INPUT_6xx)
5244 5244 #define POWERPC_BFDM_620 (bfd_mach_ppc64)
5245 5245 #define POWERPC_FLAG_620 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
5246   - POWERPC_FLAG_BUS_CLK)
  5246 + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
5247 5247 #define check_pow_620 check_pow_nocheck /* Check this */
5248 5248  
5249 5249 __attribute__ (( unused ))
... ... @@ -8313,6 +8313,9 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
8313 8313 case POWERPC_MMU_64B:
8314 8314 mmu_model = "PowerPC 64";
8315 8315 break;
  8316 + case POWERPC_MMU_620:
  8317 + mmu_model = "PowerPC 620";
  8318 + break;
8316 8319 #endif
8317 8320 default:
8318 8321 mmu_model = "Unknown or invalid";
... ...