/*
 * QEMU PCI bochs display adapter.
 *
 * 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/module.h"
#include "qemu/units.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "hw/display/bochs-vbe.h"
#include "hw/display/edid.h"

#include "qapi/error.h"

#include "ui/console.h"
#include "ui/qemu-pixman.h"

typedef struct BochsDisplayMode {
    pixman_format_code_t format;
    uint32_t             bytepp;
    uint32_t             width;
    uint32_t             height;
    uint32_t             stride;
    uint64_t             offset;
    uint64_t             size;
} BochsDisplayMode;

typedef struct BochsDisplayState {
    /* parent */
    PCIDevice        pci;

    /* device elements */
    QemuConsole      *con;
    MemoryRegion     vram;
    MemoryRegion     mmio;
    MemoryRegion     vbe;
    MemoryRegion     qext;
    MemoryRegion     edid;

    /* device config */
    uint64_t         vgamem;
    bool             enable_edid;
    qemu_edid_info   edid_info;
    uint8_t          edid_blob[256];

    /* device registers */
    uint16_t         vbe_regs[VBE_DISPI_INDEX_NB];
    bool             big_endian_fb;

    /* device state */
    BochsDisplayMode mode;
} BochsDisplayState;

#define TYPE_BOCHS_DISPLAY "bochs-display"
#define BOCHS_DISPLAY(obj) OBJECT_CHECK(BochsDisplayState, (obj), \
                                        TYPE_BOCHS_DISPLAY)

static const VMStateDescription vmstate_bochs_display = {
    .name = "bochs-display",
    .fields = (VMStateField[]) {
        VMSTATE_PCI_DEVICE(pci, BochsDisplayState),
        VMSTATE_UINT16_ARRAY(vbe_regs, BochsDisplayState, VBE_DISPI_INDEX_NB),
        VMSTATE_BOOL(big_endian_fb, BochsDisplayState),
        VMSTATE_END_OF_LIST()
    }
};

static uint64_t bochs_display_vbe_read(void *ptr, hwaddr addr,
                                       unsigned size)
{
    BochsDisplayState *s = ptr;
    unsigned int index = addr >> 1;

    switch (index) {
    case VBE_DISPI_INDEX_ID:
        return VBE_DISPI_ID5;
    case VBE_DISPI_INDEX_VIDEO_MEMORY_64K:
        return s->vgamem / (64 * KiB);
    }

    if (index >= ARRAY_SIZE(s->vbe_regs)) {
        return -1;
    }
    return s->vbe_regs[index];
}

static void bochs_display_vbe_write(void *ptr, hwaddr addr,
                                    uint64_t val, unsigned size)
{
    BochsDisplayState *s = ptr;
    unsigned int index = addr >> 1;

    if (index >= ARRAY_SIZE(s->vbe_regs)) {
        return;
    }
    s->vbe_regs[index] = val;
}

static const MemoryRegionOps bochs_display_vbe_ops = {
    .read = bochs_display_vbe_read,
    .write = bochs_display_vbe_write,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .impl.min_access_size = 2,
    .impl.max_access_size = 2,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static uint64_t bochs_display_qext_read(void *ptr, hwaddr addr,
                                        unsigned size)
{
    BochsDisplayState *s = ptr;

    switch (addr) {
    case PCI_VGA_QEXT_REG_SIZE:
        return PCI_VGA_QEXT_SIZE;
    case PCI_VGA_QEXT_REG_BYTEORDER:
        return s->big_endian_fb ?
            PCI_VGA_QEXT_BIG_ENDIAN : PCI_VGA_QEXT_LITTLE_ENDIAN;
    default:
        return 0;
    }
}

static void bochs_display_qext_write(void *ptr, hwaddr addr,
                                     uint64_t val, unsigned size)
{
    BochsDisplayState *s = ptr;

    switch (addr) {
    case PCI_VGA_QEXT_REG_BYTEORDER:
        if (val == PCI_VGA_QEXT_BIG_ENDIAN) {
            s->big_endian_fb = true;
        }
        if (val == PCI_VGA_QEXT_LITTLE_ENDIAN) {
            s->big_endian_fb = false;
        }
        break;
    }
}

static const MemoryRegionOps bochs_display_qext_ops = {
    .read = bochs_display_qext_read,
    .write = bochs_display_qext_write,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static int bochs_display_get_mode(BochsDisplayState *s,
                                   BochsDisplayMode *mode)
{
    uint16_t *vbe = s->vbe_regs;
    uint32_t virt_width;

    if (!(vbe[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
        return -1;
    }

    memset(mode, 0, sizeof(*mode));
    switch (vbe[VBE_DISPI_INDEX_BPP]) {
    case 16:
        /* best effort: support native endianess only */
        mode->format = PIXMAN_r5g6b5;
        mode->bytepp = 2;
        break;
    case 32:
        mode->format = s->big_endian_fb
            ? PIXMAN_BE_x8r8g8b8
            : PIXMAN_LE_x8r8g8b8;
        mode->bytepp = 4;
        break;
    default:
        return -1;
    }

    mode->width  = vbe[VBE_DISPI_INDEX_XRES];
    mode->height = vbe[VBE_DISPI_INDEX_YRES];
    virt_width  = vbe[VBE_DISPI_INDEX_VIRT_WIDTH];
    if (virt_width < mode->width) {
        virt_width = mode->width;
    }
    mode->stride = virt_width * mode->bytepp;
    mode->size   = (uint64_t)mode->stride * mode->height;
    mode->offset = ((uint64_t)vbe[VBE_DISPI_INDEX_X_OFFSET] * mode->bytepp +
                    (uint64_t)vbe[VBE_DISPI_INDEX_Y_OFFSET] * mode->stride);

    if (mode->width < 64 || mode->height < 64) {
        return -1;
    }
    if (mode->offset + mode->size > s->vgamem) {
        return -1;
    }
    return 0;
}

static void bochs_display_update(void *opaque)
{
    BochsDisplayState *s = opaque;
    DirtyBitmapSnapshot *snap = NULL;
    bool full_update = false;
    BochsDisplayMode mode;
    DisplaySurface *ds;
    uint8_t *ptr;
    bool dirty;
    int y, ys, ret;

    ret = bochs_display_get_mode(s, &mode);
    if (ret < 0) {
        /* no (valid) video mode */
        return;
    }

    if (memcmp(&s->mode, &mode, sizeof(mode)) != 0) {
        /* video mode switch */
        s->mode = mode;
        ptr = memory_region_get_ram_ptr(&s->vram);
        ds = qemu_create_displaysurface_from(mode.width,
                                             mode.height,
                                             mode.format,
                                             mode.stride,
                                             ptr + mode.offset);
        dpy_gfx_replace_surface(s->con, ds);
        full_update = true;
    }

    if (full_update) {
        dpy_gfx_update_full(s->con);
    } else {
        snap = memory_region_snapshot_and_clear_dirty(&s->vram,
                                                      mode.offset, mode.size,
                                                      DIRTY_MEMORY_VGA);
        ys = -1;
        for (y = 0; y < mode.height; y++) {
            dirty = memory_region_snapshot_get_dirty(&s->vram, snap,
                                                     mode.offset + mode.stride * y,
                                                     mode.stride);
            if (dirty && ys < 0) {
                ys = y;
            }
            if (!dirty && ys >= 0) {
                dpy_gfx_update(s->con, 0, ys,
                               mode.width, y - ys);
                ys = -1;
            }
        }
        if (ys >= 0) {
            dpy_gfx_update(s->con, 0, ys,
                           mode.width, y - ys);
        }

        g_free(snap);
    }
}

static const GraphicHwOps bochs_display_gfx_ops = {
    .gfx_update = bochs_display_update,
};

static void bochs_display_realize(PCIDevice *dev, Error **errp)
{
    BochsDisplayState *s = BOCHS_DISPLAY(dev);
    Object *obj = OBJECT(dev);
    int ret;

    if (s->vgamem < 4 * MiB) {
        error_setg(errp, "bochs-display: video memory too small");
        return;
    }
    if (s->vgamem > 256 * MiB) {
        error_setg(errp, "bochs-display: video memory too big");
        return;
    }
    s->vgamem = pow2ceil(s->vgamem);

    s->con = graphic_console_init(DEVICE(dev), 0, &bochs_display_gfx_ops, s);

    memory_region_init_ram(&s->vram, obj, "bochs-display-vram", s->vgamem,
                           &error_fatal);
    memory_region_init_io(&s->vbe, obj, &bochs_display_vbe_ops, s,
                          "bochs dispi interface", PCI_VGA_BOCHS_SIZE);
    memory_region_init_io(&s->qext, obj, &bochs_display_qext_ops, s,
                          "qemu extended regs", PCI_VGA_QEXT_SIZE);

    memory_region_init_io(&s->mmio, obj, &unassigned_io_ops, NULL,
                          "bochs-display-mmio", PCI_VGA_MMIO_SIZE);
    memory_region_add_subregion(&s->mmio, PCI_VGA_BOCHS_OFFSET, &s->vbe);
    memory_region_add_subregion(&s->mmio, PCI_VGA_QEXT_OFFSET, &s->qext);

    pci_set_byte(&s->pci.config[PCI_REVISION_ID], 2);
    pci_register_bar(&s->pci, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
    pci_register_bar(&s->pci, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);

    if (s->enable_edid) {
        qemu_edid_generate(s->edid_blob, sizeof(s->edid_blob), &s->edid_info);
        qemu_edid_region_io(&s->edid, obj, s->edid_blob, sizeof(s->edid_blob));
        memory_region_add_subregion(&s->mmio, 0, &s->edid);
    }

    if (pci_bus_is_express(pci_get_bus(dev))) {
        ret = pcie_endpoint_cap_init(dev, 0x80);
        assert(ret > 0);
    } else {
        dev->cap_present &= ~QEMU_PCI_CAP_EXPRESS;
    }

    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
}

static bool bochs_display_get_big_endian_fb(Object *obj, Error **errp)
{
    BochsDisplayState *s = BOCHS_DISPLAY(obj);

    return s->big_endian_fb;
}

static void bochs_display_set_big_endian_fb(Object *obj, bool value,
                                            Error **errp)
{
    BochsDisplayState *s = BOCHS_DISPLAY(obj);

    s->big_endian_fb = value;
}

static void bochs_display_init(Object *obj)
{
    PCIDevice *dev = PCI_DEVICE(obj);

    /* Expose framebuffer byteorder via QOM */
    object_property_add_bool(obj, "big-endian-framebuffer",
                             bochs_display_get_big_endian_fb,
                             bochs_display_set_big_endian_fb);

    dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
}

static void bochs_display_exit(PCIDevice *dev)
{
    BochsDisplayState *s = BOCHS_DISPLAY(dev);

    graphic_console_close(s->con);
}

static Property bochs_display_properties[] = {
    DEFINE_PROP_SIZE("vgamem", BochsDisplayState, vgamem, 16 * MiB),
    DEFINE_PROP_BOOL("edid", BochsDisplayState, enable_edid, true),
    DEFINE_EDID_PROPERTIES(BochsDisplayState, edid_info),
    DEFINE_PROP_END_OF_LIST(),
};

static void bochs_display_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->class_id  = PCI_CLASS_DISPLAY_OTHER;
    k->vendor_id = PCI_VENDOR_ID_QEMU;
    k->device_id = PCI_DEVICE_ID_QEMU_VGA;

    k->realize   = bochs_display_realize;
    k->romfile   = "vgabios-bochs-display.bin";
    k->exit      = bochs_display_exit;
    dc->vmsd     = &vmstate_bochs_display;
    device_class_set_props(dc, bochs_display_properties);
    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
}

static const TypeInfo bochs_display_type_info = {
    .name           = TYPE_BOCHS_DISPLAY,
    .parent         = TYPE_PCI_DEVICE,
    .instance_size  = sizeof(BochsDisplayState),
    .instance_init  = bochs_display_init,
    .class_init     = bochs_display_class_init,
    .interfaces     = (InterfaceInfo[]) {
        { INTERFACE_PCIE_DEVICE },
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

static void bochs_display_register_types(void)
{
    type_register_static(&bochs_display_type_info);
}

type_init(bochs_display_register_types)
