1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
5 * Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> *
6 * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
8 * Partially based on drivers/mtd/nand_ids.c from Linux. *
9 ***************************************************************************/
18 #include <target/target.h>
21 extern struct nand_device *nand_devices;
23 COMMAND_HANDLER(handle_nand_list_command)
25 struct nand_device *p;
29 command_print(CMD, "no NAND flash devices configured");
33 for (p = nand_devices, i = 0; p; p = p->next, i++) {
35 command_print(CMD, "#%i: %s (%s) "
36 "pagesize: %i, buswidth: %i,\n\t"
37 "blocksize: %i, blocks: %i",
38 i, p->device->name, p->manufacturer->name,
39 p->page_size, p->bus_width,
40 p->erase_size, p->num_blocks);
42 command_print(CMD, "#%i: not probed", i);
48 COMMAND_HANDLER(handle_nand_info_command)
57 return ERROR_COMMAND_SYNTAX_ERROR;
63 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], i);
68 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first);
69 COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last);
73 struct nand_device *p;
74 int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
75 if (retval != ERROR_OK)
79 command_print(CMD, "#%s: not probed", CMD_ARGV[0]);
83 if (first >= p->num_blocks)
84 first = p->num_blocks - 1;
86 if (last >= p->num_blocks)
87 last = p->num_blocks - 1;
90 "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i",
93 p->manufacturer->name,
98 for (j = first; j <= last; j++) {
99 char *erase_state, *bad_state;
101 if (p->blocks[j].is_erased == 0)
102 erase_state = "not erased";
103 else if (p->blocks[j].is_erased == 1)
104 erase_state = "erased";
106 erase_state = "erase state unknown";
108 if (p->blocks[j].is_bad == 0)
110 else if (p->blocks[j].is_bad == 1)
111 bad_state = " (marked bad)";
113 bad_state = " (block condition unknown)";
116 "\t#%i: 0x%8.8" PRIx32 " (%" PRIu32 "kB) %s%s",
119 p->blocks[j].size / 1024,
127 COMMAND_HANDLER(handle_nand_probe_command)
130 return ERROR_COMMAND_SYNTAX_ERROR;
132 struct nand_device *p;
133 int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
134 if (retval != ERROR_OK)
137 retval = nand_probe(p);
138 if (retval == ERROR_OK) {
139 command_print(CMD, "NAND flash device '%s (%s)' found",
140 p->device->name, p->manufacturer->name);
146 COMMAND_HANDLER(handle_nand_erase_command)
148 if (CMD_ARGC != 1 && CMD_ARGC != 3)
149 return ERROR_COMMAND_SYNTAX_ERROR;
151 struct nand_device *p;
152 int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
153 if (retval != ERROR_OK)
156 unsigned long offset;
157 unsigned long length;
159 /* erase specified part of the chip; or else everything */
161 unsigned long size = p->erase_size * p->num_blocks;
163 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset);
164 if ((offset % p->erase_size) != 0 || offset >= size)
165 return ERROR_COMMAND_SYNTAX_ERROR;
167 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length);
168 if ((length == 0) || (length % p->erase_size) != 0
169 || (length + offset) > size)
170 return ERROR_COMMAND_SYNTAX_ERROR;
172 offset /= p->erase_size;
173 length /= p->erase_size;
176 length = p->num_blocks;
179 retval = nand_erase(p, offset, offset + length - 1);
180 if (retval == ERROR_OK) {
181 command_print(CMD, "erased blocks %lu to %lu "
182 "on NAND flash device #%s '%s'",
183 offset, offset + length - 1,
184 CMD_ARGV[0], p->device->name);
190 COMMAND_HANDLER(handle_nand_check_bad_blocks_command)
195 if ((CMD_ARGC < 1) || (CMD_ARGC > 3) || (CMD_ARGC == 2))
196 return ERROR_COMMAND_SYNTAX_ERROR;
198 struct nand_device *p;
199 int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
200 if (retval != ERROR_OK)
204 unsigned long offset;
205 unsigned long length;
207 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset);
208 if (offset % p->erase_size)
209 return ERROR_COMMAND_SYNTAX_ERROR;
210 offset /= p->erase_size;
212 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length);
213 if (length % p->erase_size)
214 return ERROR_COMMAND_SYNTAX_ERROR;
217 length /= p->erase_size;
220 last = offset + length;
223 retval = nand_build_bbt(p, first, last);
224 if (retval == ERROR_OK) {
225 command_print(CMD, "checked NAND flash device for bad blocks, "
226 "use \"nand info\" command to list blocks");
232 COMMAND_HANDLER(handle_nand_write_command)
234 struct nand_device *nand = NULL;
235 struct nand_fileio_state s;
236 int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,
237 &s, &nand, FILEIO_READ, false, true);
238 if (retval != ERROR_OK)
241 uint32_t total_bytes = s.size;
243 int bytes_read = nand_fileio_read(nand, &s);
244 if (bytes_read <= 0) {
245 command_print(CMD, "error while reading file");
246 nand_fileio_cleanup(&s);
249 s.size -= bytes_read;
251 retval = nand_write_page(nand, s.address / nand->page_size,
252 s.page, s.page_size, s.oob, s.oob_size);
253 if (retval != ERROR_OK) {
254 command_print(CMD, "failed writing file %s "
255 "to NAND flash %s at offset 0x%8.8" PRIx32,
256 CMD_ARGV[1], CMD_ARGV[0], s.address);
257 nand_fileio_cleanup(&s);
260 s.address += s.page_size;
263 if (nand_fileio_finish(&s) == ERROR_OK) {
264 command_print(CMD, "wrote file %s to NAND flash %s up to "
265 "offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
266 CMD_ARGV[1], CMD_ARGV[0], s.address, duration_elapsed(&s.bench),
267 duration_kbps(&s.bench, total_bytes));
272 COMMAND_HANDLER(handle_nand_verify_command)
274 struct nand_device *nand = NULL;
275 struct nand_fileio_state file;
276 int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,
277 &file, &nand, FILEIO_READ, false, true);
278 if (retval != ERROR_OK)
281 struct nand_fileio_state dev;
282 nand_fileio_init(&dev);
283 dev.address = file.address;
284 dev.size = file.size;
285 dev.oob_format = file.oob_format;
286 retval = nand_fileio_start(CMD, nand, NULL, FILEIO_NONE, &dev);
287 if (retval != ERROR_OK)
290 while (file.size > 0) {
291 retval = nand_read_page(nand, dev.address / dev.page_size,
292 dev.page, dev.page_size, dev.oob, dev.oob_size);
293 if (retval != ERROR_OK) {
294 command_print(CMD, "reading NAND flash page failed");
295 nand_fileio_cleanup(&dev);
296 nand_fileio_cleanup(&file);
300 int bytes_read = nand_fileio_read(nand, &file);
301 if (bytes_read <= 0) {
302 command_print(CMD, "error while reading file");
303 nand_fileio_cleanup(&dev);
304 nand_fileio_cleanup(&file);
308 if ((dev.page && memcmp(dev.page, file.page, dev.page_size)) ||
309 (dev.oob && memcmp(dev.oob, file.oob, dev.oob_size))) {
310 command_print(CMD, "NAND flash contents differ "
311 "at 0x%8.8" PRIx32, dev.address);
312 nand_fileio_cleanup(&dev);
313 nand_fileio_cleanup(&file);
317 file.size -= bytes_read;
318 dev.address += nand->page_size;
321 if (nand_fileio_finish(&file) == ERROR_OK) {
322 command_print(CMD, "verified file %s in NAND flash %s "
323 "up to offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
324 CMD_ARGV[1], CMD_ARGV[0], dev.address, duration_elapsed(&file.bench),
325 duration_kbps(&file.bench, dev.size));
328 return nand_fileio_cleanup(&dev);
331 COMMAND_HANDLER(handle_nand_dump_command)
334 struct nand_device *nand = NULL;
335 struct nand_fileio_state s;
336 int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,
337 &s, &nand, FILEIO_WRITE, true, false);
338 if (retval != ERROR_OK)
343 retval = nand_read_page(nand, s.address / nand->page_size,
344 s.page, s.page_size, s.oob, s.oob_size);
345 if (retval != ERROR_OK) {
346 command_print(CMD, "reading NAND flash page failed");
347 nand_fileio_cleanup(&s);
352 fileio_write(s.fileio, s.page_size, s.page, &size_written);
355 fileio_write(s.fileio, s.oob_size, s.oob, &size_written);
357 s.size -= nand->page_size;
358 s.address += nand->page_size;
361 retval = fileio_size(s.fileio, &filesize);
362 if (retval != ERROR_OK)
365 if (nand_fileio_finish(&s) == ERROR_OK) {
366 command_print(CMD, "dumped %zu bytes in %fs (%0.3f KiB/s)",
367 filesize, duration_elapsed(&s.bench),
368 duration_kbps(&s.bench, filesize));
373 COMMAND_HANDLER(handle_nand_raw_access_command)
375 if ((CMD_ARGC < 1) || (CMD_ARGC > 2))
376 return ERROR_COMMAND_SYNTAX_ERROR;
378 struct nand_device *p;
379 int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
380 if (retval != ERROR_OK)
384 command_print(CMD, "#%s: not probed", CMD_ARGV[0]);
389 COMMAND_PARSE_ENABLE(CMD_ARGV[1], p->use_raw);
391 const char *msg = p->use_raw ? "enabled" : "disabled";
392 command_print(CMD, "raw access is %s", msg);
397 static const struct command_registration nand_exec_command_handlers[] = {
400 .handler = handle_nand_list_command,
401 .mode = COMMAND_EXEC,
402 .help = "list configured NAND flash devices",
407 .handler = handle_nand_info_command,
408 .mode = COMMAND_EXEC,
409 .usage = "[banknum | first_bank_num last_bank_num]",
410 .help = "print info about one or more NAND flash devices",
414 .handler = handle_nand_probe_command,
415 .mode = COMMAND_EXEC,
417 .help = "identify NAND flash device",
420 .name = "check_bad_blocks",
421 .handler = handle_nand_check_bad_blocks_command,
422 .mode = COMMAND_EXEC,
423 .usage = "bank_id [offset length]",
424 .help = "check all or part of NAND flash device for bad blocks",
428 .handler = handle_nand_erase_command,
429 .mode = COMMAND_EXEC,
430 .usage = "bank_id [offset length]",
431 .help = "erase all or subset of blocks on NAND flash device",
435 .handler = handle_nand_dump_command,
436 .mode = COMMAND_EXEC,
437 .usage = "bank_id filename offset length "
438 "['oob_raw'|'oob_only']",
439 .help = "dump from NAND flash device",
443 .handler = handle_nand_verify_command,
444 .mode = COMMAND_EXEC,
445 .usage = "bank_id filename offset "
446 "['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']",
447 .help = "verify NAND flash device",
451 .handler = handle_nand_write_command,
452 .mode = COMMAND_EXEC,
453 .usage = "bank_id filename offset "
454 "['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']",
455 .help = "write to NAND flash device",
458 .name = "raw_access",
459 .handler = handle_nand_raw_access_command,
460 .mode = COMMAND_EXEC,
461 .usage = "bank_id ['enable'|'disable']",
462 .help = "raw access to NAND flash device",
464 COMMAND_REGISTRATION_DONE
467 static int nand_init(struct command_context *cmd_ctx)
472 return register_commands(cmd_ctx, "nand", nand_exec_command_handlers);
475 COMMAND_HANDLER(handle_nand_init_command)
478 return ERROR_COMMAND_SYNTAX_ERROR;
480 static bool nand_initialized;
481 if (nand_initialized) {
482 LOG_INFO("'nand init' has already been called");
485 nand_initialized = true;
487 LOG_DEBUG("Initializing NAND devices...");
488 return nand_init(CMD_CTX);
491 static int nand_list_walker(struct nand_flash_controller *c, void *x)
493 struct command_invocation *cmd = x;
494 command_print(cmd, " %s", c->name);
498 COMMAND_HANDLER(handle_nand_list_drivers)
500 command_print(CMD, "Available NAND flash controller drivers:");
501 return nand_driver_walk(&nand_list_walker, CMD);
504 static COMMAND_HELPER(create_nand_device, const char *bank_name,
505 struct nand_flash_controller *controller)
507 struct nand_device *c;
508 struct target *target;
512 return ERROR_COMMAND_SYNTAX_ERROR;
513 target = get_target(CMD_ARGV[1]);
515 LOG_ERROR("invalid target %s", CMD_ARGV[1]);
516 return ERROR_COMMAND_ARGUMENT_INVALID;
519 if (controller->commands) {
520 retval = register_commands(CMD_CTX, NULL, controller->commands);
521 if (retval != ERROR_OK)
524 c = malloc(sizeof(struct nand_device));
526 LOG_ERROR("End of memory");
530 c->name = strdup(bank_name);
532 c->controller = controller;
533 c->controller_priv = NULL;
534 c->manufacturer = NULL;
537 c->address_cycles = 0;
542 retval = CALL_COMMAND_HANDLER(controller->nand_device_command, c);
543 if (retval != ERROR_OK) {
544 LOG_ERROR("'%s' driver rejected nand flash. Usage: %s",
551 if (!controller->usage)
552 LOG_DEBUG("'%s' driver usage field missing", controller->name);
559 COMMAND_HANDLER(handle_nand_device_command)
562 return ERROR_COMMAND_SYNTAX_ERROR;
564 /* save name and increment (for compatibility) with drivers */
565 const char *bank_name = *CMD_ARGV++;
568 const char *driver_name = CMD_ARGV[0];
569 struct nand_flash_controller *controller;
570 controller = nand_driver_find_by_name(CMD_ARGV[0]);
572 LOG_ERROR("No valid NAND flash driver found (%s)", driver_name);
573 return CALL_COMMAND_HANDLER(handle_nand_list_drivers);
575 return CALL_COMMAND_HANDLER(create_nand_device, bank_name, controller);
578 static const struct command_registration nand_config_command_handlers[] = {
581 .handler = &handle_nand_device_command,
582 .mode = COMMAND_CONFIG,
583 .help = "defines a new NAND bank",
584 .usage = "bank_id driver target [driver_options ...]",
588 .handler = &handle_nand_list_drivers,
590 .help = "lists available NAND drivers",
595 .mode = COMMAND_CONFIG,
596 .handler = &handle_nand_init_command,
597 .help = "initialize NAND devices",
600 COMMAND_REGISTRATION_DONE
603 static const struct command_registration nand_command_handlers[] = {
607 .help = "NAND flash command group",
609 .chain = nand_config_command_handlers,
611 COMMAND_REGISTRATION_DONE
614 int nand_register_commands(struct command_context *cmd_ctx)
616 return register_commands(cmd_ctx, NULL, nand_command_handlers);