[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/app/loader/loader.c b/src/bsp/lk/app/loader/loader.c
new file mode 100644
index 0000000..c363ee1
--- /dev/null
+++ b/src/bsp/lk/app/loader/loader.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2015 Carlos Pizano-Uribe <cpu@chromium.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <lib/tftp.h>
+#include <lib/cksum.h>
+#include <lib/elf.h>
+
+#include <kernel/thread.h>
+
+#if defined(WITH_LIB_CONSOLE)
+#include <lib/console.h>
+#else
+#error "loader app needs a console"
+#endif
+
+#if defined(SDRAM_BASE)
+#define DOWNLOAD_BASE ((void*)SDRAM_BASE)
+#else
+#define DOWNLOAD_BASE ((void*)0)
+#endif
+
+#define FNAME_SIZE 64
+#define DOWNLOAD_SLOT_SIZE (512 * 1024)
+
+typedef enum {
+    DOWNLOAD_ANY,
+    DOWNLOAD_ELF,
+} download_type;
+
+typedef struct {
+    unsigned char* start;
+    unsigned char* end;
+    unsigned char* max;
+    char name[FNAME_SIZE];
+    download_type type;
+} download_t;
+
+static download_t* make_download(const char* name)
+{
+    download_t* d = malloc(sizeof(download_t));
+    memset(d, 0, sizeof(download_t));
+    strncpy(d->name, name, FNAME_SIZE);
+    return d;
+}
+
+static void set_ram_zone(download_t* d, int slot) {
+    d->start = DOWNLOAD_BASE + (DOWNLOAD_SLOT_SIZE * slot);
+    d->end = d->start;
+    d->max = d->end + DOWNLOAD_SLOT_SIZE;
+    memset(d->start, 0, DOWNLOAD_SLOT_SIZE);
+}
+
+static size_t output_result(const download_t* download)
+{
+    size_t len = download->end - download->start;
+    unsigned long crc = crc32(0, download->start, len);
+    printf("[%s] done, start at: %p - %zu bytes, crc32 = %lu\n",
+           download->name, download->start, len, crc);
+    return len;
+}
+
+static int run_elf(void* entry_point)
+{
+    void (*elf_start)(void) = (void*)entry_point;
+    printf("elf (%p) running ...\n", entry_point);
+    thread_sleep(10);
+    elf_start();
+    printf("elf (%p) finished\n", entry_point);
+    return 0;
+}
+
+static void process_elf_blob(const void* start, size_t len)
+{
+    void* entrypt;
+    elf_handle_t elf;
+
+    status_t st = elf_open_handle_memory(&elf, start, len);
+    if (st < 0) {
+        printf("unable to open elf handle\n");
+        return;
+    }
+
+    st = elf_load(&elf);
+    if (st < 0) {
+        printf("elf processing failed, status : %d\n", st);
+        goto exit;
+    }
+
+    entrypt = (void*)elf.entry;
+    if (entrypt < start || entrypt >= (void*)((char*)start + len)) {
+        printf("out of bounds entrypoint for elf : %p\n", entrypt);
+        goto exit;
+    }
+
+    printf("elf looks good\n");
+    thread_resume(thread_create("elf_runner", &run_elf, entrypt,
+                                DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
+exit:
+    elf_close_handle(&elf);
+}
+
+int tftp_callback(void* data, size_t len, void* arg)
+{
+    download_t* download = arg;
+    size_t final_len;
+
+    if (!data) {
+        final_len = output_result(download);
+        if (download->type == DOWNLOAD_ELF) {
+            process_elf_blob(download->start, final_len);
+        }
+
+        download->end = download->start;
+        return 0;
+    }
+
+    if ((download->end + len) > download->max) {
+        printf("transfer too big, aborting\n");
+        return -1;
+    }
+    if (len) {
+        memcpy(download->end, data, len);
+        download->end += len;
+    }
+    return 0;
+}
+
+static int loader(int argc, const cmd_args *argv)
+{
+    static int any_slot = 0;
+    static int elf_slot = 1;
+
+    download_t* download;
+    int slot;
+
+    if (!DOWNLOAD_BASE) {
+        printf("loader not available. it needs sdram\n");
+        return 0;
+    }
+
+    if (argc < 3) {
+usage:
+        printf("load any [filename] <slot>\n"
+               "load elf [filename] <slot>\n"
+               "protocol is tftp and <slot> is optional\n");
+        return 0;
+    }
+
+    download = make_download(argv[2].str);
+
+    if (strcmp(argv[1].str, "any") == 0) {
+        download->type = DOWNLOAD_ANY;
+        slot = any_slot;
+        any_slot += 2;
+    } else if (strcmp(argv[1].str, "elf") == 0) {
+        download->type = DOWNLOAD_ELF;
+        slot = elf_slot;
+        elf_slot += 2;
+    } else {
+        goto usage;
+    }
+
+    if (argc == 4) {
+        slot = argv[3].i;
+    }
+
+    set_ram_zone(download, slot);  
+    tftp_set_write_client(download->name, &tftp_callback, download);
+    printf("ready for %s over tftp (at %p)\n", argv[2].str, download->start);
+    return 0;
+}
+
+STATIC_COMMAND_START
+STATIC_COMMAND("load", "download and run via tftp", &loader)
+STATIC_COMMAND_END(loader);
+
diff --git a/src/bsp/lk/app/loader/rules.mk b/src/bsp/lk/app/loader/rules.mk
new file mode 100644
index 0000000..e1a1f11
--- /dev/null
+++ b/src/bsp/lk/app/loader/rules.mk
@@ -0,0 +1,14 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS += \
+	$(LOCAL_DIR)/loader.c \
+
+
+MODULE_DEPS := \
+    lib/cksum \
+    lib/tftp  \
+    lib/elf
+
+include make/module.mk