[Feature][Modem]Update MTK MODEM V1.6 baseline version: MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6
MTK modem version: MT2735_IVT_MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6.tar.gz
RF modem version: NA
Change-Id: I45a4c2752fa9d1a618beacd5d40737fb39ab64fb
diff --git a/mcu/tools/MIDR_dump_post_processing.py b/mcu/tools/MIDR_dump_post_processing.py
new file mode 100755
index 0000000..13c7558
--- /dev/null
+++ b/mcu/tools/MIDR_dump_post_processing.py
@@ -0,0 +1,402 @@
+import argparse
+import os
+from subprocess import Popen, PIPE
+
+version = "1.2"
+#Fixed Pattern
+EDBGINFO = "EDBGINFO\x05\x00\x00\x00"
+SKIPPATTERN = "\x53\x4B\x49\x50"
+MRDUMPBI = "MRDUMPBI"
+
+#Start/End Guard Eable
+haveStartGuard = False
+haveEndGuard = False
+
+#Default AP vmlinux path (for auto find function)
+apSymbolPathWIN = "\\\\mtksfs00\\srv_colgin_ci\\image\\SanityLoad\\"
+apSymbolPathLINUX = "/proj/srv_colgin_ci/image/SanityLoad/"
+
+#Default value (would be overwitten)
+remappingBank4 = [[0x40000000, 0x8e000000], [0x46000000, 0x84000000]]
+remappingBank0 = [0x00000000, 0xae000000]
+DRAMOffset = 0x40000000
+fileOffset = 0x00004000
+
+def ParsingArgument() :
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-i", type=str, dest="core_dump", required=True, help="Input full ram dump path")
+ parser.add_argument("-o", type=str, dest="output", required=True, help="Output memory dump file path")
+ parser.add_argument("-p", "--use_mrdump_tool",type=str, dest="use_mrdump_tool", default="No", help="Set this flag \"True\" to use merdump tool to extract SYS_COREDUMP info for supporting lagacy version")
+ parser.add_argument("-e", "--elf", type=str, default='', dest="vmlinux", help="Input vmlinux (ELF) path")
+ parser.add_argument("-t", "--mrdump-tool", type=str, default='mrdump-gdb', dest="dump_tool_path",help="MRDUMP Tool path (ex. dump-tools-1.00/mrdump-gdb)\
+ https://wiki.mediatek.inc/pages/viewpage.action?pageId=58229130")
+
+ return (parser.parse_args().core_dump, parser.parse_args().output, parser.parse_args().use_mrdump_tool, parser.parse_args().vmlinux, parser.parse_args().dump_tool_path)
+
+def ConvertMD2APAddress(MDAddress) :
+ if MDAddress[-1] >> 4 == 0 or MDAddress[-1] >> 4 == 2 or MDAddress[-1] >> 4 == 3 or MDAddress[-1] >> 4 == 6 or MDAddress[-1] >> 4 == 9 :
+ bank = 0
+ elif MDAddress[-1] >> 4 == 1 or MDAddress[-1] >> 4 == 7 :
+ bank = 1
+ elif MDAddress[-1] >> 4 == 4 :
+ bank = 4
+ else :
+ bank = -1
+
+ intMDAddress = int.from_bytes(MDAddress[0:3], "little")
+
+ if bank == 0 :
+ APAddress = intMDAddress - remappingBank0[0] + remappingBank0[1]
+ elif bank == 1 :
+ APAddress = intMDAddress - remappingBank0[0] + remappingBank0[1] + 0x02000000
+ elif bank == 4 :
+ if MDAddress[-1] & 15 < 6 :
+ APAddress = intMDAddress - remappingBank4[0][0] + remappingBank4[0][1]
+ else :
+ APAddress = intMDAddress - remappingBank4[1][0] + remappingBank4[1][1]
+ APAddress +=0x40000000
+ else :
+ print("Can't find remapping address")
+ APAddress = intMDAddress
+
+ APAddress += (MDAddress[3] & 15) << 24
+
+ return APAddress.to_bytes(4, "little")
+
+def ParsingMIDRStartAddress(inp) :
+ inp.seek(remappingBank4[1][1] - DRAMOffset + fileOffset)
+
+ stage = 0
+ ch = inp.read(1)
+ while ch :
+ if ord(ch) == ord(EDBGINFO[stage]) :
+ stage += 1
+ else :
+ stage = 0
+
+ if stage == len(EDBGINFO) :
+ return True
+
+ ch = inp.read(1)
+
+ return False
+
+def ParsingTLV(inp, outp) :
+ global haveStartGuard, haveEndGuard
+ typeID = inp.read(1)
+
+ #By MDMP_TLV_END = 0
+ while ord(typeID) != 0:
+ lens = inp.read(2)
+ value = inp.read(int.from_bytes(lens, byteorder="little"))
+
+ if int.from_bytes(value, "little") & 1 == True :
+ haveStartGuard = True
+ if int.from_bytes(value, "little") & 2 == True :
+ haveEndGuard = True
+
+ outp.write(typeID+lens+value)
+ typeID = inp.read(1)
+
+ lens = inp.read(2)
+ outp.write(typeID+lens)
+
+def StartGuardCheck(inp, outp) :
+ startGuard = inp.read(1)
+
+ if startGuard != b'\xce' :
+ return False
+
+ outp.write(startGuard)
+ return True
+
+# ToDo: when DHL add end guard, it need to add end guard check
+def EndGuardCheck(inp, outp) :
+ endGuard = inp.read(1)
+ outp.write(endGuard)
+ return True
+
+def ProcessMemOnEMI(inp, outp, mdAddress, lens) :
+ print("Processing mem on EMI : ")
+ apAddress = ConvertMD2APAddress(mdAddress)
+ print('MD address', '0x%08x'%int.from_bytes(mdAddress, "little"))
+ print("AP address", '0x%08x'%int.from_bytes(apAddress, "little"))
+ DRAMAddress = int.from_bytes(apAddress, "little") - DRAMOffset + fileOffset
+ print("File offset", '0x%08x'%DRAMAddress)
+ storeFilePointer = inp.tell()
+ inp.seek(DRAMAddress, 0)
+ memData = inp.read(int.from_bytes(lens, "little"))
+ outp.write(memData)
+ inp.seek(storeFilePointer, 0)
+
+
+def ParsingDumpHeader(inp, outp) :
+ if haveStartGuard == True and StartGuardCheck(inp, outp) == False :
+ print("Error! Start Guard Missing")
+ exit()
+
+ memType = inp.read(1)
+ print("Mem type : ", hex(int.from_bytes(memType, "little")))
+ if memType == b'\xff' :
+ endDump = inp.read(4)
+ # end dump check
+ if endDump != b"\x44\x45\x41\x44" :
+ print("End Dump Pattern Error!")
+ exit()
+ outp.write(memType+endDump)
+ return memType
+
+ # 128 = 0b1000 0000
+ if ord(memType) & 128 :
+ headerType = 1
+ else :
+ headerType = 0
+ outp.write(memType)
+
+ address = inp.read(4)
+ outp.write(address)
+ addressMapping = -1
+
+ if headerType == 1 :
+ addressMapping = inp.read(4)
+ outp.write(addressMapping)
+
+ length = inp.read(2)
+ outp.write(length)
+
+ if length == b'\xff\xff' :
+ length = inp.read(4)
+ outp.write(length)
+ print("Length: ", int.from_bytes(length, "little"))
+
+ skip = inp.read(4)
+
+ if skip == bytes(SKIPPATTERN, "ascii") :
+ ProcessMemOnEMI(inp, outp, address, length)
+ else :
+ inp.seek(-4, 1)
+ print('MD address', '0x%08x'%int.from_bytes(address, "little"))
+ rawData = inp.read(int.from_bytes(length, "little"))
+ outp.write(rawData)
+
+ if haveEndGuard == True and EndGuardCheck(inp, outp) == False:
+ print("Error! End Guard Missing")
+
+ return memType
+
+def RebuildFullMemoryDumpFile(inputFileName, outputFileName) :
+ inp = open(inputFileName, "rb")
+ outp = open(outputFileName, "wb")
+
+ if ParsingMIDRStartAddress(inp) == False :
+ print("Not Found MIDR")
+ exit()
+
+ for byte in EDBGINFO :
+ outp.write(ord(byte).to_bytes(1, "little"))
+
+ ParsingTLV(inp, outp)
+ memType = ParsingDumpHeader(inp, outp)
+
+ while memType != b'\xff' :
+ print("\n======\n")
+ memType = ParsingDumpHeader(inp, outp)
+
+ inp.close()
+ outp.close()
+
+def GetDRAMFileOffset(inputFileName) :
+ global fileOffset
+
+ proc = Popen("readelf -l -W %s"%inputFileName, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+ commandResult = proc.communicate()
+
+ if commandResult[1] != b'' :
+ print(str(proc.communicate()[1], 'utf-8'))
+ print("%s is invalid!! Please use the correct SYS_COREDUMP file!!" %inputFileName)
+ exit()
+
+ result = commandResult[0]
+ result = str(result, 'utf-8')
+
+ SRAMPos = result.find("LOAD")
+ DRAMPos = result.find("LOAD", SRAMPos + 1)
+ hexStart = result.find("0x", DRAMPos)
+ hexEnd = result.find(" ", hexStart)
+ fileOffset = int(result[hexStart : hexEnd], 16)
+
+ print("File offset : 0x%08x" %fileOffset)
+
+def MRDUMPToolParser(inputFileName, elf, dumpToolPath) :
+ proc = Popen("%s %s %s "%(dumpToolPath, elf, inputFileName), shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+
+ result = proc.communicate("print /x modem_sys[0].mem_layout.md_bank0.base_ap_view_phy\n\
+ print /x modem_sys[0].mem_layout.md_bank0.base_md_view_phy\n\
+ print /x modem_sys[0].mem_layout.md_bank4_noncacheable.base_ap_view_phy\n\
+ print /x modem_sys[0].mem_layout.md_bank4_noncacheable.base_md_view_phy\n\
+ print /x modem_sys[0].mem_layout.md_bank4_cacheable.base_ap_view_phy\n\
+ print /x modem_sys[0].mem_layout.md_bank4_cacheable.base_md_view_phy\n".encode())[0]
+
+ result = str(result, 'utf-8')
+ remappingBank0[1] = int(result[result.find("$1")+4 : result.find('\n', result.find("$1"))], 16)
+ remappingBank0[0] = int(result[result.find("$2")+4 : result.find('\n', result.find("$2"))], 16)
+ remappingBank4[0][1] = int(result[result.find("$3")+4 : result.find('\n', result.find("$3"))], 16)
+ remappingBank4[0][0] = int(result[result.find("$4")+4 : result.find('\n', result.find("$4"))], 16)
+ remappingBank4[1][1] = int(result[result.find("$5")+4 : result.find('\n', result.find("$5"))], 16)
+ remappingBank4[1][0] = int(result[result.find("$6")+4 : result.find('\n', result.find("$6"))], 16)
+ print("Bank0/1 \t\t MD address: 0x%08x <-> AP address 0x%08x"%(remappingBank0[0], remappingBank0[1]))
+ print("Bank4(noncacheable) \t MD address: 0x%08x <-> AP address 0x%08x"%(remappingBank4[0][0], remappingBank4[0][1]))
+ print("Bank4(cacheable) \t MD address: 0x%08x <-> AP address 0x%08x"%(remappingBank4[1][0], remappingBank4[1][1]))
+
+ GetDRAMFileOffset(inputFileName)
+
+ return
+
+def GetAPInfo(coreDumpFile) :
+ checkInfoList = ["BRANCH_INFO=" , "VERNO=", "SUBTARGET=", "PLATFORM="]
+ apLoadInfo = []
+
+ inp = open(coreDumpFile, "rb")
+ for info in checkInfoList :
+ stage = 0
+ tempInfo = ""
+ wantInfo = ""
+
+ ch = inp.read(1)
+ while ch :
+ if ord(ch) == ord(info[stage]) :
+ stage += 1
+ tempInfo = tempInfo + ch.decode()
+ else :
+ stage = 0
+ tempInfo = ""
+
+ if stage == len(info) :
+ ch = inp.read(1)
+ if (ord(ch) >= ord('A') and ord(ch) <= ord('Z')) or (ord(ch) >= ord('a') and ord(ch) <= ord('z')) :
+ while ord(ch) != ord('\n') :
+ wantInfo = wantInfo + ch.decode()
+ ch = inp.read(1)
+ apLoadInfo.append(wantInfo)
+ break
+ else :
+ stage = 0
+ tempInfo = ""
+
+ ch = inp.read(1)
+ if len(checkInfoList) != len(apLoadInfo):
+ return []
+ return apLoadInfo
+
+
+def AutoFindAPELF(coreDumpFile) :
+ print ("======\nAuto find AP ELF mode...")
+ apInfo = GetAPInfo(coreDumpFile)
+ if len(apInfo) == 0 :
+ print("\nCan't find AP version info in full RAM dump!\nPlease enter the vmliux path manually!")
+ exit()
+
+ print("\nBRANCH_INFO:\t%s\nVERNO:\t\t%s\nSUBTARGET:\t%s\nPLATFORM:\t%s\n" %(apInfo[0], apInfo[1], apInfo[2], apInfo[3]))
+
+ vmlinuxPath = apSymbolPathLINUX + apInfo[0] + "/Symbols/" + apInfo[1] + "/" + apInfo[3] + "/" + apInfo[2] + "/vmlinux"
+
+ if os.path.isfile(vmlinuxPath) == False :
+ print("Can't find the vmlinux in %s !\nPlease update your AP version or enter the vmliux path manually!" %vmlinuxPath)
+ exit()
+
+ print("vmlinux path : " + vmlinuxPath + "\n")
+
+ return vmlinuxPath
+
+
+# Manual input mode (for backup)
+def ManualInput() :
+ bank0StartAddress = input("Please enter the AP address mapping to Bank0/1 (0x00000000) :\n")
+ bank4MDCacheableStartAddress = input("Please enter the Bank4 cacheable MD address :\n")
+ bank4CacheableStartAddress = input("Please enter the AP address mapping to Bank4 (cacheable) :\n")
+ bank4UncacheableStartAddress = input("Please enter the AP address mapping to Bank4 (uncacheable) :\n")
+
+ remappingBank0[1] = int(bank0StartAddress, 16)
+ remappingBank4[1][0] = int(bank4MDCacheableStartAddress, 16)
+ remappingBank4[1][1] = int(bank4CacheableStartAddress, 16)
+ remappingBank4[0][1] = int(bank4UncacheableStartAddress, 16)
+
+def ParseMRDUMPBIHeader(coreDumpFile) :
+ inp = open(coreDumpFile, "rb")
+ stage = 0
+ currentPos = 1
+ foundMRDUMPBI = False
+
+ GetDRAMFileOffset(coreDumpFile)
+
+ ch = inp.read(1)
+
+ # MRDUMPBI should be stored before DRAM dump
+ while ch and currentPos <= fileOffset:
+ # Parsing MRDUMPBI to find MD/AP remapping info
+ if ord(ch) == ord(MRDUMPBI[stage]) :
+ stage += 1
+ else :
+ stage = 0
+
+ currentPos = currentPos + 1
+
+ if stage == len(MRDUMPBI) :
+ # Get AP/MD address remapping info
+ remappingBank0[1] = int.from_bytes(inp.read(8), "little")
+ remappingBank0[0] = int.from_bytes(inp.read(8), "little")
+ remappingBank4[1][1] = int.from_bytes(inp.read(8), "little")
+ remappingBank4[1][0] = int.from_bytes(inp.read(8), "little")
+ remappingBank4[0][1] = int.from_bytes(inp.read(8), "little")
+ remappingBank4[0][0] = int.from_bytes(inp.read(8), "little")
+
+ print("Bank0/1 \t\t MD address: 0x%08x <-> AP address: 0x%08x"%(remappingBank0[0], remappingBank0[1]))
+ print("Bank4(noncacheable) \t MD address: 0x%08x <-> AP address: 0x%08x"%(remappingBank4[0][0], remappingBank4[0][1]))
+ print("Bank4(cacheable) \t MD address: 0x%08x <-> AP address: 0x%08x"%(remappingBank4[1][0], remappingBank4[1][1]))
+
+ foundMRDUMPBI = True
+
+ break
+
+ ch = inp.read(1)
+
+ if foundMRDUMPBI == False :
+ print("\nCan't find MRDUMPBI! The AP version doesn't provide AP/MD address remapping info!!\n\nEnter maunal input mode: \n")
+ ManualInput()
+
+
+
+if __name__ == "__main__":
+ print("MIDR dump post-processing script V %s"%version)
+
+ inputFileName, outputFileName, useMRDumptool, elf, dumpToolPath = ParsingArgument()
+
+ if useMRDumptool == "True" :
+ # Legacy version : need mrdump tool and vmlinux file to get AP/MD address remapping
+ if os.name != "posix" :
+ print("\nmrdump tool only can run on Linux!")
+ exit()
+
+ # Test mrdump tool
+ proc = Popen("%s "%dumpToolPath, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+ result = proc.communicate()
+ if str(result[1], 'utf-8') != "" :
+ print(str(result[1], 'utf-8'))
+ print("Please enter the correct mrdump tool path!")
+ exit()
+
+ if elf == '' :
+ elf = AutoFindAPELF(inputFileName)
+
+ print("======\nGet MD/AP address remapping information by mrdump tool...")
+ MRDUMPToolParser(inputFileName, elf, dumpToolPath)
+ print("\nDone!\n")
+ else :
+ # From V1.2 : AP write AP/MD address remapping info to SYS_COREDUMP header, we can parse header to get those info
+ print("======\nGet MD/AP address remapping information from dump header...")
+ ParseMRDUMPBIHeader(inputFileName)
+ print("\nDone!\n")
+
+ print("======\n\nGenerating FULL Memory Dump File...\n")
+ RebuildFullMemoryDumpFile(inputFileName, outputFileName)
+ print("Done!")