1 /* 2 * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU. 3 * 4 * Copyright (c) 2003-2007 Jocelyn Mayer 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "qemu/units.h" 22 #include "cpu.h" 23 #include "sysemu/kvm.h" 24 #include "kvm_ppc.h" 25 #include "mmu-hash64.h" 26 #include "mmu-hash32.h" 27 #include "exec/exec-all.h" 28 #include "exec/page-protection.h" 29 #include "exec/log.h" 30 #include "helper_regs.h" 31 #include "qemu/error-report.h" 32 #include "qemu/qemu-print.h" 33 #include "internal.h" 34 #include "mmu-book3s-v3.h" 35 #include "mmu-radix64.h" 36 #include "mmu-booke.h" 37 38 /* #define DUMP_PAGE_TABLES */ 39 40 /* Context used internally during MMU translations */ 41 typedef struct { 42 hwaddr raddr; /* Real address */ 43 int prot; /* Protection bits */ 44 } mmu_ctx_t; 45 46 void ppc_store_sdr1(CPUPPCState *env, target_ulong value) 47 { 48 PowerPCCPU *cpu = env_archcpu(env); 49 qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); 50 assert(!cpu->env.has_hv_mode || !cpu->vhyp); 51 #if defined(TARGET_PPC64) 52 if (mmu_is_64bit(env->mmu_model)) { 53 target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE; 54 target_ulong htabsize = value & SDR_64_HTABSIZE; 55 56 if (value & ~sdr_mask) { 57 qemu_log_mask(LOG_GUEST_ERROR, "Invalid bits 0x"TARGET_FMT_lx 58 " set in SDR1", value & ~sdr_mask); 59 value &= sdr_mask; 60 } 61 if (htabsize > 28) { 62 qemu_log_mask(LOG_GUEST_ERROR, "Invalid HTABSIZE 0x" TARGET_FMT_lx 63 " stored in SDR1", htabsize); 64 return; 65 } 66 } 67 #endif /* defined(TARGET_PPC64) */ 68 /* FIXME: Should check for valid HTABMASK values in 32-bit case */ 69 env->spr[SPR_SDR1] = value; 70 } 71 72 /*****************************************************************************/ 73 /* PowerPC MMU emulation */ 74 75 int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, 76 int way, int is_code) 77 { 78 int nr; 79 80 /* Select TLB num in a way from address */ 81 nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1); 82 /* Select TLB way */ 83 nr += env->tlb_per_way * way; 84 /* 6xx has separate TLBs for instructions and data */ 85 if (is_code) { 86 nr += env->nb_tlb; 87 } 88 89 return nr; 90 } 91 92 /* Software driven TLB helpers */ 93 94 static int ppc6xx_tlb_check(CPUPPCState *env, hwaddr *raddr, int *prot, 95 target_ulong eaddr, MMUAccessType access_type, 96 target_ulong ptem, bool key, bool nx) 97 { 98 ppc6xx_tlb_t *tlb; 99 target_ulong *pte1p; 100 int nr, best, way, ret; 101 bool is_code = (access_type == MMU_INST_FETCH); 102 103 /* Initialize real address with an invalid value */ 104 *raddr = (hwaddr)-1ULL; 105 best = -1; 106 ret = -1; /* No TLB found */ 107 for (way = 0; way < env->nb_ways; way++) { 108 nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code); 109 tlb = &env->tlb.tlb6[nr]; 110 /* This test "emulates" the PTE index match for hardware TLBs */ 111 if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) { 112 qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s [" TARGET_FMT_lx 113 " " TARGET_FMT_lx "] <> " TARGET_FMT_lx "\n", 114 nr, env->nb_tlb, 115 pte_is_valid(tlb->pte0) ? "valid" : "inval", 116 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr); 117 continue; 118 } 119 qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s " TARGET_FMT_lx " <> " 120 TARGET_FMT_lx " " TARGET_FMT_lx " %c %c\n", 121 nr, env->nb_tlb, 122 pte_is_valid(tlb->pte0) ? "valid" : "inval", 123 tlb->EPN, eaddr, tlb->pte1, 124 access_type == MMU_DATA_STORE ? 'S' : 'L', 125 access_type == MMU_INST_FETCH ? 'I' : 'D'); 126 /* Check validity and table match */ 127 if (!pte_is_valid(tlb->pte0) || ((tlb->pte0 >> 6) & 1) != 0 || 128 (tlb->pte0 & PTE_PTEM_MASK) != ptem) { 129 continue; 130 } 131 /* all matches should have equal RPN, WIMG & PP */ 132 if (*raddr != (hwaddr)-1ULL && 133 (*raddr & PTE_CHECK_MASK) != (tlb->pte1 & PTE_CHECK_MASK)) { 134 qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n"); 135 /* TLB inconsistency */ 136 continue; 137 } 138 /* Keep the matching PTE information */ 139 best = nr; 140 *raddr = tlb->pte1; 141 *prot = ppc_hash32_prot(key, tlb->pte1 & HPTE32_R_PP, nx); 142 if (check_prot_access_type(*prot, access_type)) { 143 qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n"); 144 ret = 0; 145 break; 146 } else { 147 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n"); 148 ret = -2; 149 } 150 } 151 if (best != -1) { 152 qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " HWADDR_FMT_plx 153 " prot=%01x ret=%d\n", 154 *raddr & TARGET_PAGE_MASK, *prot, ret); 155 /* Update page flags */ 156 pte1p = &env->tlb.tlb6[best].pte1; 157 *pte1p |= 0x00000100; /* Update accessed flag */ 158 if (!(*pte1p & 0x00000080)) { 159 if (access_type == MMU_DATA_STORE && ret == 0) { 160 /* Update changed flag */ 161 *pte1p |= 0x00000080; 162 } else { 163 /* Force page fault for first write access */ 164 *prot &= ~PAGE_WRITE; 165 } 166 } 167 } 168 if (ret == -1) { 169 int r = is_code ? SPR_ICMP : SPR_DCMP; 170 env->spr[r] = ptem; 171 } 172 #if defined(DUMP_PAGE_TABLES) 173 if (qemu_loglevel_mask(CPU_LOG_MMU)) { 174 CPUState *cs = env_cpu(env); 175 hwaddr base = ppc_hash32_hpt_base(env_archcpu(env)); 176 hwaddr len = ppc_hash32_hpt_mask(env_archcpu(env)) + 0x80; 177 uint32_t a0, a1, a2, a3; 178 179 qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n", 180 base, len); 181 for (hwaddr curaddr = base; curaddr < base + len; curaddr += 16) { 182 a0 = ldl_phys(cs->as, curaddr); 183 a1 = ldl_phys(cs->as, curaddr + 4); 184 a2 = ldl_phys(cs->as, curaddr + 8); 185 a3 = ldl_phys(cs->as, curaddr + 12); 186 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { 187 qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n", 188 curaddr, a0, a1, a2, a3); 189 } 190 } 191 } 192 #endif 193 return ret; 194 } 195 196 /* Perform BAT hit & translation */ 197 static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp, 198 int *validp, int *protp, target_ulong *BATu, 199 target_ulong *BATl) 200 { 201 target_ulong bl; 202 int pp, valid, prot; 203 204 bl = (*BATu & BATU32_BL) << 15; 205 valid = 0; 206 prot = 0; 207 if ((!FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000002)) || 208 (FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000001))) { 209 valid = 1; 210 pp = *BATl & 0x00000003; 211 if (pp != 0) { 212 prot = PAGE_READ | PAGE_EXEC; 213 if (pp == 0x2) { 214 prot |= PAGE_WRITE; 215 } 216 } 217 } 218 *blp = bl; 219 *validp = valid; 220 *protp = prot; 221 } 222 223 static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, 224 target_ulong eaddr, MMUAccessType access_type) 225 { 226 target_ulong *BATlt, *BATut, *BATu, *BATl; 227 target_ulong BEPIl, BEPIu, bl; 228 int i, valid, prot; 229 int ret = -1; 230 bool ifetch = access_type == MMU_INST_FETCH; 231 232 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT v " TARGET_FMT_lx "\n", __func__, 233 ifetch ? 'I' : 'D', eaddr); 234 if (ifetch) { 235 BATlt = env->IBAT[1]; 236 BATut = env->IBAT[0]; 237 } else { 238 BATlt = env->DBAT[1]; 239 BATut = env->DBAT[0]; 240 } 241 for (i = 0; i < env->nb_BATs; i++) { 242 BATu = &BATut[i]; 243 BATl = &BATlt[i]; 244 BEPIu = *BATu & BATU32_BEPIU; 245 BEPIl = *BATu & BATU32_BEPIL; 246 bat_size_prot(env, &bl, &valid, &prot, BATu, BATl); 247 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx " BATu " 248 TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n", __func__, 249 ifetch ? 'I' : 'D', i, eaddr, *BATu, *BATl); 250 if ((eaddr & BATU32_BEPIU) == BEPIu && 251 ((eaddr & BATU32_BEPIL) & ~bl) == BEPIl) { 252 /* BAT matches */ 253 if (valid != 0) { 254 /* Get physical address */ 255 ctx->raddr = (*BATl & BATU32_BEPIU) | 256 ((eaddr & BATU32_BEPIL & bl) | (*BATl & BATU32_BEPIL)) | 257 (eaddr & 0x0001F000); 258 /* Compute access rights */ 259 ctx->prot = prot; 260 if (check_prot_access_type(ctx->prot, access_type)) { 261 qemu_log_mask(CPU_LOG_MMU, "BAT %d match: r " HWADDR_FMT_plx 262 " prot=%c%c\n", i, ctx->raddr, 263 ctx->prot & PAGE_READ ? 'R' : '-', 264 ctx->prot & PAGE_WRITE ? 'W' : '-'); 265 ret = 0; 266 } else { 267 ret = -2; 268 } 269 break; 270 } 271 } 272 } 273 if (ret < 0) { 274 if (qemu_log_enabled()) { 275 qemu_log_mask(CPU_LOG_MMU, "no BAT match for " 276 TARGET_FMT_lx ":\n", eaddr); 277 for (i = 0; i < 4; i++) { 278 BATu = &BATut[i]; 279 BATl = &BATlt[i]; 280 BEPIu = *BATu & BATU32_BEPIU; 281 BEPIl = *BATu & BATU32_BEPIL; 282 bl = (*BATu & BATU32_BL) << 15; 283 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx 284 " BATu " TARGET_FMT_lx " BATl " TARGET_FMT_lx 285 "\n\t" TARGET_FMT_lx " " TARGET_FMT_lx " " 286 TARGET_FMT_lx "\n", __func__, ifetch ? 'I' : 'D', 287 i, eaddr, *BATu, *BATl, BEPIu, BEPIl, bl); 288 } 289 } 290 } 291 /* No hit */ 292 return ret; 293 } 294 295 static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, 296 target_ulong eaddr, 297 hwaddr *hashp, bool *keyp, 298 MMUAccessType access_type, int type) 299 { 300 PowerPCCPU *cpu = env_archcpu(env); 301 hwaddr hash; 302 target_ulong vsid, sr, pgidx, ptem; 303 bool key, pr, ds, nx; 304 305 /* First try to find a BAT entry if there are any */ 306 if (env->nb_BATs && get_bat_6xx_tlb(env, ctx, eaddr, access_type) == 0) { 307 return 0; 308 } 309 310 /* Perform segment based translation when no BATs matched */ 311 pr = FIELD_EX64(env->msr, MSR, PR); 312 313 sr = env->sr[eaddr >> 28]; 314 key = ppc_hash32_key(pr, sr); 315 *keyp = key; 316 ds = sr & SR32_T; 317 nx = sr & SR32_NX; 318 vsid = sr & SR32_VSID; 319 qemu_log_mask(CPU_LOG_MMU, 320 "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx 321 " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx 322 " ir=%d dr=%d pr=%d %d t=%d\n", 323 eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, 324 (int)FIELD_EX64(env->msr, MSR, IR), 325 (int)FIELD_EX64(env->msr, MSR, DR), pr ? 1 : 0, 326 access_type == MMU_DATA_STORE, type); 327 pgidx = (eaddr & ~SEGMENT_MASK_256M) >> TARGET_PAGE_BITS; 328 hash = vsid ^ pgidx; 329 ptem = (vsid << 7) | (pgidx >> 10); /* Virtual segment ID | API */ 330 331 qemu_log_mask(CPU_LOG_MMU, "pte segment: key=%d ds %d nx %d vsid " 332 TARGET_FMT_lx "\n", key, ds, nx, vsid); 333 if (!ds) { 334 /* Check if instruction fetch is allowed, if needed */ 335 if (type == ACCESS_CODE && nx) { 336 qemu_log_mask(CPU_LOG_MMU, "No access allowed\n"); 337 return -3; 338 } 339 /* Page address translation */ 340 qemu_log_mask(CPU_LOG_MMU, "htab_base " HWADDR_FMT_plx " htab_mask " 341 HWADDR_FMT_plx " hash " HWADDR_FMT_plx "\n", 342 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash); 343 *hashp = hash; 344 345 /* Software TLB search */ 346 return ppc6xx_tlb_check(env, &ctx->raddr, &ctx->prot, eaddr, 347 access_type, ptem, key, nx); 348 } 349 350 /* Direct-store segment : absolutely *BUGGY* for now */ 351 qemu_log_mask(CPU_LOG_MMU, "direct store...\n"); 352 switch (type) { 353 case ACCESS_INT: 354 /* Integer load/store : only access allowed */ 355 break; 356 case ACCESS_CACHE: 357 /* 358 * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi 359 * 360 * Should make the instruction do no-op. As it already do 361 * no-op, it's quite easy :-) 362 */ 363 ctx->raddr = eaddr; 364 return 0; 365 case ACCESS_CODE: /* No code fetch is allowed in direct-store areas */ 366 case ACCESS_FLOAT: /* Floating point load/store */ 367 case ACCESS_RES: /* lwarx, ldarx or srwcx. */ 368 case ACCESS_EXT: /* eciwx or ecowx */ 369 return -4; 370 } 371 if ((access_type == MMU_DATA_STORE || !key) && 372 (access_type == MMU_DATA_LOAD || key)) { 373 ctx->raddr = eaddr; 374 return 2; 375 } 376 return -2; 377 } 378 379 static const char *book3e_tsize_to_str[32] = { 380 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", 381 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", 382 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G", 383 "1T", "2T" 384 }; 385 386 static void mmubooke_dump_mmu(CPUPPCState *env) 387 { 388 ppcemb_tlb_t *entry; 389 int i; 390 391 #ifdef CONFIG_KVM 392 if (kvm_enabled() && !env->kvm_sw_tlb) { 393 qemu_printf("Cannot access KVM TLB\n"); 394 return; 395 } 396 #endif 397 398 qemu_printf("\nTLB:\n"); 399 qemu_printf("Effective Physical Size PID Prot " 400 "Attr\n"); 401 402 entry = &env->tlb.tlbe[0]; 403 for (i = 0; i < env->nb_tlb; i++, entry++) { 404 hwaddr ea, pa; 405 target_ulong mask; 406 uint64_t size = (uint64_t)entry->size; 407 char size_buf[20]; 408 409 /* Check valid flag */ 410 if (!(entry->prot & PAGE_VALID)) { 411 continue; 412 } 413 414 mask = ~(entry->size - 1); 415 ea = entry->EPN & mask; 416 pa = entry->RPN & mask; 417 /* Extend the physical address to 36 bits */ 418 pa |= (hwaddr)(entry->RPN & 0xF) << 32; 419 if (size >= 1 * MiB) { 420 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB); 421 } else { 422 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB); 423 } 424 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n", 425 (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID, 426 entry->prot, entry->attr); 427 } 428 429 } 430 431 static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset, 432 int tlbsize) 433 { 434 ppcmas_tlb_t *entry; 435 int i; 436 437 qemu_printf("\nTLB%d:\n", tlbn); 438 qemu_printf("Effective Physical Size TID TS SRWX" 439 " URWX WIMGE U0123\n"); 440 441 entry = &env->tlb.tlbm[offset]; 442 for (i = 0; i < tlbsize; i++, entry++) { 443 hwaddr ea, pa, size; 444 int tsize; 445 446 if (!(entry->mas1 & MAS1_VALID)) { 447 continue; 448 } 449 450 tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; 451 size = 1024ULL << tsize; 452 ea = entry->mas2 & ~(size - 1); 453 pa = entry->mas7_3 & ~(size - 1); 454 455 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c" 456 " U%c%c%c %c%c%c%c%c U%c%c%c%c\n", 457 (uint64_t)ea, (uint64_t)pa, 458 book3e_tsize_to_str[tsize], 459 (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT, 460 (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT, 461 entry->mas7_3 & MAS3_SR ? 'R' : '-', 462 entry->mas7_3 & MAS3_SW ? 'W' : '-', 463 entry->mas7_3 & MAS3_SX ? 'X' : '-', 464 entry->mas7_3 & MAS3_UR ? 'R' : '-', 465 entry->mas7_3 & MAS3_UW ? 'W' : '-', 466 entry->mas7_3 & MAS3_UX ? 'X' : '-', 467 entry->mas2 & MAS2_W ? 'W' : '-', 468 entry->mas2 & MAS2_I ? 'I' : '-', 469 entry->mas2 & MAS2_M ? 'M' : '-', 470 entry->mas2 & MAS2_G ? 'G' : '-', 471 entry->mas2 & MAS2_E ? 'E' : '-', 472 entry->mas7_3 & MAS3_U0 ? '0' : '-', 473 entry->mas7_3 & MAS3_U1 ? '1' : '-', 474 entry->mas7_3 & MAS3_U2 ? '2' : '-', 475 entry->mas7_3 & MAS3_U3 ? '3' : '-'); 476 } 477 } 478 479 static void mmubooke206_dump_mmu(CPUPPCState *env) 480 { 481 int offset = 0; 482 int i; 483 484 #ifdef CONFIG_KVM 485 if (kvm_enabled() && !env->kvm_sw_tlb) { 486 qemu_printf("Cannot access KVM TLB\n"); 487 return; 488 } 489 #endif 490 491 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 492 int size = booke206_tlb_size(env, i); 493 494 if (size == 0) { 495 continue; 496 } 497 498 mmubooke206_dump_one_tlb(env, i, offset, size); 499 offset += size; 500 } 501 } 502 503 static void mmu6xx_dump_BATs(CPUPPCState *env, int type) 504 { 505 target_ulong *BATlt, *BATut, *BATu, *BATl; 506 target_ulong BEPIl, BEPIu, bl; 507 int i; 508 509 switch (type) { 510 case ACCESS_CODE: 511 BATlt = env->IBAT[1]; 512 BATut = env->IBAT[0]; 513 break; 514 default: 515 BATlt = env->DBAT[1]; 516 BATut = env->DBAT[0]; 517 break; 518 } 519 520 for (i = 0; i < env->nb_BATs; i++) { 521 BATu = &BATut[i]; 522 BATl = &BATlt[i]; 523 BEPIu = *BATu & BATU32_BEPIU; 524 BEPIl = *BATu & BATU32_BEPIL; 525 bl = (*BATu & BATU32_BL) << 15; 526 qemu_printf("%s BAT%d BATu " TARGET_FMT_lx 527 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " " 528 TARGET_FMT_lx " " TARGET_FMT_lx "\n", 529 type == ACCESS_CODE ? "code" : "data", i, 530 *BATu, *BATl, BEPIu, BEPIl, bl); 531 } 532 } 533 534 static void mmu6xx_dump_mmu(CPUPPCState *env) 535 { 536 PowerPCCPU *cpu = env_archcpu(env); 537 ppc6xx_tlb_t *tlb; 538 target_ulong sr; 539 int type, way, entry, i; 540 541 qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu)); 542 qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu)); 543 544 qemu_printf("\nSegment registers:\n"); 545 for (i = 0; i < 32; i++) { 546 sr = env->sr[i]; 547 if (sr & 0x80000000) { 548 qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x " 549 "CNTLR_SPEC=0x%05x\n", i, 550 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0, 551 sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF), 552 (uint32_t)(sr & 0xFFFFF)); 553 } else { 554 qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i, 555 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0, 556 sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0, 557 (uint32_t)(sr & 0x00FFFFFF)); 558 } 559 } 560 561 qemu_printf("\nBATs:\n"); 562 mmu6xx_dump_BATs(env, ACCESS_INT); 563 mmu6xx_dump_BATs(env, ACCESS_CODE); 564 565 qemu_printf("\nTLBs [EPN EPN + SIZE]\n"); 566 for (type = 0; type < 2; type++) { 567 for (way = 0; way < env->nb_ways; way++) { 568 for (entry = env->nb_tlb * type + env->tlb_per_way * way; 569 entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1)); 570 entry++) { 571 572 tlb = &env->tlb.tlb6[entry]; 573 qemu_printf("%s TLB %02d/%02d way:%d %s [" 574 TARGET_FMT_lx " " TARGET_FMT_lx "]\n", 575 type ? "code" : "data", entry % env->nb_tlb, 576 env->nb_tlb, way, 577 pte_is_valid(tlb->pte0) ? "valid" : "inval", 578 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE); 579 } 580 } 581 } 582 } 583 584 void dump_mmu(CPUPPCState *env) 585 { 586 switch (env->mmu_model) { 587 case POWERPC_MMU_BOOKE: 588 mmubooke_dump_mmu(env); 589 break; 590 case POWERPC_MMU_BOOKE206: 591 mmubooke206_dump_mmu(env); 592 break; 593 case POWERPC_MMU_SOFT_6xx: 594 mmu6xx_dump_mmu(env); 595 break; 596 #if defined(TARGET_PPC64) 597 case POWERPC_MMU_64B: 598 case POWERPC_MMU_2_03: 599 case POWERPC_MMU_2_06: 600 case POWERPC_MMU_2_07: 601 dump_slb(env_archcpu(env)); 602 break; 603 case POWERPC_MMU_3_00: 604 if (ppc64_v3_radix(env_archcpu(env))) { 605 qemu_log_mask(LOG_UNIMP, "%s: the PPC64 MMU is unsupported\n", 606 __func__); 607 } else { 608 dump_slb(env_archcpu(env)); 609 } 610 break; 611 #endif 612 default: 613 qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__); 614 } 615 } 616 617 618 static bool ppc_real_mode_xlate(PowerPCCPU *cpu, vaddr eaddr, 619 MMUAccessType access_type, 620 hwaddr *raddrp, int *psizep, int *protp) 621 { 622 CPUPPCState *env = &cpu->env; 623 624 if (access_type == MMU_INST_FETCH ? !FIELD_EX64(env->msr, MSR, IR) 625 : !FIELD_EX64(env->msr, MSR, DR)) { 626 *raddrp = eaddr; 627 *protp = PAGE_RWX; 628 *psizep = TARGET_PAGE_BITS; 629 return true; 630 } else if (env->mmu_model == POWERPC_MMU_REAL) { 631 cpu_abort(CPU(cpu), "PowerPC in real mode shold not do translation\n"); 632 } 633 return false; 634 } 635 636 static bool ppc_40x_xlate(PowerPCCPU *cpu, vaddr eaddr, 637 MMUAccessType access_type, 638 hwaddr *raddrp, int *psizep, int *protp, 639 int mmu_idx, bool guest_visible) 640 { 641 CPUState *cs = CPU(cpu); 642 CPUPPCState *env = &cpu->env; 643 int ret; 644 645 if (ppc_real_mode_xlate(cpu, eaddr, access_type, raddrp, psizep, protp)) { 646 return true; 647 } 648 649 ret = mmu40x_get_physical_address(env, raddrp, protp, eaddr, access_type); 650 if (ret == 0) { 651 *psizep = TARGET_PAGE_BITS; 652 return true; 653 } else if (!guest_visible) { 654 return false; 655 } 656 657 log_cpu_state_mask(CPU_LOG_MMU, cs, 0); 658 if (access_type == MMU_INST_FETCH) { 659 switch (ret) { 660 case -1: 661 /* No matches in page tables or TLB */ 662 cs->exception_index = POWERPC_EXCP_ITLB; 663 env->error_code = 0; 664 env->spr[SPR_40x_DEAR] = eaddr; 665 env->spr[SPR_40x_ESR] = 0x00000000; 666 break; 667 case -2: 668 /* Access rights violation */ 669 cs->exception_index = POWERPC_EXCP_ISI; 670 env->error_code = 0x08000000; 671 break; 672 default: 673 g_assert_not_reached(); 674 } 675 } else { 676 switch (ret) { 677 case -1: 678 /* No matches in page tables or TLB */ 679 cs->exception_index = POWERPC_EXCP_DTLB; 680 env->error_code = 0; 681 env->spr[SPR_40x_DEAR] = eaddr; 682 if (access_type == MMU_DATA_STORE) { 683 env->spr[SPR_40x_ESR] = 0x00800000; 684 } else { 685 env->spr[SPR_40x_ESR] = 0x00000000; 686 } 687 break; 688 case -2: 689 /* Access rights violation */ 690 cs->exception_index = POWERPC_EXCP_DSI; 691 env->error_code = 0; 692 env->spr[SPR_40x_DEAR] = eaddr; 693 if (access_type == MMU_DATA_STORE) { 694 env->spr[SPR_40x_ESR] |= 0x00800000; 695 } 696 break; 697 default: 698 g_assert_not_reached(); 699 } 700 } 701 return false; 702 } 703 704 static bool ppc_6xx_xlate(PowerPCCPU *cpu, vaddr eaddr, 705 MMUAccessType access_type, 706 hwaddr *raddrp, int *psizep, int *protp, 707 int mmu_idx, bool guest_visible) 708 { 709 CPUState *cs = CPU(cpu); 710 CPUPPCState *env = &cpu->env; 711 mmu_ctx_t ctx; 712 hwaddr hash = 0; /* init to 0 to avoid used uninit warning */ 713 bool key; 714 int type, ret; 715 716 if (ppc_real_mode_xlate(cpu, eaddr, access_type, raddrp, psizep, protp)) { 717 return true; 718 } 719 720 if (access_type == MMU_INST_FETCH) { 721 /* code access */ 722 type = ACCESS_CODE; 723 } else if (guest_visible) { 724 /* data access */ 725 type = env->access_type; 726 } else { 727 type = ACCESS_INT; 728 } 729 730 ctx.prot = 0; 731 ret = mmu6xx_get_physical_address(env, &ctx, eaddr, &hash, &key, 732 access_type, type); 733 if (ret == 0) { 734 *raddrp = ctx.raddr; 735 *protp = ctx.prot; 736 *psizep = TARGET_PAGE_BITS; 737 return true; 738 } else if (!guest_visible) { 739 return false; 740 } 741 742 log_cpu_state_mask(CPU_LOG_MMU, cs, 0); 743 if (type == ACCESS_CODE) { 744 switch (ret) { 745 case -1: 746 /* No matches in page tables or TLB */ 747 cs->exception_index = POWERPC_EXCP_IFTLB; 748 env->error_code = 1 << 18; 749 env->spr[SPR_IMISS] = eaddr; 750 env->spr[SPR_ICMP] |= 0x80000000; 751 goto tlb_miss; 752 case -2: 753 /* Access rights violation */ 754 cs->exception_index = POWERPC_EXCP_ISI; 755 env->error_code = 0x08000000; 756 break; 757 case -3: 758 /* No execute protection violation */ 759 cs->exception_index = POWERPC_EXCP_ISI; 760 env->error_code = 0x10000000; 761 break; 762 case -4: 763 /* Direct store exception */ 764 /* No code fetch is allowed in direct-store areas */ 765 cs->exception_index = POWERPC_EXCP_ISI; 766 env->error_code = 0x10000000; 767 break; 768 } 769 } else { 770 switch (ret) { 771 case -1: 772 /* No matches in page tables or TLB */ 773 if (access_type == MMU_DATA_STORE) { 774 cs->exception_index = POWERPC_EXCP_DSTLB; 775 env->error_code = 1 << 16; 776 } else { 777 cs->exception_index = POWERPC_EXCP_DLTLB; 778 env->error_code = 0; 779 } 780 env->spr[SPR_DMISS] = eaddr; 781 env->spr[SPR_DCMP] |= 0x80000000; 782 tlb_miss: 783 env->error_code |= key << 19; 784 env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) + 785 get_pteg_offset32(cpu, hash); 786 env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) + 787 get_pteg_offset32(cpu, ~hash); 788 break; 789 case -2: 790 /* Access rights violation */ 791 cs->exception_index = POWERPC_EXCP_DSI; 792 env->error_code = 0; 793 env->spr[SPR_DAR] = eaddr; 794 if (access_type == MMU_DATA_STORE) { 795 env->spr[SPR_DSISR] = 0x0A000000; 796 } else { 797 env->spr[SPR_DSISR] = 0x08000000; 798 } 799 break; 800 case -4: 801 /* Direct store exception */ 802 switch (type) { 803 case ACCESS_FLOAT: 804 /* Floating point load/store */ 805 cs->exception_index = POWERPC_EXCP_ALIGN; 806 env->error_code = POWERPC_EXCP_ALIGN_FP; 807 env->spr[SPR_DAR] = eaddr; 808 break; 809 case ACCESS_RES: 810 /* lwarx, ldarx or stwcx. */ 811 cs->exception_index = POWERPC_EXCP_DSI; 812 env->error_code = 0; 813 env->spr[SPR_DAR] = eaddr; 814 if (access_type == MMU_DATA_STORE) { 815 env->spr[SPR_DSISR] = 0x06000000; 816 } else { 817 env->spr[SPR_DSISR] = 0x04000000; 818 } 819 break; 820 case ACCESS_EXT: 821 /* eciwx or ecowx */ 822 cs->exception_index = POWERPC_EXCP_DSI; 823 env->error_code = 0; 824 env->spr[SPR_DAR] = eaddr; 825 if (access_type == MMU_DATA_STORE) { 826 env->spr[SPR_DSISR] = 0x06100000; 827 } else { 828 env->spr[SPR_DSISR] = 0x04100000; 829 } 830 break; 831 default: 832 printf("DSI: invalid exception (%d)\n", ret); 833 cs->exception_index = POWERPC_EXCP_PROGRAM; 834 env->error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL; 835 env->spr[SPR_DAR] = eaddr; 836 break; 837 } 838 break; 839 } 840 } 841 return false; 842 } 843 844 /*****************************************************************************/ 845 846 bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type, 847 hwaddr *raddrp, int *psizep, int *protp, 848 int mmu_idx, bool guest_visible) 849 { 850 switch (cpu->env.mmu_model) { 851 #if defined(TARGET_PPC64) 852 case POWERPC_MMU_3_00: 853 if (ppc64_v3_radix(cpu)) { 854 return ppc_radix64_xlate(cpu, eaddr, access_type, raddrp, 855 psizep, protp, mmu_idx, guest_visible); 856 } 857 /* fall through */ 858 case POWERPC_MMU_64B: 859 case POWERPC_MMU_2_03: 860 case POWERPC_MMU_2_06: 861 case POWERPC_MMU_2_07: 862 return ppc_hash64_xlate(cpu, eaddr, access_type, 863 raddrp, psizep, protp, mmu_idx, guest_visible); 864 #endif 865 866 case POWERPC_MMU_32B: 867 return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp, 868 psizep, protp, mmu_idx, guest_visible); 869 case POWERPC_MMU_BOOKE: 870 case POWERPC_MMU_BOOKE206: 871 return ppc_booke_xlate(cpu, eaddr, access_type, raddrp, 872 psizep, protp, mmu_idx, guest_visible); 873 case POWERPC_MMU_SOFT_4xx: 874 return ppc_40x_xlate(cpu, eaddr, access_type, raddrp, 875 psizep, protp, mmu_idx, guest_visible); 876 case POWERPC_MMU_SOFT_6xx: 877 return ppc_6xx_xlate(cpu, eaddr, access_type, raddrp, 878 psizep, protp, mmu_idx, guest_visible); 879 case POWERPC_MMU_REAL: 880 return ppc_real_mode_xlate(cpu, eaddr, access_type, raddrp, psizep, 881 protp); 882 case POWERPC_MMU_MPC8xx: 883 cpu_abort(env_cpu(&cpu->env), "MPC8xx MMU model is not implemented\n"); 884 default: 885 cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n"); 886 } 887 } 888 889 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) 890 { 891 PowerPCCPU *cpu = POWERPC_CPU(cs); 892 hwaddr raddr; 893 int s, p; 894 895 /* 896 * Some MMUs have separate TLBs for code and data. If we only 897 * try an MMU_DATA_LOAD, we may not be able to read instructions 898 * mapped by code TLBs, so we also try a MMU_INST_FETCH. 899 */ 900 if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p, 901 ppc_env_mmu_index(&cpu->env, false), false) || 902 ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p, 903 ppc_env_mmu_index(&cpu->env, true), false)) { 904 return raddr & TARGET_PAGE_MASK; 905 } 906 return -1; 907 } 908