/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * 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.
 */
/*
 * splitted out ioport related stuffs from vl.c.
 */

#include "exec/ioport.h"
#include "trace.h"
#include "exec/memory.h"
#include "exec/address-spaces.h"

//#define DEBUG_IOPORT

#ifdef DEBUG_IOPORT
#  define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
#else
#  define LOG_IOPORT(...) do { } while (0)
#endif

typedef struct MemoryRegionPortioList {
    MemoryRegion mr;
    void *portio_opaque;
    MemoryRegionPortio ports[];
} MemoryRegionPortioList;

static uint64_t unassigned_io_read(void *opaque, hwaddr addr, unsigned size)
{
    return -1ULL;
}

static void unassigned_io_write(void *opaque, hwaddr addr, uint64_t val,
                                unsigned size)
{
}

const MemoryRegionOps unassigned_io_ops = {
    .read = unassigned_io_read,
    .write = unassigned_io_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

void cpu_outb(pio_addr_t addr, uint8_t val)
{
    LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
    trace_cpu_out(addr, val);
    address_space_write(&address_space_io, addr, &val, 1);
}

void cpu_outw(pio_addr_t addr, uint16_t val)
{
    uint8_t buf[2];

    LOG_IOPORT("outw: %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
    trace_cpu_out(addr, val);
    stw_p(buf, val);
    address_space_write(&address_space_io, addr, buf, 2);
}

void cpu_outl(pio_addr_t addr, uint32_t val)
{
    uint8_t buf[4];

    LOG_IOPORT("outl: %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
    trace_cpu_out(addr, val);
    stl_p(buf, val);
    address_space_write(&address_space_io, addr, buf, 4);
}

uint8_t cpu_inb(pio_addr_t addr)
{
    uint8_t val;

    address_space_read(&address_space_io, addr, &val, 1);
    trace_cpu_in(addr, val);
    LOG_IOPORT("inb : %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
    return val;
}

uint16_t cpu_inw(pio_addr_t addr)
{
    uint8_t buf[2];
    uint16_t val;

    address_space_read(&address_space_io, addr, buf, 2);
    val = lduw_p(buf);
    trace_cpu_in(addr, val);
    LOG_IOPORT("inw : %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
    return val;
}

uint32_t cpu_inl(pio_addr_t addr)
{
    uint8_t buf[4];
    uint32_t val;

    address_space_read(&address_space_io, addr, buf, 4);
    val = ldl_p(buf);
    trace_cpu_in(addr, val);
    LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
    return val;
}

void portio_list_init(PortioList *piolist,
                      Object *owner,
                      const MemoryRegionPortio *callbacks,
                      void *opaque, const char *name)
{
    unsigned n = 0;

    while (callbacks[n].size) {
        ++n;
    }

    piolist->ports = callbacks;
    piolist->nr = 0;
    piolist->regions = g_new0(MemoryRegion *, n);
    piolist->address_space = NULL;
    piolist->opaque = opaque;
    piolist->owner = owner;
    piolist->name = name;
    piolist->flush_coalesced_mmio = false;
}

void portio_list_set_flush_coalesced(PortioList *piolist)
{
    piolist->flush_coalesced_mmio = true;
}

void portio_list_destroy(PortioList *piolist)
{
    MemoryRegionPortioList *mrpio;
    unsigned i;

    for (i = 0; i < piolist->nr; ++i) {
        mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, mr);
        object_unparent(OBJECT(&mrpio->mr));
        g_free(mrpio);
    }
    g_free(piolist->regions);
}

static const MemoryRegionPortio *find_portio(MemoryRegionPortioList *mrpio,
                                             uint64_t offset, unsigned size,
                                             bool write)
{
    const MemoryRegionPortio *mrp;

    for (mrp = mrpio->ports; mrp->size; ++mrp) {
        if (offset >= mrp->offset && offset < mrp->offset + mrp->len &&
            size == mrp->size &&
            (write ? (bool)mrp->write : (bool)mrp->read)) {
            return mrp;
        }
    }
    return NULL;
}

static uint64_t portio_read(void *opaque, hwaddr addr, unsigned size)
{
    MemoryRegionPortioList *mrpio = opaque;
    const MemoryRegionPortio *mrp = find_portio(mrpio, addr, size, false);
    uint64_t data;

    data = ((uint64_t)1 << (size * 8)) - 1;
    if (mrp) {
        data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
    } else if (size == 2) {
        mrp = find_portio(mrpio, addr, 1, false);
        assert(mrp);
        data = mrp->read(mrpio->portio_opaque, mrp->base + addr) |
                (mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) << 8);
    }
    return data;
}

static void portio_write(void *opaque, hwaddr addr, uint64_t data,
                         unsigned size)
{
    MemoryRegionPortioList *mrpio = opaque;
    const MemoryRegionPortio *mrp = find_portio(mrpio, addr, size, true);

    if (mrp) {
        mrp->write(mrpio->portio_opaque, mrp->base + addr, data);
    } else if (size == 2) {
        mrp = find_portio(mrpio, addr, 1, true);
        assert(mrp);
        mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff);
        mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 8);
    }
}

static const MemoryRegionOps portio_ops = {
    .read = portio_read,
    .write = portio_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid.unaligned = true,
    .impl.unaligned = true,
};

static void portio_list_add_1(PortioList *piolist,
                              const MemoryRegionPortio *pio_init,
                              unsigned count, unsigned start,
                              unsigned off_low, unsigned off_high)
{
    MemoryRegionPortioList *mrpio;
    unsigned i;

    /* Copy the sub-list and null-terminate it.  */
    mrpio = g_malloc0(sizeof(MemoryRegionPortioList) +
                      sizeof(MemoryRegionPortio) * (count + 1));
    mrpio->portio_opaque = piolist->opaque;
    memcpy(mrpio->ports, pio_init, sizeof(MemoryRegionPortio) * count);
    memset(mrpio->ports + count, 0, sizeof(MemoryRegionPortio));

    /* Adjust the offsets to all be zero-based for the region.  */
    for (i = 0; i < count; ++i) {
        mrpio->ports[i].offset -= off_low;
        mrpio->ports[i].base = start + off_low;
    }

    /*
     * Use an alias so that the callback is called with an absolute address,
     * rather than an offset relative to to start + off_low.
     */
    memory_region_init_io(&mrpio->mr, piolist->owner, &portio_ops, mrpio,
                          piolist->name, off_high - off_low);
    if (piolist->flush_coalesced_mmio) {
        memory_region_set_flush_coalesced(&mrpio->mr);
    }
    memory_region_add_subregion(piolist->address_space,
                                start + off_low, &mrpio->mr);
    piolist->regions[piolist->nr] = &mrpio->mr;
    ++piolist->nr;
}

void portio_list_add(PortioList *piolist,
                     MemoryRegion *address_space,
                     uint32_t start)
{
    const MemoryRegionPortio *pio, *pio_start = piolist->ports;
    unsigned int off_low, off_high, off_last, count;

    piolist->address_space = address_space;

    /* Handle the first entry specially.  */
    off_last = off_low = pio_start->offset;
    off_high = off_low + pio_start->len;
    count = 1;

    for (pio = pio_start + 1; pio->size != 0; pio++, count++) {
        /* All entries must be sorted by offset.  */
        assert(pio->offset >= off_last);
        off_last = pio->offset;

        /* If we see a hole, break the region.  */
        if (off_last > off_high) {
            portio_list_add_1(piolist, pio_start, count, start, off_low,
                              off_high);
            /* ... and start collecting anew.  */
            pio_start = pio;
            off_low = off_last;
            off_high = off_low + pio->len;
            count = 0;
        } else if (off_last + pio->len > off_high) {
            off_high = off_last + pio->len;
        }
    }

    /* There will always be an open sub-list.  */
    portio_list_add_1(piolist, pio_start, count, start, off_low, off_high);
}

void portio_list_del(PortioList *piolist)
{
    MemoryRegionPortioList *mrpio;
    unsigned i;

    for (i = 0; i < piolist->nr; ++i) {
        mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, mr);
        memory_region_del_subregion(piolist->address_space, &mrpio->mr);
    }
}
