mirror of https://gitee.com/openkylin/qemu.git
target-s390x: wire up DIAG IPL in TCG mode
DIAG IPL is already implemented for KVM, but not wired from TCG. For that change the format of the instruction so that we can get R1 and R3 numbers in addition to the function code. The diag function can change plenty of things, including CC, so we should enter with a static CC. Also it doesn't set the value of general register 2 to 0 as in the current code. We also need to exit the CPU loop after a reset, which means a new PSW. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
cbed0ba78f
commit
8df7eef305
|
@ -87,7 +87,7 @@ DEF_HELPER_FLAGS_1(popcnt, TCG_CALL_NO_RWG_SE, i64, i64)
|
|||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
DEF_HELPER_3(servc, i32, env, i64, i64)
|
||||
DEF_HELPER_4(diag, i64, env, i32, i64, i64)
|
||||
DEF_HELPER_4(diag, void, env, i32, i32, i32)
|
||||
DEF_HELPER_3(load_psw, noreturn, env, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(spx, TCG_CALL_NO_RWG, void, env, i64)
|
||||
DEF_HELPER_FLAGS_1(stck, TCG_CALL_NO_RWG_SE, i64, env)
|
||||
|
|
|
@ -835,7 +835,7 @@
|
|||
/* COMPARE AND SWAP AND PURGE */
|
||||
C(0xb250, CSP, RRE, Z, 0, ra2, 0, 0, csp, 0)
|
||||
/* DIAGNOSE (KVM hypercall) */
|
||||
C(0x8300, DIAG, RX_a, Z, 0, 0, 0, 0, diag, 0)
|
||||
C(0x8300, DIAG, RSI, Z, 0, 0, 0, 0, diag, 0)
|
||||
/* INSERT STORAGE KEY EXTENDED */
|
||||
C(0xb229, ISKE, RRE, Z, 0, r2_o, new, r1_8, iske, 0)
|
||||
/* INVALIDATE PAGE TABLE ENTRY */
|
||||
|
|
|
@ -205,9 +205,15 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
|
|||
switch (subcode) {
|
||||
case 0:
|
||||
modified_clear_reset(s390_env_get_cpu(env));
|
||||
if (tcg_enabled()) {
|
||||
cpu_loop_exit(CPU(s390_env_get_cpu(env)));
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
load_normal_reset(s390_env_get_cpu(env));
|
||||
if (tcg_enabled()) {
|
||||
cpu_loop_exit(CPU(s390_env_get_cpu(env)));
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if ((r1 & 1) || (addr & 0x0fffULL)) {
|
||||
|
@ -254,9 +260,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* DIAG */
|
||||
uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
|
||||
uint64_t code)
|
||||
void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
|
||||
{
|
||||
uint64_t r;
|
||||
|
||||
|
@ -271,6 +275,7 @@ uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
|
|||
break;
|
||||
case 0x308:
|
||||
/* ipl */
|
||||
handle_diag_308(env, r1, r3);
|
||||
r = 0;
|
||||
break;
|
||||
default:
|
||||
|
@ -281,8 +286,6 @@ uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
|
|||
if (r) {
|
||||
program_interrupt(env, PGM_OPERATION, ILEN_LATER_INC);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Set Prefix */
|
||||
|
|
|
@ -2025,15 +2025,19 @@ static ExitStatus op_ct(DisasContext *s, DisasOps *o)
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
static ExitStatus op_diag(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
TCGv_i32 tmp;
|
||||
TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
|
||||
TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
|
||||
TCGv_i32 func_code = tcg_const_i32(get_field(s->fields, i2));
|
||||
|
||||
check_privileged(s);
|
||||
potential_page_fault(s);
|
||||
update_psw_addr(s);
|
||||
gen_op_calc_cc(s);
|
||||
|
||||
/* We pretend the format is RX_a so that D2 is the field we want. */
|
||||
tmp = tcg_const_i32(get_field(s->fields, d2) & 0xfff);
|
||||
gen_helper_diag(regs[2], cpu_env, tmp, regs[2], regs[1]);
|
||||
tcg_temp_free_i32(tmp);
|
||||
gen_helper_diag(cpu_env, r1, r3, func_code);
|
||||
|
||||
tcg_temp_free_i32(func_code);
|
||||
tcg_temp_free_i32(r3);
|
||||
tcg_temp_free_i32(r1);
|
||||
return NO_EXIT;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue