2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2002-2018 Aleph One Ltd.
6 * Created by Charles Manning <charles@aleph1.co.uk>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 * Nand simulator modelled on a Samsung K9K2G08U0A 8-bit, but capable of
14 * simulating x16 access too.
22 #include "nand_chip.h"
31 static int nandsim_debug = 0;
33 #define debug(n, fmt, ...) \
35 if (n <= nandsim_debug) \
36 printf(fmt, ## __VA_ARGS__); \
41 struct nandsim_private {
43 struct nand_store *store;
46 * Address buffer has two parts to it:
47 * 2 byte column (byte) offset
48 * 3 byte row (page) offset
51 unsigned char *buffer;
54 unsigned char addr_buffer[5];
57 * Offsets used to access address, read or write buffer.
58 * If the offset is negative then accessing is illegal.
70 * busy_count: If greater than zero then the device is busy.
71 * Busy count is decremented by check_busy() and by read_status()
76 unsigned char last_cmd_byte;
82 static void last_cmd(struct nandsim_private *ns, unsigned char val)
84 ns->last_cmd_byte = val;
87 static void check_last(struct nandsim_private *ns,
88 unsigned char should_be, int line)
90 if(ns->last_cmd_byte != should_be)
91 debug(1, "At line %d:, last_cmd should be %02x, but is %02x\n",
92 line, should_be, ns->last_cmd_byte);
95 static void idle(struct nandsim_private *ns, int line)
100 ns->write_offset = -1;
101 ns->addr_offset = -1;
102 ns->addr_expected = -1;
103 ns->addr_received = -1;
106 ns->reading_status = 0;
107 ns->read_started = 0;
111 static void expect_address(struct nandsim_private *ns,
112 int nbytes, int line)
117 case 5: /* contains an offset */
120 case 3: /* no offset */
124 debug(1, "expect_address illegal nbytes %d called at line %d\n",
129 ns->addr_offset = from;
130 ns->addr_expected = nbytes;
131 ns->addr_received = 0;
132 debug(1, "Expect %d address bytes\n",nbytes);
135 static int get_page_address(struct nandsim_private *ns)
139 addr = (ns->addr_buffer[2]) |
140 (ns->addr_buffer[3] << 8) |
141 (ns->addr_buffer[4] << 16);
145 static int get_page_offset(struct nandsim_private *ns)
149 offs = (ns->addr_buffer[0]) |
150 (ns->addr_buffer[1] << 8);
154 static void check_address(struct nandsim_private *ns, int nbytes, int line)
156 if(ns->addr_expected != 0)
157 debug(1, "Still expecting %d address bytes at line: %d\n",
158 ns->addr_expected, line);
159 if(ns->addr_received != nbytes)
160 debug(1, "Only received %d address bytes instead of %d at line %d\n",
161 ns->addr_received, nbytes, line);
164 static void set_offset(struct nandsim_private *ns)
166 ns->read_offset = -1;
167 ns->write_offset = -1;
169 if(ns->last_cmd_byte == 0x80 )
170 ns->write_offset = get_page_offset(ns);
171 else if(ns->last_cmd_byte == 0x00 || ns->last_cmd_byte == 0x05)
172 ns->read_offset = get_page_offset(ns);
173 debug(2, "Last command was %02X offsets set to read %d write %d\n",
174 ns->last_cmd_byte, ns->read_offset, ns->write_offset);
177 static void load_read_buffer(struct nandsim_private *ns)
179 int addr = get_page_address(ns);
181 debug(1, "Store read at address %d\n", addr);
182 ns->store->retrieve(ns->store, addr,ns->buffer);
184 static void save_write_buffer(struct nandsim_private *ns)
186 int addr = get_page_address(ns);
188 debug(1, "Store write at address %d\n", addr);
189 ns->store->store(ns->store, addr, ns->buffer);
192 static void check_read_buffer(struct nandsim_private *ns, int line)
198 static void end_cmd(struct nandsim_private *ns, int line)
202 ns->last_cmd_byte = 0xff;
205 static void set_busy(struct nandsim_private *ns, int cycles, int line)
209 ns->busy_count = cycles;
212 static int check_not_busy(struct nandsim_private *ns, int line)
214 if(ns->busy_count > 0)
215 debug(1, "Busy check failed at line %d\n",line);
216 return (ns->busy_count < 1);
223 static void reset_0(struct nandsim_private *ns)
228 end_cmd(ns, __LINE__);
233 * cmd: 0x00, 5 address bytes, cmd: 0x30, wait not busy, read out data
235 * Note that 0x30 can also be used to exit the status reading state
236 * and return to data reading state.
238 * The following sequence uses the busy pin to wait:
241 * Write 5 address bytes
242 * Write cmd 0x30. Device now goes busy
243 * Wait for busy pin to go idle
246 * The following sequence uses the status read to wait:
248 * Write 5 address bytes
249 * Write cmd 0x30. Device now goes busy
250 * Write 0x70: (status)
251 * Read status until device no longer busy
252 * Write command byte 0x30 to exit status read. Can now read data
258 static void read_0(struct nandsim_private *ns)
260 debug(2, "Read 0\n");
261 check_last(ns, 0xff, __LINE__);
262 if(check_not_busy(ns, __LINE__))
263 ns->reading_status = 0;
264 expect_address(ns, 5, __LINE__);
266 ns->read_started = 1;
269 static void read_1(struct nandsim_private *ns)
271 debug(2, "Read 1\n");
272 if(check_not_busy(ns, __LINE__))
273 ns->reading_status = 0;
274 if(ns->read_started){
276 ns->read_started = 0;
277 check_address(ns, 5, __LINE__);
278 load_read_buffer(ns);
279 set_busy(ns, 2, __LINE__);
280 end_cmd(ns, __LINE__);
282 /* reenter read mode after a status check */
283 end_cmd(ns, __LINE__);
288 * Random Data Output (sets read position in current page)
289 * Cmd: 0x05, 2-byte address, cmd: 0xE0. No busy
292 static void random_data_output_0(struct nandsim_private *ns)
294 debug(2, "Random data out 0\n");
295 check_last(ns, 0xff, __LINE__);
296 if(check_not_busy(ns, __LINE__))
297 ns->reading_status = 0;
298 check_read_buffer(ns, __LINE__);
299 expect_address(ns, 2, __LINE__);
303 static void random_data_output_1(struct nandsim_private *ns)
305 debug(2, "Random data out 1\n");
306 check_last(ns, 0x05, __LINE__);
307 check_address(ns, 2, __LINE__);
313 * Cmd: 0x80, 5-byte address, data bytes, Cmd: 0x10, wait not busy
314 * That can be extended with random data input by inserting
315 * any number of random data input cycles before the 0x10 command
316 * Each random data input cycle is
317 * Cmd 0x85 , 2 byte offset, data bytes
320 static void program_0(struct nandsim_private *ns)
322 debug(2, "Program 0\n");
323 check_last(ns, 0xff, __LINE__);
324 if(check_not_busy(ns, __LINE__))
325 ns->reading_status = 0;
326 expect_address(ns, 5, __LINE__);
327 memset(ns->buffer, 0xff, ns->buff_size);
330 static void random_data_input(struct nandsim_private *ns)
332 debug(2, "Random data input\n");
333 check_last(ns, 0x80, __LINE__);
334 expect_address(ns, 2, __LINE__);
338 static void program_1(struct nandsim_private *ns)
340 debug(2, "Program 1\n");
341 if(check_not_busy(ns, __LINE__))
342 ns->reading_status = 0;
343 check_last(ns, 0x80, __LINE__);
344 check_address(ns, 5, __LINE__);
345 save_write_buffer(ns);
346 set_busy(ns, 2, __LINE__);
347 end_cmd(ns, __LINE__);
354 * Cmd: 0x60, 3-byte address, cmd: 0xD0. Wait not busy.
356 static void block_erase_0(struct nandsim_private *ns)
358 debug(2, "Block Erase 0\n");
359 check_last(ns, 0xff, __LINE__);
360 if(check_not_busy(ns, __LINE__))
361 ns->reading_status = 0;
362 expect_address(ns, 3, __LINE__);
366 static void block_erase_1(struct nandsim_private *ns)
370 debug(2, "Block Erase 1\n");
371 check_last(ns, 0x60, __LINE__);
372 if(check_not_busy(ns, __LINE__))
373 ns->reading_status = 0;
374 check_address(ns, 3, __LINE__);
375 set_busy(ns, 5, __LINE__);
376 addr = get_page_address(ns);
377 debug(1, "Erasing block at address %d\n", addr);
378 ns->store->erase(ns->store, addr);
379 end_cmd(ns, __LINE__);
385 static void read_status(struct nandsim_private *ns)
387 debug(2, "Read status\n");
388 ns->reading_status = 1;
391 static void read_id(struct nandsim_private *ns)
397 static void unsupported(struct nandsim_private *ns)
402 static void nandsim_cl_write(struct nandsim_private *ns, unsigned char val)
404 debug(2, "CLE write %02X\n",val);
410 random_data_output_0(ns);
434 random_data_input(ns);
443 random_data_output_1(ns);
449 debug(1, "CLE written with invalid value %02X.\n",val);
451 /* Valid codes that we don't handle */
452 debug(1, "CLE written with invalid value %02X.\n",val);
457 static void nandsim_al_write(struct nandsim_private *ns, unsigned char val)
459 check_not_busy(ns, __LINE__);
460 if(ns->addr_expected < 1 ||
461 ns->addr_offset < 0 ||
462 ns->addr_offset >= (int)sizeof(ns->addr_buffer)){
463 debug(1, "Address write when not expected\n");
465 debug(1, "Address write when expecting %d bytes\n",
467 ns->addr_buffer[ns->addr_offset] = val;
471 if(ns->addr_expected == 0)
476 static void nandsim_dl_write(struct nandsim_private *ns,
480 check_not_busy(ns, __LINE__);
481 if( ns->write_offset < 0 || ns->write_offset >= ns->buff_size){
482 debug(1, "Write at illegal buffer offset %d\n",
484 } else if(bus_width_shift == 0) {
485 ns->buffer[ns->write_offset] = val & 0xff;
487 } else if(bus_width_shift == 1) {
488 ns->buffer[ns->write_offset] = val & 0xff;
490 ns->buffer[ns->write_offset] = (val>>8) & 0xff;
495 static unsigned nandsim_dl_read(struct nandsim_private *ns,
499 if(ns->reading_status){
501 * bit 0 == 0 pass, == 1 fail.
502 * bit 6 == 0 busy, == 1 ready
505 if(ns->busy_count > 0){
509 if(ns->write_prog_error)
511 debug(2, "Read status returning %02X\n",retval);
512 } else if(ns->busy_count > 0){
513 debug(1, "Read while still busy\n");
515 } else if(ns->read_offset < 0 || ns->read_offset >= ns->buff_size){
516 debug(1, "Read with no data available\n");
518 } else if(bus_width_shift == 0){
519 retval = ns->buffer[ns->read_offset];
521 } else if(bus_width_shift == 1){
522 retval = ns->buffer[ns->read_offset];
524 retval |= (((unsigned)ns->buffer[ns->read_offset]) << 8);
532 static struct nandsim_private *
533 nandsim_init_private(struct nand_store *store)
535 struct nandsim_private *ns;
536 unsigned char *buffer;
539 buff_size = (store->data_bytes_per_page + store->spare_bytes_per_page);
541 ns = malloc(sizeof(struct nandsim_private));
542 buffer = malloc(buff_size);
549 memset(ns, 0, sizeof(struct nandsim_private));
551 ns->buff_size = buff_size;
558 static void nandsim_set_ale(struct nand_chip * this, int ale)
560 struct nandsim_private *ns =
561 (struct nandsim_private *)this->private_data;
565 static void nandsim_set_cle(struct nand_chip * this, int cle)
567 struct nandsim_private *ns =
568 (struct nandsim_private *)this->private_data;
572 static unsigned nandsim_read_cycle(struct nand_chip * this)
575 struct nandsim_private *ns =
576 (struct nandsim_private *)this->private_data;
578 if (ns->cle || ns->ale){
579 debug(1, "Read cycle with CLE %s and ALE %s\n",
580 ns->cle ? "high" : "low",
581 ns->ale ? "high" : "low");
584 retval =nandsim_dl_read(ns, this->bus_width_shift);
586 debug(5, "Read cycle returning %02X\n",retval);
590 static void nandsim_write_cycle(struct nand_chip * this, unsigned b)
592 struct nandsim_private *ns =
593 (struct nandsim_private *)this->private_data;
596 if(ns->ale && ns->cle)
605 debug(5, "Write %02x to %s\n",
607 if (ns->cle && ns->ale)
608 debug(1, "Write cycle with both ALE and CLE high\n");
610 nandsim_cl_write(ns, b);
612 nandsim_al_write(ns, b);
614 nandsim_dl_write(ns, b, this->bus_width_shift);
617 static int nandsim_check_busy(struct nand_chip * this)
619 struct nandsim_private *ns =
620 (struct nandsim_private *)this->private_data;
623 if (ns->busy_count> 0){
625 debug(2, "Still busy\n");
628 debug(2, "Not busy\n");
633 static void nandsim_idle_fn(struct nand_chip *this)
635 struct nandsim_private *ns =
636 (struct nandsim_private *)this->private_data;
640 struct nand_chip *nandsim_init(struct nand_store *store, int bus_width_shift)
642 struct nand_chip *chip = NULL;
643 struct nandsim_private *ns = NULL;
645 chip = malloc(sizeof(struct nand_chip));
646 ns = nandsim_init_private(store);
649 memset(chip, 0, sizeof(struct nand_chip));;
651 chip->private_data = ns;
652 chip->set_ale = nandsim_set_ale;
653 chip->set_cle = nandsim_set_cle;
654 chip->read_cycle = nandsim_read_cycle;
655 chip->write_cycle = nandsim_write_cycle;
656 chip->check_busy = nandsim_check_busy;
657 chip->idle_fn = nandsim_idle_fn;
659 chip->bus_width_shift = bus_width_shift;
661 chip->blocks = ns->store->blocks;
662 chip->pages_per_block = ns->store->pages_per_block;
663 chip->data_bytes_per_page = ns->store->data_bytes_per_page;
664 chip->spare_bytes_per_page = ns->store->spare_bytes_per_page;
674 void nandsim_set_debug(int d)