Date   

[PATCH] SecurityPkg/Tcg2Config: remove TPM2_ChangEPS if is not supported.

Zhang, Qi <qi1.zhang@...>
 

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

In current implementation TPM2_ChangeEPS command is always available
in the TPM2 operation pull down list in TCG2 Configuration, which
is confusing when the command is not supported by specific TPM chip.
As a user experience improvement, TPM2_ChangeEPS command should be
removed from the list when it is not supported.
Add a new function Tpm2GetCapabilityIsCmdImpl() to query if the command
is supported.

Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Chao Zhang <chao.b.zhang@...>
Cc: Rahul Kumar <rahul1.kumar@...>
Signed-off-by: Zhang, Qi <qi1.zhang@...>
---
SecurityPkg/Include/Library/Tpm2CommandLib.h | 16 ++++++++++++++++
SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c | 40 +++++++++++++++++=
+++++++++++++++++++++++
SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr | 2 ++
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c | 7 +++++++
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h | 1 +
5 files changed, 66 insertions(+)

diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h b/SecurityPkg/Inc=
lude/Library/Tpm2CommandLib.h
index ce381e786b..ce7290c0f5 100644
--- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
+++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
@@ -790,6 +790,22 @@ Tpm2GetCapabilityAlgorithmSet (
OUT UINT32 *AlgorithmSet=0D
);=0D
=0D
+/**=0D
+ This function will query if the command is supported.=0D
+=0D
+ @param[In] Command TPM_CC command starts from TPM_CC_FIRST.=0D
+ @param[out] IsCmdImpl The command is supported or not.=0D
+=0D
+ @retval EFI_SUCCESS Operation completed successfully.=0D
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+Tpm2GetCapabilityIsCmdImpl (=0D
+ IN TPM_CC Command,=0D
+ OUT BOOLEAN *IsCmdImpl=0D
+ );=0D
+=0D
/**=0D
This command is used to check to see if specific combinations of algorit=
hm parameters are supported.=0D
=0D
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c b/Security=
Pkg/Library/Tpm2CommandLib/Tpm2Capability.c
index 85b11c7715..0c8f980e69 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c
@@ -39,6 +39,8 @@ typedef struct {
=0D
#pragma pack()=0D
=0D
+#define TPMA_CC_COMMANDINDEX_MASK 0x2000FFFF=0D
+=0D
/**=0D
This command returns various information regarding the TPM and its curre=
nt state.=0D
=0D
@@ -628,6 +630,44 @@ Tpm2GetCapabilityAlgorithmSet (
return EFI_SUCCESS;=0D
}=0D
=0D
+/**=0D
+ This function will query if the command is supported.=0D
+=0D
+ @param[In] Command TPM_CC command starts from TPM_CC_FIRST.=0D
+ @param[out] IsCmdImpl The command is supported or not.=0D
+=0D
+ @retval EFI_SUCCESS Operation completed successfully.=0D
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+Tpm2GetCapabilityIsCmdImpl (=0D
+ IN TPM_CC Command,=0D
+ OUT BOOLEAN *IsCmdImpl=0D
+ )=0D
+{=0D
+ TPMS_CAPABILITY_DATA TpmCap;=0D
+ TPMI_YES_NO MoreData;=0D
+ EFI_STATUS Status;=0D
+ UINT32 Attribute;=0D
+=0D
+ Status =3D Tpm2GetCapability (=0D
+ TPM_CAP_COMMANDS,=0D
+ Command,=0D
+ 1,=0D
+ &MoreData,=0D
+ &TpmCap=0D
+ );=0D
+ if (EFI_ERROR (Status)) {=0D
+ return Status;=0D
+ }=0D
+=0D
+ CopyMem (&Attribute, &TpmCap.data.command.commandAttributes[0], sizeof (=
UINT32));=0D
+ *IsCmdImpl =3D (Command =3D=3D (SwapBytes32(Attribute) & TPMA_CC_COMMAND=
INDEX_MASK));=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
/**=0D
This command is used to check to see if specific combinations of algorit=
hm parameters are supported.=0D
=0D
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr b/SecurityPkg/Tcg/Tc=
g2Config/Tcg2Config.vfr
index 91a463997c..47d63b009d 100644
--- a/SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr
+++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr
@@ -144,7 +144,9 @@ formset
option text =3D STRING_TOKEN(STR_TCG2_DISABLE), value =3D TCG2=
_PHYSICAL_PRESENCE_DISABLE, flags =3D RESET_REQUIRED;=0D
option text =3D STRING_TOKEN(STR_TCG2_CLEAR), value =3D TCG2_P=
HYSICAL_PRESENCE_CLEAR, flags =3D RESET_REQUIRED;=0D
option text =3D STRING_TOKEN(STR_TCG2_SET_PCD_BANKS), value =
=3D TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, flags =3D RESET_REQUIRED;=0D
+ suppressif ideqval TCG2_CONFIGURATION_INFO.ChangeEPSSupported =
=3D=3D 0;=0D
option text =3D STRING_TOKEN(STR_TCG2_CHANGE_EPS), value =3D T=
CG2_PHYSICAL_PRESENCE_CHANGE_EPS, flags =3D RESET_REQUIRED;=0D
+ endif=0D
option text =3D STRING_TOKEN(STR_TCG2_LOG_ALL_DIGESTS), value =
=3D TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS, flags =3D RESET_REQUIRED;=0D
option text =3D STRING_TOKEN(STR_TCG2_DISABLE_ENDORSEMENT_ENAB=
LE_STORAGE_HIERARCHY), value =3D TCG2_PHYSICAL_PRESENCE_DISABLE_ENDORSEMENT=
_ENABLE_STORAGE_HIERARCHY, flags =3D RESET_REQUIRED;=0D
endoneof;=0D
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c b/SecurityPkg/Tcg/=
Tcg2Config/Tcg2ConfigImpl.c
index baa8fcd08d..464cacc207 100644
--- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c
+++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c
@@ -788,6 +788,7 @@ InstallTcg2ConfigForm (
CHAR16 TempBuffer[1024];=0D
TCG2_CONFIGURATION_INFO Tcg2ConfigInfo;=0D
TPM2_PTP_INTERFACE_TYPE TpmDeviceInterfaceDetected;=0D
+ BOOLEAN IsCmdImp =3D FALSE;=0D
=0D
DriverHandle =3D NULL;=0D
ConfigAccess =3D &PrivateData->ConfigAccess;=0D
@@ -870,6 +871,12 @@ InstallTcg2ConfigForm (
HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED=
_HASH_ALGO_CONTENT), TempBuffer, NULL);=0D
}=0D
=0D
+ Status =3D Tpm2GetCapabilityIsCmdImpl(TPM_CC_ChangeEPS, &IsCmdImp);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityIsCmdImpl fails %r\n", Status))=
;=0D
+ }=0D
+ Tcg2ConfigInfo.ChangeEPSSupported =3D IsCmdImp;=0D
+=0D
FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PcdGet32 (Pcd=
Tcg2HashAlgorithmBitmap));=0D
HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_BIOS_HASH_ALGO_C=
ONTENT), TempBuffer, NULL);=0D
=0D
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h b/SecurityPkg/Tc=
g/Tcg2Config/Tcg2ConfigNvData.h
index a91c052850..b84af40a04 100644
--- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h
+++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h
@@ -70,6 +70,7 @@ typedef struct {
UINT8 TpmDeviceInterfaceAttempt;=0D
BOOLEAN TpmDeviceInterfacePtpFifoSupported;=0D
BOOLEAN TpmDeviceInterfacePtpCrbSupported;=0D
+ BOOLEAN ChangeEPSSupported;=0D
} TCG2_CONFIGURATION_INFO;=0D
=0D
//=0D
--=20
2.26.2.windows.1


Re: [Patch] BaseTools GenFv: Report the correct spare FV image size

Bob Feng
 

Reviewed-by: Bob Feng <bob.c.feng@...>

-----Original Message-----
From: Gao, Liming <liming.gao@...>
Sent: Tuesday, June 9, 2020 4:17 PM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@...>
Subject: [Patch] BaseTools GenFv: Report the correct spare FV image size

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

If the top FFS is placed in FV image, current FV will show there is no space.
In fact, the pad ffs in FV image can be regarded as the spare space.
This change reports the max pad ffs size as the spare space for use.

Signed-off-by: Liming Gao <liming.gao@...>
Cc: Bob Feng <bob.c.feng@...>
---
BaseTools/Source/C/GenFv/GenFvInternalLib.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index d29a891c9c..b5ffed93a9 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -3140,6 +3140,7 @@ Returns:
--*/
{
UINTN CurrentOffset;
+ UINTN OrigOffset;
UINTN Index;
FILE *fpin;
UINTN FfsFileSize;
@@ -3148,8 +3149,10 @@ Returns:
UINT32 FfsHeaderSize;
EFI_FFS_FILE_HEADER FfsHeader;
UINTN VtfFileSize;
+ UINTN MaxPadFileSize;

FvExtendHeaderSize = 0;
+ MaxPadFileSize = 0;
VtfFileSize = 0;
fpin = NULL;
Index = 0;
@@ -3258,8 +3261,12 @@ Returns:
//
// Only EFI_FFS_FILE_HEADER is needed for a pad section.
//
+ OrigOffset = CurrentOffset;
CurrentOffset = (CurrentOffset + FfsHeaderSize + sizeof(EFI_FFS_FILE_HEADER) + FfsAlignment - 1) & ~(FfsAlignment - 1);
CurrentOffset -= FfsHeaderSize;
+ if ((CurrentOffset - OrigOffset) > MaxPadFileSize) {
+ MaxPadFileSize = CurrentOffset - OrigOffset;
+ }
}
}

@@ -3303,6 +3310,12 @@ Returns:
//
mFvTotalSize = FvInfoPtr->Size;
mFvTakenSize = CurrentOffset;
+ if ((mFvTakenSize == mFvTotalSize) && (MaxPadFileSize > 0)) {
+ //
+ // This FV means TOP FFS has been taken. Then, check whether there is padding data for use.
+ //
+ mFvTakenSize = mFvTakenSize - MaxPadFileSize; }

return EFI_SUCCESS;
}
--
2.13.0.windows.1


Re: Additional configuration options on Armada/Cn913x

Ard Biesheuvel
 

On 6/5/20 5:19 PM, Marcin Wojtas via groups.io wrote:
Hi,
I'd like to ask for comments before I develop the actual code - currently we have 2 workarounds done specifically for Linux:
a. ECAM shift in PCIE
b. SPCR address space definition
What does this mean?

Both above are not needed e.g. in FreeBSD and I was requested to add their optional disabling.
Disabling ECAM shift is just a matter of exposing the iATU controls to the OS, right? Why do you need to disable it?

The idea is to add dedicated variables that would optionally allow to disable the quirks, accessible via BootManager. Questions:
- Would above be acceptable or is there a better way to handle such cases?
- In case it's fine, is there a dedicated place in the BootManager menu to add custom switches?
Typically in a 'platform' submenu under the Device Manager

- Are you aware of good examples for adding custom options?
You could look at SynQuacer or Raspberry Pi for inspiration on how to create HII pages in the UiApp menu system.


[PATCH v2 3/3] ArmVirtPkg: remove unused files

Ard Biesheuvel
 

We no longer use ELF PIE executables to implement the self-relocating
PrePi so drop the custom linker script and visibility override header
file.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@...>
Acked-by: Jiewen Yao <Jiewen.yao@...>
Reviewed-by: Laszlo Ersek <lersek@...>
Acked-by: Sami Mujawar <Sami.Mujawar@...>
---
ArmVirtPkg/Include/Platform/Hidden.h | 22 -----------
ArmVirtPkg/PrePi/Scripts/PrePi-PIE.lds | 41 --------------------
2 files changed, 63 deletions(-)

diff --git a/ArmVirtPkg/Include/Platform/Hidden.h b/ArmVirtPkg/Include/Plat=
form/Hidden.h
deleted file mode 100644
index 7a7bdb42b8bd..000000000000
--- a/ArmVirtPkg/Include/Platform/Hidden.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/** @file=0D
-=0D
- Copyright (c) 2018, Linaro Limited. All rights reserved.=0D
-=0D
- SPDX-License-Identifier: BSD-2-Clause-Patent=0D
-=0D
-**/=0D
-=0D
-#ifndef __PLATFORM_HIDDEN_H=0D
-#define __PLATFORM_HIDDEN_H=0D
-=0D
-//=0D
-// Setting the GCC -fvisibility=3Dhidden command line option is not quite =
the same=0D
-// as setting the pragma below: the former only affects definitions, where=
as the=0D
-// pragma affects extern declarations as well. So if we want to ensure tha=
t no=0D
-// GOT indirected symbol references are emitted, we need to use the pragma=
, or=0D
-// GOT based cross object references could be emitted, e.g., in libraries,=
and=0D
-// these cannot be relaxed to ordinary symbol references at link time.=0D
-//=0D
-#pragma GCC visibility push (hidden)=0D
-=0D
-#endif=0D
diff --git a/ArmVirtPkg/PrePi/Scripts/PrePi-PIE.lds b/ArmVirtPkg/PrePi/Scri=
pts/PrePi-PIE.lds
deleted file mode 100644
index c9a15ca3493a..000000000000
--- a/ArmVirtPkg/PrePi/Scripts/PrePi-PIE.lds
+++ /dev/null
@@ -1,41 +0,0 @@
-/** @file=0D
-=0D
- Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>=0D
-=0D
- SPDX-License-Identifier: BSD-2-Clause-Patent=0D
-=0D
-**/=0D
-=0D
-SECTIONS=0D
-{=0D
- PROVIDE(__reloc_base =3D .);=0D
-=0D
- . =3D PECOFF_HEADER_SIZE;=0D
- .text : ALIGN(CONSTANT(COMMONPAGESIZE)) {=0D
- *(.text .text*)=0D
- *(.got .got*)=0D
- *(.rodata .rodata*)=0D
- *(.data .data*)=0D
- *(.bss .bss*)=0D
-=0D
- . =3D ALIGN(0x20);=0D
- PROVIDE(__reloc_start =3D .);=0D
- *(.rel .rel.*)=0D
- *(.rela .rela.*)=0D
- PROVIDE(__reloc_end =3D .);=0D
- }=0D
-=0D
- .note (INFO) : { *(.note.gnu.build-id) }=0D
-=0D
- /DISCARD/ : {=0D
- *(.note.GNU-stack)=0D
- *(.gnu.hash)=0D
- *(.gnu_debuglink)=0D
- *(.interp)=0D
- *(.dynamic)=0D
- *(.dynsym)=0D
- *(.dynstr)=0D
- *(.hash)=0D
- *(.comment)=0D
- }=0D
-}=0D
--=20
2.26.2


[PATCH v2 2/3] ArmVirtPkg/PrePi: use standard PeCoff routines for self-relocation

Ard Biesheuvel
 

Instead of having a GCC specific routine to perform self-relocation
based on ELF metadata, use the PE/COFF metadata and the existing
PeCoff library routines. This reduces the amount of bespoke assembler
code that is a burden to maintain, and is not portable across the set
of toolchains we support.

This does require some special care, as we have no control over how
the C code references global symbols, so we need to emit these
references from the calling assembler code. Otherwise, they may be
emitted as absolute references, in which case they need to be fixed
up themselves, leading to a circular dependency.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@...>
Acked-by: Jiewen Yao <Jiewen.yao@...>
Acked-by: Laszlo Ersek <lersek@...>
Acked-by: Sami Mujawar <Sami.Mujawar@...>
---
ArmVirtPkg/ArmVirtQemuKernel.dsc | 10 ++--
ArmVirtPkg/ArmVirtXen.dsc | 10 ++--
ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 4 +-
ArmVirtPkg/PrePi/PrePi.c | 35 ++++++++++++++
ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S | 49 +++++------------=
---
ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S | 47 +++++------------=
--
6 files changed, 68 insertions(+), 87 deletions(-)

diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKerne=
l.dsc
index 2a6fd6bc06be..9449a01d6e40 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -83,14 +83,12 @@ [LibraryClasses.common.DXE_DRIVER]
[LibraryClasses.common.UEFI_DRIVER]=0D
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf=0D
=0D
-[BuildOptions.common.EDKII.SEC, BuildOptions.common.EDKII.BASE]=0D
+[BuildOptions]=0D
#=0D
- # CLANG38 with LTO support enabled uses the GNU GOLD linker, which insis=
ts=0D
- # on emitting GOT based symbol references when running in shared mode, u=
nless=0D
- # we override visibility to 'hidden' in all modules that make up the Pre=
Pi=0D
- # build.=0D
+ # We need to avoid jump tables in SEC modules, so that the PE/COFF=0D
+ # self-relocation code itself is guaranteed to be position independent.=
=0D
#=0D
- GCC:*_CLANG38_*_CC_FLAGS =3D -include $(WORKSPACE)/ArmVirtPkg/Include/Pl=
atform/Hidden.h=0D
+ GCC:*_*_*_CC_FLAGS =3D -fno-jump-tables=0D
=0D
##########################################################################=
######=0D
#=0D
diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc
index 8a489b253684..278f5d3828ce 100644
--- a/ArmVirtPkg/ArmVirtXen.dsc
+++ b/ArmVirtPkg/ArmVirtXen.dsc
@@ -52,14 +52,12 @@ [LibraryClasses]
[LibraryClasses.common.UEFI_DRIVER]=0D
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf=0D
=0D
-[BuildOptions.common.EDKII.SEC, BuildOptions.common.EDKII.BASE]=0D
+[BuildOptions]=0D
#=0D
- # CLANG38 with LTO support enabled uses the GNU GOLD linker, which insis=
ts=0D
- # on emitting GOT based symbol references when running in shared mode, u=
nless=0D
- # we override visibility to 'hidden' in all modules that make up the Pre=
Pi=0D
- # build.=0D
+ # We need to avoid jump tables in SEC modules, so that the PE/COFF=0D
+ # self-relocation code itself is guaranteed to be position independent.=
=0D
#=0D
- GCC:*_CLANG38_*_CC_FLAGS =3D -include $(WORKSPACE)/ArmVirtPkg/Include/Pl=
atform/Hidden.h=0D
+ GCC:*_*_*_CC_FLAGS =3D -fno-jump-tables=0D
=0D
##########################################################################=
######=0D
#=0D
diff --git a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmVirtP=
kg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
index 9e58e56fce09..7edf5018089d 100755
--- a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
+++ b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
@@ -46,6 +46,7 @@ [LibraryClasses]
SerialPortLib=0D
ExtractGuidedSectionLib=0D
LzmaDecompressLib=0D
+ PeCoffLib=0D
PrePiLib=0D
MemoryAllocationLib=0D
HobLib=0D
@@ -95,6 +96,3 @@ [Pcd]
gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress=0D
gArmTokenSpaceGuid.PcdFdBaseAddress=0D
gArmTokenSpaceGuid.PcdFvBaseAddress=0D
-=0D
-[BuildOptions]=0D
- GCC:*_*_*_DLINK_FLAGS =3D -Wl,-Bsymbolic,-pie,-T,$(MODULE_DIR)/Scripts/P=
rePi-PIE.lds=0D
diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c
index 72e35028c5bb..4f0c3f98bad6 100755
--- a/ArmVirtPkg/PrePi/PrePi.c
+++ b/ArmVirtPkg/PrePi/PrePi.c
@@ -9,6 +9,7 @@
#include <PiPei.h>=0D
#include <Pi/PiBootMode.h>=0D
=0D
+#include <Library/PeCoffLib.h>=0D
#include <Library/PrePiLib.h>=0D
#include <Library/PrintLib.h>=0D
#include <Library/PrePiHobListPointerLib.h>=0D
@@ -128,3 +129,37 @@ CEntryPoint (
// DXE Core should always load and never return=0D
ASSERT (FALSE);=0D
}=0D
+=0D
+VOID=0D
+RelocatePeCoffImage (=0D
+ IN EFI_PEI_FV_HANDLE FwVolHeader,=0D
+ IN PE_COFF_LOADER_READ_FILE ImageRead=0D
+ )=0D
+{=0D
+ EFI_PEI_FILE_HANDLE FileHandle;=0D
+ VOID *SectionData;=0D
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;=0D
+ EFI_STATUS Status;=0D
+=0D
+ FileHandle =3D NULL;=0D
+ Status =3D FfsFindNextFile (EFI_FV_FILETYPE_SECURITY_CORE, FwVolHeader,=
=0D
+ &FileHandle);=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionDat=
a);=0D
+ if (EFI_ERROR (Status)) {=0D
+ Status =3D FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionDat=
a);=0D
+ }=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ ZeroMem (&ImageContext, sizeof ImageContext);=0D
+=0D
+ ImageContext.Handle =3D (EFI_HANDLE)SectionData;=0D
+ ImageContext.ImageRead =3D ImageRead;=0D
+ PeCoffLoaderGetImageInfo (&ImageContext);=0D
+=0D
+ if (ImageContext.ImageAddress !=3D (UINTN)SectionData) {=0D
+ ImageContext.ImageAddress =3D (UINTN)SectionData;=0D
+ PeCoffLoaderRelocateImage (&ImageContext);=0D
+ }=0D
+}=0D
diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi=
/AArch64/ModuleEntryPoint.S
index 34d6abecb0ac..01623b6b3591 100644
--- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
+++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -9,40 +9,6 @@
#include <AsmMacroIoLibV8.h>=0D
=0D
ASM_FUNC(_ModuleEntryPoint)=0D
- //=0D
- // We are built as a ET_DYN PIE executable, so we need to process all=0D
- // relative relocations regardless of whether or not we are executing fr=
om=0D
- // the same offset we were linked at. This is only possible if we are=0D
- // running from RAM.=0D
- //=0D
- adr x8, __reloc_base=0D
- adr x9, __reloc_start=0D
- adr x10, __reloc_end=0D
-=0D
-.Lreloc_loop:=0D
- cmp x9, x10=0D
- bhs .Lreloc_done=0D
-=0D
- //=0D
- // AArch64 uses the ELF64 RELA format, which means each entry in the=0D
- // relocation table consists of=0D
- //=0D
- // UINT64 offset : the relative offset of the value that need=
s to=0D
- // be relocated=0D
- // UINT64 info : relocation type and symbol index (the latt=
er is=0D
- // not used for R_AARCH64_RELATIVE relocation=
s)=0D
- // UINT64 addend : value to be added to the value being reloc=
ated=0D
- //=0D
- ldp x11, x12, [x9], #24 // read offset into x11 and info into x12=0D
- cmp x12, #0x403 // check info =3D=3D R_AARCH64_RELATIVE?=0D
- bne .Lreloc_loop // not a relative relocation? then skip=0D
-=0D
- ldr x12, [x9, #-8] // read addend into x12=0D
- add x12, x12, x8 // add reloc base to addend to get relocated=
value=0D
- str x12, [x11, x8] // write relocated value at offset=0D
- b .Lreloc_loop=0D
-.Lreloc_done:=0D
-=0D
bl ASM_PFX(DiscoverDramFromDt)=0D
=0D
// Get ID of this CPU in Multicore system=0D
@@ -170,15 +136,24 @@ ASM_PFX(DiscoverDramFromDt):
str x1, [x8]=0D
str x7, [x9]=0D
=0D
+ //=0D
+ // The runtime address may be different from the link time address so fi=
x=0D
+ // up the PE/COFF relocations. Since we are calling a C function, use th=
e=0D
+ // window at the beginning of the FD image as a temp stack.=0D
+ //=0D
+ mov x0, x7=0D
+ adr x1, PeCoffLoaderImageReadFromMemory=0D
+ mov sp, x7=0D
+ bl RelocatePeCoffImage=0D
+=0D
//=0D
// Discover the memory size and offset from the DTB, and record in the=0D
// respective PCDs. This will also return false if a corrupt DTB is=0D
- // encountered. Since we are calling a C function, use the window at the=
=0D
- // beginning of the FD image as a temp stack.=0D
+ // encountered.=0D
//=0D
+ mov x0, x28=0D
adr x1, PcdGet64 (PcdSystemMemoryBase)=0D
adr x2, PcdGet64 (PcdSystemMemorySize)=0D
- mov sp, x7=0D
bl FindMemnode=0D
cbz x0, .Lout=0D
=0D
diff --git a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/Arm=
/ModuleEntryPoint.S
index 72d756fdb571..f0536c65eb52 100644
--- a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
+++ b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
@@ -9,38 +9,6 @@
#include <AsmMacroIoLib.h>=0D
=0D
ASM_FUNC(_ModuleEntryPoint)=0D
- //=0D
- // We are built as a ET_DYN PIE executable, so we need to process all=0D
- // relative relocations if we are executing from a different offset than=
we=0D
- // were linked at. This is only possible if we are running from RAM.=0D
- //=0D
- ADRL (r4, __reloc_base)=0D
- ADRL (r5, __reloc_start)=0D
- ADRL (r6, __reloc_end)=0D
-=0D
-.Lreloc_loop:=0D
- cmp r5, r6=0D
- bhs .Lreloc_done=0D
-=0D
- //=0D
- // AArch32 uses the ELF32 REL format, which means each entry in the=0D
- // relocation table consists of=0D
- //=0D
- // UINT32 offset : the relative offset of the value that need=
s to=0D
- // be relocated=0D
- // UINT32 info : relocation type and symbol index (the latt=
er is=0D
- // not used for R_ARM_RELATIVE relocations)=0D
- //=0D
- ldrd r8, r9, [r5], #8 // read offset into r8 and info into r9=0D
- cmp r9, #23 // check info =3D=3D R_ARM_RELATIVE?=0D
- bne .Lreloc_loop // not a relative relocation? then skip=0D
-=0D
- ldr r9, [r8, r4] // read addend into r9=0D
- add r9, r9, r1 // add image base to addend to get relocated=
value=0D
- str r9, [r8, r4] // write relocated value at offset=0D
- b .Lreloc_loop=0D
-.Lreloc_done:=0D
-=0D
// Do early platform specific actions=0D
bl ASM_PFX(ArmPlatformPeiBootAction)=0D
=0D
@@ -172,15 +140,24 @@ ASM_PFX(ArmPlatformPeiBootAction):
str r1, [r8]=0D
str r5, [r7]=0D
=0D
+ //=0D
+ // The runtime address may be different from the link time address so fi=
x=0D
+ // up the PE/COFF relocations. Since we are calling a C function, use th=
e=0D
+ // window at the beginning of the FD image as a temp stack.=0D
+ //=0D
+ mov r0, r5=0D
+ ADRL (r1, PeCoffLoaderImageReadFromMemory)=0D
+ mov sp, r5=0D
+ bl RelocatePeCoffImage=0D
+=0D
//=0D
// Discover the memory size and offset from the DTB, and record in the=0D
// respective PCDs. This will also return false if a corrupt DTB is=0D
- // encountered. Since we are calling a C function, use the window at the=
=0D
- // beginning of the FD image as a temp stack.=0D
+ // encountered.=0D
//=0D
+ mov r0, r10=0D
ADRL (r1, PcdGet64 (PcdSystemMemoryBase))=0D
ADRL (r2, PcdGet64 (PcdSystemMemorySize))=0D
- mov sp, r5=0D
bl FindMemnode=0D
teq r0, #0=0D
beq .Lout=0D
--=20
2.26.2


[PATCH v2 1/3] ArmVirtPkg: add FDF rule for self-relocating PrePi

Ard Biesheuvel
 

In preparation for making the self-relocating PrePi use the ordinary
BasePeCoffLib routines for relocating the image in place in memory
at start, add a special FDF rule that builds SEC modules as PE32
images with the relocation metadata preserved.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@...>
Acked-by: Jiewen Yao <Jiewen.yao@...>
Reviewed-by: Laszlo Ersek <lersek@...>
Acked-by: Sami Mujawar <Sami.Mujawar@...>
---
ArmVirtPkg/ArmVirtQemuKernel.fdf | 2 +-
ArmVirtPkg/ArmVirtXen.fdf | 2 +-
ArmVirtPkg/ArmVirtRules.fdf.inc | 5 +++++
3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/ArmVirtPkg/ArmVirtQemuKernel.fdf b/ArmVirtPkg/ArmVirtQemuKerne=
l.fdf
index 72fc8dd698f8..55e33aba0d55 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.fdf
+++ b/ArmVirtPkg/ArmVirtQemuKernel.fdf
@@ -136,7 +136,7 @@ [FV.FVMAIN_COMPACT]
READ_LOCK_CAP =3D TRUE=0D
READ_LOCK_STATUS =3D TRUE=0D
=0D
- INF ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf=0D
+ INF RuleOverride =3D SELF_RELOC ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelo=
catable.inf=0D
=0D
FILE FV_IMAGE =3D 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {=0D
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRE=
D =3D TRUE {=0D
diff --git a/ArmVirtPkg/ArmVirtXen.fdf b/ArmVirtPkg/ArmVirtXen.fdf
index 6a97bceeacbc..f708878f4965 100644
--- a/ArmVirtPkg/ArmVirtXen.fdf
+++ b/ArmVirtPkg/ArmVirtXen.fdf
@@ -233,7 +233,7 @@ [FV.FVMAIN_COMPACT]
READ_LOCK_CAP =3D TRUE=0D
READ_LOCK_STATUS =3D TRUE=0D
=0D
- INF ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf=0D
+ INF RuleOverride =3D SELF_RELOC ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelo=
catable.inf=0D
=0D
FILE FV_IMAGE =3D 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {=0D
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRE=
D =3D TRUE {=0D
diff --git a/ArmVirtPkg/ArmVirtRules.fdf.inc b/ArmVirtPkg/ArmVirtRules.fdf.=
inc
index 63de26abe056..b8ec040d2330 100644
--- a/ArmVirtPkg/ArmVirtRules.fdf.inc
+++ b/ArmVirtPkg/ArmVirtRules.fdf.inc
@@ -39,6 +39,11 @@ [Rule.Common.SEC]
TE TE Align =3D Auto $(INF_OUTPUT)/$(MODULE_NAME).efi=
=0D
}=0D
=0D
+[Rule.Common.SEC.SELF_RELOC]=0D
+ FILE SEC =3D $(NAMED_GUID) {=0D
+ TE TE Align =3D Auto $(INF_OUTPUT)/$(MODULE_NAME).efi=0D
+ }=0D
+=0D
[Rule.Common.PEI_CORE]=0D
FILE PEI_CORE =3D $(NAMED_GUID) FIXED {=0D
TE TE Align =3D Auto $(INF_OUTPUT)/$(MODULE_NAME).efi=
=0D
--=20
2.26.2


[PATCH v2 0/3] ArmVirtPkg: use PE/COFF metadata for self relocation

Ard Biesheuvel
 

As suggested by Jiewen in response to Ilias RFC [0], it is better to use
the PE/COFF metadata for self-relocating executables than to rely on ELF
metadata, given how the latter is only available when using ELF based
toolchains. Also, we have had some maintenance issues with this code in
the past, as PIE linking of non-position independent objects is not a wel=
l
tested code path in toolchains in general.

So implement this for the self-relocating PrePi in ArmVirtPkg first.

First, we need to ensure that the module in question is emitted with its
PE/COFF relocation metadata preserved, by creating a special FDF rule.

We also need to provide a way for the code to refer to the start of the
image directly, by adding it to the linker script.

Then, it is simply a matter of swapping out the two assembly routines,
and adding the C code that serves the same purpose but based on PE/COFF
base relocations.

Note that PE/COFF relocations are considerably more compact than ELF RELA
relocations, so this does not impact the memory footprint of the resultin=
g
image adversely.

[0] https://edk2.groups.io/g/devel/message/60835

Changes since v1:
- Drop change to linker script, and instead, use the existing FV parsing =
code
(which is already incorporated into PrePi to load other modules), to fi=
nd
the start address of the image before relocation. This way, we can supp=
ort
TE images as well as PE32 images naturally, and not rely on GCC/binutil=
s
specific artifacts that make porting to a native PE/COFF toolchain more
difficult
- Switch to TE format in the SELF_RELOC FDF rule - this is not terribly
likely to matter in practice, but since PrePi is the only module that
is incorporated in uncompressed form, and given that we used TE format
before these changes, it is a more appropriate default.
- Add acks from Jiewen, Laszlo and Sami. Note that I have dropped the
Tested-bys - apologies for wasting anyone's time, but they could not
be carried over due to the changes.

Cc: Laszlo Ersek <lersek@...>
Cc: Leif Lindholm <leif@...>
Cc: Ilias Apalodimas <ilias.apalodimas@...>
Cc: Julien Grall <julien@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Sami Mujawar <Sami.Mujawar@...>

Ard Biesheuvel (3):
ArmVirtPkg: add FDF rule for self-relocating PrePi
ArmVirtPkg/PrePi: use standard PeCoff routines for self-relocation
ArmVirtPkg: remove unused files

ArmVirtPkg/ArmVirtQemuKernel.dsc | 10 ++--
ArmVirtPkg/ArmVirtXen.dsc | 10 ++--
ArmVirtPkg/ArmVirtQemuKernel.fdf | 2 +-
ArmVirtPkg/ArmVirtXen.fdf | 2 +-
ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 4 +-
ArmVirtPkg/Include/Platform/Hidden.h | 22 ---------
ArmVirtPkg/PrePi/PrePi.c | 35 ++++++++++++++
ArmVirtPkg/ArmVirtRules.fdf.inc | 5 ++
ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S | 49 +++++----------=
-----
ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S | 47 +++++----------=
----
ArmVirtPkg/PrePi/Scripts/PrePi-PIE.lds | 41 ---------------=
-
11 files changed, 75 insertions(+), 152 deletions(-)
delete mode 100644 ArmVirtPkg/Include/Platform/Hidden.h
delete mode 100644 ArmVirtPkg/PrePi/Scripts/PrePi-PIE.lds

--=20
2.26.2


Method to identify processor manufacturer: WAS: UefiCpuPkg: Discuss: Move StandardSignatureIsAuthenticAMD function to BaseUefiCpuLib

Kirkendall, Garrett
 

[AMD Public Use]

 

+ Michael Kinney, Liming Gao for MdePkg

 

We have several instances where Intel and AMD processors differ.  Therefore, we must determine between the two X64 processors.  Currently we have multiple copies of StandardSignatureIsAuthenticAMD function throughout UefiCpuPkg.  They check CPUID:0 for AuthenticAMD.  My initial thought was to move the function to UefiCpuPkg/BaseUefiCpuLib/.  Eric Dong suggested it could be in MdePkg/Library/BaseCpuLib.

 

Does it make sense to have a way to identify the processor designer/processor technology via BaseCpuLib?  What could that look like?  Would it be many functions targeted at each designer/technology, or something different?

 

Or should we keep the functionality all within UefiCpuPkg as it is today and consolidate the functions into BaseUefiCpuLib?

 

Garrett Kirkendall
SMTS Firmware Engineer | CTE
7171 Southwest Parkway, Austin, TX 78735 USA
AMD   facebook  |  amd.com

 

From: Dong, Eric <eric.dong@...>
Sent: Thursday, June 11, 2020 2:07 AM
To: Ni, Ray <ray.ni@...>; devel@edk2.groups.io; Kirkendall, Garrett <Garrett.Kirkendall@...>
Cc: Laszlo Ersek <lersek@...>
Subject: RE: UefiCpuPkg: Discuss: Move StandardSignatureIsAuthenticAMD function to BaseUefiCpuLib

 

[CAUTION: External Email]

I mean there is already a BaseCpuLib in MdePkg. Is it possible to add it to there?

 

If no usage outside of UefiCpuPkg, I’m ok to move this function to UefiCpuLib.

 

Thanks,

Eric

 

From: Ni, Ray <ray.ni@...>
Sent: Thursday, June 11, 2020 12:56 PM
To: Dong, Eric <eric.dong@...>; devel@edk2.groups.io; garrett.kirkendall@...
Cc: Laszlo Ersek <lersek@...>
Subject: RE: UefiCpuPkg: Discuss: Move StandardSignatureIsAuthenticAMD function to BaseUefiCpuLib

 

UefiCpuLib is in UefiCpuPkg.

All consumers are in UefiCpuPkg. I think we can keep its location unchanged.

 

From: Dong, Eric <eric.dong@...>
Sent: Thursday, June 11, 2020 9:29 AM
To: Ni, Ray <ray.ni@...>; devel@edk2.groups.io; garrett.kirkendall@...
Cc: Laszlo Ersek <lersek@...>
Subject: RE: UefiCpuPkg: Discuss: Move StandardSignatureIsAuthenticAMD function to BaseUefiCpuLib

 

This proposal is ok to me.

 

I’m not sure whether it can be added to MdePkg, just like add to CpuLib. I found all the definitions and functions used in StandardSignatureIsAuthenticAMD function defined in MdePkg.

 

If it can be added to MdePkg, all code base can use this function, if it been added to UefiCpuPkg, other core packages may can’t use it.

 

Thanks,

Eric

From: Ni, Ray <ray.ni@...>
Sent: Thursday, June 11, 2020 9:12 AM
To: devel@edk2.groups.io; garrett.kirkendall@...
Cc: Dong, Eric <eric.dong@...>; Laszlo Ersek <lersek@...>
Subject: RE: UefiCpuPkg: Discuss: Move StandardSignatureIsAuthenticAMD function to BaseUefiCpuLib

 

Since all platform DSCs have already listed UefiCpuLib.inf so this change doesn't impact platform DSC.
I don't see an issue with this change.

Eric,
What's your opinion?

Thanks,
Ray

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Kirkendall, Garrett
> Sent: Wednesday, June 10, 2020 10:18 PM
> To: devel@edk2.groups.io
> Cc: Dong, Eric <eric.dong@...>; Ni, Ray <ray.ni@...>; Laszlo Ersek <lersek@...>
> Subject: [edk2-devel] UefiCpuPkg: Discuss: Move StandardSignatureIsAuthenticAMD function to BaseUefiCpuLib

> [AMD Public Use]

> There are currently three instances of StandardSignatureIsAuthenticAMD Function in the below locations.  I need to
> propose another change that will require the same function in PiSmmCpuDxeSmm.  I would like to see this function move
> to a single "LibraryClass" location.  I think no one knew where to propose the function, so we ended up with three
> instances so far.  The best place I can find would be UefiCpuPkg/BaseUefiCpuLib/.  Thoughts?  Is there a better function
> name such that a similar Intel identifier function could be created when needed in the future?

> I'm thinking this will be 3 patches
> 1. Add StandardSignatureIsAuthenticAMD to BaseUefiCpuLib
> 2. Move current instances to Library function
> 3. Propose code change in PiSmmCpuDxeSmm

> UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c: StandardSignatureIsAuthenticAMD (
> UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c: StandardSignatureIsAuthenticAMD (
> UefiCpuPkg/Library/MpInitLib/MpLib.c: StandardSignatureIsAuthenticAMD (

> GARRETT KIRKENDALL
> SMTS Firmware Engineer | CTE
> 7171 Southwest Parkway, Austin, TX 78735 USA
> AMD   facebook  |  amd.com


[PATCH v5] Features/Intel/BeepDebugFeaturePkg: add it.

Tan, Ming
 

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

The BeepDebugFeaturePkg include some useful beep debug
libraries, such as get beep value from status code and beep.

It provide a library BeepStatusCodeHandlerLib used by edk2
StatusCodeHandler.efi, used to do beep if needed.
It also provide a library of BeepMap lib, it map the status code
to beep value.
A library of Beep lib is needed by platform, and this pkg has a
Null implementation.

Cc: Eric Dong <eric.dong@...>
Cc: Liming Gao <liming.gao@...>
Signed-off-by: Ming Tan <ming.tan@...>
---
V5: In .inf files, remove some useless library.
In RuntimeDxeBeepStatusCodeHandlerLib.c, add a variable to indicate whe=
ther need unregister.
V4: Change Include/BeepDebugFeature.dsc, make it can be included in platfor=
m dsc file.
V3: Modify according the Eric's review comments.
V2: Delete the last empty line in BeepDebugFeaturePkg/Library/BeepMapLib/Be=
epMapLib.inf
.../BeepDebugFeaturePkg.dec | 36 +++
.../BeepDebugFeaturePkg.dsc | 30 ++
.../Include/BeepDebugFeature.dsc | 193 +++++++++++++
.../Include/Library/BeepLib.h | 33 +++
.../Include/Library/BeepMapLib.h | 32 +++
.../Library/BeepLib/BeepLibNull.c | 37 +++
.../Library/BeepLib/BeepLibNull.inf | 26 ++
.../Library/BeepMapLib/BeepMapLib.c | 116 ++++++++
.../Library/BeepMapLib/BeepMapLib.inf | 27 ++
.../BeepMapLib/PlatformStatusCodesInternal.h | 270 ++++++++++++++++++
.../PeiBeepStatusCodeHandlerLib.c | 101 +++++++
.../PeiBeepStatusCodeHandlerLib.inf | 49 ++++
.../RuntimeDxeBeepStatusCodeHandlerLib.c | 184 ++++++++++++
.../RuntimeDxeBeepStatusCodeHandlerLib.inf | 51 ++++
.../SmmBeepStatusCodeHandlerLib.c | 138 +++++++++
.../SmmBeepStatusCodeHandlerLib.inf | 50 ++++
.../Debugging/BeepDebugFeaturePkg/Readme.md | 126 ++++++++
17 files changed, 1499 insertions(+)
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/BeepDebugF=
eaturePkg.dec
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/BeepDebugF=
eaturePkg.dsc
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Include/Be=
epDebugFeature.dsc
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Include/Li=
brary/BeepLib.h
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Include/Li=
brary/BeepMapLib.h
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epLib/BeepLibNull.c
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epLib/BeepLibNull.inf
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epMapLib/BeepMapLib.c
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epMapLib/BeepMapLib.inf
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epMapLib/PlatformStatusCodesInternal.h
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epStatusCodeHandlerLib/PeiBeepStatusCodeHandlerLib.c
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epStatusCodeHandlerLib/PeiBeepStatusCodeHandlerLib.inf
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epStatusCodeHandlerLib/RuntimeDxeBeepStatusCodeHandlerLib.c
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epStatusCodeHandlerLib/RuntimeDxeBeepStatusCodeHandlerLib.inf
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epStatusCodeHandlerLib/SmmBeepStatusCodeHandlerLib.c
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Be=
epStatusCodeHandlerLib/SmmBeepStatusCodeHandlerLib.inf
create mode 100644 Features/Intel/Debugging/BeepDebugFeaturePkg/Readme.md

diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/BeepDebugFeatureP=
kg.dec b/Features/Intel/Debugging/BeepDebugFeaturePkg/BeepDebugFeaturePkg.d=
ec
new file mode 100644
index 0000000000..4f4b36b091
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/BeepDebugFeaturePkg.dec
@@ -0,0 +1,36 @@
+## @file=0D
+# This package provides Beep Debug feature.=0D
+# This package should only depend on EDK II Core packages, IntelSiliconPkg=
, and MinPlatformPkg.=0D
+#=0D
+# The DEC files are used by the utilities that parse DSC and=0D
+# INF files to generate AutoGen.c and AutoGen.h files=0D
+# for the build infrastructure.=0D
+#=0D
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>=0D
+#=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ DEC_SPECIFICATION =3D 0x00010017=0D
+ PACKAGE_NAME =3D BeepDebugFeaturePkg=0D
+ PACKAGE_GUID =3D DD88CEBB-E68F-4155-B754-D11E4FDF008D=0D
+ PACKAGE_VERSION =3D 0.1=0D
+=0D
+[Includes]=0D
+ Include=0D
+=0D
+[LibraryClasses]=0D
+ ## @libraryclass Provide the function to map the status code to bee=
p value.=0D
+ BeepMapLib|Include/Library/BeepMapLib.h=0D
+=0D
+ ## @libraryclass Provide the function to do the real beep.=0D
+ BeepLib|Include/Library/BeepLib.h=0D
+=0D
+[Guids]=0D
+ gBeepDebugFeaturePkgTokenSpaceGuid =3D {0x54f56fb5, 0xea0e, 0x4518, {0=
xa0, 0x3e, 0x1b, 0xeb, 0x56, 0x94, 0xd2, 0x16}}=0D
+=0D
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]=0D
+ # Beep is a legacy feature, disabled it by default=0D
+ gBeepDebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseBeep|FALSE|BOOLEAN|0x=
00000001=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/BeepDebugFeatureP=
kg.dsc b/Features/Intel/Debugging/BeepDebugFeaturePkg/BeepDebugFeaturePkg.d=
sc
new file mode 100644
index 0000000000..47254f9974
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/BeepDebugFeaturePkg.dsc
@@ -0,0 +1,30 @@
+## @file=0D
+# This package provides Beep Debug feature.=0D
+# This package should only depend on EDK II Core packages, IntelSiliconPkg=
, and MinPlatformPkg.=0D
+#=0D
+# The DEC files are used by the utilities that parse DSC and=0D
+# INF files to generate AutoGen.c and AutoGen.h files=0D
+# for the build infrastructure.=0D
+#=0D
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>=0D
+#=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ PLATFORM_NAME =3D BeepDebugFeaturePkg=0D
+ PLATFORM_GUID =3D D716EDF2-77BB-4536-9C64-4D7EEF0F3896=
=0D
+ PLATFORM_VERSION =3D 0.1=0D
+ DSC_SPECIFICATION =3D 0x00010005=0D
+ OUTPUT_DIRECTORY =3D Build/$(PLATFORM_NAME)=0D
+ SUPPORTED_ARCHITECTURES =3D IA32|X64=0D
+ BUILD_TARGETS =3D DEBUG|RELEASE|NOOPT=0D
+ SKUID_IDENTIFIER =3D DEFAULT=0D
+ PEI_ARCH =3D IA32=0D
+ DXE_ARCH =3D X64=0D
+=0D
+#=0D
+# This package always builds the feature.=0D
+#=0D
+!include Include/BeepDebugFeature.dsc=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Include/BeepDebug=
Feature.dsc b/Features/Intel/Debugging/BeepDebugFeaturePkg/Include/BeepDebu=
gFeature.dsc
new file mode 100644
index 0000000000..1ae5ad76af
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Include/BeepDebugFeature=
.dsc
@@ -0,0 +1,193 @@
+## @file=0D
+# This package provides Beep Debug feature.=0D
+# This file should be included into another package DSC file to build this=
feature.=0D
+#=0D
+# The DEC files are used by the utilities that parse DSC and=0D
+# INF files to generate AutoGen.c and AutoGen.h files=0D
+# for the build infrastructure.=0D
+#=0D
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>=0D
+#=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+##########################################################################=
######=0D
+#=0D
+# Defines Section - statements that will be processed to create a Makefile=
.=0D
+#=0D
+##########################################################################=
######=0D
+[Defines]=0D
+!ifndef $(PEI_ARCH)=0D
+ !error "PEI_ARCH must be specified to build this feature!"=0D
+!endif=0D
+!ifndef $(DXE_ARCH)=0D
+ !error "DXE_ARCH must be specified to build this feature!"=0D
+!endif=0D
+=0D
+##########################################################################=
######=0D
+#=0D
+# PCD Section - list of PCD Entries modified by the feature.=0D
+#=0D
+##########################################################################=
######=0D
+[PcdsDynamicDefault]=0D
+ gBeepDebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseBeep|TRUE=0D
+=0D
+##########################################################################=
######=0D
+#=0D
+# Library Class section - list of all Library Classes needed by this featu=
re.=0D
+#=0D
+##########################################################################=
######=0D
+[LibraryClasses]=0D
+ #######################################=0D
+ # Edk2 Packages=0D
+ #######################################=0D
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf=0D
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf=0D
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf=0D
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf=0D
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf=0D
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf=0D
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf=0D
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf=0D
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf=0D
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplat=
e.inf=0D
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBoo=
tServicesTableLib.inf=0D
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry=
Point.inf=0D
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf=0D
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/U=
efiRuntimeServicesTableLib.inf=0D
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf=0D
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHo=
okStatusCodeLibNull.inf=0D
+ SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull=
.inf=0D
+=0D
+ BeepLib|BeepDebugFeaturePkg/Library/BeepLib/BeepLibNull.inf=0D
+=0D
+ #####################################=0D
+ # Beep Debug Feature Package=0D
+ #####################################=0D
+ BeepMapLib|BeepDebugFeaturePkg/Library/BeepMapLib/BeepMapLib.inf=0D
+=0D
+[LibraryClasses.common.PEIM]=0D
+ #######################################=0D
+ # Edk2 Packages=0D
+ #######################################=0D
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf=0D
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAlloc=
ationLib.inf=0D
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/=
PeiServicesTablePointerLibIdt.inf=0D
+=0D
+[LibraryClasses.IA32.PEIM,LibraryClasses.IA32.PEI_CORE,LibraryClasses.IA32=
.SEC]=0D
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiRepor=
tStatusCodeLib.inf=0D
+=0D
+[LibraryClasses.common.DXE_DRIVER]=0D
+ #######################################=0D
+ # Edk2 Packages=0D
+ #######################################=0D
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf=0D
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll=
ocationLib.inf=0D
+=0D
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]=0D
+ #######################################=0D
+ # Edk2 Packages=0D
+ #######################################=0D
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf=0D
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll=
ocationLib.inf=0D
+ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf=0D
+ ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/R=
untimeDxeReportStatusCodeLib.inf=0D
+=0D
+[LibraryClasses.common.UEFI_DRIVER]=0D
+ #######################################=0D
+ # Edk2 Packages=0D
+ #######################################=0D
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf=0D
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll=
ocationLib.inf=0D
+=0D
+[LibraryClasses.X64.DXE_SMM_DRIVER]=0D
+ #######################################=0D
+ # Edk2 Packages=0D
+ #######################################=0D
+ SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableL=
ib.inf=0D
+ MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAlloc=
ationLib.inf=0D
+ SmmIoLib|MdePkg/Library/SmmIoLib/SmmIoLib.inf=0D
+ SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf=0D
+ ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmRepor=
tStatusCodeLib.inf=0D
+=0D
+##########################################################################=
######=0D
+#=0D
+# Component section - list of all components that need built for this feat=
ure.=0D
+#=0D
+# Note: The EDK II DSC file is not used to specify how compiled binary ima=
ges get placed=0D
+# into firmware volume images. This section is just a list of module=
s to compile from=0D
+# source into UEFI-compliant binaries.=0D
+# It is the FDF file that contains information on combining binary f=
iles into firmware=0D
+# volume images, whose concept is beyond UEFI and is described in PI=
specification.=0D
+# There may also be modules listed in this section that are not requ=
ired in the FDF file,=0D
+# When a module listed here is excluded from FDF file, then UEFI-com=
pliant binary will be=0D
+# generated for it, but the binary will not be put into any firmware=
volume.=0D
+#=0D
+##########################################################################=
######=0D
+#=0D
+# Feature PEI Components=0D
+#=0D
+=0D
+# @todo: Change below line to [Components.$(PEI_ARCH)] after https://bugzi=
lla.tianocore.org/show_bug.cgi?id=3D2308=0D
+# is completed.=0D
+[Components.IA32]=0D
+ #####################################=0D
+ # Beep Debug Feature Package=0D
+ #####################################=0D
+=0D
+ # Add library instances here that are not included in package components=
and should be tested=0D
+ # in the package build.=0D
+ BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/PeiBeepStatusCodeHa=
ndlerLib.inf=0D
+=0D
+ # The following is an example for used with StatusCodeHandler:=0D
+# MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf {=
=0D
+# <LibraryClasses>=0D
+# NULL|BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/PeiBeepSta=
tusCodeHandlerLib.inf=0D
+# }=0D
+=0D
+ # Add components here that should be included in the package build.=0D
+=0D
+#=0D
+# Feature DXE Components=0D
+#=0D
+=0D
+# @todo: Change below line to [Components.$(DXE_ARCH)] after https://bugzi=
lla.tianocore.org/show_bug.cgi?id=3D2308=0D
+# is completed.=0D
+[Components.X64]=0D
+ #####################################=0D
+ # Beep Debug Feature Package=0D
+ #####################################=0D
+=0D
+ # Add library instances here that are not included in package components=
and should be tested=0D
+ # in the package build.=0D
+ BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/RuntimeDxeBeepStatu=
sCodeHandlerLib.inf=0D
+ BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/SmmBeepStatusCodeHa=
ndlerLib.inf=0D
+=0D
+ # The following is an example for used with StatusCodeHandler:=0D
+# MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRun=
timeDxe.inf {=0D
+# <LibraryClasses>=0D
+# NULL|BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/RuntimeDxe=
BeepStatusCodeHandlerLib.inf=0D
+# }=0D
+=0D
+# MdeModulePkg/Universal/StatusCodeHandler/Smm/StatusCodeHandlerSmm.inf {=
=0D
+# <LibraryClasses>=0D
+# NULL|BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/SmmBeepSta=
tusCodeHandlerLib.inf=0D
+# }=0D
+=0D
+ # Add components here that should be included in the package build.=0D
+=0D
+##########################################################################=
#########################=0D
+#=0D
+# BuildOptions Section - Define the module specific tool chain flags that =
should be used as=0D
+# the default flags for a module. These flags are a=
ppended to any=0D
+# standard flags that are defined by the build proc=
ess. They can be=0D
+# applied for any modules or only those modules wit=
h the specific=0D
+# module style (EDK or EDKII) specified in [Compone=
nts] section.=0D
+#=0D
+# For advanced features, it is recommended to enabl=
e [BuildOptions] in=0D
+# the applicable INF file so it does not affect the=
whole board package=0D
+# build when this DSC file is active.=0D
+#=0D
+##########################################################################=
#########################=0D
+[BuildOptions]=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Include/Library/B=
eepLib.h b/Features/Intel/Debugging/BeepDebugFeaturePkg/Include/Library/Bee=
pLib.h
new file mode 100644
index 0000000000..f768acc557
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Include/Library/BeepLib.h
@@ -0,0 +1,33 @@
+/** @file=0D
+ Provides services to send progress/error codes to Beep device.=0D
+=0D
+ Copyright (c) 2011 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#ifndef __BEEP_LIB_H__=0D
+#define __BEEP_LIB_H__=0D
+=0D
+/**=0D
+ Sends a 32-bit value to Beep device.=0D
+=0D
+ Sends the 32-bit value specified by Value to Beep device, and returns Va=
lue.=0D
+ Some implementations of this library function may perform I/O operations=
=0D
+ directly to Beep device. Other implementations may send Value to=0D
+ ReportStatusCode(), and the status code reporting mechanism will eventua=
lly=0D
+ display the 32-bit value on the status reporting device.=0D
+=0D
+ Beep() must actively prevent recursion. If Beep() is called while=0D
+ processing another Post Code Library function, then=0D
+ Beep() must return Value immediately.=0D
+=0D
+ @param Value Beep count.=0D
+**/=0D
+VOID=0D
+EFIAPI=0D
+Beep (=0D
+ IN UINT32 Value=0D
+ );=0D
+=0D
+#endif=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Include/Library/B=
eepMapLib.h b/Features/Intel/Debugging/BeepDebugFeaturePkg/Include/Library/=
BeepMapLib.h
new file mode 100644
index 0000000000..7600d72ecd
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Include/Library/BeepMapL=
ib.h
@@ -0,0 +1,32 @@
+/** @file=0D
+ This library class provides Platform Beep Map.=0D
+=0D
+ Copyright (c) 2011 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#ifndef __BEEP_MAP_LIB__=0D
+#define __BEEP_MAP_LIB__=0D
+=0D
+/**=0D
+ Get BeepValue from status code type and value.=0D
+=0D
+ @param CodeType Indicates the type of status code being reporte=
d.=0D
+ @param Value Describes the current status of a hardware or=0D
+ software entity. This includes information abou=
t the class and=0D
+ subclass that is used to classify the entity as=
well as an operation.=0D
+ For progress codes, the operation is the curren=
t activity.=0D
+ For error codes, it is the exception.For debug =
codes,it is not defined at this time.=0D
+=0D
+ @return BeepValue=0D
+=0D
+**/=0D
+UINT32=0D
+EFIAPI=0D
+GetBeepValueFromStatusCode (=0D
+ IN EFI_STATUS_CODE_TYPE CodeType,=0D
+ IN EFI_STATUS_CODE_VALUE Value=0D
+ );=0D
+=0D
+#endif=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepLib/B=
eepLibNull.c b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepLib=
/BeepLibNull.c
new file mode 100644
index 0000000000..a0bd946b50
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepLib/BeepLibN=
ull.c
@@ -0,0 +1,37 @@
+/** @file=0D
+ BeepLib Null implementation.=0D
+=0D
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#include <Base.h>=0D
+#include <Uefi.h>=0D
+=0D
+/**=0D
+ NULL implemented of Beep() function, just return directly.=0D
+ Normal Beep() function will do the following:=0D
+=0D
+ Sends a 32-bit value to Beep device.=0D
+=0D
+ Sends the 32-bit value specified by Value to Beep device, and returns Va=
lue.=0D
+ Some implementations of this library function may perform I/O operations=
=0D
+ directly to Beep device. Other implementations may send Value to=0D
+ ReportStatusCode(), and the status code reporting mechanism will eventua=
lly=0D
+ display the 32-bit value on the status reporting device.=0D
+=0D
+ Beep() must actively prevent recursion. If Beep() is called while=0D
+ processing another Post Code Library function, then=0D
+ Beep() must return Value immediately.=0D
+=0D
+ @param Value Beep count.=0D
+**/=0D
+VOID=0D
+EFIAPI=0D
+Beep (=0D
+ IN UINT32 Value=0D
+ )=0D
+{=0D
+ return;=0D
+}=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepLib/B=
eepLibNull.inf b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepL=
ib/BeepLibNull.inf
new file mode 100644
index 0000000000..7f84dad082
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepLib/BeepLibN=
ull.inf
@@ -0,0 +1,26 @@
+## @file=0D
+# Instance of Platform Beep Null Library.=0D
+#=0D
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010017=0D
+ BASE_NAME =3D BeepLib=0D
+ FILE_GUID =3D 319F24D8-9F3E-4BEC-B1C4-C54BE51F3FC2=
=0D
+ VERSION_STRING =3D 1.0=0D
+ MODULE_TYPE =3D BASE=0D
+ LIBRARY_CLASS =3D BeepLib=0D
+#=0D
+# The following information is for reference only and not required by the =
build tools.=0D
+#=0D
+# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC=0D
+#=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+=0D
+[Sources]=0D
+ BeepLibNull.c=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepMapLi=
b/BeepMapLib.c b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepM=
apLib/BeepMapLib.c
new file mode 100644
index 0000000000..26c32dfd9b
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepMapLib/BeepM=
apLib.c
@@ -0,0 +1,116 @@
+/** @file=0D
+ BeepMap implementation.=0D
+=0D
+ Copyright (c) 2012 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#include <Base.h>=0D
+#include <Uefi.h>=0D
+=0D
+#include "PlatformStatusCodesInternal.h"=0D
+=0D
+STATUS_CODE_TO_DATA_MAP mBeepProgressMap[] =3D {=0D
+ //=0D
+ // PEI=0D
+ //=0D
+ // Recovery=0D
+ { PEI_RECOVERY_STARTED, 2 },=0D
+=0D
+ //=0D
+ // DXE=0D
+ //=0D
+=0D
+ {0,0}=0D
+};=0D
+=0D
+STATUS_CODE_TO_DATA_MAP mBeepErrorMap[] =3D {=0D
+ //=0D
+ // PEI=0D
+ //=0D
+ // Regular boot=0D
+ { PEI_MEMORY_NOT_DETECTED, 1 },=0D
+ { PEI_MEMORY_INSTALLED_TWICE, 1 },=0D
+ { PEI_DXEIPL_NOT_FOUND, 3 },=0D
+ { PEI_DXE_CORE_NOT_FOUND, 3 },=0D
+ { PEI_RESET_NOT_AVAILABLE, 7 },=0D
+ // Recovery=0D
+ { PEI_RECOVERY_FAILED, 4 },=0D
+ // S3 Resume=0D
+ { PEI_S3_RESUME_FAILED, 4 },=0D
+=0D
+ //=0D
+ // DXE=0D
+ //=0D
+ { DXE_ARCH_PROTOCOL_NOT_AVAILABLE, 4 },=0D
+ { DXE_NO_CON_OUT, 5 },=0D
+ { DXE_NO_CON_IN, 5 },=0D
+ { DXE_INVALID_PASSWORD, 1 },=0D
+ { DXE_FLASH_UPDATE_FAILED, 6 },=0D
+ { DXE_RESET_NOT_AVAILABLE, 7 },=0D
+=0D
+ {0,0}=0D
+};=0D
+=0D
+STATUS_CODE_TO_DATA_MAP *mBeepStatusCodesMap[] =3D {=0D
+ //#define EFI_PROGRESS_CODE 0x00000001=0D
+ mBeepProgressMap,=0D
+ //#define EFI_ERROR_CODE 0x00000002=0D
+ mBeepErrorMap=0D
+ //#define EFI_DEBUG_CODE 0x00000003=0D
+};=0D
+=0D
+/**=0D
+ Find the beep data from status code value.=0D
+=0D
+ @param Map The map used to find in.=0D
+ @param Value The status code value.=0D
+=0D
+ @return BeepValue 0 for not found.=0D
+=0D
+**/=0D
+UINT32=0D
+FindBeepData (=0D
+ IN STATUS_CODE_TO_DATA_MAP *Map,=0D
+ IN EFI_STATUS_CODE_VALUE Value=0D
+ )=0D
+{=0D
+ while (Map->Value !=3D 0) {=0D
+ if (Map->Value =3D=3D Value) {=0D
+ return Map->Data;=0D
+ }=0D
+ Map++;=0D
+ }=0D
+ return 0;=0D
+}=0D
+=0D
+/**=0D
+ Get BeepValue from status code type and value.=0D
+=0D
+ @param CodeType Indicates the type of status code being reporte=
d.=0D
+ @param Value Describes the current status of a hardware or=0D
+ software entity. This includes information abou=
t the class and=0D
+ subclass that is used to classify the entity as=
well as an operation.=0D
+ For progress codes, the operation is the curren=
t activity.=0D
+ For error codes, it is the exception.For debug =
codes,it is not defined at this time.=0D
+=0D
+ @return BeepValue=0D
+**/=0D
+UINT32=0D
+EFIAPI=0D
+GetBeepValueFromStatusCode (=0D
+ IN EFI_STATUS_CODE_TYPE CodeType,=0D
+ IN EFI_STATUS_CODE_VALUE Value=0D
+ )=0D
+{=0D
+ UINT32 CodeTypeIndex;=0D
+=0D
+ CodeTypeIndex =3D STATUS_CODE_TYPE (CodeType) - 1;=0D
+=0D
+ if (CodeTypeIndex >=3D sizeof (mBeepStatusCodesMap) / sizeof(mBeepStatus=
CodesMap[0])) {=0D
+ return 0;=0D
+ }=0D
+=0D
+ return FindBeepData (mBeepStatusCodesMap[CodeTypeIndex], Value);=0D
+}=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepMapLi=
b/BeepMapLib.inf b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/Bee=
pMapLib/BeepMapLib.inf
new file mode 100644
index 0000000000..b957eee07b
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepMapLib/BeepM=
apLib.inf
@@ -0,0 +1,27 @@
+## @file=0D
+# Instance of Beep Map Library.=0D
+#=0D
+# Copyright (c) 2011 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010017=0D
+ BASE_NAME =3D BeepMapLib=0D
+ FILE_GUID =3D 8BAFA82F-DA9E-4cce-8FA2-9DA189D7246D=
=0D
+ VERSION_STRING =3D 2.0=0D
+ MODULE_TYPE =3D BASE=0D
+ LIBRARY_CLASS =3D BeepMapLib=0D
+#=0D
+# The following information is for reference only and not required by the =
build tools.=0D
+#=0D
+# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC=0D
+#=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+=0D
+[Sources]=0D
+ BeepMapLib.c=0D
+ PlatformStatusCodesInternal.h=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepMapLi=
b/PlatformStatusCodesInternal.h b/Features/Intel/Debugging/BeepDebugFeature=
Pkg/Library/BeepMapLib/PlatformStatusCodesInternal.h
new file mode 100644
index 0000000000..a36134c933
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepMapLib/Platf=
ormStatusCodesInternal.h
@@ -0,0 +1,270 @@
+/** @file=0D
+ Beep status code definition.=0D
+=0D
+ Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#ifndef __PLATFORM_STATUS_CODES_INTERNAL_H__=0D
+#define __PLATFORM_STATUS_CODES_INTERNAL_H__=0D
+=0D
+#include <Pi/PiStatusCode.h>=0D
+=0D
+typedef struct{=0D
+ EFI_STATUS_CODE_VALUE Value;=0D
+ UINT32 Data;=0D
+} STATUS_CODE_TO_DATA_MAP;=0D
+=0D
+//=0D
+// Enable PEI/DXE status code=0D
+//=0D
+#define PEI_STATUS_CODE 1=0D
+#define DXE_STATUS_CODE 1=0D
+=0D
+#define STATUS_CODE_TYPE(Type) ((Type)&EFI_STATUS_CODE_TYPE=
_MASK)=0D
+#define STATUS_CODE_CLASS(Value) ((Value)&EFI_STATUS_CODE_CLA=
SS_MASK)=0D
+=0D
+//Progress/Error codes=0D
+#define PEI_CORE_STARTED (EFI_SOFTWARE_PEI_CORE | EFI=
_SW_PEI_CORE_PC_ENTRY_POINT)=0D
+#define PEI_RESET_NOT_AVAILABLE (EFI_SOFTWARE_PEI_CORE | EFI=
_SW_PS_EC_RESET_NOT_AVAILABLE)=0D
+#define PEI_DXEIPL_NOT_FOUND (EFI_SOFTWARE_PEI_CORE | EFI=
_SW_PEI_CORE_EC_DXEIPL_NOT_FOUND)=0D
+#define PEI_DXE_CORE_NOT_FOUND (EFI_SOFTWARE_PEI_CORE | EFI=
_SW_PEI_CORE_EC_DXE_CORRUPT)=0D
+#define PEI_S3_RESUME_ERROR (EFI_SOFTWARE_PEI_CORE | EFI=
_SW_PEI_EC_S3_RESUME_FAILED)=0D
+#define PEI_RECOVERY_FAILED (EFI_SOFTWARE_PEI_CORE | EFI=
_SW_PEI_EC_RECOVERY_FAILED)=0D
+#define DXE_CORE_STARTED (EFI_SOFTWARE_DXE_CORE | EFI=
_SW_DXE_CORE_PC_ENTRY_POINT)=0D
+=0D
+//#define DXE_EXIT_BOOT_SERVICES_BEGIN 0xF8=0D
+#define DXE_EXIT_BOOT_SERVICES_END (EFI_SOFTWARE_EFI_BOOT_SERVI=
CE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)=0D
+=0D
+// Reported by CPU PEIM=0D
+#define PEI_CAR_CPU_INIT (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_PC_POWER_ON_INIT)=0D
+=0D
+// Reported by NB PEIM=0D
+//#define PEI_CAR_NB_INIT (EFI_COMPUTING_UNIT_CHIPSE=
T | EFI_CU_CHIPSET_NORTH_INIT)=0D
+=0D
+// Reported by SB PEIM=0D
+//#define PEI_CAR_SB_INIT (EFI_COMPUTING_UNIT_CHIPSE=
T | EFI_CU_CHIPSET_PC_SOUTH_INIT)=0D
+=0D
+//Reported by Memory Detection PEIM=0D
+#define PEI_MEMORY_SPD_READ (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_PC_SPD_READ)=0D
+#define PEI_MEMORY_PRESENCE_DETECT (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_PC_PRESENCE_DETECT)=0D
+#define PEI_MEMORY_TIMING (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_PC_TIMING)=0D
+#define PEI_MEMORY_CONFIGURING (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_PC_CONFIGURING)=0D
+#define PEI_MEMORY_OPTIMIZING (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_PC_OPTIMIZING)=0D
+#define PEI_MEMORY_INIT (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_PC_INIT)=0D
+#define PEI_MEMORY_TEST (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_PC_TEST)=0D
+#define PEI_MEMORY_INVALID_TYPE (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_INVALID_TYPE)=0D
+#define PEI_MEMORY_INVALID_SPEED (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_INVALID_SPEED)=0D
+#define PEI_MEMORY_SPD_FAIL (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_SPD_FAIL)=0D
+#define PEI_MEMORY_INVALID_SIZE (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_INVALID_SIZE)=0D
+#define PEI_MEMORY_MISMATCH (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_MISMATCH)=0D
+#define PEI_MEMORY_S3_RESUME_FAILED (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_S3_RESUME_FAIL)=0D
+#define PEI_MEMORY_NOT_DETECTED (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_NONE_DETECTED)=0D
+#define PEI_MEMORY_NONE_USEFUL (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_NONE_USEFUL)=0D
+#define PEI_MEMORY_ERROR (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_EC_NON_SPECIFIC)=0D
+#define PEI_MEMORY_INSTALLED (EFI_SOFTWARE_PEI_SERVICE |=
EFI_SW_PS_PC_INSTALL_PEI_MEMORY)=0D
+#define PEI_MEMORY_NOT_INSTALLED (EFI_SOFTWARE_PEI_SERVICE |=
EFI_SW_PEI_CORE_EC_MEMORY_NOT_INSTALLED)=0D
+#define PEI_MEMORY_INSTALLED_TWICE (EFI_SOFTWARE_PEI_SERVICE |=
EFI_SW_PS_EC_MEMORY_INSTALLED_TWICE)=0D
+=0D
+//Reported by CPU PEIM=0D
+#define PEI_CPU_INIT (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_PC_INIT_BEGIN)=0D
+#define PEI_CPU_CACHE_INIT (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_PC_CACHE_INIT)=0D
+#define PEI_CPU_BSP_SELECT (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_PC_BSP_SELECT)=0D
+#define PEI_CPU_AP_INIT (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_PC_AP_INIT)=0D
+#define PEI_CPU_SMM_INIT (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_PC_SMM_INIT)=0D
+#define PEI_CPU_INVALID_TYPE (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_INVALID_TYPE)=0D
+#define PEI_CPU_INVALID_SPEED (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_INVALID_SPEED)=0D
+#define PEI_CPU_MISMATCH (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_MISMATCH)=0D
+#define PEI_CPU_SELF_TEST_FAILED (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_SELF_TEST)=0D
+#define PEI_CPU_CACHE_ERROR (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_CACHE)=0D
+#define PEI_CPU_MICROCODE_UPDATE_FAILED (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_MICROCODE_UPDATE)=0D
+#define PEI_CPU_NO_MICROCODE (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_NO_MICROCODE_UPDATE)=0D
+//If non of the errors above apply use this one=0D
+#define PEI_CPU_INTERNAL_ERROR (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_INTERNAL)=0D
+//Generic CPU error. It should only be used if non of the errors above app=
ly=0D
+#define PEI_CPU_ERROR (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_EC_NON_SPECIFIC)=0D
+=0D
+// Reported by NB PEIM=0D
+#define PEI_MEM_NB_INIT (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_PC_PEI_MEM_NB_INIT)=0D
+// Reported by SB PEIM=0D
+#define PEI_MEM_SB_INIT (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_PC_PEI_MEM_SB_INIT)=0D
+=0D
+//Reported by PEIM which detected forced or auto recovery condition=0D
+#define PEI_RECOVERY_AUTO (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_PC_RECOVERY_AUTO)=0D
+#define PEI_RECOVERY_USER (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_PC_RECOVERY_USER)=0D
+=0D
+//Reported by DXE IPL=0D
+#define PEI_RECOVERY_PPI_NOT_FOUND (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)=0D
+#define PEI_S3_RESUME_PPI_NOT_FOUND (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND)=0D
+#define PEI_S3_RESUME_FAILED (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_EC_S3_RESUME_FAILED)=0D
+=0D
+//Reported by Recovery PEIM=0D
+#define PEI_RECOVERY_STARTED (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_PC_RECOVERY_BEGIN)=0D
+#define PEI_RECOVERY_CAPSULE_FOUND (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_PC_CAPSULE_LOAD)=0D
+#define PEI_RECOVERY_NO_CAPSULE (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_EC_NO_RECOVERY_CAPSULE)=0D
+#define PEI_RECOVERY_CAPSULE_LOADED (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_PC_CAPSULE_START)=0D
+#define PEI_RECOVERY_INVALID_CAPSULE (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR)=0D
+=0D
+//Reported by S3 Resume PEIM=0D
+#define PEI_S3_BOOT_SCRIPT (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_PC_S3_BOOT_SCRIPT)=0D
+#define PEI_S3_OS_WAKE (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_PC_OS_WAKE)=0D
+#define PEI_S3_BOOT_SCRIPT_ERROR (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR)=0D
+#define PEI_S3_OS_WAKE_ERROR (EFI_SOFTWARE_PEI_MODULE | E=
FI_SW_PEI_EC_S3_OS_WAKE_ERROR)=0D
+=0D
+#define PEI_PEIM_STARTED (EFI_SOFTWARE_PEI_CORE | EFI=
_SW_PC_INIT_BEGIN)=0D
+#define PEI_PEIM_ENDED (EFI_SOFTWARE_PEI_CORE | EFI=
_SW_PC_INIT_END)=0D
+=0D
+//Reported by DXE IPL=0D
+#define PEI_DXE_IPL_STARTED (EFI_SOFTWARE_PEI_CORE | EFI=
_SW_PEI_CORE_PC_HANDOFF_TO_NEXT)=0D
+=0D
+//Reported by PEIM which installs Reset PPI=0D
+#define PEI_RESET_SYSTEM (EFI_SOFTWARE_PEI_SERVICE | =
EFI_SW_PS_PC_RESET_SYSTEM)=0D
+=0D
+//Reported by the PEIM or DXE driver which detected the error=0D
+#define GENERIC_MEMORY_CORRECTABLE_ERROR (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_CORRECTABLE)=0D
+#define GENERIC_MEMORY_UNCORRECTABLE_ERROR (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_UNCORRECTABLE)=0D
+=0D
+//Reported by Flash Update DXE driver=0D
+#define DXE_FLASH_UPDATE_FAILED (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_UPDATE_FAIL)=0D
+=0D
+//Reported by the PEIM or DXE driver which detected the error=0D
+#define GENERIC_CPU_THERMAL_ERROR (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_THERMAL)=0D
+#define GENERIC_CPU_LOW_VOLTAGE (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_LOW_VOLTAGE)=0D
+#define GENERIC_CPU_HIGH_VOLTAGE (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_HIGH_VOLTAGE)=0D
+#define GENERIC_CPU_CORRECTABLE_ERROR (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_CORRECTABLE)=0D
+#define GENERIC_CPU_UNCORRECTABLE_ERROR (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_UNCORRECTABLE)=0D
+#define GENERIC_BAD_DATE_TIME_ERROR (EFI_SOFTWARE_UNSPECIFIED | =
EFI_SW_EC_BAD_DATE_TIME)=0D
+#define GENERIC_MEMORY_SIZE_DECREASE (EFI_COMPUTING_UNIT_MEMORY |=
EFI_CU_MEMORY_EC_MISMATCH)=0D
+=0D
+//Reported by DXE Core=0D
+#define DXE_DRIVER_STARTED (EFI_SOFTWARE_EFI_DXE_SERVIC=
E | EFI_SW_PC_INIT_BEGIN)=0D
+#define DXE_DRIVER_ENED (EFI_SOFTWARE_DXE_CORE | EFI=
_SW_PC_INIT_END)=0D
+#define DXE_ARCH_PROTOCOLS_AVAILABLE (EFI_SOFTWARE_DXE_CORE | EFI=
_SW_DXE_CORE_PC_ARCH_READY)=0D
+#define DXE_DRIVER_CONNECTED (EFI_SOFTWARE_DXE_CORE | EFI=
_SW_DXE_CORE_PC_START_DRIVER)=0D
+#define DXE_ARCH_PROTOCOL_NOT_AVAILABLE (EFI_SOFTWARE_DXE_CORE | EFI=
_SW_DXE_CORE_EC_NO_ARCH)=0D
+=0D
+//Reported by DXE CPU driver=0D
+#define DXE_CPU_SELF_TEST_FAILED (EFI_COMPUTING_UNIT_HOST_PRO=
CESSOR | EFI_CU_HP_EC_SELF_TEST)=0D
+=0D
+//Reported by PCI Host Bridge driver=0D
+#define DXE_NB_HB_INIT (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_PC_DXE_HB_INIT )=0D
+=0D
+// Reported by NB Driver=0D
+#define DXE_NB_INIT (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_PC_DXE_NB_INIT )=0D
+#define DXE_NB_SMM_INIT (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_PC_DXE_NB_SMM_INIT )=0D
+#define DXE_NB_ERROR (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_EC_DXE_NB_ERROR )=0D
+=0D
+// Reported by SB Driver(s)=0D
+#define DXE_SBRUN_INIT (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_PC_DXE_SB_RT_INIT )=0D
+#define DXE_SB_INIT (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_PC_DXE_SB_INIT )=0D
+#define DXE_SB_SMM_INIT (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_PC_DXE_SB_SMM_INIT )=0D
+#define DXE_SB_DEVICES_INIT (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_PC_DXE_SB_DEVICES_INIT )=0D
+#define DXE_SB_BAD_BATTERY (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_EC_BAD_BATTERY)=0D
+#define DXE_SB_ERROR (EFI_COMPUTING_UNIT_CHIPSET =
| EFI_CHIPSET_EC_DXE_SB_ERROR )=0D
+=0D
+//Reported by DXE Core=0D
+#define DXE_BDS_STARTED (EFI_SOFTWARE_DXE_CORE | EFI=
_SW_DXE_CORE_PC_HANDOFF_TO_NEXT)=0D
+=0D
+//Reported by BDS=0D
+//#define DXE_BDS_CONNECT_DRIVERS (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS)=0D
+=0D
+//Reported by Boot Manager=0D
+#define DXE_READY_TO_BOOT (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)=0D
+=0D
+//Reported by DXE Core=0D
+#define DXE_EXIT_BOOT_SERVICES (EFI_SOFTWARE_EFI_BOOT_SERVI=
CE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)=0D
+#define DXE_EXIT_BOOT_SERVICES_EVENT (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_PC_EXIT_BOOT_SERVICES_EVENT)=0D
+=0D
+//Reported by driver that installs Runtime AP=0D
+#define RT_SET_VIRTUAL_ADDRESS_MAP_BEGIN (EFI_SOFTWARE_EFI_RUNTIME_SE=
RVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP)=0D
+#define RT_SET_VIRTUAL_ADDRESS_MAP_END (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT)=0D
+=0D
+//Reported by CSM=0D
+#define DXE_LEGACY_OPROM_INIT (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_PC_LEGACY_OPROM_INIT)=0D
+#define DXE_LEGACY_BOOT (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT)=0D
+#define DXE_LEGACY_OPROM_NO_SPACE (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE)=0D
+=0D
+//Reported by SETUP=0D
+//#define DXE_SETUP_VERIFYING_PASSWORD (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_PC_VERIFYING_PASSWORD)=0D
+#define DXE_SETUP_START (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_PC_USER_SETUP)=0D
+#define DXE_SETUP_INPUT_WAIT (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_PC_INPUT_WAIT)=0D
+#define DXE_INVALID_PASSWORD (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_EC_INVALID_PASSWORD)=0D
+#define DXE_INVALID_IDE_PASSWORD (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_EC_INVALID_IDE_PASSWORD)=0D
+#define DXE_BOOT_OPTION_LOAD_ERROR (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)=0D
+#define DXE_BOOT_OPTION_FAILED (EFI_SOFTWARE_DXE_BS_DRIVER =
| EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)=0D
+=0D
+//Reported by a Driver that installs Reset AP=0D
+#define DXE_RESET_SYSTEM (EFI_SOFTWARE_EFI_RUNTIME_SE=
RVICE | EFI_SW_RS_PC_RESET_SYSTEM)=0D
+#define DXE_RESET_NOT_AVAILABLE (EFI_SOFTWARE_EFI_RUNTIME_SE=
RVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE)=0D
+=0D
+// Reported by PCI bus driver=0D
+#define DXE_PCI_BUS_BEGIN (EFI_IO_BUS_PCI | EFI_IOB_PC=
_INIT)=0D
+#define DXE_PCI_BUS_ENUM (EFI_IO_BUS_PCI | EFI_IOB_PC=
I_PC_BUS_ENUM)=0D
+#define DXE_PCI_BUS_HPC_INIT (EFI_IO_BUS_PCI | EFI_IOB_PC=
I_PC_HPC_INIT)=0D
+#define DXE_PCI_BUS_REQUEST_RESOURCES (EFI_IO_BUS_PCI | EFI_IOB_PC=
I_PC_RES_ALLOC)=0D
+#define DXE_PCI_BUS_ASSIGN_RESOURCES (EFI_IO_BUS_PCI | EFI_IOB_PC=
_ENABLE)=0D
+#define DXE_PCI_BUS_HOTPLUG (EFI_IO_BUS_PCI | EFI_IOB_PC=
_HOTPLUG)=0D
+#define DXE_PCI_BUS_OUT_OF_RESOURCES (EFI_IO_BUS_PCI | EFI_IOB_EC=
_RESOURCE_CONFLICT)=0D
+=0D
+// Reported by USB bus driver=0D
+#define DXE_USB_BEGIN (EFI_IO_BUS_USB | EFI_IOB_PC=
_INIT)=0D
+#define DXE_USB_RESET (EFI_IO_BUS_USB | EFI_IOB_PC=
_RESET)=0D
+#define DXE_USB_DETECT (EFI_IO_BUS_USB | EFI_IOB_PC=
_DETECT)=0D
+#define DXE_USB_ENABLE (EFI_IO_BUS_USB | EFI_IOB_PC=
_ENABLE)=0D
+#define DXE_USB_HOTPLUG (EFI_IO_BUS_USB | EFI_IOB_PC=
_HOTPLUG)=0D
+=0D
+//Reported by IDE bus driver=0D
+#define DXE_IDE_BEGIN (EFI_IO_BUS_ATA_ATAPI | EFI_=
IOB_PC_INIT)=0D
+#define DXE_IDE_RESET (EFI_IO_BUS_ATA_ATAPI | EFI_=
IOB_PC_RESET)=0D
+#define DXE_IDE_DETECT (EFI_IO_BUS_ATA_ATAPI | EFI_=
IOB_PC_DETECT)=0D
+#define DXE_IDE_ENABLE (EFI_IO_BUS_ATA_ATAPI | EFI_=
IOB_PC_ENABLE)=0D
+#define DXE_IDE_SMART_ERROR (EFI_IO_BUS_ATA_ATAPI | EFI_=
IOB_ATA_BUS_SMART_OVERTHRESHOLD)=0D
+#define DXE_IDE_CONTROLLER_ERROR (EFI_IO_BUS_ATA_ATAPI | EFI_=
IOB_EC_CONTROLLER_ERROR)=0D
+#define DXE_IDE_DEVICE_FAILURE (EFI_IO_BUS_ATA_ATAPI | EFI_=
IOB_EC_INTERFACE_ERROR)=0D
+=0D
+// Reported by SCSI bus driver=0D
+#define DXE_SCSI_BEGIN (EFI_IO_BUS_SCSI | EFI_IOB_P=
C_INIT)=0D
+#define DXE_SCSI_RESET (EFI_IO_BUS_SCSI | EFI_IOB_P=
C_RESET)=0D
+#define DXE_SCSI_DETECT (EFI_IO_BUS_SCSI | EFI_IOB_P=
C_DETECT)=0D
+#define DXE_SCSI_ENABLE (EFI_IO_BUS_SCSI | EFI_IOB_P=
C_ENABLE)=0D
+=0D
+// Reported by Super I/O driver=0D
+#define DXE_SIO_INIT (EFI_IO_BUS_LPC | EFI_IOB_PC=
_INIT)=0D
+=0D
+// Reported by Keyboard driver=0D
+#define DXE_KEYBOARD_INIT (EFI_PERIPHERAL_KEYBOARD | E=
FI_P_PC_INIT)=0D
+#define DXE_KEYBOARD_RESET (EFI_PERIPHERAL_KEYBOARD | E=
FI_P_PC_RESET)=0D
+#define DXE_KEYBOARD_DISABLE (EFI_PERIPHERAL_KEYBOARD | E=
FI_P_PC_DISABLE)=0D
+#define DXE_KEYBOARD_DETECT (EFI_PERIPHERAL_KEYBOARD | E=
FI_P_PC_PRESENCE_DETECT)=0D
+#define DXE_KEYBOARD_ENABLE (EFI_PERIPHERAL_KEYBOARD | E=
FI_P_PC_ENABLE)=0D
+#define DXE_KEYBOARD_CLEAR_BUFFER (EFI_PERIPHERAL_KEYBOARD | E=
FI_P_KEYBOARD_PC_CLEAR_BUFFER)=0D
+#define DXE_KEYBOARD_SELF_TEST (EFI_PERIPHERAL_KEYBOARD | E=
FI_P_KEYBOARD_PC_SELF_TEST)=0D
+=0D
+// Reported by Mouse driver=0D
+#define DXE_MOUSE_INIT (EFI_PERIPHERAL_MOUSE | EFI_=
P_PC_INIT)=0D
+#define DXE_MOUSE_RESET (EFI_PERIPHERAL_MOUSE | EFI_=
P_PC_RESET)=0D
+#define DXE_MOUSE_DISABLE (EFI_PERIPHERAL_MOUSE | EFI_=
P_PC_DISABLE)=0D
+#define DXE_MOUSE_DETECT (EFI_PERIPHERAL_MOUSE | EFI_=
P_PC_PRESENCE_DETECT)=0D
+#define DXE_MOUSE_ENABLE (EFI_PERIPHERAL_MOUSE | EFI_=
P_PC_ENABLE)=0D
+=0D
+// Reported by Mass Storage drivers=0D
+#define DXE_FIXED_MEDIA_INIT (EFI_PERIPHERAL_FIXED_MEDIA =
| EFI_P_PC_INIT)=0D
+#define DXE_FIXED_MEDIA_RESET (EFI_PERIPHERAL_FIXED_MEDIA =
| EFI_P_PC_RESET)=0D
+#define DXE_FIXED_MEDIA_DISABLE (EFI_PERIPHERAL_FIXED_MEDIA =
| EFI_P_PC_DISABLE)=0D
+#define DXE_FIXED_MEDIA_DETECT (EFI_PERIPHERAL_FIXED_MEDIA =
| EFI_P_PC_PRESENCE_DETECT)=0D
+#define DXE_FIXED_MEDIA_ENABLE (EFI_PERIPHERAL_FIXED_MEDIA =
| EFI_P_PC_ENABLE)=0D
+#define DXE_REMOVABLE_MEDIA_INIT (EFI_PERIPHERAL_REMOVABLE_ME=
DIA | EFI_P_PC_INIT)=0D
+#define DXE_REMOVABLE_MEDIA_RESET (EFI_PERIPHERAL_REMOVABLE_ME=
DIA | EFI_P_PC_RESET)=0D
+#define DXE_REMOVABLE_MEDIA_DISABLE (EFI_PERIPHERAL_REMOVABLE_ME=
DIA | EFI_P_PC_DISABLE)=0D
+#define DXE_REMOVABLE_MEDIA_DETECT (EFI_PERIPHERAL_REMOVABLE_ME=
DIA | EFI_P_PC_PRESENCE_DETECT)=0D
+#define DXE_REMOVABLE_MEDIA_ENABLE (EFI_PERIPHERAL_REMOVABLE_ME=
DIA | EFI_P_PC_ENABLE)=0D
+=0D
+=0D
+// Reported by BDS=0D
+#define DXE_CON_OUT_CONNECT (EFI_PERIPHERAL_LOCAL_CONSOL=
E | EFI_P_PC_INIT)=0D
+#define DXE_CON_IN_CONNECT (EFI_PERIPHERAL_KEYBOARD | E=
FI_P_PC_INIT)=0D
+#define DXE_NO_CON_OUT (EFI_PERIPHERAL_LOCAL_CONSOL=
E | EFI_P_EC_NOT_DETECTED)=0D
+#define DXE_NO_CON_IN (EFI_PERIPHERAL_KEYBOARD | E=
FI_P_EC_NOT_DETECTED)=0D
+=0D
+#endif=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatu=
sCodeHandlerLib/PeiBeepStatusCodeHandlerLib.c b/Features/Intel/Debugging/Be=
epDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/PeiBeepStatusCodeHandler=
Lib.c
new file mode 100644
index 0000000000..a29d948951
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatusCodeHa=
ndlerLib/PeiBeepStatusCodeHandlerLib.c
@@ -0,0 +1,101 @@
+/** @file=0D
+ Beep status code implementation.=0D
+=0D
+ Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#include <Library/PeiServicesLib.h>=0D
+#include <Library/PeimEntryPoint.h>=0D
+#include <Library/PcdLib.h>=0D
+#include <Library/DebugLib.h>=0D
+#include <Library/ReportStatusCodeLib.h>=0D
+#include <Ppi/ReportStatusCodeHandler.h>=0D
+=0D
+#include <Library/BeepMapLib.h>=0D
+#include <Library/BeepLib.h>=0D
+=0D
+/**=0D
+ Convert status code value to the times of beep.=0D
+=0D
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES tab=
le published by the PEI Foundation.=0D
+ @param CodeType Indicates the type of status code being reporte=
d.=0D
+ @param Value Describes the current status of a hardware or=0D
+ software entity. This includes information abou=
t the class and=0D
+ subclass that is used to classify the entity as=
well as an operation.=0D
+ For progress codes, the operation is the curren=
t activity.=0D
+ For error codes, it is the exception.For debug =
codes,it is not defined at this time.=0D
+ @param Instance The enumeration of a hardware or software entit=
y within=0D
+ the system. A system may contain multiple entit=
ies that match a class/subclass=0D
+ pairing. The instance differentiates between th=
em. An instance of 0 indicates=0D
+ that instance information is unavailable, not m=
eaningful, or not relevant.=0D
+ Valid instance numbers start with 1.=0D
+ @param CallerId This optional parameter may be used to identify=
the caller.=0D
+ This parameter allows the status code driver to=
apply different rules to=0D
+ different callers.=0D
+ @param Data This optional parameter may be used to pass add=
itional data.=0D
+=0D
+ @retval EFI_SUCCESS Status code reported to beep successfully.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+BeepStatusCodeReportWorker (=0D
+ IN CONST EFI_PEI_SERVICES **PeiServices,=0D
+ IN EFI_STATUS_CODE_TYPE CodeType,=0D
+ IN EFI_STATUS_CODE_VALUE Value,=0D
+ IN UINT32 Instance,=0D
+ IN CONST EFI_GUID *CallerId,=0D
+ IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL=0D
+ )=0D
+{=0D
+ UINT32 BeepValue;=0D
+=0D
+ BeepValue =3D GetBeepValueFromStatusCode (CodeType, Value);=0D
+ if (BeepValue !=3D 0) {=0D
+ Beep (BeepValue);=0D
+ }=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+/**=0D
+ Constructor function of PeiBeepStatusCodeHandlerLib.=0D
+=0D
+ This function is the constructor function of this Beep Status Code Handl=
er Library for PEI Phase.=0D
+ It check whether need beep, and register it to gEfiPeiRscHandlerPpiGuid.=
=0D
+=0D
+ @param FileHandle Handle of the file being invoked.=0D
+ @param PeiServices Describes the list of possible PEI Services.=0D
+=0D
+ @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfull=
y.=0D
+=0D
+**/=0D
+RETURN_STATUS=0D
+EFIAPI=0D
+PeiBeepStatusCodeHandlerLibConstructor (=0D
+ IN EFI_PEI_FILE_HANDLE FileHandle,=0D
+ IN CONST EFI_PEI_SERVICES **PeiServices=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ EFI_PEI_RSC_HANDLER_PPI *RscHandlerPpi;=0D
+=0D
+ if (!PcdGetBool (PcdStatusCodeUseBeep)) {=0D
+ return RETURN_SUCCESS;=0D
+ }=0D
+=0D
+ Status =3D PeiServicesLocatePpi (=0D
+ &gEfiPeiRscHandlerPpiGuid,=0D
+ 0,=0D
+ NULL,=0D
+ (VOID **) &RscHandlerPpi=0D
+ );=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ Status =3D RscHandlerPpi->Register (BeepStatusCodeReportWorker);=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ return RETURN_SUCCESS;=0D
+}=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatu=
sCodeHandlerLib/PeiBeepStatusCodeHandlerLib.inf b/Features/Intel/Debugging/=
BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/PeiBeepStatusCodeHandl=
erLib.inf
new file mode 100644
index 0000000000..421b246663
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatusCodeHa=
ndlerLib/PeiBeepStatusCodeHandlerLib.inf
@@ -0,0 +1,49 @@
+## @file=0D
+# Beep status code implementation.=0D
+#=0D
+# Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+# vendor. This file may not be modified, except as allowed by=0D
+# additional terms of your license agreement.=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010005=0D
+ BASE_NAME =3D PeiBeepStatusCodeHandlerLib=0D
+ FILE_GUID =3D C4210E71-0A38-4728-8D25-4876348AA380=
=0D
+ MODULE_TYPE =3D PEIM=0D
+ CONSTRUCTOR =3D PeiBeepStatusCodeHandlerLibConstructo=
r=0D
+ LIBRARY_CLASS =3D StatusCodeHandlerLib|SEC PEIM PEI_COR=
=0D
+=0D
+#=0D
+# The following information is for reference only and not required by the =
build tools.=0D
+#=0D
+# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC (EBC is only for bui=
ld)=0D
+#=0D
+=0D
+[Sources]=0D
+ PeiBeepStatusCodeHandlerLib.c=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+ MdeModulePkg/MdeModulePkg.dec=0D
+ BeepDebugFeaturePkg/BeepDebugFeaturePkg.dec=0D
+=0D
+[LibraryClasses]=0D
+ PeiServicesLib=0D
+ PcdLib=0D
+ DebugLib=0D
+ ReportStatusCodeLib=0D
+ BeepMapLib=0D
+ BeepLib=0D
+=0D
+[Pcd]=0D
+ gBeepDebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseBeep ##=
CONSUMES=0D
+=0D
+[Ppis]=0D
+ gEfiPeiRscHandlerPpiGuid ## CONSUMES=0D
+=0D
+[Depex]=0D
+ TRUE=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatu=
sCodeHandlerLib/RuntimeDxeBeepStatusCodeHandlerLib.c b/Features/Intel/Debug=
ging/BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/RuntimeDxeBeepSta=
tusCodeHandlerLib.c
new file mode 100644
index 0000000000..631e2eecae
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatusCodeHa=
ndlerLib/RuntimeDxeBeepStatusCodeHandlerLib.c
@@ -0,0 +1,184 @@
+/** @file=0D
+ Beep status code implementation.=0D
+=0D
+ Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#include <Library/UefiDriverEntryPoint.h>=0D
+#include <Library/UefiBootServicesTableLib.h>=0D
+#include <Guid/EventGroup.h>=0D
+#include <Library/PcdLib.h>=0D
+#include <Library/DebugLib.h>=0D
+#include <Library/ReportStatusCodeLib.h>=0D
+#include <Protocol/ReportStatusCodeHandler.h>=0D
+=0D
+#include <Library/BeepMapLib.h>=0D
+#include <Library/BeepLib.h>=0D
+=0D
+EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol =3D NULL;=0D
+EFI_EVENT mExitBootServicesEvent =3D NULL;=0D
+BOOLEAN mRegistered =3D FALSE;=0D
+=0D
+/**=0D
+ Convert status code value to the times of beep.=0D
+=0D
+ @param CodeType Indicates the type of status code being reporte=
d.=0D
+ @param Value Describes the current status of a hardware or=0D
+ software entity. This includes information abou=
t the class and=0D
+ subclass that is used to classify the entity as=
well as an operation.=0D
+ For progress codes, the operation is the curren=
t activity.=0D
+ For error codes, it is the exception.For debug =
codes,it is not defined at this time.=0D
+ @param Instance The enumeration of a hardware or software entit=
y within=0D
+ the system. A system may contain multiple entit=
ies that match a class/subclass=0D
+ pairing. The instance differentiates between th=
em. An instance of 0 indicates=0D
+ that instance information is unavailable, not m=
eaningful, or not relevant.=0D
+ Valid instance numbers start with 1.=0D
+ @param CallerId This optional parameter may be used to identify=
the caller.=0D
+ This parameter allows the status code driver to=
apply different rules to=0D
+ different callers.=0D
+ @param Data This optional parameter may be used to pass add=
itional data.=0D
+=0D
+ @retval EFI_SUCCESS Status code reported to beep successfully.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+BeepStatusCodeReportWorker (=0D
+ IN EFI_STATUS_CODE_TYPE CodeType,=0D
+ IN EFI_STATUS_CODE_VALUE Value,=0D
+ IN UINT32 Instance,=0D
+ IN EFI_GUID *CallerId,=0D
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL=0D
+ )=0D
+{=0D
+ UINT32 BeepValue;=0D
+=0D
+ BeepValue =3D GetBeepValueFromStatusCode (CodeType, Value);=0D
+ if (BeepValue !=3D 0) {=0D
+ Beep (BeepValue);=0D
+ }=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+/**=0D
+ Unregister status code callback functions only available at boot time fr=
om=0D
+ report status code router when exiting boot services.=0D
+=0D
+ @param Event Event whose notification function is being invoked=
.=0D
+ @param Context Pointer to the notification function's context, wh=
ich is=0D
+ always zero in current implementation.=0D
+=0D
+**/=0D
+VOID=0D
+EFIAPI=0D
+UnregisterBeepBootTimeHandlers (=0D
+ IN EFI_EVENT Event,=0D
+ IN VOID *Context=0D
+ )=0D
+{=0D
+ if (mRegistered) {=0D
+ mRscHandlerProtocol->Unregister (BeepStatusCodeReportWorker);=0D
+ }=0D
+}=0D
+=0D
+/**=0D
+ Register status code callback function only when Report Status Code prot=
ocol=0D
+ is installed.=0D
+=0D
+ @param Event Event whose notification function is being invoked=
.=0D
+ @param Context Pointer to the notification function's context, wh=
ich is=0D
+ always zero in current implementation.=0D
+=0D
+**/=0D
+VOID=0D
+EFIAPI=0D
+RegisterBeepBootTimeHandlers (=0D
+ IN EFI_EVENT Event,=0D
+ IN VOID *Context=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+=0D
+ Status =3D gBS->LocateProtocol (=0D
+ &gEfiRscHandlerProtocolGuid,=0D
+ NULL,=0D
+ (VOID **) &mRscHandlerProtocol=0D
+ );=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ mRscHandlerProtocol->Register (BeepStatusCodeReportWorker, TPL_HIGH_LEVE=
L);=0D
+ ASSERT_EFI_ERROR (Status);=0D
+ mRegistered =3D TRUE;=0D
+=0D
+ Status =3D gBS->CreateEventEx (=0D
+ EVT_NOTIFY_SIGNAL,=0D
+ TPL_NOTIFY,=0D
+ UnregisterBeepBootTimeHandlers,=0D
+ NULL,=0D
+ &gEfiEventExitBootServicesGuid,=0D
+ &mExitBootServicesEvent=0D
+ );=0D
+ ASSERT_EFI_ERROR (Status);=0D
+}=0D
+=0D
+/**=0D
+ Constructor function of RuntimeDxeBeepStatusCodeHandlerLib.=0D
+=0D
+ This function allocates memory for extended status code data, caches=0D
+ the report status code service, and registers events.=0D
+=0D
+ @param ImageHandle The firmware allocated handle for the EFI image.=0D
+ @param SystemTable A pointer to the EFI System Table.=0D
+=0D
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+RuntimeDxeBeepStatusCodeHandlerLibConstructor (=0D
+ IN EFI_HANDLE ImageHandle,=0D
+ IN EFI_SYSTEM_TABLE *SystemTable=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ EFI_EVENT RegisterStatusCodeHandlerEvent;=0D
+ VOID *Registration;=0D
+=0D
+ if (!PcdGetBool (PcdStatusCodeUseBeep)) {=0D
+ return EFI_SUCCESS;=0D
+ }=0D
+=0D
+ Status =3D gBS->LocateProtocol (=0D
+ &gEfiRscHandlerProtocolGuid,=0D
+ NULL,=0D
+ (VOID **) &mRscHandlerProtocol=0D
+ );=0D
+=0D
+ if (!EFI_ERROR (Status)) {=0D
+ RegisterBeepBootTimeHandlers (NULL, NULL);=0D
+ } else {=0D
+ Status =3D gBS->CreateEvent (=0D
+ EVT_NOTIFY_SIGNAL,=0D
+ TPL_NOTIFY,=0D
+ RegisterBeepBootTimeHandlers,=0D
+ NULL,=0D
+ &RegisterStatusCodeHandlerEvent=0D
+ );=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ //=0D
+ // Register for protocol notifications on this event=0D
+ //=0D
+ Status =3D gBS->RegisterProtocolNotify (=0D
+ &gEfiRscHandlerProtocolGuid,=0D
+ RegisterStatusCodeHandlerEvent,=0D
+ &Registration=0D
+ );=0D
+ ASSERT_EFI_ERROR (Status);=0D
+ }=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatu=
sCodeHandlerLib/RuntimeDxeBeepStatusCodeHandlerLib.inf b/Features/Intel/Deb=
ugging/BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/RuntimeDxeBeepS=
tatusCodeHandlerLib.inf
new file mode 100644
index 0000000000..b9aae39128
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatusCodeHa=
ndlerLib/RuntimeDxeBeepStatusCodeHandlerLib.inf
@@ -0,0 +1,51 @@
+## @file=0D
+# Beep status code implementation.=0D
+#=0D
+# Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+# vendor. This file may not be modified, except as allowed by=0D
+# additional terms of your license agreement.=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010005=0D
+ BASE_NAME =3D RuntimeDxeBeepStatusCodeHandlerLib=0D
+ FILE_GUID =3D D05F43CE-7C70-4663-848F-8265C311A8A5=
=0D
+ MODULE_TYPE =3D DXE_RUNTIME_DRIVER=0D
+ VERSION_STRING =3D 1.0=0D
+ CONSTRUCTOR =3D RuntimeDxeBeepStatusCodeHandlerLibCon=
structor=0D
+ LIBRARY_CLASS =3D StatusCodeHandlerLib|DXE_RUNTIME_DRIV=
ER=0D
+=0D
+#=0D
+# The following information is for reference only and not required by the =
build tools.=0D
+#=0D
+# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC (EBC is only for bui=
ld)=0D
+#=0D
+=0D
+[Sources]=0D
+ RuntimeDxeBeepStatusCodeHandlerLib.c=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+ MdeModulePkg/MdeModulePkg.dec=0D
+ BeepDebugFeaturePkg/BeepDebugFeaturePkg.dec=0D
+=0D
+[LibraryClasses]=0D
+ UefiBootServicesTableLib=0D
+ UefiRuntimeLib=0D
+ PcdLib=0D
+ DebugLib=0D
+ ReportStatusCodeLib=0D
+ BeepMapLib=0D
+ BeepLib=0D
+=0D
+[Pcd]=0D
+ gBeepDebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseBeep ##=
CONSUMES=0D
+=0D
+[Protocols]=0D
+ gEfiRscHandlerProtocolGuid ## CONSUMES=0D
+=0D
+[Depex]=0D
+ TRUE=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatu=
sCodeHandlerLib/SmmBeepStatusCodeHandlerLib.c b/Features/Intel/Debugging/Be=
epDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/SmmBeepStatusCodeHandler=
Lib.c
new file mode 100644
index 0000000000..6b1125f4c2
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatusCodeHa=
ndlerLib/SmmBeepStatusCodeHandlerLib.c
@@ -0,0 +1,138 @@
+/** @file=0D
+ Beep status code implementation.=0D
+=0D
+ Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#include <Library/UefiDriverEntryPoint.h>=0D
+#include <Library/SmmServicesTableLib.h>=0D
+#include <Library/PcdLib.h>=0D
+#include <Library/DebugLib.h>=0D
+#include <Library/ReportStatusCodeLib.h>=0D
+#include <Protocol/SmmReportStatusCodeHandler.h>=0D
+=0D
+#include <Library/BeepMapLib.h>=0D
+#include <Library/BeepLib.h>=0D
+=0D
+/**=0D
+ Convert status code value to the times of beep.=0D
+=0D
+ @param CodeType Indicates the type of status code being reporte=
d.=0D
+ @param Value Describes the current status of a hardware or=0D
+ software entity. This includes information abou=
t the class and=0D
+ subclass that is used to classify the entity as=
well as an operation.=0D
+ For progress codes, the operation is the curren=
t activity.=0D
+ For error codes, it is the exception.For debug =
codes,it is not defined at this time.=0D
+ @param Instance The enumeration of a hardware or software entit=
y within=0D
+ the system. A system may contain multiple entit=
ies that match a class/subclass=0D
+ pairing. The instance differentiates between th=
em. An instance of 0 indicates=0D
+ that instance information is unavailable, not m=
eaningful, or not relevant.=0D
+ Valid instance numbers start with 1.=0D
+ @param CallerId This optional parameter may be used to identify=
the caller.=0D
+ This parameter allows the status code driver to=
apply different rules to=0D
+ different callers.=0D
+ @param Data This optional parameter may be used to pass add=
itional data.=0D
+=0D
+ @retval EFI_SUCCESS Status code reported to beep successfully.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+BeepStatusCodeReportWorker (=0D
+ IN EFI_STATUS_CODE_TYPE CodeType,=0D
+ IN EFI_STATUS_CODE_VALUE Value,=0D
+ IN UINT32 Instance,=0D
+ IN EFI_GUID *CallerId,=0D
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL=0D
+ )=0D
+{=0D
+ UINT32 BeepValue;=0D
+=0D
+ BeepValue =3D GetBeepValueFromStatusCode (CodeType, Value);=0D
+ if (BeepValue !=3D 0) {=0D
+ Beep (BeepValue);=0D
+ }=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+/**=0D
+ Register status code callback function only when Report Status Code prot=
ocol=0D
+ is installed.=0D
+=0D
+ @param Protocol Points to the protocol's unique identifier.=0D
+ @param Interface Points to the interface instance.=0D
+ @param Handle The handle on which the interface was installed.=0D
+=0D
+ @retval EFI_SUCCESS Notification runs successfully.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+RegisterBeepBootTimeHandlers (=0D
+ IN CONST EFI_GUID *Protocol,=0D
+ IN VOID *Interface,=0D
+ IN EFI_HANDLE Handle=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ EFI_SMM_RSC_HANDLER_PROTOCOL *RscHandlerProtocol;=0D
+=0D
+ Status =3D gSmst->SmmLocateProtocol (=0D
+ &gEfiSmmRscHandlerProtocolGuid,=0D
+ NULL,=0D
+ (VOID **) &RscHandlerProtocol=0D
+ );=0D
+ ASSERT_EFI_ERROR (Status);=0D
+=0D
+ RscHandlerProtocol->Register (BeepStatusCodeReportWorker);=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+/**=0D
+ Constructor function of SmmBeepStatusCodeHandlerLib.=0D
+=0D
+ This function allocates memory for extended status code data, caches=0D
+ the report status code service, and registers events.=0D
+=0D
+ @param ImageHandle The firmware allocated handle for the EFI image.=0D
+ @param SystemTable A pointer to the EFI System Table.=0D
+=0D
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+SmmBeepStatusCodeHandlerLibConstructor (=0D
+ IN EFI_HANDLE ImageHandle,=0D
+ IN EFI_SYSTEM_TABLE *SystemTable=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ VOID *Registration;=0D
+ EFI_SMM_RSC_HANDLER_PROTOCOL *RscHandlerProtocol;=0D
+=0D
+ if (!PcdGetBool (PcdStatusCodeUseBeep)) {=0D
+ return EFI_SUCCESS;=0D
+ }=0D
+=0D
+ Status =3D gSmst->SmmLocateProtocol (=0D
+ &gEfiSmmRscHandlerProtocolGuid,=0D
+ NULL,=0D
+ (VOID **) &RscHandlerProtocol=0D
+ );=0D
+ if (!EFI_ERROR (Status)) {=0D
+ RegisterBeepBootTimeHandlers (NULL, NULL, NULL);=0D
+ } else {=0D
+ gSmst->SmmRegisterProtocolNotify (=0D
+ &gEfiSmmRscHandlerProtocolGuid,=0D
+ RegisterBeepBootTimeHandlers,=0D
+ &Registration=0D
+ );=0D
+ }=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatu=
sCodeHandlerLib/SmmBeepStatusCodeHandlerLib.inf b/Features/Intel/Debugging/=
BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/SmmBeepStatusCodeHandl=
erLib.inf
new file mode 100644
index 0000000000..caa82264ae
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Library/BeepStatusCodeHa=
ndlerLib/SmmBeepStatusCodeHandlerLib.inf
@@ -0,0 +1,50 @@
+## @file=0D
+# Beep status code implementation.=0D
+#=0D
+# Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+# vendor. This file may not be modified, except as allowed by=0D
+# additional terms of your license agreement.=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010005=0D
+ BASE_NAME =3D SmmBeepStatusCodeHandlerLib=0D
+ FILE_GUID =3D 2E2BC2D4-572D-4663-9A1E-FB52FA30922A=
=0D
+ MODULE_TYPE =3D DXE_SMM_DRIVER=0D
+ VERSION_STRING =3D 1.0=0D
+ CONSTRUCTOR =3D SmmBeepStatusCodeHandlerLibConstructo=
r=0D
+ LIBRARY_CLASS =3D StatusCodeHandlerLib|DXE_SMM_DRIVER=0D
+=0D
+#=0D
+# The following information is for reference only and not required by the =
build tools.=0D
+#=0D
+# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC (EBC is only for bui=
ld)=0D
+#=0D
+=0D
+[Sources]=0D
+ SmmBeepStatusCodeHandlerLib.c=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+ MdeModulePkg/MdeModulePkg.dec=0D
+ BeepDebugFeaturePkg/BeepDebugFeaturePkg.dec=0D
+=0D
+[LibraryClasses]=0D
+ SmmServicesTableLib=0D
+ PcdLib=0D
+ DebugLib=0D
+ ReportStatusCodeLib=0D
+ BeepMapLib=0D
+ BeepLib=0D
+=0D
+[Pcd]=0D
+ gBeepDebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseBeep ##=
CONSUMES=0D
+=0D
+[Protocols]=0D
+ gEfiSmmRscHandlerProtocolGuid ## CONSUMES=0D
+=0D
+[Depex]=0D
+ TRUE=0D
diff --git a/Features/Intel/Debugging/BeepDebugFeaturePkg/Readme.md b/Featu=
res/Intel/Debugging/BeepDebugFeaturePkg/Readme.md
new file mode 100644
index 0000000000..12ae2c1582
--- /dev/null
+++ b/Features/Intel/Debugging/BeepDebugFeaturePkg/Readme.md
@@ -0,0 +1,126 @@
+# Overview=0D
+* **Feature Name:** Beep Debug=0D
+* **PI Phase(s) Supported:** PEI, DXE, SMM=0D
+* **SMM Required?** Yes=0D
+=0D
+More Information:=0D
+=0D
+## Purpose=0D
+The BeepDebugFeaturePkg include some useful beep debug libraries, such as =
get beep value from status code and beep.=0D
+This is an important capability in firmware development to get and analyze=
the early error when there is not serial port.=0D
+=0D
+=0D
+# High-Level Theory of Operation=0D
+It provide a library BeepStatusCodeHandlerLib used by edk2 StatusCodeHandl=
er.efi, used to do beep if needed.=0D
+It also provide a library of BeepMap lib, it map the status code to beep v=
alue.=0D
+A library of Beep lib is needed by platform, and this pkg has a Null imple=
mentation.=0D
+=0D
+In the library contstructor function, BeepStatusCodeHandlerLib register th=
e call back function for ReportStatusCode.=0D
+When called, it call GetBeepFromStatusCode() in BeepMapLib to get beep val=
ue from status code, and call Beep() in BeepLib to beep.=0D
+=0D
+BeepStatusCodeHandlerLib include 3 libraries for PEI, RuntimeDxe, SMM:=0D
+* PeiBeepStatusCodeHandlerLib=0D
+* RuntimeDxeBeepStatusCodeHandlerLib=0D
+* SmmBeepStatusCodeHandlerLib=0D
+=0D
+## Firmware Volumes=0D
+Linked with StatusCodeHandler.efi, and make sure put the StatusCodeHandler=
.efi after the ReportStatusCodeRouter.efi.=0D
+=0D
+## Modules=0D
+* BeepStatusCodeHandlerLib=0D
+* BeepMapLib=0D
+* BeepLibNull=0D
+=0D
+## BeepStatusCodeHandlerLib=0D
+This library register the call back function for ReportStatusCode, and get=
=0D
+beep valude from status code, and do beep.=0D
+=0D
+## BeepMapLib=0D
+This library provide a function to get beep value from status code.=0D
+=0D
+## Key Functions=0D
+* In PeiBeepStatusCodeHandlerLib:=0D
+ EFI_STATUS=0D
+ EFIAPI=0D
+ BeepStatusCodeReportWorker (=0D
+ IN CONST EFI_PEI_SERVICES **PeiServices,=0D
+ IN EFI_STATUS_CODE_TYPE CodeType,=0D
+ IN EFI_STATUS_CODE_VALUE Value,=0D
+ IN UINT32 Instance,=0D
+ IN CONST EFI_GUID *CallerId,=0D
+ IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL=0D
+ )=0D
+=0D
+* In RuntimeDxeBeepStatusCodeHandlerLib:=0D
+ EFI_STATUS=0D
+ EFIAPI=0D
+ BeepStatusCodeReportWorker (=0D
+ IN EFI_STATUS_CODE_TYPE CodeType,=0D
+ IN EFI_STATUS_CODE_VALUE Value,=0D
+ IN UINT32 Instance,=0D
+ IN EFI_GUID *CallerId,=0D
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL=0D
+ )=0D
+=0D
+* In SmmBeepStatusCodeHandlerLib:=0D
+ EFI_STATUS=0D
+ EFIAPI=0D
+ BeepStatusCodeReportWorker (=0D
+ IN EFI_STATUS_CODE_TYPE CodeType,=0D
+ IN EFI_STATUS_CODE_VALUE Value,=0D
+ IN UINT32 Instance,=0D
+ IN EFI_GUID *CallerId,=0D
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL=0D
+ )=0D
+=0D
+* In BeepMapLib:=0D
+ UINT32=0D
+ EFIAPI=0D
+ GetBeepValueFromStatusCode (=0D
+ IN EFI_STATUS_CODE_TYPE CodeType,=0D
+ IN EFI_STATUS_CODE_VALUE Value=0D
+ )=0D
+=0D
+* In BeepLib:=0D
+ VOID=0D
+ EFIAPI=0D
+ Beep (=0D
+ IN UINT32 Value=0D
+ )=0D
+=0D
+## Configuration=0D
+* Link the library to StatusCodeHandler.efi.=0D
+ Example:=0D
+ MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerR=
untimeDxe.inf {=0D
+ <LibraryClasses>=0D
+ BeepDebugFeaturePkg/Library/BeepStatusCodeHandlerLib/RuntimeDxeBeepS=
tatusCodeHandlerLib.inf=0D
+ }=0D
+ Refer to BeepDebugFeaturePkg.dsc for other example.=0D
+* Config pcd gBeepDebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseBeep=0D
+ In platform .dsc file, need to config the type of gBeepDebugFeaturePkgTo=
kenSpaceGuid.PcdStatusCodeUseBeep.=0D
+ Use PcdsFixedAtBuild to save binary size, and use PcdsDynamic if want to=
enable/disable in runtime.=0D
+* Implemented platform's special BeepMapLib if needed.=0D
+* Provide the platform's special BeepLib.=0D
+* Make sure put the StatusCodeHandler.efi after the ReportStatusCodeRouter=
.efi.=0D
+=0D
+## Data Flows=0D
+Status Code (ReportStatusCode) -> Beep Value (GetBeepValueFromStatusCode).=
=0D
+=0D
+## Control Flows=0D
+ReportStatusCode() -> BeepStatusCodeReportWorker() -> GetBeepValueFromStat=
usCode() -> Beep()=0D
+=0D
+## Build Flows=0D
+There is not special build flows.=0D
+=0D
+## Test Point Results=0D
+Verify the post code shown is correct.=0D
+=0D
+## Functional Exit Criteria=0D
+N/A=0D
+=0D
+## Feature Enabling Checklist=0D
+* Set the PCD gBeepDebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseBeep to T=
RUE.=0D
+* Plug out all the memory, check can here the beep.=0D
+=0D
+## Common Optimizations=0D
+* Implemented platform's special BeepMapLib if needed.=0D
--=20
2.24.0.windows.2


Re: [PATCH v1 1/6] ShellPkg: acpiview: Add interface for data-driven table parsing

Tomas Pilar (tpilar)
 

Krzysztof has moved on to other pastures, I'll respin the patches accordingly.

Cheers,
Tom

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Gao, Zhichao via groups.io
Sent: 11 June 2020 08:43
To: Krzysztof Koch <Krzysztof.Koch@...>; devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@...>; Sami Mujawar <Sami.Mujawar@...>; Laura.Moretta@...@arm.com; nd <nd@...>
Subject: Re: [edk2-devel] [PATCH v1 1/6] ShellPkg: acpiview: Add interface for data-driven table parsing

(1) The ASSERT only works with DEBUG build. I think we need add if condition after the ASSERT to return the error code to avoid the null pointer dereference.
(2) It is suggested to use the const (lower-case) instead of CONST. same to static.

Others are fine to me.

Thanks,
Zhichao

-----Original Message-----
From: Krzysztof Koch <krzysztof.koch@...>
Sent: Tuesday, May 5, 2020 11:46 PM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@...>; Gao, Zhichao <zhichao.gao@...>;
Sami.Mujawar@...; Laura.Moretta@...@arm.com;
nd@...
Subject: [PATCH v1 1/6] ShellPkg: acpiview: Add interface for
data-driven table parsing

Define and implement an interface to streamline metadata collection
and validation for structures present in each ACPI table.

Most ACPI tables define substructures which constitute the table.
These substructures are identified by their 'Type' field value. The
range of possible 'Type' values is defined on a per-table basis.

For more sophisticated ACPI table validation, additional data about
each structure type needs to be maintained. This patch defines a new
ACPI_STRUCT_INFO structure. It stores additional metadata about a
building block of an ACPI table. ACPI_STRUCT_INFO's are organised into
ACPI_STRUCT_DATABASE's. ACPI_STRUCT_DATABASE is an array of
ACPI_STRUCT_INFO elements which are indexed using structure's type value.

For example, in the Multiple APIC Description Table (MADT) all
Interrupt Controller Structure types form a single database. In the
database, the GIC CPU Interface (GICC) structure's metadata is the 11th entry (i.e. Type = 0xB).

ACPI_STRUCT_INFO structure consists of:
- ASCII name of the structure
- ACPI-defined stucture Type
- bitmask defining the validity of the structure for various
architectures
- instance counter
- a handler for the structure (ACPI_STRUCT_HANDLER)

The bitmask allows detection of structures in a table which are not
compatible with the target platform.

For example, the Multiple APIC Description Table (MADT) contains
Interrupt Controller Structure definitions which apply to either the
Advanced Programmable Interrupt Controller (APIC) model or the Generic
Interrupt Controller (GIC) model. Presence of APIC-related structures
on an Arm-based platform is a bug which is now detected and reported by acpiview.

This patch adds support for compatibility checks with the Arm architecture only.
However, provisions are made to allow extensions to other architectures.

ACPI_STRUCT_HANDLER describes how the contents of the structure can be
parsed. The possible options are:
- An ACPI_PARSER array which can be passed to the ParseAcpi() function
- A dedicated function for parsing the structure
(ACPI_STRUCT_PARSER_FUNC)

If neither of these options is provided, it is assumed that the
parsing logic is not implemented.

ACPI_STRUCT_PARSER_FUNC expects the the first two arguments to be the
pointer to the start of the structure to parse and the length of structure's buffer.
The remaining two optional arguments are context specific.

This patch adds methods for:
- Resetting the instance count for all structure types in a table.
- Getting the combined instance count for all types in a table.
- Validating the compatibility of a structure with the target arch.
- Printing structure counts for the types which are compatible with
the target architecture and validating that the non-compatible
structures are not present in the table.
- Parsing the structure according to the information provided by its
handle.

Finally, define a helper PrintAcpiStructName () function to streamline
the printing of ACPI structure name together with the structure's current occurrence count.

References:
- ACPI 6.3, January 2019

Signed-off-by: Krzysztof Koch <krzysztof.koch@...>
---

Notes:
v1:
- Add interface for data-driven table parsing [Krzysztof]

ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c | 263
++++++++++++++++++++
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h | 234
+++++++++++++++++
2 files changed, 497 insertions(+)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
index
3f12a33050a4e4ab3be2187c90ef8dcf0882283d..32566101e2de2eec3ccf44563ee
79379404bff62 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
@@ -6,6 +6,8 @@
**/

#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "AcpiParser.h"
@@ -466,6 +468,267 @@ PrintFieldName (
);
}

+/**
+ Produce a Null-terminated ASCII string with the name and index of
+an
+ ACPI structure.
+
+ The output string is in the following format: <Name> [<Index>]
+
+ @param [in] Name Structure name.
+ @param [in] Index Structure index.
+ @param [in] BufferSize The size, in bytes, of the output buffer.
+ @param [out] Buffer Buffer for the output string.
+
+ @return The number of bytes written to the buffer (not including Null-byte)
+**/
+UINTN
+EFIAPI
+PrintAcpiStructName (
+ IN CONST CHAR8* Name,
+ IN UINT32 Index,
+ IN UINTN BufferSize,
+ OUT CHAR8* Buffer
+ )
+{
+ ASSERT (Name != NULL);
+ ASSERT (Buffer != NULL);
+
+ return AsciiSPrint (Buffer, BufferSize, "%a [%d]", Name , Index); }
+
+/**
+ Set all ACPI structure instance counts to 0.
+
+ @param [in,out] StructDb ACPI structure database with counts to reset.
+**/
+VOID
+EFIAPI
+ResetAcpiStructCounts (
+ IN OUT ACPI_STRUCT_DATABASE* StructDb
+ )
+{
+ UINT32 Type;
+
+ ASSERT (StructDb != NULL);
+ ASSERT (StructDb->Entries != NULL);
+
+ for (Type = 0; Type < StructDb->EntryCount; Type++) {
+ StructDb->Entries[Type].Count = 0;
+ }
+}
+
+/**
+ Sum all ACPI structure instance counts.
+
+ @param [in] StructDb ACPI structure database with per-type counts to sum.
+
+ @return Total number of structure instances recorded in the database.
+**/
+UINT32
+EFIAPI
+SumAcpiStructCounts (
+ IN CONST ACPI_STRUCT_DATABASE* StructDb
+ )
+{
+ UINT32 Type;
+ UINT32 Total;
+
+ ASSERT (StructDb != NULL);
+ ASSERT (StructDb->Entries != NULL);
+
+ Total = 0;
+
+ for (Type = 0; Type < StructDb->EntryCount; Type++) {
+ Total += StructDb->Entries[Type].Count; }
+
+ return Total;
+}
+
+/**
+ Validate that a structure with a given type value is defined for
+the given
+ ACPI table and target architecture.
+
+ The target architecture is evaluated from the firmare build parameters.
+
+ @param [in] Type ACPI-defined structure type.
+ @param [in] StructDb ACPI structure database with architecture
+ compatibility info.
+
+ @retval TRUE Structure is valid.
+ @retval FALSE Structure is not valid.
+**/
+BOOLEAN
+EFIAPI
+IsAcpiStructTypeValid (
+ IN UINT32 Type,
+ IN CONST ACPI_STRUCT_DATABASE* StructDb
+ )
+{
+ UINT32 Compatible;
+
+ ASSERT (StructDb != NULL);
+ ASSERT (StructDb->Entries != NULL);
+
+ if (Type >= StructDb->EntryCount) {
+ return FALSE;
+ }
+
+#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
+ Compatible = StructDb->Entries[Type].CompatArch &
+ (ARCH_COMPAT_ARM | ARCH_COMPAT_AARCH64); #else
+ Compatible = StructDb->Entries[Type].CompatArch;
+#endif
+
+ return (Compatible != 0);
+}
+
+/**
+ Print the instance count of each structure in an ACPI table that is
+ compatible with the target architecture.
+
+ For structures which are not allowed for the target architecture,
+ validate that their instance counts are 0.
+
+ @param [in] StructDb ACPI structure database with counts to validate.
+
+ @retval TRUE All structures are compatible.
+ @retval FALSE One or more incompatible structures present.
+**/
+BOOLEAN
+EFIAPI
+ValidateAcpiStructCounts (
+ IN CONST ACPI_STRUCT_DATABASE* StructDb
+ )
+{
+ BOOLEAN AllValid;
+ UINT32 Type;
+
+ ASSERT (StructDb != NULL);
+ ASSERT (StructDb->Entries != NULL);
+
+ AllValid = TRUE;
+ Print (L"\nTable Breakdown:\n");
+
+ for (Type = 0; Type < StructDb->EntryCount; Type++) {
+ ASSERT (Type == StructDb->Entries[Type].Type);
+
+ if (IsAcpiStructTypeValid (Type, StructDb)) {
+ Print (
+ L"%*a%-*a : %d\n",
+ INSTANCE_COUNT_INDENT,
+ "",
+ OUTPUT_FIELD_COLUMN_WIDTH - INSTANCE_COUNT_INDENT,
+ StructDb->Entries[Type].Name,
+ StructDb->Entries[Type].Count
+ );
+ } else if (StructDb->Entries[Type].Count > 0) {
+ AllValid = FALSE;
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: %a Structure is not valid for the target architecture " \
+ L"(found %d)\n",
+ StructDb->Entries[Type].Name,
+ StructDb->Entries[Type].Count
+ );
+ }
+ }
+
+ return AllValid;
+}
+
+/**
+ Parse the ACPI structure with the type value given according to
+instructions
+ defined in the ACPI structure database.
+
+ If the input structure type is defined in the database, increment
+ structure's instance count.
+
+ If ACPI_PARSER array is used to parse the input structure, the
+ index of the structure (instance count for the type before update)
+ gets printed alongside the structure name. This helps debugging if
+ there are many instances of the type in a table. For
+ ACPI_STRUCT_PARSER_FUNC, the printing of the index must be
+ implemented
separately.
+
+ @param [in] Indent Number of spaces to indent the output.
+ @param [in] Ptr Ptr to the start of the structure.
+ @param [in,out] StructDb ACPI structure database with instructions on how
+ parse every structure type.
+ @param [in] Offset Structure offset from the start of the table.
+ @param [in] Type ACPI-defined structure type.
+ @param [in] Length Length of the structure in bytes.
+ @param [in] OptArg0 First optional argument to pass to parser function.
+ @param [in] OptArg1 Second optional argument to pass to parser function.
+
+ @retval TRUE ACPI structure parsed successfully.
+ @retval FALSE Undefined structure type or insufficient data to parse.
+**/
+BOOLEAN
+EFIAPI
+ParseAcpiStruct (
+ IN UINT32 Indent,
+ IN UINT8* Ptr,
+ IN OUT ACPI_STRUCT_DATABASE* StructDb,
+ IN UINT32 Offset,
+ IN UINT32 Type,
+ IN UINT32 Length,
+ IN CONST VOID* OptArg0 OPTIONAL,
+ IN CONST VOID* OptArg1 OPTIONAL
+ )
+{
+ ACPI_STRUCT_PARSER_FUNC ParserFunc;
+ CHAR8 Buffer[80];
+
+ ASSERT (Ptr != NULL);
+ ASSERT (StructDb != NULL);
+ ASSERT (StructDb->Entries != NULL); ASSERT (StructDb->Name !=
+ NULL);
+
+ PrintFieldName (Indent, L"* Offset *"); Print (L"0x%x\n", Offset);
+
+ if (Type >= StructDb->EntryCount) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Unknown %a. Type = %d\n", StructDb->Name, Type);
+ return FALSE;
+ }
+
+ if (StructDb->Entries[Type].Handler.ParserFunc != NULL) {
+ ParserFunc = StructDb->Entries[Type].Handler.ParserFunc;
+ ParserFunc (Ptr, Length, OptArg0, OptArg1); } else if
+ (StructDb->Entries[Type].Handler.ParserArray != NULL) {
+ ASSERT (StructDb->Entries[Type].Handler.Elements != 0);
+
+ PrintAcpiStructName (
+ StructDb->Entries[Type].Name,
+ StructDb->Entries[Type].Count,
+ sizeof (Buffer),
+ Buffer
+ );
+
+ ParseAcpi (
+ TRUE,
+ Indent,
+ Buffer,
+ Ptr,
+ Length,
+ StructDb->Entries[Type].Handler.ParserArray,
+ StructDb->Entries[Type].Handler.Elements
+ );
+ } else {
+ StructDb->Entries[Type].Count++;
+ Print (
+ L"ERROR: Parsing of %a Structure is not implemented\n",
+ StructDb->Entries[Type].Name
+ );
+ return FALSE;
+ }
+
+ StructDb->Entries[Type].Count++;
+ return TRUE;
+}
+
/**
This function is used to parse an ACPI table buffer.

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
index
f81ccac7e118378aa185db4b625e5bcd75f78347..70e540b3a76de0ff9ce70bcabed
8548063bea0ff 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
@@ -300,6 +300,240 @@ typedef struct AcpiParser {
VOID* Context;
} ACPI_PARSER;

+/**
+ Produce a Null-terminated ASCII string with the name and index of
+an
+ ACPI structure.
+
+ The output string is in the following format: <Name> [<Index>]
+
+ @param [in] Name Structure name.
+ @param [in] Index Structure index.
+ @param [in] BufferSize The size, in bytes, of the output buffer.
+ @param [out] Buffer Buffer for the output string.
+
+ @return The number of bytes written to the buffer (not including Null-byte)
+**/
+UINTN
+EFIAPI
+PrintAcpiStructName (
+ IN CONST CHAR8* Name,
+ IN UINT32 Index,
+ IN UINTN BufferSize,
+ OUT CHAR8* Buffer
+ );
+
+/**
+ Indentation for printing instance counts for structures in an ACPI table.
+**/
+#define INSTANCE_COUNT_INDENT 2
+
+/**
+ Common signature for functions which parse ACPI structures.
+
+ @param [in] Ptr Pointer to the start of structure's buffer.
+ @param [in] Length Length of the buffer.
+ @param [in] OptArg0 First optional argument.
+ @param [in] OptArg1 Second optional argument.
+*/
+typedef VOID (*ACPI_STRUCT_PARSER_FUNC) (
+ IN UINT8* Ptr,
+ IN UINT32 Length,
+ IN CONST VOID* OptArg0 OPTIONAL,
+ IN CONST VOID* OptArg1 OPTIONAL
+ );
+
+/**
+ Description of how an ACPI structure should be parsed.
+
+ One of ParserFunc or ParserArray should be not NULL. Otherwise, it
+is
+ assumed that parsing of an ACPI structure is not supported. If both
+ ParserFunc and ParserArray are defined, ParserFunc is used.
+**/
+typedef struct AcpiStructHandler {
+ /// Dedicated function for parsing an ACPI structure
+ ACPI_STRUCT_PARSER_FUNC ParserFunc;
+ /// Array of instructions on how each structure field should be parsed
+ CONST ACPI_PARSER* ParserArray;
+ /// Number of elements in ParserArray if ParserArray is defined
+ UINT32 Elements;
+} ACPI_STRUCT_HANDLER;
+
+/**
+ ACPI structure compatiblity with various architectures.
+
+ Some ACPI tables define structures which are, for example, only
+ valid in the X64 or Arm context. For instance, the Multiple APIC
+ Description Table
+ (MADT) describes both APIC and GIC interrupt models.
+
+ These definitions provide means to describe the belonging of a
+structure
+ in an ACPI table to a particular architecture. This way,
+incompatible
+ structures can be detected.
+**/
+#define ARCH_COMPAT_IA32 BIT0
+#define ARCH_COMPAT_X64 BIT1
+#define ARCH_COMPAT_ARM BIT2
+#define ARCH_COMPAT_AARCH64 BIT3
+#define ARCH_COMPAT_RISCV64 BIT4
+
+/**
+ Information about a structure which constitutes an ACPI table **/
+typedef struct AcpiStructInfo {
+ /// ACPI-defined structure Name
+ CONST CHAR8* Name;
+ /// ACPI-defined structure Type
+ CONST UINT32 Type;
+ /// Architecture(s) for which this structure is valid
+ CONST UINT32 CompatArch;
+ /// Structure's instance count in a table
+ UINT32 Count;
+ /// Information on how to handle the structure
+ CONST ACPI_STRUCT_HANDLER Handler;
+} ACPI_STRUCT_INFO;
+
+/**
+ Macro for defining ACPI structure info when an ACPI_PARSER array
+must
+ be used to parse the structure.
+**/
+#define ADD_ACPI_STRUCT_INFO_ARRAY(Name, Type, Compat, Array) \
+{ \
+ Name, Type, Compat, 0, {NULL, Array, ARRAY_SIZE (Array)} \
+}
+
+/**
+ Macro for defining ACPI structure info when an
+ACPI_STRUCT_PARSER_FUNC
+ must be used to parse the structure.
+**/
+#define ADD_ACPI_STRUCT_INFO_FUNC(Name, Type, Compat, Func) \
+{ \
+ Name, Type, Compat, 0, {Func, NULL, 0} \
+}
+
+/**
+ Macro for defining ACPI structure info when the structure is
+defined in
+ the ACPI spec but no parsing information is provided.
+**/
+#define ACPI_STRUCT_INFO_PARSER_NOT_IMPLEMENTED(Name, Type,
Compat) \
+{ \
+ Name, Type, Compat, 0, {NULL, NULL, 0} \
+}
+
+/**
+ Database collating information about every structure type defined
+by
+ an ACPI table.
+**/
+typedef struct AcpiStructDatabase {
+ /// ACPI-defined name for the structures being described in the database
+ CONST CHAR8* Name;
+ /// Per-structure-type information. The list must be ordered by the
+types
+ /// defined for the table. All entries must be unique and there
+should be
+ /// no gaps.
+ ACPI_STRUCT_INFO* Entries;
+ /// Total number of unique types defined for the table
+ CONST UINT32 EntryCount;
+} ACPI_STRUCT_DATABASE;
+
+/**
+ Set all ACPI structure instance counts to 0.
+
+ @param [in,out] StructDb ACPI structure database with counts to reset.
+**/
+VOID
+EFIAPI
+ResetAcpiStructCounts (
+ IN OUT ACPI_STRUCT_DATABASE* StructDb
+ );
+
+/**
+ Sum all ACPI structure instance counts.
+
+ @param [in] StructDb ACPI structure database with per-type counts to sum.
+
+ @return Total number of structure instances recorded in the database.
+**/
+UINT32
+EFIAPI
+SumAcpiStructCounts (
+ IN CONST ACPI_STRUCT_DATABASE* StructDb
+ );
+
+/**
+ Validate that a structure with a given type value is defined for
+the given
+ ACPI table and target architecture.
+
+ The target architecture is evaluated from the firmare build parameters.
+
+ @param [in] Type ACPI-defined structure type.
+ @param [in] StructDb ACPI structure database with architecture
+ compatibility info.
+
+ @retval TRUE Structure is valid.
+ @retval FALSE Structure is not valid.
+**/
+BOOLEAN
+EFIAPI
+IsAcpiStructTypeValid (
+ IN UINT32 Type,
+ IN CONST ACPI_STRUCT_DATABASE* StructDb
+ );
+
+/**
+ Print the instance count of each structure in an ACPI table that is
+ compatible with the target architecture.
+
+ For structures which are not allowed for the target architecture,
+ validate that their instance counts are 0.
+
+ @param [in] StructDb ACPI structure database with counts to validate.
+
+ @retval TRUE All structures are compatible.
+ @retval FALSE One or more incompatible structures present.
+**/
+BOOLEAN
+EFIAPI
+ValidateAcpiStructCounts (
+ IN CONST ACPI_STRUCT_DATABASE* StructDb
+ );
+
+/**
+ Parse the ACPI structure with the type value given according to
+instructions
+ defined in the ACPI structure database.
+
+ If the input structure type is defined in the database, increment
+ structure's instance count.
+
+ If ACPI_PARSER array is used to parse the input structure, the
+ index of the structure (instance count for the type before update)
+ gets printed alongside the structure name. This helps debugging if
+ there are many instances of the type in a table. For
+ ACPI_STRUCT_PARSER_FUNC, the printing of the index must be
+ implemented
separately.
+
+ @param [in] Indent Number of spaces to indent the output.
+ @param [in] Ptr Ptr to the start of the structure.
+ @param [in,out] StructDb ACPI structure database with instructions on how
+ parse every structure type.
+ @param [in] Offset Structure offset from the start of the table.
+ @param [in] Type ACPI-defined structure type.
+ @param [in] Length Length of the structure in bytes.
+ @param [in] OptArg0 First optional argument to pass to parser function.
+ @param [in] OptArg1 Second optional argument to pass to parser function.
+
+ @retval TRUE ACPI structure parsed successfully.
+ @retval FALSE Undefined structure type or insufficient data to parse.
+**/
+BOOLEAN
+EFIAPI
+ParseAcpiStruct (
+ IN UINT32 Indent,
+ IN UINT8* Ptr,
+ IN OUT ACPI_STRUCT_DATABASE* StructDb,
+ IN UINT32 Offset,
+ IN UINT32 Type,
+ IN UINT32 Length,
+ IN CONST VOID* OptArg0 OPTIONAL,
+ IN CONST VOID* OptArg1 OPTIONAL
+ );
+
/**
A structure used to store the pointers to the members of the
ACPI description header structure that was parsed.
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


Re: [PATCH] IntelFsp2Pkg: Add Fsp22SecCoreS.inf to Dsc.

Zeng, Star
 

Reviewed-by: Star Zeng <star.zeng@...> with the copyright year correction.

-----Original Message-----
From: Desimone, Nathaniel L <nathaniel.l.desimone@...>
Sent: Thursday, June 11, 2020 4:35 AM
To: Chiu, Chasel <chasel.chiu@...>; devel@edk2.groups.io
Cc: Ma, Maurice <maurice.ma@...>; Zeng, Star <star.zeng@...>
Subject: RE: [PATCH] IntelFsp2Pkg: Add Fsp22SecCoreS.inf to Dsc.

Please fix copyright year. With that change...

Reviewed-by: Nate DeSimone <nathaniel.l.desimone@...>

-----Original Message-----
From: Chiu, Chasel <chasel.chiu@...>
Sent: Tuesday, June 9, 2020 7:33 PM
To: devel@edk2.groups.io
Cc: Ma, Maurice <maurice.ma@...>; Desimone, Nathaniel L
<nathaniel.l.desimone@...>; Zeng, Star <star.zeng@...>
Subject: [PATCH] IntelFsp2Pkg: Add Fsp22SecCoreS.inf to Dsc.

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

DSC is incomplete according to the established CI policies.
Fsp22SecCoreS.inf needs to be added to the Components section for
completeness.

Cc: Maurice Ma <maurice.ma@...>
Cc: Nate DeSimone <nathaniel.l.desimone@...>
Cc: Star Zeng <star.zeng@...>
Signed-off-by: Chasel Chiu <chasel.chiu@...>
---
IntelFsp2Pkg/IntelFsp2Pkg.dsc | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dsc b/IntelFsp2Pkg/IntelFsp2Pkg.dsc
index 02fe9cb188..9b5e38c5d9 100644
--- a/IntelFsp2Pkg/IntelFsp2Pkg.dsc
+++ b/IntelFsp2Pkg/IntelFsp2Pkg.dsc
@@ -1,7 +1,7 @@
## @file
# Provides driver and definitions to build fsp.
#
-# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014 - 2022, Intel Corporation. All rights
+reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -65,6 +65,7 @@
IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf
IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf
IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf
+ IntelFsp2Pkg/FspSecCore/Fsp22SecCoreS.inf
IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf

[PcdsFixedAtBuild.common]
--
2.13.3.windows.1


Re: [PATCH v9 46/46] Maintainers.txt: Add reviewers for the OvmfPkg SEV-related files

Laszlo Ersek
 

On 06/05/20 15:27, Tom Lendacky wrote:
Register reviewers for the SEV-related files in OvmfPkg.

Cc: Andrew Fish <afish@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Leif Lindholm <leif@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Brijesh Singh <brijesh.singh@...>
Reviewed-by: Laszlo Ersek <lersek@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
---
Maintainers.txt | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/Maintainers.txt b/Maintainers.txt
index 896ac5821fc6..2aa0148e9a97 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -441,6 +441,16 @@ F: OvmfPkg/PvScsiDxe/
R: Liran Alon <liran.alon@...>
R: Nikita Leshenko <nikita.leshchenko@...>

+OvmfPkg: SEV-related modules
+F: OvmfPkg/AmdSevDxe/
+F: OvmfPkg/Include/Library/MemEncryptSevLib.h
+F: OvmfPkg/IoMmuDxe/AmdSevIoMmu.*
+F: OvmfPkg/Library/BaseMemEncryptSevLib/
+F: OvmfPkg/Library/VmgExitLib/
+F: OvmfPkg/PlatformPei/AmdSev.c
+R: Tom Lendacky <thomas.lendacky@...>
+R: Brijesh Singh <brijesh.singh@...>
+
PcAtChipsetPkg
F: PcAtChipsetPkg/
W: https://github.com/tianocore/tianocore.github.io/wiki/PcAtChipsetPkg
Thanks!

Brijesh, can you please re-ACK this patch?

Thanks,
Laszlo


Re: [PATCH v9 36/46] OvmfPkg/ResetVector: Add support for a 32-bit SEV check

Laszlo Ersek
 

On 06/05/20 15:27, Tom Lendacky wrote:
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

During BSP startup, the reset vector code will issue a CPUID instruction
while in 32-bit mode. When running as an SEV-ES guest, this will trigger
a #VC exception.

Add exception handling support to the early reset vector code to catch
these exceptions. Also, since the guest is in 32-bit mode at this point,
writes to the GHCB will be encrypted and thus not able to be read by the
hypervisor, so use the GHCB CPUID request/response protocol to obtain the
requested CPUID function values and provide these to the guest.

The exception handling support is active during the SEV check and uses the
OVMF temporary RAM space for a stack. After the SEV check is complete, the
exception handling support is removed and the stack pointer cleared.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Reviewed-by: Laszlo Ersek <lersek@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
---

This patch has been reverted to the previous v6 version.
---
OvmfPkg/ResetVector/ResetVector.inf | 3 +
OvmfPkg/ResetVector/Ia32/PageTables64.asm | 275 +++++++++++++++++++-
OvmfPkg/ResetVector/ResetVector.nasmb | 2 +
3 files changed, 277 insertions(+), 3 deletions(-)
Thanks!
Laszlo


Re: [PATCH v9 34/46] OvmfPkg: Reserve a page in memory for the SEV-ES usage

Laszlo Ersek
 

On 06/05/20 15:27, Tom Lendacky wrote:
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Reserve a fixed area of memory for SEV-ES use and set a fixed PCD,
PcdSevEsWorkAreaBase, to this value.

This area will be used by SEV-ES support for two purposes:
1. Communicating the SEV-ES status during BSP boot to SEC:
Using a byte of memory from the page, the BSP reset vector code can
communicate the SEV-ES status to SEC for use before exception
handling can be enabled in SEC. After SEC, this field is no longer
valid and the standard way of determine if SEV-ES is active should
be used.

2. Establishing an area of memory for AP boot support:
A hypervisor is not allowed to update an SEV-ES guest's register
state, so when booting an SEV-ES guest AP, the hypervisor is not
allowed to set the RIP to the guest requested value. Instead an
SEV-ES AP must be re-directed from within the guest to the actual
requested staring location as specified in the INIT-SIPI-SIPI
sequence.

Use this memory for reset vector code that can be programmed to have
the AP jump to the desired RIP location after starting the AP. This
is required for only the very first AP reset.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Reviewed-by: Laszlo Ersek <lersek@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
---

This patch has been reverted to the previous v6 version.
Thanks!


Re: [PATCH v9 29/46] OvmfPkg: Create a GHCB page for use during Sec phase

Laszlo Ersek
 

Hi Tom,

On 06/05/20 15:27, Tom Lendacky wrote:
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

A GHCB page is needed during the Sec phase, so this new page must be
created. Since the #VC exception handler routines assume that a per-CPU
variable area is immediately after the GHCB, this per-CPU variable area
must also be created. Since the GHCB must be marked as an un-encrypted,
or shared, page, an additional pagetable page is required to break down
the 2MB region where the GHCB page lives into 4K pagetable entries.

Create a new entry in the OVMF memory layout for the new page table
page and for the SEC GHCB and per-CPU variable pages. After breaking down
the 2MB page, update the GHCB page table entry to remove the encryption
mask.

The GHCB page will be used by the SEC #VC exception handler. The #VC
exception handler will fill in the necessary fields of the GHCB and exit
to the hypervisor using the VMGEXIT instruction. The hypervisor then
accesses the GHCB in order to perform the requested function.

Four new fixed PCDs are needed to support the SEC GHCB page:
- PcdOvmfSecGhcbBase UINT32 value that is the base address of the
GHCB used during the SEC phase.
- PcdOvmfSecGhcbSize UINT32 value that is the size, in bytes, of the
GHCB area used during the SEC phase.

- PcdOvmfSecGhcbPageTableBase UINT32 value that is address of a page
table page used to break down the 2MB page into
512 4K pages.
- PcdOvmfSecGhcbPageTableSize UINT32 value that is the size, in bytes,
of the page table page.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
---
OvmfPkg/OvmfPkg.dec | 9 +++
OvmfPkg/OvmfPkgX64.fdf | 6 ++
OvmfPkg/ResetVector/ResetVector.inf | 5 ++
OvmfPkg/ResetVector/Ia32/PageTables64.asm | 76 ++++++++++++++++++++
OvmfPkg/ResetVector/ResetVector.nasmb | 17 +++++
5 files changed, 113 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 65bb2bb0eb4c..02ad62ed9f43 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -281,6 +281,15 @@ [PcdsFixedAtBuild]
## Number of page frames to use for storing grant table entries.
gUefiOvmfPkgTokenSpaceGuid.PcdXenGrantFrames|4|UINT32|0x33

+ ## Specify the extra page table needed to mark the GHCB as unencrypted.
+ # The value should be a multiple of 4KB for each.
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|0x0|UINT32|0x3a
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x3b
+
+ ## The base address of the SEC GHCB page used by SEV-ES.
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0|UINT32|0x3c
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0|UINT32|0x3d
+
[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index bfca1eff9e83..88b1e880e603 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -76,6 +76,12 @@ [FD.MEMFD]
0x007000|0x001000
gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize

+0x008000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
+
+0x009000|0x002000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
+
0x010000|0x010000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize

diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
index b0ddfa5832a2..483fd90fe785 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -26,6 +26,7 @@ [Sources]
[Packages]
OvmfPkg/OvmfPkg.dec
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec

[BuildOptions]
@@ -33,5 +34,9 @@ [BuildOptions]
*_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/

[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index abad009f20f5..9f86ddf6f08f 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -21,6 +21,11 @@ BITS 32
%define PAGE_2M_MBO 0x080
%define PAGE_2M_PAT 0x01000

+%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \
+ PAGE_DIRTY + \
+ PAGE_READ_WRITE + \
+ PAGE_PRESENT)
+
%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
PAGE_ACCESSED + \
PAGE_DIRTY + \
@@ -75,6 +80,37 @@ NoSev:
SevExit:
OneTimeCallRet CheckSevFeature

+; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
+; is enabled.
+;
+; Modified: EAX, EBX, ECX
+;
+; If SEV-ES is enabled then EAX will be non-zero.
+; If SEV-ES is disabled then EAX will be zero.
+;
+CheckSevEsFeature:
+ xor eax, eax
+
+ ; SEV-ES can't be enabled if SEV isn't, so first check the encryption
+ ; mask.
+ test edx, edx
+ jz NoSevEs
+
+ ; Save current value of encryption mask
+ mov ebx, edx
+
+ ; Check if SEV-ES is enabled
+ ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
+ mov ecx, 0xc0010131
+ rdmsr
+ and eax, 2
+
+ ; Restore encryption mask
+ mov edx, ebx
+
+NoSevEs:
+ OneTimeCallRet CheckSevEsFeature
+
;
; Modified: EAX, EBX, ECX, EDX
;
@@ -139,6 +175,46 @@ pageTableEntriesLoop:
mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
loop pageTableEntriesLoop

+ OneTimeCall CheckSevEsFeature
+ test eax, eax
+ jz SetCr3
+
+ ;
+ ; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted.
+ ; This requires the 2MB page for this range be broken down into 512 4KB
+ ; pages. All will be marked encrypted, except for the GHCB.
+ ;
+ mov ecx, (GHCB_BASE >> 21)
+ mov eax, GHCB_PT_ADDR + PAGE_PDP_ATTR
+ mov [ecx * 8 + PT_ADDR (0x2000)], eax
+
+ ;
+ ; Page Table Entries (512 * 4KB entries => 2MB)
+ ;
+ mov ecx, 512
+pageTableEntries4kLoop:
+ mov eax, ecx
+ dec eax
+ shl eax, 12
+ add eax, GHCB_BASE & 0xFFE0_0000
+ add eax, PAGE_4K_PDE_ATTR
+ mov [ecx * 8 + GHCB_PT_ADDR - 8], eax
+ mov [(ecx * 8 + GHCB_PT_ADDR - 8) + 4], edx
+ loop pageTableEntries4kLoop
+
+ ;
+ ; Clear the encryption bit from the GHCB entry
+ ;
+ mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12
+ mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0
+
+ mov ecx, GHCB_SIZE / 4
+ xor eax, eax
+clearGhcbMemoryLoop:
+ mov dword[ecx * 4 + GHCB_BASE - 4], eax
+ loop clearGhcbMemoryLoop
+
This patch is now identical to v6, modulo some (welcome) commit message
updates, and the PCD token value updates. Therefore, we can re-add my:

Reviewed-by: Laszlo Ersek <lersek@...>

from v6.

However, in the v8 discussion of the patch, you indicated that the
clearing loop had been in the wrong spot (in v6) -- it should have been
placed after the CR3 setting, apparently:

http://mid.mail-archive.com/1177217e-74d9-ddb5-fd38-c5ffb02de3f3@amd.com
https://edk2.groups.io/g/devel/message/60284

But in this update (v9), the clearing loop has not been moved, relative
to v6; it's been re-instated in the same spot. (IIUC.)

So what is the right spot for the clearing loop after all?

Thanks,
Laszlo

+SetCr3:
;
; Set CR3 now that the paging structures are available
;
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 75cfe16654b1..bfb77e439105 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -53,8 +53,25 @@
%error "This implementation inherently depends on PcdOvmfSecPageTablesSize"
%endif

+ %if (FixedPcdGet32 (PcdOvmfSecGhcbPageTableSize) != 0x1000)
+ %error "This implementation inherently depends on PcdOvmfSecGhcbPageTableSize"
+ %endif
+
+ %if (FixedPcdGet32 (PcdOvmfSecGhcbSize) != 0x2000)
+ %error "This implementation inherently depends on PcdOvmfSecGhcbSize"
+ %endif
+
+ %if ((FixedPcdGet32 (PcdOvmfSecGhcbBase) >> 21) != \
+ ((FixedPcdGet32 (PcdOvmfSecGhcbBase) + FixedPcdGet32 (PcdOvmfSecGhcbSize) - 1) >> 21))
+ %error "This implementation inherently depends on PcdOvmfSecGhcbBase not straddling a 2MB boundary"
+ %endif
+
%define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))
%include "Ia32/Flat32ToFlat64.asm"
+
+ %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase))
+ %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
+ %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
%include "Ia32/PageTables64.asm"
%endif


Re: [PATCH v9 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write NAE events

Laszlo Ersek
 

On 06/11/20 11:24, Laszlo Ersek wrote:
On 06/05/20 15:27, Tom Lendacky wrote:
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
The #VC handler must provide special support to the guest for this. On
a DR7 write, the #VC handler must cache the value and issue a VMGEXIT
to notify the hypervisor of the write. However, the #VC handler must
not actually set the value of the DR7 register. On a DR7 read, the #VC
handler must return the cached value of the DR7 register to the guest.
VMGEXIT is not invoked for a DR7 register read.

The caching of the DR7 values will make use of the per-CPU data pages
that are allocated along with the GHCB pages. The per-CPU page for a
vCPU is the page that immediately follows the vCPU's GHCB page. Since
each GHCB page is unique for a vCPU, the page that follows becomes
unique for that vCPU. The SEC phase will reserves an area of memory for
a single GHCB and per-CPU page for use by the BSP. After transitioning
to the PEI phase, new GHCB and per-CPU pages are allocated for the BSP
and all APs.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 114 ++++++++++++++++++++
1 file changed, 114 insertions(+)
The patch looks good to me:

Acked-by: Laszlo Ersek <lersek@...>

Just one question: in the v8 review, I wrote:

"""
With your explanation above, about platform reset, I think I'm happy
with the current handling of "Dr7Cached". So I'd like to leave the
choice to you: please either add the clearing, or document in the commit
message and/or the code that platform reset will not happen. Whichever
you like more.
"""

So what have you chosen ultimately? I haven't found a comment to the
effect of "An SEV-ES guest can't be rebooted/reset without restarting
Qemu" in this patch, in the commit message or in the code. Did you
implement the clearing, in the end? (Sorry if I should have noticed it
already!)
If I understand correctly, it's the clearGhcbMemoryLoop part (moved to
the new, correct, location) in patch#29. (For SEC.)

For PEI, we have a ZeroMem() call in patch#31.

I'm happy with those. (Hopefully I understand the code enough to be
*justifiedly* happy. :))

Thanks!
Laszlo


diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 9d93e30a8ea4..e8f9d3fa01a8 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -126,6 +126,14 @@ UINT64
SEV_ES_INSTRUCTION_DATA *InstructionData
);

+//
+// Per-CPU data mapping structure
+//
+typedef struct {
+ BOOLEAN Dr7Cached;
+ UINT64 Dr7;
+} SEV_ES_PER_CPU_DATA;
+

/**
Checks the GHCB to determine if the specified register has been marked valid.
@@ -1478,6 +1486,104 @@ RdtscExit (
return 0;
}

+/**
+ Handle a DR7 register write event.
+
+ Use the VMGEXIT instruction to handle a DR7 write event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+Dr7WriteExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ SEV_ES_PER_CPU_DATA *SevEsData;
+ UINT64 *Register;
+ UINT64 Status;
+
+ Ext = &InstructionData->Ext;
+ SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
+
+ DecodeModRm (Regs, InstructionData);
+
+ //
+ // MOV DRn always treats MOD == 3 no matter how encoded
+ //
+ Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
+
+ //
+ // Using a value of 0 for ExitInfo1 means RAX holds the value
+ //
+ Ghcb->SaveArea.Rax = *Register;
+ GhcbSetRegValid (Ghcb, GhcbRax);
+
+ Status = VmgExit (Ghcb, SVM_EXIT_DR7_WRITE, 0, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ SevEsData->Dr7 = *Register;
+ SevEsData->Dr7Cached = TRUE;
+
+ return 0;
+}
+
+/**
+ Handle a DR7 register read event.
+
+ Use the VMGEXIT instruction to handle a DR7 read event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+
+**/
+STATIC
+UINT64
+Dr7ReadExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ SEV_ES_PER_CPU_DATA *SevEsData;
+ UINT64 *Register;
+
+ Ext = &InstructionData->Ext;
+ SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
+
+ DecodeModRm (Regs, InstructionData);
+
+ //
+ // MOV DRn always treats MOD == 3 no matter how encoded
+ //
+ Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
+
+ //
+ // If there is a cached valued for DR7, return that. Otherwise return the
+ // DR7 standard reset value of 0x400 (no debug breakpoints set).
+ //
+ *Register = (SevEsData->Dr7Cached) ? SevEsData->Dr7 : 0x400;
+
+ return 0;
+}
+
/**
Handle a #VC exception.

@@ -1522,6 +1628,14 @@ VmgExitHandleVc (

ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SVM_EXIT_DR7_READ:
+ NaeExit = Dr7ReadExit;
+ break;
+
+ case SVM_EXIT_DR7_WRITE:
+ NaeExit = Dr7WriteExit;
+ break;
+
case SVM_EXIT_RDTSC:
NaeExit = RdtscExit;
break;


Re: [PATCH v9 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write NAE events

Laszlo Ersek
 

On 06/05/20 15:27, Tom Lendacky wrote:
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
The #VC handler must provide special support to the guest for this. On
a DR7 write, the #VC handler must cache the value and issue a VMGEXIT
to notify the hypervisor of the write. However, the #VC handler must
not actually set the value of the DR7 register. On a DR7 read, the #VC
handler must return the cached value of the DR7 register to the guest.
VMGEXIT is not invoked for a DR7 register read.

The caching of the DR7 values will make use of the per-CPU data pages
that are allocated along with the GHCB pages. The per-CPU page for a
vCPU is the page that immediately follows the vCPU's GHCB page. Since
each GHCB page is unique for a vCPU, the page that follows becomes
unique for that vCPU. The SEC phase will reserves an area of memory for
a single GHCB and per-CPU page for use by the BSP. After transitioning
to the PEI phase, new GHCB and per-CPU pages are allocated for the BSP
and all APs.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 114 ++++++++++++++++++++
1 file changed, 114 insertions(+)
The patch looks good to me:

Acked-by: Laszlo Ersek <lersek@...>

Just one question: in the v8 review, I wrote:

"""
With your explanation above, about platform reset, I think I'm happy
with the current handling of "Dr7Cached". So I'd like to leave the
choice to you: please either add the clearing, or document in the commit
message and/or the code that platform reset will not happen. Whichever
you like more.
"""

So what have you chosen ultimately? I haven't found a comment to the
effect of "An SEV-ES guest can't be rebooted/reset without restarting
Qemu" in this patch, in the commit message or in the code. Did you
implement the clearing, in the end? (Sorry if I should have noticed it
already!)

Thanks,
Laszlo


diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 9d93e30a8ea4..e8f9d3fa01a8 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -126,6 +126,14 @@ UINT64
SEV_ES_INSTRUCTION_DATA *InstructionData
);

+//
+// Per-CPU data mapping structure
+//
+typedef struct {
+ BOOLEAN Dr7Cached;
+ UINT64 Dr7;
+} SEV_ES_PER_CPU_DATA;
+

/**
Checks the GHCB to determine if the specified register has been marked valid.
@@ -1478,6 +1486,104 @@ RdtscExit (
return 0;
}

+/**
+ Handle a DR7 register write event.
+
+ Use the VMGEXIT instruction to handle a DR7 write event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+Dr7WriteExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ SEV_ES_PER_CPU_DATA *SevEsData;
+ UINT64 *Register;
+ UINT64 Status;
+
+ Ext = &InstructionData->Ext;
+ SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
+
+ DecodeModRm (Regs, InstructionData);
+
+ //
+ // MOV DRn always treats MOD == 3 no matter how encoded
+ //
+ Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
+
+ //
+ // Using a value of 0 for ExitInfo1 means RAX holds the value
+ //
+ Ghcb->SaveArea.Rax = *Register;
+ GhcbSetRegValid (Ghcb, GhcbRax);
+
+ Status = VmgExit (Ghcb, SVM_EXIT_DR7_WRITE, 0, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ SevEsData->Dr7 = *Register;
+ SevEsData->Dr7Cached = TRUE;
+
+ return 0;
+}
+
+/**
+ Handle a DR7 register read event.
+
+ Use the VMGEXIT instruction to handle a DR7 read event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+
+**/
+STATIC
+UINT64
+Dr7ReadExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ SEV_ES_PER_CPU_DATA *SevEsData;
+ UINT64 *Register;
+
+ Ext = &InstructionData->Ext;
+ SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
+
+ DecodeModRm (Regs, InstructionData);
+
+ //
+ // MOV DRn always treats MOD == 3 no matter how encoded
+ //
+ Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
+
+ //
+ // If there is a cached valued for DR7, return that. Otherwise return the
+ // DR7 standard reset value of 0x400 (no debug breakpoints set).
+ //
+ *Register = (SevEsData->Dr7Cached) ? SevEsData->Dr7 : 0x400;
+
+ return 0;
+}
+
/**
Handle a #VC exception.

@@ -1522,6 +1628,14 @@ VmgExitHandleVc (

ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SVM_EXIT_DR7_READ:
+ NaeExit = Dr7ReadExit;
+ break;
+
+ case SVM_EXIT_DR7_WRITE:
+ NaeExit = Dr7WriteExit;
+ break;
+
case SVM_EXIT_RDTSC:
NaeExit = RdtscExit;
break;


Re: [PATCH v9 25/46] OvmfPkg/VmgExitLib: Add support for MWAIT/MWAITX NAE events

Laszlo Ersek
 

On 06/05/20 15:27, Tom Lendacky wrote:
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Under SEV-ES, a MWAIT/MWAITX intercept generates a #VC exception.
VMGEXIT must be used to allow the hypervisor to handle this intercept.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Acked-by: Laszlo Ersek <lersek@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 36 ++++++++++++++++++++
1 file changed, 36 insertions(+)
OK


Re: [PATCH v9 24/46] OvmfPkg/VmgExitLib: Add support for MONITOR/MONITORX NAE events

Laszlo Ersek
 

On 06/05/20 15:27, Tom Lendacky wrote:
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Under SEV-ES, a MONITOR/MONITORX intercept generates a #VC exception.
VMGEXIT must be used to allow the hypervisor to handle this intercept.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Acked-by: Laszlo Ersek <lersek@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 38 ++++++++++++++++++++
1 file changed, 38 insertions(+)
OK


Re: [PATCH v9 23/46] OvmfPkg/VmgExitLib: Add support for RDTSCP NAE events

Laszlo Ersek
 

On 06/05/20 15:27, Tom Lendacky wrote:
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

Under SEV-ES, a RDTSCP intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Acked-by: Laszlo Ersek <lersek@...>
Signed-off-by: Tom Lendacky <thomas.lendacky@...>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 47 ++++++++++++++++++++
1 file changed, 47 insertions(+)
OK