xref: /NextBSD/sys/dev/nand/nandsim_chip.c (revision 287e3b14e9552995def1802ec9c5034f4adf28ec)
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$");
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 
48 MALLOC_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 
53 static nandsim_evh_t erase_evh;
54 static nandsim_evh_t idle_evh;
55 static nandsim_evh_t poweron_evh;
56 static nandsim_evh_t reset_evh;
57 static nandsim_evh_t read_evh;
58 static nandsim_evh_t readid_evh;
59 static nandsim_evh_t readparam_evh;
60 static nandsim_evh_t write_evh;
61 
62 static void nandsim_loop(void *);
63 static void nandsim_undefined(struct nandsim_chip *, uint8_t);
64 static void nandsim_bad_address(struct nandsim_chip *, uint8_t *);
65 static void nandsim_ignore_address(struct nandsim_chip *, uint8_t);
66 static void nandsim_sm_error(struct nandsim_chip *);
67 static void nandsim_start_handler(struct nandsim_chip *, nandsim_evh_t);
68 
69 static void nandsim_callout_eh(void *);
70 static int  nandsim_delay(struct nandsim_chip *, int);
71 
72 static int  nandsim_bbm_init(struct nandsim_chip *, uint32_t, uint32_t *);
73 static int  nandsim_blk_state_init(struct nandsim_chip *, uint32_t, uint32_t);
74 static void nandsim_blk_state_destroy(struct nandsim_chip *);
75 static int  nandchip_is_block_valid(struct nandsim_chip *, int);
76 
77 static void nandchip_set_status(struct nandsim_chip *, uint8_t);
78 static void nandchip_clear_status(struct nandsim_chip *, uint8_t);
79 
80 struct proc *nandsim_proc;
81 
82 struct nandsim_chip *
nandsim_chip_init(struct nandsim_softc * sc,uint8_t chip_num,struct sim_chip * sim_chip)83 nandsim_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 
198 static int
nandsim_blk_state_init(struct nandsim_chip * chip,uint32_t size,uint32_t wear_lev)199 nandsim_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 
223 static void
nandsim_blk_state_destroy(struct nandsim_chip * chip)224 nandsim_blk_state_destroy(struct nandsim_chip *chip)
225 {
226 
227 	if (chip && chip->blk_state)
228 		free(chip->blk_state, M_NANDSIM);
229 }
230 
231 static int
nandsim_bbm_init(struct nandsim_chip * chip,uint32_t size,uint32_t * sim_bbm)232 nandsim_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 
261 void
nandsim_chip_destroy(struct nandsim_chip * chip)262 nandsim_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 
271 void
nandsim_chip_freeze(struct nandsim_chip * chip)272 nandsim_chip_freeze(struct nandsim_chip *chip)
273 {
274 
275 	chip->flags |= NANDSIM_CHIP_FROZEN;
276 }
277 
278 static void
nandsim_loop(void * arg)279 nandsim_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 
336 struct nandsim_ev *
create_event(struct nandsim_chip * chip,uint8_t type,uint8_t data_size)337 create_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 
355 void
destroy_event(struct nandsim_ev * ev)356 destroy_event(struct nandsim_ev *ev)
357 {
358 
359 	if (ev->data)
360 		free(ev->data, M_NANDSIM);
361 	free(ev, M_NANDSIM);
362 }
363 
364 int
send_event(struct nandsim_ev * ev)365 send_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 
386 static void
nandsim_callout_eh(void * arg)387 nandsim_callout_eh(void *arg)
388 {
389 	struct nandsim_ev *ev = (struct nandsim_ev *)arg;
390 
391 	send_event(ev);
392 }
393 
394 static int
nandsim_delay(struct nandsim_chip * chip,int timeout)395 nandsim_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 
419 static void
nandsim_start_handler(struct nandsim_chip * chip,nandsim_evh_t evh)420 nandsim_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 
435 static void
nandchip_set_data(struct nandsim_chip * chip,uint8_t * data,uint32_t len,uint32_t idx)436 nandchip_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 
447 static int
nandchip_chip_space(struct nandsim_chip * chip,int32_t row,int32_t column,size_t size,uint8_t writing)448 nandchip_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 
489 static int
nandchip_get_addr_byte(struct nandsim_chip * chip,void * data,uint32_t * value)490 nandchip_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 
522 static int
nandchip_is_block_valid(struct nandsim_chip * chip,int block_num)523 nandchip_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 
536 static void
nandchip_set_status(struct nandsim_chip * chip,uint8_t flags)537 nandchip_set_status(struct nandsim_chip *chip, uint8_t flags)
538 {
539 
540 	chip->chip_status |= flags;
541 }
542 
543 static void
nandchip_clear_status(struct nandsim_chip * chip,uint8_t flags)544 nandchip_clear_status(struct nandsim_chip *chip, uint8_t flags)
545 {
546 
547 	chip->chip_status &= ~flags;
548 }
549 
550 uint8_t
nandchip_get_status(struct nandsim_chip * chip)551 nandchip_get_status(struct nandsim_chip *chip)
552 {
553 	return (chip->chip_status);
554 }
555 
556 void
nandsim_chip_timeout(struct nandsim_chip * chip)557 nandsim_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 }
568 void
poweron_evh(struct nandsim_chip * chip,uint32_t type,void * data)569 poweron_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 
590 void
idle_evh(struct nandsim_chip * chip,uint32_t type,void * data)591 idle_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 
626 void
readid_evh(struct nandsim_chip * chip,uint32_t type,void * data)627 readid_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 *)&params->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 
654 void
readparam_evh(struct nandsim_chip * chip,uint32_t type,void * data)655 readparam_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 
679 void
read_evh(struct nandsim_chip * chip,uint32_t type,void * data)680 read_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 }
732 void
write_evh(struct nandsim_chip * chip,uint32_t type,void * data)733 write_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 
789 void
erase_evh(struct nandsim_chip * chip,uint32_t type,void * data)790 erase_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 
855 void
reset_evh(struct nandsim_chip * chip,uint32_t type,void * data)856 reset_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 
869 static void
nandsim_undefined(struct nandsim_chip * chip,uint8_t type)870 nandsim_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 
879 static void
nandsim_bad_address(struct nandsim_chip * chip,uint8_t * addr)880 nandsim_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 
889 static void
nandsim_ignore_address(struct nandsim_chip * chip,uint8_t byte)890 nandsim_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 
895 static void
nandsim_sm_error(struct nandsim_chip * chip)896 nandsim_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