nandsim_chip.c revision 314667
1/*- 2 * Copyright (C) 2009-2012 Semihalf 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/10/sys/dev/nand/nandsim_chip.c 314667 2017-03-04 13:03:31Z avg $"); 29 30#include <sys/param.h> 31#include <sys/types.h> 32#include <sys/systm.h> 33#include <sys/kernel.h> 34#include <sys/lock.h> 35#include <sys/malloc.h> 36#include <sys/module.h> 37#include <sys/mutex.h> 38#include <sys/proc.h> 39#include <sys/sched.h> 40#include <sys/kthread.h> 41#include <sys/unistd.h> 42 43#include <dev/nand/nand.h> 44#include <dev/nand/nandsim_chip.h> 45#include <dev/nand/nandsim_log.h> 46#include <dev/nand/nandsim_swap.h> 47 48MALLOC_DEFINE(M_NANDSIM, "NANDsim", "NANDsim dynamic data"); 49 50#define NANDSIM_CHIP_LOCK(chip) mtx_lock(&(chip)->ns_lock) 51#define NANDSIM_CHIP_UNLOCK(chip) mtx_unlock(&(chip)->ns_lock) 52 53static nandsim_evh_t erase_evh; 54static nandsim_evh_t idle_evh; 55static nandsim_evh_t poweron_evh; 56static nandsim_evh_t reset_evh; 57static nandsim_evh_t read_evh; 58static nandsim_evh_t readid_evh; 59static nandsim_evh_t readparam_evh; 60static nandsim_evh_t write_evh; 61 62static void nandsim_loop(void *); 63static void nandsim_undefined(struct nandsim_chip *, uint8_t); 64static void nandsim_bad_address(struct nandsim_chip *, uint8_t *); 65static void nandsim_ignore_address(struct nandsim_chip *, uint8_t); 66static void nandsim_sm_error(struct nandsim_chip *); 67static void nandsim_start_handler(struct nandsim_chip *, nandsim_evh_t); 68 69static void nandsim_callout_eh(void *); 70static int nandsim_delay(struct nandsim_chip *, int); 71 72static int nandsim_bbm_init(struct nandsim_chip *, uint32_t, uint32_t *); 73static int nandsim_blk_state_init(struct nandsim_chip *, uint32_t, uint32_t); 74static void nandsim_blk_state_destroy(struct nandsim_chip *); 75static int nandchip_is_block_valid(struct nandsim_chip *, int); 76 77static void nandchip_set_status(struct nandsim_chip *, uint8_t); 78static void nandchip_clear_status(struct nandsim_chip *, uint8_t); 79 80struct proc *nandsim_proc; 81 82struct nandsim_chip * 83nandsim_chip_init(struct nandsim_softc* sc, uint8_t chip_num, 84 struct sim_chip *sim_chip) 85{ 86 struct nandsim_chip *chip; 87 struct onfi_params *chip_param; 88 char swapfile[20]; 89 uint32_t size; 90 int error; 91 92 chip = malloc(sizeof(*chip), M_NANDSIM, M_WAITOK | M_ZERO); 93 if (!chip) 94 return (NULL); 95 96 mtx_init(&chip->ns_lock, "nandsim lock", NULL, MTX_DEF); 97 callout_init(&chip->ns_callout, 1); 98 STAILQ_INIT(&chip->nandsim_events); 99 100 chip->chip_num = chip_num; 101 chip->ctrl_num = sim_chip->ctrl_num; 102 chip->sc = sc; 103 104 if (!sim_chip->is_wp) 105 nandchip_set_status(chip, NAND_STATUS_WP); 106 107 chip_param = &chip->params; 108 109 chip->id.dev_id = sim_chip->device_id; 110 chip->id.man_id = sim_chip->manufact_id; 111 112 chip->error_ratio = sim_chip->error_ratio; 113 chip->wear_level = sim_chip->wear_level; 114 chip->prog_delay = sim_chip->prog_time; 115 chip->erase_delay = sim_chip->erase_time; 116 chip->read_delay = sim_chip->read_time; 117 118 chip_param->t_prog = sim_chip->prog_time; 119 chip_param->t_bers = sim_chip->erase_time; 120 chip_param->t_r = sim_chip->read_time; 121 bcopy("onfi", &chip_param->signature, 4); 122 123 chip_param->manufacturer_id = sim_chip->manufact_id; 124 strncpy(chip_param->manufacturer_name, sim_chip->manufacturer, 12); 125 chip_param->manufacturer_name[11] = 0; 126 strncpy(chip_param->device_model, sim_chip->device_model, 20); 127 chip_param->device_model[19] = 0; 128 129 chip_param->bytes_per_page = sim_chip->page_size; 130 chip_param->spare_bytes_per_page = sim_chip->oob_size; 131 chip_param->pages_per_block = sim_chip->pgs_per_blk; 132 chip_param->blocks_per_lun = sim_chip->blks_per_lun; 133 chip_param->luns = sim_chip->luns; 134 135 init_chip_geom(&chip->cg, chip_param->luns, chip_param->blocks_per_lun, 136 chip_param->pages_per_block, chip_param->bytes_per_page, 137 chip_param->spare_bytes_per_page); 138 139 chip_param->address_cycles = sim_chip->row_addr_cycles | 140 (sim_chip->col_addr_cycles << 4); 141 chip_param->features = sim_chip->features; 142 if (sim_chip->width == 16) 143 chip_param->features |= ONFI_FEAT_16BIT; 144 145 size = chip_param->blocks_per_lun * chip_param->luns; 146 147 error = nandsim_blk_state_init(chip, size, sim_chip->wear_level); 148 if (error) { 149 mtx_destroy(&chip->ns_lock); 150 free(chip, M_NANDSIM); 151 return (NULL); 152 } 153 154 error = nandsim_bbm_init(chip, size, sim_chip->bad_block_map); 155 if (error) { 156 mtx_destroy(&chip->ns_lock); 157 nandsim_blk_state_destroy(chip); 158 free(chip, M_NANDSIM); 159 return (NULL); 160 } 161 162 nandsim_start_handler(chip, poweron_evh); 163 164 nand_debug(NDBG_SIM,"Create thread for chip%d [%8p]", chip->chip_num, 165 chip); 166 /* Create chip thread */ 167 error = kproc_kthread_add(nandsim_loop, chip, &nandsim_proc, 168 &chip->nandsim_td, RFSTOPPED | RFHIGHPID, 169 0, "nandsim", "chip"); 170 if (error) { 171 mtx_destroy(&chip->ns_lock); 172 nandsim_blk_state_destroy(chip); 173 free(chip, M_NANDSIM); 174 return (NULL); 175 } 176 177 thread_lock(chip->nandsim_td); 178 sched_class(chip->nandsim_td, PRI_REALTIME); 179 sched_add(chip->nandsim_td, SRQ_BORING); 180 thread_unlock(chip->nandsim_td); 181 182 size = (chip_param->bytes_per_page + 183 chip_param->spare_bytes_per_page) * 184 chip_param->pages_per_block; 185 186 sprintf(swapfile, "chip%d%d.swp", chip->ctrl_num, chip->chip_num); 187 chip->swap = nandsim_swap_init(swapfile, chip_param->blocks_per_lun * 188 chip_param->luns, size); 189 if (!chip->swap) 190 nandsim_chip_destroy(chip); 191 192 /* Wait for new thread to enter main loop */ 193 tsleep(chip->nandsim_td, PWAIT, "ns_chip", 1 * hz); 194 195 return (chip); 196} 197 198static int 199nandsim_blk_state_init(struct nandsim_chip *chip, uint32_t size, 200 uint32_t wear_lev) 201{ 202 int i; 203 204 if (!chip || size == 0) 205 return (-1); 206 207 chip->blk_state = malloc(size * sizeof(struct nandsim_block_state), 208 M_NANDSIM, M_WAITOK | M_ZERO); 209 if (!chip->blk_state) { 210 return (-1); 211 } 212 213 for (i = 0; i < size; i++) { 214 if (wear_lev) 215 chip->blk_state[i].wear_lev = wear_lev; 216 else 217 chip->blk_state[i].wear_lev = -1; 218 } 219 220 return (0); 221} 222 223static void 224nandsim_blk_state_destroy(struct nandsim_chip *chip) 225{ 226 227 if (chip && chip->blk_state) 228 free(chip->blk_state, M_NANDSIM); 229} 230 231static int 232nandsim_bbm_init(struct nandsim_chip *chip, uint32_t size, 233 uint32_t *sim_bbm) 234{ 235 uint32_t index; 236 int i; 237 238 if ((chip == NULL) || (size == 0)) 239 return (-1); 240 241 if (chip->blk_state == NULL) 242 return (-1); 243 244 if (sim_bbm == NULL) 245 return (0); 246 247 for (i = 0; i < MAX_BAD_BLOCKS; i++) { 248 index = sim_bbm[i]; 249 250 if (index == 0xffffffff) 251 break; 252 else if (index > size) 253 return (-1); 254 else 255 chip->blk_state[index].is_bad = 1; 256 } 257 258 return (0); 259} 260 261void 262nandsim_chip_destroy(struct nandsim_chip *chip) 263{ 264 struct nandsim_ev *ev; 265 266 ev = create_event(chip, NANDSIM_EV_EXIT, 0); 267 if (ev) 268 send_event(ev); 269} 270 271void 272nandsim_chip_freeze(struct nandsim_chip *chip) 273{ 274 275 chip->flags |= NANDSIM_CHIP_FROZEN; 276} 277 278static void 279nandsim_loop(void *arg) 280{ 281 struct nandsim_chip *chip = (struct nandsim_chip *)arg; 282 struct nandsim_ev *ev; 283 284 nand_debug(NDBG_SIM,"Start main loop for chip%d [%8p]", chip->chip_num, 285 chip); 286 for(;;) { 287 NANDSIM_CHIP_LOCK(chip); 288 if (!(chip->flags & NANDSIM_CHIP_ACTIVE)) { 289 chip->flags |= NANDSIM_CHIP_ACTIVE; 290 wakeup(chip->nandsim_td); 291 } 292 293 if (STAILQ_EMPTY(&chip->nandsim_events)) { 294 nand_debug(NDBG_SIM,"Chip%d [%8p] going sleep", 295 chip->chip_num, chip); 296 msleep(chip, &chip->ns_lock, PRIBIO, "nandev", 0); 297 } 298 299 ev = STAILQ_FIRST(&chip->nandsim_events); 300 STAILQ_REMOVE_HEAD(&chip->nandsim_events, links); 301 NANDSIM_CHIP_UNLOCK(chip); 302 if (ev->type == NANDSIM_EV_EXIT) { 303 NANDSIM_CHIP_LOCK(chip); 304 destroy_event(ev); 305 wakeup(ev); 306 while (!STAILQ_EMPTY(&chip->nandsim_events)) { 307 ev = STAILQ_FIRST(&chip->nandsim_events); 308 STAILQ_REMOVE_HEAD(&chip->nandsim_events, 309 links); 310 destroy_event(ev); 311 wakeup(ev); 312 }; 313 NANDSIM_CHIP_UNLOCK(chip); 314 nandsim_log(chip, NANDSIM_LOG_SM, "destroyed\n"); 315 mtx_destroy(&chip->ns_lock); 316 nandsim_blk_state_destroy(chip); 317 nandsim_swap_destroy(chip->swap); 318 free(chip, M_NANDSIM); 319 nandsim_proc = NULL; 320 321 kthread_exit(); 322 } 323 324 if (!(chip->flags & NANDSIM_CHIP_FROZEN)) { 325 nand_debug(NDBG_SIM,"Chip [%x] get event [%x]", 326 chip->chip_num, ev->type); 327 chip->ev_handler(chip, ev->type, ev->data); 328 } 329 330 wakeup(ev); 331 destroy_event(ev); 332 } 333 334} 335 336struct nandsim_ev * 337create_event(struct nandsim_chip *chip, uint8_t type, uint8_t data_size) 338{ 339 struct nandsim_ev *ev; 340 341 ev = malloc(sizeof(*ev), M_NANDSIM, M_NOWAIT | M_ZERO); 342 if (!ev) { 343 nand_debug(NDBG_SIM,"Cannot create event"); 344 return (NULL); 345 } 346 347 if (data_size > 0) 348 ev->data = malloc(sizeof(*ev), M_NANDSIM, M_NOWAIT | M_ZERO); 349 ev->type = type; 350 ev->chip = chip; 351 352 return (ev); 353} 354 355void 356destroy_event(struct nandsim_ev *ev) 357{ 358 359 if (ev->data) 360 free(ev->data, M_NANDSIM); 361 free(ev, M_NANDSIM); 362} 363 364int 365send_event(struct nandsim_ev *ev) 366{ 367 struct nandsim_chip *chip = ev->chip; 368 369 if (!(chip->flags & NANDSIM_CHIP_FROZEN)) { 370 nand_debug(NDBG_SIM,"Chip%d [%p] send event %x", 371 chip->chip_num, chip, ev->type); 372 373 NANDSIM_CHIP_LOCK(chip); 374 STAILQ_INSERT_TAIL(&chip->nandsim_events, ev, links); 375 NANDSIM_CHIP_UNLOCK(chip); 376 377 wakeup(chip); 378 if ((ev->type != NANDSIM_EV_TIMEOUT) && chip->nandsim_td && 379 (curthread != chip->nandsim_td)) 380 tsleep(ev, PWAIT, "ns_ev", 5 * hz); 381 } 382 383 return (0); 384} 385 386static void 387nandsim_callout_eh(void *arg) 388{ 389 struct nandsim_ev *ev = (struct nandsim_ev *)arg; 390 391 send_event(ev); 392} 393 394static int 395nandsim_delay(struct nandsim_chip *chip, int timeout) 396{ 397 struct nandsim_ev *ev; 398 struct timeval delay; 399 int tm; 400 401 nand_debug(NDBG_SIM,"Chip[%d] Set delay: %d", chip->chip_num, timeout); 402 403 ev = create_event(chip, NANDSIM_EV_TIMEOUT, 0); 404 if (!ev) 405 return (-1); 406 407 chip->sm_state = NANDSIM_STATE_TIMEOUT; 408 tm = (timeout/10000) * (hz / 100); 409 if (callout_reset(&chip->ns_callout, tm, nandsim_callout_eh, ev)) 410 return (-1); 411 412 delay.tv_sec = chip->read_delay / 1000000; 413 delay.tv_usec = chip->read_delay % 1000000; 414 timevaladd(&chip->delay_tv, &delay); 415 416 return (0); 417} 418 419static void 420nandsim_start_handler(struct nandsim_chip *chip, nandsim_evh_t evh) 421{ 422 struct nandsim_ev *ev; 423 424 chip->ev_handler = evh; 425 426 nand_debug(NDBG_SIM,"Start handler %p for chip%d [%p]", evh, 427 chip->chip_num, chip); 428 ev = create_event(chip, NANDSIM_EV_START, 0); 429 if (!ev) 430 nandsim_sm_error(chip); 431 432 send_event(ev); 433} 434 435static void 436nandchip_set_data(struct nandsim_chip *chip, uint8_t *data, uint32_t len, 437 uint32_t idx) 438{ 439 440 nand_debug(NDBG_SIM,"Chip [%x] data %p [%x] at %x", chip->chip_num, 441 data, len, idx); 442 chip->data.data_ptr = data; 443 chip->data.size = len; 444 chip->data.index = idx; 445} 446 447static int 448nandchip_chip_space(struct nandsim_chip *chip, int32_t row, int32_t column, 449 size_t size, uint8_t writing) 450{ 451 struct block_space *blk_space; 452 uint32_t lun, block, page, offset, block_size; 453 int err; 454 455 block_size = chip->cg.block_size + 456 (chip->cg.oob_size * chip->cg.pgs_per_blk); 457 458 err = nand_row_to_blkpg(&chip->cg, row, &lun, &block, &page); 459 if (err) { 460 nand_debug(NDBG_SIM,"cannot get address\n"); 461 return (-1); 462 } 463 464 if (!nandchip_is_block_valid(chip, block)) { 465 nandchip_set_data(chip, NULL, 0, 0); 466 return (-1); 467 } 468 469 blk_space = get_bs(chip->swap, block, writing); 470 if (!blk_space) { 471 nandchip_set_data(chip, NULL, 0, 0); 472 return (-1); 473 } 474 475 if (size > block_size) 476 size = block_size; 477 478 if (size == block_size) { 479 offset = 0; 480 column = 0; 481 } else 482 offset = page * (chip->cg.page_size + chip->cg.oob_size); 483 484 nandchip_set_data(chip, &blk_space->blk_ptr[offset], size, column); 485 486 return (0); 487} 488 489static int 490nandchip_get_addr_byte(struct nandsim_chip *chip, void *data, uint32_t *value) 491{ 492 int ncycles = 0; 493 uint8_t byte; 494 uint8_t *buffer; 495 496 buffer = (uint8_t *)value; 497 byte = *((uint8_t *)data); 498 499 KASSERT((chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW || 500 chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL), 501 ("unexpected state")); 502 503 if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) { 504 ncycles = chip->params.address_cycles & 0xf; 505 buffer[chip->sm_addr_cycle++] = byte; 506 } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) { 507 ncycles = (chip->params.address_cycles >> 4) & 0xf; 508 buffer[chip->sm_addr_cycle++] = byte; 509 } 510 511 nand_debug(NDBG_SIM, "Chip [%x] read addr byte: %02x (%d of %d)\n", 512 chip->chip_num, byte, chip->sm_addr_cycle, ncycles); 513 514 if (chip->sm_addr_cycle == ncycles) { 515 chip->sm_addr_cycle = 0; 516 return (0); 517 } 518 519 return (1); 520} 521 522static int 523nandchip_is_block_valid(struct nandsim_chip *chip, int block_num) 524{ 525 526 if (!chip || !chip->blk_state) 527 return (0); 528 529 if (chip->blk_state[block_num].wear_lev == 0 || 530 chip->blk_state[block_num].is_bad) 531 return (0); 532 533 return (1); 534} 535 536static void 537nandchip_set_status(struct nandsim_chip *chip, uint8_t flags) 538{ 539 540 chip->chip_status |= flags; 541} 542 543static void 544nandchip_clear_status(struct nandsim_chip *chip, uint8_t flags) 545{ 546 547 chip->chip_status &= ~flags; 548} 549 550uint8_t 551nandchip_get_status(struct nandsim_chip *chip) 552{ 553 return (chip->chip_status); 554} 555 556void 557nandsim_chip_timeout(struct nandsim_chip *chip) 558{ 559 struct timeval tv; 560 561 getmicrotime(&tv); 562 563 if (chip->sm_state == NANDSIM_STATE_TIMEOUT && 564 timevalcmp(&tv, &chip->delay_tv, >=)) { 565 nandchip_set_status(chip, NAND_STATUS_RDY); 566 } 567} 568void 569poweron_evh(struct nandsim_chip *chip, uint32_t type, void *data) 570{ 571 uint8_t cmd; 572 573 if (type == NANDSIM_EV_START) 574 chip->sm_state = NANDSIM_STATE_IDLE; 575 else if (type == NANDSIM_EV_CMD) { 576 cmd = *(uint8_t *)data; 577 switch(cmd) { 578 case NAND_CMD_RESET: 579 nandsim_log(chip, NANDSIM_LOG_SM, "in RESET state\n"); 580 nandsim_start_handler(chip, reset_evh); 581 break; 582 default: 583 nandsim_undefined(chip, type); 584 break; 585 } 586 } else 587 nandsim_undefined(chip, type); 588} 589 590void 591idle_evh(struct nandsim_chip *chip, uint32_t type, void *data) 592{ 593 uint8_t cmd; 594 595 if (type == NANDSIM_EV_START) { 596 nandsim_log(chip, NANDSIM_LOG_SM, "in IDLE state\n"); 597 chip->sm_state = NANDSIM_STATE_WAIT_CMD; 598 } else if (type == NANDSIM_EV_CMD) { 599 nandchip_clear_status(chip, NAND_STATUS_FAIL); 600 getmicrotime(&chip->delay_tv); 601 cmd = *(uint8_t *)data; 602 switch(cmd) { 603 case NAND_CMD_READ_ID: 604 nandsim_start_handler(chip, readid_evh); 605 break; 606 case NAND_CMD_READ_PARAMETER: 607 nandsim_start_handler(chip, readparam_evh); 608 break; 609 case NAND_CMD_READ: 610 nandsim_start_handler(chip, read_evh); 611 break; 612 case NAND_CMD_PROG: 613 nandsim_start_handler(chip, write_evh); 614 break; 615 case NAND_CMD_ERASE: 616 nandsim_start_handler(chip, erase_evh); 617 break; 618 default: 619 nandsim_undefined(chip, type); 620 break; 621 } 622 } else 623 nandsim_undefined(chip, type); 624} 625 626void 627readid_evh(struct nandsim_chip *chip, uint32_t type, void *data) 628{ 629 struct onfi_params *params; 630 uint8_t addr; 631 632 params = &chip->params; 633 634 if (type == NANDSIM_EV_START) { 635 nandsim_log(chip, NANDSIM_LOG_SM, "in READID state\n"); 636 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_BYTE; 637 } else if (type == NANDSIM_EV_ADDR) { 638 639 addr = *((uint8_t *)data); 640 641 if (addr == 0x0) 642 nandchip_set_data(chip, (uint8_t *)&chip->id, 2, 0); 643 else if (addr == ONFI_SIG_ADDR) 644 nandchip_set_data(chip, (uint8_t *)¶ms->signature, 645 4, 0); 646 else 647 nandsim_bad_address(chip, &addr); 648 649 nandsim_start_handler(chip, idle_evh); 650 } else 651 nandsim_undefined(chip, type); 652} 653 654void 655readparam_evh(struct nandsim_chip *chip, uint32_t type, void *data) 656{ 657 struct onfi_params *params; 658 uint8_t addr; 659 660 params = &chip->params; 661 662 if (type == NANDSIM_EV_START) { 663 nandsim_log(chip, NANDSIM_LOG_SM, "in READPARAM state\n"); 664 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_BYTE; 665 } else if (type == NANDSIM_EV_ADDR) { 666 addr = *((uint8_t *)data); 667 668 if (addr == 0) { 669 nandchip_set_data(chip, (uint8_t *)params, 670 sizeof(*params), 0); 671 } else 672 nandsim_bad_address(chip, &addr); 673 674 nandsim_start_handler(chip, idle_evh); 675 } else 676 nandsim_undefined(chip, type); 677} 678 679void 680read_evh(struct nandsim_chip *chip, uint32_t type, void *data) 681{ 682 static uint32_t column = 0, row = 0; 683 uint32_t size; 684 uint8_t cmd; 685 686 size = chip->cg.page_size + chip->cg.oob_size; 687 688 switch (type) { 689 case NANDSIM_EV_START: 690 nandsim_log(chip, NANDSIM_LOG_SM, "in READ state\n"); 691 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_COL; 692 break; 693 case NANDSIM_EV_ADDR: 694 if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) { 695 if (nandchip_get_addr_byte(chip, data, &column)) 696 break; 697 698 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW; 699 } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) { 700 if (nandchip_get_addr_byte(chip, data, &row)) 701 break; 702 703 chip->sm_state = NANDSIM_STATE_WAIT_CMD; 704 } else 705 nandsim_ignore_address(chip, *((uint8_t *)data)); 706 break; 707 case NANDSIM_EV_CMD: 708 cmd = *(uint8_t *)data; 709 if (chip->sm_state == NANDSIM_STATE_WAIT_CMD && 710 cmd == NAND_CMD_READ_END) { 711 if (chip->read_delay != 0 && 712 nandsim_delay(chip, chip->read_delay) == 0) 713 nandchip_clear_status(chip, NAND_STATUS_RDY); 714 else { 715 nandchip_chip_space(chip, row, column, size, 0); 716 nandchip_set_status(chip, NAND_STATUS_RDY); 717 nandsim_start_handler(chip, idle_evh); 718 } 719 } else 720 nandsim_undefined(chip, type); 721 break; 722 case NANDSIM_EV_TIMEOUT: 723 if (chip->sm_state == NANDSIM_STATE_TIMEOUT) { 724 nandchip_chip_space(chip, row, column, size, 0); 725 nandchip_set_status(chip, NAND_STATUS_RDY); 726 nandsim_start_handler(chip, idle_evh); 727 } else 728 nandsim_undefined(chip, type); 729 break; 730 } 731} 732void 733write_evh(struct nandsim_chip *chip, uint32_t type, void *data) 734{ 735 static uint32_t column, row; 736 uint32_t size; 737 uint8_t cmd; 738 int err; 739 740 size = chip->cg.page_size + chip->cg.oob_size; 741 742 switch(type) { 743 case NANDSIM_EV_START: 744 nandsim_log(chip, NANDSIM_LOG_SM, "in WRITE state\n"); 745 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_COL; 746 break; 747 case NANDSIM_EV_ADDR: 748 if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) { 749 if (nandchip_get_addr_byte(chip, data, &column)) 750 break; 751 752 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW; 753 } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) { 754 if (nandchip_get_addr_byte(chip, data, &row)) 755 break; 756 757 err = nandchip_chip_space(chip, row, column, size, 1); 758 if (err == -1) 759 nandchip_set_status(chip, NAND_STATUS_FAIL); 760 761 chip->sm_state = NANDSIM_STATE_WAIT_CMD; 762 } else 763 nandsim_ignore_address(chip, *((uint8_t *)data)); 764 break; 765 case NANDSIM_EV_CMD: 766 cmd = *(uint8_t *)data; 767 if (chip->sm_state == NANDSIM_STATE_WAIT_CMD && 768 cmd == NAND_CMD_PROG_END) { 769 if (chip->prog_delay != 0 && 770 nandsim_delay(chip, chip->prog_delay) == 0) 771 nandchip_clear_status(chip, NAND_STATUS_RDY); 772 else { 773 nandchip_set_status(chip, NAND_STATUS_RDY); 774 nandsim_start_handler(chip, idle_evh); 775 } 776 } else 777 nandsim_undefined(chip, type); 778 break; 779 case NANDSIM_EV_TIMEOUT: 780 if (chip->sm_state == NANDSIM_STATE_TIMEOUT) { 781 nandsim_start_handler(chip, idle_evh); 782 nandchip_set_status(chip, NAND_STATUS_RDY); 783 } else 784 nandsim_undefined(chip, type); 785 break; 786 } 787} 788 789void 790erase_evh(struct nandsim_chip *chip, uint32_t type, void *data) 791{ 792 static uint32_t row, block_size; 793 uint32_t lun, block, page; 794 int err; 795 uint8_t cmd; 796 797 block_size = chip->cg.block_size + 798 (chip->cg.oob_size * chip->cg.pgs_per_blk); 799 800 switch (type) { 801 case NANDSIM_EV_START: 802 nandsim_log(chip, NANDSIM_LOG_SM, "in ERASE state\n"); 803 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW; 804 break; 805 case NANDSIM_EV_CMD: 806 cmd = *(uint8_t *)data; 807 if (chip->sm_state == NANDSIM_STATE_WAIT_CMD && 808 cmd == NAND_CMD_ERASE_END) { 809 if (chip->data.data_ptr != NULL && 810 chip->data.size == block_size) 811 memset(chip->data.data_ptr, 0xff, block_size); 812 else 813 nand_debug(NDBG_SIM,"Bad block erase data\n"); 814 815 err = nand_row_to_blkpg(&chip->cg, row, &lun, 816 &block, &page); 817 if (!err) { 818 if (chip->blk_state[block].wear_lev > 0) 819 chip->blk_state[block].wear_lev--; 820 } 821 822 if (chip->erase_delay != 0 && 823 nandsim_delay(chip, chip->erase_delay) == 0) 824 nandchip_clear_status(chip, NAND_STATUS_RDY); 825 else { 826 nandchip_set_status(chip, NAND_STATUS_RDY); 827 nandsim_start_handler(chip, idle_evh); 828 } 829 } else 830 nandsim_undefined(chip, type); 831 break; 832 case NANDSIM_EV_ADDR: 833 if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) { 834 if (nandchip_get_addr_byte(chip, data, &row)) 835 break; 836 837 err = nandchip_chip_space(chip, row, 0, block_size, 1); 838 if (err == -1) { 839 nandchip_set_status(chip, NAND_STATUS_FAIL); 840 } 841 chip->sm_state = NANDSIM_STATE_WAIT_CMD; 842 } else 843 nandsim_ignore_address(chip, *((uint8_t *)data)); 844 break; 845 case NANDSIM_EV_TIMEOUT: 846 if (chip->sm_state == NANDSIM_STATE_TIMEOUT) { 847 nandchip_set_status(chip, NAND_STATUS_RDY); 848 nandsim_start_handler(chip, idle_evh); 849 } else 850 nandsim_undefined(chip, type); 851 break; 852 } 853} 854 855void 856reset_evh(struct nandsim_chip *chip, uint32_t type, void *data) 857{ 858 859 if (type == NANDSIM_EV_START) { 860 nandsim_log(chip, NANDSIM_LOG_SM, "in RESET state\n"); 861 chip->sm_state = NANDSIM_STATE_TIMEOUT; 862 nandchip_set_data(chip, NULL, 0, 0); 863 DELAY(500); 864 nandsim_start_handler(chip, idle_evh); 865 } else 866 nandsim_undefined(chip, type); 867} 868 869static void 870nandsim_undefined(struct nandsim_chip *chip, uint8_t type) 871{ 872 873 nandsim_log(chip, NANDSIM_LOG_ERR, 874 "ERR: Chip received ev %x in state %x\n", 875 type, chip->sm_state); 876 nandsim_start_handler(chip, idle_evh); 877} 878 879static void 880nandsim_bad_address(struct nandsim_chip *chip, uint8_t *addr) 881{ 882 883 nandsim_log(chip, NANDSIM_LOG_ERR, 884 "ERR: Chip received out of range address" 885 "%02x%02x - %02x%02x%02x\n", addr[0], addr[1], addr[2], 886 addr[3], addr[4]); 887} 888 889static void 890nandsim_ignore_address(struct nandsim_chip *chip, uint8_t byte) 891{ 892 nandsim_log(chip, NANDSIM_LOG_SM, "ignored address byte: %d\n", byte); 893} 894 895static void 896nandsim_sm_error(struct nandsim_chip *chip) 897{ 898 899 nandsim_log(chip, NANDSIM_LOG_ERR, "ERR: State machine error." 900 "Restart required.\n"); 901} 902