#include "fileio.h"
#include "image.h"
-int nand_register_commands(struct command_context_s *cmd_ctx);
-int handle_nand_list_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_nand_check_bad_blocks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_nand_list_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_nand_check_bad_blocks_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int nand_read_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
-int nand_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
-int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size);
+static int nand_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
+//static int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size);
-int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
-int nand_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
+static int nand_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
/* NAND flash controller
*/
/* extern nand_flash_controller_t boundary_scan_nand_controller; */
-nand_flash_controller_t *nand_flash_controllers[] =
+static nand_flash_controller_t *nand_flash_controllers[] =
{
&lpc3180_nand_controller,
&orion_nand_controller,
};
/* configured NAND devices and NAND Flash command handler */
-nand_device_t *nand_devices = NULL;
+static nand_device_t *nand_devices = NULL;
static command_t *nand_cmd;
/* Chip ID list
* 256 256 Byte page size
* 512 512 Byte page size
*/
-nand_info_t nand_flash_ids[] =
+static nand_info_t nand_flash_ids[] =
{
{"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
{"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0},
/* Manufacturer ID list
*/
-nand_manufacturer_t nand_manuf_ids[] =
+static nand_manufacturer_t nand_manuf_ids[] =
{
{0x0, "unknown"},
{NAND_MFR_TOSHIBA, "Toshiba"},
{0x0, NULL},
};
+/*
+ * Define default oob placement schemes for large and small page devices
+ */
+
+#if 0
+static nand_ecclayout_t nand_oob_8 = {
+ .eccbytes = 3,
+ .eccpos = {0, 1, 2},
+ .oobfree = {
+ {.offset = 3,
+ .length = 2},
+ {.offset = 6,
+ .length = 2}}
+};
+#endif
+
+static nand_ecclayout_t nand_oob_16 = {
+ .eccbytes = 6,
+ .eccpos = {0, 1, 2, 3, 6, 7},
+ .oobfree = {
+ {.offset = 8,
+ . length = 8}}
+};
+
+static nand_ecclayout_t nand_oob_64 = {
+ .eccbytes = 24,
+ .eccpos = {
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63},
+ .oobfree = {
+ {.offset = 2,
+ .length = 38}}
+};
+
/* nand device <nand_controller> [controller options]
*/
-int handle_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
int i;
int retval;
register_command(cmd_ctx, nand_cmd, "dump", handle_nand_dump_command, COMMAND_EXEC,
"dump from NAND flash device <num> <filename> <offset> <size> [options]");
register_command(cmd_ctx, nand_cmd, "write", handle_nand_write_command, COMMAND_EXEC,
- "write to NAND flash device <num> <filename> <offset> [oob_raw|oob_only]");
+ "write to NAND flash device <num> <filename> <offset> [oob_raw|oob_only|oob_softecc]");
register_command(cmd_ctx, nand_cmd, "raw_access", handle_nand_raw_access_command, COMMAND_EXEC,
"raw access to NAND flash device <num> ['enable'|'disable']");
}
return NULL;
}
-int nand_build_bbt(struct nand_device_s *device, int first, int last)
+static int nand_build_bbt(struct nand_device_s *device, int first, int last)
{
u32 page = 0x0;
int i;
return ERROR_OK;
}
-int nand_poll_ready(struct nand_device_s *device, int timeout)
+static int nand_poll_ready(struct nand_device_s *device, int timeout)
{
u8 status;
return ERROR_OK;
}
-int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size)
+#if 0
+static int nand_read_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size)
{
u8 *page;
return ERROR_OK;
}
-int nand_write_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size)
+static int nand_write_plain(struct nand_device_s *device, u32 address, u8 *data, u32 data_size)
{
u8 *page;
return ERROR_OK;
}
+#endif
int nand_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)
{
return device->controller->write_page(device, page, data, data_size, oob, oob_size);
}
-int nand_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)
+static int nand_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)
{
if (!device->device)
return ERROR_NAND_DEVICE_NOT_PROBED;
return ERROR_OK;
}
-int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_nand_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
nand_device_t *p;
int i = 0;
return ERROR_OK;
}
-int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_nand_probe_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
nand_device_t *p;
int retval;
return ERROR_OK;
}
-int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_nand_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
nand_device_t *p;
int retval;
return ERROR_OK;
}
-int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
nand_device_t *p;
return ERROR_OK;
}
-int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
u32 offset;
u32 binary_size;
u32 page_size = 0;
u8 *oob = NULL;
u32 oob_size = 0;
+ const int *eccpos = NULL;
offset = strtoul(args[2], NULL, 0);
oob_format |= NAND_OOB_RAW;
else if (!strcmp(args[i], "oob_only"))
oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;
+ else if (!strcmp(args[i], "oob_softecc"))
+ oob_format |= NAND_OOB_SW_ECC;
else
{
command_print(cmd_ctx, "unknown option: %s", args[i]);
page = malloc(p->page_size);
}
- if (oob_format & NAND_OOB_RAW)
+ if (oob_format & (NAND_OOB_RAW | NAND_OOB_SW_ECC))
{
- if (p->page_size == 512)
+ if (p->page_size == 512) {
oob_size = 16;
- else if (p->page_size == 2048)
+ eccpos = nand_oob_16.eccpos;
+ } else if (p->page_size == 2048) {
oob_size = 64;
+ eccpos = nand_oob_64.eccpos;
+ }
oob = malloc(oob_size);
}
memset(page + size_read, 0xff, page_size - size_read);
}
}
-
- if (NULL != oob)
+
+ if (oob_format & NAND_OOB_SW_ECC)
+ {
+ int i, j;
+ u8 ecc[3];
+ memset(oob, 0xff, oob_size);
+ for (i = 0, j = 0; i < page_size; i += 256) {
+ nand_calculate_ecc(p, page+i, ecc);
+ oob[eccpos[j++]] = ecc[0];
+ oob[eccpos[j++]] = ecc[1];
+ oob[eccpos[j++]] = ecc[2];
+ }
+ }
+ else if (NULL != oob)
{
fileio_read(&fileio, oob_size, oob, &size_read);
buf_cnt -= size_read;
return ERROR_OK;
}
-int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_nand_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
nand_device_t *p;
return ERROR_OK;
}
-int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_nand_raw_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
nand_device_t *p;