[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/lib/bootimage/bootimage.c b/src/bsp/lk/lib/bootimage/bootimage.c
new file mode 100644
index 0000000..436d19c
--- /dev/null
+++ b/src/bsp/lk/lib/bootimage/bootimage.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2014 Travis Geiselbrecht
+ *
+ * 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 <lib/bootimage.h>
+#include <trace.h>
+#include <err.h>
+#include <debug.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lib/bootimage_struct.h>
+#include <lib/mincrypt/sha256.h>
+
+#define LOCAL_TRACE 1
+
+struct bootimage {
+    const uint8_t *ptr;
+    size_t len;
+};
+
+static status_t validate_bootimage(bootimage_t *bi)
+{
+    if (!bi)
+        return ERR_INVALID_ARGS;
+
+    /* is it large enough to hold the first entry */
+    if (bi->len < 4096) {
+        LTRACEF("bootentry too short\n");
+        return ERR_BAD_LEN;
+    }
+
+    bootentry *be = (bootentry *)bi->ptr;
+
+    /* check that the first entry is a file, type boot info, and is 4096 bytes at offset 0 */
+    if (be->kind != KIND_FILE ||
+            be->file.type != TYPE_BOOT_IMAGE ||
+            be->file.offset != 0 ||
+            be->file.length != 4096 ||
+            memcmp(be->file.name, BOOT_MAGIC, sizeof(be->file.name))) {
+        LTRACEF("invalid first entry\n");
+        return ERR_INVALID_ARGS;
+    }
+
+    /* check the sha256 of the rest of the first page */
+    SHA256_CTX ctx;
+    SHA256_init(&ctx);
+
+    SHA256_update(&ctx, be + 1, 4096 - sizeof(bootentry));
+    const uint8_t *hash = SHA256_final(&ctx);
+
+    if (memcmp(hash, be->file.sha256, sizeof(be->file.sha256)) != 0) {
+        LTRACEF("bad hash of first section\n");
+
+        return ERR_CHECKSUM_FAIL;
+    }
+
+    /* look at the second entry, which should be a boot info structure */
+    if (be[1].kind != KIND_BOOT_INFO) {
+        LTRACEF("second entry not boot info\n");
+        return ERR_INVALID_ARGS;
+    }
+
+    bootentry_info *info = &be[1].info;
+
+    /* is the image a handled version */
+    if (info->version > BOOT_VERSION) {
+        LTRACEF("unhandled version 0x%x\n", info->version);
+        return ERR_INVALID_ARGS;
+    }
+
+    /* is the image the right size? */
+    if (info->image_size > bi->len) {
+        LTRACEF("boot image block says image is too big (0x%x bytes)\n", info->image_size);
+        return ERR_INVALID_ARGS;
+    }
+
+    /* trim the len to what the info block says */
+    bi->len = info->image_size;
+
+    /* iterate over the remaining entries in the list */
+    for (size_t i = 2; i < info->entry_count; i++) {
+        if (be[i].kind == 0)
+            break;
+
+        LTRACEF("%u: kind 0x%x\n", i, be[i].kind);
+
+        switch (be[i].kind) {
+            case KIND_BOOT_INFO:
+                break;
+            case KIND_BOARD:
+                break;
+            case KIND_BUILD:
+                break;
+            case KIND_FILE: {
+                LTRACEF("\ttype %c%c%c%c offset 0x%x, length 0x%x\n",
+                        (be[i].file.type >> 0) & 0xff, (be[i].file.type >> 8) & 0xff,
+                        (be[i].file.type >> 16) & 0xff, (be[i].file.type >> 24) & 0xff,
+                        be[i].file.offset, be[i].file.length);
+
+                /* check that the file section is inside the overall image */
+                uint32_t end = be[i].file.offset + be[i].file.length;
+                if (end < be[i].file.offset || end > info->image_size) {
+                    LTRACEF("bad file section, size too large\n");
+                    return ERR_INVALID_ARGS;
+                }
+
+                /* check the sha256 hash */
+                SHA256_init(&ctx);
+
+                LTRACEF("\tvalidating SHA256 hash\n");
+                SHA256_update(&ctx, (const uint8_t *)bi->ptr + be[i].file.offset, be[i].file.length);
+                const uint8_t *hash = SHA256_final(&ctx);
+
+                if (memcmp(hash, be[i].file.sha256, sizeof(be[i].file.sha256)) != 0) {
+                    LTRACEF("bad hash of file section\n");
+
+                    return ERR_CHECKSUM_FAIL;
+                }
+
+                break;
+            }
+            default:
+                LTRACEF("unknown kind 0x%x\n", be[i].kind);
+                return ERR_INVALID_ARGS;
+        }
+    }
+
+    LTRACEF("image good\n");
+    return NO_ERROR;
+}
+
+status_t bootimage_open(const void *ptr, size_t len, bootimage_t **bi)
+{
+    LTRACEF("ptr %p, len %zu\n", ptr, len);
+
+    if (!bi)
+        return ERR_INVALID_ARGS;
+
+    *bi = calloc(1, sizeof(bootimage_t));
+    if (!*bi)
+        return ERR_NO_MEMORY;
+
+    (*bi)->ptr = ptr;
+    (*bi)->len = len;
+
+    /* try to validate it */
+    status_t err = validate_bootimage(*bi);
+    if (err < 0) {
+        bootimage_close(*bi);
+        return err;
+    }
+
+    return NO_ERROR;
+}
+
+status_t bootimage_close(bootimage_t *bi)
+{
+    if (bi)
+        free(bi);
+
+    return NO_ERROR;
+}
+
+status_t bootimage_get_range(bootimage_t *bi, const void **ptr, size_t *len)
+{
+    if (!bi)
+        return ERR_INVALID_ARGS;
+
+    if (ptr)
+        *ptr = bi->ptr;
+    if (len)
+        *len = bi->len;
+
+    return NO_ERROR;
+}
+
+status_t bootimage_get_file_section(bootimage_t *bi, uint32_t type, const void **ptr, size_t *len)
+{
+    if (!bi)
+        return ERR_INVALID_ARGS;
+
+    bootentry *be = (bootentry *)bi->ptr;
+    bootentry_info *info = &be[1].info;
+
+    for (size_t i = 2; i < info->entry_count; i++) {
+        if (be[i].kind == 0)
+            break;
+
+        if (be[i].kind != KIND_FILE)
+            continue;
+
+        if (type == be[i].file.type) {
+            if (ptr)
+                *ptr = bi->ptr + be[i].file.offset;
+            if (len)
+                *len = be[i].file.length;
+            return NO_ERROR;
+        }
+    }
+
+    return ERR_NOT_FOUND;
+}
+
diff --git a/src/bsp/lk/lib/bootimage/include/lib/bootimage.h b/src/bsp/lk/lib/bootimage/include/lib/bootimage.h
new file mode 100644
index 0000000..2318048
--- /dev/null
+++ b/src/bsp/lk/lib/bootimage/include/lib/bootimage.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Travis Geiselbrecht
+ *
+ * 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.
+ */
+#pragma once
+
+#include <sys/types.h>
+#include <compiler.h>
+#include <lib/bootimage_struct.h>
+
+typedef struct bootimage bootimage_t;
+
+status_t bootimage_open(const void *ptr, size_t len, bootimage_t **bi) __NONNULL();
+status_t bootimage_close(bootimage_t *bi) __NONNULL();
+status_t bootimage_get_range(bootimage_t *bi, const void **ptr, size_t *len) __NONNULL((1));
+
+/* ask for a file section of the bootimage, by type */
+status_t bootimage_get_file_section(bootimage_t *bi, uint32_t type, const void **ptr, size_t *len) __NONNULL((1));
+
diff --git a/src/bsp/lk/lib/bootimage/include/lib/bootimage_struct.h b/src/bsp/lk/lib/bootimage/include/lib/bootimage_struct.h
new file mode 100644
index 0000000..a59768e
--- /dev/null
+++ b/src/bsp/lk/lib/bootimage/include/lib/bootimage_struct.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014 Brian Swetland
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+typedef struct {
+    uint32_t kind;
+    uint32_t type;
+    uint32_t offset;    /* byte offset from start of file */
+    uint32_t length;    /* length in bytes */
+    uint8_t name[16];
+    uint8_t sha256[32];
+} __attribute__ ((packed)) bootentry_file;
+
+typedef struct {
+    uint32_t kind;
+    union {
+        uint32_t u[15];
+        uint8_t b[60];
+    } __attribute__((packed)) u;
+} __attribute__((packed)) bootentry_data;
+
+typedef struct {
+    uint32_t kind;
+    uint32_t version;       /* bootimage version */
+    uint32_t image_size;    /* byte size of entire image */
+    uint32_t entry_count;   /* number of valid bootentries */
+    uint32_t reserved[12];
+} __attribute__((packed)) bootentry_info;
+
+typedef union {
+    uint32_t kind;
+    bootentry_file file;
+    bootentry_data data;
+    bootentry_info info;
+} bootentry;
+
+#define BOOT_VERSION 0x00010000     /* 1.0 */
+
+#define BOOT_MAGIC "<lk-boot-image>"
+#define BOOT_MAGIC_LENGTH 16
+
+// header (bootentry_file, but special):
+
+// bootentry kinds:
+#define KIND_FILE           0x656c6966  // 'file'
+#define KIND_BOOT_INFO      0x6f666e69  // 'info'
+#define KIND_BOARD          0x67726174  // 'targ' board id string
+#define KIND_BUILD          0x706d7473  // 'stmp' build id string
+
+// bootentry_file types:
+#define TYPE_BOOT_IMAGE     0x746f6f62  // 'boot'
+#define TYPE_LK             0x6b6c6b6c  // 'lklk'
+#define TYPE_FPGA_IMAGE     0x61677066  // 'fpga'
+#define TYPE_LINUX_KERNEL   0x6b78636c  // 'lcxk'
+#define TYPE_LINUX_INITRD   0x64697264  // 'drid'
+#define TYPE_DEVICE_TREE    0x74766564  // 'devt'
+#define TYPE_SYSPARAMS      0x70737973  // 'sysp'
+#define TYPE_UNKNOWN        0x6e6b6e75  // 'unkn'
+
+// first entry must be:
+//   kind: KIND_FILE
+//   type: TYPE_BOOT_IMAGE
+//   offset: 0
+//   length: 4096
+//   name: BOOT_MAGIC
+//   sha256: of bootentry[1..63]
+
+// second entry must be:
+//   kind: KIND_BOOT_INFO
+
+// offsets should be multiple-of-4096 
diff --git a/src/bsp/lk/lib/bootimage/rules.mk b/src/bsp/lk/lib/bootimage/rules.mk
new file mode 100644
index 0000000..e75cfce
--- /dev/null
+++ b/src/bsp/lk/lib/bootimage/rules.mk
@@ -0,0 +1,11 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_DEPS := \
+    lib/mincrypt
+
+MODULE_SRCS := \
+	$(LOCAL_DIR)/bootimage.c
+
+include make/module.mk