mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
target/s390x: Expose load_psw and get_psw_mask to cpu.h
Rename to s390_cpu_set_psw and s390_cpu_get_psw_mask at the same time. Adjust so that they compile for user-only. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: David Hildenbrand <david@redhat.com> Tested-by: jonathan.albrecht <jonathan.albrecht@linux.vnet.ibm.com> Tested-by: <ruixin.bao@ibm.com> Message-Id: <20210615030744.1252385-2-richard.henderson@linaro.org> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
3af448b386
commit
e2b2a8649b
6 changed files with 69 additions and 61 deletions
|
@ -509,7 +509,7 @@ uint32_t HELPER(calc_cc)(CPUS390XState *env, uint32_t cc_op, uint64_t src,
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
void HELPER(load_psw)(CPUS390XState *env, uint64_t mask, uint64_t addr)
|
void HELPER(load_psw)(CPUS390XState *env, uint64_t mask, uint64_t addr)
|
||||||
{
|
{
|
||||||
load_psw(env, mask, addr);
|
s390_cpu_set_psw(env, mask, addr);
|
||||||
cpu_loop_exit(env_cpu(env));
|
cpu_loop_exit(env_cpu(env));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -845,6 +845,9 @@ int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
|
||||||
int s390_cpu_restart(S390CPU *cpu);
|
int s390_cpu_restart(S390CPU *cpu);
|
||||||
void s390_init_sigp(void);
|
void s390_init_sigp(void);
|
||||||
|
|
||||||
|
/* helper.c */
|
||||||
|
void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr);
|
||||||
|
uint64_t s390_cpu_get_psw_mask(CPUS390XState *env);
|
||||||
|
|
||||||
/* outside of target/s390x/ */
|
/* outside of target/s390x/ */
|
||||||
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
|
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
|
||||||
|
|
|
@ -252,7 +252,7 @@ static void do_program_interrupt(CPUS390XState *env)
|
||||||
|
|
||||||
lowcore->pgm_ilen = cpu_to_be16(ilen);
|
lowcore->pgm_ilen = cpu_to_be16(ilen);
|
||||||
lowcore->pgm_code = cpu_to_be16(env->int_pgm_code);
|
lowcore->pgm_code = cpu_to_be16(env->int_pgm_code);
|
||||||
lowcore->program_old_psw.mask = cpu_to_be64(get_psw_mask(env));
|
lowcore->program_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
|
||||||
lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr);
|
lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr);
|
||||||
mask = be64_to_cpu(lowcore->program_new_psw.mask);
|
mask = be64_to_cpu(lowcore->program_new_psw.mask);
|
||||||
addr = be64_to_cpu(lowcore->program_new_psw.addr);
|
addr = be64_to_cpu(lowcore->program_new_psw.addr);
|
||||||
|
@ -260,7 +260,7 @@ static void do_program_interrupt(CPUS390XState *env)
|
||||||
|
|
||||||
cpu_unmap_lowcore(lowcore);
|
cpu_unmap_lowcore(lowcore);
|
||||||
|
|
||||||
load_psw(env, mask, addr);
|
s390_cpu_set_psw(env, mask, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_svc_interrupt(CPUS390XState *env)
|
static void do_svc_interrupt(CPUS390XState *env)
|
||||||
|
@ -272,14 +272,14 @@ static void do_svc_interrupt(CPUS390XState *env)
|
||||||
|
|
||||||
lowcore->svc_code = cpu_to_be16(env->int_svc_code);
|
lowcore->svc_code = cpu_to_be16(env->int_svc_code);
|
||||||
lowcore->svc_ilen = cpu_to_be16(env->int_svc_ilen);
|
lowcore->svc_ilen = cpu_to_be16(env->int_svc_ilen);
|
||||||
lowcore->svc_old_psw.mask = cpu_to_be64(get_psw_mask(env));
|
lowcore->svc_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
|
||||||
lowcore->svc_old_psw.addr = cpu_to_be64(env->psw.addr + env->int_svc_ilen);
|
lowcore->svc_old_psw.addr = cpu_to_be64(env->psw.addr + env->int_svc_ilen);
|
||||||
mask = be64_to_cpu(lowcore->svc_new_psw.mask);
|
mask = be64_to_cpu(lowcore->svc_new_psw.mask);
|
||||||
addr = be64_to_cpu(lowcore->svc_new_psw.addr);
|
addr = be64_to_cpu(lowcore->svc_new_psw.addr);
|
||||||
|
|
||||||
cpu_unmap_lowcore(lowcore);
|
cpu_unmap_lowcore(lowcore);
|
||||||
|
|
||||||
load_psw(env, mask, addr);
|
s390_cpu_set_psw(env, mask, addr);
|
||||||
|
|
||||||
/* When a PER event is pending, the PER exception has to happen
|
/* When a PER event is pending, the PER exception has to happen
|
||||||
immediately after the SERVICE CALL one. */
|
immediately after the SERVICE CALL one. */
|
||||||
|
@ -348,12 +348,12 @@ static void do_ext_interrupt(CPUS390XState *env)
|
||||||
|
|
||||||
mask = be64_to_cpu(lowcore->external_new_psw.mask);
|
mask = be64_to_cpu(lowcore->external_new_psw.mask);
|
||||||
addr = be64_to_cpu(lowcore->external_new_psw.addr);
|
addr = be64_to_cpu(lowcore->external_new_psw.addr);
|
||||||
lowcore->external_old_psw.mask = cpu_to_be64(get_psw_mask(env));
|
lowcore->external_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
|
||||||
lowcore->external_old_psw.addr = cpu_to_be64(env->psw.addr);
|
lowcore->external_old_psw.addr = cpu_to_be64(env->psw.addr);
|
||||||
|
|
||||||
cpu_unmap_lowcore(lowcore);
|
cpu_unmap_lowcore(lowcore);
|
||||||
|
|
||||||
load_psw(env, mask, addr);
|
s390_cpu_set_psw(env, mask, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_io_interrupt(CPUS390XState *env)
|
static void do_io_interrupt(CPUS390XState *env)
|
||||||
|
@ -373,7 +373,7 @@ static void do_io_interrupt(CPUS390XState *env)
|
||||||
lowcore->subchannel_nr = cpu_to_be16(io->nr);
|
lowcore->subchannel_nr = cpu_to_be16(io->nr);
|
||||||
lowcore->io_int_parm = cpu_to_be32(io->parm);
|
lowcore->io_int_parm = cpu_to_be32(io->parm);
|
||||||
lowcore->io_int_word = cpu_to_be32(io->word);
|
lowcore->io_int_word = cpu_to_be32(io->word);
|
||||||
lowcore->io_old_psw.mask = cpu_to_be64(get_psw_mask(env));
|
lowcore->io_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
|
||||||
lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
|
lowcore->io_old_psw.addr = cpu_to_be64(env->psw.addr);
|
||||||
mask = be64_to_cpu(lowcore->io_new_psw.mask);
|
mask = be64_to_cpu(lowcore->io_new_psw.mask);
|
||||||
addr = be64_to_cpu(lowcore->io_new_psw.addr);
|
addr = be64_to_cpu(lowcore->io_new_psw.addr);
|
||||||
|
@ -381,7 +381,7 @@ static void do_io_interrupt(CPUS390XState *env)
|
||||||
cpu_unmap_lowcore(lowcore);
|
cpu_unmap_lowcore(lowcore);
|
||||||
g_free(io);
|
g_free(io);
|
||||||
|
|
||||||
load_psw(env, mask, addr);
|
s390_cpu_set_psw(env, mask, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct MchkExtSaveArea {
|
typedef struct MchkExtSaveArea {
|
||||||
|
@ -457,14 +457,14 @@ static void do_mchk_interrupt(CPUS390XState *env)
|
||||||
lowcore->clock_comp_save_area = cpu_to_be64(env->ckc >> 8);
|
lowcore->clock_comp_save_area = cpu_to_be64(env->ckc >> 8);
|
||||||
|
|
||||||
lowcore->mcic = cpu_to_be64(mcic);
|
lowcore->mcic = cpu_to_be64(mcic);
|
||||||
lowcore->mcck_old_psw.mask = cpu_to_be64(get_psw_mask(env));
|
lowcore->mcck_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
|
||||||
lowcore->mcck_old_psw.addr = cpu_to_be64(env->psw.addr);
|
lowcore->mcck_old_psw.addr = cpu_to_be64(env->psw.addr);
|
||||||
mask = be64_to_cpu(lowcore->mcck_new_psw.mask);
|
mask = be64_to_cpu(lowcore->mcck_new_psw.mask);
|
||||||
addr = be64_to_cpu(lowcore->mcck_new_psw.addr);
|
addr = be64_to_cpu(lowcore->mcck_new_psw.addr);
|
||||||
|
|
||||||
cpu_unmap_lowcore(lowcore);
|
cpu_unmap_lowcore(lowcore);
|
||||||
|
|
||||||
load_psw(env, mask, addr);
|
s390_cpu_set_psw(env, mask, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void s390_cpu_do_interrupt(CPUState *cs)
|
void s390_cpu_do_interrupt(CPUState *cs)
|
||||||
|
@ -592,9 +592,11 @@ void s390x_cpu_debug_excp_handler(CPUState *cs)
|
||||||
and MVCS instrutions are not used. */
|
and MVCS instrutions are not used. */
|
||||||
env->per_perc_atmid |= env->psw.mask & (PSW_MASK_ASC) >> 46;
|
env->per_perc_atmid |= env->psw.mask & (PSW_MASK_ASC) >> 46;
|
||||||
|
|
||||||
/* Remove all watchpoints to re-execute the code. A PER exception
|
/*
|
||||||
will be triggered, it will call load_psw which will recompute
|
* Remove all watchpoints to re-execute the code. A PER exception
|
||||||
the watchpoints. */
|
* will be triggered, it will call s390_cpu_set_psw which will
|
||||||
|
* recompute the watchpoints.
|
||||||
|
*/
|
||||||
cpu_watchpoint_remove_all(cs, BP_CPU);
|
cpu_watchpoint_remove_all(cs, BP_CPU);
|
||||||
cpu_loop_exit_noexc(cs);
|
cpu_loop_exit_noexc(cs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,44 +104,6 @@ void s390_handle_wait(S390CPU *cpu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
|
|
||||||
{
|
|
||||||
uint64_t old_mask = env->psw.mask;
|
|
||||||
|
|
||||||
env->psw.addr = addr;
|
|
||||||
env->psw.mask = mask;
|
|
||||||
|
|
||||||
/* KVM will handle all WAITs and trigger a WAIT exit on disabled_wait */
|
|
||||||
if (!tcg_enabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
env->cc_op = (mask >> 44) & 3;
|
|
||||||
|
|
||||||
if ((old_mask ^ mask) & PSW_MASK_PER) {
|
|
||||||
s390_cpu_recompute_watchpoints(env_cpu(env));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & PSW_MASK_WAIT) {
|
|
||||||
s390_handle_wait(env_archcpu(env));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t get_psw_mask(CPUS390XState *env)
|
|
||||||
{
|
|
||||||
uint64_t r = env->psw.mask;
|
|
||||||
|
|
||||||
if (tcg_enabled()) {
|
|
||||||
env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst,
|
|
||||||
env->cc_vr);
|
|
||||||
|
|
||||||
r &= ~PSW_MASK_CC;
|
|
||||||
assert(!(env->cc_op & ~3));
|
|
||||||
r |= (uint64_t)env->cc_op << 44;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
LowCore *cpu_map_lowcore(CPUS390XState *env)
|
LowCore *cpu_map_lowcore(CPUS390XState *env)
|
||||||
{
|
{
|
||||||
LowCore *lowcore;
|
LowCore *lowcore;
|
||||||
|
@ -168,7 +130,7 @@ void do_restart_interrupt(CPUS390XState *env)
|
||||||
|
|
||||||
lowcore = cpu_map_lowcore(env);
|
lowcore = cpu_map_lowcore(env);
|
||||||
|
|
||||||
lowcore->restart_old_psw.mask = cpu_to_be64(get_psw_mask(env));
|
lowcore->restart_old_psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(env));
|
||||||
lowcore->restart_old_psw.addr = cpu_to_be64(env->psw.addr);
|
lowcore->restart_old_psw.addr = cpu_to_be64(env->psw.addr);
|
||||||
mask = be64_to_cpu(lowcore->restart_new_psw.mask);
|
mask = be64_to_cpu(lowcore->restart_new_psw.mask);
|
||||||
addr = be64_to_cpu(lowcore->restart_new_psw.addr);
|
addr = be64_to_cpu(lowcore->restart_new_psw.addr);
|
||||||
|
@ -176,7 +138,7 @@ void do_restart_interrupt(CPUS390XState *env)
|
||||||
cpu_unmap_lowcore(lowcore);
|
cpu_unmap_lowcore(lowcore);
|
||||||
env->pending_int &= ~INTERRUPT_RESTART;
|
env->pending_int &= ~INTERRUPT_RESTART;
|
||||||
|
|
||||||
load_psw(env, mask, addr);
|
s390_cpu_set_psw(env, mask, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void s390_cpu_recompute_watchpoints(CPUState *cs)
|
void s390_cpu_recompute_watchpoints(CPUState *cs)
|
||||||
|
@ -266,7 +228,7 @@ int s390_store_status(S390CPU *cpu, hwaddr addr, bool store_arch)
|
||||||
sa->grs[i] = cpu_to_be64(cpu->env.regs[i]);
|
sa->grs[i] = cpu_to_be64(cpu->env.regs[i]);
|
||||||
}
|
}
|
||||||
sa->psw.addr = cpu_to_be64(cpu->env.psw.addr);
|
sa->psw.addr = cpu_to_be64(cpu->env.psw.addr);
|
||||||
sa->psw.mask = cpu_to_be64(get_psw_mask(&cpu->env));
|
sa->psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(&cpu->env));
|
||||||
sa->prefix = cpu_to_be32(cpu->env.psa);
|
sa->prefix = cpu_to_be32(cpu->env.psa);
|
||||||
sa->fpc = cpu_to_be32(cpu->env.fpc);
|
sa->fpc = cpu_to_be32(cpu->env.fpc);
|
||||||
sa->todpr = cpu_to_be32(cpu->env.todpr);
|
sa->todpr = cpu_to_be32(cpu->env.todpr);
|
||||||
|
@ -323,8 +285,53 @@ int s390_store_adtl_status(S390CPU *cpu, hwaddr addr, hwaddr len)
|
||||||
cpu_physical_memory_unmap(sa, len, 1, len);
|
cpu_physical_memory_unmap(sa, len, 1, len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/* For user-only, tcg is always enabled. */
|
||||||
|
#define tcg_enabled() true
|
||||||
#endif /* CONFIG_USER_ONLY */
|
#endif /* CONFIG_USER_ONLY */
|
||||||
|
|
||||||
|
void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
uint64_t old_mask = env->psw.mask;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
env->psw.addr = addr;
|
||||||
|
env->psw.mask = mask;
|
||||||
|
|
||||||
|
/* KVM will handle all WAITs and trigger a WAIT exit on disabled_wait */
|
||||||
|
if (!tcg_enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
env->cc_op = (mask >> 44) & 3;
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
if ((old_mask ^ mask) & PSW_MASK_PER) {
|
||||||
|
s390_cpu_recompute_watchpoints(env_cpu(env));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & PSW_MASK_WAIT) {
|
||||||
|
s390_handle_wait(env_archcpu(env));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t s390_cpu_get_psw_mask(CPUS390XState *env)
|
||||||
|
{
|
||||||
|
uint64_t r = env->psw.mask;
|
||||||
|
|
||||||
|
if (tcg_enabled()) {
|
||||||
|
env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst,
|
||||||
|
env->cc_vr);
|
||||||
|
|
||||||
|
r &= ~PSW_MASK_CC;
|
||||||
|
assert(!(env->cc_op & ~3));
|
||||||
|
r |= (uint64_t)env->cc_op << 44;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
void s390_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
void s390_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
||||||
{
|
{
|
||||||
S390CPU *cpu = S390_CPU(cs);
|
S390CPU *cpu = S390_CPU(cs);
|
||||||
|
|
|
@ -235,10 +235,6 @@ int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||||
const char *cc_name(enum cc_op cc_op);
|
const char *cc_name(enum cc_op cc_op);
|
||||||
uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
|
uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
|
||||||
uint64_t vr);
|
uint64_t vr);
|
||||||
#ifndef CONFIG_USER_ONLY
|
|
||||||
void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr);
|
|
||||||
#endif /* CONFIG_USER_ONLY */
|
|
||||||
|
|
||||||
|
|
||||||
/* cpu.c */
|
/* cpu.c */
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
@ -312,7 +308,6 @@ void s390_cpu_gdb_init(CPUState *cs);
|
||||||
void s390_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
|
void s390_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
|
||||||
void do_restart_interrupt(CPUS390XState *env);
|
void do_restart_interrupt(CPUS390XState *env);
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
uint64_t get_psw_mask(CPUS390XState *env);
|
|
||||||
void s390_cpu_recompute_watchpoints(CPUState *cs);
|
void s390_cpu_recompute_watchpoints(CPUState *cs);
|
||||||
void s390x_tod_timer(void *opaque);
|
void s390x_tod_timer(void *opaque);
|
||||||
void s390x_cpu_timer(void *opaque);
|
void s390x_cpu_timer(void *opaque);
|
||||||
|
|
|
@ -235,7 +235,8 @@ static void sigp_restart(CPUState *cs, run_on_cpu_data arg)
|
||||||
cpu_synchronize_state(cs);
|
cpu_synchronize_state(cs);
|
||||||
/*
|
/*
|
||||||
* Set OPERATING (and unhalting) before loading the restart PSW.
|
* Set OPERATING (and unhalting) before loading the restart PSW.
|
||||||
* load_psw() will then properly halt the CPU again if necessary (TCG).
|
* s390_cpu_set_psw() will then properly halt the CPU again if
|
||||||
|
* necessary (TCG).
|
||||||
*/
|
*/
|
||||||
s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
|
s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
|
||||||
do_restart_interrupt(&cpu->env);
|
do_restart_interrupt(&cpu->env);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue