qsr1000: Adding hnvram initialization to uboot

Added factory reset for hnvram partition. Zeros the partition,
and manually writes PLATFORM_NAME, defaulting to "gfrg240".

Change-Id: Ic958d8806129a55b224bc1171fe1b70d4cfcf9d9
diff --git a/board/ruby/ruby.c b/board/ruby/ruby.c
index c1e0c5c..3d6947b 100644
--- a/board/ruby/ruby.c
+++ b/board/ruby/ruby.c
@@ -199,7 +199,7 @@
 		}
 	}
 #ifdef CONFIG_CMD_HNVRAM
-        RUN("hnvram");
+        RUN("hnvram load");
 #endif
 	return 0;
 }
diff --git a/common/cmd_hnvram.c b/common/cmd_hnvram.c
index 52f0ae1..2f4d308 100644
--- a/common/cmd_hnvram.c
+++ b/common/cmd_hnvram.c
@@ -25,6 +25,7 @@
 #include <common.h>
 #include <malloc.h>
 #include <spi_flash.h>
+#include <asm/byteorder.h>
 
 /* local debug macro */
 #undef HNVRAM_DEBUG
@@ -221,7 +222,7 @@
 }
 
 #if defined(CONFIG_CMD_HNVRAM)
-int do_hnvram(void) {
+int do_hnvram_load(void) {
         char command[60];
         sprintf(command, "spi_flash read 0x%x 0x%x 0x%x", HNVRAM_MTD_OFFSET, HNVRAM_DRAM_OFFSET, MAX_HNVRAM_SIZE);
         int ret = run_command(command, 0);
@@ -248,19 +249,97 @@
                 return -1;
         }
 
-        free(buf);
+        return CMD_RET_SUCCESS;
+}
+
+int do_hnvram_init(char *val) {
+        // Erase entire partition
+        char command[60];
+        sprintf(command, "spi_flash erase 0x%x 0x%x", HNVRAM_MTD_OFFSET, MAX_HNVRAM_SIZE);
+        int ret = run_command(command, 0);
+
+        if (ret) {
+          printf("failed to erase hnvram partition\n");
+          return ret;
+        }
+
+        char key[] = "PLATFORM_NAME";
+        int val_len = strlen(val);
+        // size variable should fit in one byte
+        if (val_len < 1 || 255 < val_len) {
+          printf("Intial value for %s has bad size: %d", key, val_len);
+          return CMD_RET_FAILURE;
+        }
+        // +5 to count key length (1) and record length (4) bytes
+        int rec_len = sizeof(key) + val_len + 5;
+
+        // Use 2MB of (hopefully) free DRAM
+        char *buf = HNVRAM_DRAM_OFFSET;
+        memset(buf, 0x00, MAX_HNVRAM_SIZE);
+
+        // Write platform_name to RW section
+        int i = HNVRAM_B1_OFFSET;
+
+        // Record start
+        buf[i++] = 0x01;
+
+        // Record length
+        int nbyte_order = htonl(rec_len); // hnvram expects big endian
+        memcpy(buf + i, &nbyte_order, sizeof(nbyte_order));
+        i += sizeof(nbyte_order);
+
+        // Key length
+        buf[i++] = sizeof(key);
+
+        // Key
+        memcpy(buf + i, &key, sizeof(key));
+        i += sizeof(key);
+
+        // Val length
+        nbyte_order = htonl(val_len);
+        memcpy(buf + i, &nbyte_order, sizeof(nbyte_order));
+        i += sizeof(nbyte_order);
+
+        // Val
+        memcpy(buf + i, val, val_len);
+
+        sprintf(command, "spi_flash write 0x%x 0x%p 0x%x", HNVRAM_MTD_OFFSET, buf, MAX_HNVRAM_SIZE);
+        ret = run_command(command, 0);
+
+        if (ret) {
+          printf("failed to write init to hnvram partition\n");
+          return ret;
+        }
+
+        // Load platform_name into environment variables
+        do_hnvram_load();
+
         return CMD_RET_SUCCESS;
 }
 
 static int do_hnvram_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
                 char * const argv[]) {
-        return do_hnvram();
+        if (argc == 2 && strcmp(argv[1], "load") == 0) {
+          return do_hnvram_load();
+        } else if (argc == 2 && strcmp(argv[1], "init") == 0) {
+          return do_hnvram_init("GFRG240");
+        } else if (argc == 3 && strcmp(argv[1], "init") == 0) {
+          return do_hnvram_init(argv[2]);
+        } else {
+          printf("hnvram - incorrect usage. Please use one of:\n");
+          printf("hnvram load\n");
+          printf("hnvram init <model>\n");
+          return CMD_RET_USAGE;
+        }
 }
 
 U_BOOT_CMD(
-        hnvram, 1, 0, do_hnvram_cmd,
-        "load hnvram from flash",
+        hnvram, 3, 0, do_hnvram_cmd,
+        "HNVRAM key-val storage on flash",
         "\n"
-        "load hnvram from flash into environment vars named HNV_<name>\n"
+        "hnvram load            - reads all variables from flash partition and"
+        "                         places into environment vars as HNV_<name>"
+        "hnvram init [model]    - zeros hnvram and writes PLATFORM_NAME=<model>"
+        "                         Uses GFRG240 by default if no arg given"
         );
 #endif  /* CONFIG_CMD_HNVRAM */