Date   

[PATCH v1 0/2] Fix VS2017 build errors

PierreGondois
 

Building edk2\EmbeddedPkg\EmbeddedPkg.dsc with
VS2017 triggered some errors. This patch set is
intended to fix them.

The changes can be seen at: https://github.com/PierreARM/edk2/commits/831_Fix_VS2017_build_error_v1

Pierre Gondois (2):
EmbeddedPkg: Fix build error for MmcDxe
EmbeddedPkg: Add cast from (void*) for VS2017 build

EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c | 13 ++++++++-----
EmbeddedPkg/Universal/MmcDxe/Diagnostics.c | 10 +++++++---
EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c | 6 +++---
3 files changed, 18 insertions(+), 11 deletions(-)

--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


Re: [PATCH] FmpDevicePkg: Enhance capsule verification with secure boot keys

Guomin Jiang
 

Liming,

The end user have the ability to enroll their DB without too many effort.

And I think some end user also have the ability to get insecure firmware which not from the device vendor.

I suggest that tell the device vendor that it is critical that set the PcdFmpDevicePkcs7CertBufferXdr rather than decrease the security.

Best Regards
Guomin

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Liming
Sun
Sent: Tuesday, June 30, 2020 11:33 AM
To: Jiang, Guomin <guomin.jiang@intel.com>; devel@edk2.groups.io; Xu,
Wei6 <wei6.xu@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney,
Michael D <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Subject: Re: [edk2-devel] [PATCH] FmpDevicePkg: Enhance capsule
verification with secure boot keys

Thanks Guomin for the comments!

Below is the main scenario for the proposed change:

- Device Manufacturer provides the devices with UEFI preinstalled in non-
secure state and no hard-coded keys ( PcdFmpDevicePkcs7CertBufferXdr).

- Customer (not End-User) enrolls their own keys in trusted environment
before delivering to End User.
This capsule approach can be used for large deployment without involving any
private keys.

Yes, I do agree that once it's delivered to End User it won't be considered
secure.

Thanks,
Liming

-----Original Message-----
From: Jiang, Guomin <guomin.jiang@intel.com>
Sent: Sunday, June 28, 2020 11:18 PM
To: devel@edk2.groups.io; Liming Sun <lsun@mellanox.com>; Xu, Wei6
<wei6.xu@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney,
Michael D <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Subject: RE: [edk2-devel] [PATCH] FmpDevicePkg: Enhance capsule
verification with secure boot keys

I think it have some vulnerability, the case as below.

1. Untrusted End User enroll the new DB key -> sign the untrusted
device firmware -> flash the untrusted device firmware -> the system will
become unsafe.

I think the end user is untrusted and we need to make sure only few person
can have the privilege.

Best Regards
Guomin

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
Liming Sun
Sent: Saturday, June 20, 2020 1:48 AM
To: Xu, Wei6 <wei6.xu@intel.com>; Gao, Liming
<liming.gao@intel.com>; Kinney, Michael D
<michael.d.kinney@intel.com>
Cc: Liming Sun <lsun@mellanox.com>; devel@edk2.groups.io; Sean
Brogan <sean.brogan@microsoft.com>
Subject: [edk2-devel] [PATCH] FmpDevicePkg: Enhance capsule
verification with secure boot keys

This commit enhances the FmpDevicePkg package to optionally verify
capsule with the secure boot keys when
PcdFmpDevicePkcs7CertBufferXdr is not set and the new PCD variable
PcdFmpDeviceAllowSecureBootKeys is configured. Below is the check
logic:
- Pass if verified with PK key, or PK key not set yet;
- Deny if verified with the DBX keys;
- Verified it against the DB keys;

One purpose for this change is to auto-deploy the UEFI secure boot
keys with UEFI capsule. Initially it's done in trusted environment.
Once secure boot is enabled, the same keys will be used to verify
the signed capsules as well for further updates.

Signed-off-by: Liming Sun <lsun@mellanox.com>
---
FmpDevicePkg/FmpDevicePkg.dec | 6 +++
FmpDevicePkg/FmpDxe/FmpDxe.c | 109
++++++++++++++++++++++++++++++++++++--
FmpDevicePkg/FmpDxe/FmpDxe.h | 1 +
FmpDevicePkg/FmpDxe/FmpDxe.inf | 3 ++
FmpDevicePkg/FmpDxe/FmpDxeLib.inf | 1 +
5 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/FmpDevicePkg/FmpDevicePkg.dec
b/FmpDevicePkg/FmpDevicePkg.dec index cab63f5..3aeb89c 100644
--- a/FmpDevicePkg/FmpDevicePkg.dec
+++ b/FmpDevicePkg/FmpDevicePkg.dec
@@ -126,6 +126,12 @@
# @Prompt Firmware Device Image Type ID

gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid|{0}|VOID
*|0x40000010

+ ## This option is used to verify the capsule using secure boot
+ keys if the # PcdFmpDevicePkcs7CertBufferXdr is not configured.
+ In such case, the check # will pass if secure boot hasn't been enabled
yet.
+ # @A flag to tell whether to use secure boot keys when
PcdFmpDevicePkcs7CertBufferXdr is not set.
+
+
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceAllowSecureBootKeys|0x0|
UINT8|
+ 0x40000012
+
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic,
PcdsDynamicEx]
## One or more PKCS7 certificates used to verify a firmware device
capsule
# update image. Encoded using the Variable-Length Opaque Data
format of RFC diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c
b/FmpDevicePkg/FmpDxe/FmpDxe.c index 5884177..6f82aee 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.c
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.c
@@ -682,6 +682,102 @@ GetAllHeaderSize (
return CalculatedSize;
}

+EFI_STATUS
+CheckTheImageWithSecureBootVariable (
+ IN CONST CHAR16 *Name,
+ IN CONST EFI_GUID *Guid,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ UINTN Length;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *CertData;
+ UINTN CertCount;
+ UINTN Index;
+
+ Status = GetVariable2 (Name, Guid, &Data, &Length); if
+ (EFI_ERROR
+ (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ CertList = (EFI_SIGNATURE_LIST *) Data; while ((Length > 0) &&
+ (Length >= CertList->SignatureListSize)) {
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
+ CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList +
+ sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST)
-
+ CertList->SignatureHeaderSize) / CertList->SignatureSize;
+
+ for (Index = 0; Index < CertCount; Index++) {
+ Status = AuthenticateFmpImage (
+ (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image,
+ ImageSize,
+ CertData->SignatureData,
+ CertList->SignatureSize - sizeof (EFI_GUID)
+ );
+ if (!EFI_ERROR (Status))
+ goto Done;
+
+ CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertData +
+ CertList-
SignatureSize);
+ }
+ }
+
+ Length -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+ CertList->SignatureListSize); }
+
+Done:
+ FreePool (Data);
+ return Status;
+}
+
+EFI_STATUS
+CheckTheImageWithSecureBootKeys (
+ IN CONST VOID *Image,
+ IN UINTN ImageSize
+ )
+{
+ EFI_STATUS Status;
+
+ // PK check.
+ Status = CheckTheImageWithSecureBootVariable(
+ EFI_PLATFORM_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ Image,
+ ImageSize
+ );
+ if (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND) {
+ // Return SUCCESS if verified by PK key or PK key not configured.
+ DEBUG ((DEBUG_INFO, "FmpDxe: Verified capsule with PK key.\n"));
+ return EFI_SUCCESS;
+ }
+
+ // DBX check.
+ Status = CheckTheImageWithSecureBootVariable(
+ EFI_IMAGE_SECURITY_DATABASE1,
+ &gEfiImageSecurityDatabaseGuid,
+ Image,
+ ImageSize
+ );
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "FmpDxe: Reject capsule with DBX key.\n"));
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ // DB check.
+ DEBUG ((DEBUG_INFO, "FmpDxe: Verify capsule with DB key.\n"));
+ Status = CheckTheImageWithSecureBootVariable(
+ EFI_IMAGE_SECURITY_DATABASE,
+ &gEfiImageSecurityDatabaseGuid,
+ Image,
+ ImageSize
+ );
+ return Status;
+}
+
/**
Checks if the firmware image is valid for the device.

@@ -728,6 +824,7 @@ CheckTheImage (
UINT8 *PublicKeyDataXdrEnd;
EFI_FIRMWARE_IMAGE_DEP *Dependencies;
UINT32 DependenciesSize;
+ UINT8 AllowSecureBootKeys;

Status = EFI_SUCCESS;
RawSize = 0;
@@ -782,9 +879,15 @@ CheckTheImage (
PublicKeyDataXdr = PcdGetPtr (PcdFmpDevicePkcs7CertBufferXdr);
PublicKeyDataXdrEnd = PublicKeyDataXdr + PcdGetSize
(PcdFmpDevicePkcs7CertBufferXdr);

- if (PublicKeyDataXdr == NULL || (PublicKeyDataXdr ==
PublicKeyDataXdrEnd)) {
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Invalid certificate, skipping it.\n",
mImageIdName));
- Status = EFI_ABORTED;
+ if (PublicKeyDataXdr == NULL || (PublicKeyDataXdrEnd -
+ PublicKeyDataXdr
< sizeof (UINT32))) {
+ AllowSecureBootKeys = PcdGet8
(PcdFmpDeviceAllowSecureBootKeys);
+ if (AllowSecureBootKeys) {
+ DEBUG ((DEBUG_INFO, "FmpDxe: Use secure boot certs.\n"));
+ Status = CheckTheImageWithSecureBootKeys (Image, ImageSize);
+ } else {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Invalid certificate,
+ skipping
it.\n", mImageIdName));
+ Status = EFI_ABORTED;
+ }
} else {
//
// Try each key from PcdFmpDevicePkcs7CertBufferXdr diff --git
a/FmpDevicePkg/FmpDxe/FmpDxe.h b/FmpDevicePkg/FmpDxe/FmpDxe.h
index
30754de..72a6ce6 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.h
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.h
@@ -34,6 +34,7 @@
#include <Protocol/FirmwareManagement.h> #include
<Protocol/FirmwareManagementProgress.h>
#include <Protocol/VariableLock.h>
+#include <Guid/ImageAuthentication.h>
#include <Guid/SystemResourceTable.h> #include <Guid/EventGroup.h>

diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.inf
b/FmpDevicePkg/FmpDxe/FmpDxe.inf index eeb904a..60b02d4 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.inf
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf
@@ -58,6 +58,8 @@

[Guids]
gEfiEndOfDxeEventGroupGuid
+ gEfiCertX509Guid
+ gEfiImageSecurityDatabaseGuid

[Protocols]
gEdkiiVariableLockProtocolGuid ## CONSUMES
@@ -74,6 +76,7 @@
gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr
## CONSUMES
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest
## CONSUMES
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid
## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceAllowSecureBootKeys
## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ##
SOMETIMES_PRODUCES

[Depex]
diff --git a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
index 9a93b5e..1308cae 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
+++ b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
@@ -74,6 +74,7 @@
gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr
## CONSUMES
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest
## CONSUMES
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid
## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceAllowSecureBootKeys
## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ##
SOMETIMES_PRODUCES

[Depex]
--
1.8.3.1




[PATCH 6/6] SecurityPkg/Tcg2Pei: Use Migrated FV Info Hob for calculating hash (CVE-2019-11098)

Guomin Jiang
 

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614

When we allocate pool to save rebased the PEIMs, the address will change
randomly, therefore the hash will change and result PCR0 change as well.
To avoid this, we save the raw PEIMs and use it to calculate hash.
The Tcg2Pei calculate the hash and it use the Migrated FV Info.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Qi Zhang <qi1.zhang@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
---
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c | 31 ++++++++++++++++++++++++++---
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf | 1 +
2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
index 4852d8690617..651a60c1f0e2 100644
--- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
+++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
@@ -21,6 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/TcgEventHob.h>
#include <Guid/MeasuredFvHob.h>
#include <Guid/TpmInstance.h>
+#include <Guid/MigratedFvInfo.h>

#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
@@ -536,6 +537,10 @@ MeasureFvImage (
EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI *PrehashedFvPpi;
HASH_INFO *PreHashInfo;
UINT32 HashAlgoMask;
+ EFI_PHYSICAL_ADDRESS FvOrgBase;
+ EFI_PHYSICAL_ADDRESS FvDataBase;
+ EFI_PEI_HOB_POINTERS Hob;
+ EDKII_MIGRATED_FV_INFO *MigratedFvInfo;

//
// Check Excluded FV list
@@ -621,6 +626,26 @@ MeasureFvImage (
Instance++;
} while (!EFI_ERROR(Status));

+ //
+ // Search the matched migration FV info
+ //
+ FvOrgBase = FvBase;
+ FvDataBase = FvBase;
+ Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
+ while (Hob.Raw != NULL) {
+ MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
+ if ((MigratedFvInfo->FvNewBase == (UINT32) FvBase) && (MigratedFvInfo->FvLength == (UINT32) FvLength)) {
+ //
+ // Found the migrated FV info
+ //
+ FvOrgBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvOrgBase;
+ FvDataBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvDataBase;
+ break;
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
+ }
+
//
// Init the log event for FV measurement
//
@@ -631,13 +656,13 @@ MeasureFvImage (
if (FvName != NULL) {
AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);
}
- FvBlob2.BlobBase = FvBase;
+ FvBlob2.BlobBase = FvOrgBase;
FvBlob2.BlobLength = FvLength;
TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;
TcgEventHdr.EventSize = sizeof (FvBlob2);
EventData = &FvBlob2;
} else {
- FvBlob.BlobBase = FvBase;
+ FvBlob.BlobBase = FvOrgBase;
FvBlob.BlobLength = FvLength;
TcgEventHdr.PCRIndex = 0;
TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
@@ -672,7 +697,7 @@ MeasureFvImage (
//
Status = HashLogExtendEvent (
0,
- (UINT8*) (UINTN) FvBase, // HashData
+ (UINT8*) (UINTN) FvDataBase, // HashData
(UINTN) FvLength, // HashDataLen
&TcgEventHdr, // EventHdr
EventData // EventData
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
index 3d361e8859e7..367df21eedaf 100644
--- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
+++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
@@ -63,6 +63,7 @@ [Guids]
gTcgEvent2EntryHobGuid ## PRODUCES ## HOB
gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_PRODUCES ## GUID # TPM device identifier
gEfiTpmDeviceInstanceTpm12Guid ## SOMETIMES_PRODUCES ## GUID # TPM device identifier
+ gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB

[Ppis]
gEfiPeiFirmwareVolumeInfoPpiGuid ## SOMETIMES_CONSUMES ## NOTIFY
--
2.25.1.windows.1


[PATCH 5/6] MdeModulePkg/Core: Create Migrated FV Info Hob for calculating hash (CVE-2019-11098)

Guomin Jiang
 

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614

When we allocate pool to save rebased the PEIMs, the address will change
randomly, therefore the hash will change and result PCR0 change as well.
To avoid this, we save the raw PEIMs and use it to calculate hash.

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Harry Han <harry.han@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Signed-off-by: Guomin Jiang <guomin.jiang@intel.com>
---
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 15 +++++++++++++
MdeModulePkg/Core/Pei/PeiMain.h | 1 +
MdeModulePkg/Core/Pei/PeiMain.inf | 1 +
MdeModulePkg/Include/Guid/MigratedFvInfo.h | 22 +++++++++++++++++++
MdeModulePkg/MdeModulePkg.dec | 3 +++
5 files changed, 42 insertions(+)
create mode 100644 MdeModulePkg/Include/Guid/MigratedFvInfo.h

diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index ef88b3423376..7e1ac38f35c8 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -1223,10 +1223,12 @@ EvacuateTempRam (
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
EFI_FIRMWARE_VOLUME_HEADER *ChildFvHeader;
EFI_FIRMWARE_VOLUME_HEADER *MigratedFvHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *RawDataFvHeader;
EFI_FIRMWARE_VOLUME_HEADER *MigratedChildFvHeader;

PEI_CORE_FV_HANDLE PeiCoreFvHandle;
EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi;
+ EDKII_MIGRATED_FV_INFO MigratedFvInfo;

ASSERT (Private->PeiMemoryInstalled);

@@ -1270,6 +1272,13 @@ EvacuateTempRam (
);
ASSERT_EFI_ERROR (Status);

+ Status = PeiServicesAllocatePages (
+ EfiBootServicesCode,
+ EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength),
+ (EFI_PHYSICAL_ADDRESS *) &RawDataFvHeader
+ );
+ ASSERT_EFI_ERROR (Status);
+
DEBUG ((
DEBUG_VERBOSE,
" Migrating FV[%d] from 0x%08X to 0x%08X\n",
@@ -1279,6 +1288,12 @@ EvacuateTempRam (
));

CopyMem (MigratedFvHeader, FvHeader, (UINTN) FvHeader->FvLength);
+ CopyMem (RawDataFvHeader, MigratedFvHeader, (UINTN) FvHeader->FvLength);
+ MigratedFvInfo.FvOrgBase = (UINT32) (UINTN) FvHeader;
+ MigratedFvInfo.FvNewBase = (UINT32) (UINTN) MigratedFvHeader;
+ MigratedFvInfo.FvDataBase = (UINT32) (UINTN) RawDataFvHeader;
+ MigratedFvInfo.FvLength = (UINT32) (UINTN) FvHeader->FvLength;
+ BuildGuidDataHob (&gEdkiiMigratedFvInfoGuid, &MigratedFvInfo, sizeof (MigratedFvInfo));

//
// Migrate any children for this FV now
diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h
index b0101dba5e30..cbf74d5b9d9a 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.h
+++ b/MdeModulePkg/Core/Pei/PeiMain.h
@@ -44,6 +44,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/FirmwareFileSystem2.h>
#include <Guid/FirmwareFileSystem3.h>
#include <Guid/AprioriFileName.h>
+#include <Guid/MigratedFvInfo.h>

///
/// It is an FFS type extension used for PeiFindFileEx. It indicates current
diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
index 5ff14100a65f..c80d16b4efa6 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.inf
+++ b/MdeModulePkg/Core/Pei/PeiMain.inf
@@ -77,6 +77,7 @@ [Guids]
## CONSUMES ## GUID # Used to compare with FV's file system GUID and get the FV's file system format
gEfiFirmwareFileSystem3Guid
gStatusCodeCallbackGuid
+ gEdkiiMigratedFvInfoGuid ## SOMETIMES_PRODUCES ## HOB

[Ppis]
gEfiPeiStatusCodePpiGuid ## SOMETIMES_CONSUMES # PeiReportStatusService is not ready if this PPI doesn't exist
diff --git a/MdeModulePkg/Include/Guid/MigratedFvInfo.h b/MdeModulePkg/Include/Guid/MigratedFvInfo.h
new file mode 100644
index 000000000000..061c17ed0e48
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/MigratedFvInfo.h
@@ -0,0 +1,22 @@
+/** @file
+ Migrated FV information
+
+Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EDKII_MIGRATED_FV_INFO_GUID_H__
+#define __EDKII_MIGRATED_FV_INFO_GUID_H__
+
+typedef struct {
+ UINT32 FvOrgBase; // original FV address
+ UINT32 FvNewBase; // new FV address
+ UINT32 FvDataBase; // original FV data
+ UINT32 FvLength; // Fv Length
+} EDKII_MIGRATED_FV_INFO;
+
+extern EFI_GUID gEdkiiMigratedFvInfoGuid;
+
+#endif // #ifndef __EDKII_MIGRATED_FV_INFO_GUID_H__
+
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 843e963ad34b..5e25cbe98ada 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -389,6 +389,9 @@ [Guids]
## GUID indicates the capsule is to store Capsule On Disk file names.
gEdkiiCapsuleOnDiskNameGuid = { 0x98c80a4f, 0xe16b, 0x4d11, { 0x93, 0x9a, 0xab, 0xe5, 0x61, 0x26, 0x3, 0x30 } }

+ ## Include/Guid/MigratedFvInfo.h
+ gEdkiiMigratedFvInfoGuid = { 0xc1ab12f7, 0x74aa, 0x408d, { 0xa2, 0xf4, 0xc6, 0xce, 0xfd, 0x17, 0x98, 0x71 } }
+
[Ppis]
## Include/Ppi/AtaController.h
gPeiAtaControllerPpiGuid = { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a, 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d }}
--
2.25.1.windows.1


[PATCH 4/6] MdeModulePkg/DxeIplPeim: Register for shadow on S3 shadowed boot (CVE-2019-11098)

Guomin Jiang
 

From: Jian J Wang <jian.j.wang@intel.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 3 +++
MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index 3f1702854660..4ab54594ed66 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -121,6 +121,9 @@ [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES

+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot ## CONSUMES
+
[Depex]
gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid

diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
index d48028cea0dd..9e1831c69819 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
@@ -77,7 +77,7 @@ PeimInitializeDxeIpl (

BootMode = GetBootModeHob ();

- if (BootMode != BOOT_ON_S3_RESUME) {
+ if (BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot)) {
Status = PeiServicesRegisterForShadow (FileHandle);
if (Status == EFI_SUCCESS) {
//
--
2.25.1.windows.1


[PATCH 3/6] UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098)

Guomin Jiang
 

From: Michael Kubacki <michael.a.kubacki@intel.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614

Adds a PEIM that republishes structures produced in SEC. This
is done because SEC modules may not be shadowed in some platforms
due to space constraints or special alignment requirements. The
SecMigrationPei module locates interfaces that may be published in
SEC and reinstalls the interface with permanent memory addresses.

This is important if pre-memory address access is forbidden after
memory initialization and data such as a PPI descriptor, PPI GUID,
or PPI inteface reside in pre-memory.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Harry Han <harry.han@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
UefiCpuPkg/Include/Ppi/RepublishSecPpi.h | 54 +++
UefiCpuPkg/SecCore/SecCore.inf | 2 +
UefiCpuPkg/SecCore/SecMain.c | 26 +-
UefiCpuPkg/SecCore/SecMain.h | 1 +
UefiCpuPkg/SecMigrationPei/SecMigrationPei.c | 372 ++++++++++++++++++
UefiCpuPkg/SecMigrationPei/SecMigrationPei.h | 170 ++++++++
.../SecMigrationPei/SecMigrationPei.inf | 64 +++
.../SecMigrationPei/SecMigrationPei.uni | 13 +
UefiCpuPkg/UefiCpuPkg.dec | 4 +
UefiCpuPkg/UefiCpuPkg.dsc | 1 +
10 files changed, 705 insertions(+), 2 deletions(-)
create mode 100644 UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni

diff --git a/UefiCpuPkg/Include/Ppi/RepublishSecPpi.h b/UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
new file mode 100644
index 000000000000..6fb9f1b005b4
--- /dev/null
+++ b/UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
@@ -0,0 +1,54 @@
+/** @file
+ This file declares Sec Platform Information PPI.
+
+ This service is the primary handoff state into the PEI Foundation.
+ The Security (SEC) component creates the early, transitory memory
+ environment and also encapsulates knowledge of at least the
+ location of the Boot Firmware Volume (BFV).
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ This PPI is introduced in PI Version 1.0.
+
+**/
+
+#ifndef __REPUBLISH_SEC_PPI_H__
+#define __REPUBLISH_SEC_PPI_H__
+
+#include <Pi/PiPeiCis.h>
+
+#define REPUBLISH_SEC_PPI_PPI_GUID \
+ { \
+ 0x27a71b1e, 0x73ee, 0x43d6, { 0xac, 0xe3, 0x52, 0x1a, 0x2d, 0xc5, 0xd0, 0x92 } \
+ }
+
+typedef struct _REPUBLISH_SEC_PPI_PPI REPUBLISH_SEC_PPI_PPI;
+
+/**
+ This interface re-installs PPIs installed in SecCore from a post-memory PEIM.
+
+ This is to allow a platform that may not support relocation of SecCore to update the PPI instance to a post-memory
+ copy from a PEIM that has been shadowed to permanent memory.
+
+ @retval EFI_SUCCESS The SecCore PPIs were re-installed successfully.
+ @retval Others An error occurred re-installing the SecCore PPIs.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REPUBLISH_SEC_PPI_REPUBLISH_SEC_PPIS)(
+ VOID
+ );
+
+///
+///
+///
+struct _REPUBLISH_SEC_PPI_PPI {
+ REPUBLISH_SEC_PPI_REPUBLISH_SEC_PPIS RepublishSecPpis;
+};
+
+extern EFI_GUID gRepublishSecPpiPpiGuid;
+
+#endif
diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf
index 0562820c95e0..545781d6b4b3 100644
--- a/UefiCpuPkg/SecCore/SecCore.inf
+++ b/UefiCpuPkg/SecCore/SecCore.inf
@@ -68,6 +68,8 @@ [Ppis]
## SOMETIMES_CONSUMES
gPeiSecPerformancePpiGuid
gEfiPeiCoreFvLocationPpiGuid
+ ## CONSUMES
+ gRepublishSecPpiPpiGuid

[Guids]
## SOMETIMES_PRODUCES ## HOB
diff --git a/UefiCpuPkg/SecCore/SecMain.c b/UefiCpuPkg/SecCore/SecMain.c
index 5d5e7f17dced..155be49a6011 100644
--- a/UefiCpuPkg/SecCore/SecMain.c
+++ b/UefiCpuPkg/SecCore/SecMain.c
@@ -370,13 +370,35 @@ SecTemporaryRamDone (
VOID
)
{
- BOOLEAN State;
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+ UINTN Index;
+ BOOLEAN State;
+ EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
+ REPUBLISH_SEC_PPI_PPI *RepublishSecPpiPpi;

//
// Republish Sec Platform Information(2) PPI
//
RepublishSecPlatformInformationPpi ();

+ //
+ // Re-install SEC PPIs using a PEIM produced service if published
+ //
+ for (Index = 0, Status = EFI_SUCCESS; Status == EFI_SUCCESS; Index++) {
+ Status = PeiServicesLocatePpi (
+ &gRepublishSecPpiPpiGuid,
+ Index,
+ &PeiPpiDescriptor,
+ (VOID **) &RepublishSecPpiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Calling RepublishSecPpi instance %d.\n", Index));
+ Status2 = RepublishSecPpiPpi->RepublishSecPpis ();
+ ASSERT_EFI_ERROR (Status2);
+ }
+ }
+
//
// Migrate DebugAgentContext.
//
@@ -385,7 +407,7 @@ SecTemporaryRamDone (
//
// Disable interrupts and save current interrupt state
//
- State = SaveAndDisableInterrupts();
+ State = SaveAndDisableInterrupts ();

//
// Disable Temporary RAM after Stack and Heap have been migrated at this point.
diff --git a/UefiCpuPkg/SecCore/SecMain.h b/UefiCpuPkg/SecCore/SecMain.h
index e8c05d713668..e20bcf86532c 100644
--- a/UefiCpuPkg/SecCore/SecMain.h
+++ b/UefiCpuPkg/SecCore/SecMain.h
@@ -15,6 +15,7 @@
#include <Ppi/TemporaryRamDone.h>
#include <Ppi/SecPerformance.h>
#include <Ppi/PeiCoreFvLocation.h>
+#include <Ppi/RepublishSecPpi.h>

#include <Guid/FirmwarePerformance.h>

diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.c b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
new file mode 100644
index 000000000000..f96013b09b21
--- /dev/null
+++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
@@ -0,0 +1,372 @@
+/** @file
+ Migrates SEC structures after permanent memory is installed.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+
+#include "SecMigrationPei.h"
+
+STATIC REPUBLISH_SEC_PPI_PPI mEdkiiRepublishSecPpiPpi = {
+ RepublishSecPpis
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPostMemoryPpi = {
+ SecPlatformInformationPostMemory
+ };
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_TEMPORARY_RAM_DONE_PPI mSecTemporaryRamDonePostMemoryPpi = {
+ SecTemporaryRamDonePostMemory
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPostMemoryPpi = {
+ SecTemporaryRamSupportPostMemory
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED PEI_SEC_PERFORMANCE_PPI mSecPerformancePpi = {
+ GetPerformancePostMemory
+ };
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mEdkiiRepublishSecPpiDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gRepublishSecPpiPpiGuid,
+ &mEdkiiRepublishSecPpiPpi
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mSecPlatformInformationPostMemoryDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiSecPlatformInformationPpiGuid,
+ &mSecPlatformInformationPostMemoryPpi
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mSecTemporaryRamDonePostMemoryDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamDonePpiGuid,
+ &mSecTemporaryRamDonePostMemoryPpi
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mSecTemporaryRamSupportPostMemoryDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamSupportPpiGuid,
+ &mSecTemporaryRamSupportPostMemoryPpi
+ };
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mSecPerformancePpiDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiSecPerformancePpiGuid,
+ &mSecPerformancePpi
+ };
+
+/**
+ Disables the use of Temporary RAM.
+
+ If present, this service is invoked by the PEI Foundation after
+ the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamDonePostMemory (
+ VOID
+ )
+{
+ //
+ // Temporary RAM Done is already done in post-memory
+ // install a stub function that is located in permanent memory
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+ This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupportPostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ //
+ // Temporary RAM Support is already done in post-memory
+ // install a stub function that is located in permanent memory
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+ This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+ This service is published by the SEC phase. The SEC phase handoff has an optional
+ EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+ PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+ this information is encapsulated into the data structure abstracted by this service.
+ This information is collected for the boot-strap processor (BSP) on IA-32.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+ @param[out] Performance The pointer to performance data collected in SEC phase.
+
+ @retval EFI_SUCCESS The performance data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPerformancePostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SEC_PERFORMANCE_PPI *This,
+ OUT FIRMWARE_SEC_PERFORMANCE *Performance
+ )
+{
+ SEC_PLATFORM_INFORMATION_CONTEXT_HOB *SecPlatformInformationContexHob;
+
+ if (This == NULL || Performance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SecPlatformInformationContexHob = GetFirstGuidHob (&gEfiCallerIdGuid);
+ if (SecPlatformInformationContexHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Performance->ResetEnd = SecPlatformInformationContexHob->FirmwareSecPerformance.ResetEnd;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This interface conveys state information out of the Security (SEC) phase into PEI.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in,out] StructureSize Pointer to the variable describing size of the input buffer.
+ @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformationPostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ )
+{
+ SEC_PLATFORM_INFORMATION_CONTEXT_HOB *SecPlatformInformationContexHob;
+
+ if (StructureSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SecPlatformInformationContexHob = GetFirstGuidHob (&gEfiCallerIdGuid);
+ if (SecPlatformInformationContexHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (*StructureSize < SecPlatformInformationContexHob->Context.StructureSize) {
+ *StructureSize = SecPlatformInformationContexHob->Context.StructureSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (PlatformInformationRecord == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *StructureSize = SecPlatformInformationContexHob->Context.StructureSize;
+ CopyMem (
+ (VOID *) PlatformInformationRecord,
+ (VOID *) SecPlatformInformationContexHob->Context.PlatformInformationRecord,
+ (UINTN) SecPlatformInformationContexHob->Context.StructureSize
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This interface re-installs PPIs installed in SecCore from a post-memory PEIM.
+
+ This is to allow a platform that may not support relocation of SecCore to update the PPI instance to a post-memory
+ copy from a PEIM that has been shadowed to permanent memory.
+
+ @retval EFI_SUCCESS The SecCore PPIs were re-installed successfully.
+ @retval Others An error occurred re-installing the SecCore PPIs.
+
+**/
+EFI_STATUS
+EFIAPI
+RepublishSecPpis (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
+ VOID *PeiPpi;
+ SEC_PLATFORM_INFORMATION_CONTEXT_HOB *SecPlatformInformationContextHob;
+ EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformationPtr;
+ UINT64 SecStructureSize;
+
+ SecPlatformInformationPtr = NULL;
+ SecStructureSize = 0;
+
+ Status = PeiServicesLocatePpi (
+ &gEfiTemporaryRamDonePpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ (VOID **) &PeiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mSecTemporaryRamDonePostMemoryDescriptor
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ Status = PeiServicesLocatePpi (
+ &gEfiTemporaryRamSupportPpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ (VOID **) &PeiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mSecTemporaryRamSupportPostMemoryDescriptor
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ Status = PeiServicesCreateHob (
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof (SEC_PLATFORM_INFORMATION_CONTEXT_HOB),
+ (VOID **) &SecPlatformInformationContextHob
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SecPlatformInformation Context HOB could not be created.\n"));
+ return Status;
+ }
+
+ SecPlatformInformationContextHob->Header.Name = gEfiCallerIdGuid;
+ SecPlatformInformationContextHob->Revision = 1;
+
+ Status = PeiServicesLocatePpi (
+ &gPeiSecPerformancePpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ (VOID **) &PeiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = ((PEI_SEC_PERFORMANCE_PPI *) PeiPpi)->GetPerformance (
+ GetPeiServicesTablePointer (),
+ (PEI_SEC_PERFORMANCE_PPI *) PeiPpi,
+ &SecPlatformInformationContextHob->FirmwareSecPerformance
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mSecPerformancePpiDescriptor
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ Status = PeiServicesLocatePpi (
+ &gEfiSecPlatformInformationPpiGuid,
+ 0,
+ &PeiPpiDescriptor,
+ (VOID **) &PeiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = ((EFI_SEC_PLATFORM_INFORMATION_PPI *) PeiPpi)->PlatformInformation (
+ GetPeiServicesTablePointer (),
+ &SecStructureSize,
+ SecPlatformInformationPtr
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return EFI_NOT_FOUND;
+ }
+
+ ZeroMem ((VOID *) &(SecPlatformInformationContextHob->Context), sizeof (SEC_PLATFORM_INFORMATION_CONTEXT));
+ SecPlatformInformationContextHob->Context.PlatformInformationRecord = AllocatePool ((UINTN) SecStructureSize);
+ ASSERT (SecPlatformInformationContextHob->Context.PlatformInformationRecord != NULL);
+ if (SecPlatformInformationContextHob->Context.PlatformInformationRecord == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ SecPlatformInformationContextHob->Context.StructureSize = SecStructureSize;
+
+ Status = ((EFI_SEC_PLATFORM_INFORMATION_PPI *) PeiPpi)->PlatformInformation (
+ GetPeiServicesTablePointer (),
+ &(SecPlatformInformationContextHob->Context.StructureSize),
+ SecPlatformInformationContextHob->Context.PlatformInformationRecord
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ Status = PeiServicesReInstallPpi (
+ PeiPpiDescriptor,
+ &mSecPlatformInformationPostMemoryDescriptor
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is the entry point which installs an instance of REPUBLISH_SEC_PPI_PPI.
+
+ @param[in] FileHandle Pointer to image file handle.
+ @param[in] PeiServices Pointer to PEI Services Table
+
+ @retval EFI_SUCCESS An instance of REPUBLISH_SEC_PPI_PPI was installed successfully.
+ @retval Others An error occurred installing and instance of REPUBLISH_SEC_PPI_PPI.
+
+**/
+EFI_STATUS
+EFIAPI
+SecMigrationPeiInitialize (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PeiServicesInstallPpi (&mEdkiiRepublishSecPpiDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.h b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
new file mode 100644
index 000000000000..372f8044bdb2
--- /dev/null
+++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
@@ -0,0 +1,170 @@
+/** @file
+ Migrates SEC structures after permanent memory is installed.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __SEC_MIGRATION_H__
+#define __SEC_MIGRATION_H__
+
+#include <Base.h>
+
+#include <Pi/PiPeiCis.h>
+#include <Ppi/RepublishSecPpi.h>
+#include <Ppi/SecPerformance.h>
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPlatformInformation2.h>
+#include <Ppi/TemporaryRamDone.h>
+#include <Ppi/TemporaryRamSupport.h>
+
+/**
+ This interface conveys state information out of the Security (SEC) phase into PEI.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in,out] StructureSize Pointer to the variable describing size of the input buffer.
+ @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformationPostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ );
+
+/**
+ Re-installs the SEC Platform Information PPIs to implementation in this module to support post-memory.
+
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS The SEC Platform Information PPI could not be re-installed.
+ @return Others An error occurred during PPI re-install.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformationPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ This interface re-installs PPIs installed in SecCore from a post-memory PEIM.
+
+ This is to allow a platform that may not support relocation of SecCore to update the PPI instance to a post-memory
+ copy from a PEIM that has been shadowed to permanent memory.
+
+ @retval EFI_SUCCESS The SecCore PPIs were re-installed successfully.
+ @retval Others An error occurred re-installing the SecCore PPIs.
+
+**/
+EFI_STATUS
+EFIAPI
+RepublishSecPpis (
+ VOID
+ );
+
+/**
+ Disables the use of Temporary RAM.
+
+ If present, this service is invoked by the PEI Foundation after
+ the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamDonePostMemory (
+ VOID
+ );
+
+/**
+ This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupportPostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ );
+
+/**
+ This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+ This service is published by the SEC phase. The SEC phase handoff has an optional
+ EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+ PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+ this information is encapsulated into the data structure abstracted by this service.
+ This information is collected for the boot-strap processor (BSP) on IA-32.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+ @param[out] Performance The pointer to performance data collected in SEC phase.
+
+ @retval EFI_SUCCESS The performance data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPerformancePostMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SEC_PERFORMANCE_PPI *This,
+ OUT FIRMWARE_SEC_PERFORMANCE *Performance
+ );
+
+// /**
+// Disables the use of Temporary RAM.
+
+// If present, this service is invoked by the PEI Foundation after
+// the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+// @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+// @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+// **/
+// EFI_STATUS
+// EFIAPI
+// SecTemporaryRamDonePostMemory (
+// VOID
+// );
+
+typedef struct {
+ UINT64 StructureSize;
+ EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord;
+} SEC_PLATFORM_INFORMATION_CONTEXT;
+
+typedef struct {
+ EFI_HOB_GUID_TYPE Header;
+ UINT8 Revision;
+ UINT8 Reserved[3];
+ FIRMWARE_SEC_PERFORMANCE FirmwareSecPerformance;
+ SEC_PLATFORM_INFORMATION_CONTEXT Context;
+} SEC_PLATFORM_INFORMATION_CONTEXT_HOB;
+
+#endif
diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
new file mode 100644
index 000000000000..e29c04710941
--- /dev/null
+++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
@@ -0,0 +1,64 @@
+## @file
+# Migrates SEC structures after permanent memory is installed.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SecMigrationPei
+ MODULE_UNI_FILE = SecMigrationPei.uni
+ FILE_GUID = 58B35361-8922-41BC-B313-EF7ED9ADFDF7
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SecMigrationPeiInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ SecMigrationPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ MemoryAllocationLib
+ PeimEntryPoint
+ PeiServicesLib
+ PeiServicesTablePointerLib
+
+[Ppis]
+ ## PRODUCES
+ gRepublishSecPpiPpiGuid
+
+ ## SOMETIMES_PRODUCES
+ gEfiTemporaryRamDonePpiGuid
+
+ ## SOMETIME_PRODUCES
+ gEfiTemporaryRamSupportPpiGuid
+
+ ## SOMETIMES_PRODUCES
+ gPeiSecPerformancePpiGuid
+
+ ## SOMETIMES_CONSUMES
+ ## PRODUCES
+ gEfiSecPlatformInformationPpiGuid
+
+ ## SOMETIMES_CONSUMES
+ ## SOMETIMES_PRODUCES
+ gEfiSecPlatformInformation2PpiGuid
+
+[Depex]
+ TRUE
diff --git a/UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
new file mode 100644
index 000000000000..62c2064ba217
--- /dev/null
+++ b/UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni
@@ -0,0 +1,13 @@
+// /** @file
+// Migrates SEC structures after permanent memory is installed.
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Migrates SEC structures after permanent memory is installed"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Migrates SEC structures after permanent memory is installed."
+
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 762badf5d239..0a005bd20311 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -66,6 +66,10 @@ [Guids]
## Include/Guid/MicrocodePatchHob.h
gEdkiiMicrocodePatchHobGuid = { 0xd178f11d, 0x8716, 0x418e, { 0xa1, 0x31, 0x96, 0x7d, 0x2a, 0xc4, 0x28, 0x43 }}

+[Ppis]
+ ## Include/Ppi/RepublishSecPpi.h
+ gRepublishSecPpiPpiGuid = { 0x27a71b1e, 0x73ee, 0x43d6, { 0xac, 0xe3, 0x52, 0x1a, 0x2d, 0xc5, 0xd0, 0x92 }}
+
[Protocols]
## Include/Protocol/SmmCpuService.h
gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }}
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index afa304128221..964720048dd7 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -146,6 +146,7 @@ [Components.IA32, Components.X64]
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
UefiCpuPkg/SecCore/SecCore.inf
+ UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
<Defines>
--
2.25.1.windows.1


[PATCH 2/6] UefiCpuPkg/CpuMpPei: Add GDT and IDT migration support (CVE-2019-11098)

Guomin Jiang
 

From: Michael Kubacki <michael.a.kubacki@intel.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614

Moves the GDT and IDT to permanent memory in a memory discovered
callback. This is done to ensure the GDT and IDT authenticated in
pre-memory is not fetched from outside a verified location after
the permanent memory transition.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
UefiCpuPkg/CpuMpPei/CpuMpPei.c | 40 ++++++++++++++++++-
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 13 ++++++
UefiCpuPkg/CpuMpPei/CpuPaging.c | 14 +++++--
.../Ia32/ArchExceptionHandler.c | 4 +-
.../SecPeiCpuException.c | 2 +-
5 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
index 07ccbe7c6a91..2d6f1bc98851 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -429,6 +429,44 @@ GetGdtr (
AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer);
}

+/**
+ Migrates the Global Descriptor Table (GDT) to permanent memory.
+
+ @retval EFI_SUCCESS The GDT was migrated successfully.
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
+
+**/
+EFI_STATUS
+EFIAPI
+MigrateGdt (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN GdtBufferSize;
+ IA32_DESCRIPTOR Gdtr;
+ UINT8 *GdtBuffer;
+
+ AsmReadGdtr ((IA32_DESCRIPTOR *) &Gdtr);
+ GdtBufferSize = sizeof (IA32_TSS_DESCRIPTOR) + Gdtr.Limit + 1;
+
+ Status = PeiServicesAllocatePool (
+ GdtBufferSize,
+ (VOID **) &GdtBuffer
+ );
+ ASSERT (GdtBuffer != NULL);
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_TSS_DESCRIPTOR));
+ CopyMem ((VOID *) (UINTN) GdtBuffer, (VOID *) Gdtr.Base, Gdtr.Limit + 1);
+ Gdtr.Base = (UINT32)(UINTN) GdtBuffer;
+ AsmWriteGdtr (&Gdtr);
+
+ return EFI_SUCCESS;
+}
+
/**
Initializes CPU exceptions handlers for the sake of stack switch requirement.

@@ -644,7 +682,7 @@ InitializeCpuMpWorker (
&gEfiVectorHandoffInfoPpiGuid,
0,
NULL,
- (VOID **)&VectorHandoffInfoPpi
+ (VOID **) &VectorHandoffInfoPpi
);
if (Status == EFI_SUCCESS) {
VectorInfo = VectorHandoffInfoPpi->Info;
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index 7d5c527d6006..5dc956409594 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -397,6 +397,19 @@ SecPlatformInformation2 (
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
);

+/**
+ Migrates the Global Descriptor Table (GDT) to permanent memory.
+
+ @retval EFI_SUCCESS The GDT was migrated successfully.
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
+
+**/
+EFI_STATUS
+EFIAPI
+MigrateGdt (
+ VOID
+ );
+
/**
Initializes MP and exceptions handlers.

diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c
index a462e7ee1e38..d0cbebf70bbf 100644
--- a/UefiCpuPkg/CpuMpPei/CpuPaging.c
+++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c
@@ -152,7 +152,7 @@ GetPhysicalAddressWidth (
Get the type of top level page table.

@retval Page512G PML4 paging.
- @retval Page1G PAE paing.
+ @retval Page1G PAE paging.

**/
PAGE_ATTRIBUTE
@@ -582,7 +582,7 @@ SetupStackGuardPage (
}

/**
- Enabl/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.
+ Enable/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.

Doing this in the memory-discovered callback is to make sure the Stack Guard
feature to cover as most PEI code as possible.
@@ -602,8 +602,14 @@ MemoryDiscoveredPpiNotifyCallback (
IN VOID *Ppi
)
{
- EFI_STATUS Status;
- BOOLEAN InitStackGuard;
+ EFI_STATUS Status;
+ BOOLEAN InitStackGuard;
+ BOOLEAN InterruptState;
+
+ InterruptState = SaveAndDisableInterrupts ();
+ Status = MigrateGdt ();
+ ASSERT_EFI_ERROR (Status);
+ SetInterruptState (InterruptState);

//
// Paging must be setup first. Otherwise the exception TSS setup during MP
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index 1aafb7dac139..903449e0daa9 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -18,8 +18,8 @@
**/
VOID
ArchUpdateIdtEntry (
- IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
- IN UINTN InterruptHandler
+ OUT IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
+ IN UINTN InterruptHandler
)
{
IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
index 20148db74cf8..d4ae153c5742 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
@@ -87,7 +87,7 @@ InitializeCpuExceptionHandlers (
IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
if (IdtEntryCount > CPU_EXCEPTION_NUM) {
//
- // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most
+ // CPU exception library only setup CPU_EXCEPTION_NUM exception handler at most
//
IdtEntryCount = CPU_EXCEPTION_NUM;
}
--
2.25.1.windows.1


[PATCH 1/6] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098)

Guomin Jiang
 

From: Michael Kubacki <michael.a.kubacki@intel.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614

Introduces new changes to PeiCore to move the contents of temporary
RAM visible to the PeiCore to permanent memory. This expands on
pre-existing shadowing support in the PeiCore to perform the following
additional actions:

1. Migrate pointers in PPIs installed in PeiCore to the permanent
memory copy of PeiCore.

2. Copy all installed firmware volumes to permanent memory.

3. Relocate and fix up the PEIMs within the firmware volumes.

4. Convert all PPIs into the migrated firmware volume to the corresponding
PPI address in the permanent memory location.

This applies to PPIs and PEI notifications.

5. Convert all status code callbacks in the migrated firmware volume to
the corresponding address in the permanent memory location.

6. Update the FV HOB to the corresponding firmware volume in permanent
memory.

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Harry Han <harry.han@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 402 ++++++++++++++++++
MdeModulePkg/Core/Pei/Image/Image.c | 115 +++++
MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 82 ++++
MdeModulePkg/Core/Pei/PeiMain.h | 168 ++++++++
MdeModulePkg/Core/Pei/PeiMain.inf | 1 +
MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 16 +
MdeModulePkg/Core/Pei/Ppi/Ppi.c | 287 +++++++++++++
7 files changed, 1071 insertions(+)

diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index 4c2eac1384e8..ef88b3423376 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -952,6 +952,408 @@ PeiCheckAndSwitchStack (
}
}

+/**
+ Migrate a PEIM from Temporary RAM to permanent memory.
+
+ @param PeimFileHandle Pointer to the FFS file header of the image.
+ @param MigratedFileHandle Pointer to the FFS file header of the migrated image.
+
+ @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanent memory.
+
+**/
+EFI_STATUS
+EFIAPI
+MigratePeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN EFI_PEI_FILE_HANDLE MigratedFileHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER *FileHeader;
+ VOID *Pe32Data;
+ VOID *ImageAddress;
+ CHAR8 *AsciiString;
+ UINTN Index;
+
+ Status = EFI_SUCCESS;
+
+ FileHeader = (EFI_FFS_FILE_HEADER *) FileHandle;
+ ASSERT (!IS_FFS_FILE2 (FileHeader));
+
+ ImageAddress = NULL;
+ PeiGetPe32Data (MigratedFileHandle, &ImageAddress);
+ if (ImageAddress != NULL) {
+ AsciiString = PeCoffLoaderGetPdbPointer (ImageAddress);
+ for (Index = 0; AsciiString[Index] != 0; Index++) {
+ if (AsciiString[Index] == '\\' || AsciiString[Index] == '/') {
+ AsciiString = AsciiString + Index + 1;
+ Index = 0;
+ } else if (AsciiString[Index] == '.') {
+ AsciiString[Index] = 0;
+ }
+ }
+ DEBUG ((DEBUG_INFO, "%a", AsciiString));
+
+ Pe32Data = (VOID *) ((UINTN) ImageAddress - (UINTN) MigratedFileHandle + (UINTN) FileHandle);
+ Status = LoadAndRelocatePeCoffImageInPlace (Pe32Data, ImageAddress);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
+
+/**
+ Migrate Status Code Callback function pointers inside an FV from temporary memory to permanent memory.
+
+ @param OrgFvHandle Address of FV Handle in temporary memory.
+ @param FvHandle Address of FV Handle in permanent memory.
+ @param FvSize Size of the FV.
+
+**/
+VOID
+ConvertStatusCodeCallbacks (
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle,
+ IN UINTN FvSize
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN *NumberOfEntries;
+ UINTN *CallbackEntry;
+ UINTN Index;
+
+ Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+ while (Hob.Raw != NULL) {
+ NumberOfEntries = GET_GUID_HOB_DATA (Hob);
+ CallbackEntry = NumberOfEntries + 1;
+ for (Index = 0; Index < *NumberOfEntries; Index++) {
+ if (((VOID *) CallbackEntry[Index]) != NULL) {
+ if ((CallbackEntry[Index] >= OrgFvHandle) && (CallbackEntry[Index] < (OrgFvHandle + FvSize))) {
+ DEBUG ((DEBUG_INFO, "Migrating CallbackEntry[%d] from 0x%08X to ", Index, CallbackEntry[Index]));
+ if (OrgFvHandle > FvHandle) {
+ CallbackEntry[Index] = CallbackEntry[Index] - (OrgFvHandle - FvHandle);
+ } else {
+ CallbackEntry[Index] = CallbackEntry[Index] + (FvHandle - OrgFvHandle);
+ }
+ DEBUG ((DEBUG_INFO, "0x%08X\n", CallbackEntry[Index]));
+ }
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw);
+ }
+}
+
+/**
+ Migrates SEC modules in the given firmware volume.
+
+ Migrating SECURITY_CORE files requires special treatment since they are not tracked for PEI dispatch.
+
+ This functioun should be called after the FV has been copied to its post-memory location and the PEI Core FV list has
+ been updated.
+
+ @param Private Pointer to the PeiCore's private data structure.
+ @param FvIndex The firmware volume index to migrate.
+ @param OrgFvHandle The handle to the firmware volume in temporary memory.
+
+ @retval EFI_SUCCESS SEC modules were migrated successfully
+ @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+MigrateSecModulesInFv (
+ IN PEI_CORE_INSTANCE *Private,
+ IN UINTN FvIndex,
+ IN UINTN OrgFvHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS FindFileStatus;
+ EFI_PEI_FILE_HANDLE MigratedFileHandle;
+ EFI_PEI_FILE_HANDLE FileHandle;
+ UINT32 SectionAuthenticationStatus;
+ UINT32 FileSize;
+ VOID *OrgPe32SectionData;
+ VOID *Pe32SectionData;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ EFI_COMMON_SECTION_HEADER *Section;
+ BOOLEAN IsFfs3Fv;
+ UINTN SectionInstance;
+
+ if (Private == NULL || FvIndex >= Private->FvCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ do {
+ FindFileStatus = PeiFfsFindNextFile (
+ GetPeiServicesTablePointer (),
+ EFI_FV_FILETYPE_SECURITY_CORE,
+ Private->Fv[FvIndex].FvHandle,
+ &MigratedFileHandle
+ );
+ if (!EFI_ERROR (FindFileStatus ) && MigratedFileHandle != NULL) {
+ FileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) MigratedFileHandle - (UINTN) Private->Fv[FvIndex].FvHandle + OrgFvHandle);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *) MigratedFileHandle;
+
+ DEBUG ((DEBUG_VERBOSE, " Migrating SEC_CORE MigratedFileHandle at 0x%x.\n", (UINTN) MigratedFileHandle));
+ DEBUG ((DEBUG_VERBOSE, " FileHandle at 0x%x.\n", (UINTN) FileHandle));
+
+ IsFfs3Fv = CompareGuid (&Private->Fv[FvIndex].FvHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);
+ if (IS_FFS_FILE2 (FfsFileHeader)) {
+ ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF);
+ if (!IsFfs3Fv) {
+ DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
+ return EFI_NOT_FOUND;
+ }
+ Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
+ FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
+ } else {
+ Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
+ FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
+ }
+
+ SectionInstance = 1;
+ SectionAuthenticationStatus = 0;
+ Status = ProcessSection (
+ GetPeiServicesTablePointer (),
+ EFI_SECTION_PE32,
+ &SectionInstance,
+ Section,
+ FileSize,
+ &Pe32SectionData,
+ &SectionAuthenticationStatus,
+ IsFfs3Fv
+ );
+
+ if (!EFI_ERROR (Status)) {
+ OrgPe32SectionData = (VOID *) ((UINTN) Pe32SectionData - (UINTN) MigratedFileHandle + (UINTN) FileHandle);
+ DEBUG ((DEBUG_VERBOSE, " PE32 section in migrated file at 0x%x.\n", (UINTN) Pe32SectionData));
+ DEBUG ((DEBUG_VERBOSE, " PE32 section in original file at 0x%x.\n", (UINTN) OrgPe32SectionData));
+ Status = LoadAndRelocatePeCoffImageInPlace (OrgPe32SectionData, Pe32SectionData);
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ } while (!EFI_ERROR (FindFileStatus));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Migrates PEIMs in the given firmware volume.
+
+ @param Private Pointer to the PeiCore's private data structure.
+ @param FvIndex The firmware volume index to migrate.
+ @param OrgFvHandle The handle to the firmware volume in temporary memory.
+ @param FvHandle The handle to the firmware volume in permanent memory.
+
+ @retval EFI_SUCCESS The PEIMs in the FV were migrated successfully
+ @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+MigratePeimsInFv (
+ IN PEI_CORE_INSTANCE *Private,
+ IN UINTN FvIndex,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle
+ )
+{
+ EFI_STATUS Status;
+ volatile UINTN FileIndex;
+ EFI_PEI_FILE_HANDLE MigratedFileHandle;
+ EFI_PEI_FILE_HANDLE FileHandle;
+
+ if (Private == NULL || FvIndex >= Private->FvCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Private->Fv[FvIndex].ScanFv) {
+ for (FileIndex = 0; FileIndex < Private->Fv[FvIndex].PeimCount; FileIndex++) {
+ if (Private->Fv[FvIndex].FvFileHandles[FileIndex] != NULL) {
+ FileHandle = Private->Fv[FvIndex].FvFileHandles[FileIndex];
+
+ MigratedFileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) FileHandle - OrgFvHandle + FvHandle);
+
+ DEBUG ((DEBUG_VERBOSE, " Migrating FileHandle %2d ", FileIndex));
+ Status = MigratePeim (FileHandle, MigratedFileHandle);
+ DEBUG ((DEBUG_INFO, "\n"));
+ ASSERT_EFI_ERROR (Status);
+
+ if (!EFI_ERROR (Status)) {
+ // if (Private->Fv[FvIndex].PeimState[FileIndex] == PEIM_STATE_REGISTER_FOR_SHADOW) {
+ // Private->Fv[FvIndex].PeimState[FileIndex]++;
+ // }
+ Private->Fv[FvIndex].FvFileHandles[FileIndex] = MigratedFileHandle;
+ if (FvIndex == Private->CurrentPeimFvCount) {
+ Private->CurrentFvFileHandles[FileIndex] = MigratedFileHandle;
+ }
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Migrate FVs out of temporary RAM before the cache is flushed.
+
+ @param Private PeiCore's private data structure
+ @param SecCoreData Points to a data structure containing information about the PEI core's operating
+ environment, such as the size and location of temporary RAM, the stack location and
+ the BFV location.
+
+ @retval EFI_SUCCESS Succesfully migrated installed FVs from temporary RAM to permanent memory.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate needed pages.
+
+**/
+EFI_STATUS
+EFIAPI
+EvacuateTempRam (
+ IN PEI_CORE_INSTANCE *Private,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+{
+ EFI_STATUS Status;
+ volatile UINTN FvIndex;
+ volatile UINTN FvChildIndex;
+ UINTN ChildFvOffset;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *ChildFvHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *MigratedFvHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *MigratedChildFvHeader;
+
+ PEI_CORE_FV_HANDLE PeiCoreFvHandle;
+ EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi;
+
+ ASSERT (Private->PeiMemoryInstalled);
+
+ DEBUG ((DEBUG_VERBOSE, "Beginning evacuation of content in temporary RAM.\n"));
+
+ //
+ // Migrate PPI Pointers of PEI_CORE from temporary memory to newly loaded PEI_CORE in permanent memory.
+ //
+ Status = PeiLocatePpi ((CONST EFI_PEI_SERVICES **) &Private->Ps, &gEfiPeiCoreFvLocationPpiGuid, 0, NULL, (VOID **) &PeiCoreFvLocationPpi);
+ if (!EFI_ERROR (Status) && (PeiCoreFvLocationPpi->PeiCoreFvLocation != NULL)) {
+ PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE) PeiCoreFvLocationPpi->PeiCoreFvLocation;
+ } else {
+ PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE) SecCoreData->BootFirmwareVolumeBase;
+ }
+ for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
+ if (Private->Fv[FvIndex].FvHandle == PeiCoreFvHandle.FvHandle) {
+ PeiCoreFvHandle = Private->Fv[FvIndex];
+ break;
+ }
+ }
+ Status = EFI_SUCCESS;
+
+ ConvertPeiCorePpiPointers (Private, PeiCoreFvHandle);
+
+ for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
+ FvHeader = Private->Fv[FvIndex].FvHeader;
+ ASSERT (FvHeader != NULL);
+ ASSERT (FvIndex < Private->FvCount);
+
+ DEBUG ((DEBUG_VERBOSE, "FV[%02d] at 0x%x.\n", FvIndex, (UINTN) FvHeader));
+ if (
+ !(
+ ((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader >= Private->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader + (FvHeader->FvLength - 1)) < Private->FreePhysicalMemoryTop)
+ )
+ ) {
+ Status = PeiServicesAllocatePages (
+ EfiBootServicesCode,
+ EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength),
+ (EFI_PHYSICAL_ADDRESS *) &MigratedFvHeader
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ " Migrating FV[%d] from 0x%08X to 0x%08X\n",
+ FvIndex,
+ (UINTN) FvHeader,
+ (UINTN) MigratedFvHeader
+ ));
+
+ CopyMem (MigratedFvHeader, FvHeader, (UINTN) FvHeader->FvLength);
+
+ //
+ // Migrate any children for this FV now
+ //
+ for (FvChildIndex = FvIndex; FvChildIndex < Private->FvCount; FvChildIndex++) {
+ ChildFvHeader = Private->Fv[FvChildIndex].FvHeader;
+ if (
+ ((UINTN) ChildFvHeader > (UINTN) FvHeader) &&
+ (((UINTN) ChildFvHeader + ChildFvHeader->FvLength) < ((UINTN) FvHeader) + FvHeader->FvLength)
+ ) {
+ DEBUG ((DEBUG_VERBOSE, " Child FV[%02d] is being migrated.\n", FvChildIndex));
+ ChildFvOffset = (UINTN) ChildFvHeader - (UINTN) FvHeader;
+ DEBUG ((DEBUG_VERBOSE, " Child FV offset = 0x%x.\n", ChildFvOffset));
+ MigratedChildFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) MigratedFvHeader + ChildFvOffset);
+ Private->Fv[FvChildIndex].FvHeader = MigratedChildFvHeader;
+ Private->Fv[FvChildIndex].FvHandle = (EFI_PEI_FV_HANDLE) MigratedChildFvHeader;
+ DEBUG ((DEBUG_VERBOSE, " Child migrated FV header at 0x%x.\n", (UINTN) MigratedChildFvHeader));
+
+ // @todo: find issue with file and section alignment in SEC PE32 images for migration
+ // (alignment in P32 is given as 32-bit when actual alignment is 16-bit)
+ // SEC PPIs are currently re-installed with a dedicated PEIM
+ // Status = MigrateSecModulesInFv (Private, FvChildIndex, (UINTN) ChildFvHeader);
+ // ASSERT_EFI_ERROR (Status);
+ Status = MigratePeimsInFv (Private, FvChildIndex, (UINTN) ChildFvHeader, (UINTN) MigratedChildFvHeader);
+ ASSERT_EFI_ERROR (Status);
+
+ ConvertPpiPointersFv (
+ Private,
+ (UINTN) ChildFvHeader,
+ (UINTN) MigratedChildFvHeader,
+ (UINTN) ChildFvHeader->FvLength - 1
+ );
+
+ ConvertStatusCodeCallbacks (
+ (UINTN) ChildFvHeader,
+ (UINTN) MigratedChildFvHeader,
+ (UINTN) ChildFvHeader->FvLength - 1
+ );
+
+ ConvertFvHob (Private, (UINTN) ChildFvHeader, (UINTN) MigratedChildFvHeader);
+ }
+ }
+ Private->Fv[FvIndex].FvHeader = MigratedFvHeader;
+ Private->Fv[FvIndex].FvHandle = (EFI_PEI_FV_HANDLE) MigratedFvHeader;
+
+ // @todo: find issue with file and section alignment in SEC PE32 images for migration
+ // (alignment in P32 is given as 32-bit when actual alignment is 16-bit)
+ // SEC PPIs are currently re-installed with a dedicated PEIM
+ // Status = MigrateSecModulesInFv (Private, FvIndex, (UINTN) FvHeader);
+ // ASSERT_EFI_ERROR (Status);
+ Status = MigratePeimsInFv (Private, FvIndex, (UINTN) FvHeader, (UINTN) MigratedFvHeader);
+ ASSERT_EFI_ERROR (Status);
+
+ ConvertPpiPointersFv (
+ Private,
+ (UINTN) FvHeader,
+ (UINTN) MigratedFvHeader,
+ (UINTN) FvHeader->FvLength - 1
+ );
+
+ ConvertStatusCodeCallbacks (
+ (UINTN) FvHeader,
+ (UINTN) MigratedFvHeader,
+ (UINTN) FvHeader->FvLength - 1
+ );
+
+ ConvertFvHob (Private, (UINTN) FvHeader, (UINTN) MigratedFvHeader);
+ }
+ }
+
+ RemoveFvHobsInTemporaryMemory (Private);
+
+ return Status;
+}
+
/**
Conduct PEIM dispatch.

diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c
index e3ee3699337f..612797722a3e 100644
--- a/MdeModulePkg/Core/Pei/Image/Image.c
+++ b/MdeModulePkg/Core/Pei/Image/Image.c
@@ -444,6 +444,121 @@ LoadAndRelocatePeCoffImage (
return ReturnStatus;
}

+/**
+ Loads and relocates a PE/COFF image in place.
+
+ @param Pe32Data The base address of the PE/COFF file that is to be loaded and relocated
+ @param ImageAddress The base address of the relocated PE/COFF image
+
+ @retval EFI_SUCCESS The file was loaded and relocated
+
+**/
+EFI_STATUS
+LoadAndRelocatePeCoffImageInPlace (
+ IN VOID *Pe32Data,
+ IN VOID *ImageAddress
+ )
+{
+ EFI_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ ZeroMem (&ImageContext, sizeof (ImageContext));
+ ImageContext.Handle = Pe32Data;
+ ImageContext.ImageRead = PeiImageRead;
+
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN) ImageAddress;
+
+ //
+ // Load the image in place
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ //
+ // Relocate the image in place
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ //
+ // Flush the instruction cache so the image data is written before we execute it
+ //
+ if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data) {
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
+ }
+
+ return Status;
+}
+
+/**
+ Find the PE32 Data for an FFS file.
+
+ @param FileHandle Pointer to the FFS file header of the image.
+ @param Pe32Data Pointer to a (VOID *) PE32 Data pointer.
+
+ @retval EFI_SUCCESS Image is successfully loaded.
+ @retval EFI_NOT_FOUND Fail to locate PE32 Data.
+
+**/
+EFI_STATUS
+PeiGetPe32Data (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **Pe32Data
+ )
+{
+ EFI_STATUS Status;
+ EFI_SECTION_TYPE SearchType1;
+ EFI_SECTION_TYPE SearchType2;
+ UINT32 AuthenticationState;
+
+ *Pe32Data = NULL;
+
+ if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {
+ SearchType1 = EFI_SECTION_TE;
+ SearchType2 = EFI_SECTION_PE32;
+ } else {
+ SearchType1 = EFI_SECTION_PE32;
+ SearchType2 = EFI_SECTION_TE;
+ }
+
+ //
+ // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst
+ // is true, TE will be searched first).
+ //
+ Status = PeiServicesFfsFindSectionData3 (
+ SearchType1,
+ 0,
+ FileHandle,
+ Pe32Data,
+ &AuthenticationState
+ );
+ //
+ // If we didn't find a first exe section, try to find the second exe section.
+ //
+ if (EFI_ERROR (Status)) {
+ Status = PeiServicesFfsFindSectionData3 (
+ SearchType2,
+ 0,
+ FileHandle,
+ Pe32Data,
+ &AuthenticationState
+ );
+ }
+ return Status;
+}
+
/**
Loads a PEIM into memory for subsequent execution. If there are compressed
images or images that need to be relocated into memory for performance reasons,
diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
index 6b3a64a811cd..9d933f0393a8 100644
--- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
+++ b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
@@ -166,6 +166,88 @@ MigrateMemoryPages (
Private->FreePhysicalMemoryTop = NewMemPagesBase;
}

+/**
+ Removes any FV HOBs whose base address is not in PEI installed memory.
+
+ @param[in] Private Pointer to PeiCore's private data structure.
+
+**/
+VOID
+RemoveFvHobsInTemporaryMemory (
+ IN PEI_CORE_INSTANCE *Private
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;
+
+ DEBUG ((DEBUG_INFO, "Removing FVs in FV HOB not already migrated to permanent memory.\n"));
+
+ for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV || GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2 || GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3) {
+ FirmwareVolumeHob = Hob.FirmwareVolume;
+ DEBUG ((DEBUG_INFO, " Found FV HOB.\n"));
+ DEBUG ((
+ DEBUG_INFO,
+ " BA=%016lx L=%016lx\n",
+ FirmwareVolumeHob->BaseAddress,
+ FirmwareVolumeHob->Length
+ ));
+ if (
+ !(
+ ((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob->BaseAddress >= Private->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob->BaseAddress + (FirmwareVolumeHob->Length - 1)) < Private->FreePhysicalMemoryTop)
+ )
+ ) {
+ DEBUG ((DEBUG_INFO, " Removing FV HOB to an FV in T-RAM (was not migrated).\n"));
+ Hob.Header->HobType = EFI_HOB_TYPE_UNUSED;
+ }
+ }
+ }
+}
+
+/**
+ Migrate the base address in firmware volume allocation HOBs
+ from temporary memory to PEI installed memory.
+
+ @param[in] PrivateData Pointer to PeiCore's private data structure.
+ @param[in] OrgFvHandle Address of FV Handle in temporary memory.
+ @param[in] FvHandle Address of FV Handle in permanent memory.
+
+**/
+VOID
+ConvertFvHob (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;
+ EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2Hob;
+ EFI_HOB_FIRMWARE_VOLUME3 *FirmwareVolume3Hob;
+
+ DEBUG ((DEBUG_INFO, "Converting FVs in FV HOB.\n"));
+
+ for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {
+ FirmwareVolumeHob = Hob.FirmwareVolume;
+ if (FirmwareVolumeHob->BaseAddress == OrgFvHandle) {
+ FirmwareVolumeHob->BaseAddress = FvHandle;
+ }
+ } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) {
+ FirmwareVolume2Hob = Hob.FirmwareVolume2;
+ if (FirmwareVolume2Hob->BaseAddress == OrgFvHandle) {
+ FirmwareVolume2Hob->BaseAddress = FvHandle;
+ }
+ } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3) {
+ FirmwareVolume3Hob = Hob.FirmwareVolume3;
+ if (FirmwareVolume3Hob->BaseAddress == OrgFvHandle) {
+ FirmwareVolume3Hob->BaseAddress = FvHandle;
+ }
+ }
+ }
+}
+
/**
Migrate MemoryBaseAddress in memory allocation HOBs
from the temporary memory to PEI installed memory.
diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h
index 56b3bd85793d..b0101dba5e30 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.h
+++ b/MdeModulePkg/Core/Pei/PeiMain.h
@@ -394,6 +394,41 @@ PeimDispatchReadiness (
IN VOID *DependencyExpression
);

+/**
+ Migrate a PEIM from Temporary RAM to permanent memory.
+
+ @param PeimFileHandle Pointer to the FFS file header of the image.
+ @param MigratedFileHandle Pointer to the FFS file header of the migrated image.
+
+ @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanent memory.
+
+**/
+EFI_STATUS
+EFIAPI
+MigratePeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN EFI_PEI_FILE_HANDLE MigratedFileHandle
+ );
+
+/**
+ Migrate FVs out of Temporary RAM before the cache is flushed.
+
+ @param Private PeiCore's private data structure
+ @param SecCoreData Points to a data structure containing information about the PEI core's operating
+ environment, such as the size and location of temporary RAM, the stack location and
+ the BFV location.
+
+ @retval EFI_SUCCESS Succesfully migrated installed FVs from Temporary RAM to permanent memory.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate needed pages.
+
+**/
+EFI_STATUS
+EFIAPI
+EvacuateTempRam (
+ IN PEI_CORE_INSTANCE *Private,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ );
+
/**
Conduct PEIM dispatch.

@@ -477,6 +512,50 @@ ConvertPpiPointers (
IN PEI_CORE_INSTANCE *PrivateData
);

+/**
+
+ Migrate Notify Pointers inside an FV from temporary memory to permanent memory.
+
+ @param PrivateData Pointer to PeiCore's private data structure.
+ @param OrgFvHandle Address of FV Handle in temporary memory.
+ @param FvHandle Address of FV Handle in permanent memory.
+ @param FvSize Size of the FV.
+
+**/
+VOID
+ConvertPpiPointersFv (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle,
+ IN UINTN FvSize
+ );
+
+/**
+
+ Migrate PPI Pointers of PEI_CORE from temporary memory to permanent memory.
+
+ @param PrivateData Pointer to PeiCore's private data structure.
+ @param CoreFvHandle Address of PEI_CORE FV Handle in temporary memory.
+
+**/
+VOID
+ConvertPeiCorePpiPointers (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ PEI_CORE_FV_HANDLE CoreFvHandle
+ );
+
+/**
+
+ Dumps the PPI lists to debug output.
+
+ @param PrivateData Points to PeiCore's private instance data.
+
+**/
+VOID
+DumpPpiList (
+ IN PEI_CORE_INSTANCE *PrivateData
+ );
+
/**

Install PPI services. It is implementation of EFI_PEI_SERVICE.InstallPpi.
@@ -808,6 +887,37 @@ PeiFfsFindNextFile (
IN OUT EFI_PEI_FILE_HANDLE *FileHandle
);

+/**
+ Go through the file to search SectionType section.
+ Search within encapsulation sections (compression and GUIDed) recursively,
+ until the match section is found.
+
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param SectionType Filter to find only section of this type.
+ @param SectionInstance Pointer to the filter to find the specific instance of section.
+ @param Section From where to search.
+ @param SectionSize The file size to search.
+ @param OutputBuffer A pointer to the discovered section, if successful.
+ NULL if section not found
+ @param AuthenticationStatus Updated upon return to point to the authentication status for this section.
+ @param IsFfs3Fv Indicates the FV format.
+
+ @return EFI_NOT_FOUND The match section is not found.
+ @return EFI_SUCCESS The match section is found.
+
+**/
+EFI_STATUS
+ProcessSection (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN OUT UINTN *SectionInstance,
+ IN EFI_COMMON_SECTION_HEADER *Section,
+ IN UINTN SectionSize,
+ OUT VOID **OutputBuffer,
+ OUT UINT32 *AuthenticationStatus,
+ IN BOOLEAN IsFfs3Fv
+ );
+
/**
Searches for the next matching section within the specified file.

@@ -931,6 +1041,33 @@ MigrateMemoryPages (
IN BOOLEAN TemporaryRamMigrated
);

+/**
+ Removes any FV HOBs whose base address is not in PEI installed memory.
+
+ @param[in] Private Pointer to PeiCore's private data structure.
+
+**/
+VOID
+RemoveFvHobsInTemporaryMemory (
+ IN PEI_CORE_INSTANCE *Private
+ );
+
+/**
+ Migrate the base address in firmware volume allocation HOBs
+ from temporary memory to PEI installed memory.
+
+ @param[in] PrivateData Pointer to PeiCore's private data structure.
+ @param[in] OrgFvHandle Address of FV Handle in temporary memory.
+ @param[in] FvHandle Address of FV Handle in permanent memory.
+
+**/
+VOID
+ConvertFvHob (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle
+ );
+
/**
Migrate MemoryBaseAddress in memory allocation HOBs
from the temporary memory to PEI installed memory.
@@ -1249,6 +1386,37 @@ InitializeImageServices (
IN PEI_CORE_INSTANCE *OldCoreData
);

+/**
+ Loads and relocates a PE/COFF image in place.
+
+ @param Pe32Data The base address of the PE/COFF file that is to be loaded and relocated
+ @param ImageAddress The base address of the relocated PE/COFF image
+
+ @retval EFI_SUCCESS The file was loaded and relocated
+
+**/
+EFI_STATUS
+LoadAndRelocatePeCoffImageInPlace (
+ IN VOID *Pe32Data,
+ IN VOID *ImageAddress
+ );
+
+/**
+ Find the PE32 Data for an FFS file.
+
+ @param FileHandle Pointer to the FFS file header of the image.
+ @param Pe32Data Pointer to a (VOID *) PE32 Data pointer.
+
+ @retval EFI_SUCCESS Image is successfully loaded.
+ @retval EFI_NOT_FOUND Fail to locate PE32 Data.
+
+**/
+EFI_STATUS
+PeiGetPe32Data (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **Pe32Data
+ );
+
/**
The wrapper function of PeiLoadImageLoadImage().

diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
index 6e25cc40232a..5ff14100a65f 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.inf
+++ b/MdeModulePkg/Core/Pei/PeiMain.inf
@@ -76,6 +76,7 @@ [Guids]
## CONSUMES ## UNDEFINED # Locate PPI
## CONSUMES ## GUID # Used to compare with FV's file system GUID and get the FV's file system format
gEfiFirmwareFileSystem3Guid
+ gStatusCodeCallbackGuid

[Ppis]
gEfiPeiStatusCodePpiGuid ## SOMETIMES_CONSUMES # PeiReportStatusService is not ready if this PPI doesn't exist
diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
index cca57c4c0686..802cd239e2eb 100644
--- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
+++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
@@ -418,6 +418,22 @@ PeiCore (
ProcessPpiListFromSec ((CONST EFI_PEI_SERVICES **) &PrivateData.Ps, PpiList);
}
} else {
+ if (
+ (!(PrivateData.HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME) && PcdGetBool (PcdShadowPeimOnBoot)) ||
+ ((PrivateData.HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME) && PcdGetBool (PcdShadowPeimOnS3Boot))
+ ) {
+ DEBUG ((DEBUG_VERBOSE, "PPI lists before temporary RAM evacuation:\n"));
+ DumpPpiList (&PrivateData);
+
+ //
+ // Migrate installed content from Temporary RAM to Permanent RAM
+ //
+ EvacuateTempRam (&PrivateData, SecCoreData);
+
+ DEBUG ((DEBUG_VERBOSE, "PPI lists after temporary RAM evacuation:\n"));
+ DumpPpiList (&PrivateData);
+ }
+
//
// Try to locate Temporary RAM Done Ppi.
//
diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
index 1ffe718c4702..018b25f86470 100644
--- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c
+++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
@@ -198,6 +198,227 @@ ConvertPpiPointers (
}
}

+/**
+
+ Migrate Notify Pointers inside an FV from temporary memory to permanent memory.
+
+ @param PrivateData Pointer to PeiCore's private data structure.
+ @param OrgFvHandle Address of FV Handle in temporary memory.
+ @param FvHandle Address of FV Handle in permanent memory.
+ @param FvSize Size of the FV.
+
+**/
+VOID
+ConvertPpiPointersFv (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN UINTN OrgFvHandle,
+ IN UINTN FvHandle,
+ IN UINTN FvSize
+ )
+{
+ UINT8 Index;
+ UINTN Offset;
+ BOOLEAN OffsetPositive;
+ EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;
+ UINT8 GuidIndex;
+ EFI_GUID *Guid;
+ EFI_GUID *GuidCheckList[2];
+
+ GuidCheckList[0] = &gEfiPeiFirmwareVolumeInfoPpiGuid;
+ GuidCheckList[1] = &gEfiPeiFirmwareVolumeInfo2PpiGuid;
+
+ if (FvHandle > OrgFvHandle) {
+ OffsetPositive = TRUE;
+ Offset = FvHandle - OrgFvHandle;
+ } else {
+ OffsetPositive = FALSE;
+ Offset = OrgFvHandle - FvHandle;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "Converting PPI pointers in FV.\n"));
+ DEBUG ((
+ DEBUG_VERBOSE,
+ " OrgFvHandle at 0x%08x. FvHandle at 0x%08x. FvSize = 0x%x\n",
+ (UINTN) OrgFvHandle,
+ (UINTN) FvHandle,
+ FvSize
+ ));
+ DEBUG ((
+ DEBUG_VERBOSE,
+ " OrgFvHandle range: 0x%08x - 0x%08x\n",
+ OrgFvHandle,
+ OrgFvHandle + FvSize
+ ));
+
+ for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Notify,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ }
+
+ for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Notify,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ }
+
+ for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ ConvertPointer (
+ (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+
+ Guid = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid;
+ for (GuidIndex = 0; GuidIndex < ARRAY_SIZE (GuidCheckList); ++GuidIndex) {
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)Guid)[0] == ((INT32 *)GuidCheckList[GuidIndex])[0]) &&
+ (((INT32 *)Guid)[1] == ((INT32 *)GuidCheckList[GuidIndex])[1]) &&
+ (((INT32 *)Guid)[2] == ((INT32 *)GuidCheckList[GuidIndex])[2]) &&
+ (((INT32 *)Guid)[3] == ((INT32 *)GuidCheckList[GuidIndex])[3])) {
+ FvInfoPpi = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi;
+ DEBUG ((DEBUG_VERBOSE, " FvInfo: %p -> ", FvInfoPpi->FvInfo));
+ if ((UINTN)FvInfoPpi->FvInfo == OrgFvHandle) {
+ ConvertPointer (
+ (VOID **)&FvInfoPpi->FvInfo,
+ OrgFvHandle,
+ OrgFvHandle + FvSize,
+ Offset,
+ OffsetPositive
+ );
+ DEBUG ((DEBUG_VERBOSE, "%p", FvInfoPpi->FvInfo));
+ }
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+ break;
+ }
+ }
+ }
+}
+
+/**
+
+ Dumps the PPI lists to debug output.
+
+ @param PrivateData Points to PeiCore's private instance data.
+
+**/
+VOID
+DumpPpiList (
+ IN PEI_CORE_INSTANCE *PrivateData
+ )
+{
+ DEBUG_CODE_BEGIN ();
+ UINTN Index;
+
+ if (PrivateData == NULL) {
+ return;
+ }
+
+ for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "CallbackNotify[%2d] {%g} at 0x%x (%a)\n",
+ Index,
+ PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
+ (UINTN) PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
+ (
+ !(
+ ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
+ )
+ ? "CAR" : "Post-Memory"
+ )
+ ));
+ }
+ for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
+ DEBUG ((DEBUG_VERBOSE,
+ "DispatchNotify[%2d] {%g} at 0x%x (%a)\n",
+ Index,
+ PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
+ (UINTN) PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
+ (
+ !(
+ ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw >=PrivateData->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
+ )
+ ? "CAR" : "Post-Memory"
+ )
+ ));
+ }
+ for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
+ DEBUG ((DEBUG_VERBOSE,
+ "PPI[%2d] {%g} at 0x%x (%a)\n",
+ Index,
+ PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
+ (UINTN) PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
+ (
+ !(
+ ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
+ (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw) + sizeof (EFI_PEI_PPI_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
+ )
+ ? "CAR" : "Post-Memory"
+ )
+ ));
+ }
+ DEBUG_CODE_END ();
+}
+
/**

This function installs an interface in the PEI PPI database by GUID.
@@ -830,3 +1051,69 @@ ProcessPpiListFromSec (
}
}

+/**
+
+ Migrate PPI Pointers of PEI_CORE from temporary memory to permanent memory.
+
+ @param PrivateData Pointer to PeiCore's private data structure.
+ @param CoreFvHandle Address of PEI_CORE FV Handle in temporary memory.
+
+**/
+
+VOID
+ConvertPeiCorePpiPointers (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ PEI_CORE_FV_HANDLE CoreFvHandle
+ )
+{
+ EFI_FV_FILE_INFO FileInfo;
+ EFI_PHYSICAL_ADDRESS OrgImageBase;
+ EFI_PHYSICAL_ADDRESS MigratedImageBase;
+ UINTN PeiCoreModuleSize;
+ EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
+ VOID *PeiCoreImageBase;
+ VOID *PeiCoreEntryPoint;
+ EFI_STATUS Status;
+
+ PeiCoreFileHandle = NULL;
+
+ //
+ // Find the PEI Core in the BFV in temporary memory.
+ //
+ Status = CoreFvHandle.FvPpi->FindFileByType (
+ CoreFvHandle.FvPpi,
+ EFI_FV_FILETYPE_PEI_CORE,
+ CoreFvHandle.FvHandle,
+ &PeiCoreFileHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (!EFI_ERROR (Status)) {
+ Status = CoreFvHandle.FvPpi->GetFileInfo (CoreFvHandle.FvPpi, PeiCoreFileHandle, &FileInfo);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Find PEI Core EntryPoint in the BFV in temporary memory.
+ //
+ Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, &PeiCoreEntryPoint);
+ ASSERT_EFI_ERROR (Status);
+
+ OrgImageBase = (UINTN) PeiCoreImageBase;
+ MigratedImageBase = (UINTN) _ModuleEntryPoint - ((UINTN) PeiCoreEntryPoint - (UINTN) PeiCoreImageBase);
+
+ //
+ // Size of loaded PEI_CORE in permanent memory.
+ //
+ PeiCoreModuleSize = (UINTN)FileInfo.BufferSize - ((UINTN) OrgImageBase - (UINTN) FileInfo.Buffer);
+
+ //
+ // Migrate PEI_CORE PPI pointers from temporary memory to newly
+ // installed PEI_CORE in permanent memory.
+ //
+ ConvertPpiPointersFv (PrivateData, (UINTN) OrgImageBase, (UINTN) MigratedImageBase, PeiCoreModuleSize);
+ }
+}
+
--
2.25.1.windows.1


[PATCH 0/6] Migrate Pointer from flash to permanent memory (CVE-2019-11098)

Guomin Jiang
 

The TOCTOU vulnerability allow that the physical present person to replace the code with the normal BootGuard check and PCR0 value.
The issue occur when BootGuard measure IBB and access flash code after NEM disable.
the reason why we access the flash code is that we have some pointer to flash.
To avoid this vulnerability, we need to convert those pointers, the patch series do this work and make sure that no code will access flash address.

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Harry Han <harry.han@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Qi Zhang <qi1.zhang@intel.com>

Guomin Jiang (2):
MdeModulePkg/Core: Create Migrated FV Info Hob for calculating hash
(CVE-2019-11098)
SecurityPkg/Tcg2Pei: Use Migrated FV Info Hob for calculating hash
(CVE-2019-11098)

Jian J Wang (1):
MdeModulePkg/DxeIplPeim: Register for shadow on S3 shadowed boot
(CVE-2019-11098)

Michael Kubacki (3):
MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore
(CVE-2019-11098)
UefiCpuPkg/CpuMpPei: Add GDT and IDT migration support
(CVE-2019-11098)
UefiCpuPkg/SecMigrationPei: Add initial PEIM (CVE-2019-11098)

MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 3 +
MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 2 +-
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 417 ++++++++++++++++++
MdeModulePkg/Core/Pei/Image/Image.c | 115 +++++
MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 82 ++++
MdeModulePkg/Core/Pei/PeiMain.h | 169 +++++++
MdeModulePkg/Core/Pei/PeiMain.inf | 2 +
MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 16 +
MdeModulePkg/Core/Pei/Ppi/Ppi.c | 287 ++++++++++++
MdeModulePkg/Include/Guid/MigratedFvInfo.h | 22 +
MdeModulePkg/MdeModulePkg.dec | 3 +
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c | 31 +-
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf | 1 +
UefiCpuPkg/CpuMpPei/CpuMpPei.c | 40 +-
UefiCpuPkg/CpuMpPei/CpuMpPei.h | 13 +
UefiCpuPkg/CpuMpPei/CpuPaging.c | 14 +-
UefiCpuPkg/Include/Ppi/RepublishSecPpi.h | 54 +++
.../Ia32/ArchExceptionHandler.c | 4 +-
.../SecPeiCpuException.c | 2 +-
UefiCpuPkg/SecCore/SecCore.inf | 2 +
UefiCpuPkg/SecCore/SecMain.c | 26 +-
UefiCpuPkg/SecCore/SecMain.h | 1 +
UefiCpuPkg/SecMigrationPei/SecMigrationPei.c | 372 ++++++++++++++++
UefiCpuPkg/SecMigrationPei/SecMigrationPei.h | 170 +++++++
.../SecMigrationPei/SecMigrationPei.inf | 64 +++
.../SecMigrationPei/SecMigrationPei.uni | 13 +
UefiCpuPkg/UefiCpuPkg.dec | 4 +
UefiCpuPkg/UefiCpuPkg.dsc | 1 +
28 files changed, 1916 insertions(+), 14 deletions(-)
create mode 100644 MdeModulePkg/Include/Guid/MigratedFvInfo.h
create mode 100644 UefiCpuPkg/Include/Ppi/RepublishSecPpi.h
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.c
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.h
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
create mode 100644 UefiCpuPkg/SecMigrationPei/SecMigrationPei.uni

--
2.25.1.windows.1


Re: [PATCH] FmpDevicePkg: Enhance capsule verification with secure boot keys

Liming Sun
 

Thanks Guomin for the comments!

Below is the main scenario for the proposed change:

- Device Manufacturer provides the devices with UEFI preinstalled in non-secure state and no hard-coded keys ( PcdFmpDevicePkcs7CertBufferXdr).

- Customer (not End-User) enrolls their own keys in trusted environment before delivering to End User.
This capsule approach can be used for large deployment without involving any private keys.

Yes, I do agree that once it's delivered to End User it won't be considered secure.

Thanks,
Liming

-----Original Message-----
From: Jiang, Guomin <guomin.jiang@intel.com>
Sent: Sunday, June 28, 2020 11:18 PM
To: devel@edk2.groups.io; Liming Sun <lsun@mellanox.com>; Xu, Wei6 <wei6.xu@intel.com>; Gao, Liming <liming.gao@intel.com>;
Kinney, Michael D <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Subject: RE: [edk2-devel] [PATCH] FmpDevicePkg: Enhance capsule verification with secure boot keys

I think it have some vulnerability, the case as below.

1. Untrusted End User enroll the new DB key -> sign the untrusted device firmware -> flash the untrusted device firmware -> the
system will become unsafe.

I think the end user is untrusted and we need to make sure only few person can have the privilege.

Best Regards
Guomin

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Liming
Sun
Sent: Saturday, June 20, 2020 1:48 AM
To: Xu, Wei6 <wei6.xu@intel.com>; Gao, Liming <liming.gao@intel.com>;
Kinney, Michael D <michael.d.kinney@intel.com>
Cc: Liming Sun <lsun@mellanox.com>; devel@edk2.groups.io; Sean Brogan
<sean.brogan@microsoft.com>
Subject: [edk2-devel] [PATCH] FmpDevicePkg: Enhance capsule verification
with secure boot keys

This commit enhances the FmpDevicePkg package to optionally verify
capsule with the secure boot keys when PcdFmpDevicePkcs7CertBufferXdr is
not set and the new PCD variable PcdFmpDeviceAllowSecureBootKeys is
configured. Below is the check logic:
- Pass if verified with PK key, or PK key not set yet;
- Deny if verified with the DBX keys;
- Verified it against the DB keys;

One purpose for this change is to auto-deploy the UEFI secure boot keys
with UEFI capsule. Initially it's done in trusted environment.
Once secure boot is enabled, the same keys will be used to verify the signed
capsules as well for further updates.

Signed-off-by: Liming Sun <lsun@mellanox.com>
---
FmpDevicePkg/FmpDevicePkg.dec | 6 +++
FmpDevicePkg/FmpDxe/FmpDxe.c | 109
++++++++++++++++++++++++++++++++++++--
FmpDevicePkg/FmpDxe/FmpDxe.h | 1 +
FmpDevicePkg/FmpDxe/FmpDxe.inf | 3 ++
FmpDevicePkg/FmpDxe/FmpDxeLib.inf | 1 +
5 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/FmpDevicePkg/FmpDevicePkg.dec
b/FmpDevicePkg/FmpDevicePkg.dec index cab63f5..3aeb89c 100644
--- a/FmpDevicePkg/FmpDevicePkg.dec
+++ b/FmpDevicePkg/FmpDevicePkg.dec
@@ -126,6 +126,12 @@
# @Prompt Firmware Device Image Type ID

gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid|{0}|VOID
*|0x40000010

+ ## This option is used to verify the capsule using secure boot keys
+ if the # PcdFmpDevicePkcs7CertBufferXdr is not configured. In such
+ case, the check # will pass if secure boot hasn't been enabled yet.
+ # @A flag to tell whether to use secure boot keys when
PcdFmpDevicePkcs7CertBufferXdr is not set.
+
+
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceAllowSecureBootKeys|0x0|
UINT8|
+ 0x40000012
+
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## One or more PKCS7 certificates used to verify a firmware device capsule
# update image. Encoded using the Variable-Length Opaque Data format
of RFC diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c
b/FmpDevicePkg/FmpDxe/FmpDxe.c index 5884177..6f82aee 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.c
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.c
@@ -682,6 +682,102 @@ GetAllHeaderSize (
return CalculatedSize;
}

+EFI_STATUS
+CheckTheImageWithSecureBootVariable (
+ IN CONST CHAR16 *Name,
+ IN CONST EFI_GUID *Guid,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ UINTN Length;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *CertData;
+ UINTN CertCount;
+ UINTN Index;
+
+ Status = GetVariable2 (Name, Guid, &Data, &Length); if (EFI_ERROR
+ (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ CertList = (EFI_SIGNATURE_LIST *) Data; while ((Length > 0) &&
+ (Length >= CertList->SignatureListSize)) {
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
+ CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList +
+ sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) -
+ CertList->SignatureHeaderSize) / CertList->SignatureSize;
+
+ for (Index = 0; Index < CertCount; Index++) {
+ Status = AuthenticateFmpImage (
+ (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image,
+ ImageSize,
+ CertData->SignatureData,
+ CertList->SignatureSize - sizeof (EFI_GUID)
+ );
+ if (!EFI_ERROR (Status))
+ goto Done;
+
+ CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertData + CertList-
SignatureSize);
+ }
+ }
+
+ Length -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+ CertList->SignatureListSize); }
+
+Done:
+ FreePool (Data);
+ return Status;
+}
+
+EFI_STATUS
+CheckTheImageWithSecureBootKeys (
+ IN CONST VOID *Image,
+ IN UINTN ImageSize
+ )
+{
+ EFI_STATUS Status;
+
+ // PK check.
+ Status = CheckTheImageWithSecureBootVariable(
+ EFI_PLATFORM_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ Image,
+ ImageSize
+ );
+ if (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND) {
+ // Return SUCCESS if verified by PK key or PK key not configured.
+ DEBUG ((DEBUG_INFO, "FmpDxe: Verified capsule with PK key.\n"));
+ return EFI_SUCCESS;
+ }
+
+ // DBX check.
+ Status = CheckTheImageWithSecureBootVariable(
+ EFI_IMAGE_SECURITY_DATABASE1,
+ &gEfiImageSecurityDatabaseGuid,
+ Image,
+ ImageSize
+ );
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "FmpDxe: Reject capsule with DBX key.\n"));
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ // DB check.
+ DEBUG ((DEBUG_INFO, "FmpDxe: Verify capsule with DB key.\n"));
+ Status = CheckTheImageWithSecureBootVariable(
+ EFI_IMAGE_SECURITY_DATABASE,
+ &gEfiImageSecurityDatabaseGuid,
+ Image,
+ ImageSize
+ );
+ return Status;
+}
+
/**
Checks if the firmware image is valid for the device.

@@ -728,6 +824,7 @@ CheckTheImage (
UINT8 *PublicKeyDataXdrEnd;
EFI_FIRMWARE_IMAGE_DEP *Dependencies;
UINT32 DependenciesSize;
+ UINT8 AllowSecureBootKeys;

Status = EFI_SUCCESS;
RawSize = 0;
@@ -782,9 +879,15 @@ CheckTheImage (
PublicKeyDataXdr = PcdGetPtr (PcdFmpDevicePkcs7CertBufferXdr);
PublicKeyDataXdrEnd = PublicKeyDataXdr + PcdGetSize
(PcdFmpDevicePkcs7CertBufferXdr);

- if (PublicKeyDataXdr == NULL || (PublicKeyDataXdr ==
PublicKeyDataXdrEnd)) {
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Invalid certificate, skipping it.\n",
mImageIdName));
- Status = EFI_ABORTED;
+ if (PublicKeyDataXdr == NULL || (PublicKeyDataXdrEnd - PublicKeyDataXdr
< sizeof (UINT32))) {
+ AllowSecureBootKeys = PcdGet8 (PcdFmpDeviceAllowSecureBootKeys);
+ if (AllowSecureBootKeys) {
+ DEBUG ((DEBUG_INFO, "FmpDxe: Use secure boot certs.\n"));
+ Status = CheckTheImageWithSecureBootKeys (Image, ImageSize);
+ } else {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Invalid certificate, skipping
it.\n", mImageIdName));
+ Status = EFI_ABORTED;
+ }
} else {
//
// Try each key from PcdFmpDevicePkcs7CertBufferXdr diff --git
a/FmpDevicePkg/FmpDxe/FmpDxe.h b/FmpDevicePkg/FmpDxe/FmpDxe.h
index 30754de..72a6ce6 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.h
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.h
@@ -34,6 +34,7 @@
#include <Protocol/FirmwareManagement.h> #include
<Protocol/FirmwareManagementProgress.h>
#include <Protocol/VariableLock.h>
+#include <Guid/ImageAuthentication.h>
#include <Guid/SystemResourceTable.h>
#include <Guid/EventGroup.h>

diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.inf
b/FmpDevicePkg/FmpDxe/FmpDxe.inf index eeb904a..60b02d4 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.inf
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf
@@ -58,6 +58,8 @@

[Guids]
gEfiEndOfDxeEventGroupGuid
+ gEfiCertX509Guid
+ gEfiImageSecurityDatabaseGuid

[Protocols]
gEdkiiVariableLockProtocolGuid ## CONSUMES
@@ -74,6 +76,7 @@
gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr
## CONSUMES
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest
## CONSUMES
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid
## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceAllowSecureBootKeys
## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ##
SOMETIMES_PRODUCES

[Depex]
diff --git a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
index 9a93b5e..1308cae 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
+++ b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
@@ -74,6 +74,7 @@
gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr
## CONSUMES
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest
## CONSUMES
gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid
## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceAllowSecureBootKeys
## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ##
SOMETIMES_PRODUCES

[Depex]
--
1.8.3.1



Re: Standalone AcpiView

Gao, Zhichao
 

Hi Tomas,

 

I already reopen then pull request and add the push label. It would be merged after passing the open-CI check.

 

Thanks,

Zhichao

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Tomas Pilar (tpilar)
Sent: Monday, June 29, 2020 10:25 PM
To: devel@edk2.groups.io; Tomas Pilar <Tomas.Pilar@...>
Cc: Ni, Ray <ray.ni@...>; Gao, Zhichao <zhichao.gao@...>; Sami Mujawar <Sami.Mujawar@...>; nd <nd@...>
Subject: Re: [edk2-devel] Standalone AcpiView

 

Oh, it looks like any pull requests created by non-maintainers get auto-closed by mergify. Nevermind then.

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Tomas Pilar (tpilar) via groups.io
Sent: 29 June 2020 15:11
To:
devel@edk2.groups.io
Cc: Ray Ni <
ray.ni@...>; Zhichao Gao <zhichao.gao@...>; Sami Mujawar <Sami.Mujawar@...>
Subject: [edk2-devel] Standalone AcpiView

 

Hi Ray, Zhichao,

 

I’ve created a pull request with the standalone acpiview patches for your convenience. Could you please merge it once it passes the CI checks?

 

Cheers,

Tom

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [edk2-platforms][PATCH 1/1] Platform/RaspberryPi/Drivers: Add SD card detection

Andrei Warkentin
 

Looks good to me, but I would like to (personally) first test on CM3 (which has eMMC), before this is merged. Stay tuned...

And thanks again for working on this. I like the approach taken.


From: Pete Batard <pete@...>
Sent: Monday, June 29, 2020 1:36 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: ard.biesheuvel@... <ard.biesheuvel@...>; leif@... <leif@...>; Andrei Warkentin <awarkentin@...>
Subject: [edk2-platforms][PATCH 1/1] Platform/RaspberryPi/Drivers: Add SD card detection
 
The Raspberry Pi 3 and Pi 4 platforms (with latest EEPROM) can boot
straight from USB, without the need for an SD card being present.
However, the IsCardPresent () calls from the ArasanMmcHost and SdHost
drivers are currently hardwired to return TRUE, which results in
straight to USB boot failing due to the SD drivers looping on
errors while trying to poke at a non-existent card...

Ideally, we would use the Card Detect signal from the uSD slot, to
report on the presence or absence of a card, but the Raspberry Pi
Foundation did not wire those signals in the Pi 2 and subsequent
models, leaving us with only potentially interfering SD commands
as means to perform card detection.

As a result of this, we are left with no other choice but limit
detection to occurring only once, prior to formal SD card init,
and then return the detected value for subsequent calls. This,
however, is more than good enough for the intended purpose, which
is to allow straight to USB boot.

Tested on Raspberry Pi 3 and 4, and for both SD controllers.

Addresses pftf/RPi3#13, pftf/RPi3#14, pftf/RPi4#37.

Signed-off-by: Pete Batard <pete@...>
---
 Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c | 66 ++++++++++++++++---
 Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c               | 69 +++++++++++++++++---
 Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h               |  6 ++
 3 files changed, 122 insertions(+), 19 deletions(-)

diff --git a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c
index 6d706af6f276..08e5be1f015f 100644
--- a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c
+++ b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c
@@ -11,7 +11,8 @@
 
 #define DEBUG_MMCHOST_SD DEBUG_VERBOSE
 
-BOOLEAN PreviousIsCardPresent = FALSE;
+BOOLEAN CardIsPresent = FALSE;
+CARD_DETECT_STATE CardDetectState = CardDetectRequired;
 UINT32 LastExecutedCommand = (UINT32) -1;
 
 STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL *mFwProtocol;
@@ -239,14 +240,6 @@ CalculateClockFrequencyDivisor (
   return EFI_SUCCESS;
 }
 
-BOOLEAN
-MMCIsCardPresent (
-  IN EFI_MMC_HOST_PROTOCOL *This
-)
-{
-  return TRUE;
-}
-
 BOOLEAN
 MMCIsReadOnly (
   IN EFI_MMC_HOST_PROTOCOL *This
@@ -418,6 +411,10 @@ MMCNotifyState (
 
   DEBUG ((DEBUG_MMCHOST_SD, "ArasanMMCHost: MMCNotifyState(State: %d)\n", State));
 
+  // Stall all operations except init until card detection has occurred.
+  if (State != MmcHwInitializationState && CardDetectState != CardDetectCompleted)
+    return EFI_NOT_READY;
+
   switch (State) {
   case MmcHwInitializationState:
     {
@@ -489,6 +486,57 @@ MMCNotifyState (
   return EFI_SUCCESS;
 }
 
+BOOLEAN
+MMCIsCardPresent (
+  IN EFI_MMC_HOST_PROTOCOL *This
+)
+{
+  EFI_STATUS Status;
+
+  //
+  // If we are already in progress (we may get concurrent calls)
+  // or completed the detection, just return the current value.
+  //
+  if (CardDetectState != CardDetectRequired)
+    return CardIsPresent;
+
+  CardDetectState = CardDetectInProgress;
+  CardIsPresent = FALSE;
+
+  //
+  // The two following commands should succeed even if no card is present.
+  //
+  Status = MMCNotifyState (This, MmcHwInitializationState);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "MMCIsCardPresent: Error MmcHwInitializationState, Status=%r.\n", Status));
+    // If we failed init, go back to requiring card detection
+    CardDetectState = CardDetectRequired;
+    return FALSE;
+  }
+
+  Status = MMCSendCommand (This, MMC_CMD0, 0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "MMCIsCardPresent: CMD0 Error, Status=%r.\n", Status));
+    goto out;
+  }
+
+  //
+  // CMD8 should tell us if a card is present.
+  //
+  Status = MMCSendCommand (This, MMC_CMD8, CMD8_SD_ARG);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "MMCIsCardPresent: No card detected, Status=%r.\n", Status));
+    goto out;
+  }
+
+  DEBUG ((DEBUG_INFO, "MMCIsCardPresent: Card detected.\n"));
+  CardIsPresent = TRUE;
+
+out:
+  CardDetectState = CardDetectCompleted;
+  return CardIsPresent;
+}
+
 EFI_STATUS
 MMCReceiveResponse (
   IN EFI_MMC_HOST_PROTOCOL    *This,
diff --git a/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c b/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c
index 2f31c5eb8c46..d96344fd0f8e 100644
--- a/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c
+++ b/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c
@@ -64,7 +64,9 @@ STATIC CONST CHAR8 *mFsmState[] = { "identmode", "datamode", "readdata",
                                     "genpulses", "writewait2", "?",
                                     "startpowdown" };
 #endif /* NDEBUG */
-STATIC UINT32 mLastGoodCmd = MMC_GET_INDX (MMC_CMD0);
+STATIC BOOLEAN CardIsPresent = FALSE;
+STATIC CARD_DETECT_STATE CardDetectState = CardDetectRequired;
+static UINT32 mLastGoodCmd = MMC_GET_INDX (MMC_CMD0);
 
 STATIC inline BOOLEAN
 IsAppCmd (
@@ -264,15 +266,7 @@ SdHostSetClockFrequency (
   return Status;
 }
 
-STATIC BOOLEAN
-SdIsCardPresent (
-  IN EFI_MMC_HOST_PROTOCOL *This
-  )
-{
-  return TRUE;
-}
-
-STATIC BOOLEAN
+static BOOLEAN
 SdIsReadOnly (
   IN EFI_MMC_HOST_PROTOCOL *This
   )
@@ -639,6 +633,10 @@ SdNotifyState (
 {
   DEBUG ((DEBUG_MMCHOST_SD, "SdHost: SdNotifyState(State: %d) ", State));
 
+  // Stall all operations except init until card detection has occurred.
+  if (State != MmcHwInitializationState && CardDetectState != CardDetectCompleted)
+    return EFI_NOT_READY;
+
   switch (State) {
   case MmcHwInitializationState:
     DEBUG ((DEBUG_MMCHOST_SD, "MmcHwInitializationState\n", State));
@@ -718,6 +716,57 @@ SdNotifyState (
   return EFI_SUCCESS;
 }
 
+STATIC BOOLEAN
+SdIsCardPresent (
+  IN EFI_MMC_HOST_PROTOCOL *This
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // If we are already in progress (we may get concurrent calls)
+  // or completed the detection, just return the current value.
+  //
+  if (CardDetectState != CardDetectRequired)
+    return CardIsPresent;
+
+  CardDetectState = CardDetectInProgress;
+  CardIsPresent = FALSE;
+
+  //
+  // The two following commands should succeed even if no card is present.
+  //
+  Status = SdNotifyState (This, MmcHwInitializationState);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "SdIsCardPresent: Error MmcHwInitializationState, Status=%r.\n", Status));
+    // If we failed init, go back to requiring card detection
+    CardDetectState = CardDetectRequired;
+    return FALSE;
+  }
+
+  Status = SdSendCommand (This, MMC_CMD0, 0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "SdIsCardPresent: CMD0 Error, Status=%r.\n", Status));
+    goto out;
+  }
+
+  //
+  // CMD8 should tell us if a card is present.
+  //
+  Status = SdSendCommand (This, MMC_CMD8, CMD8_SD_ARG);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "SdIsCardPresent: No card detected, Status=%r.\n", Status));
+    goto out;
+  }
+
+  DEBUG ((DEBUG_INFO, "SdIsCardPresent: Card detected.\n"));
+  CardIsPresent = TRUE;
+
+out:
+  CardDetectState = CardDetectCompleted;
+  return CardIsPresent;
+}
+
 BOOLEAN
 SdIsMultiBlock (
   IN EFI_MMC_HOST_PROTOCOL *This
diff --git a/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h b/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h
index c558e00bf500..78514a31bc4e 100644
--- a/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h
+++ b/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h
@@ -82,6 +82,12 @@ typedef enum _MMC_STATE {
     MmcDisconnectState,
 } MMC_STATE;
 
+typedef enum _CARD_DETECT_STATE {
+    CardDetectRequired = 0,
+    CardDetectInProgress,
+    CardDetectCompleted
+} CARD_DETECT_STATE;
+
 #define EMMCBACKWARD         (0)
 #define EMMCHS26             (1 << 0)      // High-Speed @26MHz at rated device voltages
 #define EMMCHS52             (1 << 1)      // High-Speed @52MHz at rated device voltages
--
2.21.0.windows.1


Upcoming Event: TianoCore Bug Triage - APAC / NAMO - Tue, 06/30/2020 6:30pm-7:30pm #cal-reminder

devel@edk2.groups.io Calendar <devel@...>
 

Reminder: TianoCore Bug Triage - APAC / NAMO

When: Tuesday, 30 June 2020, 6:30pm to 7:30pm, (GMT-07:00) America/Los Angeles

Where:https://bluejeans.com/889357567?src=join_info

View Event

Organizer: Brian Richardson brian.richardson@...

Description:

https://www.tianocore.org/bug-triage

 

Meeting URL

https://bluejeans.com/889357567?src=join_info

 

Meeting ID

889 357 567

 

Want to dial in from a phone?

Dial one of the following numbers:

+1.408.740.7256 (US (San Jose))

+1.408.317.9253 (US (Primary, San Jose))

 

(see all numbers - https://www.bluejeans.com/numbers)

Enter the meeting ID and passcode followed by #


Re: [PATCH edk2 v1 1/1] MdeModulePkg/Variable: Move FindVariable after AutoUpdateLangVariable

Guomin Jiang
 

Hi Huang,

From issue statement, I guess that
1. AutoUpdateLangVariable() invoked, and it will invoke FindVariable() first, at the same time, reclaim occur and Variable.CurrPtr is invalid, it return with success
2. UpdateVariable() is invoked when The old Lang's State is valid and the new Lang's State is also valid.
3. In the situation, FindVariable() checked Lang's State and only enable one Lang's State. But it didn't in fact.
4. BmForEachVariable() deadloop in the situation.

Am I right?

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Ming
Huang via groups.io
Sent: Monday, June 29, 2020 2:06 PM
To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A
<hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>
Cc: lidongzhan@huawei.com; huangming23@huawei.com;
songdongkuang@huawei.com; wanghuiqiang@huawei.com;
qiuliangen@huawei.com; shenlimei@huawei.com; xiewenyi2@huawei.com
Subject: [edk2-devel] [PATCH edk2 v1 1/1] MdeModulePkg/Variable: Move
FindVariable after AutoUpdateLangVariable

When occur reclaim in AutoUpdateLangVariable(), the CurrPtr of Variable is
invalid. The State will be update with wrong position after UpdateVariable in
this situation and two valid PlatformLang or Lang variables will exist.
BmForEachVariable() will enter endless loop while exist two valid
PlatformLang variables. So FindVariable() should be invoked atfer
AutoUpdateLangVariable().

https://bugzilla.tianocore.org/show_bug.cgi?id=2667

Signed-off-by: Ming Huang <huangming23@huawei.com>
---
MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | 26
++++++++++----------
1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index 1e71fc6..0cec981 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -2741,6 +2741,19 @@ VariableServiceSetVariable (
mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN)
NextVariable - (UINTN) Point;
}

+ if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
+ //
+ // Hook the operation of setting PlatformLangCodes/PlatformLang and
LangCodes/Lang.
+ //
+ Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
+ if (EFI_ERROR (Status)) {
+ //
+ // The auto update operation failed, directly return to avoid
inconsistency between PlatformLang and Lang.
+ //
+ goto Done;
+ }
+ }
+
//
// Check whether the input variable is already existed.
//
@@ -2763,19 +2776,6 @@ VariableServiceSetVariable (
}
}

- if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
- //
- // Hook the operation of setting PlatformLangCodes/PlatformLang and
LangCodes/Lang.
- //
- Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
- if (EFI_ERROR (Status)) {
- //
- // The auto update operation failed, directly return to avoid inconsistency
between PlatformLang and Lang.
- //
- goto Done;
- }
- }
-
if (mVariableModuleGlobal->VariableGlobal.AuthSupport) {
Status = AuthVariableLibProcessVariable (VariableName, VendorGuid,
Data, DataSize, Attributes);
} else {
--
2.8.1



Re: [PATCH v1 0/3] Add EDKII CI support for DynamicTablesPkg

Sean
 

Two additional questions/comments with this patch set.

1. Is this package not compatible with MSVC toolchain? From the readme update it looks like GCC/Ubuntu only. From the DSC it looks like ARM|AARCH64 only? Is there any reason this isn't compatible?

2. You need one more patch to get this run as part of CI.
You need to add the package to the matrix.
https://github.com/tianocore/edk2/blob/master/.azurepipelines/templates/pr-gate-build-job.yml#L38

It can probably be added in with an existing package. Usually i look over the build job summary and find a job with less than the max time and has similar packages and then add it there.
For example looking at the CI GCC build here: https://dev.azure.com/tianocore/edk2-ci/_build/results?buildId=8964&view=results

It looks like adding to FMP_FAT_TEST would work.

Thanks
Sean

On 6/29/2020 6:27 AM, Sami Mujawar wrote:
The TianoCore EDKII project has introduced a Core CI infrastructure
using TianoCore EDKII Tools PIP modules.
This patch series adds support for building DynamicTablesPkg using
the EKDII Core CI.
The changes can be seen at:
https://github.com/samimujawar/edk2/tree/839_dynamictablespkg_ci_v1
Sami Mujawar (3):
DynamicTablesPkg: Fix issues reported by EDKII CI
DynamicTablesPkg: Add EDK2 Core CI support
.pytool: CI Settings to support DynamicTablesPkg
.pytool/CISettings.py | 2 +
.pytool/Readme.md | 2 +-
DynamicTablesPkg/DynamicTablesPkg.ci.yaml | 103 ++++++++++++++++++++
DynamicTablesPkg/DynamicTablesPkg.dec | 7 +-
DynamicTablesPkg/DynamicTablesPkg.dsc | 4 +-
DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 6 +-
DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c | 4 +-
DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c | 8 +-
DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c | 12 +--
DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c | 6 +-
DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c | 4 +-
DynamicTablesPkg/Readme.md | 73 +++++++++++++-
12 files changed, 205 insertions(+), 26 deletions(-)
create mode 100644 DynamicTablesPkg/DynamicTablesPkg.ci.yaml


[edk2-platforms][PATCH 1/1] Silicon/Broadcom/Bcm283x: GpioLib enhancements

Pete Batard
 

* Add GpioPinSet () function to set a GPIO pin value
* Add GpioPinGet () function to read a GPIO pin value
* Add GpioSetPull () function to set pullup/down state of a GPIO pin

GpioSetPull () supports both the legacy method used on Bcm283[5-7]
as well as the new method used on Bcm2711.

Each of these calls was tested on Raspberry Pi 3 B+ as well as on a
Raspberry Pi 4 B.

Signed-off-by: Pete Batard <pete@akeo.ie>
---
Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h | 44 ++++++++-
Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h | 17 ++++
Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c | 93 ++++++++++++++++++++
Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf | 1 +
4 files changed, 152 insertions(+), 3 deletions(-)

diff --git a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h
index e65cc5c3bbb4..8ad81776b43a 100644
--- a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h
+++ b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h
@@ -1,5 +1,6 @@
/** @file
*
+ * Copyright (c) 2020, Pete Batard <pete@akeo.ie>
* Copyright (c) 2018, Andrei Warkentin <andrey.warkentin@gmail.com>
* Copyright (c) Microsoft Corporation. All rights reserved.
*
@@ -23,12 +24,45 @@
#define GPIO_GPFSEL4 (GPIO_BASE_ADDRESS + 0x10)
#define GPIO_GPFSEL5 (GPIO_BASE_ADDRESS + 0x14)

-#define GPIO_GPCLR0 (GPIO_BASE_ADDRESS + 0x28)
-#define GPIO_GPCLR1 (GPIO_BASE_ADDRESS + 0x2C)
-
#define GPIO_GPSET0 (GPIO_BASE_ADDRESS + 0x1C)
#define GPIO_GPSET1 (GPIO_BASE_ADDRESS + 0x20)

+#define GPIO_GPCLR0 (GPIO_BASE_ADDRESS + 0x28)
+#define GPIO_GPCLR1 (GPIO_BASE_ADDRESS + 0x2C)
+
+#define GPIO_GPLEV0 (GPIO_BASE_ADDRESS + 0x34)
+#define GPIO_GPLEV1 (GPIO_BASE_ADDRESS + 0x38)
+
+#define GPIO_GPEDS0 (GPIO_BASE_ADDRESS + 0x40)
+#define GPIO_GPEDS1 (GPIO_BASE_ADDRESS + 0x44)
+
+#define GPIO_GPREN0 (GPIO_BASE_ADDRESS + 0x4C)
+#define GPIO_GPREN1 (GPIO_BASE_ADDRESS + 0x50)
+
+#define GPIO_GPFEN0 (GPIO_BASE_ADDRESS + 0x58)
+#define GPIO_GPFEN1 (GPIO_BASE_ADDRESS + 0x5C)
+
+#define GPIO_GPHEN0 (GPIO_BASE_ADDRESS + 0x64)
+#define GPIO_GPHEN1 (GPIO_BASE_ADDRESS + 0x68)
+
+#define GPIO_GPLEN0 (GPIO_BASE_ADDRESS + 0x70)
+#define GPIO_GPLEN1 (GPIO_BASE_ADDRESS + 0x74)
+
+#define GPIO_GPAREN0 (GPIO_BASE_ADDRESS + 0x7C)
+#define GPIO_GPAREN1 (GPIO_BASE_ADDRESS + 0x80)
+
+#define GPIO_GPAFEN0 (GPIO_BASE_ADDRESS + 0x88)
+#define GPIO_GPAFEN1 (GPIO_BASE_ADDRESS + 0x8C)
+
+#define GPIO_GPPUD (GPIO_BASE_ADDRESS + 0x94)
+#define GPIO_GPPUDCLK0 (GPIO_BASE_ADDRESS + 0x98)
+#define GPIO_GPPUDCLK1 (GPIO_BASE_ADDRESS + 0x9C)
+
+#define GPIO_GPPUPPDN0 (GPIO_BASE_ADDRESS + 0xE4)
+#define GPIO_GPPUPPDN1 (GPIO_BASE_ADDRESS + 0xE8)
+#define GPIO_GPPUPPDN2 (GPIO_BASE_ADDRESS + 0xEC)
+#define GPIO_GPPUPPDN3 (GPIO_BASE_ADDRESS + 0xF0)
+
#define GPIO_FSEL_INPUT 0x0
#define GPIO_FSEL_OUTPUT 0x1
#define GPIO_FSEL_ALT0 0x4
@@ -44,4 +78,8 @@

#define GPIO_PINS 54

+#define GPIO_PULL_NONE 0x00
+#define GPIO_PULL_DOWN 0x01
+#define GPIO_PULL_UP 0x02
+
#endif /* __BCM2836_GPIO_H__ */
diff --git a/Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h b/Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h
index 014c6b07a29f..75c2c8be51aa 100644
--- a/Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h
+++ b/Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h
@@ -24,4 +24,21 @@ GpioPinFuncGet (
IN UINTN Pin
);

+VOID
+GpioPinSet (
+ IN UINTN Pin,
+ IN UINTN Val
+ );
+
+UINTN
+GpioPinGet (
+ IN UINTN Pin
+ );
+
+VOID
+GpioSetPull (
+ IN UINTN Pin,
+ IN UINTN Pud
+);
+
#endif /* __GPIO_LIB__ */
diff --git a/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c b/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c
index 542b6e8f6b2f..a4b4af59ebb1 100644
--- a/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c
+++ b/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c
@@ -2,6 +2,7 @@
*
* GPIO manipulation.
*
+ * Copyright (c) 2020, Pete Batard <pete@akeo.ie>
* Copyright (c) 2018, Andrei Warkentin <andrey.warkentin@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -13,6 +14,7 @@
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/GpioLib.h>
+#include <Library/TimerLib.h>
#include <IndustryStandard/Bcm2836.h>
#include <IndustryStandard/Bcm2836Gpio.h>

@@ -81,3 +83,94 @@ GpioPinFuncGet (
Val &= GPIO_FSEL_MASK;
return Val;
}
+
+VOID
+GpioPinSet (
+ IN UINTN Pin,
+ IN UINTN Val
+ )
+{
+ EFI_PHYSICAL_ADDRESS Reg;
+ UINTN RegIndex;
+ UINTN SelIndex;
+
+ ASSERT (Pin < GPIO_PINS);
+
+ RegIndex = Pin / 32;
+ SelIndex = Pin % 32;
+
+ //
+ // Different base addresses are used for clear and set
+ //
+ Reg = (Val == 0) ? GPIO_GPCLR0 : GPIO_GPSET0;
+ Reg += RegIndex * sizeof (UINT32);
+ MmioWrite32 (Reg, 1 << SelIndex);
+}
+
+UINTN
+GpioPinGet (
+ IN UINTN Pin
+ )
+{
+ EFI_PHYSICAL_ADDRESS Reg;
+ UINTN RegIndex;
+ UINTN SelIndex;
+ UINT32 Val;
+
+ ASSERT (Pin < GPIO_PINS);
+
+ RegIndex = Pin / 32;
+ SelIndex = Pin % 32;
+
+ Reg = RegIndex * sizeof (UINT32) + GPIO_GPLEV0;
+ Val = MmioRead32 (Reg) >> SelIndex;
+ return Val & 1;
+}
+
+VOID
+GpioSetPull (
+ IN UINTN Pin,
+ IN UINTN Pud
+)
+{
+ EFI_PHYSICAL_ADDRESS Reg;
+ UINTN RegIndex;
+ UINTN SelIndex;
+ UINT32 Val;
+
+ ASSERT (Pin < GPIO_PINS);
+ ASSERT (Pud <= GPIO_PULL_UP);
+
+ //
+ // Check if we should use the legacy or newer method of
+ // enabling pullup/pulldown by querying GPPUPPDN3, which
+ // is unused on Bcm2835/2836/2837 and returns 'gpio'.
+ //
+ if (MmioRead32 (GPIO_GPPUPPDN3) == 0x6770696f) {
+ RegIndex = Pin / 32;
+ SelIndex = Pin % 32;
+
+ MmioWrite32 (GPIO_GPPUD, Pud);
+ MicroSecondDelay (5);
+
+ Reg = RegIndex * sizeof (UINT32) + GPIO_GPPUDCLK0;
+ MmioWrite32 (Reg, 1 << SelIndex);
+ MicroSecondDelay (5);
+
+ MmioWrite32 (GPIO_GPPUD, 0);
+ MmioWrite32 (Reg, 0);
+ } else {
+ //
+ // The newer method uses inverted values for up/down.
+ //
+ if (Pud != 0)
+ Pud ^= 0x3;
+ RegIndex = Pin / 16;
+ SelIndex = (Pin % 16) * 2;
+ Reg = RegIndex * sizeof (UINT32) + GPIO_GPPUPPDN0;
+ Val = MmioRead32 (Reg);
+ Val &= ~(0x3 << SelIndex);
+ Val |= Pud << SelIndex;
+ MmioWrite32 (Reg, Val);
+ }
+}
diff --git a/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf b/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf
index ff1b5af6db6e..a0356306d83c 100644
--- a/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf
+++ b/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf
@@ -30,6 +30,7 @@ [LibraryClasses]
BaseLib
DebugLib
IoLib
+ TimerLib

[FixedPcd]
gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress
--
2.21.0.windows.1


[edk2-platforms][PATCH 1/1] Platform/RaspberryPi/Drivers: Add SD card detection

Pete Batard
 

The Raspberry Pi 3 and Pi 4 platforms (with latest EEPROM) can boot
straight from USB, without the need for an SD card being present.
However, the IsCardPresent () calls from the ArasanMmcHost and SdHost
drivers are currently hardwired to return TRUE, which results in
straight to USB boot failing due to the SD drivers looping on
errors while trying to poke at a non-existent card...

Ideally, we would use the Card Detect signal from the uSD slot, to
report on the presence or absence of a card, but the Raspberry Pi
Foundation did not wire those signals in the Pi 2 and subsequent
models, leaving us with only potentially interfering SD commands
as means to perform card detection.

As a result of this, we are left with no other choice but limit
detection to occurring only once, prior to formal SD card init,
and then return the detected value for subsequent calls. This,
however, is more than good enough for the intended purpose, which
is to allow straight to USB boot.

Tested on Raspberry Pi 3 and 4, and for both SD controllers.

Addresses pftf/RPi3#13, pftf/RPi3#14, pftf/RPi4#37.

Signed-off-by: Pete Batard <pete@akeo.ie>
---
Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c | 66 ++++++++++++++++---
Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c | 69 +++++++++++++++++---
Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h | 6 ++
3 files changed, 122 insertions(+), 19 deletions(-)

diff --git a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c
index 6d706af6f276..08e5be1f015f 100644
--- a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c
+++ b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c
@@ -11,7 +11,8 @@

#define DEBUG_MMCHOST_SD DEBUG_VERBOSE

-BOOLEAN PreviousIsCardPresent = FALSE;
+BOOLEAN CardIsPresent = FALSE;
+CARD_DETECT_STATE CardDetectState = CardDetectRequired;
UINT32 LastExecutedCommand = (UINT32) -1;

STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL *mFwProtocol;
@@ -239,14 +240,6 @@ CalculateClockFrequencyDivisor (
return EFI_SUCCESS;
}

-BOOLEAN
-MMCIsCardPresent (
- IN EFI_MMC_HOST_PROTOCOL *This
-)
-{
- return TRUE;
-}
-
BOOLEAN
MMCIsReadOnly (
IN EFI_MMC_HOST_PROTOCOL *This
@@ -418,6 +411,10 @@ MMCNotifyState (

DEBUG ((DEBUG_MMCHOST_SD, "ArasanMMCHost: MMCNotifyState(State: %d)\n", State));

+ // Stall all operations except init until card detection has occurred.
+ if (State != MmcHwInitializationState && CardDetectState != CardDetectCompleted)
+ return EFI_NOT_READY;
+
switch (State) {
case MmcHwInitializationState:
{
@@ -489,6 +486,57 @@ MMCNotifyState (
return EFI_SUCCESS;
}

+BOOLEAN
+MMCIsCardPresent (
+ IN EFI_MMC_HOST_PROTOCOL *This
+)
+{
+ EFI_STATUS Status;
+
+ //
+ // If we are already in progress (we may get concurrent calls)
+ // or completed the detection, just return the current value.
+ //
+ if (CardDetectState != CardDetectRequired)
+ return CardIsPresent;
+
+ CardDetectState = CardDetectInProgress;
+ CardIsPresent = FALSE;
+
+ //
+ // The two following commands should succeed even if no card is present.
+ //
+ Status = MMCNotifyState (This, MmcHwInitializationState);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "MMCIsCardPresent: Error MmcHwInitializationState, Status=%r.\n", Status));
+ // If we failed init, go back to requiring card detection
+ CardDetectState = CardDetectRequired;
+ return FALSE;
+ }
+
+ Status = MMCSendCommand (This, MMC_CMD0, 0);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "MMCIsCardPresent: CMD0 Error, Status=%r.\n", Status));
+ goto out;
+ }
+
+ //
+ // CMD8 should tell us if a card is present.
+ //
+ Status = MMCSendCommand (This, MMC_CMD8, CMD8_SD_ARG);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "MMCIsCardPresent: No card detected, Status=%r.\n", Status));
+ goto out;
+ }
+
+ DEBUG ((DEBUG_INFO, "MMCIsCardPresent: Card detected.\n"));
+ CardIsPresent = TRUE;
+
+out:
+ CardDetectState = CardDetectCompleted;
+ return CardIsPresent;
+}
+
EFI_STATUS
MMCReceiveResponse (
IN EFI_MMC_HOST_PROTOCOL *This,
diff --git a/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c b/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c
index 2f31c5eb8c46..d96344fd0f8e 100644
--- a/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c
+++ b/Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.c
@@ -64,7 +64,9 @@ STATIC CONST CHAR8 *mFsmState[] = { "identmode", "datamode", "readdata",
"genpulses", "writewait2", "?",
"startpowdown" };
#endif /* NDEBUG */
-STATIC UINT32 mLastGoodCmd = MMC_GET_INDX (MMC_CMD0);
+STATIC BOOLEAN CardIsPresent = FALSE;
+STATIC CARD_DETECT_STATE CardDetectState = CardDetectRequired;
+static UINT32 mLastGoodCmd = MMC_GET_INDX (MMC_CMD0);

STATIC inline BOOLEAN
IsAppCmd (
@@ -264,15 +266,7 @@ SdHostSetClockFrequency (
return Status;
}

-STATIC BOOLEAN
-SdIsCardPresent (
- IN EFI_MMC_HOST_PROTOCOL *This
- )
-{
- return TRUE;
-}
-
-STATIC BOOLEAN
+static BOOLEAN
SdIsReadOnly (
IN EFI_MMC_HOST_PROTOCOL *This
)
@@ -639,6 +633,10 @@ SdNotifyState (
{
DEBUG ((DEBUG_MMCHOST_SD, "SdHost: SdNotifyState(State: %d) ", State));

+ // Stall all operations except init until card detection has occurred.
+ if (State != MmcHwInitializationState && CardDetectState != CardDetectCompleted)
+ return EFI_NOT_READY;
+
switch (State) {
case MmcHwInitializationState:
DEBUG ((DEBUG_MMCHOST_SD, "MmcHwInitializationState\n", State));
@@ -718,6 +716,57 @@ SdNotifyState (
return EFI_SUCCESS;
}

+STATIC BOOLEAN
+SdIsCardPresent (
+ IN EFI_MMC_HOST_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // If we are already in progress (we may get concurrent calls)
+ // or completed the detection, just return the current value.
+ //
+ if (CardDetectState != CardDetectRequired)
+ return CardIsPresent;
+
+ CardDetectState = CardDetectInProgress;
+ CardIsPresent = FALSE;
+
+ //
+ // The two following commands should succeed even if no card is present.
+ //
+ Status = SdNotifyState (This, MmcHwInitializationState);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SdIsCardPresent: Error MmcHwInitializationState, Status=%r.\n", Status));
+ // If we failed init, go back to requiring card detection
+ CardDetectState = CardDetectRequired;
+ return FALSE;
+ }
+
+ Status = SdSendCommand (This, MMC_CMD0, 0);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SdIsCardPresent: CMD0 Error, Status=%r.\n", Status));
+ goto out;
+ }
+
+ //
+ // CMD8 should tell us if a card is present.
+ //
+ Status = SdSendCommand (This, MMC_CMD8, CMD8_SD_ARG);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "SdIsCardPresent: No card detected, Status=%r.\n", Status));
+ goto out;
+ }
+
+ DEBUG ((DEBUG_INFO, "SdIsCardPresent: Card detected.\n"));
+ CardIsPresent = TRUE;
+
+out:
+ CardDetectState = CardDetectCompleted;
+ return CardIsPresent;
+}
+
BOOLEAN
SdIsMultiBlock (
IN EFI_MMC_HOST_PROTOCOL *This
diff --git a/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h b/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h
index c558e00bf500..78514a31bc4e 100644
--- a/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h
+++ b/Platform/RaspberryPi/Include/Protocol/RpiMmcHost.h
@@ -82,6 +82,12 @@ typedef enum _MMC_STATE {
MmcDisconnectState,
} MMC_STATE;

+typedef enum _CARD_DETECT_STATE {
+ CardDetectRequired = 0,
+ CardDetectInProgress,
+ CardDetectCompleted
+} CARD_DETECT_STATE;
+
#define EMMCBACKWARD (0)
#define EMMCHS26 (1 << 0) // High-Speed @26MHz at rated device voltages
#define EMMCHS52 (1 << 1) // High-Speed @52MHz at rated device voltages
--
2.21.0.windows.1


Re: [PATCH v1 2/3] DynamicTablesPkg: Add EDK2 Core CI support

Sami Mujawar
 

Hi Sean,

I realised that the INF files were not listed in the components section, and this is causing the 'DscCompleteCheck' to fail.
I will submit an update patch series with this fixed.

Regards,

Sami Mujawar

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sean via groups.io
Sent: 29 June 2020 06:30 PM
To: devel@edk2.groups.io; Sami Mujawar <Sami.Mujawar@arm.com>
Cc: Alexei Fedorov <Alexei.Fedorov@arm.com>; sean.brogan@microsoft.com; liming.gao@intel.com; michael.d.kinney@intel.com; Bret.Barkelew@microsoft.com; Ard Biesheuvel <Ard.Biesheuvel@arm.com>; Matteo Carlini <Matteo.Carlini@arm.com>; Laura Moretta <Laura.Moretta@arm.com>; nd <nd@arm.com>
Subject: Re: [edk2-devel] [PATCH v1 2/3] DynamicTablesPkg: Add EDK2 Core CI support

Mostly curious but why are there modules not built during ci (The files listed in the DscCompleteCheck[IgnoreInf] list)?

Thanks
Sean




On 6/29/2020 6:27 AM, Sami Mujawar wrote:
The TianoCore EDKII project has introduced a Core CI infrastructure
using TianoCore EDKII Tools PIP modules:
* https://pypi.org/project/edk2-pytool-library/
* https://pypi.org/project/edk2-pytool-extensions/

The edk2\.pytool\Readme.md provides information to configure the
environment and to run local builds.

This patch defines the necessary settings for enabling the Core CI
builds for DynamicTablesPkg.
- Add DynamicTablesPkg.ci.yaml for Core CI
- Update ReadMe.md for details and instructions

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTablesPkg.ci.yaml | 103 ++++++++++++++++++++
DynamicTablesPkg/Readme.md | 71 ++++++++++++++
2 files changed, 174 insertions(+)

diff --git a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
new file mode 100644
index
0000000000000000000000000000000000000000..637e5450e3105bb90082924dfa30
cf55cdea1e50
--- /dev/null
+++ b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
@@ -0,0 +1,103 @@
+## @file
+# CI configuration for DynamicTablesPkg # # Copyright (c) 2020, ARM
+Limited. All rights reserved.<BR> # SPDX-License-Identifier:
+BSD-2-Clause-Patent ## {
+ ## options defined .pytool/Plugin/CompilerPlugin
+ "CompilerPlugin": {
+ "DscPath": "DynamicTablesPkg.dsc"
+ },
+
+ ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+ "HostUnitTestCompilerPlugin": {
+ "DscPath": "" # Don't support this test
+ },
+
+ ## options defined .pytool/Plugin/CharEncodingCheck
+ "CharEncodingCheck": {
+ "IgnoreFiles": []
+ },
+
+ ## options defined .pytool/Plugin/DependencyCheck
+ "DependencyCheck": {
+ "AcceptableDependencies": [
+ "ArmPlatformPkg/ArmPlatformPkg.dec",
+ "EmbeddedPkg/EmbeddedPkg.dec",
+ "DynamicTablesPkg/DynamicTablesPkg.dec",
+ "MdeModulePkg/MdeModulePkg.dec",
+ "MdePkg/MdePkg.dec"
+ ],
+ # For host based unit tests
+ "AcceptableDependencies-HOST_APPLICATION":[
+ "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+ ],
+ # For UEFI shell based apps
+ "AcceptableDependencies-UEFI_APPLICATION":[],
+ "IgnoreInf": []
+ },
+
+ ## options defined .pytool/Plugin/DscCompleteCheck
+ "DscCompleteCheck": {
+ "IgnoreInf": [
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf"
+ ],
+ "DscPath": "DynamicTablesPkg.dsc"
+ },
+
+ ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+ "HostUnitTestDscCompleteCheck": {
+ "IgnoreInf": [""],
+ "DscPath": "" # Don't support this test
+ },
+
+ ## options defined .pytool/Plugin/GuidCheck
+ "GuidCheck": {
+ "IgnoreGuidName": [],
+ "IgnoreGuidValue": [],
+ "IgnoreFoldersAndFiles": [],
+ "IgnoreDuplicates": [],
+ },
+
+ ## options defined .pytool/Plugin/LibraryClassCheck
+ "LibraryClassCheck": {
+ "IgnoreHeaderFile": []
+ },
+
+ ## options defined .pytool/Plugin/SpellCheck
+ "SpellCheck": {
+ "AuditOnly": False,
+ "IgnoreFiles": [], # use gitignore syntax to ignore errors
+ # in matching files
+ "ExtendWords": [
+ "CCIDX",
+ "CCSIDR",
+ "countof",
+ "EOBJECT",
+ "GTBLOCK",
+ "MPIDR",
+ "pytool",
+ "Roadmap",
+ "SMMUV",
+ "standardised",
+ "TABLEEX",
+ "TNSID",
+ "Vatos",
+ "WBINVD"
+ ], # words to extend to the dictionary for this package
+ "IgnoreStandardPaths": [], # Standard Plugin defined paths that
+ # should be ignore
+ "AdditionalIncludePaths": [] # Additional paths to spell check
+ # (wildcards supported)
+ }
+}
diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md
index
bcaae6daa5fff24d9f62639149e9f82c2665c682..e17ed3ac6fd2fbcaced7d64393b3
16d4d6f75283 100644
--- a/DynamicTablesPkg/Readme.md
+++ b/DynamicTablesPkg/Readme.md
@@ -131,9 +131,80 @@ Ensure that the iASL compiler used for building *Dynamic Tables Framework* has t
This feature was made available in the *ACPICA Compiler update
[Version 20180508](https://www.acpica.org/node/156)*, dated 8 May 2018 (2018-05-08).

+
+Running CI builds locally
+-------------------------
+
+The TianoCore EDKII project has introduced Core CI infrastructure using TianoCore EDKII Tools PIP modules:
+
+ -
+ *[edk2-pytool-library](https://pypi.org/project/edk2-pytool-library)
+ *
+
+ -
+ *[edk2-pytool-extensions](https://pypi.org/project/edk2-pytool-exten
+ sions)*
+
+
+The instructions to setup the CI environment are in
+*'edk2\\.pytool\\Readme.md'*
+
+## Building DynamicTablesPkg with Pytools
+
+1. [Optional] Create a Python Virtual Environment - generally once
+per workspace
+
+ ```
+ python -m venv <name of virtual environment>
+
+ e.g. python -m venv edk2-ci
+ ```
+
+2. [Optional] Activate Virtual Environment - each time new
+shell/command window is opened
+
+ ```
+ <name of virtual environment>/Scripts/activate
+
+ e.g. On a windows host PC run:
+ edk2-ci\Scripts\activate.bat
+ ```
+3. Install Pytools - generally once per virtual env or whenever
+pip-requirements.txt changes
+
+ ```
+ pip install --upgrade -r pip-requirements.txt
+ ```
+
+4. Initialize & Update Submodules - only when submodules updated
+
+ ```
+ stuart_setup -c .pytool/CISettings.py
+ TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+ e.g. stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5
+ ```
+
+5. Initialize & Update Dependencies - only as needed when ext_deps
+change
+
+ ```
+ stuart_update -c .pytool/CISettings.py
+ TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+ e.g. stuart_update -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5
+ ```
+
+6. Compile the basetools if necessary - only when basetools C source
+files change
+
+ ```
+ python BaseTools/Edk2ToolsBuild.py -t <ToolChainTag>
+ ```
+
+7. Compile DynamicTablesPkg
+
+ ```
+ stuart_build-c .pytool/CISettings.py
+ TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+ e.g. stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 -p DynamicTablesPkg -a AARCH64 --verbose
+ ```
+
+ - use `stuart_build -c .pytool/CISettings.py -h` option to see help on additional options.
+
+
Documentation
-------------

Refer to the following presentation from *UEFI Plugfest Seattle 2018*:

[Dynamic Tables Framework: A Step Towards Automatic Generation of
Advanced Configuration and Power Interface (ACPI) & System Management
BIOS (SMBIOS)
Tables](http://www.uefi.org/sites/default/files/resources/Arm_Dynamic%
20Tables%20Framework%20A%20Step%20Towards%20Automatic%20Generation%20o
f%20Advanced%20Configuration%20and%20Power%20Interface%20%28ACPI%29%20
%26%20System%20Management%20BIOS%20%28SMBIOS%29%20Tables%20_0.pdf)
+


Re: [PATCH v1 2/3] DynamicTablesPkg: Add EDK2 Core CI support

Sean
 

Mostly curious but why are there modules not built during ci (The files listed in the DscCompleteCheck[IgnoreInf] list)?

Thanks
Sean

On 6/29/2020 6:27 AM, Sami Mujawar wrote:
The TianoCore EDKII project has introduced a Core CI infrastructure
using TianoCore EDKII Tools PIP modules:
* https://pypi.org/project/edk2-pytool-library/
* https://pypi.org/project/edk2-pytool-extensions/
The edk2\.pytool\Readme.md provides information to configure the
environment and to run local builds.
This patch defines the necessary settings for enabling the Core CI
builds for DynamicTablesPkg.
- Add DynamicTablesPkg.ci.yaml for Core CI
- Update ReadMe.md for details and instructions
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTablesPkg.ci.yaml | 103 ++++++++++++++++++++
DynamicTablesPkg/Readme.md | 71 ++++++++++++++
2 files changed, 174 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..637e5450e3105bb90082924dfa30cf55cdea1e50
--- /dev/null
+++ b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
@@ -0,0 +1,103 @@
+## @file
+# CI configuration for DynamicTablesPkg
+#
+# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+ ## options defined .pytool/Plugin/CompilerPlugin
+ "CompilerPlugin": {
+ "DscPath": "DynamicTablesPkg.dsc"
+ },
+
+ ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+ "HostUnitTestCompilerPlugin": {
+ "DscPath": "" # Don't support this test
+ },
+
+ ## options defined .pytool/Plugin/CharEncodingCheck
+ "CharEncodingCheck": {
+ "IgnoreFiles": []
+ },
+
+ ## options defined .pytool/Plugin/DependencyCheck
+ "DependencyCheck": {
+ "AcceptableDependencies": [
+ "ArmPlatformPkg/ArmPlatformPkg.dec",
+ "EmbeddedPkg/EmbeddedPkg.dec",
+ "DynamicTablesPkg/DynamicTablesPkg.dec",
+ "MdeModulePkg/MdeModulePkg.dec",
+ "MdePkg/MdePkg.dec"
+ ],
+ # For host based unit tests
+ "AcceptableDependencies-HOST_APPLICATION":[
+ "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+ ],
+ # For UEFI shell based apps
+ "AcceptableDependencies-UEFI_APPLICATION":[],
+ "IgnoreInf": []
+ },
+
+ ## options defined .pytool/Plugin/DscCompleteCheck
+ "DscCompleteCheck": {
+ "IgnoreInf": [
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf",
+ "DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf"
+ ],
+ "DscPath": "DynamicTablesPkg.dsc"
+ },
+
+ ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+ "HostUnitTestDscCompleteCheck": {
+ "IgnoreInf": [""],
+ "DscPath": "" # Don't support this test
+ },
+
+ ## options defined .pytool/Plugin/GuidCheck
+ "GuidCheck": {
+ "IgnoreGuidName": [],
+ "IgnoreGuidValue": [],
+ "IgnoreFoldersAndFiles": [],
+ "IgnoreDuplicates": [],
+ },
+
+ ## options defined .pytool/Plugin/LibraryClassCheck
+ "LibraryClassCheck": {
+ "IgnoreHeaderFile": []
+ },
+
+ ## options defined .pytool/Plugin/SpellCheck
+ "SpellCheck": {
+ "AuditOnly": False,
+ "IgnoreFiles": [], # use gitignore syntax to ignore errors
+ # in matching files
+ "ExtendWords": [
+ "CCIDX",
+ "CCSIDR",
+ "countof",
+ "EOBJECT",
+ "GTBLOCK",
+ "MPIDR",
+ "pytool",
+ "Roadmap",
+ "SMMUV",
+ "standardised",
+ "TABLEEX",
+ "TNSID",
+ "Vatos",
+ "WBINVD"
+ ], # words to extend to the dictionary for this package
+ "IgnoreStandardPaths": [], # Standard Plugin defined paths that
+ # should be ignore
+ "AdditionalIncludePaths": [] # Additional paths to spell check
+ # (wildcards supported)
+ }
+}
diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md
index bcaae6daa5fff24d9f62639149e9f82c2665c682..e17ed3ac6fd2fbcaced7d64393b316d4d6f75283 100644
--- a/DynamicTablesPkg/Readme.md
+++ b/DynamicTablesPkg/Readme.md
@@ -131,9 +131,80 @@ Ensure that the iASL compiler used for building *Dynamic Tables Framework* has t
This feature was made available in the *ACPICA Compiler update
[Version 20180508](https://www.acpica.org/node/156)*, dated 8 May 2018 (2018-05-08).
+
+Running CI builds locally
+-------------------------
+
+The TianoCore EDKII project has introduced Core CI infrastructure using TianoCore EDKII Tools PIP modules:
+
+ - *[edk2-pytool-library](https://pypi.org/project/edk2-pytool-library)*
+
+ - *[edk2-pytool-extensions](https://pypi.org/project/edk2-pytool-extensions)*
+
+
+The instructions to setup the CI environment are in *'edk2\\.pytool\\Readme.md'*
+
+## Building DynamicTablesPkg with Pytools
+
+1. [Optional] Create a Python Virtual Environment - generally once per workspace
+
+ ```
+ python -m venv <name of virtual environment>
+
+ e.g. python -m venv edk2-ci
+ ```
+
+2. [Optional] Activate Virtual Environment - each time new shell/command window is opened
+
+ ```
+ <name of virtual environment>/Scripts/activate
+
+ e.g. On a windows host PC run:
+ edk2-ci\Scripts\activate.bat
+ ```
+3. Install Pytools - generally once per virtual env or whenever pip-requirements.txt changes
+
+ ```
+ pip install --upgrade -r pip-requirements.txt
+ ```
+
+4. Initialize & Update Submodules - only when submodules updated
+
+ ```
+ stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+ e.g. stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5
+ ```
+
+5. Initialize & Update Dependencies - only as needed when ext_deps change
+
+ ```
+ stuart_update -c .pytool/CISettings.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+ e.g. stuart_update -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5
+ ```
+
+6. Compile the basetools if necessary - only when basetools C source files change
+
+ ```
+ python BaseTools/Edk2ToolsBuild.py -t <ToolChainTag>
+ ```
+
+7. Compile DynamicTablesPkg
+
+ ```
+ stuart_build-c .pytool/CISettings.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+ e.g. stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 -p DynamicTablesPkg -a AARCH64 --verbose
+ ```
+
+ - use `stuart_build -c .pytool/CISettings.py -h` option to see help on additional options.
+
+
Documentation
-------------
Refer to the following presentation from *UEFI Plugfest Seattle 2018*:
[Dynamic Tables Framework: A Step Towards Automatic Generation of Advanced Configuration and Power Interface (ACPI) & System Management BIOS (SMBIOS) Tables](http://www.uefi.org/sites/default/files/resources/Arm_Dynamic%20Tables%20Framework%20A%20Step%20Towards%20Automatic%20Generation%20of%20Advanced%20Configuration%20and%20Power%20Interface%20%28ACPI%29%20%26%20System%20Management%20BIOS%20%28SMBIOS%29%20Tables%20_0.pdf)
+


[PATCH 3/8] ShellPkg/AcpiView: Modify error message

Tomas Pilar (tpilar)
 

Modify the DumpFile error message to be more in line
with the rest of the error messages in the same file.

Cc: Ray Ni <ray.ni@intel.com>
Cc: Zhichao Gao <zhichao.gao@intel.com>
Signed-off-by: Tomas Pilar <tomas.pilar@arm.com>
---
.../UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
index 9613c16f5703..11e97afabc52 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -147,10 +147,8 @@ ShellDumpBufferToFile (
);

if (EFI_ERROR (Status)) {
- Print (L"ERROR: Failed to write binary file.\n");
+ Print (L"acpiview: Failed to write binary file.\n");
TransferBytes = 0;
- } else {
- Print (L"DONE.\n");
}

ShellCloseFile (&DumpFileHandle);
--
2.24.1.windows.2