/*
 * QEMU S/390 CPU
 *
 * Copyright (c) 2009 Ulrich Hecht
 * Copyright (c) 2011 Alexander Graf
 * Copyright (c) 2012 SUSE LINUX Products GmbH
 * Copyright (c) 2012 IBM Corp.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "cpu.h"
#include "internal.h"
#include "kvm_s390x.h"
#include "sysemu/kvm.h"
#include "sysemu/reset.h"
#include "qemu/timer.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "trace.h"
#include "qapi/visitor.h"
#include "qapi/qapi-types-machine.h"
#include "qapi/qapi-visit-run-state.h"
#include "sysemu/hw_accel.h"
#include "hw/qdev-properties.h"
#ifndef CONFIG_USER_ONLY
#include "hw/s390x/pv.h"
#include "hw/boards.h"
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "sysemu/tcg.h"
#endif
#include "fpu/softfloat-helpers.h"

#define CR0_RESET       0xE0UL
#define CR14_RESET      0xC2000000UL;

static void s390_cpu_set_pc(CPUState *cs, vaddr value)
{
    S390CPU *cpu = S390_CPU(cs);

    cpu->env.psw.addr = value;
}

static bool s390_cpu_has_work(CPUState *cs)
{
    S390CPU *cpu = S390_CPU(cs);

    /* STOPPED cpus can never wake up */
    if (s390_cpu_get_state(cpu) != S390_CPU_STATE_LOAD &&
        s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING) {
        return false;
    }

    if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
        return false;
    }

    return s390_cpu_has_int(cpu);
}

#if !defined(CONFIG_USER_ONLY)
/* S390CPUClass::load_normal() */
static void s390_cpu_load_normal(CPUState *s)
{
    S390CPU *cpu = S390_CPU(s);
    uint64_t spsw;

    if (!s390_is_pv()) {
        spsw = ldq_phys(s->as, 0);
        cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL;
        /*
         * Invert short psw indication, so SIE will report a specification
         * exception if it was not set.
         */
        cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
        cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR;
    } else {
        /*
         * Firmware requires us to set the load state before we set
         * the cpu to operating on protected guests.
         */
        s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu);
    }
    s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
}
#endif

/* S390CPUClass::reset() */
static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
{
    S390CPU *cpu = S390_CPU(s);
    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
    CPUS390XState *env = &cpu->env;
    DeviceState *dev = DEVICE(s);

    scc->parent_reset(dev);
    cpu->env.sigp_order = 0;
    s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);

    switch (type) {
    case S390_CPU_RESET_CLEAR:
        memset(env, 0, offsetof(CPUS390XState, start_initial_reset_fields));
        /* fall through */
    case S390_CPU_RESET_INITIAL:
        /* initial reset does not clear everything! */
        memset(&env->start_initial_reset_fields, 0,
               offsetof(CPUS390XState, start_normal_reset_fields) -
               offsetof(CPUS390XState, start_initial_reset_fields));

        /* architectured initial value for Breaking-Event-Address register */
        env->gbea = 1;

        /* architectured initial values for CR 0 and 14 */
        env->cregs[0] = CR0_RESET;
        env->cregs[14] = CR14_RESET;

#if defined(CONFIG_USER_ONLY)
        /* user mode should always be allowed to use the full FPU */
        env->cregs[0] |= CR0_AFP;
        if (s390_has_feat(S390_FEAT_VECTOR)) {
            env->cregs[0] |= CR0_VECTOR;
        }
#endif

        /* tininess for underflow is detected before rounding */
        set_float_detect_tininess(float_tininess_before_rounding,
                                  &env->fpu_status);
       /* fall through */
    case S390_CPU_RESET_NORMAL:
        env->psw.mask &= ~PSW_MASK_RI;
        memset(&env->start_normal_reset_fields, 0,
               offsetof(CPUS390XState, end_reset_fields) -
               offsetof(CPUS390XState, start_normal_reset_fields));

        env->pfault_token = -1UL;
        env->bpbc = false;
        break;
    default:
        g_assert_not_reached();
    }

    /* Reset state inside the kernel that we cannot access yet from QEMU. */
    if (kvm_enabled()) {
        switch (type) {
        case S390_CPU_RESET_CLEAR:
            kvm_s390_reset_vcpu_clear(cpu);
            break;
        case S390_CPU_RESET_INITIAL:
            kvm_s390_reset_vcpu_initial(cpu);
            break;
        case S390_CPU_RESET_NORMAL:
            kvm_s390_reset_vcpu_normal(cpu);
            break;
        }
    }
}

#if !defined(CONFIG_USER_ONLY)
static void s390_cpu_machine_reset_cb(void *opaque)
{
    S390CPU *cpu = opaque;

    run_on_cpu(CPU(cpu), s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
}
#endif

static void s390_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
{
    info->mach = bfd_mach_s390_64;
    info->print_insn = print_insn_s390;
}

static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
{
    CPUState *cs = CPU(dev);
    S390CPUClass *scc = S390_CPU_GET_CLASS(dev);
#if !defined(CONFIG_USER_ONLY)
    S390CPU *cpu = S390_CPU(dev);
#endif
    Error *err = NULL;

    /* the model has to be realized before qemu_init_vcpu() due to kvm */
    s390_realize_cpu_model(cs, &err);
    if (err) {
        goto out;
    }

#if !defined(CONFIG_USER_ONLY)
    MachineState *ms = MACHINE(qdev_get_machine());
    unsigned int max_cpus = ms->smp.max_cpus;
    if (cpu->env.core_id >= max_cpus) {
        error_setg(&err, "Unable to add CPU with core-id: %" PRIu32
                   ", maximum core-id: %d", cpu->env.core_id,
                   max_cpus - 1);
        goto out;
    }

    if (cpu_exists(cpu->env.core_id)) {
        error_setg(&err, "Unable to add CPU with core-id: %" PRIu32
                   ", it already exists", cpu->env.core_id);
        goto out;
    }

    /* sync cs->cpu_index and env->core_id. The latter is needed for TCG. */
    cs->cpu_index = cpu->env.core_id;
#endif

    cpu_exec_realizefn(cs, &err);
    if (err != NULL) {
        goto out;
    }

#if !defined(CONFIG_USER_ONLY)
    qemu_register_reset(s390_cpu_machine_reset_cb, cpu);
#endif
    s390_cpu_gdb_init(cs);
    qemu_init_vcpu(cs);

    /*
     * KVM requires the initial CPU reset ioctl to be executed on the target
     * CPU thread. CPU hotplug under single-threaded TCG will not work with
     * run_on_cpu(), as run_on_cpu() will not work properly if called while
     * the main thread is already running but the CPU hasn't been realized.
     */
    if (kvm_enabled()) {
        run_on_cpu(cs, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
    } else {
        cpu_reset(cs);
    }

    scc->parent_realize(dev, &err);
out:
    error_propagate(errp, err);
}

#if !defined(CONFIG_USER_ONLY)
static GuestPanicInformation *s390_cpu_get_crash_info(CPUState *cs)
{
    GuestPanicInformation *panic_info;
    S390CPU *cpu = S390_CPU(cs);

    cpu_synchronize_state(cs);
    panic_info = g_malloc0(sizeof(GuestPanicInformation));

    panic_info->type = GUEST_PANIC_INFORMATION_TYPE_S390;
    panic_info->u.s390.core = cpu->env.core_id;
    panic_info->u.s390.psw_mask = cpu->env.psw.mask;
    panic_info->u.s390.psw_addr = cpu->env.psw.addr;
    panic_info->u.s390.reason = cpu->env.crash_reason;

    return panic_info;
}

static void s390_cpu_get_crash_info_qom(Object *obj, Visitor *v,
                                        const char *name, void *opaque,
                                        Error **errp)
{
    CPUState *cs = CPU(obj);
    GuestPanicInformation *panic_info;

    if (!cs->crash_occurred) {
        error_setg(errp, "No crash occurred");
        return;
    }

    panic_info = s390_cpu_get_crash_info(cs);

    visit_type_GuestPanicInformation(v, "crash-information", &panic_info,
                                     errp);
    qapi_free_GuestPanicInformation(panic_info);
}
#endif

static void s390_cpu_initfn(Object *obj)
{
    CPUState *cs = CPU(obj);
    S390CPU *cpu = S390_CPU(obj);

    cpu_set_cpustate_pointers(cpu);
    cs->exception_index = EXCP_HLT;
#if !defined(CONFIG_USER_ONLY)
    cs->start_powered_off = true;
    object_property_add(obj, "crash-information", "GuestPanicInformation",
                        s390_cpu_get_crash_info_qom, NULL, NULL, NULL);
    cpu->env.tod_timer =
        timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);
    cpu->env.cpu_timer =
        timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu);
    s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
#endif
    s390_cpu_model_register_props(obj);
}

static void s390_cpu_finalize(Object *obj)
{
#if !defined(CONFIG_USER_ONLY)
    S390CPU *cpu = S390_CPU(obj);

    qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu);
    g_free(cpu->irqstate);
#endif
}

#if !defined(CONFIG_USER_ONLY)
static bool disabled_wait(CPUState *cpu)
{
    return cpu->halted && !(S390_CPU(cpu)->env.psw.mask &
                            (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK));
}

static unsigned s390_count_running_cpus(void)
{
    CPUState *cpu;
    int nr_running = 0;

    CPU_FOREACH(cpu) {
        uint8_t state = S390_CPU(cpu)->env.cpu_state;
        if (state == S390_CPU_STATE_OPERATING ||
            state == S390_CPU_STATE_LOAD) {
            if (!disabled_wait(cpu)) {
                nr_running++;
            }
        }
    }

    return nr_running;
}

unsigned int s390_cpu_halt(S390CPU *cpu)
{
    CPUState *cs = CPU(cpu);
    trace_cpu_halt(cs->cpu_index);

    if (!cs->halted) {
        cs->halted = 1;
        cs->exception_index = EXCP_HLT;
    }

    return s390_count_running_cpus();
}

void s390_cpu_unhalt(S390CPU *cpu)
{
    CPUState *cs = CPU(cpu);
    trace_cpu_unhalt(cs->cpu_index);

    if (cs->halted) {
        cs->halted = 0;
        cs->exception_index = -1;
    }
}

unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
 {
    trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state);

    switch (cpu_state) {
    case S390_CPU_STATE_STOPPED:
    case S390_CPU_STATE_CHECK_STOP:
        /* halt the cpu for common infrastructure */
        s390_cpu_halt(cpu);
        break;
    case S390_CPU_STATE_OPERATING:
    case S390_CPU_STATE_LOAD:
        /*
         * Starting a CPU with a PSW WAIT bit set:
         * KVM: handles this internally and triggers another WAIT exit.
         * TCG: will actually try to continue to run. Don't unhalt, will
         *      be done when the CPU actually has work (an interrupt).
         */
        if (!tcg_enabled() || !(cpu->env.psw.mask & PSW_MASK_WAIT)) {
            s390_cpu_unhalt(cpu);
        }
        break;
    default:
        error_report("Requested CPU state is not a valid S390 CPU state: %u",
                     cpu_state);
        exit(1);
    }
    if (kvm_enabled() && cpu->env.cpu_state != cpu_state) {
        kvm_s390_set_cpu_state(cpu, cpu_state);
    }
    cpu->env.cpu_state = cpu_state;

    return s390_count_running_cpus();
}

int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit)
{
    if (kvm_enabled()) {
        return kvm_s390_set_mem_limit(new_limit, hw_limit);
    }
    return 0;
}

void s390_set_max_pagesize(uint64_t pagesize, Error **errp)
{
    if (kvm_enabled()) {
        kvm_s390_set_max_pagesize(pagesize, errp);
    }
}

void s390_cmma_reset(void)
{
    if (kvm_enabled()) {
        kvm_s390_cmma_reset();
    }
}

int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
                                int vq, bool assign)
{
    if (kvm_enabled()) {
        return kvm_s390_assign_subch_ioeventfd(notifier, sch_id, vq, assign);
    } else {
        return 0;
    }
}

void s390_crypto_reset(void)
{
    if (kvm_enabled()) {
        kvm_s390_crypto_reset();
    }
}

void s390_enable_css_support(S390CPU *cpu)
{
    if (kvm_enabled()) {
        kvm_s390_enable_css_support(cpu);
    }
}
#endif

static gchar *s390_gdb_arch_name(CPUState *cs)
{
    return g_strdup("s390:64-bit");
}

static Property s390x_cpu_properties[] = {
#if !defined(CONFIG_USER_ONLY)
    DEFINE_PROP_UINT32("core-id", S390CPU, env.core_id, 0),
#endif
    DEFINE_PROP_END_OF_LIST()
};

static void s390_cpu_reset_full(DeviceState *dev)
{
    CPUState *s = CPU(dev);
    return s390_cpu_reset(s, S390_CPU_RESET_CLEAR);
}

static void s390_cpu_class_init(ObjectClass *oc, void *data)
{
    S390CPUClass *scc = S390_CPU_CLASS(oc);
    CPUClass *cc = CPU_CLASS(scc);
    DeviceClass *dc = DEVICE_CLASS(oc);

    device_class_set_parent_realize(dc, s390_cpu_realizefn,
                                    &scc->parent_realize);
    device_class_set_props(dc, s390x_cpu_properties);
    dc->user_creatable = true;

    device_class_set_parent_reset(dc, s390_cpu_reset_full, &scc->parent_reset);
#if !defined(CONFIG_USER_ONLY)
    scc->load_normal = s390_cpu_load_normal;
#endif
    scc->reset = s390_cpu_reset;
    cc->class_by_name = s390_cpu_class_by_name,
    cc->has_work = s390_cpu_has_work;
#ifdef CONFIG_TCG
    cc->do_interrupt = s390_cpu_do_interrupt;
#endif
    cc->dump_state = s390_cpu_dump_state;
    cc->set_pc = s390_cpu_set_pc;
    cc->gdb_read_register = s390_cpu_gdb_read_register;
    cc->gdb_write_register = s390_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
    cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
    cc->vmsd = &vmstate_s390_cpu;
    cc->get_crash_info = s390_cpu_get_crash_info;
    cc->write_elf64_note = s390_cpu_write_elf64_note;
#ifdef CONFIG_TCG
    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
    cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
    cc->do_unaligned_access = s390x_cpu_do_unaligned_access;
#endif
#endif
    cc->disas_set_info = s390_cpu_disas_set_info;
#ifdef CONFIG_TCG
    cc->tcg_initialize = s390x_translate_init;
    cc->tlb_fill = s390_cpu_tlb_fill;
#endif

    cc->gdb_num_core_regs = S390_NUM_CORE_REGS;
    cc->gdb_core_xml_file = "s390x-core64.xml";
    cc->gdb_arch_name = s390_gdb_arch_name;

    s390_cpu_model_class_register_props(oc);
}

static const TypeInfo s390_cpu_type_info = {
    .name = TYPE_S390_CPU,
    .parent = TYPE_CPU,
    .instance_size = sizeof(S390CPU),
    .instance_init = s390_cpu_initfn,
    .instance_finalize = s390_cpu_finalize,
    .abstract = true,
    .class_size = sizeof(S390CPUClass),
    .class_init = s390_cpu_class_init,
};

static void s390_cpu_register_types(void)
{
    type_register_static(&s390_cpu_type_info);
}

type_init(s390_cpu_register_types)
