/*
 * TI OMAP general purpose memory controller emulation.
 *
 * Copyright (C) 2007-2009 Nokia Corporation
 * Original code written by Andrzej Zaborowski <andrew@openedhand.com>
 * Enhancements for OMAP3 and NAND support written by Juha Riihimäki
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 or
 * (at your option) any later version of the License.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */
#include "hw/hw.h"
#include "hw/block/flash.h"
#include "hw/arm/omap.h"
#include "exec/memory.h"
#include "exec/address-spaces.h"

/* General-Purpose Memory Controller */
struct omap_gpmc_s {
    qemu_irq irq;
    qemu_irq drq;
    MemoryRegion iomem;
    int accept_256;

    uint8_t revision;
    uint8_t sysconfig;
    uint16_t irqst;
    uint16_t irqen;
    uint16_t lastirq;
    uint16_t timeout;
    uint16_t config;
    struct omap_gpmc_cs_file_s {
        uint32_t config[7];
        MemoryRegion *iomem;
        MemoryRegion container;
        MemoryRegion nandiomem;
        DeviceState *dev;
    } cs_file[8];
    int ecc_cs;
    int ecc_ptr;
    uint32_t ecc_cfg;
    ECCState ecc[9];
    struct prefetch {
        uint32_t config1; /* GPMC_PREFETCH_CONFIG1 */
        uint32_t transfercount; /* GPMC_PREFETCH_CONFIG2:TRANSFERCOUNT */
        int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */
        int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */
        int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */
        MemoryRegion iomem;
        uint8_t fifo[64];
    } prefetch;
};

#define OMAP_GPMC_8BIT 0
#define OMAP_GPMC_16BIT 1
#define OMAP_GPMC_NOR 0
#define OMAP_GPMC_NAND 2

static int omap_gpmc_devtype(struct omap_gpmc_cs_file_s *f)
{
    return (f->config[0] >> 10) & 3;
}

static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f)
{
    /* devsize field is really 2 bits but we ignore the high
     * bit to ensure consistent behaviour if the guest sets
     * it (values 2 and 3 are reserved in the TRM)
     */
    return (f->config[0] >> 12) & 1;
}

/* Extract the chip-select value from the prefetch config1 register */
static int prefetch_cs(uint32_t config1)
{
    return (config1 >> 24) & 7;
}

static int prefetch_threshold(uint32_t config1)
{
    return (config1 >> 8) & 0x7f;
}

static void omap_gpmc_int_update(struct omap_gpmc_s *s)
{
    /* The TRM is a bit unclear, but it seems to say that
     * the TERMINALCOUNTSTATUS bit is set only on the
     * transition when the prefetch engine goes from
     * active to inactive, whereas the FIFOEVENTSTATUS
     * bit is held high as long as the fifo has at
     * least THRESHOLD bytes available.
     * So we do the latter here, but TERMINALCOUNTSTATUS
     * is set elsewhere.
     */
    if (s->prefetch.fifopointer >= prefetch_threshold(s->prefetch.config1)) {
        s->irqst |= 1;
    }
    if ((s->irqen & s->irqst) != s->lastirq) {
        s->lastirq = s->irqen & s->irqst;
        qemu_set_irq(s->irq, s->lastirq);
    }
}

static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
{
    if (s->prefetch.config1 & 4) {
        qemu_set_irq(s->drq, value);
    }
}

/* Access functions for when a NAND-like device is mapped into memory:
 * all addresses in the region behave like accesses to the relevant
 * GPMC_NAND_DATA_i register (which is actually implemented to call these)
 */
static uint64_t omap_nand_read(void *opaque, hwaddr addr,
                               unsigned size)
{
    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
    uint64_t v;
    nand_setpins(f->dev, 0, 0, 0, 1, 0);
    switch (omap_gpmc_devsize(f)) {
    case OMAP_GPMC_8BIT:
        v = nand_getio(f->dev);
        if (size == 1) {
            return v;
        }
        v |= (nand_getio(f->dev) << 8);
        if (size == 2) {
            return v;
        }
        v |= (nand_getio(f->dev) << 16);
        v |= (nand_getio(f->dev) << 24);
        return v;
    case OMAP_GPMC_16BIT:
        v = nand_getio(f->dev);
        if (size == 1) {
            /* 8 bit read from 16 bit device : probably a guest bug */
            return v & 0xff;
        }
        if (size == 2) {
            return v;
        }
        v |= (nand_getio(f->dev) << 16);
        return v;
    default:
        abort();
    }
}

static void omap_nand_setio(DeviceState *dev, uint64_t value,
                            int nandsize, int size)
{
    /* Write the specified value to the NAND device, respecting
     * both size of the NAND device and size of the write access.
     */
    switch (nandsize) {
    case OMAP_GPMC_8BIT:
        switch (size) {
        case 1:
            nand_setio(dev, value & 0xff);
            break;
        case 2:
            nand_setio(dev, value & 0xff);
            nand_setio(dev, (value >> 8) & 0xff);
            break;
        case 4:
        default:
            nand_setio(dev, value & 0xff);
            nand_setio(dev, (value >> 8) & 0xff);
            nand_setio(dev, (value >> 16) & 0xff);
            nand_setio(dev, (value >> 24) & 0xff);
            break;
        }
        break;
    case OMAP_GPMC_16BIT:
        switch (size) {
        case 1:
            /* writing to a 16bit device with 8bit access is probably a guest
             * bug; pass the value through anyway.
             */
        case 2:
            nand_setio(dev, value & 0xffff);
            break;
        case 4:
        default:
            nand_setio(dev, value & 0xffff);
            nand_setio(dev, (value >> 16) & 0xffff);
            break;
        }
        break;
    }
}

static void omap_nand_write(void *opaque, hwaddr addr,
                            uint64_t value, unsigned size)
{
    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
    nand_setpins(f->dev, 0, 0, 0, 1, 0);
    omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
}

static const MemoryRegionOps omap_nand_ops = {
    .read = omap_nand_read,
    .write = omap_nand_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void fill_prefetch_fifo(struct omap_gpmc_s *s)
{
    /* Fill the prefetch FIFO by reading data from NAND.
     * We do this synchronously, unlike the hardware which
     * will do this asynchronously. We refill when the
     * FIFO has THRESHOLD bytes free, and we always refill
     * as much data as possible starting at the top end
     * of the FIFO.
     * (We have to refill at THRESHOLD rather than waiting
     * for the FIFO to empty to allow for the case where
     * the FIFO size isn't an exact multiple of THRESHOLD
     * and we're doing DMA transfers.)
     * This means we never need to handle wrap-around in
     * the fifo-reading code, and the next byte of data
     * to read is always fifo[63 - fifopointer].
     */
    int fptr;
    int cs = prefetch_cs(s->prefetch.config1);
    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
    int bytes;
    /* Don't believe the bit of the OMAP TRM that says that COUNTVALUE
     * and TRANSFERCOUNT are in units of 16 bit words for 16 bit NAND.
     * Instead believe the bit that says it is always a byte count.
     */
    bytes = 64 - s->prefetch.fifopointer;
    if (bytes > s->prefetch.count) {
        bytes = s->prefetch.count;
    }
    s->prefetch.count -= bytes;
    s->prefetch.fifopointer += bytes;
    fptr = 64 - s->prefetch.fifopointer;
    /* Move the existing data in the FIFO so it sits just
     * before what we're about to read in
     */
    while (fptr < (64 - bytes)) {
        s->prefetch.fifo[fptr] = s->prefetch.fifo[fptr + bytes];
        fptr++;
    }
    while (fptr < 64) {
        if (is16bit) {
            uint32_t v = omap_nand_read(&s->cs_file[cs], 0, 2);
            s->prefetch.fifo[fptr++] = v & 0xff;
            s->prefetch.fifo[fptr++] = (v >> 8) & 0xff;
        } else {
            s->prefetch.fifo[fptr++] = omap_nand_read(&s->cs_file[cs], 0, 1);
        }
    }
    if (s->prefetch.startengine && (s->prefetch.count == 0)) {
        /* This was the final transfer: raise TERMINALCOUNTSTATUS */
        s->irqst |= 2;
        s->prefetch.startengine = 0;
    }
    /* If there are any bytes in the FIFO at this point then
     * we must raise a DMA request (either this is a final part
     * transfer, or we filled the FIFO in which case we certainly
     * have THRESHOLD bytes available)
     */
    if (s->prefetch.fifopointer != 0) {
        omap_gpmc_dma_update(s, 1);
    }
    omap_gpmc_int_update(s);
}

/* Access functions for a NAND-like device when the prefetch/postwrite
 * engine is enabled -- all addresses in the region behave alike:
 * data is read or written to the FIFO.
 */
static uint64_t omap_gpmc_prefetch_read(void *opaque, hwaddr addr,
                                        unsigned size)
{
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
    uint32_t data;
    if (s->prefetch.config1 & 1) {
        /* The TRM doesn't define the behaviour if you read from the
         * FIFO when the prefetch engine is in write mode. We choose
         * to always return zero.
         */
        return 0;
    }
    /* Note that trying to read an empty fifo repeats the last byte */
    if (s->prefetch.fifopointer) {
        s->prefetch.fifopointer--;
    }
    data = s->prefetch.fifo[63 - s->prefetch.fifopointer];
    if (s->prefetch.fifopointer ==
        (64 - prefetch_threshold(s->prefetch.config1))) {
        /* We've drained THRESHOLD bytes now. So deassert the
         * DMA request, then refill the FIFO (which will probably
         * assert it again.)
         */
        omap_gpmc_dma_update(s, 0);
        fill_prefetch_fifo(s);
    }
    omap_gpmc_int_update(s);
    return data;
}

static void omap_gpmc_prefetch_write(void *opaque, hwaddr addr,
                                     uint64_t value, unsigned size)
{
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
    int cs = prefetch_cs(s->prefetch.config1);
    if ((s->prefetch.config1 & 1) == 0) {
        /* The TRM doesn't define the behaviour of writing to the
         * FIFO when the prefetch engine is in read mode. We
         * choose to ignore the write.
         */
        return;
    }
    if (s->prefetch.count == 0) {
        /* The TRM doesn't define the behaviour of writing to the
         * FIFO if the transfer is complete. We choose to ignore.
         */
        return;
    }
    /* The only reason we do any data buffering in postwrite
     * mode is if we are talking to a 16 bit NAND device, in
     * which case we need to buffer the first byte of the
     * 16 bit word until the other byte arrives.
     */
    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
    if (is16bit) {
        /* fifopointer alternates between 64 (waiting for first
         * byte of word) and 63 (waiting for second byte)
         */
        if (s->prefetch.fifopointer == 64) {
            s->prefetch.fifo[0] = value;
            s->prefetch.fifopointer--;
        } else {
            value = (value << 8) | s->prefetch.fifo[0];
            omap_nand_write(&s->cs_file[cs], 0, value, 2);
            s->prefetch.count--;
            s->prefetch.fifopointer = 64;
        }
    } else {
        /* Just write the byte : fifopointer remains 64 at all times */
        omap_nand_write(&s->cs_file[cs], 0, value, 1);
        s->prefetch.count--;
    }
    if (s->prefetch.count == 0) {
        /* Final transfer: raise TERMINALCOUNTSTATUS */
        s->irqst |= 2;
        s->prefetch.startengine = 0;
    }
    omap_gpmc_int_update(s);
}

static const MemoryRegionOps omap_prefetch_ops = {
    .read = omap_gpmc_prefetch_read,
    .write = omap_gpmc_prefetch_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl.min_access_size = 1,
    .impl.max_access_size = 1,
};

static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs)
{
    /* Return the MemoryRegion* to map/unmap for this chipselect */
    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
    if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) {
        return f->iomem;
    }
    if ((s->prefetch.config1 & 0x80) &&
        (prefetch_cs(s->prefetch.config1) == cs)) {
        /* The prefetch engine is enabled for this CS: map the FIFO */
        return &s->prefetch.iomem;
    }
    return &f->nandiomem;
}

static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
{
    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
    uint32_t mask = (f->config[6] >> 8) & 0xf;
    uint32_t base = f->config[6] & 0x3f;
    uint32_t size;

    if (!f->iomem && !f->dev) {
        return;
    }

    if (!(f->config[6] & (1 << 6))) {
        /* Do nothing unless CSVALID */
        return;
    }

    /* TODO: check for overlapping regions and report access errors */
    if (mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf
         && !(s->accept_256 && !mask)) {
        fprintf(stderr, "%s: invalid chip-select mask address (0x%x)\n",
                 __func__, mask);
    }

    base <<= 24;
    size = (0x0fffffff & ~(mask << 24)) + 1;
    /* TODO: rather than setting the size of the mapping (which should be
     * constant), the mask should cause wrapping of the address space, so
     * that the same memory becomes accessible at every <i>size</i> bytes
     * starting from <i>base</i>.  */
    memory_region_init(&f->container, NULL, "omap-gpmc-file", size);
    memory_region_add_subregion(&f->container, 0,
                                omap_gpmc_cs_memregion(s, cs));
    memory_region_add_subregion(get_system_memory(), base,
                                &f->container);
}

static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
{
    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
    if (!(f->config[6] & (1 << 6))) {
        /* Do nothing unless CSVALID */
        return;
    }
    if (!f->iomem && !f->dev) {
        return;
    }
    memory_region_del_subregion(get_system_memory(), &f->container);
    memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs));
    memory_region_destroy(&f->container);
}

void omap_gpmc_reset(struct omap_gpmc_s *s)
{
    int i;

    s->sysconfig = 0;
    s->irqst = 0;
    s->irqen = 0;
    omap_gpmc_int_update(s);
    for (i = 0; i < 8; i++) {
        /* This has to happen before we change any of the config
         * used to determine which memory regions are mapped or unmapped.
         */
        omap_gpmc_cs_unmap(s, i);
    }
    s->timeout = 0;
    s->config = 0xa00;
    s->prefetch.config1 = 0x00004000;
    s->prefetch.transfercount = 0x00000000;
    s->prefetch.startengine = 0;
    s->prefetch.fifopointer = 0;
    s->prefetch.count = 0;
    for (i = 0; i < 8; i ++) {
        s->cs_file[i].config[1] = 0x101001;
        s->cs_file[i].config[2] = 0x020201;
        s->cs_file[i].config[3] = 0x10031003;
        s->cs_file[i].config[4] = 0x10f1111;
        s->cs_file[i].config[5] = 0;
        s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);

        s->cs_file[i].config[6] = 0xf00;
        /* In theory we could probe attached devices for some CFG1
         * bits here, but we just retain them across resets as they
         * were set initially by omap_gpmc_attach().
         */
        if (i == 0) {
            s->cs_file[i].config[0] &= 0x00433e00;
            s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */
            omap_gpmc_cs_map(s, i);
        } else {
            s->cs_file[i].config[0] &= 0x00403c00;
        }
    }
    s->ecc_cs = 0;
    s->ecc_ptr = 0;
    s->ecc_cfg = 0x3fcff000;
    for (i = 0; i < 9; i ++)
        ecc_reset(&s->ecc[i]);
}

static int gpmc_wordaccess_only(hwaddr addr)
{
    /* Return true if the register offset is to a register that
     * only permits word width accesses.
     * Non-word accesses are only OK for GPMC_NAND_DATA/ADDRESS/COMMAND
     * for any chipselect.
     */
    if (addr >= 0x60 && addr <= 0x1d4) {
        int cs = (addr - 0x60) / 0x30;
        addr -= cs * 0x30;
        if (addr >= 0x7c && addr < 0x88) {
            /* GPMC_NAND_COMMAND, GPMC_NAND_ADDRESS, GPMC_NAND_DATA */
            return 0;
        }
    }
    return 1;
}

static uint64_t omap_gpmc_read(void *opaque, hwaddr addr,
                               unsigned size)
{
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
    int cs;
    struct omap_gpmc_cs_file_s *f;

    if (size != 4 && gpmc_wordaccess_only(addr)) {
        return omap_badwidth_read32(opaque, addr);
    }

    switch (addr) {
    case 0x000:	/* GPMC_REVISION */
        return s->revision;

    case 0x010:	/* GPMC_SYSCONFIG */
        return s->sysconfig;

    case 0x014:	/* GPMC_SYSSTATUS */
        return 1;						/* RESETDONE */

    case 0x018:	/* GPMC_IRQSTATUS */
        return s->irqst;

    case 0x01c:	/* GPMC_IRQENABLE */
        return s->irqen;

    case 0x040:	/* GPMC_TIMEOUT_CONTROL */
        return s->timeout;

    case 0x044:	/* GPMC_ERR_ADDRESS */
    case 0x048:	/* GPMC_ERR_TYPE */
        return 0;

    case 0x050:	/* GPMC_CONFIG */
        return s->config;

    case 0x054:	/* GPMC_STATUS */
        return 0x001;

    case 0x060 ... 0x1d4:
        cs = (addr - 0x060) / 0x30;
        addr -= cs * 0x30;
        f = s->cs_file + cs;
        switch (addr) {
        case 0x60:      /* GPMC_CONFIG1 */
            return f->config[0];
        case 0x64:      /* GPMC_CONFIG2 */
            return f->config[1];
        case 0x68:      /* GPMC_CONFIG3 */
            return f->config[2];
        case 0x6c:      /* GPMC_CONFIG4 */
            return f->config[3];
        case 0x70:      /* GPMC_CONFIG5 */
            return f->config[4];
        case 0x74:      /* GPMC_CONFIG6 */
            return f->config[5];
        case 0x78:      /* GPMC_CONFIG7 */
            return f->config[6];
        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                return omap_nand_read(f, 0, size);
            }
            return 0;
        }
        break;

    case 0x1e0:	/* GPMC_PREFETCH_CONFIG1 */
        return s->prefetch.config1;
    case 0x1e4:	/* GPMC_PREFETCH_CONFIG2 */
        return s->prefetch.transfercount;
    case 0x1ec:	/* GPMC_PREFETCH_CONTROL */
        return s->prefetch.startengine;
    case 0x1f0:	/* GPMC_PREFETCH_STATUS */
        /* NB: The OMAP3 TRM is inconsistent about whether the GPMC
         * FIFOTHRESHOLDSTATUS bit should be set when
         * FIFOPOINTER > FIFOTHRESHOLD or when it is >= FIFOTHRESHOLD.
         * Apparently the underlying functional spec from which the TRM was
         * created states that the behaviour is ">=", and this also
         * makes more conceptual sense.
         */
        return (s->prefetch.fifopointer << 24) |
                ((s->prefetch.fifopointer >=
                  ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) |
                s->prefetch.count;

    case 0x1f4:	/* GPMC_ECC_CONFIG */
        return s->ecc_cs;
    case 0x1f8:	/* GPMC_ECC_CONTROL */
        return s->ecc_ptr;
    case 0x1fc:	/* GPMC_ECC_SIZE_CONFIG */
        return s->ecc_cfg;
    case 0x200 ... 0x220:	/* GPMC_ECC_RESULT */
        cs = (addr & 0x1f) >> 2;
        /* TODO: check correctness */
        return
                ((s->ecc[cs].cp    &  0x07) <<  0) |
                ((s->ecc[cs].cp    &  0x38) << 13) |
                ((s->ecc[cs].lp[0] & 0x1ff) <<  3) |
                ((s->ecc[cs].lp[1] & 0x1ff) << 19);

    case 0x230:	/* GPMC_TESTMODE_CTRL */
        return 0;
    case 0x234:	/* GPMC_PSA_LSB */
    case 0x238:	/* GPMC_PSA_MSB */
        return 0x00000000;
    }

    OMAP_BAD_REG(addr);
    return 0;
}

static void omap_gpmc_write(void *opaque, hwaddr addr,
                            uint64_t value, unsigned size)
{
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
    int cs;
    struct omap_gpmc_cs_file_s *f;

    if (size != 4 && gpmc_wordaccess_only(addr)) {
        return omap_badwidth_write32(opaque, addr, value);
    }

    switch (addr) {
    case 0x000:	/* GPMC_REVISION */
    case 0x014:	/* GPMC_SYSSTATUS */
    case 0x054:	/* GPMC_STATUS */
    case 0x1f0:	/* GPMC_PREFETCH_STATUS */
    case 0x200 ... 0x220:	/* GPMC_ECC_RESULT */
    case 0x234:	/* GPMC_PSA_LSB */
    case 0x238:	/* GPMC_PSA_MSB */
        OMAP_RO_REG(addr);
        break;

    case 0x010:	/* GPMC_SYSCONFIG */
        if ((value >> 3) == 0x3)
            fprintf(stderr, "%s: bad SDRAM idle mode %"PRIi64"\n",
                            __FUNCTION__, value >> 3);
        if (value & 2)
            omap_gpmc_reset(s);
        s->sysconfig = value & 0x19;
        break;

    case 0x018:	/* GPMC_IRQSTATUS */
        s->irqst &= ~value;
        omap_gpmc_int_update(s);
        break;

    case 0x01c:	/* GPMC_IRQENABLE */
        s->irqen = value & 0xf03;
        omap_gpmc_int_update(s);
        break;

    case 0x040:	/* GPMC_TIMEOUT_CONTROL */
        s->timeout = value & 0x1ff1;
        break;

    case 0x044:	/* GPMC_ERR_ADDRESS */
    case 0x048:	/* GPMC_ERR_TYPE */
        break;

    case 0x050:	/* GPMC_CONFIG */
        s->config = value & 0xf13;
        break;

    case 0x060 ... 0x1d4:
        cs = (addr - 0x060) / 0x30;
        addr -= cs * 0x30;
        f = s->cs_file + cs;
        switch (addr) {
        case 0x60:      /* GPMC_CONFIG1 */
            f->config[0] = value & 0xffef3e13;
            break;
        case 0x64:      /* GPMC_CONFIG2 */
            f->config[1] = value & 0x001f1f8f;
            break;
        case 0x68:      /* GPMC_CONFIG3 */
            f->config[2] = value & 0x001f1f8f;
            break;
        case 0x6c:      /* GPMC_CONFIG4 */
            f->config[3] = value & 0x1f8f1f8f;
            break;
        case 0x70:      /* GPMC_CONFIG5 */
            f->config[4] = value & 0x0f1f1f1f;
            break;
        case 0x74:      /* GPMC_CONFIG6 */
            f->config[5] = value & 0x00000fcf;
            break;
        case 0x78:      /* GPMC_CONFIG7 */
            if ((f->config[6] ^ value) & 0xf7f) {
                omap_gpmc_cs_unmap(s, cs);
                f->config[6] = value & 0x00000f7f;
                omap_gpmc_cs_map(s, cs);
            }
            break;
        case 0x7c ... 0x7f: /* GPMC_NAND_COMMAND */
            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                nand_setpins(f->dev, 1, 0, 0, 1, 0); /* CLE */
                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
            }
            break;
        case 0x80 ... 0x83: /* GPMC_NAND_ADDRESS */
            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                nand_setpins(f->dev, 0, 1, 0, 1, 0); /* ALE */
                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
            }
            break;
        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                omap_nand_write(f, 0, value, size);
            }
            break;
        default:
            goto bad_reg;
        }
        break;

    case 0x1e0:	/* GPMC_PREFETCH_CONFIG1 */
        if (!s->prefetch.startengine) {
            uint32_t newconfig1 = value & 0x7f8f7fbf;
            uint32_t changed;
            changed = newconfig1 ^ s->prefetch.config1;
            if (changed & (0x80 | 0x7000000)) {
                /* Turning the engine on or off, or mapping it somewhere else.
                 * cs_map() and cs_unmap() check the prefetch config and
                 * overall CSVALID bits, so it is sufficient to unmap-and-map
                 * both the old cs and the new one. Note that we adhere to
                 * the "unmap/change config/map" order (and not unmap twice
                 * if newcs == oldcs), otherwise we'll try to delete the wrong
                 * memory region.
                 */
                int oldcs = prefetch_cs(s->prefetch.config1);
                int newcs = prefetch_cs(newconfig1);
                omap_gpmc_cs_unmap(s, oldcs);
                if (oldcs != newcs) {
                    omap_gpmc_cs_unmap(s, newcs);
                }
                s->prefetch.config1 = newconfig1;
                omap_gpmc_cs_map(s, oldcs);
                if (oldcs != newcs) {
                    omap_gpmc_cs_map(s, newcs);
                }
            } else {
                s->prefetch.config1 = newconfig1;
            }
        }
        break;

    case 0x1e4:	/* GPMC_PREFETCH_CONFIG2 */
        if (!s->prefetch.startengine) {
            s->prefetch.transfercount = value & 0x3fff;
        }
        break;

    case 0x1ec:	/* GPMC_PREFETCH_CONTROL */
        if (s->prefetch.startengine != (value & 1)) {
            s->prefetch.startengine = value & 1;
            if (s->prefetch.startengine) {
                /* Prefetch engine start */
                s->prefetch.count = s->prefetch.transfercount;
                if (s->prefetch.config1 & 1) {
                    /* Write */
                    s->prefetch.fifopointer = 64;
                } else {
                    /* Read */
                    s->prefetch.fifopointer = 0;
                    fill_prefetch_fifo(s);
                }
            } else {
                /* Prefetch engine forcibly stopped. The TRM
                 * doesn't define the behaviour if you do this.
                 * We clear the prefetch count, which means that
                 * we permit no more writes, and don't read any
                 * more data from NAND. The CPU can still drain
                 * the FIFO of unread data.
                 */
                s->prefetch.count = 0;
            }
            omap_gpmc_int_update(s);
        }
        break;

    case 0x1f4:	/* GPMC_ECC_CONFIG */
        s->ecc_cs = 0x8f;
        break;
    case 0x1f8:	/* GPMC_ECC_CONTROL */
        if (value & (1 << 8))
            for (cs = 0; cs < 9; cs ++)
                ecc_reset(&s->ecc[cs]);
        s->ecc_ptr = value & 0xf;
        if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
            s->ecc_ptr = 0;
            s->ecc_cs &= ~1;
        }
        break;
    case 0x1fc:	/* GPMC_ECC_SIZE_CONFIG */
        s->ecc_cfg = value & 0x3fcff1ff;
        break;
    case 0x230:	/* GPMC_TESTMODE_CTRL */
        if (value & 7)
            fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
        break;

    default:
    bad_reg:
        OMAP_BAD_REG(addr);
        return;
    }
}

static const MemoryRegionOps omap_gpmc_ops = {
    .read = omap_gpmc_read,
    .write = omap_gpmc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
                                   hwaddr base,
                                   qemu_irq irq, qemu_irq drq)
{
    int cs;
    struct omap_gpmc_s *s = (struct omap_gpmc_s *)
            g_malloc0(sizeof(struct omap_gpmc_s));

    memory_region_init_io(&s->iomem, NULL, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
    memory_region_add_subregion(get_system_memory(), base, &s->iomem);

    s->irq = irq;
    s->drq = drq;
    s->accept_256 = cpu_is_omap3630(mpu);
    s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
    s->lastirq = 0;
    omap_gpmc_reset(s);

    /* We have to register a different IO memory handler for each
     * chip select region in case a NAND device is mapped there. We
     * make the region the worst-case size of 256MB and rely on the
     * container memory region in cs_map to chop it down to the actual
     * guest-requested size.
     */
    for (cs = 0; cs < 8; cs++) {
        memory_region_init_io(&s->cs_file[cs].nandiomem, NULL,
                              &omap_nand_ops,
                              &s->cs_file[cs],
                              "omap-nand",
                              256 * 1024 * 1024);
    }

    memory_region_init_io(&s->prefetch.iomem, NULL, &omap_prefetch_ops, s,
                          "omap-gpmc-prefetch", 256 * 1024 * 1024);
    return s;
}

void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
{
    struct omap_gpmc_cs_file_s *f;
    assert(iomem);

    if (cs < 0 || cs >= 8) {
        fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
        exit(-1);
    }
    f = &s->cs_file[cs];

    omap_gpmc_cs_unmap(s, cs);
    f->config[0] &= ~(0xf << 10);
    f->iomem = iomem;
    omap_gpmc_cs_map(s, cs);
}

void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand)
{
    struct omap_gpmc_cs_file_s *f;
    assert(nand);

    if (cs < 0 || cs >= 8) {
        fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs);
        exit(-1);
    }
    f = &s->cs_file[cs];

    omap_gpmc_cs_unmap(s, cs);
    f->config[0] &= ~(0xf << 10);
    f->config[0] |= (OMAP_GPMC_NAND << 10);
    f->dev = nand;
    if (nand_getbuswidth(f->dev) == 16) {
        f->config[0] |= OMAP_GPMC_16BIT << 12;
    }
    omap_gpmc_cs_map(s, cs);
}
