Merge changes I14921481,Icf51ed24,I5f3758a8
* changes:
WindCharger: Adds shared name when editing sysvar/uboot env.
WindCharger: Fixes up shared variable behavior.
WindCharger: Refactors sysvar data access code.
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index a34f20f..10673b8 100755
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -130,7 +130,7 @@
if (k < 0) {
continue;
}
- if (is_sysvar_shared(name)) {
+ if (get_sysvar_shared(name)) {
puts(">>> ");
}
puts (name);
@@ -393,10 +393,16 @@
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
- if (argc >= 2 && is_sysvar_shared(argv[1])) {
- printf("ERR: %s is a sysvar-shared variable.\n"
- " Please use setvar/sysvar instead\n", argv[1]);
- return 1;
+ if (argc >= 2) {
+ const char *name = get_sysvar_shared(argv[1]);
+ if (name) {
+ printf("ERR: %s is a sysvar-shared variable.\n"
+ " Please edit '%s' using setvar/sysvar "
+ "instead\n",
+ argv[1],
+ name);
+ return 1;
+ }
}
return _do_setenv (flag, argc, argv);
diff --git a/common/cmd_sysvar.c b/common/cmd_sysvar.c
index 49bab01..134a370 100644
--- a/common/cmd_sysvar.c
+++ b/common/cmd_sysvar.c
@@ -45,26 +45,69 @@
};
/*
- * print_msg - print the message string
+ * str_to_int - Converts a string into an int.
+ *
+ * Returns an error by setting "err" to something non-zero.
*/
-static void print_msg(char *msg, int idx) {
- if (idx < 0) {
- printf("SV: %s\n", msg);
- } else {
- printf("SV: System variables(%s) has been %s\n",
- (idx < SYSVAR_RO_BUF) ? "RW" : "RO", msg);
+static int str_to_int(const char *str, int *err) {
+ int res = 0;
+ char *p;
+ for (p = str; *p != '\0'; ++p) {
+ switch (*p) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ res = res * 10 + (*p - '0');
+ break;
+ default:
+ if (err) {
+ *err = 1;
+ }
+ return res;
+ }
}
+ return res;
}
-/*
- * print_err - print the error message
- */
-static void print_err(char *err, int idx) {
- if (idx < 0) {
- printf("## Error: %s\n", err);
- } else {
- printf("## Error: failed to %s system variables(%s)\n",
- err, (idx < SYSVAR_RO_BUF) ? "RW" : "RO");
+static void print_err(int code, void *arg) {
+ switch (code) {
+ case SYSVAR_CRC_ERR:
+ printf("## Error: CRC check failure on index %d\n", *(int*)arg);
+ break;
+ case SYSVAR_DELETE_ERR:
+ printf("## Error: failed to delete '%s'\n", (char*)arg);
+ break;
+ case SYSVAR_ERASE_ERR:
+ printf("## Error: erase failure on index %d\n", *(int*)arg);
+ break;
+ case SYSVAR_EXISTED_ERR:
+ printf("## Error: '%s' is already a read/write variable\n", (char*)arg);
+ break;
+ case SYSVAR_INDEX_ERR:
+ printf("## Error: invalid SPI flash device %d\n", *(int*)arg);
+ break;
+ case SYSVAR_READONLY_ERR:
+ printf("## Error: '%s' is a read only variable\n", (char*)arg);
+ break;
+ case SYSVAR_SET_ERR:
+ printf("## Error: '%s' not found\n", (char*)arg);
+ break;
+ case SYSVAR_SUCCESS:
+ break;
+ case SYSVAR_WRITE_ERR:
+ printf("## Error: unable to write to index %d\n", *(int*)arg);
+ break;
+ default:
+ /* Unknown error code. */
+ printf("## Error: code %d\n", code);
+ break;
}
}
@@ -72,10 +115,9 @@
* data_recovery - system variables recovering routine
*/
int data_recovery(struct sysvar_buf *buf, int idx) {
- int i, j, ret, sector;
+ int i, j, ret = SYSVAR_SUCCESS, sector;
/* load the system variables */
- printf("SV: Recovering data");
for (i = idx, j = idx + 1; i < idx + 2; i++, j--) {
/* read the data from SPI flash */
if (read_buff(flash_info, buf->data, sysvar_offset[i], buf->data_len))
@@ -87,33 +129,32 @@
sector = __SYSVAR_ERASE_SECTOR(sysvar_offset[j]);
ret = flash_erase(flash_info, sector, sector);
if (ret) {
- print_err("erase", j);
+ ret = SYSVAR_ERASE_ERR;
goto recovery_err;
}
/* check crc32 and wc32 (write count) */
- if (check_var(buf, SYSVAR_SAVE_MODE))
+ if (check_var(buf, SYSVAR_SAVE_MODE)) {
+ ret = SYSVAR_CRC_ERR;
goto recovery_err;
+ }
/* write system variables(RW) to SPI flash */
ret = write_buff(flash_info, buf->data, sysvar_offset[j] + CFG_FLASH_BASE,
buf->data_len);
- printf("\n");
if (ret) {
- print_err("write", j);
+ ret = SYSVAR_WRITE_ERR;
goto recovery_err;
}
buf->loaded = true;
- print_msg("Data recovery was completed", SYSVAR_MESSAGE);
- return 0;
+ return SYSVAR_SUCCESS;
}
}
recovery_err:
clear_buf(buf);
- printf("\n");
- return 0;
+ return ret;
}
/*
@@ -137,9 +178,10 @@
}
load_err:
- if (buf->failed[0] || buf->failed[1])
- return data_recovery(buf, idx);
- return 0;
+ if (buf->failed[0] || buf->failed[1]) {
+ return SYSVAR_LOAD_ERR;
+ }
+ return SYSVAR_SUCCESS;
}
/*
@@ -151,317 +193,28 @@
/* save the system variables */
for (j = 0; j < 2; j++) {
i = idx[j];
- printf("SV: Erasing SPI flash 0x%08lx - 0x%08lx\n",
- sysvar_offset[i], sysvar_offset[i] + buf->data_len);
sector = __SYSVAR_ERASE_SECTOR(sysvar_offset[i]);
ret = flash_erase(flash_info, sector, sector);
if (ret) {
- print_err("erase", i);
- return 1;
+ return SYSVAR_SAVE_ERR;
}
/* check crc32 and wc32 (write count) */
if (check_var(buf, SYSVAR_SAVE_MODE)) {
- print_err("save", SYSVAR_RO_BUF);
- return 1;
+ return SYSVAR_CRC_ERR;
}
/* write system variables to SPI flash */
- printf("SV: Writing to SPI flash");
ret = write_buff(flash_info, buf->data, sysvar_offset[i] + CFG_FLASH_BASE,
buf->data_len);
- printf("\n");
if (ret) {
- print_err("write", i);
- return 1;
+ return SYSVAR_WRITE_ERR;
}
}
- return 0;
+ return SYSVAR_SUCCESS;
}
/*
- * sf_loadvar - load the data from SPI flash to data buffer
- */
-int sf_loadvar(void) {
- if (data_load(&rw_buf, SYSVAR_RW_BUF)) {
- return 1;
- }
-
- /* move the data from data buffer to data list */
- if (load_var(&rw_buf)) {
- return 1;
- }
- rw_buf.loaded = true;
- print_msg("loaded", SYSVAR_RW_BUF);
-
- if (data_load(&ro_buf, SYSVAR_RO_BUF))
- return 1;
-
- /* move the data from data buffer to data list */
- if (load_var(&ro_buf))
- return 1;
-
- ro_buf.loaded = true;
- print_msg("loaded", SYSVAR_RO_BUF);
- return 0;
-}
-
-/*
- * sf_savevar - save the data from data buffer to SPI flash
- */
-int sf_savevar(struct sysvar_buf *buf, int idx) {
- int save_idx[2];
-
- /* move the data from data list to data buffer */
- if (save_var(buf))
- return 1;
-
- /* erase failed partition first
- * part0 part1 erase
- * ----- ----- -----
- * ok ok 0, 1
- * failed ok 0, 1
- * ok failed 1, 0
- * failed failed 0, 1
- */
- if (buf->failed[1]) {
- save_idx[0] = idx + 1;
- save_idx[1] = idx;
- } else {
- save_idx[0] = idx;
- save_idx[1] = idx + 1;
- }
-
- /* save the data from data buffer to SPI flash */
- if (data_save(buf, save_idx))
- return 1;
-
- printf("\n");
- print_msg("saved", idx);
- return 0;
-}
-
-/*
- * sf_getvar - get or print the system variable from data list
- */
-int sf_getvar(char *name, char *value, int len) {
- struct sysvar_list *var = NULL;
-
- if (name == NULL) {
- /* print all system variables(RO) */
- print_var(&ro_buf);
- /* print all system variables(RW) */
- print_var(&rw_buf);
- return 0;
- }
-
- /* find the system variable(RO) */
- var = find_var(&ro_buf, name);
- if (var != NULL)
- goto get_data;
-
- /* find the system variable(RW) */
- var = find_var(&rw_buf, name);
- if (var != NULL)
- goto get_data;
-
- /* system variable not found */
- printf("## SYSVAR: '%s' not found\n", name);
- return 1;
-
-get_data:
- return get_var(var, name, value, len);
-}
-
-/*
- * sf_setvar - add or delete the system variable in data list
- */
-int sf_setvar(struct sysvar_buf *buf, int idx, char *name, char *value) {
- struct sysvar_list *var = NULL;
- int ret = 0;
-
- if (name != NULL) {
- if (idx < SYSVAR_RO_BUF) {
- /* read only variable? */
- var = find_var(&ro_buf, name);
- } else {
- /* variable existed? */
- var = find_var(&rw_buf, name);
- }
-
- if (var != NULL) {
- if (idx < SYSVAR_RO_BUF) {
- printf("## Error: '%s' is read only variable\n", name);
- return 1;
- } else {
- printf("## Error: '%s' is not read only variable\n", name);
- return 1;
- }
- }
-
- var = find_var(buf, name);
- if (var != NULL) {
- /* delete system variable */
- ret = delete_var(buf, var);
- if (ret != SYSVAR_SUCCESS) {
- printf("## Error: failed to delete '%s'\n", name);
- return 1;
- }
-
- /* add system variable */
- if (value != NULL) {
- ret = set_var(buf, name, value);
- if (ret == 0)
- print_msg("added", idx);
- } else {
- print_msg("deleted", idx);
- }
- } else {
- /* add system variable */
- if (value != NULL) {
- ret = set_var(buf, name, value);
- if (ret == 0)
- print_msg("added", idx);
- } else {
- printf("## Error: '%s' not found\n", name);
- ret = 1;
- }
- }
- } else {
- /* delete all of system variables */
- ret = clear_var(buf);
- if (ret == 0)
- print_msg("deleted", idx);
- }
- return ret;
-}
-
-/*
- * do_flloadvar - load system variables from SPI flash
- *
- * sf_loadvar command:
- * sf_loadvar - load system variables from persistent storage
- */
-int do_flloadvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
- /* load system variables from SPI flash */
- return sf_loadvar();
-}
-
-U_BOOT_CMD(
- loadvar, 1, 0, do_flloadvar,
- "loadvar - load system variables\n",
- " - load system variables from SPI flash\n"
-);
-
-/*
- * do_flsavevar - save system variables(RW) to SPI flash
- *
- * sf_savevar command:
- * sf_savevar - save system variables(RW) to SPI flash
- */
-int do_flsavevar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
- /* save system variables(RW) */
- return sf_savevar(&rw_buf, SYSVAR_RW_BUF);
-}
-
-U_BOOT_CMD(
- savevar, 1, 0, do_flsavevar,
- "savevar - save system variables(RW)\n",
- " - save system variables(RW) to SPI flash\n"
-);
-
-/*
- * do_flprintvar - print system variables
- *
- * printvar command:
- * printvar name - print system variable with name
- * printvar - print all system variables
- */
-int do_flprintvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
- char value[SYSVAR_VALUE];
-
- if (argv[1] == NULL) {
- /* print all system variables */
- sf_getvar(NULL, NULL, 0);
-
- printf("\nSV: System Variables(RO): %d/%d bytes\n",
- ro_buf.used_len, ro_buf.total_len);
- printf("SV: System Variables(RW): %d/%d bytes\n",
- rw_buf.used_len, rw_buf.total_len);
- } else {
- /* get a system variable */
- if (sf_getvar(argv[1], value, SYSVAR_VALUE) == 0) {
- puts(argv[1]);
- putc('=');
- /* puts value in case CONFIG_SYS_PBSIZE < SYSVAR_VALUE */
- puts(value);
- putc('\n');
- printf("\nSV: System Variable: %d bytes\n",
- (int)(SYSVAR_NAME + 2 + strlen(value)));
- }
- }
- return 0;
-}
-
-U_BOOT_CMD(
- printvar, 2, 0, do_flprintvar,
- "printvar - print system variables\n",
- " - print values of all system variables\n"
- "printvar name ...\n"
- " - print value of system variable 'name'\n"
-);
-
-int set_sysvar_uboot(const char *var, const char *name) {
- const char *uboot_name = get_uboot_name(var);
- if (uboot_name) {
- setenv(uboot_name, name);
- }
-}
-
-/*
- * do_flsetvar - add or delete system variables(RW)
- *
- * sf_setvar command:
- * sf_setvar name value - add system variable with name:value
- * sf_setvar name - delete system variable with name
- * sf_setvar - delete all system variables
- */
-int do_flsetvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
- int ret = 0;
-
- if (argc == 3) {
- /* add a system variable(RW) */
- ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, argv[1], argv[2]);
- if (ret == SYSVAR_SUCCESS) {
- set_sysvar_uboot(argv[1], argv[2]);
- }
- } else if (argc == 2) {
- /* delete a system variable(RW) */
- ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, argv[1], NULL);
- if (ret == SYSVAR_SUCCESS) {
- set_sysvar_uboot(argv[1], NULL);
- }
- } else {
- /* delete all system variables(RW) */
- ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, NULL, NULL);
- delete_uboot_vars();
- }
- return ret;
-}
-
-U_BOOT_CMD(
- setvar, 3, 0, do_flsetvar,
- "setvar - set system variables(RW)\n",
- "setvar name value ...\n"
- " - set system variable(RW) 'name' to 'value ...'\n"
- "setvar name\n"
- " - delete system variable(RW) 'name'\n"
- "setvar\n"
- " - delete all system variables(RW)\n"
-);
-
-/*
* sysvar_dump - dump the data buffer in binary/ascii format
*/
void sysvar_dump(struct sysvar_buf *buf, int idx, bool load) {
@@ -508,23 +261,16 @@
*/
int sysvar_io(int argc, char *argv[]) {
struct sysvar_buf *buf;
- int i, idx, sector, ret = 0;
+ int i, idx, sector, ret = 0, str_to_int_err = 0;
- if (strcmp(argv[1], "0") == 0) {
- idx = 0;
+ idx = str_to_int(argv[1], &str_to_int_err);
+ if (str_to_int_err || idx < 0 || idx > 3) {
+ return SYSVAR_INDEX_ERR;
+ }
+ if (idx < 2) {
buf = &rw_buf;
- } else if (strcmp(argv[1], "1") == 0) {
- idx = 1;
- buf = &rw_buf;
- } else if (strcmp(argv[1], "2") == 0) {
- idx = 2;
- buf = &ro_buf;
- } else if (strcmp(argv[1], "3") == 0) {
- idx = 3;
- buf = &ro_buf;
} else {
- print_err("invalid SPI flash device", SYSVAR_MESSAGE);
- return 1;
+ buf = &ro_buf;
}
if (strcmp(argv[0], "write") == 0) {
@@ -535,11 +281,16 @@
/* write the data buffer to spi_flash */
ret = write_buff(flash_info, buf->data, sysvar_offset[idx] + CFG_FLASH_BASE,
buf->data_len);
- printf("\n");
+ if (ret) {
+ ret = SYSVAR_WRITE_ERR;
+ }
} else if (strcmp(argv[0], "erase") == 0) {
/* erase spi_flash */
sector = __SYSVAR_ERASE_SECTOR(sysvar_offset[idx]);
ret = flash_erase(flash_info, sector, sector);
+ if (ret) {
+ ret = SYSVAR_ERASE_ERR;
+ }
}
if (ret == 0) {
@@ -557,76 +308,9 @@
return ret;
}
-/*
- * do_flsysvar - system variable debug functions
- */
-int do_flsysvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
- if (argc < 2)
- goto usage;
-
- if (strcmp(argv[1], "set") == 0) {
- if (argc == 4) {
- /* add a system variable(RO) */
- return sf_setvar(&ro_buf, SYSVAR_RO_BUF, argv[2], argv[3]);
- } else if (argc == 3) {
- /* delete a system variable(RO) */
- return sf_setvar(&ro_buf, SYSVAR_RO_BUF, argv[2], NULL);
- } else if (argc == 2) {
- /* delete all system variables(RO) */
- return sf_setvar(&ro_buf, SYSVAR_RO_BUF, NULL, NULL);
- } else {
- goto usage;
- }
- }
-
- if (strcmp(argv[1], "save") == 0 && argc == 2) {
- /* save system variables(RO) */
- return sf_savevar(&ro_buf, SYSVAR_RO_BUF);
- }
-
- if (strcmp(argv[1], "dump") == 0 && argc == 3) {
- if (strcmp(argv[2], "rw") == 0) {
- /* dump data in data buffer(RW) */
- sysvar_dump(&rw_buf, SYSVAR_RW_BUF, true);
- } else if (strcmp(argv[2], "ro") == 0) {
- /* dump data in data buffer(RO) */
- sysvar_dump(&ro_buf, SYSVAR_RO_BUF, true);
- } else {
- goto usage;
- }
- return 0;
- }
-
- if ((strcmp(argv[1], "read") == 0 && argc == 3) ||
- (strcmp(argv[1], "write") == 0 && argc == 3) ||
- (strcmp(argv[1], "erase") == 0 && argc == 3))
- return sysvar_io(argc - 1, argv + 1);
-
-usage:
- printf("Usage:\n%s\n", cmdtp->usage);
- return 1;
-}
-
-U_BOOT_CMD(
- sysvar, 4, 0, do_flsysvar,
- "sysvar - system variable debug functions\n",
- "set name value\n"
- " - set system variable(RO) 'name' to 'value ...'\n"
- "sysvar set name\n"
- " - delete system variable(RO) 'name'\n"
- "sysvar set\n"
- " - delete all system variables(RO)\n"
- "sysvar save\n"
- " - save system variables(RO) to SPI flash\n"
- "sysvar dump rw|ro\n"
- " - dump data in data buffer\n"
- "sysvar read 0|1|2|3\n"
- " - read data from SPI flash 0|1|2|3 to data buffer\n"
- "sysvar write 0|1|2|3\n"
- " - write data from data buffer to SPI flash 0|1|2|3\n"
- "sysvar erase 0|1|2|3\n"
- " - erase data on SPI flash 0|1|2|3\n"
-);
+////////////////////////////////////////////////////////////////////////////////
+// Sysvar/Uboot Integration
+////////////////////////////////////////////////////////////////////////////////
/*
* sysvar_buf_init - Initializes a sysvar_buf struct.
@@ -661,7 +345,32 @@
return SYSVAR_SUCCESS;
}
-static void sysvar_env_init(struct sysvar_buf *buf) {
+/*
+ * sysvar_env_clear_shared - Takes sysvar buf and clears anything that may be
+ * mapped to the uboot env. Does not delete any sysvar variables.
+ */
+static void sysvar_env_clear_shared(struct sysvar_buf *buf) {
+ struct sysvar_list *curr = buf->list->next;
+ while (curr != NULL) {
+ /* Only clear env variables for shared vars. */
+ set_sysvar_uboot(curr->name, NULL);
+ curr = curr->next;
+ }
+}
+
+/*
+ * sysvar_uboot_env_clear - Clears all potential uboot shared variables
+ * from the environment.
+ */
+void sysvar_uboot_env_clear(void) {
+ int i;
+ for (i = 0; i < ARRAY_SIZE(su_mappings); ++i) {
+ setenv(su_mappings[i].uboot_name, NULL);
+ }
+}
+
+/* Helper function for sysvar_uboot_env_load. */
+static void _sysvar_uboot_env_load(struct sysvar_buf *buf) {
struct sysvar_list *curr = buf->list->next;
while (curr != NULL) {
/* Should only set env variables for special vars. */
@@ -670,28 +379,50 @@
}
}
+/*
+ * sysvar_uboot_env_load - Loads sysvar/uboot shared variables to the
+ * uboot environment.
+ */
+void sysvar_uboot_env_load(void) {
+ _sysvar_uboot_env_load(&ro_buf);
+ _sysvar_uboot_env_load(&rw_buf);
+}
+
int sysvar_init(void) {
- printf("sysvar_init. . .\n");
+ printf("sysvar_init. . . ");
if (sysvar_buf_init(&rw_buf, false) || sysvar_buf_init(&ro_buf, true) ||
- sf_loadvar()) {
+ sf_loadvar(&rw_buf, SYSVAR_RW_BUF) ||
+ sf_loadvar(&ro_buf, SYSVAR_RO_BUF)) {
printf("init failure!\n");
return SYSVAR_MEMORY_ERR;
}
- sysvar_env_init(&rw_buf);
- sysvar_env_init(&ro_buf);
- printf("init success!\n");
+ sysvar_uboot_env_load();
+ printf("success!\n");
return SYSVAR_SUCCESS;
}
-int is_sysvar_shared(const char *var) {
+/*
+ * get_sysvar_shared - Determines if there's a mapping from sysvar -> uboot or
+ * vice versa.
+ *
+ * If there is a mapping:
+ * If given a sysvar name, returns the uboot env name that the sysvar name
+ * maps to. If given a uboot env name, returns the sysvar name that it maps
+ * to.
+ *
+ * If there is no mapping, returns NULL.
+ */
+const char *get_sysvar_shared(const char *var) {
int i;
for (i = 0; i < ARRAY_SIZE(su_mappings); ++i) {
- if (strcmp(var, su_mappings[i].uboot_name) == 0 ||
- strcmp(var, su_mappings[i].sysvar_name) == 0) {
- return true;
+ if (strcmp(var, su_mappings[i].uboot_name) == 0) {
+ return su_mappings[i].sysvar_name;
+ }
+ if (strcmp(var, su_mappings[i].sysvar_name) == 0) {
+ return su_mappings[i].uboot_name;
}
}
- return false;
+ return NULL;
}
const char *get_uboot_name(const char *sysvar_name) {
@@ -704,10 +435,381 @@
return NULL;
}
-void delete_uboot_vars(void) {
- int i;
- for (i = 0; i < ARRAY_SIZE(su_mappings); ++i) {
- setenv(su_mappings[i].sysvar_name, NULL);
- setenv(su_mappings[i].uboot_name, NULL);
+/*
+ * set_sysvar_uboot - Sets the given variable to the value specified in the
+ * uboot env if sysvar name is shared with uboot.
+ */
+void set_sysvar_uboot(const char *var, const char *value) {
+ char *uboot_name = get_uboot_name(var);
+ if (uboot_name) {
+ printf(">>> mapping SV:'%s' to UB:'%s' . . .\n", var, uboot_name);
+ setenv(uboot_name, value);
}
}
+
+////////////////////////////////////////////////////////////////////////////////
+// Sysvar Flash Impl Functions
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * sf_loadvar - load the data from SPI flash to data buffer
+ */
+int sf_loadvar(struct sysvar_buf *buf, int idx) {
+ if (data_load(buf, idx)) {
+ /* TODO(awdavies): Inform the user of potential data recovery failure. */
+ data_recovery(buf, idx);
+ }
+
+ /* move the data from data buffer to data list */
+ if (load_var(buf)) {
+ return SYSVAR_LOAD_ERR;
+ }
+ buf->loaded = true;
+ return SYSVAR_SUCCESS;
+}
+
+/*
+ * sf_savevar - save the data from data buffer to SPI flash
+ */
+int sf_savevar(struct sysvar_buf *buf, int idx) {
+ int ret;
+ int save_idx[2];
+
+ /* move the data from data list to data buffer */
+ if (save_var(buf))
+ return SYSVAR_SAVE_ERR;
+
+ /* erase failed partition first
+ * part0 part1 erase
+ * ----- ----- -----
+ * ok ok 0, 1
+ * failed ok 0, 1
+ * ok failed 1, 0
+ * failed failed 0, 1
+ */
+ if (buf->failed[1]) {
+ save_idx[0] = idx + 1;
+ save_idx[1] = idx;
+ } else {
+ save_idx[0] = idx;
+ save_idx[1] = idx + 1;
+ }
+
+ /* save the data from data buffer to SPI flash */
+ if ((ret = data_save(buf, save_idx)))
+ return ret;
+ return SYSVAR_SUCCESS;
+}
+
+/*
+ * sf_getvar - get or print the system variable from data list
+ */
+int sf_getvar(char *name, char *value, int len) {
+ struct sysvar_list *var = NULL;
+
+ if (name == NULL) {
+ /* print all system variables(RO) */
+ print_var(&ro_buf);
+ /* print all system variables(RW) */
+ print_var(&rw_buf);
+ return SYSVAR_SUCCESS;
+ }
+
+ /* find the system variable(RO) */
+ var = find_var(&ro_buf, name);
+ if (var != NULL)
+ goto get_data;
+
+ /* find the system variable(RW) */
+ var = find_var(&rw_buf, name);
+ if (var != NULL)
+ goto get_data;
+
+ /* system variable not found */
+ return SYSVAR_GET_ERR;
+
+get_data:
+ return get_var(var, name, value, len);
+}
+
+/*
+ * sf_setvar - add or delete the system variable in data list
+ */
+int sf_setvar(struct sysvar_buf *buf, int idx, char *name, char *value) {
+ struct sysvar_list *var = NULL;
+ int ret = 0;
+
+ if (name != NULL) {
+ if (idx < SYSVAR_RO_BUF) {
+ /* read only variable? */
+ var = find_var(&ro_buf, name);
+ } else {
+ /* variable existed? */
+ var = find_var(&rw_buf, name);
+ }
+
+ if (var != NULL) {
+ if (idx < SYSVAR_RO_BUF) {
+ return SYSVAR_READONLY_ERR;
+ } else {
+ return SYSVAR_EXISTED_ERR;
+ }
+ }
+
+ var = find_var(buf, name);
+ if (var != NULL) {
+ /* delete system variable */
+ ret = delete_var(buf, var);
+ if (ret != SYSVAR_SUCCESS) {
+ return SYSVAR_DELETE_ERR;
+ }
+
+ /* add system variable */
+ if (value != NULL) {
+ ret = set_var(buf, name, value);
+ }
+ } else {
+ /* add system variable */
+ if (value != NULL) {
+ ret = set_var(buf, name, value);
+ } else {
+ ret = SYSVAR_SET_ERR;
+ }
+ }
+ } else {
+ /* delete all of system variables */
+ ret = clear_var(buf);
+ }
+ return ret;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Uboot Commands
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * do_flloadvar - load system variables from SPI flash
+ *
+ * sf_loadvar command:
+ * sf_loadvar - load system variables from persistent storage
+ */
+int do_flloadvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
+ /* load system variables from SPI flash */
+ int res, idx;
+ idx = SYSVAR_RW_BUF;
+ res = sf_loadvar(&rw_buf, idx);
+ print_err(res, &idx);
+ if (res != SYSVAR_SUCCESS) {
+ return res;
+ }
+ idx = SYSVAR_RO_BUF;
+ res = sf_loadvar(&ro_buf, idx);
+ print_err(res, &idx);
+ return res;
+}
+
+U_BOOT_CMD(
+ loadvar, 1, 0, do_flloadvar,
+ "loadvar - load system variables\n",
+ " - load system variables from SPI flash\n"
+);
+
+/*
+ * do_flsavevar - save system variables(RW) to SPI flash
+ */
+int do_flsavevar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ /* save system variables(RW) */
+ printf("SV: Saving. . .\n");
+ int idx = SYSVAR_RW_BUF;
+ int res = sf_savevar(&rw_buf, idx);
+ print_err(res, &idx);
+ return res;
+}
+
+U_BOOT_CMD(
+ savevar, 1, 0, do_flsavevar,
+ "savevar - save system variables(RW)\n",
+ " - save system variables(RW) to SPI flash\n"
+);
+
+/*
+ * do_flprintvar - print system variables
+ *
+ * printvar command:
+ * printvar name - print system variable with name
+ * printvar - print all system variables
+ */
+int do_flprintvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
+ char value[SYSVAR_VALUE];
+
+ if (argv[1] == NULL) {
+ /* print all system variables */
+ sf_getvar(NULL, NULL, 0);
+
+ printf("\nSV: System Variables(RO): %d/%d bytes\n",
+ ro_buf.used_len, ro_buf.total_len);
+ printf("SV: System Variables(RW): %d/%d bytes\n",
+ rw_buf.used_len, rw_buf.total_len);
+ } else {
+ /* get a system variable */
+ if (sf_getvar(argv[1], value, SYSVAR_VALUE) == 0) {
+ puts(argv[1]);
+ putc('=');
+ /* puts value in case CONFIG_SYS_PBSIZE < SYSVAR_VALUE */
+ puts(value);
+ putc('\n');
+ printf("\nSV: System Variable: %d bytes\n",
+ (int)(SYSVAR_NAME + 2 + strlen(value)));
+ } else {
+ printf("## SYSVAR: '%s' not found\n", argv[1]);
+ }
+ }
+ return SYSVAR_SUCCESS;
+}
+
+U_BOOT_CMD(
+ printvar, 2, 0, do_flprintvar,
+ "printvar - print system variables\n",
+ " - print values of all system variables\n"
+ "printvar name ...\n"
+ " - print value of system variable 'name'\n"
+);
+
+/*
+ * do_flsetvar - add or delete system variables(RW)
+ *
+ * setvar command:
+ * setvar name value - add system variable with name:value
+ * setvar name - delete system variable with name
+ * setvar - delete all system variables
+ */
+int do_flsetvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
+ int ret = 0;
+
+ if (argc == 3) {
+ /* add a system variable(RW) */
+ printf("SV: adding %s\n", argv[1]);
+ ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, argv[1], argv[2]);
+ if (ret == SYSVAR_SUCCESS) {
+ set_sysvar_uboot(argv[1], argv[2]);
+ }
+ } else if (argc == 2) {
+ /* delete a system variable(RW) */
+ printf("SV: deleting %s\n", argv[1]);
+ ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, argv[1], NULL);
+ if (ret == SYSVAR_SUCCESS) {
+ set_sysvar_uboot(argv[1], NULL);
+ }
+ } else {
+ /* delete all system variables(RW) */
+ printf("SV: deleting all RW vars. . .\n");
+ sysvar_env_clear_shared(&rw_buf);
+ ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, NULL, NULL);
+ }
+ print_err(ret, argc > 1 ? argv[1] : NULL);
+ return ret;
+}
+
+U_BOOT_CMD(
+ setvar, 3, 0, do_flsetvar,
+ "setvar - set system variables(RW)\n",
+ "setvar name value ...\n"
+ " - set system variable(RW) 'name' to 'value ...'\n"
+ "setvar name\n"
+ " - delete system variable(RW) 'name'\n"
+ "setvar\n"
+ " - delete all system variables(RW)\n"
+);
+
+/*
+ * do_flsysvar - system variable debug functions
+ */
+int do_flsysvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
+ int ret = 0;
+ int idx;
+ void *err_arg = NULL;
+ if (argc < 2)
+ goto usage;
+
+ if (strcmp(argv[1], "set") == 0) {
+ if (argc == 4) {
+ /* add a system variable(RO) */
+ printf("SV: adding %s\n", argv[2]);
+ ret = sf_setvar(&ro_buf, SYSVAR_RO_BUF, argv[2], argv[3]);
+ } else if (argc == 3) {
+ /* delete a system variable(RO) */
+ printf("SV: deleting %s\n", argv[2]);
+ ret = sf_setvar(&ro_buf, SYSVAR_RO_BUF, argv[2], NULL);
+ } else if (argc == 2) {
+ /* delete all system variables(RO) */
+ printf("SV: deleting all RO vars. . .\n");
+ sysvar_env_clear_shared(&ro_buf);
+ ret = sf_setvar(&ro_buf, SYSVAR_RO_BUF, NULL, NULL);
+ } else {
+ goto usage;
+ }
+ if (argc > 2) {
+ err_arg = argv[2];
+ }
+ goto err_handle;
+ }
+
+ if (strcmp(argv[1], "save") == 0 && argc == 2) {
+ /* save system variables(RO) */
+ printf("SV: saving RO vars. . .\n");
+ idx = SYSVAR_RO_BUF;
+ ret = sf_savevar(&ro_buf, idx);
+ err_arg = &idx;
+ goto err_handle;
+ }
+
+ if (strcmp(argv[1], "dump") == 0 && argc == 3) {
+ if (strcmp(argv[2], "rw") == 0) {
+ /* dump data in data buffer(RW) */
+ sysvar_dump(&rw_buf, SYSVAR_RW_BUF, true);
+ } else if (strcmp(argv[2], "ro") == 0) {
+ /* dump data in data buffer(RO) */
+ sysvar_dump(&ro_buf, SYSVAR_RO_BUF, true);
+ } else {
+ goto usage;
+ }
+ return SYSVAR_SUCCESS;
+ }
+
+ if ((strcmp(argv[1], "read") == 0 && argc == 3) ||
+ (strcmp(argv[1], "write") == 0 && argc == 3) ||
+ (strcmp(argv[1], "erase") == 0 && argc == 3)) {
+ ret = sysvar_io(argc - 1, argv + 1);
+ idx = str_to_int(argv[2], NULL);
+ err_arg = &idx;
+ }
+
+err_handle:
+ print_err(ret, err_arg);
+ return ret;
+usage:
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+U_BOOT_CMD(
+ sysvar, 4, 0, do_flsysvar,
+ "sysvar - system variable debug functions\n",
+ "set name value\n"
+ " - set system variable(RO) 'name' to 'value ...'\n"
+ "sysvar set name\n"
+ " - delete system variable(RO) 'name'\n"
+ "sysvar set\n"
+ " - delete all system variables(RO)\n"
+ "sysvar save\n"
+ " - save system variables(RO) to SPI flash\n"
+ "sysvar dump rw|ro\n"
+ " - dump data in data buffer\n"
+ "sysvar read 0|1|2|3\n"
+ " - read data from SPI flash 0|1|2|3 to data buffer\n"
+ "sysvar write 0|1|2|3\n"
+ " - write data from data buffer to SPI flash 0|1|2|3\n"
+ "sysvar erase 0|1|2|3\n"
+ " - erase data on SPI flash 0|1|2|3\n"
+);
diff --git a/common/env_dataflash.c b/common/env_dataflash.c
index 0b77d99..aa4f4fa 100755
--- a/common/env_dataflash.c
+++ b/common/env_dataflash.c
@@ -58,9 +58,11 @@
/* env must be copied to do not alter env structure in memory*/
unsigned char temp[CFG_ENV_SIZE];
int i;
- /* Delete special sysvar-only variables. */
- delete_uboot_vars();
+ /* Deletes anything that can be shared with sysvar, then restores it. */
+ sysvar_uboot_env_clear();
memcpy(temp, env_ptr, CFG_ENV_SIZE);
+ env_restore_defaults();
+ sysvar_uboot_env_load();
return write_dataflash (CFG_ENV_ADDR, (unsigned long)temp, CFG_ENV_SIZE);
}
diff --git a/common/hush.c b/common/hush.c
index feb5627..c8549ff 100755
--- a/common/hush.c
+++ b/common/hush.c
@@ -3194,7 +3194,11 @@
code = 0;
/* XXX hackish way to not allow exit from main loop */
if (inp->peek == file_peek) {
- printf("exit not allowed from main input shell.\n");
+ /*
+ * TODO(awdavies) Commented out due to negative sysvar ret
+ * codes.
+ */
+ /* printf("exit not allowed from main input shell.\n"); */
continue;
}
break;
diff --git a/include/common.h b/include/common.h
index 2d7aa6c..9865222 100755
--- a/include/common.h
+++ b/include/common.h
@@ -219,9 +219,10 @@
#define MAC_ADDR1_SV "MAC_ADDR1"
#define MAC_ADDR1_UB "ethaddr"
int sysvar_init(void);
-int is_sysvar_shared(const char *var);
+const char *get_sysvar_shared(const char *var);
const char *get_uboot_name(const char *sysvar_name);
-void delete_uboot_vars(void);
+void sysvar_uboot_env_clear(void);
+void sysvar_uboot_env_load(void);
/* common/env_common.c */
int env_restore_defaults(void);
diff --git a/include/sysvar.h b/include/sysvar.h
index 855a101..301ea55 100644
--- a/include/sysvar.h
+++ b/include/sysvar.h
@@ -68,6 +68,7 @@
#define SYSVAR_READONLY_ERR -13
#define SYSVAR_EXISTED_ERR -14
#define SYSVAR_DEBUG_ERR -15
+#define SYSVAR_INDEX_ERR -16
#define PAGE_SIZE 256
#define SYSVAR_VALUE 2048