/*
 * Copyright (c) 2019, Nutanix Inc. All rights reserved.
 *     Author: Thanos Makatos <thanos@nutanix.com>
 *             Swapnil Ingle <swapnil.ingle@nutanix.com>
 *             Felipe Franciosi <felipe@nutanix.com>
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *      * Neither the name of Nutanix nor the names of its contributors may be
 *        used to endorse or promote products derived from this software without
 *        specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 *  DAMAGE.
 *
 */

/*
 * gpio-pci-idio-16: a simple example server identifying as a GPIO PCI device.
 */

#include <stdio.h>
#include <err.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <assert.h>

#include "common.h"
#include "libvfio-user.h"

static void
_log(vfu_ctx_t *vfu_ctx UNUSED, UNUSED int level, char const *msg)
{
    fprintf(stderr, "gpio: %s\n", msg);
}

static int pin;
bool dirty = true;

static ssize_t
bar2_access(vfu_ctx_t *vfu_ctx UNUSED, char * const buf,
            size_t count, loff_t offset, const bool is_write)
{
    if (offset == 0 && !is_write)
        buf[0] = pin++ / 3;

    dirty = true;

    return count;
}

static void _sa_handler(UNUSED int signum)
{
}

static int
migration_device_state_transition(vfu_ctx_t *vfu_ctx, vfu_migr_state_t state)
{
    vfu_log(vfu_ctx, LOG_DEBUG, "migration: transition to state %d", state);
    return 0;
}

static uint64_t
migration_get_pending_bytes(UNUSED vfu_ctx_t *vfu_ctx)
{
    if (dirty) {
        return sizeof(pin);
    }
    return 0;
}

static int
migration_prepare_data(UNUSED vfu_ctx_t *vfu_ctx,
                       uint64_t *offset, uint64_t *size)
{
    *offset = 0;
    if (size != NULL) { /* null means resuming */
        *size = sizeof(pin);
    }
    return 0;
}

static ssize_t
migration_read_data(UNUSED vfu_ctx_t *vfu_ctx, void *buf,
                    uint64_t size, uint64_t offset)
{
    assert(offset == 0);
    assert(size == sizeof(pin));
    memcpy(buf, &pin, sizeof(pin));
    dirty = false;
    return 0;
}

static int
migration_data_written(UNUSED vfu_ctx_t *vfu_ctx, uint64_t count)
{
    assert(count == sizeof(pin));
    return 0;
}

static ssize_t
migration_write_data(UNUSED vfu_ctx_t *vfu_ctx, void *buf,
                     uint64_t size, uint64_t offset)
{
    assert(offset == 0);
    assert(size == sizeof(pin));
    memcpy(&pin, buf, sizeof(pin));
    return 0;
}

static void
dma_register(UNUSED vfu_ctx_t *vfu_ctx, UNUSED vfu_dma_info_t *info)
{
}

static void
dma_unregister(UNUSED vfu_ctx_t *vfu_ctx, UNUSED vfu_dma_info_t *info)
{
}

int
main(int argc, char *argv[])
{
    int ret;
    bool verbose = false;
    bool restart = true;
    bool enable_migr = true;
    int opt;
    struct sigaction act = { .sa_handler = _sa_handler };
    vfu_ctx_t *vfu_ctx;
    size_t migr_regs_size = vfu_get_migr_register_area_size();
    size_t migr_data_size = sysconf(_SC_PAGE_SIZE);
    size_t migr_size = migr_regs_size + migr_data_size;
    const vfu_migration_callbacks_t migr_callbacks = {
        .version = VFU_MIGR_CALLBACKS_VERS,
        .transition = &migration_device_state_transition,
        .get_pending_bytes = &migration_get_pending_bytes,
        .prepare_data = &migration_prepare_data,
        .read_data = &migration_read_data,
        .data_written = &migration_data_written,
        .write_data = &migration_write_data
    };

    while ((opt = getopt(argc, argv, "MRv")) != -1) {
        switch (opt) {
            case 'R':
                restart = false;
                break;
            case 'v':
                verbose = true;
                break;
            case 'M':
                enable_migr = false;
                break;
            default: /* '?' */
                fprintf(stderr, "Usage: %s [-Rv] <socketpath>\n", argv[0]);
                exit(EXIT_FAILURE);
        }
    }

    if (optind >= argc) {
        errx(EXIT_FAILURE, "missing vfio-user socket path");
    }

    sigemptyset(&act.sa_mask);
    if (sigaction(SIGINT, &act, NULL) == -1) {
        err(EXIT_FAILURE, "failed to register signal handler");
    }

    vfu_ctx = vfu_create_ctx(VFU_TRANS_SOCK, argv[optind], 0, NULL,
                             VFU_DEV_TYPE_PCI);
    if (vfu_ctx == NULL) {
        if (errno == EINTR) {
            printf("interrupted\n");
            exit(EXIT_SUCCESS);
        }
        err(EXIT_FAILURE, "failed to initialize device emulation");
    }

    ret = vfu_setup_log(vfu_ctx, _log, verbose ? LOG_DEBUG : LOG_ERR);
    if (ret < 0) {
        err(EXIT_FAILURE, "failed to setup log");
    }

    ret = vfu_pci_init(vfu_ctx, VFU_PCI_TYPE_CONVENTIONAL,
                       PCI_HEADER_TYPE_NORMAL, 0);
    if (ret < 0) {
        err(EXIT_FAILURE, "vfu_pci_init() failed");
    }

    vfu_pci_set_id(vfu_ctx, 0x494f, 0x0dc8, 0x0, 0x0);

    ret = vfu_setup_region(vfu_ctx, VFU_PCI_DEV_BAR2_REGION_IDX, 0x100,
                           &bar2_access, VFU_REGION_FLAG_RW, NULL, 0, -1, 0);
    if (ret < 0) {
        err(EXIT_FAILURE, "failed to setup region");
    }

    if (enable_migr) {
        ret = vfu_setup_region(vfu_ctx, VFU_PCI_DEV_MIGR_REGION_IDX, migr_size,
                               NULL, VFU_REGION_FLAG_RW, NULL, 0, -1, 0);
        if (ret < 0) {
            err(EXIT_FAILURE, "failed to setup migration region");
        }
        ret = vfu_setup_device_migration_callbacks(vfu_ctx, &migr_callbacks,
                                                   migr_regs_size);
        if (ret < 0) {
            err(EXIT_FAILURE, "failed to setup device migration");
        }
    }

    ret = vfu_setup_device_nr_irqs(vfu_ctx, VFU_DEV_INTX_IRQ, 1);
    if (ret < 0) {
        err(EXIT_FAILURE, "failed to setup irq counts");
    }

    ret = vfu_setup_device_dma(vfu_ctx, dma_register, dma_unregister);
    if (ret < 0) {
        err(EXIT_FAILURE, "failed to setup DMA");
    }

    ret = vfu_realize_ctx(vfu_ctx);
    if (ret < 0) {
        err(EXIT_FAILURE, "failed to realize device");
    }

    ret = vfu_attach_ctx(vfu_ctx);
    if (ret < 0) {
        int _errno = errno;
        vfu_destroy_ctx(vfu_ctx);
        errno = _errno;
        err(EXIT_FAILURE, "failed to attach device");
    }

    do {
        ret = vfu_run_ctx(vfu_ctx);
        if (ret != 0) {
            if (errno == ENOTCONN) {
                ret = vfu_attach_ctx(vfu_ctx);
                if (ret < 0) {
                    err(EXIT_FAILURE, "failed to re-attach device");
                 }
            } else if (errno != EINTR) {
                err(EXIT_FAILURE, "vfu_run_ctx() failed");
            }
        }
    } while (restart);

    vfu_destroy_ctx(vfu_ctx);
    return EXIT_SUCCESS;
}

/* ex: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */
