/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program 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 General Public License for more details.
*/

#include "hw/hw.h"
#include "hw/boards.h"
#include "hw/devices.h"
#include "hw/loader.h"
#include "net/net.h"
#include "sysemu/sysemu.h"
#include "hw/mips/mips.h"
#include "hw/android/goldfish/device.h"
#include "hw/android/goldfish/pipe.h"
#include "android/globals.h"
#include "audio/audio.h"
#include "exec/ram_addr.h"
#include "sysemu/blockdev.h"

#include "android/utils/debug.h"

#define  D(...)  VERBOSE_PRINT(init,__VA_ARGS__)

#define MIPS_CPU_SAVE_VERSION  1
#define GOLDFISH_IO_SPACE       0x1f000000
#define GOLDFISH_INTERRUPT	0x1f000000
#define GOLDFISH_DEVICEBUS	0x1f001000
#define GOLDFISH_TTY		0x1f002000
#define GOLDFISH_RTC		0x1f003000
#define GOLDFISH_AUDIO		0x1f004000
#define GOLDFISH_MMC		0x1f005000
#define GOLDFISH_MEMLOG		0x1f006000
#define GOLDFISH_DEVICES	0x1f010000

char* audio_input_source = NULL;

static struct goldfish_device event0_device = {
    .name = "goldfish_events",
    .id = 0,
    .size = 0x1000,
    .irq_count = 1
};

static struct goldfish_device nand_device = {
    .name = "goldfish_nand",
    .id = 0,
    .size = 0x1000
};

/* Board init.  */

#define VIRT_TO_PHYS_ADDEND (0xffffffff80000000LL)

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

static void android_load_kernel(CPUOldState *env, int ram_size, const char *kernel_filename,
              const char *kernel_cmdline, const char *initrd_filename)
{
    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, VIRT_TO_PHYS_ADDEND,
         (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
         (uint64_t *)&kernel_high) < 0) {
    fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
    exit(1);
    }
    env->active_tc.PC = (int32_t)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 loca 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);

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

#if 0
    if (initrd_size > 0)
        sprintf (phys_ram_base+cmdline, "%s rd_start=0x" TARGET_FMT_lx " rd_size=%li",
                       kernel_cmdline,
                       PHYS_TO_VIRT(initrd_offset), initrd_size);
    else
        strcpy (phys_ram_base+cmdline, kernel_cmdline);
#endif

    env->active_tc.gpr[4] = PHYS_TO_VIRT(cmdline);/* a0 */
    env->active_tc.gpr[5] = ram_size;       /* a1 */
    env->active_tc.gpr[6] = 0;          /* a2 */
    env->active_tc.gpr[7] = 0;          /* a3 */

}


static void android_mips_init_(ram_addr_t ram_size,
    const char *boot_device,
    const char *kernel_filename,
    const char *kernel_cmdline,
    const char *initrd_filename,
    const char *cpu_model)
{
    CPUOldState *env;
    qemu_irq *goldfish_pic;
    int i;
    ram_addr_t ram_offset;

    if (!cpu_model)
        cpu_model = "24Kf";

    env = cpu_mips_init(cpu_model);

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

    if (ram_size > GOLDFISH_IO_SPACE)
        ram_size = GOLDFISH_IO_SPACE;   /* avoid overlap of ram and IO regs */
    ram_offset = qemu_ram_alloc(NULL, "android_mips", ram_size);
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);

    /* Init internal devices */
    cpu_mips_irq_init_cpu(env);
    cpu_mips_clock_init(env);

    goldfish_pic = goldfish_interrupt_init(GOLDFISH_INTERRUPT,
					   env->irq[2], env->irq[3]);
    goldfish_device_init(goldfish_pic, GOLDFISH_DEVICES, 0x7f0000, 10, 22);

    goldfish_device_bus_init(GOLDFISH_DEVICEBUS, 1);

    goldfish_timer_and_rtc_init(GOLDFISH_RTC, 3);

    goldfish_tty_add(serial_hds[0], 0, GOLDFISH_TTY, 4);
    for(i = 1; i < MAX_SERIAL_PORTS; i++) {
        if(serial_hds[i]) {
            goldfish_tty_add(serial_hds[i], i, 0, 0);
        }
    }

    for(i = 0; i < MAX_NICS; i++) {
        if (nd_table[i].vlan) {
            if (nd_table[i].model == NULL
                || strcmp(nd_table[i].model, "smc91c111") == 0) {
                struct goldfish_device *smc_device;
                smc_device = g_malloc0(sizeof(*smc_device));
                smc_device->name = "smc91x";
                smc_device->id = i;
                smc_device->size = 0x1000;
                smc_device->irq_count = 1;
                goldfish_add_device_no_io(smc_device);
                smc91c111_init(&nd_table[i], smc_device->base, goldfish_pic[smc_device->irq]);
            } else {
                fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
                exit (1);
            }
        }
    }

    goldfish_fb_init(0);
#ifdef HAS_AUDIO
    goldfish_audio_init(GOLDFISH_AUDIO, 0, audio_input_source);
#endif
    {
        DriveInfo* info = drive_get( IF_IDE, 0, 0 );
        if (info != NULL) {
            goldfish_mmc_init(GOLDFISH_MMC, 0, info->bdrv);
	}
    }
    goldfish_battery_init(android_hw->hw_battery);

    goldfish_add_device_no_io(&event0_device);
    events_dev_init(event0_device.base, goldfish_pic[event0_device.irq]);

#ifdef CONFIG_NAND
    goldfish_add_device_no_io(&nand_device);
    nand_dev_init(nand_device.base);
#endif

    bool newDeviceNaming =
            (androidHwConfig_getKernelDeviceNaming(android_hw) >= 1);
    pipe_dev_init(newDeviceNaming);

    android_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, initrd_filename);
}


QEMUMachine android_mips_machine = {
    "android_mips",
    "MIPS Android Emulator",
    android_mips_init_,
    0,
    0,
    1,
    NULL
};

static void android_mips_init(void)
{
    qemu_register_machine(&android_mips_machine);
}

machine_init(android_mips_init);
