MdeModulePkg/NvmExpressPei: Use PCI_DEVICE_PPI to manage Nvme device

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

This change modifies NvmExpressPei library
to allow usage both EDKII_PCI_DEVICE_PPI and
EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI to manage Nvme device.

Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Xiao X Chen <xiao.x.chen@intel.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
This commit is contained in:
Chen, Xiao X 2022-08-30 13:46:48 +08:00 committed by mergify[bot]
parent 31a94f7fba
commit 9ca7ece8b3
4 changed files with 488 additions and 252 deletions

View File

@ -37,50 +37,6 @@ EFI_DEVICE_PATH_PROTOCOL mNvmeEndDevicePathNodeTemplate = {
} }
}; };
/**
Returns the 16-bit Length field of a device path node.
Returns the 16-bit Length field of the device path node specified by Node.
Node is not required to be aligned on a 16-bit boundary, so it is recommended
that a function such as ReadUnaligned16() be used to extract the contents of
the Length field.
If Node is NULL, then ASSERT().
@param Node A pointer to a device path node data structure.
@return The 16-bit Length field of the device path node specified by Node.
**/
UINTN
DevicePathNodeLength (
IN CONST VOID *Node
)
{
ASSERT (Node != NULL);
return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
}
/**
Returns a pointer to the next node in a device path.
If Node is NULL, then ASSERT().
@param Node A pointer to a device path node data structure.
@return a pointer to the device path node that follows the device path node
specified by Node.
**/
EFI_DEVICE_PATH_PROTOCOL *
NextDevicePathNode (
IN CONST VOID *Node
)
{
ASSERT (Node != NULL);
return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength (Node));
}
/** /**
Get the size of the current device path instance. Get the size of the current device path instance.

View File

@ -40,6 +40,18 @@ EFI_PEI_NOTIFY_DESCRIPTOR mNvmeEndOfPeiNotifyListTemplate = {
NvmePeimEndOfPei NvmePeimEndOfPei
}; };
EFI_PEI_NOTIFY_DESCRIPTOR mNvmeHostControllerNotify = {
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEdkiiPeiNvmExpressHostControllerPpiGuid,
NvmeHostControllerPpiInstallationCallback
};
EFI_PEI_NOTIFY_DESCRIPTOR mPciDevicePpiNotify = {
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEdkiiPeiPciDevicePpiGuid,
NvmePciDevicePpiInstallationCallback
};
/** /**
Check if the specified Nvm Express device namespace is active, and then get the Identify Check if the specified Nvm Express device namespace is active, and then get the Identify
Namespace data. Namespace data.
@ -212,28 +224,25 @@ NvmePeimEndOfPei (
} }
/** /**
Entry point of the PEIM. Initialize and install PrivateData PPIs.
@param[in] FileHandle Handle of the file being invoked. @param[in] MmioBase MMIO base address of specific Nvme controller
@param[in] PeiServices Describes the list of possible PEI Services. @param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL
structure.
@retval EFI_SUCCESS PPI successfully installed. @param[in] DevicePathLength Length of the device path.
@retval EFI_SUCCESS Nvme controller initialized and PPIs installed
@retval others Failed to initialize Nvme controller
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI NvmeInitPrivateData (
NvmExpressPeimEntry ( IN UINTN MmioBase,
IN EFI_PEI_FILE_HANDLE FileHandle, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CONST EFI_PEI_SERVICES **PeiServices IN UINTN DevicePathLength
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_BOOT_MODE BootMode; EFI_BOOT_MODE BootMode;
EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *NvmeHcPpi;
UINT8 Controller;
UINTN MmioBase;
UINTN DevicePathLength;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
PEI_NVME_CONTROLLER_PRIVATE_DATA *Private; PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
EFI_PHYSICAL_ADDRESS DeviceAddress; EFI_PHYSICAL_ADDRESS DeviceAddress;
@ -248,51 +257,6 @@ NvmExpressPeimEntry (
return Status; return Status;
} }
//
// Locate the NVME host controller PPI
//
Status = PeiServicesLocatePpi (
&gEdkiiPeiNvmExpressHostControllerPpiGuid,
0,
NULL,
(VOID **)&NvmeHcPpi
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Fail to locate NvmeHostControllerPpi.\n", __FUNCTION__));
return EFI_UNSUPPORTED;
}
Controller = 0;
MmioBase = 0;
while (TRUE) {
Status = NvmeHcPpi->GetNvmeHcMmioBar (
NvmeHcPpi,
Controller,
&MmioBase
);
//
// When status is error, meant no controller is found
//
if (EFI_ERROR (Status)) {
break;
}
Status = NvmeHcPpi->GetNvmeHcDevicePath (
NvmeHcPpi,
Controller,
&DevicePathLength,
&DevicePath
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Fail to allocate get the device path for Controller %d.\n",
__FUNCTION__,
Controller
));
return Status;
}
// //
// Check validity of the device path of the NVM Express controller. // Check validity of the device path of the NVM Express controller.
// //
@ -301,11 +265,9 @@ NvmExpressPeimEntry (
DEBUG (( DEBUG ((
DEBUG_ERROR, DEBUG_ERROR,
"%a: The device path is invalid for Controller %d.\n", "%a: The device path is invalid for Controller %d.\n",
__FUNCTION__, __FUNCTION__
Controller
)); ));
Controller++; return Status;
continue;
} }
// //
@ -319,12 +281,10 @@ NvmExpressPeimEntry (
{ {
DEBUG (( DEBUG ((
DEBUG_ERROR, DEBUG_ERROR,
"%a: Controller %d is skipped during S3.\n", "%a: skipped during S3.\n",
__FUNCTION__, __FUNCTION__
Controller
)); ));
Controller++; return EFI_SUCCESS;
continue;
} }
// //
@ -334,9 +294,8 @@ NvmExpressPeimEntry (
if (Private == NULL) { if (Private == NULL) {
DEBUG (( DEBUG ((
DEBUG_ERROR, DEBUG_ERROR,
"%a: Fail to allocate private data for Controller %d.\n", "%a: Fail to allocate private data.\n",
__FUNCTION__, __FUNCTION__
Controller
)); ));
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
@ -353,9 +312,8 @@ NvmExpressPeimEntry (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG (( DEBUG ((
DEBUG_ERROR, DEBUG_ERROR,
"%a: Fail to allocate DMA buffers for Controller %d.\n", "%a: Fail to allocate DMA buffers.\n",
__FUNCTION__, __FUNCTION__
Controller
)); ));
return Status; return Status;
} }
@ -378,14 +336,12 @@ NvmExpressPeimEntry (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG (( DEBUG ((
DEBUG_ERROR, DEBUG_ERROR,
"%a: Controller initialization fail for Controller %d with Status - %r.\n", "%a: Controller initialization fail with Status - %r.\n",
__FUNCTION__, __FUNCTION__,
Controller,
Status Status
)); ));
NvmeFreeDmaResource (Private); NvmeFreeDmaResource (Private);
Controller++; return Status;
continue;
} }
// //
@ -398,14 +354,12 @@ NvmExpressPeimEntry (
// //
DEBUG (( DEBUG ((
DEBUG_ERROR, DEBUG_ERROR,
"%a: Namespaces discovery fail for Controller %d with Status - %r.\n", "%a: Namespaces discovery fail with Status - %r.\n",
__FUNCTION__, __FUNCTION__,
Controller,
Status Status
)); ));
NvmeFreeDmaResource (Private); NvmeFreeDmaResource (Private);
Controller++; return Status;
continue;
} }
// //
@ -459,9 +413,8 @@ NvmExpressPeimEntry (
if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) { if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) {
DEBUG (( DEBUG ((
DEBUG_INFO, DEBUG_INFO,
"%a: Security Security Command PPI will be produced for Controller %d.\n", "%a: Security Security Command PPI will be produced.\n",
__FUNCTION__, __FUNCTION__
Controller
)); ));
Private->StorageSecurityPpi.Revision = EDKII_STORAGE_SECURITY_PPI_REVISION; Private->StorageSecurityPpi.Revision = EDKII_STORAGE_SECURITY_PPI_REVISION;
Private->StorageSecurityPpi.GetNumberofDevices = NvmeStorageSecurityGetDeviceNo; Private->StorageSecurityPpi.GetNumberofDevices = NvmeStorageSecurityGetDeviceNo;
@ -484,14 +437,286 @@ NvmExpressPeimEntry (
); );
PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList); PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
return EFI_SUCCESS;
}
/**
Initialize Nvme controller from fiven PCI_DEVICE_PPI.
@param[in] PciDevice Pointer to the PCI Device PPI instance.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller for given device
**/
EFI_STATUS
NvmeInitControllerDataFromPciDevice (
EDKII_PCI_DEVICE_PPI *PciDevice
)
{
EFI_STATUS Status;
PCI_TYPE00 PciData;
UINTN MmioBase;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN DevicePathLength;
UINT64 EnabledPciAttributes;
UINT32 MmioBaseH;
//
// Now further check the PCI header: Base Class (offset 0x0B), Sub Class (offset 0x0A) and
// Programming Interface (offset 0x09). This controller should be an Nvme controller
//
Status = PciDevice->PciIo.Pci.Read (
&PciDevice->PciIo,
EfiPciIoWidthUint8,
PCI_CLASSCODE_OFFSET,
sizeof (PciData.Hdr.ClassCode),
PciData.Hdr.ClassCode
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
if (!IS_PCI_NVMHCI (&PciData)) {
return EFI_UNSUPPORTED;
}
Status = PciDevice->PciIo.Attributes (
&PciDevice->PciIo,
EfiPciIoAttributeOperationSupported,
0,
&EnabledPciAttributes
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
} else {
EnabledPciAttributes &= (UINT64)EFI_PCI_DEVICE_ENABLE;
Status = PciDevice->PciIo.Attributes (
&PciDevice->PciIo,
EfiPciIoAttributeOperationEnable,
EnabledPciAttributes,
NULL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
Status = PciDevice->PciIo.Pci.Read (
&PciDevice->PciIo,
EfiPciIoWidthUint32,
PCI_BASE_ADDRESSREG_OFFSET,
1,
&MmioBase
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
switch (MmioBase & 0x07) {
case 0x0:
//
// Memory space for 32 bit bar address
//
MmioBase = MmioBase & 0xFFFFFFF0;
break;
case 0x4:
//
// For 64 bit bar address, read the high 32bits of this 64 bit bar
//
Status = PciDevice->PciIo.Pci.Read (
&PciDevice->PciIo,
EfiPciIoWidthUint32,
PCI_BASE_ADDRESSREG_OFFSET + 4,
1,
&MmioBaseH
);
//
// For 32 bit environment, high 32bits of the bar should be zero.
//
if ( EFI_ERROR (Status)
|| ((MmioBaseH != 0) && (sizeof (UINTN) == sizeof (UINT32))))
{
return EFI_UNSUPPORTED;
}
MmioBase = MmioBase & 0xFFFFFFF0;
MmioBase |= LShiftU64 ((UINT64)MmioBaseH, 32);
break;
default:
//
// Unknown bar type
//
return EFI_UNSUPPORTED;
}
DevicePathLength = GetDevicePathSize (PciDevice->DevicePath);
DevicePath = PciDevice->DevicePath;
Status = NvmeInitPrivateData (MmioBase, DevicePath, DevicePathLength);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_INFO,
"%a: Failed to init controller, with Status - %r\n",
__FUNCTION__,
Status
));
}
return EFI_SUCCESS;
}
/**
Callback for EDKII_PCI_DEVICE_PPI installation.
@param[in] PeiServices Pointer to PEI Services Table.
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification
event that caused this function to execute.
@param[in] Ppi Pointer to the PPI data associated with this function.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller from given PCI_DEVICE_PPI
**/
EFI_STATUS
EFIAPI
NvmePciDevicePpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
EDKII_PCI_DEVICE_PPI *PciDevice;
PciDevice = (EDKII_PCI_DEVICE_PPI *)Ppi;
return NvmeInitControllerDataFromPciDevice (PciDevice);
}
/**
Initialize Nvme controller from EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI instance.
@param[in] NvmeHcPpi Pointer to the Nvme Host Controller PPI instance.
@retval EFI_SUCCESS PPI successfully installed.
**/
EFI_STATUS
NvmeInitControllerFromHostControllerPpi (
IN EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *NvmeHcPpi
)
{
UINT8 Controller;
UINTN MmioBase;
UINTN DevicePathLength;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_STATUS Status;
Controller = 0;
MmioBase = 0;
while (TRUE) {
Status = NvmeHcPpi->GetNvmeHcMmioBar (
NvmeHcPpi,
Controller,
&MmioBase
);
//
// When status is error, meant no controller is found
//
if (EFI_ERROR (Status)) {
break;
}
Status = NvmeHcPpi->GetNvmeHcDevicePath (
NvmeHcPpi,
Controller,
&DevicePathLength,
&DevicePath
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Fail to allocate get the device path for Controller %d.\n",
__FUNCTION__,
Controller
));
return Status;
}
Status = NvmeInitPrivateData (MmioBase, DevicePath, DevicePathLength);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Controller initialization fail for Controller %d with Status - %r.\n",
__FUNCTION__,
Controller,
Status
));
} else {
DEBUG (( DEBUG ((
DEBUG_INFO, DEBUG_INFO,
"%a: Controller %d has been successfully initialized.\n", "%a: Controller %d has been successfully initialized.\n",
__FUNCTION__, __FUNCTION__,
Controller Controller
)); ));
}
Controller++; Controller++;
} }
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Callback for EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI installation.
@param[in] PeiServices Pointer to PEI Services Table.
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification
event that caused this function to execute.
@param[in] Ppi Pointer to the PPI data associated with this function.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller from given EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI
**/
EFI_STATUS
EFIAPI
NvmeHostControllerPpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *NvmeHcPpi;
if (Ppi == NULL) {
return EFI_INVALID_PARAMETER;
}
NvmeHcPpi = (EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *)Ppi;
return NvmeInitControllerFromHostControllerPpi (NvmeHcPpi);
}
/**
Entry point of the PEIM.
@param[in] FileHandle Handle of the file being invoked.
@param[in] PeiServices Describes the list of possible PEI Services.
@retval EFI_SUCCESS PPI successfully installed.
**/
EFI_STATUS
EFIAPI
NvmExpressPeimEntry (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__));
PeiServicesNotifyPpi (&mNvmeHostControllerNotify);
PeiServicesNotifyPpi (&mPciDevicePpiNotify);
return EFI_SUCCESS;
}

View File

@ -14,6 +14,7 @@
#include <PiPei.h> #include <PiPei.h>
#include <IndustryStandard/Nvme.h> #include <IndustryStandard/Nvme.h>
#include <IndustryStandard/Pci.h>
#include <Ppi/NvmExpressHostController.h> #include <Ppi/NvmExpressHostController.h>
#include <Ppi/BlockIo.h> #include <Ppi/BlockIo.h>
@ -22,6 +23,7 @@
#include <Ppi/NvmExpressPassThru.h> #include <Ppi/NvmExpressPassThru.h>
#include <Ppi/IoMmu.h> #include <Ppi/IoMmu.h>
#include <Ppi/EndOfPeiPhase.h> #include <Ppi/EndOfPeiPhase.h>
#include <Ppi/PciDevice.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/PeiServicesLib.h> #include <Library/PeiServicesLib.h>
@ -29,6 +31,7 @@
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/IoLib.h> #include <Library/IoLib.h>
#include <Library/TimerLib.h> #include <Library/TimerLib.h>
#include <Library/DevicePathLib.h>
// //
// Structure forward declarations // Structure forward declarations
@ -36,6 +39,17 @@
typedef struct _PEI_NVME_NAMESPACE_INFO PEI_NVME_NAMESPACE_INFO; typedef struct _PEI_NVME_NAMESPACE_INFO PEI_NVME_NAMESPACE_INFO;
typedef struct _PEI_NVME_CONTROLLER_PRIVATE_DATA PEI_NVME_CONTROLLER_PRIVATE_DATA; typedef struct _PEI_NVME_CONTROLLER_PRIVATE_DATA PEI_NVME_CONTROLLER_PRIVATE_DATA;
/**
Macro that checks whether device is a NVMHCI Interface.
@param _p Specified device.
@retval TRUE Device is a NVMHCI Interface.
@retval FALSE Device is not a NVMHCI Interface.
**/
#define IS_PCI_NVMHCI(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SOLID_STATE, PCI_IF_MASS_STORAGE_SOLID_STATE_ENTERPRISE_NVMHCI)
#include "NvmExpressPeiHci.h" #include "NvmExpressPeiHci.h"
#include "NvmExpressPeiPassThru.h" #include "NvmExpressPeiPassThru.h"
#include "NvmExpressPeiBlockIo.h" #include "NvmExpressPeiBlockIo.h"
@ -345,4 +359,44 @@ NvmeS3SkipThisController (
IN UINTN HcDevicePathLength IN UINTN HcDevicePathLength
); );
/**
Callback for EDKII_PCI_DEVICE_PPI installation.
@param[in] PeiServices Pointer to PEI Services Table.
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification
event that caused this function to execute.
@param[in] Ppi Pointer to the PPI data associated with this function.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller from given PCI_DEVICE_PPI
**/
EFI_STATUS
EFIAPI
NvmePciDevicePpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
/**
Callback for EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI installation.
@param[in] PeiServices Pointer to PEI Services Table.
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification
event that caused this function to execute.
@param[in] Ppi Pointer to the PPI data associated with this function.
@retval EFI_SUCCESS The function completes successfully
@retval Others Cannot initialize Nvme controller from given EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI
**/
EFI_STATUS
EFIAPI
NvmeHostControllerPpiInstallationCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
#endif #endif

View File

@ -44,6 +44,7 @@
[LibraryClasses] [LibraryClasses]
DebugLib DebugLib
DevicePathLib
PeiServicesLib PeiServicesLib
MemoryAllocationLib MemoryAllocationLib
BaseMemoryLib BaseMemoryLib
@ -56,6 +57,7 @@
gEdkiiPeiNvmExpressHostControllerPpiGuid ## CONSUMES gEdkiiPeiNvmExpressHostControllerPpiGuid ## CONSUMES
gEdkiiIoMmuPpiGuid ## CONSUMES gEdkiiIoMmuPpiGuid ## CONSUMES
gEfiEndOfPeiSignalPpiGuid ## CONSUMES gEfiEndOfPeiSignalPpiGuid ## CONSUMES
gEdkiiPeiPciDevicePpiGuid ## CONSUMES
gEdkiiPeiNvmExpressPassThruPpiGuid ## SOMETIMES_PRODUCES gEdkiiPeiNvmExpressPassThruPpiGuid ## SOMETIMES_PRODUCES
gEfiPeiVirtualBlockIoPpiGuid ## SOMETIMES_PRODUCES gEfiPeiVirtualBlockIoPpiGuid ## SOMETIMES_PRODUCES
gEfiPeiVirtualBlockIo2PpiGuid ## SOMETIMES_PRODUCES gEfiPeiVirtualBlockIo2PpiGuid ## SOMETIMES_PRODUCES
@ -66,7 +68,6 @@
[Depex] [Depex]
gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiMemoryDiscoveredPpiGuid AND
gEdkiiPeiNvmExpressHostControllerPpiGuid AND
gEfiPeiMasterBootModePpiGuid gEfiPeiMasterBootModePpiGuid
[UserExtensions.TianoCore."ExtraFiles"] [UserExtensions.TianoCore."ExtraFiles"]