/*
 *  IOAPIC emulation logic - common bits of emulated and KVM kernel model
 *
 *  Copyright (c) 2004-2005 Fabrice Bellard
 *  Copyright (c) 2009      Xiantao Zhang, Intel
 *  Copyright (c) 2011      Jan Kiszka, Siemens AG
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "migration/vmstate.h"
#include "monitor/monitor.h"
#include "hw/i386/ioapic.h"
#include "hw/i386/ioapic_internal.h"
#include "hw/intc/intc.h"
#include "hw/sysbus.h"

/* ioapic_no count start from 0 to MAX_IOAPICS,
 * remove as static variable from ioapic_common_init.
 * now as a global variable, let child to increase the counter
 * then we can drop the 'instance_no' argument
 * and convert to our QOM's realize function
 */
int ioapic_no;

void ioapic_stat_update_irq(IOAPICCommonState *s, int irq, int level)
{
    if (level != s->irq_level[irq]) {
        s->irq_level[irq] = level;
        if (level == 1) {
            s->irq_count[irq]++;
        }
    }
}

static bool ioapic_get_statistics(InterruptStatsProvider *obj,
                                  uint64_t **irq_counts,
                                  unsigned int *nb_irqs)
{
    IOAPICCommonState *s = IOAPIC_COMMON(obj);

    *irq_counts = s->irq_count;
    *nb_irqs = IOAPIC_NUM_PINS;

    return true;
}

static void ioapic_irr_dump(Monitor *mon, const char *name, uint32_t bitmap)
{
    int i;

    monitor_printf(mon, "%-10s ", name);
    if (bitmap == 0) {
        monitor_printf(mon, "(none)\n");
        return;
    }
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
        if (bitmap & (1 << i)) {
            monitor_printf(mon, "%-2u ", i);
        }
    }
    monitor_printf(mon, "\n");
}

static void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s)
{
    static const char *delm_str[] = {
        "fixed", "lowest", "SMI", "...", "NMI", "INIT", "...", "extINT"};
    uint32_t remote_irr = 0;
    int i;

    monitor_printf(mon, "ioapic0: ver=0x%x id=0x%02x sel=0x%02x",
                   s->version, s->id, s->ioregsel);
    if (s->ioregsel) {
        monitor_printf(mon, " (redir[%u])\n",
                       (s->ioregsel - IOAPIC_REG_REDTBL_BASE) >> 1);
    } else {
        monitor_printf(mon, "\n");
    }
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
        uint64_t entry = s->ioredtbl[i];
        uint32_t delm = (uint32_t)((entry & IOAPIC_LVT_DELIV_MODE) >>
                                   IOAPIC_LVT_DELIV_MODE_SHIFT);
        monitor_printf(mon, "  pin %-2u 0x%016"PRIx64" dest=%"PRIx64
                       " vec=%-3"PRIu64" %s %-5s %-6s %-6s %s\n",
                       i, entry,
                       (entry >> IOAPIC_LVT_DEST_SHIFT) &
                            (entry & IOAPIC_LVT_DEST_MODE ? 0xff : 0xf),
                       entry & IOAPIC_VECTOR_MASK,
                       entry & IOAPIC_LVT_POLARITY ? "active-lo" : "active-hi",
                       entry & IOAPIC_LVT_TRIGGER_MODE ? "level" : "edge",
                       entry & IOAPIC_LVT_MASKED ? "masked" : "",
                       delm_str[delm],
                       entry & IOAPIC_LVT_DEST_MODE ? "logical" : "physical");

        remote_irr |= entry & IOAPIC_LVT_TRIGGER_MODE ?
                        (entry & IOAPIC_LVT_REMOTE_IRR ? (1 << i) : 0) : 0;
    }
    ioapic_irr_dump(mon, "  IRR", s->irr);
    ioapic_irr_dump(mon, "  Remote IRR", remote_irr);
}

void ioapic_reset_common(DeviceState *dev)
{
    IOAPICCommonState *s = IOAPIC_COMMON(dev);
    int i;

    s->id = 0;
    s->ioregsel = 0;
    s->irr = 0;
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
        s->ioredtbl[i] = 1 << IOAPIC_LVT_MASKED_SHIFT;
    }
}

static int ioapic_dispatch_pre_save(void *opaque)
{
    IOAPICCommonState *s = IOAPIC_COMMON(opaque);
    IOAPICCommonClass *info = IOAPIC_COMMON_GET_CLASS(s);

    if (info->pre_save) {
        info->pre_save(s);
    }

    return 0;
}

static int ioapic_dispatch_post_load(void *opaque, int version_id)
{
    IOAPICCommonState *s = IOAPIC_COMMON(opaque);
    IOAPICCommonClass *info = IOAPIC_COMMON_GET_CLASS(s);

    if (info->post_load) {
        info->post_load(s);
    }
    return 0;
}

static void ioapic_common_realize(DeviceState *dev, Error **errp)
{
    IOAPICCommonState *s = IOAPIC_COMMON(dev);
    IOAPICCommonClass *info;

    if (ioapic_no >= MAX_IOAPICS) {
        error_setg(errp, "Only %d ioapics allowed", MAX_IOAPICS);
        return;
    }

    info = IOAPIC_COMMON_GET_CLASS(s);
    info->realize(dev, errp);

    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io_memory);
    ioapic_no++;
}

static void ioapic_print_info(InterruptStatsProvider *obj,
                              Monitor *mon)
{
    IOAPICCommonState *s = IOAPIC_COMMON(obj);

    ioapic_dispatch_pre_save(s);
    ioapic_print_redtbl(mon, s);
}

static const VMStateDescription vmstate_ioapic_common = {
    .name = "ioapic",
    .version_id = 3,
    .minimum_version_id = 1,
    .pre_save = ioapic_dispatch_pre_save,
    .post_load = ioapic_dispatch_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(id, IOAPICCommonState),
        VMSTATE_UINT8(ioregsel, IOAPICCommonState),
        VMSTATE_UNUSED_V(2, 8), /* to account for qemu-kvm's v2 format */
        VMSTATE_UINT32_V(irr, IOAPICCommonState, 2),
        VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICCommonState, IOAPIC_NUM_PINS),
        VMSTATE_END_OF_LIST()
    }
};

static void ioapic_common_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);

    dc->realize = ioapic_common_realize;
    dc->vmsd = &vmstate_ioapic_common;
    ic->print_info = ioapic_print_info;
    ic->get_statistics = ioapic_get_statistics;
}

static const TypeInfo ioapic_common_type = {
    .name = TYPE_IOAPIC_COMMON,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IOAPICCommonState),
    .class_size = sizeof(IOAPICCommonClass),
    .class_init = ioapic_common_class_init,
    .abstract = true,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_INTERRUPT_STATS_PROVIDER },
        { }
    },
};

static void ioapic_common_register_types(void)
{
    type_register_static(&ioapic_common_type);
}

type_init(ioapic_common_register_types)
