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