[TGL] Invalidate bad DSO region
This patch invalidates the DSO region with a marker after a DSO hang (caused by corrupted DSO) is detected (by WDT timeout). With the marker, stage1b can know the DSO tuning should be skipped. The bad DSO mark is defined as both Signature and Size in the TCCT component header are zero. With this patch, the previous defined WDT scratchpad bit, WDT_FLAG_TCC_BAD_DSO, is removed. TEST=Verified on TGL-U RVP Signed-off-by: Stanley Chang <stanley.chang@intel.com>
This commit is contained in:
parent
c533416ef8
commit
d66202f25d
|
@ -754,13 +754,17 @@ UpdateContainerComp (
|
|||
//
|
||||
ComponentBase = ContainerEntryPtr->Base + ContainerHdr->DataOffset + ComponentEntryPtr->Offset;
|
||||
|
||||
// Check Svn for container component
|
||||
// Current implementation only supports compressed header.
|
||||
// Exception: empty Signature and Size, which is a mark for previously detected bad region, e.g., TCCT
|
||||
FlashCompLzHeader = (LOADER_COMPRESSED_HEADER *) (UINTN) ComponentBase;
|
||||
CapCompLzHeader = (LOADER_COMPRESSED_HEADER *) ((UINTN)ImageHdr + sizeof(EFI_FW_MGMT_CAP_IMAGE_HEADER));
|
||||
if ((IS_COMPRESSED (FlashCompLzHeader) == FALSE) || (IS_COMPRESSED (CapCompLzHeader) == FALSE)) {
|
||||
if (((IS_COMPRESSED (FlashCompLzHeader) == FALSE) &&
|
||||
((FlashCompLzHeader->Signature != 0) || (FlashCompLzHeader->Size != 0))) ||
|
||||
(IS_COMPRESSED (CapCompLzHeader) == FALSE)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// Check Svn for container component
|
||||
if (CapCompLzHeader->Svn < FlashCompLzHeader->Svn) {
|
||||
DEBUG((DEBUG_INFO, "Container Component svn did not met!"));
|
||||
return EFI_UNSUPPORTED;
|
||||
|
|
|
@ -58,6 +58,117 @@ GetBoardId (
|
|||
OUT UINT8 *BoardId
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Check if the BAD DSO mark exists or not
|
||||
BAD DSO mark is defined as
|
||||
LOADER_COMPRESSED_HEADER of the component in flash
|
||||
Its Signature' and 'Size' fields are 0 (zero).
|
||||
Other fields are subject to change
|
||||
|
||||
@retval TRUE DSO was marked as BAD DSO
|
||||
@retval FALSE No BAD DSO mark found
|
||||
|
||||
*/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
IsMarkedBadDso (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 Length;
|
||||
LOADER_COMPRESSED_HEADER *Hdr;
|
||||
LOADER_COMPRESSED_HEADER BadDsoMark = {0};
|
||||
|
||||
DEBUG ((DEBUG_INFO, "Check BAD DSO mark\n"));
|
||||
|
||||
Status = LocateComponent (SIGNATURE_32 ('I', 'P', 'F', 'W'),
|
||||
SIGNATURE_32 ('T', 'C', 'C', 'T'),
|
||||
(VOID *)&Hdr, &Length);
|
||||
if (EFI_ERROR (Status) || (Length < sizeof(LOADER_COMPRESSED_HEADER))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((Hdr->Signature == BadDsoMark.Signature) && (Hdr->Size == BadDsoMark.Size)) {
|
||||
DEBUG ((DEBUG_INFO, "BAD DSO(TCCT) detected!\n"));
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Invalidate BAD DSO
|
||||
|
||||
@retval EFI_SUCCESS
|
||||
@retval EFI_NOT_FOUND Unable to find IPFW/TCCT
|
||||
@retval EFI_OUT_OF_RESOURCES Bios region is too small
|
||||
@retval Others Errors during SPI operations
|
||||
|
||||
*/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InvalidateBadDso (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 Address;
|
||||
UINT32 Length;
|
||||
UINT32 BaseAddress;
|
||||
UINT32 RegionSize;
|
||||
CONTAINER_ENTRY *ContainerEntry;
|
||||
COMPONENT_ENTRY *CompEntry;
|
||||
CONTAINER_HDR *ContainerHdr;
|
||||
// BAD DSO mark: The 'Signature' and 'Size' fields are zero(0)
|
||||
// Other fields are subject to change
|
||||
LOADER_COMPRESSED_HEADER BadDsoMark = {0};
|
||||
|
||||
DEBUG ((DEBUG_INFO, "Invalidate BAD DSO region\n"));
|
||||
|
||||
Status = LocateComponentEntry (SIGNATURE_32 ('I', 'P', 'F', 'W'),
|
||||
SIGNATURE_32 ('T', 'C', 'C', 'T'),
|
||||
&ContainerEntry, &CompEntry);
|
||||
if (EFI_ERROR (Status) || (ContainerEntry == NULL) || (CompEntry == NULL)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* a region should have 4KB as min erase size */
|
||||
Length = SIZE_4KB;
|
||||
if (CompEntry->Size < Length) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
ContainerHdr = (CONTAINER_HDR *)(UINTN)ContainerEntry->HeaderCache;
|
||||
Address = ContainerEntry->Base + ContainerHdr->DataOffset + CompEntry->Offset;
|
||||
|
||||
/* Svn is kept for anti-rollback control */
|
||||
BadDsoMark.Svn = ((LOADER_COMPRESSED_HEADER *)(UINTN)Address)->Svn;
|
||||
|
||||
Status = SpiGetRegionAddress (FlashRegionBios, &BaseAddress, &RegionSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
BaseAddress = ((UINT32)(~RegionSize) + 1);
|
||||
|
||||
Address -= BaseAddress;
|
||||
if ((Address + Length) > RegionSize) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = SpiFlashErase (FlashRegionBios, Address, Length);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
Status = SpiFlashWrite (FlashRegionBios, Address, sizeof(BadDsoMark), (VOID *)&BadDsoMark);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
DEBUG ((DEBUG_INFO, "Mark BAD DSO(TCCT) successfully\n"));
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Update FSP-M UPD config data for TCC mode and tuning
|
||||
|
||||
|
@ -108,12 +219,14 @@ TccModePreMemConfig (
|
|||
DEBUG ((DEBUG_INFO, "S0ix is turned off when TCC is enabled\n"));
|
||||
}
|
||||
|
||||
if (IsWdtFlagsSet(WDT_FLAG_TCC_BAD_DSO) ||
|
||||
(IsWdtFlagsSet(WDT_FLAG_TCC_DSO_IN_PROGRESS) && IsWdtTimeout())) {
|
||||
if (IsMarkedBadDso ()) {
|
||||
DEBUG ((DEBUG_ERROR, "Incorrect TCC tuning parameters. Platform rebooted with default values.\n"));
|
||||
FspmUpd->FspmConfig.TccStreamCfgStatusPreMem = 1;
|
||||
} else if (IsWdtFlagsSet(WDT_FLAG_TCC_DSO_IN_PROGRESS) && IsWdtTimeout()) {
|
||||
DEBUG ((DEBUG_ERROR, "Incorrect TCC tuning parameters. Platform rebooted with default values.\n"));
|
||||
WdtClearScratchpad (WDT_FLAG_TCC_DSO_IN_PROGRESS);
|
||||
WdtSetScratchpad (WDT_FLAG_TCC_BAD_DSO);
|
||||
FspmUpd->FspmConfig.TccStreamCfgStatusPreMem = 1;
|
||||
InvalidateBadDso ();
|
||||
} else if (TccCfgData->TccTuning != 0) {
|
||||
// Setup Watch dog timer
|
||||
WdtReloadAndStart (WDT_TIMEOUT_TCC_DSO, WDT_FLAG_TCC_DSO_IN_PROGRESS);
|
||||
|
|
|
@ -1024,9 +1024,6 @@ BoardInit (
|
|||
case ReadyToBoot:
|
||||
if ((GetBootMode() != BOOT_ON_FLASH_UPDATE) && (GetPayloadId() == 0)) {
|
||||
ProgramSecuritySetting ();
|
||||
} else if (GetBootMode() == BOOT_ON_FLASH_UPDATE) {
|
||||
/* clear bad DSO mark (if have), so next boot is a fresh restart */
|
||||
WdtClearScratchpad (WDT_FLAG_TCC_BAD_DSO);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -3026,3 +3023,4 @@ PlatformUpdateAcpiGnvs (
|
|||
PlatformNvs->Rtd3Support = mTccRtd3Support;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#define WDT_TIMEOUT_TCC_DSO 200 // 200 seconds
|
||||
#define WDT_FLAG_TCC_DSO_IN_PROGRESS BIT17
|
||||
#define WDT_FLAG_TCC_BAD_DSO BIT18
|
||||
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue