#include "system/reset.h"
#endif
#include "hw/s390x/cpu-topology.h"
+#include "tcg/tcg_s390x.h"
#define CR0_RESET 0xE0UL
#define CR14_RESET 0xC2000000UL;
env->psw.mask = mask;
/* KVM will handle all WAITs and trigger a WAIT exit on disabled_wait */
- if (!tcg_enabled()) {
- return;
- }
- env->cc_op = (mask >> 44) & 3;
+ if (tcg_enabled()) {
+ env->cc_op = (mask >> 44) & 3;
#ifndef CONFIG_USER_ONLY
- if (is_early_exception_psw(mask, addr)) {
- env->int_pgm_ilen = 0;
- trigger_pgm_exception(env, PGM_SPECIFICATION);
- return;
- }
+ if (is_early_exception_psw(mask, addr)) {
+ env->int_pgm_ilen = 0;
+ trigger_pgm_exception(env, PGM_SPECIFICATION);
+ return;
+ }
- if ((old_mask ^ mask) & PSW_MASK_PER) {
- s390_cpu_recompute_watchpoints(env_cpu(env));
- }
+ if ((old_mask ^ mask) & PSW_MASK_PER) {
+ s390_cpu_recompute_watchpoints(env_cpu(env));
+ }
- if (mask & PSW_MASK_WAIT) {
- s390_handle_wait(env_archcpu(env));
- }
+ if (mask & PSW_MASK_WAIT) {
+ s390_handle_wait(env_archcpu(env));
+ }
#endif
+ }
}
uint64_t s390_cpu_get_psw_mask(CPUS390XState *env)
s390_cpu_set_psw(env, mask, addr);
}
-
-void s390_cpu_recompute_watchpoints(CPUState *cs)
-{
- const int wp_flags = BP_CPU | BP_MEM_WRITE | BP_STOP_BEFORE_ACCESS;
- CPUS390XState *env = cpu_env(cs);
-
- /* We are called when the watchpoints have changed. First
- remove them all. */
- cpu_watchpoint_remove_all(cs, BP_CPU);
-
- /* Return if PER is not enabled */
- if (!(env->psw.mask & PSW_MASK_PER)) {
- return;
- }
-
- /* Return if storage-alteration event is not enabled. */
- if (!(env->cregs[9] & PER_CR9_EVENT_STORE)) {
- return;
- }
-
- if (env->cregs[10] == 0 && env->cregs[11] == -1LL) {
- /* We can't create a watchoint spanning the whole memory range, so
- split it in two parts. */
- cpu_watchpoint_insert(cs, 0, 1ULL << 63, wp_flags, NULL);
- cpu_watchpoint_insert(cs, 1ULL << 63, 1ULL << 63, wp_flags, NULL);
- } else if (env->cregs[10] > env->cregs[11]) {
- /* The address range loops, create two watchpoints. */
- cpu_watchpoint_insert(cs, env->cregs[10], -env->cregs[10],
- wp_flags, NULL);
- cpu_watchpoint_insert(cs, 0, env->cregs[11] + 1, wp_flags, NULL);
-
- } else {
- /* Default case, create a single watchpoint. */
- cpu_watchpoint_insert(cs, env->cregs[10],
- env->cregs[11] - env->cregs[10] + 1,
- wp_flags, NULL);
- }
-}
/* excp_helper.c */
-void s390x_cpu_debug_excp_handler(CPUState *cs);
void s390_cpu_do_interrupt(CPUState *cpu);
bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
void s390_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
void do_restart_interrupt(CPUS390XState *env);
#ifndef CONFIG_USER_ONLY
-void s390_cpu_recompute_watchpoints(CPUState *cs);
void s390x_tod_timer(void *opaque);
void s390x_cpu_timer(void *opaque);
void s390_handle_wait(S390CPU *cpu);
--- /dev/null
+/*
+ * QEMU S/390 debug routines
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "exec/breakpoint.h"
+#include "exec/watchpoint.h"
+#include "target/s390x/cpu.h"
+#include "target/s390x/s390x-internal.h"
+#include "tcg_s390x.h"
+
+void s390_cpu_recompute_watchpoints(CPUState *cs)
+{
+ const int wp_flags = BP_CPU | BP_MEM_WRITE | BP_STOP_BEFORE_ACCESS;
+ CPUS390XState *env = cpu_env(cs);
+
+ /* We are called when the watchpoints have changed. First
+ remove them all. */
+ cpu_watchpoint_remove_all(cs, BP_CPU);
+
+ /* Return if PER is not enabled */
+ if (!(env->psw.mask & PSW_MASK_PER)) {
+ return;
+ }
+
+ /* Return if storage-alteration event is not enabled. */
+ if (!(env->cregs[9] & PER_CR9_EVENT_STORE)) {
+ return;
+ }
+
+ if (env->cregs[10] == 0 && env->cregs[11] == -1LL) {
+ /* We can't create a watchoint spanning the whole memory range, so
+ split it in two parts. */
+ cpu_watchpoint_insert(cs, 0, 1ULL << 63, wp_flags, NULL);
+ cpu_watchpoint_insert(cs, 1ULL << 63, 1ULL << 63, wp_flags, NULL);
+ } else if (env->cregs[10] > env->cregs[11]) {
+ /* The address range loops, create two watchpoints. */
+ cpu_watchpoint_insert(cs, env->cregs[10], -env->cregs[10],
+ wp_flags, NULL);
+ cpu_watchpoint_insert(cs, 0, env->cregs[11] + 1, wp_flags, NULL);
+
+ } else {
+ /* Default case, create a single watchpoint. */
+ cpu_watchpoint_insert(cs, env->cregs[10],
+ env->cregs[11] - env->cregs[10] + 1,
+ wp_flags, NULL);
+ }
+}
+
+void s390x_cpu_debug_excp_handler(CPUState *cs)
+{
+ CPUS390XState *env = cpu_env(cs);
+ CPUWatchpoint *wp_hit = cs->watchpoint_hit;
+
+ if (wp_hit && wp_hit->flags & BP_CPU) {
+ /*
+ * FIXME: When the storage-alteration-space control bit is set,
+ * the exception should only be triggered if the memory access
+ * is done using an address space with the storage-alteration-event
+ * bit set. We have no way to detect that with the current
+ * watchpoint code.
+ */
+ cs->watchpoint_hit = NULL;
+
+ env->per_address = env->psw.addr;
+ env->per_perc_atmid |= PER_CODE_EVENT_STORE | get_per_atmid(env);
+ /*
+ * FIXME: We currently no way to detect the address space used
+ * to trigger the watchpoint. For now just consider it is the
+ * current default ASC. This turn to be true except when MVCP
+ * and MVCS instructions are not used.
+ */
+ env->per_perc_atmid |= env->psw.mask & (PSW_MASK_ASC) >> 46;
+
+ /*
+ * Remove all watchpoints to re-execute the code. A PER exception
+ * will be triggered, it will call s390_cpu_set_psw which will
+ * recompute the watchpoints.
+ */
+ cpu_watchpoint_remove_all(cs, BP_CPU);
+ cpu_loop_exit_noexc(cs);
+ }
+}
#include "exec/helper-proto.h"
#include "exec/cputlb.h"
#include "exec/target_page.h"
-#include "exec/watchpoint.h"
#include "s390x-internal.h"
#include "tcg_s390x.h"
#ifndef CONFIG_USER_ONLY
return false;
}
-void s390x_cpu_debug_excp_handler(CPUState *cs)
-{
- CPUS390XState *env = cpu_env(cs);
- CPUWatchpoint *wp_hit = cs->watchpoint_hit;
-
- if (wp_hit && wp_hit->flags & BP_CPU) {
- /* FIXME: When the storage-alteration-space control bit is set,
- the exception should only be triggered if the memory access
- is done using an address space with the storage-alteration-event
- bit set. We have no way to detect that with the current
- watchpoint code. */
- cs->watchpoint_hit = NULL;
-
- env->per_address = env->psw.addr;
- env->per_perc_atmid |= PER_CODE_EVENT_STORE | get_per_atmid(env);
- /* FIXME: We currently no way to detect the address space used
- to trigger the watchpoint. For now just consider it is the
- current default ASC. This turn to be true except when MVCP
- and MVCS instrutions are not used. */
- env->per_perc_atmid |= env->psw.mask & (PSW_MASK_ASC) >> 46;
-
- /*
- * Remove all watchpoints to re-execute the code. A PER exception
- * will be triggered, it will call s390_cpu_set_psw which will
- * recompute the watchpoints.
- */
- cpu_watchpoint_remove_all(cs, BP_CPU);
- cpu_loop_exit_noexc(cs);
- }
-}
-
void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr)
'vec_int_helper.c',
'vec_string_helper.c',
))
+s390x_system_ss.add(when: 'CONFIG_TCG', if_true: files(
+ 'debug.c',
+))
G_NORETURN void tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
uintptr_t ra);
+#ifndef CONFIG_USER_ONLY
+void s390_cpu_recompute_watchpoints(CPUState *cs);
+void s390x_cpu_debug_excp_handler(CPUState *cs);
+#endif
+
#endif /* TCG_S390X_H */