diff --git a/descriptor.h b/descriptor.h index 5bdefd5..1c496db 100644 --- a/descriptor.h +++ b/descriptor.h @@ -31,6 +31,22 @@ typedef struct _FLASH_DESCRIPTOR_HEADER { // Descriptor region size #define FLASH_DESCRIPTOR_SIZE 0x1000 +// Descriptor version was reserved in older firmware +#define FLASH_DESCRIPTOR_VERSION_INVALID 0xFFFFFFFF + +// Descriptor version present in Coffee Lake and newer +typedef struct _FLASH_DESCRIPTOR_VERSION_V3 { + UINT32 Reserved : 14; + UINT32 VersionMinor : 7; + UINT32 VersionMajor : 11; +} FLASH_DESCRIPTOR_VERSION_V3; + +// Descripror version +typedef union _FLASH_DESCRIPTOR_VERSION { + UINT32 RawValue; + FLASH_DESCRIPTOR_VERSION_V3 V3; +} FLASH_DESCRIPTOR_VERSION; + // Descriptor map // Base fields are storing bits [11:4] of actual base addresses, all other bits are 0 typedef struct _FLASH_DESCRIPTOR_MAP { @@ -51,6 +67,8 @@ typedef struct _FLASH_DESCRIPTOR_MAP { UINT32 ProcStrapsBase : 8; UINT32 NumberOfProcStraps : 8; // One-based number of UINT32s to read as processor straps, min=0, max=255 (1 Kb) UINT32: 16; + // FLMAP 3 + FLASH_DESCRIPTOR_VERSION Version; // Reserved prior to v3 } FLASH_DESCRIPTOR_MAP; #define FLASH_DESCRIPTOR_MAX_BASE 0xE0 diff --git a/ffsengine.cpp b/ffsengine.cpp index 8831391..94bca3d 100644 --- a/ffsengine.cpp +++ b/ffsengine.cpp @@ -3033,23 +3033,35 @@ UINT8 FfsEngine::reconstructIntelImage(const QModelIndex& index, QByteArray& rec UINT32 ecBegin = 0; UINT32 ecEnd = 0; - const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8((const UINT8*)descriptor.constData(), descriptorMap->ComponentBase); - // Check descriptor version by getting hardcoded value of FlashParameters.ReadClockFrequency UINT8 descriptorVersion = 0; - if (componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_20MHZ) { // Old descriptor - descriptorVersion = 1; + if (descriptorMap->Version.RawValue != FLASH_DESCRIPTOR_VERSION_INVALID) { + // Normally this is 1.0, check only the major value to avoid unnecessary future incompatibilities. + if (descriptorMap->Version.V3.VersionMajor != 1) { + msg(tr("reconstructIntelImage: unknown descriptor version: %1.%2").arg(descriptorMap->Version.V3.VersionMajor) + .arg(descriptorMap->Version.V3.VersionMinor)); + return ERR_INVALID_FLASH_DESCRIPTOR; + } + descriptorVersion = 3; } - else if (componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_17MHZ || // Skylake+ descriptor - componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_50MHZ_30MHZ) { // Coffee Lake+ descriptor - descriptorVersion = 2; + else { + // Check legacy descriptor version by getting hardcoded value of FlashParameters.ReadClockFrequency + const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8((const UINT8*)descriptor.constData(), descriptorMap->ComponentBase); + 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("reconstructIntelImage: unknown descriptor version with ReadClockFrequency %1h").hexarg(componentSection->FlashParameters.ReadClockFrequency)); + return ERR_INVALID_FLASH_DESCRIPTOR; + } + } + + if (descriptorVersion >= 2) { ecBegin = calculateRegionOffset(regionSection->EcBase); ecEnd = ecBegin + calculateRegionSize(regionSection->EcBase, regionSection->EcLimit); } - else { - msg(tr("reconstructIntelImage: unknown descriptor version with ReadClockFrequency %1h").hexarg(componentSection->FlashParameters.ReadClockFrequency)); - return ERR_INVALID_FLASH_DESCRIPTOR; - } - UINT32 offset = descriptor.size(); // Reconstruct other regions