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"
|
#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 */
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user