/*
 *  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 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 "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");
}

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)
