#include "biosvar.h" // GET_BDA
#include "output.h" // dprintf
#include "string.h" // memset16_far
#include "vgautil.h" // VBE_total_memory
#include "std/pmm.h" // struct pmmheader
#include "byteorder.h"
#include "fw/paravirt.h"

/* ---------------------------------------------------------------------- */
/* minimal qemu fc_cfg support bits, requires dma support                 */

#define QEMU_CFG_FILE_DIR               0x19

struct QemuCfgFile {
    u32  size;        /* file size */
    u16  select;      /* write this to 0x510 to read it */
    u16  reserved;
    char name[56];
};

static void
qemu_cfg_dma_transfer(void *address, u32 length, u32 control)
{
    QemuCfgDmaAccess access;

    if (length == 0) {
        return;
    }

    access.address = cpu_to_be64((u64)(u32)address);
    access.length = cpu_to_be32(length);
    access.control = cpu_to_be32(control);

    barrier();

    outl(cpu_to_be32((u32)&access), PORT_QEMU_CFG_DMA_ADDR_LOW);

    while(be32_to_cpu(access.control) & ~QEMU_CFG_DMA_CTL_ERROR)
        /* wait */;
}

static void
qemu_cfg_read(void *buf, int len)
{
    qemu_cfg_dma_transfer(buf, len, QEMU_CFG_DMA_CTL_READ);
}

static void
qemu_cfg_read_entry(void *buf, int e, int len)
{
    u32 control = (e << 16) | QEMU_CFG_DMA_CTL_SELECT
        | QEMU_CFG_DMA_CTL_READ;
    qemu_cfg_dma_transfer(buf, len, control);
}

static void
qemu_cfg_write_entry(void *buf, int e, int len)
{
    u32 control = (e << 16) | QEMU_CFG_DMA_CTL_SELECT
        | QEMU_CFG_DMA_CTL_WRITE;
    qemu_cfg_dma_transfer(buf, len, control);
}

static int
qemu_cfg_find_file(const char *filename)
{
    u32 count, e, select;

    qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
    count = be32_to_cpu(count);
    for (select = 0, e = 0; e < count; e++) {
        struct QemuCfgFile qfile;
        qemu_cfg_read(&qfile, sizeof(qfile));
        if (memcmp_far(GET_SEG(SS), qfile.name,
                       GET_SEG(CS), filename, 10) == 0)
            select = be16_to_cpu(qfile.select);
    }
    return select;
}

/* ---------------------------------------------------------------------- */

#define FRAMEBUFFER_WIDTH      1024
#define FRAMEBUFFER_HEIGHT     768
#define FRAMEBUFFER_BPP        4
#define FRAMEBUFFER_STRIDE     (FRAMEBUFFER_BPP * FRAMEBUFFER_WIDTH)
#define FRAMEBUFFER_SIZE       (FRAMEBUFFER_STRIDE * FRAMEBUFFER_HEIGHT)

struct QemuRAMFBCfg {
    u64 addr;
    u32 fourcc;
    u32 flags;
    u32 width;
    u32 height;
    u32 stride;
};

#define fourcc_code(a, b, c, d) ((u32)(a) | ((u32)(b) << 8) | \
                                 ((u32)(c) << 16) | ((u32)(d) << 24))

#define DRM_FORMAT_RGB565       fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */
#define DRM_FORMAT_RGB888       fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */
#define DRM_FORMAT_XRGB8888     fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */

static u32
allocate_framebuffer(void)
{
    u32 res = allocate_pmm(FRAMEBUFFER_SIZE, 1, 1);
    if (!res)
        return 0;
    dprintf(1, "ramfb: framebuffer allocated at %x\n", res);
    return res;
}

int
ramfb_setup(void)
{
    dprintf(1, "ramfb: init\n");

    if (GET_GLOBAL(HaveRunInit))
        return 0;

    u32 select = qemu_cfg_find_file("etc/ramfb");
    if (select == 0) {
        dprintf(1, "ramfb: fw_cfg (etc/ramfb) file not found\n");
        return -1;
    }

    dprintf(1, "ramfb: fw_cfg (etc/ramfb) file at slot 0x%x\n", select);
    u32 fb = allocate_framebuffer();
    if (!fb) {
        dprintf(1, "ramfb: allocating framebuffer failed\n");
        return -1;
    }

    u64 addr = fb;
    u8 bpp = FRAMEBUFFER_BPP * 8;
    u32 xlines = FRAMEBUFFER_WIDTH;
    u32 ylines = FRAMEBUFFER_HEIGHT;
    u32 linelength = FRAMEBUFFER_STRIDE;
    dprintf(1, "Found FB @ %llx %dx%d with %d bpp (%d stride)\n"
            , addr, xlines, ylines, bpp, linelength);

    if (!addr || addr > 0xffffffff
        || (bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32)) {
        dprintf(1, "Unable to use FB\n");
        return -1;
    }

    cbvga_setup_modes(addr, bpp, xlines, ylines, linelength);

    struct QemuRAMFBCfg cfg = {
        .addr   = cpu_to_be64(fb),
        .fourcc = cpu_to_be32(DRM_FORMAT_XRGB8888),
        .flags  = cpu_to_be32(0),
        .width  = cpu_to_be32(FRAMEBUFFER_WIDTH),
        .height = cpu_to_be32(FRAMEBUFFER_HEIGHT),
        .stride = cpu_to_be32(FRAMEBUFFER_STRIDE),
    };
    qemu_cfg_write_entry(&cfg, select, sizeof(cfg));

    return 0;
}
