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 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 #include "qemu/osdep.h" 20 #include "qemu/units.h" 21 #include "cpu.h" 22 #include "exec/helper-proto.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/cpu_ldst.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 "mmu-book3s-v3.h" 34 #include "mmu-radix64.h" 35 36 /* #define DEBUG_MMU */ 37 /* #define DEBUG_BATS */ 38 /* #define DEBUG_SOFTWARE_TLB */ 39 /* #define DUMP_PAGE_TABLES */ 40 /* #define FLUSH_ALL_TLBS */ 41 42 #ifdef DEBUG_MMU 43 # define LOG_MMU_STATE(cpu) log_cpu_state_mask(CPU_LOG_MMU, (cpu), 0) 44 #else 45 # define LOG_MMU_STATE(cpu) do { } while (0) 46 #endif 47 48 #ifdef DEBUG_SOFTWARE_TLB 49 # define LOG_SWTLB(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__) 50 #else 51 # define LOG_SWTLB(...) do { } while (0) 52 #endif 53 54 #ifdef DEBUG_BATS 55 # define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__) 56 #else 57 # define LOG_BATS(...) do { } while (0) 58 #endif 59 60 /*****************************************************************************/ 61 /* PowerPC MMU emulation */ 62 63 /* Context used internally during MMU translations */ 64 typedef struct mmu_ctx_t mmu_ctx_t; 65 struct mmu_ctx_t { 66 hwaddr raddr; /* Real address */ 67 hwaddr eaddr; /* Effective address */ 68 int prot; /* Protection bits */ 69 hwaddr hash[2]; /* Pagetable hash values */ 70 target_ulong ptem; /* Virtual segment ID | API */ 71 int key; /* Access key */ 72 int nx; /* Non-execute area */ 73 }; 74 75 /* Common routines used by software and hardware TLBs emulation */ 76 static inline int pte_is_valid(target_ulong pte0) 77 { 78 return pte0 & 0x80000000 ? 1 : 0; 79 } 80 81 static inline void pte_invalidate(target_ulong *pte0) 82 { 83 *pte0 &= ~0x80000000; 84 } 85 86 #define PTE_PTEM_MASK 0x7FFFFFBF 87 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B) 88 89 static int pp_check(int key, int pp, int nx) 90 { 91 int access; 92 93 /* Compute access rights */ 94 access = 0; 95 if (key == 0) { 96 switch (pp) { 97 case 0x0: 98 case 0x1: 99 case 0x2: 100 access |= PAGE_WRITE; 101 /* No break here */ 102 case 0x3: 103 access |= PAGE_READ; 104 break; 105 } 106 } else { 107 switch (pp) { 108 case 0x0: 109 access = 0; 110 break; 111 case 0x1: 112 case 0x3: 113 access = PAGE_READ; 114 break; 115 case 0x2: 116 access = PAGE_READ | PAGE_WRITE; 117 break; 118 } 119 } 120 if (nx == 0) { 121 access |= PAGE_EXEC; 122 } 123 124 return access; 125 } 126 127 static int check_prot(int prot, int rw, int access_type) 128 { 129 int ret; 130 131 if (access_type == ACCESS_CODE) { 132 if (prot & PAGE_EXEC) { 133 ret = 0; 134 } else { 135 ret = -2; 136 } 137 } else if (rw) { 138 if (prot & PAGE_WRITE) { 139 ret = 0; 140 } else { 141 ret = -2; 142 } 143 } else { 144 if (prot & PAGE_READ) { 145 ret = 0; 146 } else { 147 ret = -2; 148 } 149 } 150 151 return ret; 152 } 153 154 static inline int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0, 155 target_ulong pte1, int h, 156 int rw, int type) 157 { 158 target_ulong ptem, mmask; 159 int access, ret, pteh, ptev, pp; 160 161 ret = -1; 162 /* Check validity and table match */ 163 ptev = pte_is_valid(pte0); 164 pteh = (pte0 >> 6) & 1; 165 if (ptev && h == pteh) { 166 /* Check vsid & api */ 167 ptem = pte0 & PTE_PTEM_MASK; 168 mmask = PTE_CHECK_MASK; 169 pp = pte1 & 0x00000003; 170 if (ptem == ctx->ptem) { 171 if (ctx->raddr != (hwaddr)-1ULL) { 172 /* all matches should have equal RPN, WIMG & PP */ 173 if ((ctx->raddr & mmask) != (pte1 & mmask)) { 174 qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n"); 175 return -3; 176 } 177 } 178 /* Compute access rights */ 179 access = pp_check(ctx->key, pp, ctx->nx); 180 /* Keep the matching PTE informations */ 181 ctx->raddr = pte1; 182 ctx->prot = access; 183 ret = check_prot(ctx->prot, rw, type); 184 if (ret == 0) { 185 /* Access granted */ 186 qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n"); 187 } else { 188 /* Access right violation */ 189 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n"); 190 } 191 } 192 } 193 194 return ret; 195 } 196 197 static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p, 198 int ret, int rw) 199 { 200 int store = 0; 201 202 /* Update page flags */ 203 if (!(*pte1p & 0x00000100)) { 204 /* Update accessed flag */ 205 *pte1p |= 0x00000100; 206 store = 1; 207 } 208 if (!(*pte1p & 0x00000080)) { 209 if (rw == 1 && ret == 0) { 210 /* Update changed flag */ 211 *pte1p |= 0x00000080; 212 store = 1; 213 } else { 214 /* Force page fault for first write access */ 215 ctx->prot &= ~PAGE_WRITE; 216 } 217 } 218 219 return store; 220 } 221 222 /* Software driven TLB helpers */ 223 static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, 224 int way, int is_code) 225 { 226 int nr; 227 228 /* Select TLB num in a way from address */ 229 nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1); 230 /* Select TLB way */ 231 nr += env->tlb_per_way * way; 232 /* 6xx have separate TLBs for instructions and data */ 233 if (is_code && env->id_tlbs == 1) { 234 nr += env->nb_tlb; 235 } 236 237 return nr; 238 } 239 240 static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env) 241 { 242 PowerPCCPU *cpu = ppc_env_get_cpu(env); 243 ppc6xx_tlb_t *tlb; 244 int nr, max; 245 246 /* LOG_SWTLB("Invalidate all TLBs\n"); */ 247 /* Invalidate all defined software TLB */ 248 max = env->nb_tlb; 249 if (env->id_tlbs == 1) { 250 max *= 2; 251 } 252 for (nr = 0; nr < max; nr++) { 253 tlb = &env->tlb.tlb6[nr]; 254 pte_invalidate(&tlb->pte0); 255 } 256 tlb_flush(CPU(cpu)); 257 } 258 259 static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env, 260 target_ulong eaddr, 261 int is_code, int match_epn) 262 { 263 #if !defined(FLUSH_ALL_TLBS) 264 CPUState *cs = CPU(ppc_env_get_cpu(env)); 265 ppc6xx_tlb_t *tlb; 266 int way, nr; 267 268 /* Invalidate ITLB + DTLB, all ways */ 269 for (way = 0; way < env->nb_ways; way++) { 270 nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code); 271 tlb = &env->tlb.tlb6[nr]; 272 if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) { 273 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr, 274 env->nb_tlb, eaddr); 275 pte_invalidate(&tlb->pte0); 276 tlb_flush_page(cs, tlb->EPN); 277 } 278 } 279 #else 280 /* XXX: PowerPC specification say this is valid as well */ 281 ppc6xx_tlb_invalidate_all(env); 282 #endif 283 } 284 285 static inline void ppc6xx_tlb_invalidate_virt(CPUPPCState *env, 286 target_ulong eaddr, int is_code) 287 { 288 ppc6xx_tlb_invalidate_virt2(env, eaddr, is_code, 0); 289 } 290 291 static void ppc6xx_tlb_store(CPUPPCState *env, target_ulong EPN, int way, 292 int is_code, target_ulong pte0, target_ulong pte1) 293 { 294 ppc6xx_tlb_t *tlb; 295 int nr; 296 297 nr = ppc6xx_tlb_getnum(env, EPN, way, is_code); 298 tlb = &env->tlb.tlb6[nr]; 299 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx 300 " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1); 301 /* Invalidate any pending reference in QEMU for this virtual address */ 302 ppc6xx_tlb_invalidate_virt2(env, EPN, is_code, 1); 303 tlb->pte0 = pte0; 304 tlb->pte1 = pte1; 305 tlb->EPN = EPN; 306 /* Store last way for LRU mechanism */ 307 env->last_way = way; 308 } 309 310 static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx, 311 target_ulong eaddr, int rw, int access_type) 312 { 313 ppc6xx_tlb_t *tlb; 314 int nr, best, way; 315 int ret; 316 317 best = -1; 318 ret = -1; /* No TLB found */ 319 for (way = 0; way < env->nb_ways; way++) { 320 nr = ppc6xx_tlb_getnum(env, eaddr, way, 321 access_type == ACCESS_CODE ? 1 : 0); 322 tlb = &env->tlb.tlb6[nr]; 323 /* This test "emulates" the PTE index match for hardware TLBs */ 324 if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) { 325 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx " " TARGET_FMT_lx 326 "] <> " TARGET_FMT_lx "\n", nr, env->nb_tlb, 327 pte_is_valid(tlb->pte0) ? "valid" : "inval", 328 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr); 329 continue; 330 } 331 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx " <> " TARGET_FMT_lx " " 332 TARGET_FMT_lx " %c %c\n", nr, env->nb_tlb, 333 pte_is_valid(tlb->pte0) ? "valid" : "inval", 334 tlb->EPN, eaddr, tlb->pte1, 335 rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D'); 336 switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1, 337 0, rw, access_type)) { 338 case -3: 339 /* TLB inconsistency */ 340 return -1; 341 case -2: 342 /* Access violation */ 343 ret = -2; 344 best = nr; 345 break; 346 case -1: 347 default: 348 /* No match */ 349 break; 350 case 0: 351 /* access granted */ 352 /* 353 * XXX: we should go on looping to check all TLBs 354 * consistency but we can speed-up the whole thing as 355 * the result would be undefined if TLBs are not 356 * consistent. 357 */ 358 ret = 0; 359 best = nr; 360 goto done; 361 } 362 } 363 if (best != -1) { 364 done: 365 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n", 366 ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret); 367 /* Update page flags */ 368 pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, rw); 369 } 370 371 return ret; 372 } 373 374 /* Perform BAT hit & translation */ 375 static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp, 376 int *validp, int *protp, target_ulong *BATu, 377 target_ulong *BATl) 378 { 379 target_ulong bl; 380 int pp, valid, prot; 381 382 bl = (*BATu & 0x00001FFC) << 15; 383 valid = 0; 384 prot = 0; 385 if (((msr_pr == 0) && (*BATu & 0x00000002)) || 386 ((msr_pr != 0) && (*BATu & 0x00000001))) { 387 valid = 1; 388 pp = *BATl & 0x00000003; 389 if (pp != 0) { 390 prot = PAGE_READ | PAGE_EXEC; 391 if (pp == 0x2) { 392 prot |= PAGE_WRITE; 393 } 394 } 395 } 396 *blp = bl; 397 *validp = valid; 398 *protp = prot; 399 } 400 401 static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, 402 target_ulong virtual, int rw, int type) 403 { 404 target_ulong *BATlt, *BATut, *BATu, *BATl; 405 target_ulong BEPIl, BEPIu, bl; 406 int i, valid, prot; 407 int ret = -1; 408 409 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__, 410 type == ACCESS_CODE ? 'I' : 'D', virtual); 411 switch (type) { 412 case ACCESS_CODE: 413 BATlt = env->IBAT[1]; 414 BATut = env->IBAT[0]; 415 break; 416 default: 417 BATlt = env->DBAT[1]; 418 BATut = env->DBAT[0]; 419 break; 420 } 421 for (i = 0; i < env->nb_BATs; i++) { 422 BATu = &BATut[i]; 423 BATl = &BATlt[i]; 424 BEPIu = *BATu & 0xF0000000; 425 BEPIl = *BATu & 0x0FFE0000; 426 bat_size_prot(env, &bl, &valid, &prot, BATu, BATl); 427 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx 428 " BATl " TARGET_FMT_lx "\n", __func__, 429 type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl); 430 if ((virtual & 0xF0000000) == BEPIu && 431 ((virtual & 0x0FFE0000) & ~bl) == BEPIl) { 432 /* BAT matches */ 433 if (valid != 0) { 434 /* Get physical address */ 435 ctx->raddr = (*BATl & 0xF0000000) | 436 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) | 437 (virtual & 0x0001F000); 438 /* Compute access rights */ 439 ctx->prot = prot; 440 ret = check_prot(ctx->prot, rw, type); 441 if (ret == 0) { 442 LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n", 443 i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-', 444 ctx->prot & PAGE_WRITE ? 'W' : '-'); 445 } 446 break; 447 } 448 } 449 } 450 if (ret < 0) { 451 #if defined(DEBUG_BATS) 452 if (qemu_log_enabled()) { 453 LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", virtual); 454 for (i = 0; i < 4; i++) { 455 BATu = &BATut[i]; 456 BATl = &BATlt[i]; 457 BEPIu = *BATu & 0xF0000000; 458 BEPIl = *BATu & 0x0FFE0000; 459 bl = (*BATu & 0x00001FFC) << 15; 460 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx 461 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " " 462 TARGET_FMT_lx " " TARGET_FMT_lx "\n", 463 __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual, 464 *BATu, *BATl, BEPIu, BEPIl, bl); 465 } 466 } 467 #endif 468 } 469 /* No hit */ 470 return ret; 471 } 472 473 /* Perform segment based translation */ 474 static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, 475 target_ulong eaddr, int rw, int type) 476 { 477 PowerPCCPU *cpu = ppc_env_get_cpu(env); 478 hwaddr hash; 479 target_ulong vsid; 480 int ds, pr, target_page_bits; 481 int ret; 482 target_ulong sr, pgidx; 483 484 pr = msr_pr; 485 ctx->eaddr = eaddr; 486 487 sr = env->sr[eaddr >> 28]; 488 ctx->key = (((sr & 0x20000000) && (pr != 0)) || 489 ((sr & 0x40000000) && (pr == 0))) ? 1 : 0; 490 ds = sr & 0x80000000 ? 1 : 0; 491 ctx->nx = sr & 0x10000000 ? 1 : 0; 492 vsid = sr & 0x00FFFFFF; 493 target_page_bits = TARGET_PAGE_BITS; 494 qemu_log_mask(CPU_LOG_MMU, 495 "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx 496 " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx 497 " ir=%d dr=%d pr=%d %d t=%d\n", 498 eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir, 499 (int)msr_dr, pr != 0 ? 1 : 0, rw, type); 500 pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits; 501 hash = vsid ^ pgidx; 502 ctx->ptem = (vsid << 7) | (pgidx >> 10); 503 504 qemu_log_mask(CPU_LOG_MMU, 505 "pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n", 506 ctx->key, ds, ctx->nx, vsid); 507 ret = -1; 508 if (!ds) { 509 /* Check if instruction fetch is allowed, if needed */ 510 if (type != ACCESS_CODE || ctx->nx == 0) { 511 /* Page address translation */ 512 qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx 513 " htab_mask " TARGET_FMT_plx 514 " hash " TARGET_FMT_plx "\n", 515 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash); 516 ctx->hash[0] = hash; 517 ctx->hash[1] = ~hash; 518 519 /* Initialize real address with an invalid value */ 520 ctx->raddr = (hwaddr)-1ULL; 521 /* Software TLB search */ 522 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type); 523 #if defined(DUMP_PAGE_TABLES) 524 if (qemu_loglevel_mask(CPU_LOG_MMU)) { 525 CPUState *cs = ENV_GET_CPU(env); 526 hwaddr curaddr; 527 uint32_t a0, a1, a2, a3; 528 529 qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx 530 "\n", ppc_hash32_hpt_base(cpu), 531 ppc_hash32_hpt_mask(env) + 0x80); 532 for (curaddr = ppc_hash32_hpt_base(cpu); 533 curaddr < (ppc_hash32_hpt_base(cpu) 534 + ppc_hash32_hpt_mask(cpu) + 0x80); 535 curaddr += 16) { 536 a0 = ldl_phys(cs->as, curaddr); 537 a1 = ldl_phys(cs->as, curaddr + 4); 538 a2 = ldl_phys(cs->as, curaddr + 8); 539 a3 = ldl_phys(cs->as, curaddr + 12); 540 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { 541 qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n", 542 curaddr, a0, a1, a2, a3); 543 } 544 } 545 } 546 #endif 547 } else { 548 qemu_log_mask(CPU_LOG_MMU, "No access allowed\n"); 549 ret = -3; 550 } 551 } else { 552 target_ulong sr; 553 554 qemu_log_mask(CPU_LOG_MMU, "direct store...\n"); 555 /* Direct-store segment : absolutely *BUGGY* for now */ 556 557 /* 558 * Direct-store implies a 32-bit MMU. 559 * Check the Segment Register's bus unit ID (BUID). 560 */ 561 sr = env->sr[eaddr >> 28]; 562 if ((sr & 0x1FF00000) >> 20 == 0x07f) { 563 /* 564 * Memory-forced I/O controller interface access 565 * 566 * If T=1 and BUID=x'07F', the 601 performs a memory 567 * access to SR[28-31] LA[4-31], bypassing all protection 568 * mechanisms. 569 */ 570 ctx->raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF); 571 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 572 return 0; 573 } 574 575 switch (type) { 576 case ACCESS_INT: 577 /* Integer load/store : only access allowed */ 578 break; 579 case ACCESS_CODE: 580 /* No code fetch is allowed in direct-store areas */ 581 return -4; 582 case ACCESS_FLOAT: 583 /* Floating point load/store */ 584 return -4; 585 case ACCESS_RES: 586 /* lwarx, ldarx or srwcx. */ 587 return -4; 588 case ACCESS_CACHE: 589 /* 590 * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi 591 * 592 * Should make the instruction do no-op. As it already do 593 * no-op, it's quite easy :-) 594 */ 595 ctx->raddr = eaddr; 596 return 0; 597 case ACCESS_EXT: 598 /* eciwx or ecowx */ 599 return -4; 600 default: 601 qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need " 602 "address translation\n"); 603 return -4; 604 } 605 if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) { 606 ctx->raddr = eaddr; 607 ret = 2; 608 } else { 609 ret = -2; 610 } 611 } 612 613 return ret; 614 } 615 616 /* Generic TLB check function for embedded PowerPC implementations */ 617 static int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb, 618 hwaddr *raddrp, 619 target_ulong address, uint32_t pid, int ext, 620 int i) 621 { 622 target_ulong mask; 623 624 /* Check valid flag */ 625 if (!(tlb->prot & PAGE_VALID)) { 626 return -1; 627 } 628 mask = ~(tlb->size - 1); 629 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx 630 " " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN, 631 mask, (uint32_t)tlb->PID, tlb->prot); 632 /* Check PID */ 633 if (tlb->PID != 0 && tlb->PID != pid) { 634 return -1; 635 } 636 /* Check effective address */ 637 if ((address & mask) != tlb->EPN) { 638 return -1; 639 } 640 *raddrp = (tlb->RPN & mask) | (address & ~mask); 641 if (ext) { 642 /* Extend the physical address to 36 bits */ 643 *raddrp |= (uint64_t)(tlb->RPN & 0xF) << 32; 644 } 645 646 return 0; 647 } 648 649 /* Generic TLB search function for PowerPC embedded implementations */ 650 static int ppcemb_tlb_search(CPUPPCState *env, target_ulong address, 651 uint32_t pid) 652 { 653 ppcemb_tlb_t *tlb; 654 hwaddr raddr; 655 int i, ret; 656 657 /* Default return value is no match */ 658 ret = -1; 659 for (i = 0; i < env->nb_tlb; i++) { 660 tlb = &env->tlb.tlbe[i]; 661 if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) { 662 ret = i; 663 break; 664 } 665 } 666 667 return ret; 668 } 669 670 /* Helpers specific to PowerPC 40x implementations */ 671 static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env) 672 { 673 PowerPCCPU *cpu = ppc_env_get_cpu(env); 674 ppcemb_tlb_t *tlb; 675 int i; 676 677 for (i = 0; i < env->nb_tlb; i++) { 678 tlb = &env->tlb.tlbe[i]; 679 tlb->prot &= ~PAGE_VALID; 680 } 681 tlb_flush(CPU(cpu)); 682 } 683 684 static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, 685 target_ulong address, int rw, 686 int access_type) 687 { 688 ppcemb_tlb_t *tlb; 689 hwaddr raddr; 690 int i, ret, zsel, zpr, pr; 691 692 ret = -1; 693 raddr = (hwaddr)-1ULL; 694 pr = msr_pr; 695 for (i = 0; i < env->nb_tlb; i++) { 696 tlb = &env->tlb.tlbe[i]; 697 if (ppcemb_tlb_check(env, tlb, &raddr, address, 698 env->spr[SPR_40x_PID], 0, i) < 0) { 699 continue; 700 } 701 zsel = (tlb->attr >> 4) & 0xF; 702 zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3; 703 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n", 704 __func__, i, zsel, zpr, rw, tlb->attr); 705 /* Check execute enable bit */ 706 switch (zpr) { 707 case 0x2: 708 if (pr != 0) { 709 goto check_perms; 710 } 711 /* No break here */ 712 case 0x3: 713 /* All accesses granted */ 714 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 715 ret = 0; 716 break; 717 case 0x0: 718 if (pr != 0) { 719 /* Raise Zone protection fault. */ 720 env->spr[SPR_40x_ESR] = 1 << 22; 721 ctx->prot = 0; 722 ret = -2; 723 break; 724 } 725 /* No break here */ 726 case 0x1: 727 check_perms: 728 /* Check from TLB entry */ 729 ctx->prot = tlb->prot; 730 ret = check_prot(ctx->prot, rw, access_type); 731 if (ret == -2) { 732 env->spr[SPR_40x_ESR] = 0; 733 } 734 break; 735 } 736 if (ret >= 0) { 737 ctx->raddr = raddr; 738 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx 739 " %d %d\n", __func__, address, ctx->raddr, ctx->prot, 740 ret); 741 return 0; 742 } 743 } 744 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx 745 " %d %d\n", __func__, address, raddr, ctx->prot, ret); 746 747 return ret; 748 } 749 750 void store_40x_sler(CPUPPCState *env, uint32_t val) 751 { 752 PowerPCCPU *cpu = ppc_env_get_cpu(env); 753 754 /* XXX: TO BE FIXED */ 755 if (val != 0x00000000) { 756 cpu_abort(CPU(cpu), "Little-endian regions are not supported by now\n"); 757 } 758 env->spr[SPR_405_SLER] = val; 759 } 760 761 static inline int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb, 762 hwaddr *raddr, int *prot, 763 target_ulong address, int rw, 764 int access_type, int i) 765 { 766 int ret, prot2; 767 768 if (ppcemb_tlb_check(env, tlb, raddr, address, 769 env->spr[SPR_BOOKE_PID], 770 !env->nb_pids, i) >= 0) { 771 goto found_tlb; 772 } 773 774 if (env->spr[SPR_BOOKE_PID1] && 775 ppcemb_tlb_check(env, tlb, raddr, address, 776 env->spr[SPR_BOOKE_PID1], 0, i) >= 0) { 777 goto found_tlb; 778 } 779 780 if (env->spr[SPR_BOOKE_PID2] && 781 ppcemb_tlb_check(env, tlb, raddr, address, 782 env->spr[SPR_BOOKE_PID2], 0, i) >= 0) { 783 goto found_tlb; 784 } 785 786 LOG_SWTLB("%s: TLB entry not found\n", __func__); 787 return -1; 788 789 found_tlb: 790 791 if (msr_pr != 0) { 792 prot2 = tlb->prot & 0xF; 793 } else { 794 prot2 = (tlb->prot >> 4) & 0xF; 795 } 796 797 /* Check the address space */ 798 if (access_type == ACCESS_CODE) { 799 if (msr_ir != (tlb->attr & 1)) { 800 LOG_SWTLB("%s: AS doesn't match\n", __func__); 801 return -1; 802 } 803 804 *prot = prot2; 805 if (prot2 & PAGE_EXEC) { 806 LOG_SWTLB("%s: good TLB!\n", __func__); 807 return 0; 808 } 809 810 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2); 811 ret = -3; 812 } else { 813 if (msr_dr != (tlb->attr & 1)) { 814 LOG_SWTLB("%s: AS doesn't match\n", __func__); 815 return -1; 816 } 817 818 *prot = prot2; 819 if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) { 820 LOG_SWTLB("%s: found TLB!\n", __func__); 821 return 0; 822 } 823 824 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2); 825 ret = -2; 826 } 827 828 return ret; 829 } 830 831 static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, 832 target_ulong address, int rw, 833 int access_type) 834 { 835 ppcemb_tlb_t *tlb; 836 hwaddr raddr; 837 int i, ret; 838 839 ret = -1; 840 raddr = (hwaddr)-1ULL; 841 for (i = 0; i < env->nb_tlb; i++) { 842 tlb = &env->tlb.tlbe[i]; 843 ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw, 844 access_type, i); 845 if (ret != -1) { 846 break; 847 } 848 } 849 850 if (ret >= 0) { 851 ctx->raddr = raddr; 852 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx 853 " %d %d\n", __func__, address, ctx->raddr, ctx->prot, 854 ret); 855 } else { 856 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx 857 " %d %d\n", __func__, address, raddr, ctx->prot, ret); 858 } 859 860 return ret; 861 } 862 863 static void booke206_flush_tlb(CPUPPCState *env, int flags, 864 const int check_iprot) 865 { 866 PowerPCCPU *cpu = ppc_env_get_cpu(env); 867 int tlb_size; 868 int i, j; 869 ppcmas_tlb_t *tlb = env->tlb.tlbm; 870 871 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 872 if (flags & (1 << i)) { 873 tlb_size = booke206_tlb_size(env, i); 874 for (j = 0; j < tlb_size; j++) { 875 if (!check_iprot || !(tlb[j].mas1 & MAS1_IPROT)) { 876 tlb[j].mas1 &= ~MAS1_VALID; 877 } 878 } 879 } 880 tlb += booke206_tlb_size(env, i); 881 } 882 883 tlb_flush(CPU(cpu)); 884 } 885 886 static hwaddr booke206_tlb_to_page_size(CPUPPCState *env, 887 ppcmas_tlb_t *tlb) 888 { 889 int tlbm_size; 890 891 tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; 892 893 return 1024ULL << tlbm_size; 894 } 895 896 /* TLB check function for MAS based SoftTLBs */ 897 static int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb, 898 hwaddr *raddrp, target_ulong address, 899 uint32_t pid) 900 { 901 hwaddr mask; 902 uint32_t tlb_pid; 903 904 if (!msr_cm) { 905 /* In 32bit mode we can only address 32bit EAs */ 906 address = (uint32_t)address; 907 } 908 909 /* Check valid flag */ 910 if (!(tlb->mas1 & MAS1_VALID)) { 911 return -1; 912 } 913 914 mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); 915 LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx " PID=0x%x MAS1=0x%x MAS2=0x%" 916 PRIx64 " mask=0x%" HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%" 917 PRIx32 "\n", __func__, address, pid, tlb->mas1, tlb->mas2, mask, 918 tlb->mas7_3, tlb->mas8); 919 920 /* Check PID */ 921 tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT; 922 if (tlb_pid != 0 && tlb_pid != pid) { 923 return -1; 924 } 925 926 /* Check effective address */ 927 if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) { 928 return -1; 929 } 930 931 if (raddrp) { 932 *raddrp = (tlb->mas7_3 & mask) | (address & ~mask); 933 } 934 935 return 0; 936 } 937 938 static bool is_epid_mmu(int mmu_idx) 939 { 940 return mmu_idx == PPC_TLB_EPID_STORE || mmu_idx == PPC_TLB_EPID_LOAD; 941 } 942 943 static uint32_t mmubooke206_esr(int mmu_idx, bool rw) 944 { 945 uint32_t esr = 0; 946 if (rw) { 947 esr |= ESR_ST; 948 } 949 if (is_epid_mmu(mmu_idx)) { 950 esr |= ESR_EPID; 951 } 952 return esr; 953 } 954 955 /* 956 * Get EPID register given the mmu_idx. If this is regular load, 957 * construct the EPID access bits from current processor state 958 * 959 * Get the effective AS and PR bits and the PID. The PID is returned 960 * only if EPID load is requested, otherwise the caller must detect 961 * the correct EPID. Return true if valid EPID is returned. 962 */ 963 static bool mmubooke206_get_as(CPUPPCState *env, 964 int mmu_idx, uint32_t *epid_out, 965 bool *as_out, bool *pr_out) 966 { 967 if (is_epid_mmu(mmu_idx)) { 968 uint32_t epidr; 969 if (mmu_idx == PPC_TLB_EPID_STORE) { 970 epidr = env->spr[SPR_BOOKE_EPSC]; 971 } else { 972 epidr = env->spr[SPR_BOOKE_EPLC]; 973 } 974 *epid_out = (epidr & EPID_EPID) >> EPID_EPID_SHIFT; 975 *as_out = !!(epidr & EPID_EAS); 976 *pr_out = !!(epidr & EPID_EPR); 977 return true; 978 } else { 979 *as_out = msr_ds; 980 *pr_out = msr_pr; 981 return false; 982 } 983 } 984 985 /* Check if the tlb found by hashing really matches */ 986 static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb, 987 hwaddr *raddr, int *prot, 988 target_ulong address, int rw, 989 int access_type, int mmu_idx) 990 { 991 int ret; 992 int prot2 = 0; 993 uint32_t epid; 994 bool as, pr; 995 bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr); 996 997 if (!use_epid) { 998 if (ppcmas_tlb_check(env, tlb, raddr, address, 999 env->spr[SPR_BOOKE_PID]) >= 0) { 1000 goto found_tlb; 1001 } 1002 1003 if (env->spr[SPR_BOOKE_PID1] && 1004 ppcmas_tlb_check(env, tlb, raddr, address, 1005 env->spr[SPR_BOOKE_PID1]) >= 0) { 1006 goto found_tlb; 1007 } 1008 1009 if (env->spr[SPR_BOOKE_PID2] && 1010 ppcmas_tlb_check(env, tlb, raddr, address, 1011 env->spr[SPR_BOOKE_PID2]) >= 0) { 1012 goto found_tlb; 1013 } 1014 } else { 1015 if (ppcmas_tlb_check(env, tlb, raddr, address, epid) >= 0) { 1016 goto found_tlb; 1017 } 1018 } 1019 1020 LOG_SWTLB("%s: TLB entry not found\n", __func__); 1021 return -1; 1022 1023 found_tlb: 1024 1025 if (pr) { 1026 if (tlb->mas7_3 & MAS3_UR) { 1027 prot2 |= PAGE_READ; 1028 } 1029 if (tlb->mas7_3 & MAS3_UW) { 1030 prot2 |= PAGE_WRITE; 1031 } 1032 if (tlb->mas7_3 & MAS3_UX) { 1033 prot2 |= PAGE_EXEC; 1034 } 1035 } else { 1036 if (tlb->mas7_3 & MAS3_SR) { 1037 prot2 |= PAGE_READ; 1038 } 1039 if (tlb->mas7_3 & MAS3_SW) { 1040 prot2 |= PAGE_WRITE; 1041 } 1042 if (tlb->mas7_3 & MAS3_SX) { 1043 prot2 |= PAGE_EXEC; 1044 } 1045 } 1046 1047 /* Check the address space and permissions */ 1048 if (access_type == ACCESS_CODE) { 1049 /* There is no way to fetch code using epid load */ 1050 assert(!use_epid); 1051 if (msr_ir != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { 1052 LOG_SWTLB("%s: AS doesn't match\n", __func__); 1053 return -1; 1054 } 1055 1056 *prot = prot2; 1057 if (prot2 & PAGE_EXEC) { 1058 LOG_SWTLB("%s: good TLB!\n", __func__); 1059 return 0; 1060 } 1061 1062 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2); 1063 ret = -3; 1064 } else { 1065 if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { 1066 LOG_SWTLB("%s: AS doesn't match\n", __func__); 1067 return -1; 1068 } 1069 1070 *prot = prot2; 1071 if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) { 1072 LOG_SWTLB("%s: found TLB!\n", __func__); 1073 return 0; 1074 } 1075 1076 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2); 1077 ret = -2; 1078 } 1079 1080 return ret; 1081 } 1082 1083 static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, 1084 target_ulong address, int rw, 1085 int access_type, int mmu_idx) 1086 { 1087 ppcmas_tlb_t *tlb; 1088 hwaddr raddr; 1089 int i, j, ret; 1090 1091 ret = -1; 1092 raddr = (hwaddr)-1ULL; 1093 1094 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 1095 int ways = booke206_tlb_ways(env, i); 1096 1097 for (j = 0; j < ways; j++) { 1098 tlb = booke206_get_tlbm(env, i, address, j); 1099 if (!tlb) { 1100 continue; 1101 } 1102 ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address, 1103 rw, access_type, mmu_idx); 1104 if (ret != -1) { 1105 goto found_tlb; 1106 } 1107 } 1108 } 1109 1110 found_tlb: 1111 1112 if (ret >= 0) { 1113 ctx->raddr = raddr; 1114 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx 1115 " %d %d\n", __func__, address, ctx->raddr, ctx->prot, 1116 ret); 1117 } else { 1118 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx 1119 " %d %d\n", __func__, address, raddr, ctx->prot, ret); 1120 } 1121 1122 return ret; 1123 } 1124 1125 static const char *book3e_tsize_to_str[32] = { 1126 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", 1127 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", 1128 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G", 1129 "1T", "2T" 1130 }; 1131 1132 static void mmubooke_dump_mmu(CPUPPCState *env) 1133 { 1134 ppcemb_tlb_t *entry; 1135 int i; 1136 1137 if (kvm_enabled() && !env->kvm_sw_tlb) { 1138 qemu_printf("Cannot access KVM TLB\n"); 1139 return; 1140 } 1141 1142 qemu_printf("\nTLB:\n"); 1143 qemu_printf("Effective Physical Size PID Prot " 1144 "Attr\n"); 1145 1146 entry = &env->tlb.tlbe[0]; 1147 for (i = 0; i < env->nb_tlb; i++, entry++) { 1148 hwaddr ea, pa; 1149 target_ulong mask; 1150 uint64_t size = (uint64_t)entry->size; 1151 char size_buf[20]; 1152 1153 /* Check valid flag */ 1154 if (!(entry->prot & PAGE_VALID)) { 1155 continue; 1156 } 1157 1158 mask = ~(entry->size - 1); 1159 ea = entry->EPN & mask; 1160 pa = entry->RPN & mask; 1161 /* Extend the physical address to 36 bits */ 1162 pa |= (hwaddr)(entry->RPN & 0xF) << 32; 1163 if (size >= 1 * MiB) { 1164 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB); 1165 } else { 1166 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB); 1167 } 1168 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n", 1169 (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID, 1170 entry->prot, entry->attr); 1171 } 1172 1173 } 1174 1175 static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset, 1176 int tlbsize) 1177 { 1178 ppcmas_tlb_t *entry; 1179 int i; 1180 1181 qemu_printf("\nTLB%d:\n", tlbn); 1182 qemu_printf("Effective Physical Size TID TS SRWX" 1183 " URWX WIMGE U0123\n"); 1184 1185 entry = &env->tlb.tlbm[offset]; 1186 for (i = 0; i < tlbsize; i++, entry++) { 1187 hwaddr ea, pa, size; 1188 int tsize; 1189 1190 if (!(entry->mas1 & MAS1_VALID)) { 1191 continue; 1192 } 1193 1194 tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; 1195 size = 1024ULL << tsize; 1196 ea = entry->mas2 & ~(size - 1); 1197 pa = entry->mas7_3 & ~(size - 1); 1198 1199 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c" 1200 "U%c%c%c %c%c%c%c%c U%c%c%c%c\n", 1201 (uint64_t)ea, (uint64_t)pa, 1202 book3e_tsize_to_str[tsize], 1203 (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT, 1204 (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT, 1205 entry->mas7_3 & MAS3_SR ? 'R' : '-', 1206 entry->mas7_3 & MAS3_SW ? 'W' : '-', 1207 entry->mas7_3 & MAS3_SX ? 'X' : '-', 1208 entry->mas7_3 & MAS3_UR ? 'R' : '-', 1209 entry->mas7_3 & MAS3_UW ? 'W' : '-', 1210 entry->mas7_3 & MAS3_UX ? 'X' : '-', 1211 entry->mas2 & MAS2_W ? 'W' : '-', 1212 entry->mas2 & MAS2_I ? 'I' : '-', 1213 entry->mas2 & MAS2_M ? 'M' : '-', 1214 entry->mas2 & MAS2_G ? 'G' : '-', 1215 entry->mas2 & MAS2_E ? 'E' : '-', 1216 entry->mas7_3 & MAS3_U0 ? '0' : '-', 1217 entry->mas7_3 & MAS3_U1 ? '1' : '-', 1218 entry->mas7_3 & MAS3_U2 ? '2' : '-', 1219 entry->mas7_3 & MAS3_U3 ? '3' : '-'); 1220 } 1221 } 1222 1223 static void mmubooke206_dump_mmu(CPUPPCState *env) 1224 { 1225 int offset = 0; 1226 int i; 1227 1228 if (kvm_enabled() && !env->kvm_sw_tlb) { 1229 qemu_printf("Cannot access KVM TLB\n"); 1230 return; 1231 } 1232 1233 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 1234 int size = booke206_tlb_size(env, i); 1235 1236 if (size == 0) { 1237 continue; 1238 } 1239 1240 mmubooke206_dump_one_tlb(env, i, offset, size); 1241 offset += size; 1242 } 1243 } 1244 1245 static void mmu6xx_dump_BATs(CPUPPCState *env, int type) 1246 { 1247 target_ulong *BATlt, *BATut, *BATu, *BATl; 1248 target_ulong BEPIl, BEPIu, bl; 1249 int i; 1250 1251 switch (type) { 1252 case ACCESS_CODE: 1253 BATlt = env->IBAT[1]; 1254 BATut = env->IBAT[0]; 1255 break; 1256 default: 1257 BATlt = env->DBAT[1]; 1258 BATut = env->DBAT[0]; 1259 break; 1260 } 1261 1262 for (i = 0; i < env->nb_BATs; i++) { 1263 BATu = &BATut[i]; 1264 BATl = &BATlt[i]; 1265 BEPIu = *BATu & 0xF0000000; 1266 BEPIl = *BATu & 0x0FFE0000; 1267 bl = (*BATu & 0x00001FFC) << 15; 1268 qemu_printf("%s BAT%d BATu " TARGET_FMT_lx 1269 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " " 1270 TARGET_FMT_lx " " TARGET_FMT_lx "\n", 1271 type == ACCESS_CODE ? "code" : "data", i, 1272 *BATu, *BATl, BEPIu, BEPIl, bl); 1273 } 1274 } 1275 1276 static void mmu6xx_dump_mmu(CPUPPCState *env) 1277 { 1278 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1279 ppc6xx_tlb_t *tlb; 1280 target_ulong sr; 1281 int type, way, entry, i; 1282 1283 qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu)); 1284 qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu)); 1285 1286 qemu_printf("\nSegment registers:\n"); 1287 for (i = 0; i < 32; i++) { 1288 sr = env->sr[i]; 1289 if (sr & 0x80000000) { 1290 qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x " 1291 "CNTLR_SPEC=0x%05x\n", i, 1292 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0, 1293 sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF), 1294 (uint32_t)(sr & 0xFFFFF)); 1295 } else { 1296 qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i, 1297 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0, 1298 sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0, 1299 (uint32_t)(sr & 0x00FFFFFF)); 1300 } 1301 } 1302 1303 qemu_printf("\nBATs:\n"); 1304 mmu6xx_dump_BATs(env, ACCESS_INT); 1305 mmu6xx_dump_BATs(env, ACCESS_CODE); 1306 1307 if (env->id_tlbs != 1) { 1308 qemu_printf("ERROR: 6xx MMU should have separated TLB" 1309 " for code and data\n"); 1310 } 1311 1312 qemu_printf("\nTLBs [EPN EPN + SIZE]\n"); 1313 1314 for (type = 0; type < 2; type++) { 1315 for (way = 0; way < env->nb_ways; way++) { 1316 for (entry = env->nb_tlb * type + env->tlb_per_way * way; 1317 entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1)); 1318 entry++) { 1319 1320 tlb = &env->tlb.tlb6[entry]; 1321 qemu_printf("%s TLB %02d/%02d way:%d %s [" 1322 TARGET_FMT_lx " " TARGET_FMT_lx "]\n", 1323 type ? "code" : "data", entry % env->nb_tlb, 1324 env->nb_tlb, way, 1325 pte_is_valid(tlb->pte0) ? "valid" : "inval", 1326 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE); 1327 } 1328 } 1329 } 1330 } 1331 1332 void dump_mmu(CPUPPCState *env) 1333 { 1334 switch (env->mmu_model) { 1335 case POWERPC_MMU_BOOKE: 1336 mmubooke_dump_mmu(env); 1337 break; 1338 case POWERPC_MMU_BOOKE206: 1339 mmubooke206_dump_mmu(env); 1340 break; 1341 case POWERPC_MMU_SOFT_6xx: 1342 case POWERPC_MMU_SOFT_74xx: 1343 mmu6xx_dump_mmu(env); 1344 break; 1345 #if defined(TARGET_PPC64) 1346 case POWERPC_MMU_64B: 1347 case POWERPC_MMU_2_03: 1348 case POWERPC_MMU_2_06: 1349 case POWERPC_MMU_2_07: 1350 dump_slb(ppc_env_get_cpu(env)); 1351 break; 1352 case POWERPC_MMU_3_00: 1353 if (ppc64_v3_radix(ppc_env_get_cpu(env))) { 1354 /* TODO - Unsupported */ 1355 } else { 1356 dump_slb(ppc_env_get_cpu(env)); 1357 break; 1358 } 1359 #endif 1360 default: 1361 qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__); 1362 } 1363 } 1364 1365 static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, 1366 target_ulong eaddr, int rw) 1367 { 1368 int in_plb, ret; 1369 1370 ctx->raddr = eaddr; 1371 ctx->prot = PAGE_READ | PAGE_EXEC; 1372 ret = 0; 1373 switch (env->mmu_model) { 1374 case POWERPC_MMU_SOFT_6xx: 1375 case POWERPC_MMU_SOFT_74xx: 1376 case POWERPC_MMU_SOFT_4xx: 1377 case POWERPC_MMU_REAL: 1378 case POWERPC_MMU_BOOKE: 1379 ctx->prot |= PAGE_WRITE; 1380 break; 1381 1382 case POWERPC_MMU_SOFT_4xx_Z: 1383 if (unlikely(msr_pe != 0)) { 1384 /* 1385 * 403 family add some particular protections, using 1386 * PBL/PBU registers for accesses with no translation. 1387 */ 1388 in_plb = 1389 /* Check PLB validity */ 1390 (env->pb[0] < env->pb[1] && 1391 /* and address in plb area */ 1392 eaddr >= env->pb[0] && eaddr < env->pb[1]) || 1393 (env->pb[2] < env->pb[3] && 1394 eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0; 1395 if (in_plb ^ msr_px) { 1396 /* Access in protected area */ 1397 if (rw == 1) { 1398 /* Access is not allowed */ 1399 ret = -2; 1400 } 1401 } else { 1402 /* Read-write access is allowed */ 1403 ctx->prot |= PAGE_WRITE; 1404 } 1405 } 1406 break; 1407 1408 default: 1409 /* Caller's checks mean we should never get here for other models */ 1410 abort(); 1411 return -1; 1412 } 1413 1414 return ret; 1415 } 1416 1417 static int get_physical_address_wtlb( 1418 CPUPPCState *env, mmu_ctx_t *ctx, 1419 target_ulong eaddr, int rw, int access_type, 1420 int mmu_idx) 1421 { 1422 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1423 int ret = -1; 1424 bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0) 1425 || (access_type != ACCESS_CODE && msr_dr == 0); 1426 1427 switch (env->mmu_model) { 1428 case POWERPC_MMU_SOFT_6xx: 1429 case POWERPC_MMU_SOFT_74xx: 1430 if (real_mode) { 1431 ret = check_physical(env, ctx, eaddr, rw); 1432 } else { 1433 /* Try to find a BAT */ 1434 if (env->nb_BATs != 0) { 1435 ret = get_bat_6xx_tlb(env, ctx, eaddr, rw, access_type); 1436 } 1437 if (ret < 0) { 1438 /* We didn't match any BAT entry or don't have BATs */ 1439 ret = get_segment_6xx_tlb(env, ctx, eaddr, rw, access_type); 1440 } 1441 } 1442 break; 1443 1444 case POWERPC_MMU_SOFT_4xx: 1445 case POWERPC_MMU_SOFT_4xx_Z: 1446 if (real_mode) { 1447 ret = check_physical(env, ctx, eaddr, rw); 1448 } else { 1449 ret = mmu40x_get_physical_address(env, ctx, eaddr, 1450 rw, access_type); 1451 } 1452 break; 1453 case POWERPC_MMU_BOOKE: 1454 ret = mmubooke_get_physical_address(env, ctx, eaddr, 1455 rw, access_type); 1456 break; 1457 case POWERPC_MMU_BOOKE206: 1458 ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw, 1459 access_type, mmu_idx); 1460 break; 1461 case POWERPC_MMU_MPC8xx: 1462 /* XXX: TODO */ 1463 cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n"); 1464 break; 1465 case POWERPC_MMU_REAL: 1466 if (real_mode) { 1467 ret = check_physical(env, ctx, eaddr, rw); 1468 } else { 1469 cpu_abort(CPU(cpu), 1470 "PowerPC in real mode do not do any translation\n"); 1471 } 1472 return -1; 1473 default: 1474 cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n"); 1475 return -1; 1476 } 1477 1478 return ret; 1479 } 1480 1481 static int get_physical_address( 1482 CPUPPCState *env, mmu_ctx_t *ctx, 1483 target_ulong eaddr, int rw, int access_type) 1484 { 1485 return get_physical_address_wtlb(env, ctx, eaddr, rw, access_type, 0); 1486 } 1487 1488 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) 1489 { 1490 PowerPCCPU *cpu = POWERPC_CPU(cs); 1491 CPUPPCState *env = &cpu->env; 1492 mmu_ctx_t ctx; 1493 1494 switch (env->mmu_model) { 1495 #if defined(TARGET_PPC64) 1496 case POWERPC_MMU_64B: 1497 case POWERPC_MMU_2_03: 1498 case POWERPC_MMU_2_06: 1499 case POWERPC_MMU_2_07: 1500 return ppc_hash64_get_phys_page_debug(cpu, addr); 1501 case POWERPC_MMU_3_00: 1502 return ppc64_v3_get_phys_page_debug(cpu, addr); 1503 #endif 1504 1505 case POWERPC_MMU_32B: 1506 case POWERPC_MMU_601: 1507 return ppc_hash32_get_phys_page_debug(cpu, addr); 1508 1509 default: 1510 ; 1511 } 1512 1513 if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) { 1514 1515 /* 1516 * Some MMUs have separate TLBs for code and data. If we only 1517 * try an ACCESS_INT, we may not be able to read instructions 1518 * mapped by code TLBs, so we also try a ACCESS_CODE. 1519 */ 1520 if (unlikely(get_physical_address(env, &ctx, addr, 0, 1521 ACCESS_CODE) != 0)) { 1522 return -1; 1523 } 1524 } 1525 1526 return ctx.raddr & TARGET_PAGE_MASK; 1527 } 1528 1529 static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address, 1530 int rw, int mmu_idx) 1531 { 1532 uint32_t epid; 1533 bool as, pr; 1534 uint32_t missed_tid = 0; 1535 bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr); 1536 if (rw == 2) { 1537 as = msr_ir; 1538 } 1539 env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK; 1540 env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK; 1541 env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK; 1542 env->spr[SPR_BOOKE_MAS3] = 0; 1543 env->spr[SPR_BOOKE_MAS6] = 0; 1544 env->spr[SPR_BOOKE_MAS7] = 0; 1545 1546 /* AS */ 1547 if (as) { 1548 env->spr[SPR_BOOKE_MAS1] |= MAS1_TS; 1549 env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS; 1550 } 1551 1552 env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID; 1553 env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK; 1554 1555 if (!use_epid) { 1556 switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) { 1557 case MAS4_TIDSELD_PID0: 1558 missed_tid = env->spr[SPR_BOOKE_PID]; 1559 break; 1560 case MAS4_TIDSELD_PID1: 1561 missed_tid = env->spr[SPR_BOOKE_PID1]; 1562 break; 1563 case MAS4_TIDSELD_PID2: 1564 missed_tid = env->spr[SPR_BOOKE_PID2]; 1565 break; 1566 } 1567 env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16; 1568 } else { 1569 missed_tid = epid; 1570 env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16; 1571 } 1572 env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT); 1573 1574 1575 /* next victim logic */ 1576 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT; 1577 env->last_way++; 1578 env->last_way &= booke206_tlb_ways(env, 0) - 1; 1579 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; 1580 } 1581 1582 /* Perform address translation */ 1583 static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, 1584 int rw, int mmu_idx) 1585 { 1586 CPUState *cs = CPU(ppc_env_get_cpu(env)); 1587 PowerPCCPU *cpu = POWERPC_CPU(cs); 1588 mmu_ctx_t ctx; 1589 int access_type; 1590 int ret = 0; 1591 1592 if (rw == 2) { 1593 /* code access */ 1594 rw = 0; 1595 access_type = ACCESS_CODE; 1596 } else { 1597 /* data access */ 1598 access_type = env->access_type; 1599 } 1600 ret = get_physical_address_wtlb(env, &ctx, address, rw, 1601 access_type, mmu_idx); 1602 if (ret == 0) { 1603 tlb_set_page(cs, address & TARGET_PAGE_MASK, 1604 ctx.raddr & TARGET_PAGE_MASK, ctx.prot, 1605 mmu_idx, TARGET_PAGE_SIZE); 1606 ret = 0; 1607 } else if (ret < 0) { 1608 LOG_MMU_STATE(cs); 1609 if (access_type == ACCESS_CODE) { 1610 switch (ret) { 1611 case -1: 1612 /* No matches in page tables or TLB */ 1613 switch (env->mmu_model) { 1614 case POWERPC_MMU_SOFT_6xx: 1615 cs->exception_index = POWERPC_EXCP_IFTLB; 1616 env->error_code = 1 << 18; 1617 env->spr[SPR_IMISS] = address; 1618 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; 1619 goto tlb_miss; 1620 case POWERPC_MMU_SOFT_74xx: 1621 cs->exception_index = POWERPC_EXCP_IFTLB; 1622 goto tlb_miss_74xx; 1623 case POWERPC_MMU_SOFT_4xx: 1624 case POWERPC_MMU_SOFT_4xx_Z: 1625 cs->exception_index = POWERPC_EXCP_ITLB; 1626 env->error_code = 0; 1627 env->spr[SPR_40x_DEAR] = address; 1628 env->spr[SPR_40x_ESR] = 0x00000000; 1629 break; 1630 case POWERPC_MMU_BOOKE206: 1631 booke206_update_mas_tlb_miss(env, address, 2, mmu_idx); 1632 /* fall through */ 1633 case POWERPC_MMU_BOOKE: 1634 cs->exception_index = POWERPC_EXCP_ITLB; 1635 env->error_code = 0; 1636 env->spr[SPR_BOOKE_DEAR] = address; 1637 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, 0); 1638 return -1; 1639 case POWERPC_MMU_MPC8xx: 1640 /* XXX: TODO */ 1641 cpu_abort(cs, "MPC8xx MMU model is not implemented\n"); 1642 break; 1643 case POWERPC_MMU_REAL: 1644 cpu_abort(cs, "PowerPC in real mode should never raise " 1645 "any MMU exceptions\n"); 1646 return -1; 1647 default: 1648 cpu_abort(cs, "Unknown or invalid MMU model\n"); 1649 return -1; 1650 } 1651 break; 1652 case -2: 1653 /* Access rights violation */ 1654 cs->exception_index = POWERPC_EXCP_ISI; 1655 env->error_code = 0x08000000; 1656 break; 1657 case -3: 1658 /* No execute protection violation */ 1659 if ((env->mmu_model == POWERPC_MMU_BOOKE) || 1660 (env->mmu_model == POWERPC_MMU_BOOKE206)) { 1661 env->spr[SPR_BOOKE_ESR] = 0x00000000; 1662 } 1663 cs->exception_index = POWERPC_EXCP_ISI; 1664 env->error_code = 0x10000000; 1665 break; 1666 case -4: 1667 /* Direct store exception */ 1668 /* No code fetch is allowed in direct-store areas */ 1669 cs->exception_index = POWERPC_EXCP_ISI; 1670 env->error_code = 0x10000000; 1671 break; 1672 } 1673 } else { 1674 switch (ret) { 1675 case -1: 1676 /* No matches in page tables or TLB */ 1677 switch (env->mmu_model) { 1678 case POWERPC_MMU_SOFT_6xx: 1679 if (rw == 1) { 1680 cs->exception_index = POWERPC_EXCP_DSTLB; 1681 env->error_code = 1 << 16; 1682 } else { 1683 cs->exception_index = POWERPC_EXCP_DLTLB; 1684 env->error_code = 0; 1685 } 1686 env->spr[SPR_DMISS] = address; 1687 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem; 1688 tlb_miss: 1689 env->error_code |= ctx.key << 19; 1690 env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) + 1691 get_pteg_offset32(cpu, ctx.hash[0]); 1692 env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) + 1693 get_pteg_offset32(cpu, ctx.hash[1]); 1694 break; 1695 case POWERPC_MMU_SOFT_74xx: 1696 if (rw == 1) { 1697 cs->exception_index = POWERPC_EXCP_DSTLB; 1698 } else { 1699 cs->exception_index = POWERPC_EXCP_DLTLB; 1700 } 1701 tlb_miss_74xx: 1702 /* Implement LRU algorithm */ 1703 env->error_code = ctx.key << 19; 1704 env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) | 1705 ((env->last_way + 1) & (env->nb_ways - 1)); 1706 env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem; 1707 break; 1708 case POWERPC_MMU_SOFT_4xx: 1709 case POWERPC_MMU_SOFT_4xx_Z: 1710 cs->exception_index = POWERPC_EXCP_DTLB; 1711 env->error_code = 0; 1712 env->spr[SPR_40x_DEAR] = address; 1713 if (rw) { 1714 env->spr[SPR_40x_ESR] = 0x00800000; 1715 } else { 1716 env->spr[SPR_40x_ESR] = 0x00000000; 1717 } 1718 break; 1719 case POWERPC_MMU_MPC8xx: 1720 /* XXX: TODO */ 1721 cpu_abort(cs, "MPC8xx MMU model is not implemented\n"); 1722 break; 1723 case POWERPC_MMU_BOOKE206: 1724 booke206_update_mas_tlb_miss(env, address, rw, mmu_idx); 1725 /* fall through */ 1726 case POWERPC_MMU_BOOKE: 1727 cs->exception_index = POWERPC_EXCP_DTLB; 1728 env->error_code = 0; 1729 env->spr[SPR_BOOKE_DEAR] = address; 1730 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, rw); 1731 return -1; 1732 case POWERPC_MMU_REAL: 1733 cpu_abort(cs, "PowerPC in real mode should never raise " 1734 "any MMU exceptions\n"); 1735 return -1; 1736 default: 1737 cpu_abort(cs, "Unknown or invalid MMU model\n"); 1738 return -1; 1739 } 1740 break; 1741 case -2: 1742 /* Access rights violation */ 1743 cs->exception_index = POWERPC_EXCP_DSI; 1744 env->error_code = 0; 1745 if (env->mmu_model == POWERPC_MMU_SOFT_4xx 1746 || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) { 1747 env->spr[SPR_40x_DEAR] = address; 1748 if (rw) { 1749 env->spr[SPR_40x_ESR] |= 0x00800000; 1750 } 1751 } else if ((env->mmu_model == POWERPC_MMU_BOOKE) || 1752 (env->mmu_model == POWERPC_MMU_BOOKE206)) { 1753 env->spr[SPR_BOOKE_DEAR] = address; 1754 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, rw); 1755 } else { 1756 env->spr[SPR_DAR] = address; 1757 if (rw == 1) { 1758 env->spr[SPR_DSISR] = 0x0A000000; 1759 } else { 1760 env->spr[SPR_DSISR] = 0x08000000; 1761 } 1762 } 1763 break; 1764 case -4: 1765 /* Direct store exception */ 1766 switch (access_type) { 1767 case ACCESS_FLOAT: 1768 /* Floating point load/store */ 1769 cs->exception_index = POWERPC_EXCP_ALIGN; 1770 env->error_code = POWERPC_EXCP_ALIGN_FP; 1771 env->spr[SPR_DAR] = address; 1772 break; 1773 case ACCESS_RES: 1774 /* lwarx, ldarx or stwcx. */ 1775 cs->exception_index = POWERPC_EXCP_DSI; 1776 env->error_code = 0; 1777 env->spr[SPR_DAR] = address; 1778 if (rw == 1) { 1779 env->spr[SPR_DSISR] = 0x06000000; 1780 } else { 1781 env->spr[SPR_DSISR] = 0x04000000; 1782 } 1783 break; 1784 case ACCESS_EXT: 1785 /* eciwx or ecowx */ 1786 cs->exception_index = POWERPC_EXCP_DSI; 1787 env->error_code = 0; 1788 env->spr[SPR_DAR] = address; 1789 if (rw == 1) { 1790 env->spr[SPR_DSISR] = 0x06100000; 1791 } else { 1792 env->spr[SPR_DSISR] = 0x04100000; 1793 } 1794 break; 1795 default: 1796 printf("DSI: invalid exception (%d)\n", ret); 1797 cs->exception_index = POWERPC_EXCP_PROGRAM; 1798 env->error_code = 1799 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL; 1800 env->spr[SPR_DAR] = address; 1801 break; 1802 } 1803 break; 1804 } 1805 } 1806 ret = 1; 1807 } 1808 1809 return ret; 1810 } 1811 1812 /*****************************************************************************/ 1813 /* BATs management */ 1814 #if !defined(FLUSH_ALL_TLBS) 1815 static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu, 1816 target_ulong mask) 1817 { 1818 CPUState *cs = CPU(ppc_env_get_cpu(env)); 1819 target_ulong base, end, page; 1820 1821 base = BATu & ~0x0001FFFF; 1822 end = base + mask + 0x00020000; 1823 LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " (" 1824 TARGET_FMT_lx ")\n", base, end, mask); 1825 for (page = base; page != end; page += TARGET_PAGE_SIZE) { 1826 tlb_flush_page(cs, page); 1827 } 1828 LOG_BATS("Flush done\n"); 1829 } 1830 #endif 1831 1832 static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr, 1833 target_ulong value) 1834 { 1835 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", ID, 1836 nr, ul == 0 ? 'u' : 'l', value, env->nip); 1837 } 1838 1839 void helper_store_ibatu(CPUPPCState *env, uint32_t nr, target_ulong value) 1840 { 1841 target_ulong mask; 1842 #if defined(FLUSH_ALL_TLBS) 1843 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1844 #endif 1845 1846 dump_store_bat(env, 'I', 0, nr, value); 1847 if (env->IBAT[0][nr] != value) { 1848 mask = (value << 15) & 0x0FFE0000UL; 1849 #if !defined(FLUSH_ALL_TLBS) 1850 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1851 #endif 1852 /* 1853 * When storing valid upper BAT, mask BEPI and BRPN and 1854 * invalidate all TLBs covered by this BAT 1855 */ 1856 mask = (value << 15) & 0x0FFE0000UL; 1857 env->IBAT[0][nr] = (value & 0x00001FFFUL) | 1858 (value & ~0x0001FFFFUL & ~mask); 1859 env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) | 1860 (env->IBAT[1][nr] & ~0x0001FFFF & ~mask); 1861 #if !defined(FLUSH_ALL_TLBS) 1862 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1863 #else 1864 tlb_flush(CPU(cpu)); 1865 #endif 1866 } 1867 } 1868 1869 void helper_store_ibatl(CPUPPCState *env, uint32_t nr, target_ulong value) 1870 { 1871 dump_store_bat(env, 'I', 1, nr, value); 1872 env->IBAT[1][nr] = value; 1873 } 1874 1875 void helper_store_dbatu(CPUPPCState *env, uint32_t nr, target_ulong value) 1876 { 1877 target_ulong mask; 1878 #if defined(FLUSH_ALL_TLBS) 1879 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1880 #endif 1881 1882 dump_store_bat(env, 'D', 0, nr, value); 1883 if (env->DBAT[0][nr] != value) { 1884 /* 1885 * When storing valid upper BAT, mask BEPI and BRPN and 1886 * invalidate all TLBs covered by this BAT 1887 */ 1888 mask = (value << 15) & 0x0FFE0000UL; 1889 #if !defined(FLUSH_ALL_TLBS) 1890 do_invalidate_BAT(env, env->DBAT[0][nr], mask); 1891 #endif 1892 mask = (value << 15) & 0x0FFE0000UL; 1893 env->DBAT[0][nr] = (value & 0x00001FFFUL) | 1894 (value & ~0x0001FFFFUL & ~mask); 1895 env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) | 1896 (env->DBAT[1][nr] & ~0x0001FFFF & ~mask); 1897 #if !defined(FLUSH_ALL_TLBS) 1898 do_invalidate_BAT(env, env->DBAT[0][nr], mask); 1899 #else 1900 tlb_flush(CPU(cpu)); 1901 #endif 1902 } 1903 } 1904 1905 void helper_store_dbatl(CPUPPCState *env, uint32_t nr, target_ulong value) 1906 { 1907 dump_store_bat(env, 'D', 1, nr, value); 1908 env->DBAT[1][nr] = value; 1909 } 1910 1911 void helper_store_601_batu(CPUPPCState *env, uint32_t nr, target_ulong value) 1912 { 1913 target_ulong mask; 1914 #if defined(FLUSH_ALL_TLBS) 1915 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1916 int do_inval; 1917 #endif 1918 1919 dump_store_bat(env, 'I', 0, nr, value); 1920 if (env->IBAT[0][nr] != value) { 1921 #if defined(FLUSH_ALL_TLBS) 1922 do_inval = 0; 1923 #endif 1924 mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL; 1925 if (env->IBAT[1][nr] & 0x40) { 1926 /* Invalidate BAT only if it is valid */ 1927 #if !defined(FLUSH_ALL_TLBS) 1928 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1929 #else 1930 do_inval = 1; 1931 #endif 1932 } 1933 /* 1934 * When storing valid upper BAT, mask BEPI and BRPN and 1935 * invalidate all TLBs covered by this BAT 1936 */ 1937 env->IBAT[0][nr] = (value & 0x00001FFFUL) | 1938 (value & ~0x0001FFFFUL & ~mask); 1939 env->DBAT[0][nr] = env->IBAT[0][nr]; 1940 if (env->IBAT[1][nr] & 0x40) { 1941 #if !defined(FLUSH_ALL_TLBS) 1942 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1943 #else 1944 do_inval = 1; 1945 #endif 1946 } 1947 #if defined(FLUSH_ALL_TLBS) 1948 if (do_inval) { 1949 tlb_flush(CPU(cpu)); 1950 } 1951 #endif 1952 } 1953 } 1954 1955 void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value) 1956 { 1957 #if !defined(FLUSH_ALL_TLBS) 1958 target_ulong mask; 1959 #else 1960 PowerPCCPU *cpu = ppc_env_get_cpu(env); 1961 int do_inval; 1962 #endif 1963 1964 dump_store_bat(env, 'I', 1, nr, value); 1965 if (env->IBAT[1][nr] != value) { 1966 #if defined(FLUSH_ALL_TLBS) 1967 do_inval = 0; 1968 #endif 1969 if (env->IBAT[1][nr] & 0x40) { 1970 #if !defined(FLUSH_ALL_TLBS) 1971 mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL; 1972 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1973 #else 1974 do_inval = 1; 1975 #endif 1976 } 1977 if (value & 0x40) { 1978 #if !defined(FLUSH_ALL_TLBS) 1979 mask = (value << 17) & 0x0FFE0000UL; 1980 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 1981 #else 1982 do_inval = 1; 1983 #endif 1984 } 1985 env->IBAT[1][nr] = value; 1986 env->DBAT[1][nr] = value; 1987 #if defined(FLUSH_ALL_TLBS) 1988 if (do_inval) { 1989 tlb_flush(CPU(cpu)); 1990 } 1991 #endif 1992 } 1993 } 1994 1995 /*****************************************************************************/ 1996 /* TLB management */ 1997 void ppc_tlb_invalidate_all(CPUPPCState *env) 1998 { 1999 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2000 2001 #if defined(TARGET_PPC64) 2002 if (env->mmu_model & POWERPC_MMU_64) { 2003 env->tlb_need_flush = 0; 2004 tlb_flush(CPU(cpu)); 2005 } else 2006 #endif /* defined(TARGET_PPC64) */ 2007 switch (env->mmu_model) { 2008 case POWERPC_MMU_SOFT_6xx: 2009 case POWERPC_MMU_SOFT_74xx: 2010 ppc6xx_tlb_invalidate_all(env); 2011 break; 2012 case POWERPC_MMU_SOFT_4xx: 2013 case POWERPC_MMU_SOFT_4xx_Z: 2014 ppc4xx_tlb_invalidate_all(env); 2015 break; 2016 case POWERPC_MMU_REAL: 2017 cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n"); 2018 break; 2019 case POWERPC_MMU_MPC8xx: 2020 /* XXX: TODO */ 2021 cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n"); 2022 break; 2023 case POWERPC_MMU_BOOKE: 2024 tlb_flush(CPU(cpu)); 2025 break; 2026 case POWERPC_MMU_BOOKE206: 2027 booke206_flush_tlb(env, -1, 0); 2028 break; 2029 case POWERPC_MMU_32B: 2030 case POWERPC_MMU_601: 2031 env->tlb_need_flush = 0; 2032 tlb_flush(CPU(cpu)); 2033 break; 2034 default: 2035 /* XXX: TODO */ 2036 cpu_abort(CPU(cpu), "Unknown MMU model %x\n", env->mmu_model); 2037 break; 2038 } 2039 } 2040 2041 void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) 2042 { 2043 #if !defined(FLUSH_ALL_TLBS) 2044 addr &= TARGET_PAGE_MASK; 2045 #if defined(TARGET_PPC64) 2046 if (env->mmu_model & POWERPC_MMU_64) { 2047 /* tlbie invalidate TLBs for all segments */ 2048 /* 2049 * XXX: given the fact that there are too many segments to invalidate, 2050 * and we still don't have a tlb_flush_mask(env, n, mask) in QEMU, 2051 * we just invalidate all TLBs 2052 */ 2053 env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; 2054 } else 2055 #endif /* defined(TARGET_PPC64) */ 2056 switch (env->mmu_model) { 2057 case POWERPC_MMU_SOFT_6xx: 2058 case POWERPC_MMU_SOFT_74xx: 2059 ppc6xx_tlb_invalidate_virt(env, addr, 0); 2060 if (env->id_tlbs == 1) { 2061 ppc6xx_tlb_invalidate_virt(env, addr, 1); 2062 } 2063 break; 2064 case POWERPC_MMU_32B: 2065 case POWERPC_MMU_601: 2066 /* 2067 * Actual CPUs invalidate entire congruence classes based on 2068 * the geometry of their TLBs and some OSes take that into 2069 * account, we just mark the TLB to be flushed later (context 2070 * synchronizing event or sync instruction on 32-bit). 2071 */ 2072 env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; 2073 break; 2074 default: 2075 /* Should never reach here with other MMU models */ 2076 assert(0); 2077 } 2078 #else 2079 ppc_tlb_invalidate_all(env); 2080 #endif 2081 } 2082 2083 /*****************************************************************************/ 2084 /* Special registers manipulation */ 2085 void ppc_store_sdr1(CPUPPCState *env, target_ulong value) 2086 { 2087 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2088 qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); 2089 assert(!cpu->vhyp); 2090 #if defined(TARGET_PPC64) 2091 if (env->mmu_model & POWERPC_MMU_64) { 2092 target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE; 2093 target_ulong htabsize = value & SDR_64_HTABSIZE; 2094 2095 if (value & ~sdr_mask) { 2096 error_report("Invalid bits 0x"TARGET_FMT_lx" set in SDR1", 2097 value & ~sdr_mask); 2098 value &= sdr_mask; 2099 } 2100 if (htabsize > 28) { 2101 error_report("Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SDR1", 2102 htabsize); 2103 return; 2104 } 2105 } 2106 #endif /* defined(TARGET_PPC64) */ 2107 /* FIXME: Should check for valid HTABMASK values in 32-bit case */ 2108 env->spr[SPR_SDR1] = value; 2109 } 2110 2111 #if defined(TARGET_PPC64) 2112 void ppc_store_ptcr(CPUPPCState *env, target_ulong value) 2113 { 2114 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2115 target_ulong ptcr_mask = PTCR_PATB | PTCR_PATS; 2116 target_ulong patbsize = value & PTCR_PATS; 2117 2118 qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); 2119 2120 assert(!cpu->vhyp); 2121 assert(env->mmu_model & POWERPC_MMU_3_00); 2122 2123 if (value & ~ptcr_mask) { 2124 error_report("Invalid bits 0x"TARGET_FMT_lx" set in PTCR", 2125 value & ~ptcr_mask); 2126 value &= ptcr_mask; 2127 } 2128 2129 if (patbsize > 24) { 2130 error_report("Invalid Partition Table size 0x" TARGET_FMT_lx 2131 " stored in PTCR", patbsize); 2132 return; 2133 } 2134 2135 env->spr[SPR_PTCR] = value; 2136 } 2137 2138 #endif /* defined(TARGET_PPC64) */ 2139 2140 /* Segment registers load and store */ 2141 target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num) 2142 { 2143 #if defined(TARGET_PPC64) 2144 if (env->mmu_model & POWERPC_MMU_64) { 2145 /* XXX */ 2146 return 0; 2147 } 2148 #endif 2149 return env->sr[sr_num]; 2150 } 2151 2152 void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) 2153 { 2154 qemu_log_mask(CPU_LOG_MMU, 2155 "%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__, 2156 (int)srnum, value, env->sr[srnum]); 2157 #if defined(TARGET_PPC64) 2158 if (env->mmu_model & POWERPC_MMU_64) { 2159 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2160 uint64_t esid, vsid; 2161 2162 /* ESID = srnum */ 2163 esid = ((uint64_t)(srnum & 0xf) << 28) | SLB_ESID_V; 2164 2165 /* VSID = VSID */ 2166 vsid = (value & 0xfffffff) << 12; 2167 /* flags = flags */ 2168 vsid |= ((value >> 27) & 0xf) << 8; 2169 2170 ppc_store_slb(cpu, srnum, esid, vsid); 2171 } else 2172 #endif 2173 if (env->sr[srnum] != value) { 2174 env->sr[srnum] = value; 2175 /* 2176 * Invalidating 256MB of virtual memory in 4kB pages is way 2177 * longer than flusing the whole TLB. 2178 */ 2179 #if !defined(FLUSH_ALL_TLBS) && 0 2180 { 2181 target_ulong page, end; 2182 /* Invalidate 256 MB of virtual memory */ 2183 page = (16 << 20) * srnum; 2184 end = page + (16 << 20); 2185 for (; page != end; page += TARGET_PAGE_SIZE) { 2186 tlb_flush_page(CPU(cpu), page); 2187 } 2188 } 2189 #else 2190 env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; 2191 #endif 2192 } 2193 } 2194 2195 /* TLB management */ 2196 void helper_tlbia(CPUPPCState *env) 2197 { 2198 ppc_tlb_invalidate_all(env); 2199 } 2200 2201 void helper_tlbie(CPUPPCState *env, target_ulong addr) 2202 { 2203 ppc_tlb_invalidate_one(env, addr); 2204 } 2205 2206 void helper_tlbiva(CPUPPCState *env, target_ulong addr) 2207 { 2208 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2209 2210 /* tlbiva instruction only exists on BookE */ 2211 assert(env->mmu_model == POWERPC_MMU_BOOKE); 2212 /* XXX: TODO */ 2213 cpu_abort(CPU(cpu), "BookE MMU model is not implemented\n"); 2214 } 2215 2216 /* Software driven TLBs management */ 2217 /* PowerPC 602/603 software TLB load instructions helpers */ 2218 static void do_6xx_tlb(CPUPPCState *env, target_ulong new_EPN, int is_code) 2219 { 2220 target_ulong RPN, CMP, EPN; 2221 int way; 2222 2223 RPN = env->spr[SPR_RPA]; 2224 if (is_code) { 2225 CMP = env->spr[SPR_ICMP]; 2226 EPN = env->spr[SPR_IMISS]; 2227 } else { 2228 CMP = env->spr[SPR_DCMP]; 2229 EPN = env->spr[SPR_DMISS]; 2230 } 2231 way = (env->spr[SPR_SRR1] >> 17) & 1; 2232 (void)EPN; /* avoid a compiler warning */ 2233 LOG_SWTLB("%s: EPN " TARGET_FMT_lx " " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx 2234 " PTE1 " TARGET_FMT_lx " way %d\n", __func__, new_EPN, EPN, CMP, 2235 RPN, way); 2236 /* Store this TLB */ 2237 ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK), 2238 way, is_code, CMP, RPN); 2239 } 2240 2241 void helper_6xx_tlbd(CPUPPCState *env, target_ulong EPN) 2242 { 2243 do_6xx_tlb(env, EPN, 0); 2244 } 2245 2246 void helper_6xx_tlbi(CPUPPCState *env, target_ulong EPN) 2247 { 2248 do_6xx_tlb(env, EPN, 1); 2249 } 2250 2251 /* PowerPC 74xx software TLB load instructions helpers */ 2252 static void do_74xx_tlb(CPUPPCState *env, target_ulong new_EPN, int is_code) 2253 { 2254 target_ulong RPN, CMP, EPN; 2255 int way; 2256 2257 RPN = env->spr[SPR_PTELO]; 2258 CMP = env->spr[SPR_PTEHI]; 2259 EPN = env->spr[SPR_TLBMISS] & ~0x3; 2260 way = env->spr[SPR_TLBMISS] & 0x3; 2261 (void)EPN; /* avoid a compiler warning */ 2262 LOG_SWTLB("%s: EPN " TARGET_FMT_lx " " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx 2263 " PTE1 " TARGET_FMT_lx " way %d\n", __func__, new_EPN, EPN, CMP, 2264 RPN, way); 2265 /* Store this TLB */ 2266 ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK), 2267 way, is_code, CMP, RPN); 2268 } 2269 2270 void helper_74xx_tlbd(CPUPPCState *env, target_ulong EPN) 2271 { 2272 do_74xx_tlb(env, EPN, 0); 2273 } 2274 2275 void helper_74xx_tlbi(CPUPPCState *env, target_ulong EPN) 2276 { 2277 do_74xx_tlb(env, EPN, 1); 2278 } 2279 2280 /*****************************************************************************/ 2281 /* PowerPC 601 specific instructions (POWER bridge) */ 2282 2283 target_ulong helper_rac(CPUPPCState *env, target_ulong addr) 2284 { 2285 mmu_ctx_t ctx; 2286 int nb_BATs; 2287 target_ulong ret = 0; 2288 2289 /* 2290 * We don't have to generate many instances of this instruction, 2291 * as rac is supervisor only. 2292 * 2293 * XXX: FIX THIS: Pretend we have no BAT 2294 */ 2295 nb_BATs = env->nb_BATs; 2296 env->nb_BATs = 0; 2297 if (get_physical_address(env, &ctx, addr, 0, ACCESS_INT) == 0) { 2298 ret = ctx.raddr; 2299 } 2300 env->nb_BATs = nb_BATs; 2301 return ret; 2302 } 2303 2304 static inline target_ulong booke_tlb_to_page_size(int size) 2305 { 2306 return 1024 << (2 * size); 2307 } 2308 2309 static inline int booke_page_size_to_tlb(target_ulong page_size) 2310 { 2311 int size; 2312 2313 switch (page_size) { 2314 case 0x00000400UL: 2315 size = 0x0; 2316 break; 2317 case 0x00001000UL: 2318 size = 0x1; 2319 break; 2320 case 0x00004000UL: 2321 size = 0x2; 2322 break; 2323 case 0x00010000UL: 2324 size = 0x3; 2325 break; 2326 case 0x00040000UL: 2327 size = 0x4; 2328 break; 2329 case 0x00100000UL: 2330 size = 0x5; 2331 break; 2332 case 0x00400000UL: 2333 size = 0x6; 2334 break; 2335 case 0x01000000UL: 2336 size = 0x7; 2337 break; 2338 case 0x04000000UL: 2339 size = 0x8; 2340 break; 2341 case 0x10000000UL: 2342 size = 0x9; 2343 break; 2344 case 0x40000000UL: 2345 size = 0xA; 2346 break; 2347 #if defined(TARGET_PPC64) 2348 case 0x000100000000ULL: 2349 size = 0xB; 2350 break; 2351 case 0x000400000000ULL: 2352 size = 0xC; 2353 break; 2354 case 0x001000000000ULL: 2355 size = 0xD; 2356 break; 2357 case 0x004000000000ULL: 2358 size = 0xE; 2359 break; 2360 case 0x010000000000ULL: 2361 size = 0xF; 2362 break; 2363 #endif 2364 default: 2365 size = -1; 2366 break; 2367 } 2368 2369 return size; 2370 } 2371 2372 /* Helpers for 4xx TLB management */ 2373 #define PPC4XX_TLB_ENTRY_MASK 0x0000003f /* Mask for 64 TLB entries */ 2374 2375 #define PPC4XX_TLBHI_V 0x00000040 2376 #define PPC4XX_TLBHI_E 0x00000020 2377 #define PPC4XX_TLBHI_SIZE_MIN 0 2378 #define PPC4XX_TLBHI_SIZE_MAX 7 2379 #define PPC4XX_TLBHI_SIZE_DEFAULT 1 2380 #define PPC4XX_TLBHI_SIZE_SHIFT 7 2381 #define PPC4XX_TLBHI_SIZE_MASK 0x00000007 2382 2383 #define PPC4XX_TLBLO_EX 0x00000200 2384 #define PPC4XX_TLBLO_WR 0x00000100 2385 #define PPC4XX_TLBLO_ATTR_MASK 0x000000FF 2386 #define PPC4XX_TLBLO_RPN_MASK 0xFFFFFC00 2387 2388 target_ulong helper_4xx_tlbre_hi(CPUPPCState *env, target_ulong entry) 2389 { 2390 ppcemb_tlb_t *tlb; 2391 target_ulong ret; 2392 int size; 2393 2394 entry &= PPC4XX_TLB_ENTRY_MASK; 2395 tlb = &env->tlb.tlbe[entry]; 2396 ret = tlb->EPN; 2397 if (tlb->prot & PAGE_VALID) { 2398 ret |= PPC4XX_TLBHI_V; 2399 } 2400 size = booke_page_size_to_tlb(tlb->size); 2401 if (size < PPC4XX_TLBHI_SIZE_MIN || size > PPC4XX_TLBHI_SIZE_MAX) { 2402 size = PPC4XX_TLBHI_SIZE_DEFAULT; 2403 } 2404 ret |= size << PPC4XX_TLBHI_SIZE_SHIFT; 2405 env->spr[SPR_40x_PID] = tlb->PID; 2406 return ret; 2407 } 2408 2409 target_ulong helper_4xx_tlbre_lo(CPUPPCState *env, target_ulong entry) 2410 { 2411 ppcemb_tlb_t *tlb; 2412 target_ulong ret; 2413 2414 entry &= PPC4XX_TLB_ENTRY_MASK; 2415 tlb = &env->tlb.tlbe[entry]; 2416 ret = tlb->RPN; 2417 if (tlb->prot & PAGE_EXEC) { 2418 ret |= PPC4XX_TLBLO_EX; 2419 } 2420 if (tlb->prot & PAGE_WRITE) { 2421 ret |= PPC4XX_TLBLO_WR; 2422 } 2423 return ret; 2424 } 2425 2426 void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, 2427 target_ulong val) 2428 { 2429 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2430 CPUState *cs = CPU(cpu); 2431 ppcemb_tlb_t *tlb; 2432 target_ulong page, end; 2433 2434 LOG_SWTLB("%s entry %d val " TARGET_FMT_lx "\n", __func__, (int)entry, 2435 val); 2436 entry &= PPC4XX_TLB_ENTRY_MASK; 2437 tlb = &env->tlb.tlbe[entry]; 2438 /* Invalidate previous TLB (if it's valid) */ 2439 if (tlb->prot & PAGE_VALID) { 2440 end = tlb->EPN + tlb->size; 2441 LOG_SWTLB("%s: invalidate old TLB %d start " TARGET_FMT_lx " end " 2442 TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end); 2443 for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { 2444 tlb_flush_page(cs, page); 2445 } 2446 } 2447 tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT) 2448 & PPC4XX_TLBHI_SIZE_MASK); 2449 /* 2450 * We cannot handle TLB size < TARGET_PAGE_SIZE. 2451 * If this ever occurs, we should implement TARGET_PAGE_BITS_VARY 2452 */ 2453 if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) { 2454 cpu_abort(cs, "TLB size " TARGET_FMT_lu " < %u " 2455 "are not supported (%d)\n" 2456 "Please implement TARGET_PAGE_BITS_VARY\n", 2457 tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7)); 2458 } 2459 tlb->EPN = val & ~(tlb->size - 1); 2460 if (val & PPC4XX_TLBHI_V) { 2461 tlb->prot |= PAGE_VALID; 2462 if (val & PPC4XX_TLBHI_E) { 2463 /* XXX: TO BE FIXED */ 2464 cpu_abort(cs, 2465 "Little-endian TLB entries are not supported by now\n"); 2466 } 2467 } else { 2468 tlb->prot &= ~PAGE_VALID; 2469 } 2470 tlb->PID = env->spr[SPR_40x_PID]; /* PID */ 2471 LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx 2472 " size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__, 2473 (int)entry, tlb->RPN, tlb->EPN, tlb->size, 2474 tlb->prot & PAGE_READ ? 'r' : '-', 2475 tlb->prot & PAGE_WRITE ? 'w' : '-', 2476 tlb->prot & PAGE_EXEC ? 'x' : '-', 2477 tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); 2478 /* Invalidate new TLB (if valid) */ 2479 if (tlb->prot & PAGE_VALID) { 2480 end = tlb->EPN + tlb->size; 2481 LOG_SWTLB("%s: invalidate TLB %d start " TARGET_FMT_lx " end " 2482 TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end); 2483 for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { 2484 tlb_flush_page(cs, page); 2485 } 2486 } 2487 } 2488 2489 void helper_4xx_tlbwe_lo(CPUPPCState *env, target_ulong entry, 2490 target_ulong val) 2491 { 2492 ppcemb_tlb_t *tlb; 2493 2494 LOG_SWTLB("%s entry %i val " TARGET_FMT_lx "\n", __func__, (int)entry, 2495 val); 2496 entry &= PPC4XX_TLB_ENTRY_MASK; 2497 tlb = &env->tlb.tlbe[entry]; 2498 tlb->attr = val & PPC4XX_TLBLO_ATTR_MASK; 2499 tlb->RPN = val & PPC4XX_TLBLO_RPN_MASK; 2500 tlb->prot = PAGE_READ; 2501 if (val & PPC4XX_TLBLO_EX) { 2502 tlb->prot |= PAGE_EXEC; 2503 } 2504 if (val & PPC4XX_TLBLO_WR) { 2505 tlb->prot |= PAGE_WRITE; 2506 } 2507 LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx 2508 " size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__, 2509 (int)entry, tlb->RPN, tlb->EPN, tlb->size, 2510 tlb->prot & PAGE_READ ? 'r' : '-', 2511 tlb->prot & PAGE_WRITE ? 'w' : '-', 2512 tlb->prot & PAGE_EXEC ? 'x' : '-', 2513 tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); 2514 } 2515 2516 target_ulong helper_4xx_tlbsx(CPUPPCState *env, target_ulong address) 2517 { 2518 return ppcemb_tlb_search(env, address, env->spr[SPR_40x_PID]); 2519 } 2520 2521 /* PowerPC 440 TLB management */ 2522 void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry, 2523 target_ulong value) 2524 { 2525 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2526 ppcemb_tlb_t *tlb; 2527 target_ulong EPN, RPN, size; 2528 int do_flush_tlbs; 2529 2530 LOG_SWTLB("%s word %d entry %d value " TARGET_FMT_lx "\n", 2531 __func__, word, (int)entry, value); 2532 do_flush_tlbs = 0; 2533 entry &= 0x3F; 2534 tlb = &env->tlb.tlbe[entry]; 2535 switch (word) { 2536 default: 2537 /* Just here to please gcc */ 2538 case 0: 2539 EPN = value & 0xFFFFFC00; 2540 if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN) { 2541 do_flush_tlbs = 1; 2542 } 2543 tlb->EPN = EPN; 2544 size = booke_tlb_to_page_size((value >> 4) & 0xF); 2545 if ((tlb->prot & PAGE_VALID) && tlb->size < size) { 2546 do_flush_tlbs = 1; 2547 } 2548 tlb->size = size; 2549 tlb->attr &= ~0x1; 2550 tlb->attr |= (value >> 8) & 1; 2551 if (value & 0x200) { 2552 tlb->prot |= PAGE_VALID; 2553 } else { 2554 if (tlb->prot & PAGE_VALID) { 2555 tlb->prot &= ~PAGE_VALID; 2556 do_flush_tlbs = 1; 2557 } 2558 } 2559 tlb->PID = env->spr[SPR_440_MMUCR] & 0x000000FF; 2560 if (do_flush_tlbs) { 2561 tlb_flush(CPU(cpu)); 2562 } 2563 break; 2564 case 1: 2565 RPN = value & 0xFFFFFC0F; 2566 if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN) { 2567 tlb_flush(CPU(cpu)); 2568 } 2569 tlb->RPN = RPN; 2570 break; 2571 case 2: 2572 tlb->attr = (tlb->attr & 0x1) | (value & 0x0000FF00); 2573 tlb->prot = tlb->prot & PAGE_VALID; 2574 if (value & 0x1) { 2575 tlb->prot |= PAGE_READ << 4; 2576 } 2577 if (value & 0x2) { 2578 tlb->prot |= PAGE_WRITE << 4; 2579 } 2580 if (value & 0x4) { 2581 tlb->prot |= PAGE_EXEC << 4; 2582 } 2583 if (value & 0x8) { 2584 tlb->prot |= PAGE_READ; 2585 } 2586 if (value & 0x10) { 2587 tlb->prot |= PAGE_WRITE; 2588 } 2589 if (value & 0x20) { 2590 tlb->prot |= PAGE_EXEC; 2591 } 2592 break; 2593 } 2594 } 2595 2596 target_ulong helper_440_tlbre(CPUPPCState *env, uint32_t word, 2597 target_ulong entry) 2598 { 2599 ppcemb_tlb_t *tlb; 2600 target_ulong ret; 2601 int size; 2602 2603 entry &= 0x3F; 2604 tlb = &env->tlb.tlbe[entry]; 2605 switch (word) { 2606 default: 2607 /* Just here to please gcc */ 2608 case 0: 2609 ret = tlb->EPN; 2610 size = booke_page_size_to_tlb(tlb->size); 2611 if (size < 0 || size > 0xF) { 2612 size = 1; 2613 } 2614 ret |= size << 4; 2615 if (tlb->attr & 0x1) { 2616 ret |= 0x100; 2617 } 2618 if (tlb->prot & PAGE_VALID) { 2619 ret |= 0x200; 2620 } 2621 env->spr[SPR_440_MMUCR] &= ~0x000000FF; 2622 env->spr[SPR_440_MMUCR] |= tlb->PID; 2623 break; 2624 case 1: 2625 ret = tlb->RPN; 2626 break; 2627 case 2: 2628 ret = tlb->attr & ~0x1; 2629 if (tlb->prot & (PAGE_READ << 4)) { 2630 ret |= 0x1; 2631 } 2632 if (tlb->prot & (PAGE_WRITE << 4)) { 2633 ret |= 0x2; 2634 } 2635 if (tlb->prot & (PAGE_EXEC << 4)) { 2636 ret |= 0x4; 2637 } 2638 if (tlb->prot & PAGE_READ) { 2639 ret |= 0x8; 2640 } 2641 if (tlb->prot & PAGE_WRITE) { 2642 ret |= 0x10; 2643 } 2644 if (tlb->prot & PAGE_EXEC) { 2645 ret |= 0x20; 2646 } 2647 break; 2648 } 2649 return ret; 2650 } 2651 2652 target_ulong helper_440_tlbsx(CPUPPCState *env, target_ulong address) 2653 { 2654 return ppcemb_tlb_search(env, address, env->spr[SPR_440_MMUCR] & 0xFF); 2655 } 2656 2657 /* PowerPC BookE 2.06 TLB management */ 2658 2659 static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env) 2660 { 2661 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2662 uint32_t tlbncfg = 0; 2663 int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT; 2664 int ea = (env->spr[SPR_BOOKE_MAS2] & MAS2_EPN_MASK); 2665 int tlb; 2666 2667 tlb = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT; 2668 tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlb]; 2669 2670 if ((tlbncfg & TLBnCFG_HES) && (env->spr[SPR_BOOKE_MAS0] & MAS0_HES)) { 2671 cpu_abort(CPU(cpu), "we don't support HES yet\n"); 2672 } 2673 2674 return booke206_get_tlbm(env, tlb, ea, esel); 2675 } 2676 2677 void helper_booke_setpid(CPUPPCState *env, uint32_t pidn, target_ulong pid) 2678 { 2679 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2680 2681 env->spr[pidn] = pid; 2682 /* changing PIDs mean we're in a different address space now */ 2683 tlb_flush(CPU(cpu)); 2684 } 2685 2686 void helper_booke_set_eplc(CPUPPCState *env, target_ulong val) 2687 { 2688 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2689 env->spr[SPR_BOOKE_EPLC] = val & EPID_MASK; 2690 tlb_flush_by_mmuidx(CPU(cpu), 1 << PPC_TLB_EPID_LOAD); 2691 } 2692 void helper_booke_set_epsc(CPUPPCState *env, target_ulong val) 2693 { 2694 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2695 env->spr[SPR_BOOKE_EPSC] = val & EPID_MASK; 2696 tlb_flush_by_mmuidx(CPU(cpu), 1 << PPC_TLB_EPID_STORE); 2697 } 2698 2699 static inline void flush_page(CPUPPCState *env, ppcmas_tlb_t *tlb) 2700 { 2701 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2702 2703 if (booke206_tlb_to_page_size(env, tlb) == TARGET_PAGE_SIZE) { 2704 tlb_flush_page(CPU(cpu), tlb->mas2 & MAS2_EPN_MASK); 2705 } else { 2706 tlb_flush(CPU(cpu)); 2707 } 2708 } 2709 2710 void helper_booke206_tlbwe(CPUPPCState *env) 2711 { 2712 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2713 uint32_t tlbncfg, tlbn; 2714 ppcmas_tlb_t *tlb; 2715 uint32_t size_tlb, size_ps; 2716 target_ulong mask; 2717 2718 2719 switch (env->spr[SPR_BOOKE_MAS0] & MAS0_WQ_MASK) { 2720 case MAS0_WQ_ALWAYS: 2721 /* good to go, write that entry */ 2722 break; 2723 case MAS0_WQ_COND: 2724 /* XXX check if reserved */ 2725 if (0) { 2726 return; 2727 } 2728 break; 2729 case MAS0_WQ_CLR_RSRV: 2730 /* XXX clear entry */ 2731 return; 2732 default: 2733 /* no idea what to do */ 2734 return; 2735 } 2736 2737 if (((env->spr[SPR_BOOKE_MAS0] & MAS0_ATSEL) == MAS0_ATSEL_LRAT) && 2738 !msr_gs) { 2739 /* XXX we don't support direct LRAT setting yet */ 2740 fprintf(stderr, "cpu: don't support LRAT setting yet\n"); 2741 return; 2742 } 2743 2744 tlbn = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT; 2745 tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn]; 2746 2747 tlb = booke206_cur_tlb(env); 2748 2749 if (!tlb) { 2750 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2751 POWERPC_EXCP_INVAL | 2752 POWERPC_EXCP_INVAL_INVAL, GETPC()); 2753 } 2754 2755 /* check that we support the targeted size */ 2756 size_tlb = (env->spr[SPR_BOOKE_MAS1] & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; 2757 size_ps = booke206_tlbnps(env, tlbn); 2758 if ((env->spr[SPR_BOOKE_MAS1] & MAS1_VALID) && (tlbncfg & TLBnCFG_AVAIL) && 2759 !(size_ps & (1 << size_tlb))) { 2760 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2761 POWERPC_EXCP_INVAL | 2762 POWERPC_EXCP_INVAL_INVAL, GETPC()); 2763 } 2764 2765 if (msr_gs) { 2766 cpu_abort(CPU(cpu), "missing HV implementation\n"); 2767 } 2768 2769 if (tlb->mas1 & MAS1_VALID) { 2770 /* 2771 * Invalidate the page in QEMU TLB if it was a valid entry. 2772 * 2773 * In "PowerPC e500 Core Family Reference Manual, Rev. 1", 2774 * Section "12.4.2 TLB Write Entry (tlbwe) Instruction": 2775 * (https://www.nxp.com/docs/en/reference-manual/E500CORERM.pdf) 2776 * 2777 * "Note that when an L2 TLB entry is written, it may be displacing an 2778 * already valid entry in the same L2 TLB location (a victim). If a 2779 * valid L1 TLB entry corresponds to the L2 MMU victim entry, that L1 2780 * TLB entry is automatically invalidated." 2781 */ 2782 flush_page(env, tlb); 2783 } 2784 2785 tlb->mas7_3 = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) | 2786 env->spr[SPR_BOOKE_MAS3]; 2787 tlb->mas1 = env->spr[SPR_BOOKE_MAS1]; 2788 2789 if ((env->spr[SPR_MMUCFG] & MMUCFG_MAVN) == MMUCFG_MAVN_V2) { 2790 /* For TLB which has a fixed size TSIZE is ignored with MAV2 */ 2791 booke206_fixed_size_tlbn(env, tlbn, tlb); 2792 } else { 2793 if (!(tlbncfg & TLBnCFG_AVAIL)) { 2794 /* force !AVAIL TLB entries to correct page size */ 2795 tlb->mas1 &= ~MAS1_TSIZE_MASK; 2796 /* XXX can be configured in MMUCSR0 */ 2797 tlb->mas1 |= (tlbncfg & TLBnCFG_MINSIZE) >> 12; 2798 } 2799 } 2800 2801 /* Make a mask from TLB size to discard invalid bits in EPN field */ 2802 mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); 2803 /* Add a mask for page attributes */ 2804 mask |= MAS2_ACM | MAS2_VLE | MAS2_W | MAS2_I | MAS2_M | MAS2_G | MAS2_E; 2805 2806 if (!msr_cm) { 2807 /* 2808 * Executing a tlbwe instruction in 32-bit mode will set bits 2809 * 0:31 of the TLB EPN field to zero. 2810 */ 2811 mask &= 0xffffffff; 2812 } 2813 2814 tlb->mas2 = env->spr[SPR_BOOKE_MAS2] & mask; 2815 2816 if (!(tlbncfg & TLBnCFG_IPROT)) { 2817 /* no IPROT supported by TLB */ 2818 tlb->mas1 &= ~MAS1_IPROT; 2819 } 2820 2821 flush_page(env, tlb); 2822 } 2823 2824 static inline void booke206_tlb_to_mas(CPUPPCState *env, ppcmas_tlb_t *tlb) 2825 { 2826 int tlbn = booke206_tlbm_to_tlbn(env, tlb); 2827 int way = booke206_tlbm_to_way(env, tlb); 2828 2829 env->spr[SPR_BOOKE_MAS0] = tlbn << MAS0_TLBSEL_SHIFT; 2830 env->spr[SPR_BOOKE_MAS0] |= way << MAS0_ESEL_SHIFT; 2831 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; 2832 2833 env->spr[SPR_BOOKE_MAS1] = tlb->mas1; 2834 env->spr[SPR_BOOKE_MAS2] = tlb->mas2; 2835 env->spr[SPR_BOOKE_MAS3] = tlb->mas7_3; 2836 env->spr[SPR_BOOKE_MAS7] = tlb->mas7_3 >> 32; 2837 } 2838 2839 void helper_booke206_tlbre(CPUPPCState *env) 2840 { 2841 ppcmas_tlb_t *tlb = NULL; 2842 2843 tlb = booke206_cur_tlb(env); 2844 if (!tlb) { 2845 env->spr[SPR_BOOKE_MAS1] = 0; 2846 } else { 2847 booke206_tlb_to_mas(env, tlb); 2848 } 2849 } 2850 2851 void helper_booke206_tlbsx(CPUPPCState *env, target_ulong address) 2852 { 2853 ppcmas_tlb_t *tlb = NULL; 2854 int i, j; 2855 hwaddr raddr; 2856 uint32_t spid, sas; 2857 2858 spid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID_MASK) >> MAS6_SPID_SHIFT; 2859 sas = env->spr[SPR_BOOKE_MAS6] & MAS6_SAS; 2860 2861 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 2862 int ways = booke206_tlb_ways(env, i); 2863 2864 for (j = 0; j < ways; j++) { 2865 tlb = booke206_get_tlbm(env, i, address, j); 2866 2867 if (!tlb) { 2868 continue; 2869 } 2870 2871 if (ppcmas_tlb_check(env, tlb, &raddr, address, spid)) { 2872 continue; 2873 } 2874 2875 if (sas != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { 2876 continue; 2877 } 2878 2879 booke206_tlb_to_mas(env, tlb); 2880 return; 2881 } 2882 } 2883 2884 /* no entry found, fill with defaults */ 2885 env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK; 2886 env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK; 2887 env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK; 2888 env->spr[SPR_BOOKE_MAS3] = 0; 2889 env->spr[SPR_BOOKE_MAS7] = 0; 2890 2891 if (env->spr[SPR_BOOKE_MAS6] & MAS6_SAS) { 2892 env->spr[SPR_BOOKE_MAS1] |= MAS1_TS; 2893 } 2894 2895 env->spr[SPR_BOOKE_MAS1] |= (env->spr[SPR_BOOKE_MAS6] >> 16) 2896 << MAS1_TID_SHIFT; 2897 2898 /* next victim logic */ 2899 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT; 2900 env->last_way++; 2901 env->last_way &= booke206_tlb_ways(env, 0) - 1; 2902 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; 2903 } 2904 2905 static inline void booke206_invalidate_ea_tlb(CPUPPCState *env, int tlbn, 2906 uint32_t ea) 2907 { 2908 int i; 2909 int ways = booke206_tlb_ways(env, tlbn); 2910 target_ulong mask; 2911 2912 for (i = 0; i < ways; i++) { 2913 ppcmas_tlb_t *tlb = booke206_get_tlbm(env, tlbn, ea, i); 2914 if (!tlb) { 2915 continue; 2916 } 2917 mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); 2918 if (((tlb->mas2 & MAS2_EPN_MASK) == (ea & mask)) && 2919 !(tlb->mas1 & MAS1_IPROT)) { 2920 tlb->mas1 &= ~MAS1_VALID; 2921 } 2922 } 2923 } 2924 2925 void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address) 2926 { 2927 CPUState *cs; 2928 2929 if (address & 0x4) { 2930 /* flush all entries */ 2931 if (address & 0x8) { 2932 /* flush all of TLB1 */ 2933 booke206_flush_tlb(env, BOOKE206_FLUSH_TLB1, 1); 2934 } else { 2935 /* flush all of TLB0 */ 2936 booke206_flush_tlb(env, BOOKE206_FLUSH_TLB0, 0); 2937 } 2938 return; 2939 } 2940 2941 if (address & 0x8) { 2942 /* flush TLB1 entries */ 2943 booke206_invalidate_ea_tlb(env, 1, address); 2944 CPU_FOREACH(cs) { 2945 tlb_flush(cs); 2946 } 2947 } else { 2948 /* flush TLB0 entries */ 2949 booke206_invalidate_ea_tlb(env, 0, address); 2950 CPU_FOREACH(cs) { 2951 tlb_flush_page(cs, address & MAS2_EPN_MASK); 2952 } 2953 } 2954 } 2955 2956 void helper_booke206_tlbilx0(CPUPPCState *env, target_ulong address) 2957 { 2958 /* XXX missing LPID handling */ 2959 booke206_flush_tlb(env, -1, 1); 2960 } 2961 2962 void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address) 2963 { 2964 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2965 int i, j; 2966 int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); 2967 ppcmas_tlb_t *tlb = env->tlb.tlbm; 2968 int tlb_size; 2969 2970 /* XXX missing LPID handling */ 2971 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 2972 tlb_size = booke206_tlb_size(env, i); 2973 for (j = 0; j < tlb_size; j++) { 2974 if (!(tlb[j].mas1 & MAS1_IPROT) && 2975 ((tlb[j].mas1 & MAS1_TID_MASK) == tid)) { 2976 tlb[j].mas1 &= ~MAS1_VALID; 2977 } 2978 } 2979 tlb += booke206_tlb_size(env, i); 2980 } 2981 tlb_flush(CPU(cpu)); 2982 } 2983 2984 void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address) 2985 { 2986 PowerPCCPU *cpu = ppc_env_get_cpu(env); 2987 int i, j; 2988 ppcmas_tlb_t *tlb; 2989 int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); 2990 int pid = tid >> MAS6_SPID_SHIFT; 2991 int sgs = env->spr[SPR_BOOKE_MAS5] & MAS5_SGS; 2992 int ind = (env->spr[SPR_BOOKE_MAS6] & MAS6_SIND) ? MAS1_IND : 0; 2993 /* XXX check for unsupported isize and raise an invalid opcode then */ 2994 int size = env->spr[SPR_BOOKE_MAS6] & MAS6_ISIZE_MASK; 2995 /* XXX implement MAV2 handling */ 2996 bool mav2 = false; 2997 2998 /* XXX missing LPID handling */ 2999 /* flush by pid and ea */ 3000 for (i = 0; i < BOOKE206_MAX_TLBN; i++) { 3001 int ways = booke206_tlb_ways(env, i); 3002 3003 for (j = 0; j < ways; j++) { 3004 tlb = booke206_get_tlbm(env, i, address, j); 3005 if (!tlb) { 3006 continue; 3007 } 3008 if ((ppcmas_tlb_check(env, tlb, NULL, address, pid) != 0) || 3009 (tlb->mas1 & MAS1_IPROT) || 3010 ((tlb->mas1 & MAS1_IND) != ind) || 3011 ((tlb->mas8 & MAS8_TGS) != sgs)) { 3012 continue; 3013 } 3014 if (mav2 && ((tlb->mas1 & MAS1_TSIZE_MASK) != size)) { 3015 /* XXX only check when MMUCFG[TWC] || TLBnCFG[HES] */ 3016 continue; 3017 } 3018 /* XXX e500mc doesn't match SAS, but other cores might */ 3019 tlb->mas1 &= ~MAS1_VALID; 3020 } 3021 } 3022 tlb_flush(CPU(cpu)); 3023 } 3024 3025 void helper_booke206_tlbflush(CPUPPCState *env, target_ulong type) 3026 { 3027 int flags = 0; 3028 3029 if (type & 2) { 3030 flags |= BOOKE206_FLUSH_TLB1; 3031 } 3032 3033 if (type & 4) { 3034 flags |= BOOKE206_FLUSH_TLB0; 3035 } 3036 3037 booke206_flush_tlb(env, flags, 1); 3038 } 3039 3040 3041 void helper_check_tlb_flush_local(CPUPPCState *env) 3042 { 3043 check_tlb_flush(env, false); 3044 } 3045 3046 void helper_check_tlb_flush_global(CPUPPCState *env) 3047 { 3048 check_tlb_flush(env, true); 3049 } 3050 3051 /*****************************************************************************/ 3052 3053 /* 3054 * try to fill the TLB and return an exception if error. If retaddr is 3055 * NULL, it means that the function was called in C code (i.e. not 3056 * from generated code or from helper.c) 3057 * 3058 * XXX: fix it to restore all registers 3059 */ 3060 void tlb_fill(CPUState *cs, target_ulong addr, int size, 3061 MMUAccessType access_type, int mmu_idx, uintptr_t retaddr) 3062 { 3063 PowerPCCPU *cpu = POWERPC_CPU(cs); 3064 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); 3065 CPUPPCState *env = &cpu->env; 3066 int ret; 3067 3068 if (pcc->handle_mmu_fault) { 3069 ret = pcc->handle_mmu_fault(cpu, addr, access_type, mmu_idx); 3070 } else { 3071 ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, mmu_idx); 3072 } 3073 if (unlikely(ret != 0)) { 3074 raise_exception_err_ra(env, cs->exception_index, env->error_code, 3075 retaddr); 3076 } 3077 } 3078