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