#include "hw/sysbus.h"
#include "hw/devices.h"
#include "hw/mips/mips.h"
#include "hw/mips/cpudevs.h"
#include "net/net.h"
#include "sysemu/device_tree.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "hw/boards.h"
#include "exec/address-spaces.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "qemu/config-file.h"
#include "sysemu/char.h"
#include "monitor/monitor.h"
#include "hw/misc/android_pipe.h"
#include "hw/loader.h"
#include "elf.h"
#include "hw/intc/goldfish_pic.h"
#include "hw/irq.h"

#ifdef CONFIG_ANDROID
#include "android/android.h"
#endif  // CONFIG_ANDROID

#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fffffff)

#define MIPS_CPU_SAVE_VERSION 1
#define MIPS_CPU_IRQ_BASE     8

#define HIGHMEM_OFFSET    0x20000000
#define GOLDFISH_IO_SPACE 0x1f000000

#define VIRTIO_TRANSPORTS 16
#define MAX_GF_TTYS       3

#define TYPE_MIPS_RANCHU "mips-ranchu"
#define MIPS_RANCHU(obj) OBJECT_CHECK(RanchuState, (obj), TYPE_MIPS_RANCHU)
#define MIPS_RANCHU_REV "1"

typedef struct {
    SysBusDevice parent_obj;

    qemu_irq *gfpic;
} RanchuState;

#define MAX_RAM_SIZE_MB 4079UL

enum {
    RANCHU_GF_PIC,
    RANCHU_GF_TTY,
    RANCHU_GF_TIMER,
    RANCHU_GF_RTC,
    RANCHU_GF_BATTERY,
    RANCHU_GF_FB,
    RANCHU_GF_EVDEV,
    RANCHU_ANDROID_PIPE,
    RANCHU_GF_AUDIO,
    RANCHU_MMIO,
};

typedef struct DevMapEntry {
    hwaddr base;
    hwaddr size;
    int irq;
    const char* qemu_name;
    const char* dt_name;
    const char* dt_compatible;
} DevMapEntry;

static DevMapEntry devmap[] = {
    [RANCHU_GF_PIC] =       { GOLDFISH_IO_SPACE, 0x1000, 0,
        NULL, "goldfish_pic", "generic,goldfish-pic" },
    /* ttyGF0 base address remains hardcoded in the kernel.
     * Early printing (prom_putchar()) relies on finding device
     * mapped on this address. DT can not be used at that early stage
     * for acquiring the base address of the device in the kernel.
     */
    [RANCHU_GF_TTY] =       { GOLDFISH_IO_SPACE + 0x02000, 0x1000, 2,
        "goldfish_tty", "goldfish_tty", "generic,goldfish-tty" },
    /* repeats for a total of MAX_GF_TTYS */
    [RANCHU_GF_TIMER] =     { GOLDFISH_IO_SPACE + 0x05000, 0x1000, 5,
        "goldfish_timer", "goldfish_timer", "generic,goldfish-timer" },
    [RANCHU_GF_RTC] =       { GOLDFISH_IO_SPACE + 0x06000, 0x1000, 6,
        "goldfish_rtc", "goldfish_rtc", "generic,goldfish-rtc" },
    [RANCHU_GF_BATTERY] =   { GOLDFISH_IO_SPACE + 0x07000, 0x1000, 7,
        "goldfish_battery", "goldfish_battery", "generic,goldfish-battery" },
    [RANCHU_GF_FB] =        { GOLDFISH_IO_SPACE + 0x08000, 0x0100, 8,
        "goldfish_fb", "goldfish_fb", "generic,goldfish-fb" },
    [RANCHU_GF_EVDEV] =     { GOLDFISH_IO_SPACE + 0x09000, 0x1000, 9,
        "goldfish-events", "goldfish_events", "generic,goldfish-events-keypad" },
    [RANCHU_ANDROID_PIPE] = { GOLDFISH_IO_SPACE + 0x0A000, 0x2000, 10,
        "android_pipe", "android_pipe", "generic,android-pipe" },
    [RANCHU_GF_AUDIO] =     { GOLDFISH_IO_SPACE + 0x0C000, 0x0100, 11,
        "goldfish_audio", "goldfish_audio", "generic,goldfish-audio" },
    [RANCHU_MMIO] =         { GOLDFISH_IO_SPACE + 0x10000, 0x0200, 16,
        "virtio-mmio", "virtio_mmio", "virtio,mmio" },
    /* ...repeating for a total of VIRTIO_TRANSPORTS, each of that size */
};

struct machine_params {
    uint64_t kernel_entry;
    uint64_t cmdline_ptr;
    unsigned ram_size;
    unsigned highmem_size;
    MIPSCPU *cpu;
} ranchu_params;

static void main_cpu_reset(void* opaque1)
{
    struct machine_params *opaque = (struct machine_params *)opaque1;
    MIPSCPU *cpu = opaque->cpu;

    cpu_reset(CPU(cpu));

    cpu->env.active_tc.PC = opaque->kernel_entry;
    cpu->env.active_tc.gpr[4] = opaque->cmdline_ptr; /* a0 */
    cpu->env.active_tc.gpr[5] = opaque->ram_size;    /* a1 */
    cpu->env.active_tc.gpr[6] = opaque->highmem_size;/* a2 */
    cpu->env.active_tc.gpr[7] = 0;                   /* a3 */

}

static void android_load_kernel(CPUMIPSState *env, int ram_size,
                                const char *kernel_filename,
                                const char *kernel_cmdline,
                                const char *initrd_filename,
                                void* fdt, int fdt_size)
{
    int initrd_size;
    ram_addr_t initrd_offset;
    uint64_t kernel_entry, kernel_low, kernel_high;
    unsigned int cmdline;

    /* Load the kernel.  */
    if (!kernel_filename) {
        fprintf(stderr, "Kernel image must be specified\n");
        exit(1);
    }

    if (load_elf(kernel_filename, cpu_mips_kseg0_to_phys, NULL,
        (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
        (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) {
        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
        exit(1);
    }

    /* Load the DTB at the kernel_high address, that is the place where
     * kernel with Appended DT support enabled will look for it
     */
    if (fdt) {
        cpu_physical_memory_write(kernel_high, fdt, fdt_size);
        kernel_high += fdt_size;
    }

    ranchu_params.kernel_entry = kernel_entry;

    /* load initrd */
    initrd_size = 0;
    initrd_offset = 0;
    if (initrd_filename) {
        initrd_size = get_image_size (initrd_filename);
        if (initrd_size > 0) {
            initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
            if (initrd_offset + initrd_size > ram_size) {
                fprintf(stderr,
                    "qemu: memory too small for initial ram disk '%s'\n",
                    initrd_filename);
                exit(1);
            }
            initrd_size = load_image_targphys(initrd_filename,
                                               initrd_offset,
                                               ram_size - initrd_offset);
        }

        if (initrd_size == (target_ulong) -1) {
            fprintf(stderr,
                "qemu: could not load initial ram disk '%s'\n",
                initrd_filename);
            exit(1);
        }
    }

    /* Store command line in top page of memory
     * kernel will copy the command line to a local buffer
     */
    cmdline = ram_size - TARGET_PAGE_SIZE;
    char kernel_cmd[1024];
    if (initrd_size > 0)
        sprintf (kernel_cmd, "%s rd_start=0x%" HWADDR_PRIx " rd_size=%li",
                 kernel_cmdline,
                 (hwaddr)PHYS_TO_VIRT(initrd_offset),
                 (long int)initrd_size);
    else
        strcpy (kernel_cmd, kernel_cmdline);

    /* Setup Highmem */
    char kernel_cmd2[1024];
    if (ranchu_params.highmem_size) {
        sprintf (kernel_cmd2, "%s mem=%um@0x0 mem=%um@0x%x",
                 kernel_cmd,
                 GOLDFISH_IO_SPACE / (1024 * 1024),
                 ranchu_params.highmem_size / (1024 * 1024),
                 HIGHMEM_OFFSET);
    } else {
        strcpy (kernel_cmd2, kernel_cmd);
    }

    cpu_physical_memory_write(ram_size - TARGET_PAGE_SIZE,
                              (void *)kernel_cmd2,
                              strlen(kernel_cmd2) + 1);

    ranchu_params.cmdline_ptr = PHYS_TO_VIRT(cmdline);
}

/* create_device(void* fdt, DevMapEntry* dev, qemu_irq* pic,
 *               int num_devices, int is_virtio)
 *
 * In case of interrupt controller dev->irq stores
 * dt handle previously referenced as interrupt-parent
 *
 * @fdt - Place where DT nodes will be stored
 * @dev - Device information (base, irq, name)
 * @pic - Interrupt controller parent. If NULL, 'intc' node assumed.
 * @num_devices - If you want to allocate multiple continuous device mappings
 */
static void create_device(void* fdt, DevMapEntry* dev, qemu_irq* pic,
                          int num_devices, int is_virtio)
{
    int i;

    for (i = 0; i < num_devices; i++) {
        hwaddr base = dev->base + i * dev->size;

        char* nodename = g_strdup_printf("/%s@%" PRIx64, dev->dt_name, base);
        qemu_fdt_add_subnode(fdt, nodename);
        qemu_fdt_setprop(fdt, nodename, "compatible",
                         dev->dt_compatible,
                         strlen(dev->dt_compatible) + 1);
        qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", 1, base, 2, dev->size);

        if (pic == NULL) {
            qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
            qemu_fdt_setprop_cell(fdt, nodename, "phandle", dev->irq);
            qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 0x1);
        } else {
            qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
                                   dev->irq + i + MIPS_CPU_IRQ_BASE);
            if (is_virtio) {
                /* Note that we have to create the transports in forwards order
                 * so that command line devices are inserted lowest address first,
                 * and then add dtb nodes in reverse order so that they appear in
                 * the finished device tree lowest address first.
                 */
                sysbus_create_simple(dev->qemu_name,
                    dev->base + (num_devices - i - 1) * dev->size,
                    pic[dev->irq + num_devices - i - 1]);
            } else {
                sysbus_create_simple(dev->qemu_name, base, pic[dev->irq + i]);
            }
        }
        g_free(nodename);
    }
}

static void ranchu_init(MachineState *machine)
{
    MIPSCPU *cpu;
    CPUMIPSState *env;
    qemu_irq *goldfish_pic;
    int i, fdt_size;
    void *fdt;

    DeviceState *dev = qdev_create(NULL, TYPE_MIPS_RANCHU);
    RanchuState *s = MIPS_RANCHU(dev);

    MemoryRegion *ram_lo = g_new(MemoryRegion, 1);
    MemoryRegion *ram_hi = g_new(MemoryRegion, 1);

    /* init CPUs */
    if (machine->cpu_model == NULL) {
#ifdef TARGET_MIPS64
        machine->cpu_model = "MIPS64R2-generic";
#else
        machine->cpu_model = "74Kf";
#endif
    }
    cpu = cpu_mips_init(machine->cpu_model);
    if (cpu == NULL) {
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }

    env = &cpu->env;

    register_savevm(NULL,
                    "cpu",
                    0,
                    MIPS_CPU_SAVE_VERSION,
                    cpu_save,
                    cpu_load,
                    env);

    qemu_register_reset(main_cpu_reset, &ranchu_params);

    if (ram_size > (MAX_RAM_SIZE_MB << 20)) {
        fprintf(stderr, "qemu: Too much memory for this machine. "
                        "RAM size reduced to %lu MB\n", MAX_RAM_SIZE_MB);
        ram_size = MAX_RAM_SIZE_MB << 20;
    }

    fdt = create_device_tree(&fdt_size);

    if (!fdt) {
        error_report("create_device_tree() failed");
        exit(1);
    }

    memory_region_init_ram(ram_lo, NULL, "ranchu_low.ram",
        MIN(ram_size, GOLDFISH_IO_SPACE), &error_abort);
    vmstate_register_ram_global(ram_lo);
    memory_region_add_subregion(get_system_memory(), 0, ram_lo);

    ranchu_params.ram_size = MIN(ram_size, GOLDFISH_IO_SPACE);

    /* post IO hole, if there is enough RAM */
    if (ram_size > GOLDFISH_IO_SPACE) {
        memory_region_init_ram(ram_hi, NULL, "ranchu_high.ram",
            ram_size - GOLDFISH_IO_SPACE, &error_abort);
        vmstate_register_ram_global(ram_hi);
        memory_region_add_subregion(get_system_memory(), HIGHMEM_OFFSET, ram_hi);
        ranchu_params.highmem_size = ram_size - GOLDFISH_IO_SPACE;
    }

    ranchu_params.cpu = cpu;

    cpu_mips_irq_init_cpu(env);
    cpu_mips_clock_init(env);

    /* Initialize Goldfish PIC */
    s->gfpic = goldfish_pic = goldfish_interrupt_init(devmap[RANCHU_GF_PIC].base,
                                            env->irq[2], env->irq[3]);
    /* Alocate dt handle (label) for interrupt-parent */
    devmap[RANCHU_GF_PIC].irq = qemu_fdt_alloc_phandle(fdt);

    qemu_fdt_setprop_string(fdt, "/", "model", "ranchu");
    qemu_fdt_setprop_string(fdt, "/", "compatible", "mti,goldfish");
    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x1);
    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
    qemu_fdt_setprop_cell(fdt, "/", "interrupt-parent", devmap[RANCHU_GF_PIC].irq);

    /* Firmware node */
    qemu_fdt_add_subnode(fdt, "/firmware");
    qemu_fdt_add_subnode(fdt, "/firmware/android");
    qemu_fdt_setprop_string(fdt, "/firmware/android", "compatible", "android,firmware");
    qemu_fdt_setprop_string(fdt, "/firmware/android", "hardware", "ranchu");
    qemu_fdt_setprop_string(fdt, "/firmware/android", "revision", MIPS_RANCHU_REV);

    /* CPU node */
    qemu_fdt_add_subnode(fdt, "/cpus");
    qemu_fdt_add_subnode(fdt, "/cpus/cpu@0");
    qemu_fdt_setprop_string(fdt, "/cpus/cpu@0", "device_type", "cpu");
    qemu_fdt_setprop_string(fdt, "/cpus/cpu@0", "compatible", "mti,5KEf");

    /* Memory node */
    qemu_fdt_add_subnode(fdt, "/memory");
    qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
    if (ram_size > GOLDFISH_IO_SPACE) {
        qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
                    1, 0, 2, GOLDFISH_IO_SPACE,
                    1, HIGHMEM_OFFSET, 2, ram_size - GOLDFISH_IO_SPACE);
    } else {
        qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg", 1, 0, 2, ram_size);
    }

    /* Create goldfish_pic controller node in dt */
    create_device(fdt, &devmap[RANCHU_GF_PIC], NULL, 1, 0);

    /* Create 4 Goldfish TTYs */
    create_device(fdt, &devmap[RANCHU_GF_TTY], goldfish_pic, MAX_GF_TTYS, 0);

    /* Other Goldfish Platform devices */
    for (i = RANCHU_GF_AUDIO; i >= RANCHU_GF_TIMER ; i--) {
        create_device(fdt, &devmap[i], goldfish_pic, 1, 0);
    }

    /* Virtio MMIO devices */
    create_device(fdt, &devmap[RANCHU_MMIO], goldfish_pic, VIRTIO_TRANSPORTS, 1);

    qemu_fdt_dumpdtb(fdt, fdt_size);

    android_load_kernel(env, MIN(ram_size, GOLDFISH_IO_SPACE),
                        machine->kernel_filename,
                        machine->kernel_cmdline,
                        machine->initrd_filename,
                        fdt, fdt_size);
}

static int mips_ranchu_sysbus_device_init(SysBusDevice *sysbusdev)
{
    return 0;
}

static void mips_ranchu_class_init(ObjectClass *klass, void *data)
{
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = mips_ranchu_sysbus_device_init;
}

static const TypeInfo mips_ranchu_device = {
    .name          = TYPE_MIPS_RANCHU,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(RanchuState),
    .class_init    = mips_ranchu_class_init,
};

static QEMUMachine ranchu_machine = {
    .name = "ranchu",
    .desc = "Ranchu Virtual Machine for Android Emulator",
    .init = ranchu_init,
    .max_cpus = 1,
};

static void mips_ranchu_register_types(void)
{
    type_register_static(&mips_ranchu_device);
}

static void ranchu_machine_init(void)
{
    qemu_register_machine(&ranchu_machine);
}

type_init(mips_ranchu_register_types)
machine_init(ranchu_machine_init);
