diff options
author | David Hildenbrand <david@redhat.com> | 2017-09-28 22:36:41 +0200 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2017-10-20 13:32:10 +0200 |
commit | 14ca122e753c7bc925e6cedc4f16588bc154090d (patch) | |
tree | 289c4be39f20c20f69cd02d51f51199e6347b97e /target/s390x/excp_helper.c | |
parent | d516f74c99b1a2c289cfba0bacf125cbc9b681e3 (diff) | |
download | qemu-14ca122e753c7bc925e6cedc4f16588bc154090d.zip qemu-14ca122e753c7bc925e6cedc4f16588bc154090d.tar.gz qemu-14ca122e753c7bc925e6cedc4f16588bc154090d.tar.bz2 |
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.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c index f585106..44e9b2c 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; |