qemu/hw/block/onenand.c
<<
>>
Prefs
   1/*
   2 * OneNAND flash memories emulation.
   3 *
   4 * Copyright (C) 2008 Nokia Corporation
   5 * Written by Andrzej Zaborowski <andrew@openedhand.com>
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 or
  10 * (at your option) version 3 of the License.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License along
  18 * with this program; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include "qemu-common.h"
  22#include "hw/hw.h"
  23#include "hw/block/flash.h"
  24#include "hw/irq.h"
  25#include "sysemu/blockdev.h"
  26#include "exec/memory.h"
  27#include "exec/address-spaces.h"
  28#include "hw/sysbus.h"
  29#include "qemu/error-report.h"
  30
  31/* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
  32#define PAGE_SHIFT      11
  33
  34/* Fixed */
  35#define BLOCK_SHIFT     (PAGE_SHIFT + 6)
  36
  37#define TYPE_ONE_NAND "onenand"
  38#define ONE_NAND(obj) OBJECT_CHECK(OneNANDState, (obj), TYPE_ONE_NAND)
  39
  40typedef struct OneNANDState {
  41    SysBusDevice parent_obj;
  42
  43    struct {
  44        uint16_t man;
  45        uint16_t dev;
  46        uint16_t ver;
  47    } id;
  48    int shift;
  49    hwaddr base;
  50    qemu_irq intr;
  51    qemu_irq rdy;
  52    BlockDriverState *bdrv;
  53    BlockDriverState *bdrv_cur;
  54    uint8_t *image;
  55    uint8_t *otp;
  56    uint8_t *current;
  57    MemoryRegion ram;
  58    MemoryRegion mapped_ram;
  59    uint8_t current_direction;
  60    uint8_t *boot[2];
  61    uint8_t *data[2][2];
  62    MemoryRegion iomem;
  63    MemoryRegion container;
  64    int cycle;
  65    int otpmode;
  66
  67    uint16_t addr[8];
  68    uint16_t unladdr[8];
  69    int bufaddr;
  70    int count;
  71    uint16_t command;
  72    uint16_t config[2];
  73    uint16_t status;
  74    uint16_t intstatus;
  75    uint16_t wpstatus;
  76
  77    ECCState ecc;
  78
  79    int density_mask;
  80    int secs;
  81    int secs_cur;
  82    int blocks;
  83    uint8_t *blockwp;
  84} OneNANDState;
  85
  86enum {
  87    ONEN_BUF_BLOCK = 0,
  88    ONEN_BUF_BLOCK2 = 1,
  89    ONEN_BUF_DEST_BLOCK = 2,
  90    ONEN_BUF_DEST_PAGE = 3,
  91    ONEN_BUF_PAGE = 7,
  92};
  93
  94enum {
  95    ONEN_ERR_CMD = 1 << 10,
  96    ONEN_ERR_ERASE = 1 << 11,
  97    ONEN_ERR_PROG = 1 << 12,
  98    ONEN_ERR_LOAD = 1 << 13,
  99};
 100
 101enum {
 102    ONEN_INT_RESET = 1 << 4,
 103    ONEN_INT_ERASE = 1 << 5,
 104    ONEN_INT_PROG = 1 << 6,
 105    ONEN_INT_LOAD = 1 << 7,
 106    ONEN_INT = 1 << 15,
 107};
 108
 109enum {
 110    ONEN_LOCK_LOCKTIGHTEN = 1 << 0,
 111    ONEN_LOCK_LOCKED = 1 << 1,
 112    ONEN_LOCK_UNLOCKED = 1 << 2,
 113};
 114
 115static void onenand_mem_setup(OneNANDState *s)
 116{
 117    /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
 118     * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
 119     * write boot commands.  Also take note of the BWPS bit.  */
 120    memory_region_init(&s->container, OBJECT(s), "onenand",
 121                       0x10000 << s->shift);
 122    memory_region_add_subregion(&s->container, 0, &s->iomem);
 123    memory_region_init_alias(&s->mapped_ram, OBJECT(s), "onenand-mapped-ram",
 124                             &s->ram, 0x0200 << s->shift,
 125                             0xbe00 << s->shift);
 126    memory_region_add_subregion_overlap(&s->container,
 127                                        0x0200 << s->shift,
 128                                        &s->mapped_ram,
 129                                        1);
 130}
 131
 132static void onenand_intr_update(OneNANDState *s)
 133{
 134    qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
 135}
 136
 137static void onenand_pre_save(void *opaque)
 138{
 139    OneNANDState *s = opaque;
 140    if (s->current == s->otp) {
 141        s->current_direction = 1;
 142    } else if (s->current == s->image) {
 143        s->current_direction = 2;
 144    } else {
 145        s->current_direction = 0;
 146    }
 147}
 148
 149static int onenand_post_load(void *opaque, int version_id)
 150{
 151    OneNANDState *s = opaque;
 152    switch (s->current_direction) {
 153    case 0:
 154        break;
 155    case 1:
 156        s->current = s->otp;
 157        break;
 158    case 2:
 159        s->current = s->image;
 160        break;
 161    default:
 162        return -1;
 163    }
 164    onenand_intr_update(s);
 165    return 0;
 166}
 167
 168static const VMStateDescription vmstate_onenand = {
 169    .name = "onenand",
 170    .version_id = 1,
 171    .minimum_version_id = 1,
 172    .minimum_version_id_old = 1,
 173    .pre_save = onenand_pre_save,
 174    .post_load = onenand_post_load,
 175    .fields = (VMStateField[]) {
 176        VMSTATE_UINT8(current_direction, OneNANDState),
 177        VMSTATE_INT32(cycle, OneNANDState),
 178        VMSTATE_INT32(otpmode, OneNANDState),
 179        VMSTATE_UINT16_ARRAY(addr, OneNANDState, 8),
 180        VMSTATE_UINT16_ARRAY(unladdr, OneNANDState, 8),
 181        VMSTATE_INT32(bufaddr, OneNANDState),
 182        VMSTATE_INT32(count, OneNANDState),
 183        VMSTATE_UINT16(command, OneNANDState),
 184        VMSTATE_UINT16_ARRAY(config, OneNANDState, 2),
 185        VMSTATE_UINT16(status, OneNANDState),
 186        VMSTATE_UINT16(intstatus, OneNANDState),
 187        VMSTATE_UINT16(wpstatus, OneNANDState),
 188        VMSTATE_INT32(secs_cur, OneNANDState),
 189        VMSTATE_PARTIAL_VBUFFER(blockwp, OneNANDState, blocks),
 190        VMSTATE_UINT8(ecc.cp, OneNANDState),
 191        VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2),
 192        VMSTATE_UINT16(ecc.count, OneNANDState),
 193        VMSTATE_BUFFER_POINTER_UNSAFE(otp, OneNANDState, 0,
 194            ((64 + 2) << PAGE_SHIFT)),
 195        VMSTATE_END_OF_LIST()
 196    }
 197};
 198
 199/* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
 200static void onenand_reset(OneNANDState *s, int cold)
 201{
 202    memset(&s->addr, 0, sizeof(s->addr));
 203    s->command = 0;
 204    s->count = 1;
 205    s->bufaddr = 0;
 206    s->config[0] = 0x40c0;
 207    s->config[1] = 0x0000;
 208    onenand_intr_update(s);
 209    qemu_irq_raise(s->rdy);
 210    s->status = 0x0000;
 211    s->intstatus = cold ? 0x8080 : 0x8010;
 212    s->unladdr[0] = 0;
 213    s->unladdr[1] = 0;
 214    s->wpstatus = 0x0002;
 215    s->cycle = 0;
 216    s->otpmode = 0;
 217    s->bdrv_cur = s->bdrv;
 218    s->current = s->image;
 219    s->secs_cur = s->secs;
 220
 221    if (cold) {
 222        /* Lock the whole flash */
 223        memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
 224
 225        if (s->bdrv_cur && bdrv_read(s->bdrv_cur, 0, s->boot[0], 8) < 0) {
 226            hw_error("%s: Loading the BootRAM failed.\n", __func__);
 227        }
 228    }
 229}
 230
 231static void onenand_system_reset(DeviceState *dev)
 232{
 233    OneNANDState *s = ONE_NAND(dev);
 234
 235    onenand_reset(s, 1);
 236}
 237
 238static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
 239                void *dest)
 240{
 241    if (s->bdrv_cur)
 242        return bdrv_read(s->bdrv_cur, sec, dest, secn) < 0;
 243    else if (sec + secn > s->secs_cur)
 244        return 1;
 245
 246    memcpy(dest, s->current + (sec << 9), secn << 9);
 247
 248    return 0;
 249}
 250
 251static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
 252                void *src)
 253{
 254    int result = 0;
 255
 256    if (secn > 0) {
 257        uint32_t size = (uint32_t)secn * 512;
 258        const uint8_t *sp = (const uint8_t *)src;
 259        uint8_t *dp = 0;
 260        if (s->bdrv_cur) {
 261            dp = g_malloc(size);
 262            if (!dp || bdrv_read(s->bdrv_cur, sec, dp, secn) < 0) {
 263                result = 1;
 264            }
 265        } else {
 266            if (sec + secn > s->secs_cur) {
 267                result = 1;
 268            } else {
 269                dp = (uint8_t *)s->current + (sec << 9);
 270            }
 271        }
 272        if (!result) {
 273            uint32_t i;
 274            for (i = 0; i < size; i++) {
 275                dp[i] &= sp[i];
 276            }
 277            if (s->bdrv_cur) {
 278                result = bdrv_write(s->bdrv_cur, sec, dp, secn) < 0;
 279            }
 280        }
 281        if (dp && s->bdrv_cur) {
 282            g_free(dp);
 283        }
 284    }
 285
 286    return result;
 287}
 288
 289static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
 290                void *dest)
 291{
 292    uint8_t buf[512];
 293
 294    if (s->bdrv_cur) {
 295        if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
 296            return 1;
 297        memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
 298    } else if (sec + secn > s->secs_cur)
 299        return 1;
 300    else
 301        memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
 302 
 303    return 0;
 304}
 305
 306static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
 307                void *src)
 308{
 309    int result = 0;
 310    if (secn > 0) {
 311        const uint8_t *sp = (const uint8_t *)src;
 312        uint8_t *dp = 0, *dpp = 0;
 313        if (s->bdrv_cur) {
 314            dp = g_malloc(512);
 315            if (!dp || bdrv_read(s->bdrv_cur,
 316                                 s->secs_cur + (sec >> 5),
 317                                 dp, 1) < 0) {
 318                result = 1;
 319            } else {
 320                dpp = dp + ((sec & 31) << 4);
 321            }
 322        } else {
 323            if (sec + secn > s->secs_cur) {
 324                result = 1;
 325            } else {
 326                dpp = s->current + (s->secs_cur << 9) + (sec << 4);
 327            }
 328        }
 329        if (!result) {
 330            uint32_t i;
 331            for (i = 0; i < (secn << 4); i++) {
 332                dpp[i] &= sp[i];
 333            }
 334            if (s->bdrv_cur) {
 335                result = bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5),
 336                                    dp, 1) < 0;
 337            }
 338        }
 339        if (dp) {
 340            g_free(dp);
 341        }
 342    }
 343    return result;
 344}
 345
 346static inline int onenand_erase(OneNANDState *s, int sec, int num)
 347{
 348    uint8_t *blankbuf, *tmpbuf;
 349    blankbuf = g_malloc(512);
 350    if (!blankbuf) {
 351        return 1;
 352    }
 353    tmpbuf = g_malloc(512);
 354    if (!tmpbuf) {
 355        g_free(blankbuf);
 356        return 1;
 357    }
 358    memset(blankbuf, 0xff, 512);
 359    for (; num > 0; num--, sec++) {
 360        if (s->bdrv_cur) {
 361            int erasesec = s->secs_cur + (sec >> 5);
 362            if (bdrv_write(s->bdrv_cur, sec, blankbuf, 1) < 0) {
 363                goto fail;
 364            }
 365            if (bdrv_read(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) {
 366                goto fail;
 367            }
 368            memcpy(tmpbuf + ((sec & 31) << 4), blankbuf, 1 << 4);
 369            if (bdrv_write(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) {
 370                goto fail;
 371            }
 372        } else {
 373            if (sec + 1 > s->secs_cur) {
 374                goto fail;
 375            }
 376            memcpy(s->current + (sec << 9), blankbuf, 512);
 377            memcpy(s->current + (s->secs_cur << 9) + (sec << 4),
 378                   blankbuf, 1 << 4);
 379        }
 380    }
 381
 382    g_free(tmpbuf);
 383    g_free(blankbuf);
 384    return 0;
 385
 386fail:
 387    g_free(tmpbuf);
 388    g_free(blankbuf);
 389    return 1;
 390}
 391
 392static void onenand_command(OneNANDState *s)
 393{
 394    int b;
 395    int sec;
 396    void *buf;
 397#define SETADDR(block, page)                    \
 398    sec = (s->addr[page] & 3) +                 \
 399            ((((s->addr[page] >> 2) & 0x3f) +   \
 400              (((s->addr[block] & 0xfff) |      \
 401                (s->addr[block] >> 15 ?         \
 402                 s->density_mask : 0)) << 6)) << (PAGE_SHIFT - 9));
 403#define SETBUF_M()                              \
 404    buf = (s->bufaddr & 8) ?                    \
 405            s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0];     \
 406    buf += (s->bufaddr & 3) << 9;
 407#define SETBUF_S()                              \
 408    buf = (s->bufaddr & 8) ?                    \
 409            s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1];     \
 410    buf += (s->bufaddr & 3) << 4;
 411
 412    switch (s->command) {
 413    case 0x00:  /* Load single/multiple sector data unit into buffer */
 414        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
 415
 416        SETBUF_M()
 417        if (onenand_load_main(s, sec, s->count, buf))
 418            s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
 419
 420#if 0
 421        SETBUF_S()
 422        if (onenand_load_spare(s, sec, s->count, buf))
 423            s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
 424#endif
 425
 426        /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
 427         * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
 428         * then we need two split the read/write into two chunks.
 429         */
 430        s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
 431        break;
 432    case 0x13:  /* Load single/multiple spare sector into buffer */
 433        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
 434
 435        SETBUF_S()
 436        if (onenand_load_spare(s, sec, s->count, buf))
 437            s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
 438
 439        /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
 440         * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
 441         * then we need two split the read/write into two chunks.
 442         */
 443        s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
 444        break;
 445    case 0x80:  /* Program single/multiple sector data unit from buffer */
 446        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
 447
 448        SETBUF_M()
 449        if (onenand_prog_main(s, sec, s->count, buf))
 450            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
 451
 452#if 0
 453        SETBUF_S()
 454        if (onenand_prog_spare(s, sec, s->count, buf))
 455            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
 456#endif
 457
 458        /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
 459         * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
 460         * then we need two split the read/write into two chunks.
 461         */
 462        s->intstatus |= ONEN_INT | ONEN_INT_PROG;
 463        break;
 464    case 0x1a:  /* Program single/multiple spare area sector from buffer */
 465        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
 466
 467        SETBUF_S()
 468        if (onenand_prog_spare(s, sec, s->count, buf))
 469            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
 470
 471        /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
 472         * or    if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
 473         * then we need two split the read/write into two chunks.
 474         */
 475        s->intstatus |= ONEN_INT | ONEN_INT_PROG;
 476        break;
 477    case 0x1b:  /* Copy-back program */
 478        SETBUF_S()
 479
 480        SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
 481        if (onenand_load_main(s, sec, s->count, buf))
 482            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
 483
 484        SETADDR(ONEN_BUF_DEST_BLOCK, ONEN_BUF_DEST_PAGE)
 485        if (onenand_prog_main(s, sec, s->count, buf))
 486            s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
 487
 488        /* TODO: spare areas */
 489
 490        s->intstatus |= ONEN_INT | ONEN_INT_PROG;
 491        break;
 492
 493    case 0x23:  /* Unlock NAND array block(s) */
 494        s->intstatus |= ONEN_INT;
 495
 496        /* XXX the previous (?) area should be locked automatically */
 497        for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
 498            if (b >= s->blocks) {
 499                s->status |= ONEN_ERR_CMD;
 500                break;
 501            }
 502            if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
 503                break;
 504
 505            s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
 506        }
 507        break;
 508    case 0x27:  /* Unlock All NAND array blocks */
 509        s->intstatus |= ONEN_INT;
 510
 511        for (b = 0; b < s->blocks; b ++) {
 512            if (b >= s->blocks) {
 513                s->status |= ONEN_ERR_CMD;
 514                break;
 515            }
 516            if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
 517                break;
 518
 519            s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
 520        }
 521        break;
 522
 523    case 0x2a:  /* Lock NAND array block(s) */
 524        s->intstatus |= ONEN_INT;
 525
 526        for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
 527            if (b >= s->blocks) {
 528                s->status |= ONEN_ERR_CMD;
 529                break;
 530            }
 531            if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
 532                break;
 533
 534            s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED;
 535        }
 536        break;
 537    case 0x2c:  /* Lock-tight NAND array block(s) */
 538        s->intstatus |= ONEN_INT;
 539
 540        for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
 541            if (b >= s->blocks) {
 542                s->status |= ONEN_ERR_CMD;
 543                break;
 544            }
 545            if (s->blockwp[b] == ONEN_LOCK_UNLOCKED)
 546                continue;
 547
 548            s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN;
 549        }
 550        break;
 551
 552    case 0x71:  /* Erase-Verify-Read */
 553        s->intstatus |= ONEN_INT;
 554        break;
 555    case 0x95:  /* Multi-block erase */
 556        qemu_irq_pulse(s->intr);
 557        /* Fall through.  */
 558    case 0x94:  /* Block erase */
 559        sec = ((s->addr[ONEN_BUF_BLOCK] & 0xfff) |
 560                        (s->addr[ONEN_BUF_BLOCK] >> 15 ? s->density_mask : 0))
 561                << (BLOCK_SHIFT - 9);
 562        if (onenand_erase(s, sec, 1 << (BLOCK_SHIFT - 9)))
 563            s->status |= ONEN_ERR_CMD | ONEN_ERR_ERASE;
 564
 565        s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
 566        break;
 567    case 0xb0:  /* Erase suspend */
 568        break;
 569    case 0x30:  /* Erase resume */
 570        s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
 571        break;
 572
 573    case 0xf0:  /* Reset NAND Flash core */
 574        onenand_reset(s, 0);
 575        break;
 576    case 0xf3:  /* Reset OneNAND */
 577        onenand_reset(s, 0);
 578        break;
 579
 580    case 0x65:  /* OTP Access */
 581        s->intstatus |= ONEN_INT;
 582        s->bdrv_cur = NULL;
 583        s->current = s->otp;
 584        s->secs_cur = 1 << (BLOCK_SHIFT - 9);
 585        s->addr[ONEN_BUF_BLOCK] = 0;
 586        s->otpmode = 1;
 587        break;
 588
 589    default:
 590        s->status |= ONEN_ERR_CMD;
 591        s->intstatus |= ONEN_INT;
 592        fprintf(stderr, "%s: unknown OneNAND command %x\n",
 593                        __func__, s->command);
 594    }
 595
 596    onenand_intr_update(s);
 597}
 598
 599static uint64_t onenand_read(void *opaque, hwaddr addr,
 600                             unsigned size)
 601{
 602    OneNANDState *s = (OneNANDState *) opaque;
 603    int offset = addr >> s->shift;
 604
 605    switch (offset) {
 606    case 0x0000 ... 0xc000:
 607        return lduw_le_p(s->boot[0] + addr);
 608
 609    case 0xf000:        /* Manufacturer ID */
 610        return s->id.man;
 611    case 0xf001:        /* Device ID */
 612        return s->id.dev;
 613    case 0xf002:        /* Version ID */
 614        return s->id.ver;
 615    /* TODO: get the following values from a real chip!  */
 616    case 0xf003:        /* Data Buffer size */
 617        return 1 << PAGE_SHIFT;
 618    case 0xf004:        /* Boot Buffer size */
 619        return 0x200;
 620    case 0xf005:        /* Amount of buffers */
 621        return 1 | (2 << 8);
 622    case 0xf006:        /* Technology */
 623        return 0;
 624
 625    case 0xf100 ... 0xf107:     /* Start addresses */
 626        return s->addr[offset - 0xf100];
 627
 628    case 0xf200:        /* Start buffer */
 629        return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10)));
 630
 631    case 0xf220:        /* Command */
 632        return s->command;
 633    case 0xf221:        /* System Configuration 1 */
 634        return s->config[0] & 0xffe0;
 635    case 0xf222:        /* System Configuration 2 */
 636        return s->config[1];
 637
 638    case 0xf240:        /* Controller Status */
 639        return s->status;
 640    case 0xf241:        /* Interrupt */
 641        return s->intstatus;
 642    case 0xf24c:        /* Unlock Start Block Address */
 643        return s->unladdr[0];
 644    case 0xf24d:        /* Unlock End Block Address */
 645        return s->unladdr[1];
 646    case 0xf24e:        /* Write Protection Status */
 647        return s->wpstatus;
 648
 649    case 0xff00:        /* ECC Status */
 650        return 0x00;
 651    case 0xff01:        /* ECC Result of main area data */
 652    case 0xff02:        /* ECC Result of spare area data */
 653    case 0xff03:        /* ECC Result of main area data */
 654    case 0xff04:        /* ECC Result of spare area data */
 655        hw_error("%s: imeplement ECC\n", __FUNCTION__);
 656        return 0x0000;
 657    }
 658
 659    fprintf(stderr, "%s: unknown OneNAND register %x\n",
 660                    __FUNCTION__, offset);
 661    return 0;
 662}
 663
 664static void onenand_write(void *opaque, hwaddr addr,
 665                          uint64_t value, unsigned size)
 666{
 667    OneNANDState *s = (OneNANDState *) opaque;
 668    int offset = addr >> s->shift;
 669    int sec;
 670
 671    switch (offset) {
 672    case 0x0000 ... 0x01ff:
 673    case 0x8000 ... 0x800f:
 674        if (s->cycle) {
 675            s->cycle = 0;
 676
 677            if (value == 0x0000) {
 678                SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
 679                onenand_load_main(s, sec,
 680                                1 << (PAGE_SHIFT - 9), s->data[0][0]);
 681                s->addr[ONEN_BUF_PAGE] += 4;
 682                s->addr[ONEN_BUF_PAGE] &= 0xff;
 683            }
 684            break;
 685        }
 686
 687        switch (value) {
 688        case 0x00f0:    /* Reset OneNAND */
 689            onenand_reset(s, 0);
 690            break;
 691
 692        case 0x00e0:    /* Load Data into Buffer */
 693            s->cycle = 1;
 694            break;
 695
 696        case 0x0090:    /* Read Identification Data */
 697            memset(s->boot[0], 0, 3 << s->shift);
 698            s->boot[0][0 << s->shift] = s->id.man & 0xff;
 699            s->boot[0][1 << s->shift] = s->id.dev & 0xff;
 700            s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
 701            break;
 702
 703        default:
 704            fprintf(stderr, "%s: unknown OneNAND boot command %"PRIx64"\n",
 705                            __FUNCTION__, value);
 706        }
 707        break;
 708
 709    case 0xf100 ... 0xf107:     /* Start addresses */
 710        s->addr[offset - 0xf100] = value;
 711        break;
 712
 713    case 0xf200:        /* Start buffer */
 714        s->bufaddr = (value >> 8) & 0xf;
 715        if (PAGE_SHIFT == 11)
 716            s->count = (value & 3) ?: 4;
 717        else if (PAGE_SHIFT == 10)
 718            s->count = (value & 1) ?: 2;
 719        break;
 720
 721    case 0xf220:        /* Command */
 722        if (s->intstatus & (1 << 15))
 723            break;
 724        s->command = value;
 725        onenand_command(s);
 726        break;
 727    case 0xf221:        /* System Configuration 1 */
 728        s->config[0] = value;
 729        onenand_intr_update(s);
 730        qemu_set_irq(s->rdy, (s->config[0] >> 7) & 1);
 731        break;
 732    case 0xf222:        /* System Configuration 2 */
 733        s->config[1] = value;
 734        break;
 735
 736    case 0xf241:        /* Interrupt */
 737        s->intstatus &= value;
 738        if ((1 << 15) & ~s->intstatus)
 739            s->status &= ~(ONEN_ERR_CMD | ONEN_ERR_ERASE |
 740                            ONEN_ERR_PROG | ONEN_ERR_LOAD);
 741        onenand_intr_update(s);
 742        break;
 743    case 0xf24c:        /* Unlock Start Block Address */
 744        s->unladdr[0] = value & (s->blocks - 1);
 745        /* For some reason we have to set the end address to by default
 746         * be same as start because the software forgets to write anything
 747         * in there.  */
 748        s->unladdr[1] = value & (s->blocks - 1);
 749        break;
 750    case 0xf24d:        /* Unlock End Block Address */
 751        s->unladdr[1] = value & (s->blocks - 1);
 752        break;
 753
 754    default:
 755        fprintf(stderr, "%s: unknown OneNAND register %x\n",
 756                        __FUNCTION__, offset);
 757    }
 758}
 759
 760static const MemoryRegionOps onenand_ops = {
 761    .read = onenand_read,
 762    .write = onenand_write,
 763    .endianness = DEVICE_NATIVE_ENDIAN,
 764};
 765
 766static int onenand_initfn(SysBusDevice *sbd)
 767{
 768    DeviceState *dev = DEVICE(sbd);
 769    OneNANDState *s = ONE_NAND(dev);
 770    uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
 771    void *ram;
 772
 773    s->base = (hwaddr)-1;
 774    s->rdy = NULL;
 775    s->blocks = size >> BLOCK_SHIFT;
 776    s->secs = size >> 9;
 777    s->blockwp = g_malloc(s->blocks);
 778    s->density_mask = (s->id.dev & 0x08)
 779        ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0;
 780    memory_region_init_io(&s->iomem, OBJECT(s), &onenand_ops, s, "onenand",
 781                          0x10000 << s->shift);
 782    if (!s->bdrv) {
 783        s->image = memset(g_malloc(size + (size >> 5)),
 784                          0xff, size + (size >> 5));
 785    } else {
 786        if (bdrv_is_read_only(s->bdrv)) {
 787            error_report("Can't use a read-only drive");
 788            return -1;
 789        }
 790        s->bdrv_cur = s->bdrv;
 791    }
 792    s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
 793                    0xff, (64 + 2) << PAGE_SHIFT);
 794    memory_region_init_ram(&s->ram, OBJECT(s), "onenand.ram",
 795                           0xc000 << s->shift);
 796    vmstate_register_ram_global(&s->ram);
 797    ram = memory_region_get_ram_ptr(&s->ram);
 798    s->boot[0] = ram + (0x0000 << s->shift);
 799    s->boot[1] = ram + (0x8000 << s->shift);
 800    s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift);
 801    s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift);
 802    s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
 803    s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
 804    onenand_mem_setup(s);
 805    sysbus_init_irq(sbd, &s->intr);
 806    sysbus_init_mmio(sbd, &s->container);
 807    vmstate_register(dev,
 808                     ((s->shift & 0x7f) << 24)
 809                     | ((s->id.man & 0xff) << 16)
 810                     | ((s->id.dev & 0xff) << 8)
 811                     | (s->id.ver & 0xff),
 812                     &vmstate_onenand, s);
 813    return 0;
 814}
 815
 816static Property onenand_properties[] = {
 817    DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0),
 818    DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
 819    DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
 820    DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
 821    DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv),
 822    DEFINE_PROP_END_OF_LIST(),
 823};
 824
 825static void onenand_class_init(ObjectClass *klass, void *data)
 826{
 827    DeviceClass *dc = DEVICE_CLASS(klass);
 828    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 829
 830    k->init = onenand_initfn;
 831    dc->reset = onenand_system_reset;
 832    dc->props = onenand_properties;
 833}
 834
 835static const TypeInfo onenand_info = {
 836    .name          = TYPE_ONE_NAND,
 837    .parent        = TYPE_SYS_BUS_DEVICE,
 838    .instance_size = sizeof(OneNANDState),
 839    .class_init    = onenand_class_init,
 840};
 841
 842static void onenand_register_types(void)
 843{
 844    type_register_static(&onenand_info);
 845}
 846
 847void *onenand_raw_otp(DeviceState *onenand_device)
 848{
 849    OneNANDState *s = ONE_NAND(onenand_device);
 850
 851    return s->otp;
 852}
 853
 854type_init(onenand_register_types)
 855