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