1 /* 2 * s390x exception / interrupt helpers 3 * 4 * Copyright (c) 2009 Ulrich Hecht 5 * Copyright (c) 2011 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/log.h" 23 #include "cpu.h" 24 #include "exec/helper-proto.h" 25 #include "exec/exec-all.h" 26 #include "exec/cpu_ldst.h" 27 #include "s390x-internal.h" 28 #include "tcg_s390x.h" 29 #ifndef CONFIG_USER_ONLY 30 #include "qemu/timer.h" 31 #include "exec/address-spaces.h" 32 #include "hw/s390x/ioinst.h" 33 #include "hw/s390x/s390_flic.h" 34 #include "hw/boards.h" 35 #endif 36 37 G_NORETURN void tcg_s390_program_interrupt(CPUS390XState *env, 38 uint32_t code, uintptr_t ra) 39 { 40 CPUState *cs = env_cpu(env); 41 42 cpu_restore_state(cs, ra); 43 qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n", 44 env->psw.addr); 45 trigger_pgm_exception(env, code); 46 cpu_loop_exit(cs); 47 } 48 49 G_NORETURN void tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc, 50 uintptr_t ra) 51 { 52 g_assert(dxc <= 0xff); 53 #if !defined(CONFIG_USER_ONLY) 54 /* Store the DXC into the lowcore */ 55 stl_phys(env_cpu(env)->as, 56 env->psa + offsetof(LowCore, data_exc_code), dxc); 57 #endif 58 59 /* Store the DXC into the FPC if AFP is enabled */ 60 if (env->cregs[0] & CR0_AFP) { 61 env->fpc = deposit32(env->fpc, 8, 8, dxc); 62 } 63 tcg_s390_program_interrupt(env, PGM_DATA, ra); 64 } 65 66 G_NORETURN void tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc, 67 uintptr_t ra) 68 { 69 g_assert(vxc <= 0xff); 70 #if !defined(CONFIG_USER_ONLY) 71 /* Always store the VXC into the lowcore, without AFP it is undefined */ 72 stl_phys(env_cpu(env)->as, 73 env->psa + offsetof(LowCore, data_exc_code), vxc); 74 #endif 75 76 /* Always store the VXC into the FPC, without AFP it is undefined */ 77 env->fpc = deposit32(env->fpc, 8, 8, vxc); 78 tcg_s390_program_interrupt(env, PGM_VECTOR_PROCESSING, ra); 79 } 80 81 void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc) 82 { 83 tcg_s390_data_exception(env, dxc, GETPC()); 84 } 85 86 /* 87 * Unaligned accesses are only diagnosed with MO_ALIGN. At the moment, 88 * this is only for the atomic and relative long operations, for which we want 89 * to raise a specification exception. 90 */ 91 static G_NORETURN 92 void do_unaligned_access(CPUState *cs, uintptr_t retaddr) 93 { 94 S390CPU *cpu = S390_CPU(cs); 95 CPUS390XState *env = &cpu->env; 96 97 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, retaddr); 98 } 99 100 #if defined(CONFIG_USER_ONLY) 101 102 void s390_cpu_do_interrupt(CPUState *cs) 103 { 104 cs->exception_index = -1; 105 } 106 107 void s390_cpu_record_sigsegv(CPUState *cs, vaddr address, 108 MMUAccessType access_type, 109 bool maperr, uintptr_t retaddr) 110 { 111 S390CPU *cpu = S390_CPU(cs); 112 113 trigger_pgm_exception(&cpu->env, maperr ? PGM_ADDRESSING : PGM_PROTECTION); 114 /* 115 * On real machines this value is dropped into LowMem. Since this 116 * is userland, simply put this someplace that cpu_loop can find it. 117 * S390 only gives the page of the fault, not the exact address. 118 * C.f. the construction of TEC in mmu_translate(). 119 */ 120 cpu->env.__excp_addr = address & TARGET_PAGE_MASK; 121 cpu_loop_exit_restore(cs, retaddr); 122 } 123 124 void s390_cpu_record_sigbus(CPUState *cs, vaddr address, 125 MMUAccessType access_type, uintptr_t retaddr) 126 { 127 do_unaligned_access(cs, retaddr); 128 } 129 130 #else /* !CONFIG_USER_ONLY */ 131 132 static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx) 133 { 134 switch (mmu_idx) { 135 case MMU_PRIMARY_IDX: 136 return PSW_ASC_PRIMARY; 137 case MMU_SECONDARY_IDX: 138 return PSW_ASC_SECONDARY; 139 case MMU_HOME_IDX: 140 return PSW_ASC_HOME; 141 default: 142 abort(); 143 } 144 } 145 146 bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size, 147 MMUAccessType access_type, int mmu_idx, 148 bool probe, uintptr_t retaddr) 149 { 150 S390CPU *cpu = S390_CPU(cs); 151 CPUS390XState *env = &cpu->env; 152 target_ulong vaddr, raddr; 153 uint64_t asc, tec; 154 int prot, excp; 155 156 qemu_log_mask(CPU_LOG_MMU, "%s: addr 0x%" VADDR_PRIx " rw %d mmu_idx %d\n", 157 __func__, address, access_type, mmu_idx); 158 159 vaddr = address; 160 161 if (mmu_idx < MMU_REAL_IDX) { 162 asc = cpu_mmu_idx_to_asc(mmu_idx); 163 /* 31-Bit mode */ 164 if (!(env->psw.mask & PSW_MASK_64)) { 165 vaddr &= 0x7fffffff; 166 } 167 excp = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, &tec); 168 } else if (mmu_idx == MMU_REAL_IDX) { 169 /* 31-Bit mode */ 170 if (!(env->psw.mask & PSW_MASK_64)) { 171 vaddr &= 0x7fffffff; 172 } 173 excp = mmu_translate_real(env, vaddr, access_type, &raddr, &prot, &tec); 174 } else { 175 g_assert_not_reached(); 176 } 177 178 env->tlb_fill_exc = excp; 179 env->tlb_fill_tec = tec; 180 181 if (!excp) { 182 qemu_log_mask(CPU_LOG_MMU, 183 "%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n", 184 __func__, (uint64_t)vaddr, (uint64_t)raddr, prot); 185 tlb_set_page(cs, address & TARGET_PAGE_MASK, raddr, prot, 186 mmu_idx, TARGET_PAGE_SIZE); 187 return true; 188 } 189 if (probe) { 190 return false; 191 } 192 193 if (excp != PGM_ADDRESSING) { 194 stq_phys(env_cpu(env)->as, 195 env->psa + offsetof(LowCore, trans_exc_code), tec); 196 } 197 198 /* 199 * For data accesses, ILEN will be filled in from the unwind info, 200 * within cpu_loop_exit_restore. For code accesses, retaddr == 0, 201 * and so unwinding will not occur. However, ILEN is also undefined 202 * for that case -- we choose to set ILEN = 2. 203 */ 204 env->int_pgm_ilen = 2; 205 trigger_pgm_exception(env, excp); 206 cpu_loop_exit_restore(cs, retaddr); 207 } 208 209 static void do_program_interrupt(CPUS390XState *env) 210 { 211 uint64_t mask, addr; 212 LowCore *lowcore; 213 int ilen = env->int_pgm_ilen; 214 215 assert((env->int_pgm_code == PGM_SPECIFICATION && ilen == 0) || 216 ilen == 2 || ilen == 4 || ilen == 6); 217 218 switch (env->int_pgm_code) { 219 case PGM_PER: 220 if (env->per_perc_atmid & PER_CODE_EVENT_NULLIFICATION) { 221 break; 222 } 223 /* FALL THROUGH */ 224 case PGM_OPERATION: 225 case PGM_PRIVILEGED: 226 case PGM_EXECUTE: 227 case PGM_PROTECTION: 228 case PGM_ADDRESSING: 229 case PGM_SPECIFICATION: 230 case PGM_DATA: 231 case PGM_FIXPT_OVERFLOW: 232 case PGM_FIXPT_DIVIDE: 233 case PGM_DEC_OVERFLOW: 234 case PGM_DEC_DIVIDE: 235 case PGM_HFP_EXP_OVERFLOW: 236 case PGM_HFP_EXP_UNDERFLOW: 237 case PGM_HFP_SIGNIFICANCE: 238 case PGM_HFP_DIVIDE: 239 case PGM_TRANS_SPEC: 240 case PGM_SPECIAL_OP: 241 case PGM_OPERAND: 242 case PGM_HFP_SQRT: 243 case PGM_PC_TRANS_SPEC: 244 case PGM_ALET_SPEC: 245 case PGM_MONITOR: 246 /* advance the PSW if our exception is not nullifying */ 247 env->psw.addr += ilen; 248 break; 249 } 250 251 qemu_log_mask(CPU_LOG_INT, 252 "%s: code=0x%x ilen=%d psw: %" PRIx64 " %" PRIx64 "\n", 253 __func__, env->int_pgm_code, ilen, env->psw.mask, 254 env->psw.addr); 255 256 lowcore = cpu_map_lowcore(env); 257 258 /* Signal PER events with the exception. */ 259 if (env->per_perc_atmid) { 260 env->int_pgm_code |= PGM_PER; 261 lowcore->per_address = cpu_to_be64(env->per_address); 262 lowcore->per_perc_atmid = cpu_to_be16(env->per_perc_atmid); 263 env->per_perc_atmid = 0; 264 } 265 266 lowcore->pgm_ilen = cpu_to_be16(ilen); 267 lowcore->pgm_code = cpu_to_be16(env->int_pgm_code); 268 lowcore->program_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env)); 269 lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr); 270 mask = be64_to_cpu(lowcore->program_new_psw.mask); 271 addr = be64_to_cpu(lowcore->program_new_psw.addr); 272 lowcore->per_breaking_event_addr = cpu_to_be64(env->gbea); 273 274 cpu_unmap_lowcore(lowcore); 275 276 s390_cpu_set_psw(env, mask, addr); 277 } 278 279 static void do_svc_interrupt(CPUS390XState *env) 280 { 281 uint64_t mask, addr; 282 LowCore *lowcore; 283 284 lowcore = cpu_map_lowcore(env); 285 286 lowcore->svc_code = cpu_to_be16(env->int_svc_code); 287 lowcore->svc_ilen = cpu_to_be16(env->int_svc_ilen); 288 lowcore->svc_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env)); 289 lowcore->svc_old_psw.addr = cpu_to_be64(env->psw.addr + env->int_svc_ilen); 290 mask = be64_to_cpu(lowcore->svc_new_psw.mask); 291 addr = be64_to_cpu(lowcore->svc_new_psw.addr); 292 293 cpu_unmap_lowcore(lowcore); 294 295 s390_cpu_set_psw(env, mask, addr); 296 297 /* When a PER event is pending, the PER exception has to happen 298 immediately after the SERVICE CALL one. */ 299 if (env->per_perc_atmid) { 300 env->int_pgm_code = PGM_PER; 301 env->int_pgm_ilen = env->int_svc_ilen; 302 do_program_interrupt(env); 303 } 304 } 305 306 #define VIRTIO_SUBCODE_64 0x0D00 307 308 static void do_ext_interrupt(CPUS390XState *env) 309 { 310 QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic()); 311 S390CPU *cpu = env_archcpu(env); 312 uint64_t mask, addr; 313 uint16_t cpu_addr; 314 LowCore *lowcore; 315 316 if (!(env->psw.mask & PSW_MASK_EXT)) { 317 cpu_abort(CPU(cpu), "Ext int w/o ext mask\n"); 318 } 319 320 lowcore = cpu_map_lowcore(env); 321 322 if ((env->pending_int & INTERRUPT_EMERGENCY_SIGNAL) && 323 (env->cregs[0] & CR0_EMERGENCY_SIGNAL_SC)) { 324 MachineState *ms = MACHINE(qdev_get_machine()); 325 unsigned int max_cpus = ms->smp.max_cpus; 326 327 lowcore->ext_int_code = cpu_to_be16(EXT_EMERGENCY); 328 cpu_addr = find_first_bit(env->emergency_signals, S390_MAX_CPUS); 329 g_assert(cpu_addr < S390_MAX_CPUS); 330 lowcore->cpu_addr = cpu_to_be16(cpu_addr); 331 clear_bit(cpu_addr, env->emergency_signals); 332 if (bitmap_empty(env->emergency_signals, max_cpus)) { 333 env->pending_int &= ~INTERRUPT_EMERGENCY_SIGNAL; 334 } 335 } else if ((env->pending_int & INTERRUPT_EXTERNAL_CALL) && 336 (env->cregs[0] & CR0_EXTERNAL_CALL_SC)) { 337 lowcore->ext_int_code = cpu_to_be16(EXT_EXTERNAL_CALL); 338 lowcore->cpu_addr = cpu_to_be16(env->external_call_addr); 339 env->pending_int &= ~INTERRUPT_EXTERNAL_CALL; 340 } else if ((env->pending_int & INTERRUPT_EXT_CLOCK_COMPARATOR) && 341 (env->cregs[0] & CR0_CKC_SC)) { 342 lowcore->ext_int_code = cpu_to_be16(EXT_CLOCK_COMP); 343 lowcore->cpu_addr = 0; 344 env->pending_int &= ~INTERRUPT_EXT_CLOCK_COMPARATOR; 345 } else if ((env->pending_int & INTERRUPT_EXT_CPU_TIMER) && 346 (env->cregs[0] & CR0_CPU_TIMER_SC)) { 347 lowcore->ext_int_code = cpu_to_be16(EXT_CPU_TIMER); 348 lowcore->cpu_addr = 0; 349 env->pending_int &= ~INTERRUPT_EXT_CPU_TIMER; 350 } else if (qemu_s390_flic_has_service(flic) && 351 (env->cregs[0] & CR0_SERVICE_SC)) { 352 uint32_t param; 353 354 param = qemu_s390_flic_dequeue_service(flic); 355 lowcore->ext_int_code = cpu_to_be16(EXT_SERVICE); 356 lowcore->ext_params = cpu_to_be32(param); 357 lowcore->cpu_addr = 0; 358 } else { 359 g_assert_not_reached(); 360 } 361 362 mask = be64_to_cpu(lowcore->external_new_psw.mask); 363 addr = be64_to_cpu(lowcore->external_new_psw.addr); 364 lowcore->external_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env)); 365 lowcore->external_old_psw.addr = cpu_to_be64(env->psw.addr); 366 367 cpu_unmap_lowcore(lowcore); 368 369 s390_cpu_set_psw(env, mask, addr); 370 } 371 372 static void do_io_interrupt(CPUS390XState *env) 373 { 374 QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic()); 375 uint64_t mask, addr; 376 QEMUS390FlicIO *io; 377 LowCore *lowcore; 378 379 g_assert(env->psw.mask & PSW_MASK_IO); 380 io = qemu_s390_flic_dequeue_io(flic, env->cregs[6]); 381 g_assert(io); 382 383 lowcore = cpu_map_lowcore(env); 384 385 lowcore->subchannel_id = cpu_to_be16(io->id); 386 lowcore->subchannel_nr = cpu_to_be16(io->nr); 387 lowcore->io_int_parm = cpu_to_be32(io->parm); 388 lowcore->io_int_word = cpu_to_be32(io->word); 389 lowcore->io_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env)); 390 lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr); 391 mask = be64_to_cpu(lowcore->io_new_psw.mask); 392 addr = be64_to_cpu(lowcore->io_new_psw.addr); 393 394 cpu_unmap_lowcore(lowcore); 395 g_free(io); 396 397 s390_cpu_set_psw(env, mask, addr); 398 } 399 400 typedef struct MchkExtSaveArea { 401 uint64_t vregs[32][2]; /* 0x0000 */ 402 uint8_t pad_0x0200[0x0400 - 0x0200]; /* 0x0200 */ 403 } MchkExtSaveArea; 404 QEMU_BUILD_BUG_ON(sizeof(MchkExtSaveArea) != 1024); 405 406 static int mchk_store_vregs(CPUS390XState *env, uint64_t mcesao) 407 { 408 hwaddr len = sizeof(MchkExtSaveArea); 409 MchkExtSaveArea *sa; 410 int i; 411 412 sa = cpu_physical_memory_map(mcesao, &len, true); 413 if (!sa) { 414 return -EFAULT; 415 } 416 if (len != sizeof(MchkExtSaveArea)) { 417 cpu_physical_memory_unmap(sa, len, 1, 0); 418 return -EFAULT; 419 } 420 421 for (i = 0; i < 32; i++) { 422 sa->vregs[i][0] = cpu_to_be64(env->vregs[i][0]); 423 sa->vregs[i][1] = cpu_to_be64(env->vregs[i][1]); 424 } 425 426 cpu_physical_memory_unmap(sa, len, 1, len); 427 return 0; 428 } 429 430 static void do_mchk_interrupt(CPUS390XState *env) 431 { 432 QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic()); 433 uint64_t mcic = s390_build_validity_mcic() | MCIC_SC_CP; 434 uint64_t mask, addr, mcesao = 0; 435 LowCore *lowcore; 436 int i; 437 438 /* for now we only support channel report machine checks (floating) */ 439 g_assert(env->psw.mask & PSW_MASK_MCHECK); 440 g_assert(env->cregs[14] & CR14_CHANNEL_REPORT_SC); 441 442 qemu_s390_flic_dequeue_crw_mchk(flic); 443 444 lowcore = cpu_map_lowcore(env); 445 446 /* extended save area */ 447 if (mcic & MCIC_VB_VR) { 448 /* length and alignment is 1024 bytes */ 449 mcesao = be64_to_cpu(lowcore->mcesad) & ~0x3ffull; 450 } 451 452 /* try to store vector registers */ 453 if (!mcesao || mchk_store_vregs(env, mcesao)) { 454 mcic &= ~MCIC_VB_VR; 455 } 456 457 /* we are always in z/Architecture mode */ 458 lowcore->ar_access_id = 1; 459 460 for (i = 0; i < 16; i++) { 461 lowcore->floating_pt_save_area[i] = cpu_to_be64(*get_freg(env, i)); 462 lowcore->gpregs_save_area[i] = cpu_to_be64(env->regs[i]); 463 lowcore->access_regs_save_area[i] = cpu_to_be32(env->aregs[i]); 464 lowcore->cregs_save_area[i] = cpu_to_be64(env->cregs[i]); 465 } 466 lowcore->prefixreg_save_area = cpu_to_be32(env->psa); 467 lowcore->fpt_creg_save_area = cpu_to_be32(env->fpc); 468 lowcore->tod_progreg_save_area = cpu_to_be32(env->todpr); 469 lowcore->cpu_timer_save_area = cpu_to_be64(env->cputm); 470 lowcore->clock_comp_save_area = cpu_to_be64(env->ckc >> 8); 471 472 lowcore->mcic = cpu_to_be64(mcic); 473 lowcore->mcck_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env)); 474 lowcore->mcck_old_psw.addr = cpu_to_be64(env->psw.addr); 475 mask = be64_to_cpu(lowcore->mcck_new_psw.mask); 476 addr = be64_to_cpu(lowcore->mcck_new_psw.addr); 477 478 cpu_unmap_lowcore(lowcore); 479 480 s390_cpu_set_psw(env, mask, addr); 481 } 482 483 void s390_cpu_do_interrupt(CPUState *cs) 484 { 485 QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic()); 486 S390CPU *cpu = S390_CPU(cs); 487 CPUS390XState *env = &cpu->env; 488 bool stopped = false; 489 490 qemu_log_mask(CPU_LOG_INT, "%s: %d at psw=%" PRIx64 ":%" PRIx64 "\n", 491 __func__, cs->exception_index, env->psw.mask, env->psw.addr); 492 493 try_deliver: 494 /* handle machine checks */ 495 if (cs->exception_index == -1 && s390_cpu_has_mcck_int(cpu)) { 496 cs->exception_index = EXCP_MCHK; 497 } 498 /* handle external interrupts */ 499 if (cs->exception_index == -1 && s390_cpu_has_ext_int(cpu)) { 500 cs->exception_index = EXCP_EXT; 501 } 502 /* handle I/O interrupts */ 503 if (cs->exception_index == -1 && s390_cpu_has_io_int(cpu)) { 504 cs->exception_index = EXCP_IO; 505 } 506 /* RESTART interrupt */ 507 if (cs->exception_index == -1 && s390_cpu_has_restart_int(cpu)) { 508 cs->exception_index = EXCP_RESTART; 509 } 510 /* STOP interrupt has least priority */ 511 if (cs->exception_index == -1 && s390_cpu_has_stop_int(cpu)) { 512 cs->exception_index = EXCP_STOP; 513 } 514 515 switch (cs->exception_index) { 516 case EXCP_PGM: 517 do_program_interrupt(env); 518 break; 519 case EXCP_SVC: 520 do_svc_interrupt(env); 521 break; 522 case EXCP_EXT: 523 do_ext_interrupt(env); 524 break; 525 case EXCP_IO: 526 do_io_interrupt(env); 527 break; 528 case EXCP_MCHK: 529 do_mchk_interrupt(env); 530 break; 531 case EXCP_RESTART: 532 do_restart_interrupt(env); 533 break; 534 case EXCP_STOP: 535 do_stop_interrupt(env); 536 stopped = true; 537 break; 538 } 539 540 if (cs->exception_index != -1 && !stopped) { 541 /* check if there are more pending interrupts to deliver */ 542 cs->exception_index = -1; 543 goto try_deliver; 544 } 545 cs->exception_index = -1; 546 547 /* we might still have pending interrupts, but not deliverable */ 548 if (!env->pending_int && !qemu_s390_flic_has_any(flic)) { 549 cs->interrupt_request &= ~CPU_INTERRUPT_HARD; 550 } 551 552 /* WAIT PSW during interrupt injection or STOP interrupt */ 553 if ((env->psw.mask & PSW_MASK_WAIT) || stopped) { 554 /* don't trigger a cpu_loop_exit(), use an interrupt instead */ 555 cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT); 556 } else if (cs->halted) { 557 /* unhalt if we had a WAIT PSW somewhere in our injection chain */ 558 s390_cpu_unhalt(cpu); 559 } 560 } 561 562 bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request) 563 { 564 if (interrupt_request & CPU_INTERRUPT_HARD) { 565 S390CPU *cpu = S390_CPU(cs); 566 CPUS390XState *env = &cpu->env; 567 568 if (env->ex_value) { 569 /* Execution of the target insn is indivisible from 570 the parent EXECUTE insn. */ 571 return false; 572 } 573 if (s390_cpu_has_int(cpu)) { 574 s390_cpu_do_interrupt(cs); 575 return true; 576 } 577 if (env->psw.mask & PSW_MASK_WAIT) { 578 /* Woken up because of a floating interrupt but it has already 579 * been delivered. Go back to sleep. */ 580 cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT); 581 } 582 } 583 return false; 584 } 585 586 void s390x_cpu_debug_excp_handler(CPUState *cs) 587 { 588 S390CPU *cpu = S390_CPU(cs); 589 CPUS390XState *env = &cpu->env; 590 CPUWatchpoint *wp_hit = cs->watchpoint_hit; 591 592 if (wp_hit && wp_hit->flags & BP_CPU) { 593 /* FIXME: When the storage-alteration-space control bit is set, 594 the exception should only be triggered if the memory access 595 is done using an address space with the storage-alteration-event 596 bit set. We have no way to detect that with the current 597 watchpoint code. */ 598 cs->watchpoint_hit = NULL; 599 600 env->per_address = env->psw.addr; 601 env->per_perc_atmid |= PER_CODE_EVENT_STORE | get_per_atmid(env); 602 /* FIXME: We currently no way to detect the address space used 603 to trigger the watchpoint. For now just consider it is the 604 current default ASC. This turn to be true except when MVCP 605 and MVCS instrutions are not used. */ 606 env->per_perc_atmid |= env->psw.mask & (PSW_MASK_ASC) >> 46; 607 608 /* 609 * Remove all watchpoints to re-execute the code. A PER exception 610 * will be triggered, it will call s390_cpu_set_psw which will 611 * recompute the watchpoints. 612 */ 613 cpu_watchpoint_remove_all(cs, BP_CPU); 614 cpu_loop_exit_noexc(cs); 615 } 616 } 617 618 void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr, 619 MMUAccessType access_type, 620 int mmu_idx, uintptr_t retaddr) 621 { 622 do_unaligned_access(cs, retaddr); 623 } 624 625 static G_NORETURN 626 void monitor_event(CPUS390XState *env, 627 uint64_t monitor_code, 628 uint8_t monitor_class, uintptr_t ra) 629 { 630 /* Store the Monitor Code and the Monitor Class Number into the lowcore */ 631 stq_phys(env_cpu(env)->as, 632 env->psa + offsetof(LowCore, monitor_code), monitor_code); 633 stw_phys(env_cpu(env)->as, 634 env->psa + offsetof(LowCore, mon_class_num), monitor_class); 635 636 tcg_s390_program_interrupt(env, PGM_MONITOR, ra); 637 } 638 639 void HELPER(monitor_call)(CPUS390XState *env, uint64_t monitor_code, 640 uint32_t monitor_class) 641 { 642 g_assert(monitor_class <= 0xff); 643 644 if (env->cregs[8] & (0x8000 >> monitor_class)) { 645 monitor_event(env, monitor_code, monitor_class, GETPC()); 646 } 647 } 648 649 #endif /* !CONFIG_USER_ONLY */ 650