/*
 * QEMU MIPS Jazz support
 *
 * Copyright (c) 2007-2008 Hervé Poussineau
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu/datadir.h"
#include "hw/clock.h"
#include "hw/mips/mips.h"
#include "hw/intc/i8259.h"
#include "hw/dma/i8257.h"
#include "hw/char/serial.h"
#include "hw/char/parallel.h"
#include "hw/isa/isa.h"
#include "hw/block/fdc.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "net/net.h"
#include "hw/scsi/esp.h"
#include "hw/mips/bios.h"
#include "hw/loader.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/timer/i8254.h"
#include "hw/display/vga.h"
#include "hw/display/bochs-vbe.h"
#include "hw/audio/pcspk.h"
#include "hw/input/i8042.h"
#include "hw/sysbus.h"
#include "sysemu/qtest.h"
#include "sysemu/reset.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/help_option.h"
#ifdef CONFIG_TCG
#include "hw/core/tcg-cpu-ops.h"
#endif /* CONFIG_TCG */

enum jazz_model_e {
    JAZZ_MAGNUM,
    JAZZ_PICA61,
};

static void main_cpu_reset(void *opaque)
{
    MIPSCPU *cpu = opaque;

    cpu_reset(CPU(cpu));
}

static uint64_t rtc_read(void *opaque, hwaddr addr, unsigned size)
{
    uint8_t val;
    address_space_read(&address_space_memory, 0x90000071,
                       MEMTXATTRS_UNSPECIFIED, &val, 1);
    return val;
}

static void rtc_write(void *opaque, hwaddr addr,
                      uint64_t val, unsigned size)
{
    uint8_t buf = val & 0xff;
    address_space_write(&address_space_memory, 0x90000071,
                        MEMTXATTRS_UNSPECIFIED, &buf, 1);
}

static const MemoryRegionOps rtc_ops = {
    .read = rtc_read,
    .write = rtc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static uint64_t dma_dummy_read(void *opaque, hwaddr addr,
                               unsigned size)
{
    /*
     * Nothing to do. That is only to ensure that
     * the current DMA acknowledge cycle is completed.
     */
    return 0xff;
}

static void dma_dummy_write(void *opaque, hwaddr addr,
                            uint64_t val, unsigned size)
{
    /*
     * Nothing to do. That is only to ensure that
     * the current DMA acknowledge cycle is completed.
     */
}

static const MemoryRegionOps dma_dummy_ops = {
    .read = dma_dummy_read,
    .write = dma_dummy_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void mips_jazz_init_net(NICInfo *nd, IOMMUMemoryRegion *rc4030_dma_mr,
                               DeviceState *rc4030, MemoryRegion *dp8393x_prom)
{
    DeviceState *dev;
    SysBusDevice *sysbus;
    int checksum, i;
    uint8_t *prom;

    qemu_check_nic_model(nd, "dp83932");

    dev = qdev_new("dp8393x");
    qdev_set_nic_properties(dev, nd);
    qdev_prop_set_uint8(dev, "it_shift", 2);
    qdev_prop_set_bit(dev, "big_endian", TARGET_BIG_ENDIAN);
    object_property_set_link(OBJECT(dev), "dma_mr",
                             OBJECT(rc4030_dma_mr), &error_abort);
    sysbus = SYS_BUS_DEVICE(dev);
    sysbus_realize_and_unref(sysbus, &error_fatal);
    sysbus_mmio_map(sysbus, 0, 0x80001000);
    sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 4));

    /* Add MAC address with valid checksum to PROM */
    prom = memory_region_get_ram_ptr(dp8393x_prom);
    checksum = 0;
    for (i = 0; i < 6; i++) {
        prom[i] = nd->macaddr.a[i];
        checksum += prom[i];
        if (checksum > 0xff) {
            checksum = (checksum + 1) & 0xff;
        }
    }
    prom[7] = 0xff - checksum;
}

#define MAGNUM_BIOS_SIZE_MAX 0x7e000
#define MAGNUM_BIOS_SIZE                                                       \
        (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)

#define SONIC_PROM_SIZE 0x1000

static void mips_jazz_init(MachineState *machine,
                           enum jazz_model_e jazz_model)
{
    MemoryRegion *address_space = get_system_memory();
    char *filename;
    int bios_size, n;
    Clock *cpuclk;
    MIPSCPU *cpu;
    MIPSCPUClass *mcc;
    CPUMIPSState *env;
    qemu_irq *i8259;
    rc4030_dma *dmas;
    IOMMUMemoryRegion *rc4030_dma_mr;
    MemoryRegion *isa_mem = g_new(MemoryRegion, 1);
    MemoryRegion *isa_io = g_new(MemoryRegion, 1);
    MemoryRegion *rtc = g_new(MemoryRegion, 1);
    MemoryRegion *dma_dummy = g_new(MemoryRegion, 1);
    MemoryRegion *dp8393x_prom = g_new(MemoryRegion, 1);
    DeviceState *dev, *rc4030;
    MMIOKBDState *i8042;
    SysBusDevice *sysbus;
    ISABus *isa_bus;
    ISADevice *pit;
    ISADevice *pcspk;
    DriveInfo *fds[MAX_FD];
    MemoryRegion *bios = g_new(MemoryRegion, 1);
    MemoryRegion *bios2 = g_new(MemoryRegion, 1);
    SysBusESPState *sysbus_esp;
    ESPState *esp;
    static const struct {
        unsigned freq_hz;
        unsigned pll_mult;
    } ext_clk[] = {
        [JAZZ_MAGNUM] = {50000000, 2},
        [JAZZ_PICA61] = {33333333, 4},
    };

    if (machine->ram_size > 256 * MiB) {
        error_report("RAM size more than 256Mb is not supported");
        exit(EXIT_FAILURE);
    }

    cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
    clock_set_hz(cpuclk, ext_clk[jazz_model].freq_hz
                         * ext_clk[jazz_model].pll_mult);

    /* init CPUs */
    cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk);
    env = &cpu->env;
    qemu_register_reset(main_cpu_reset, cpu);

    /*
     * Chipset returns 0 in invalid reads and do not raise data exceptions.
     * However, we can't simply add a global memory region to catch
     * everything, as this would make all accesses including instruction
     * accesses be ignored and not raise exceptions.
     *
     * NOTE: this behaviour of raising exceptions for bad instruction
     * fetches but not bad data accesses was added in commit 54e755588cf1e9
     * to restore behaviour broken by c658b94f6e8c206, but it is not clear
     * whether the real hardware behaves this way. It is possible that
     * real hardware ignores bad instruction fetches as well -- if so then
     * we could replace this hijacking of CPU methods with a simple global
     * memory region that catches all memory accesses, as we do on Malta.
     */
    mcc = MIPS_CPU_GET_CLASS(cpu);
    mcc->no_data_aborts = true;

    /* allocate RAM */
    memory_region_add_subregion(address_space, 0, machine->ram);

    memory_region_init_rom(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE,
                           &error_fatal);
    memory_region_init_alias(bios2, NULL, "mips_jazz.bios", bios,
                             0, MAGNUM_BIOS_SIZE);
    memory_region_add_subregion(address_space, 0x1fc00000LL, bios);
    memory_region_add_subregion(address_space, 0xfff00000LL, bios2);

    /* load the BIOS image. */
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware ?: BIOS_FILENAME);
    if (filename) {
        bios_size = load_image_targphys(filename, 0xfff00000LL,
                                        MAGNUM_BIOS_SIZE);
        g_free(filename);
    } else {
        bios_size = -1;
    }
    if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE)
        && machine->firmware && !qtest_enabled()) {
        error_report("Could not load MIPS bios '%s'", machine->firmware);
        exit(1);
    }

    /* Init CPU internal devices */
    cpu_mips_irq_init_cpu(cpu);
    cpu_mips_clock_init(cpu);

    /* Chipset */
    rc4030 = rc4030_init(&dmas, &rc4030_dma_mr);
    sysbus = SYS_BUS_DEVICE(rc4030);
    sysbus_connect_irq(sysbus, 0, env->irq[6]);
    sysbus_connect_irq(sysbus, 1, env->irq[3]);
    memory_region_add_subregion(address_space, 0x80000000,
                                sysbus_mmio_get_region(sysbus, 0));
    memory_region_add_subregion(address_space, 0xf0000000,
                                sysbus_mmio_get_region(sysbus, 1));
    memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops,
                          NULL, "dummy_dma", 0x1000);
    memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);

    memory_region_init_rom(dp8393x_prom, NULL, "dp8393x-jazz.prom",
                           SONIC_PROM_SIZE, &error_fatal);
    memory_region_add_subregion(address_space, 0x8000b000, dp8393x_prom);

    /* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */
    memory_region_init(isa_io, NULL, "isa-io", 0x00010000);
    memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000);
    memory_region_add_subregion(address_space, 0x90000000, isa_io);
    memory_region_add_subregion(address_space, 0x91000000, isa_mem);
    isa_bus = isa_bus_new(NULL, isa_mem, isa_io, &error_abort);

    /* ISA devices */
    i8259 = i8259_init(isa_bus, env->irq[4]);
    isa_bus_register_input_irqs(isa_bus, i8259);
    i8257_dma_init(isa_bus, 0);
    pit = i8254_pit_init(isa_bus, 0x40, 0, NULL);
    pcspk = isa_new(TYPE_PC_SPEAKER);
    object_property_set_link(OBJECT(pcspk), "pit", OBJECT(pit), &error_fatal);
    isa_realize_and_unref(pcspk, isa_bus, &error_fatal);

    /* Video card */
    switch (jazz_model) {
    case JAZZ_MAGNUM:
        dev = qdev_new("sysbus-g364");
        sysbus = SYS_BUS_DEVICE(dev);
        sysbus_realize_and_unref(sysbus, &error_fatal);
        sysbus_mmio_map(sysbus, 0, 0x60080000);
        sysbus_mmio_map(sysbus, 1, 0x40000000);
        sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 3));
        {
            /* Simple ROM, so user doesn't have to provide one */
            MemoryRegion *rom_mr = g_new(MemoryRegion, 1);
            memory_region_init_rom(rom_mr, NULL, "g364fb.rom", 0x80000,
                                   &error_fatal);
            uint8_t *rom = memory_region_get_ram_ptr(rom_mr);
            memory_region_add_subregion(address_space, 0x60000000, rom_mr);
            rom[0] = 0x10; /* Mips G364 */
        }
        break;
    case JAZZ_PICA61:
        dev = qdev_new(TYPE_VGA_MMIO);
        qdev_prop_set_uint8(dev, "it_shift", 0);
        sysbus = SYS_BUS_DEVICE(dev);
        sysbus_realize_and_unref(sysbus, &error_fatal);
        sysbus_mmio_map(sysbus, 0, 0x60000000);
        sysbus_mmio_map(sysbus, 1, 0x400a0000);
        sysbus_mmio_map(sysbus, 2, VBE_DISPI_LFB_PHYSICAL_ADDRESS);
        break;
    default:
        break;
    }

    /* Network controller */
    if (nb_nics == 1) {
        mips_jazz_init_net(&nd_table[0], rc4030_dma_mr, rc4030, dp8393x_prom);
    } else if (nb_nics > 1) {
        error_report("This machine only supports one NIC");
        exit(1);
    }

    /* SCSI adapter */
    dev = qdev_new(TYPE_SYSBUS_ESP);
    sysbus_esp = SYSBUS_ESP(dev);
    esp = &sysbus_esp->esp;
    esp->dma_memory_read = rc4030_dma_read;
    esp->dma_memory_write = rc4030_dma_write;
    esp->dma_opaque = dmas[0];
    sysbus_esp->it_shift = 0;
    /* XXX for now until rc4030 has been changed to use DMA enable signal */
    esp->dma_enabled = 1;

    sysbus = SYS_BUS_DEVICE(dev);
    sysbus_realize_and_unref(sysbus, &error_fatal);
    sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 5));
    sysbus_mmio_map(sysbus, 0, 0x80002000);

    scsi_bus_legacy_handle_cmdline(&esp->bus);

    /* Floppy */
    for (n = 0; n < MAX_FD; n++) {
        fds[n] = drive_get(IF_FLOPPY, 0, n);
    }
    /* FIXME: we should enable DMA with a custom IsaDma device */
    fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), 0x80003000, fds);

    /* Real time clock */
    mc146818_rtc_init(isa_bus, 1980, NULL);
    memory_region_init_io(rtc, NULL, &rtc_ops, NULL, "rtc", 0x1000);
    memory_region_add_subregion(address_space, 0x80004000, rtc);

    /* Keyboard (i8042) */
    i8042 = I8042_MMIO(qdev_new(TYPE_I8042_MMIO));
    qdev_prop_set_uint64(DEVICE(i8042), "mask", 1);
    qdev_prop_set_uint32(DEVICE(i8042), "size", 0x1000);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(i8042), &error_fatal);

    qdev_connect_gpio_out(DEVICE(i8042), I8042_KBD_IRQ,
                          qdev_get_gpio_in(rc4030, 6));
    qdev_connect_gpio_out(DEVICE(i8042), I8042_MOUSE_IRQ,
                          qdev_get_gpio_in(rc4030, 7));

    memory_region_add_subregion(address_space, 0x80005000,
                                sysbus_mmio_get_region(SYS_BUS_DEVICE(i8042),
                                                       0));

    /* Serial ports */
    serial_mm_init(address_space, 0x80006000, 0,
                   qdev_get_gpio_in(rc4030, 8), 8000000 / 16,
                   serial_hd(0), DEVICE_NATIVE_ENDIAN);
    serial_mm_init(address_space, 0x80007000, 0,
                   qdev_get_gpio_in(rc4030, 9), 8000000 / 16,
                   serial_hd(1), DEVICE_NATIVE_ENDIAN);

    /* Parallel port */
    if (parallel_hds[0])
        parallel_mm_init(address_space, 0x80008000, 0,
                         qdev_get_gpio_in(rc4030, 0), parallel_hds[0]);

    /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */

    /* NVRAM */
    dev = qdev_new("ds1225y");
    sysbus = SYS_BUS_DEVICE(dev);
    sysbus_realize_and_unref(sysbus, &error_fatal);
    sysbus_mmio_map(sysbus, 0, 0x80009000);

    /* LED indicator */
    sysbus_create_simple("jazz-led", 0x8000f000, NULL);

    g_free(dmas);
}

static
void mips_magnum_init(MachineState *machine)
{
    mips_jazz_init(machine, JAZZ_MAGNUM);
}

static
void mips_pica61_init(MachineState *machine)
{
    mips_jazz_init(machine, JAZZ_PICA61);
}

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

    mc->desc = "MIPS Magnum";
    mc->init = mips_magnum_init;
    mc->block_default_type = IF_SCSI;
    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("R4000");
    mc->default_ram_id = "mips_jazz.ram";
}

static const TypeInfo mips_magnum_type = {
    .name = MACHINE_TYPE_NAME("magnum"),
    .parent = TYPE_MACHINE,
    .class_init = mips_magnum_class_init,
};

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

    mc->desc = "Acer Pica 61";
    mc->init = mips_pica61_init;
    mc->block_default_type = IF_SCSI;
    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("R4000");
    mc->default_ram_id = "mips_jazz.ram";
}

static const TypeInfo mips_pica61_type = {
    .name = MACHINE_TYPE_NAME("pica61"),
    .parent = TYPE_MACHINE,
    .class_init = mips_pica61_class_init,
};

static void mips_jazz_machine_init(void)
{
    type_register_static(&mips_magnum_type);
    type_register_static(&mips_pica61_type);
}

type_init(mips_jazz_machine_init)
