[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/devtools/mrdump/mrdump_tool_source/mrdump_tool.c b/src/devtools/mrdump/mrdump_tool_source/mrdump_tool.c
new file mode 100644
index 0000000..085aabe
--- /dev/null
+++ b/src/devtools/mrdump/mrdump_tool_source/mrdump_tool.c
@@ -0,0 +1,405 @@
+/* uint64_t ...*/
+#include <inttypes.h>
+#include <stdbool.h>
+
+/* vprintf, vsnprintf */
+#include <stdio.h>
+
+/* exit(), atoi() */
+#include <stdlib.h>
+
+/* getopt, optind */
+#include <unistd.h>
+
+/* sysenv */
+#include "mrdump_defaults.h"
+
+/* strcmp */
+#include <string.h>
+
+#include <getopt.h>
+/* mrdump related */
+#include "mrdump_log.h"
+#include "mrdump_common.h"
+#include "mrdump_status.h"
+#include "mrdump_support_ext4.h"
+#include "mrdump_support_mpart.h"
+
+static void usage(const char *prog) __attribute__((noreturn));
+static void usage(const char *prog)
+{
+    printf("Usage\n"
+        "\t%1$s is-supported\n\n"
+        "\t%1$s status-get\n"
+        "\t%1$s status-log\n"
+        "\t%1$s status-clear\n\n"
+        "\t%1$s file-setup\n"
+        "\t%1$s file-allocate n\n"
+        "\t\tn is 0(disable file output) 1(halfmem) 2(fullmem) >256\n"
+        "\t%1$s file-extract-core [-r] filename\n"
+        "\t\t-r\tre-init pre-allocated file\n"
+        "\t%1$s file-info\n\n"
+        "\t%1$s mem-size-set n\n"
+        "\t\tn is between 64 ~ 16384(m), 0 is output total-mem-size\n\n"
+        "\t%1$s output-set output\n"
+        "\t\tsetting mrdump output device\n"
+        "\t\t  none\n"
+        "\t\t  null\n"
+        "\t\t  usb\n"
+        "\t\t  partition: mrdump partition\n"
+        "\t\t  internal-storage: ext4, f2fs\n"
+        "\t%1$s output-get\n"
+        "\t\tgetting mrdump output device\n",
+        prog);
+    exit(1);
+}
+
+static void dump_status_ok(const struct mrdump_status_result *result)
+{
+    printf("Ok\n");
+    printf("\tMode: %s\n\tOutput: ", result->mode);
+
+    switch (result->output) {
+    case MRDUMP_OUTPUT_NULL:
+        printf("null\n");
+        break;
+    case MRDUMP_OUTPUT_USB:
+        printf("usb\n");
+        break;
+    case MRDUMP_OUTPUT_DATA_FS:
+        printf("ext4/data partition\n");
+        break;
+    case MRDUMP_OUTPUT_PARTITION:
+        printf("dynamic mrdump partition\n");
+        break;
+    default:
+        printf("not supported\n");
+        break;
+    }
+}
+
+static int file_setup_command(int argc, char * __attribute__((unused)) argv[])
+{
+    if (!mrdump_is_supported()) {
+        error("file-setup not allowed in this mode.\n");
+    }
+    if (argc != 1) {
+        error("Invalid file-setup command argument\n");
+    }
+    mrdump_file_setup(false);
+    return 0;
+}
+
+static void file_allocate_command(int argc, char *argv[])
+{
+    if (!mrdump_is_supported()) {
+        error("file-allocate not allowed in this mode.\n");
+    }
+    if (argc != 2) {
+        error("Invaid file-allocate command argument\n");
+    }
+    int size_m = atoi(argv[1]);
+
+    if (size_m < 0)
+        size_m = 0;
+
+    if ((size_m <= 2) || (size_m >= MRDUMP_EXT4_MIN_ALLOCATE)) {
+        // enable condition: only 0, 1, 2, >256
+        mrdump_file_set_maxsize(size_m);
+    }
+    else {
+        error("Invalid dump size %d\n", size_m);
+    }
+}
+
+static int file_extract_core_command(int argc, char *argv[])
+{
+    int opt;
+    bool reinit = false;
+
+    while ((opt = getopt(argc, argv, "r")) != -1) {
+        switch (opt) {
+        case 'r':
+            reinit = true;
+            break;
+        default:
+            error("Invalid file-extract-core parameter\n");
+        }
+    }
+    if (optind >= argc) {
+        error("Expected filename after options\n");
+    }
+
+    const char *fn = argv[optind];
+    const char *output_dev = sysenv_get("mrdump_output");
+
+    MD_LOGI("%s: mrdump_output= %s\n",__func__, output_dev);
+
+    if (output_dev) {
+        if (!strncmp(output_dev, "partition", 9)) {
+            MD_LOGI("%s: partition solution\n",__func__);
+            if (mrdump_file_fetch_zip_coredump_partition(fn)) {
+                return 0;
+            }
+        }
+        else if (!strncmp(output_dev, "internal-storage", 21)) {
+            MD_LOGI("%s: ext4 solution\n",__func__);
+            if (mrdump_file_fetch_zip_coredump(fn)) {
+                mrdump_file_setup(reinit);
+                return 0;
+            }
+        }
+    }
+
+    error("Fetching Coredump data failed\n");
+}
+
+static int file_info_command(int argc, char * __attribute__((unused)) argv[])
+{
+    if (argc != 1) {
+        error("Invalid file-info command argument\n");
+    }
+
+    struct mrdump_pafile_info info;
+    if (mrdump_file_get_info(MRDUMP_EXT4_ALLOCATE_FILE, &info)) {
+        printf("\tInfo LBA :      %" PRIu32 "\n"
+               "\tAddress LBA :   %" PRIu32 "\n"
+               "\tFile Size :     %" PRIu64 "\n"
+               "\tCoredump Size : %" PRIu64 "\n"
+               "\tTimestamp :     %" PRIx64 "\n",
+               info.info_lba, info.addr_lba,
+               info.filesize, info.coredump_size,
+               info.timestamp
+              );
+        return 0;
+    }
+    else {
+        error("Cannot get pre-allocate file info\n");
+    }
+}
+
+static void mem_size_set_command(int argc, char *argv[])
+{
+    char msize[5];
+
+    if (argc != 2) {
+        error("Invaid mem-size-set command argument\n");
+    }
+
+    int size_m = atoi(argv[1]);
+    if ((size_m == 0) || ((size_m >= 64) && (size_m <= 16 * 1024))) {
+        if (size_m != 0) {
+            snprintf(msize, sizeof(msize), "%d", size_m);
+            if (sysenv_set("mrdump_mem_size", msize) == 0) {
+                MD_LOGI("mem-size-set done.\n");
+            }
+        }
+        else {
+            if (sysenv_set("mrdump_mem_size", "") == 0) {
+                MD_LOGI("total-mem-size done.\n");
+            }
+            else {
+                error("failed to set memory dump size, plz try again later.\n");
+            }
+        }
+    }
+    else {
+        error("Invalid memory dump size\n");
+    }
+}
+
+static void output_set_command(int argc, char *argv[])
+{
+    if(argc < 2) {
+        error("Invalid output device, valid input [none, null, usb, partition, internal-storage]\n");
+    }
+    else {
+        const char *output_dev = argv[1];
+        int need_reboot = 0;
+        const char *prev_output_dev = sysenv_get("mrdump_output");
+
+        if (strcmp(prev_output_dev, "partition") == 0) {
+            if (mrdump_check_partition()) {
+                need_reboot = 1;
+            }
+        }
+        if (strcmp(output_dev, "partition") == 0) {
+            if (!mrdump_check_partition()) {
+                error("mrdump partition doesn't exist, cannot dump to partition.\n");
+            }
+            need_reboot = 1;
+        }
+        else if (strcmp(output_dev, "none") &&
+                 strcmp(output_dev, "null") &&
+                 strcmp(output_dev, "usb") &&
+                 strcmp(output_dev, "internal-storage")) {
+            error("Unknown output %s\n", output_dev);
+        }
+
+        if (sysenv_set("mrdump_output", output_dev) == 0) {
+            MD_LOGI("mrdump_output = %s\n", output_dev);
+        }
+        else {
+            error("output-set failed.(%s)\n", output_dev);
+        }
+
+        if (strcmp(output_dev, "internal-storage") == 0) {
+            mrdump_file_set_maxsize(DEFAULT_FULLMEM);
+        }
+        else {
+            mrdump_file_set_maxsize(DEFAULT_DISABLE);
+        }
+
+        if (need_reboot) {
+            if (0 > execl("/system/bin/reboot", "reboot", NULL, NULL))
+                error("%s: failed to reboot into LK for partition resize.\n", __func__);
+        }
+    }
+}
+
+static void status_get_command(int __attribute((unused)) argc,
+                               char * __attribute ((unused)) argv[])
+{
+    struct mrdump_status_result result;
+    if (mrdump_status_get(&result)) {
+        printf("MT-RAMDUMP\n\tStatus:");
+        switch (result.status) {
+        case MRDUMP_STATUS_NONE:
+            printf("None\n");
+            break;
+        case MRDUMP_STATUS_FAILED:
+            printf("Failed\n");
+            break;
+        case MRDUMP_STATUS_OK:
+            dump_status_ok(&result);
+            break;
+        }
+    }
+    else {
+        error("MT-RAMDUMP get status failed\n");
+    }
+}
+
+static int parse_log_level(const char *log_level)
+{
+    if (strcmp(log_level, "debug") == 0)
+        return LOG_DEBUG;
+    else if (strcmp(log_level, "info") == 0)
+        return LOG_INFO;
+    else if (strcmp(log_level, "warn") == 0)
+        return LOG_WARNING;
+    else if (strcmp(log_level, "error") == 0)
+        return LOG_ERR;
+    return LOG_WARNING;
+}
+
+int main(int argc, char *argv[])
+{
+    int log_level = LOG_WARNING;
+    int log_syslog = 0;
+
+    static struct option long_options[]= {
+        {"help", no_argument, 0, 0},
+        {"log-level", required_argument, 0, 0},
+        {"log-syslog", no_argument, 0, 0},
+        {0, 0, 0, 0},
+    };
+
+    while (1) {
+        int option_index, c;
+        c = getopt_long(argc, argv, "+", long_options, &option_index);
+        if (c == -1)
+            break;
+
+        switch (c) {
+        case 0:
+            if (strcmp(long_options[option_index].name, "log-level") == 0) {
+                log_level = parse_log_level(optarg);
+            }
+            else if (strcmp(long_options[option_index].name, "log-syslog") == 0) {
+                log_syslog = 1;
+            }
+            else if (strcmp(long_options[option_index].name, "help") == 0) {
+                usage(argv[0]);
+            }
+            break;
+
+        default:
+            usage(argv[0]);
+        }
+    }
+
+    mdlog_init(log_level, log_syslog);
+
+    const int command_argc = argc - optind;
+    if (command_argc < 1) {
+        error("No command given\n");
+    }
+    const char *command = argv[optind];
+    char **command_argv = &argv[optind];
+
+    if (strcmp(command, "is-supported") == 0) {
+        if (mrdump_is_supported()) {
+            printf("MT-RAMDUMP support ok\n");
+        }
+        else {
+            printf("MT-RAMDUMP not support\n");
+        }
+    }
+    else if (strcmp(command, "status-get") == 0) {
+        status_get_command(command_argc, command_argv);
+    }
+    else if (strcmp(command, "status-log") == 0) {
+        struct mrdump_status_result result;
+        bool res = mrdump_status_get(&result);
+
+        printf("=>status line:\n%s\n=>log:\n%s\n", result.status_line, result.log_buf);
+        if (!res) {
+            error("MT-RAMDUMP get status failed\n");
+        }
+    }
+    else if (strcmp(command, "status-clear") == 0) {
+        if (!mrdump_is_supported()) {
+            error("MT-RAMDUMP not support\n");
+        }
+        if (!mrdump_status_clear()) {
+            error("MT-RAMDUMP Status clear failed\n");
+        }
+    }
+    else if (strcmp(command, "file-setup") == 0) {
+        file_setup_command(command_argc, command_argv);
+    }
+    else if (strcmp(command, "file-allocate") == 0) {
+        file_allocate_command(command_argc, command_argv);
+    }
+    else if (strcmp(command, "file-extract-core") == 0) {
+        file_extract_core_command(command_argc, command_argv);
+    }
+    else if (strcmp(command, "file-info") == 0) {
+        file_info_command(command_argc, command_argv);
+    }
+    else if (strcmp(command, "mem-size-set") == 0) {
+        mem_size_set_command(command_argc, command_argv);
+    }
+    else if (strcmp(command, "output-set") == 0) {
+        output_set_command(command_argc, command_argv);
+    }
+    else if (strcmp(command, "partition") == 0) {
+        /* ignored "-Wunused-result" */
+        if (1 == mrdump_check_partition()) {;}
+    }
+    else if (strcmp(command, "output-get") == 0) {
+        const char *output_dev = sysenv_get("mrdump_output");
+        if (!output_dev) {
+            printf("default\n");
+        }
+        else {
+            printf("%s\n", output_dev);
+        }
+    }
+    else {
+        error("Unknown command %s\n", command);
+    }
+
+    return 0;
+}