[vim2] fix issues with passing entropy to zircon.

This CL fixes a bunch of small issues that surfaced when we tried to
port this change to a different board.

Changes:

* Sort includes in alphabetical order.
* Remove magic constant specifying the size of the kernel entropy
cmdline string.
* Fix error in the static_assert checking bounds of the
CMDLINE_ENTROPY_SIZE (each char would produce 4 bits of entropy instead
of 8)
* Add static_assert checking that CMDLINE_ENTROPY_BITS is multiple of
32, to avoid writing more than we request.
* Separate the hw_rand_hex into a function that only reads the hw rng
and another that converts an uint32 into a 8 hex chars.
* Fix a typo that avoided adding a '\0' at the end of the cmdline
string.
* Add a mandatory_memset implementation, and call that instead of
memset for clearing the cmdline buffer after adding the zbi cmdline.

TEST=flashed into a vim2 and checked that zircon received the entropy.
Manually verified that the static asserts have the right bounds.

Change-Id: I93a33c48d201572be3a6603c11b381a297459eb0
diff --git a/board/khadas/kvim2/zircon.c b/board/khadas/kvim2/zircon.c
index 00a249d..7f86a9f 100644
--- a/board/khadas/kvim2/zircon.c
+++ b/board/khadas/kvim2/zircon.c
@@ -4,11 +4,11 @@
  * SPDX-License-Identifier:	BSD-3-Clause
  */
 
+#include <aml_i2c.h>
+#include <asm/arch/secure_apb.h>
 #include <common.h>
 #include <part.h>
 #include <zircon/zircon.h>
-#include <asm/arch/secure_apb.h>
-#include <aml_i2c.h>
 
 #define PDEV_VID_KHADAS             4
 #define PDEV_PID_VIM2               2
@@ -17,13 +17,22 @@
 
 #define CMDLINE_ENTROPY_SIZE        1024
 #define CMDLINE_ENTROPY_BITS        256 // random bits to pass to zircon.
+
+#define ENTROPY_BITS_PER_CHAR       4
+
+static char entropy_cmdline[CMDLINE_ENTROPY_SIZE] = {0};
+static const char zircon_entropy_arg[] = "kernel.entropy-mixin=";
+
 #define static_assert _Static_assert
-static_assert((CMDLINE_ENTROPY_BITS/8) + 22 < CMDLINE_ENTROPY_SIZE,
+static_assert(CMDLINE_ENTROPY_BITS % 32 == 0,
+              "Requested entropy must be a multiple of 32");
+
+static_assert((CMDLINE_ENTROPY_BITS/ENTROPY_BITS_PER_CHAR) \
+              + sizeof(zircon_entropy_arg) < CMDLINE_ENTROPY_SIZE,
               "Requested entropy doesn't fit in cmdline.");
 
-static const char BOOTLOADER_VERSION[] = "zircon-bootloader=0.11";
+static const char BOOTLOADER_VERSION[] = "zircon-bootloader=0.12";
 
-static char entropy_cmdline[CMDLINE_ENTROPY_SIZE] = "kernel.entropy-mixin=";
 
 static const zbi_cpu_config_t cpu_config = {
     .cluster_count = 2,
@@ -187,6 +196,16 @@
     },
 };
 
+static void* mandatory_memset(void* dst, int c, size_t n) {
+    volatile unsigned char* out = dst;
+    size_t i = 0;
+
+    for (i = 0; i < n; ++i) {
+        out[i] = (unsigned char)c;
+    }
+    return dst;
+}
+
 static void add_partition_map(zbi_header_t* zbi) {
     block_dev_desc_t* dev_desc;
     disk_partition_t bootloader_info;
@@ -314,32 +333,40 @@
     printf("MAC address parsing failed for \"%s\"\n", getenv("eth_mac"));
 }
 
-// fills an 8 char buffer with random hex digits, drawn from the
-// hardware cprng.
+// fills an 8 char buffer with the lowercase hex representation of the given
+// value.
 // WARNING this does not add a '\0' to the end of the buffer.
-static inline void hw_rand_hex(char buf[static 8]) {
-  static const char* hex = "0123456789abcdef";
+static inline void uint32_to_hex(uint32_t val, char buf[static 8]) {
+  static const char hex[] = "0123456789abcdef";
+  int i = 0;
 
-  uint32_t rnd = readl(P_RAND64_ADDR0);
-  int i;
-  for (i = 0; i < 8; ++i) {
-    buf[i] = hex[rnd & 0xF];
-    rnd >>= 4;
+  for (i = 7; i >= 0; i--) {
+    buf[i] = hex[val & 0xF];
+    val >>= 4;
   }
 }
 
-static void add_cmdline_entropy(zbi_header_t* zbi) {
-    char *entropy = entropy_cmdline + strlen(entropy_cmdline);
+// Reads a value from the userspace hardware random number generator.
+// NOTE that there is no guarantee of the quality of this rng.
+static inline uint32_t read_hw_rng(void) {
+  return readl(P_RAND64_ADDR0);
+}
 
-    int i;
+static void add_cmdline_entropy(zbi_header_t* zbi) {
+    strcpy(entropy_cmdline, zircon_entropy_arg);
+    char *entropy = entropy_cmdline + strlen(zircon_entropy_arg);
+    int i = 0;
+
     for (i = 0; i < CMDLINE_ENTROPY_BITS; i += 32) {
-      hw_rand_hex(entropy);
+      uint32_to_hex(read_hw_rng(), entropy);
       entropy += 8;
     }
-    entropy = '\0';
+    *entropy = '\0';
 
-    zircon_append_boot_item(zbi, ZBI_TYPE_CMDLINE, 0, entropy_cmdline, CMDLINE_ENTROPY_SIZE);
-    memset(entropy_cmdline, '\0', CMDLINE_ENTROPY_SIZE);
+    zircon_append_boot_item(zbi, ZBI_TYPE_CMDLINE, 0, entropy_cmdline,
+                            sizeof(entropy_cmdline));
+
+    mandatory_memset(entropy_cmdline, '\0', sizeof(entropy_cmdline));
 }
 
 int zircon_preboot(zbi_header_t* zbi) {