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