1 /* 2 * S/390 misc helper routines 3 * 4 * Copyright (c) 2009 Ulrich Hecht 5 * Copyright (c) 2009 Alexander Graf 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "qemu/cutils.h" 23 #include "qemu/log.h" 24 #include "cpu.h" 25 #include "s390x-internal.h" 26 #include "qemu/host-utils.h" 27 #include "exec/helper-proto.h" 28 #include "qemu/timer.h" 29 #include "exec/exec-all.h" 30 #include "exec/cputlb.h" 31 #include "accel/tcg/cpu-ldst.h" 32 #include "exec/target_page.h" 33 #include "qapi/error.h" 34 #include "tcg_s390x.h" 35 #include "s390-tod.h" 36 37 #if !defined(CONFIG_USER_ONLY) 38 #include "system/cpus.h" 39 #include "system/system.h" 40 #include "hw/s390x/ebcdic.h" 41 #include "hw/s390x/s390-hypercall.h" 42 #include "hw/s390x/sclp.h" 43 #include "hw/s390x/s390_flic.h" 44 #include "hw/s390x/ioinst.h" 45 #include "hw/s390x/s390-pci-inst.h" 46 #include "hw/boards.h" 47 #include "hw/s390x/tod.h" 48 #include CONFIG_DEVICES 49 #endif 50 51 /* #define DEBUG_HELPER */ 52 #ifdef DEBUG_HELPER 53 #define HELPER_LOG(x...) qemu_log(x) 54 #else 55 #define HELPER_LOG(x...) 56 #endif 57 58 /* Raise an exception statically from a TB. */ 59 void HELPER(exception)(CPUS390XState *env, uint32_t excp) 60 { 61 CPUState *cs = env_cpu(env); 62 63 HELPER_LOG("%s: exception %d\n", __func__, excp); 64 cs->exception_index = excp; 65 cpu_loop_exit(cs); 66 } 67 68 /* Store CPU Timer (also used for EXTRACT CPU TIME) */ 69 uint64_t HELPER(stpt)(CPUS390XState *env) 70 { 71 #if defined(CONFIG_USER_ONLY) 72 /* 73 * Fake a descending CPU timer. We could get negative values here, 74 * but we don't care as it is up to the OS when to process that 75 * interrupt and reset to > 0. 76 */ 77 return UINT64_MAX - (uint64_t)cpu_get_host_ticks(); 78 #else 79 return time2tod(env->cputm - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); 80 #endif 81 } 82 83 /* Store Clock */ 84 uint64_t HELPER(stck)(CPUS390XState *env) 85 { 86 #ifdef CONFIG_USER_ONLY 87 struct timespec ts; 88 uint64_t ns; 89 90 clock_gettime(CLOCK_REALTIME, &ts); 91 ns = ts.tv_sec * NANOSECONDS_PER_SECOND + ts.tv_nsec; 92 93 return TOD_UNIX_EPOCH + time2tod(ns); 94 #else 95 S390TODState *td = s390_get_todstate(); 96 S390TODClass *tdc = S390_TOD_GET_CLASS(td); 97 S390TOD tod; 98 99 tdc->get(td, &tod, &error_abort); 100 return tod.low; 101 #endif 102 } 103 104 #ifndef CONFIG_USER_ONLY 105 /* SCLP service call */ 106 uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2) 107 { 108 bql_lock(); 109 int r = sclp_service_call(env_archcpu(env), r1, r2); 110 bql_unlock(); 111 if (r < 0) { 112 tcg_s390_program_interrupt(env, -r, GETPC()); 113 } 114 return r; 115 } 116 117 void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num) 118 { 119 uint64_t r; 120 121 switch (num) { 122 #ifdef CONFIG_S390_CCW_VIRTIO 123 case 0x500: 124 /* QEMU/KVM hypercall */ 125 bql_lock(); 126 handle_diag_500(env_archcpu(env), GETPC()); 127 bql_unlock(); 128 r = 0; 129 break; 130 #endif /* CONFIG_S390_CCW_VIRTIO */ 131 case 0x44: 132 /* yield */ 133 r = 0; 134 break; 135 case 0x308: 136 /* ipl */ 137 bql_lock(); 138 handle_diag_308(env, r1, r3, GETPC()); 139 bql_unlock(); 140 r = 0; 141 break; 142 case 0x288: 143 /* time bomb (watchdog) */ 144 r = handle_diag_288(env, r1, r3); 145 break; 146 default: 147 r = -1; 148 break; 149 } 150 151 if (r) { 152 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC()); 153 } 154 } 155 156 /* Set Prefix */ 157 void HELPER(spx)(CPUS390XState *env, uint64_t a1) 158 { 159 const uint32_t prefix = a1 & 0x7fffe000; 160 const uint32_t old_prefix = env->psa; 161 CPUState *cs = env_cpu(env); 162 163 if (prefix == old_prefix) { 164 return; 165 } 166 /* 167 * Since prefix got aligned to 8k and memory increments are a multiple of 168 * 8k checking the first page is sufficient 169 */ 170 if (!mmu_absolute_addr_valid(prefix, true)) { 171 tcg_s390_program_interrupt(env, PGM_ADDRESSING, GETPC()); 172 } 173 174 env->psa = prefix; 175 HELPER_LOG("prefix: %#x\n", prefix); 176 tlb_flush_page(cs, 0); 177 tlb_flush_page(cs, TARGET_PAGE_SIZE); 178 if (prefix != 0) { 179 tlb_flush_page(cs, prefix); 180 tlb_flush_page(cs, prefix + TARGET_PAGE_SIZE); 181 } 182 if (old_prefix != 0) { 183 tlb_flush_page(cs, old_prefix); 184 tlb_flush_page(cs, old_prefix + TARGET_PAGE_SIZE); 185 } 186 } 187 188 static void update_ckc_timer(CPUS390XState *env) 189 { 190 S390TODState *td = s390_get_todstate(); 191 uint64_t time; 192 193 /* stop the timer and remove pending CKC IRQs */ 194 timer_del(env->tod_timer); 195 g_assert(bql_locked()); 196 env->pending_int &= ~INTERRUPT_EXT_CLOCK_COMPARATOR; 197 198 /* the tod has to exceed the ckc, this can never happen if ckc is all 1's */ 199 if (env->ckc == -1ULL) { 200 return; 201 } 202 203 /* difference between origins */ 204 time = env->ckc - td->base.low; 205 206 /* nanoseconds */ 207 time = tod2time(time); 208 209 timer_mod(env->tod_timer, time); 210 } 211 212 /* Set Clock Comparator */ 213 void HELPER(sckc)(CPUS390XState *env, uint64_t ckc) 214 { 215 env->ckc = ckc; 216 217 bql_lock(); 218 update_ckc_timer(env); 219 bql_unlock(); 220 } 221 222 void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque) 223 { 224 update_ckc_timer(cpu_env(cs)); 225 } 226 227 /* Set Clock */ 228 uint32_t HELPER(sck)(CPUS390XState *env, uint64_t tod_low) 229 { 230 S390TODState *td = s390_get_todstate(); 231 S390TODClass *tdc = S390_TOD_GET_CLASS(td); 232 S390TOD tod = { 233 .high = 0, 234 .low = tod_low, 235 }; 236 237 bql_lock(); 238 tdc->set(td, &tod, &error_abort); 239 bql_unlock(); 240 return 0; 241 } 242 243 /* Set Tod Programmable Field */ 244 void HELPER(sckpf)(CPUS390XState *env, uint64_t r0) 245 { 246 uint32_t val = r0; 247 248 if (val & 0xffff0000) { 249 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC()); 250 } 251 env->todpr = val; 252 } 253 254 /* Store Clock Comparator */ 255 uint64_t HELPER(stckc)(CPUS390XState *env) 256 { 257 return env->ckc; 258 } 259 260 /* Set CPU Timer */ 261 void HELPER(spt)(CPUS390XState *env, uint64_t time) 262 { 263 if (time == -1ULL) { 264 return; 265 } 266 267 /* nanoseconds */ 268 time = tod2time(time); 269 270 env->cputm = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time; 271 272 timer_mod(env->cpu_timer, env->cputm); 273 } 274 275 /* Store System Information */ 276 uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1) 277 { 278 const uintptr_t ra = GETPC(); 279 const uint32_t sel1 = r0 & STSI_R0_SEL1_MASK; 280 const uint32_t sel2 = r1 & STSI_R1_SEL2_MASK; 281 const MachineState *ms = MACHINE(qdev_get_machine()); 282 uint16_t total_cpus = 0, conf_cpus = 0, reserved_cpus = 0; 283 S390CPU *cpu = env_archcpu(env); 284 SysIB sysib = { }; 285 int i, cc = 0; 286 287 if ((r0 & STSI_R0_FC_MASK) > STSI_R0_FC_LEVEL_3) { 288 /* invalid function code: no other checks are performed */ 289 return 3; 290 } 291 292 if ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK)) { 293 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); 294 } 295 296 if ((r0 & STSI_R0_FC_MASK) == STSI_R0_FC_CURRENT) { 297 /* query the current level: no further checks are performed */ 298 env->regs[0] = STSI_R0_FC_LEVEL_3; 299 return 0; 300 } 301 302 if (a0 & ~TARGET_PAGE_MASK) { 303 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); 304 } 305 306 /* count the cpus and split them into configured and reserved ones */ 307 for (i = 0; i < ms->possible_cpus->len; i++) { 308 total_cpus++; 309 if (ms->possible_cpus->cpus[i].cpu) { 310 conf_cpus++; 311 } else { 312 reserved_cpus++; 313 } 314 } 315 316 /* 317 * In theory, we could report Level 1 / Level 2 as current. However, 318 * the Linux kernel will detect this as running under LPAR and assume 319 * that we have a sclp linemode console (which is always present on 320 * LPAR, but not the default for QEMU), therefore not displaying boot 321 * messages and making booting a Linux kernel under TCG harder. 322 * 323 * For now we fake the same SMP configuration on all levels. 324 * 325 * TODO: We could later make the level configurable via the machine 326 * and change defaults (linemode console) based on machine type 327 * and accelerator. 328 */ 329 switch (r0 & STSI_R0_FC_MASK) { 330 case STSI_R0_FC_LEVEL_1: 331 if ((sel1 == 1) && (sel2 == 1)) { 332 /* Basic Machine Configuration */ 333 char type[5] = {}; 334 335 ebcdic_put(sysib.sysib_111.manuf, "QEMU ", 16); 336 /* same as machine type number in STORE CPU ID, but in EBCDIC */ 337 snprintf(type, ARRAY_SIZE(type), "%X", cpu->model->def->type); 338 ebcdic_put(sysib.sysib_111.type, type, 4); 339 /* model number (not stored in STORE CPU ID for z/Architecture) */ 340 ebcdic_put(sysib.sysib_111.model, "QEMU ", 16); 341 ebcdic_put(sysib.sysib_111.sequence, "QEMU ", 16); 342 ebcdic_put(sysib.sysib_111.plant, "QEMU", 4); 343 } else if ((sel1 == 2) && (sel2 == 1)) { 344 /* Basic Machine CPU */ 345 ebcdic_put(sysib.sysib_121.sequence, "QEMUQEMUQEMUQEMU", 16); 346 ebcdic_put(sysib.sysib_121.plant, "QEMU", 4); 347 sysib.sysib_121.cpu_addr = cpu_to_be16(env->core_id); 348 } else if ((sel1 == 2) && (sel2 == 2)) { 349 /* Basic Machine CPUs */ 350 sysib.sysib_122.capability = cpu_to_be32(0x443afc29); 351 sysib.sysib_122.total_cpus = cpu_to_be16(total_cpus); 352 sysib.sysib_122.conf_cpus = cpu_to_be16(conf_cpus); 353 sysib.sysib_122.reserved_cpus = cpu_to_be16(reserved_cpus); 354 } else { 355 cc = 3; 356 } 357 break; 358 case STSI_R0_FC_LEVEL_2: 359 if ((sel1 == 2) && (sel2 == 1)) { 360 /* LPAR CPU */ 361 ebcdic_put(sysib.sysib_221.sequence, "QEMUQEMUQEMUQEMU", 16); 362 ebcdic_put(sysib.sysib_221.plant, "QEMU", 4); 363 sysib.sysib_221.cpu_addr = cpu_to_be16(env->core_id); 364 } else if ((sel1 == 2) && (sel2 == 2)) { 365 /* LPAR CPUs */ 366 sysib.sysib_222.lcpuc = 0x80; /* dedicated */ 367 sysib.sysib_222.total_cpus = cpu_to_be16(total_cpus); 368 sysib.sysib_222.conf_cpus = cpu_to_be16(conf_cpus); 369 sysib.sysib_222.reserved_cpus = cpu_to_be16(reserved_cpus); 370 ebcdic_put(sysib.sysib_222.name, "QEMU ", 8); 371 sysib.sysib_222.caf = cpu_to_be32(1000); 372 sysib.sysib_222.dedicated_cpus = cpu_to_be16(conf_cpus); 373 } else { 374 cc = 3; 375 } 376 break; 377 case STSI_R0_FC_LEVEL_3: 378 if ((sel1 == 2) && (sel2 == 2)) { 379 /* VM CPUs */ 380 sysib.sysib_322.count = 1; 381 sysib.sysib_322.vm[0].total_cpus = cpu_to_be16(total_cpus); 382 sysib.sysib_322.vm[0].conf_cpus = cpu_to_be16(conf_cpus); 383 sysib.sysib_322.vm[0].reserved_cpus = cpu_to_be16(reserved_cpus); 384 sysib.sysib_322.vm[0].caf = cpu_to_be32(1000); 385 /* Linux kernel uses this to distinguish us from z/VM */ 386 ebcdic_put(sysib.sysib_322.vm[0].cpi, "KVM/Linux ", 16); 387 sysib.sysib_322.vm[0].ext_name_encoding = 2; /* UTF-8 */ 388 389 /* If our VM has a name, use the real name */ 390 if (qemu_name) { 391 memset(sysib.sysib_322.vm[0].name, 0x40, 392 sizeof(sysib.sysib_322.vm[0].name)); 393 ebcdic_put(sysib.sysib_322.vm[0].name, qemu_name, 394 MIN(sizeof(sysib.sysib_322.vm[0].name), 395 strlen(qemu_name))); 396 strpadcpy((char *)sysib.sysib_322.ext_names[0], 397 sizeof(sysib.sysib_322.ext_names[0]), 398 qemu_name, '\0'); 399 400 } else { 401 ebcdic_put(sysib.sysib_322.vm[0].name, "TCGguest", 8); 402 strcpy((char *)sysib.sysib_322.ext_names[0], "TCGguest"); 403 } 404 405 /* add the uuid */ 406 memcpy(sysib.sysib_322.vm[0].uuid, &qemu_uuid, 407 sizeof(sysib.sysib_322.vm[0].uuid)); 408 } else { 409 cc = 3; 410 } 411 break; 412 } 413 414 if (cc == 0) { 415 if (s390_cpu_virt_mem_write(cpu, a0, 0, &sysib, sizeof(sysib))) { 416 s390_cpu_virt_mem_handle_exc(cpu, ra); 417 } 418 } 419 420 return cc; 421 } 422 423 uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1, 424 uint32_t r3) 425 { 426 int cc; 427 428 /* TODO: needed to inject interrupts - push further down */ 429 bql_lock(); 430 cc = handle_sigp(env, order_code & SIGP_ORDER_MASK, r1, r3); 431 bql_unlock(); 432 433 return cc; 434 } 435 #endif 436 437 #ifndef CONFIG_USER_ONLY 438 void HELPER(xsch)(CPUS390XState *env, uint64_t r1) 439 { 440 S390CPU *cpu = env_archcpu(env); 441 bql_lock(); 442 ioinst_handle_xsch(cpu, r1, GETPC()); 443 bql_unlock(); 444 } 445 446 void HELPER(csch)(CPUS390XState *env, uint64_t r1) 447 { 448 S390CPU *cpu = env_archcpu(env); 449 bql_lock(); 450 ioinst_handle_csch(cpu, r1, GETPC()); 451 bql_unlock(); 452 } 453 454 void HELPER(hsch)(CPUS390XState *env, uint64_t r1) 455 { 456 S390CPU *cpu = env_archcpu(env); 457 bql_lock(); 458 ioinst_handle_hsch(cpu, r1, GETPC()); 459 bql_unlock(); 460 } 461 462 void HELPER(msch)(CPUS390XState *env, uint64_t r1, uint64_t inst) 463 { 464 S390CPU *cpu = env_archcpu(env); 465 bql_lock(); 466 ioinst_handle_msch(cpu, r1, inst >> 16, GETPC()); 467 bql_unlock(); 468 } 469 470 void HELPER(rchp)(CPUS390XState *env, uint64_t r1) 471 { 472 S390CPU *cpu = env_archcpu(env); 473 bql_lock(); 474 ioinst_handle_rchp(cpu, r1, GETPC()); 475 bql_unlock(); 476 } 477 478 void HELPER(rsch)(CPUS390XState *env, uint64_t r1) 479 { 480 S390CPU *cpu = env_archcpu(env); 481 bql_lock(); 482 ioinst_handle_rsch(cpu, r1, GETPC()); 483 bql_unlock(); 484 } 485 486 void HELPER(sal)(CPUS390XState *env, uint64_t r1) 487 { 488 S390CPU *cpu = env_archcpu(env); 489 490 bql_lock(); 491 ioinst_handle_sal(cpu, r1, GETPC()); 492 bql_unlock(); 493 } 494 495 void HELPER(schm)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint64_t inst) 496 { 497 S390CPU *cpu = env_archcpu(env); 498 499 bql_lock(); 500 ioinst_handle_schm(cpu, r1, r2, inst >> 16, GETPC()); 501 bql_unlock(); 502 } 503 504 void HELPER(ssch)(CPUS390XState *env, uint64_t r1, uint64_t inst) 505 { 506 S390CPU *cpu = env_archcpu(env); 507 bql_lock(); 508 ioinst_handle_ssch(cpu, r1, inst >> 16, GETPC()); 509 bql_unlock(); 510 } 511 512 void HELPER(stcrw)(CPUS390XState *env, uint64_t inst) 513 { 514 S390CPU *cpu = env_archcpu(env); 515 516 bql_lock(); 517 ioinst_handle_stcrw(cpu, inst >> 16, GETPC()); 518 bql_unlock(); 519 } 520 521 void HELPER(stsch)(CPUS390XState *env, uint64_t r1, uint64_t inst) 522 { 523 S390CPU *cpu = env_archcpu(env); 524 bql_lock(); 525 ioinst_handle_stsch(cpu, r1, inst >> 16, GETPC()); 526 bql_unlock(); 527 } 528 529 uint32_t HELPER(tpi)(CPUS390XState *env, uint64_t addr) 530 { 531 const uintptr_t ra = GETPC(); 532 S390CPU *cpu = env_archcpu(env); 533 QEMUS390FLICState *flic = s390_get_qemu_flic(s390_get_flic()); 534 QEMUS390FlicIO *io = NULL; 535 LowCore *lowcore; 536 537 if (addr & 0x3) { 538 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); 539 } 540 541 bql_lock(); 542 io = qemu_s390_flic_dequeue_io(flic, env->cregs[6]); 543 if (!io) { 544 bql_unlock(); 545 return 0; 546 } 547 548 if (addr) { 549 struct { 550 uint16_t id; 551 uint16_t nr; 552 uint32_t parm; 553 } intc = { 554 .id = cpu_to_be16(io->id), 555 .nr = cpu_to_be16(io->nr), 556 .parm = cpu_to_be32(io->parm), 557 }; 558 559 if (s390_cpu_virt_mem_write(cpu, addr, 0, &intc, sizeof(intc))) { 560 /* writing failed, reinject and properly clean up */ 561 s390_io_interrupt(io->id, io->nr, io->parm, io->word); 562 bql_unlock(); 563 g_free(io); 564 s390_cpu_virt_mem_handle_exc(cpu, ra); 565 return 0; 566 } 567 } else { 568 /* no protection applies */ 569 lowcore = cpu_map_lowcore(env); 570 lowcore->subchannel_id = cpu_to_be16(io->id); 571 lowcore->subchannel_nr = cpu_to_be16(io->nr); 572 lowcore->io_int_parm = cpu_to_be32(io->parm); 573 lowcore->io_int_word = cpu_to_be32(io->word); 574 cpu_unmap_lowcore(lowcore); 575 } 576 577 g_free(io); 578 bql_unlock(); 579 return 1; 580 } 581 582 void HELPER(tsch)(CPUS390XState *env, uint64_t r1, uint64_t inst) 583 { 584 S390CPU *cpu = env_archcpu(env); 585 bql_lock(); 586 ioinst_handle_tsch(cpu, r1, inst >> 16, GETPC()); 587 bql_unlock(); 588 } 589 590 void HELPER(chsc)(CPUS390XState *env, uint64_t inst) 591 { 592 S390CPU *cpu = env_archcpu(env); 593 bql_lock(); 594 ioinst_handle_chsc(cpu, inst >> 16, GETPC()); 595 bql_unlock(); 596 } 597 #endif 598 599 #ifndef CONFIG_USER_ONLY 600 static G_NORETURN void per_raise_exception(CPUS390XState *env) 601 { 602 trigger_pgm_exception(env, PGM_PER); 603 cpu_loop_exit(env_cpu(env)); 604 } 605 606 static G_NORETURN void per_raise_exception_log(CPUS390XState *env) 607 { 608 qemu_log_mask(CPU_LOG_INT, "PER interrupt after 0x%" PRIx64 "\n", 609 env->per_address); 610 per_raise_exception(env); 611 } 612 613 void HELPER(per_check_exception)(CPUS390XState *env) 614 { 615 /* psw_addr, per_address and int_pgm_ilen are already set. */ 616 if (unlikely(env->per_perc_atmid)) { 617 per_raise_exception_log(env); 618 } 619 } 620 621 /* Check if an address is within the PER starting address and the PER 622 ending address. The address range might loop. */ 623 static inline bool get_per_in_range(CPUS390XState *env, uint64_t addr) 624 { 625 if (env->cregs[10] <= env->cregs[11]) { 626 return env->cregs[10] <= addr && addr <= env->cregs[11]; 627 } else { 628 return env->cregs[10] <= addr || addr <= env->cregs[11]; 629 } 630 } 631 632 void HELPER(per_branch)(CPUS390XState *env, uint64_t dest, uint32_t ilen) 633 { 634 if ((env->cregs[9] & PER_CR9_CONTROL_BRANCH_ADDRESS) 635 && !get_per_in_range(env, dest)) { 636 return; 637 } 638 639 env->psw.addr = dest; 640 env->int_pgm_ilen = ilen; 641 env->per_address = env->gbea; 642 env->per_perc_atmid = PER_CODE_EVENT_BRANCH | get_per_atmid(env); 643 per_raise_exception_log(env); 644 } 645 646 void HELPER(per_ifetch)(CPUS390XState *env, uint32_t ilen) 647 { 648 if (get_per_in_range(env, env->psw.addr)) { 649 env->per_address = env->psw.addr; 650 env->int_pgm_ilen = ilen; 651 env->per_perc_atmid = PER_CODE_EVENT_IFETCH | get_per_atmid(env); 652 653 /* If the instruction has to be nullified, trigger the 654 exception immediately. */ 655 if (env->cregs[9] & PER_CR9_EVENT_IFETCH_NULLIFICATION) { 656 env->per_perc_atmid |= PER_CODE_EVENT_NULLIFICATION; 657 qemu_log_mask(CPU_LOG_INT, "PER interrupt before 0x%" PRIx64 "\n", 658 env->per_address); 659 per_raise_exception(env); 660 } 661 } 662 } 663 664 void HELPER(per_store_real)(CPUS390XState *env, uint32_t ilen) 665 { 666 /* PSW is saved just before calling the helper. */ 667 env->per_address = env->psw.addr; 668 env->int_pgm_ilen = ilen; 669 env->per_perc_atmid = PER_CODE_EVENT_STORE_REAL | get_per_atmid(env); 670 per_raise_exception_log(env); 671 } 672 #endif 673 674 static uint8_t stfl_bytes[2048]; 675 static unsigned int used_stfl_bytes; 676 677 static void prepare_stfl(void) 678 { 679 static bool initialized; 680 int i; 681 682 /* racy, but we don't care, the same values are always written */ 683 if (initialized) { 684 return; 685 } 686 687 s390_get_feat_block(S390_FEAT_TYPE_STFL, stfl_bytes); 688 for (i = 0; i < sizeof(stfl_bytes); i++) { 689 if (stfl_bytes[i]) { 690 used_stfl_bytes = i + 1; 691 } 692 } 693 initialized = true; 694 } 695 696 #ifndef CONFIG_USER_ONLY 697 void HELPER(stfl)(CPUS390XState *env) 698 { 699 LowCore *lowcore; 700 701 lowcore = cpu_map_lowcore(env); 702 prepare_stfl(); 703 memcpy(&lowcore->stfl_fac_list, stfl_bytes, sizeof(lowcore->stfl_fac_list)); 704 cpu_unmap_lowcore(lowcore); 705 } 706 #endif 707 708 uint32_t HELPER(stfle)(CPUS390XState *env, uint64_t addr) 709 { 710 const uintptr_t ra = GETPC(); 711 const int count_bytes = ((env->regs[0] & 0xff) + 1) * 8; 712 int max_bytes; 713 int i; 714 715 if (addr & 0x7) { 716 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); 717 } 718 719 prepare_stfl(); 720 max_bytes = ROUND_UP(used_stfl_bytes, 8); 721 722 /* 723 * The PoP says that doublewords beyond the highest-numbered facility 724 * bit may or may not be stored. However, existing hardware appears to 725 * not store the words, and existing software depend on that. 726 */ 727 for (i = 0; i < MIN(count_bytes, max_bytes); ++i) { 728 cpu_stb_data_ra(env, addr + i, stfl_bytes[i], ra); 729 } 730 731 env->regs[0] = deposit64(env->regs[0], 0, 8, (max_bytes / 8) - 1); 732 return count_bytes >= max_bytes ? 0 : 3; 733 } 734 735 #ifndef CONFIG_USER_ONLY 736 /* 737 * Note: we ignore any return code of the functions called for the pci 738 * instructions, as the only time they return !0 is when the stub is 739 * called, and in that case we didn't even offer the zpci facility. 740 * The only exception is SIC, where program checks need to be handled 741 * by the caller. 742 */ 743 void HELPER(clp)(CPUS390XState *env, uint32_t r2) 744 { 745 S390CPU *cpu = env_archcpu(env); 746 747 bql_lock(); 748 clp_service_call(cpu, r2, GETPC()); 749 bql_unlock(); 750 } 751 752 void HELPER(pcilg)(CPUS390XState *env, uint32_t r1, uint32_t r2) 753 { 754 S390CPU *cpu = env_archcpu(env); 755 756 bql_lock(); 757 pcilg_service_call(cpu, r1, r2, GETPC()); 758 bql_unlock(); 759 } 760 761 void HELPER(pcistg)(CPUS390XState *env, uint32_t r1, uint32_t r2) 762 { 763 S390CPU *cpu = env_archcpu(env); 764 765 bql_lock(); 766 pcistg_service_call(cpu, r1, r2, GETPC()); 767 bql_unlock(); 768 } 769 770 void HELPER(stpcifc)(CPUS390XState *env, uint32_t r1, uint64_t fiba, 771 uint32_t ar) 772 { 773 S390CPU *cpu = env_archcpu(env); 774 775 bql_lock(); 776 stpcifc_service_call(cpu, r1, fiba, ar, GETPC()); 777 bql_unlock(); 778 } 779 780 void HELPER(sic)(CPUS390XState *env, uint64_t r1, uint64_t r3) 781 { 782 S390CPU *cpu = env_archcpu(env); 783 int r; 784 785 bql_lock(); 786 r = css_do_sic(cpu, (r3 >> 27) & 0x7, r1 & 0xffff); 787 bql_unlock(); 788 /* css_do_sic() may actually return a PGM_xxx value to inject */ 789 if (r) { 790 tcg_s390_program_interrupt(env, -r, GETPC()); 791 } 792 } 793 794 void HELPER(rpcit)(CPUS390XState *env, uint32_t r1, uint32_t r2) 795 { 796 S390CPU *cpu = env_archcpu(env); 797 798 bql_lock(); 799 rpcit_service_call(cpu, r1, r2, GETPC()); 800 bql_unlock(); 801 } 802 803 void HELPER(pcistb)(CPUS390XState *env, uint32_t r1, uint32_t r3, 804 uint64_t gaddr, uint32_t ar) 805 { 806 S390CPU *cpu = env_archcpu(env); 807 808 bql_lock(); 809 pcistb_service_call(cpu, r1, r3, gaddr, ar, GETPC()); 810 bql_unlock(); 811 } 812 813 void HELPER(mpcifc)(CPUS390XState *env, uint32_t r1, uint64_t fiba, 814 uint32_t ar) 815 { 816 S390CPU *cpu = env_archcpu(env); 817 818 bql_lock(); 819 mpcifc_service_call(cpu, r1, fiba, ar, GETPC()); 820 bql_unlock(); 821 } 822 #endif 823