/* 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_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);
