/*
 * QEMU IDE Emulation: mmio support (for embedded).
 *
 * Copyright (c) 2003 Fabrice Bellard
 * Copyright (c) 2006 Openedhand Ltd.
 *
 * 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 <hw/hw.h>
#include "block.h"
#include "block_int.h"
#include "sysemu.h"
#include "dma.h"

#include <hw/ide/internal.h>

/***********************************************************/
/* MMIO based ide port
 * This emulates IDE device connected directly to the CPU bus without
 * dedicated ide controller, which is often seen on embedded boards.
 */

typedef struct {
    IDEBus *bus;
    int shift;
} MMIOState;

static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
{
    MMIOState *s = (MMIOState*)opaque;
    IDEBus *bus = s->bus;
    addr >>= s->shift;
    if (addr & 7)
        return ide_ioport_read(bus, addr);
    else
        return ide_data_readw(bus, 0);
}

static void mmio_ide_write (void *opaque, target_phys_addr_t addr,
	uint32_t val)
{
    MMIOState *s = (MMIOState*)opaque;
    IDEBus *bus = s->bus;
    addr >>= s->shift;
    if (addr & 7)
        ide_ioport_write(bus, addr, val);
    else
        ide_data_writew(bus, 0, val);
}

static CPUReadMemoryFunc * const mmio_ide_reads[] = {
    mmio_ide_read,
    mmio_ide_read,
    mmio_ide_read,
};

static CPUWriteMemoryFunc * const mmio_ide_writes[] = {
    mmio_ide_write,
    mmio_ide_write,
    mmio_ide_write,
};

static uint32_t mmio_ide_status_read (void *opaque, target_phys_addr_t addr)
{
    MMIOState *s= (MMIOState*)opaque;
    IDEBus *bus = s->bus;
    return ide_status_read(bus, 0);
}

static void mmio_ide_cmd_write (void *opaque, target_phys_addr_t addr,
	uint32_t val)
{
    MMIOState *s = (MMIOState*)opaque;
    IDEBus *bus = s->bus;
    ide_cmd_write(bus, 0, val);
}

static CPUReadMemoryFunc * const mmio_ide_status[] = {
    mmio_ide_status_read,
    mmio_ide_status_read,
    mmio_ide_status_read,
};

static CPUWriteMemoryFunc * const mmio_ide_cmd[] = {
    mmio_ide_cmd_write,
    mmio_ide_cmd_write,
    mmio_ide_cmd_write,
};

static void mmio_ide_save(QEMUFile* f, void *opaque)
{
    MMIOState *s = opaque;

    idebus_save(f, s->bus);
    ide_save(f, &s->bus->ifs[0]);
    ide_save(f, &s->bus->ifs[1]);
}

static int mmio_ide_load(QEMUFile* f, void *opaque, int version_id)
{
    MMIOState *s = opaque;

    idebus_load(f, s->bus, version_id);
    ide_load(f, &s->bus->ifs[0], version_id);
    ide_load(f, &s->bus->ifs[1], version_id);
    return 0;
}

void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
                    qemu_irq irq, int shift,
                    DriveInfo *hd0, DriveInfo *hd1)
{
    MMIOState *s = qemu_mallocz(sizeof(MMIOState));
    IDEBus *bus = qemu_mallocz(sizeof(*bus));
    int mem1, mem2;

    ide_init2(bus, hd0, hd1, irq);

    s->bus = bus;
    s->shift = shift;

    mem1 = cpu_register_io_memory(mmio_ide_reads, mmio_ide_writes, s);
    mem2 = cpu_register_io_memory(mmio_ide_status, mmio_ide_cmd, s);
    cpu_register_physical_memory(membase, 16 << shift, mem1);
    cpu_register_physical_memory(membase2, 2 << shift, mem2);
    register_savevm("mmio-ide", 0, 3, mmio_ide_save, mmio_ide_load, s);
}

