diff --git a/UEFITool/uefitool.cpp b/UEFITool/uefitool.cpp index abd7cc5..f2ef7cb 100644 --- a/UEFITool/uefitool.cpp +++ b/UEFITool/uefitool.cpp @@ -17,7 +17,7 @@ UEFITool::UEFITool(QWidget *parent) : QMainWindow(parent), ui(new Ui::UEFITool), -version(tr("0.30.0_alpha8")) +version(tr("0.30.0_alpha9")) { clipboard = QApplication::clipboard(); diff --git a/common/descriptor.h b/common/descriptor.h index 82ff6da..19cab55 100644 --- a/common/descriptor.h +++ b/common/descriptor.h @@ -34,37 +34,39 @@ typedef struct _FLASH_DESCRIPTOR_HEADER { // Descriptor map // Base fields are storing bits [11:4] of actual base addresses, all other bits are 0 typedef struct _FLASH_DESCRIPTOR_MAP { - UINT8 ComponentBase; // 0x03 on most machines - UINT8 NumberOfFlashChips; // Zero-based number of flash chips installed on board - UINT8 RegionBase; // 0x04 on most machines - UINT8 NumberOfRegions; // Zero-based number of flash regions (descriptor is always included) - UINT8 MasterBase; // 0x06 on most machines - UINT8 NumberOfMasters; // Zero-based number of flash masters - UINT8 PchStrapsBase; // 0x10 on most machines - UINT8 NumberOfPchStraps; // One-based number of UINT32s to read as PCH Straps, min=0, max=255 (1 Kb) - UINT8 ProcStrapsBase; // 0x20 on most machines - UINT8 NumberOfProcStraps; // Number of PROC straps to be read, can be 0 or 1 - UINT8 IccTableBase; // 0x21 on most machines - UINT8 NumberOfIccTableEntries; // 0x00 on most machines - UINT8 DmiTableBase; // 0x25 on most machines - UINT8 NumberOfDmiTableEntries; // 0x00 on most machines - UINT16 ReservedZero; // Still unknown, zeros in all descriptors I have seen + // FLMAP0 + UINT32 ComponentBase : 8; + UINT32 NumberOfFlashChips : 2; // Zero-based number of flash chips installed on board + UINT32 : 6; + UINT32 RegionBase : 8; + UINT32 NumberOfRegions : 3; // Reserved in v2 descriptor + UINT32 : 5; + // FLMAP 1 + UINT32 MasterBase : 8; + UINT32 NumberOfMasters : 2; // Zero-based number of flash masters + UINT32 : 6; + UINT32 PchStrapsBase : 8; + UINT32 NumberOfPchStraps : 8; // One-based number of UINT32s to read as PCH straps, min=0, max=255 (1 Kb) + // FLMAP 2 + UINT32 ProcStrapsBase : 8; + UINT32 NumberOfProcStraps : 8; // One-based number of UINT32s to read as processor straps, min=0, max=255 (1 Kb) + UINT32 : 16; } FLASH_DESCRIPTOR_MAP; // Component section // Flash parameters DWORD structure typedef struct _FLASH_PARAMETERS { - UINT8 FirstChipDensity : 3; - UINT8 SecondChipDensity : 3; - UINT8 ReservedZero0 : 2; // Still unknown, zeros in all descriptors I have seen - UINT8 ReservedZero1 : 8; // Still unknown, zeros in all descriptors I have seen - UINT8 ReservedZero2 : 4; // Still unknown, zeros in all descriptors I have seen + UINT8 FirstChipDensity : 4; + UINT8 SecondChipDensity : 4; + UINT8 : 8; + UINT8 : 1; + UINT8 ReadClockFrequency : 3; // Hardcoded value of 20 Mhz (000b) in v1 descriptors and 17 Mhz (110b) in v2 ones UINT8 FastReadEnabled : 1; - UINT8 FastReadFreqency : 3; - UINT8 FlashReadStatusFrequency : 3; + UINT8 FastReadFrequency : 3; UINT8 FlashWriteFrequency : 3; + UINT8 FlashReadStatusFrequency : 3; UINT8 DualOutputFastReadSupported : 1; - UINT8 ReservedZero3 : 1; // Still unknown, zero in all descriptors I have seen + UINT8 : 1; } FLASH_PARAMETERS; // Flash densities @@ -74,11 +76,16 @@ typedef struct _FLASH_PARAMETERS { #define FLASH_DENSITY_4MB 0x03 #define FLASH_DENSITY_8MB 0x04 #define FLASH_DENSITY_16MB 0x05 +#define FLASH_DENSITY_32MB 0x06 +#define FLASH_DENSITY_64MB 0x07 +#define FLASH_DENSITY_UNUSED 0x0F // Flash frequencies -#define FLASH_FREQUENCY_20MHZ 0x00 -#define FLASH_FREQUENCY_33MHZ 0x01 -#define FLASH_FREQUENCY_50MHZ 0x04 +#define FLASH_FREQUENCY_20MHZ 0x00 +#define FLASH_FREQUENCY_33MHZ 0x01 +#define FLASH_FREQUENCY_48MHZ 0x02 +#define FLASH_FREQUENCY_50MHZ_30MHZ 0x04 +#define FLASH_FREQUENCY_17MHZ 0x06 // Component section structure typedef struct _FLASH_DESCRIPTOR_COMPONENT_SECTION { @@ -95,23 +102,28 @@ typedef struct _FLASH_DESCRIPTOR_COMPONENT_SECTION { // All base and limit register are storing upper part of actual UINT32 base and limit // If limit is zero - region is not present typedef struct _FLASH_DESCRIPTOR_REGION_SECTION { - UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen - UINT16 FlashBlockEraseSize; // Size of block erased by single BLOCK ERASE command - UINT16 BiosBase; - UINT16 BiosLimit; - UINT16 MeBase; - UINT16 MeLimit; - UINT16 GbeBase; - UINT16 GbeLimit; - UINT16 PdrBase; - UINT16 PdrLimit; + UINT16 DescriptorBase; // Descriptor + UINT16 DescriptorLimit; // + UINT16 BiosBase; // BIOS + UINT16 BiosLimit; // + UINT16 MeBase; // ME + UINT16 MeLimit; // + UINT16 GbeBase; // GbE + UINT16 GbeLimit; // + UINT16 PdrBase; // PDR + UINT16 PdrLimit; // + UINT16 Region5Base; // Reserved region + UINT16 Region5Limit; // + UINT16 Region6Base; // Reserved region + UINT16 Region6Limit; // + UINT16 Region7Base; // Reserved region + UINT16 Region7Limit; // + UINT16 EcBase; // EC + UINT16 EcLimit; // + UINT16 Region9Base; // Reserved region + UINT16 Region9Limit; // } FLASH_DESCRIPTOR_REGION_SECTION; -// Flash block erase sizes -#define FLASH_BLOCK_ERASE_SIZE_4KB 0x0000 -#define FLASH_BLOCK_ERASE_SIZE_8KB 0x0001 -#define FLASH_BLOCK_ERASE_SIZE_64KB 0x000F - // Master section typedef struct _FLASH_DESCRIPTOR_MASTER_SECTION { UINT16 BiosId; @@ -125,14 +137,30 @@ typedef struct _FLASH_DESCRIPTOR_MASTER_SECTION { UINT8 GbeWrite; } FLASH_DESCRIPTOR_MASTER_SECTION; +// Master section v2 (Skylake+) +typedef struct _FLASH_DESCRIPTOR_MASTER_SECTION_V2 { + UINT32 : 8; + UINT32 BiosRead : 12; + UINT32 BiosWrite : 12; + UINT32 : 8; + UINT32 MeRead : 12; + UINT32 MeWrite : 12; + UINT32 : 8; + UINT32 GbeRead : 12; + UINT32 GbeWrite : 12; + UINT32 : 32; + UINT32 : 8; + UINT32 EcRead : 12; + UINT32 EcWrite : 12; +} FLASH_DESCRIPTOR_MASTER_SECTION_V2; + // Region access bits in master section #define FLASH_DESCRIPTOR_REGION_ACCESS_DESC 0x01 #define FLASH_DESCRIPTOR_REGION_ACCESS_BIOS 0x02 #define FLASH_DESCRIPTOR_REGION_ACCESS_ME 0x04 #define FLASH_DESCRIPTOR_REGION_ACCESS_GBE 0x08 #define FLASH_DESCRIPTOR_REGION_ACCESS_PDR 0x10 - -//!TODO: Describe PCH and PROC straps sections, as well as ICC and DMI tables +#define FLASH_DESCRIPTOR_REGION_ACCESS_EC 0x20 // Base address of descriptor upper map #define FLASH_DESCRIPTOR_UPPER_MAP_BASE 0x0EFC @@ -155,7 +183,7 @@ typedef struct _VSCC_TABLE_ENTRY { // Base address and size of OEM section #define FLASH_DESCRIPTOR_OEM_SECTION_BASE 0x0F00 -#define FLASH_DESCRIPTOR_OEM_SECTION_SIZE 0xFF +#define FLASH_DESCRIPTOR_OEM_SECTION_SIZE 0x100 // Restore previous packing rules #pragma pack(pop) diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp index b1ddc31..61c0a65 100644 --- a/common/ffsparser.cpp +++ b/common/ffsparser.cpp @@ -216,18 +216,19 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)(descriptor + sizeof(FLASH_DESCRIPTOR_HEADER)); const FLASH_DESCRIPTOR_UPPER_MAP* upperMap = (const FLASH_DESCRIPTOR_UPPER_MAP*)(descriptor + FLASH_DESCRIPTOR_UPPER_MAP_BASE); const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8(descriptor, descriptorMap->RegionBase); - const FLASH_DESCRIPTOR_MASTER_SECTION* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION*)calculateAddress8(descriptor, descriptorMap->MasterBase); + const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8(descriptor, descriptorMap->ComponentBase); - // GbE region - QByteArray gbe; - UINT32 gbeBegin = 0; - UINT32 gbeEnd = 0; - if (regionSection->GbeLimit) { - gbeBegin = calculateRegionOffset(regionSection->GbeBase); - gbeEnd = calculateRegionSize(regionSection->GbeBase, regionSection->GbeLimit); - gbe = intelImage.mid(gbeBegin, gbeEnd); - gbeEnd += gbeBegin; + // Check descriptor version by getting hardcoded value of FlashParameters.ReadClockFrequency + UINT8 descriptorVersion = 0; + if (componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_20MHZ) // Old descriptor + descriptorVersion = 1; + else if (componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_17MHZ) // Skylake+ descriptor + descriptorVersion = 2; + else { + msg(tr("parseIntelImage: unknown descriptor version with ReadClockFrequency %1h").hexarg(componentSection->FlashParameters.ReadClockFrequency)); + return ERR_INVALID_FLASH_DESCRIPTOR; } + // ME region QByteArray me; UINT32 meBegin = 0; @@ -238,16 +239,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa me = intelImage.mid(meBegin, meEnd); meEnd += meBegin; } - // PDR region - QByteArray pdr; - UINT32 pdrBegin = 0; - UINT32 pdrEnd = 0; - if (regionSection->PdrLimit) { - pdrBegin = calculateRegionOffset(regionSection->PdrBase); - pdrEnd = calculateRegionSize(regionSection->PdrBase, regionSection->PdrLimit); - pdr = intelImage.mid(pdrBegin, pdrEnd); - pdrEnd += pdrBegin; - } + // BIOS region QByteArray bios; UINT32 biosBegin = 0; @@ -273,7 +265,43 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa return ERR_INVALID_FLASH_DESCRIPTOR; } + // GbE region + QByteArray gbe; + UINT32 gbeBegin = 0; + UINT32 gbeEnd = 0; + if (regionSection->GbeLimit) { + gbeBegin = calculateRegionOffset(regionSection->GbeBase); + gbeEnd = calculateRegionSize(regionSection->GbeBase, regionSection->GbeLimit); + gbe = intelImage.mid(gbeBegin, gbeEnd); + gbeEnd += gbeBegin; + } + + // PDR region + QByteArray pdr; + UINT32 pdrBegin = 0; + UINT32 pdrEnd = 0; + if (regionSection->PdrLimit) { + pdrBegin = calculateRegionOffset(regionSection->PdrBase); + pdrEnd = calculateRegionSize(regionSection->PdrBase, regionSection->PdrLimit); + pdr = intelImage.mid(pdrBegin, pdrEnd); + pdrEnd += pdrBegin; + } + + // EC region + QByteArray ec; + UINT32 ecBegin = 0; + UINT32 ecEnd = 0; + if (descriptorVersion == 2) { + if (regionSection->EcLimit) { + pdrBegin = calculateRegionOffset(regionSection->EcBase); + pdrEnd = calculateRegionSize(regionSection->EcBase, regionSection->EcLimit); + pdr = intelImage.mid(ecBegin, ecEnd); + ecEnd += ecBegin; + } + } + // Check for intersections between regions + // Descriptor if (hasIntersection(descriptorBegin, descriptorEnd, gbeBegin, gbeEnd)) { msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with GbE region")); return ERR_INVALID_FLASH_DESCRIPTOR; @@ -290,6 +318,11 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with PDR region")); return ERR_INVALID_FLASH_DESCRIPTOR; } + if (descriptorVersion == 2 && hasIntersection(descriptorBegin, descriptorEnd, ecBegin, ecEnd)) { + msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with EC region")); + return ERR_INVALID_FLASH_DESCRIPTOR; + } + // GbE if (hasIntersection(gbeBegin, gbeEnd, meBegin, meEnd)) { msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with ME region")); return ERR_INVALID_FLASH_DESCRIPTOR; @@ -302,6 +335,11 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with PDR region")); return ERR_INVALID_FLASH_DESCRIPTOR; } + if (descriptorVersion == 2 && hasIntersection(gbeBegin, gbeEnd, ecBegin, ecEnd)) { + msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with EC region")); + return ERR_INVALID_FLASH_DESCRIPTOR; + } + // ME if (hasIntersection(meBegin, meEnd, biosBegin, biosEnd)) { msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with BIOS region")); return ERR_INVALID_FLASH_DESCRIPTOR; @@ -310,23 +348,36 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with PDR region")); return ERR_INVALID_FLASH_DESCRIPTOR; } + if (descriptorVersion == 2 && hasIntersection(meBegin, meEnd, ecBegin, ecEnd)) { + msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with EC region")); + return ERR_INVALID_FLASH_DESCRIPTOR; + } + // BIOS if (hasIntersection(biosBegin, biosEnd, pdrBegin, pdrEnd)) { msg(tr("parseIntelImage: descriptor parsing failed, BIOS region has intersection with PDR region")); return ERR_INVALID_FLASH_DESCRIPTOR; } + if (descriptorVersion == 2 && hasIntersection(biosBegin, biosEnd, ecBegin, ecEnd)) { + msg(tr("parseIntelImage: descriptor parsing failed, BIOS region has intersection with EC region")); + return ERR_INVALID_FLASH_DESCRIPTOR; + } + // PDR + if (descriptorVersion == 2 && hasIntersection(pdrBegin, pdrEnd, ecBegin, ecEnd)) { + msg(tr("parseIntelImage: descriptor parsing failed, PDR region has intersection with EC region")); + return ERR_INVALID_FLASH_DESCRIPTOR; + } // Region map is consistent // Intel image QString name = tr("Intel image"); - QString info = tr("Full size: %1h (%2)\nFlash chips: %3\nRegions: %4\nMasters: %5\nPCH straps: %6\nPROC straps: %7\nICC table entries: %8") + QString info = tr("Full size: %1h (%2)\nFlash chips: %3\nRegions: %4\nMasters: %5\nPCH straps: %6\nPROC straps: %7") .hexarg(intelImage.size()).arg(intelImage.size()) .arg(descriptorMap->NumberOfFlashChips + 1) // .arg(descriptorMap->NumberOfRegions + 1) // Zero-based numbers in storage .arg(descriptorMap->NumberOfMasters + 1) // .arg(descriptorMap->NumberOfPchStraps) - .arg(descriptorMap->NumberOfProcStraps) - .arg(descriptorMap->NumberOfIccTableEntries); + .arg(descriptorMap->NumberOfProcStraps); // Construct parsing data pdata.fixed = TRUE; @@ -363,31 +414,67 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa } // Region access settings - info += tr("\nRegion access settings:"); - info += tr("\nBIOS:%1%2h ME:%3%4h GbE:%5%6h") - .hexarg2(masterSection->BiosRead, 2) - .hexarg2(masterSection->BiosWrite, 2) - .hexarg2(masterSection->MeRead, 2) - .hexarg2(masterSection->MeWrite, 2) - .hexarg2(masterSection->GbeRead, 2) - .hexarg2(masterSection->GbeWrite, 2); + if (descriptorVersion == 1) { + const FLASH_DESCRIPTOR_MASTER_SECTION* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION*)calculateAddress8(descriptor, descriptorMap->MasterBase); + info += tr("\nRegion access settings:"); + info += tr("\nBIOS:%1h %2h ME:%3h %4h GbE:%5h %6h") + .hexarg2(masterSection->BiosRead, 2) + .hexarg2(masterSection->BiosWrite, 2) + .hexarg2(masterSection->MeRead, 2) + .hexarg2(masterSection->MeWrite, 2) + .hexarg2(masterSection->GbeRead, 2) + .hexarg2(masterSection->GbeWrite, 2); - // BIOS access table - info += tr("\nBIOS access table:"); - info += tr("\n Read Write"); - info += tr("\nDesc %1 %2") - .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No ") - .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No "); - info += tr("\nBIOS Yes Yes"); - info += tr("\nME %1 %2") - .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No ") - .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No "); - info += tr("\nGbE %1 %2") - .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No ") - .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No "); - info += tr("\nPDR %1 %2") - .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ") - .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No "); + // BIOS access table + info += tr("\nBIOS access table:"); + info += tr("\n Read Write"); + info += tr("\nDesc %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No "); + info += tr("\nBIOS Yes Yes"); + info += tr("\nME %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No "); + info += tr("\nGbE %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No "); + info += tr("\nPDR %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No "); + } + else if (descriptorVersion == 2) { + const FLASH_DESCRIPTOR_MASTER_SECTION_V2* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION_V2*)calculateAddress8(descriptor, descriptorMap->MasterBase); + info += tr("\nRegion access settings:"); + info += tr("\nBIOS: %1h %2h ME: %3h %4h\nGbE: %5h %6h EC: %7h %8h") + .hexarg2(masterSection->BiosRead, 3) + .hexarg2(masterSection->BiosWrite, 3) + .hexarg2(masterSection->MeRead, 3) + .hexarg2(masterSection->MeWrite, 3) + .hexarg2(masterSection->GbeRead, 3) + .hexarg2(masterSection->GbeWrite, 3) + .hexarg2(masterSection->EcRead, 3) + .hexarg2(masterSection->EcWrite, 3); + + // BIOS access table + info += tr("\nBIOS access table:"); + info += tr("\n Read Write"); + info += tr("\nDesc %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No "); + info += tr("\nBIOS Yes Yes"); + info += tr("\nME %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No "); + info += tr("\nGbE %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No "); + info += tr("\nPDR %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No "); + info += tr("\nEC %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No "); + } // VSCC table const VSCC_TABLE_ENTRY* vsccTableEntry = (const VSCC_TABLE_ENTRY*)(descriptor + ((UINT16)upperMap->VsccTableBase << 4)); @@ -430,6 +517,11 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa QModelIndex pdrIndex; result = parsePdrRegion(pdr, pdrBegin, index, pdrIndex); } + // Parse EC region + else if (descriptorVersion == 2 && offsets.at(i) == ecBegin) { + QModelIndex ecIndex; + result = parseEcRegion(ec, ecBegin, index, ecIndex); + } if (result) return result; } @@ -445,6 +537,8 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa IntelDataEnd = biosEnd; else if (LastRegionOffset == pdrBegin) IntelDataEnd = pdrEnd; + else if (descriptorVersion == 2 && LastRegionOffset == ecBegin) + IntelDataEnd = ecEnd; if (IntelDataEnd > (UINT32)intelImage.size()) { // Image file is truncated msg(tr("parseIntelImage: image size %1 (%2) is smaller than the end of last region %3 (%4), may be damaged") @@ -613,6 +707,31 @@ STATUS FfsParser::parsePdrRegion(const QByteArray & pdr, const UINT32 parentOffs return ERR_SUCCESS; } +STATUS FfsParser::parseEcRegion(const QByteArray & ec, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index) +{ + // Check sanity + if (ec.isEmpty()) + return ERR_EMPTY_REGION; + + // Get parent's parsing data + PARSING_DATA pdata = parsingDataFromQModelIndex(parent); + + // Get info + QString name = tr("EC region"); + QString info = tr("Full size: %1h (%2)"). + hexarg(ec.size()).arg(ec.size()); + + // Construct parsing data + pdata.fixed = TRUE; + pdata.offset += parentOffset; + if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset)); + + // Add tree item + index = model->addItem(Types::Region, Subtypes::PdrRegion, name, QString(), info, QByteArray(), ec, parsingDataToQByteArray(pdata), parent); + + return ERR_SUCCESS; +} + STATUS FfsParser::parseBiosRegion(const QByteArray & bios, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index) { // Sanity check diff --git a/common/ffsparser.h b/common/ffsparser.h index ca7e385..9be8f35 100644 --- a/common/ffsparser.h +++ b/common/ffsparser.h @@ -66,6 +66,7 @@ private: STATUS parseMeRegion(const QByteArray & me, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); STATUS parseBiosRegion(const QByteArray & bios, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); STATUS parsePdrRegion(const QByteArray & pdr, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); + STATUS parseEcRegion(const QByteArray & ec, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); STATUS parsePadFileBody(const QModelIndex & index); STATUS parseSections(QByteArray sections, const QModelIndex & index);