/*
 * 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)
{
    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);
        memory_region_destroy(&mrpio->mr);
        g_free(mrpio);
        piolist->regions[i] = NULL;
    }
}
