/*
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include "qemu-common.h"
#include "flash.h"
#include "irq.h"
#include "sysemu.h"
#include "block.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)

struct onenand_s {
    uint32_t id;
    int shift;
    target_phys_addr_t base;
    qemu_irq intr;
    qemu_irq rdy;
    BlockDriverState *bdrv;
    BlockDriverState *bdrv_cur;
    uint8_t *image;
    uint8_t *otp;
    uint8_t *current;
    ram_addr_t ram;
    uint8_t *boot[2];
    uint8_t *data[2][2];
    int iomemtype;
    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;

    struct ecc_state_s ecc;

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

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,
};

void onenand_base_update(void *opaque, target_phys_addr_t new)
{
    struct onenand_s *s = (struct onenand_s *) opaque;

    s->base = new;

    /* 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.  */
    cpu_register_physical_memory(s->base + (0x0000 << s->shift),
                    0x0200 << s->shift, s->iomemtype);
    cpu_register_physical_memory(s->base + (0x0200 << s->shift),
                    0xbe00 << s->shift,
                    (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM);
    if (s->iomemtype)
        cpu_register_physical_memory(s->base + (0xc000 << s->shift),
                        0x4000 << s->shift, s->iomemtype);
}

void onenand_base_unmap(void *opaque)
{
    struct onenand_s *s = (struct onenand_s *) opaque;

    cpu_register_physical_memory(s->base,
                    0x10000 << s->shift, IO_MEM_UNASSIGNED);
}

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

/* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
static void onenand_reset(struct onenand_s *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->bdrv_cur = s->bdrv;
    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->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0)
            cpu_abort(cpu_single_env, "%s: Loading the BootRAM failed.\n",
                            __FUNCTION__);
    }
}

static inline int onenand_load_main(struct onenand_s *s, int sec, int secn,
                void *dest)
{
    if (s->bdrv_cur)
        return bdrv_read(s->bdrv_cur, sec, dest, secn) < 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(struct onenand_s *s, int sec, int secn,
                void *src)
{
    if (s->bdrv_cur)
        return bdrv_write(s->bdrv_cur, sec, src, secn) < 0;
    else if (sec + secn > s->secs_cur)
        return 1;

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

    return 0;
}

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

    if (s->bdrv_cur) {
        if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 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(struct onenand_s *s, int sec, int secn,
                void *src)
{
    uint8_t buf[512];

    if (s->bdrv_cur) {
        if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
            return 1;
        memcpy(buf + ((sec & 31) << 4), src, secn << 4);
        return bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0;
    } else if (sec + secn > s->secs_cur)
        return 1;

    memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4);
 
    return 0;
}

static inline int onenand_erase(struct onenand_s *s, int sec, int num)
{
    /* TODO: optimise */
    uint8_t buf[512];

    memset(buf, 0xff, sizeof(buf));
    for (; num > 0; num --, sec ++) {
        if (onenand_prog_main(s, sec, 1, buf))
            return 1;
        if (onenand_prog_spare(s, sec, 1, buf))
            return 1;
    }

    return 0;
}

static void onenand_command(struct onenand_s *s, int cmd)
{
    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 (cmd) {
    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 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->bdrv_cur = 0;
        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;
        fprintf(stderr, "%s: unknown OneNAND command %x\n",
                        __FUNCTION__, cmd);
    }

    onenand_intr_update(s);
}

static uint32_t onenand_read(void *opaque, target_phys_addr_t addr)
{
    struct onenand_s *s = (struct onenand_s *) opaque;
    int offset = (addr - s->base) >> s->shift;

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

    case 0xf000:	/* Manufacturer ID */
        return (s->id >> 16) & 0xff;
    case 0xf001:	/* Device ID */
        return (s->id >>  8) & 0xff;
    /* TODO: get the following values from a real chip!  */
    case 0xf002:	/* Version ID */
        return (s->id >>  0) & 0xff;
    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 */
        cpu_abort(cpu_single_env, "%s: imeplement ECC\n", __FUNCTION__);
        return 0x0000;
    }

    fprintf(stderr, "%s: unknown OneNAND register %x\n",
                    __FUNCTION__, offset);
    return 0;
}

static void onenand_write(void *opaque, target_phys_addr_t addr,
                uint32_t value)
{
    struct onenand_s *s = (struct onenand_s *) opaque;
    int offset = (addr - s->base) >> 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 >> 16) & 0xff;
            s->boot[0][1 << s->shift] = (s->id >>  8) & 0xff;
            s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
            break;

        default:
            fprintf(stderr, "%s: unknown OneNAND boot command %x\n",
                            __FUNCTION__, 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, s->command);
        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:
        fprintf(stderr, "%s: unknown OneNAND register %x\n",
                        __FUNCTION__, offset);
    }
}

static CPUReadMemoryFunc *onenand_readfn[] = {
    onenand_read,	/* TODO */
    onenand_read,
    onenand_read,
};

static CPUWriteMemoryFunc *onenand_writefn[] = {
    onenand_write,	/* TODO */
    onenand_write,
    onenand_write,
};

void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
{
    struct onenand_s *s = (struct onenand_s *) qemu_mallocz(sizeof(*s));
    int bdrv_index = drive_get_index(IF_MTD, 0, 0);
    uint32_t size = 1 << (24 + ((id >> 12) & 7));
    void *ram;

    s->shift = regshift;
    s->intr = irq;
    s->rdy = 0;
    s->id = id;
    s->blocks = size >> BLOCK_SHIFT;
    s->secs = size >> 9;
    s->blockwp = qemu_malloc(s->blocks);
    s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0;
    s->iomemtype = cpu_register_io_memory(0, onenand_readfn,
                    onenand_writefn, s);
    if (bdrv_index == -1)
        s->image = memset(qemu_malloc(size + (size >> 5)),
                        0xff, size + (size >> 5));
    else
        s->bdrv = drives_table[bdrv_index].bdrv;
    s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT),
                    0xff, (64 + 2) << PAGE_SHIFT);
    s->ram = qemu_ram_alloc(0xc000 << s->shift);
    ram = phys_ram_base + 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_reset(s, 1);

    return s;
}
