Merge 1cb6ffe550e9a7c146098ce612212fe362efbfba on remote branch

Change-Id: I2600cc3649bff08f5af6407f97cb2146aa73cf0c
diff --git a/dcc_parser/dcc_parser.py b/dcc_parser/dcc_parser.py
index 406f101..7a77851 100644
--- a/dcc_parser/dcc_parser.py
+++ b/dcc_parser/dcc_parser.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, 2017, 2019-2020 The Linux Foundation. All rights reserved.
+# Copyright (c) 2015, 2017, 2019-2021 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
@@ -81,6 +81,7 @@
 def read_config(config_pt):
     offset = 0
     base = 0
+    length = 1
     list_nr.append(0)
     count = 0
     if options.version is None:
diff --git a/linux-ramdump-parser-v2/debug_image_v2.py b/linux-ramdump-parser-v2/debug_image_v2.py
index b4a8b20..b0c3260 100644
--- a/linux-ramdump-parser-v2/debug_image_v2.py
+++ b/linux-ramdump-parser-v2/debug_image_v2.py
@@ -161,7 +161,6 @@
     def __init__(self, ramdump):
         self.qdss = QDSSDump()
         self.dump_type_lookup_table = []
-        self.dump_table_id_lookup_table = []
         self.dump_data_id_lookup_table  = {}
         if ramdump.kernel_version > (3, 9, 9):
             self.event_call = 'struct trace_event_call'
@@ -243,8 +242,6 @@
     def parse_cpu_ctx(self, version, start, end, client_id, ram_dump):
         core = client_id - client.MSM_DUMP_DATA_CPU_CTX
 
-        print_out_str(
-            'Parsing CPU{2} context start {0:x} end {1:x} version {3} client_id-> {4}'.format(start, end, core,version,client_id))
         if version == 32 or version == "32":
             try:
                 cpu_type_offset  = ram_dump.field_offset(
@@ -283,12 +280,14 @@
                                 'struct msm_dump_cpu_register_entry', 'regset_addr')
                 if regset_addr_offset is None:
                     regset_addr_offset = 0x8
-
+                cpu_index = ram_dump.read_u32(start + cpu_index_offset,False)
+                
+                print_out_str(
+                    'Parsing CPU{2:x} context start {0:x} end {1:x} version {3} client_id-> {4:x}'.format(start, end, cpu_index,version,client_id))
                 cpu_type = ram_dump.read_u32(start + cpu_type_offset,False)
                 print_out_str("cpu_type = {0}".format(msm_dump_cpu_type[cpu_type]))
                 ctx_type = ram_dump.read_u32(start + ctx_type_offset,False)
                 print_out_str("ctx_type = {0}".format(msm_dump_ctx_type[ctx_type]))
-                cpu_index = ram_dump.read_u32(start + cpu_index_offset,False)
                 print_out_str("cpu_index = {0}".format(cpu_index))
                 regset_num_register = ram_dump.read_u32(start + regset_num_register_offset,False)
                 registers = start + registers_offset
@@ -534,9 +533,7 @@
         self.formats_out.write("print fmt: {0}\n".format(fmt_str))
 
     def collect_ftrace_format(self, ram_dump):
-        formats = os.path.join('qtf', 'map_files', 'formats.txt')
-        formats_out = ram_dump.open_file(formats)
-        self.formats_out = formats_out
+        self.formats_out = ram_dump.open_file('formats.txt')
 
         ftrace_events_list = ram_dump.address_of('ftrace_events')
         next_offset = ram_dump.field_offset(self.event_call, 'list')
@@ -545,166 +542,6 @@
 
         self.formats_out.close
 
-    def wait_for_completion_timeout(self, task, timeout):
-        delay = 2.0
-        #while the process is still executing and we haven't timed-out yet
-        while task.poll() is None and timeout > 0:
-            time.sleep(delay)
-            timeout -= delay
-        if timeout <= 0:
-            print_out_str("QTF command timed out")
-            task.kill()
-
-    def parse_qtf(self, ram_dump):
-        out_dir = ram_dump.outdir
-        if platform.system() != 'Windows':
-            return
-
-        qtf_path = ram_dump.qtf_path
-        if qtf_path is None:
-            try:
-                import local_settings
-                try:
-                    qtf_path = local_settings.qtf_path
-                except AttributeError as e:
-                    print_out_str("attribute qtf_path in local_settings.py looks bogus. Please see README.txt")
-                    print_out_str("Full message: %s" % e.message)
-                    return
-            except ImportError:
-                print_out_str("missing qtf_path local_settings.")
-                print_out_str("Please see the README for instructions on setting up local_settings.py")
-                return
-
-        if qtf_path is None:
-            print_out_str("!!! Incorrect path for qtf specified.")
-            print_out_str("!!! Please see the README for instructions on setting up local_settings.py")
-            return
-
-        if not os.path.exists(qtf_path):
-            print_out_str("!!! qtf_path {0} does not exist! Check your settings!".format(qtf_path))
-            return
-
-        if not os.access(qtf_path, os.X_OK):
-            print_out_str("!!! No execute permissions on qtf path {0}".format(qtf_path))
-            return
-
-        if os.path.getsize(os.path.join(out_dir, 'tmc-etf.bin')) > 0:
-            trace_file = os.path.join(out_dir, 'tmc-etf.bin')
-        elif os.path.getsize(os.path.join(out_dir, 'tmc-etr.bin')) > 0:
-            trace_file = os.path.join(out_dir, 'tmc-etr.bin')
-        else:
-            return
-
-        port = None
-        server_proc = None
-        qtf_success = False
-        max_tries = 3
-        qtf_dir = os.path.join(out_dir, 'qtf')
-        workspace = os.path.join(qtf_dir, 'qtf.workspace')
-        qtf_out = os.path.join(out_dir, 'qtf.txt')
-        chipset = ram_dump.hw_id
-        if "sdm" not in ram_dump.hw_id.lower() and \
-          "qcs" not in ram_dump.hw_id.lower():
-            chipset = "msm" + ram_dump.hw_id
-        hlos = 'LA'
-
-        #Temp change to handle descripancy between tools usage
-        if chipset == 'msmcobalt':
-            chipset = 'msm8998'
-
-        # Resolve any port collisions with other running qtf_server instances
-        for tries in range(max_tries):
-            port = random.randint(12000, 13000)
-            server_proc = subprocess.Popen(
-                [qtf_path, '-s', '{:d}'.format(port)], shell=True,stderr=subprocess.PIPE)
-            time.sleep(15)
-            server_proc.poll()
-            if server_proc.returncode == 1:
-                server_proc.terminate()
-                continue
-            else:
-                qtf_success = True
-                break
-        if not qtf_success:
-            server_proc.terminate()
-            print_out_str('!!! Could not open a QTF server instance with a '
-                          'unique port (last port tried: '
-                          '{0})'.format(str(port)))
-            print_out_str('!!! Please kill all currently running qtf_server '
-                          'processes and try again')
-            return
-        #subprocess.call('{0} -c {1} new workspace {2} {3} {4}'.format(qtf_path, port, qtf_dir, chipset, hlos))
-        server_proc1 = subprocess.Popen(
-                   [qtf_path, '-c', '{:d}'.format(port),'new workspace {0} {1} {2}'.format(qtf_dir, chipset, hlos)], shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
-        server_proc1.communicate()
-        self.collect_ftrace_format(ram_dump)
-        server_proc1.kill()
-
-        p = subprocess.Popen('{0} -c {1} open workspace {2}'.format(qtf_path, port, workspace))
-        self.wait_for_completion_timeout(p,60)
-        p = subprocess.Popen('{0} -c {1} open bin {2}'.format(qtf_path, port, trace_file))
-        self.wait_for_completion_timeout(p,90)
-        p = subprocess.Popen('{0} -c {1} stream trace table {2}'.format(qtf_path, port, qtf_out))
-        self.wait_for_completion_timeout(p,300)
-        p = subprocess.Popen('{0} -c {1} close'.format(qtf_path, port))
-        self.wait_for_completion_timeout(p,60)
-        p = subprocess.Popen('{0} -c {1} exit'.format(qtf_path, port))
-        self.wait_for_completion_timeout(p,60)
-        try:
-            import psutil
-            pid = server_proc.pid
-            pid = int(pid)
-            parent = psutil.Process(pid)
-            # or parent.children() for recursive=False
-            for child in parent.children(recursive=True):
-                print_out_str("child process = {0} which needs to be killed forcefully after QTF timeout".format(child))
-                if (psutil.pid_exists(child.pid)):
-                    try:
-                        child.kill()
-                    except Exception as e:
-                        print_out_str("Error: {0} while killing the child of QTF process".format(e))
-                        pass
-            server_proc.kill()
-        except Exception as e1:
-            print_out_str("psutil module import error = {0}".format(e1))
-            pass
-
-    def parse_dcc(self, ram_dump):
-        out_dir = ram_dump.outdir
-        if ram_dump.ram_addr is None:
-            bin_dir = ram_dump.autodump
-        else:
-            bin_dir = ram_dump.ram_addr
-            bin_dir="\\".join(bin_dir[0][0].split('\\')[:-1])
-        dcc_parser_path = os.path.join(os.path.dirname(__file__), '..', 'dcc_parser', 'dcc_parser.py')
-        if dcc_parser_path is None:
-            print_out_str("!!! Incorrect path for DCC specified.")
-            return
-
-        if not os.path.exists(dcc_parser_path):
-            print_out_str("!!! dcc_parser_path {0} does not exist! Check your settings!".format(dcc_parser_path))
-            return
-
-        if (os.path.isfile(os.path.join(bin_dir, 'DCC_SRAM.BIN'))):
-            sram_file = os.path.join(bin_dir, 'DCC_SRAM.BIN')
-            cmd = [sys.executable, dcc_parser_path, "-s" , sram_file, "--out-dir", out_dir, "--config-offset", "0x6000", "--v2"]
-            p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
-                                 stderr=subprocess.STDOUT,
-                                 universal_newlines=True)
-            print_out_str('--------')
-            print_out_str(p.communicate()[0])
-        elif os.path.isfile(os.path.join(out_dir, 'sram.bin')):
-            sram_file = os.path.join(out_dir, 'sram.bin')
-            p = subprocess.Popen([sys.executable, dcc_parser_path, '-s', sram_file, '--out-dir', out_dir],
-                                 stdout=subprocess.PIPE,
-                                 stderr=subprocess.STDOUT,
-                                 universal_newlines=True)
-            print_out_str('--------')
-            print_out_str(p.communicate()[0])
-        else:
-            print_out_str('DCC SRAM data is not populated!!')
-            return
-
     def parse_sysreg(self,ram_dump):
         out_dir = ram_dump.outdir
         sysreg_parser_path_minidump = os.path.join(os.path.dirname(__file__), '..', 'dcc_parser',
@@ -841,8 +678,6 @@
     def parse_dump_v2(self, ram_dump):
         self.dump_type_lookup_table = ram_dump.gdbmi.get_enum_lookup_table(
             'msm_dump_type', 2)
-        self.dump_table_id_lookup_table = ram_dump.gdbmi.get_enum_lookup_table(
-            'msm_dump_table_ids', MAX_NUM_ENTRIES)
         cpus = ram_dump.get_num_cpus()
         # per cpu entries
         for i in range(0, cpus):
@@ -978,11 +813,6 @@
                 entry_type = ram_dump.read_u32(this_entry + dump_entry_type_offset, virtual = False)
                 entry_addr = ram_dump.read_word(this_entry + dump_entry_addr_offset, virtual = False)
 
-                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))
@@ -1000,8 +830,8 @@
                     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],
+                    'Debug image version: {0}.{1} Entry type: {2} Number of entries: {3}'.format(
+                        table_version >> 20, table_version & 0xFFFFF,
                         self.dump_type_lookup_table[entry_type], table_num_entries))
 
                 lst = self.sorted_dump_data_clients(
@@ -1090,10 +920,6 @@
                 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:
@@ -1109,8 +935,6 @@
                         getattr(DebugImage_v2, func)(
                             self, 20, client_entry,
                             client_end, client_id, ram_dump)
-
-        self.parse_dcc(ram_dump)
         if ram_dump.sysreg:
             self.parse_sysreg(ram_dump)
         self.qdss.dump_standard(ram_dump)
@@ -1118,6 +942,6 @@
             self.qdss.save_etf_bin(ram_dump)
             self.qdss.save_etf_swao_bin(ram_dump)
             self.qdss.save_etr_bin(ram_dump)
-        if ram_dump.qtf:
-            self.parse_qtf(ram_dump)
+        if ram_dump.ftrace_format:
+            self.collect_ftrace_format(ram_dump)
 
diff --git a/linux-ramdump-parser-v2/mm.py b/linux-ramdump-parser-v2/mm.py
index 2beeef2..45d1aa9 100644
--- a/linux-ramdump-parser-v2/mm.py
+++ b/linux-ramdump-parser-v2/mm.py
@@ -382,6 +382,22 @@
         self.rd = ramdump
         self.SECTION_SIZE_BITS = 0
 
+    def lookup_page_ext(self, pfn):
+        if not self.rd.is_config_defined('CONFIG_PAGE_EXTENSION'):
+            return None
+
+        if not self.rd.is_config_defined('CONFIG_SPARSEMEM'):
+            contig_page_data = self.rd.address_of('contig_page_data')
+            offset = self.rd.field_offset('struct pglist_data', 'node_page_ext')
+            page_ext = self.rd.read_word(contig_page_data + offset)
+        else:
+            mem_section = pfn_to_section(self.rd, pfn)
+            offset = self.rd.field_offset('struct mem_section', 'page_ext')
+            page_ext = self.rd.read_word(mem_section + offset)
+
+        return page_ext
+
+
 class Sparsemem:
     def __init__(self, ramdump):
         self.rd = ramdump
@@ -399,16 +415,26 @@
         sections_per_root = 4096 // memsection_struct_size
         root_nr = section_nr // sections_per_root
         section_nr = section_nr % sections_per_root
-        mem_section_base = ramdump.read_word('mem_section')
 
-        if ramdump.is_config_defined('CONFIG_SPARSEMEM_EXTREME'):
-            #struct mem_section *mem_section[NR_SECTION_ROOTS];
+        if ramdump.is_config_defined('CONFIG_SPARSEMEM_EXTREME') and \
+                ramdump.kernel_version >= (4, 14):
+            #struct mem_section **mem_section
+            mem_section_base = ramdump.read_word('mem_section')
+            offset = pointer_size * root_nr
+            ptr = ramdump.read_word(mem_section_base + offset)
+            offset = memsection_struct_size * section_nr
+            mem_section_ptr = ptr + offset
+        elif ramdump.is_config_defined('CONFIG_SPARSEMEM_EXTREME') and \
+                ramdump.kernel_version < (4, 14):
+            #struct mem_section *mem_section[NR_SECTION_ROOTS]
+            mem_section_base = ramdump.address_of('mem_section')
             offset = pointer_size * root_nr
             ptr = ramdump.read_word(mem_section_base + offset)
             offset = memsection_struct_size * section_nr
             mem_section_ptr = ptr + offset
         else:
             #struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT];
+            mem_section_base = ramdump.address_of('mem_section')
             offset = memsection_struct_size * (section_nr + root_nr * sections_per_root)
             mem_section_ptr = mem_section_base + offset
 
diff --git a/linux-ramdump-parser-v2/parsers/ftrace.py b/linux-ramdump-parser-v2/parsers/ftrace.py
index e8907b7..e21cd7d 100644
--- a/linux-ramdump-parser-v2/parsers/ftrace.py
+++ b/linux-ramdump-parser-v2/parsers/ftrace.py
@@ -311,7 +311,7 @@
             ftrace_file_map["007"] = ftrace_core7_fd
 
             sorted_dict = {k: ftrace_time_data[k] for k in sorted(ftrace_time_data)}
-            for key in sorted_dict.keys():
+            for key in sorted(sorted_dict.keys()):
                 line = str(ftrace_time_data[key])
                 if "sched_switch:" in line:
                     cpu_number = line.split("[")[1]
diff --git a/linux-ramdump-parser-v2/parsers/ftrace_event.py b/linux-ramdump-parser-v2/parsers/ftrace_event.py
index 06e9159..5625f5c 100644
--- a/linux-ramdump-parser-v2/parsers/ftrace_event.py
+++ b/linux-ramdump-parser-v2/parsers/ftrace_event.py
@@ -550,105 +550,109 @@
                 fmt_str =  fmt_str.replace('work struct','work_struct')
             offset_data = event_data[0]
             fmt_name_value_map = OrderedDict()
-            d = str(fmt_str.split('",')[1].replace("'", ''))
-            pr = str(fmt_str.split('",')[0].replace("'", ''))
-            pr = str(pr.split('",')[0].replace('"', ''))
-            pr = str(pr.split('",')[0].replace('[', ''))
-            pr = str(pr.split('",')[0].replace(']', ''))
-            if "cpuhp_latency" == event_name:
-                pr = pr.replace("USEC ret: %d","USEC_ret:%d")
-            if "thermal_device_update" == event_name:
-                pr = pr.replace("received event","received_event")
-            temp_a = []
-            for ii in d.split(","):
-                ii = str(ii).replace("'","").replace(" ","")
-                temp_a.append(ii)
-            j = 0
-            temp_a = []
-            pr_f = []
-            if "workqueue_execute" in event_name:
-                for ki in pr.split(": "):
-                    pr_f.append(str(ki))
-            else:
-                if ", " in pr and event_name != 'user_fault':
-                    for ki in pr.split(", "):
-                        if len(ki) >= 1:
-                            pr_f.append(str(ki).replace(" ",""))
+            try:
+                d = str(fmt_str.split('",')[1].replace("'", ''))
+                pr = str(fmt_str.split('",')[0].replace("'", ''))
+                pr = str(pr.split('",')[0].replace('"', ''))
+                pr = str(pr.split('",')[0].replace('[', ''))
+                pr = str(pr.split('",')[0].replace(']', ''))
+                if "cpuhp_latency" == event_name:
+                    pr = pr.replace("USEC ret: %d","USEC_ret:%d")
+                if "thermal_device_update" == event_name:
+                    pr = pr.replace("received event","received_event")
+                temp_a = []
+                for ii in d.split(","):
+                    ii = str(ii).replace("'","").replace(" ","")
+                    temp_a.append(ii)
+                j = 0
+                temp_a = []
+                pr_f = []
+                if "workqueue_execute" in event_name:
+                    for ki in pr.split(": "):
+                        pr_f.append(str(ki))
                 else:
-                    for ki in pr.split(" "):
-                        if len(ki) >= 1:
-                            pr_f.append(str(ki).replace(" ",""))
-            for item,item_list in offset_data.items():
-                type_str,offset,size = item_list
-                if 'unsigned char' in type_str or 'long' in type_str or 'int' in type_str or 'u32' in type_str or 'bool' in type_str or 'pid_t' in type_str:
-                    v = self.ramdump.read_u32(ftrace_raw_entry + offset)
-                    fmt_name_value_map[item] = v
-                elif 'char' in type_str or '__data_loc char' in type_str or 'const char *' in type_str or '__data_loc char[]' in type_str:
-                    if '__data_loc' in type_str:
+                    if ", " in pr and event_name != 'user_fault':
+                        for ki in pr.split(", "):
+                            if len(ki) >= 1:
+                                pr_f.append(str(ki).replace(" ",""))
+                    else:
+                        for ki in pr.split(" "):
+                            if len(ki) >= 1:
+                                pr_f.append(str(ki).replace(" ",""))
+                for item,item_list in offset_data.items():
+                    type_str,offset,size = item_list
+                    if 'unsigned char' in type_str or 'long' in type_str or 'int' in type_str or 'u32' in type_str or 'bool' in type_str or 'pid_t' in type_str:
                         v = self.ramdump.read_u32(ftrace_raw_entry + offset)
-                        v = self.ramdump.read_cstring(ftrace_raw_entry + (v & 0xffff), (v >> 16))
-                        if isinstance(v, bytes):
-                            v = self.ramdump.read_cstring(ftrace_raw_entry + (offset*4))
-                    else:
-                        v = self.ramdump.read_cstring(ftrace_raw_entry + offset)
-                    fmt_name_value_map[item] = v
-                elif 'unsigned long' in type_str or 'u64' in type_str or 'void *' in type_str:
-                    if self.ramdump.arm64:
-                        v = self.ramdump.read_u64(ftrace_raw_entry + offset)
-                    else:
-                        v = self.ramdump.read_u32(ftrace_raw_entry + offset)
-                    if "func" not in item:
-                        fmt_name_value_map[item] = hex(int(v))
-                    else:
                         fmt_name_value_map[item] = v
-                elif 'unsigned short' in type_str or 'u16' in type_str:
-                    v = self.ramdump.read_u16(ftrace_raw_entry + offset)
-                    fmt_name_value_map[item] = v
-                elif 'short' in type_str or 'signed short' in type_str or 's16' in type_str:
-                    v = self.ramdump.read_s32(ftrace_raw_entry + offset)
-                    fmt_name_value_map[item] = v
-                elif 's64' in type_str:
-                    v = self.ramdump.read_s64(ftrace_raw_entry + offset)
-                    fmt_name_value_map[item] = v
-                else:
-                    v = self.ramdump.read_u32(ftrace_raw_entry + offset)
-                    fmt_name_value_map[item] = v
-
-                if "softirq" in event_name:
-                    if v > len(softirq_action_list) -1:
-                        action = v
-                    else:
-                        action = softirq_action_list[v]
-                    fmt_name_value_map['action'] = action
-                temp_a.append(v)
-                j = j + 1
-            temp = ""
-            t1 = len(temp_a)
-            t2 = len(pr_f)
-            f = False
-            try:
-                for keyinfo in fmt_name_value_map:
-                    if "function" == keyinfo:
-                        wq_function1 = self.ramdump.get_symbol_info1(fmt_name_value_map[keyinfo])
-                        tt = keyinfo + "=" + wq_function1
-                    if "func" in keyinfo:
-                        wq_function1 = self.ramdump.get_symbol_info1(fmt_name_value_map[keyinfo])
-                        if wq_function1 and len(wq_function1) > 1 and wq_function1 != 'No':
-                            tt = keyinfo + "=" + wq_function1
+                    elif 'char' in type_str or '__data_loc char' in type_str or 'const char *' in type_str or '__data_loc char[]' in type_str:
+                        if '__data_loc' in type_str:
+                            v = self.ramdump.read_u32(ftrace_raw_entry + offset)
+                            v = self.ramdump.read_cstring(ftrace_raw_entry + (v & 0xffff), (v >> 16))
+                            if isinstance(v, bytes):
+                                v = self.ramdump.read_cstring(ftrace_raw_entry + (offset*4))
                         else:
-                            tt = keyinfo + "=" + str(hex(fmt_name_value_map[keyinfo]))
+                            v = self.ramdump.read_cstring(ftrace_raw_entry + offset)
+                        fmt_name_value_map[item] = v
+                    elif 'unsigned long' in type_str or 'u64' in type_str or 'void *' in type_str:
+                        if self.ramdump.arm64:
+                            v = self.ramdump.read_u64(ftrace_raw_entry + offset)
+                        else:
+                            v = self.ramdump.read_u32(ftrace_raw_entry + offset)
+                        if "func" not in item:
+                            fmt_name_value_map[item] = hex(int(v))
+                        else:
+                            fmt_name_value_map[item] = v
+                    elif 'unsigned short' in type_str or 'u16' in type_str:
+                        v = self.ramdump.read_u16(ftrace_raw_entry + offset)
+                        fmt_name_value_map[item] = v
+                    elif 'short' in type_str or 'signed short' in type_str or 's16' in type_str:
+                        v = self.ramdump.read_s32(ftrace_raw_entry + offset)
+                        fmt_name_value_map[item] = v
+                    elif 's64' in type_str:
+                        v = self.ramdump.read_s64(ftrace_raw_entry + offset)
+                        fmt_name_value_map[item] = v
                     else:
-                        tt = keyinfo + "=" + str(fmt_name_value_map[keyinfo])
-                    temp = temp + tt + "  "
-            except Exception as err:
-                print_out_str("missing event = {0} err = {1}".format(event_name,str(err)))
-                pass
-            try:
-                temp = temp + "\n"
-                temp_data = "                {4}    {0}   {1:.6f}:  {2}   {3}".format(self.cpu, round(local_timestamp / 1000000000.0, 6),event_name,temp,curr_com)
-                t = local_timestamp / 1000000000.0
-                self.ftrace_time_data[t] = temp_data
+                        v = self.ramdump.read_u32(ftrace_raw_entry + offset)
+                        fmt_name_value_map[item] = v
+
+                    if "softirq" in event_name:
+                        if v > len(softirq_action_list) -1:
+                            action = v
+                        else:
+                            action = softirq_action_list[v]
+                        fmt_name_value_map['action'] = action
+                    temp_a.append(v)
+                    j = j + 1
                 temp = ""
+                t1 = len(temp_a)
+                t2 = len(pr_f)
+                f = False
+                try:
+                    for keyinfo in fmt_name_value_map:
+                        if "function" == keyinfo and isinstance(fmt_name_value_map[keyinfo], int):
+                            wq_function1 = self.ramdump.get_symbol_info1(fmt_name_value_map[keyinfo])
+                            tt = keyinfo + "=" + wq_function1
+                        if "func" in keyinfo and isinstance(fmt_name_value_map[keyinfo], int):
+                            wq_function1 = self.ramdump.get_symbol_info1(fmt_name_value_map[keyinfo])
+                            if wq_function1 and len(wq_function1) > 1 and wq_function1 != 'No':
+                                tt = keyinfo + "=" + wq_function1
+                            else:
+                                tt = keyinfo + "=" + str(hex(fmt_name_value_map[keyinfo]))
+                        else:
+                            tt = keyinfo + "=" + str(fmt_name_value_map[keyinfo])
+                        temp = temp + tt + "  "
+                except Exception as err:
+                    print_out_str("missing event = {0} err = {1}".format(event_name,str(err)))
+                    pass
+                try:
+                    temp = temp + "\n"
+                    temp_data = "                {4}    {0}   {1:.6f}:  {2}   {3}".format(self.cpu, round(local_timestamp / 1000000000.0, 6),event_name,temp,curr_com)
+                    t = local_timestamp / 1000000000.0
+                    self.ftrace_time_data[t] = temp_data
+                    temp = ""
+                except Exception as err:
+                    print_out_str("missing event = {0} err = {1}".format(event_name,str(err)))
+                    pass
             except Exception as err:
                 print_out_str("missing event = {0} err = {1}".format(event_name,str(err)))
                 pass
diff --git a/linux-ramdump-parser-v2/parsers/gpu/gpu_eventlog.py b/linux-ramdump-parser-v2/parsers/gpu/gpu_eventlog.py
new file mode 100644
index 0000000..65d76e6
--- /dev/null
+++ b/linux-ramdump-parser-v2/parsers/gpu/gpu_eventlog.py
@@ -0,0 +1,222 @@
+# Copyright (c) 2021 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.
+
+from ctypes import c_uint32, c_uint64, c_char, sizeof, Structure
+
+MAGIC = 0xabbaabba
+
+LOG_SKIP = 1
+LOG_FIRE_EVENT = 2
+LOG_CMDBATCH_SUBMITTED_EVENT = 3
+LOG_CMDBATCH_RETIRED_EVENT = 4
+LOG_SYNCPOINT_FENCE_EVENT = 5
+LOG_SYNCPOINT_FENCE_EXPIRE_EVENT = 6
+LOG_TIMELINE_FENCE_ALLOC_EVENT = 7
+LOG_TIMELINE_FENCE_RELEASE_EVENT = 8
+
+KGSL_EVENT_RETIRED = 1
+KGSL_EVENT_CANCELLED = 2
+
+NANO_TO_SEC = 1000000000
+
+
+class fire_event (Structure):
+    _fields_ = [('id', c_uint32),
+                ('ts', c_uint32),
+                ('type', c_uint32),
+                ('age', c_uint32)]
+
+
+class cmdbatch_submitted (Structure):
+    _fields_ = [('id', c_uint32),
+                ('ts', c_uint32),
+                ('prio', c_uint32),
+                ('flags', c_uint64)]
+
+
+class cmdbatch_retired (Structure):
+    _fields_ = [('id', c_uint32),
+                ('ts', c_uint32),
+                ('prio', c_uint32),
+                ('flag', c_uint64),
+                ('start', c_uint64),
+                ('retire', c_uint64)]
+
+
+class syncpoint_fence (Structure):
+    _fields_ = [('id', c_uint32),
+                ('name', c_char*74)]
+
+
+class timeline_fence (Structure):
+    _fields_ = [('id', c_uint32),
+                ('seqno', c_uint64)]
+
+
+def fire_event_write(func_writeln, dump, kgsl_eventlog_buffer, header):
+    if header["payload_size"] != sizeof(fire_event):
+        return True
+    id = dump.read_u32(kgsl_eventlog_buffer + fire_event.id.offset)
+    ts = dump.read_u32(kgsl_eventlog_buffer + fire_event.ts.offset)
+    type = dump.read_u32(kgsl_eventlog_buffer + fire_event.type.offset)
+    age = dump.read_u32(kgsl_eventlog_buffer + fire_event.age.offset)
+    if type == KGSL_EVENT_RETIRED:
+        type = "retired"
+    elif type == KGSL_EVENT_CANCELLED:
+        type = "cancelled"
+
+    format_str = "pid:{0:<12}{1:<16.6f}" \
+                 "kgsl_fire_event: ctx={2} ts={3} type={4} age={5}"
+    func_writeln(format_str.format(header["pid"], header["time"],
+                                   id, ts, type, age))
+    return False
+
+
+def cmdbatch_submitted_event_write(func_writeln, dump, kgsl_eventlog_buffer,
+                                   header):
+    if header["payload_size"] != sizeof(cmdbatch_submitted):
+        return True
+    id = dump.read_u32(kgsl_eventlog_buffer + cmdbatch_submitted.id.offset)
+    ts = dump.read_u32(kgsl_eventlog_buffer + cmdbatch_submitted.ts.offset)
+    prio = dump.read_u32(kgsl_eventlog_buffer +
+                         cmdbatch_submitted.prio.offset)
+    flags = dump.read_u64(kgsl_eventlog_buffer +
+                          cmdbatch_submitted.flags.offset)
+    format_str = "pid:{0:<12}{1:<16.6f}" \
+                 "adreno_cmdbatch_submitted: ctx={2} ctx_prio={3} " \
+                 "ts={4} flags={5}"
+    func_writeln(format_str.format(header["pid"], header["time"],
+                                   id, prio, ts, flags))
+    return False
+
+
+def cmdbatch_retired_event_write(func_writeln, dump, kgsl_eventlog_buffer,
+                                 header):
+    if header["payload_size"] != sizeof(cmdbatch_retired):
+        return True
+    id = dump.read_u32(kgsl_eventlog_buffer + cmdbatch_retired.id.offset)
+    ts = dump.read_u32(kgsl_eventlog_buffer + cmdbatch_retired.ts.offset)
+    prio = dump.read_u32(kgsl_eventlog_buffer + cmdbatch_retired.prio.offset)
+    flag = dump.read_u64(kgsl_eventlog_buffer + cmdbatch_retired.flag.offset)
+    start = dump.read_u64(kgsl_eventlog_buffer +
+                          cmdbatch_retired.start.offset)
+    retire = dump.read_u64(kgsl_eventlog_buffer +
+                           cmdbatch_retired.retire.offset)
+    format_str = "pid:{0:<12}{1:<16.6f}" \
+                 "adreno_cmdbatch_retired: ctx={2} ctx_prio={3} " \
+                 "ts={4} flags={5} start={6} retire={7}"
+    func_writeln(format_str.format(header["pid"], header["time"], id,
+                 prio, ts, flag, start, retire))
+    return False
+
+
+def syncpoint_fence_event_write(func_writeln, dump, kgsl_eventlog_buffer,
+                                header):
+    if header["payload_size"] != sizeof(syncpoint_fence):
+        return True
+    id = dump.read_u32(kgsl_eventlog_buffer + syncpoint_fence.id.offset)
+    name = dump.read_cstring(kgsl_eventlog_buffer +
+                             syncpoint_fence.name.offset, 74)
+    if header["event_id"] == LOG_SYNCPOINT_FENCE_EVENT:
+        event = "syncpoint_fence"
+    elif header["event_id"] == LOG_SYNCPOINT_FENCE_EXPIRE_EVENT:
+        event = "syncpoint_fence_expire"
+
+    format_str = "pid:{0:<12}{1:<16.6f}" \
+                 "{2}: ctx={3} name={4}"
+    func_writeln(format_str.format(header["pid"], header["time"],
+                                   event, id, name))
+    return False
+
+
+def timeline_fence_event_write(func_writeln, dump, kgsl_eventlog_buffer,
+                               header):
+    if header["payload_size"] != sizeof(timeline_fence):
+        return True
+    id = dump.read_u32(kgsl_eventlog_buffer + timeline_fence.id.offset)
+    seqno = dump.read_u64(kgsl_eventlog_buffer + timeline_fence.seqno.offset)
+    if header["event_id"] == LOG_TIMELINE_FENCE_ALLOC_EVENT:
+        event = "kgsl_timeline_fence_alloc"
+    elif header["event_id"] == LOG_TIMELINE_FENCE_RELEASE_EVENT:
+        event = "kgsl_timeline_fence_release"
+
+    format_str = "pid:{0:<12}{1:<16.6f}" \
+                 "{2}: timeline={3} seqno={4}"
+    func_writeln(format_str.format(header["pid"], header["time"], event,
+                                   id, seqno))
+    return False
+
+
+def parse_eventlog_buffer(func_writeln, dump):
+    kgsl_eventlog_buffer = dump.read('kgsl_eventlog')
+    format_str = '{0:<15} {1:<16}{2}'
+    func_writeln(format_str.format("PID", "Timestamp", "Function"))
+    min_timestamp = None
+    offset = 0
+    ret = True
+    header = {}
+    while offset < 8192:
+        header["magic_num"] = dump.read_structure_field(
+                              kgsl_eventlog_buffer, 'struct kgsl_log_header',
+                              'magic')
+        header["event_id"] = dump.read_structure_field(
+                             kgsl_eventlog_buffer,
+                             'struct kgsl_log_header', 'eventid')
+        header["time"] = dump.read_structure_field(
+                         kgsl_eventlog_buffer,
+                         'struct kgsl_log_header', 'time') / NANO_TO_SEC
+        header["pid"] = dump.read_structure_field(
+                        kgsl_eventlog_buffer,
+                        'struct kgsl_log_header', 'pid')
+        header["payload_size"] = dump.read_structure_field(
+                                 kgsl_eventlog_buffer,
+                                 'struct kgsl_log_header', 'size')
+
+        if (header["magic_num"] != MAGIC) or (header["event_id"] > 8) or \
+           (header["event_id"] < 1):
+            offset += 1
+            kgsl_eventlog_buffer += 1
+            continue
+
+        if min_timestamp is None:
+            min_timestamp = header["time"]
+
+        kgsl_eventlog_buffer += dump.sizeof('struct kgsl_log_header')
+        if min_timestamp > header["time"]:
+            func_writeln("End of logging".center(90, '-') + '\n')
+            min_timestamp = header["time"]
+        if header["event_id"] == LOG_SKIP:
+            break
+        elif header["event_id"] == LOG_FIRE_EVENT:
+            ret = fire_event_write(func_writeln, dump, kgsl_eventlog_buffer,
+                                   header)
+        elif header["event_id"] == LOG_CMDBATCH_SUBMITTED_EVENT:
+            ret = cmdbatch_submitted_event_write(func_writeln, dump,
+                                                 kgsl_eventlog_buffer, header)
+        elif header["event_id"] == LOG_CMDBATCH_RETIRED_EVENT:
+            ret = cmdbatch_retired_event_write(func_writeln, dump,
+                                               kgsl_eventlog_buffer, header)
+        elif (header["event_id"] == LOG_SYNCPOINT_FENCE_EVENT) or \
+             (header["event_id"] == LOG_SYNCPOINT_FENCE_EXPIRE_EVENT):
+            ret = syncpoint_fence_event_write(func_writeln, dump,
+                                              kgsl_eventlog_buffer, header)
+        elif (header["event_id"] == LOG_TIMELINE_FENCE_ALLOC_EVENT) or \
+             (header["event_id"] == LOG_TIMELINE_FENCE_RELEASE_EVENT):
+            ret = timeline_fence_event_write(func_writeln, dump,
+                                             kgsl_eventlog_buffer, header)
+        if ret:
+            offset += 1
+            kgsl_eventlog_buffer += 1
+            continue
+
+        offset += dump.sizeof('struct kgsl_log_header') + \
+            header["payload_size"]
+        kgsl_eventlog_buffer += header["payload_size"]
diff --git a/linux-ramdump-parser-v2/parsers/gpu/gpu_snapshot.py b/linux-ramdump-parser-v2/parsers/gpu/gpu_snapshot.py
new file mode 100644
index 0000000..f48c7b3
--- /dev/null
+++ b/linux-ramdump-parser-v2/parsers/gpu/gpu_snapshot.py
@@ -0,0 +1,289 @@
+# Copyright (c) 2021 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.
+
+from ctypes import c_int, c_int64, c_uint, c_ushort, sizeof, Structure
+
+# High word is static, low word is snapshot version ID
+SNAPSHOT_MAGIC = 0x504D0002
+
+# Section header
+SNAPSHOT_SECTION_MAGIC = 0xABCD
+
+# Snapshot Sections
+KGSL_SNAPSHOT_SECTION_OS            =   0x0101
+KGSL_SNAPSHOT_SECTION_END           =   0xFFFF
+KGSL_SNAPSHOT_SECTION_RB_V2         =   0x0302
+KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2 =   0x0B02
+KGSL_SNAPSHOT_SECTION_MEMLIST_V2    =   0x0E02
+KGSL_SNAPSHOT_SECTION_MEM_HISTORY   =   0x1202
+KGSL_SNAPSHOT_SECTION_IB_V2         =   0x0402
+KGSL_SNAPSHOT_SECTION_REGS          =   0x0201
+KGSL_SNAPSHOT_SECTION_MVC           =   0x1501
+KGSL_SNAPSHOT_SECTION_INDEXED_REGS  =   0x0501
+KGSL_SNAPSHOT_SECTION_DEBUG         =   0x0901
+KGSL_SNAPSHOT_SECTION_DEBUGBUS      =   0x0A01
+KGSL_SNAPSHOT_SECTION_SHADER        =   0x1201
+KGSL_SNAPSHOT_SECTION_GMU           =   0x1601
+KGSL_SNAPSHOT_SECTION_GMU_MEMORY    =   0x1701
+
+# Ringbuffer
+KGSL_RB_SIZE                =   (32 * 1024)
+KGSL_RB_DWORDS              =   (KGSL_RB_SIZE >> 2)
+
+# GMU Sections
+GMU_SECTION_TYPE_OTHER      =   0
+GMU_SECTION_TYPE_HFIMEM     =   1
+GMU_SECTION_TYPE_LOG        =   2
+GMU_SECTION_TYPE_BWMEM      =   3
+GMU_SECTION_TYPE_DEBUG      =   4
+GMU_SECTION_TYPE_DCACHE     =   5
+GMU_SECTION_TYPE_ICACHE     =   6
+GMU_SECTION_TYPE_UNCACHE    =   7
+GMU_SECTION_TYPE_REASON     =   8
+GMU_SECTION_TYPE_VERSION    =   9
+
+# GMU Memory Sections
+SNAPSHOT_GMU_MEM_UNKNOWN    =   0
+SNAPSHOT_GMU_MEM_HFI        =   1
+SNAPSHOT_GMU_MEM_LOG        =   2
+SNAPSHOT_GMU_MEM_BWTABLE    =   3
+SNAPSHOT_GMU_MEM_DEBUG      =   4
+SNAPSHOT_GMU_MEM_BIN_BLOCK  =   5
+
+
+# KGSL structures
+class kgsl_snapshot_header(Structure):
+    _pack_ = 1
+    _fields_ = [('magic', c_uint),
+                ('gpuid', c_uint),
+                ('chipid', c_uint)]
+
+
+class kgsl_snapshot_section_header(Structure):
+    _pack_ = 1
+    _fields_ = [('magic', c_ushort),
+                ('id', c_ushort),
+                ('size', c_uint)]
+
+
+class kgsl_snapshot_rb_v2(Structure):
+    _pack_ = 1
+    _fields_ = [('start', c_int),
+                ('end', c_int),
+                ('rbsize', c_int),
+                ('wptr', c_int),
+                ('rptr', c_int),
+                ('count', c_int),
+                ('timestamp_queued', c_uint),
+                ('timestamp_retired', c_uint),
+                ('gpuaddr', c_int64),
+                ('id', c_uint)]
+
+
+class kgsl_snapshot_gmu_mem(Structure):
+    _pack_ = 1
+    _fields_ = [('type', c_int),
+                ('hostaddr', c_int64),
+                ('gmuaddr', c_int64),
+                ('gpuaddr', c_int64)]
+
+
+def gmu_log(devp, dump, chipid):
+    if chipid >= 0x7000000:
+        gmu_dev = dump.sibling_field_addr(devp, 'struct genc_device',
+                                          'adreno_dev', 'gmu')
+        gmu_logs = dump.read_structure_field(gmu_dev,
+                                             'struct genc_gmu_device',
+                                             'gmu_log')
+    else:
+        gmu_dev = dump.sibling_field_addr(devp, 'struct a6xx_device',
+                                          'adreno_dev', 'gmu')
+        gmu_logs = dump.read_structure_field(gmu_dev,
+                                             'struct a6xx_gmu_device',
+                                             'gmu_log')
+
+    gmu_log_hostptr = dump.read_structure_field(gmu_logs,
+                                                'struct gmu_memdesc',
+                                                'hostptr')
+    gmu_log_size = dump.read_structure_field(gmu_logs,
+                                             'struct gmu_memdesc', 'size')
+    gmu_log_gmuaddr = dump.read_structure_field(gmu_logs,
+                                                'struct gmu_memdesc',
+                                                'gmuaddr')
+    return (gmu_log_hostptr, gmu_log_size, gmu_log_gmuaddr)
+
+
+def hfi_mem(devp, dump, chipid):
+    if chipid >= 0x7000000:
+        gmu_dev = dump.sibling_field_addr(devp, 'struct genc_device',
+                                          'adreno_dev', 'gmu')
+        hfi = dump.struct_field_addr(gmu_dev, 'struct genc_gmu_device',
+                                     'hfi')
+        hfi_mem = dump.read_structure_field(hfi, 'struct genc_hfi',
+                                            'hfi_mem')
+    else:
+        gmu_dev = dump.sibling_field_addr(devp, 'struct a6xx_device',
+                                          'adreno_dev', 'gmu')
+        hfi = dump.struct_field_addr(gmu_dev, 'struct a6xx_gmu_device',
+                                     'hfi')
+        hfi_mem = dump.read_structure_field(hfi, 'struct a6xx_hfi',
+                                            'hfi_mem')
+
+    hfi_mem_hostptr = dump.read_structure_field(hfi_mem,
+                                                'struct gmu_memdesc',
+                                                'hostptr')
+    hfi_mem_size = dump.read_structure_field(hfi_mem,
+                                             'struct gmu_memdesc', 'size')
+    hfi_mem_gmuaddr = dump.read_structure_field(hfi_mem,
+                                                'struct gmu_memdesc',
+                                                'gmuaddr')
+    return (hfi_mem_hostptr, hfi_mem_size, hfi_mem_gmuaddr)
+
+
+def snapshot_gmu_mem_section(devp, dump, chipid, file, hdr_type):
+    if hdr_type == SNAPSHOT_GMU_MEM_HFI:
+        (gmu_mem_hostptr, gmu_mem_size, gmu_mem_gmuaddr) = hfi_mem(devp, dump,
+                                                                   chipid)
+    elif hdr_type == SNAPSHOT_GMU_MEM_LOG:
+        (gmu_mem_hostptr, gmu_mem_size, gmu_mem_gmuaddr) = gmu_log(devp, dump,
+                                                                   chipid)
+    else:
+        return
+
+    section_header = kgsl_snapshot_section_header()
+    section_header.magic = SNAPSHOT_SECTION_MAGIC
+    section_header.id = KGSL_SNAPSHOT_SECTION_GMU_MEMORY
+    section_header.size = (gmu_mem_size + sizeof(kgsl_snapshot_gmu_mem) +
+                           sizeof(kgsl_snapshot_section_header))
+    file.write(section_header)
+
+    mem_hdr = kgsl_snapshot_gmu_mem()
+    mem_hdr.type = hdr_type
+    mem_hdr.hostaddr = gmu_mem_hostptr
+    mem_hdr.gmuaddr = gmu_mem_gmuaddr
+    mem_hdr.gpuaddr = 0
+    file.write(mem_hdr)
+
+    data = dump.read_binarystring(gmu_mem_hostptr, gmu_mem_size)
+    file.write(data)
+
+
+def snapshot_rb_section(devp, dump, file, rb_type):
+    # Scratch buffer information
+    scratch_obj = dump.read_structure_field(devp,
+                                            'struct kgsl_device',
+                                            'scratch')
+    scratch_hostptr = dump.read_structure_field(scratch_obj,
+                                                'struct kgsl_memdesc',
+                                                'hostptr')
+
+    # Memstore information
+    memstore_obj = dump.read_structure_field(devp,
+                                             'struct kgsl_device',
+                                             'memstore')
+    memstore_hostptr = dump.read_structure_field(memstore_obj,
+                                                 'struct kgsl_memdesc',
+                                                 'hostptr')
+
+    # RB information
+    rb = dump.read_structure_field(devp,
+                                   'struct adreno_device', rb_type)
+    if (not rb):
+        return
+
+    rb_id = dump.read_structure_field(rb,
+                                      'struct adreno_ringbuffer',
+                                      'id')
+    rb_wptr = dump.read_structure_field(rb,
+                                        'struct adreno_ringbuffer',
+                                        'wptr')
+    rb_rptr = dump.read_s32(scratch_hostptr + rb_id * 4)
+    rb_queued_ts = dump.read_structure_field(rb,
+                                             'struct adreno_ringbuffer',
+                                             'timestamp')
+    rb_buffer_desc = dump.read_structure_field(rb,
+                                               'struct adreno_ringbuffer',
+                                               'buffer_desc')
+    rb_gpuaddr = dump.read_structure_field(rb_buffer_desc,
+                                           'struct kgsl_memdesc',
+                                           'gpuaddr')
+    rb_hostptr = dump.read_structure_field(rb_buffer_desc,
+                                           'struct kgsl_memdesc',
+                                           'hostptr')
+    rb_size = dump.read_structure_field(rb_buffer_desc,
+                                        'struct kgsl_memdesc', 'size')
+    rb_retired_ts = dump.read_s32(memstore_hostptr +
+                                  ((rb_id + 0x32E) * 0x28 + 0x8))
+
+    # RB section
+    section_header = kgsl_snapshot_section_header()
+    section_header.magic = SNAPSHOT_SECTION_MAGIC
+    section_header.id = KGSL_SNAPSHOT_SECTION_RB_V2
+    section_header.size = (KGSL_RB_SIZE + sizeof(kgsl_snapshot_rb_v2) +
+                           sizeof(kgsl_snapshot_section_header))
+    file.write(section_header)
+
+    rb_header = kgsl_snapshot_rb_v2()
+    rb_header.start = 0
+    rb_header.end = KGSL_RB_DWORDS
+    rb_header.wptr = rb_wptr
+    rb_header.rptr = rb_rptr
+    rb_header.rbsize = KGSL_RB_DWORDS
+    rb_header.count = KGSL_RB_DWORDS
+    rb_header.timestamp_queued = rb_queued_ts
+    rb_header.timestamp_retired = rb_retired_ts
+    rb_header.gpuaddr = rb_gpuaddr
+    rb_header.id = rb_id
+    file.write(rb_header)
+
+    data = dump.read_binarystring(rb_hostptr, rb_size)
+    file.write(data)
+
+
+def create_snapshot_from_ramdump(devp, dump):
+    # GPU revision
+    gpucore = dump.read_structure_field(devp,
+                                        'struct adreno_device',
+                                        'gpucore')
+    gpurev = dump.read_structure_field(gpucore,
+                                       'struct adreno_gpu_core', 'gpurev')
+
+    # Gpu chip id
+    chipid = dump.read_structure_field(devp,
+                                       'struct adreno_device',
+                                       'chipid')
+
+    file_name = 'mini_snapshot.bpmd'
+    file = dump.open_file('gpu_parser/' + file_name, 'wb')
+
+    # Dump snapshot header
+    header = kgsl_snapshot_header()
+    header.magic = SNAPSHOT_MAGIC
+    header.gpuid = (0x0003 << 16) | gpurev
+    header.chipid = chipid
+    file.write(header)
+
+    # Dump RBs
+    snapshot_rb_section(devp, dump, file, 'cur_rb')
+    snapshot_rb_section(devp, dump, file, 'prev_rb')
+
+    # Dump GMU info
+    snapshot_gmu_mem_section(devp, dump, chipid, file, SNAPSHOT_GMU_MEM_HFI)
+    snapshot_gmu_mem_section(devp, dump, chipid, file, SNAPSHOT_GMU_MEM_LOG)
+
+    # Dump last section
+    last_section = kgsl_snapshot_section_header()
+    last_section.magic = SNAPSHOT_SECTION_MAGIC
+    last_section.id = KGSL_SNAPSHOT_SECTION_END
+    last_section.size = sizeof(kgsl_snapshot_section_header)
+    file.write(last_section)
+
+    file.close()
diff --git a/linux-ramdump-parser-v2/parsers/gpu/gpuinfo_510.py b/linux-ramdump-parser-v2/parsers/gpu/gpuinfo_510.py
index cad34eb..794a655 100644
--- a/linux-ramdump-parser-v2/parsers/gpu/gpuinfo_510.py
+++ b/linux-ramdump-parser-v2/parsers/gpu/gpuinfo_510.py
@@ -9,11 +9,15 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
-from parser_util import RamParser
-from print_out import print_out_str
 import linux_list
-import traceback
 import linux_radix_tree
+import traceback
+
+from parser_util import RamParser
+from parsers.gpu.gpu_snapshot import create_snapshot_from_ramdump
+from parsers.gpu.gpu_eventlog import parse_eventlog_buffer
+from print_out import print_out_str
+
 
 # Global Configurations
 ADRENO_DISPATCH_DRAWQUEUE_SIZE = 128
@@ -53,6 +57,7 @@
             (self.parse_fence_data, "Fences", 'gpu_sync_fences.txt'),
             (self.parse_open_process_mementry, "Open Process Mementries",
              'open_process_mementries.txt'),
+            (self.parse_eventlog_data, "Eventlog Buffer", 'eventlog.txt'),
         ]
 
         self.rtw = linux_radix_tree.RadixTreeWalker(dump)
@@ -297,6 +302,9 @@
             self.writeln('\t' + str(pool_order[i]) + ' order pool size: ' +
                          str_convert_to_kb(pool_size[i]*PAGE_SIZE))
 
+    def parse_eventlog_data(self, dump):
+        parse_eventlog_buffer(self.writeln, dump)
+
     def parse_dispatcher_data(self, dump):
         dispatcher_addr = dump.struct_field_addr(self.devp,
                                                  'struct adreno_device',
@@ -935,6 +943,7 @@
         atomic_snapshot = dump.read_bool(atomic_snapshot_addr)
         if not atomic_snapshot:
             self.writeln('No atomic snapshot detected.')
+            self.create_mini_snapshot(dump)
             return
 
         atomic_snapshot_offset = dump.field_offset(
@@ -946,6 +955,7 @@
 
         if atomic_snapshot_base == 0 or atomic_snapshot_size == 0:
             self.writeln('Invalid atomic snapshot.')
+            self.create_mini_snapshot(dump)
             return
 
         self.writeln('Atomic Snapshot Details:')
@@ -958,3 +968,6 @@
         self.writeln('\nData dumped to atomic_snapshot.bpmd')
         file.write(data)
         file.close()
+
+    def create_mini_snapshot(self, dump):
+        create_snapshot_from_ramdump(self.devp, dump)
diff --git a/linux-ramdump-parser-v2/parsers/gpu/gpuinfo_54.py b/linux-ramdump-parser-v2/parsers/gpu/gpuinfo_54.py
index f37bee2..9de000e 100644
--- a/linux-ramdump-parser-v2/parsers/gpu/gpuinfo_54.py
+++ b/linux-ramdump-parser-v2/parsers/gpu/gpuinfo_54.py
@@ -9,11 +9,14 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
-from parser_util import RamParser
-from print_out import print_out_str
 import linux_list
-import traceback
 import linux_radix_tree
+import traceback
+
+from parser_util import RamParser
+from parsers.gpu.gpu_snapshot import create_snapshot_from_ramdump
+from print_out import print_out_str
+
 
 # Global Configurations
 ADRENO_DISPATCH_DRAWQUEUE_SIZE = 128
@@ -1151,6 +1154,7 @@
         atomic_snapshot = dump.read_bool(atomic_snapshot_addr)
         if not atomic_snapshot:
             self.writeln('No atomic snapshot detected.')
+            self.create_mini_snapshot(dump)
             return
 
         atomic_snapshot_offset = dump.field_offset(
@@ -1162,6 +1166,7 @@
 
         if atomic_snapshot_base == 0 or atomic_snapshot_size == 0:
             self.writeln('Invalid atomic snapshot.')
+            self.create_mini_snapshot(dump)
             return
 
         self.writeln('Atomic Snapshot Details:')
@@ -1174,3 +1179,6 @@
         self.writeln('\nData dumped to atomic_snapshot.bpmd')
         file.write(data)
         file.close()
+
+    def create_mini_snapshot(self, dump):
+        create_snapshot_from_ramdump(self.devp, dump)
diff --git a/linux-ramdump-parser-v2/parsers/gpuinfo.py b/linux-ramdump-parser-v2/parsers/gpuinfo.py
index f3ebee6..d866f77 100644
--- a/linux-ramdump-parser-v2/parsers/gpuinfo.py
+++ b/linux-ramdump-parser-v2/parsers/gpuinfo.py
@@ -22,7 +22,8 @@
         super(GpuParser, self).__init__(dump)
 
     def parse(self):
-        if not self.ramdump.is_config_defined('CONFIG_QCOM_KGSL'):
+        if not (self.ramdump.is_config_defined('CONFIG_QCOM_KGSL') or
+                'msm_kgsl' in self.ramdump.ko_file_names):
             print_out_str(
                 "No GPU support detected... Skipping GPU parser.")
             return
diff --git a/linux-ramdump-parser-v2/parsers/ion_buffer_parse.py b/linux-ramdump-parser-v2/parsers/ion_buffer_parse.py
index f1aea7c..e143947 100644
--- a/linux-ramdump-parser-v2/parsers/ion_buffer_parse.py
+++ b/linux-ramdump-parser-v2/parsers/ion_buffer_parse.py
@@ -37,6 +37,7 @@
 grand_total = 0
 TASK_NAME_LENGTH = 16
 ion_heap_buffers = []
+dmabuf_heap_names = ["qcom_dma_heaps"]
 
 
 def bytes_to_KB(bytes):
@@ -50,7 +51,34 @@
         if bytes != 0:
             val = (bytes // 1024) // 1024
         return val
-        
+
+def get_dmabuf_heap_names(self, ramdump, ion_info):
+    heap_list = ramdump.address_of('heap_list')
+    if heap_list is None:
+        ion_info.write("NOTE: 'heap_list' list not found to extract the "
+                        "dmabuf heap type list")
+        return False
+
+    list_offset = ramdump.field_offset('struct dma_heap', 'list')
+    name_offset = ramdump.field_offset('struct dma_heap', 'name')
+    next_offset = ramdump.field_offset('struct list_head', 'next')
+    prev_offset = ramdump.field_offset('struct list_head', 'prev')
+
+    head = ramdump.read_word(heap_list + next_offset)
+    while (head != heap_list):
+        dma_heap_addr = head - list_offset
+        dma_heap_name_addr = ramdump.read_word(dma_heap_addr + name_offset)
+        dma_heap_name = ramdump.read_cstring(dma_heap_name_addr, 48)
+        dmabuf_heap_names.append(dma_heap_name)
+
+        head = ramdump.read_word(head + next_offset)
+        prev = ramdump.read_word(head + prev_offset)
+        if head == 0 or prev == 0:
+            ion_info.write("NOTE: 'dmabuf heap_list' is corrupted")
+            return False
+
+    return True
+
 def ion_buffer_info(self, ramdump, ion_info):
     ion_info = ramdump.open_file('ionbuffer.txt')
     db_list = ramdump.address_of('db_list')
@@ -76,6 +104,10 @@
     ion_info.write("{0:40} {1:4} {2:15} {3:10} {4:10} {5:10} {6:20}\n".format(
             'File_addr', 'REF', 'Name', 'Size', 'Exp', 'Heap', 'Size in KB'))
     dma_buf_info = []
+    if (ramdump.kernel_version >= (5, 10)):
+        if get_dmabuf_heap_names(self, ramdump, ion_info) is False:
+            return
+
     while (head != db_list):
         dma_buf_addr = head - list_node_offset
         size = ramdump.read_word(dma_buf_addr + size_offset)
@@ -86,7 +118,7 @@
         exp_name = ramdump.read_cstring(exp_name, 48)
         ionheap_name = None
         if (ramdump.kernel_version >= (5, 10)):
-            if 'qcom_dma_heaps' in exp_name:
+            if exp_name in dmabuf_heap_names:
                 ion_buffer = ramdump.read_structure_field(dma_buf_addr, 'struct dma_buf', 'priv')
                 ion_heap = ramdump.read_structure_field(ion_buffer, 'struct qcom_sg_buffer', 'heap')
                 ionheap_name_addr = ramdump.read_structure_field(ion_heap, 'struct dma_heap', 'name')
@@ -121,7 +153,7 @@
                 exp_name = ramdump.read_word(dma_buf_addr + exp_name_offset)
                 exp_name = ramdump.read_cstring(exp_name, 48)
                 if (ramdump.kernel_version >= (5, 10)):
-                    if exp_name == 'qcom_dma_heaps':
+                    if exp_name in dmabuf_heap_names:
                         ion_buffer = ramdump.read_structure_field(dma_buf_addr, 'struct dma_buf', 'priv')
                         ion_heap = ramdump.read_structure_field(ion_buffer, 'struct qcom_sg_buffer', 'heap')
                         ionheap_name_addr = ramdump.read_structure_field(ion_heap, 'struct dma_heap', 'name')
diff --git a/linux-ramdump-parser-v2/parsers/lpm.py b/linux-ramdump-parser-v2/parsers/lpm.py
index 1856450..8e9cb40 100644
--- a/linux-ramdump-parser-v2/parsers/lpm.py
+++ b/linux-ramdump-parser-v2/parsers/lpm.py
@@ -164,6 +164,9 @@
         name += ":idle_states:S{}"
 
         state_count = self.ramdump.read_structure_field(node, 'struct generic_pm_domain', 'state_count')
+        #sanity check for state count , CPUIDLE_STATE_MAX
+        if state_count >= 10:
+            return
         accounting_time = self.ramdump.read_structure_field(node, 'struct generic_pm_domain', 'accounting_time')
         gpd_power_state_size = self.ramdump.sizeof('struct genpd_power_state')
         power_state_offset = self.ramdump.field_offset('struct generic_pm_domain', 'states')
diff --git a/linux-ramdump-parser-v2/parsers/mdpinfo.py b/linux-ramdump-parser-v2/parsers/mdpinfo.py
index d9517f3..4eb87fe 100644
--- a/linux-ramdump-parser-v2/parsers/mdpinfo.py
+++ b/linux-ramdump-parser-v2/parsers/mdpinfo.py
@@ -47,7 +47,7 @@
     _fields = {
             'evtlog': Struct.get_pointer,
             'reglog': Struct.get_pointer,
-            'reg_base_list': Struct.get_pointer,
+            'reg_base_list': Struct.get_address,
             'enable_reg_dump' : Struct.get_u32,
             'panic_on_err' : Struct.get_u32,
             'dbgbus_sde': Struct.get_address,
@@ -2611,16 +2611,16 @@
                           struct_name="struct sde_dbg_reglog",
                           fields={'enable': Struct.get_u32,
                                   'last': Struct.get_u32,
-                                  'curr': Struct.get_u32,
+                                  'curr': Struct.get_u64,
                                   'logs': Struct.get_address,
                                   'last_dump': Struct.get_u32})
                 SDE_REGLOG_ENTRY = 1024
                 self.outfile.write('%-21.5s%-11.5s%-13.7s%-13.5s%s\n' % ("TIME", "PID", "ADDRESS", "VAL", "BLK_ID"))
                 sde_reglog_start = 0
                 sde_reglog_repeat = 0
-                sde_reglog_curr = reg_log.curr % SDE_REGLOG_ENTRY
+                sde_reglog_curr = abs(reg_log.curr % SDE_REGLOG_ENTRY)
                 if (sde_reglog_curr != reg_log.last):
-                    sde_reglog_start = sde_reglog_curr
+                    sde_reglog_start = sde_reglog_curr + 1
                 else:
                     sde_reglog_repeat = 1
                 sde_reglog_count = 0
@@ -2661,38 +2661,38 @@
             evtlog = f_evtlog.readline()
             reglog = f_reglog.readline()
             curr_timestamp = 0
-
+            self.outfile.write('{:<54}{:<29}{:<6}{:<3}{:<200}\n'.format("EVTLOG_REGLOG_MERGED", "TIMESTAMP", "PID", "CPU", "DATA"))
             while (evtlog and reglog):
                 if "FUNCTION_NAME" in evtlog:
                     evtlog = f_evtlog.readline()
                 if "TIME" in reglog:
                     reglog = f_reglog.readline()
+                if "COMMIT" in evtlog:
+                    evtlog = f_evtlog.readline()
                 if not evtlog or not reglog:
                     break
 
-                evtlog_tmp = re.split(r'==>|: |\n', evtlog)
+                evtlog_tmp = re.split(r'==>|: |\n', evtlog, 2)
                 data_tmp = evtlog_tmp[2].split("[", 1)
                 reglog_tmp = re.sub(r'\s+', ' ', reglog)
                 reglog_tmp = reglog.split()
 
                 if (int(evtlog_tmp[1]) > int(reglog_tmp[0])):
                     self.outfile.write('{:<54}{:<29}{:<6}{:<3}{:<200}'.format("sde_reg_write", "==>"+str(reglog_tmp[0])+": "+str(int(reglog_tmp[0]) - curr_timestamp), "["+reglog_tmp[1]+"]","[N]", reglog_tmp[2] + " " + reglog_tmp[3] + " " + reglog_tmp[4]))
-                    self.outfile.write('\n')
                     reglog = f_reglog.readline()
                     curr_timestamp = int(reglog_tmp[0])
+                    self.outfile.write('\n')
                 else:
                     self.outfile.write('{:<54}{:<29}{:<200}'.format(evtlog_tmp[0], "==>"+str(evtlog_tmp[1])+": "+str(int(evtlog_tmp[1]) - curr_timestamp),"["+data_tmp[1]))
                     evtlog = f_evtlog.readline()
                     curr_timestamp = int(evtlog_tmp[1])
-                    self.outfile.write('\n')
 
             while(evtlog):
-                evtlog_tmp = re.split(r'==>|: |\n', evtlog)
+                evtlog_tmp = re.split(r'==>|: |\n', evtlog, 2)
                 data_tmp = evtlog_tmp[2].split("[", 1)
                 self.outfile.write('{:<54}{:<29}{:<200}'.format(evtlog_tmp[0], "==>"+str(evtlog_tmp[1])+": "+str(int(evtlog_tmp[1]) - curr_timestamp),"["+data_tmp[1]))
                 evtlog = f_evtlog.readline()
                 curr_timestamp = int(evtlog_tmp[1])
-                self.outfile.write('\n')
 
             while(reglog):
                 reglog_tmp = re.sub(r'\s+', ' ', reglog)
@@ -2728,13 +2728,13 @@
 
             self.outfile.write('=================================sde debug bus points=================================\n\n')
             self.outfile.write('{:<12}{:<12}{:<12}{:<15}'.format("wr_addr", "block_id", "test_id", "val"))
-            self.outfile.write('\n')
+            self.outfile.write('\n\n')
             while (i < dbgbus_sde_cmn.content_size):
                 j = 0
                 while (j < 16):
                     self.outfile.write('%-10.8x ' % (self.ramdump.read_u32(dbgbus_sde_cmn.dumped_content + (i*4) + j)))
                     j = j + 4
-                self.outfile.write('\n\n')
+                self.outfile.write('\n')
                 i = i + 4
 
             i = 0
diff --git a/linux-ramdump-parser-v2/parsers/memstat.py b/linux-ramdump-parser-v2/parsers/memstat.py
index 15c0cdc..cd4174b 100644
--- a/linux-ramdump-parser-v2/parsers/memstat.py
+++ b/linux-ramdump-parser-v2/parsers/memstat.py
@@ -12,12 +12,19 @@
 from parser_util import register_parser, RamParser
 import os
 import linux_list as llist
+import linux_radix_tree
 
 VM_ALLOC = 0x00000002
 
 
 @register_parser('--print-memstat', 'Print memory stats ')
 class MemStats(RamParser):
+    def __init__(self, dump):
+        super(MemStats, self).__init__(dump)
+
+        if (self.ramdump.kernel_version >= (5, 4)):
+            self.zram_dev_rtw = linux_radix_tree.RadixTreeWalker(self.ramdump)
+            self.zram_mem_mb = 0
 
     def list_func(self, vmlist):
         vm = self.ramdump.read_word(vmlist + self.vm_offset)
@@ -148,6 +155,21 @@
         grandtotal = self.bytes_to_mb(grandtotal)
         return grandtotal
 
+    def calculate_zram_dev_mem_allocated(self, zram):
+        mem_pool = zram + self.ramdump.field_offset('struct zram', 'mem_pool')
+        mem_pool = self.ramdump.read_word(mem_pool)
+
+        pages_allocated = mem_pool + self.ramdump.field_offset('struct zs_pool',
+                                                              'pages_allocated')
+
+        stat_val = self.ramdump.read_word(pages_allocated)
+        if stat_val is None:
+            stat_val = 0
+        else:
+            stat_val = self.pages_to_mb(stat_val)
+
+        self.zram_mem_mb += stat_val
+
     def print_mem_stats(self, out_mem_stat):
         # Total memory
         if(self.ramdump.kernel_version > (4, 20, 0)):
@@ -217,43 +239,42 @@
             if zram_index_idr is None:
                 stat_val = 0
             else:
-                #From Kernel 9.5, The 'struct radix_tree_root', 'rnode' is replaced by 'struct xarray', 'xa_head'
-                #   refer LA.UM.9.14/kernel/msm-5.4/include/linux/xarray.h
+                #'struct radix_tree_root' was replaced by 'struct xarray' on kernel 5.4+
                 if self.ramdump.kernel_version >= (5, 4):
-                    idr_layer_ary_offset = self.ramdump.field_offset(
-                            'struct xarray', 'xa_head')
-                    idr_layer_ary = self.ramdump.read_word(zram_index_idr +
+                    self.zram_dev_rtw.walk_radix_tree(zram_index_idr,
+                                          self.calculate_zram_dev_mem_allocated)
+                    stat_val = self.zram_mem_mb
+                else:
+                    if self.ramdump.kernel_version >= (4, 14):
+                        idr_layer_ary_offset = self.ramdump.field_offset(
+                                    'struct radix_tree_root', 'rnode')
+                        idr_layer_ary = self.ramdump.read_word(zram_index_idr +
+                                    idr_layer_ary_offset)
+                    else:
+                        idr_layer_ary_offset = self.ramdump.field_offset(
+                                    'struct idr_layer', 'ary')
+                        idr_layer_ary = self.ramdump.read_word(zram_index_idr +
                                                            idr_layer_ary_offset)
-                elif self.ramdump.kernel_version >= (4, 14):
-                    idr_layer_ary_offset = self.ramdump.field_offset(
-                            'struct radix_tree_root', 'rnode')
-                    idr_layer_ary = self.ramdump.read_word(zram_index_idr +
-                                                   idr_layer_ary_offset)
-                else:
-                    idr_layer_ary_offset = self.ramdump.field_offset(
-                                'struct idr_layer', 'ary')
-                    idr_layer_ary = self.ramdump.read_word(zram_index_idr +
-                                                       idr_layer_ary_offset)
-                try:
-                    zram_meta = idr_layer_ary + self.ramdump.field_offset(
-                                    'struct zram', 'meta')
-                    zram_meta = self.ramdump.read_word(zram_meta)
-                    mem_pool = zram_meta + self.ramdump.field_offset(
-                            'struct zram_meta', 'mem_pool')
-                    mem_pool = self.ramdump.read_word(mem_pool)
-                except TypeError:
-                    mem_pool = idr_layer_ary + self.ramdump.field_offset(
-                                'struct zram', 'mem_pool')
-                    mem_pool = self.ramdump.read_word(mem_pool)
-                if mem_pool is None:
-                    stat_val = 0
-                else:
-                    page_allocated = mem_pool + self.ramdump.field_offset(
-                                    'struct zs_pool', 'pages_allocated')
-                    stat_val = self.ramdump.read_word(page_allocated)
-                    if stat_val is None:
+                    try:
+                        zram_meta = idr_layer_ary + self.ramdump.field_offset(
+                                        'struct zram', 'meta')
+                        zram_meta = self.ramdump.read_word(zram_meta)
+                        mem_pool = zram_meta + self.ramdump.field_offset(
+                                'struct zram_meta', 'mem_pool')
+                        mem_pool = self.ramdump.read_word(mem_pool)
+                    except TypeError:
+                        mem_pool = idr_layer_ary + self.ramdump.field_offset(
+                                    'struct zram', 'mem_pool')
+                        mem_pool = self.ramdump.read_word(mem_pool)
+                    if mem_pool is None:
                         stat_val = 0
-                    stat_val = self.pages_to_mb(stat_val)
+                    else:
+                        page_allocated = mem_pool + self.ramdump.field_offset(
+                                        'struct zs_pool', 'pages_allocated')
+                        stat_val = self.ramdump.read_word(page_allocated)
+                        if stat_val is None:
+                            stat_val = 0
+                        stat_val = self.pages_to_mb(stat_val)
         else:
             zram_devices_word = self.ramdump.read_word('zram_devices')
             if zram_devices_word is not None:
diff --git a/linux-ramdump-parser-v2/parsers/pagetracking.py b/linux-ramdump-parser-v2/parsers/pagetracking.py
index 33bef51..47896ef 100644
--- a/linux-ramdump-parser-v2/parsers/pagetracking.py
+++ b/linux-ramdump-parser-v2/parsers/pagetracking.py
@@ -23,13 +23,6 @@
     def __init__(self, *args):
         super(PageTracking, self).__init__(*args)
         self.trace_entry_size = self.ramdump.sizeof('unsigned long')
-        if self.ramdump.is_config_defined('CONFIG_SPARSEMEM'):
-            self.page_ext_offset = self.ramdump.field_offset(
-                            'struct mem_section', 'page_ext')
-        else:
-            self.page_ext_offset = self.ramdump.field_offset(
-                            'struct pglist_data', 'node_page_ext')
-
         self.trace_offset = 0
         self.nr_entries_offset = 0
         self.trace_entries_offset = 0
@@ -99,8 +92,7 @@
             phys = pfn << 12
             if phys is None or phys == 0:
                 return -1, -1, -1, -1
-            mem_section = pfn_to_section(self.ramdump, pfn)
-            page_ext = self.ramdump.read_word(mem_section + self.page_ext_offset)
+            page_ext = self.ramdump.mm.lookup_page_ext(pfn)
             """
             page_ext will be null here if the first page of a section is not valid.
             See page_ext_init().
@@ -237,15 +229,13 @@
     def parse(self):
         ranges = None
         if self.ramdump.minidump:
-            addr = self.ramdump.address_of('md_pageowner_dump_addr')
-            if addr is None:
-                print_out_str("NOTE: " +
-                        "Pageowner Minidump is not supported")
-                return
             for eb_file in self.ramdump.ebi_files:
                 path1 = eb_file[3]
             path = os.path.join(path1.split("MD_S")[0], "md_PAGEOWNER.bin")
-            input_file = open(path, 'r')
+            if not os.path.exists(path):
+                print_out_str(path + " not found")
+                return
+            input_file = open(path, 'r', errors="ignore")
             lines = input_file.readlines()
             i = 0
             functions = defaultdict(list)
diff --git a/linux-ramdump-parser-v2/parsers/slabinfo.py b/linux-ramdump-parser-v2/parsers/slabinfo.py
index b356cce..a4cf530 100755
--- a/linux-ramdump-parser-v2/parsers/slabinfo.py
+++ b/linux-ramdump-parser-v2/parsers/slabinfo.py
@@ -532,15 +532,13 @@
 
     def parse(self):
         if self.ramdump.minidump:
-            addr = self.ramdump.address_of('md_slabowner_dump_addr')
-            if addr is None:
-                print_out_str("NOTE: " +
-                        "slabowner Minidump is not supported")
-                return
             for eb_file in self.ramdump.ebi_files:
                 path1 = eb_file[3]
             path = os.path.join(path1.split("MD_S")[0], "md_SLABOWNER.bin")
-            input_file = open(path, 'r')
+            if not os.path.exists(path):
+                print_out_str(path + " not found")
+                return
+            input_file = open(path, 'r', errors="ignore")
             output_file = self.ramdump.open_file("slabowner_dump.txt", 'w')
             lines = input_file.readlines()
             i = 0
diff --git a/linux-ramdump-parser-v2/parsers/taskdump.py b/linux-ramdump-parser-v2/parsers/taskdump.py
index 4ac6ce9..c652d73 100644
--- a/linux-ramdump-parser-v2/parsers/taskdump.py
+++ b/linux-ramdump-parser-v2/parsers/taskdump.py
@@ -159,7 +159,7 @@
 
         task_last_enqueued_ts = 0
         task_last_sleep_ts = 0
-        if offset_last_enqueued_ts is None and ramdump.is_config_defined('CONFIG_SCHED_WALT'):
+        if offset_last_enqueued_ts is None and (ramdump.is_config_defined('CONFIG_SCHED_WALT') or 'sched_walt' in ramdump.ko_file_names):
             offset_last_enqueued_ts = ramdump.field_offset('struct walt_task_struct', 'last_enqueued_ts')
             if (ramdump.kernel_version >= (5, 10, 0)):
                 walt_task_struct_offset = ramdump.field_offset('struct task_struct', 'android_vendor_data1')
@@ -171,7 +171,7 @@
             task_last_enqueued_ts = ramdump.read_u64(next_thread_last_enqueued)
             if task_last_enqueued_ts is None:
                 task_last_enqueued_ts = 0
-        if offset_last_sleep_ts is None and ramdump.is_config_defined('CONFIG_SCHED_WALT'):
+        if offset_last_sleep_ts is None and (ramdump.is_config_defined('CONFIG_SCHED_WALT') or 'sched_walt' in ramdump.ko_file_names):
             offset_last_sleep_ts = ramdump.field_offset('struct walt_task_struct', 'last_sleep_ts ')
             if (ramdump.kernel_version >= (5, 10, 0)):
                 walt_task_struct_offset = ramdump.field_offset('struct task_struct', 'android_vendor_data1')
@@ -216,13 +216,13 @@
                 task_out.write(
                     '=====================================================\n')
                 first = 1
-            task_out.write('    Task name: {0} pid: {1} cpu: {2} prio: {7} start: {'
+            task_out.write('    Task name: {0} [affinity: 0x{11:x}] pid: {1} cpu: {2} prio: {7} start: {'
                            '6:x}\n    state: 0x{3:x}[{8}] exit_state: 0x{4:x}'
                            ' stack base: 0x{5:x}\n'
                            '    Last_enqueued_ts:{9:18.9f} Last_sleep_ts:{10:18.9f}\n'.format(
                 thread_task_name, thread_task_pid, task_cpu, task_state,
                 task_exit_state, addr_stack, next_thread_start, thread_task_prio, task_state_str,
-                task_last_enqueued_ts/1000000000.0, task_last_sleep_ts/1000000000.0))
+                task_last_enqueued_ts/1000000000.0, task_last_sleep_ts/1000000000.0,thread_task_affine))
             if task_on_cpu == 1:
                 taskhighlight_out.write("Task currently running on CPU. Please check dmesg_tz for callstack")
             else:
diff --git a/linux-ramdump-parser-v2/parsers/thermal_data.py b/linux-ramdump-parser-v2/parsers/thermal_data.py
index 8bd47cb..1804441 100755
--- a/linux-ramdump-parser-v2/parsers/thermal_data.py
+++ b/linux-ramdump-parser-v2/parsers/thermal_data.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
+# Copyright (c) 2015, 2020-2021 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
@@ -11,7 +11,10 @@
 
 from print_out import print_out_str
 from parser_util import register_parser, RamParser
+import linux_list as llist
 
+TSENS_MAX_SENSORS = 16
+DEBUG_SIZE = 10
 
 @register_parser(
     '--thermal-info', 'Useful information from thermal data structures')
@@ -75,10 +78,47 @@
             time_stamp,
             sensor_mapping)
 
+    def list_func(self, tsens_device_p):
+        dev_o = self.ramdump.field_offset('struct tsens_device', 'dev')
+        dev = self.ramdump.read_word(dev_o + tsens_device_p)
+        kobj_o = self.ramdump.field_offset('struct device', ' kobj')
+        kobj = (dev + kobj_o)
+        name_o = self.ramdump.field_offset('struct kobject', 'name')
+        name_addr = self.ramdump.read_word(name_o + kobj)
+        name = self.ramdump.read_cstring(name_addr)
+        if name is not None:
+            print("%s" % (name), file=self.output_file)
+            tsens_dbg_o = self.ramdump.field_offset('struct tsens_device', 'tsens_dbg')
+            tsens_dbg = tsens_device_p + tsens_dbg_o
+            sensor_dbg_info_o = self.ramdump.field_offset('struct tsens_dbg_context', 'sensor_dbg_info')
+            sensor_dbg_info = sensor_dbg_info_o  + tsens_dbg
+            self.output_file.write('v.v (struct tsens_device)0x{:8x} 0x{:8x}\n'.format(tsens_device_p, sensor_dbg_info))
+            for i in range(0, TSENS_MAX_SENSORS):
+                idx = self.ramdump.read_u32(self.ramdump.array_index(sensor_dbg_info, 'struct tsens_dbg', i))
+                tsens_dbg_addr = self.ramdump.array_index(sensor_dbg_info, 'struct tsens_dbg', i)
+                print ("    idx: %d tsens_dbg_addr 0x%x" %(idx, tsens_dbg_addr), file=self.output_file)
+                time_stmp_o = self.ramdump.field_offset('struct tsens_dbg', 'time_stmp')
+                temp_o = self.ramdump.field_offset('struct tsens_dbg', 'temp')
+                print("             time_stmp       temp ", file=self.output_file)
+                for j in range(0, DEBUG_SIZE):
+                    time_stmp = self.ramdump.read_word(self.ramdump.array_index(time_stmp_o + tsens_dbg_addr, 'unsigned long long', j))
+                    temp = self.ramdump.read_u64(
+                    self.ramdump.array_index(temp_o + tsens_dbg_addr, 'unsigned long', j))
+                    print("             %d   %d" % (time_stmp, temp), file=self.output_file)
+
+
+    def get_thermal_info(self):
+        tsens_device_list = self.ramdump.address_of('tsens_device_list')
+        list_offset = self.ramdump.field_offset('struct tsens_device', 'list')
+        list_walker = llist.ListWalker(self.ramdump, tsens_device_list, list_offset)
+        list_walker.walk(tsens_device_list, self.list_func)
+
     def parse(self):
         self.output_file = self.ramdump.open_file('thermal_info.txt')
-
-        self.tmdev_data(self.ramdump)
+        if self.ramdump.kernel_version >= (5, 4):
+            self.get_thermal_info()
+        else:
+            self.tmdev_data(self.ramdump)
 
         self.output_file.close()
         print_out_str("--- Wrote the output to thermal_info.txt")
diff --git a/linux-ramdump-parser-v2/parsers/timerlist.py b/linux-ramdump-parser-v2/parsers/timerlist.py
index a6805c1..591a2d6 100644
--- a/linux-ramdump-parser-v2/parsers/timerlist.py
+++ b/linux-ramdump-parser-v2/parsers/timerlist.py
@@ -69,7 +69,7 @@
         else:
            data = ""
 
-        if function == "delayed_work_timer_fn":
+        if function.split('[')[0] == "delayed_work_timer_fn":
             timer_list_offset = self.ramdump.field_offset('struct delayed_work', 'timer')
             work_addr = node - timer_list_offset
             func_addr = work_addr + self.ramdump.field_offset('struct work_struct', 'func')
diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py
index 25bb105..2e1e11b 100644
--- a/linux-ramdump-parser-v2/ramdump.py
+++ b/linux-ramdump-parser-v2/ramdump.py
@@ -598,6 +598,7 @@
         self.arm64 = options.arm64
         self.ndk_compatible = False
         self.lookup_table = []
+        self.ko_file_names = []
 
         if gdb_ndk_path:
             self.gdbmi = gdbmi.GdbMI(self.gdb_ndk_path, self.vmlinux,
@@ -624,7 +625,7 @@
         self.page_offset = 0xc0000000
         self.thread_size = 8192
         self.qtf_path = options.qtf_path
-        self.qtf = options.qtf
+        self.ftrace_format = options.ftrace_format
         self.skip_qdss_bin = options.skip_qdss_bin
         self.debug = options.debug
         self.dcc = False
@@ -1208,7 +1209,6 @@
 
         if not self.minidump:
             if self.arm64:
-                startup_script.write('Register.Set NS 1\n')
                 if self.svm:
                     startup_script.write('Data.Set SPR:0x30201 %Quad 0x{0:x}\n'.format(
                     self.ttbr_data))
@@ -1256,15 +1256,8 @@
                         startup_script.write('Data.Set SPR:0x30A30 %Quad 0x0000000000000000\n')
                         startup_script.write('Data.Set SPR:0x30100 %Quad 0x0000000004C5D93D\n')
 
-                startup_script.write('TRANSlation.COMMON NS:0xF000000000000000--0xffffffffffffffff\n')
-                startup_script.write('trans.tablewalk on\n')
-                startup_script.write('trans.on\n')
-                if not self.svm:
-                    startup_script.write('Register.Set CPSR 0x3C5\n')
-                    startup_script.write('MMU.Delete\n')
-                    startup_script.write('MMU.SCAN PT 0xFFFFFF8000000000--0xFFFFFFFFFFFFFFFF\n')
-                    startup_script.write('mmu.on\n')
-                    startup_script.write('mmu.pt.list 0xffffff8000000000\n')
+                    startup_script.write('Register.Set NS 1\n')
+                    startup_script.write('Register.Set CPSR 0x1C5\n')
             else:
                 # ARM-32: MMU is enabled by default on most platforms.
                 mmu_enabled = 1
@@ -1292,12 +1285,22 @@
         dloadelf = 'data.load.elf {} /nocode\n'.format(where)
         startup_script.write(dloadelf)
 
+        if self.arm64:
+            startup_script.write('TRANSlation.COMMON NS:0xF000000000000000--0xffffffffffffffff\n')
+            startup_script.write('trans.tablewalk on\n')
+            startup_script.write('trans.on\n')
+            if not self.svm and self.cpu_type != 'ARMV9-A':
+                startup_script.write('MMU.Delete\n')
+                startup_script.write('MMU.SCAN PT 0xFFFFFF8000000000--0xFFFFFFFFFFFFFFFF\n')
+                startup_script.write('mmu.on\n')
+                startup_script.write('mmu.pt.list 0xffffff8000000000\n')
+
         if t32_host_system != 'Linux':
             if self.arm64:
                 startup_script.write(
-                     'task.config C:\\T32\\demo\\arm64\\kernel\\linux\\linux-3.x\\linux3.t32\n')
+                     'task.config C:\\T32\\demo\\arm64\\kernel\\linux\\awareness\\linux.t32 /ACCESS NS:\n')
                 startup_script.write(
-                     'menu.reprogram C:\\T32\\demo\\arm64\\kernel\\linux\\linux-3.x\\linux.men\n')
+                     'menu.reprogram C:\\T32\\demo\\arm64\\kernel\\linux\\awareness\\linux.men\n')
             else:
                 if self.kernel_version > (3, 0, 0):
                     startup_script.write(
@@ -1327,15 +1330,25 @@
                     startup_script.write(
                         'menu.reprogram /opt/t32/demo/arm/kernel/linux/linux.men\n')
 
-        for mod_tbl_ent in self.module_table.module_table:
-            mod_sym_path = mod_tbl_ent.get_sym_path()
-            if mod_sym_path != '':
-                where = os.path.abspath(mod_sym_path)
-                if 'wlan' in mod_tbl_ent.name:
-                    ld_mod_sym = "Data.LOAD.Elf " + where + " " + str(hex(mod_tbl_ent.module_offset)) +  " /NoCODE /NoClear /NAME " + mod_tbl_ent.name + " /reloctype 0x3" + "\n"
-                else:
-                    ld_mod_sym = "Data.LOAD.Elf " + where + " /NoCODE /NoClear /NAME " + mod_tbl_ent.name + " /reloctype 0x3" + "\n"
-                startup_script.write(ld_mod_sym)
+        if self.cpu_type == 'ARMV9-A':
+            mod_dir = os.path.dirname(self.vmlinux)
+            mod_dir = os.path.abspath(mod_dir)
+            startup_script.write('sYmbol.AUTOLOAD.CHECKCOMMAND  ' + '"do C:\\T32\\demo\\arm64\\kernel\\linux\\awareness\\autoload.cmm"' + '\n')
+            startup_script.write('sYmbol.SourcePATH.Set ' + '"' + mod_dir + '"' + "\n")
+            startup_script.write('TASK.sYmbol.Option AutoLoad Module\n')
+            startup_script.write('TASK.sYmbol.Option AutoLoad noprocess\n')
+            startup_script.write('sYmbol.AutoLOAD.List\n')
+            startup_script.write('sYmbol.AutoLOAD.CHECK\n')
+        else:
+            for mod_tbl_ent in self.module_table.module_table:
+                mod_sym_path = mod_tbl_ent.get_sym_path()
+                if mod_sym_path != '':
+                    where = os.path.abspath(mod_sym_path)
+                    if 'wlan' in mod_tbl_ent.name:
+                        ld_mod_sym = "Data.LOAD.Elf " + where + " " + str(hex(mod_tbl_ent.module_offset)) +  " /NoCODE /NoClear /NAME " + mod_tbl_ent.name + " /reloctype 0x3" + "\n"
+                    else:
+                        ld_mod_sym = "Data.LOAD.Elf " + where + " /NoCODE /NoClear /NAME " + mod_tbl_ent.name + " /reloctype 0x3" + "\n"
+                    startup_script.write(ld_mod_sym)
 
         if not self.minidump:
             startup_script.write('task.dtask\n')
@@ -1358,7 +1371,7 @@
             elif is_cortex_a53:
                 t32_binary = 'C:\\T32\\bin\\windows64\\t32MARM64.exe'
             else:
-                t32_binary = 'c:\\t32\\t32MARM.exe'
+                t32_binary = 'c:\\T32\\bin\\windows64\\t32MARM.exe'
             t32_bat.write(('start '+ t32_binary + ' -c ' + out_path + '/t32_config.t32, ' +
                           out_path + '/t32_startup_script.cmm'))
             t32_bat.close()
@@ -1730,6 +1743,7 @@
                 if ko_file_list.get(name, '').endswith('.ko.unstripped') and file.endswith('.ko'):
                     return
                 ko_file_list[name] = file
+                self.ko_file_names.append(name)
             self.walk_depth(path, on_file)
 
         for mod_tbl_ent in self.module_table.module_table:
@@ -1873,8 +1887,9 @@
         else:
             addr1 = addr
         #print "hex of address in get_symbol_info1 {0}".format(hex(addr1))
+        addr1, desc = self.step_through_jump_table(addr1)
         symbol_obj =  self.gdbmi.get_symbol_info(addr1)
-        return symbol_obj.symbol
+        return symbol_obj.symbol + desc
 
     def type_of(self, symbol):
         """
@@ -1936,6 +1951,30 @@
                 except gdbmi.GdbMIException:
                     pass
 
+    def step_through_jump_table(self, addr):
+        """
+        Steps through a jump table, if the address points to a unconditional branch
+        """
+
+        if addr is None:
+            return addr, ''
+
+        fn_addr = addr
+        if self.is_config_defined('CONFIG_ARM64_BTI_KERNEL'):
+            # Skip past BTI instruction to the real branch instr
+            fn_addr += 4
+        if self.cpu_type in ['ARMV9-A', 'CORTEXA53']:
+            instr = self.read_u32(fn_addr)
+            if instr is None or (instr & 0xFC000000) != 0x14000000:
+                return addr, ''
+            imm26_mask = 0x3FFFFFF
+            offset = instr & imm26_mask
+            if (offset & imm26_mask) >> 25:
+                offset -= (imm26_mask + 1)
+            fn_addr += 4 * offset
+            return fn_addr, '[jt]'
+        return addr, ''
+
     def unwind_lookup(self, addr, symbol_size=0):
         """
         Returns closest symbols <= addr and either the relative offset
@@ -1950,6 +1989,8 @@
         low = 0
         high = len(self.lookup_table) - 1
 
+        addr, desc = self.step_through_jump_table(addr)
+
         if addr is None or addr < table[low][0] or addr > table[high][0]:
             return None
 
@@ -1978,9 +2019,9 @@
             size = table[low + 1][0] - table[low][0]
 
         if symbol_size == 0:
-            return (table[low][1], offset)
+            return (table[low][1] + desc, offset)
         else:
-            return (table[low][1], size)
+            return (table[low][1] + desc, size)
 
     def read_physical(self, addr, length):
         if not isinstance(addr, int) or not isinstance(length, int):
diff --git a/linux-ramdump-parser-v2/ramparse.py b/linux-ramdump-parser-v2/ramparse.py
index 0af1fc4..2cf9aa7 100644
--- a/linux-ramdump-parser-v2/ramparse.py
+++ b/linux-ramdump-parser-v2/ramparse.py
@@ -114,8 +114,10 @@
                       help='Run an interactive python interpreter with the ramdump loaded')
     parser.add_option('', '--classic-shell', action='store_true',
                       help='Like --shell, but forces the use of the classic python shell, even if ipython is installed')
-    parser.add_option('', '--qtf', action='store_true', dest='qtf',
+    parser.add_option('', '--qtf', action='store_true', dest='ftrace_format',
                       help='Use QTF tool to parse and save QDSS trace data')
+    parser.add_option('', '--ftrace-formats', action='store_true', dest='ftrace_format',
+                      help='Extracts formats.txt used for generating ftrace')
     parser.add_option('', '--qtf-path', dest='qtf_path',
                       help='QTF tool executable')
     parser.add_option('', '--skip-qdss-bin', action='store_true',
diff --git a/linux-ramdump-parser-v2/scandump_reader.py b/linux-ramdump-parser-v2/scandump_reader.py
index 11fd7d8..e121ba4 100644
--- a/linux-ramdump-parser-v2/scandump_reader.py
+++ b/linux-ramdump-parser-v2/scandump_reader.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+# Copyright (c) 2016-2018,2021 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
@@ -157,7 +157,7 @@
             fd = open(output, "r")
             for line in fd:
                 match_flag = False
-                matchObj = re.match('^REGISTER.SET ([xse].*[0-9]+)\s(0x[0-9a-f]{0,})', line, re.M | re.I)
+                matchObj = re.match('^REGISTER.SET ([xse].*[0-9]+)\s+(0x[0-9a-f]{0,})', line, re.M | re.I)
                 if matchObj:
                     regVal = matchObj.group(2)
                     if regVal == "0x":
@@ -165,24 +165,24 @@
                     self.regs[(matchObj.group(1)).lower()] = int(regVal, 16)
                     match_flag = True
                 else:
-                    matchObj = re.match('^REGISTER.SET (PC)\s(0x[0-9a-f]{0,})', line, re.M | re.I)
+                    matchObj = re.match('^REGISTER.SET (PC)\s+(0x[0-9a-f]{0,})', line, re.M | re.I)
                     if matchObj:
                         regVal = matchObj.group(2)
                         if regVal == "0x":
                             regVal = "0x0000000000000000"
                         pc_val = regVal
 
-                    matchObj_altpc = re.match('^REGISTER.SET (ALT_PC_1)\s(0x[0-9a-f]{0,})', line, re.M | re.I)
+                    matchObj_altpc = re.match('^REGISTER.SET (ALT_PC_1)\s+(0x[0-9a-f]{0,})', line, re.M | re.I)
                     if matchObj_altpc:
                         alt_pc_1 = matchObj_altpc.group(2)
                         if alt_pc_1 == "0x":
                             alt_pc_1 = "0x0000000000000000"
-                    matchObj_altpc = re.match('^REGISTER.SET (ALT_PC_2)\s(0x[0-9a-f]{0,})', line, re.M | re.I)
+                    matchObj_altpc = re.match('^REGISTER.SET (ALT_PC_2)\s+(0x[0-9a-f]{0,})', line, re.M | re.I)
                     if matchObj_altpc:
                         alt_pc_2 = matchObj_altpc.group(2)
                         if alt_pc_2 == "0x":
                             alt_pc_2 = "0x0000000000000000"
-                matchObj = re.match('^REGISTER.SET ([xse].*[0-9]+)\s([0-9a-f])', line, re.M | re.I)
+                matchObj = re.match('^REGISTER.SET ([xse].*[0-9]+)\s+([0-9a-f])', line, re.M | re.I)
                 if matchObj and match_flag == False:
                     regVal = matchObj.group(2)
                     if regVal == "0":
diff --git a/linux-ramdump-parser-v2/sched_info.py b/linux-ramdump-parser-v2/sched_info.py
index fe6af85..b8df3a6 100644
--- a/linux-ramdump-parser-v2/sched_info.py
+++ b/linux-ramdump-parser-v2/sched_info.py
@@ -46,7 +46,8 @@
         cpu_isolated_bits = ramdump.read_word('__cpu_isolated_mask')
     elif (ramdump.kernel_version >= (4, 4, 0)):
         cpu_isolated_bits = ramdump.read_word('cpu_isolated_bits')
-
+    if cpu_isolated_bits == None:
+        cpu_isolated_bits = 0
     return cpu_isolated_bits