qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

onenand.c (26472B)


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