diff --git a/dcc_parser/dcc_parser.py b/dcc_parser/dcc_parser.py
index b296cd52acdda87c0b95a3a1d95065e86e4a6264..bfa26ebe6f283668896f9a8dd165c222ece3d8c6 100644
--- a/dcc_parser/dcc_parser.py
+++ b/dcc_parser/dcc_parser.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, The Linux Foundation. All rights reserved.
+# Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -44,6 +44,12 @@ def add_addr(base, offset, length):
         address.append(addr)
 
 
+def add_loop_addr(loop_nr, loop_count):
+    for i in range(0, loop_count):
+        for j in range(len(address) - loop_nr, len(address)):
+            address.append(address[j])
+
+
 def read_data(data_pt):
     nr = count
     while nr > 0:
@@ -59,9 +65,30 @@ def read_data(data_pt):
 
 
 def read_config(config_pt):
-    nr = 0
+    list_nr = []
+    list_nr.append(0)
     offset = 0
     base = 0
+
+    if options.version is None:
+        address_descriptor = 0x1 << 31
+        link_descriptor = 0
+        loop_descriptor = None
+        rd_mod_wr_descriptor = None
+        dcc_write_ind = None
+        link_second_arg = 8
+        # We return zero and fail
+        on_zero_link_len = 0
+    else:
+        address_descriptor = 0
+        link_descriptor = 0x3 << 30
+        loop_descriptor = 0x1 << 30
+        rd_mod_wr_descriptor = 0x1 << 31
+	dcc_write_ind = 0x1 << 28
+        link_second_arg = 7
+        #indicates end of list
+        on_zero_link_len = -1
+
     while True:
         word = config_pt.read(4)
         if len(word) != 4:
@@ -72,27 +99,64 @@ def read_config(config_pt):
         if val == 0:
             break
 
-        if val & (1 << 31):
+        descriptor = val & (0x3 << 30)
+	read_write_ind = val & (0x1 << 28)
+
+	if read_write_ind == dcc_write_ind:
+            config_pt.seek(8, 1)
+        elif descriptor == address_descriptor:
             base = ((val & 0x0FFFFFFF) << 4)
             offset = 0
-        else:
+        elif descriptor == link_descriptor:
             for i in range(0, 2):
                 offset = offset + (val & 0xFF) * 4
                 val = val >> 8
 
                 length = (val & 0x7f)
-                val = val >> 8
+                val = val >> link_second_arg
 
                 if length != 0:
-                    nr += length
+                    list_nr.append(length + list_nr[- 1])
                     add_addr(base, offset, length)
                 else:
-                    if (i == 0):
-                        log.error("Error! Found zero length!")
-                        return 0
+                    if (i == 0 ):
+                        return list_nr[on_zero_link_len]
                     else:
                         offset = 0
-    return nr
+        elif descriptor == loop_descriptor:
+            loop_offset = val & 0x1FFF
+            loop_count = (val & 0xFFFE000) >> 13
+
+            if loop_offset == 0:
+                continue
+
+            loop_nr = list_nr[-1] - list_nr[-loop_offset]
+            list_nr.append(loop_nr * loop_count + list_nr[-1])
+            add_loop_addr(loop_nr, loop_count)
+
+        elif descriptor == rd_mod_wr_descriptor:
+            '''
+            Skip over mask and value of rd_mod_wr.
+            There is no gaurantee of this being actually written
+            and we never read the value back to confirm.
+            '''
+            config_pt.seek(8, 1)
+
+    return list_nr[-1]
+
+
+def new_linked_list(config_pt):
+    word = config_pt.read(4)
+
+    if len(word)!= 4:
+        return False
+    else:
+        val = struct.unpack('<L', word)[0]
+        if val != 0:
+            config_pt.seek(-4, 1)
+            return True
+        else:
+            return False
 
 
 def dump_regs_json(options):
@@ -128,11 +192,16 @@ def dump_regs_xml(options):
 
 
 def dump_regs(options):
+    if not address:
+        log.error('No configuration found in SRAM!!')
+        sys.exit(1)
+
     if options.json is True:
         dump_regs_json(options)
     else:
         dump_regs_xml(options)
 
+
 if __name__ == '__main__':
     usage = 'usage: %prog [options to print]. Run with --help for more details'
     parser = OptionParser(usage)
@@ -148,6 +217,8 @@ if __name__ == '__main__':
     parser.add_option('', '--chip-name', dest='chipname', help='chip name')
     parser.add_option('', '--chip-version', dest='chipversion',
                       help='chip version')
+    parser.add_option('--v2', dest='version', action="store_const", const='2',
+                      help='DCC driver version 2')
 
     (options, args) = parser.parse_args()
 
@@ -199,18 +270,20 @@ if __name__ == '__main__':
             sys.exit(1)
 
     count = 0
-    count = read_config(sram_file)
-    if options.atbfile is None:
-        atb_file = sram_file
-    if count == 0:
-        log.error('No configuration found in SRAM!!')
-        sys.exit(1)
+    while True:
+        count = read_config(sram_file)
 
-    if read_data(atb_file):
-        log.error('Couldn\'t read complete data.')
-    else:
-        parsed_data = log_init('PARSED_DATA', options.outdir, options.outfile)
-        dump_regs(options)
+        if options.atbfile is None:
+            atb_file = sram_file
+
+        if read_data(sram_file):
+            log.error('Couldn\'t read complete data.')
+            break
+
+        if new_linked_list(sram_file) is False:
+            parsed_data = log_init('PARSED_DATA', options.outdir, options.outfile)
+            dump_regs(options)
+            break
 
     sram_file.close()
 
diff --git a/linux-ramdump-parser-v2/README b/linux-ramdump-parser-v2/README
index efeea31b704496bf2a433ad2decd78694b32158a..ac50385e585f2d8409b5bd9e69f94e35bd6e7acd 100644
--- a/linux-ramdump-parser-v2/README
+++ b/linux-ramdump-parser-v2/README
@@ -72,6 +72,11 @@ specify the paths to these tools. This can be done in three ways
 1) Using --gdb-path and --nm-path to specify the absolute path
 2) Using CROSS_COMPILE to specify the prefix
 3) Using local_settings.py as described below
+4) Install this library from https://github.com/eliben/pyelftools
+    - Download the code from avobe github link. Download the zip file.
+    - After download the zip file, you will find a folder pyelftools-master.
+    - Inside this folder you will find another folder named "elftools"
+	- copy that entire folder and paste it in below directory <installed Python path>\Lib\site-packages
 
 Just having gdb/nm on the path is not supported as there are too many
 variations on names to invoke.
diff --git a/linux-ramdump-parser-v2/boards.py b/linux-ramdump-parser-v2/boards.py
old mode 100755
new mode 100644
index 3909b106623b8774ad99ede4b8d907230b00d093..fc96d4dcb10a9cbc6f71baf349f91e20ef9ea1cc
--- a/linux-ramdump-parser-v2/boards.py
+++ b/linux-ramdump-parser-v2/boards.py
@@ -451,6 +451,7 @@ class Board660(Board):
         self.cpu = 'CORTEXA53'
         self.ram_start = 0x80000000
         self.smem_addr = 0x6000000
+        self.smem_addr_buildinfo = 0x6006ec0
         self.phys_offset = 0x80000000
         self.imem_start = 0x14680000
         self.kaslr_addr = 0x146bf6d0
diff --git a/linux-ramdump-parser-v2/cachedumplib.py b/linux-ramdump-parser-v2/cachedumplib.py
index ce5014be815fbfa28d846ae77cd403c4e57fafa5..40ba0cfc1196814da5569035604c5a4d93dd2020 100644
--- a/linux-ramdump-parser-v2/cachedumplib.py
+++ b/linux-ramdump-parser-v2/cachedumplib.py
@@ -445,7 +445,7 @@ class L1_DCache_KRYO3XX_SILVER(CacheDumpType_v1):
         self.NumSets = 0x80
         self.NumWays = 4
 
-    def MESI_to_string(MESI_d):
+    def MESI_to_string(self, MESI_d):
         if MESI_d == 0:
             return 'I'
         elif MESI_d == 1:
@@ -483,7 +483,7 @@ class L1_ICache_KRYO3XX_SILVER(CacheDumpType_v1):
         self.NumSets = 0x80
         self.NumWays = 4
 
-    def valid_to_string(valid_d):
+    def valid_to_string(self, valid_d):
         if valid_d == 0:
             return 'A32'
         elif valid_d == 1:
@@ -518,7 +518,7 @@ class L1_DCache_KRYO3XX_GOLD(CacheDumpType_v1):
         self.NumSets = 0x40
         self.NumWays = 16
 
-    def MESI_to_string(MESI_d):
+    def MESI_to_string(self, MESI_d):
         if MESI_d == 0:
             return 'I'
         elif MESI_d == 1:
@@ -537,7 +537,7 @@ class L1_DCache_KRYO3XX_GOLD(CacheDumpType_v1):
         mesi_d = (data[0] >> 2) & 0x3
 
         addr = (addr_higher << 22) | addr_lower
-        mesi = MESI_to_string(mesi_d)
+        mesi = self.MESI_to_string(mesi_d)
         output.append(addr)
         output.append(mesi)
 
diff --git a/linux-ramdump-parser-v2/debug_image_v2.py b/linux-ramdump-parser-v2/debug_image_v2.py
old mode 100755
new mode 100644
index 51539703c26f8c1c671ad02367f14143594d9328..5e6332a970db917c28675cb722962d21fe52b562
--- a/linux-ramdump-parser-v2/debug_image_v2.py
+++ b/linux-ramdump-parser-v2/debug_image_v2.py
@@ -86,6 +86,25 @@ qdss_tag_to_field_name = {
     'MSM_DUMP_DATA_DBGUI_REG': 'dbgui_start',
 }
 
+# Client functions will be executed in top-to-bottom order
+minidump_dump_table_type = [
+    ('MSM_DUMP_DATA_SCANDUMP', 'KSCANDUMP'),
+    ('MSM_DUMP_DATA_CPU_CTX', 'KCPU_CTX'),
+    ('MSM_DUMP_DATA_L1_INST_TLB', 'KCPUSS'),
+    ('MSM_DUMP_DATA_L1_DATA_TLB','KCPUSS'),
+    ('MSM_DUMP_DATA_L1_INST_CACHE', 'KCPUSS'),
+    ('MSM_DUMP_DATA_L1_DATA_CACHE', 'KCPUSS'),
+    ('MSM_DUMP_DATA_L2_CACHE', 'KCPUSS'),
+    ('MSM_DUMP_DATA_L3_CACHE', 'KCPUSS'),
+    ('MSM_DUMP_DATA_VSENSE', 'KVSENSE'),
+    ('MSM_DUMP_DATA_PMIC', 'KPMIC'),
+    ('MSM_DUMP_DATA_DCC_REG', 'KDCC_REG'),
+    ('MSM_DUMP_DATA_DCC_SRAM', 'KDCC_SRAM'),
+    ('MSM_DUMP_DATA_TMC_ETF', 'KTMC_ETF'),
+    ('MSM_DUMP_DATA_TMC_REG', 'KTMC_REG')
+
+]
+
 class DebugImage_v2():
 
     def __init__(self, ramdump):
@@ -476,7 +495,7 @@ class DebugImage_v2():
                             client_entry + dump_entry_id_offset, False)
 
             if (client_id < 0 or
-                    client_id > len(self.dump_data_id_lookup_table)):
+                    client_id >= len(self.dump_data_id_lookup_table)):
                 print_out_str(
                     '!!! Invalid dump client id found {0:x}'.format(client_id))
                 continue
@@ -491,6 +510,21 @@ class DebugImage_v2():
 
         results.sort(key=lambda(x): client_names.index(x[0]))
         return results
+    def minidump_data_clients(self, ram_dump, client_id,entry_pa_addr,
+                                      end_addr):
+        results = list()
+        client_table = dict(client_types)
+        # get first column of client_types
+
+        client_name = self.dump_data_id_lookup_table[client_id]
+
+        if client_name not in client_table:
+            print_out_str(
+                '!!! {0} Does not have an associated function. Skipping!'.format(client_name))
+            return None
+
+        results.append((client_name, client_id,client_table[client_name], entry_pa_addr,end_addr))
+        return results
 
     def parse_dump_v2(self, ram_dump):
         self.dump_type_lookup_table = ram_dump.gdbmi.get_enum_lookup_table(
@@ -532,141 +566,207 @@ class DebugImage_v2():
             client.MSM_DUMP_DATA_LOG_BUF_FIRST_IDX] = 'MSM_DUMP_DATA_LOG_BUF_FIRST_IDX'
         self.dump_data_id_lookup_table[
             client.MSM_DUMP_DATA_L2_TLB] = 'MSM_DUMP_DATA_L2_TLB'
-        dump_table_ptr_offset = ram_dump.field_offset(
-            'struct msm_memory_dump', 'table')
-        dump_table_version_offset = ram_dump.field_offset(
-            'struct msm_dump_table', 'version')
-        dump_table_num_entry_offset = ram_dump.field_offset(
-            'struct msm_dump_table', 'num_entries')
-        dump_table_entry_offset = ram_dump.field_offset(
-            'struct msm_dump_table', 'entries')
-        dump_entry_id_offset = ram_dump.field_offset(
-            'struct msm_dump_entry', 'id')
-        dump_entry_name_offset = ram_dump.field_offset(
-            'struct msm_dump_entry', 'name')
-        dump_entry_type_offset = ram_dump.field_offset(
-            'struct msm_dump_entry', 'type')
-        dump_entry_addr_offset = ram_dump.field_offset(
-            'struct msm_dump_entry', 'addr')
-        dump_data_version_offset = ram_dump.field_offset(
-            'struct msm_dump_data', 'version')
-        dump_data_magic_offset =  ram_dump.field_offset(
-            'struct msm_dump_data', 'magic')
-        dump_data_name_offset = ram_dump.field_offset(
-            'struct msm_dump_data', 'name')
-        dump_data_addr_offset = ram_dump.field_offset(
-            'struct msm_dump_data', 'addr')
-        dump_data_len_offset = ram_dump.field_offset(
-            'struct msm_dump_data', 'len')
-        dump_data_reserved_offset = ram_dump.field_offset(
-            'struct msm_dump_data', 'reserved')
-        dump_entry_size = ram_dump.sizeof('struct msm_dump_entry')
-        dump_data_size = ram_dump.sizeof('struct msm_dump_data')
-
-        mem_dump_data = ram_dump.address_of('memdump')
-
-        mem_dump_table = ram_dump.read_word(
-            mem_dump_data + dump_table_ptr_offset)
-
-        mem_table_version = ram_dump.read_u32(
-            mem_dump_table + dump_table_version_offset)
-        if mem_table_version is None:
-            print_out_str('Version is bogus! Can\'t parse debug image')
-            return
-        mem_table_num_entry = ram_dump.read_u32(
-            mem_dump_table + dump_table_num_entry_offset)
-        if mem_table_num_entry is None or mem_table_num_entry > 100:
-            print_out_str('num_entries is bogus! Can\'t parse debug image')
-            return
-
-        print_out_str('\nDebug image version: {0}.{1} Number of table entries {2}'.format(
-            mem_table_version >> 20, mem_table_version & 0xFFFFF, mem_table_num_entry))
-        print_out_str('--------')
-
-        for i in range(0, mem_table_num_entry):
-            this_entry = mem_dump_table + dump_table_entry_offset + \
-                i * dump_entry_size
-            entry_id = ram_dump.read_u32(this_entry + dump_entry_id_offset)
-            entry_type = ram_dump.read_u32(this_entry + dump_entry_type_offset)
-            entry_addr = ram_dump.read_word(this_entry + dump_entry_addr_offset)
-
-            if entry_id < 0 or entry_id > len(self.dump_table_id_lookup_table):
-                print_out_str(
-                    '!!! Invalid dump table entry id found {0:x}'.format(entry_id))
-                continue
-
-            if entry_type > len(self.dump_type_lookup_table):
-                print_out_str(
-                    '!!! Invalid dump table entry type found {0:x}'.format(entry_type))
-                continue
 
-            table_version = ram_dump.read_u32(
-                entry_addr + dump_table_version_offset, False)
-            if table_version is None:
-                print_out_str('Dump table entry version is bogus! Can\'t parse debug image')
+        if not ram_dump.minidump:
+            dump_table_ptr_offset = ram_dump.field_offset(
+                'struct msm_memory_dump', 'table')
+            dump_table_version_offset = ram_dump.field_offset(
+                'struct msm_dump_table', 'version')
+            dump_table_num_entry_offset = ram_dump.field_offset(
+                'struct msm_dump_table', 'num_entries')
+            dump_table_entry_offset = ram_dump.field_offset(
+                'struct msm_dump_table', 'entries')
+            dump_entry_id_offset = ram_dump.field_offset(
+                'struct msm_dump_entry', 'id')
+            dump_entry_name_offset = ram_dump.field_offset(
+                'struct msm_dump_entry', 'name')
+            dump_entry_type_offset = ram_dump.field_offset(
+                'struct msm_dump_entry', 'type')
+            dump_entry_addr_offset = ram_dump.field_offset(
+                'struct msm_dump_entry', 'addr')
+            dump_data_version_offset = ram_dump.field_offset(
+                'struct msm_dump_data', 'version')
+            dump_data_magic_offset =  ram_dump.field_offset(
+                'struct msm_dump_data', 'magic')
+            dump_data_name_offset = ram_dump.field_offset(
+                'struct msm_dump_data', 'name')
+            dump_data_addr_offset = ram_dump.field_offset(
+                'struct msm_dump_data', 'addr')
+            dump_data_len_offset = ram_dump.field_offset(
+                'struct msm_dump_data', 'len')
+            dump_data_reserved_offset = ram_dump.field_offset(
+                'struct msm_dump_data', 'reserved')
+            dump_entry_size = ram_dump.sizeof('struct msm_dump_entry')
+            dump_data_size = ram_dump.sizeof('struct msm_dump_data')
+
+            mem_dump_data = ram_dump.address_of('memdump')
+
+            mem_dump_table = ram_dump.read_word(
+                mem_dump_data + dump_table_ptr_offset)
+
+            mem_table_version = ram_dump.read_u32(
+                mem_dump_table + dump_table_version_offset)
+            if mem_table_version is None:
+                print_out_str('Version is bogus! Can\'t parse debug image')
                 return
-            table_num_entries = ram_dump.read_u32(
-                entry_addr + dump_table_num_entry_offset, False)
-            if table_num_entries is None or table_num_entries > 100:
-                print_out_str('Dump table entry num_entries is bogus! Can\'t parse debug image')
+            mem_table_num_entry = ram_dump.read_u32(
+                mem_dump_table + dump_table_num_entry_offset)
+            if mem_table_num_entry is None or mem_table_num_entry > 100:
+                print_out_str('num_entries is bogus! Can\'t parse debug image')
                 return
 
-            print_out_str(
-                'Debug image version: {0}.{1} Entry id: {2} Entry type: {3} Number of entries: {4}'.format(
-                    table_version >> 20, table_version & 0xFFFFF, self.dump_table_id_lookup_table[entry_id],
-                    self.dump_type_lookup_table[entry_type], table_num_entries))
-
-            lst = self.sorted_dump_data_clients(
-                    ram_dump, entry_addr + dump_table_entry_offset,
-                    table_num_entries)
-            for (client_name, func, client_entry) in lst:
-                print_out_str('--------')
-                client_id = ram_dump.read_u32(
-                                client_entry + dump_entry_id_offset, False)
-                client_type = ram_dump.read_u32(
-                                client_entry + dump_entry_type_offset, False)
-                client_addr = ram_dump.read_word(
-                                client_entry + dump_entry_addr_offset, False)
-
-                if client_type > len(self.dump_type_lookup_table):
+            print_out_str('\nDebug image version: {0}.{1} Number of table entries {2}'.format(
+                mem_table_version >> 20, mem_table_version & 0xFFFFF, mem_table_num_entry))
+            print_out_str('--------')
+
+            for i in range(0, mem_table_num_entry):
+                this_entry = mem_dump_table + dump_table_entry_offset + \
+                    i * dump_entry_size
+                entry_id = ram_dump.read_u32(this_entry + dump_entry_id_offset)
+                entry_type = ram_dump.read_u32(this_entry + dump_entry_type_offset)
+                entry_addr = ram_dump.read_word(this_entry + dump_entry_addr_offset)
+
+                if entry_id < 0 or entry_id > len(self.dump_table_id_lookup_table):
                     print_out_str(
-                        '!!! Invalid dump client type found {0:x}'.format(client_type))
+                        '!!! Invalid dump table entry id found {0:x}'.format(entry_id))
                     continue
 
-                dump_data_magic = ram_dump.read_u32(
-                                client_addr + dump_data_magic_offset, False)
-                dump_data_version = ram_dump.read_u32(
-                                client_addr + dump_data_version_offset, False)
-                dump_data_name = ram_dump.read_cstring(
-                        client_addr + dump_data_name_offset,
-                        ram_dump.sizeof('((struct msm_dump_data *)0x0)->name'),
-                        False)
-                dump_data_addr = ram_dump.read_dword(
-                                    client_addr + dump_data_addr_offset, False)
-                dump_data_len = ram_dump.read_dword(
-                                    client_addr + dump_data_len_offset, False)
-                print_out_str('Parsing debug information for {0}. Version: {1} Magic: {2:x} Source: {3}'.format(
-                    client_name, dump_data_version, dump_data_magic,
-                    dump_data_name))
-
-                if dump_data_magic is None:
-                    print_out_str("!!! Address {0:x} is bogus! Can't parse!".format(
-                                client_addr + dump_data_magic_offset))
+                if entry_type > len(self.dump_type_lookup_table):
+                    print_out_str(
+                        '!!! Invalid dump table entry type found {0:x}'.format(entry_type))
                     continue
 
-                if dump_data_magic != MEMDUMPV2_MAGIC:
-                    print_out_str("!!! Magic {0:x} doesn't match! No context will be parsed".format(dump_data_magic))
+                table_version = ram_dump.read_u32(
+                    entry_addr + dump_table_version_offset, False)
+                if table_version is None:
+                    print_out_str('Dump table entry version is bogus! Can\'t parse debug image')
+                    return
+                table_num_entries = ram_dump.read_u32(
+                    entry_addr + dump_table_num_entry_offset, False)
+                if table_num_entries is None or table_num_entries > 100:
+                    print_out_str('Dump table entry num_entries is bogus! Can\'t parse debug image')
+                    return
+
+                print_out_str(
+                    'Debug image version: {0}.{1} Entry id: {2} Entry type: {3} Number of entries: {4}'.format(
+                        table_version >> 20, table_version & 0xFFFFF, self.dump_table_id_lookup_table[entry_id],
+                        self.dump_type_lookup_table[entry_type], table_num_entries))
+
+                lst = self.sorted_dump_data_clients(
+                        ram_dump, entry_addr + dump_table_entry_offset,
+                        table_num_entries)
+                for (client_name, func, client_entry) in lst:
+                    print_out_str('--------')
+                    client_id = ram_dump.read_u32(
+                                    client_entry + dump_entry_id_offset, False)
+                    client_type = ram_dump.read_u32(
+                                    client_entry + dump_entry_type_offset, False)
+                    client_addr = ram_dump.read_word(
+                                    client_entry + dump_entry_addr_offset, False)
+
+                    if client_type > len(self.dump_type_lookup_table):
+                        print_out_str(
+                            '!!! Invalid dump client type found {0:x}'.format(client_type))
+                        continue
+
+                    dump_data_magic = ram_dump.read_u32(
+                                    client_addr + dump_data_magic_offset, False)
+                    dump_data_version = ram_dump.read_u32(
+                                    client_addr + dump_data_version_offset, False)
+                    dump_data_name = ram_dump.read_cstring(
+                            client_addr + dump_data_name_offset,
+                            ram_dump.sizeof('((struct msm_dump_data *)0x0)->name'),
+                            False)
+                    dump_data_addr = ram_dump.read_dword(
+                                        client_addr + dump_data_addr_offset, False)
+                    dump_data_len = ram_dump.read_dword(
+                                        client_addr + dump_data_len_offset, False)
+                    print_out_str('Parsing debug information for {0}. Version: {1} Magic: {2:x} Source: {3}'.format(
+                        client_name, dump_data_version, dump_data_magic,
+                        dump_data_name))
+
+                    if dump_data_magic is None:
+                        print_out_str("!!! Address {0:x} is bogus! Can't parse!".format(
+                                    client_addr + dump_data_magic_offset))
+                        continue
+
+                    if dump_data_magic != MEMDUMPV2_MAGIC:
+                        print_out_str("!!! Magic {0:x} doesn't match! No context will be parsed".format(dump_data_magic))
+                        continue
+
+                    getattr(DebugImage_v2, func)(
+                        self, dump_data_version, dump_data_addr,
+                        dump_data_addr + dump_data_len, client_id, ram_dump)
+        else:
+            dump_smem_table_ptr_offset = ram_dump.field_offset(
+                'struct md_table', 'md_smem_table')
+            dump_table_version_offset = ram_dump.field_offset(
+                'struct md_smem_table', 'version')
+            dump_table_num_entry_offset = ram_dump.field_offset(
+                'struct md_table', 'num_regions')
+            dump_table_entry_offset = ram_dump.field_offset(
+                'struct md_table', 'entry')
+            dump_entry_name_offset = ram_dump.field_offset(
+                'struct md_region', 'name')
+            dump_entry_id_offset = ram_dump.field_offset(
+                'struct md_region', 'id')
+            dump_entry_va_offset = ram_dump.field_offset(
+                'struct md_region', 'virt_addr')
+            dump_entry_pa_offset = ram_dump.field_offset(
+                'struct md_region', 'phys_addr')
+            dump_entry_size_offset = ram_dump.field_offset(
+                'struct md_region', 'size')
+
+            dump_entry_size = ram_dump.sizeof('struct md_region')
+
+            mem_dump_data = ram_dump.address_of('minidump_table')
+
+            mem_dump_table = ram_dump.read_word(
+                mem_dump_data + dump_table_entry_offset)
+
+            mem_dump_smem_table = ram_dump.read_word(
+                mem_dump_data + dump_smem_table_ptr_offset)
+
+            mem_table_version = ram_dump.read_u32(
+                mem_dump_smem_table + dump_table_version_offset)
+            mem_table_num_entry = ram_dump.read_u32(
+                mem_dump_data + dump_table_num_entry_offset)
+
+            print_out_str('--------')
+
+            for i in range(0, mem_table_num_entry):
+                this_entry = mem_dump_data + dump_table_entry_offset + \
+                             i * dump_entry_size
+                entry_id = ram_dump.read_u32(this_entry + dump_entry_id_offset)
+                entry_va_addr = ram_dump.read_u64(this_entry + dump_entry_va_offset)
+                entry_pa_addr = ram_dump.read_u64(this_entry + dump_entry_pa_offset)
+                entry_size = ram_dump.read_u64(this_entry + dump_entry_size_offset)
+
+                if entry_id < 0 or entry_id > len(self.dump_table_id_lookup_table):
+                    print_out_str(
+                        '!!! Invalid dump table entry id found {0:x}'.format(entry_id))
                     continue
+                end_addr = entry_pa_addr + entry_size
+                minidump_dump_table_value = dict(minidump_dump_table_type)
+                if entry_pa_addr in ram_dump.ebi_pa_name_map:
+                    section_name = ram_dump.ebi_pa_name_map[entry_pa_addr]
+                    section_name = re.sub("\d+", "", section_name)
+                    if section_name in minidump_dump_table_value.values():
+                        lst = self.minidump_data_clients(
+                            ram_dump, entry_id,entry_pa_addr,end_addr)
+                        if lst:
+                            client_name, client_id,func,\
+                                client_entry,client_end = lst[0]
+                            print_out_str('--------')
+                            getattr(DebugImage_v2, func)(
+                                self, 20, client_entry,
+                                client_end, client_id, ram_dump)
+        if ram_dump.dcc:
+            self.parse_dcc(ram_dump)
+        self.qdss.dump_standard(ram_dump)
+        if not ram_dump.skip_qdss_bin:
+            self.qdss.save_etf_bin(ram_dump)
+            self.qdss.save_etr_bin(ram_dump)
+        if ram_dump.qtf:
+            self.parse_qtf(ram_dump)
 
-                getattr(DebugImage_v2, func)(
-                    self, dump_data_version, dump_data_addr,
-                    dump_data_addr + dump_data_len, client_id, ram_dump)
-
-            self.qdss.dump_standard(ram_dump)
-            if not ram_dump.skip_qdss_bin:
-                self.qdss.save_etf_bin(ram_dump)
-                self.qdss.save_etr_bin(ram_dump)
-            if ram_dump.qtf:
-                self.parse_qtf(ram_dump)
-            if ram_dump.dcc:
-                self.parse_dcc(ram_dump)
diff --git a/linux-ramdump-parser-v2/minidump_util.py b/linux-ramdump-parser-v2/minidump_util.py
new file mode 100644
index 0000000000000000000000000000000000000000..92ef72b29cb6355f2e4a107989076fff2bb966ed
--- /dev/null
+++ b/linux-ramdump-parser-v2/minidump_util.py
@@ -0,0 +1,56 @@
+# Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 and
+# only version 2 as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+import sys
+import re
+import os
+from print_out import print_out_str
+
+
+def minidump_virt_to_phys(ebi_files,addr):
+    pa_addr = None
+    for a in ebi_files:
+        idx, pa, end_addr, va,size = a
+        if addr >= va and addr <= va +  size:
+            offset = addr - va
+            pa_addr = pa + offset
+            return pa_addr
+    return pa_addr
+
+def read_physical_minidump(ebi_files,ebi_files_ramfile,elffile,addr,length):
+    ebi = [-1, -1, -1, -1, -1]
+    for a in ebi_files:
+        idx, start, end, va, size = a
+        if addr >= start and addr <= end:
+            ebi = a
+            break
+    if ebi[0] != -1:
+        idx = ebi[0]
+        textSec = elffile.get_segment(idx)
+        off = addr - ebi[1]
+        elf_content = bytearray(a[4])
+        val = textSec.data()
+        elf_content[0:a[4]] = val
+        data = elf_content[off:]
+        return data[:length]
+    else:
+        ebi = (-1, -1, -1)
+        for a in ebi_files_ramfile:
+            fd, start, end, path = a
+            if addr >= start and addr <= end:
+                ebi = a
+                break
+        if ebi[0] is -1:
+            return None
+        offset = addr - ebi[1]
+        ebi[0].seek(offset)
+        a = ebi[0].read(length)
+        return a
diff --git a/linux-ramdump-parser-v2/parsers/memusage.py b/linux-ramdump-parser-v2/parsers/memusage.py
old mode 100755
new mode 100644
index ef86e54ef07198f9debce60e410a5e2c11d916c0..e610f429f6d194ae7af46d0523e73f403c82191a
--- a/linux-ramdump-parser-v2/parsers/memusage.py
+++ b/linux-ramdump-parser-v2/parsers/memusage.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 The Linux Foundation. All rights reserved.
+# Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -18,7 +18,10 @@ def do_dump_process_memory(ramdump):
         "NR_FREE_PAGES", "NR_SLAB_RECLAIMABLE",
         "NR_SLAB_UNRECLAIMABLE", "NR_SHMEM"]
     vmstat_data = {}
-    vmstats_addr = ramdump.address_of('vm_stat')
+    if(ramdump.kernel_version >= (4,9,0)):
+        vmstats_addr = ramdump.address_of('vm_zone_stat')
+    else:
+        vmstats_addr = ramdump.address_of('vm_stat')
     for x in vmstat_names:
         i = ramdump.gdbmi.get_value_of(x)
         vmstat_data[x] = ramdump.read_word(
diff --git a/linux-ramdump-parser-v2/parsers/slabsummary.py b/linux-ramdump-parser-v2/parsers/slabsummary.py
index 328cafd53d1872c9835d9a77dba14a035c3bb465..f9358090b8ed919c41df402673fe8ad87b0175f4 100644
--- a/linux-ramdump-parser-v2/parsers/slabsummary.py
+++ b/linux-ramdump-parser-v2/parsers/slabsummary.py
@@ -145,5 +145,8 @@ class Slabinfo_summary(RamParser):
 
     def parse(self):
         slab_out = self.ramdump.open_file('slabsummary.txt')
-        self.print_slab_summary(slab_out)
+        if(self.ramdump.is_config_defined('CONFIG_SLUB_DEBUG_ON')):
+            self.print_slab_summary(slab_out)
+        else:
+            slab_out.write('CONFIG_SLUB_DEBUG_ON is disabled in this build')
         slab_out.close()
diff --git a/linux-ramdump-parser-v2/parsers/timerlist.py b/linux-ramdump-parser-v2/parsers/timerlist.py
index a6ddaecb1496e9885f62d79fdc9fa32a1d160f87..650fea738f561b64a003d7bf9c2424d10829caa9 100644
--- a/linux-ramdump-parser-v2/parsers/timerlist.py
+++ b/linux-ramdump-parser-v2/parsers/timerlist.py
@@ -27,6 +27,7 @@ class TimerList(RamParser) :
         self.tvec_base = 'struct tvec_base'
         self.tvec_bases = 'tvec_bases'
         self.next_timer = 'next_timer'
+        self.global_deferrable = 'tvec_base_deferrable'
 
         if (major, minor) >= (4, 9):
             self.vectors = {'vectors': 512}
@@ -34,6 +35,7 @@ class TimerList(RamParser) :
             self.tvec_base = 'struct timer_base'
             self.tvec_bases = 'timer_bases'
             self.next_timer = 'next_expiry'
+            self.global_deferrable = 'timer_base_deferrable'
         # Timerlist structure changed in kernel 4.2
         # Requires separate processing
         if (major, minor) >= (4, 2):
@@ -110,7 +112,7 @@ class TimerList(RamParser) :
     def get_timer_list(self):
         self.output_file.write("Timer List Dump\n\n")
 
-        tvec_base_deferral_addr = self.ramdump.address_of('tvec_base_deferrable')
+        tvec_base_deferral_addr = self.ramdump.address_of(self.global_deferrable)
         if tvec_base_deferral_addr:
             timer_jiffies_addr = tvec_base_deferral_addr + self.ramdump.field_offset(self.tvec_base, self.timer_jiffies)
             next_timer_addr = tvec_base_deferral_addr + self.ramdump.field_offset(self.tvec_base, self.next_timer)
diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py
index 8d126080e578ad26bf71c80875335732cd1a8ba1..d6814a8da1463bfe6cc31633b43c463fe535736c 100644
--- a/linux-ramdump-parser-v2/ramdump.py
+++ b/linux-ramdump-parser-v2/ramdump.py
@@ -27,6 +27,8 @@ import gdbmi
 from print_out import print_out_str
 from mmu import Armv7MMU, Armv7LPAEMMU, Armv8MMU
 import parser_util
+import minidump_util
+from importlib import import_module
 
 FP = 11
 SP = 13
@@ -49,7 +51,8 @@ extra_mem_file_names = ['EBI1CS1.BIN', 'DDRCS1.BIN', 'ebi1_cs1.bin',
 
 DDR_FILE_NAMES = ['DDRCS0.BIN', 'DDRCS1.BIN', 'DDRCS0_0.BIN',
                   'DDRCS1_0.BIN', 'DDRCS0_1.BIN', 'DDRCS1_1.BIN']
-OTHER_DUMP_FILE_NAMES = ['PIMEM.BIN', 'OCIMEM.BIN']
+OTHER_DUMP_FILE_NAMES = ['PIMEM.BIN', 'OCIMEM.BIN','md_shared_imem.BIN',
+                         'md_smem_info.BIN']
 RAM_FILE_NAMES = set(DDR_FILE_NAMES +
                      OTHER_DUMP_FILE_NAMES +
                      first_mem_file_names +
@@ -499,6 +502,8 @@ class RamDump():
 
     def __init__(self, options, nm_path, gdb_path, objdump_path):
         self.ebi_files = []
+        self.ebi_files_minidump = []
+        self.ebi_pa_name_map = {}
         self.phys_offset = None
         self.kaslr_offset = options.kaslr_offset
         self.tz_start = 0
@@ -530,6 +535,20 @@ class RamDump():
         self.ipc_log_help = options.ipc_help
         self.use_stdout = options.stdout
         self.kernel_version = (0, 0, 0)
+        self.minidump = options.minidump
+        self.elffile = None
+        self.ram_elf_file = None
+
+        if self.minidump:
+            try:
+                mod = import_module('elftools.elf.elffile')
+                ELFFile = mod.ELFFile
+                StringTableSection = mod.StringTableSection
+                mod = import_module('elftools.common.py3compat')
+                bytes2str = mod.bytes2str
+            except ImportError:
+                print "Oops, missing required library for minidump. Check README"
+                sys.exit(1)
 
         if options.ram_addr is not None:
             # TODO sanity check to make sure the memory regions don't overlap
@@ -540,11 +559,31 @@ class RamDump():
                         'Could not open {0}. Will not be part of dump'.format(file_path))
                     continue
                 self.ebi_files.append((fd, start, end, file_path))
-        else:
+        elif not options.minidump:
             if not self.auto_parse(options.autodump):
                 return None
-        if self.ebi_start == 0:
-            self.ebi_start = self.ebi_files[0][1]
+        if options.minidump:
+            file_path = options.ram_elf_addr
+            self.ram_elf_file = file_path
+            fd = open(file_path, 'rb')
+            self.elffile = ELFFile(fd)
+            for idx, s in enumerate(self.elffile.iter_segments()):
+                pa = int(s['p_paddr'])
+                va = int(s['p_vaddr'])
+                size = int(s['p_filesz'])
+                end_addr = pa + size
+                for section in self.elffile.iter_sections():
+                    if (not section.is_null() and
+                            s.section_in_segment(section)):
+                        self.ebi_pa_name_map[pa] = section.name
+                self.ebi_files_minidump.append((idx, pa, end_addr, va,size))
+
+        if options.minidump:
+            if self.ebi_start == 0:
+                self.ebi_start = self.ebi_files_minidump[0][1]
+        else:
+            if self.ebi_start == 0:
+                self.ebi_start = self.ebi_files[0][1]
         if self.phys_offset is None:
             self.get_hw_id()
 
@@ -600,10 +639,12 @@ class RamDump():
         self.swapper_pg_dir_addr = self.address_of('swapper_pg_dir')
         if self.swapper_pg_dir_addr is None:
             print_out_str('!!! Could not get the swapper page directory!')
-            print_out_str(
-                '!!! Your vmlinux is probably wrong for these dumps')
-            print_out_str('!!! Exiting now')
-            sys.exit(1)
+            if not self.minidump:
+                print_out_str(
+                    '!!! Your vmlinux is probably wrong for these dumps')
+
+                print_out_str('!!! Exiting now')
+                sys.exit(1)
 
         stext = self.address_of('stext')
         if self.kimage_voffset is None:
@@ -664,11 +705,12 @@ class RamDump():
                 '!!! Your vmlinux is probably wrong for these dumps')
             print_out_str('!!! Exiting now')
             sys.exit(1)
-        if not self.get_config():
-            print_out_str('!!! Could not get saved configuration')
-            print_out_str(
-                '!!! This is really bad and probably indicates RAM corruption')
-            print_out_str('!!! Some features may be disabled!')
+        if not self.minidump:
+            if not self.get_config():
+                print_out_str('!!! Could not get saved configuration')
+                print_out_str(
+                    '!!! This is really bad and probably indicates RAM corruption')
+                print_out_str('!!! Some features may be disabled!')
 
         self.unwind = self.Unwinder(self)
 
@@ -755,14 +797,17 @@ class RamDump():
         return s in self.config
 
     def kernel_virt_to_phys(self, addr):
-        va_bits = 39
-        if self.kimage_voffset is None:
-            return addr - self.page_offset + self.phys_offset
+        if self.minidump:
+            return minidump_util.minidump_virt_to_phys(self.ebi_files_minidump,addr)
         else:
-            if addr & (1 << (va_bits - 1)):
+            va_bits = 39
+            if self.kimage_voffset is None:
                 return addr - self.page_offset + self.phys_offset
             else:
-                return addr - (self.kimage_voffset)
+                if addr & (1 << (va_bits - 1)):
+                    return addr - self.page_offset + self.phys_offset
+                else:
+                    return addr - (self.kimage_voffset)
 
     def get_version(self):
         banner_addr = self.address_of('linux_banner')
@@ -803,10 +848,34 @@ class RamDump():
         else:
             print_out_str('!!! Could not lookup saved command line address')
             return False
+        
+    def print_socinfo_minidump(self):
+        content_socinfo = None
+        boards = get_supported_boards()
+        for board in boards:
+            if self.hw_id == board.board_num:
+                content_socinfo = board.ram_start + board.smem_addr_buildinfo
+                break
+        sernum_offset = self.field_offset('struct socinfo_v10', 'serial_number')
+        if sernum_offset is None:
+            sernum_offset = self.field_offset('struct socinfo_v0_10', 'serial_number')
+            if sernum_offset is None:
+                print_out_str("No serial number information available")
+                return False
+        if content_socinfo:
+            addr_of_sernum = content_socinfo + sernum_offset
+            serial_number = self.read_u32(addr_of_sernum, False)
+            if serial_number is not None:
+                print_out_str('Serial number %s' % hex(serial_number))
+                return True
+            return False
+
+        return False
 
     def print_socinfo(self):
         content_socinfo = hex(self.read_pointer('socinfo'))
         content_socinfo = content_socinfo.strip('L')
+
         sernum_offset = self.field_offset('struct socinfo_v10', 'serial_number')
         if sernum_offset is None:
             sernum_offset = self.field_offset('struct socinfo_v0_10', 'serial_number')
@@ -819,6 +888,7 @@ class RamDump():
         if serial_number is not None:
             print_out_str('Serial number %s' % hex(serial_number))
             return True
+
         return False
 
     def auto_parse(self, file_path):
@@ -889,41 +959,46 @@ class RamDump():
             ebi_path = os.path.abspath(ram[3])
             startup_script.write('data.load.binary {0} 0x{1:x}\n'.format(
                 ebi_path, ram[1]).encode('ascii', 'ignore'))
-        if self.arm64:
-            startup_script.write('Register.Set NS 1\n'.encode('ascii', 'ignore'))
-            startup_script.write('Data.Set SPR:0x30201 %Quad 0x{0:x}\n'.format(
-                self.kernel_virt_to_phys(self.swapper_pg_dir_addr))
-                .encode('ascii', 'ignore'))
-
-            if is_cortex_a53:
-                startup_script.write('Data.Set SPR:0x30202 %Quad 0x00000012B5193519\n'.encode('ascii', 'ignore'))
-                startup_script.write('Data.Set SPR:0x30A20 %Quad 0x000000FF440C0400\n'.encode('ascii', 'ignore'))
-                startup_script.write('Data.Set SPR:0x30A30 %Quad 0x0000000000000000\n'.encode('ascii', 'ignore'))
-                startup_script.write('Data.Set SPR:0x30100 %Quad 0x0000000034D5D91D\n'.encode('ascii', 'ignore'))
+        if self.minidump:
+            dload_ram_elf = 'data.load.elf {} /LOGLOAD /nosymbol\n'.format(self.ram_elf_file)
+            startup_script.write(dload_ram_elf.encode('ascii', 'ignore'))
+
+        if not self.minidump:
+            if self.arm64:
+                startup_script.write('Register.Set NS 1\n'.encode('ascii', 'ignore'))
+                startup_script.write('Data.Set SPR:0x30201 %Quad 0x{0:x}\n'.format(
+                    self.kernel_virt_to_phys(self.swapper_pg_dir_addr))
+                    .encode('ascii', 'ignore'))
+
+                if is_cortex_a53:
+                    startup_script.write('Data.Set SPR:0x30202 %Quad 0x00000012B5193519\n'.encode('ascii', 'ignore'))
+                    startup_script.write('Data.Set SPR:0x30A20 %Quad 0x000000FF440C0400\n'.encode('ascii', 'ignore'))
+                    startup_script.write('Data.Set SPR:0x30A30 %Quad 0x0000000000000000\n'.encode('ascii', 'ignore'))
+                    startup_script.write('Data.Set SPR:0x30100 %Quad 0x0000000034D5D91D\n'.encode('ascii', 'ignore'))
+                else:
+                    startup_script.write('Data.Set SPR:0x30202 %Quad 0x00000032B5193519\n'.encode('ascii', 'ignore'))
+                    startup_script.write('Data.Set SPR:0x30A20 %Quad 0x000000FF440C0400\n'.encode('ascii', 'ignore'))
+                    startup_script.write('Data.Set SPR:0x30A30 %Quad 0x0000000000000000\n'.encode('ascii', 'ignore'))
+                    startup_script.write('Data.Set SPR:0x30100 %Quad 0x0000000004C5D93D\n'.encode('ascii', 'ignore'))
+
+                startup_script.write('Register.Set CPSR 0x3C5\n'.encode('ascii', 'ignore'))
+                startup_script.write('MMU.Delete\n'.encode('ascii', 'ignore'))
+                startup_script.write('MMU.SCAN PT 0xFFFFFF8000000000--0xFFFFFFFFFFFFFFFF\n'.encode('ascii', 'ignore'))
+                startup_script.write('mmu.on\n'.encode('ascii', 'ignore'))
+                startup_script.write('mmu.pt.list 0xffffff8000000000\n'.encode('ascii', 'ignore'))
             else:
-                startup_script.write('Data.Set SPR:0x30202 %Quad 0x00000032B5193519\n'.encode('ascii', 'ignore'))
-                startup_script.write('Data.Set SPR:0x30A20 %Quad 0x000000FF440C0400\n'.encode('ascii', 'ignore'))
-                startup_script.write('Data.Set SPR:0x30A30 %Quad 0x0000000000000000\n'.encode('ascii', 'ignore'))
-                startup_script.write('Data.Set SPR:0x30100 %Quad 0x0000000004C5D93D\n'.encode('ascii', 'ignore'))
-
-            startup_script.write('Register.Set CPSR 0x3C5\n'.encode('ascii', 'ignore'))
-            startup_script.write('MMU.Delete\n'.encode('ascii', 'ignore'))
-            startup_script.write('MMU.SCAN PT 0xFFFFFF8000000000--0xFFFFFFFFFFFFFFFF\n'.encode('ascii', 'ignore'))
-            startup_script.write('mmu.on\n'.encode('ascii', 'ignore'))
-            startup_script.write('mmu.pt.list 0xffffff8000000000\n'.encode('ascii', 'ignore'))
-        else:
-            startup_script.write(
-                'PER.S.F C15:0x2 %L 0x{0:x}\n'.format(self.mmu.ttbr).encode('ascii', 'ignore'))
-            if isinstance(self.mmu, Armv7LPAEMMU):
-                # TTBR1. This gets setup once and never change again even if TTBR0
-                # changes
-                startup_script.write('PER.S.F C15:0x102 %L 0x{0:x}\n'.format(
-                    self.mmu.ttbr + 0x4000).encode('ascii', 'ignore'))
-                # TTBCR with EAE and T1SZ set approprately
                 startup_script.write(
-                    'PER.S.F C15:0x202 %L 0x80030000\n'.encode('ascii', 'ignore'))
-            startup_script.write('mmu.on\n'.encode('ascii', 'ignore'))
-            startup_script.write('mmu.scan\n'.encode('ascii', 'ignore'))
+                    'PER.S.F C15:0x2 %L 0x{0:x}\n'.format(self.mmu.ttbr).encode('ascii', 'ignore'))
+                if isinstance(self.mmu, Armv7LPAEMMU):
+                    # TTBR1. This gets setup once and never change again even if TTBR0
+                    # changes
+                    startup_script.write('PER.S.F C15:0x102 %L 0x{0:x}\n'.format(
+                        self.mmu.ttbr + 0x4000).encode('ascii', 'ignore'))
+                    # TTBCR with EAE and T1SZ set approprately
+                    startup_script.write(
+                        'PER.S.F C15:0x202 %L 0x80030000\n'.encode('ascii', 'ignore'))
+                startup_script.write('mmu.on\n'.encode('ascii', 'ignore'))
+                startup_script.write('mmu.scan\n'.encode('ascii', 'ignore'))
 
         where = os.path.abspath(self.vmlinux)
         if self.kaslr_offset is not None:
@@ -953,8 +1028,8 @@ class RamDump():
                     'task.config /opt/t32/demo/arm/kernel/linux/linux.t32\n'.encode('ascii', 'ignore'))
                 startup_script.write(
                     'menu.reprogram /opt/t32/demo/arm/kernel/linux/linux.men\n'.encode('ascii', 'ignore'))
-
-        startup_script.write('task.dtask\n'.encode('ascii', 'ignore'))
+        if not self.minidump:
+            startup_script.write('task.dtask\n'.encode('ascii', 'ignore'))
         startup_script.write(
             'v.v  %ASCII %STRING linux_banner\n'.encode('ascii', 'ignore'))
         if os.path.exists(out_path + '/regs_panic.cmm'):
@@ -1024,30 +1099,38 @@ class RamDump():
         boards = get_supported_boards()
 
         if (self.hw_id is None):
-            heap_toc_offset = self.field_offset('struct smem_shared', 'heap_toc')
-            if heap_toc_offset is None:
-                print_out_str(
-                    '!!!! Could not get a necessary offset for auto detection!')
-                print_out_str(
-                    '!!!! Please check the gdb path which is used for offsets!')
-                print_out_str('!!!! Also check that the vmlinux is not stripped')
-                print_out_str('!!!! Exiting...')
-                sys.exit(1)
+            if not self.minidump:
+                heap_toc_offset = self.field_offset('struct smem_shared', 'heap_toc')
+                if heap_toc_offset is None:
+                    print_out_str(
+                        '!!!! Could not get a necessary offset for auto detection!')
+                    print_out_str(
+                        '!!!! Please check the gdb path which is used for offsets!')
+                    print_out_str('!!!! Also check that the vmlinux is not stripped')
+                    print_out_str('!!!! Exiting...')
+                    sys.exit(1)
 
-            smem_heap_entry_size = self.sizeof('struct smem_heap_entry')
-            offset_offset = self.field_offset('struct smem_heap_entry', 'offset')
+                smem_heap_entry_size = self.sizeof('struct smem_heap_entry')
+                offset_offset = self.field_offset('struct smem_heap_entry', 'offset')
             for board in boards:
-                socinfo_start_addr = board.smem_addr + heap_toc_offset + smem_heap_entry_size * SMEM_HW_SW_BUILD_ID + offset_offset
+                if not self.minidump:
+                    socinfo_start_addr = board.smem_addr + heap_toc_offset + smem_heap_entry_size * SMEM_HW_SW_BUILD_ID + offset_offset
+                else:
+                    if hasattr(board, 'smem_addr_buildinfo'):
+                        socinfo_start_addr = board.smem_addr_buildinfo
+                    else:
+                        continue
                 if add_offset:
                     socinfo_start_addr += board.ram_start
-                soc_start = self.read_int(socinfo_start_addr, False)
-                if soc_start is None:
-                    continue
-
-                socinfo_start = board.smem_addr + soc_start
-                if add_offset:
-                    socinfo_start += board.ram_start
-
+                if not self.minidump:
+                    soc_start = self.read_int(socinfo_start_addr, False)
+                    if soc_start is None:
+                        continue
+                    socinfo_start = board.smem_addr + soc_start
+                    if add_offset:
+                        socinfo_start += board.ram_start
+                else:
+                    socinfo_start = socinfo_start_addr
                 socinfo_id = self.read_int(socinfo_start + 4, False)
                 if socinfo_id != board.socid:
                     continue
@@ -1117,7 +1200,10 @@ class RamDump():
     def virt_to_phys(self, virt_or_name):
         """Does a virtual-to-physical address lookup of the virtual address or
         variable name."""
-        return self.mmu.virt_to_phys(self.resolve_virt(virt_or_name))
+        if self.minidump:
+            return minidump_util.minidump_virt_to_phys(self.ebi_files_minidump,self.resolve_virt(virt_or_name))
+        else:
+            return self.mmu.virt_to_phys(self.resolve_virt(virt_or_name))
 
     def setup_symbol_tables(self):
         stream = os.popen(self.nm_path + ' -n ' + self.vmlinux)
@@ -1249,18 +1335,24 @@ class RamDump():
             return (self.lookup_table[mid][1], self.lookup_table[mid + 1][0] - self.lookup_table[mid][0])
 
     def read_physical(self, addr, length):
-        ebi = (-1, -1, -1)
-        for a in self.ebi_files:
-            fd, start, end, path = a
-            if addr >= start and addr <= end:
-                ebi = a
-                break
-        if ebi[0] is -1:
-            return None
-        offset = addr - ebi[1]
-        ebi[0].seek(offset)
-        a = ebi[0].read(length)
-        return a
+        if self.minidump:
+            addr_data = minidump_util.read_physical_minidump(
+                        self.ebi_files_minidump, self.ebi_files,self.elffile,
+                        addr, length)
+            return addr_data
+        else:
+            ebi = (-1, -1, -1)
+            for a in self.ebi_files:
+                fd, start, end, path = a
+                if addr >= start and addr <= end:
+                    ebi = a
+                    break
+            if ebi[0] is -1:
+                return None
+            offset = addr - ebi[1]
+            ebi[0].seek(offset)
+            a = ebi[0].read(length)
+            return a
 
     def read_dword(self, addr_or_name, virtual=True, cpu=None):
         s = self.read_string(addr_or_name, '<Q', virtual, cpu)
diff --git a/linux-ramdump-parser-v2/ramparse.py b/linux-ramdump-parser-v2/ramparse.py
index 7245e9bbb3a05809f892c1985ac666f1af0f249c..89a6257a7e216c4b2dd790207d231a5c93986759 100644
--- a/linux-ramdump-parser-v2/ramparse.py
+++ b/linux-ramdump-parser-v2/ramparse.py
@@ -152,6 +152,10 @@ if __name__ == '__main__':
     parser.add_option('', '--eval',
                       help='Evaluate some python code directly, or from stdin if "-" is passed. The "dump" variable will be available, as it is with the --shell option.')  # noqa
     parser.add_option('', '--wlan', dest='wlan', help='wlan.ko path')
+    parser.add_option('', '--minidump', action='store_true', dest='minidump',
+                      help='Parse minidump')
+    parser.add_option('', '--ram-elf', dest='ram_elf_addr',
+                      help='pass ap_minidump.elf generated by crashscope')
 
     for p in parser_util.get_parsers():
         parser.add_option(p.shortopt or '',
@@ -161,6 +165,11 @@ if __name__ == '__main__':
                           action='store_true')
 
     (options, args) = parser.parse_args()
+    if options.minidump:
+        default_list = []
+        default_list.append("Dmesg")
+        default_list.append("RTB")
+        default_list.append("DebugImage")
 
     if options.outdir:
         if not os.path.exists(options.outdir):
@@ -224,7 +233,7 @@ if __name__ == '__main__':
 
     print_out_str('using vmlinux file {0}'.format(options.vmlinux))
 
-    if options.ram_addr is None and options.autodump is None:
+    if options.ram_addr is None and options.autodump is None and not options.minidump:
         print_out_str('Need one of --auto-dump or at least one --ram-file')
         sys.exit(1)
 
@@ -343,14 +352,20 @@ if __name__ == '__main__':
             shell.interact()
         sys.exit(0)
 
-    if not dump.print_command_line():
-        print_out_str('!!! Error printing saved command line.')
-        print_out_str('!!! The vmlinux is probably wrong for the ramdumps')
-        print_out_str('!!! Exiting now...')
-        sys.exit(1)
+    if not options.minidump:
+        if not dump.print_command_line():
+            print_out_str('!!! Error printing saved command line.')
+            print_out_str('!!! The vmlinux is probably wrong for the ramdumps')
+            print_out_str('!!! Exiting now...')
+            sys.exit(1)
 
-    if not dump.print_socinfo():
-        print_out_str('!!! No serial number information available.')
+    if options.minidump:
+        if not dump.print_socinfo_minidump():
+            print_out_str('!!! No serial number information '
+                          'available for this minidump.')
+    else:
+        if not dump.print_socinfo():
+            print_out_str('!!! No serial number information available.')
 
     if options.qdss:
         print_out_str('!!! --parse-qdss is now deprecated')
@@ -365,12 +380,24 @@ if __name__ == '__main__':
     # we called parser.add_option with dest=p.cls.__name__ above,
     # so if the user passed that option then `options' will have a
     # p.cls.__name__ attribute.
-    parsers_to_run = [p for p in parser_util.get_parsers()
+    if options.minidump:
+        parsers_to_run = [p for p in parser_util.get_parsers()
+                          if getattr(options, p.cls.__name__)
+                          or (options.everything and p.cls.__name__ in default_list)]
+    else:
+        parsers_to_run = [p for p in parser_util.get_parsers()
                       if getattr(options, p.cls.__name__)
                       or (options.everything and not p.optional)]
     for i,p in enumerate(parsers_to_run):
         if i == 0:
             sys.stderr.write("\n")
+        if options.minidump:
+            if p.cls.__name__ not in default_list:
+                sys.stderr.write("    [%d/%d] %s ... not supported in minidump \n" %
+                                 (i + 1, len(parsers_to_run), p.longopt))
+                continue
+
+
         sys.stderr.write("    [%d/%d] %s ... " %
                          (i + 1, len(parsers_to_run), p.longopt))
         before = time.time()
@@ -387,5 +414,6 @@ if __name__ == '__main__':
 
     sys.stderr.write("\n")
 
-    if options.t32launcher or options.everything:
+    if options.t32launcher or options.everything or options.minidump:
         dump.create_t32_launcher()
+