/*
 * s390x SIGP instruction handling
 *
 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
 * Copyright IBM Corp. 2012
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "s390x-internal.h"
#include "sysemu/hw_accel.h"
#include "sysemu/runstate.h"
#include "exec/address-spaces.h"
#include "exec/exec-all.h"
#include "sysemu/tcg.h"
#include "trace.h"
#include "qapi/qapi-types-machine.h"

QemuMutex qemu_sigp_mutex;

typedef struct SigpInfo {
    uint64_t param;
    int cc;
    uint64_t *status_reg;
} SigpInfo;

static void set_sigp_status(SigpInfo *si, uint64_t status)
{
    *si->status_reg &= 0xffffffff00000000ULL;
    *si->status_reg |= status;
    si->cc = SIGP_CC_STATUS_STORED;
}

static void sigp_sense(S390CPU *dst_cpu, SigpInfo *si)
{
    uint8_t state = s390_cpu_get_state(dst_cpu);
    bool ext_call = dst_cpu->env.pending_int & INTERRUPT_EXTERNAL_CALL;
    uint64_t status = 0;

    if (!tcg_enabled()) {
        /* handled in KVM */
        set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
        return;
    }

    /* sensing without locks is racy, but it's the same for real hw */
    if (state != S390_CPU_STATE_STOPPED && !ext_call) {
        si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
    } else {
        if (ext_call) {
            status |= SIGP_STAT_EXT_CALL_PENDING;
        }
        if (state == S390_CPU_STATE_STOPPED) {
            status |= SIGP_STAT_STOPPED;
        }
        set_sigp_status(si, status);
    }
}

static void sigp_external_call(S390CPU *src_cpu, S390CPU *dst_cpu, SigpInfo *si)
{
    int ret;

    if (!tcg_enabled()) {
        /* handled in KVM */
        set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
        return;
    }

    ret = cpu_inject_external_call(dst_cpu, src_cpu->env.core_id);
    if (!ret) {
        si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
    } else {
        set_sigp_status(si, SIGP_STAT_EXT_CALL_PENDING);
    }
}

static void sigp_emergency(S390CPU *src_cpu, S390CPU *dst_cpu, SigpInfo *si)
{
    if (!tcg_enabled()) {
        /* handled in KVM */
        set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
        return;
    }

    cpu_inject_emergency_signal(dst_cpu, src_cpu->env.core_id);
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_start(CPUState *cs, run_on_cpu_data arg)
{
    S390CPU *cpu = S390_CPU(cs);
    SigpInfo *si = arg.host_ptr;

    if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
        si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
        return;
    }

    s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_stop(CPUState *cs, run_on_cpu_data arg)
{
    S390CPU *cpu = S390_CPU(cs);
    SigpInfo *si = arg.host_ptr;

    if (s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING) {
        si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
        return;
    }

    /* disabled wait - sleeping in user space */
    if (cs->halted) {
        s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
    } else {
        /* execute the stop function */
        cpu->env.sigp_order = SIGP_STOP;
        cpu_inject_stop(cpu);
    }
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg)
{
    S390CPU *cpu = S390_CPU(cs);
    SigpInfo *si = arg.host_ptr;

    /* disabled wait - sleeping in user space */
    if (s390_cpu_get_state(cpu) == S390_CPU_STATE_OPERATING && cs->halted) {
        s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
    }

    switch (s390_cpu_get_state(cpu)) {
    case S390_CPU_STATE_OPERATING:
        cpu->env.sigp_order = SIGP_STOP_STORE_STATUS;
        cpu_inject_stop(cpu);
        /* store will be performed in do_stop_interrupt() */
        break;
    case S390_CPU_STATE_STOPPED:
        /* already stopped, just store the status */
        cpu_synchronize_state(cs);
        s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
        break;
    }
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_store_status_at_address(CPUState *cs, run_on_cpu_data arg)
{
    S390CPU *cpu = S390_CPU(cs);
    SigpInfo *si = arg.host_ptr;
    uint32_t address = si->param & 0x7ffffe00u;

    /* cpu has to be stopped */
    if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
        set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
        return;
    }

    cpu_synchronize_state(cs);

    if (s390_store_status(cpu, address, false)) {
        set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
        return;
    }
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

#define ADTL_SAVE_LC_MASK  0xfUL
static void sigp_store_adtl_status(CPUState *cs, run_on_cpu_data arg)
{
    S390CPU *cpu = S390_CPU(cs);
    SigpInfo *si = arg.host_ptr;
    uint8_t lc = si->param & ADTL_SAVE_LC_MASK;
    hwaddr addr = si->param & ~ADTL_SAVE_LC_MASK;
    hwaddr len = 1UL << (lc ? lc : 10);

    if (!s390_has_feat(S390_FEAT_VECTOR) &&
        !s390_has_feat(S390_FEAT_GUARDED_STORAGE)) {
        set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
        return;
    }

    /* cpu has to be stopped */
    if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
        set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
        return;
    }

    /* address must be aligned to length */
    if (addr & (len - 1)) {
        set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
        return;
    }

    /* no GS: only lc == 0 is valid */
    if (!s390_has_feat(S390_FEAT_GUARDED_STORAGE) &&
        lc != 0) {
        set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
        return;
    }

    /* GS: 0, 10, 11, 12 are valid */
    if (s390_has_feat(S390_FEAT_GUARDED_STORAGE) &&
        lc != 0 &&
        lc != 10 &&
        lc != 11 &&
        lc != 12) {
        set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
        return;
    }

    cpu_synchronize_state(cs);

    if (s390_store_adtl_status(cpu, addr, len)) {
        set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
        return;
    }
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_restart(CPUState *cs, run_on_cpu_data arg)
{
    S390CPU *cpu = S390_CPU(cs);
    SigpInfo *si = arg.host_ptr;

    switch (s390_cpu_get_state(cpu)) {
    case S390_CPU_STATE_STOPPED:
        /* the restart irq has to be delivered prior to any other pending irq */
        cpu_synchronize_state(cs);
        /*
         * Set OPERATING (and unhalting) before loading the restart PSW.
         * s390_cpu_set_psw() will then properly halt the CPU again if
         * necessary (TCG).
         */
        s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
        do_restart_interrupt(&cpu->env);
        break;
    case S390_CPU_STATE_OPERATING:
        cpu_inject_restart(cpu);
        break;
    }
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_initial_cpu_reset(CPUState *cs, run_on_cpu_data arg)
{
    S390CPU *cpu = S390_CPU(cs);
    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
    SigpInfo *si = arg.host_ptr;

    cpu_synchronize_state(cs);
    scc->reset(cs, S390_CPU_RESET_INITIAL);
    cpu_synchronize_post_reset(cs);
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_cpu_reset(CPUState *cs, run_on_cpu_data arg)
{
    S390CPU *cpu = S390_CPU(cs);
    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
    SigpInfo *si = arg.host_ptr;

    cpu_synchronize_state(cs);
    scc->reset(cs, S390_CPU_RESET_NORMAL);
    cpu_synchronize_post_reset(cs);
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_set_prefix(CPUState *cs, run_on_cpu_data arg)
{
    S390CPU *cpu = S390_CPU(cs);
    SigpInfo *si = arg.host_ptr;
    uint32_t addr = si->param & 0x7fffe000u;

    cpu_synchronize_state(cs);

    if (!address_space_access_valid(&address_space_memory, addr,
                                    sizeof(struct LowCore), false,
                                    MEMTXATTRS_UNSPECIFIED)) {
        set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
        return;
    }

    /* cpu has to be stopped */
    if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
        set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
        return;
    }

    cpu->env.psa = addr;
    tlb_flush(cs);
    cpu_synchronize_post_init(cs);
    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_cond_emergency(S390CPU *src_cpu, S390CPU *dst_cpu,
                                SigpInfo *si)
{
    const uint64_t psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT;
    uint16_t p_asn, s_asn, asn;
    uint64_t psw_addr, psw_mask;
    bool idle;

    if (!tcg_enabled()) {
        /* handled in KVM */
        set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
        return;
    }

    /* this looks racy, but these values are only used when STOPPED */
    idle = CPU(dst_cpu)->halted;
    psw_addr = dst_cpu->env.psw.addr;
    psw_mask = dst_cpu->env.psw.mask;
    asn = si->param;
    p_asn = dst_cpu->env.cregs[4] & 0xffff;  /* Primary ASN */
    s_asn = dst_cpu->env.cregs[3] & 0xffff;  /* Secondary ASN */

    if (s390_cpu_get_state(dst_cpu) != S390_CPU_STATE_STOPPED ||
        (psw_mask & psw_int_mask) != psw_int_mask ||
        (idle && psw_addr != 0) ||
        (!idle && (asn == p_asn || asn == s_asn))) {
        cpu_inject_emergency_signal(dst_cpu, src_cpu->env.core_id);
    } else {
        set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
    }

    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

static void sigp_sense_running(S390CPU *dst_cpu, SigpInfo *si)
{
    if (!tcg_enabled()) {
        /* handled in KVM */
        set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
        return;
    }

    /* sensing without locks is racy, but it's the same for real hw */
    if (!s390_has_feat(S390_FEAT_SENSE_RUNNING_STATUS)) {
        set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
        return;
    }

    /* If halted (which includes also STOPPED), it is not running */
    if (CPU(dst_cpu)->halted) {
        set_sigp_status(si, SIGP_STAT_NOT_RUNNING);
    } else {
        si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
    }
}

static int handle_sigp_single_dst(S390CPU *cpu, S390CPU *dst_cpu, uint8_t order,
                                  uint64_t param, uint64_t *status_reg)
{
    SigpInfo si = {
        .param = param,
        .status_reg = status_reg,
    };

    /* cpu available? */
    if (dst_cpu == NULL) {
        return SIGP_CC_NOT_OPERATIONAL;
    }

    /* only resets can break pending orders */
    if (dst_cpu->env.sigp_order != 0 &&
        order != SIGP_CPU_RESET &&
        order != SIGP_INITIAL_CPU_RESET) {
        return SIGP_CC_BUSY;
    }

    switch (order) {
    case SIGP_SENSE:
        sigp_sense(dst_cpu, &si);
        break;
    case SIGP_EXTERNAL_CALL:
        sigp_external_call(cpu, dst_cpu, &si);
        break;
    case SIGP_EMERGENCY:
        sigp_emergency(cpu, dst_cpu, &si);
        break;
    case SIGP_START:
        run_on_cpu(CPU(dst_cpu), sigp_start, RUN_ON_CPU_HOST_PTR(&si));
        break;
    case SIGP_STOP:
        run_on_cpu(CPU(dst_cpu), sigp_stop, RUN_ON_CPU_HOST_PTR(&si));
        break;
    case SIGP_RESTART:
        run_on_cpu(CPU(dst_cpu), sigp_restart, RUN_ON_CPU_HOST_PTR(&si));
        break;
    case SIGP_STOP_STORE_STATUS:
        run_on_cpu(CPU(dst_cpu), sigp_stop_and_store_status, RUN_ON_CPU_HOST_PTR(&si));
        break;
    case SIGP_STORE_STATUS_ADDR:
        run_on_cpu(CPU(dst_cpu), sigp_store_status_at_address, RUN_ON_CPU_HOST_PTR(&si));
        break;
    case SIGP_STORE_ADTL_STATUS:
        run_on_cpu(CPU(dst_cpu), sigp_store_adtl_status, RUN_ON_CPU_HOST_PTR(&si));
        break;
    case SIGP_SET_PREFIX:
        run_on_cpu(CPU(dst_cpu), sigp_set_prefix, RUN_ON_CPU_HOST_PTR(&si));
        break;
    case SIGP_INITIAL_CPU_RESET:
        run_on_cpu(CPU(dst_cpu), sigp_initial_cpu_reset, RUN_ON_CPU_HOST_PTR(&si));
        break;
    case SIGP_CPU_RESET:
        run_on_cpu(CPU(dst_cpu), sigp_cpu_reset, RUN_ON_CPU_HOST_PTR(&si));
        break;
    case SIGP_COND_EMERGENCY:
        sigp_cond_emergency(cpu, dst_cpu, &si);
        break;
    case SIGP_SENSE_RUNNING:
        sigp_sense_running(dst_cpu, &si);
        break;
    default:
        set_sigp_status(&si, SIGP_STAT_INVALID_ORDER);
    }

    return si.cc;
}

static int sigp_set_architecture(S390CPU *cpu, uint32_t param,
                                 uint64_t *status_reg)
{
    *status_reg &= 0xffffffff00000000ULL;

    /* Reject set arch order, with czam we're always in z/Arch mode. */
    *status_reg |= SIGP_STAT_INVALID_PARAMETER;
    return SIGP_CC_STATUS_STORED;
}

int handle_sigp(CPUS390XState *env, uint8_t order, uint64_t r1, uint64_t r3)
{
    uint64_t *status_reg = &env->regs[r1];
    uint64_t param = (r1 % 2) ? env->regs[r1] : env->regs[r1 + 1];
    S390CPU *cpu = env_archcpu(env);
    S390CPU *dst_cpu = NULL;
    int ret;

    if (qemu_mutex_trylock(&qemu_sigp_mutex)) {
        ret = SIGP_CC_BUSY;
        goto out;
    }

    switch (order) {
    case SIGP_SET_ARCH:
        ret = sigp_set_architecture(cpu, param, status_reg);
        break;
    default:
        /* all other sigp orders target a single vcpu */
        dst_cpu = s390_cpu_addr2state(env->regs[r3]);
        ret = handle_sigp_single_dst(cpu, dst_cpu, order, param, status_reg);
    }
    qemu_mutex_unlock(&qemu_sigp_mutex);

out:
    trace_sigp_finished(order, CPU(cpu)->cpu_index,
                        dst_cpu ? CPU(dst_cpu)->cpu_index : -1, ret);
    g_assert(ret >= 0);

    return ret;
}

int s390_cpu_restart(S390CPU *cpu)
{
    SigpInfo si = {};

    run_on_cpu(CPU(cpu), sigp_restart, RUN_ON_CPU_HOST_PTR(&si));
    return 0;
}

void do_stop_interrupt(CPUS390XState *env)
{
    S390CPU *cpu = env_archcpu(env);

    /*
     * Complete the STOP operation before exposing the CPU as
     * STOPPED to the system.
     */
    if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {
        s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
    }
    env->sigp_order = 0;
    if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
    }
    env->pending_int &= ~INTERRUPT_STOP;
}

void s390_init_sigp(void)
{
    qemu_mutex_init(&qemu_sigp_mutex);
}
