summaryrefslogtreecommitdiff
path: root/target/s390x/excp_helper.c
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2017-09-28 22:36:41 +0200
committerCornelia Huck <cohuck@redhat.com>2017-10-20 13:32:10 +0200
commit14ca122e753c7bc925e6cedc4f16588bc154090d (patch)
tree289c4be39f20c20f69cd02d51f51199e6347b97e /target/s390x/excp_helper.c
parentd516f74c99b1a2c289cfba0bacf125cbc9b681e3 (diff)
downloadqemu-14ca122e753c7bc925e6cedc4f16588bc154090d.zip
s390x/tcg: injection of emergency signals and external calls
Preparation for new TCG SIGP code. Especially also prepare for indicating that another external call is already pending. Take care of interrupt priority. Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20170928203708.9376-4-david@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/excp_helper.c')
-rw-r--r--target/s390x/excp_helper.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index f5851069b5..44e9b2c6a6 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -240,6 +240,7 @@ static void do_ext_interrupt(CPUS390XState *env)
{
S390CPU *cpu = s390_env_get_cpu(env);
uint64_t mask, addr;
+ uint16_t cpu_addr;
LowCore *lowcore;
if (!(env->psw.mask & PSW_MASK_EXT)) {
@@ -248,7 +249,20 @@ static void do_ext_interrupt(CPUS390XState *env)
lowcore = cpu_map_lowcore(env);
- if (env->pending_int & INTERRUPT_EXT_CLOCK_COMPARATOR) {
+ if (env->pending_int & INTERRUPT_EMERGENCY_SIGNAL) {
+ lowcore->ext_int_code = cpu_to_be16(EXT_EMERGENCY);
+ cpu_addr = find_first_bit(env->emergency_signals, S390_MAX_CPUS);
+ g_assert(cpu_addr < S390_MAX_CPUS);
+ lowcore->cpu_addr = cpu_to_be16(cpu_addr);
+ clear_bit(cpu_addr, env->emergency_signals);
+ if (bitmap_empty(env->emergency_signals, max_cpus)) {
+ env->pending_int &= ~INTERRUPT_EMERGENCY_SIGNAL;
+ }
+ } else if (env->pending_int & INTERRUPT_EXTERNAL_CALL) {
+ lowcore->ext_int_code = cpu_to_be16(EXT_EXTERNAL_CALL);
+ lowcore->cpu_addr = cpu_to_be16(env->external_call_addr);
+ env->pending_int &= ~INTERRUPT_EXTERNAL_CALL;
+ } else if (env->pending_int & INTERRUPT_EXT_CLOCK_COMPARATOR) {
lowcore->ext_int_code = cpu_to_be16(EXT_CLOCK_COMP);
lowcore->cpu_addr = 0;
env->pending_int &= ~INTERRUPT_EXT_CLOCK_COMPARATOR;