Adds sysvar to u-boot for WindCharger.

This is a baseline addition of sysvar.  This does not yet do anything
fancy like allow for adding sysvar variables into the uboot environment.

Specifically this patch adds:
-- A sysvar init function to main.c (to keep cmd_sysvar.c from having to
check for sysvar initialization during every function call).

-- A copy of the main sysvar API from vendor/google/platform/sysvar
(more specifically commit a18b4cb).  The only changes are to the
locations of the sysvar offsets.

-- An implementation of cmd_sysvar.c for use in u-boot command line.
This was modeled after cmd_sysvar.c in uboot/prism commit 3709c13.

Change-Id: I0c3422db7b72c4bd3971da72c0f4a7a121d514d7
diff --git a/common/Makefile b/common/Makefile
index b5cce85..df50354 100755
--- a/common/Makefile
+++ b/common/Makefile
@@ -33,6 +33,7 @@
 COBJS	= main.o circbuf.o \
 	  cmd_boot.o cmd_bootm.o \
 	  cmd_cache.o cmd_console.o \
+	  cmd_sysvar.o \
 	  cmd_date.o cmd_dcr.o cmd_display.o cmd_doc.o \
 	  cmd_eeprom.o \
 	  cmd_flash.o \
@@ -47,11 +48,12 @@
 	  exports.o \
 	  hush.o lcd.o lists.o \
 	  memsize.o miiphybb.o miiphyutil.o \
-	  serial.o crc16.o
+	  serial.o crc16.o sysvar.o
 else
 COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o \
 	  cmd_ace.o cmd_autoscript.o \
 	  cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \
+	  cmd_sysvar.o \
 	  cmd_cache.o cmd_console.o \
 	  cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \
 	  cmd_eeprom.o cmd_elf.o cmd_ext2.o \
@@ -73,7 +75,7 @@
 	  memsize.o miiphybb.o miiphyutil.o \
 	  s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
 	  usb.o usb_kbd.o usb_storage.o \
-	  virtex2.o xilinx.o crc16.o xyzModem.o
+	  virtex2.o xilinx.o crc16.o xyzModem.o sysvar.o
 endif
 
 ifndef BOOT_FROM_NAND
diff --git a/common/cmd_sysvar.c b/common/cmd_sysvar.c
index ea0a477..3eb1f2f 100644
--- a/common/cmd_sysvar.c
+++ b/common/cmd_sysvar.c
@@ -1,38 +1,33 @@
-/* Copyright 2012 Google Inc. All Rights Reserved.
- * Author: weixiaofeng@google.com (Xiaofeng Wei)
+/* Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Note: flash_erase usage in here sends start and end as the same address.
+ * This is because the size of each sysvar env is a single erase-block (64k).
+ * The flash_erase function includes the addresses under the "last" param as
+ * part of the erase section, meaning inclusion of 0x8 as an address will erase
+ * 0x8 up to 0x9 (64k).  0x9 cannot be included as the end address because it is
+ * not in a sector boundary.
  */
+#include <sysvar.h>
 
-#include <common.h>
-#include <spi_flash.h>
 #include <asm/io.h>
+#include <common.h>
+#include <config.h>
+#include <command.h>
+#include <flash.h>
 
-#include "sysvar.h"
+// Some bit twiddling for erasing the correct sector on Atheros flash.  This
+// only erases multiples of 64kb.
+#define __SYSVAR_ERASE_SECTOR(x) (((x) >> 16) & 0xff)
 
-#define PAGE_SIZE           256
-#define SYSVAR_VALUE        256
-
-#define SYSVAR_RO_MEM       0x00000100
-#define SYSVAR_RW_MEM       SYSVAR_RO_MEM + SYSVAR_BLOCK_SIZE
-
-struct spi_flash *sf_dev = NULL;
+// Board-based implementation supplies pointer to flash info.
+extern flash_info_t flash_info[];
 struct sysvar_buf ro_buf;
 struct sysvar_buf rw_buf;
-static const long sysvar_offset[SYSVAR_SPI_BLOCK] = {
+
+const long sysvar_offset[SYSVAR_SPI_BLOCK] = {
   SYSVAR_RW_OFFSET0, SYSVAR_RW_OFFSET1, SYSVAR_RO_OFFSET0, SYSVAR_RO_OFFSET1
 };
 
-static int data_recovery(struct sysvar_buf *buf, int idx);
-static int data_load(struct sysvar_buf *buf, int idx);
-static int data_save(struct sysvar_buf *buf, int *idx);
-
-static int open_sf(bool load);
-static void close_sf(void);
-
-static int loadvar(void);
-static int savevar(struct sysvar_buf *buf, int idx);
-static int getvar(char *name, char *value, int len);
-static int setvar(struct sysvar_buf *buf, int idx, char *name, char *value);
-
 /*
  * print_msg - print the message string
  */
@@ -60,29 +55,21 @@
 /*
  * data_recovery - system variables recovering routine
  */
-static int data_recovery(struct sysvar_buf *buf, int idx) {
-  int i, j, ret;
+int data_recovery(struct sysvar_buf *buf, int idx) {
+  int i, j, ret, 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 (spi_flash_read(sf_dev, sysvar_offset[i], buf->data_len, buf->data))
+    if (read_buff(flash_info, buf->data, sysvar_offset[i], buf->data_len))
       continue;
 
     /* check crc32 and wc32 (write count) */
     if (check_var(buf, SYSVAR_LOAD_MODE) == SYSVAR_SUCCESS) {
-#ifdef CONFIG_SPI_FLASH_PROTECTION
-      printf("SV: Unprotecting flash\n");
-      ret = spi_flash_protect(sf_dev, 0);
-      if (ret) {
-        printf("## Error: failed to unprotect flash\n");
-        goto recovery_err;
-      }
-#endif
-
       /* erase SPI flash */
-      ret = spi_flash_erase(sf_dev, sysvar_offset[j], buf->data_len);
+      sector = __SYSVAR_ERASE_SECTOR(sysvar_offset[j]);
+      ret = flash_erase(flash_info, sector, sector);
       if (ret) {
         print_err("erase", j);
         goto recovery_err;
@@ -93,21 +80,14 @@
         goto recovery_err;
 
       /* write system variables(RW) to SPI flash */
-      ret = spi_flash_write(sf_dev, sysvar_offset[j],
-                            buf->data_len, buf->data);
+      ret = write_buff(flash_info, buf->data, sysvar_offset[j] + CFG_FLASH_BASE,
+                       buf->data_len);
       printf("\n");
       if (ret) {
         print_err("write", j);
         goto recovery_err;
       }
 
-#ifdef CONFIG_SPI_FLASH_PROTECTION
-     printf("SV: Protecting flash\n");
-     ret = spi_flash_protect(sf_dev, 1);
-     if (ret)
-       printf("## Error: failed to protect flash\n");
-#endif
-
       buf->loaded = true;
       print_msg("Data recovery was completed", SYSVAR_MESSAGE);
       return 0;
@@ -116,16 +96,14 @@
 
 recovery_err:
   clear_buf(buf);
-
   printf("\n");
-  print_err("recovery", idx);
   return 0;
 }
 
 /*
  * data_load - load the data from SPI flash to data buffer
  */
-static int data_load(struct sysvar_buf *buf, int idx) {
+int data_load(struct sysvar_buf *buf, int idx) {
   int i, j;
 
   /* load the system variables */
@@ -133,8 +111,9 @@
     buf->failed[j] = false;
 
     /* read the data from SPI flash */
-    if (spi_flash_read(sf_dev, sysvar_offset[i], buf->data_len, buf->data))
+    if (read_buff(flash_info, buf->data, sysvar_offset[i], buf->data_len)) {
       buf->failed[j] = true;
+    }
 
     /* check crc32 and wc32 (write count) */
     if (check_var(buf, SYSVAR_LOAD_MODE))
@@ -150,24 +129,16 @@
 /*
  * data_save - save the data from data buffer to SPI flash
  */
-static int data_save(struct sysvar_buf *buf, int *idx) {
-  int i, j, ret;
-
-#ifdef CONFIG_SPI_FLASH_PROTECTION
-  printf("SV: Unprotecting flash\n");
-  ret = spi_flash_protect(sf_dev, 0);
-  if (ret) {
-    printf("## Error: failed to unprotect flash\n");
-    return 1;
-  }
-#endif
+int data_save(struct sysvar_buf *buf, int *idx) {
+  int i, j, ret, sector;
 
   /* 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);
-    ret = spi_flash_erase(sf_dev, 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;
@@ -181,129 +152,29 @@
 
     /* write system variables to SPI flash */
     printf("SV: Writing to SPI flash");
-    ret = spi_flash_write(sf_dev, sysvar_offset[i], buf->data_len, buf->data);
+    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;
     }
   }
-
-#ifdef CONFIG_SPI_FLASH_PROTECTION
-  printf("SV: Protecting flash\n");
-  ret = spi_flash_protect(sf_dev, 1);
-  if (ret) {
-    printf("## Error: failed to protect flash\n");
-    return 1;
-  }
-#endif
-
   return 0;
 }
 
 /*
- * open_sf - open SPI flash and read the data to buffer
+ * sf_loadvar - load the data from SPI flash to data buffer
  */
-static int open_sf(bool load) {
-  /* check SPI flash */
-  if (sf_dev != NULL)
-    return 0;
-
-  memset(&rw_buf, 0, sizeof(rw_buf));
-  memset(&ro_buf, 0, sizeof(ro_buf));
-
-  /* probe SPI flash */
-  sf_dev = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
-                           CONFIG_ENV_SPI_MAX_HZ, SPI_MODE_3);
-  if (sf_dev == NULL) {
-    print_err("failed to initialize SPI flash", SYSVAR_MESSAGE);
+int sf_loadvar(void) {
+  if (data_load(&rw_buf, SYSVAR_RW_BUF)) {
     return 1;
   }
 
-  /* allocate data buffers */
-  rw_buf.data = (uchar *)map_physmem(SYSVAR_RW_MEM,
-                                     SYSVAR_BLOCK_SIZE, MAP_WRBACK);
-  ro_buf.data = (uchar *)map_physmem(SYSVAR_RO_MEM,
-                                     SYSVAR_BLOCK_SIZE, MAP_WRBACK);
-  if (!rw_buf.data || !ro_buf.data) {
-    print_err("failed to map physical memory", SYSVAR_MESSAGE);
-    goto open_err;
-  }
-
-  /* allocate data lists */
-  rw_buf.list = (struct sysvar_list *)malloc(sizeof(struct sysvar_list));
-  ro_buf.list = (struct sysvar_list *)malloc(sizeof(struct sysvar_list));
-  if (!rw_buf.list || !ro_buf.list) {
-    print_err("failed to allocate data list", SYSVAR_MESSAGE);
-    goto open_err;
-  }
-
-  rw_buf.data_len = SYSVAR_BLOCK_SIZE;
-  rw_buf.total_len = SYSVAR_BLOCK_SIZE - SYSVAR_HEAD;
-  rw_buf.free_len = rw_buf.total_len;
-  rw_buf.readonly = false;
-
-  strncpy(rw_buf.list->name, "rw", SYSVAR_NAME);
-  rw_buf.list->value = NULL;
-  rw_buf.list->len = SYSVAR_NAME + 2;
-  rw_buf.list->next = NULL;
-
-  ro_buf.data_len = SYSVAR_BLOCK_SIZE;
-  ro_buf.total_len = SYSVAR_BLOCK_SIZE - SYSVAR_HEAD;
-  ro_buf.free_len = ro_buf.total_len;
-  ro_buf.readonly = true;
-
-  strncpy(rw_buf.list->name, "ro", SYSVAR_NAME);
-  ro_buf.list->value = NULL;
-  ro_buf.list->len = SYSVAR_NAME + 2;
-  ro_buf.list->next = NULL;
-
-  /* load data from SPI flash to data buffer */
-  if (load) {
-    if (loadvar())
-      goto open_err;
-  }
-  return 0;
-
-open_err:
-  close_sf();
-  return 1;
-}
-
-/*
- * close_sf - close SPI flash and release the data buffer
- */
-static void close_sf(void) {
-  /* release data lists */
-  if (rw_buf.list != NULL) {
-    clear_var(&rw_buf);
-    free(rw_buf.list);
-  }
-  if (ro_buf.list != NULL) {
-    clear_var(&ro_buf);
-    free(ro_buf.list);
-  }
-
-  /* release data buffers */
-  if (rw_buf.data != NULL)
-    unmap_physmem(rw_buf.data, rw_buf.data_len);
-  if (ro_buf.data != NULL)
-    unmap_physmem(ro_buf.data, ro_buf.data_len);
-
-  sf_dev = NULL;
-}
-
-/*
- * loadvar - load the data from SPI flash to data buffer
- */
-static int 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))
+  if (load_var(&rw_buf)) {
     return 1;
-
+  }
   rw_buf.loaded = true;
   print_msg("loaded", SYSVAR_RW_BUF);
 
@@ -320,14 +191,11 @@
 }
 
 /*
- * savevar - save the data from data buffer to SPI flash
+ * sf_savevar - save the data from data buffer to SPI flash
  */
-static int savevar(struct sysvar_buf *buf, int idx) {
+int sf_savevar(struct sysvar_buf *buf, int idx) {
   int save_idx[2];
 
-  if (open_sf(true))
-    return 1;
-
   /* move the data from data list to data buffer */
   if (save_var(buf))
     return 1;
@@ -358,14 +226,11 @@
 }
 
 /*
- * getvar - get or print the system variable from data list
+ * sf_getvar - get or print the system variable from data list
  */
-static int getvar(char *name, char *value, int len) {
+int sf_getvar(char *name, char *value, int len) {
   struct sysvar_list *var = NULL;
 
-  if (open_sf(true))
-    return 1;
-
   if (name == NULL) {
     /* print all system variables(RO) */
     print_var(&ro_buf);
@@ -385,7 +250,7 @@
     goto get_data;
 
   /* system variable not found */
-  printf("## Error: '%s' not found\n", name);
+  printf("## SYSVAR: '%s' not found\n", name);
   return 1;
 
 get_data:
@@ -393,15 +258,12 @@
 }
 
 /*
- * setvar - add or delete the system variable in data list
+ * sf_setvar - add or delete the system variable in data list
  */
-static int setvar(struct sysvar_buf *buf, int idx, char *name, char *value) {
+int sf_setvar(struct sysvar_buf *buf, int idx, char *name, char *value) {
   struct sysvar_list *var = NULL;
   int ret = 0;
 
-  if (open_sf(true))
-    return 1;
-
   if (name != NULL) {
     if (idx < SYSVAR_RO_BUF) {
       /* read only variable? */
@@ -459,59 +321,53 @@
 }
 
 /*
- * do_loadvar - load system variables from SPI flash
+ * do_flloadvar - load system variables from SPI flash
  *
- * loadvar command:
- *    loadvar - load system variables from persistent storage
+ * sf_loadvar command:
+ *    sf_loadvar - load system variables from persistent storage
  */
-static int do_loadvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
-  if (open_sf(false))
-    return 1;
-
+int do_flloadvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
   /* load system variables from SPI flash */
-  return loadvar();
+  return sf_loadvar();
 }
 
 U_BOOT_CMD(
-  loadvar, 1, 0, do_loadvar,
-  "load system variables",
-  "\n    - load system variables from SPI flash\n"
+  loadvar, 1, 0, do_flloadvar,
+  "loadvar   - load system variables\n",
+  "    - load system variables from SPI flash\n"
 );
 
 /*
- * do_savevar - save system variables(RW) to SPI flash
+ * do_flsavevar - save system variables(RW) to SPI flash
  *
- * savevar command:
- *    savevar - save system variables(RW) to SPI flash
+ * sf_savevar command:
+ *    sf_savevar - save system variables(RW) to SPI flash
  */
-static int do_savevar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+int do_flsavevar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
   /* save system variables(RW) */
-  return savevar(&rw_buf, SYSVAR_RW_BUF);
+  return sf_savevar(&rw_buf, SYSVAR_RW_BUF);
 }
 
 U_BOOT_CMD(
-  savevar, 1, 0, do_savevar,
-  "save system variables(RW)",
-  "\n    - save system variables(RW) to SPI flash\n"
+  savevar, 1, 0, do_flsavevar,
+  "savevar   - save system variables(RW)\n",
+  "    - save system variables(RW) to SPI flash\n"
 );
 
 /*
- * do_printvar - print system variables
+ * do_flprintvar - print system variables
  *
  * printvar command:
  *    printvar name - print system variable with name
  *    printvar      - print all system variables
  */
-static int do_printvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
+int do_flprintvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
   char value[SYSVAR_VALUE];
 
-  if (open_sf(true))
-    return 1;
-
   if (argv[1] == NULL) {
     /* print all system variables */
-    getvar(NULL, NULL, 0);
+    sf_getvar(NULL, NULL, 0);
 
     printf("\nSV: System Variables(RO): %d/%d bytes\n",
       ro_buf.used_len, ro_buf.total_len);
@@ -519,8 +375,11 @@
       rw_buf.used_len, rw_buf.total_len);
   } else {
     /* get a system variable */
-    if (getvar(argv[1], value, SYSVAR_VALUE) == 0) {
-      printf("%s=%s\n", argv[1], value);
+    if (sf_getvar(argv[1], value, SYSVAR_VALUE) == 0) {
+      printf("%s=", argv[1]);
+      /* 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)));
     }
@@ -529,41 +388,41 @@
 }
 
 U_BOOT_CMD(
-  printvar, 2, 0, do_printvar,
-  "print system variables",
-  "\n    - print values of all system variables\n"
+  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_setvar - add or delete system variables(RW)
+ * 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
+ * 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
  */
-static int do_setvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
+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 = setvar(&rw_buf, SYSVAR_RW_BUF, argv[1], argv[2]);
+    ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, argv[1], argv[2]);
   } else if (argc == 2) {
     /* delete a system variable(RW) */
-    ret = setvar(&rw_buf, SYSVAR_RW_BUF, argv[1], NULL);
+    ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, argv[1], NULL);
   } else {
     /* delete all system variables(RW) */
-    ret = setvar(&rw_buf, SYSVAR_RW_BUF, NULL, NULL);
+    ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, NULL, NULL);
   }
   return ret;
 }
 
 U_BOOT_CMD(
-  setvar, 3, 0, do_setvar,
-  "set system variables(RW)",
-  "name value ...\n"
+  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"
@@ -574,13 +433,10 @@
 /*
  * sysvar_dump - dump the data buffer in binary/ascii format
  */
-static void sysvar_dump(struct sysvar_buf *buf, int idx, bool load) {
+void sysvar_dump(struct sysvar_buf *buf, int idx, bool load) {
   extern char console_buffer[];
   int start = 0;
 
-  if (open_sf(load))
-    return 1;
-
   printf("System Variables(%s):\n", (idx < SYSVAR_RO_BUF) ? "RW" : "RO");
   printf("offset : 0x%08lx\n", sysvar_offset[idx]);
   printf("size   : %d bytes\n", buf->data_len);
@@ -619,12 +475,9 @@
 /*
  * sysvar_io - SPI flash IO operations
  */
-static int sysvar_io(int argc, char *argv[]) {
+int sysvar_io(int argc, char *argv[]) {
   struct sysvar_buf *buf;
-  int i, idx, ret = 0;
-
-  if (open_sf(false))
-    return 1;
+  int i, idx, sector, ret = 0;
 
   if (strcmp(argv[1], "0") == 0) {
     idx = 0;
@@ -649,17 +502,17 @@
       buf->data[i] = i;
 
     /* write the data buffer to spi_flash */
-    ret = spi_flash_write(sf_dev, sysvar_offset[idx],
-                          buf->data_len, buf->data);
+    ret = write_buff(flash_info, buf->data, sysvar_offset[idx] + CFG_FLASH_BASE,
+                     buf->data_len);
     printf("\n");
   } else if (strcmp(argv[0], "erase") == 0) {
     /* erase spi_flash */
-    ret = spi_flash_erase(sf_dev, sysvar_offset[idx], buf->data_len);
+    sector = __SYSVAR_ERASE_SECTOR(sysvar_offset[idx]);
+    ret = flash_erase(flash_info, sector, sector);
   }
 
   if (ret == 0) {
-    ret = spi_flash_read(sf_dev, sysvar_offset[idx],
-                         buf->data_len, buf->data);
+    ret = read_buff(flash_info, buf->data, sysvar_offset[idx], buf->data_len);
     if (ret == 0)
       sysvar_dump(buf, idx, false);
   }
@@ -674,22 +527,22 @@
 }
 
 /*
- * do_sysvar - system variable debug functions
+ * do_flsysvar - system variable debug functions
  */
-static int do_sysvar(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
+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 setvar(&ro_buf, SYSVAR_RO_BUF, argv[2], argv[3]);
+      return sf_setvar(&ro_buf, SYSVAR_RO_BUF, argv[2], argv[3]);
     } else if (argc == 3) {
       /* delete a system variable(RO) */
-      return setvar(&ro_buf, SYSVAR_RO_BUF, argv[2], NULL);
+      return sf_setvar(&ro_buf, SYSVAR_RO_BUF, argv[2], NULL);
     } else if (argc == 2) {
       /* delete all system variables(RO) */
-      return setvar(&ro_buf, SYSVAR_RO_BUF, NULL, NULL);
+      return sf_setvar(&ro_buf, SYSVAR_RO_BUF, NULL, NULL);
     } else {
       goto usage;
     }
@@ -697,7 +550,7 @@
 
   if (strcmp(argv[1], "save") == 0 && argc == 2) {
     /* save system variables(RO) */
-    return savevar(&ro_buf, SYSVAR_RO_BUF);
+    return sf_savevar(&ro_buf, SYSVAR_RO_BUF);
   }
 
   if (strcmp(argv[1], "dump") == 0 && argc == 3) {
@@ -719,13 +572,13 @@
     return sysvar_io(argc - 1, argv + 1);
 
 usage:
-  cmd_usage(cmdtp);
+  printf("Usage:\n%s\n", cmdtp->usage);
   return 1;
 }
 
 U_BOOT_CMD(
-  sysvar, 4, 0, do_sysvar,
-  "system variable debug functions",
+  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"
@@ -744,3 +597,45 @@
   "    - erase data on SPI flash 0|1|2|3\n"
 );
 
+/*
+ * sysvar_buf_init - Initializes a sysvar_buf struct.
+ */
+static bool sysvar_buf_init(struct sysvar_buf *buf, bool is_ro) {
+  if (buf == NULL) {
+    return false;
+  }
+  memset(buf, 0, sizeof(*buf));
+  buf->list = (struct sysvar_list *)malloc(sizeof(struct sysvar_list));
+  if (buf->list == NULL) {
+    printf("list allocation ");
+    return false;
+  }
+  buf->data = (uchar *) map_physmem(is_ro ? SYSVAR_RO_MEM : SYSVAR_RW_MEM);
+  if (buf->data == NULL) {
+    printf("data allocation ");
+    free(buf->list);
+    return false;
+  }
+
+  buf->data_len = SYSVAR_BLOCK_SIZE;
+  buf->total_len = SYSVAR_BLOCK_SIZE - SYSVAR_HEAD;
+  buf->free_len = buf->total_len;
+  buf->readonly = is_ro;
+
+  strncpy(buf->list->name, is_ro ? "ro" : "rw", SYSVAR_NAME);
+  buf->list->value = NULL;
+  buf->list->len = SYSVAR_NAME + 2;
+  buf->list->next = NULL;
+  buf->loaded = false;
+  return true;
+}
+
+int sysvar_init(void) {
+  printf("sysvar_init. . .");
+  if (!sysvar_buf_init(&rw_buf, false) || !sysvar_buf_init(&ro_buf, true)) {
+    printf("failure!\n");
+    return SYSVAR_MEMORY_ERR;
+  }
+  printf("success!\n");
+  return SYSVAR_SUCCESS;
+}
diff --git a/common/main.c b/common/main.c
index e8d3a4f..6696f31 100755
--- a/common/main.c
+++ b/common/main.c
@@ -28,6 +28,7 @@
 #include <common.h>
 #include <watchdog.h>
 #include <command.h>
+
 #ifdef CONFIG_MODEM_SUPPORT
 #include <malloc.h>		/* for free() prototype */
 #endif
@@ -52,7 +53,6 @@
 
 extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
-
 #define MAX_DELAY_STOP_STR 32
 
 static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);
@@ -423,6 +423,8 @@
 
 //	debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
 
+        sysvar_init();
+
 	if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
 # ifdef CONFIG_AUTOBOOT_KEYED
 		int prev = disable_ctrlc(1);	/* disable Control C checking */
@@ -461,7 +463,6 @@
 	    video_banner();
 	}
 #endif
-
 	/*
 	 * Main Loop for Monitor Command Processing
 	 */
diff --git a/common/sysvar.c b/common/sysvar.c
index 55cd162..b77b5ac 100644
--- a/common/sysvar.c
+++ b/common/sysvar.c
@@ -2,7 +2,8 @@
  * Author: weixiaofeng@google.com (Xiaofeng Wei)
  */
 
-#include "sysvar.h"
+#include <sysvar.h>
+#include <common.h>
 
 static const unsigned long crc_table[256] = {
   0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
@@ -103,7 +104,8 @@
 /*
  * sysvar_copy - copy data from/to the data buffer
  */
-static void sysvar_copy(char *dst, char *src, int len, char end) {
+static void sysvar_copy(unsigned char *dst, unsigned char *src, int len,
+                        unsigned char end) {
   int i;
 
   if (end == SYSVAR_STR_TO_BUF) {
@@ -188,11 +190,13 @@
 
   /* system variable: name(32) + len(2) + value ... */
   for (i = 0; i < buf->total_len && ret == SYSVAR_SUCCESS; i += len) {
-    if (buf->data[i] == 0xff)
+    if (buf->data[i] == 0xff) {
       break;
+    }
 
     /* name of system variable */
-    sysvar_copy(name, (char *)&buf->data[i], SYSVAR_NAME, SYSVAR_BUF_TO_STR);
+    sysvar_copy((unsigned char *)name, &buf->data[i], SYSVAR_NAME,
+                SYSVAR_BUF_TO_STR);
     i += SYSVAR_NAME;
 
     /* length of system variable */
@@ -206,7 +210,7 @@
 
     i += 2;
     /* copy system variable */
-    sysvar_copy(value, (char *)&buf->data[i], len, SYSVAR_BUF_TO_STR);
+    sysvar_copy((unsigned char *)value, &buf->data[i], len, SYSVAR_BUF_TO_STR);
 
     /* add system variable to data list */
     ret = set_var(buf, name, value);
@@ -228,8 +232,8 @@
 
   for (i = 0; i < buf->total_len && curr != NULL; i += len) {
     /* name of system variable */
-    sysvar_copy((char *)&buf->data[i], curr->name,
-                 SYSVAR_NAME, SYSVAR_STR_TO_BUF);
+    sysvar_copy(&buf->data[i], (unsigned char *)curr->name, SYSVAR_NAME,
+                SYSVAR_STR_TO_BUF);
     i += SYSVAR_NAME;
 
     /* length of system variable */
@@ -242,7 +246,8 @@
     i += 2;
 
     /* copy system variable */
-    sysvar_copy((char *)&buf->data[i], curr->value, len, SYSVAR_STR_TO_BUF);
+    sysvar_copy(&buf->data[i], (unsigned char *)curr->value, len,
+                SYSVAR_STR_TO_BUF);
 
     curr = curr->next;
   }
@@ -316,7 +321,6 @@
  */
 int delete_var(struct sysvar_buf *buf, struct sysvar_list *var) {
   struct sysvar_list *curr = buf->list->next;
-
   /* last system variable? */
   if (curr == var) {
     buf->list->next = var->next;
@@ -350,7 +354,6 @@
   struct sysvar_list *curr = buf->list->next;
   struct sysvar_list *var;
   int ret = SYSVAR_SUCCESS;
-
   while (curr != NULL && ret == SYSVAR_SUCCESS) {
     /* store next position of variable */
     var = curr->next;
@@ -419,7 +422,7 @@
 
   while (curr != NULL) {
     /* print variable name */
-    printf("%s(%s)=%s\n", curr->name,
+    printf("%s\t%s\t%s\n", curr->name,
            buf->readonly ? "RO" : "RW", curr->value);
     curr = curr->next;
   }
diff --git a/include/common.h b/include/common.h
index 390b2bc..b445c57 100755
--- a/include/common.h
+++ b/include/common.h
@@ -211,6 +211,9 @@
 
 extern ulong load_addr;		/* Default Load Address */
 
+/* common/cmd_sysvar.c */
+int sysvar_init(void);
+
 /* common/cmd_nvedit.c */
 int	env_init     (void);
 void	env_relocate (void);
diff --git a/include/sysvar.h b/include/sysvar.h
index 4e73b1f..855a101 100644
--- a/include/sysvar.h
+++ b/include/sysvar.h
@@ -6,7 +6,6 @@
 #define _SYSVAR_H_
 
 #define SYSVAR_UBOOT
-
 #ifndef SYSVAR_UBOOT
 #include <stdio.h>
 #include <stdlib.h>
@@ -29,10 +28,10 @@
 #define SYSVAR_BLOCK_SIZE   0x00010000  /* size of system variables (64K) */
 
 #define SYSVAR_SPI_BLOCK    4           /* number of SPI flash blocks */
-#define SYSVAR_RW_OFFSET0   0x00100000  /* location of system variables(RW) */
-#define SYSVAR_RW_OFFSET1   0x00120000  /* location of system variables(RW backup) */
-#define SYSVAR_RO_OFFSET0   0x00140000  /* location of system variables(RO) */
-#define SYSVAR_RO_OFFSET1   0x00160000  /* location of system variables(RO backup) */
+#define SYSVAR_RW_OFFSET0   0x00060000  /* location of system variables(RW) */
+#define SYSVAR_RW_OFFSET1   0x00080000  /* location of system variables(RW backup) */
+#define SYSVAR_RO_OFFSET0   0x000A0000  /* location of system variables(RO) */
+#define SYSVAR_RO_OFFSET1   0x000C0000  /* location of system variables(RO backup) */
 
 #define SYSVAR_MTD_DEVICE   4           /* number of MTD devices */
 #define SYSVAR_RW_NAME0     "/dev/mtd2" /* MTD device of system variables(RW) */
@@ -68,6 +67,13 @@
 #define SYSVAR_CRC_ERR      -12
 #define SYSVAR_READONLY_ERR -13
 #define SYSVAR_EXISTED_ERR  -14
+#define SYSVAR_DEBUG_ERR    -15
+
+#define PAGE_SIZE           256
+#define SYSVAR_VALUE        2048
+
+#define SYSVAR_RO_MEM       0x00000100
+#define SYSVAR_RW_MEM       SYSVAR_RO_MEM + SYSVAR_BLOCK_SIZE
 
 struct sysvar_list {
   char name[SYSVAR_NAME + 1]; /* name of system variable */