/*
 *  QEMU model for the Milkymist board.
 *
 *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "sysbus.h"
#include "hw.h"
#include "net.h"
#include "flash.h"
#include "sysemu.h"
#include "devices.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
#include "blockdev.h"
#include "milkymist-hw.h"
#include "lm32.h"
#include "exec-memory.h"

#define BIOS_FILENAME    "mmone-bios.bin"
#define BIOS_OFFSET      0x00860000
#define BIOS_SIZE        (512*1024)
#define KERNEL_LOAD_ADDR 0x40000000

typedef struct {
    CPUState *env;
    target_phys_addr_t bootstrap_pc;
    target_phys_addr_t flash_base;
    target_phys_addr_t initrd_base;
    size_t initrd_size;
    target_phys_addr_t cmdline_base;
} ResetInfo;

static void cpu_irq_handler(void *opaque, int irq, int level)
{
    CPUState *env = opaque;

    if (level) {
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
    } else {
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
    }
}

static void main_cpu_reset(void *opaque)
{
    ResetInfo *reset_info = opaque;
    CPUState *env = reset_info->env;

    cpu_reset(env);

    /* init defaults */
    env->pc = reset_info->bootstrap_pc;
    env->regs[R_R1] = reset_info->cmdline_base;
    env->regs[R_R2] = reset_info->initrd_base;
    env->regs[R_R3] = reset_info->initrd_base + reset_info->initrd_size;
    env->eba = reset_info->flash_base;
    env->deba = reset_info->flash_base;
}

static void
milkymist_init(ram_addr_t ram_size_not_used,
                          const char *boot_device,
                          const char *kernel_filename,
                          const char *kernel_cmdline,
                          const char *initrd_filename, const char *cpu_model)
{
    CPUState *env;
    int kernel_size;
    DriveInfo *dinfo;
    MemoryRegion *address_space_mem = get_system_memory();
    MemoryRegion *phys_sdram = g_new(MemoryRegion, 1);
    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
    qemu_irq irq[32], *cpu_irq;
    int i;
    char *bios_filename;
    ResetInfo *reset_info;

    /* memory map */
    target_phys_addr_t flash_base   = 0x00000000;
    size_t flash_sector_size        = 128 * 1024;
    size_t flash_size               = 32 * 1024 * 1024;
    target_phys_addr_t sdram_base   = 0x40000000;
    size_t sdram_size               = 128 * 1024 * 1024;

    target_phys_addr_t initrd_base  = sdram_base + 0x1002000;
    target_phys_addr_t cmdline_base = sdram_base + 0x1000000;
    size_t initrd_max = sdram_size - 0x1002000;

    reset_info = g_malloc0(sizeof(ResetInfo));

    if (cpu_model == NULL) {
        cpu_model = "lm32-full";
    }
    env = cpu_init(cpu_model);
    reset_info->env = env;

    cpu_lm32_set_phys_msb_ignore(env, 1);

    memory_region_init_ram(phys_sdram, NULL, "milkymist.sdram", sdram_size);
    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram);

    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
                                  NULL, "milkymist.flash", flash_size);
    dinfo = drive_get(IF_PFLASH, 0, 0);
    /* Numonyx JS28F256J3F105 */
    pflash_cfi01_register(flash_base, phys_flash,
                          dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                          flash_size / flash_sector_size, 2,
                          0x00, 0x89, 0x00, 0x1d);

    /* create irq lines */
    cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
    env->pic_state = lm32_pic_init(*cpu_irq);
    for (i = 0; i < 32; i++) {
        irq[i] = qdev_get_gpio_in(env->pic_state, i);
    }

    /* load bios rom */
    if (bios_name == NULL) {
        bios_name = BIOS_FILENAME;
    }
    bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    if (bios_filename) {
        load_image_targphys(bios_filename, BIOS_OFFSET, BIOS_SIZE);
    }

    reset_info->bootstrap_pc = BIOS_OFFSET;

    /* if no kernel is given no valid bios rom is a fatal error */
    if (!kernel_filename && !dinfo && !bios_filename) {
        fprintf(stderr, "qemu: could not load Milkymist One bios '%s'\n",
                bios_name);
        exit(1);
    }

    milkymist_uart_create(0x60000000, irq[0], irq[1]);
    milkymist_sysctl_create(0x60001000, irq[2], irq[3], irq[4],
            80000000, 0x10014d31, 0x0000041f, 0x00000001);
    milkymist_hpdmc_create(0x60002000);
    milkymist_vgafb_create(0x60003000, 0x40000000, 0x0fffffff);
    milkymist_memcard_create(0x60004000);
    milkymist_ac97_create(0x60005000, irq[5], irq[6], irq[7], irq[8]);
    milkymist_pfpu_create(0x60006000, irq[9]);
    milkymist_tmu2_create(0x60007000, irq[10]);
    milkymist_minimac2_create(0x60008000, 0x30000000, irq[11], irq[12]);
    milkymist_softusb_create(0x6000f000, irq[17],
            0x20000000, 0x1000, 0x20020000, 0x2000);

    /* make sure juart isn't the first chardev */
    env->juart_state = lm32_juart_init();

    if (kernel_filename) {
        uint64_t entry;

        /* Boots a kernel elf binary.  */
        kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,
                               1, ELF_MACHINE, 0);
        reset_info->bootstrap_pc = entry;

        if (kernel_size < 0) {
            kernel_size = load_image_targphys(kernel_filename, sdram_base,
                                              sdram_size);
            reset_info->bootstrap_pc = sdram_base;
        }

        if (kernel_size < 0) {
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
                    kernel_filename);
            exit(1);
        }
    }

    if (kernel_cmdline && strlen(kernel_cmdline)) {
        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE,
                kernel_cmdline);
        reset_info->cmdline_base = (uint32_t)cmdline_base;
    }

    if (initrd_filename) {
        size_t initrd_size;
        initrd_size = load_image_targphys(initrd_filename, initrd_base,
                initrd_max);
        reset_info->initrd_base = (uint32_t)initrd_base;
        reset_info->initrd_size = (uint32_t)initrd_size;
    }

    qemu_register_reset(main_cpu_reset, reset_info);
}

static QEMUMachine milkymist_machine = {
    .name = "milkymist",
    .desc = "Milkymist One",
    .init = milkymist_init,
    .is_default = 0
};

static void milkymist_machine_init(void)
{
    qemu_register_machine(&milkymist_machine);
}

machine_init(milkymist_machine_init);
