Nicolas Pitre nico at cam.org The ECC data is automatically computed and written to the OOB area
when the oob_softecc option is passed to the "nand write" command. git-svn-id: svn://svn.berlios.de/openocd/trunk@1446 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
parent
c3d96a3a6e
commit
3725fded17
|
@ -186,6 +186,39 @@ nand_manufacturer_t nand_manuf_ids[] =
|
||||||
{0x0, NULL},
|
{0x0, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define default oob placement schemes for large and small page devices
|
||||||
|
*/
|
||||||
|
|
||||||
|
nand_ecclayout_t nand_oob_8 = {
|
||||||
|
.eccbytes = 3,
|
||||||
|
.eccpos = {0, 1, 2},
|
||||||
|
.oobfree = {
|
||||||
|
{.offset = 3,
|
||||||
|
.length = 2},
|
||||||
|
{.offset = 6,
|
||||||
|
.length = 2}}
|
||||||
|
};
|
||||||
|
|
||||||
|
nand_ecclayout_t nand_oob_16 = {
|
||||||
|
.eccbytes = 6,
|
||||||
|
.eccpos = {0, 1, 2, 3, 6, 7},
|
||||||
|
.oobfree = {
|
||||||
|
{.offset = 8,
|
||||||
|
. length = 8}}
|
||||||
|
};
|
||||||
|
|
||||||
|
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]
|
/* nand device <nand_controller> [controller options]
|
||||||
*/
|
*/
|
||||||
int handle_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
int handle_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
|
@ -1291,6 +1324,7 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
u32 page_size = 0;
|
u32 page_size = 0;
|
||||||
u8 *oob = NULL;
|
u8 *oob = NULL;
|
||||||
u32 oob_size = 0;
|
u32 oob_size = 0;
|
||||||
|
const int *eccpos = NULL;
|
||||||
|
|
||||||
offset = strtoul(args[2], NULL, 0);
|
offset = strtoul(args[2], NULL, 0);
|
||||||
|
|
||||||
|
@ -1303,6 +1337,8 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
oob_format |= NAND_OOB_RAW;
|
oob_format |= NAND_OOB_RAW;
|
||||||
else if (!strcmp(args[i], "oob_only"))
|
else if (!strcmp(args[i], "oob_only"))
|
||||||
oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;
|
oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;
|
||||||
|
else if (!strcmp(args[i], "oob_softecc"))
|
||||||
|
oob_format |= NAND_OOB_SW_ECC;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, "unknown option: %s", args[i]);
|
command_print(cmd_ctx, "unknown option: %s", args[i]);
|
||||||
|
@ -1326,12 +1362,15 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
page = malloc(p->page_size);
|
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;
|
oob_size = 16;
|
||||||
else if (p->page_size == 2048)
|
eccpos = nand_oob_16.eccpos;
|
||||||
|
} else if (p->page_size == 2048) {
|
||||||
oob_size = 64;
|
oob_size = 64;
|
||||||
|
eccpos = nand_oob_64.eccpos;
|
||||||
|
}
|
||||||
oob = malloc(oob_size);
|
oob = malloc(oob_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1358,7 +1397,19 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
fileio_read(&fileio, oob_size, oob, &size_read);
|
||||||
buf_cnt -= size_read;
|
buf_cnt -= size_read;
|
||||||
|
|
|
@ -56,6 +56,18 @@ typedef struct nand_block_s
|
||||||
int is_bad;
|
int is_bad;
|
||||||
} nand_block_t;
|
} nand_block_t;
|
||||||
|
|
||||||
|
struct nand_oobfree {
|
||||||
|
int offset;
|
||||||
|
int length;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct nand_ecclayout_s {
|
||||||
|
int eccbytes;
|
||||||
|
int eccpos[64];
|
||||||
|
int oobavail;
|
||||||
|
struct nand_oobfree oobfree[2];
|
||||||
|
} nand_ecclayout_t;
|
||||||
|
|
||||||
typedef struct nand_device_s
|
typedef struct nand_device_s
|
||||||
{
|
{
|
||||||
nand_flash_controller_t *controller;
|
nand_flash_controller_t *controller;
|
||||||
|
|
Loading…
Reference in New Issue