diff --git a/linux-ramdump-parser-v2/boards.py b/linux-ramdump-parser-v2/boards.py
index 70d20b8d6400337358fc5231f725dffd4584ebda..79c385f49f1e66e6a61788c434c3d8a56f4f3bad 100755
--- a/linux-ramdump-parser-v2/boards.py
+++ b/linux-ramdump-parser-v2/boards.py
@@ -401,6 +401,20 @@ class BoardCalifornium(Board):
         self.imem_file_name = 'OCIMEM.BIN'
 
 
+class BoardCobalt(Board):
+    def __init__(self, socid):
+        super(BoardCobalt, self).__init__()
+        self.socid = socid
+        self.board_num = "cobalt"
+        self.cpu = 'CORTEXA53'
+        self.ram_start = 0x80000000
+        self.smem_addr = 0x6000000
+        self.phys_offset = 0x80000000
+        self.imem_start = 0x14680000
+        self.kaslr_addr = 0x146bf6d0
+        self.wdog_addr = 0x146BF658
+        self.imem_file_name = 'OCIMEM.BIN'
+
 class Board8998(Board):
     def __init__(self, socid):
         super(Board8998, self).__init__()
@@ -411,6 +425,33 @@ class Board8998(Board):
         self.smem_addr = 0x6000000
         self.phys_offset = 0x80000000
         self.imem_start = 0x14680000
+        self.kaslr_addr = 0x146bf6d0
+        self.wdog_addr = 0x146BF658
+        self.imem_file_name = 'OCIMEM.BIN'
+
+class Board660(Board):
+    def __init__(self, socid):
+        super(Board660, self).__init__()
+        self.socid = socid
+        self.board_num = "660"
+        self.cpu = 'CORTEXA53'
+        self.ram_start = 0x80000000
+        self.smem_addr = 0x6000000
+        self.phys_offset = 0x80000000
+        self.imem_start = 0x14680000
+        self.wdog_addr = 0x146BF658
+        self.imem_file_name = 'OCIMEM.BIN'
+
+class Board630(Board):
+    def __init__(self, socid):
+        super(Board630, self).__init__()
+        self.socid = socid
+        self.board_num = "630"
+        self.cpu = 'CORTEXA53'
+        self.ram_start = 0x80000000
+        self.smem_addr = 0x6000000
+        self.phys_offset = 0x80000000
+        self.imem_start = 0x14680000
         self.wdog_addr = 0x146BF658
         self.imem_file_name = 'OCIMEM.BIN'
 
@@ -613,8 +654,16 @@ boards.append(Board8920(socid=320))
 
 boards.append(BoardCalifornium(socid=279))
 
+boards.append(BoardCobalt(socid=292))
 boards.append(Board8998(socid=292))
 
+boards.append(Board660(socid=317))
+boards.append(Board660(socid=324))
+boards.append(Board660(socid=325))
+boards.append(Board660(socid=326))
+
+boards.append(Board630(socid=318))
+boards.append(Board630(socid=327))
 
 def get_supported_boards():
     """ Called by other part of the code to get a list of boards """
diff --git a/linux-ramdump-parser-v2/cachedumplib.py b/linux-ramdump-parser-v2/cachedumplib.py
index 2fc1c439607a5daa86790c959b9e14276ad8d251..d6568940a26e451978584a2a60658f8b70be809f 100755
--- a/linux-ramdump-parser-v2/cachedumplib.py
+++ b/linux-ramdump-parser-v2/cachedumplib.py
@@ -454,6 +454,43 @@ lookuptable[("8998", 0x65, 0x14)] = L1_ICache_KRYO2XX_GOLD()
 lookuptable[("8998", 0x66, 0x14)] = L1_ICache_KRYO2XX_GOLD()
 lookuptable[("8998", 0x67, 0x14)] = L1_ICache_KRYO2XX_GOLD()
 
+# "sdm660"
+lookuptable[("660", 0x80, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("660", 0x81, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("660", 0x82, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("660", 0x83, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("660", 0x84, 0x14)] = L1_DCache_KRYO2XX_GOLD()
+lookuptable[("660", 0x85, 0x14)] = L1_DCache_KRYO2XX_GOLD()
+lookuptable[("660", 0x86, 0x14)] = L1_DCache_KRYO2XX_GOLD()
+lookuptable[("660", 0x87, 0x14)] = L1_DCache_KRYO2XX_GOLD()
+
+lookuptable[("660", 0x60, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("660", 0x61, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("660", 0x62, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("660", 0x63, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("660", 0x64, 0x14)] = L1_ICache_KRYO2XX_GOLD()
+lookuptable[("660", 0x65, 0x14)] = L1_ICache_KRYO2XX_GOLD()
+lookuptable[("660", 0x66, 0x14)] = L1_ICache_KRYO2XX_GOLD()
+lookuptable[("660", 0x67, 0x14)] = L1_ICache_KRYO2XX_GOLD()
+
+# "sdm630"
+lookuptable[("630", 0x80, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("630", 0x81, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("630", 0x82, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("630", 0x83, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("630", 0x84, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("630", 0x85, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("630", 0x86, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+lookuptable[("630", 0x87, 0x14)] = L1_DCache_KRYO2XX_SILVER()
+
+lookuptable[("630", 0x60, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("630", 0x61, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("630", 0x62, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("630", 0x63, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("630", 0x64, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("630", 0x65, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("630", 0x66, 0x14)] = L1_ICache_KYRO2XX_SILVER()
+lookuptable[("630", 0x67, 0x14)] = L1_ICache_KYRO2XX_SILVER()
 
 # 8994
 
diff --git a/linux-ramdump-parser-v2/debug_image_v2.py b/linux-ramdump-parser-v2/debug_image_v2.py
index b6b3655926ee614384e910a0f315ae5dd3eef7ea..8d0e7b12a0dda3dbf16ee153041eaa6882df97c4 100755
--- a/linux-ramdump-parser-v2/debug_image_v2.py
+++ b/linux-ramdump-parser-v2/debug_image_v2.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+# Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -335,9 +335,13 @@ class DebugImage_v2():
         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 = 'msm' + str(ram_dump.hw_id)
+        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)
@@ -448,8 +452,7 @@ class DebugImage_v2():
             'msm_dump_table_ids', MAX_NUM_ENTRIES)
         self.dump_data_id_lookup_table = ram_dump.gdbmi.get_enum_lookup_table(
             'msm_dump_data_ids', MAX_NUM_ENTRIES)
-        cpu_present_bits = ram_dump.read_word('cpu_present_bits')
-        cpus = bin(cpu_present_bits).count('1')
+        cpus = ram_dump.get_num_cpus()
         # per cpu entries
         for i in range(1, cpus):
 
diff --git a/linux-ramdump-parser-v2/parsers/cpr3_info.py b/linux-ramdump-parser-v2/parsers/cpr3_info.py
index ca5d9ddf472c73945a904408f1bb9ad753790d20..3f0be291fd8be868fddc4b8d6db41acc46d26b2b 100644
--- a/linux-ramdump-parser-v2/parsers/cpr3_info.py
+++ b/linux-ramdump-parser-v2/parsers/cpr3_info.py
@@ -430,9 +430,19 @@ class CPR3Info(RamParser):
         else:
             cpr_mode = "closed-loop"
 
-        tmp = ""
-        if cpr_controller_name is None:
+        thread_addr = self.ramdump.read_word(
+            ctrl_addr +
+            self.ramdump.field_offset(
+                'struct cpr3_controller', 'thread'))
+        if thread_addr is None:
             return
+        thread_ctrl_addr = self.ramdump.read_word(
+            thread_addr +
+            self.ramdump.field_offset('struct cpr3_thread', 'ctrl'))
+
+        if cpr_controller_name is None or thread_ctrl_addr != ctrl_addr:
+            return
+        tmp = ""
         tmp += "=" * 80 + "\n"
         tmp += 'CPR3 controller state: %s\n' % cpr_controller_name
         tmp += "=" * 80 + "\n"
@@ -464,10 +474,6 @@ class CPR3Info(RamParser):
             self.output.append("\nCPR aggregated voltages:\n")
             self.dump_cpr3_corner_info(aggr_corner_addr, 0, 0, 0)
 
-        thread_addr = self.ramdump.read_word(
-            ctrl_addr +
-            self.ramdump.field_offset(
-                'struct cpr3_controller', 'thread'))
         thread_count = self.ramdump.read_int(
             ctrl_addr +
             self.ramdump.field_offset(
diff --git a/linux-ramdump-parser-v2/parsers/irqstate.py b/linux-ramdump-parser-v2/parsers/irqstate.py
index b9f8d3e754e8a5683c688bde66651a3c531f3a14..66215d42ec56054c6a596021eab924f064e66744 100755
--- a/linux-ramdump-parser-v2/parsers/irqstate.py
+++ b/linux-ramdump-parser-v2/parsers/irqstate.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+# Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -20,9 +20,7 @@ class IrqParse(RamParser):
         print_out_str(
             '=========================== IRQ STATE ===============================')
         per_cpu_offset_addr = ram_dump.address_of('__per_cpu_offset')
-        cpu_present_bits_addr = ram_dump.address_of('cpu_present_bits')
-        cpu_present_bits = ram_dump.read_word(cpu_present_bits_addr)
-        cpus = bin(cpu_present_bits).count('1')
+        cpus = ram_dump.get_num_cpus()
         irq_desc = ram_dump.address_of('irq_desc')
         foo, irq_desc_size = ram_dump.unwind_lookup(irq_desc, 1)
         h_irq_offset = ram_dump.field_offset('struct irq_desc', 'handle_irq')
@@ -72,6 +70,50 @@ class IrqParse(RamParser):
                 print_out_str(
                     '{0:4} {1} {2:30} {3:10}'.format(irqnum, irq_stats_str, name, chip_name))
 
+    def shift_to_maxindex(self, shift):
+        radix_tree_map_shift = 6
+        radix_tree_map_size = 1 << radix_tree_map_shift
+        return (radix_tree_map_size << shift) - 1
+
+    def is_internal_node(self, addr):
+        radix_tree_entry_mask = 0x3
+        radix_tree_internal_node = 0x1
+        return (addr & radix_tree_entry_mask) == radix_tree_internal_node
+
+    def entry_to_node(self, addr):
+        return addr & 0xfffffffffffffffe
+
+    def radix_tree_lookup_element_v2(self, ram_dump, root_addr, index):
+        rnode_offset = ram_dump.field_offset('struct radix_tree_root', 'rnode')
+        rnode_shift_offset = ram_dump.field_offset('struct radix_tree_node', 'shift')
+        slots_offset = ram_dump.field_offset('struct radix_tree_node', 'slots')
+        pointer_size = ram_dump.sizeof('struct radix_tree_node *')
+        maxindex = 0
+        # if CONFIG_BASE_SMALL=0: radix_tree_map_shift = 6
+        radix_tree_map_shift = 6
+        radix_tree_map_mask = 0x3f
+
+        rnode_addr = ram_dump.read_word(root_addr + rnode_offset)
+        if self.is_internal_node(rnode_addr):
+            node_addr = self.entry_to_node(rnode_addr)
+            shift = ram_dump.read_byte(node_addr + rnode_shift_offset)
+            maxindex = self.shift_to_maxindex(shift)
+
+        if index > maxindex:
+            return None
+
+        while self.is_internal_node(rnode_addr):
+            parent_addr = self.entry_to_node(rnode_addr)
+            parent_shift = ram_dump.read_byte(parent_addr + rnode_shift_offset)
+            offset = (index >> parent_shift) & radix_tree_map_mask
+            rnode_addr = ram_dump.read_word(parent_addr + slots_offset +
+                (offset * pointer_size))
+
+        if rnode_addr is 0:
+            return None
+
+        return rnode_addr
+
     def radix_tree_lookup_element(self, ram_dump, root_addr, index):
         rnode_offset = ram_dump.field_offset('struct radix_tree_root', 'rnode')
         if (ram_dump.kernel_version[0], ram_dump.kernel_version[1]) >= (3, 18):
@@ -142,11 +184,19 @@ class IrqParse(RamParser):
         if nr_irqs > 50000:
             return
 
+        major, minor, patch = ram_dump.kernel_version
         for i in range(0, nr_irqs):
-            irq_desc = self.radix_tree_lookup_element(
-                ram_dump, irq_desc_tree, i)
+
+            if (major, minor) >= (4, 9):
+                irq_desc = self.radix_tree_lookup_element_v2(
+                    ram_dump, irq_desc_tree, i)
+            else:
+                irq_desc = self.radix_tree_lookup_element(
+                    ram_dump, irq_desc_tree, i)
+
             if irq_desc is None:
                 continue
+
             irqnum = ram_dump.read_int(irq_desc + irq_data_offset + irq_num_offset)
             irqcount = ram_dump.read_int(irq_desc + irq_count_offset)
             action = ram_dump.read_word(irq_desc + irq_action_offset)
diff --git a/linux-ramdump-parser-v2/parsers/rtb.py b/linux-ramdump-parser-v2/parsers/rtb.py
index 602012d80005ce9b72f56515dd176d4df25553de..ca1b770bff3386867075fff42fb8ea47683e0f37 100755
--- a/linux-ramdump-parser-v2/parsers/rtb.py
+++ b/linux-ramdump-parser-v2/parsers/rtb.py
@@ -17,10 +17,11 @@ from parser_util import register_parser, RamParser
 # struct msm_rtb_layout {
 #        unsigned char sentinel[3];
 #        unsigned char log_type;
-#        void *caller;
 #        unsigned long idx;
+#        void *caller;
 #        void *data;
-#        void *time
+#        void *timestamp;
+#        void *cycle_count;
 #} __attribute__ ((__packed__));
 
 print_table = {
@@ -63,6 +64,12 @@ class RTB(RamParser):
         timestamp = format(timestamp,'.6f')
         return timestamp
 
+    def get_cycle_count(self, rtb_ptr):
+        cycle_count = self.ramdump.read_structure_field(rtb_ptr, 'struct msm_rtb_layout', 'cycle_count')
+        if cycle_count == None:
+            return 0
+        return cycle_count
+
     def print_none(self, rtbout, rtb_ptr, logtype):
         rtbout.write('{0} No data\n'.format(logtype).encode('ascii', 'ignore'))
 
@@ -82,8 +89,9 @@ class RTB(RamParser):
         func = self.get_fun_name(caller)
         line = self.get_caller(caller)
         timestamp = self.get_timestamp(rtb_ptr)
-        rtbout.write('[{0}] : {1} from address {2:x}({3}) called from addr {4:x} {5} {6}\n'.format(
-            timestamp, logtype, data, physical, caller, func, line).encode('ascii', 'ignore'))
+	cycle_count = self.get_cycle_count(rtb_ptr)
+        rtbout.write('[{0}] [{1}] : {2} from address {3:x}({4}) called from addr {5:x} {6} {7}\n'.format(
+            timestamp, cycle_count, logtype, data, physical, caller, func, line).encode('ascii', 'ignore'))
 
     def print_logbuf(self, rtbout, rtb_ptr, logtype):
         data = self.ramdump.read_structure_field(rtb_ptr, 'struct msm_rtb_layout', 'data')
@@ -91,8 +99,9 @@ class RTB(RamParser):
         func = self.get_fun_name(caller)
         line = self.get_caller(caller)
         timestamp = self.get_timestamp(rtb_ptr)
-        rtbout.write('[{0}] : {1} log end {2:x} called from addr {3:x} {4} {5}\n'.format(
-            timestamp, logtype, data, caller, func, line).encode('ascii', 'ignore'))
+	cycle_count = self.get_cycle_count(rtb_ptr)
+        rtbout.write('[{0}] [{1}] : {2} log end {3:x} called from addr {4:x} {5} {6}\n'.format(
+            timestamp, cycle_count, logtype, data, caller, func, line).encode('ascii', 'ignore'))
 
     def print_hotplug(self, rtbout, rtb_ptr, logtype):
         data = self.ramdump.read_structure_field(rtb_ptr, 'struct msm_rtb_layout', 'data')
@@ -100,8 +109,9 @@ class RTB(RamParser):
         func = self.get_fun_name(caller)
         line = self.get_caller(caller)
         timestamp = self.get_timestamp(rtb_ptr)
-        rtbout.write('[{0}] : {1} cpu data {2:x} called from addr {3:x} {4} {5}\n'.format(
-            timestamp, logtype, data, caller, func, line).encode('ascii', 'ignore'))
+	cycle_count = self.get_cycle_count(rtb_ptr)
+        rtbout.write('[{0}] [{1}] : {2} cpu data {3:x} called from addr {4:x} {5} {6}\n'.format(
+            timestamp, cycle_count, logtype, data, caller, func, line).encode('ascii', 'ignore'))
 
     def print_ctxid(self, rtbout, rtb_ptr, logtype):
         data = self.ramdump.read_structure_field(rtb_ptr, 'struct msm_rtb_layout', 'data')
@@ -109,14 +119,16 @@ class RTB(RamParser):
         func = self.get_fun_name(caller)
         line = self.get_caller(caller)
         timestamp = self.get_timestamp(rtb_ptr)
-        rtbout.write('[{0}] : {1} context id {2:x} called from addr {3:x} {4} {5}\n'.format(
-            timestamp, logtype, data, caller, func, line).encode('ascii', 'ignore'))
+	cycle_count = self.get_cycle_count(rtb_ptr)
+        rtbout.write('[{0}] [{1}] : {2} context id {3:x} called from addr {4:x} {5} {6}\n'.format(
+            timestamp, cycle_count, logtype, data, caller, func, line).encode('ascii', 'ignore'))
 
     def print_timestamp(self, rtbout, rtb_ptr, logtype):
         data = self.ramdump.read_structure_field(rtb_ptr, 'struct msm_rtb_layout', 'data')
         caller = self.ramdump.read_structure_field(rtb_ptr, 'struct msm_rtb_layout', 'caller')
-        rtbout.write('[{0}] Timestamp: {1:x}{2:x}\n'.format(
-            logtype, data, caller).encode('ascii', 'ignore'))
+	cycle_count = self.get_cycle_count(rtb_ptr)
+        rtbout.write('[{0}] : [{1}] Timestamp: {2:x}{3:x}\n'.format(
+            cycle_count, logtype, data, caller).encode('ascii', 'ignore'))
 
     def print_cp_rw(self, rtbout, rtb_ptr, logtype):
         data = self.ramdump.read_structure_field(rtb_ptr, 'struct msm_rtb_layout', 'data')
@@ -124,8 +136,9 @@ class RTB(RamParser):
         func = self.get_fun_name(caller)
         line = self.get_caller(caller)
         timestamp = self.get_timestamp(rtb_ptr)
-        rtbout.write('[{0}] : {1} from offset {2:x} called from addr {3:x} {4} {5}\n'.format(
-            timestamp, logtype, data, caller, func, line).encode('ascii', 'ignore'))
+	cycle_count = self.get_cycle_count(rtb_ptr)
+        rtbout.write('[{0}] [{1}] : {2} from offset {3:x} called from addr {4:x} {5} {6}\n'.format(
+            timestamp, cycle_count, logtype, data, caller, func, line).encode('ascii', 'ignore'))
 
     def print_irq(self, rtbout, rtb_ptr, logtype):
         data = self.ramdump.read_structure_field(rtb_ptr, 'struct msm_rtb_layout', 'data')
@@ -133,8 +146,9 @@ class RTB(RamParser):
         func = self.get_fun_name(caller)
         line = self.get_caller(caller)
         timestamp = self.get_timestamp(rtb_ptr)
-        rtbout.write('[{0}] : {1} interrupt {2:x} handled from addr {3:x} {4} {5}\n'.format(
-            timestamp, logtype, data, caller, func, line).encode('ascii', 'ignore'))
+	cycle_count = self.get_cycle_count(rtb_ptr)
+        rtbout.write('[{0}] [{1}] : {2} interrupt {3:x} handled from addr {4:x} {5} {6}\n'.format(
+            timestamp, cycle_count, logtype, data, caller, func, line).encode('ascii', 'ignore'))
 
     def next_rtb_entry(self, index, step_size, mask):
         unused_buffer_size = (mask + 1) % step_size
diff --git a/linux-ramdump-parser-v2/parsers/slabinfo.py b/linux-ramdump-parser-v2/parsers/slabinfo.py
index 460c08ea5cc108e9dd060dc098c8a1d028180707..e65fb1504c95cc409ba78f931414868eff9a9fa1 100644
--- a/linux-ramdump-parser-v2/parsers/slabinfo.py
+++ b/linux-ramdump-parser-v2/parsers/slabinfo.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+# Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -284,9 +284,7 @@ class Slabinfo(RamParser):
     def validate_slab_cache(self, slab_out, input_slabname,  map_fn):
         slab_name_found = False
         original_slab = self.ramdump.address_of('slab_caches')
-        cpu_present_bits_addr = self.ramdump.address_of('cpu_present_bits')
-        cpu_present_bits = self.ramdump.read_word(cpu_present_bits_addr)
-        cpus = bin(cpu_present_bits).count('1')
+        cpus = self.ramdump.get_num_cpus()
         offsetof = struct_member_offset(self.ramdump)
         self.initializeOffset()
         slab_list_offset = g_offsetof.kmemcache_list
diff --git a/linux-ramdump-parser-v2/parsers/slabsummary.py b/linux-ramdump-parser-v2/parsers/slabsummary.py
index 34b43dc496f544a81a855ea6370c0cdba9d955a8..abe47dc90570ab320d1e25775b6e0fa12163187a 100644
--- a/linux-ramdump-parser-v2/parsers/slabsummary.py
+++ b/linux-ramdump-parser-v2/parsers/slabsummary.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+# Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -10,7 +10,7 @@
 # GNU General Public License for more details.
 
 import math
-
+import operator
 from mm import pfn_to_page
 from parser_util import register_parser, RamParser
 
@@ -55,10 +55,10 @@ class Slabinfo_summary(RamParser):
     # Currently with assumption there is only one numa node
     def print_slab_summary(self, slab_out):
         total_freeobjects = 0
+        slab_summary = {}
+        nCounter = 0
         original_slab = self.ramdump.address_of('slab_caches')
-        cpu_present_bits_addr = self.ramdump.address_of('cpu_present_bits')
-        cpu_present_bits = self.ramdump.read_word(cpu_present_bits_addr)
-        cpus = bin(cpu_present_bits).count('1')
+        cpus = self.ramdump.get_num_cpus()
         slab_list_offset = self.ramdump.field_offset(
             'struct kmem_cache', 'list')
         slab_name_offset = self.ramdump.field_offset(
@@ -130,11 +130,18 @@ class Slabinfo_summary(RamParser):
             slab_size = int(math.pow(2, page_order + PAGE_SHIFT))
             slab_size = slab_size / 1024
             slab = self.ramdump.read_word(slab + slab_list_offset)
+            slab_summary[nCounter] = [
+                    slab_name, obj_size,
+                    total_allocated, nr_total_objects,
+                    (objsize_w_metadata * nr_total_objects)/1024,
+                    num_slabs, slab_size]
+            nCounter += 1
+        sorted_summary = sorted(slab_summary.values(),
+                                key=operator.itemgetter(4), reverse=True)
+        for val in sorted_summary:
             slab_out.write(format_string.format(
-                                slab_name, obj_size, total_allocated,
-                                nr_total_objects,
-                                (objsize_w_metadata * nr_total_objects)/1024,
-                                num_slabs, slab_size))
+                                val[0], val[1], val[2], val[3], val[4],
+                                val[5], val[6]))
 
     def parse(self):
         slab_out = self.ramdump.open_file('slabsummary.txt')
diff --git a/linux-ramdump-parser-v2/parsers/timerlist.py b/linux-ramdump-parser-v2/parsers/timerlist.py
index c1b7318bd7cbc147bf3766f51a9bec9af0797327..80510a01f43caa7044c5b4751280b22bd9e109d9 100755
--- a/linux-ramdump-parser-v2/parsers/timerlist.py
+++ b/linux-ramdump-parser-v2/parsers/timerlist.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+# Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -99,6 +99,34 @@ class TimerList(RamParser) :
     def get_timer_list(self):
         self.output_file.write("Timer List Dump\n\n")
 
+        tvec_base_deferral_addr = self.ramdump.address_of('tvec_base_deferrable')
+        if tvec_base_deferral_addr:
+            timer_jiffies_addr = tvec_base_deferral_addr + self.ramdump.field_offset('struct tvec_base', 'timer_jiffies')
+            next_timer_addr = tvec_base_deferral_addr + self.ramdump.field_offset('struct tvec_base', 'next_timer')
+
+            timer_jiffies = self.ramdump.read_word(timer_jiffies_addr)
+            next_timer = self.ramdump.read_word(next_timer_addr)
+            active_timers_offset = self.ramdump.field_offset('struct tvec_base', 'active_timers')
+            if active_timers_offset is not None:
+                    active_timers_addr = tvec_base_deferral_addr + self.ramdump.field_offset('struct tvec_base', 'active_timers')
+                    active_timers = self.ramdump.read_word(active_timers_addr)
+            else:
+                    active_timers = "NA"
+
+            title = "(deferrable_base: {0:x} ".format(tvec_base_deferral_addr)
+            title += "timer_jiffies: {0} next_timer: {1} active_timers: {2})\n".format(timer_jiffies, next_timer, active_timers)
+            self.output_file.write("-" * len(title) + "\n")
+            self.output_file.write(title)
+            self.output_file.write("-" * len(title) + "\n\n")
+
+            for vec in sorted(self.vectors):
+                self.output = []
+                if self.timer_42:
+                      self.iterate_vec_v2(vec, tvec_base_deferral_addr)
+                else:
+                     self.iterate_vec(vec, tvec_base_deferral_addr)
+                self.print_vec(vec)
+
         tvec_bases_addr = self.ramdump.address_of('tvec_bases')
 
         for cpu in range(0, self.ramdump.get_num_cpus()):
diff --git a/linux-ramdump-parser-v2/parsers/workqueue.py b/linux-ramdump-parser-v2/parsers/workqueue.py
index 21c7b920fb72f79a9c3aa65598684d2783e42331..86e23124cb24216a6877879e1893188088b2f040 100644
--- a/linux-ramdump-parser-v2/parsers/workqueue.py
+++ b/linux-ramdump-parser-v2/parsers/workqueue.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+# Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -212,9 +212,7 @@ class Workqueues(RamParser):
         worker_pool_size = ram_dump.sizeof('struct worker_pool')
         pending_work_offset = ram_dump.field_offset(
             'struct worker_pool', 'worklist')
-        cpu_present_bits_addr = ram_dump.address_of('cpu_present_bits')
-        cpu_present_bits = ram_dump.read_word(cpu_present_bits_addr)
-        cpus = bin(cpu_present_bits).count('1')
+        cpus = ram_dump.get_num_cpus()
 
         s = '<'
         for a in range(0, 64):
diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py
index a4a7bf1d9724698c81ccee86576f0324be89f1a0..289b850cde1e491610f1cf7cf64e97879c37c92d 100755
--- a/linux-ramdump-parser-v2/ramdump.py
+++ b/linux-ramdump-parser-v2/ramdump.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+# Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -547,6 +547,12 @@ class RamDump():
             self.ebi_start = self.ebi_files[0][1]
         if self.phys_offset is None:
             self.get_hw_id()
+
+        if self.kaslr_offset is None:
+            self.get_kaslr_offset()
+            if self.kaslr_offset is not None:
+                self.gdbmi.kaslr_offset = self.kaslr_offset
+
         if options.phys_offset is not None:
             print_out_str(
                 '[!!!] Phys offset was set to {0:x}'.format(\
@@ -577,7 +583,8 @@ class RamDump():
 
         self.kimage_vaddr = self.va_start + self.kasan_shadow_size + \
             modules_vsize
-
+        if self.kaslr_offset is not None:
+            self.kimage_vaddr = self.kimage_vaddr + self.kaslr_offset
         self.modules_end = self.page_offset
         self.kimage_voffset = self.address_of("kimage_voffset")
         if self.kimage_voffset is not None:
@@ -803,7 +810,7 @@ class RamDump():
         return False
 
     def create_t32_launcher(self):
-        out_path = self.outdir
+        out_path = os.path.abspath(self.outdir)
 
         t32_host_system = self.t32_host_system or platform.system()
 
@@ -822,10 +829,14 @@ class RamDump():
         launch_config.write('PBI=SIM\n')
         launch_config.write('\n')
         launch_config.write('SCREEN=\n')
-        launch_config.write('FONT=SMALL\n')
+        if t32_host_system != 'Linux':
+            launch_config.write('FONT=SMALL\n')
+        else:
+            launch_config.write('FONT=LARGE\n')
         launch_config.write('HEADER=Trace32-ScorpionSimulator\n')
         launch_config.write('\n')
-        launch_config.write('PRINTER=WINDOWS\n')
+        if t32_host_system != 'Linux':
+            launch_config.write('PRINTER=WINDOWS\n')
         launch_config.write('\n')
         launch_config.write('RCL=NETASSIST\n')
         launch_config.write('PACKLEN=1024\n')
@@ -927,7 +938,8 @@ class RamDump():
         startup_script.close()
 
         if t32_host_system != 'Linux':
-            t32_bat = open(out_path + '/launch_t32.bat', 'wb')
+            launch_file = os.path.join(out_path, 'launch_t32.bat')
+            t32_bat = open(launch_file, 'wb')
             if self.arm64:
                 t32_binary = 'C:\\T32\\bin\\windows64\\t32MARM64.exe'
             elif is_cortex_a53:
@@ -936,22 +948,23 @@ class RamDump():
                 t32_binary = 'c:\\t32\\t32MARM.exe'
             t32_bat.write(('start '+ t32_binary + ' -c ' + out_path + '/t32_config.t32, ' +
                           out_path + '/t32_startup_script.cmm').encode('ascii', 'ignore'))
+            t32_bat.close()
         else:
-            t32_bat = open(out_path + '/launch_t32.sh', 'wb')
+            launch_file = os.path.join(out_path, 'launch_t32.sh')
+            t32_sh = open(launch_file, 'wb')
             if self.arm64:
                 t32_binary = '/opt/t32/bin/pc_linux64/t32marm64-qt'
             elif is_cortex_a53:
                 t32_binary = '/opt/t32/bin/pc_linux64/t32marm-qt'
             else:
                 t32_binary = '/opt/t32/bin/pc_linux64/t32marm-qt'
-            t32_bat.write('#!/bin/sh\n\n')
-            t32_bat.write('cd $(dirname $0)\n')
-            t32_bat.write('{} -c t32_config.t32, t32_startup_script.cmm &\n'.format(t32_binary))
-            os.chmod(out_path + '/launch_t32.sh', stat.S_IRWXU)
+            t32_sh.write('#!/bin/sh\n\n')
+            t32_sh.write('{0} -c {1}/t32_config.t32, {1}/t32_startup_script.cmm &\n'.format(t32_binary, out_path))
+            t32_sh.close()
+            os.chmod(launch_file, stat.S_IRWXU)
 
-        t32_bat.close()
         print_out_str(
-            '--- Created a T32 Simulator launcher (run {0}/launch_t32.bat)'.format(out_path))
+            '--- Created a T32 Simulator launcher (run {})'.format(launch_file))
 
     def read_tz_offset(self):
         if self.tz_addr == 0:
@@ -961,6 +974,18 @@ class RamDump():
         else:
             return self.read_word(self.tz_addr, False)
 
+    def get_kaslr_offset(self):
+        if(self.kaslr_addr is None):
+            print_out_str('!!!! Kaslr addr is not provided.')
+        else:
+            kaslr_magic = self.read_u32(self.kaslr_addr, False)
+            if kaslr_magic != 0xdead4ead:
+                print_out_str('!!!! Kaslr magic does not match.')
+                self.kaslr_offset = None
+            else:
+                self.kaslr_offset = self.read_u64(self.kaslr_addr + 4, False)
+                print_out_str("The kaslr_offset extracted is: " + str(hex(self.kaslr_offset)))
+
     def get_hw_id(self, add_offset=True):
         socinfo_format = -1
         socinfo_id = -1
@@ -1047,6 +1072,10 @@ class RamDump():
         self.hw_id = board.board_num
         self.cpu_type = board.cpu
         self.imem_fname = board.imem_file_name
+        if hasattr(board, 'kaslr_addr'):
+            self.kaslr_addr = board.kaslr_addr
+        else:
+            self.kaslr_addr = None
         return True
 
     def resolve_virt(self, virt_or_name):
@@ -1370,8 +1399,14 @@ class RamDump():
 
     def get_num_cpus(self):
         """Gets the number of CPUs in the system."""
+        major, minor, patch = self.kernel_version
         cpu_present_bits_addr = self.address_of('cpu_present_bits')
         cpu_present_bits = self.read_word(cpu_present_bits_addr)
+
+        if (major, minor) >= (4, 5):
+            cpu_present_bits_addr = self.address_of('__cpu_present_mask')
+            bits_offset = self.field_offset('struct cpumask', 'bits')
+            cpu_present_bits = self.read_word(cpu_present_bits_addr + bits_offset)
         return bin(cpu_present_bits).count('1')
 
     def iter_cpus(self):
diff --git a/linux-ramdump-parser-v2/watchdog_v2.py b/linux-ramdump-parser-v2/watchdog_v2.py
index dba99d615f277bc521011a4f76643fce2c763767..c9e856e8513de3c531534ae985cd0a2777c9d9cd 100755
--- a/linux-ramdump-parser-v2/watchdog_v2.py
+++ b/linux-ramdump-parser-v2/watchdog_v2.py
@@ -15,6 +15,7 @@ import re
 from scandump_reader import Scandump_v2
 from print_out import print_out_str
 from bitops import is_set
+from parser_util import register_parser, RamParser
 
 # name from tz dump, corresponding T32 register, whether or not to
 # print_out_str (the function name)
@@ -836,3 +837,48 @@ class TZRegDump_v2():
         self.sec_regs = TZCpuCtx_v2(self.version, sc_secure,
                                     self.neon_regs, ram_dump)
         return True
+
+
+@register_parser('--watchdog', 'Extracts NS Watchdog related info')
+class Watchdog(RamParser):
+    def parse(self):
+        get_wdog_timing(self.ramdump)
+
+
+def get_wdog_timing(ramdump):
+    jiffies = ramdump.read_word('jiffies')
+    last_jiffies_update = ramdump.read_word('last_jiffies_update')
+    tick_do_timer_cpu = ramdump.read_word('tick_do_timer_cpu')
+    wdog_data_addr = ramdump.read_word('wdog_data')
+    pet_timer_off = ramdump.field_offset(
+        'struct msm_watchdog_data', 'pet_timer')
+    timer_expires_off = ramdump.field_offset('struct timer_list', 'expires')
+    pet_timer_expires = ramdump.read_word(
+        wdog_data_addr + pet_timer_off + timer_expires_off)
+    last_pet_off = ramdump.field_offset('struct msm_watchdog_data', 'last_pet')
+    wdog_last_pet = ramdump.read_word(wdog_data_addr + last_pet_off)
+    timer_expired_off = ramdump.field_offset(
+        'struct msm_watchdog_data', 'timer_expired')
+    pet_timer_expired = ramdump.read_word(wdog_data_addr + timer_expired_off)
+    pet_time_off = ramdump.field_offset('struct msm_watchdog_data', 'pet_time')
+    bark_time_off = ramdump.field_offset(
+        'struct msm_watchdog_data', 'bark_time')
+    pet_time = ramdump.read_int(wdog_data_addr + pet_time_off)
+    bark_time = ramdump.read_int(wdog_data_addr + bark_time_off)
+    print_out_str('Non-secure Watchdog data')
+    print_out_str('Pet time: {0}s'.format(pet_time/1000.0))
+    print_out_str('Bark time: {0}s'.format(bark_time/1000.0))
+    print_out_str('Watchdog last pet: {0}'.format(wdog_last_pet/1000000000.0))
+    if pet_timer_expired == 1:
+        print_out_str('Watchdog pet timer expired')
+    else:
+        print_out_str('Watchdog pet timer not expired')
+        if jiffies > pet_timer_expires:
+            print_out_str('Current jiffies crossed pet_timer expires jiffies')
+    print_out_str('pet_timer_expires: {0}'.format(pet_timer_expires))
+    print_out_str('Current jiffies  : {0}'.format(jiffies))
+    print_out_str(
+        'Timestamp of last timer interrupt(last_jiffies_update): {0}'.format(
+            last_jiffies_update/1000000000.0))
+    print_out_str('Core which updates jiffies(tick_do_timer_cpu): {0}'.format(
+        tick_do_timer_cpu))