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