|
@@ -4,6 +4,10 @@
|
|
* (c) 1999 Machine Vision Holdings, Inc.
|
|
* (c) 1999 Machine Vision Holdings, Inc.
|
|
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
|
|
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
|
|
*
|
|
*
|
|
|
|
+ * Ported 'dynenv' to 'nand env.oob' command
|
|
|
|
+ * (C) 2010 Nanometrics, Inc.
|
|
|
|
+ * 'dynenv' -- Dynamic environment offset in NAND OOB
|
|
|
|
+ * (C) Copyright 2006-2007 OpenMoko, Inc.
|
|
* Added 16-bit nand support
|
|
* Added 16-bit nand support
|
|
* (C) 2004 Texas Instruments
|
|
* (C) 2004 Texas Instruments
|
|
*/
|
|
*/
|
|
@@ -193,6 +197,90 @@ static void do_nand_status(nand_info_t *nand)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef CONFIG_ENV_OFFSET_OOB
|
|
|
|
+unsigned long nand_env_oob_offset;
|
|
|
|
+
|
|
|
|
+int do_nand_env_oob(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
|
|
|
+ int argc, char * const argv[])
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+ uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)];
|
|
|
|
+
|
|
|
|
+ char *cmd = argv[1];
|
|
|
|
+
|
|
|
|
+ if (!strcmp(cmd, "get")) {
|
|
|
|
+ ret = get_nand_env_oob(nand, &nand_env_oob_offset);
|
|
|
|
+ if (!ret)
|
|
|
|
+ printf("0x%08lx\n", nand_env_oob_offset);
|
|
|
|
+ else
|
|
|
|
+ return 1;
|
|
|
|
+ } else if (!strcmp(cmd, "set")) {
|
|
|
|
+ ulong addr;
|
|
|
|
+ size_t dummy_size;
|
|
|
|
+ struct mtd_oob_ops ops;
|
|
|
|
+
|
|
|
|
+ if (argc < 3)
|
|
|
|
+ goto usage;
|
|
|
|
+
|
|
|
|
+ if (arg_off_size(argc-2, argv + 2, nand, &addr,
|
|
|
|
+ &dummy_size) < 0) {
|
|
|
|
+ printf("Offset or partition name expected\n");
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (nand->oobavail < ENV_OFFSET_SIZE) {
|
|
|
|
+ printf("Insufficient available OOB bytes: %d OOB bytes"
|
|
|
|
+ " available but %d required for env.oob support\n",
|
|
|
|
+ nand->oobavail,
|
|
|
|
+ ENV_OFFSET_SIZE);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((addr & (nand->erasesize - 1)) != 0) {
|
|
|
|
+ printf("Environment offset must be block-aligned\n");
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ops.datbuf = NULL;
|
|
|
|
+ ops.mode = MTD_OOB_AUTO;
|
|
|
|
+ ops.ooboffs = 0;
|
|
|
|
+ ops.ooblen = ENV_OFFSET_SIZE;
|
|
|
|
+ ops.oobbuf = (void *) oob_buf;
|
|
|
|
+
|
|
|
|
+ oob_buf[0] = ENV_OOB_MARKER;
|
|
|
|
+ oob_buf[1] = addr / nand->erasesize;
|
|
|
|
+
|
|
|
|
+ ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops);
|
|
|
|
+ if (!ret) {
|
|
|
|
+ ret = get_nand_env_oob(nand, &nand_env_oob_offset);
|
|
|
|
+ if (ret) {
|
|
|
|
+ printf("Error reading env offset in OOB\n");
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (addr != nand_env_oob_offset) {
|
|
|
|
+ printf("Verification of env offset in OOB "
|
|
|
|
+ "failed: 0x%08lx expected but got "
|
|
|
|
+ "0x%08lx\n", addr, nand_env_oob_offset);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ printf("Error writing OOB block 0\n");
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ goto usage;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
|
|
+usage:
|
|
|
|
+ cmd_usage(cmdtp);
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#endif
|
|
|
|
+
|
|
static void nand_print_info(int idx)
|
|
static void nand_print_info(int idx)
|
|
{
|
|
{
|
|
nand_info_t *nand = &nand_info[idx];
|
|
nand_info_t *nand = &nand_info[idx];
|
|
@@ -272,9 +360,19 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
|
strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 &&
|
|
strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 &&
|
|
strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 &&
|
|
strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 &&
|
|
strcmp(cmd, "biterr") != 0 &&
|
|
strcmp(cmd, "biterr") != 0 &&
|
|
- strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 )
|
|
|
|
|
|
+ strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0
|
|
|
|
+#ifdef CONFIG_ENV_OFFSET_OOB
|
|
|
|
+ && strcmp(cmd, "env.oob") != 0
|
|
|
|
+#endif
|
|
|
|
+ )
|
|
goto usage;
|
|
goto usage;
|
|
|
|
|
|
|
|
+#ifdef CONFIG_ENV_OFFSET_OOB
|
|
|
|
+ /* this command operates only on the first nand device */
|
|
|
|
+ if (strcmp(cmd, "env.oob") == 0)
|
|
|
|
+ return do_nand_env_oob(cmdtp, &nand_info[0], argc - 1, argv + 1);
|
|
|
|
+#endif
|
|
|
|
+
|
|
/* the following commands operate on the current device */
|
|
/* the following commands operate on the current device */
|
|
if (nand_curr_device < 0 || nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
|
|
if (nand_curr_device < 0 || nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
|
|
!nand_info[nand_curr_device].name) {
|
|
!nand_info[nand_curr_device].name) {
|
|
@@ -502,6 +600,13 @@ U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,
|
|
" bring nand to lock state or display locked pages\n"
|
|
" bring nand to lock state or display locked pages\n"
|
|
"nand unlock [offset] [size] - unlock section"
|
|
"nand unlock [offset] [size] - unlock section"
|
|
#endif
|
|
#endif
|
|
|
|
+#ifdef CONFIG_ENV_OFFSET_OOB
|
|
|
|
+ "\n"
|
|
|
|
+ "nand env.oob - environment offset in OOB of block 0 of"
|
|
|
|
+ " first device.\n"
|
|
|
|
+ "nand env.oob set off|partition - set enviromnent offset\n"
|
|
|
|
+ "nand env.oob get - get environment offset"
|
|
|
|
+#endif
|
|
);
|
|
);
|
|
|
|
|
|
static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|
|
static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
|