/*
 * 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_device.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"
#include "qom/object.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;

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;
};

#define TYPE_BOCHS_DISPLAY "bochs-display"
OBJECT_DECLARE_SIMPLE_TYPE(BochsDisplayState, BOCHS_DISPLAY)

static const VMStateDescription vmstate_bochs_display = {
    .name = "bochs-display",
    .fields = (const 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 endianness 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)
