2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2010-2011 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)
98 ns->write_offset = -1;
100 ns->addr_expected = -1;
101 ns->addr_received = -1;
104 ns->reading_status = 0;
105 ns->read_started = 0;
109 static void expect_address(struct nandsim_private *ns,
110 int nbytes, int line)
115 case 5: /* contains an offset */
118 case 3: /* no offset */
122 debug(1, "expect_address illegal nbytes %d called at line %d\n",
127 ns->addr_offset = from;
128 ns->addr_expected = nbytes;
129 ns->addr_received = 0;
130 debug(1, "Expect %d address bytes\n",nbytes);
133 static int get_page_address(struct nandsim_private *ns)
137 addr = (ns->addr_buffer[2]) |
138 (ns->addr_buffer[3] << 8) |
139 (ns->addr_buffer[4] << 16);
143 static int get_page_offset(struct nandsim_private *ns)
147 offs = (ns->addr_buffer[0]) |
148 (ns->addr_buffer[1] << 8);
152 static void check_address(struct nandsim_private *ns, int nbytes, int line)
154 if(ns->addr_expected != 0)
155 debug(1, "Still expecting %d address bytes at line: %d\n",
156 ns->addr_expected, line);
157 if(ns->addr_received != nbytes)
158 debug(1, "Only received %d address bytes instead of %d at line %d\n",
159 ns->addr_received, nbytes, line);
162 static void set_offset(struct nandsim_private *ns)
164 ns->read_offset = -1;
165 ns->write_offset = -1;
167 if(ns->last_cmd_byte == 0x80 )
168 ns->write_offset = get_page_offset(ns);
169 else if(ns->last_cmd_byte == 0x00 || ns->last_cmd_byte == 0x05)
170 ns->read_offset = get_page_offset(ns);
171 debug(2, "Last command was %02X offsets set to read %d write %d\n",
172 ns->last_cmd_byte, ns->read_offset, ns->write_offset);
175 static void load_read_buffer(struct nandsim_private *ns)
177 int addr = get_page_address(ns);
178 debug(1, "Store read at address %d\n", addr);
179 ns->store->retrieve(ns->store, addr,ns->buffer);
181 static void save_write_buffer(struct nandsim_private *ns)
183 int addr = get_page_address(ns);
184 debug(1, "Store write at address %d\n", addr);
185 ns->store->store(ns->store, addr, ns->buffer);
188 static void check_read_buffer(struct nandsim_private *ns, int line)
192 static void end_cmd(struct nandsim_private *ns, int line)
194 ns->last_cmd_byte = 0xff;
197 static void set_busy(struct nandsim_private *ns, int cycles, int line)
199 ns->busy_count = cycles;
202 static int check_not_busy(struct nandsim_private *ns, int line)
204 if(ns->busy_count > 0)
205 debug(1, "Busy check failed at line %d\n",line);
206 return (ns->busy_count < 1);
213 static void reset_0(struct nandsim_private *ns)
218 end_cmd(ns, __LINE__);
223 * cmd: 0x00, 5 address bytes, cmd: 0x30, wait not busy, read out data
225 * Note that 0x30 can also be used to exit the status reading state
226 * and return to data reading state.
228 * The following sequence uses the busy pin to wait:
231 * Write 5 address bytes
232 * Write cmd 0x30. Device now goes busy
233 * Wait for busy pin to go idle
236 * The following sequence uses the status read to wait:
238 * Write 5 address bytes
239 * Write cmd 0x30. Device now goes busy
240 * Write 0x70: (status)
241 * Read status until device no longer busy
242 * Write command byte 0x30 to exit status read. Can now read data
248 static void read_0(struct nandsim_private *ns)
250 debug(2, "Read 0\n");
251 check_last(ns, 0xff, __LINE__);
252 if(check_not_busy(ns, __LINE__))
253 ns->reading_status = 0;
254 expect_address(ns, 5, __LINE__);
256 ns->read_started = 1;
259 static void read_1(struct nandsim_private *ns)
261 debug(2, "Read 1\n");
262 if(check_not_busy(ns, __LINE__))
263 ns->reading_status = 0;
264 if(ns->read_started){
266 ns->read_started = 0;
267 check_address(ns, 5, __LINE__);
268 load_read_buffer(ns);
269 set_busy(ns, 2, __LINE__);
270 end_cmd(ns, __LINE__);
272 /* reenter read mode after a status check */
273 end_cmd(ns, __LINE__);
278 * Random Data Output (sets read position in current page)
279 * Cmd: 0x05, 2-byte address, cmd: 0xE0. No busy
282 static void random_data_output_0(struct nandsim_private *ns)
284 debug(2, "Random data out 0\n");
285 check_last(ns, 0xff, __LINE__);
286 if(check_not_busy(ns, __LINE__))
287 ns->reading_status = 0;
288 check_read_buffer(ns, __LINE__);
289 expect_address(ns, 2, __LINE__);
293 static void random_data_output_1(struct nandsim_private *ns)
295 debug(2, "Random data out 1\n");
296 check_last(ns, 0x05, __LINE__);
297 check_address(ns, 2, __LINE__);
303 * Cmd: 0x80, 5-byte address, data bytes, Cmd: 0x10, wait not busy
304 * That can be extended with random data input by inserting
305 * any number of random data input cycles before the 0x10 command
306 * Each random data input cycle is
307 * Cmd 0x85 , 2 byte offset, data bytes
310 static void program_0(struct nandsim_private *ns)
312 debug(2, "Program 0\n");
313 check_last(ns, 0xff, __LINE__);
314 if(check_not_busy(ns, __LINE__))
315 ns->reading_status = 0;
316 expect_address(ns, 5, __LINE__);
317 memset(ns->buffer, 0xff, ns->buff_size);
320 static void random_data_input(struct nandsim_private *ns)
322 debug(2, "Random data input\n");
323 check_last(ns, 0x80, __LINE__);
324 expect_address(ns, 2, __LINE__);
328 static void program_1(struct nandsim_private *ns)
330 debug(2, "Program 1\n");
331 if(check_not_busy(ns, __LINE__))
332 ns->reading_status = 0;
333 check_last(ns, 0x80, __LINE__);
334 check_address(ns, 5, __LINE__);
335 save_write_buffer(ns);
336 set_busy(ns, 2, __LINE__);
337 end_cmd(ns, __LINE__);
344 * Cmd: 0x60, 3-byte address, cmd: 0xD0. Wait not busy.
346 static void block_erase_0(struct nandsim_private *ns)
348 debug(2, "Block Erase 0\n");
349 check_last(ns, 0xff, __LINE__);
350 if(check_not_busy(ns, __LINE__))
351 ns->reading_status = 0;
352 expect_address(ns, 3, __LINE__);
356 static void block_erase_1(struct nandsim_private *ns)
360 debug(2, "Block Erase 1\n");
361 check_last(ns, 0x60, __LINE__);
362 if(check_not_busy(ns, __LINE__))
363 ns->reading_status = 0;
364 check_address(ns, 3, __LINE__);
365 set_busy(ns, 5, __LINE__);
366 addr = get_page_address(ns);
367 debug(1, "Erasing block at address %d\n", addr);
368 ns->store->erase(ns->store, addr);
369 end_cmd(ns, __LINE__);
375 static void read_status(struct nandsim_private *ns)
377 debug(2, "Read status\n");
378 ns->reading_status = 1;
381 static void read_id(struct nandsim_private *ns)
386 static void unsupported(struct nandsim_private *ns)
390 static void nandsim_cl_write(struct nandsim_private *ns, unsigned char val)
392 debug(2, "CLE write %02X\n",val);
398 random_data_output_0(ns);
422 random_data_input(ns);
431 random_data_output_1(ns);
437 debug(1, "CLE written with invalid value %02X.\n",val);
439 /* Valid codes that we don't handle */
440 debug(1, "CLE written with invalid value %02X.\n",val);
445 static void nandsim_al_write(struct nandsim_private *ns, unsigned char val)
447 check_not_busy(ns, __LINE__);
448 if(ns->addr_expected < 1 ||
449 ns->addr_offset < 0 ||
450 ns->addr_offset >= sizeof(ns->addr_buffer)){
451 debug(1, "Address write when not expected\n");
453 debug(1, "Address write when expecting %d bytes\n",
455 ns->addr_buffer[ns->addr_offset] = val;
459 if(ns->addr_expected == 0)
464 static void nandsim_dl_write(struct nandsim_private *ns,
468 check_not_busy(ns, __LINE__);
469 if( ns->write_offset < 0 || ns->write_offset >= ns->buff_size){
470 debug(1, "Write at illegal buffer offset %d\n",
472 } else if(bus_width_shift == 0) {
473 ns->buffer[ns->write_offset] = val & 0xff;
475 } else if(bus_width_shift == 1) {
476 ns->buffer[ns->write_offset] = val & 0xff;
478 ns->buffer[ns->write_offset] = (val>>8) & 0xff;
483 static unsigned nandsim_dl_read(struct nandsim_private *ns,
487 if(ns->reading_status){
489 * bit 0 == 0 pass, == 1 fail.
490 * bit 6 == 0 busy, == 1 ready
493 if(ns->busy_count > 0){
497 if(ns->write_prog_error)
499 debug(2, "Read status returning %02X\n",retval);
500 } else if(ns->busy_count > 0){
501 debug(1, "Read while still busy\n");
503 } else if(ns->read_offset < 0 || ns->read_offset >= ns->buff_size){
504 debug(1, "Read with no data available\n");
506 } else if(bus_width_shift == 0){
507 retval = ns->buffer[ns->read_offset];
509 } else if(bus_width_shift == 1){
510 retval = ns->buffer[ns->read_offset];
512 retval |= (((unsigned)ns->buffer[ns->read_offset]) << 8);
520 static struct nandsim_private *
521 nandsim_init_private(struct nand_store *store)
523 struct nandsim_private *ns;
524 unsigned char *buffer;
527 buff_size = (store->data_bytes_per_page + store->spare_bytes_per_page);
529 ns = malloc(sizeof(struct nandsim_private));
530 buffer = malloc(buff_size);
537 memset(ns, 0, sizeof(struct nandsim_private));
539 ns->buff_size = buff_size;
546 static void nandsim_set_ale(struct nand_chip * this, int ale)
548 struct nandsim_private *ns =
549 (struct nandsim_private *)this->private_data;
553 static void nandsim_set_cle(struct nand_chip * this, int cle)
555 struct nandsim_private *ns =
556 (struct nandsim_private *)this->private_data;
560 static unsigned nandsim_read_cycle(struct nand_chip * this)
563 struct nandsim_private *ns =
564 (struct nandsim_private *)this->private_data;
566 if (ns->cle || ns->ale){
567 debug(1, "Read cycle with CLE %s and ALE %s\n",
568 ns->cle ? "high" : "low",
569 ns->ale ? "high" : "low");
572 retval =nandsim_dl_read(ns, this->bus_width_shift);
574 debug(5, "Read cycle returning %02X\n",retval);
578 static void nandsim_write_cycle(struct nand_chip * this, unsigned b)
580 struct nandsim_private *ns =
581 (struct nandsim_private *)this->private_data;
584 if(ns->ale && ns->cle)
593 debug(5, "Write %02x to %s\n",
595 if (ns->cle && ns->ale)
596 debug(1, "Write cycle with both ALE and CLE high\n");
598 nandsim_cl_write(ns, b);
600 nandsim_al_write(ns, b);
602 nandsim_dl_write(ns, b, this->bus_width_shift);
605 static int nandsim_check_busy(struct nand_chip * this)
607 struct nandsim_private *ns =
608 (struct nandsim_private *)this->private_data;
611 if (ns->busy_count> 0){
613 debug(2, "Still busy\n");
616 debug(2, "Not busy\n");
621 static void nandsim_idle_fn(struct nand_chip *this)
623 struct nandsim_private *ns =
624 (struct nandsim_private *)this->private_data;
628 struct nand_chip *nandsim_init(struct nand_store *store, int bus_width_shift)
630 struct nand_chip *chip = NULL;
631 struct nandsim_private *ns = NULL;
633 chip = malloc(sizeof(struct nand_chip));
634 ns = nandsim_init_private(store);
637 memset(chip, 0, sizeof(struct nand_chip));;
639 chip->private_data = ns;
640 chip->set_ale = nandsim_set_ale;
641 chip->set_cle = nandsim_set_cle;
642 chip->read_cycle = nandsim_read_cycle;
643 chip->write_cycle = nandsim_write_cycle;
644 chip->check_busy = nandsim_check_busy;
645 chip->idle_fn = nandsim_idle_fn;
647 chip->bus_width_shift = bus_width_shift;
649 chip->blocks = ns->store->blocks;
650 chip->pages_per_block = ns->store->pages_per_block;
651 chip->data_bytes_per_page = ns->store->data_bytes_per_page;
652 chip->spare_bytes_per_page = ns->store->spare_bytes_per_page;
662 void nandsim_set_debug(int d)