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