mirror of
https://github.com/LongSoft/UEFITool.git
synced 2025-02-13 15:22:42 +08:00
Improve descriptor version handling
This commit is contained in:
parent
acb1a4d099
commit
3993bd7090
17
descriptor.h
17
descriptor.h
@ -33,18 +33,15 @@ typedef struct _FLASH_DESCRIPTOR_HEADER {
|
|||||||
|
|
||||||
// Descriptor version was reserved in older firmware
|
// Descriptor version was reserved in older firmware
|
||||||
#define FLASH_DESCRIPTOR_VERSION_INVALID 0xFFFFFFFF
|
#define FLASH_DESCRIPTOR_VERSION_INVALID 0xFFFFFFFF
|
||||||
|
// The only known version found in Coffee Lake
|
||||||
|
#define FLASH_DESCRIPTOR_VERSION_MAJOR 1
|
||||||
|
#define FLASH_DESCRIPTOR_VERSION_MINOR 0
|
||||||
|
|
||||||
// Descriptor version present in Coffee Lake and newer
|
// Descriptor version present in Coffee Lake and newer
|
||||||
typedef struct _FLASH_DESCRIPTOR_VERSION_V3 {
|
typedef struct _FLASH_DESCRIPTOR_VERSION {
|
||||||
UINT32 Reserved : 14;
|
UINT32 Reserved : 14;
|
||||||
UINT32 VersionMinor : 7;
|
UINT32 Minor : 7;
|
||||||
UINT32 VersionMajor : 11;
|
UINT32 Major : 11;
|
||||||
} FLASH_DESCRIPTOR_VERSION_V3;
|
|
||||||
|
|
||||||
// Descripror version
|
|
||||||
typedef union _FLASH_DESCRIPTOR_VERSION {
|
|
||||||
UINT32 RawValue;
|
|
||||||
FLASH_DESCRIPTOR_VERSION_V3 V3;
|
|
||||||
} FLASH_DESCRIPTOR_VERSION;
|
} FLASH_DESCRIPTOR_VERSION;
|
||||||
|
|
||||||
// Descriptor map
|
// Descriptor map
|
||||||
@ -68,7 +65,7 @@ typedef struct _FLASH_DESCRIPTOR_MAP {
|
|||||||
UINT32 NumberOfProcStraps : 8; // One-based number of UINT32s to read as processor straps, min=0, max=255 (1 Kb)
|
UINT32 NumberOfProcStraps : 8; // One-based number of UINT32s to read as processor straps, min=0, max=255 (1 Kb)
|
||||||
UINT32: 16;
|
UINT32: 16;
|
||||||
// FLMAP 3
|
// FLMAP 3
|
||||||
FLASH_DESCRIPTOR_VERSION Version; // Reserved prior to v3
|
UINT32 DescriptorVersion; // Reserved prior to Coffee Lake
|
||||||
} FLASH_DESCRIPTOR_MAP;
|
} FLASH_DESCRIPTOR_MAP;
|
||||||
|
|
||||||
#define FLASH_DESCRIPTOR_MAX_BASE 0xE0
|
#define FLASH_DESCRIPTOR_MAX_BASE 0xE0
|
||||||
|
@ -286,14 +286,10 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8(descriptor, descriptorMap->RegionBase);
|
const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8(descriptor, descriptorMap->RegionBase);
|
||||||
const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8(descriptor, descriptorMap->ComponentBase);
|
const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8(descriptor, descriptorMap->ComponentBase);
|
||||||
|
|
||||||
UINT8 descriptorVersion = 0;
|
// Check for legacy descriptor version by getting hardcoded value of FlashParameters.ReadClockFrequency
|
||||||
if (descriptorMap->Version.RawValue != FLASH_DESCRIPTOR_VERSION_INVALID) // Kaby Lake+ descriptor
|
UINT8 descriptorVersion = 2; // Skylake+ descriptor
|
||||||
descriptorVersion = 3;
|
if (componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_20MHZ) // Legacy descriptor
|
||||||
// Check descriptor version by getting hardcoded value of FlashParameters.ReadClockFrequency
|
|
||||||
else if (componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_20MHZ) // Old descriptor
|
|
||||||
descriptorVersion = 1;
|
descriptorVersion = 1;
|
||||||
else // Skylake+ descriptor
|
|
||||||
descriptorVersion = 2;
|
|
||||||
|
|
||||||
// ME region
|
// ME region
|
||||||
QByteArray me;
|
QByteArray me;
|
||||||
@ -360,7 +356,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
QByteArray ec;
|
QByteArray ec;
|
||||||
UINT32 ecBegin = 0;
|
UINT32 ecBegin = 0;
|
||||||
UINT32 ecEnd = 0;
|
UINT32 ecEnd = 0;
|
||||||
if (descriptorVersion >= 2) {
|
if (descriptorVersion == 2) {
|
||||||
if (regionSection->EcLimit) {
|
if (regionSection->EcLimit) {
|
||||||
ecBegin = calculateRegionOffset(regionSection->EcBase);
|
ecBegin = calculateRegionOffset(regionSection->EcBase);
|
||||||
ecEnd = calculateRegionSize(regionSection->EcBase, regionSection->EcLimit);
|
ecEnd = calculateRegionSize(regionSection->EcBase, regionSection->EcLimit);
|
||||||
@ -387,7 +383,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with PDR region"));
|
msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with PDR region"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
if (descriptorVersion >= 2 && hasIntersection(descriptorBegin, descriptorEnd, ecBegin, ecEnd)) {
|
if (descriptorVersion == 2 && hasIntersection(descriptorBegin, descriptorEnd, ecBegin, ecEnd)) {
|
||||||
msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with EC region"));
|
msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with EC region"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
@ -404,7 +400,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with PDR region"));
|
msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with PDR region"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
if (descriptorVersion >= 2 && hasIntersection(gbeBegin, gbeEnd, ecBegin, ecEnd)) {
|
if (descriptorVersion == 2 && hasIntersection(gbeBegin, gbeEnd, ecBegin, ecEnd)) {
|
||||||
msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with EC region"));
|
msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with EC region"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
@ -417,7 +413,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with PDR region"));
|
msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with PDR region"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
if (descriptorVersion >= 2 && hasIntersection(meBegin, meEnd, ecBegin, ecEnd)) {
|
if (descriptorVersion == 2 && hasIntersection(meBegin, meEnd, ecBegin, ecEnd)) {
|
||||||
msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with EC region"));
|
msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with EC region"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
@ -426,12 +422,12 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
msg(tr("parseIntelImage: descriptor parsing failed, BIOS region has intersection with PDR region"));
|
msg(tr("parseIntelImage: descriptor parsing failed, BIOS region has intersection with PDR region"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
if (descriptorVersion >= 2 && hasIntersection(biosBegin, biosEnd, ecBegin, ecEnd)) {
|
if (descriptorVersion == 2 && hasIntersection(biosBegin, biosEnd, ecBegin, ecEnd)) {
|
||||||
msg(tr("parseIntelImage: descriptor parsing failed, BIOS region has intersection with EC region"));
|
msg(tr("parseIntelImage: descriptor parsing failed, BIOS region has intersection with EC region"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
// PDR
|
// PDR
|
||||||
if (descriptorVersion >= 2 && hasIntersection(pdrBegin, pdrEnd, ecBegin, ecEnd)) {
|
if (descriptorVersion == 2 && hasIntersection(pdrBegin, pdrEnd, ecBegin, ecEnd)) {
|
||||||
msg(tr("parseIntelImage: descriptor parsing failed, PDR region has intersection with EC region"));
|
msg(tr("parseIntelImage: descriptor parsing failed, PDR region has intersection with EC region"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
@ -474,7 +470,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
offsets.append(pdrBegin);
|
offsets.append(pdrBegin);
|
||||||
info += tr("\nPDR region offset: %1h").hexarg(pdrBegin);
|
info += tr("\nPDR region offset: %1h").hexarg(pdrBegin);
|
||||||
}
|
}
|
||||||
if (descriptorVersion >= 2 && regionSection->EcLimit) {
|
if (descriptorVersion == 2 && regionSection->EcLimit) {
|
||||||
offsets.append(ecBegin);
|
offsets.append(ecBegin);
|
||||||
info += tr("\nEC region offset: %1h").hexarg(ecBegin);
|
info += tr("\nEC region offset: %1h").hexarg(ecBegin);
|
||||||
}
|
}
|
||||||
@ -508,7 +504,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
.arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ")
|
.arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ")
|
||||||
.arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ");
|
.arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ");
|
||||||
}
|
}
|
||||||
else if (descriptorVersion >= 2) {
|
else if (descriptorVersion == 2) {
|
||||||
const FLASH_DESCRIPTOR_MASTER_SECTION_V2* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION_V2*)calculateAddress8(descriptor, descriptorMap->MasterBase);
|
const FLASH_DESCRIPTOR_MASTER_SECTION_V2* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION_V2*)calculateAddress8(descriptor, descriptorMap->MasterBase);
|
||||||
info += tr("\nRegion access settings:");
|
info += tr("\nRegion access settings:");
|
||||||
info += tr("\nBIOS: %1h %2h ME: %3h %4h\nGbE: %5h %6h EC: %7h %8h")
|
info += tr("\nBIOS: %1h %2h ME: %3h %4h\nGbE: %5h %6h EC: %7h %8h")
|
||||||
@ -540,6 +536,17 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
info += tr("\nEC %1 %2")
|
info += tr("\nEC %1 %2")
|
||||||
.arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No ")
|
.arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No ")
|
||||||
.arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No ");
|
.arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_EC ? "Yes " : "No ");
|
||||||
|
|
||||||
|
// Prepend descriptor version if present
|
||||||
|
if (descriptorMap->DescriptorVersion != FLASH_DESCRIPTOR_VERSION_INVALID) {
|
||||||
|
const FLASH_DESCRIPTOR_VERSION* version = (const FLASH_DESCRIPTOR_VERSION*)&descriptorMap->DescriptorVersion;
|
||||||
|
QString versionStr = tr("Flash descriptor version: %1.%2").arg(version->Major).arg(version->Minor);
|
||||||
|
if (version->Major != FLASH_DESCRIPTOR_VERSION_MAJOR || version->Minor != FLASH_DESCRIPTOR_VERSION_MINOR) {
|
||||||
|
versionStr += tr(", unknown");
|
||||||
|
msg(tr("parseIntelImage: unknown flash descriptor version %1.%2").arg(version->Major).arg(version->Minor));
|
||||||
|
}
|
||||||
|
info = versionStr + "\n" + info;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VSCC table
|
// VSCC table
|
||||||
@ -584,7 +591,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
result = parsePdrRegion(pdr, pdrIndex, index);
|
result = parsePdrRegion(pdr, pdrIndex, index);
|
||||||
}
|
}
|
||||||
// Parse EC region
|
// Parse EC region
|
||||||
else if (descriptorVersion >= 2 && offsets.at(i) == ecBegin) {
|
else if (descriptorVersion == 2 && offsets.at(i) == ecBegin) {
|
||||||
QModelIndex ecIndex;
|
QModelIndex ecIndex;
|
||||||
result = parseEcRegion(ec, ecIndex, index);
|
result = parseEcRegion(ec, ecIndex, index);
|
||||||
}
|
}
|
||||||
@ -603,7 +610,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
IntelDataEnd = biosEnd;
|
IntelDataEnd = biosEnd;
|
||||||
else if (LastRegionOffset == pdrBegin)
|
else if (LastRegionOffset == pdrBegin)
|
||||||
IntelDataEnd = pdrEnd;
|
IntelDataEnd = pdrEnd;
|
||||||
else if (descriptorVersion >= 2 && LastRegionOffset == ecBegin)
|
else if (descriptorVersion == 2 && LastRegionOffset == ecBegin)
|
||||||
IntelDataEnd = ecEnd;
|
IntelDataEnd = ecEnd;
|
||||||
|
|
||||||
if (IntelDataEnd > (UINT32)intelImage.size()) { // Image file is truncated
|
if (IntelDataEnd > (UINT32)intelImage.size()) { // Image file is truncated
|
||||||
@ -3037,32 +3044,21 @@ UINT8 FfsEngine::reconstructIntelImage(const QModelIndex& index, QByteArray& rec
|
|||||||
UINT32 ecBegin = 0;
|
UINT32 ecBegin = 0;
|
||||||
UINT32 ecEnd = 0;
|
UINT32 ecEnd = 0;
|
||||||
|
|
||||||
UINT8 descriptorVersion = 0;
|
// Check for legacy descriptor version by getting hardcoded value of FlashParameters.ReadClockFrequency
|
||||||
if (descriptorMap->Version.RawValue != FLASH_DESCRIPTOR_VERSION_INVALID) {
|
UINT8 descriptorVersion = 2; // Skylake+ descriptor
|
||||||
// Normally this is 1.0, check only the major value to avoid unnecessary future incompatibilities.
|
const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8((const UINT8*)descriptor.constData(), descriptorMap->ComponentBase);
|
||||||
if (descriptorMap->Version.V3.VersionMajor != 1) {
|
if (componentSection->FlashParameters.ReadClockFrequency == FLASH_FREQUENCY_20MHZ) // Legacy descriptor
|
||||||
msg(tr("reconstructIntelImage: unknown descriptor version: %1.%2").arg(descriptorMap->Version.V3.VersionMajor)
|
descriptorVersion = 1;
|
||||||
.arg(descriptorMap->Version.V3.VersionMinor));
|
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
if (descriptorVersion == 2 && descriptorMap->DescriptorVersion != FLASH_DESCRIPTOR_VERSION_INVALID) {
|
||||||
}
|
// Warn about incompatible version descriptor in case it is different.
|
||||||
descriptorVersion = 3;
|
const FLASH_DESCRIPTOR_VERSION *version = (const FLASH_DESCRIPTOR_VERSION *)&descriptorMap->DescriptorVersion;
|
||||||
}
|
if (version->Major != FLASH_DESCRIPTOR_VERSION_MAJOR || version->Minor != FLASH_DESCRIPTOR_VERSION_MINOR)
|
||||||
else {
|
msg(tr("reconstructIntelImage: discovered unexpected %1.%2 descriptor version, trying to continue...")
|
||||||
// Check legacy descriptor version by getting hardcoded value of FlashParameters.ReadClockFrequency
|
.arg(version->Major).arg(version->Minor));
|
||||||
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) {
|
if (descriptorVersion == 2) {
|
||||||
ecBegin = calculateRegionOffset(regionSection->EcBase);
|
ecBegin = calculateRegionOffset(regionSection->EcBase);
|
||||||
ecEnd = ecBegin + calculateRegionSize(regionSection->EcBase, regionSection->EcLimit);
|
ecEnd = ecBegin + calculateRegionSize(regionSection->EcBase, regionSection->EcLimit);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user