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:
parent
4f2b55d184
commit
3f10341ffb
@ -352,7 +352,10 @@ int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
|
||||
|
||||
#include "ioinst.h"
|
||||
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
void do_restart_interrupt(CPUS390XState *env);
|
||||
|
||||
static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb)
|
||||
{
|
||||
hwaddr addr = 0;
|
||||
@ -671,7 +674,7 @@ typedef struct LowCore
|
||||
PSW mcck_old_psw; /* 0x160 */
|
||||
PSW io_old_psw; /* 0x170 */
|
||||
uint8_t pad7[0x1a0-0x180]; /* 0x180 */
|
||||
PSW restart_psw; /* 0x1a0 */
|
||||
PSW restart_new_psw; /* 0x1a0 */
|
||||
PSW external_new_psw; /* 0x1b0 */
|
||||
PSW svc_new_psw; /* 0x1c0 */
|
||||
PSW program_new_psw; /* 0x1d0 */
|
||||
|
@ -183,7 +183,9 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
|
||||
{
|
||||
env->psw.addr = addr;
|
||||
env->psw.mask = mask;
|
||||
env->cc_op = (mask >> 44) & 3;
|
||||
if (tcg_enabled()) {
|
||||
env->cc_op = (mask >> 44) & 3;
|
||||
}
|
||||
|
||||
if (mask & PSW_MASK_WAIT) {
|
||||
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)
|
||||
{
|
||||
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;
|
||||
assert(!(env->cc_op & ~3));
|
||||
r |= (uint64_t)env->cc_op << 44;
|
||||
r &= ~PSW_MASK_CC;
|
||||
assert(!(env->cc_op & ~3));
|
||||
r |= (uint64_t)env->cc_op << 44;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -229,6 +233,23 @@ static void cpu_unmap_lowcore(LowCore *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)
|
||||
{
|
||||
uint64_t mask, addr;
|
||||
|
Loading…
Reference in New Issue
Block a user