[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/app/blxboot/dto.c b/src/bsp/lk/app/blxboot/dto.c
new file mode 100644
index 0000000..7a6b2b0
--- /dev/null
+++ b/src/bsp/lk/app/blxboot/dto.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ *
+ * 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 <debug.h>
+#include <lib/android_dtbo.h>
+#include <lib/mempool.h>
+#include <libfdt.h>
+#include <platform.h>
+#include <trace.h>
+
+#include "blxboot_plat.h"
+#include "imageinfo.h"
+
+#define LOCAL_TRACE 0
+
+struct bootargs_overlay {
+    int noffset;
+    int len;
+    const void *path;
+    const char *prop;
+};
+
+int extract_fdt(void *fdt, int size)
+{
+    int ret = 0;
+
+    ret = fdt_open_into(fdt, fdt, size);
+    if (ret) {
+        dprintf(CRITICAL, "open fdt failed\n");
+        return ret;
+    }
+    ret = fdt_check_header(fdt);
+    if (ret) {
+        dprintf(CRITICAL, "check fdt failed\n");
+        return ret;
+    }
+
+    return ret;
+}
+
+static int dtbo_overlay(void *fdt_dtb, void *dtbo_entry)
+{
+    struct bootargs_overlay bootargs;
+    int noffset;
+
+    if (fdt_check_header(dtbo_entry)) {
+        LTRACEF("%s failed.\n", "dtbo check header");
+        return -1;
+    }
+
+    do {
+        noffset = fdt_path_offset(dtbo_entry, "/__symbols__");
+        if (noffset < 0)
+            break;
+
+        bootargs.path = fdt_getprop(dtbo_entry, noffset, "chosen", NULL);
+        if (bootargs.path == NULL)
+            break;
+
+        bootargs.noffset = fdt_path_offset(dtbo_entry, bootargs.path);
+        if (bootargs.noffset < 0)
+            break;
+
+        bootargs.prop = fdt_getprop(dtbo_entry, bootargs.noffset,
+            "bootargs_ext", &bootargs.len);
+        if (bootargs.prop == NULL)
+            break;
+
+        plat_fixup_append((char *)bootargs.prop);
+    } while (0);
+
+    if (fdt_overlay_apply(fdt_dtb, dtbo_entry)) {
+        LTRACEF("%s failed.\n", "fdt_overlay_apply");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int android_dtbo_overlay(void *fdt_dtb, void *dtbo, bool update_cmd)
+{
+/* assume the maxium dtbo entries in dtbo.img */
+#define MAX_DTBO_ENTRIES_COUNT  100
+
+    static const char android_dtbo_param[] = "androidboot.dtbo_idx=";
+    uint32_t i;
+    uint32_t dtbo_entry_count;
+    uint32_t dtbo_version;
+    char *dtbo_idx_str;
+    char *dtbo_idx_str_end;
+    void *dtbo_entry;
+    struct dt_table_entry *tbl_entry;
+
+    if (android_dtbo_check_header(dtbo) != DTBO_RET_OK) {
+        LTRACEF("%s failed.\n", "android dtbo check header");
+        return -1;
+    }
+
+    dtbo_entry_count = android_dtbo_dt_entry_count(dtbo);
+    if (dtbo_entry_count >= MAX_DTBO_ENTRIES_COUNT) {
+        LTRACEF("Too many dtbo entries.\n");
+        return -1;
+    }
+
+    dtbo_idx_str_end = NULL;
+    if (update_cmd) {
+        dtbo_idx_str = mempool_alloc((dtbo_entry_count * 3) +
+                       strlen(android_dtbo_param) + 1, MEMPOOL_ANY);
+        if (dtbo_idx_str == NULL) {
+            LTRACEF("mempool_alloc for dtboidx_str failed.\n");
+            return -1;
+        }
+        dtbo_idx_str_end = dtbo_idx_str;
+        sprintf(dtbo_idx_str_end, "%s", android_dtbo_param);
+        dtbo_idx_str_end += strlen(android_dtbo_param);
+    }
+
+    dtbo_version = android_dtbo_version(dtbo);
+    for (i = 0; i < dtbo_entry_count; i++) {
+        if (android_dtbo_get_dt_table_entry(dtbo, i, &tbl_entry) != DTBO_RET_OK)
+            break;
+
+        if (plat_compare_dtbo_hwinfo(dtbo_version, tbl_entry) != 0)
+            continue;
+
+        dtbo_entry = android_dtbo_get_dt_dtbo_entry(dtbo, i);
+        if (dtbo_entry == NULL)
+            break;
+
+        if (dtbo_overlay(fdt_dtb, dtbo_entry)) {
+            LTRACEF("fdt_overlay_apply failed: index=%u\n", i);
+            continue;
+        }
+
+        if (update_cmd) {
+            sprintf(dtbo_idx_str_end, "%d,", i);
+            dtbo_idx_str_end += i < 10 ? 2 : 3;
+        }
+    }
+
+    if (update_cmd) {
+        if (dtbo_idx_str_end != (dtbo_idx_str + strlen(android_dtbo_param))) {
+            *(dtbo_idx_str + strlen(dtbo_idx_str) - 1) = '\0';
+            plat_fixup_append(dtbo_idx_str);
+        }
+        mempool_free(dtbo_idx_str);
+    }
+
+    return 0;
+}
+
+int overlay_fdt(void *fdt_dtb, void *dtbo, void *vpd)
+{
+    /* [TODO] clarify: can we remove ERR_ADDR, just to check it against NULL */
+    if (fdt_dtb == (void *)ERR_ADDR) {
+        LTRACEF("no valid dtb.\n");
+        return -1;
+    }
+
+    if (extract_fdt(fdt_dtb, MAX_DTB_SIZE)) {
+        LTRACEF("%s failed.\n", "extract_fdt");
+        return -1;
+    }
+
+    if (vpd && (android_dtbo_overlay(fdt_dtb, vpd, false) != 0) &&
+            (dtbo_overlay(fdt_dtb, vpd) != 0))
+        return -1;
+
+    if (dtbo && (android_dtbo_overlay(fdt_dtb, dtbo, true) != 0) &&
+            (dtbo_overlay(fdt_dtb, dtbo) != 0))
+        return -1;
+
+    if (fdt_pack(fdt_dtb))
+        return -1;
+
+    return 0;
+}