s390x: add function to deliver restart irqs

This patch adds a helper function to deliver restart irqs. To be able to be used
by kvm, the psw load/store methods have to perform special cc-code handling only
when running with tcg.

Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Message-Id: <1424783731-43426-9-git-send-email-jfrei@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
David Hildenbrand 2015-02-24 14:15:29 +01:00 committed by Christian Borntraeger
parent 4f2b55d184
commit 3f10341ffb
2 changed files with 32 additions and 8 deletions

View file

@ -352,7 +352,10 @@ int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
#include "ioinst.h" #include "ioinst.h"
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
void do_restart_interrupt(CPUS390XState *env);
static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb) static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb)
{ {
hwaddr addr = 0; hwaddr addr = 0;
@ -671,7 +674,7 @@ typedef struct LowCore
PSW mcck_old_psw; /* 0x160 */ PSW mcck_old_psw; /* 0x160 */
PSW io_old_psw; /* 0x170 */ PSW io_old_psw; /* 0x170 */
uint8_t pad7[0x1a0-0x180]; /* 0x180 */ uint8_t pad7[0x1a0-0x180]; /* 0x180 */
PSW restart_psw; /* 0x1a0 */ PSW restart_new_psw; /* 0x1a0 */
PSW external_new_psw; /* 0x1b0 */ PSW external_new_psw; /* 0x1b0 */
PSW svc_new_psw; /* 0x1c0 */ PSW svc_new_psw; /* 0x1c0 */
PSW program_new_psw; /* 0x1d0 */ PSW program_new_psw; /* 0x1d0 */

View file

@ -183,7 +183,9 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
{ {
env->psw.addr = addr; env->psw.addr = addr;
env->psw.mask = mask; env->psw.mask = mask;
env->cc_op = (mask >> 44) & 3; if (tcg_enabled()) {
env->cc_op = (mask >> 44) & 3;
}
if (mask & PSW_MASK_WAIT) { if (mask & PSW_MASK_WAIT) {
S390CPU *cpu = s390_env_get_cpu(env); S390CPU *cpu = s390_env_get_cpu(env);
@ -197,14 +199,16 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
static uint64_t get_psw_mask(CPUS390XState *env) static uint64_t get_psw_mask(CPUS390XState *env)
{ {
uint64_t r; uint64_t r = env->psw.mask;
env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr); if (tcg_enabled()) {
env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst,
env->cc_vr);
r = env->psw.mask; r &= ~PSW_MASK_CC;
r &= ~PSW_MASK_CC; assert(!(env->cc_op & ~3));
assert(!(env->cc_op & ~3)); r |= (uint64_t)env->cc_op << 44;
r |= (uint64_t)env->cc_op << 44; }
return r; return r;
} }
@ -229,6 +233,23 @@ static void cpu_unmap_lowcore(LowCore *lowcore)
cpu_physical_memory_unmap(lowcore, sizeof(LowCore), 1, sizeof(LowCore)); cpu_physical_memory_unmap(lowcore, sizeof(LowCore), 1, sizeof(LowCore));
} }
void do_restart_interrupt(CPUS390XState *env)
{
uint64_t mask, addr;
LowCore *lowcore;
lowcore = cpu_map_lowcore(env);
lowcore->restart_old_psw.mask = cpu_to_be64(get_psw_mask(env));
lowcore->restart_old_psw.addr = cpu_to_be64(env->psw.addr);
mask = be64_to_cpu(lowcore->restart_new_psw.mask);
addr = be64_to_cpu(lowcore->restart_new_psw.addr);
cpu_unmap_lowcore(lowcore);
load_psw(env, mask, addr);
}
static void do_svc_interrupt(CPUS390XState *env) static void do_svc_interrupt(CPUS390XState *env)
{ {
uint64_t mask, addr; uint64_t mask, addr;