diff --git a/linux-ramdump-parser-v2/bitops.py b/linux-ramdump-parser-v2/bitops.py
index dc2d3108425cb1f5ee225f53bed8a7b66d700776..4f9da69254b587f587f3a94f642bb65c20a4dc50 100644
--- a/linux-ramdump-parser-v2/bitops.py
+++ b/linux-ramdump-parser-v2/bitops.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013, The Linux Foundation. All rights reserved.
+# Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 and
@@ -18,3 +18,10 @@ def bm(msb, lsb):
 def bvalsel(msb, lsb, val):
     'Masks and returns the bits from msb to lsb in val'
     return ((val & bm(msb, lsb)) >> lsb)
+
+
+def is_set(val, bit):
+    'Checks whether particular bit is set in val'
+    if (val >> bit) & 0x1:
+        return True
+    return False
diff --git a/linux-ramdump-parser-v2/watchdog_v2.py b/linux-ramdump-parser-v2/watchdog_v2.py
index 659663e2da2c604343c6a5e598fb825913ff6fb0..e01636d0d1edc4ad39b2a7f628edf14c69aea469 100644
--- a/linux-ramdump-parser-v2/watchdog_v2.py
+++ b/linux-ramdump-parser-v2/watchdog_v2.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+# Copyright (c) 2012-2015, 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
@@ -12,8 +12,10 @@
 import struct
 import re
 from print_out import print_out_str
+from bitops import is_set
 
-# (name from tz dump, corresponding T32 register, whether or not to print_out_str (the function name))
+# name from tz dump, corresponding T32 register, whether or not to
+# print_out_str (the function name)
 sysdbg_cpu64_register_names_default = [
     ('x0', 'x0', False),
     ('x1', 'x1', False),
@@ -302,6 +304,250 @@ sysdbg_cpu64_ctxt_regs_type_v1_3 = ''.join([
     'Q',  # __reserved2
 ])
 
+sysdbg_cpu64_register_names_v1_4 = [
+    ('x0', 'x0', False),
+    ('x1', 'x1', False),
+    ('x2', 'x2', False),
+    ('x3', 'x3', False),
+    ('x4', 'x4', False),
+    ('x5', 'x5', False),
+    ('x6', 'x6', False),
+    ('x7', 'x7', False),
+    ('x8', 'x8', False),
+    ('x9', 'x9', False),
+    ('x10', 'x10', False),
+    ('x11', 'x11', False),
+    ('x12', 'x12', False),
+    ('x13', 'x13', False),
+    ('x14', 'x14', False),
+    ('x15', 'x15', False),
+    ('x16', 'x16', False),
+    ('x17', 'x17', False),
+    ('x18', 'x18', False),
+    ('x19', 'x19', False),
+    ('x20', 'x20', False),
+    ('x21', 'x21', False),
+    ('x22', 'x22', False),
+    ('x23', 'x23', False),
+    ('x24', 'x24', False),
+    ('x25', 'x25', False),
+    ('x26', 'x26', False),
+    ('x27', 'x27', False),
+    ('x28', 'x28', False),
+    ('x29', 'x29', False),
+    ('x30', 'x30', True),
+    ('pc', 'pc', True),
+    ('currentEL', None, False),
+    ('sp_el3', 'sp_el3', False),
+    ('elr_el3', 'elr_el3', True),
+    ('spsr_el3', 'spsr_el3', False),
+    ('sp_el2', 'sp_el2', False),
+    ('elr_el2', 'elr_el2', True),
+    ('spsr_el2', 'spsr_el2', False),
+    ('sp_el1', 'sp_el1', False),
+    ('elr_el1', 'elr_el1', True),
+    ('spsr_el1', 'spsr_el1', False),
+    ('sp_el0', 'sp_el0', False),
+    ('dirty_flag', 'dirty_flag', False),
+    ('PStateMisc', 'PStateMisc', False),
+    ('trust0', 'trust0', False),
+    ('trust1', 'trust1', False),
+    ('trust2', 'trust2', False),
+    ('__reserved1', '__reserved1', False),
+    ('__reserved2', '__reserved2', False),
+    ('__reserved3', '__reserved3', False),
+    ('__reserved4', '__reserved4', False),
+]
+
+sysdbg_cpu64_ctxt_regs_type_v1_4 = ''.join([
+    'Q',  # x0
+    'Q',  # x1
+    'Q',  # x2
+    'Q',  # x3
+    'Q',  # x4
+    'Q',  # x5
+    'Q',  # x6
+    'Q',  # x7
+    'Q',  # x8
+    'Q',  # x9
+    'Q',  # x10
+    'Q',  # x11
+    'Q',  # x12
+    'Q',  # x13
+    'Q',  # x14
+    'Q',  # x15
+    'Q',  # x16
+    'Q',  # x17
+    'Q',  # x18
+    'Q',  # x19
+    'Q',  # x20
+    'Q',  # x21
+    'Q',  # x22
+    'Q',  # x23
+    'Q',  # x24
+    'Q',  # x25
+    'Q',  # x26
+    'Q',  # x27
+    'Q',  # x28
+    'Q',  # x29
+    'Q',  # x30
+    'Q',  # pc
+    'Q',  # currentEL
+    'Q',  # sp_el3
+    'Q',  # elr_el3
+    'Q',  # spsr_el3
+    'Q',  # sp_el2
+    'Q',  # elr_el2
+    'Q',  # spsr_el2
+    'Q',  # sp_el1
+    'Q',  # elr_el1
+    'Q',  # spsr_el1
+    'Q',  # sp_el0
+    'Q',  # dirty_flag
+    'Q',  # PStateMisc
+    'Q',  # trust0
+    'Q',  # trust1
+    'Q',  # trust2
+    'Q',  # __reserved1
+    'Q',  # __reserved2
+    'Q',  # __reserved3
+    'Q',  # __reserved4
+])
+
+sysdbg_neon128_register_names_v1_4 = [
+    ('q0-lower', 'v0-lower', False),
+    ('q0-upper', 'v0-upper', False),
+    ('q1-lower', 'v1-lower', False),
+    ('q1-upper', 'v1-upper', False),
+    ('q2-lower', 'v2-lower', False),
+    ('q2-upper', 'v2-upper', False),
+    ('q3-lower', 'v3-lower', False),
+    ('q3-upper', 'v3-upper', False),
+    ('q4-lower', 'v4-lower', False),
+    ('q4-upper', 'v4-upper', False),
+    ('q5-lower', 'v5-lower', False),
+    ('q5-upper', 'v5-upper', False),
+    ('q6-lower', 'v6-lower', False),
+    ('q6-upper', 'v6-upper', False),
+    ('q7-lower', 'v7-lower', False),
+    ('q7-upper', 'v7-upper', False),
+    ('q8-lower', 'v8-lower', False),
+    ('q8-upper', 'v8-upper', False),
+    ('q9-lower', 'v9-lower', False),
+    ('q9-upper', 'v9-upper', False),
+    ('q10-lower', 'v10-lower', False),
+    ('q10-upper', 'v10-upper', False),
+    ('q11-lower', 'v11-lower', False),
+    ('q11-upper', 'v11-upper', False),
+    ('q12-lower', 'v12-lower', False),
+    ('q12-upper', 'v12-upper', False),
+    ('q13-lower', 'v13-lower', False),
+    ('q13-upper', 'v13-upper', False),
+    ('q14-lower', 'v14-lower', False),
+    ('q14-upper', 'v14-upper', False),
+    ('q15-lower', 'v15-lower', False),
+    ('q15-upper', 'v15-upper', False),
+    ('q16-lower', 'v16-lower', False),
+    ('q16-upper', 'v16-upper', False),
+    ('q17-lower', 'v17-lower', False),
+    ('q17-upper', 'v17-upper', False),
+    ('q18-lower', 'v18-lower', False),
+    ('q18-upper', 'v18-upper', False),
+    ('q19-lower', 'v19-lower', False),
+    ('q19-upper', 'v19-upper', False),
+    ('q20-lower', 'v20-lower', False),
+    ('q20-upper', 'v20-upper', False),
+    ('q21-lower', 'v21-lower', False),
+    ('q21-upper', 'v21-upper', False),
+    ('q22-lower', 'v22-lower', False),
+    ('q22-upper', 'v22-upper', False),
+    ('q23-lower', 'v23-lower', False),
+    ('q23-upper', 'v23-upper', False),
+    ('q24-lower', 'v24-lower', False),
+    ('q24-upper', 'v24-upper', False),
+    ('q25-lower', 'v25-lower', False),
+    ('q25-upper', 'v25-upper', False),
+    ('q26-lower', 'v26-lower', False),
+    ('q26-upper', 'v26-upper', False),
+    ('q27-lower', 'v27-lower', False),
+    ('q27-upper', 'v27-upper', False),
+    ('q28-lower', 'v28-lower', False),
+    ('q28-upper', 'v28-upper', False),
+    ('q29-lower', 'v29-lower', False),
+    ('q29-upper', 'v29-upper', False),
+    ('q30-lower', 'v30-lower', False),
+    ('q30-upper', 'v30-upper', False),
+    ('q31-lower', 'v31-lower', False),
+    ('q31-upper', 'v31-upper', False),
+]
+
+sysdbg_neon128_register_type_v1_4 = ''.join([
+    'Q',  # q0-lower
+    'Q',  # q0-upper
+    'Q',  # q1-lower
+    'Q',  # q1-upper
+    'Q',  # q2-lower
+    'Q',  # q2-upper
+    'Q',  # q3-lower
+    'Q',  # q3-upper
+    'Q',  # q4-lower
+    'Q',  # q4-upper
+    'Q',  # q5-lower
+    'Q',  # q5-upper
+    'Q',  # q6-lower
+    'Q',  # q6-upper
+    'Q',  # q7-lower
+    'Q',  # q7-upper
+    'Q',  # q8-lower
+    'Q',  # q8-upper
+    'Q',  # q9-lower
+    'Q',  # q9-upper
+    'Q',  # q10-lower
+    'Q',  # q10-upper
+    'Q',  # q11-lower
+    'Q',  # q11-upper
+    'Q',  # q12-lower
+    'Q',  # q12-upper
+    'Q',  # q13-lower
+    'Q',  # q13-upper
+    'Q',  # q14-lower
+    'Q',  # q14-upper
+    'Q',  # q15-lower
+    'Q',  # q15-upper
+    'Q',  # q16-lower
+    'Q',  # q16-upper
+    'Q',  # q17-lower
+    'Q',  # q17-upper
+    'Q',  # q18-lower
+    'Q',  # q18-upper
+    'Q',  # q19-lower
+    'Q',  # q19-upper
+    'Q',  # q20-lower
+    'Q',  # q20-upper
+    'Q',  # q21-lower
+    'Q',  # q21-upper
+    'Q',  # q22-lower
+    'Q',  # q22-upper
+    'Q',  # q23-lower
+    'Q',  # q23-upper
+    'Q',  # q24-lower
+    'Q',  # q24-upper
+    'Q',  # q25-lower
+    'Q',  # q25-upper
+    'Q',  # q26-lower
+    'Q',  # q26-upper
+    'Q',  # q27-lower
+    'Q',  # q27-upper
+    'Q',  # q28-lower
+    'Q',  # q28-upper
+    'Q',  # q29-lower
+    'Q',  # q29-upper
+    'Q',  # q30-lower
+    'Q',  # q30-upper
+    'Q',  # q31-lower
+    'Q',  # q31-upper
+])
+
 cpu_name = (
     'Invalid',
     'A53',
@@ -323,9 +569,80 @@ sysdbg_cpu32_ctxt_regs_type['default'] = sysdbg_cpu32_ctxt_regs_type_default
 sysdbg_cpu64_register_names['1.3'] = sysdbg_cpu64_register_names_v1_3
 sysdbg_cpu64_ctxt_regs_type['1.3'] = sysdbg_cpu64_ctxt_regs_type_v1_3
 
+# Version 1.4
+sysdbg_cpu64_register_names['1.4'] = sysdbg_cpu64_register_names_v1_4
+sysdbg_cpu64_ctxt_regs_type['1.4'] = sysdbg_cpu64_ctxt_regs_type_v1_4
+
+
+class NeonCtxType():
+
+    def __init__(self, regs_t, ramdump):
+        i = 0
+        self.regs = {}
+
+        if ramdump.arm64 is None:
+            return
+
+        register_name = sysdbg_neon128_register_names_v1_4
+        for r in regs_t:
+            self.regs[register_name[i][0]] = r
+            i += 1
+
+
 class TZCpuCtx_v2():
 
-    def __init__(self, version, regs_t, ramdump):
+    def compute_pc(self, neon_regs):
+        pstate = self.regs['PStateMisc']
+        trust0 = self.regs['trust0']
+        trust2 = self.regs['trust2']
+        pc = self.regs['pc']
+
+        # AArch32 Mode
+        if is_set(pstate, 4):
+            val = pstate & 0xF
+            if val == 0x0 and is_set(trust0, 14):
+                self.regs['pc'] = self.regs['x14']
+            elif val == 0x1 and is_set(trust0, 30):
+                self.regs['pc'] = self.regs['x30']
+            elif val == 0x2 and is_set(trust0, 16):
+                self.regs['pc'] = self.regs['x16']
+            elif val == 0x3 and is_set(trust0, 18):
+                self.regs['pc'] = self.regs['x18']
+            elif val == 0x7 and is_set(trust0, 20):
+                self.regs['pc'] = self.regs['x20']
+            elif val == 0xB and is_set(trust0, 22):
+                self.regs['pc'] = self.regs['x22']
+            elif val == 0x6 and is_set(trust2, 31):
+                self.regs['pc'] = neon_regs['q31-upper']
+            elif val == 0xA:
+                self.regs['pc'] = self.regs['elr_el2']
+            elif val == 0xF and is_set(trust0, 14):
+                self.regs['pc'] = self.regs['x14']
+            else:
+                print_out_str('!!! AArch32 PC Approximation Logic Failed!')
+        # AArch64 Mode
+        else:
+            if is_set(trust0, 30):
+                self.regs['pc'] = self.regs['x30']
+            else:
+                val = (pstate >> 2) & 0x3
+                if val == 0x0:
+                    self.regs['pc'] = self.regs['elr_el1']
+                elif val == 0x1:
+                    self.regs['pc'] = self.regs['elr_el1']
+                elif val == 0x2:
+                    self.regs['pc'] = self.regs['elr_el2']
+                elif val == 0x3:
+                    self.regs['pc'] = self.regs['elr_el3']
+                else:
+                    print_out_str('!!! AArch64 PC Approximation Logic Failed!')
+
+        if pc and pc != self.regs['pc']:
+            print_out_str(
+                '!!! PC computed by SDI {0} and Parser {1} are different!'
+                .format(hex(pc), hex(self.regs['pc'])))
+
+    def __init__(self, version, regs_t, neon_regs, ramdump):
         i = 0
         self.regs = {}
         self.version = version
@@ -338,6 +655,11 @@ class TZCpuCtx_v2():
             self.regs[register_name[i][0]] = r
             i += 1
 
+        if self.version == '1.4' and self.regs['dirty_flag'] == 0x1:
+            print_out_str(
+                '!!! PC is invalid, applying "PC Approximation Logic"!')
+            self.compute_pc(neon_regs)
+
     def print_regs(self, outfile, ramdump):
         if ramdump.arm64:
             register_names = sysdbg_cpu64_register_names[self.version]
@@ -358,24 +680,27 @@ class TZCpuCtx_v2():
                 pc_string = None
             if pc_string is not None:
                 print_out_str('   {0:8} = 0x{1:016x} {2}'.format(
-                    reg_name, self.regs[reg_name], pc_string))
+                              reg_name, self.regs[reg_name], pc_string))
             else:
                 print_out_str('   {0:8} = 0x{1:016x}'.format(
-                    reg_name, self.regs[reg_name]))
+                              reg_name, self.regs[reg_name]))
             if t32_name is not None:
                 outfile.write(
                     'r.s {0} 0x{1:x}\n'.format(t32_name, self.regs[reg_name]))
 
+
 class TZRegDump_v2():
 
     def __init__(self):
         self.core_regs = None
         self.sec_regs = None
+        self.neon_regs = {}
         self.version = 0
         self.start_addr = 0
         self.end_addr = 0
         self.core = 0
-	self.status = []
+        self.status = []
+        self.neon_fields = []
 
     def dump_all_regs(self, ram_dump):
         coren_regs = ram_dump.open_file('core{0}_regs.cmm'.format(self.core))
@@ -384,7 +709,8 @@ class TZRegDump_v2():
         self.core_regs.print_regs(coren_regs, ram_dump)
         coren_regs.close()
 
-        secure_regs = ram_dump.open_file('secure_world_core{0}_regs.cmm'.format(self.core))
+        secure_regs = ram_dump.open_file(
+            'secure_world_core{0}_regs.cmm'.format(self.core))
         print_out_str('\n=============== secure contex ===========')
         self.sec_regs.print_regs(secure_regs, ram_dump)
         print_out_str('============ end secure context ===========')
@@ -408,7 +734,8 @@ class TZRegDump_v2():
             symname = 'UNKNOWN'
             offset = 0
         print_out_str(
-            'Core {3} PC: {0}+{1:x} <{2:x}>'.format(symname, offset, pc, self.core))
+            'Core {3} PC: {0}+{1:x} <{2:x}>'.format(symname, offset,
+                                                    pc, self.core))
         a = ram_dump.unwind_lookup(lr)
         if a is not None:
             symname, offset = a
@@ -416,7 +743,8 @@ class TZRegDump_v2():
             symname = 'UNKNOWN'
             offset = 0
         print_out_str(
-            'Core {3} LR: {0}+{1:x} <{2:x}>'.format(symname, offset, lr, self.core))
+            'Core {3} LR: {0}+{1:x} <{2:x}>'.format(symname, offset,
+                                                    lr, self.core))
         print_out_str('')
         ram_dump.unwind.unwind_backtrace(bt, fp, pc, lr, '')
         print_out_str('')
@@ -444,19 +772,49 @@ class TZRegDump_v2():
 
         if ram_dump.arm64:
             sc_regs = ram_dump.read_string(
-                self.start_addr, sysdbg_cpu64_ctxt_regs_type[self.version], False)
-            self.start_addr += struct.calcsize(sysdbg_cpu64_ctxt_regs_type[self.version])
+                self.start_addr,
+                sysdbg_cpu64_ctxt_regs_type[self.version],
+                False)
+            self.start_addr += struct.calcsize(
+                sysdbg_cpu64_ctxt_regs_type[self.version])
             sc_secure = ram_dump.read_string(
-               self.start_addr, sysdbg_cpu64_ctxt_regs_type[self.version] , False)
-            self.start_addr += struct.calcsize(sysdbg_cpu64_ctxt_regs_type[self.version])
+                self.start_addr,
+                sysdbg_cpu64_ctxt_regs_type[self.version],
+                False)
+            self.start_addr += struct.calcsize(
+                sysdbg_cpu64_ctxt_regs_type[self.version])
+
+            if self.version == '1.4':
+                for i in range(0, 3):
+                    self.neon_fields.append(ram_dump.read_u32(
+                                            self.start_addr, False))
+                    self.start_addr += 4
+
+                neon_ctx_regs = ram_dump.read_string(
+                    self.start_addr,
+                    sysdbg_neon128_register_type_v1_4,
+                    False)
+                self.start_addr += struct.calcsize(
+                    sysdbg_neon128_register_type_v1_4)
+
+                neon = NeonCtxType(neon_ctx_regs, ram_dump)
+                self.neon_regs = neon.regs
         else:
             sc_regs = ram_dump.read_string(
-                self.start_addr, sysdbg_cpu32_ctxt_regs_type[self.version], False)
-            self.start_addr += struct.calcsize(sysdbg_cpu32_ctxt_regs_type[self.version])
+                self.start_addr,
+                sysdbg_cpu32_ctxt_regs_type[self.version],
+                False)
+            self.start_addr += struct.calcsize(
+                sysdbg_cpu32_ctxt_regs_type[self.version])
             sc_secure = ram_dump.read_string(
-                self.start_addr, sysdbg_cpu32_ctxt_regs_type[self.version] , False)
-            self.start_addr += struct.calcsize(sysdbg_cpu32_ctxt_regs_type[self.version])
+                self.start_addr,
+                sysdbg_cpu32_ctxt_regs_type[self.version],
+                False)
+            self.start_addr += struct.calcsize(
+                sysdbg_cpu32_ctxt_regs_type[self.version])
 
-        self.core_regs = TZCpuCtx_v2(self.version, sc_regs, ram_dump)
-        self.sec_regs = TZCpuCtx_v2(self.version, sc_secure, ram_dump)
+        self.core_regs = TZCpuCtx_v2(self.version, sc_regs,
+                                     self.neon_regs, ram_dump)
+        self.sec_regs = TZCpuCtx_v2(self.version, sc_secure,
+                                    self.neon_regs, ram_dump)
         return True