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