/*
 * OneNAND flash memories emulation.
 *
 * Copyright (C) 2008 Nokia Corporation
 * Written by Andrzej Zaborowski <andrew@openedhand.com>
 *
 * 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) version 3 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 "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/block/flash.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "sysemu/block-backend.h"
#include "exec/memory.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/module.h"

/* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
#define PAGE_SHIFT	11

/* Fixed */
#define BLOCK_SHIFT	(PAGE_SHIFT + 6)

#define TYPE_ONE_NAND "onenand"
#define ONE_NAND(obj) OBJECT_CHECK(OneNANDState, (obj), TYPE_ONE_NAND)

typedef struct OneNANDState {
    SysBusDevice parent_obj;

    struct {
        uint16_t man;
        uint16_t dev;
        uint16_t ver;
    } id;
    int shift;
    hwaddr base;
    qemu_irq intr;
    qemu_irq rdy;
    BlockBackend *blk;
    BlockBackend *blk_cur;
    uint8_t *image;
    uint8_t *otp;
    uint8_t *current;
    MemoryRegion ram;
    MemoryRegion mapped_ram;
    uint8_t current_direction;
    uint8_t *boot[2];
    uint8_t *data[2][2];
    MemoryRegion iomem;
    MemoryRegion container;
    int cycle;
    int otpmode;

    uint16_t addr[8];
    uint16_t unladdr[8];
    int bufaddr;
    int count;
    uint16_t command;
    uint16_t config[2];
    uint16_t status;
    uint16_t intstatus;
    uint16_t wpstatus;

    ECCState ecc;

    int density_mask;
    int secs;
    int secs_cur;
    int blocks;
    uint8_t *blockwp;
} OneNANDState;

enum {
    ONEN_BUF_BLOCK = 0,
    ONEN_BUF_BLOCK2 = 1,
    ONEN_BUF_DEST_BLOCK = 2,
    ONEN_BUF_DEST_PAGE = 3,
    ONEN_BUF_PAGE = 7,
};

enum {
    ONEN_ERR_CMD = 1 << 10,
    ONEN_ERR_ERASE = 1 << 11,
    ONEN_ERR_PROG = 1 << 12,
    ONEN_ERR_LOAD = 1 << 13,
};

enum {
    ONEN_INT_RESET = 1 << 4,
    ONEN_INT_ERASE = 1 << 5,
    ONEN_INT_PROG = 1 << 6,
    ONEN_INT_LOAD = 1 << 7,
    ONEN_INT = 1 << 15,
};

enum {
    ONEN_LOCK_LOCKTIGHTEN = 1 << 0,
    ONEN_LOCK_LOCKED = 1 << 1,
    ONEN_LOCK_UNLOCKED = 1 << 2,
};

static void onenand_mem_setup(OneNANDState *s)
{
    /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
     * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
     * write boot commands.  Also take note of the BWPS bit.  */
    memory_region_init(&s->container, OBJECT(s), "onenand",
                       0x10000 << s->shift);
    memory_region_add_subregion(&s->container, 0, &s->iomem);
    memory_region_init_alias(&s->mapped_ram, OBJECT(s), "onenand-mapped-ram",
                             &s->ram, 0x0200 << s->shift,
                             0xbe00 << s->shift);
    memory_region_add_subregion_overlap(&s->container,
                                        0x0200 << s->shift,
                                        &s->mapped_ram,
                                        1);
}

static void onenand_intr_update(OneNANDState *s)
{
    qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
}

static int onenand_pre_save(void *opaque)
{
    OneNANDState *s = opaque;
    if (s->current == s->otp) {
        s->current_direction = 1;
    } else if (s->current == s->image) {
        s->current_direction = 2;
    } else {
        s->current_direction = 0;
    }

    return 0;
}

static int onenand_post_load(void *opaque, int version_id)
{
    OneNANDState *s = opaque;
    switch (s->current_direction) {
    case 0:
        break;
    case 1:
        s->current = s->otp;
        break;
    case 2:
        s->current = s->image;
        break;
    default:
        return -1;
    }
    onenand_intr_update(s);
    return 0;
}

static const VMStateDescription vmstate_onenand = {
    .name = "onenand",
    .version_id = 1,
    .minimum_version_id = 1,
    .pre_save = onenand_pre_save,
    .post_load = onenand_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(current_direction, OneNANDState),
        VMSTATE_INT32(cycle, OneNANDState),
        VMSTATE_INT32(otpmode, OneNANDState),
        VMSTATE_UINT16_ARRAY(addr, OneNANDState, 8),
        VMSTATE_UINT16_ARRAY(unladdr, OneNANDState, 8),
        VMSTATE_INT32(bufaddr, OneNANDState),
        VMSTATE_INT32(count, OneNANDState),
        VMSTATE_UINT16(command, OneNANDState),
        VMSTATE_UINT16_ARRAY(config, OneNANDState, 2),
        VMSTATE_UINT16(status, OneNANDState),
        VMSTATE_UINT16(intstatus, OneNANDState),
        VMSTATE_UINT16(wpstatus, OneNANDState),
        VMSTATE_INT32(secs_cur, OneNANDState),
        VMSTATE_PARTIAL_VBUFFER(blockwp, OneNANDState, blocks),
        VMSTATE_UINT8(ecc.cp, OneNANDState),
        VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2),
        VMSTATE_UINT16(ecc.count, OneNANDState),
        VMSTATE_BUFFER_POINTER_UNSAFE(otp, OneNANDState, 0,
            ((64 + 2) << PAGE_SHIFT)),
        VMSTATE_END_OF_LIST()
    }
};

/* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
static void onenand_reset(OneNANDState *s, int cold)
{
    memset(&s->addr, 0, sizeof(s->addr));
    s->command = 0;
    s->count = 1;
    s->bufaddr = 0;
    s->config[0] = 0x40c0;
    s->config[1] = 0x0000;
    onenand_intr_update(s);
    qemu_irq_raise(s->rdy);
    s->status = 0x0000;
    s->intstatus = cold ? 0x8080 : 0x8010;
    s->unladdr[0] = 0;
    s->unladdr[1] = 0;
    s->wpstatus = 0x0002;
    s->cycle = 0;
    s->otpmode = 0;
    s->blk_cur = s->blk;
    s->current = s->image;
    s->secs_cur = s->secs;

    if (cold) {
        /* Lock the whole flash */
        memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);

        if (s->blk_cur && blk_pread(s->blk_cur, 0, s->boot[0],
                                    8 << BDRV_SECTOR_BITS) < 0) {
            hw_error("%s: Loading the BootRAM failed.\n", __func__);
        }
    }
}

static void onenand_system_reset(DeviceState *dev)
{
    OneNANDState *s = ONE_NAND(dev);

    onenand_reset(s, 1);
}

static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
                void *dest)
{
    assert(UINT32_MAX >> BDRV_SECTOR_BITS > sec);
    assert(UINT32_MAX >> BDRV_SECTOR_BITS > secn);
    if (s->blk_cur) {
        return blk_pread(s->blk_cur, sec << BDRV_SECTOR_BITS, dest,
                         secn << BDRV_SECTOR_BITS) < 0;
    } else if (sec + secn > s->secs_cur) {
        return 1;
    }

    memcpy(dest, s->current + (sec << 9), secn << 9);

    return 0;
}

static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
                void *src)
{
    int result = 0;

    if (secn > 0) {
        uint32_t size = secn << BDRV_SECTOR_BITS;
        uint32_t offset = sec << BDRV_SECTOR_BITS;
        assert(UINT32_MAX >> BDRV_SECTOR_BITS > sec);
        assert(UINT32_MAX >> BDRV_SECTOR_BITS > secn);
        const uint8_t *sp = (const uint8_t *)src;
        uint8_t *dp = 0;
        if (s->blk_cur) {
            dp = g_malloc(size);
            if (!dp || blk_pread(s->blk_cur, offset, dp, size) < 0) {
                result = 1;
            }
        } else {
            if (sec + secn > s->secs_cur) {
                result = 1;
            } else {
                dp = (uint8_t *)s->current + offset;
            }
        }
        if (!result) {
            uint32_t i;
            for (i = 0; i < size; i++) {
                dp[i] &= sp[i];
            }
            if (s->blk_cur) {
                result = blk_pwrite(s->blk_cur, offset, dp, size, 0) < 0;
            }
        }
        if (dp && s->blk_cur) {
            g_free(dp);
        }
    }

    return result;
}

static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
                void *dest)
{
    uint8_t buf[512];

    if (s->blk_cur) {
        uint32_t offset = (s->secs_cur + (sec >> 5)) << BDRV_SECTOR_BITS;
        if (blk_pread(s->blk_cur, offset, buf, BDRV_SECTOR_SIZE) < 0) {
            return 1;
        }
        memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
    } else if (sec + secn > s->secs_cur) {
        return 1;
    } else {
        memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
    }

    return 0;
}

static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
                void *src)
{
    int result = 0;
    if (secn > 0) {
        const uint8_t *sp = (const uint8_t *)src;
        uint8_t *dp = 0, *dpp = 0;
        uint32_t offset = (s->secs_cur + (sec >> 5)) << BDRV_SECTOR_BITS;
        assert(UINT32_MAX >> BDRV_SECTOR_BITS > s->secs_cur + (sec >> 5));
        if (s->blk_cur) {
            dp = g_malloc(512);
            if (!dp
                || blk_pread(s->blk_cur, offset, dp, BDRV_SECTOR_SIZE) < 0) {
                result = 1;
            } else {
                dpp = dp + ((sec & 31) << 4);
            }
        } else {
            if (sec + secn > s->secs_cur) {
                result = 1;
            } else {
                dpp = s->current + (s->secs_cur << 9) + (sec << 4);
            }
        }
        if (!result) {
            uint32_t i;
            for (i = 0; i < (secn << 4); i++) {
                dpp[i] &= sp[i];
            }
            if (s->blk_cur) {
                result = blk_pwrite(s->blk_cur, offset, dp,
                                    BDRV_SECTOR_SIZE, 0) < 0;
            }
        }
        g_free(dp);
    }
    return result;
}

static inline int onenand_erase(OneNANDState *s, int sec, int num)
{
    uint8_t *blankbuf, *tmpbuf;

    blankbuf = g_malloc(512);
    tmpbuf = g_malloc(512);
    memset(blankbuf, 0xff, 512);
    for (; num > 0; num--, sec++) {
        if (s->blk_cur) {
            int erasesec = s->secs_cur + (sec >> 5);
            if (blk_pwrite(s->blk_cur, sec << BDRV_SECTOR_BITS, blankbuf,
                           BDRV_SECTOR_SIZE, 0) < 0) {
                goto fail;
            }
            if (blk_pread(s->blk_cur, erasesec << BDRV_SECTOR_BITS, tmpbuf,
                          BDRV_SECTOR_SIZE) < 0) {
                goto fail;
            }
            memcpy(tmpbuf + ((sec & 31) << 4), blankbuf, 1 << 4);
            if (blk_pwrite(s->blk_cur, erasesec << BDRV_SECTOR_BITS, tmpbuf,
                           BDRV_SECTOR_SIZE, 0) < 0) {
                goto fail;
            }
        } else {
            if (sec + 1 > s->secs_cur) {
                goto fail;
            }
            memcpy(s->current + (sec << 9), blankbuf, 512);
            memcpy(s->current + (s->secs_cur << 9) + (sec << 4),
                   blankbuf, 1 << 4);
        }
    }

    g_free(tmpbuf);
    g_free(blankbuf);
    return 0;

fail:
    g_free(tmpbuf);
    g_free(blankbuf);
    return 1;
}

static void onenand_command(OneNANDState *s)
{
    int b;
    int sec;
    void *buf;
#define SETADDR(block, page)			\
    sec = (s->addr[page] & 3) +			\
            ((((s->addr[page] >> 2) & 0x3f) +	\
              (((s->addr[block] & 0xfff) |	\
                (s->addr[block] >> 15 ?		\
                 s->density_mask : 0)) << 6)) << (PAGE_SHIFT - 9));
#define SETBUF_M()				\
    buf = (s->bufaddr & 8) ?			\
            s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0];	\
    buf += (s->bufaddr & 3) << 9;
#define SETBUF_S()				\
    buf = (s->bufaddr & 8) ?			\
            s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1];	\
    buf += (s->bufaddr & 3) << 4;

    switch (s->command) {
    case 0x00:	/* Load single/multiple sector data unit into buffer */
        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)

        SETBUF_M()
        if (onenand_load_main(s, sec, s->count, buf))
            s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;

#if 0
        SETBUF_S()
        if (onenand_load_spare(s, sec, s->count, buf))
            s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
#endif

        /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
         * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
         * then we need two split the read/write into two chunks.
         */
        s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
        break;
    case 0x13:	/* Load single/multiple spare sector into buffer */
        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)

        SETBUF_S()
        if (onenand_load_spare(s, sec, s->count, buf))
            s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;

        /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
         * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
         * then we need two split the read/write into two chunks.
         */
        s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
        break;
    case 0x80:	/* Program single/multiple sector data unit from buffer */
        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)

        SETBUF_M()
        if (onenand_prog_main(s, sec, s->count, buf))
            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;

#if 0
        SETBUF_S()
        if (onenand_prog_spare(s, sec, s->count, buf))
            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
#endif

        /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
         * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
         * then we need two split the read/write into two chunks.
         */
        s->intstatus |= ONEN_INT | ONEN_INT_PROG;
        break;
    case 0x1a:	/* Program single/multiple spare area sector from buffer */
        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)

        SETBUF_S()
        if (onenand_prog_spare(s, sec, s->count, buf))
            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;

        /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
         * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
         * then we need two split the read/write into two chunks.
         */
        s->intstatus |= ONEN_INT | ONEN_INT_PROG;
        break;
    case 0x1b:	/* Copy-back program */
        SETBUF_S()

        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
        if (onenand_load_main(s, sec, s->count, buf))
            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;

        SETADDR(ONEN_BUF_DEST_BLOCK, ONEN_BUF_DEST_PAGE)
        if (onenand_prog_main(s, sec, s->count, buf))
            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;

        /* TODO: spare areas */

        s->intstatus |= ONEN_INT | ONEN_INT_PROG;
        break;

    case 0x23:	/* Unlock NAND array block(s) */
        s->intstatus |= ONEN_INT;

        /* XXX the previous (?) area should be locked automatically */
        for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
            if (b >= s->blocks) {
                s->status |= ONEN_ERR_CMD;
                break;
            }
            if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
                break;

            s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
        }
        break;
    case 0x27:	/* Unlock All NAND array blocks */
        s->intstatus |= ONEN_INT;

        for (b = 0; b < s->blocks; b ++) {
            if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
                break;

            s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
        }
        break;

    case 0x2a:	/* Lock NAND array block(s) */
        s->intstatus |= ONEN_INT;

        for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
            if (b >= s->blocks) {
                s->status |= ONEN_ERR_CMD;
                break;
            }
            if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
                break;

            s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED;
        }
        break;
    case 0x2c:	/* Lock-tight NAND array block(s) */
        s->intstatus |= ONEN_INT;

        for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
            if (b >= s->blocks) {
                s->status |= ONEN_ERR_CMD;
                break;
            }
            if (s->blockwp[b] == ONEN_LOCK_UNLOCKED)
                continue;

            s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN;
        }
        break;

    case 0x71:	/* Erase-Verify-Read */
        s->intstatus |= ONEN_INT;
        break;
    case 0x95:	/* Multi-block erase */
        qemu_irq_pulse(s->intr);
        /* Fall through.  */
    case 0x94:	/* Block erase */
        sec = ((s->addr[ONEN_BUF_BLOCK] & 0xfff) |
                        (s->addr[ONEN_BUF_BLOCK] >> 15 ? s->density_mask : 0))
                << (BLOCK_SHIFT - 9);
        if (onenand_erase(s, sec, 1 << (BLOCK_SHIFT - 9)))
            s->status |= ONEN_ERR_CMD | ONEN_ERR_ERASE;

        s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
        break;
    case 0xb0:	/* Erase suspend */
        break;
    case 0x30:	/* Erase resume */
        s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
        break;

    case 0xf0:	/* Reset NAND Flash core */
        onenand_reset(s, 0);
        break;
    case 0xf3:	/* Reset OneNAND */
        onenand_reset(s, 0);
        break;

    case 0x65:	/* OTP Access */
        s->intstatus |= ONEN_INT;
        s->blk_cur = NULL;
        s->current = s->otp;
        s->secs_cur = 1 << (BLOCK_SHIFT - 9);
        s->addr[ONEN_BUF_BLOCK] = 0;
        s->otpmode = 1;
        break;

    default:
        s->status |= ONEN_ERR_CMD;
        s->intstatus |= ONEN_INT;
        qemu_log_mask(LOG_GUEST_ERROR, "unknown OneNAND command %x\n",
                      s->command);
    }

    onenand_intr_update(s);
}

static uint64_t onenand_read(void *opaque, hwaddr addr,
                             unsigned size)
{
    OneNANDState *s = (OneNANDState *) opaque;
    int offset = addr >> s->shift;

    switch (offset) {
    case 0x0000 ... 0xbffe:
        return lduw_le_p(s->boot[0] + addr);

    case 0xf000:	/* Manufacturer ID */
        return s->id.man;
    case 0xf001:	/* Device ID */
        return s->id.dev;
    case 0xf002:	/* Version ID */
        return s->id.ver;
    /* TODO: get the following values from a real chip!  */
    case 0xf003:	/* Data Buffer size */
        return 1 << PAGE_SHIFT;
    case 0xf004:	/* Boot Buffer size */
        return 0x200;
    case 0xf005:	/* Amount of buffers */
        return 1 | (2 << 8);
    case 0xf006:	/* Technology */
        return 0;

    case 0xf100 ... 0xf107:	/* Start addresses */
        return s->addr[offset - 0xf100];

    case 0xf200:	/* Start buffer */
        return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10)));

    case 0xf220:	/* Command */
        return s->command;
    case 0xf221:	/* System Configuration 1 */
        return s->config[0] & 0xffe0;
    case 0xf222:	/* System Configuration 2 */
        return s->config[1];

    case 0xf240:	/* Controller Status */
        return s->status;
    case 0xf241:	/* Interrupt */
        return s->intstatus;
    case 0xf24c:	/* Unlock Start Block Address */
        return s->unladdr[0];
    case 0xf24d:	/* Unlock End Block Address */
        return s->unladdr[1];
    case 0xf24e:	/* Write Protection Status */
        return s->wpstatus;

    case 0xff00:	/* ECC Status */
        return 0x00;
    case 0xff01:	/* ECC Result of main area data */
    case 0xff02:	/* ECC Result of spare area data */
    case 0xff03:	/* ECC Result of main area data */
    case 0xff04:	/* ECC Result of spare area data */
        qemu_log_mask(LOG_UNIMP,
                      "onenand: ECC result registers unimplemented\n");
        return 0x0000;
    }

    qemu_log_mask(LOG_GUEST_ERROR, "read of unknown OneNAND register 0x%x\n",
                  offset);
    return 0;
}

static void onenand_write(void *opaque, hwaddr addr,
                          uint64_t value, unsigned size)
{
    OneNANDState *s = (OneNANDState *) opaque;
    int offset = addr >> s->shift;
    int sec;

    switch (offset) {
    case 0x0000 ... 0x01ff:
    case 0x8000 ... 0x800f:
        if (s->cycle) {
            s->cycle = 0;

            if (value == 0x0000) {
                SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
                onenand_load_main(s, sec,
                                1 << (PAGE_SHIFT - 9), s->data[0][0]);
                s->addr[ONEN_BUF_PAGE] += 4;
                s->addr[ONEN_BUF_PAGE] &= 0xff;
            }
            break;
        }

        switch (value) {
        case 0x00f0:	/* Reset OneNAND */
            onenand_reset(s, 0);
            break;

        case 0x00e0:	/* Load Data into Buffer */
            s->cycle = 1;
            break;

        case 0x0090:	/* Read Identification Data */
            memset(s->boot[0], 0, 3 << s->shift);
            s->boot[0][0 << s->shift] = s->id.man & 0xff;
            s->boot[0][1 << s->shift] = s->id.dev & 0xff;
            s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
            break;

        default:
            qemu_log_mask(LOG_GUEST_ERROR,
                          "unknown OneNAND boot command %" PRIx64 "\n",
                          value);
        }
        break;

    case 0xf100 ... 0xf107:	/* Start addresses */
        s->addr[offset - 0xf100] = value;
        break;

    case 0xf200:	/* Start buffer */
        s->bufaddr = (value >> 8) & 0xf;
        if (PAGE_SHIFT == 11)
            s->count = (value & 3) ?: 4;
        else if (PAGE_SHIFT == 10)
            s->count = (value & 1) ?: 2;
        break;

    case 0xf220:	/* Command */
        if (s->intstatus & (1 << 15))
            break;
        s->command = value;
        onenand_command(s);
        break;
    case 0xf221:	/* System Configuration 1 */
        s->config[0] = value;
        onenand_intr_update(s);
        qemu_set_irq(s->rdy, (s->config[0] >> 7) & 1);
        break;
    case 0xf222:	/* System Configuration 2 */
        s->config[1] = value;
        break;

    case 0xf241:	/* Interrupt */
        s->intstatus &= value;
        if ((1 << 15) & ~s->intstatus)
            s->status &= ~(ONEN_ERR_CMD | ONEN_ERR_ERASE |
                            ONEN_ERR_PROG | ONEN_ERR_LOAD);
        onenand_intr_update(s);
        break;
    case 0xf24c:	/* Unlock Start Block Address */
        s->unladdr[0] = value & (s->blocks - 1);
        /* For some reason we have to set the end address to by default
         * be same as start because the software forgets to write anything
         * in there.  */
        s->unladdr[1] = value & (s->blocks - 1);
        break;
    case 0xf24d:	/* Unlock End Block Address */
        s->unladdr[1] = value & (s->blocks - 1);
        break;

    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "write to unknown OneNAND register 0x%x\n",
                      offset);
    }
}

static const MemoryRegionOps onenand_ops = {
    .read = onenand_read,
    .write = onenand_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void onenand_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    OneNANDState *s = ONE_NAND(dev);
    uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
    void *ram;
    Error *local_err = NULL;

    s->base = (hwaddr)-1;
    s->rdy = NULL;
    s->blocks = size >> BLOCK_SHIFT;
    s->secs = size >> 9;
    s->blockwp = g_malloc(s->blocks);
    s->density_mask = (s->id.dev & 0x08)
        ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0;
    memory_region_init_io(&s->iomem, OBJECT(s), &onenand_ops, s, "onenand",
                          0x10000 << s->shift);
    if (!s->blk) {
        s->image = memset(g_malloc(size + (size >> 5)),
                          0xff, size + (size >> 5));
    } else {
        if (blk_is_read_only(s->blk)) {
            error_setg(errp, "Can't use a read-only drive");
            return;
        }
        blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
                     BLK_PERM_ALL, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            return;
        }
        s->blk_cur = s->blk;
    }
    s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
                    0xff, (64 + 2) << PAGE_SHIFT);
    memory_region_init_ram_nomigrate(&s->ram, OBJECT(s), "onenand.ram",
                           0xc000 << s->shift, &error_fatal);
    vmstate_register_ram_global(&s->ram);
    ram = memory_region_get_ram_ptr(&s->ram);
    s->boot[0] = ram + (0x0000 << s->shift);
    s->boot[1] = ram + (0x8000 << s->shift);
    s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift);
    s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift);
    s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
    s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
    onenand_mem_setup(s);
    sysbus_init_irq(sbd, &s->intr);
    sysbus_init_mmio(sbd, &s->container);
    vmstate_register(VMSTATE_IF(dev),
                     ((s->shift & 0x7f) << 24)
                     | ((s->id.man & 0xff) << 16)
                     | ((s->id.dev & 0xff) << 8)
                     | (s->id.ver & 0xff),
                     &vmstate_onenand, s);
}

static Property onenand_properties[] = {
    DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0),
    DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
    DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
    DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
    DEFINE_PROP_DRIVE("drive", OneNANDState, blk),
    DEFINE_PROP_END_OF_LIST(),
};

static void onenand_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = onenand_realize;
    dc->reset = onenand_system_reset;
    device_class_set_props(dc, onenand_properties);
}

static const TypeInfo onenand_info = {
    .name          = TYPE_ONE_NAND,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(OneNANDState),
    .class_init    = onenand_class_init,
};

static void onenand_register_types(void)
{
    type_register_static(&onenand_info);
}

void *onenand_raw_otp(DeviceState *onenand_device)
{
    OneNANDState *s = ONE_NAND(onenand_device);

    return s->otp;
}

type_init(onenand_register_types)
