Improve detection of BPDT partition tables in raw areas, update the list of known BPDT entry types

This commit is contained in:
Nikolaj Schlej 2022-10-09 07:18:28 +02:00
parent acc913769b
commit 7e5e02b4b4
3 changed files with 112 additions and 72 deletions

View File

@ -274,36 +274,52 @@ UString sectionTypeToUString(const UINT8 type)
UString bpdtEntryTypeToUString(const UINT16 type) UString bpdtEntryTypeToUString(const UINT16 type)
{ {
switch (type) { switch (type) {
case BPDT_ENTRY_TYPE_OEM_SMIP: return UString("OEM SMIP"); case BPDT_ENTRY_TYPE_SMIP: return UString("OEM SMIP");
case BPDT_ENTRY_TYPE_OEM_RBE: return UString("CSE RBE"); case BPDT_ENTRY_TYPE_RBEP: return UString("ROM Boot Extensions");
case BPDT_ENTRY_TYPE_CSE_BUP: return UString("CSE BUP"); case BPDT_ENTRY_TYPE_FTPR: return UString("Bring Up");
case BPDT_ENTRY_TYPE_UCODE: return UString("uCode"); case BPDT_ENTRY_TYPE_UCOD: return UString("Microcode");
case BPDT_ENTRY_TYPE_IBB: return UString("IBB"); case BPDT_ENTRY_TYPE_IBBP: return UString("IBB");
case BPDT_ENTRY_TYPE_SBPDT: return UString("S-BPDT"); case BPDT_ENTRY_TYPE_S_BPDT: return UString("Secondary BPDT");
case BPDT_ENTRY_TYPE_OBB: return UString("OBB"); case BPDT_ENTRY_TYPE_OBBP: return UString("OBB");
case BPDT_ENTRY_TYPE_CSE_MAIN: return UString("CSE Main"); case BPDT_ENTRY_TYPE_NFTP: return UString("Main");
case BPDT_ENTRY_TYPE_ISH: return UString("ISH"); case BPDT_ENTRY_TYPE_ISHC: return UString("ISH");
case BPDT_ENTRY_TYPE_CSE_IDLM: return UString("CSE IDLM"); case BPDT_ENTRY_TYPE_DLMP: return UString("Debug Launch Module");
case BPDT_ENTRY_TYPE_IFP_OVERRIDE: return UString("IFP Override"); case BPDT_ENTRY_TYPE_UEBP: return UString("IFP Bypass");
case BPDT_ENTRY_TYPE_DEBUG_TOKENS: return UString("Debug Tokens"); case BPDT_ENTRY_TYPE_UTOK: return UString("Debug Tokens");
case BPDT_ENTRY_TYPE_USF_PHY_CONFIG: return UString("USF Phy Config"); case BPDT_ENTRY_TYPE_UFS_PHY: return UString("UFS PHY Config");
case BPDT_ENTRY_TYPE_USF_GPP_LUN_ID: return UString("USF GPP LUN ID"); case BPDT_ENTRY_TYPE_UFS_GPP_LUN: return UString("UFS GPP LUN");
case BPDT_ENTRY_TYPE_PMC: return UString("PMC"); case BPDT_ENTRY_TYPE_PMCP: return UString("PMC");
case BPDT_ENTRY_TYPE_IUNIT: return UString("iUnit"); case BPDT_ENTRY_TYPE_IUNP: return UString("iUnit");
case BPDT_ENTRY_TYPE_NVM_CONFIG: return UString("NVM Config"); case BPDT_ENTRY_TYPE_NVMC: return UString("NVM Config");
case BPDT_ENTRY_TYPE_UEP: return UString("UEP"); case BPDT_ENTRY_TYPE_UEP: return UString("Unified Emulation");
case BPDT_ENTRY_TYPE_WLAN_UCODE: return UString("WLAN uCode"); case BPDT_ENTRY_TYPE_WCOD: return UString("WLAN Microcode");
case BPDT_ENTRY_TYPE_LOCL_SPRITES: return UString("LOCL Sprites"); case BPDT_ENTRY_TYPE_LOCL: return UString("LOCL Sprites");
case BPDT_ENTRY_TYPE_OEM_KEY_MANIFEST: return UString("OEM Key Manifest"); case BPDT_ENTRY_TYPE_OEMP: return UString("OEM Key Manifest");
case BPDT_ENTRY_TYPE_DEFAULTS: return UString("Defaults"); case BPDT_ENTRY_TYPE_FITC: return UString("fitc.cfg");
case BPDT_ENTRY_TYPE_PAVP: return UString("PAVP"); case BPDT_ENTRY_TYPE_PAVP: return UString("PAVP");
case BPDT_ENTRY_TYPE_TCSS_FW_IOM: return UString("TCSS FW IOM"); case BPDT_ENTRY_TYPE_IOMP: return UString("TCSS FW IOM");
case BPDT_ENTRY_TYPE_TCSS_FW_PHY: return UString("TCSS FW PHY"); case BPDT_ENTRY_TYPE_XPHY: return UString("TCSS FW PHY");
case BPDT_ENTRY_TYPE_TBT: return UString("TCSS TBT"); case BPDT_ENTRY_TYPE_TBTP: return UString("TCSS TBT");
case BPDT_ENTRY_TYPE_USB_PHY: return UString("USB PHY"); case BPDT_ENTRY_TYPE_PLTS: return UString("Platform Settings");
case BPDT_ENTRY_TYPE_PCHC: return UString("PCHC"); case BPDT_ENTRY_TYPE_RES27: return UString("Reserved 27");
case BPDT_ENTRY_TYPE_SAMF: return UString("SAMF"); case BPDT_ENTRY_TYPE_RES28: return UString("Reserved 28");
case BPDT_ENTRY_TYPE_RES29: return UString("Reserved 29");
case BPDT_ENTRY_TYPE_RES30: return UString("Reserved 30");
case BPDT_ENTRY_TYPE_DPHY: return UString("Dekel PHY");
case BPDT_ENTRY_TYPE_PCHC: return UString("PCH Config");
case BPDT_ENTRY_TYPE_ISIF: return UString("ISI FW");
case BPDT_ENTRY_TYPE_ISIC: return UString("ISI Config");
case BPDT_ENTRY_TYPE_HBMI: return UString("HBM IO");
case BPDT_ENTRY_TYPE_OMSM: return UString("OOB MSM");
case BPDT_ENTRY_TYPE_GTGP: return UString("GT-GPU");
case BPDT_ENTRY_TYPE_MDFI: return UString("MDF IO");
case BPDT_ENTRY_TYPE_PUNP: return UString("PUnit");
case BPDT_ENTRY_TYPE_PHYP: return UString("GSC PHY");
case BPDT_ENTRY_TYPE_SAMF: return UString("SAM FW");
case BPDT_ENTRY_TYPE_PPHY: return UString("PPHY"); case BPDT_ENTRY_TYPE_PPHY: return UString("PPHY");
case BPDT_ENTRY_TYPE_GBST: return UString("GBST");
case BPDT_ENTRY_TYPE_TCCP: return UString("TCC");
case BPDT_ENTRY_TYPE_PSEP: return UString("PSE");
} }
return usprintf("Unknown %04Xh", type); return usprintf("Unknown %04Xh", type);
} }

View File

@ -286,7 +286,7 @@ UINT64 ExtendedSize;
} EFI_FFS_FILE_HEADER2; } EFI_FFS_FILE_HEADER2;
// Lenovo large file header // Lenovo large file header
typedef struct EFI_FFS_FILE_HEADER_LENOVO_ { typedef struct EFI_FFS_FILE_HEADER2_LENOVO_ {
EFI_GUID Name; EFI_GUID Name;
EFI_FFS_INTEGRITY_CHECK IntegrityCheck; EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
UINT8 Type; UINT8 Type;
@ -579,36 +579,53 @@ typedef struct BPDT_ENTRY_ {
UINT32 Size; UINT32 Size;
} BPDT_ENTRY; } BPDT_ENTRY;
#define BPDT_ENTRY_TYPE_OEM_SMIP 0 // https://github.com/platomav/MEAnalyzer/blob/master/MEA.py#L10595
#define BPDT_ENTRY_TYPE_OEM_RBE 1 #define BPDT_ENTRY_TYPE_SMIP 0
#define BPDT_ENTRY_TYPE_CSE_BUP 2 #define BPDT_ENTRY_TYPE_RBEP 1
#define BPDT_ENTRY_TYPE_UCODE 3 #define BPDT_ENTRY_TYPE_FTPR 2
#define BPDT_ENTRY_TYPE_IBB 4 #define BPDT_ENTRY_TYPE_UCOD 3
#define BPDT_ENTRY_TYPE_SBPDT 5 #define BPDT_ENTRY_TYPE_IBBP 4
#define BPDT_ENTRY_TYPE_OBB 6 #define BPDT_ENTRY_TYPE_S_BPDT 5
#define BPDT_ENTRY_TYPE_CSE_MAIN 7 #define BPDT_ENTRY_TYPE_OBBP 6
#define BPDT_ENTRY_TYPE_ISH 8 #define BPDT_ENTRY_TYPE_NFTP 7
#define BPDT_ENTRY_TYPE_CSE_IDLM 9 #define BPDT_ENTRY_TYPE_ISHC 8
#define BPDT_ENTRY_TYPE_IFP_OVERRIDE 10 #define BPDT_ENTRY_TYPE_DLMP 9
#define BPDT_ENTRY_TYPE_DEBUG_TOKENS 11 #define BPDT_ENTRY_TYPE_UEBP 10
#define BPDT_ENTRY_TYPE_USF_PHY_CONFIG 12 #define BPDT_ENTRY_TYPE_UTOK 11
#define BPDT_ENTRY_TYPE_USF_GPP_LUN_ID 13 #define BPDT_ENTRY_TYPE_UFS_PHY 12
#define BPDT_ENTRY_TYPE_PMC 14 #define BPDT_ENTRY_TYPE_UFS_GPP_LUN 13
#define BPDT_ENTRY_TYPE_IUNIT 15 #define BPDT_ENTRY_TYPE_PMCP 14
#define BPDT_ENTRY_TYPE_NVM_CONFIG 16 #define BPDT_ENTRY_TYPE_IUNP 15
#define BPDT_ENTRY_TYPE_NVMC 16
#define BPDT_ENTRY_TYPE_UEP 17 #define BPDT_ENTRY_TYPE_UEP 17
#define BPDT_ENTRY_TYPE_WLAN_UCODE 18 #define BPDT_ENTRY_TYPE_WCOD 18
#define BPDT_ENTRY_TYPE_LOCL_SPRITES 19 #define BPDT_ENTRY_TYPE_LOCL 19
#define BPDT_ENTRY_TYPE_OEM_KEY_MANIFEST 20 #define BPDT_ENTRY_TYPE_OEMP 20
#define BPDT_ENTRY_TYPE_DEFAULTS 21 #define BPDT_ENTRY_TYPE_FITC 21
#define BPDT_ENTRY_TYPE_PAVP 22 #define BPDT_ENTRY_TYPE_PAVP 22
#define BPDT_ENTRY_TYPE_TCSS_FW_IOM 23 #define BPDT_ENTRY_TYPE_IOMP 23
#define BPDT_ENTRY_TYPE_TCSS_FW_PHY 24 #define BPDT_ENTRY_TYPE_XPHY 24
#define BPDT_ENTRY_TYPE_TBT 25 #define BPDT_ENTRY_TYPE_TBTP 25
#define BPDT_ENTRY_TYPE_USB_PHY 31 #define BPDT_ENTRY_TYPE_PLTS 26
#define BPDT_ENTRY_TYPE_RES27 27
#define BPDT_ENTRY_TYPE_RES28 28
#define BPDT_ENTRY_TYPE_RES29 29
#define BPDT_ENTRY_TYPE_RES30 30
#define BPDT_ENTRY_TYPE_DPHY 31
#define BPDT_ENTRY_TYPE_PCHC 32 #define BPDT_ENTRY_TYPE_PCHC 32
#define BPDT_ENTRY_TYPE_ISIF 33
#define BPDT_ENTRY_TYPE_ISIC 34
#define BPDT_ENTRY_TYPE_HBMI 35
#define BPDT_ENTRY_TYPE_OMSM 36
#define BPDT_ENTRY_TYPE_GTGP 37
#define BPDT_ENTRY_TYPE_MDFI 38
#define BPDT_ENTRY_TYPE_PUNP 39
#define BPDT_ENTRY_TYPE_PHYP 40
#define BPDT_ENTRY_TYPE_SAMF 41 #define BPDT_ENTRY_TYPE_SAMF 41
#define BPDT_ENTRY_TYPE_PPHY 42 #define BPDT_ENTRY_TYPE_PPHY 42
#define BPDT_ENTRY_TYPE_GBST 43
#define BPDT_ENTRY_TYPE_TCCP 44
#define BPDT_ENTRY_TYPE_PSEP 45
// CPD // CPD
#define CPD_SIGNATURE 0x44504324 //$CPD #define CPD_SIGNATURE 0x44504324 //$CPD

View File

@ -929,7 +929,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
// Add tree item // Add tree item
UModelIndex paddingIndex = model->addItem(headerSize + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); UModelIndex paddingIndex = model->addItem(headerSize + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
msg(usprintf("%s: one of volumes inside overlaps the end of data", __FUNCTION__), paddingIndex); msg(usprintf("%s: one of objects inside overlaps the end of data", __FUNCTION__), paddingIndex);
// Update variables // Update variables
prevItemOffset = itemOffset; prevItemOffset = itemOffset;
@ -1381,8 +1381,17 @@ USTATUS FfsParser::findNextRawAreaItem(const UModelIndex & index, const UINT32 l
continue; continue;
const BPDT_HEADER *bpdtHeader = (const BPDT_HEADER *)currentPos; const BPDT_HEADER *bpdtHeader = (const BPDT_HEADER *)currentPos;
// Check version
if (bpdtHeader->HeaderVersion != BPDT_HEADER_VERSION_1) // IFWI 2.0 only for now // Check NumEntries to be sane
if (bpdtHeader->NumEntries > 0x100)
continue;
// Check HeaderVersion to be 1
if (bpdtHeader->HeaderVersion != BPDT_HEADER_VERSION_1) // Check only for IFWI 2.0 headers in raw areas
continue;
// Check RedundancyFlag to be 0 or 1
if (bpdtHeader->RedundancyFlag != 0 && bpdtHeader->RedundancyFlag != 1) // Check only for IFWI 2.0 headers in raw areas
continue; continue;
UINT32 ptBodySize = bpdtHeader->NumEntries * sizeof(BPDT_ENTRY); UINT32 ptBodySize = bpdtHeader->NumEntries * sizeof(BPDT_ENTRY);
@ -4053,13 +4062,15 @@ USTATUS FfsParser::parseBpdtRegion(const UByteArray & region, const UINT32 local
UByteArray body = region.mid(sizeof(BPDT_HEADER), ptBodySize); UByteArray body = region.mid(sizeof(BPDT_HEADER), ptBodySize);
UString name = UString("BPDT partition table"); UString name = UString("BPDT partition table");
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nNumber of entries: %u\nVersion: %2Xh\n" UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n"
"Number of entries: %u\nVersion: %02Xh\nRedundancyFlag: %Xh\n"
"IFWI version: %Xh\nFITC version: %u.%u.%u.%u", "IFWI version: %Xh\nFITC version: %u.%u.%u.%u",
ptSize, ptSize, ptSize, ptSize,
(UINT32)header.size(), (UINT32)header.size(), (UINT32)header.size(), (UINT32)header.size(),
ptBodySize, ptBodySize, ptBodySize, ptBodySize,
ptHeader->NumEntries, ptHeader->NumEntries,
ptHeader->HeaderVersion, ptHeader->HeaderVersion,
ptHeader->RedundancyFlag,
ptHeader->IfwiVersion, ptHeader->IfwiVersion,
ptHeader->FitcMajor, ptHeader->FitcMinor, ptHeader->FitcHotfix, ptHeader->FitcBuild); ptHeader->FitcMajor, ptHeader->FitcMinor, ptHeader->FitcHotfix, ptHeader->FitcBuild);
@ -4204,7 +4215,7 @@ make_partition_table_consistent:
UModelIndex partitionIndex = model->addItem(localOffset + partitions[i].ptEntry.Offset, Types::BpdtPartition, 0, name, text, info, UByteArray(), partition, UByteArray(), Fixed, parent); UModelIndex partitionIndex = model->addItem(localOffset + partitions[i].ptEntry.Offset, Types::BpdtPartition, 0, name, text, info, UByteArray(), partition, UByteArray(), Fixed, parent);
// Special case of S-BPDT // Special case of S-BPDT
if (partitions[i].ptEntry.Type == BPDT_ENTRY_TYPE_SBPDT) { if (partitions[i].ptEntry.Type == BPDT_ENTRY_TYPE_S_BPDT) {
UModelIndex sbpdtIndex; UModelIndex sbpdtIndex;
parseBpdtRegion(partition, 0, partitions[i].ptEntry.Offset, partitionIndex, sbpdtIndex); // Third parameter is a fixup for S-BPDT offset entries, because they are calculated from the start of BIOS region parseBpdtRegion(partition, 0, partitions[i].ptEntry.Offset, partitionIndex, sbpdtIndex); // Third parameter is a fixup for S-BPDT offset entries, because they are calculated from the start of BIOS region
} }
@ -4216,12 +4227,8 @@ make_partition_table_consistent:
parseCpdRegion(partition, 0, partitionIndex, cpdIndex); parseCpdRegion(partition, 0, partitionIndex, cpdIndex);
} }
// There needs to be a more generic way to do it, but it is fine for now // Check for entry type to be known
if (partitions[i].ptEntry.Type > BPDT_ENTRY_TYPE_TBT if (partitions[i].ptEntry.Type > BPDT_ENTRY_TYPE_PSEP) {
&& partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_USB_PHY
&& partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_PCHC
&& partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_SAMF
&& partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_PPHY) {
msg(usprintf("%s: BPDT entry of unknown type found", __FUNCTION__), partitionIndex); msg(usprintf("%s: BPDT entry of unknown type found", __FUNCTION__), partitionIndex);
} }
} }