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