1 /* 2 * PowerPC MMU, TLB and BAT emulation helpers for QEMU. 3 * 4 * Copyright (c) 2003-2007 Jocelyn Mayer 5 * Copyright (c) 2013 David Gibson, IBM Corporation 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "cpu.h" 23 #include "exec/exec-all.h" 24 #include "exec/page-protection.h" 25 #include "exec/target_page.h" 26 #include "system/kvm.h" 27 #include "kvm_ppc.h" 28 #include "internal.h" 29 #include "mmu-hash32.h" 30 #include "mmu-books.h" 31 #include "exec/log.h" 32 33 /* #define DEBUG_BATS */ 34 35 #ifdef DEBUG_BATS 36 # define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__) 37 #else 38 # define LOG_BATS(...) do { } while (0) 39 #endif 40 41 static target_ulong hash32_bat_size(int mmu_idx, 42 target_ulong batu, target_ulong batl) 43 { 44 if ((mmuidx_pr(mmu_idx) && !(batu & BATU32_VP)) 45 || (!mmuidx_pr(mmu_idx) && !(batu & BATU32_VS))) { 46 return 0; 47 } 48 49 return BATU32_BEPI & ~((batu & BATU32_BL) << 15); 50 } 51 52 static hwaddr ppc_hash32_bat_lookup(PowerPCCPU *cpu, target_ulong ea, 53 MMUAccessType access_type, int *prot, 54 int mmu_idx) 55 { 56 CPUPPCState *env = &cpu->env; 57 target_ulong *BATlt, *BATut; 58 bool ifetch = access_type == MMU_INST_FETCH; 59 int i; 60 61 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__, 62 ifetch ? 'I' : 'D', ea); 63 if (ifetch) { 64 BATlt = env->IBAT[1]; 65 BATut = env->IBAT[0]; 66 } else { 67 BATlt = env->DBAT[1]; 68 BATut = env->DBAT[0]; 69 } 70 for (i = 0; i < env->nb_BATs; i++) { 71 target_ulong batu = BATut[i]; 72 target_ulong batl = BATlt[i]; 73 target_ulong mask; 74 75 mask = hash32_bat_size(mmu_idx, batu, batl); 76 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx 77 " BATl " TARGET_FMT_lx "\n", __func__, 78 ifetch ? 'I' : 'D', i, ea, batu, batl); 79 80 if (mask && ((ea & mask) == (batu & BATU32_BEPI))) { 81 hwaddr raddr = (batl & mask) | (ea & ~mask); 82 83 *prot = ppc_hash32_bat_prot(batu, batl); 84 85 return raddr & TARGET_PAGE_MASK; 86 } 87 } 88 89 /* No hit */ 90 #if defined(DEBUG_BATS) 91 if (qemu_log_enabled()) { 92 target_ulong *BATu, *BATl; 93 target_ulong BEPIl, BEPIu, bl; 94 95 LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", ea); 96 for (i = 0; i < 4; i++) { 97 BATu = &BATut[i]; 98 BATl = &BATlt[i]; 99 BEPIu = *BATu & BATU32_BEPIU; 100 BEPIl = *BATu & BATU32_BEPIL; 101 bl = (*BATu & 0x00001FFC) << 15; 102 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx 103 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " " 104 TARGET_FMT_lx " " TARGET_FMT_lx "\n", 105 __func__, ifetch ? 'I' : 'D', i, ea, 106 *BATu, *BATl, BEPIu, BEPIl, bl); 107 } 108 } 109 #endif 110 111 return -1; 112 } 113 114 static bool ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr, 115 target_ulong eaddr, 116 MMUAccessType access_type, 117 hwaddr *raddr, int *prot, int mmu_idx, 118 bool guest_visible) 119 { 120 CPUState *cs = CPU(cpu); 121 CPUPPCState *env = &cpu->env; 122 123 qemu_log_mask(CPU_LOG_MMU, "direct store...\n"); 124 125 if (access_type == MMU_INST_FETCH) { 126 /* No code fetch is allowed in direct-store areas */ 127 if (guest_visible) { 128 cs->exception_index = POWERPC_EXCP_ISI; 129 env->error_code = 0x10000000; 130 } 131 return false; 132 } 133 134 /* 135 * From ppc_cpu_get_phys_page_debug, env->access_type is not set. 136 * Assume ACCESS_INT for that case. 137 */ 138 switch (guest_visible ? env->access_type : ACCESS_INT) { 139 case ACCESS_INT: 140 /* Integer load/store : only access allowed */ 141 break; 142 case ACCESS_FLOAT: 143 /* Floating point load/store */ 144 cs->exception_index = POWERPC_EXCP_ALIGN; 145 env->error_code = POWERPC_EXCP_ALIGN_FP; 146 env->spr[SPR_DAR] = eaddr; 147 return false; 148 case ACCESS_RES: 149 /* lwarx, ldarx or srwcx. */ 150 env->error_code = 0; 151 env->spr[SPR_DAR] = eaddr; 152 if (access_type == MMU_DATA_STORE) { 153 env->spr[SPR_DSISR] = 0x06000000; 154 } else { 155 env->spr[SPR_DSISR] = 0x04000000; 156 } 157 return false; 158 case ACCESS_CACHE: 159 /* 160 * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi 161 * 162 * Should make the instruction do no-op. As it already do 163 * no-op, it's quite easy :-) 164 */ 165 *raddr = eaddr; 166 return true; 167 case ACCESS_EXT: 168 /* eciwx or ecowx */ 169 cs->exception_index = POWERPC_EXCP_DSI; 170 env->error_code = 0; 171 env->spr[SPR_DAR] = eaddr; 172 if (access_type == MMU_DATA_STORE) { 173 env->spr[SPR_DSISR] = 0x06100000; 174 } else { 175 env->spr[SPR_DSISR] = 0x04100000; 176 } 177 return false; 178 default: 179 cpu_abort(cs, "ERROR: insn should not need address translation\n"); 180 } 181 182 if (ppc_hash32_key(mmuidx_pr(mmu_idx), sr)) { 183 *prot = PAGE_READ | PAGE_WRITE; 184 } else { 185 *prot = PAGE_READ; 186 } 187 if (check_prot_access_type(*prot, access_type)) { 188 *raddr = eaddr; 189 return true; 190 } 191 192 if (guest_visible) { 193 cs->exception_index = POWERPC_EXCP_DSI; 194 env->error_code = 0; 195 env->spr[SPR_DAR] = eaddr; 196 if (access_type == MMU_DATA_STORE) { 197 env->spr[SPR_DSISR] = 0x0a000000; 198 } else { 199 env->spr[SPR_DSISR] = 0x08000000; 200 } 201 } 202 return false; 203 } 204 205 static hwaddr ppc_hash32_pteg_search(PowerPCCPU *cpu, hwaddr pteg_off, 206 bool secondary, target_ulong ptem, 207 ppc_hash_pte32_t *pte) 208 { 209 hwaddr pte_offset = pteg_off; 210 target_ulong pte0, pte1; 211 int i; 212 213 for (i = 0; i < HPTES_PER_GROUP; i++) { 214 pte0 = ppc_hash32_load_hpte0(cpu, pte_offset); 215 /* 216 * pte0 contains the valid bit and must be read before pte1, 217 * otherwise we might see an old pte1 with a new valid bit and 218 * thus an inconsistent hpte value 219 */ 220 smp_rmb(); 221 pte1 = ppc_hash32_load_hpte1(cpu, pte_offset); 222 223 if ((pte0 & HPTE32_V_VALID) 224 && (secondary == !!(pte0 & HPTE32_V_SECONDARY)) 225 && HPTE32_V_COMPARE(pte0, ptem)) { 226 pte->pte0 = pte0; 227 pte->pte1 = pte1; 228 return pte_offset; 229 } 230 231 pte_offset += HASH_PTE_SIZE_32; 232 } 233 234 return -1; 235 } 236 237 static void ppc_hash32_set_r(PowerPCCPU *cpu, hwaddr pte_offset, uint32_t pte1) 238 { 239 target_ulong base = ppc_hash32_hpt_base(cpu); 240 hwaddr offset = pte_offset + 6; 241 242 /* The HW performs a non-atomic byte update */ 243 stb_phys(CPU(cpu)->as, base + offset, ((pte1 >> 8) & 0xff) | 0x01); 244 } 245 246 static void ppc_hash32_set_c(PowerPCCPU *cpu, hwaddr pte_offset, uint64_t pte1) 247 { 248 target_ulong base = ppc_hash32_hpt_base(cpu); 249 hwaddr offset = pte_offset + 7; 250 251 /* The HW performs a non-atomic byte update */ 252 stb_phys(CPU(cpu)->as, base + offset, (pte1 & 0xff) | 0x80); 253 } 254 255 static hwaddr ppc_hash32_htab_lookup(PowerPCCPU *cpu, 256 target_ulong sr, target_ulong eaddr, 257 ppc_hash_pte32_t *pte) 258 { 259 hwaddr pteg_off, pte_offset; 260 hwaddr hash; 261 uint32_t vsid, pgidx, ptem; 262 263 vsid = sr & SR32_VSID; 264 pgidx = (eaddr & ~SEGMENT_MASK_256M) >> TARGET_PAGE_BITS; 265 hash = vsid ^ pgidx; 266 ptem = (vsid << 7) | (pgidx >> 10); 267 268 /* Page address translation */ 269 qemu_log_mask(CPU_LOG_MMU, "htab_base " HWADDR_FMT_plx 270 " htab_mask " HWADDR_FMT_plx 271 " hash " HWADDR_FMT_plx "\n", 272 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash); 273 274 /* Primary PTEG lookup */ 275 qemu_log_mask(CPU_LOG_MMU, "0 htab=" HWADDR_FMT_plx "/" HWADDR_FMT_plx 276 " vsid=%" PRIx32 " ptem=%" PRIx32 277 " hash=" HWADDR_FMT_plx "\n", 278 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), 279 vsid, ptem, hash); 280 pteg_off = get_pteg_offset32(cpu, hash); 281 pte_offset = ppc_hash32_pteg_search(cpu, pteg_off, 0, ptem, pte); 282 if (pte_offset == -1) { 283 /* Secondary PTEG lookup */ 284 qemu_log_mask(CPU_LOG_MMU, "1 htab=" HWADDR_FMT_plx "/" HWADDR_FMT_plx 285 " vsid=%" PRIx32 " api=%" PRIx32 286 " hash=" HWADDR_FMT_plx "\n", ppc_hash32_hpt_base(cpu), 287 ppc_hash32_hpt_mask(cpu), vsid, ptem, ~hash); 288 pteg_off = get_pteg_offset32(cpu, ~hash); 289 pte_offset = ppc_hash32_pteg_search(cpu, pteg_off, 1, ptem, pte); 290 } 291 292 return pte_offset; 293 } 294 295 bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type, 296 hwaddr *raddrp, int *psizep, int *protp, int mmu_idx, 297 bool guest_visible) 298 { 299 CPUState *cs = CPU(cpu); 300 CPUPPCState *env = &cpu->env; 301 target_ulong sr; 302 hwaddr pte_offset, raddr; 303 ppc_hash_pte32_t pte; 304 bool key; 305 int prot; 306 307 /* There are no hash32 large pages. */ 308 *psizep = TARGET_PAGE_BITS; 309 310 /* 1. Handle real mode accesses */ 311 if (mmuidx_real(mmu_idx)) { 312 /* Translation is off */ 313 *raddrp = eaddr; 314 *protp = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 315 return true; 316 } 317 318 /* 2. Check Block Address Translation entries (BATs) */ 319 if (env->nb_BATs != 0) { 320 raddr = ppc_hash32_bat_lookup(cpu, eaddr, access_type, protp, mmu_idx); 321 if (raddr != -1) { 322 if (!check_prot_access_type(*protp, access_type)) { 323 if (guest_visible) { 324 if (access_type == MMU_INST_FETCH) { 325 cs->exception_index = POWERPC_EXCP_ISI; 326 env->error_code = 0x08000000; 327 } else { 328 cs->exception_index = POWERPC_EXCP_DSI; 329 env->error_code = 0; 330 env->spr[SPR_DAR] = eaddr; 331 if (access_type == MMU_DATA_STORE) { 332 env->spr[SPR_DSISR] = 0x0a000000; 333 } else { 334 env->spr[SPR_DSISR] = 0x08000000; 335 } 336 } 337 } 338 return false; 339 } 340 *raddrp = raddr; 341 return true; 342 } 343 } 344 345 /* 3. Look up the Segment Register */ 346 sr = env->sr[eaddr >> 28]; 347 348 /* 4. Handle direct store segments */ 349 if (sr & SR32_T) { 350 return ppc_hash32_direct_store(cpu, sr, eaddr, access_type, 351 raddrp, protp, mmu_idx, guest_visible); 352 } 353 354 /* 5. Check for segment level no-execute violation */ 355 if (access_type == MMU_INST_FETCH && (sr & SR32_NX)) { 356 if (guest_visible) { 357 cs->exception_index = POWERPC_EXCP_ISI; 358 env->error_code = 0x10000000; 359 } 360 return false; 361 } 362 363 /* 6. Locate the PTE in the hash table */ 364 pte_offset = ppc_hash32_htab_lookup(cpu, sr, eaddr, &pte); 365 if (pte_offset == -1) { 366 if (guest_visible) { 367 if (access_type == MMU_INST_FETCH) { 368 cs->exception_index = POWERPC_EXCP_ISI; 369 env->error_code = 0x40000000; 370 } else { 371 cs->exception_index = POWERPC_EXCP_DSI; 372 env->error_code = 0; 373 env->spr[SPR_DAR] = eaddr; 374 if (access_type == MMU_DATA_STORE) { 375 env->spr[SPR_DSISR] = 0x42000000; 376 } else { 377 env->spr[SPR_DSISR] = 0x40000000; 378 } 379 } 380 } 381 return false; 382 } 383 qemu_log_mask(CPU_LOG_MMU, 384 "found PTE at offset %08" HWADDR_PRIx "\n", pte_offset); 385 386 /* 7. Check access permissions */ 387 key = ppc_hash32_key(mmuidx_pr(mmu_idx), sr); 388 prot = ppc_hash32_prot(key, pte.pte1 & HPTE32_R_PP, sr & SR32_NX); 389 390 if (!check_prot_access_type(prot, access_type)) { 391 /* Access right violation */ 392 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n"); 393 if (guest_visible) { 394 if (access_type == MMU_INST_FETCH) { 395 cs->exception_index = POWERPC_EXCP_ISI; 396 env->error_code = 0x08000000; 397 } else { 398 cs->exception_index = POWERPC_EXCP_DSI; 399 env->error_code = 0; 400 env->spr[SPR_DAR] = eaddr; 401 if (access_type == MMU_DATA_STORE) { 402 env->spr[SPR_DSISR] = 0x0a000000; 403 } else { 404 env->spr[SPR_DSISR] = 0x08000000; 405 } 406 } 407 } 408 return false; 409 } 410 411 qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n"); 412 413 /* 8. Update PTE referenced and changed bits if necessary */ 414 415 if (!(pte.pte1 & HPTE32_R_R)) { 416 ppc_hash32_set_r(cpu, pte_offset, pte.pte1); 417 } 418 if (!(pte.pte1 & HPTE32_R_C)) { 419 if (access_type == MMU_DATA_STORE) { 420 ppc_hash32_set_c(cpu, pte_offset, pte.pte1); 421 } else { 422 /* 423 * Treat the page as read-only for now, so that a later write 424 * will pass through this function again to set the C bit 425 */ 426 prot &= ~PAGE_WRITE; 427 } 428 } 429 *protp = prot; 430 431 /* 9. Determine the real address from the PTE */ 432 *raddrp = pte.pte1 & HPTE32_R_RPN; 433 *raddrp &= TARGET_PAGE_MASK; 434 *raddrp |= eaddr & ~TARGET_PAGE_MASK; 435 return true; 436 } 437