/*
 * Generic PKUnity SoC machine and board descriptor
 *
 * Copyright (C) 2010-2012 Guan Xuetao
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation, or any later version.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
#include "ui/console.h"
#include "elf.h"
#include "exec/address-spaces.h"
#include "hw/sysbus.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/i386/pc.h"
#include "qemu/error-report.h"
#include "sysemu/qtest.h"

#undef DEBUG_PUV3
#include "hw/unicore32/puv3.h"

#define KERNEL_LOAD_ADDR        0x03000000
#define KERNEL_MAX_SIZE         0x00800000 /* Just a guess */

static void puv3_intc_cpu_handler(void *opaque, int irq, int level)
{
    UniCore32CPU *cpu = opaque;
    CPUState *cs = CPU(cpu);

    assert(irq == 0);
    if (level) {
        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
    } else {
        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
    }
}

static void puv3_soc_init(CPUUniCore32State *env)
{
    qemu_irq cpu_intc, irqs[PUV3_IRQS_NR];
    DeviceState *dev;
    MemoryRegion *i8042 = g_new(MemoryRegion, 1);
    int i;

    /* Initialize interrupt controller */
    cpu_intc = qemu_allocate_irq(puv3_intc_cpu_handler,
                                 uc32_env_get_cpu(env), 0);
    dev = sysbus_create_simple("puv3_intc", PUV3_INTC_BASE, cpu_intc);
    for (i = 0; i < PUV3_IRQS_NR; i++) {
        irqs[i] = qdev_get_gpio_in(dev, i);
    }

    /* Initialize minimal necessary devices for kernel booting */
    sysbus_create_simple("puv3_pm", PUV3_PM_BASE, NULL);
    sysbus_create_simple("puv3_dma", PUV3_DMA_BASE, NULL);
    sysbus_create_simple("puv3_ost", PUV3_OST_BASE, irqs[PUV3_IRQS_OST0]);
    sysbus_create_varargs("puv3_gpio", PUV3_GPIO_BASE,
            irqs[PUV3_IRQS_GPIOLOW0], irqs[PUV3_IRQS_GPIOLOW1],
            irqs[PUV3_IRQS_GPIOLOW2], irqs[PUV3_IRQS_GPIOLOW3],
            irqs[PUV3_IRQS_GPIOLOW4], irqs[PUV3_IRQS_GPIOLOW5],
            irqs[PUV3_IRQS_GPIOLOW6], irqs[PUV3_IRQS_GPIOLOW7],
            irqs[PUV3_IRQS_GPIOHIGH], NULL);

    /* Keyboard (i8042), mouse disabled for nographic */
    i8042_mm_init(irqs[PUV3_IRQS_PS2_KBD], NULL, i8042, PUV3_REGS_OFFSET, 4);
    memory_region_add_subregion(get_system_memory(), PUV3_PS2_BASE, i8042);
}

static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
{
    MemoryRegion *ram_memory = g_new(MemoryRegion, 1);

    /* SDRAM at address zero.  */
    memory_region_init_ram(ram_memory, NULL, "puv3.ram", ram_size,
                           &error_fatal);
    vmstate_register_ram_global(ram_memory);
    memory_region_add_subregion(get_system_memory(), 0, ram_memory);
}

static const GraphicHwOps no_ops;

static void puv3_load_kernel(const char *kernel_filename)
{
    int size;

    if (kernel_filename == NULL && qtest_enabled()) {
        return;
    }
    assert(kernel_filename != NULL);

    /* only zImage format supported */
    size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR,
            KERNEL_MAX_SIZE);
    if (size < 0) {
        error_report("Load kernel error: '%s'", kernel_filename);
        exit(1);
    }

    /* cheat curses that we have a graphic console, only under ocd console */
    graphic_console_init(NULL, 0, &no_ops, NULL);
}

static void puv3_init(MachineState *machine)
{
    ram_addr_t ram_size = machine->ram_size;
    const char *cpu_model = machine->cpu_model;
    const char *kernel_filename = machine->kernel_filename;
    const char *initrd_filename = machine->initrd_filename;
    CPUUniCore32State *env;
    UniCore32CPU *cpu;

    if (initrd_filename) {
        error_report("Please use kernel built-in initramdisk");
        exit(1);
    }

    if (!cpu_model) {
        cpu_model = "UniCore-II";
    }

    cpu = uc32_cpu_init(cpu_model);
    if (!cpu) {
        error_report("Unable to find CPU definition");
        exit(1);
    }
    env = &cpu->env;

    puv3_soc_init(env);
    puv3_board_init(env, ram_size);
    puv3_load_kernel(kernel_filename);
}

static void puv3_machine_init(MachineClass *mc)
{
    mc->desc = "PKUnity Version-3 based on UniCore32";
    mc->init = puv3_init;
    mc->is_default = 1;
}

DEFINE_MACHINE("puv3", puv3_machine_init)
