/*
 * Gumstix Platforms
 *
 * Copyright (c) 2007 by Thorsten Zitterell <info@bitmux.org>
 *
 * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
 *
 * This code is licensed under the GNU GPL v2.
 *
 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.
 */
 
/* 
 * Example usage:
 * 
 * connex:
 * =======
 * create image:
 * # dd of=flash bs=1k count=16k if=/dev/zero
 * # dd of=flash bs=1k conv=notrunc if=u-boot.bin
 * # dd of=flash bs=1k conv=notrunc seek=256 if=rootfs.arm_nofpu.jffs2
 * start it:
 * # qemu-system-arm -M connex -pflash flash -monitor null -nographic
 *
 * verdex:
 * =======
 * create image:
 * # dd of=flash bs=1k count=32k if=/dev/zero
 * # dd of=flash bs=1k conv=notrunc if=u-boot.bin
 * # dd of=flash bs=1k conv=notrunc seek=256 if=rootfs.arm_nofpu.jffs2
 * # dd of=flash bs=1k conv=notrunc seek=31744 if=uImage
 * start it:
 * # qemu-system-arm -M verdex -pflash flash -monitor null -nographic -m 289
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "hw/hw.h"
#include "hw/arm/pxa.h"
#include "net/net.h"
#include "hw/block/flash.h"
#include "hw/devices.h"
#include "hw/boards.h"
#include "exec/address-spaces.h"
#include "sysemu/qtest.h"
#include "cpu.h"

static const int sector_len = 128 * 1024;

static void connex_init(MachineState *machine)
{
    PXA2xxState *cpu;
    DriveInfo *dinfo;
    int be;
    MemoryRegion *address_space_mem = get_system_memory();

    uint32_t connex_rom = 0x01000000;
    uint32_t connex_ram = 0x04000000;

    cpu = pxa255_init(address_space_mem, connex_ram);

    dinfo = drive_get(IF_PFLASH, 0, 0);
    if (!dinfo && !qtest_enabled()) {
        error_report("A flash image must be given with the "
                     "'pflash' parameter");
        exit(1);
    }

#ifdef TARGET_WORDS_BIGENDIAN
    be = 1;
#else
    be = 0;
#endif
    if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                               sector_len, connex_rom / sector_len,
                               2, 0, 0, 0, 0, be)) {
        error_report("Error registering flash memory");
        exit(1);
    }

    /* Interrupt line of NIC is connected to GPIO line 36 */
    smc91c111_init(&nd_table[0], 0x04000300,
                    qdev_get_gpio_in(cpu->gpio, 36));
}

static void verdex_init(MachineState *machine)
{
    PXA2xxState *cpu;
    DriveInfo *dinfo;
    int be;
    MemoryRegion *address_space_mem = get_system_memory();

    uint32_t verdex_rom = 0x02000000;
    uint32_t verdex_ram = 0x10000000;

    cpu = pxa270_init(address_space_mem, verdex_ram, machine->cpu_type);

    dinfo = drive_get(IF_PFLASH, 0, 0);
    if (!dinfo && !qtest_enabled()) {
        error_report("A flash image must be given with the "
                     "'pflash' parameter");
        exit(1);
    }

#ifdef TARGET_WORDS_BIGENDIAN
    be = 1;
#else
    be = 0;
#endif
    if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
                               dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
                               sector_len, verdex_rom / sector_len,
                               2, 0, 0, 0, 0, be)) {
        error_report("Error registering flash memory");
        exit(1);
    }

    /* Interrupt line of NIC is connected to GPIO line 99 */
    smc91c111_init(&nd_table[0], 0x04000300,
                    qdev_get_gpio_in(cpu->gpio, 99));
}

static void connex_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);

    mc->desc = "Gumstix Connex (PXA255)";
    mc->init = connex_init;
    mc->ignore_memory_transaction_failures = true;
}

static const TypeInfo connex_type = {
    .name = MACHINE_TYPE_NAME("connex"),
    .parent = TYPE_MACHINE,
    .class_init = connex_class_init,
};

static void verdex_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);

    mc->desc = "Gumstix Verdex (PXA270)";
    mc->init = verdex_init;
    mc->ignore_memory_transaction_failures = true;
    mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
}

static const TypeInfo verdex_type = {
    .name = MACHINE_TYPE_NAME("verdex"),
    .parent = TYPE_MACHINE,
    .class_init = verdex_class_init,
};

static void gumstix_machine_init(void)
{
    type_register_static(&connex_type);
    type_register_static(&verdex_type);
}

type_init(gumstix_machine_init)
