/*
 * Remote IO Hub
 *
 * Copyright © 2018, 2021 Oracle and/or its affiliates.
 *
 * 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 "qemu-common.h"

#include "hw/pci/pci.h"
#include "hw/pci/pci_ids.h"
#include "hw/pci/pci_bus.h"
#include "qemu/thread.h"
#include "hw/remote/machine.h"
#include "hw/remote/iohub.h"
#include "qemu/main-loop.h"

void remote_iohub_init(RemoteIOHubState *iohub)
{
    int pirq;

    memset(&iohub->irqfds, 0, sizeof(iohub->irqfds));
    memset(&iohub->resamplefds, 0, sizeof(iohub->resamplefds));

    for (pirq = 0; pirq < REMOTE_IOHUB_NB_PIRQS; pirq++) {
        qemu_mutex_init(&iohub->irq_level_lock[pirq]);
        iohub->irq_level[pirq] = 0;
        event_notifier_init_fd(&iohub->irqfds[pirq], -1);
        event_notifier_init_fd(&iohub->resamplefds[pirq], -1);
    }
}

void remote_iohub_finalize(RemoteIOHubState *iohub)
{
    int pirq;

    for (pirq = 0; pirq < REMOTE_IOHUB_NB_PIRQS; pirq++) {
        qemu_set_fd_handler(event_notifier_get_fd(&iohub->resamplefds[pirq]),
                            NULL, NULL, NULL);
        event_notifier_cleanup(&iohub->irqfds[pirq]);
        event_notifier_cleanup(&iohub->resamplefds[pirq]);
        qemu_mutex_destroy(&iohub->irq_level_lock[pirq]);
    }
}

int remote_iohub_map_irq(PCIDevice *pci_dev, int intx)
{
    return pci_dev->devfn;
}

void remote_iohub_set_irq(void *opaque, int pirq, int level)
{
    RemoteIOHubState *iohub = opaque;

    assert(pirq >= 0);
    assert(pirq < PCI_DEVFN_MAX);

    QEMU_LOCK_GUARD(&iohub->irq_level_lock[pirq]);

    if (level) {
        if (++iohub->irq_level[pirq] == 1) {
            event_notifier_set(&iohub->irqfds[pirq]);
        }
    } else if (iohub->irq_level[pirq] > 0) {
        iohub->irq_level[pirq]--;
    }
}

static void intr_resample_handler(void *opaque)
{
    ResampleToken *token = opaque;
    RemoteIOHubState *iohub = token->iohub;
    int pirq, s;

    pirq = token->pirq;

    s = event_notifier_test_and_clear(&iohub->resamplefds[pirq]);

    assert(s >= 0);

    QEMU_LOCK_GUARD(&iohub->irq_level_lock[pirq]);

    if (iohub->irq_level[pirq]) {
        event_notifier_set(&iohub->irqfds[pirq]);
    }
}

void process_set_irqfd_msg(PCIDevice *pci_dev, MPQemuMsg *msg)
{
    RemoteMachineState *machine = REMOTE_MACHINE(current_machine);
    RemoteIOHubState *iohub = &machine->iohub;
    int pirq, intx;

    intx = pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;

    pirq = remote_iohub_map_irq(pci_dev, intx);

    if (event_notifier_get_fd(&iohub->irqfds[pirq]) != -1) {
        qemu_set_fd_handler(event_notifier_get_fd(&iohub->resamplefds[pirq]),
                            NULL, NULL, NULL);
        event_notifier_cleanup(&iohub->irqfds[pirq]);
        event_notifier_cleanup(&iohub->resamplefds[pirq]);
        memset(&iohub->token[pirq], 0, sizeof(ResampleToken));
    }

    event_notifier_init_fd(&iohub->irqfds[pirq], msg->fds[0]);
    event_notifier_init_fd(&iohub->resamplefds[pirq], msg->fds[1]);

    iohub->token[pirq].iohub = iohub;
    iohub->token[pirq].pirq = pirq;

    qemu_set_fd_handler(msg->fds[1], intr_resample_handler, NULL,
                        &iohub->token[pirq]);
}
