- "flash write_binary" is now "flash write_bank" to clarify the focus of the
[fw/openocd] / src / flash / nand.c
1 /***************************************************************************\r
2  *   Copyright (C) 2007 by Dominic Rath                                    *\r
3  *   Dominic.Rath@gmx.de                                                   *\r
4  *                                                                         *\r
5  *   partially based on                                                    *\r
6  *       drivers/mtd/nand_ids.c                                            *\r
7  *                                                                         *\r
8  *   Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)               *\r
9  *                                                                         *\r
10  *   This program is free software; you can redistribute it and/or modify  *\r
11  *   it under the terms of the GNU General Public License as published by  *\r
12  *   the Free Software Foundation; either version 2 of the License, or     *\r
13  *   (at your option) any later version.                                   *\r
14  *                                                                         *\r
15  *   This program is distributed in the hope that it will be useful,       *\r
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
18  *   GNU General Public License for more details.                          *\r
19  *                                                                         *\r
20  *   You should have received a copy of the GNU General Public License     *\r
21  *   along with this program; if not, write to the                         *\r
22  *   Free Software Foundation, Inc.,                                       *\r
23  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
24  ***************************************************************************/\r
25 #ifdef HAVE_CONFIG_H\r
26 #include "config.h"\r
27 #endif\r
28 \r
29 #include "replacements.h"\r
30 #include "log.h"\r
31 \r
32 #include <stdlib.h>\r
33 #include <string.h>\r
34 #include <inttypes.h>\r
35 \r
36 #include <errno.h>\r
37 \r
38 #include "nand.h"\r
39 #include "flash.h"\r
40 #include "time_support.h"\r
41 #include "fileio.h"\r
42 #include "image.h"\r
43 \r
44 int nand_register_commands(struct command_context_s *cmd_ctx);\r
45 int handle_nand_list_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
46 int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
47 int handle_nand_check_bad_blocks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
48 int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
49 int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
50 int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
51 int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
52 int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
53 \r
54 int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
55 \r
56 int nand_read_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);\r
57 int nand_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);\r
58 int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size);\r
59 \r
60 int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);\r
61 int nand_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);\r
62 \r
63 /* NAND flash controller\r
64  */\r
65 extern nand_flash_controller_t lpc3180_nand_controller;\r
66 extern nand_flash_controller_t s3c2410_nand_controller;\r
67 extern nand_flash_controller_t s3c2412_nand_controller;\r
68 extern nand_flash_controller_t s3c2440_nand_controller;\r
69 extern nand_flash_controller_t s3c2443_nand_controller;\r
70 \r
71 /* extern nand_flash_controller_t boundary_scan_nand_controller; */\r
72 \r
73 nand_flash_controller_t *nand_flash_controllers[] =\r
74 {\r
75         &lpc3180_nand_controller,\r
76         &s3c2410_nand_controller,\r
77         &s3c2412_nand_controller,\r
78         &s3c2440_nand_controller,\r
79         &s3c2443_nand_controller,\r
80 /*      &boundary_scan_nand_controller, */\r
81         NULL\r
82 };\r
83 \r
84 /* configured NAND devices and NAND Flash command handler */\r
85 nand_device_t *nand_devices = NULL;\r
86 static command_t *nand_cmd;\r
87 \r
88 /*      Chip ID list\r
89  *\r
90  *      Name, ID code, pagesize, chipsize in MegaByte, eraseblock size,\r
91  *      options\r
92  *\r
93  *      Pagesize; 0, 256, 512\r
94  *      0       get this information from the extended chip ID\r
95  *      256     256 Byte page size\r
96  *      512     512 Byte page size\r
97  */\r
98 nand_info_t nand_flash_ids[] =\r
99 {\r
100         {"NAND 1MiB 5V 8-bit",          0x6e, 256, 1, 0x1000, 0},\r
101         {"NAND 2MiB 5V 8-bit",          0x64, 256, 2, 0x1000, 0},\r
102         {"NAND 4MiB 5V 8-bit",          0x6b, 512, 4, 0x2000, 0},\r
103         {"NAND 1MiB 3,3V 8-bit",        0xe8, 256, 1, 0x1000, 0},\r
104         {"NAND 1MiB 3,3V 8-bit",        0xec, 256, 1, 0x1000, 0},\r
105         {"NAND 2MiB 3,3V 8-bit",        0xea, 256, 2, 0x1000, 0},\r
106         {"NAND 4MiB 3,3V 8-bit",        0xd5, 512, 4, 0x2000, 0},\r
107         {"NAND 4MiB 3,3V 8-bit",        0xe3, 512, 4, 0x2000, 0},\r
108         {"NAND 4MiB 3,3V 8-bit",        0xe5, 512, 4, 0x2000, 0},\r
109         {"NAND 8MiB 3,3V 8-bit",        0xd6, 512, 8, 0x2000, 0},\r
110 \r
111         {"NAND 8MiB 1,8V 8-bit",        0x39, 512, 8, 0x2000, 0},\r
112         {"NAND 8MiB 3,3V 8-bit",        0xe6, 512, 8, 0x2000, 0},\r
113         {"NAND 8MiB 1,8V 16-bit",       0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},\r
114         {"NAND 8MiB 3,3V 16-bit",       0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},\r
115 \r
116         {"NAND 16MiB 1,8V 8-bit",       0x33, 512, 16, 0x4000, 0},\r
117         {"NAND 16MiB 3,3V 8-bit",       0x73, 512, 16, 0x4000, 0},\r
118         {"NAND 16MiB 1,8V 16-bit",      0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},\r
119         {"NAND 16MiB 3,3V 16-bit",      0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},\r
120 \r
121         {"NAND 32MiB 1,8V 8-bit",       0x35, 512, 32, 0x4000, 0},\r
122         {"NAND 32MiB 3,3V 8-bit",       0x75, 512, 32, 0x4000, 0},\r
123         {"NAND 32MiB 1,8V 16-bit",      0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},\r
124         {"NAND 32MiB 3,3V 16-bit",      0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},\r
125 \r
126         {"NAND 64MiB 1,8V 8-bit",       0x36, 512, 64, 0x4000, 0},\r
127         {"NAND 64MiB 3,3V 8-bit",       0x76, 512, 64, 0x4000, 0},\r
128         {"NAND 64MiB 1,8V 16-bit",      0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},\r
129         {"NAND 64MiB 3,3V 16-bit",      0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},\r
130 \r
131         {"NAND 128MiB 1,8V 8-bit",      0x78, 512, 128, 0x4000, 0},\r
132         {"NAND 128MiB 1,8V 8-bit",      0x39, 512, 128, 0x4000, 0},\r
133         {"NAND 128MiB 3,3V 8-bit",      0x79, 512, 128, 0x4000, 0},\r
134         {"NAND 128MiB 1,8V 16-bit",     0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},\r
135         {"NAND 128MiB 1,8V 16-bit",     0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},\r
136         {"NAND 128MiB 3,3V 16-bit",     0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},\r
137         {"NAND 128MiB 3,3V 16-bit",     0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},\r
138 \r
139         {"NAND 256MiB 3,3V 8-bit",      0x71, 512, 256, 0x4000, 0},\r
140 \r
141         {"NAND 64MiB 1,8V 8-bit",       0xA2, 0,  64, 0, LP_OPTIONS},\r
142         {"NAND 64MiB 3,3V 8-bit",       0xF2, 0,  64, 0, LP_OPTIONS},\r
143         {"NAND 64MiB 1,8V 16-bit",      0xB2, 0,  64, 0, LP_OPTIONS16},\r
144         {"NAND 64MiB 3,3V 16-bit",      0xC2, 0,  64, 0, LP_OPTIONS16},\r
145 \r
146         {"NAND 128MiB 1,8V 8-bit",      0xA1, 0, 128, 0, LP_OPTIONS},\r
147         {"NAND 128MiB 3,3V 8-bit",      0xF1, 0, 128, 0, LP_OPTIONS},\r
148         {"NAND 128MiB 1,8V 16-bit",     0xB1, 0, 128, 0, LP_OPTIONS16},\r
149         {"NAND 128MiB 3,3V 16-bit",     0xC1, 0, 128, 0, LP_OPTIONS16},\r
150 \r
151         {"NAND 256MiB 1,8V 8-bit",      0xAA, 0, 256, 0, LP_OPTIONS},\r
152         {"NAND 256MiB 3,3V 8-bit",      0xDA, 0, 256, 0, LP_OPTIONS},\r
153         {"NAND 256MiB 1,8V 16-bit",     0xBA, 0, 256, 0, LP_OPTIONS16},\r
154         {"NAND 256MiB 3,3V 16-bit",     0xCA, 0, 256, 0, LP_OPTIONS16},\r
155 \r
156         {"NAND 512MiB 1,8V 8-bit",      0xAC, 0, 512, 0, LP_OPTIONS},\r
157         {"NAND 512MiB 3,3V 8-bit",      0xDC, 0, 512, 0, LP_OPTIONS},\r
158         {"NAND 512MiB 1,8V 16-bit",     0xBC, 0, 512, 0, LP_OPTIONS16},\r
159         {"NAND 512MiB 3,3V 16-bit",     0xCC, 0, 512, 0, LP_OPTIONS16},\r
160 \r
161         {"NAND 1GiB 1,8V 8-bit",        0xA3, 0, 1024, 0, LP_OPTIONS},\r
162         {"NAND 1GiB 3,3V 8-bit",        0xD3, 0, 1024, 0, LP_OPTIONS},\r
163         {"NAND 1GiB 1,8V 16-bit",       0xB3, 0, 1024, 0, LP_OPTIONS16},\r
164         {"NAND 1GiB 3,3V 16-bit",       0xC3, 0, 1024, 0, LP_OPTIONS16},\r
165 \r
166         {"NAND 2GiB 1,8V 8-bit",        0xA5, 0, 2048, 0, LP_OPTIONS},\r
167         {"NAND 2GiB 3,3V 8-bit",        0xD5, 0, 2048, 0, LP_OPTIONS},\r
168         {"NAND 2GiB 1,8V 16-bit",       0xB5, 0, 2048, 0, LP_OPTIONS16},\r
169         {"NAND 2GiB 3,3V 16-bit",       0xC5, 0, 2048, 0, LP_OPTIONS16},\r
170 \r
171         {NULL, 0,}\r
172 };\r
173 \r
174 /* Manufacturer ID list\r
175  */\r
176 nand_manufacturer_t nand_manuf_ids[] =\r
177 {\r
178         {0x0, "unknown"},\r
179         {NAND_MFR_TOSHIBA, "Toshiba"},\r
180         {NAND_MFR_SAMSUNG, "Samsung"},\r
181         {NAND_MFR_FUJITSU, "Fujitsu"},\r
182         {NAND_MFR_NATIONAL, "National"},\r
183         {NAND_MFR_RENESAS, "Renesas"},\r
184         {NAND_MFR_STMICRO, "ST Micro"},\r
185         {NAND_MFR_HYNIX, "Hynix"},\r
186         {0x0, NULL},\r
187 };\r
188 \r
189 /* nand device <nand_controller> [controller options]\r
190  */\r
191 int handle_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
192 {\r
193         int i;\r
194         int retval;\r
195                 \r
196         if (argc < 1)\r
197         {\r
198                 WARNING("incomplete flash device nand configuration");\r
199                 return ERROR_FLASH_BANK_INVALID;\r
200         }\r
201         \r
202         for (i = 0; nand_flash_controllers[i]; i++)\r
203         {\r
204                 nand_device_t *p, *c;\r
205                 \r
206                 if (strcmp(args[0], nand_flash_controllers[i]->name) == 0)\r
207                 {\r
208                         /* register flash specific commands */\r
209                         if (nand_flash_controllers[i]->register_commands(cmd_ctx) != ERROR_OK)\r
210                         {\r
211                                 ERROR("couldn't register '%s' commands", args[0]);\r
212                                 exit(-1);\r
213                         }\r
214         \r
215                         c = malloc(sizeof(nand_device_t));\r
216 \r
217                         c->controller = nand_flash_controllers[i];\r
218                         c->controller_priv = NULL;\r
219                         c->manufacturer = NULL;\r
220                         c->device = NULL;\r
221                         c->bus_width = 0;\r
222                         c->address_cycles = 0;\r
223                         c->page_size = 0;\r
224                         c->use_raw = 0;\r
225                         c->next = NULL;\r
226 \r
227                         if ((retval = nand_flash_controllers[i]->nand_device_command(cmd_ctx, cmd, args, argc, c)) != ERROR_OK)\r
228                         {\r
229                                 ERROR("'%s' driver rejected nand flash", c->controller->name);\r
230                                 free(c);\r
231                                 return ERROR_OK;\r
232                         }\r
233                         \r
234                         /* put NAND device in linked list */\r
235                         if (nand_devices)\r
236                         {\r
237                                 /* find last flash device */\r
238                                 for (p = nand_devices; p && p->next; p = p->next);\r
239                                 if (p)\r
240                                         p->next = c;\r
241                         }\r
242                         else\r
243                         {\r
244                                 nand_devices = c;\r
245                         }\r
246                         \r
247                         return ERROR_OK;\r
248                 }\r
249         }\r
250 \r
251         /* no valid NAND controller was found (i.e. the configuration option,\r
252          * didn't match one of the compiled-in controllers)\r
253          */\r
254         ERROR("No valid NAND flash controller found (%s)", args[0]);\r
255         ERROR("compiled-in NAND flash controllers:");\r
256         for (i = 0; nand_flash_controllers[i]; i++)\r
257         {\r
258                 ERROR("%i: %s", i, nand_flash_controllers[i]->name);\r
259         }\r
260         \r
261         return ERROR_OK;\r
262 }\r
263 \r
264 int nand_register_commands(struct command_context_s *cmd_ctx)\r
265 {\r
266         nand_cmd = register_command(cmd_ctx, NULL, "nand", NULL, COMMAND_ANY, "NAND specific commands");\r
267         \r
268         register_command(cmd_ctx, nand_cmd, "device", handle_nand_device_command, COMMAND_CONFIG, NULL);\r
269         \r
270         return ERROR_OK;\r
271 }\r
272 \r
273 int nand_init(struct command_context_s *cmd_ctx)\r
274 {\r
275         if (nand_devices)\r
276         {\r
277                 register_command(cmd_ctx, nand_cmd, "list", handle_nand_list_command, COMMAND_EXEC,\r
278                                                  "list configured NAND flash devices");\r
279                 register_command(cmd_ctx, nand_cmd, "info", handle_nand_info_command, COMMAND_EXEC,\r
280                                                  "print info about NAND flash device <num>");\r
281                 register_command(cmd_ctx, nand_cmd, "probe", handle_nand_probe_command, COMMAND_EXEC,\r
282                                                  "identify NAND flash device <num>");\r
283                 register_command(cmd_ctx, nand_cmd, "check_bad_blocks", handle_nand_check_bad_blocks_command, COMMAND_EXEC,\r
284                                                  "check NAND flash device <num> for bad blocks [<first> <last>]");\r
285                 register_command(cmd_ctx, nand_cmd, "erase", handle_nand_erase_command, COMMAND_EXEC,\r
286                                                  "erase blocks on NAND flash device <num> <first> <last>");\r
287                 register_command(cmd_ctx, nand_cmd, "copy", handle_nand_copy_command, COMMAND_EXEC,\r
288                                                  "copy from NAND flash device <num> <offset> <length> <ram-address>");\r
289                 register_command(cmd_ctx, nand_cmd, "dump", handle_nand_dump_command, COMMAND_EXEC,\r
290                                                  "dump from NAND flash device <num> <filename> <offset> <size> [options]");\r
291                 register_command(cmd_ctx, nand_cmd, "write", handle_nand_write_command, COMMAND_EXEC,\r
292                                                  "write to NAND flash device <num> <filename> <offset> [options]");\r
293                 register_command(cmd_ctx, nand_cmd, "raw_access", handle_nand_raw_access_command, COMMAND_EXEC,\r
294                                                  "raw access to NAND flash device <num> ['enable'|'disable']");\r
295         }\r
296         \r
297         return ERROR_OK;\r
298 }\r
299 \r
300 nand_device_t *get_nand_device_by_num(int num)\r
301 {\r
302         nand_device_t *p;\r
303         int i = 0;\r
304 \r
305         for (p = nand_devices; p; p = p->next)\r
306         {\r
307                 if (i++ == num)\r
308                 {\r
309                         return p;\r
310                 }\r
311         }\r
312         \r
313         return NULL;\r
314 }\r
315 \r
316 int nand_build_bbt(struct nand_device_s *device, int first, int last)\r
317 {\r
318         u32 page = 0x0;\r
319         int i;\r
320         u8 *oob;\r
321         \r
322         oob = malloc(6);\r
323         \r
324         if ((first < 0) || (first >= device->num_blocks))\r
325                 first = 0;\r
326         \r
327         if ((last >= device->num_blocks) || (last == -1))\r
328                 last = device->num_blocks - 1;\r
329         \r
330         for (i = first; i < last; i++)\r
331         {\r
332                 nand_read_page(device, page, NULL, 0, oob, 6);\r
333                 \r
334                 if (((device->device->options & NAND_BUSWIDTH_16) && ((oob[0] & oob[1]) != 0xff))\r
335                         || (((device->page_size == 512) && (oob[5] != 0xff)) ||\r
336                                 ((device->page_size == 2048) && (oob[0] != 0xff))))\r
337                 {\r
338                         WARNING("invalid block: %i", i);\r
339                         device->blocks[i].is_bad = 1;\r
340                 }\r
341                 else\r
342                 {\r
343                         device->blocks[i].is_bad = 0;\r
344                 }\r
345                 \r
346                 page += (device->erase_size / device->page_size);\r
347         }\r
348         \r
349         return ERROR_OK;\r
350 }\r
351 \r
352 int nand_read_status(struct nand_device_s *device, u8 *status)\r
353 {\r
354         if (!device->device)\r
355                 return ERROR_NAND_DEVICE_NOT_PROBED;\r
356                 \r
357         /* Send read status command */\r
358         device->controller->command(device, NAND_CMD_STATUS);\r
359         \r
360         usleep(1000);\r
361         \r
362         /* read status */\r
363         if (device->device->options & NAND_BUSWIDTH_16)\r
364         {\r
365                 u16 data;\r
366                 device->controller->read_data(device, &data);\r
367                 *status = data & 0xff;\r
368         }\r
369         else\r
370         {\r
371                 device->controller->read_data(device, status);\r
372         }\r
373                         \r
374         return ERROR_OK;\r
375 }\r
376 \r
377 int nand_probe(struct nand_device_s *device)\r
378 {\r
379         u8 manufacturer_id, device_id;\r
380         u8 id_buff[5];\r
381         int retval;\r
382         int i;\r
383 \r
384         /* clear device data */\r
385         device->device = NULL;\r
386         device->manufacturer = NULL;\r
387         \r
388         /* clear device parameters */\r
389         device->bus_width = 0;\r
390         device->address_cycles = 0;\r
391         device->page_size = 0;\r
392         device->erase_size = 0;\r
393         \r
394         /* initialize controller (device parameters are zero, use controller default) */\r
395         if ((retval = device->controller->init(device) != ERROR_OK))\r
396         {\r
397                 switch (retval)\r
398                 {\r
399                         case ERROR_NAND_OPERATION_FAILED:\r
400                                 DEBUG("controller initialization failed");\r
401                                 return ERROR_NAND_OPERATION_FAILED;\r
402                         case ERROR_NAND_OPERATION_NOT_SUPPORTED:\r
403                                 ERROR("BUG: controller reported that it doesn't support default parameters");\r
404                                 return ERROR_NAND_OPERATION_FAILED;\r
405                         default:\r
406                                 ERROR("BUG: unknown controller initialization failure");\r
407                                 return ERROR_NAND_OPERATION_FAILED;\r
408                 }\r
409         }\r
410         \r
411         device->controller->command(device, NAND_CMD_RESET);\r
412         device->controller->reset(device);\r
413 \r
414         device->controller->command(device, NAND_CMD_READID);\r
415         device->controller->address(device, 0x0);\r
416         \r
417         if (device->bus_width == 8)\r
418         {\r
419                 device->controller->read_data(device, &manufacturer_id);\r
420                 device->controller->read_data(device, &device_id);\r
421         }\r
422         else\r
423         {\r
424                 u16 data_buf;\r
425                 device->controller->read_data(device, &data_buf);\r
426                 manufacturer_id = data_buf & 0xff;\r
427                 device->controller->read_data(device, &data_buf);\r
428                 device_id = data_buf & 0xff;\r
429         }\r
430                 \r
431         for (i = 0; nand_flash_ids[i].name; i++)\r
432         {\r
433                 if (nand_flash_ids[i].id == device_id)\r
434                 {\r
435                         device->device = &nand_flash_ids[i];\r
436                         break;\r
437                 }\r
438         }\r
439         \r
440         for (i = 0; nand_manuf_ids[i].name; i++)\r
441         {\r
442                 if (nand_manuf_ids[i].id == manufacturer_id)\r
443                 {\r
444                         device->manufacturer = &nand_manuf_ids[i];\r
445                         break;\r
446                 }\r
447         }\r
448         \r
449         if (!device->manufacturer)\r
450         {\r
451                 device->manufacturer = &nand_manuf_ids[0];\r
452                 device->manufacturer->id = manufacturer_id;\r
453         }\r
454         \r
455         if (!device->device)\r
456         {\r
457                 ERROR("unknown NAND flash device found, manufacturer id: 0x%2.2x device id: 0x%2.2x",\r
458                         manufacturer_id, device_id);\r
459                 return ERROR_NAND_OPERATION_FAILED;\r
460         }\r
461         \r
462         DEBUG("found %s (%s)", device->device->name, device->manufacturer->name);\r
463         \r
464         /* initialize device parameters */\r
465         \r
466         /* bus width */ \r
467         if (device->device->options & NAND_BUSWIDTH_16)\r
468                 device->bus_width = 16;\r
469         else\r
470                 device->bus_width = 8;\r
471 \r
472         /* Do we need extended device probe information? */\r
473         if (device->device->page_size == 0 ||\r
474             device->device->erase_size == 0)\r
475         {\r
476                 if (device->bus_width == 8)\r
477                 {\r
478                         device->controller->read_data(device, id_buff+3);\r
479                         device->controller->read_data(device, id_buff+4);\r
480                         device->controller->read_data(device, id_buff+5);\r
481                 }\r
482                 else\r
483                 {\r
484                         u16 data_buf;\r
485 \r
486                         device->controller->read_data(device, &data_buf);\r
487                         id_buff[3] = data_buf;\r
488 \r
489                         device->controller->read_data(device, &data_buf);\r
490                         id_buff[4] = data_buf;\r
491 \r
492                         device->controller->read_data(device, &data_buf);\r
493                         id_buff[5] = data_buf >> 8;\r
494                 }\r
495         }\r
496                 \r
497         /* page size */\r
498         if (device->device->page_size == 0)\r
499         {\r
500                 device->page_size = 1 << (10 + (id_buff[4] & 3));\r
501         }\r
502         else if (device->device->page_size == 256)\r
503         {\r
504                 ERROR("NAND flashes with 256 byte pagesize are not supported");\r
505                 return ERROR_NAND_OPERATION_FAILED;\r
506         }\r
507         else\r
508         {\r
509                 device->page_size = device->device->page_size;\r
510         }\r
511         \r
512         /* number of address cycles */\r
513         if (device->page_size <= 512)\r
514         {\r
515                 /* small page devices */\r
516                 if (device->device->chip_size <= 32)\r
517                         device->address_cycles = 3;\r
518                 else if (device->device->chip_size <= 8*1024)\r
519                         device->address_cycles = 4;\r
520                 else\r
521                 {\r
522                         ERROR("BUG: small page NAND device with more than 8 GiB encountered");\r
523                         device->address_cycles = 5;\r
524                 }\r
525         }\r
526         else\r
527         {\r
528                 /* large page devices */\r
529                 if (device->device->chip_size <= 128)\r
530                         device->address_cycles = 4;\r
531                 else if (device->device->chip_size <= 32*1024)\r
532                         device->address_cycles = 5;\r
533                 else\r
534                 {\r
535                         ERROR("BUG: small page NAND device with more than 32 GiB encountered");\r
536                         device->address_cycles = 6;\r
537                 }\r
538         }\r
539         \r
540         /* erase size */\r
541         if (device->device->erase_size == 0)\r
542         {\r
543                 switch ((id_buff[4] >> 4) & 3) {\r
544                 case 0:\r
545                         device->erase_size = 64 << 10;\r
546                         break;\r
547                 case 1:\r
548                         device->erase_size = 128 << 10;\r
549                         break;\r
550                 case 2:\r
551                         device->erase_size = 256 << 10;\r
552                         break;\r
553                 case 3:\r
554                         device->erase_size =512 << 10;\r
555                         break;\r
556                 }\r
557         }\r
558         else\r
559         {\r
560                 device->erase_size = device->device->erase_size;\r
561         }\r
562         \r
563         /* initialize controller, but leave parameters at the controllers default */\r
564         if ((retval = device->controller->init(device) != ERROR_OK))\r
565         {\r
566                 switch (retval)\r
567                 {\r
568                         case ERROR_NAND_OPERATION_FAILED:\r
569                                 DEBUG("controller initialization failed");\r
570                                 return ERROR_NAND_OPERATION_FAILED;\r
571                         case ERROR_NAND_OPERATION_NOT_SUPPORTED:\r
572                                 ERROR("controller doesn't support requested parameters (buswidth: %i, address cycles: %i, page size: %i)",\r
573                                         device->bus_width, device->address_cycles, device->page_size);\r
574                                 return ERROR_NAND_OPERATION_FAILED;\r
575                         default:\r
576                                 ERROR("BUG: unknown controller initialization failure");\r
577                                 return ERROR_NAND_OPERATION_FAILED;\r
578                 }\r
579         }\r
580         \r
581         device->num_blocks = (device->device->chip_size * 1024) / (device->erase_size / 1024);\r
582         device->blocks = malloc(sizeof(nand_block_t) * device->num_blocks);\r
583         \r
584         for (i = 0; i < device->num_blocks; i++)\r
585         {\r
586                 device->blocks[i].size = device->erase_size;\r
587                 device->blocks[i].offset = i * device->erase_size;\r
588                 device->blocks[i].is_erased = -1;\r
589                 device->blocks[i].is_bad = -1;\r
590         }\r
591         \r
592         return ERROR_OK;\r
593 }\r
594 \r
595 int nand_erase(struct nand_device_s *device, int first_block, int last_block)\r
596 {\r
597         int i;\r
598         u32 page;\r
599         u8 status;\r
600         int retval;\r
601         \r
602         if (!device->device)\r
603                 return ERROR_NAND_DEVICE_NOT_PROBED;\r
604         \r
605         if ((first_block < 0) || (last_block > device->num_blocks))\r
606                 return ERROR_INVALID_ARGUMENTS;\r
607         \r
608         /* make sure we know if a block is bad before erasing it */\r
609         for (i = first_block; i <= last_block; i++)\r
610         {\r
611                 if (device->blocks[i].is_bad == -1)\r
612                 {\r
613                         nand_build_bbt(device, i, last_block);\r
614                         break;\r
615                 }\r
616         }\r
617         \r
618         for (i = first_block; i <= last_block; i++)\r
619         {\r
620                 /* Send erase setup command */\r
621                 device->controller->command(device, NAND_CMD_ERASE1);\r
622                 \r
623                 page = i * (device->erase_size / device->page_size);\r
624                 \r
625                 /* Send page address */\r
626                 if (device->page_size <= 512)\r
627                 {\r
628                         /* row */\r
629                         device->controller->address(device, page & 0xff);\r
630                         device->controller->address(device, (page >> 8) & 0xff);\r
631                         \r
632                         /* 3rd cycle only on devices with more than 32 MiB */\r
633                         if (device->address_cycles >= 4)\r
634                                 device->controller->address(device, (page >> 16) & 0xff);\r
635         \r
636                         /* 4th cycle only on devices with more than 8 GiB */\r
637                         if (device->address_cycles >= 5)\r
638                                 device->controller->address(device, (page >> 24) & 0xff);\r
639                 }\r
640                 else\r
641                 {\r
642                         /* row */\r
643                         device->controller->address(device, page & 0xff);\r
644                         device->controller->address(device, (page >> 8) & 0xff);\r
645         \r
646                         /* 3rd cycle only on devices with more than 128 MiB */\r
647                         if (device->address_cycles >= 5)\r
648                                 device->controller->address(device, (page >> 16) & 0xff);\r
649                 }\r
650                 \r
651                 /* Send erase confirm command */\r
652                 device->controller->command(device, NAND_CMD_ERASE2);\r
653                 \r
654                 if (!device->controller->nand_ready(device, 1000))\r
655                 {\r
656                         ERROR("timeout waiting for NAND flash block erase to complete");\r
657                         return ERROR_NAND_OPERATION_TIMEOUT;\r
658                 }\r
659                 \r
660                 if ((retval = nand_read_status(device, &status)) != ERROR_OK)\r
661                 {\r
662                         ERROR("couldn't read status");\r
663                         return ERROR_NAND_OPERATION_FAILED;\r
664                 }\r
665                 \r
666                 if (status & 0x1)\r
667                 {\r
668                         ERROR("erase operation didn't pass, status: 0x%2.2x", status);\r
669                         return ERROR_NAND_OPERATION_FAILED;\r
670                 }\r
671         }\r
672         \r
673         return ERROR_OK;\r
674 }\r
675 \r
676 int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size)\r
677 {\r
678         u8 *page;\r
679         \r
680         if (!device->device)\r
681                 return ERROR_NAND_DEVICE_NOT_PROBED;\r
682                 \r
683         if (address % device->page_size)\r
684         {\r
685                 ERROR("reads need to be page aligned");\r
686                 return ERROR_NAND_OPERATION_FAILED;\r
687         }\r
688         \r
689         page = malloc(device->page_size);\r
690         \r
691         while (data_size > 0 )\r
692         {\r
693                 u32 thisrun_size = (data_size > device->page_size) ? device->page_size : data_size;\r
694                 u32 page_address;\r
695                 \r
696                 \r
697                 page_address = address / device->page_size;\r
698                 \r
699                 nand_read_page(device, page_address, page, device->page_size, NULL, 0);\r
700 \r
701                 memcpy(data, page, thisrun_size);\r
702                 \r
703                 address += thisrun_size;\r
704                 data += thisrun_size;\r
705                 data_size -= thisrun_size;\r
706         }\r
707         \r
708         free(page);\r
709         \r
710         return ERROR_OK;\r
711 }\r
712 \r
713 int nand_write_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size)\r
714 {\r
715         u8 *page;\r
716         \r
717         if (!device->device)\r
718                 return ERROR_NAND_DEVICE_NOT_PROBED;\r
719                 \r
720         if (address % device->page_size)\r
721         {\r
722                 ERROR("writes need to be page aligned");\r
723                 return ERROR_NAND_OPERATION_FAILED;\r
724         }\r
725         \r
726         page = malloc(device->page_size);\r
727         \r
728         while (data_size > 0 )\r
729         {\r
730                 u32 thisrun_size = (data_size > device->page_size) ? device->page_size : data_size;\r
731                 u32 page_address;\r
732                 \r
733                 memset(page, 0xff, device->page_size);\r
734                 memcpy(page, data, thisrun_size);\r
735                 \r
736                 page_address = address / device->page_size;\r
737                 \r
738                 nand_write_page(device, page_address, page, device->page_size, NULL, 0);\r
739                 \r
740                 address += thisrun_size;\r
741                 data += thisrun_size;\r
742                 data_size -= thisrun_size;\r
743         }\r
744         \r
745         free(page);\r
746         \r
747         return ERROR_OK;\r
748 }\r
749 \r
750 int nand_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)\r
751 {\r
752         if (!device->device)\r
753                 return ERROR_NAND_DEVICE_NOT_PROBED;\r
754                 \r
755         if (device->use_raw || device->controller->write_page == NULL)\r
756                 return nand_write_page_raw(device, page, data, data_size, oob, oob_size);\r
757         else\r
758                 return device->controller->write_page(device, page, data, data_size, oob, oob_size);\r
759 }\r
760 \r
761 int nand_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)\r
762 {\r
763         if (!device->device)\r
764                 return ERROR_NAND_DEVICE_NOT_PROBED;\r
765                 \r
766         if (device->use_raw || device->controller->read_page == NULL)\r
767                 return nand_read_page_raw(device, page, data, data_size, oob, oob_size);\r
768         else\r
769                 return device->controller->read_page(device, page, data, data_size, oob, oob_size);\r
770 }\r
771 \r
772 int nand_read_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)\r
773 {\r
774         int i;\r
775         \r
776         if (!device->device)\r
777                 return ERROR_NAND_DEVICE_NOT_PROBED;\r
778 \r
779         if (device->page_size <= 512)\r
780         {\r
781                 /* small page device */\r
782                 if (data)\r
783                         device->controller->command(device, NAND_CMD_READ0);\r
784                 else\r
785                         device->controller->command(device, NAND_CMD_READOOB);\r
786                 \r
787                 /* column (always 0, we start at the beginning of a page/OOB area) */\r
788                 device->controller->address(device, 0x0);\r
789                 \r
790                 /* row */\r
791                 device->controller->address(device, page & 0xff);\r
792                 device->controller->address(device, (page >> 8) & 0xff);\r
793                 \r
794                 /* 4th cycle only on devices with more than 32 MiB */\r
795                 if (device->address_cycles >= 4)\r
796                         device->controller->address(device, (page >> 16) & 0xff);\r
797 \r
798                 /* 5th cycle only on devices with more than 8 GiB */\r
799                 if (device->address_cycles >= 5)\r
800                         device->controller->address(device, (page >> 24) & 0xff);\r
801         }\r
802         else\r
803         {\r
804                 /* large page device */\r
805                 device->controller->command(device, NAND_CMD_READ0);\r
806                 \r
807                 /* column (0 when we start at the beginning of a page,\r
808                  * or 2048 for the beginning of OOB area)\r
809                  */\r
810                 device->controller->address(device, 0x0);\r
811                 device->controller->address(device, 0x8);\r
812                 \r
813                 /* row */\r
814                 device->controller->address(device, page & 0xff);\r
815                 device->controller->address(device, (page >> 8) & 0xff);\r
816 \r
817                 /* 5th cycle only on devices with more than 128 MiB */\r
818                 if (device->address_cycles >= 5)\r
819                         device->controller->address(device, (page >> 16) & 0xff);\r
820 \r
821                 /* large page devices need a start command */\r
822                 device->controller->command(device, NAND_CMD_READSTART);\r
823         }\r
824         \r
825         if (!device->controller->nand_ready(device, 100))\r
826                 return ERROR_NAND_OPERATION_TIMEOUT;\r
827         \r
828         if (data)\r
829         {\r
830                 if (device->controller->read_block_data != NULL)\r
831                         (device->controller->read_block_data)(device, data, data_size);\r
832                 else\r
833                 {\r
834                         for (i = 0; i < data_size;)\r
835                         {\r
836                                 if (device->device->options & NAND_BUSWIDTH_16)\r
837                                 {\r
838                                         device->controller->read_data(device, data);\r
839                                         data += 2;\r
840                                         i += 2;\r
841                                 }\r
842                                 else\r
843                                 {\r
844                                         device->controller->read_data(device, data);\r
845                                         data += 1;\r
846                                         i += 1;\r
847                                 }\r
848                         }\r
849                 }\r
850         }\r
851         \r
852         if (oob)\r
853         {\r
854                 if (device->controller->read_block_data != NULL)\r
855                         (device->controller->read_block_data)(device, oob, oob_size);\r
856                 else\r
857                 {\r
858                         for (i = 0; i < oob_size;)\r
859                         {\r
860                                 if (device->device->options & NAND_BUSWIDTH_16)\r
861                                 {\r
862                                         device->controller->read_data(device, oob);\r
863                                         oob += 2;\r
864                                         i += 2;\r
865                                 }\r
866                                 else\r
867                                 {\r
868                                         device->controller->read_data(device, oob);\r
869                                         oob += 1;\r
870                                         i += 1;\r
871                                 }\r
872                         }\r
873                 }\r
874         }\r
875         \r
876         return ERROR_OK;        \r
877 }\r
878 \r
879 int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)\r
880 {\r
881         int i;\r
882         int retval;\r
883         u8 status;\r
884         \r
885         if (!device->device)\r
886                 return ERROR_NAND_DEVICE_NOT_PROBED;\r
887 \r
888         device->controller->command(device, NAND_CMD_SEQIN);\r
889         \r
890         if (device->page_size <= 512)\r
891         {\r
892                 /* column (always 0, we start at the beginning of a page/OOB area) */\r
893                 device->controller->address(device, 0x0);\r
894                 \r
895                 /* row */\r
896                 device->controller->address(device, page & 0xff);\r
897                 device->controller->address(device, (page >> 8) & 0xff);\r
898                 \r
899                 /* 4th cycle only on devices with more than 32 MiB */\r
900                 if (device->address_cycles >= 4)\r
901                         device->controller->address(device, (page >> 16) & 0xff);\r
902 \r
903                 /* 5th cycle only on devices with more than 8 GiB */\r
904                 if (device->address_cycles >= 5)\r
905                         device->controller->address(device, (page >> 24) & 0xff);\r
906         }\r
907         else\r
908         {\r
909                 /* column (0 when we start at the beginning of a page,\r
910                  * or 2048 for the beginning of OOB area)\r
911                  */\r
912                 device->controller->address(device, 0x0);\r
913                 device->controller->address(device, 0x8);\r
914                 \r
915                 /* row */\r
916                 device->controller->address(device, page & 0xff);\r
917                 device->controller->address(device, (page >> 8) & 0xff);\r
918 \r
919                 /* 5th cycle only on devices with more than 128 MiB */\r
920                 if (device->address_cycles >= 5)\r
921                         device->controller->address(device, (page >> 16) & 0xff);\r
922         }\r
923         \r
924         if (data)\r
925         {\r
926                 if (device->controller->write_block_data != NULL)\r
927                         (device->controller->write_block_data)(device, data, data_size);\r
928                 else\r
929                 {\r
930                         for (i = 0; i < data_size;)\r
931                         {\r
932                                 if (device->device->options & NAND_BUSWIDTH_16)\r
933                                 {\r
934                                         u16 data_buf = le_to_h_u16(data);\r
935                                         device->controller->write_data(device, data_buf);\r
936                                         data += 2;\r
937                                         i += 2;\r
938                                 }\r
939                                 else\r
940                                 {\r
941                                         device->controller->write_data(device, *data);\r
942                                         data += 1;\r
943                                         i += 1;\r
944                                 }\r
945                         }\r
946                 }\r
947         }\r
948         \r
949         if (oob)\r
950         {\r
951                 if (device->controller->write_block_data != NULL)\r
952                         (device->controller->write_block_data)(device, oob, oob_size);\r
953                 else\r
954                 {\r
955                         for (i = 0; i < oob_size;)\r
956                         {\r
957                                 if (device->device->options & NAND_BUSWIDTH_16)\r
958                                 {\r
959                                         u16 oob_buf = le_to_h_u16(data);\r
960                                         device->controller->write_data(device, oob_buf);\r
961                                         oob += 2;\r
962                                         i += 2;\r
963                                 }\r
964                                 else\r
965                                 {\r
966                                         device->controller->write_data(device, *oob);\r
967                                         oob += 1;\r
968                                         i += 1;\r
969                                 }\r
970                         }\r
971                 }\r
972         }\r
973         \r
974         device->controller->command(device, NAND_CMD_PAGEPROG);\r
975         \r
976         if (!device->controller->nand_ready(device, 100))\r
977                 return ERROR_NAND_OPERATION_TIMEOUT;\r
978         \r
979         if ((retval = nand_read_status(device, &status)) != ERROR_OK)\r
980         {\r
981                 ERROR("couldn't read status");\r
982                 return ERROR_NAND_OPERATION_FAILED;\r
983         }\r
984                 \r
985         if (status & NAND_STATUS_FAIL)\r
986         {\r
987                 ERROR("write operation didn't pass, status: 0x%2.2x", status);\r
988                 return ERROR_NAND_OPERATION_FAILED;\r
989         }\r
990         \r
991         return ERROR_OK;        \r
992 }\r
993 \r
994 int handle_nand_list_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
995 {\r
996         nand_device_t *p;\r
997         int i = 0;\r
998         \r
999         if (!nand_devices)\r
1000         {\r
1001                 command_print(cmd_ctx, "no NAND flash devices configured");\r
1002                 return ERROR_OK;\r
1003         }\r
1004         \r
1005         for (p = nand_devices; p; p = p->next)\r
1006         {\r
1007                 if (p->device)\r
1008                         command_print(cmd_ctx, "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i",\r
1009                                 i++, p->device->name, p->manufacturer->name, p->page_size, p->bus_width, p->erase_size);\r
1010                 else\r
1011                         command_print(cmd_ctx, "#%i: not probed");\r
1012         }\r
1013         \r
1014         return ERROR_OK;\r
1015 }\r
1016 \r
1017 int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
1018 {\r
1019         nand_device_t *p;\r
1020         int i = 0;\r
1021         int j = 0;\r
1022         int first = -1;\r
1023         int last = -1;\r
1024                 \r
1025         if ((argc < 1) || (argc > 3))\r
1026         {\r
1027                 return ERROR_COMMAND_SYNTAX_ERROR;\r
1028 \r
1029         }\r
1030         \r
1031         if (argc == 2)\r
1032         {\r
1033                 first = last = strtoul(args[1], NULL, 0);\r
1034         }\r
1035         else if (argc == 3)\r
1036         {\r
1037                 first = strtoul(args[1], NULL, 0);\r
1038                 last = strtoul(args[2], NULL, 0);\r
1039         }\r
1040                 \r
1041         p = get_nand_device_by_num(strtoul(args[0], NULL, 0));\r
1042         if (p)\r
1043         {\r
1044                 if (p->device)\r
1045                 {\r
1046                         if (first >= p->num_blocks)\r
1047                                 first = p->num_blocks - 1;\r
1048                         \r
1049                         if (last >= p->num_blocks)\r
1050                                 last = p->num_blocks - 1;\r
1051                         \r
1052                         command_print(cmd_ctx, "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i",\r
1053                                 i++, p->device->name, p->manufacturer->name, p->page_size, p->bus_width, p->erase_size);\r
1054                         \r
1055                         for (j = first; j <= last; j++)\r
1056                         {\r
1057                                 char *erase_state, *bad_state;\r
1058                                 \r
1059                                 if (p->blocks[j].is_erased == 0)\r
1060                                         erase_state = "not erased";\r
1061                                 else if (p->blocks[j].is_erased == 1)\r
1062                                         erase_state = "erased";\r
1063                                 else\r
1064                                         erase_state = "erase state unknown";\r
1065                                 \r
1066                                 if (p->blocks[j].is_bad == 0)\r
1067                                         bad_state = "";\r
1068                                 else if (p->blocks[j].is_bad == 1)\r
1069                                         bad_state = " (marked bad)";\r
1070                                 else\r
1071                                         bad_state = " (block condition unknown)";\r
1072 \r
1073                                 command_print(cmd_ctx, "\t#%i: 0x%8.8x (0x%xkB) %s%s",\r
1074                                                         j, p->blocks[j].offset, p->blocks[j].size / 1024,\r
1075                                                         erase_state, bad_state);\r
1076                         }\r
1077                 }\r
1078                 else\r
1079                 {\r
1080                         command_print(cmd_ctx, "#%i: not probed");\r
1081                 }\r
1082         }\r
1083         \r
1084         return ERROR_OK;\r
1085 }\r
1086 \r
1087 int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
1088 {\r
1089         nand_device_t *p;\r
1090         int retval;\r
1091                 \r
1092         if (argc != 1)\r
1093         {\r
1094                 return ERROR_COMMAND_SYNTAX_ERROR;\r
1095         }\r
1096         \r
1097         p = get_nand_device_by_num(strtoul(args[0], NULL, 0));\r
1098         if (p)\r
1099         {\r
1100                 if ((retval = nand_probe(p)) == ERROR_OK)\r
1101                 {\r
1102                         command_print(cmd_ctx, "NAND flash device '%s' found", p->device->name);\r
1103                 }\r
1104                 else if (retval == ERROR_NAND_OPERATION_FAILED)\r
1105                 {\r
1106                         command_print(cmd_ctx, "probing failed for NAND flash device");\r
1107                 }\r
1108                 else\r
1109                 {\r
1110                         command_print(cmd_ctx, "unknown error when probing NAND flash device");\r
1111                 }\r
1112         }\r
1113         else\r
1114         {\r
1115                 command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);\r
1116         }\r
1117         \r
1118         return ERROR_OK;\r
1119 }\r
1120 \r
1121 int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
1122 {\r
1123         nand_device_t *p;\r
1124         int retval;\r
1125                 \r
1126         if (argc != 3)\r
1127         {\r
1128                 return ERROR_COMMAND_SYNTAX_ERROR;\r
1129 \r
1130         }\r
1131         \r
1132         p = get_nand_device_by_num(strtoul(args[0], NULL, 0));\r
1133         if (p)\r
1134         {\r
1135                 int first = strtoul(args[1], NULL, 0);\r
1136                 int last = strtoul(args[2], NULL, 0);\r
1137                 \r
1138                 if ((retval = nand_erase(p, first, last)) == ERROR_OK)\r
1139                 {\r
1140                         command_print(cmd_ctx, "successfully erased blocks %i to %i on NAND flash device '%s'", first, last, p->device->name);\r
1141                 }\r
1142                 else if (retval == ERROR_NAND_OPERATION_FAILED)\r
1143                 {\r
1144                         command_print(cmd_ctx, "erase failed");\r
1145                 }\r
1146                 else\r
1147                 {\r
1148                         command_print(cmd_ctx, "unknown error when erasing NAND flash device");\r
1149                 }\r
1150         }\r
1151         else\r
1152         {\r
1153                 command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);\r
1154         }\r
1155         \r
1156         return ERROR_OK;\r
1157 }\r
1158 \r
1159 int handle_nand_check_bad_blocks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
1160 {\r
1161         nand_device_t *p;\r
1162         int retval;\r
1163         int first = -1;\r
1164         int last = -1;\r
1165                 \r
1166         if ((argc < 1) || (argc > 3) || (argc == 2))\r
1167         {\r
1168                 return ERROR_COMMAND_SYNTAX_ERROR;\r
1169 \r
1170         }\r
1171         \r
1172         if (argc == 3)\r
1173         {\r
1174                 first = strtoul(args[1], NULL, 0);\r
1175                 last = strtoul(args[2], NULL, 0);\r
1176         }\r
1177         \r
1178         p = get_nand_device_by_num(strtoul(args[0], NULL, 0));\r
1179         if (p)\r
1180         {\r
1181                 if ((retval = nand_build_bbt(p, first, last)) == ERROR_OK)\r
1182                 {\r
1183                         command_print(cmd_ctx, "checked NAND flash device for bad blocks, use \"nand info\" command to list blocks", p->device->name);\r
1184                 }\r
1185                 else if (retval == ERROR_NAND_OPERATION_FAILED)\r
1186                 {\r
1187                         command_print(cmd_ctx, "error when checking for bad blocks on NAND flash device");\r
1188                 }\r
1189                 else\r
1190                 {\r
1191                         command_print(cmd_ctx, "unknown error when checking for bad blocks on NAND flash device");\r
1192                 }\r
1193         }\r
1194         else\r
1195         {\r
1196                 command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);\r
1197         }\r
1198         \r
1199         return ERROR_OK;\r
1200 }\r
1201 \r
1202 int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
1203 {\r
1204         nand_device_t *p;\r
1205                 \r
1206         if (argc != 4)\r
1207         {\r
1208                 return ERROR_COMMAND_SYNTAX_ERROR;\r
1209 \r
1210         }\r
1211         \r
1212         p = get_nand_device_by_num(strtoul(args[0], NULL, 0));\r
1213         if (p)\r
1214         {\r
1215 \r
1216         }\r
1217         else\r
1218         {\r
1219                 command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);\r
1220         }\r
1221         \r
1222         return ERROR_OK;\r
1223 }\r
1224 \r
1225 int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
1226 {\r
1227         u32 offset;\r
1228         u32 binary_size;\r
1229         u32 buf_cnt;\r
1230         enum oob_formats oob_format = NAND_OOB_NONE;\r
1231         \r
1232         fileio_t fileio;\r
1233         \r
1234         duration_t duration;\r
1235         char *duration_text;\r
1236         \r
1237         nand_device_t *p;\r
1238                 \r
1239         if (argc < 3)\r
1240         {\r
1241                 return ERROR_COMMAND_SYNTAX_ERROR;\r
1242 \r
1243         }\r
1244         \r
1245         p = get_nand_device_by_num(strtoul(args[0], NULL, 0));\r
1246         if (p)\r
1247         {\r
1248                 u8 *page = NULL;\r
1249                 u32 page_size = 0;\r
1250                 u8 *oob = NULL;\r
1251                 u32 oob_size = 0;\r
1252                         \r
1253                 duration_start_measure(&duration);\r
1254                 offset = strtoul(args[2], NULL, 0);\r
1255                 \r
1256                 if (argc > 3)\r
1257                 {\r
1258                         int i;\r
1259                         for (i = 3; i < argc; i++)\r
1260                         {\r
1261                                 if (!strcmp(args[i], "oob_raw"))\r
1262                                         oob_format |= NAND_OOB_RAW;\r
1263                                 else if (!strcmp(args[i], "oob_only"))\r
1264                                         oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;\r
1265                                 else\r
1266                                 {\r
1267                                         command_print(cmd_ctx, "unknown option: %s", args[i]);\r
1268                                 }\r
1269                         }\r
1270                 }\r
1271                 \r
1272                 if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)\r
1273                 {\r
1274                         command_print(cmd_ctx, "file open error: %s", fileio.error_str);\r
1275                         return ERROR_OK;\r
1276                 }\r
1277         \r
1278                 buf_cnt = binary_size = fileio.size;\r
1279                 \r
1280                 if (!(oob_format & NAND_OOB_ONLY))\r
1281                 {\r
1282                         page_size = p->page_size;\r
1283                         page = malloc(p->page_size);\r
1284                 }\r
1285 \r
1286                 if (oob_format & NAND_OOB_RAW)\r
1287                 {\r
1288                         if (p->page_size == 512)\r
1289                                 oob_size = 16;\r
1290                         else if (p->page_size == 2048)\r
1291                                 oob_size = 64;\r
1292                         oob = malloc(oob_size);\r
1293                 }\r
1294                 \r
1295                 if (offset % p->page_size)\r
1296                 {\r
1297                         command_print(cmd_ctx, "only page size aligned offsets and sizes are supported");\r
1298                         return ERROR_OK;\r
1299                 }\r
1300                 \r
1301                 while (buf_cnt > 0)\r
1302                 {\r
1303                         u32 size_read;\r
1304                         \r
1305                         if (page)\r
1306                         {\r
1307                                 fileio_read(&fileio, page_size, page, &size_read);\r
1308                                 buf_cnt -= size_read;\r
1309                                 if (size_read < page_size)\r
1310                                 {\r
1311                                         memset(page + size_read, 0xff, page_size - size_read);\r
1312                                 }\r
1313                         }\r
1314                                 \r
1315                         if (oob)\r
1316                         {\r
1317                                 fileio_read(&fileio, oob_size, oob, &size_read);\r
1318                                 buf_cnt -= size_read;\r
1319                                 if (size_read < oob_size)\r
1320                                 {\r
1321                                         memset(oob + size_read, 0xff, oob_size - size_read);\r
1322                                 }\r
1323                         }\r
1324                         \r
1325                         if (nand_write_page(p, offset / p->page_size, page, page_size, oob, oob_size) != ERROR_OK)\r
1326                         {\r
1327                                 command_print(cmd_ctx, "failed writing file %s to NAND flash %s at offset 0x%8.8x",\r
1328                                         args[1], args[0], offset);\r
1329                                 return ERROR_OK;\r
1330                         }\r
1331                         offset += page_size;\r
1332                 }\r
1333 \r
1334                 fileio_close(&fileio);\r
1335                 \r
1336                 duration_stop_measure(&duration, &duration_text);\r
1337                 command_print(cmd_ctx, "wrote file %s to NAND flash %s at offset 0x%8.8x in %s",\r
1338                         args[1], args[0], offset, duration_text);\r
1339                 free(duration_text);\r
1340         }\r
1341         else\r
1342         {\r
1343                 command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);\r
1344         }\r
1345         \r
1346         return ERROR_OK;\r
1347 }\r
1348 \r
1349 int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
1350 {\r
1351         nand_device_t *p;\r
1352                         \r
1353         if (argc < 4)\r
1354         {\r
1355                 return ERROR_COMMAND_SYNTAX_ERROR;\r
1356         }\r
1357         \r
1358         p = get_nand_device_by_num(strtoul(args[0], NULL, 0));\r
1359         if (p)\r
1360         {\r
1361                 if (p->device)\r
1362                 {\r
1363                         fileio_t fileio;\r
1364                         duration_t duration;\r
1365                         char *duration_text;\r
1366                         int retval;\r
1367                         \r
1368                         u8 *page = NULL;\r
1369                         u32 page_size = 0;\r
1370                         u8 *oob = NULL;\r
1371                         u32 oob_size = 0;\r
1372                         u32 address = strtoul(args[2], NULL, 0);\r
1373                         u32 size = strtoul(args[3], NULL, 0);\r
1374                         u32 bytes_done = 0;\r
1375                         enum oob_formats oob_format = NAND_OOB_NONE;\r
1376                         \r
1377                         if (argc > 4)\r
1378                         {\r
1379                                 int i;\r
1380                                 for (i = 4; i < argc; i++)\r
1381                                 {\r
1382                                         if (!strcmp(args[i], "oob_raw"))\r
1383                                                 oob_format |= NAND_OOB_RAW;\r
1384                                         else if (!strcmp(args[i], "oob_only"))\r
1385                                                 oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;\r
1386                                         else\r
1387                                                 command_print(cmd_ctx, "unknown option: '%s'", args[i]); \r
1388                                 }\r
1389                         }\r
1390                         \r
1391                         if ((address % p->page_size) || (size % p->page_size))\r
1392                         {\r
1393                                 command_print(cmd_ctx, "only page size aligned addresses and sizes are supported");\r
1394                                 return ERROR_OK;\r
1395                         }\r
1396                 \r
1397                         if (!(oob_format & NAND_OOB_ONLY))\r
1398                         {\r
1399                                 page_size = p->page_size;\r
1400                                 page = malloc(p->page_size);\r
1401                         }\r
1402 \r
1403                         if (oob_format & NAND_OOB_RAW)\r
1404                         {\r
1405                                 if (p->page_size == 512)\r
1406                                         oob_size = 16;\r
1407                                 else if (p->page_size == 2048)\r
1408                                         oob_size = 64;\r
1409                                 oob = malloc(oob_size);\r
1410                         }\r
1411                         \r
1412                         if (fileio_open(&fileio, args[1], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)\r
1413                         {\r
1414                                 command_print(cmd_ctx, "dump_image error: %s", fileio.error_str);\r
1415                                 return ERROR_OK;\r
1416                         }\r
1417         \r
1418                         duration_start_measure(&duration);\r
1419                         \r
1420                         while (size > 0)\r
1421                         {\r
1422                                 u32 size_written;\r
1423                                 if ((retval = nand_read_page(p, address / p->page_size, page, page_size, oob, oob_size)) != ERROR_OK)\r
1424                                 {\r
1425                                         command_print(cmd_ctx, "reading NAND flash page failed");\r
1426                                         return ERROR_OK;\r
1427                                 }\r
1428                                 \r
1429                                 if (page)\r
1430                                 {\r
1431                                         fileio_write(&fileio, page_size, page, &size_written);\r
1432                                         bytes_done += page_size;\r
1433                                 }\r
1434                                         \r
1435                                 if (oob)\r
1436                                 {\r
1437                                         fileio_write(&fileio, oob_size, oob, &size_written);\r
1438                                         bytes_done += oob_size;\r
1439                                 }\r
1440                                         \r
1441                                 size -= p->page_size;\r
1442                                 address += p->page_size;\r
1443                         }\r
1444                         \r
1445                         if (page)\r
1446                                 free(page);\r
1447                                 \r
1448                         if (oob)\r
1449                                 free(oob);\r
1450                         \r
1451                         fileio_close(&fileio);\r
1452 \r
1453                         duration_stop_measure(&duration, &duration_text);\r
1454                         command_print(cmd_ctx, "dumped %"PRIi64" byte in %s", fileio.size, duration_text);\r
1455                         free(duration_text);\r
1456                 }\r
1457                 else\r
1458                 {\r
1459                         command_print(cmd_ctx, "#%i: not probed");\r
1460                 }\r
1461         }\r
1462         else\r
1463         {\r
1464                 command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);\r
1465         }\r
1466         \r
1467         return ERROR_OK;\r
1468 }\r
1469 \r
1470 int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
1471 {\r
1472         nand_device_t *p;\r
1473                 \r
1474         if ((argc < 1) || (argc > 2))\r
1475         {\r
1476                 return ERROR_COMMAND_SYNTAX_ERROR;\r
1477         }\r
1478         \r
1479         p = get_nand_device_by_num(strtoul(args[0], NULL, 0));\r
1480         if (p)\r
1481         {\r
1482                 if (p->device)\r
1483                 {\r
1484                         if (argc == 2)\r
1485                         {\r
1486                                 if (strcmp("enable", args[1]) == 0)\r
1487                                 {\r
1488                                         p->use_raw = 1;\r
1489                                 }\r
1490                                 else if (strcmp("disable", args[1]) == 0)\r
1491                                 {\r
1492                                         p->use_raw = 0;\r
1493                                 }\r
1494                                 else\r
1495                                 {\r
1496                                         return ERROR_COMMAND_SYNTAX_ERROR;\r
1497                                 }\r
1498                         }\r
1499         \r
1500                         command_print(cmd_ctx, "raw access is %s", (p->use_raw) ? "enabled" : "disabled");\r
1501                 }\r
1502                 else\r
1503                 {\r
1504                         command_print(cmd_ctx, "#%i: not probed");\r
1505                 }\r
1506         }\r
1507         else\r
1508         {\r
1509                 command_print(cmd_ctx, "NAND flash device '#%s' is out of bounds", args[0]);\r
1510         }\r
1511         \r
1512         return ERROR_OK;\r
1513 }\r
1514 \r