1 /* 2 * PowerPC memory access 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 "cpu.h" 22 #include "exec/target_page.h" 23 #include "qemu/host-utils.h" 24 #include "exec/helper-proto.h" 25 #include "helper_regs.h" 26 #include "accel/tcg/cpu-ldst.h" 27 #include "accel/tcg/helper-retaddr.h" 28 #include "accel/tcg/probe.h" 29 #include "internal.h" 30 #include "qemu/atomic128.h" 31 32 /* #define DEBUG_OP */ 33 34 static inline bool needs_byteswap(const CPUPPCState *env) 35 { 36 #if TARGET_BIG_ENDIAN 37 return FIELD_EX64(env->msr, MSR, LE); 38 #else 39 return !FIELD_EX64(env->msr, MSR, LE); 40 #endif 41 } 42 43 /*****************************************************************************/ 44 /* Memory load and stores */ 45 46 static inline target_ulong addr_add(CPUPPCState *env, target_ulong addr, 47 target_long arg) 48 { 49 #if defined(TARGET_PPC64) 50 if (!msr_is_64bit(env, env->msr)) { 51 return (uint32_t)(addr + arg); 52 } else 53 #endif 54 { 55 return addr + arg; 56 } 57 } 58 59 static void *probe_contiguous(CPUPPCState *env, target_ulong addr, uint32_t nb, 60 MMUAccessType access_type, int mmu_idx, 61 uintptr_t raddr) 62 { 63 void *host1, *host2; 64 uint32_t nb_pg1, nb_pg2; 65 66 nb_pg1 = -(addr | TARGET_PAGE_MASK); 67 if (likely(nb <= nb_pg1)) { 68 /* The entire operation is on a single page. */ 69 return probe_access(env, addr, nb, access_type, mmu_idx, raddr); 70 } 71 72 /* The operation spans two pages. */ 73 nb_pg2 = nb - nb_pg1; 74 host1 = probe_access(env, addr, nb_pg1, access_type, mmu_idx, raddr); 75 addr = addr_add(env, addr, nb_pg1); 76 host2 = probe_access(env, addr, nb_pg2, access_type, mmu_idx, raddr); 77 78 /* If the two host pages are contiguous, optimize. */ 79 if (host2 == host1 + nb_pg1) { 80 return host1; 81 } 82 return NULL; 83 } 84 85 void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg) 86 { 87 uintptr_t raddr = GETPC(); 88 int mmu_idx = ppc_env_mmu_index(env, false); 89 void *host = probe_contiguous(env, addr, (32 - reg) * 4, 90 MMU_DATA_LOAD, mmu_idx, raddr); 91 92 if (likely(host)) { 93 /* Fast path -- the entire operation is in RAM at host. */ 94 for (; reg < 32; reg++) { 95 env->gpr[reg] = (uint32_t)ldl_be_p(host); 96 host += 4; 97 } 98 } else { 99 /* Slow path -- at least some of the operation requires i/o. */ 100 for (; reg < 32; reg++) { 101 env->gpr[reg] = cpu_ldl_mmuidx_ra(env, addr, mmu_idx, raddr); 102 addr = addr_add(env, addr, 4); 103 } 104 } 105 } 106 107 void helper_stmw(CPUPPCState *env, target_ulong addr, uint32_t reg) 108 { 109 uintptr_t raddr = GETPC(); 110 int mmu_idx = ppc_env_mmu_index(env, false); 111 void *host = probe_contiguous(env, addr, (32 - reg) * 4, 112 MMU_DATA_STORE, mmu_idx, raddr); 113 114 if (likely(host)) { 115 /* Fast path -- the entire operation is in RAM at host. */ 116 for (; reg < 32; reg++) { 117 stl_be_p(host, env->gpr[reg]); 118 host += 4; 119 } 120 } else { 121 /* Slow path -- at least some of the operation requires i/o. */ 122 for (; reg < 32; reg++) { 123 cpu_stl_mmuidx_ra(env, addr, env->gpr[reg], mmu_idx, raddr); 124 addr = addr_add(env, addr, 4); 125 } 126 } 127 } 128 129 static void do_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb, 130 uint32_t reg, uintptr_t raddr) 131 { 132 int mmu_idx; 133 void *host; 134 uint32_t val; 135 136 if (unlikely(nb == 0)) { 137 return; 138 } 139 140 mmu_idx = ppc_env_mmu_index(env, false); 141 host = probe_contiguous(env, addr, nb, MMU_DATA_LOAD, mmu_idx, raddr); 142 143 if (likely(host)) { 144 /* Fast path -- the entire operation is in RAM at host. */ 145 for (; nb > 3; nb -= 4) { 146 env->gpr[reg] = (uint32_t)ldl_be_p(host); 147 reg = (reg + 1) % 32; 148 host += 4; 149 } 150 switch (nb) { 151 default: 152 return; 153 case 1: 154 val = ldub_p(host) << 24; 155 break; 156 case 2: 157 val = lduw_be_p(host) << 16; 158 break; 159 case 3: 160 val = (lduw_be_p(host) << 16) | (ldub_p(host + 2) << 8); 161 break; 162 } 163 } else { 164 /* Slow path -- at least some of the operation requires i/o. */ 165 for (; nb > 3; nb -= 4) { 166 env->gpr[reg] = cpu_ldl_mmuidx_ra(env, addr, mmu_idx, raddr); 167 reg = (reg + 1) % 32; 168 addr = addr_add(env, addr, 4); 169 } 170 switch (nb) { 171 default: 172 return; 173 case 1: 174 val = cpu_ldub_mmuidx_ra(env, addr, mmu_idx, raddr) << 24; 175 break; 176 case 2: 177 val = cpu_lduw_mmuidx_ra(env, addr, mmu_idx, raddr) << 16; 178 break; 179 case 3: 180 val = cpu_lduw_mmuidx_ra(env, addr, mmu_idx, raddr) << 16; 181 addr = addr_add(env, addr, 2); 182 val |= cpu_ldub_mmuidx_ra(env, addr, mmu_idx, raddr) << 8; 183 break; 184 } 185 } 186 env->gpr[reg] = val; 187 } 188 189 void helper_lsw(CPUPPCState *env, target_ulong addr, 190 uint32_t nb, uint32_t reg) 191 { 192 do_lsw(env, addr, nb, reg, GETPC()); 193 } 194 195 /* 196 * PPC32 specification says we must generate an exception if rA is in 197 * the range of registers to be loaded. In an other hand, IBM says 198 * this is valid, but rA won't be loaded. For now, I'll follow the 199 * spec... 200 */ 201 void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg, 202 uint32_t ra, uint32_t rb) 203 { 204 if (likely(xer_bc != 0)) { 205 int num_used_regs = DIV_ROUND_UP(xer_bc, 4); 206 if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) || 207 lsw_reg_in_range(reg, num_used_regs, rb))) { 208 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 209 POWERPC_EXCP_INVAL | 210 POWERPC_EXCP_INVAL_LSWX, GETPC()); 211 } else { 212 do_lsw(env, addr, xer_bc, reg, GETPC()); 213 } 214 } 215 } 216 217 void helper_stsw(CPUPPCState *env, target_ulong addr, uint32_t nb, 218 uint32_t reg) 219 { 220 uintptr_t raddr = GETPC(); 221 int mmu_idx; 222 void *host; 223 uint32_t val; 224 225 if (unlikely(nb == 0)) { 226 return; 227 } 228 229 mmu_idx = ppc_env_mmu_index(env, false); 230 host = probe_contiguous(env, addr, nb, MMU_DATA_STORE, mmu_idx, raddr); 231 232 if (likely(host)) { 233 /* Fast path -- the entire operation is in RAM at host. */ 234 for (; nb > 3; nb -= 4) { 235 stl_be_p(host, env->gpr[reg]); 236 reg = (reg + 1) % 32; 237 host += 4; 238 } 239 val = env->gpr[reg]; 240 switch (nb) { 241 case 1: 242 stb_p(host, val >> 24); 243 break; 244 case 2: 245 stw_be_p(host, val >> 16); 246 break; 247 case 3: 248 stw_be_p(host, val >> 16); 249 stb_p(host + 2, val >> 8); 250 break; 251 } 252 } else { 253 for (; nb > 3; nb -= 4) { 254 cpu_stl_mmuidx_ra(env, addr, env->gpr[reg], mmu_idx, raddr); 255 reg = (reg + 1) % 32; 256 addr = addr_add(env, addr, 4); 257 } 258 val = env->gpr[reg]; 259 switch (nb) { 260 case 1: 261 cpu_stb_mmuidx_ra(env, addr, val >> 24, mmu_idx, raddr); 262 break; 263 case 2: 264 cpu_stw_mmuidx_ra(env, addr, val >> 16, mmu_idx, raddr); 265 break; 266 case 3: 267 cpu_stw_mmuidx_ra(env, addr, val >> 16, mmu_idx, raddr); 268 addr = addr_add(env, addr, 2); 269 cpu_stb_mmuidx_ra(env, addr, val >> 8, mmu_idx, raddr); 270 break; 271 } 272 } 273 } 274 275 static void dcbz_common(CPUPPCState *env, target_ulong addr, 276 int mmu_idx, int dcbz_size, uintptr_t retaddr) 277 { 278 target_ulong mask = ~(target_ulong)(dcbz_size - 1); 279 void *haddr; 280 281 /* Align address */ 282 addr &= mask; 283 284 /* Check reservation */ 285 if (unlikely((env->reserve_addr & mask) == addr)) { 286 env->reserve_addr = (target_ulong)-1ULL; 287 } 288 289 /* Try fast path translate */ 290 #ifdef CONFIG_USER_ONLY 291 haddr = tlb_vaddr_to_host(env, addr, MMU_DATA_STORE, mmu_idx); 292 #else 293 haddr = probe_write(env, addr, dcbz_size, mmu_idx, retaddr); 294 if (unlikely(!haddr)) { 295 /* Slow path */ 296 for (int i = 0; i < dcbz_size; i += 8) { 297 cpu_stq_mmuidx_ra(env, addr + i, 0, mmu_idx, retaddr); 298 } 299 return; 300 } 301 #endif 302 303 set_helper_retaddr(retaddr); 304 memset(haddr, 0, dcbz_size); 305 clear_helper_retaddr(); 306 } 307 308 void helper_dcbz(CPUPPCState *env, target_ulong addr, int mmu_idx) 309 { 310 dcbz_common(env, addr, mmu_idx, env->dcache_line_size, GETPC()); 311 } 312 313 #ifdef TARGET_PPC64 314 void helper_dcbzl(CPUPPCState *env, target_ulong addr) 315 { 316 int dcbz_size = env->dcache_line_size; 317 318 /* 319 * The translator checked for POWERPC_EXCP_970. 320 * All that's left is to check HID5. 321 */ 322 if (((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) { 323 dcbz_size = 32; 324 } 325 326 dcbz_common(env, addr, ppc_env_mmu_index(env, false), dcbz_size, GETPC()); 327 } 328 #endif 329 330 void helper_icbi(CPUPPCState *env, target_ulong addr) 331 { 332 addr &= ~(env->dcache_line_size - 1); 333 /* 334 * Invalidate one cache line : 335 * PowerPC specification says this is to be treated like a load 336 * (not a fetch) by the MMU. To be sure it will be so, 337 * do the load "by hand". 338 */ 339 cpu_ldl_data_ra(env, addr, GETPC()); 340 } 341 342 void helper_icbiep(CPUPPCState *env, target_ulong addr) 343 { 344 #if !defined(CONFIG_USER_ONLY) 345 /* See comments above */ 346 addr &= ~(env->dcache_line_size - 1); 347 cpu_ldl_mmuidx_ra(env, addr, PPC_TLB_EPID_LOAD, GETPC()); 348 #endif 349 } 350 351 /* XXX: to be tested */ 352 target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg, 353 uint32_t ra, uint32_t rb) 354 { 355 int i, c, d; 356 357 d = 24; 358 for (i = 0; i < xer_bc; i++) { 359 c = cpu_ldub_data_ra(env, addr, GETPC()); 360 addr = addr_add(env, addr, 1); 361 /* ra (if not 0) and rb are never modified */ 362 if (likely(reg != rb && (ra == 0 || reg != ra))) { 363 env->gpr[reg] = (env->gpr[reg] & ~(0xFF << d)) | (c << d); 364 } 365 if (unlikely(c == xer_cmp)) { 366 break; 367 } 368 if (likely(d != 0)) { 369 d -= 8; 370 } else { 371 d = 24; 372 reg++; 373 reg = reg & 0x1F; 374 } 375 } 376 return i; 377 } 378 379 /*****************************************************************************/ 380 /* Altivec extension helpers */ 381 #if HOST_BIG_ENDIAN 382 #define HI_IDX 0 383 #define LO_IDX 1 384 #else 385 #define HI_IDX 1 386 #define LO_IDX 0 387 #endif 388 389 /* 390 * We use MSR_LE to determine index ordering in a vector. However, 391 * byteswapping is not simply controlled by MSR_LE. We also need to 392 * take into account endianness of the target. This is done for the 393 * little-endian PPC64 user-mode target. 394 */ 395 396 #define LVE(name, access, swap, element) \ 397 void helper_##name(CPUPPCState *env, ppc_avr_t *r, \ 398 target_ulong addr) \ 399 { \ 400 size_t n_elems = ARRAY_SIZE(r->element); \ 401 int adjust = HI_IDX * (n_elems - 1); \ 402 int sh = sizeof(r->element[0]) >> 1; \ 403 int index = (addr & 0xf) >> sh; \ 404 if (FIELD_EX64(env->msr, MSR, LE)) { \ 405 index = n_elems - index - 1; \ 406 } \ 407 \ 408 if (needs_byteswap(env)) { \ 409 r->element[LO_IDX ? index : (adjust - index)] = \ 410 swap(access(env, addr, GETPC())); \ 411 } else { \ 412 r->element[LO_IDX ? index : (adjust - index)] = \ 413 access(env, addr, GETPC()); \ 414 } \ 415 } 416 #define I(x) (x) 417 LVE(LVEBX, cpu_ldub_data_ra, I, u8) 418 LVE(LVEHX, cpu_lduw_data_ra, bswap16, u16) 419 LVE(LVEWX, cpu_ldl_data_ra, bswap32, u32) 420 #undef I 421 #undef LVE 422 423 #define STVE(name, access, swap, element) \ 424 void helper_##name(CPUPPCState *env, ppc_avr_t *r, \ 425 target_ulong addr) \ 426 { \ 427 size_t n_elems = ARRAY_SIZE(r->element); \ 428 int adjust = HI_IDX * (n_elems - 1); \ 429 int sh = sizeof(r->element[0]) >> 1; \ 430 int index = (addr & 0xf) >> sh; \ 431 if (FIELD_EX64(env->msr, MSR, LE)) { \ 432 index = n_elems - index - 1; \ 433 } \ 434 \ 435 if (needs_byteswap(env)) { \ 436 access(env, addr, swap(r->element[LO_IDX ? index : \ 437 (adjust - index)]), \ 438 GETPC()); \ 439 } else { \ 440 access(env, addr, r->element[LO_IDX ? index : \ 441 (adjust - index)], GETPC()); \ 442 } \ 443 } 444 #define I(x) (x) 445 STVE(STVEBX, cpu_stb_data_ra, I, u8) 446 STVE(STVEHX, cpu_stw_data_ra, bswap16, u16) 447 STVE(STVEWX, cpu_stl_data_ra, bswap32, u32) 448 #undef I 449 #undef LVE 450 451 #ifdef TARGET_PPC64 452 #define GET_NB(rb) ((rb >> 56) & 0xFF) 453 454 #define VSX_LXVL(name, lj) \ 455 void helper_##name(CPUPPCState *env, target_ulong addr, \ 456 ppc_vsr_t *xt, target_ulong rb) \ 457 { \ 458 ppc_vsr_t t; \ 459 uint64_t nb = GET_NB(rb); \ 460 int i; \ 461 \ 462 t.s128 = int128_zero(); \ 463 if (nb) { \ 464 nb = (nb >= 16) ? 16 : nb; \ 465 if (FIELD_EX64(env->msr, MSR, LE) && !lj) { \ 466 for (i = 16; i > 16 - nb; i--) { \ 467 t.VsrB(i - 1) = cpu_ldub_data_ra(env, addr, GETPC()); \ 468 addr = addr_add(env, addr, 1); \ 469 } \ 470 } else { \ 471 for (i = 0; i < nb; i++) { \ 472 t.VsrB(i) = cpu_ldub_data_ra(env, addr, GETPC()); \ 473 addr = addr_add(env, addr, 1); \ 474 } \ 475 } \ 476 } \ 477 *xt = t; \ 478 } 479 480 VSX_LXVL(LXVL, 0) 481 VSX_LXVL(LXVLL, 1) 482 #undef VSX_LXVL 483 484 #define VSX_STXVL(name, lj) \ 485 void helper_##name(CPUPPCState *env, target_ulong addr, \ 486 ppc_vsr_t *xt, target_ulong rb) \ 487 { \ 488 target_ulong nb = GET_NB(rb); \ 489 int i; \ 490 \ 491 if (!nb) { \ 492 return; \ 493 } \ 494 \ 495 nb = (nb >= 16) ? 16 : nb; \ 496 if (FIELD_EX64(env->msr, MSR, LE) && !lj) { \ 497 for (i = 16; i > 16 - nb; i--) { \ 498 cpu_stb_data_ra(env, addr, xt->VsrB(i - 1), GETPC()); \ 499 addr = addr_add(env, addr, 1); \ 500 } \ 501 } else { \ 502 for (i = 0; i < nb; i++) { \ 503 cpu_stb_data_ra(env, addr, xt->VsrB(i), GETPC()); \ 504 addr = addr_add(env, addr, 1); \ 505 } \ 506 } \ 507 } 508 509 VSX_STXVL(STXVL, 0) 510 VSX_STXVL(STXVLL, 1) 511 #undef VSX_STXVL 512 #undef GET_NB 513 #endif /* TARGET_PPC64 */ 514 515 #undef HI_IDX 516 #undef LO_IDX 517 518 void helper_tbegin(CPUPPCState *env) 519 { 520 /* 521 * As a degenerate implementation, always fail tbegin. The reason 522 * given is "Nesting overflow". The "persistent" bit is set, 523 * providing a hint to the error handler to not retry. The TFIAR 524 * captures the address of the failure, which is this tbegin 525 * instruction. Instruction execution will continue with the next 526 * instruction in memory, which is precisely what we want. 527 */ 528 529 env->spr[SPR_TEXASR] = 530 (1ULL << TEXASR_FAILURE_PERSISTENT) | 531 (1ULL << TEXASR_NESTING_OVERFLOW) | 532 (FIELD_EX64_HV(env->msr) << TEXASR_PRIVILEGE_HV) | 533 (FIELD_EX64(env->msr, MSR, PR) << TEXASR_PRIVILEGE_PR) | 534 (1ULL << TEXASR_FAILURE_SUMMARY) | 535 (1ULL << TEXASR_TFIAR_EXACT); 536 env->spr[SPR_TFIAR] = env->nip | (FIELD_EX64_HV(env->msr) << 1) | 537 FIELD_EX64(env->msr, MSR, PR); 538 env->spr[SPR_TFHAR] = env->nip + 4; 539 env->crf[0] = 0xB; /* 0b1010 = transaction failure */ 540 } 541