void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)

{

    uint64_t addr =  env->regs[r1];

    uint64_t subcode = env->regs[r3];

    IplParameterBlock *iplb;



    if (env->psw.mask & PSW_MASK_PSTATE) {

        program_interrupt(env, PGM_PRIVILEGED, ILEN_LATER_INC);

        return;

    }



    if ((subcode & ~0x0ffffULL) || (subcode > 6)) {

        program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);

        return;

    }



    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 3:

        s390_reipl_request();

        if (tcg_enabled()) {

            cpu_loop_exit(CPU(s390_env_get_cpu(env)));

        }

        break;

    case 5:

        if ((r1 & 1) || (addr & 0x0fffULL)) {

            program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);

            return;

        }

        if (!address_space_access_valid(&address_space_memory, addr,

                                        sizeof(IplParameterBlock), false)) {

            program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC);

            return;

        }

        iplb = g_malloc0(sizeof(IplParameterBlock));

        cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));

        if (!iplb_valid_len(iplb)) {

            env->regs[r1 + 1] = DIAG_308_RC_INVALID;

            goto out;

        }



        cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));



        if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {

            env->regs[r1 + 1] = DIAG_308_RC_INVALID;

            goto out;

        }



        s390_ipl_update_diag308(iplb);

        env->regs[r1 + 1] = DIAG_308_RC_OK;

out:

        g_free(iplb);

        return;

    case 6:

        if ((r1 & 1) || (addr & 0x0fffULL)) {

            program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);

            return;

        }

        if (!address_space_access_valid(&address_space_memory, addr,

                                        sizeof(IplParameterBlock), true)) {

            program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC);

            return;

        }

        iplb = s390_ipl_get_iplb();

        if (iplb) {

            cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));

            env->regs[r1 + 1] = DIAG_308_RC_OK;

        } else {

            env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;

        }

        return;

    default:

        hw_error("Unhandled diag308 subcode %" PRIx64, subcode);

        break;

    }

}

void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)

{

    uint64_t addr =  env->regs[r1];

    uint64_t subcode = env->regs[r3];

    IplParameterBlock *iplb;



    if (env->psw.mask & PSW_MASK_PSTATE) {

        program_interrupt(env, PGM_PRIVILEGED, ILEN_LATER_INC);

        return;

    }



    if ((subcode & ~0x0ffffULL) || (subcode > 6)) {

        program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);

        return;

    }



    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 3:

        s390_reipl_request();

        if (tcg_enabled()) {

            cpu_loop_exit(CPU(s390_env_get_cpu(env)));

        }

        break;

    case 5:

        if ((r1 & 1) || (addr & 0x0fffULL)) {

            program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);

            return;

        }

        if (!address_space_access_valid(&address_space_memory, addr,

                                        sizeof(IplParameterBlock), false)) {

            program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC);

            return;

        }

        iplb = g_malloc0(sizeof(IplParameterBlock));

        cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));

        if (!iplb_valid_len(iplb)) {

            env->regs[r1 + 1] = DIAG_308_RC_INVALID;

            goto out;

        }



        cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));



        if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {

            env->regs[r1 + 1] = DIAG_308_RC_INVALID;

            goto out;

        }



        s390_ipl_update_diag308(iplb);

        env->regs[r1 + 1] = DIAG_308_RC_OK;

out:

        g_free(iplb);

        return;

    case 6:

        if ((r1 & 1) || (addr & 0x0fffULL)) {

            program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);

            return;

        }

        if (!address_space_access_valid(&address_space_memory, addr,

                                        sizeof(IplParameterBlock), true)) {

            program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC);

            return;

        }

        iplb = s390_ipl_get_iplb();

        if (iplb) {

            cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));

            env->regs[r1 + 1] = DIAG_308_RC_OK;

        } else {

            env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;

        }

        return;

    default:

        hw_error("Unhandled diag308 subcode %" PRIx64, subcode);

        break;

    }

}

void FUNC_0(CPUS390XState *VAR_0, uint64_t VAR_1, uint64_t VAR_2)

{

    uint64_t addr =  VAR_0->regs[VAR_1];

    uint64_t subcode = VAR_0->regs[VAR_2];

    IplParameterBlock *iplb;



    if (VAR_0->psw.mask & PSW_MASK_PSTATE) {

        program_interrupt(VAR_0, PGM_PRIVILEGED, ILEN_LATER_INC);

        return;

    }



    if ((subcode & ~0x0ffffULL) || (subcode > 6)) {

        program_interrupt(VAR_0, PGM_SPECIFICATION, ILEN_LATER_INC);

        return;

    }



    switch (subcode) {

    case 0:

        modified_clear_reset(s390_env_get_cpu(VAR_0));

        if (tcg_enabled()) {

            cpu_loop_exit(CPU(s390_env_get_cpu(VAR_0)));

        }

        break;

    case 1:

        load_normal_reset(s390_env_get_cpu(VAR_0));

        if (tcg_enabled()) {

            cpu_loop_exit(CPU(s390_env_get_cpu(VAR_0)));

        }

        break;

    case 3:

        s390_reipl_request();

        if (tcg_enabled()) {

            cpu_loop_exit(CPU(s390_env_get_cpu(VAR_0)));

        }

        break;

    case 5:

        if ((VAR_1 & 1) || (addr & 0x0fffULL)) {

            program_interrupt(VAR_0, PGM_SPECIFICATION, ILEN_LATER_INC);

            return;

        }

        if (!address_space_access_valid(&address_space_memory, addr,

                                        sizeof(IplParameterBlock), false)) {

            program_interrupt(VAR_0, PGM_ADDRESSING, ILEN_LATER_INC);

            return;

        }

        iplb = g_malloc0(sizeof(IplParameterBlock));

        cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));

        if (!iplb_valid_len(iplb)) {

            VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_INVALID;

            goto out;

        }



        cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));



        if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {

            VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_INVALID;

            goto out;

        }



        s390_ipl_update_diag308(iplb);

        VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_OK;

out:

        g_free(iplb);

        return;

    case 6:

        if ((VAR_1 & 1) || (addr & 0x0fffULL)) {

            program_interrupt(VAR_0, PGM_SPECIFICATION, ILEN_LATER_INC);

            return;

        }

        if (!address_space_access_valid(&address_space_memory, addr,

                                        sizeof(IplParameterBlock), true)) {

            program_interrupt(VAR_0, PGM_ADDRESSING, ILEN_LATER_INC);

            return;

        }

        iplb = s390_ipl_get_iplb();

        if (iplb) {

            cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));

            VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_OK;

        } else {

            VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_NO_CONF;

        }

        return;

    default:

        hw_error("Unhandled diag308 subcode %" PRIx64, subcode);

        break;

    }

}

void FUNC_0(CPUS390XState *VAR_0, uint64_t VAR_1, uint64_t VAR_2)
{ uint64_t addr =  VAR_0->regs[VAR_1]; uint64_t subcode = VAR_0->regs[VAR_2]; IplParameterBlock *iplb; if (VAR_0->psw.mask & PSW_MASK_PSTATE) { program_interrupt(VAR_0, PGM_PRIVILEGED, ILEN_LATER_INC); return; } if ((subcode & ~0x0ffffULL) || (subcode > 6)) { program_interrupt(VAR_0, PGM_SPECIFICATION, ILEN_LATER_INC); return; } switch (subcode) { case 0:
modified_clear_reset(s390_env_get_cpu(VAR_0)); if (tcg_enabled()) { cpu_loop_exit(CPU(s390_env_get_cpu(VAR_0))); } break; case 1:
load_normal_reset(s390_env_get_cpu(VAR_0)); if (tcg_enabled()) { cpu_loop_exit(CPU(s390_env_get_cpu(VAR_0))); } break; case 3:
s390_reipl_request(); if (tcg_enabled()) { cpu_loop_exit(CPU(s390_env_get_cpu(VAR_0))); } break; case 5:
if ((VAR_1 & 1) || (addr & 0x0fffULL)) { program_interrupt(VAR_0, PGM_SPECIFICATION, ILEN_LATER_INC); return; } if (!address_space_access_valid(&address_space_memory, addr,
sizeof(IplParameterBlock), false)) { program_interrupt(VAR_0, PGM_ADDRESSING, ILEN_LATER_INC); return; } iplb = g_malloc0(sizeof(IplParameterBlock)); cpu_physical_memory_read(addr, iplb, sizeof(iplb->len)); if (!iplb_valid_len(iplb)) { VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_INVALID; goto out; } cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len)); if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) { VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_INVALID; goto out; } s390_ipl_update_diag308(iplb); VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_OK; out:
g_free(iplb); return; case 6:
if ((VAR_1 & 1) || (addr & 0x0fffULL)) { program_interrupt(VAR_0, PGM_SPECIFICATION, ILEN_LATER_INC); return; } if (!address_space_access_valid(&address_space_memory, addr,
sizeof(IplParameterBlock), true)) { program_interrupt(VAR_0, PGM_ADDRESSING, ILEN_LATER_INC); return; } iplb = s390_ipl_get_iplb(); if (iplb) { cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len)); VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_OK; } else { VAR_0->regs[VAR_1 + 1] = DIAG_308_RC_NO_CONF; } return; default:
hw_error("Unhandled diag308 subcode %" PRIx64, subcode); break; } }