[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/lib/aee/mrdump_elf.c b/src/bsp/lk/lib/aee/mrdump_elf.c
new file mode 100644
index 0000000..c24a813
--- /dev/null
+++ b/src/bsp/lk/lib/aee/mrdump_elf.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2018 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 <kernel/vm.h>
+#include <malloc.h>
+#include <printf.h>
+#include <stdlib.h>
+#include <string.h>
+#include "kdump.h"
+#include "mrdump_elf.h"
+
+/* An ELF note in memory */
+struct memelfnote {
+    const char *name;
+    int type;
+    unsigned int datasz;
+    void *data;
+};
+
+static int notesize(struct memelfnote *en)
+{
+    int sz;
+
+    sz = sizeof(struct elf_note);
+    sz += ROUNDUP((strlen(en->name) + 1), 4);
+    sz += ROUNDUP(en->datasz, 4);
+
+    return sz;
+}
+
+static uint8_t *storenote(struct memelfnote *men, uint8_t *bufp)
+{
+    struct elf_note en;
+    en.n_namesz = strlen(men->name) + 1;
+    en.n_descsz = men->datasz;
+    en.n_type = men->type;
+
+    memcpy(bufp, &en, sizeof(en));
+    bufp += sizeof(en);
+
+    memcpy(bufp, men->name, en.n_namesz);
+    bufp += en.n_namesz;
+
+    bufp = (uint8_t *) ROUNDUP((unsigned long)bufp, 4);
+    memcpy(bufp, men->data, men->datasz);
+    bufp += men->datasz;
+
+    bufp = (uint8_t *) ROUNDUP((unsigned long)bufp, 4);
+    return bufp;
+}
+
+static uint8_t *kdump_core_write_cpu_note(const struct mrdump_control_block *mrdump_cb, int cpu, struct elf32_phdr *nhdr, uint8_t *bufp)
+{
+    struct memelfnote notes;
+    struct elf32_arm_prstatus prstatus;
+    char cpustr[16];
+
+    memset(&prstatus, 0, sizeof(struct elf32_arm_prstatus));
+
+    snprintf(cpustr, sizeof(cpustr), "CPU%d", cpu);
+    /* set up the process status */
+    notes.name = cpustr;
+    notes.type = NT_PRSTATUS;
+    notes.datasz = sizeof(struct elf32_arm_prstatus);
+    notes.data = &prstatus;
+
+    prstatus.pr_pid = cpu + 1;
+    memcpy(&prstatus.pr_reg, (unsigned long *)&mrdump_cb->crash_record.cpu_regs[cpu].arm32_regs, sizeof(elf_arm_gregset_t));
+
+    nhdr->p_filesz += notesize(&notes);
+    return storenote(&notes, bufp);
+}
+
+static uint8_t *kdump_core_write_machdesc(const struct mrdump_control_block *mrdump_cb, struct elf32_phdr *nhdr, uint8_t *bufp)
+{
+    struct memelfnote notes;
+    struct elf_mrdump_machdesc machdesc;
+    const struct mrdump_machdesc *kparams = &mrdump_cb->machdesc;
+
+    memset(&machdesc, 0, sizeof(struct elf_mrdump_machdesc));
+
+    notes.name = "MRDUMP01";
+    notes.type = NT_MRDUMP_MACHDESC;
+    notes.datasz = sizeof(struct elf_mrdump_machdesc);
+    notes.data = &machdesc;
+
+    machdesc.flags = MRDUMP_TYPE_FULL_MEMORY;
+    machdesc.nr_cpus = kparams->nr_cpus;
+    machdesc.phys_offset = kparams->phys_offset;
+    machdesc.page_offset = kparams->page_offset;
+    machdesc.high_memory = kparams->high_memory;
+    machdesc.kimage_vaddr = kparams->kimage_vaddr;
+    machdesc.modules_start = kparams->modules_start;
+    machdesc.modules_end = kparams->modules_end;
+    machdesc.vmalloc_start = kparams->vmalloc_start;
+    machdesc.vmalloc_end = kparams->vmalloc_end;
+    machdesc.master_page_table = kparams->master_page_table;
+
+    nhdr->p_filesz += notesize(&notes);
+    return storenote(&notes, bufp);
+}
+
+static uint8_t *kdump_core_write_mrdump_cb(const struct mrdump_control_block *mrdump_cb, struct elf32_phdr *nhdr, uint8_t *bufp)
+{
+    struct memelfnote notes;
+    uint64_t mrdump_cb_paddr = (uint64_t)(uintptr_t)kvaddr_to_paddr((void *)mrdump_cb);
+
+    notes.name = MRDUMP_GO_DUMP;
+    notes.type = NT_MRDUMP_CBLOCK;
+    notes.datasz = sizeof(mrdump_cb_paddr);
+    notes.data = &mrdump_cb_paddr;
+
+    nhdr->p_filesz += notesize(&notes);
+    return storenote(&notes, bufp);
+}
+
+void kdump_core32_header_init(const struct mrdump_control_block *mrdump_cb, const struct kzip_addlist *memlist)
+{
+    struct elf32_phdr *nhdr, *phdr;
+    struct elf32_hdr *elf;
+    off_t offset = 0;
+    const struct mrdump_machdesc *kparams = &mrdump_cb->machdesc;
+
+    uint8_t *bufp = (uint8_t *)(uintptr_t)memlist[0].address;
+
+    elf = (struct elf32_hdr *) bufp;
+    bufp += sizeof(struct elf32_hdr);
+    offset += sizeof(struct elf32_hdr);
+
+    nhdr = (struct elf32_phdr *) bufp;
+    bufp += sizeof(struct elf32_phdr);
+    offset += sizeof(struct elf32_phdr);
+    memset(nhdr, 0, sizeof(struct elf32_phdr));
+    nhdr->p_type = PT_NOTE;
+
+    unsigned long long foffset = KDUMP_CORE_HEADER_SIZE;
+    int i;
+    for (i = 1; memlist[i].address != 0; i++) {
+        phdr = (struct elf32_phdr *) bufp;
+        bufp += sizeof(struct elf32_phdr);
+        offset += sizeof(struct elf32_phdr);
+
+        phdr->p_type    = PT_LOAD;
+        phdr->p_flags   = PF_R|PF_W|PF_X;
+        phdr->p_offset  = foffset;
+        phdr->p_vaddr   = 0;
+        phdr->p_paddr   = (Elf32_Addr)kvaddr_to_paddr((void *)memlist[i].address);
+        phdr->p_filesz  = memlist[i].size;
+        phdr->p_memsz   = memlist[i].size;
+        phdr->p_align   = 0;
+
+        foffset += phdr->p_filesz;
+    }
+
+    mrdump_elf_setup_eident(elf->e_ident, ELFCLASS32);
+    mrdump_elf_setup_elfhdr(elf, EM_ARM, struct elf32_hdr, struct elf32_phdr, i);
+
+    nhdr->p_offset = offset;
+
+    /* NT_PRPSINFO */
+    struct elf32_prpsinfo prpsinfo;
+    struct memelfnote notes;
+    /* set up the process info */
+    notes.name = CORE_STR;
+    notes.type = NT_PRPSINFO;
+    notes.datasz = sizeof(struct elf32_prpsinfo);
+    notes.data = &prpsinfo;
+
+    memset(&prpsinfo, 0, sizeof(struct elf32_prpsinfo));
+    prpsinfo.pr_state = 0;
+    prpsinfo.pr_sname = 'R';
+    prpsinfo.pr_zomb = 0;
+    prpsinfo.pr_gid = prpsinfo.pr_uid = mrdump_cb->crash_record.fault_cpu + 1;
+    strlcpy(prpsinfo.pr_fname, "vmlinux", sizeof(prpsinfo.pr_fname));
+    strlcpy(prpsinfo.pr_psargs, "vmlinux", ELF_PRARGSZ);
+
+    nhdr->p_filesz += notesize(&notes);
+    bufp = storenote(&notes, bufp);
+
+    bufp = kdump_core_write_machdesc(mrdump_cb, nhdr, bufp);
+
+    /* Store pre-cpu backtrace */
+    bufp = kdump_core_write_cpu_note(mrdump_cb, mrdump_cb->crash_record.fault_cpu, nhdr, bufp);
+    for (unsigned int cpu = 0; cpu < kparams->nr_cpus; cpu++) {
+        if (cpu != mrdump_cb->crash_record.fault_cpu) {
+            bufp = kdump_core_write_cpu_note(mrdump_cb, cpu, nhdr, bufp);
+        }
+    }
+
+    /* store mrdump control block */
+    bufp = kdump_core_write_mrdump_cb(mrdump_cb, nhdr, bufp);
+}