Add glibc support(default)

Change-Id: I7675edcf14df8707ecd424a962e4cc464a4c6ae4
diff --git a/mbtk/aboot-tiny/jacana/jacana_firmware.c b/mbtk/aboot-tiny/jacana/jacana_firmware.c
new file mode 100755
index 0000000..c65465b
--- /dev/null
+++ b/mbtk/aboot-tiny/jacana/jacana_firmware.c
@@ -0,0 +1,163 @@
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include "aboot-tiny.h"
+#include "jacana_firmware.h"
+#include "jacana_pvt.h"
+
+/*---------------------------------------------------------------------------*/
+static int
+firmware_read_next_to_cache(firmware_handle_t *firmware)
+{
+  size_t size = firmware->end_ptr - firmware->read_ptr;
+  memmove(firmware->read_ptr - firmware->read_sz, firmware->read_ptr, size);
+  firmware->read_ptr -= firmware->read_sz;
+  firmware->end_ptr -= firmware->read_sz;
+  size_t remainder = firmware->end - firmware->start;
+  if(remainder > 0) {
+    size_t size = remainder > firmware->read_sz ? firmware->read_sz : remainder;
+    int len = jacana_firmware_raw_read(firmware->priv, firmware->start,
+                                       (uint8_t *)firmware->middle_ptr, size);
+    if(len < 0) {
+      return -1;
+    }
+    firmware->start += len;
+    firmware->end_ptr += len;
+  }
+
+  return 0;
+}
+/*---------------------------------------------------------------------------*/
+int
+jacana_firmware_open(firmware_handle_t *firmware, void *priv)
+{
+  firmware->priv = priv;
+  firmware->start = 0;
+  firmware->end = jacana_firmware_raw_get_total_size(priv);
+
+  firmware->data = aboot_tiny_mem_alloc(MAX_READ_CACHE_SZ * 2);
+  if(!firmware->data) {
+    aboot_tiny_log_printf("Failed: can not alloc data buf\n");
+    return -1;
+  }
+
+  firmware->read_sz = MAX_READ_CACHE_SZ;
+  firmware->middle_ptr = (char *)firmware->data + firmware->read_sz;
+  firmware->end_ptr = firmware->middle_ptr + firmware->read_sz;
+  firmware->read_ptr = firmware->end_ptr;
+  if(firmware_read_next_to_cache(firmware) < 0) {
+    goto failed;
+  }
+
+  char cmd_line[ABOOT_COMMAND_SZ];
+  char magic[9];
+  uint32_t size;
+  int num;
+
+  if(jacana_firmware_read_line(firmware, cmd_line) <= 0) {
+    aboot_tiny_log_printf("Failed: can not read a cmd line\n");
+    goto failed;
+  }
+  num = sscanf(cmd_line, "%08s%" SCNx32, magic, &size);
+  if(num != 2 || size > firmware->end) {
+    aboot_tiny_log_printf("Failed: cmd line format error\n");
+    goto failed;
+  }
+  firmware->end = (size_t)size;
+  if(strcmp(magic, "!JACANA!")) {
+    aboot_tiny_log_printf("Magic error: not a valid firmware\n");
+    goto failed;
+  }
+
+  return 0;
+
+failed:
+  aboot_tiny_mem_free(firmware->data);
+  firmware->data = NULL;
+  return -1;
+}
+/*---------------------------------------------------------------------------*/
+int
+jacana_firmware_read_line(firmware_handle_t *firmware, char *line)
+{
+  while(1) {
+    if(firmware->read_ptr < firmware->middle_ptr) {
+      const char *p = (const char *)strchr(firmware->read_ptr, '\n');
+      if(!p || p >= firmware->end_ptr) {
+        return -1;
+      }
+      int len = p - firmware->read_ptr + 1;
+      memcpy(line, firmware->read_ptr, len);
+      line[len] = '\0';
+      firmware->read_ptr += len;
+      if(firmware->read_ptr == firmware->end_ptr) {
+        /* firmware download finished, prepare for continue with pvt */
+        void *priv = jacana_pvt_raw_open();
+        if(!priv) {
+          return -1;
+        }
+        jacana_firmware_raw_close(firmware->priv);
+        jacana_firmware_close(firmware);
+        if(jacana_pvt_open(firmware, priv) < 0) {
+          return -1;
+        }
+        aboot_tiny_firmware_read_line = jacana_pvt_read_line;
+        aboot_tiny_firmware_read_data = jacana_pvt_read_data;
+      }
+      if(line[0] == '\n') {
+        continue;
+      } else {
+        line[len - 1] = '\0'; /* replace '\n' to '\0' */
+        return len - 1;
+      }
+    } else {
+      /* read_ptr >= middle_ptr */
+      if(firmware_read_next_to_cache(firmware) < 0) {
+        return -1;
+      }
+    }
+  }
+}
+/*---------------------------------------------------------------------------*/
+int
+jacana_firmware_read_data(firmware_handle_t *firmware, uint8_t *data, size_t size)
+{
+  while(1) {
+    if(firmware->read_ptr == firmware->end_ptr) {
+      return 0;
+    }
+
+    if(firmware->read_ptr < firmware->middle_ptr) {
+      size_t remainder = firmware->middle_ptr - firmware->read_ptr;
+      if(remainder < size) {
+        size = remainder;
+      }
+      memcpy(data, firmware->read_ptr, size);
+      firmware->read_ptr += size;
+      return size;
+    } else {
+      /* read_ptr >= middle_ptr */
+      if(firmware_read_next_to_cache(firmware) < 0) {
+        return -1;
+      }
+    }
+  }
+}
+/*---------------------------------------------------------------------------*/
+void
+jacana_firmware_close(firmware_handle_t *firmware)
+{
+  firmware->priv = NULL;
+  firmware->start = 0;
+  firmware->end = 0;
+  if(firmware->data) {
+    aboot_tiny_mem_free(firmware->data);
+    firmware->data = NULL;
+  }
+  firmware->read_sz = 0;
+  firmware->read_ptr = NULL;
+  firmware->middle_ptr = NULL;
+  firmware->end_ptr = NULL;
+}
+/*---------------------------------------------------------------------------*/