/*
 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
 *
 * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
 *
 * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#include "qemu/osdep.h"
#include "trace.h"
#include "qemu/timer.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "hw/ppc/xics.h"
#include "hw/ppc/xics_spapr.h"
#include "hw/ppc/fdt.h"
#include "qapi/visitor.h"
#include "qapi/type-helpers.h"
#include "monitor/monitor.h"

/*
 * Guest interfaces
 */

static bool check_emulated_xics(SpaprMachineState *spapr, const char *func)
{
    if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ||
        kvm_irqchip_in_kernel()) {
        error_report("pseries: %s must only be called for emulated XICS",
                     func);
        return false;
    }

    return true;
}

#define CHECK_EMULATED_XICS_HCALL(spapr)               \
    do {                                               \
        if (!check_emulated_xics((spapr), __func__)) { \
            return H_HARDWARE;                         \
        }                                              \
    } while (0)

static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
                           target_ulong opcode, target_ulong *args)
{
    target_ulong cppr = args[0];

    CHECK_EMULATED_XICS_HCALL(spapr);

    icp_set_cppr(spapr_cpu_state(cpu)->icp, cppr);
    return H_SUCCESS;
}

static target_ulong h_ipi(PowerPCCPU *cpu, SpaprMachineState *spapr,
                          target_ulong opcode, target_ulong *args)
{
    target_ulong mfrr = args[1];
    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);

    CHECK_EMULATED_XICS_HCALL(spapr);

    if (!icp) {
        return H_PARAMETER;
    }

    icp_set_mfrr(icp, mfrr);
    return H_SUCCESS;
}

static target_ulong h_xirr(PowerPCCPU *cpu, SpaprMachineState *spapr,
                           target_ulong opcode, target_ulong *args)
{
    uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);

    CHECK_EMULATED_XICS_HCALL(spapr);

    args[0] = xirr;
    return H_SUCCESS;
}

static target_ulong h_xirr_x(PowerPCCPU *cpu, SpaprMachineState *spapr,
                             target_ulong opcode, target_ulong *args)
{
    uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);

    CHECK_EMULATED_XICS_HCALL(spapr);

    args[0] = xirr;
    args[1] = cpu_get_host_ticks();
    return H_SUCCESS;
}

static target_ulong h_eoi(PowerPCCPU *cpu, SpaprMachineState *spapr,
                          target_ulong opcode, target_ulong *args)
{
    target_ulong xirr = args[0];

    CHECK_EMULATED_XICS_HCALL(spapr);

    icp_eoi(spapr_cpu_state(cpu)->icp, xirr);
    return H_SUCCESS;
}

static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
{
    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);
    uint32_t mfrr;
    uint32_t xirr;

    CHECK_EMULATED_XICS_HCALL(spapr);

    if (!icp) {
        return H_PARAMETER;
    }

    xirr = icp_ipoll(icp, &mfrr);

    args[0] = xirr;
    args[1] = mfrr;

    return H_SUCCESS;
}

#define CHECK_EMULATED_XICS_RTAS(spapr, rets)          \
    do {                                               \
        if (!check_emulated_xics((spapr), __func__)) { \
            rtas_st((rets), 0, RTAS_OUT_HW_ERROR);     \
            return;                                    \
        }                                              \
    } while (0)

static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
                          uint32_t token,
                          uint32_t nargs, target_ulong args,
                          uint32_t nret, target_ulong rets)
{
    ICSState *ics = spapr->ics;
    uint32_t nr, srcno, server, priority;

    CHECK_EMULATED_XICS_RTAS(spapr, rets);

    if ((nargs != 3) || (nret != 1)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }
    if (!ics) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    nr = rtas_ld(args, 0);
    server = rtas_ld(args, 1);
    priority = rtas_ld(args, 2);

    if (!ics_valid_irq(ics, nr) || !xics_icp_get(XICS_FABRIC(spapr), server)
        || (priority > 0xff)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    srcno = nr - ics->offset;
    ics_write_xive(ics, srcno, server, priority, priority);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}

static void rtas_get_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
                          uint32_t token,
                          uint32_t nargs, target_ulong args,
                          uint32_t nret, target_ulong rets)
{
    ICSState *ics = spapr->ics;
    uint32_t nr, srcno;

    CHECK_EMULATED_XICS_RTAS(spapr, rets);

    if ((nargs != 1) || (nret != 3)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }
    if (!ics) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    nr = rtas_ld(args, 0);

    if (!ics_valid_irq(ics, nr)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    srcno = nr - ics->offset;
    rtas_st(rets, 1, ics->irqs[srcno].server);
    rtas_st(rets, 2, ics->irqs[srcno].priority);
}

static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
                         uint32_t token,
                         uint32_t nargs, target_ulong args,
                         uint32_t nret, target_ulong rets)
{
    ICSState *ics = spapr->ics;
    uint32_t nr, srcno;

    CHECK_EMULATED_XICS_RTAS(spapr, rets);

    if ((nargs != 1) || (nret != 1)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }
    if (!ics) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    nr = rtas_ld(args, 0);

    if (!ics_valid_irq(ics, nr)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    srcno = nr - ics->offset;
    ics_write_xive(ics, srcno, ics->irqs[srcno].server, 0xff,
                   ics->irqs[srcno].priority);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}

static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
                        uint32_t token,
                        uint32_t nargs, target_ulong args,
                        uint32_t nret, target_ulong rets)
{
    ICSState *ics = spapr->ics;
    uint32_t nr, srcno;

    CHECK_EMULATED_XICS_RTAS(spapr, rets);

    if ((nargs != 1) || (nret != 1)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }
    if (!ics) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        return;
    }

    nr = rtas_ld(args, 0);

    if (!ics_valid_irq(ics, nr)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    srcno = nr - ics->offset;
    ics_write_xive(ics, srcno, ics->irqs[srcno].server,
                   ics->irqs[srcno].saved_priority,
                   ics->irqs[srcno].saved_priority);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}

static void ics_spapr_realize(DeviceState *dev, Error **errp)
{
    ICSState *ics = ICS_SPAPR(dev);
    ICSStateClass *icsc = ICS_GET_CLASS(ics);
    Error *local_err = NULL;

    icsc->parent_realize(dev, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
    spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
    spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
    spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_int_on);

    spapr_register_hypercall(H_CPPR, h_cppr);
    spapr_register_hypercall(H_IPI, h_ipi);
    spapr_register_hypercall(H_XIRR, h_xirr);
    spapr_register_hypercall(H_XIRR_X, h_xirr_x);
    spapr_register_hypercall(H_EOI, h_eoi);
    spapr_register_hypercall(H_IPOLL, h_ipoll);
}

static void xics_spapr_dt(SpaprInterruptController *intc, uint32_t nr_servers,
                          void *fdt, uint32_t phandle)
{
    uint32_t interrupt_server_ranges_prop[] = {
        0, cpu_to_be32(nr_servers),
    };
    int node;

    _FDT(node = fdt_add_subnode(fdt, 0, "interrupt-controller"));

    _FDT(fdt_setprop_string(fdt, node, "device_type",
                            "PowerPC-External-Interrupt-Presentation"));
    _FDT(fdt_setprop_string(fdt, node, "compatible", "IBM,ppc-xicp"));
    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
    _FDT(fdt_setprop(fdt, node, "ibm,interrupt-server-ranges",
                     interrupt_server_ranges_prop,
                     sizeof(interrupt_server_ranges_prop)));
    _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
    _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
    _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
}

static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
                                       PowerPCCPU *cpu, Error **errp)
{
    ICSState *ics = ICS_SPAPR(intc);
    Object *obj;
    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);

    obj = icp_create(OBJECT(cpu), TYPE_ICP, ics->xics, errp);
    if (!obj) {
        return -1;
    }

    spapr_cpu->icp = ICP(obj);
    return 0;
}

static void xics_spapr_cpu_intc_reset(SpaprInterruptController *intc,
                                     PowerPCCPU *cpu)
{
    icp_reset(spapr_cpu_state(cpu)->icp);
}

static void xics_spapr_cpu_intc_destroy(SpaprInterruptController *intc,
                                        PowerPCCPU *cpu)
{
    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);

    icp_destroy(spapr_cpu->icp);
    spapr_cpu->icp = NULL;
}

static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
                                bool lsi, Error **errp)
{
    ICSState *ics = ICS_SPAPR(intc);

    assert(ics);
    assert(ics_valid_irq(ics, irq));

    if (!ics_irq_free(ics, irq - ics->offset)) {
        error_setg(errp, "IRQ %d is not free", irq);
        return -EBUSY;
    }

    ics_set_irq_type(ics, irq - ics->offset, lsi);
    return 0;
}

static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
{
    ICSState *ics = ICS_SPAPR(intc);
    uint32_t srcno = irq - ics->offset;

    assert(ics_valid_irq(ics, irq));

    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
}

static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
{
    ICSState *ics = ICS_SPAPR(intc);
    uint32_t srcno = irq - ics->offset;

    ics_set_irq(ics, srcno, val);
}

static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon)
{
    ICSState *ics = ICS_SPAPR(intc);
    CPUState *cs;
    g_autoptr(GString) buf = g_string_new("");
    g_autoptr(HumanReadableText) info = NULL;

    CPU_FOREACH(cs) {
        PowerPCCPU *cpu = POWERPC_CPU(cs);

        icp_pic_print_info(spapr_cpu_state(cpu)->icp, buf);
    }
    ics_pic_print_info(ics, buf);

    info = human_readable_text_from_str(buf);
    monitor_puts(mon, info->human_readable_text);
}

static int xics_spapr_post_load(SpaprInterruptController *intc, int version_id)
{
    if (!kvm_irqchip_in_kernel()) {
        CPUState *cs;
        CPU_FOREACH(cs) {
            PowerPCCPU *cpu = POWERPC_CPU(cs);
            icp_resend(spapr_cpu_state(cpu)->icp);
        }
    }
    return 0;
}

static int xics_spapr_activate(SpaprInterruptController *intc,
                               uint32_t nr_servers, Error **errp)
{
    if (kvm_enabled()) {
        return spapr_irq_init_kvm(xics_kvm_connect, intc, nr_servers, errp);
    }
    return 0;
}

static void xics_spapr_deactivate(SpaprInterruptController *intc)
{
    if (kvm_irqchip_in_kernel()) {
        xics_kvm_disconnect(intc);
    }
}

static void ics_spapr_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ICSStateClass *isc = ICS_CLASS(klass);
    SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);

    device_class_set_parent_realize(dc, ics_spapr_realize,
                                    &isc->parent_realize);
    sicc->activate = xics_spapr_activate;
    sicc->deactivate = xics_spapr_deactivate;
    sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
    sicc->cpu_intc_reset = xics_spapr_cpu_intc_reset;
    sicc->cpu_intc_destroy = xics_spapr_cpu_intc_destroy;
    sicc->claim_irq = xics_spapr_claim_irq;
    sicc->free_irq = xics_spapr_free_irq;
    sicc->set_irq = xics_spapr_set_irq;
    sicc->print_info = xics_spapr_print_info;
    sicc->dt = xics_spapr_dt;
    sicc->post_load = xics_spapr_post_load;
}

static const TypeInfo ics_spapr_info = {
    .name = TYPE_ICS_SPAPR,
    .parent = TYPE_ICS,
    .class_init = ics_spapr_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_SPAPR_INTC },
        { }
    },
};

static void xics_spapr_register_types(void)
{
    type_register_static(&ics_spapr_info);
}

type_init(xics_spapr_register_types)
