WindCharger: Added in sysvar_shared variables.

Sysvar shared variables are shared with sysvar and the uboot env.  They
can only be edited via sysvar, and are not saved during saveenv or
loading of the uboot environment.

Change-Id: Ie1e91586e37b8b03cc1a514d062ce6d03c910b9f
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 6257fbd..340c73e 100755
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -130,6 +130,9 @@
 			if (k < 0) {
 				continue;
 			}
+			if (is_sysvar_shared(name)) {
+				puts(">>> ");
+			}
 			puts (name);
 			putc ('=');
 			while (k < nxt)
@@ -395,6 +398,10 @@
 		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 _do_setenv (flag, argc, argv);
 }
diff --git a/common/cmd_sysvar.c b/common/cmd_sysvar.c
index da083cf..4eacbb5 100644
--- a/common/cmd_sysvar.c
+++ b/common/cmd_sysvar.c
@@ -15,6 +15,30 @@
 #include <command.h>
 #include <flash.h>
 
+struct sysvar_uboot {
+  const char *sysvar_name;
+  const char *uboot_name;
+};
+
+struct sysvar_uboot_map {
+  struct sysvar_uboot *map;
+};
+
+static const struct sysvar_uboot su_mappings[] = {
+  {
+    .sysvar_name = ACTIVATED_KERNEL_NAME_SV,
+    .uboot_name = ACTIVATED_KERNEL_NAME_UB,
+  },
+  {
+    .sysvar_name = MAC_ADDR1_SV,
+    .uboot_name = MAC_ADDR1_UB,
+  },
+};
+
+static const struct sysvar_uboot_map su_map = {
+  .map = su_mappings,
+};
+
 // 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)
@@ -376,7 +400,8 @@
   } else {
     /* get a system variable */
     if (sf_getvar(argv[1], value, SYSVAR_VALUE) == 0) {
-      printf("%s=", argv[1]);
+      puts(argv[1]);
+      putc('=');
       /* puts value in case CONFIG_SYS_PBSIZE < SYSVAR_VALUE */
       puts(value);
       putc('\n');
@@ -395,6 +420,13 @@
   "    - 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)
  *
@@ -409,12 +441,19 @@
   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;
 }
@@ -633,7 +672,8 @@
 static void sysvar_env_init(struct sysvar_buf *buf) {
   struct sysvar_list *curr = buf->list->next;
   while (curr != NULL) {
-    setenv(curr->name, curr->value);
+    /* Should only set env variables for special vars. */
+    set_sysvar_uboot(curr->name, curr->value);
     curr = curr->next;
   }
 }
@@ -650,3 +690,32 @@
   printf("init success!\n");
   return SYSVAR_SUCCESS;
 }
+
+int is_sysvar_shared(const char *var) {
+  int i;
+  for (i = 0; i < ARRAY_SIZE(su_map.map); ++i) {
+    if (strcmp(var, su_map.map[i].uboot_name) == 0 ||
+        strcmp(var, su_map.map[i].sysvar_name) == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+const char *get_uboot_name(const char *sysvar_name) {
+  int i;
+  for (i = 0; i < ARRAY_SIZE(su_map.map); ++i) {
+    if (strcmp(sysvar_name, su_map.map[i].uboot_name) == 0) {
+      return su_map.map[i].uboot_name;
+    }
+  }
+  return NULL;
+}
+
+void delete_uboot_vars(void) {
+  int i;
+  for (i = 0; i < ARRAY_SIZE(su_map.map); ++i) {
+    setenv(su_map.map[i].sysvar_name, NULL);
+    setenv(su_map.map[i].uboot_name, NULL);
+  }
+}
diff --git a/common/env_dataflash.c b/common/env_dataflash.c
index 93fff29..0b77d99 100755
--- a/common/env_dataflash.c
+++ b/common/env_dataflash.c
@@ -58,6 +58,8 @@
 /* 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();
 	memcpy(temp, env_ptr, CFG_ENV_SIZE);
 	return write_dataflash (CFG_ENV_ADDR, (unsigned long)temp, CFG_ENV_SIZE);
 }
diff --git a/include/common.h b/include/common.h
index b445c57..a39a27c 100755
--- a/include/common.h
+++ b/include/common.h
@@ -174,6 +174,8 @@
 
 void	hang		(void) __attribute__ ((noreturn));
 
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
 /* */
 long int initdram (int);
 int	display_options (void);
@@ -212,7 +214,14 @@
 extern ulong load_addr;		/* Default Load Address */
 
 /* common/cmd_sysvar.c */
+#define ACTIVATED_KERNEL_NAME_SV "ACTIVATED_KERNEL_NAME"
+#define ACTIVATED_KERNEL_NAME_UB ACTIVATED_KERNEL_NAME_SV
+#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_uboot_name(const char *sysvar_name);
+void delete_uboot_vars(void);
 
 /* common/cmd_nvedit.c */
 int	env_init     (void);