1 #ifndef MMU_HASH32_H 2 #define MMU_HASH32_H 3 4 #ifndef CONFIG_USER_ONLY 5 6 bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type, 7 hwaddr *raddrp, int *psizep, int *protp, int mmu_idx, 8 bool guest_visible); 9 10 /* 11 * Segment register definitions 12 */ 13 14 #define SR32_T 0x80000000 15 #define SR32_KS 0x40000000 16 #define SR32_KP 0x20000000 17 #define SR32_NX 0x10000000 18 #define SR32_VSID 0x00ffffff 19 20 /* 21 * Block Address Translation (BAT) definitions 22 */ 23 24 #define BATU32_BEPIU 0xf0000000 25 #define BATU32_BEPIL 0x0ffe0000 26 #define BATU32_BEPI 0xfffe0000 27 #define BATU32_BL 0x00001ffc 28 #define BATU32_VS 0x00000002 29 #define BATU32_VP 0x00000001 30 31 32 #define BATL32_BRPN 0xfffe0000 33 #define BATL32_WIMG 0x00000078 34 #define BATL32_PP 0x00000003 35 36 /* 37 * Hash page table definitions 38 */ 39 #define SDR_32_HTABORG 0xFFFF0000UL 40 #define SDR_32_HTABMASK 0x000001FFUL 41 42 #define HPTES_PER_GROUP 8 43 #define HASH_PTE_SIZE_32 8 44 #define HASH_PTEG_SIZE_32 (HASH_PTE_SIZE_32 * HPTES_PER_GROUP) 45 46 #define HPTE32_V_VALID 0x80000000 47 #define HPTE32_V_VSID 0x7fffff80 48 #define HPTE32_V_SECONDARY 0x00000040 49 #define HPTE32_V_API 0x0000003f 50 #define HPTE32_V_COMPARE(x, y) (!(((x) ^ (y)) & 0x7fffffbf)) 51 52 #define HPTE32_R_RPN 0xfffff000 53 #define HPTE32_R_R 0x00000100 54 #define HPTE32_R_C 0x00000080 55 #define HPTE32_R_W 0x00000040 56 #define HPTE32_R_I 0x00000020 57 #define HPTE32_R_M 0x00000010 58 #define HPTE32_R_G 0x00000008 59 #define HPTE32_R_WIMG 0x00000078 60 #define HPTE32_R_PP 0x00000003 61 62 static inline hwaddr ppc_hash32_hpt_base(PowerPCCPU *cpu) 63 { 64 return cpu->env.spr[SPR_SDR1] & SDR_32_HTABORG; 65 } 66 67 static inline hwaddr ppc_hash32_hpt_mask(PowerPCCPU *cpu) 68 { 69 return ((cpu->env.spr[SPR_SDR1] & SDR_32_HTABMASK) << 16) | 0xFFFF; 70 } 71 72 static inline target_ulong ppc_hash32_load_hpte0(PowerPCCPU *cpu, 73 hwaddr pte_offset) 74 { 75 target_ulong base = ppc_hash32_hpt_base(cpu); 76 77 return ldl_phys(CPU(cpu)->as, base + pte_offset); 78 } 79 80 static inline target_ulong ppc_hash32_load_hpte1(PowerPCCPU *cpu, 81 hwaddr pte_offset) 82 { 83 target_ulong base = ppc_hash32_hpt_base(cpu); 84 85 return ldl_phys(CPU(cpu)->as, base + pte_offset + HASH_PTE_SIZE_32 / 2); 86 } 87 88 static inline void ppc_hash32_store_hpte0(PowerPCCPU *cpu, 89 hwaddr pte_offset, target_ulong pte0) 90 { 91 target_ulong base = ppc_hash32_hpt_base(cpu); 92 93 stl_phys(CPU(cpu)->as, base + pte_offset, pte0); 94 } 95 96 static inline void ppc_hash32_store_hpte1(PowerPCCPU *cpu, 97 hwaddr pte_offset, target_ulong pte1) 98 { 99 target_ulong base = ppc_hash32_hpt_base(cpu); 100 101 stl_phys(CPU(cpu)->as, base + pte_offset + HASH_PTE_SIZE_32 / 2, pte1); 102 } 103 104 static inline hwaddr get_pteg_offset32(PowerPCCPU *cpu, hwaddr hash) 105 { 106 return (hash * HASH_PTEG_SIZE_32) & ppc_hash32_hpt_mask(cpu); 107 } 108 109 static inline bool ppc_hash32_key(bool pr, target_ulong sr) 110 { 111 return pr ? (sr & SR32_KP) : (sr & SR32_KS); 112 } 113 114 static inline int ppc_hash32_prot(bool key, int pp, bool nx) 115 { 116 int prot; 117 118 if (key) { 119 switch (pp) { 120 case 0x0: 121 prot = 0; 122 break; 123 case 0x1: 124 case 0x3: 125 prot = PAGE_READ; 126 break; 127 case 0x2: 128 prot = PAGE_READ | PAGE_WRITE; 129 break; 130 default: 131 g_assert_not_reached(); 132 } 133 } else { 134 switch (pp) { 135 case 0x0: 136 case 0x1: 137 case 0x2: 138 prot = PAGE_READ | PAGE_WRITE; 139 break; 140 case 0x3: 141 prot = PAGE_READ; 142 break; 143 default: 144 g_assert_not_reached(); 145 } 146 } 147 return nx ? prot : prot | PAGE_EXEC; 148 } 149 150 static inline int ppc_hash32_bat_prot(target_ulong batu, target_ulong batl) 151 { 152 int prot = 0; 153 int pp = batl & BATL32_PP; 154 155 if (pp) { 156 prot = PAGE_READ | PAGE_EXEC; 157 if (pp == 0x2) { 158 prot |= PAGE_WRITE; 159 } 160 } 161 return prot; 162 } 163 164 typedef struct { 165 uint32_t pte0, pte1; 166 } ppc_hash_pte32_t; 167 168 #endif /* CONFIG_USER_ONLY */ 169 170 #endif /* MMU_HASH32_H */ 171