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