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"
33 static int nandsim_debug = 0;
35 #define debug(n, fmt, ...) \
37 if (n <= nandsim_debug) \
38 printf(fmt, ## __VA_ARGS__); \
43 struct nandsim_private {
45 struct nand_store *store;
48 * Address buffer has two parts to it:
49 * 2 byte column (byte) offset
50 * 3 byte row (page) offset
53 unsigned char *buffer;
56 unsigned char addr_buffer[5];
59 * Offsets used to access address, read or write buffer.
60 * If the offset is negative then accessing is illegal.
72 * busy_count: If greater than zero then the device is busy.
73 * Busy count is decremented by check_busy() and by read_status()
78 unsigned char last_cmd_byte;
84 static void last_cmd(struct nandsim_private *ns, unsigned char val)
86 ns->last_cmd_byte = val;
89 static void check_last(struct nandsim_private *ns,
90 unsigned char should_be, int line)
92 if(ns->last_cmd_byte != should_be)
93 debug(1, "At line %d:, last_cmd should be %02x, but is %02x\n",
94 line, should_be, ns->last_cmd_byte);
97 static void idle(struct nandsim_private *ns, int line)
101 ns->read_offset = -1;
102 ns->write_offset = -1;
103 ns->addr_offset = -1;
104 ns->addr_expected = -1;
105 ns->addr_received = -1;
108 ns->reading_status = 0;
109 ns->read_started = 0;
113 static void expect_address(struct nandsim_private *ns,
114 int nbytes, int line)
120 case 5: /* contains an offset */
123 case 3: /* no offset */
127 debug(1, "expect_address illegal nbytes %d called at line %d\n",
132 ns->addr_offset = from;
133 ns->addr_expected = nbytes;
134 ns->addr_received = 0;
135 debug(1, "Expect %d address bytes\n",nbytes);
138 static int get_page_address(struct nandsim_private *ns)
142 addr = (ns->addr_buffer[2]) |
143 (ns->addr_buffer[3] << 8) |
144 (ns->addr_buffer[4] << 16);
148 static int get_page_offset(struct nandsim_private *ns)
152 offs = (ns->addr_buffer[0]) |
153 (ns->addr_buffer[1] << 8);
157 static void check_address(struct nandsim_private *ns, int nbytes, int line)
159 if(ns->addr_expected != 0)
160 debug(1, "Still expecting %d address bytes at line: %d\n",
161 ns->addr_expected, line);
162 if(ns->addr_received != nbytes)
163 debug(1, "Only received %d address bytes instead of %d at line %d\n",
164 ns->addr_received, nbytes, line);
167 static void set_offset(struct nandsim_private *ns)
169 ns->read_offset = -1;
170 ns->write_offset = -1;
172 if(ns->last_cmd_byte == 0x80 )
173 ns->write_offset = get_page_offset(ns);
174 else if(ns->last_cmd_byte == 0x00 || ns->last_cmd_byte == 0x05)
175 ns->read_offset = get_page_offset(ns);
176 debug(2, "Last command was %02X offsets set to read %d write %d\n",
177 ns->last_cmd_byte, ns->read_offset, ns->write_offset);
180 static void load_read_buffer(struct nandsim_private *ns)
182 int addr = get_page_address(ns);
184 debug(1, "Store read at address %d\n", addr);
185 ns->store->retrieve(ns->store, addr,ns->buffer);
187 static void save_write_buffer(struct nandsim_private *ns)
189 int addr = get_page_address(ns);
191 debug(1, "Store write at address %d\n", addr);
192 ns->store->store(ns->store, addr, ns->buffer);
195 static void check_read_buffer(struct nandsim_private *ns, int line)
201 static void end_cmd(struct nandsim_private *ns, int line)
204 ns->last_cmd_byte = 0xff;
207 static void set_busy(struct nandsim_private *ns, int cycles, int line)
211 ns->busy_count = cycles;
214 static int check_not_busy(struct nandsim_private *ns, int line)
216 if(ns->busy_count > 0)
217 debug(1, "Busy check failed at line %d\n",line);
218 return (ns->busy_count < 1);
225 static void reset_0(struct nandsim_private *ns)
230 end_cmd(ns, __LINE__);
235 * cmd: 0x00, 5 address bytes, cmd: 0x30, wait not busy, read out data
237 * Note that 0x30 can also be used to exit the status reading state
238 * and return to data reading state.
240 * The following sequence uses the busy pin to wait:
243 * Write 5 address bytes
244 * Write cmd 0x30. Device now goes busy
245 * Wait for busy pin to go idle
248 * The following sequence uses the status read to wait:
250 * Write 5 address bytes
251 * Write cmd 0x30. Device now goes busy
252 * Write 0x70: (status)
253 * Read status until device no longer busy
254 * Write command byte 0x30 to exit status read. Can now read data
260 static void read_0(struct nandsim_private *ns)
262 debug(2, "Read 0\n");
263 check_last(ns, 0xff, __LINE__);
264 if(check_not_busy(ns, __LINE__))
265 ns->reading_status = 0;
266 expect_address(ns, 5, __LINE__);
268 ns->read_started = 1;
271 static void read_1(struct nandsim_private *ns)
273 debug(2, "Read 1\n");
274 if(check_not_busy(ns, __LINE__))
275 ns->reading_status = 0;
276 if(ns->read_started){
278 ns->read_started = 0;
279 check_address(ns, 5, __LINE__);
280 load_read_buffer(ns);
281 set_busy(ns, 2, __LINE__);
282 end_cmd(ns, __LINE__);
284 /* reenter read mode after a status check */
285 end_cmd(ns, __LINE__);
290 * Random Data Output (sets read position in current page)
291 * Cmd: 0x05, 2-byte address, cmd: 0xE0. No busy
294 static void random_data_output_0(struct nandsim_private *ns)
296 debug(2, "Random data out 0\n");
297 check_last(ns, 0xff, __LINE__);
298 if(check_not_busy(ns, __LINE__))
299 ns->reading_status = 0;
300 check_read_buffer(ns, __LINE__);
301 expect_address(ns, 2, __LINE__);
305 static void random_data_output_1(struct nandsim_private *ns)
307 debug(2, "Random data out 1\n");
308 check_last(ns, 0x05, __LINE__);
309 check_address(ns, 2, __LINE__);
315 * Cmd: 0x80, 5-byte address, data bytes, Cmd: 0x10, wait not busy
316 * That can be extended with random data input by inserting
317 * any number of random data input cycles before the 0x10 command
318 * Each random data input cycle is
319 * Cmd 0x85 , 2 byte offset, data bytes
322 static void program_0(struct nandsim_private *ns)
324 debug(2, "Program 0\n");
325 check_last(ns, 0xff, __LINE__);
326 if(check_not_busy(ns, __LINE__))
327 ns->reading_status = 0;
328 expect_address(ns, 5, __LINE__);
329 memset(ns->buffer, 0xff, ns->buff_size);
332 static void random_data_input(struct nandsim_private *ns)
334 debug(2, "Random data input\n");
335 check_last(ns, 0x80, __LINE__);
336 expect_address(ns, 2, __LINE__);
340 static void program_1(struct nandsim_private *ns)
342 debug(2, "Program 1\n");
343 if(check_not_busy(ns, __LINE__))
344 ns->reading_status = 0;
345 check_last(ns, 0x80, __LINE__);
346 check_address(ns, 5, __LINE__);
347 save_write_buffer(ns);
348 set_busy(ns, 2, __LINE__);
349 end_cmd(ns, __LINE__);
356 * Cmd: 0x60, 3-byte address, cmd: 0xD0. Wait not busy.
358 static void block_erase_0(struct nandsim_private *ns)
360 debug(2, "Block Erase 0\n");
361 check_last(ns, 0xff, __LINE__);
362 if(check_not_busy(ns, __LINE__))
363 ns->reading_status = 0;
364 expect_address(ns, 3, __LINE__);
368 static void block_erase_1(struct nandsim_private *ns)
372 debug(2, "Block Erase 1\n");
373 check_last(ns, 0x60, __LINE__);
374 if(check_not_busy(ns, __LINE__))
375 ns->reading_status = 0;
376 check_address(ns, 3, __LINE__);
377 set_busy(ns, 5, __LINE__);
378 addr = get_page_address(ns);
379 debug(1, "Erasing block at address %d\n", addr);
380 ns->store->erase(ns->store, addr);
381 end_cmd(ns, __LINE__);
387 static void read_status(struct nandsim_private *ns)
389 debug(2, "Read status\n");
390 ns->reading_status = 1;
393 static void read_id(struct nandsim_private *ns)
399 static void unsupported(struct nandsim_private *ns)
404 static void nandsim_cl_write(struct nandsim_private *ns, unsigned char val)
406 debug(2, "CLE write %02X\n",val);
412 random_data_output_0(ns);
436 random_data_input(ns);
445 random_data_output_1(ns);
451 debug(1, "CLE written with invalid value %02X.\n",val);
453 /* Valid codes that we don't handle */
454 debug(1, "CLE written with invalid value %02X.\n",val);
459 static void nandsim_al_write(struct nandsim_private *ns, unsigned char val)
461 check_not_busy(ns, __LINE__);
462 if(ns->addr_expected < 1 ||
463 ns->addr_offset < 0 ||
464 ns->addr_offset >= (int)sizeof(ns->addr_buffer)){
465 debug(1, "Address write when not expected\n");
467 debug(1, "Address write when expecting %d bytes\n",
469 ns->addr_buffer[ns->addr_offset] = val;
473 if(ns->addr_expected == 0)
478 static void nandsim_dl_write(struct nandsim_private *ns,
482 check_not_busy(ns, __LINE__);
483 if( ns->write_offset < 0 || ns->write_offset >= ns->buff_size){
484 debug(1, "Write at illegal buffer offset %d\n",
486 } else if(bus_width_shift == 0) {
487 ns->buffer[ns->write_offset] = val & 0xff;
489 } else if(bus_width_shift == 1) {
490 ns->buffer[ns->write_offset] = val & 0xff;
492 ns->buffer[ns->write_offset] = (val>>8) & 0xff;
497 static unsigned nandsim_dl_read(struct nandsim_private *ns,
501 if(ns->reading_status){
503 * bit 0 == 0 pass, == 1 fail.
504 * bit 6 == 0 busy, == 1 ready
507 if(ns->busy_count > 0){
511 if(ns->write_prog_error)
513 debug(2, "Read status returning %02X\n",retval);
514 } else if(ns->busy_count > 0){
515 debug(1, "Read while still busy\n");
517 } else if(ns->read_offset < 0 || ns->read_offset >= ns->buff_size){
518 debug(1, "Read with no data available\n");
520 } else if(bus_width_shift == 0){
521 retval = ns->buffer[ns->read_offset];
523 } else if(bus_width_shift == 1){
524 retval = ns->buffer[ns->read_offset];
526 retval |= (((unsigned)ns->buffer[ns->read_offset]) << 8);
534 static struct nandsim_private *
535 nandsim_init_private(struct nand_store *store)
537 struct nandsim_private *ns;
538 unsigned char *buffer;
541 buff_size = (store->data_bytes_per_page + store->spare_bytes_per_page);
543 ns = malloc(sizeof(struct nandsim_private));
544 buffer = malloc(buff_size);
551 memset(ns, 0, sizeof(struct nandsim_private));
553 ns->buff_size = buff_size;
560 static void nandsim_set_ale(struct nand_chip * this, int ale)
562 struct nandsim_private *ns =
563 (struct nandsim_private *)this->private_data;
567 static void nandsim_set_cle(struct nand_chip * this, int cle)
569 struct nandsim_private *ns =
570 (struct nandsim_private *)this->private_data;
574 static unsigned nandsim_read_cycle(struct nand_chip * this)
577 struct nandsim_private *ns =
578 (struct nandsim_private *)this->private_data;
580 if (ns->cle || ns->ale){
581 debug(1, "Read cycle with CLE %s and ALE %s\n",
582 ns->cle ? "high" : "low",
583 ns->ale ? "high" : "low");
586 retval =nandsim_dl_read(ns, this->bus_width_shift);
588 debug(5, "Read cycle returning %02X\n",retval);
592 static void nandsim_write_cycle(struct nand_chip * this, unsigned b)
594 struct nandsim_private *ns =
595 (struct nandsim_private *)this->private_data;
598 if(ns->ale && ns->cle)
607 debug(5, "Write %02x to %s\n",
609 if (ns->cle && ns->ale)
610 debug(1, "Write cycle with both ALE and CLE high\n");
612 nandsim_cl_write(ns, b);
614 nandsim_al_write(ns, b);
616 nandsim_dl_write(ns, b, this->bus_width_shift);
619 static int nandsim_check_busy(struct nand_chip * this)
621 struct nandsim_private *ns =
622 (struct nandsim_private *)this->private_data;
625 if (ns->busy_count> 0){
627 debug(2, "Still busy\n");
630 debug(2, "Not busy\n");
635 static void nandsim_idle_fn(struct nand_chip *this)
637 struct nandsim_private *ns =
638 (struct nandsim_private *)this->private_data;
642 struct nand_chip *nandsim_init(struct nand_store *store, int bus_width_shift)
644 struct nand_chip *chip = NULL;
645 struct nandsim_private *ns = NULL;
647 chip = malloc(sizeof(struct nand_chip));
648 ns = nandsim_init_private(store);
651 memset(chip, 0, sizeof(struct nand_chip));;
653 chip->private_data = ns;
654 chip->set_ale = nandsim_set_ale;
655 chip->set_cle = nandsim_set_cle;
656 chip->read_cycle = nandsim_read_cycle;
657 chip->write_cycle = nandsim_write_cycle;
658 chip->check_busy = nandsim_check_busy;
659 chip->idle_fn = nandsim_idle_fn;
661 chip->bus_width_shift = bus_width_shift;
663 chip->blocks = ns->store->blocks;
664 chip->pages_per_block = ns->store->pages_per_block;
665 chip->data_bytes_per_page = ns->store->data_bytes_per_page;
666 chip->spare_bytes_per_page = ns->store->spare_bytes_per_page;
676 void nandsim_set_debug(int d)