Date   

[PATCH 03/13] MdePkg/Register/Amd: define GHCB macros for hypervisor feature detection

Brijesh Singh
 

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

Version 2 of GHCB introduces advertisement of features that are supported
by the hypervisor. See the GHCB spec section 2.2 for an additional details.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewd-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
MdePkg/Include/Register/Amd/Fam17Msr.h | 7 +++++++
MdePkg/Include/Register/Amd/Ghcb.h | 8 ++++++++
2 files changed, 15 insertions(+)

diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h b/MdePkg/Include/Register/Amd/Fam17Msr.h
index 7368ce7af02a..cdb8f588ccf8 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -48,6 +48,11 @@ typedef union {
UINT32 Reserved2:32;
} GhcbTerminate;

+ struct {
+ UINT64 Function:12;
+ UINT64 Features:52;
+ } GhcbHypervisorFeatures;
+
VOID *Ghcb;

UINT64 GhcbPhysicalAddress;
@@ -57,6 +62,8 @@ typedef union {
#define GHCB_INFO_SEV_INFO_GET 2
#define GHCB_INFO_CPUID_REQUEST 4
#define GHCB_INFO_CPUID_RESPONSE 5
+#define GHCB_HYPERVISOR_FEATURES_REQUEST 128
+#define GHCB_HYPERVISOR_FEATURES_RESPONSE 129
#define GHCB_INFO_TERMINATE_REQUEST 256

#define GHCB_TERMINATE_GHCB 0
diff --git a/MdePkg/Include/Register/Amd/Ghcb.h b/MdePkg/Include/Register/Amd/Ghcb.h
index 712dc8e769c0..326b11479779 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -54,6 +54,7 @@
#define SVM_EXIT_NMI_COMPLETE 0x80000003ULL
#define SVM_EXIT_AP_RESET_HOLD 0x80000004ULL
#define SVM_EXIT_AP_JUMP_TABLE 0x80000005ULL
+#define SVM_EXIT_HYPERVISOR_FEATURES 0x8000FFFDULL
#define SVM_EXIT_UNSUPPORTED 0x8000FFFFULL

//
@@ -154,4 +155,11 @@ typedef union {
#define GHCB_EVENT_INJECTION_TYPE_EXCEPTION 3
#define GHCB_EVENT_INJECTION_TYPE_SOFT_INT 4

+//
+// Hypervisor features dections
+//
+#define GHCB_HV_FEATURES_SNP BIT0
+#define GHCB_HV_FEATURES_SNP_AP_CREATE (GHCB_HV_FEATURES_SNP | BIT1)
+#define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION (GHCB_HV_FEATURES_SNP_AP_CREATE | BIT2)
+#define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION_TIMER (GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION | BIT3)
#endif
--
2.17.1


[PATCH 01/13] MdePkg/Register/Amd: expand the SEV MSR to include the SNP definition

Brijesh Singh
 

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

Define the SEV-SNP MSR bits.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
MdePkg/Include/Register/Amd/Fam17Msr.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h b/MdePkg/Include/Register/Amd/Fam17Msr.h
index e4db09c5184c..716d52fd508d 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -87,7 +87,12 @@ typedef union {
///
UINT32 SevEsBit:1;

- UINT32 Reserved:30;
+ ///
+ /// [Bit 2] Secure Nested Paging (SevSnp) is enabled
+ ///
+ UINT32 SevSnpBit:1;
+
+ UINT32 Reserved2:29;
} Bits;
///
/// All bit fields as a 32-bit value
--
2.17.1


[PATCH 02/13] MdePkg/Amd: add white spaces to retain alignment for future expansion

Brijesh Singh
 

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

Version 2 of the GHCB spec introduces several new SNP-specific NAEs.
Unfortunately, the names for those NAEs break the alignment. Add some
white spaces so that the SNP support patches do not break the alignment.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
MdePkg/Include/Register/Amd/Fam17Msr.h | 10 +++++-----
MdePkg/Include/Register/Amd/Ghcb.h | 12 ++++++------
2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h b/MdePkg/Include/Register/Amd/Fam17Msr.h
index 716d52fd508d..7368ce7af02a 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -53,11 +53,11 @@ typedef union {
UINT64 GhcbPhysicalAddress;
} MSR_SEV_ES_GHCB_REGISTER;

-#define GHCB_INFO_SEV_INFO 1
-#define GHCB_INFO_SEV_INFO_GET 2
-#define GHCB_INFO_CPUID_REQUEST 4
-#define GHCB_INFO_CPUID_RESPONSE 5
-#define GHCB_INFO_TERMINATE_REQUEST 256
+#define GHCB_INFO_SEV_INFO 1
+#define GHCB_INFO_SEV_INFO_GET 2
+#define GHCB_INFO_CPUID_REQUEST 4
+#define GHCB_INFO_CPUID_RESPONSE 5
+#define GHCB_INFO_TERMINATE_REQUEST 256

#define GHCB_TERMINATE_GHCB 0
#define GHCB_TERMINATE_GHCB_GENERAL 0
diff --git a/MdePkg/Include/Register/Amd/Ghcb.h b/MdePkg/Include/Register/Amd/Ghcb.h
index ccdb662af7a7..712dc8e769c0 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -49,12 +49,12 @@
//
// VMG Special Exit Codes
//
-#define SVM_EXIT_MMIO_READ 0x80000001ULL
-#define SVM_EXIT_MMIO_WRITE 0x80000002ULL
-#define SVM_EXIT_NMI_COMPLETE 0x80000003ULL
-#define SVM_EXIT_AP_RESET_HOLD 0x80000004ULL
-#define SVM_EXIT_AP_JUMP_TABLE 0x80000005ULL
-#define SVM_EXIT_UNSUPPORTED 0x8000FFFFULL
+#define SVM_EXIT_MMIO_READ 0x80000001ULL
+#define SVM_EXIT_MMIO_WRITE 0x80000002ULL
+#define SVM_EXIT_NMI_COMPLETE 0x80000003ULL
+#define SVM_EXIT_AP_RESET_HOLD 0x80000004ULL
+#define SVM_EXIT_AP_JUMP_TABLE 0x80000005ULL
+#define SVM_EXIT_UNSUPPORTED 0x8000FFFFULL

//
// IOIO Exit Information
--
2.17.1


[PATCH 00/13] Add GHCBv2 macro and helpers

Brijesh Singh
 

This series is taken from the SNP RFC. This series defines the GHCBv2
macros and NAE events. Additionally, it also introduces a helper to
clear the page encryption mask from the Mmio region.

The series is based on the commit:
f297b7f20010 UnitTestFrameworkPkg: Sample unit test hangs when running in OVMF/QEMU

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>

Brijesh Singh (11):
MdePkg/Register/Amd: expand the SEV MSR to include the SNP definition
MdePkg/Amd: add white spaces to retain alignment for future expansion
MdePkg/Register/Amd: define GHCB macros for hypervisor feature
detection
MdePkg/Register/Amd: define GHCB macro for Register GPA structure
MdePkg/Register/Amd: define GHCB macro for the Page State Change
MdePkg/BaseLib: add support for PVALIDATE instruction
OvmfPkg/BaseMemEncryptSevLib: introduce
MemEncryptSevClearMmioPageEncMask()
OvmfPkg/AmdSevDxe: use MemEncryptSevClearMmioPageEncMask() to clear
EncMask
OvmfPkg/QemuFlashFvbServicesRuntimeDxe: use Mmio helper to clear enc
mask
OvmfPkg/TpmMmioSevDecryptPei: use MemEncryptSevClearMmioPageEncMask()
OvmfPkg/BaseMemEncryptSevLib: remove Flush parameter

Tom Lendacky (2):
MdePkg/Register/Amd: define GHCB macros for SNP AP creation
MdePkg/BaseLib: add support for RMPADJUST instruction

MdePkg/Library/BaseLib/BaseLib.inf | 2 +
MdePkg/Include/Library/BaseLib.h | 80 ++++++++++++
MdePkg/Include/Register/Amd/Fam17Msr.h | 46 ++++++-
MdePkg/Include/Register/Amd/Ghcb.h | 123 +++++++++++++++++-
OvmfPkg/Include/Library/MemEncryptSevLib.h | 35 +++--
.../BaseMemEncryptSevLib/X64/VirtualMemory.h | 33 +++--
OvmfPkg/AmdSevDxe/AmdSevDxe.c | 13 +-
OvmfPkg/IoMmuDxe/AmdSevIoMmu.c | 6 +-
.../Ia32/MemEncryptSevLib.c | 41 ++++--
.../X64/MemEncryptSevLib.c | 49 +++++--
.../X64/PeiDxeVirtualMemory.c | 63 +++++++--
.../X64/SecVirtualMemory.c | 8 +-
.../SmmCpuFeaturesLib/SmmCpuFeaturesLib.c | 3 +-
OvmfPkg/PlatformPei/AmdSev.c | 3 +-
.../FwBlockServiceDxe.c | 5 +-
.../QemuFlashSmm.c | 5 +-
.../TpmMmioSevDecryptPeim.c | 5 +-
MdePkg/Include/X64/Nasm.inc | 16 +++
MdePkg/Library/BaseLib/X64/Pvalidate.nasm | 42 ++++++
MdePkg/Library/BaseLib/X64/RmpAdjust.nasm | 40 ++++++
20 files changed, 526 insertions(+), 92 deletions(-)
create mode 100644 MdePkg/Library/BaseLib/X64/Pvalidate.nasm
create mode 100644 MdePkg/Library/BaseLib/X64/RmpAdjust.nasm

--
2.17.1


Re: [PATCH v1 1/1] ArmPkg: Update SCMI Base Protocol version to 0x20000

Ard Biesheuvel
 

Hello Pierre,

On Thu, 6 May 2021 at 12:43, <Pierre.Gondois@arm.com> wrote:

From: Nicola Mazzucato <nicola.mazzucato@arm.com>

The SCP-firmware has moved to full support for SCMIv2 which means that
the base protocol can be either compliant with SCMI v1 or v2.

Allow any version between SCMI v1.0 and SCMI v2.0 to be compatible
with the current implementation.

Signed-off-by: Nicola Mazzucato <nicola.mazzucato@arm.com>
SOB is not an attribution of authorship, it is a statement made by the
person contributing the patch asserting that the contribution complies
with the license.

IOW, you can keep the From: line, but please change the SOB to your
name and email.

Thanks,
Ard.

---
The changes can be seen at: https://github.com/PierreARM/edk2/tree/1732_Update_SCMI_version_v1

ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c | 10 ++++++----
ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h | 10 +++++-----
2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c b/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c
index d5890a7633a2..fb4e79aa3610 100644
--- a/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c
+++ b/ArmPkg/Drivers/ArmScmiDxe/ScmiDxe.c
@@ -4,9 +4,9 @@

SPDX-License-Identifier: BSD-2-Clause-Patent

- System Control and Management Interface V1.0
- http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
- DEN0056A_System_Control_and_Management_Interface.pdf
+ @par Specification Reference:
+ - Arm System Control and Management Interface - Platform Design Document
+ (https://developer.arm.com/documentation/den0056/)
**/

#include <Base.h>
@@ -86,7 +86,9 @@ ArmScmiDxeEntryPoint (
return Status;
}

- if (Version != BASE_PROTOCOL_VERSION) {
+ // Accept any version between SCMI v1.0 and SCMI v2.0
+ if ((Version < BASE_PROTOCOL_VERSION_V1) ||
+ (Version > BASE_PROTOCOL_VERSION_V2)) {
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
diff --git a/ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h b/ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
index 73ad3e32a2f5..c4b81c0f56d3 100644
--- a/ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
+++ b/ArmPkg/Include/Protocol/ArmScmiBaseProtocol.h
@@ -4,9 +4,9 @@

SPDX-License-Identifier: BSD-2-Clause-Patent

- System Control and Management Interface V1.0
- http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/
- DEN0056A_System_Control_and_Management_Interface.pdf
+ @par Specification Reference:
+ - Arm System Control and Management Interface - Platform Design Document
+ (https://developer.arm.com/documentation/den0056/)
**/

#ifndef ARM_SCMI_BASE_PROTOCOL_H_
@@ -14,7 +14,8 @@

#include <Protocol/ArmScmi.h>

-#define BASE_PROTOCOL_VERSION 0x10000
+#define BASE_PROTOCOL_VERSION_V1 0x10000
+#define BASE_PROTOCOL_VERSION_V2 0x20000

#define NUM_PROTOCOL_MASK 0xFFU
#define NUM_AGENT_MASK 0xFFU
@@ -165,4 +166,3 @@ typedef enum {
} SCMI_MESSAGE_ID_BASE;

#endif /* ARM_SCMI_BASE_PROTOCOL_H_ */
-
--
2.17.1


Re: [PATCH v2 0/2] MdePkg,SecurityPkg: Add support to RngDxe and BaseRngLib for AARCH64 RNDR

Ard Biesheuvel
 

On Fri, 7 May 2021 at 16:23, Rebecca Cran <rebecca@nuviainc.com> wrote:

Update MdePkg BaseRngLib and SecurityPkg RngDxe to add support for
the AARCH64 RNDR instruction.

Changes from v1 to v2:

o Added a PCD, gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm to
specify which algorighm the platform supports.
o Moved ArmRndr() and ArmRndrrs() into BaseRngLib.
o Added Doxygen headers.
o Merged X64 and AARCH64 *GetBytes functions into a single RngGetBytes
function.
o Updated constructors to return EFI_STATUS instead of RETURN_STATUS.
o Added ArchIsRngSupported function that gets called before each call to
ArchGetRandomNumber*.

Rebecca Cran (2):
MdePkg/BaseRngLib: Add support for ARMv8.5 RNG instructions
SecurityPkg: Add support for RngDxe on AARCH64
I don't maintain any of the packages involved, but the changes look fine to me.

Acked-by: Ard Biesheuvel <ardb@kernel.org>


MdePkg/MdePkg.dec | 9 +-
SecurityPkg/SecurityPkg.dec | 2 +
MdePkg/MdePkg.dsc | 4 +-
SecurityPkg/SecurityPkg.dsc | 11 +-
MdePkg/Library/BaseRngLib/BaseRngLib.inf | 23 ++-
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf | 24 ++-
MdePkg/Library/BaseRngLib/AArch64/ArmRng.h | 59 +++++++
MdePkg/Library/BaseRngLib/BaseRngLibInternals.h | 79 +++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h | 0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h | 17 --
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h | 117 ++++++++++++++
MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 139 ++++++++++++++++
MdePkg/Library/BaseRngLib/BaseRng.c | 87 +++++-----
MdePkg/Library/BaseRngLib/Rand/RdRand.c | 131 +++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c | 127 +++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c | 0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c | 45 +-----
SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c | 146 +++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c | 170 ++++++++------------
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S | 31 ++++
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm | 30 ++++
MdePkg/Library/BaseRngLib/AArch64/ArmRng.S | 61 +++++++
MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm | 64 ++++++++
MdePkg/Library/BaseRngLib/BaseRngLib.uni | 6 +-
24 files changed, 1152 insertions(+), 230 deletions(-)
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
create mode 100644 MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h (100%)
rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h (72%)
create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/Rndr.c
create mode 100644 MdePkg/Library/BaseRngLib/Rand/RdRand.c
create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c (100%)
rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c (71%)
create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm

--
2.26.2


Re: [PATCH RFC v2 09/28] OvmfPkg/VmgExitLib: Allow PMBASE register access in Dxe phase

Laszlo Ersek
 

On 05/07/21 17:19, Brijesh Singh wrote:

On 5/7/21 10:10 AM, Laszlo Ersek wrote:

Sounds good. What's your thought if I take out patch 1 - 9 from this RFC
series and submit them as non-RFC for the further review and acceptance
? The patch# 1-9 are basically prepatch before we get into SNP specific
bits.
More precisely, that means patches 1-8 (because patch#9 should be
replaced by the module-scope override, and also moved to just before
what is currently patch#21).

Other than that, I agree, this is a good idea. I've anyway thought that
the MdePkg stuff (5 patches) could be / should be merged up-front in
separation, and then the subsequent 3 patches for OvmfPkg are basically
refactoring. We can record the resultant commit range (8 commits) in
TianoCore#3275, and keep the BZ open for the rest of the work. So go
ahead please.
Yes, I will keep patch#9 in SNP series.

FYI, I will add couple of more patches in MdePkg to define the macros
for AP creation and RMPAJUST instruction. Now that GHCB spec is final,
we are working to get the AP creation implemented for the next version.
If the spec is final, then extending the MdePkg patches makes sense, yes.

Thanks
Laszlo


Re: [PATCH RFC v2 09/28] OvmfPkg/VmgExitLib: Allow PMBASE register access in Dxe phase

Brijesh Singh
 

On 5/7/21 10:10 AM, Laszlo Ersek wrote:

Sounds good. What's your thought if I take out patch 1 - 9 from this RFC
series and submit them as non-RFC for the further review and acceptance
? The patch# 1-9 are basically prepatch before we get into SNP specific
bits.
More precisely, that means patches 1-8 (because patch#9 should be
replaced by the module-scope override, and also moved to just before
what is currently patch#21).

Other than that, I agree, this is a good idea. I've anyway thought that
the MdePkg stuff (5 patches) could be / should be merged up-front in
separation, and then the subsequent 3 patches for OvmfPkg are basically
refactoring. We can record the resultant commit range (8 commits) in
TianoCore#3275, and keep the BZ open for the rest of the work. So go
ahead please.
Yes, I will keep patch#9 in SNP series.

FYI, I will add couple of more patches in MdePkg to define the macros
for AP creation and RMPAJUST instruction. Now that GHCB spec is final,
we are working to get the AP creation implemented for the next version.

-Brijesh


Re: [PATCH RFC v2 09/28] OvmfPkg/VmgExitLib: Allow PMBASE register access in Dxe phase

Laszlo Ersek
 

On 05/07/21 15:29, Brijesh Singh wrote:

On 5/6/21 9:08 AM, Laszlo Ersek wrote:
On 04/30/21 13:51, Brijesh Singh wrote:
BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&;data=04%7C01%7Cbrijesh.singh%40amd.com%7C01d3e5c5268043c18bdf08d910987251%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637559069206222390%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=CN2hZrjsKzfSqMAxcQLtoHTUqBOlZmdDEO9vY9XT%2FTQ%3D&amp;reserved=0

Commit 85b8eac59b8c5bd9c7eb9afdb64357ce1aa2e803 added support to ensure
that MMIO is only performed against the un-encrypted memory. If MMIO
is performed against encrypted memory, a #GP is raised.

The VmgExitLib library depends on ApicTimerLib to get the APIC base
address so that it can exclude the APIC range from the un-encrypted
check. The OvmfPkg provides ApicTimerLib for the DXE phase. The
constructor AcpiTimerLibConstructor() used in the ApicTimerLib uses
the PciRead to get the PMBASE register. The PciRead() will cause an
MMIO access.

The AmdSevDxe driver clears the memory encryption attribute from the
MMIO ranges. However, if VmgExitLib is linked to AmdSevDxe driver then the
AcpiTimerLibConstructor() will be called before AmdSevDxe driver can
clear the encryption attributes for the MMIO regions.

Exclude the PMBASE register from the encrypted check so that we
can link VmgExitLib to the MemEncryptSevLib; which gets linked to
AmdSevDxe driver.
The above explanation is inexact. There are several typos ("APIC" is
incorrect, "ACPI" would be correct, for the TimerLib instance in
question), but that's really just a side observation.

The precise explanation is the following library instance dependency
chain:

OvmfPkg/AmdSevDxe/AmdSevDxe.inf
-----> MemEncryptSevLib class
-----> "OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf" instance
-[*]-> VmgExitLib class
-----> "OvmfPkg/Library/VmgExitLib/VmgExitLib.inf" instance
-----> LocalApicLib class
-----> "UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf" instance
-----> TimerLib class
-----> "OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf" instance
-----> PciLib class
-----> "OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf" instance
-----> PciExpressLib class
-----> "MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf" instance

The link (or dependency) marked with [*] is introduced in patch #26
("OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table").
That's the change that triggers the symptom. (In combination with you
testing on Q35, because on i440fx, the DxePciLibI440FxQ35 lib instance
accesses PCI config space via the 0xCF8, 0xCFC IO Ports, and those are
unaffected by SEV-ES.)

The symptom is somewhat "unjustified", because at the end of the series,
the AmdSevDxe driver makes no calls to actual TimerLib APIs (I checked
-- I disassembled the "AmdSevDxe.debug" file with "objdump -S", and
there is no call to any API declared in the "TimerLib.h" class header).
However, the ECAM (MMCONFIG) access is still triggered, because the
AcpiTimerLibConstructor() function, in
"OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c", is the constructor for
the "OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf" instance, and
AcpiTimerLibConstructor() calls PciRead32().

If you check the "OvmfPkg/OvmfPkgX64.dsc" file, you'll find that the
PciLib class is resolved to
"MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf" by default, and to
"OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf" for the
following module types:

- DXE_DRIVER,
- DXE_RUNTIME_DRIVER,
- SMM_CORE,
- DXE_SMM_DRIVER,
- UEFI_DRIVER,
- UEFI_APPLICATION.

The consequence is that modules strictly after the DXE_CORE get
dynamically enabled extended config space access (ECAM) on Q35 via the
PciLib class, whereas all modules strictly before the DXE_CORE, and the
DXE_CORE itself, are restricted to normal config space (IO Ports 0xCF8 /
0xCFC) via the PciLib class.

AmdSevDxe is a DXE_DRIVER, so it used to get DxePciLibI440FxQ35 as well.

The solution should be simple. In the AmdSevDxe driver specifically, we
need no access to extended PCI config space. Accessing normal PCI config
space, via IO Ports 0xCF8 / 0xCFC, should suffice. That can be achieved
with the following module-scope override:
Thanks Laszlo, I was not aware of the module-scope override. I will go
with this approach and make sure it works after the inclusion of the
VmgExitLib.



diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 8d9a0a077601..45a02b236633 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -966,7 +966,10 @@ [Components]
!endif

OvmfPkg/PlatformDxe/Platform.inf
- OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+ OvmfPkg/AmdSevDxe/AmdSevDxe.inf {
+ <LibraryClasses>
+ PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+ }
OvmfPkg/IoMmuDxe/IoMmuDxe.inf
OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
(

For consistency, all DSC files that include
"OvmfPkg/AmdSevDxe/AmdSevDxe.inf" should be modified similarly:

- OvmfPkg/AmdSev/AmdSevX64.dsc
- OvmfPkg/Bhyve/BhyveX64.dsc
- OvmfPkg/OvmfPkgIa32X64.dsc
- OvmfPkg/OvmfPkgX64.dsc
- OvmfPkg/OvmfXen.dsc

)

Therefore, please try dropping this patch, and modifying patch#26
instead -- the above module-scope override (for 5 DSC files) should be
squashed into patch#26, *and* the explanation I provided above should be
included in the commit message of patch#26.

... Correction: you have an independent bug in the series that affects
my above analysis. Namely, you *seem* to add the VmgExitLib dependency
to the "OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf"
library instance, in patch#26. That's where you modify the INF file. But
that's wrong: in patch#21 ("OvmfPkg/MemEncryptSevLib: Add support to
validate system RAM"), you add a VmgInit() call to the same library
instance, via the new file
"OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c".

The bug in that patch is clear from the fact that you introduce an
#include <Library/VmgExitLib.h> directive, but that's not mirrored by an
appropriate [LibraryClasses] change in the "DxeMemEncryptSevLib.inf"
file. (The other two lib instance INF files, "SecMemEncryptSevLib.inf"
and "PeiMemEncryptSevLib.inf" *are* modified as needed.)

So you even need to move some stuff from patch#26 to patch#21, and
*then* squash the above module-scope override (and explanation) into
patch#21.

A significant amount of work is needed on this series. I'll stop
reviewing RFC v2 here, because I don't want to look at the remaining
patches deeply as long as code movements etc are going to affect them.
Please post the next version -- assuming no other reviewer would like to
finish reviewing this version first!

Sounds good. What's your thought if I take out patch 1 - 9 from this RFC
series and submit them as non-RFC for the further review and acceptance
? The patch# 1-9 are basically prepatch before we get into SNP specific
bits.
More precisely, that means patches 1-8 (because patch#9 should be
replaced by the module-scope override, and also moved to just before
what is currently patch#21).

Other than that, I agree, this is a good idea. I've anyway thought that
the MdePkg stuff (5 patches) could be / should be merged up-front in
separation, and then the subsequent 3 patches for OvmfPkg are basically
refactoring. We can record the resultant commit range (8 commits) in
TianoCore#3275, and keep the BZ open for the rest of the work. So go
ahead please.

Thanks!
Laszlo




Thanks
Laszlo

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf | 4 ++
OvmfPkg/Library/VmgExitLib/VmgExitLib.inf | 7 +++
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 45 ++++++++++++++++++++
3 files changed, 56 insertions(+)

diff --git a/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf b/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
index e6f6ea7972..22435a0590 100644
--- a/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
+++ b/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
@@ -27,6 +27,7 @@
SecVmgExitVcHandler.c

[Packages]
+ MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
OvmfPkg/OvmfPkg.dec
UefiCpuPkg/UefiCpuPkg.dec
@@ -42,4 +43,7 @@
[FixedPcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress

+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
index c66c68726c..d3175c260e 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
@@ -27,6 +27,7 @@
PeiDxeVmgExitVcHandler.c

[Packages]
+ MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
OvmfPkg/OvmfPkg.dec
UefiCpuPkg/UefiCpuPkg.dec
@@ -37,4 +38,10 @@
DebugLib
LocalApicLib
MemEncryptSevLib
+ PcdLib

+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 24259060fd..01ac5d8c19 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -14,7 +14,10 @@
#include <Library/VmgExitLib.h>
#include <Register/Amd/Msr.h>
#include <Register/Intel/Cpuid.h>
+#include <IndustryStandard/Q35MchIch9.h>
+#include <IndustryStandard/I440FxPiix4.h>
#include <IndustryStandard/InstructionParsing.h>
+#include <Library/PcdLib.h>

#include "VmgExitVcHandler.h"

@@ -596,6 +599,40 @@ UnsupportedExit (
return Status;
}

+STATIC
+BOOLEAN
+IsPmbaBaseAddress (
+ IN UINTN Address
+ )
+{
+ UINT16 HostBridgeDevId;
+ UINTN Pmba;
+
+ //
+ // Query Host Bridge DID to determine platform type
+ //
+ HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);
+ switch (HostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+ break;
+ case INTEL_Q35_MCH_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
+ //
+ // Add the MMCONFIG base address to get the Pmba base access address
+ //
+ Pmba += FixedPcdGet64 (PcdPciExpressBaseAddress);
+ break;
+ default:
+ return FALSE;
+ }
+
+ // Round up the offset to page size
+ Pmba = Pmba & ~(SIZE_4KB - 1);
+
+ return (Address == Pmba);
+}
+
/**
Validate that the MMIO memory access is not to encrypted memory.

@@ -640,6 +677,14 @@ ValidateMmioMemory (
return 0;
}

+ //
+ // Allow PMBASE accesses (which will have the encryption bit set before
+ // AmdSevDxe runs in the DXE phase)
+ //
+ if (IsPmbaBaseAddress (Address)) {
+ return 0;
+ }
+
//
// Any state other than unencrypted is an error, issue a #GP.
//


[PATCH v2 2/2] SecurityPkg: Add support for RngDxe on AARCH64

Rebecca Cran <rebecca@...>
 

AARCH64 support has been added to BaseRngLib via the optional
ARMv8.5 FEAT_RNG.

Refactor RngDxe to support AARCH64, note support for it in the
VALID_ARCHITECTURES line of RngDxe.inf and enable it in SecurityPkg.dsc.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
SecurityPkg/SecurityPkg.dec | 2 +
SecurityPkg/SecurityPkg.dsc | 11 +-
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf | 24 ++-
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h | 0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h | 17 --
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h | 117 ++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c | 127 +++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c | 0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c | 45 +-----
SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c | 146 +++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c | 170 ++++++++------------
11 files changed, 483 insertions(+), 176 deletions(-)

diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index dfbbb0365a2b..a45104fe3e6c 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -297,6 +297,8 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationPass|0x0303100A|UINT32|0x00010030
gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationFail|0x0303100B|UINT32|0x00010031

+ gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm|{0}|VOID*|0x00010032
+
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## Image verification policy for OptionRom. Only following values are valid:<BR><BR>
# NOTE: Do NOT use 0x5 and 0x2 since it violates the UEFI specification and has been removed.<BR>
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index 12ccd1634941..bd4b810bce61 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -259,6 +259,12 @@ [Components]
[Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf

+[Components.IA32, Components.X64, Components.AARCH64]
+ #
+ # Random Number Generator
+ #
+ SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+
[Components.IA32, Components.X64]
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf

@@ -334,11 +340,6 @@ [Components.IA32, Components.X64]
SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.inf
SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.inf

- #
- # Random Number Generator
- #
- SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
-
#
# Opal Password solution
#
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
index 99d6f6b35fc2..f3300971993f 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
@@ -26,15 +26,22 @@ [Defines]
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
#

[Sources.common]
RngDxe.c
- RdRand.c
- RdRand.h
- AesCore.c
- AesCore.h
+ RngDxeInternals.h
+
+[Sources.IA32, Sources.X64]
+ Rand/RngDxe.c
+ Rand/RdRand.c
+ Rand/RdRand.h
+ Rand/AesCore.c
+ Rand/AesCore.h
+
+[Sources.AARCH64]
+ AArch64/RngDxe.c

[Packages]
MdePkg/MdePkg.dec
@@ -50,12 +57,19 @@ [LibraryClasses]
RngLib

[Guids]
+ gEfiRngAlgorithmSp80090Hash256Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG
+ gEfiRngAlgorithmSp80090Hmac256Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG
gEfiRngAlgorithmSp80090Ctr256Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG
+ gEfiRngAlgorithmX9313DesGuid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG
+ gEfiRngAlgorithmX931AesGuid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG
gEfiRngAlgorithmRaw ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG

[Protocols]
gEfiRngProtocolGuid ## PRODUCES

+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm ## CONSUMES
+
[Depex]
TRUE

diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
similarity index 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
similarity index 72%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
index 12ab1f34ec6d..072378e062e7 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
@@ -23,23 +23,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/TimerLib.h>
#include <Protocol/Rng.h>

-/**
- Calls RDRAND to fill a buffer of arbitrary size with random bytes.
-
- @param[in] Length Size of the buffer, in bytes, to fill with.
- @param[out] RandBuffer Pointer to the buffer to store the random result.
-
- @retval EFI_SUCCESS Random bytes generation succeeded.
- @retval EFI_NOT_READY Failed to request random bytes.
-
-**/
-EFI_STATUS
-EFIAPI
-RdRandGetBytes (
- IN UINTN Length,
- OUT UINT8 *RandBuffer
- );
-
/**
Generate high-quality entropy source through RDRAND.

diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
new file mode 100644
index 000000000000..2660ed5875e0
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
@@ -0,0 +1,117 @@
+/** @file
+ Function prototypes for UEFI Random Number Generator protocol support.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RNGDXE_INTERNALS_H_
+#define RNGDXE_INTERNALS_H_
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+ On output with a return code of EFI_SUCCESS, the size
+ in bytes of the data returned in RNGAlgorithmList. On output
+ with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
+ with one EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must not change across multiple
+ calls to the same driver. The first algorithm in the list
+ is the default algorithm for the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
+ @retval EFI_UNSUPPORTED The services is not supported by this driver.
+ @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a
+ hardware or firmware error.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetInfo (
+ IN EFI_RNG_PROTOCOL *This,
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ );
+
+/**
+ Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be NULL in which case the function will
+ use its default RNG algorithm.
+ @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
+ RNGValue. The driver shall return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random data available to satisfy the length
+ requested by RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ );
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+ On output with a return code of EFI_SUCCESS, the size
+ in bytes of the data returned in RNGAlgorithmList. On output
+ with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
+ with one EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must not change across multiple
+ calls to the same driver. The first algorithm in the list
+ is the default algorithm for the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithms (
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ );
+
+/**
+ Runs CPU RNG instruction to fill a buffer of arbitrary size with random bytes.
+
+ @param[in] Length Size of the buffer, in bytes, to fill with.
+ @param[out] RandBuffer Pointer to the buffer to store the random result.
+
+ @retval EFI_SUCCESS Random bytes generation succeeded.
+ @retval EFI_NOT_READY Failed to request random bytes.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ );
+
+#endif // RNGDXE_INTERNALS_H_
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
new file mode 100644
index 000000000000..2810a9eb94ad
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
@@ -0,0 +1,127 @@
+/** @file
+ RNG Driver to produce the UEFI Random Number Generator protocol.
+
+ The driver will use the RNDR instruction to produce random numbers.
+
+ RNG Algorithms defined in UEFI 2.4:
+ - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID
+ - EFI_RNG_ALGORITHM_RAW - Unsupported
+ - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID
+ - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID
+ - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/Rng.h>
+
+#include "RngDxeInternals.h"
+
+/**
+ Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be NULL in which case the function will
+ use its default RNG algorithm.
+ @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
+ RNGValue. The driver shall return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random data available to satisfy the length
+ requested by RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ )
+{
+ EFI_STATUS Status;
+
+ if ((RNGValueLength == 0) || (RNGValue == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (RNGAlgorithm == NULL) {
+ //
+ // Use the default RNG algorithm if RNGAlgorithm is NULL.
+ //
+ RNGAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
+ }
+
+ if (CompareGuid (RNGAlgorithm, PcdGetPtr (PcdCpuRngSupportedAlgorithm))) {
+ Status = RngGetBytes (RNGValueLength, RNGValue);
+ return Status;
+ }
+
+ //
+ // Other algorithms are unsupported by this driver.
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+ On output with a return code of EFI_SUCCESS, the size
+ in bytes of the data returned in RNGAlgorithmList. On output
+ with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
+ with one EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must not change across multiple
+ calls to the same driver. The first algorithm in the list
+ is the default algorithm for the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithms (
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ )
+{
+ UINTN RequiredSize;
+ EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm;
+
+ RequiredSize = sizeof (EFI_RNG_ALGORITHM);
+
+ if (*RNGAlgorithmListSize < RequiredSize) {
+ *RNGAlgorithmListSize = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
+
+ CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof (EFI_RNG_ALGORITHM));
+
+ *RNGAlgorithmListSize = RequiredSize;
+ return EFI_SUCCESS;
+}
+
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
similarity index 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
similarity index 71%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
index e7dd5ab18111..83025a47d43d 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
@@ -8,48 +8,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/RngLib.h>

-#include "RdRand.h"
#include "AesCore.h"
-
-/**
- Calls RDRAND to fill a buffer of arbitrary size with random bytes.
-
- @param[in] Length Size of the buffer, in bytes, to fill with.
- @param[out] RandBuffer Pointer to the buffer to store the random result.
-
- @retval EFI_SUCCESS Random bytes generation succeeded.
- @retval EFI_NOT_READY Failed to request random bytes.
-
-**/
-EFI_STATUS
-EFIAPI
-RdRandGetBytes (
- IN UINTN Length,
- OUT UINT8 *RandBuffer
- )
-{
- BOOLEAN IsRandom;
- UINT64 TempRand[2];
-
- while (Length > 0) {
- IsRandom = GetRandomNumber128 (TempRand);
- if (!IsRandom) {
- return EFI_NOT_READY;
- }
- if (Length >= sizeof (TempRand)) {
- WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]);
- RandBuffer += sizeof (UINT64);
- WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]);
- RandBuffer += sizeof (UINT64);
- Length -= sizeof (TempRand);
- } else {
- CopyMem (RandBuffer, TempRand, Length);
- Length = 0;
- }
- }
-
- return EFI_SUCCESS;
-}
+#include "RdRand.h"
+#include "RngDxeInternals.h"

/**
Creates a 128bit random value that is fully forward and backward prediction resistant,
@@ -92,7 +53,7 @@ RdRandGetSeed128 (
//
for (Index = 0; Index < 32; Index++) {
MicroSecondDelay (10);
- Status = RdRandGetBytes (16, RandByte);
+ Status = RngGetBytes (16, RandByte);
if (EFI_ERROR (Status)) {
return Status;
}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
new file mode 100644
index 000000000000..6b628a9f8bc6
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
@@ -0,0 +1,146 @@
+/** @file
+ RNG Driver to produce the UEFI Random Number Generator protocol.
+
+ The driver will use the new RDRAND instruction to produce high-quality, high-performance
+ entropy and random number.
+
+ RNG Algorithms defined in UEFI 2.4:
+ - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID - Supported
+ (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based DRBG)
+ - EFI_RNG_ALGORITHM_RAW - Supported
+ (Structuring RDRAND invocation can be guaranteed as high-quality entropy source)
+ - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported
+
+ Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RdRand.h"
+#include "RngDxeInternals.h"
+
+/**
+ Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be NULL in which case the function will
+ use its default RNG algorithm.
+ @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
+ RNGValue. The driver shall return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random data available to satisfy the length
+ requested by RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ )
+{
+ EFI_STATUS Status;
+
+ if ((RNGValueLength == 0) || (RNGValue == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_UNSUPPORTED;
+ if (RNGAlgorithm == NULL) {
+ //
+ // Use the default RNG algorithm if RNGAlgorithm is NULL.
+ //
+ RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
+ }
+
+ //
+ // NIST SP800-90-AES-CTR-256 supported by RDRAND
+ //
+ if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) {
+ Status = RngGetBytes (RNGValueLength, RNGValue);
+ return Status;
+ }
+
+ //
+ // The "raw" algorithm is intended to provide entropy directly
+ //
+ if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
+ //
+ // When a DRBG is used on the output of a entropy source,
+ // its security level must be at least 256 bits according to UEFI Spec.
+ //
+ if (RNGValueLength < 32) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
+ return Status;
+ }
+
+ //
+ // Other algorithms were unsupported by this driver.
+ //
+ return Status;
+}
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+ On output with a return code of EFI_SUCCESS, the size
+ in bytes of the data returned in RNGAlgorithmList. On output
+ with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
+ with one EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must not change across multiple
+ calls to the same driver. The first algorithm in the list
+ is the default algorithm for the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithms (
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ )
+{
+ UINTN RequiredSize;
+ EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm;
+
+ RequiredSize = 2 * sizeof (EFI_RNG_ALGORITHM);
+
+ if (*RNGAlgorithmListSize < RequiredSize) {
+ *RNGAlgorithmListSize = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
+
+ CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof (EFI_RNG_ALGORITHM));
+
+ // x86 platforms also support EFI_RNG_ALGORITHM_RAW via RDSEED
+ CopyMem(&RNGAlgorithmList[1], &gEfiRngAlgorithmRaw, sizeof (EFI_RNG_ALGORITHM));
+
+ *RNGAlgorithmListSize = RequiredSize;
+ return EFI_SUCCESS;
+}
+
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
index 13d3dbd0bfbe..b959c70536ea 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
@@ -1,34 +1,32 @@
/** @file
RNG Driver to produce the UEFI Random Number Generator protocol.

- The driver will use the new RDRAND instruction to produce high-quality, high-performance
- entropy and random number.
+ The driver uses CPU RNG instructions to produce high-quality,
+ high-performance entropy and random number.

RNG Algorithms defined in UEFI 2.4:
- - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID - Supported
- (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based DRBG)
- - EFI_RNG_ALGORITHM_RAW - Supported
- (Structuring RDRAND invocation can be guaranteed as high-quality entropy source)
- - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
- - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
- - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
- - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID
+ - EFI_RNG_ALGORITHM_RAW
+ - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID
+ - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID
+ - EFI_RNG_ALGORITHM_X9_31_3DES_GUID
+ - EFI_RNG_ALGORITHM_X9_31_AES_GUID

Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

-#include "RdRand.h"
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/RngLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/Rng.h>

-//
-// Supported RNG Algorithms list by this driver.
-//
-EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
- EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
- EFI_RNG_ALGORITHM_RAW
-};
+#include "RngDxeInternals.h"

/**
Returns information about the random number generation implementation.
@@ -62,106 +60,23 @@ RngGetInfo (
)
{
EFI_STATUS Status;
- UINTN RequiredSize;

if ((This == NULL) || (RNGAlgorithmListSize == NULL)) {
return EFI_INVALID_PARAMETER;
}

- RequiredSize = sizeof (mSupportedRngAlgorithms);
- if (*RNGAlgorithmListSize < RequiredSize) {
- Status = EFI_BUFFER_TOO_SMALL;
+ //
+ // Return algorithm list supported by driver.
+ //
+ if (RNGAlgorithmList != NULL) {
+ Status = ArchGetSupportedRngAlgorithms (RNGAlgorithmListSize, RNGAlgorithmList);
} else {
- //
- // Return algorithm list supported by driver.
- //
- if (RNGAlgorithmList != NULL) {
- CopyMem (RNGAlgorithmList, mSupportedRngAlgorithms, RequiredSize);
- Status = EFI_SUCCESS;
- } else {
- Status = EFI_INVALID_PARAMETER;
- }
+ Status = EFI_INVALID_PARAMETER;
}
- *RNGAlgorithmListSize = RequiredSize;

return Status;
}

-/**
- Produces and returns an RNG value using either the default or specified RNG algorithm.
-
- @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
- @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
- algorithm to use. May be NULL in which case the function will
- use its default RNG algorithm.
- @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
- RNGValue. The driver shall return exactly this numbers of bytes.
- @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
- resulting RNG value.
-
- @retval EFI_SUCCESS The RNG value was returned successfully.
- @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
- this driver.
- @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
- firmware error.
- @retval EFI_NOT_READY There is not enough random data available to satisfy the length
- requested by RNGValueLength.
- @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
-
-**/
-EFI_STATUS
-EFIAPI
-RngGetRNG (
- IN EFI_RNG_PROTOCOL *This,
- IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
- IN UINTN RNGValueLength,
- OUT UINT8 *RNGValue
- )
-{
- EFI_STATUS Status;
-
- if ((RNGValueLength == 0) || (RNGValue == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = EFI_UNSUPPORTED;
- if (RNGAlgorithm == NULL) {
- //
- // Use the default RNG algorithm if RNGAlgorithm is NULL.
- //
- RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
- }
-
- //
- // NIST SP800-90-AES-CTR-256 supported by RDRAND
- //
- if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) {
- Status = RdRandGetBytes (RNGValueLength, RNGValue);
- return Status;
- }
-
- //
- // The "raw" algorithm is intended to provide entropy directly
- //
- if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
- //
- // When a DRBG is used on the output of a entropy source,
- // its security level must be at least 256 bits according to UEFI Spec.
- //
- if (RNGValueLength < 32) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
- return Status;
- }
-
- //
- // Other algorithms were unsupported by this driver.
- //
- return Status;
-}
-
//
// The Random Number Generator (RNG) protocol
//
@@ -204,3 +119,44 @@ RngDriverEntry (

return Status;
}
+
+
+/**
+ Calls RDRAND to fill a buffer of arbitrary size with random bytes.
+
+ @param[in] Length Size of the buffer, in bytes, to fill with.
+ @param[out] RandBuffer Pointer to the buffer to store the random result.
+
+ @retval EFI_SUCCESS Random bytes generation succeeded.
+ @retval EFI_NOT_READY Failed to request random bytes.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ )
+{
+ BOOLEAN IsRandom;
+ UINT64 TempRand[2];
+
+ while (Length > 0) {
+ IsRandom = GetRandomNumber128 (TempRand);
+ if (!IsRandom) {
+ return EFI_NOT_READY;
+ }
+ if (Length >= sizeof (TempRand)) {
+ WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]);
+ RandBuffer += sizeof (UINT64);
+ WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]);
+ RandBuffer += sizeof (UINT64);
+ Length -= sizeof (TempRand);
+ } else {
+ CopyMem (RandBuffer, TempRand, Length);
+ Length = 0;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
--
2.26.2


[PATCH v2 1/2] MdePkg/BaseRngLib: Add support for ARMv8.5 RNG instructions

Rebecca Cran <rebecca@...>
 

Make BaseRngLib more generic by moving x86 specific functionality from
BaseRng.c into Rand/RdRand.c, and adding AArch64/Rndr.c, which supports
the optional ARMv8.5 RNG instructions RNDR and RNDRRS that are a part of
FEAT_RNG.

Add support for the optional ARMv8.5 RNDR and RNDRRS instructions that
are a part of FEAT_RNG to BaseLib, and add a function to read the ISAR0
register which indicates whether the CPU supports FEAT_RNG.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
MdePkg/MdePkg.dec | 9 +-
MdePkg/MdePkg.dsc | 4 +-
MdePkg/Library/BaseRngLib/BaseRngLib.inf | 23 +++-
MdePkg/Library/BaseRngLib/AArch64/ArmRng.h | 59 +++++++++
MdePkg/Library/BaseRngLib/BaseRngLibInternals.h | 79 +++++++++++
MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 139 ++++++++++++++++++++
MdePkg/Library/BaseRngLib/BaseRng.c | 87 ++++++------
MdePkg/Library/BaseRngLib/Rand/RdRand.c | 131 ++++++++++++++++++
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S | 31 +++++
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm | 30 +++++
MdePkg/Library/BaseRngLib/AArch64/ArmRng.S | 61 +++++++++
MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm | 64 +++++++++
MdePkg/Library/BaseRngLib/BaseRngLib.uni | 6 +-
13 files changed, 669 insertions(+), 54 deletions(-)

diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 8965e903e093..b49f88d8e18f 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -267,6 +267,11 @@ [LibraryClasses]
#
RegisterFilterLib|Include/Library/RegisterFilterLib.h

+[LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64]
+ ## @libraryclass Provides services to generate random number.
+ #
+ RngLib|Include/Library/RngLib.h
+
[LibraryClasses.IA32, LibraryClasses.X64]
## @libraryclass Abstracts both S/W SMI generation and detection.
##
@@ -288,10 +293,6 @@ [LibraryClasses.IA32, LibraryClasses.X64]
#
SmmPeriodicSmiLib|Include/Library/SmmPeriodicSmiLib.h

- ## @libraryclass Provides services to generate random number.
- #
- RngLib|Include/Library/RngLib.h
-
## @libraryclass Provides services to log the SMI handler registration.
SmiHandlerProfileLib|Include/Library/SmiHandlerProfileLib.h

diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index d363419006ea..a94959169b2f 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -145,6 +145,9 @@ [Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf
MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.inf

+[Components.IA32, Components.X64, Components.AARCH64]
+ MdePkg/Library/BaseRngLib/BaseRngLib.inf
+
[Components.IA32, Components.X64]
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
@@ -168,7 +171,6 @@ [Components.IA32, Components.X64]
MdePkg/Library/BaseS3StallLib/BaseS3StallLib.inf
MdePkg/Library/SmmMemLib/SmmMemLib.inf
MdePkg/Library/SmmIoLib/SmmIoLib.inf
- MdePkg/Library/BaseRngLib/BaseRngLib.inf
MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf
MdePkg/Library/SmiHandlerProfileLibNull/SmiHandlerProfileLibNull.inf
MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.inf b/MdePkg/Library/BaseRngLib/BaseRngLib.inf
index 31740751c69c..1fcceb941495 100644
--- a/MdePkg/Library/BaseRngLib/BaseRngLib.inf
+++ b/MdePkg/Library/BaseRngLib/BaseRngLib.inf
@@ -1,9 +1,10 @@
## @file
# Instance of RNG (Random Number Generator) Library.
#
-# BaseRng Library that uses CPU RdRand instruction access to provide
-# high-quality random numbers.
+# BaseRng Library that uses CPU RNG instructions (e.g. RdRand) to
+# provide random numbers.
#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -22,11 +23,25 @@ [Defines]
CONSTRUCTOR = BaseRngLibConstructor

#
-# VALID_ARCHITECTURES = IA32 X64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
#

-[Sources.Ia32, Sources.X64]
+[Sources]
BaseRng.c
+ BaseRngLibInternals.h
+
+[Sources.Ia32, Sources.X64]
+ Rand/RdRand.c
+
+[Sources.AARCH64]
+ AArch64/Rndr.c
+ AArch64/ArmRng.h
+
+ AArch64/ArmReadIdIsar0.S | GCC
+ AArch64/ArmRng.S | GCC
+
+ AArch64/ArmReadIdIsar0.asm | MSFT
+ AArch64/ArmRng.asm | MSFT

[Packages]
MdePkg/MdePkg.dec
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
new file mode 100644
index 000000000000..595bd87ba60c
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
@@ -0,0 +1,59 @@
+/** @file
+ Random number generator service that uses the RNDR instruction
+ to provide pseudorandom numbers.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ARM_RNG_H_
+#define ARM_RNG_H_
+
+/**
+ Generates a random number using RNDR.
+ Returns TRUE on success; FALSE on failure.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArmRndr (
+ OUT UINT64 *Rand
+ );
+
+/**
+ Generates a random number using RNDRRS.
+ Returns TRUE on success; FALSE on failure.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArmRndrrs (
+ OUT UINT64 *Rand
+ );
+
+/**
+ Reads the ID_AA64ISAR0 Register.
+
+ @return The contents of the ID_AA64ISAR0 register.
+
+**/
+UINT64
+EFIAPI
+ArmReadIdIsar0 (
+ VOID
+ );
+
+#endif /* ARM_RNG_H_ */
+
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
new file mode 100644
index 000000000000..338ba6ea5313
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
@@ -0,0 +1,79 @@
+/** @file
+
+ Architecture specific interface to RNG functionality.
+
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef BASE_RNGLIB_INTERNALS_H_
+
+/**
+ Generates a 16-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber16 (
+ OUT UINT16 *Rand
+ );
+
+/**
+ Generates a 32-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber32 (
+ OUT UINT32 *Rand
+ );
+
+/**
+ Generates a 64-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber64 (
+ OUT UINT64 *Rand
+ );
+
+/**
+ Checks whether the RNG instruction is supported.
+
+ @retval TRUE RNG instruction is supported.
+ @retval FALSE RNG instruction is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+ArchIsRngSupported (
+ VOID
+ );
+
+#if defined (MDE_CPU_AARCH64)
+
+// RNDR, Random Number
+#define RNDR S3_3_C2_C4_0
+#define RNDRRS S3_3_C2_C4_1
+
+#endif
+
+#endif // BASE_RNGLIB_INTERNALS_H_
diff --git a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
new file mode 100644
index 000000000000..d658ad2bea89
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
@@ -0,0 +1,139 @@
+/** @file
+ Random number generator service that uses the RNDR instruction
+ to provide pseudorandom numbers.
+
+ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
+
+#include "ArmRng.h"
+#include "BaseRngLibInternals.h"
+
+STATIC BOOLEAN mRndrSupported;
+
+//
+// Bit mask used to determine if RNDR instruction is supported.
+//
+#define RNDR_MASK ((UINT64)MAX_UINT16 << 60U)
+
+/**
+ The constructor function checks whether or not RNDR instruction is supported
+ by the host hardware.
+
+ The constructor function checks whether or not RNDR instruction is supported.
+ It will ASSERT() if RNDR instruction is not supported.
+ It will always return EFI_SUCCESS.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+BaseRngLibConstructor (
+ VOID
+ )
+{
+ UINT64 Isar0;
+ //
+ // Determine RNDR support by examining bits 63:60 of the ISAR0 register returned by
+ // MSR. A non-zero value indicates that the processor supports the RNDR instruction.
+ //
+ Isar0 = ArmReadIdIsar0 ();
+ ASSERT ((Isar0 & RNDR_MASK) != 0);
+
+ mRndrSupported = ((Isar0 & RNDR_MASK) != 0);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Generates a 16-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ UINT64 Rand64;
+
+ if (ArchGetRandomNumber64 (&Rand64)) {
+ *Rand = Rand64 & MAX_UINT16;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 32-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ UINT64 Rand64;
+
+ if (ArchGetRandomNumber64 (&Rand64)) {
+ *Rand = Rand64 & MAX_UINT32;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 64-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ return ArmRndr (Rand);
+}
+
+/**
+ Checks whether RNDR and RNDRRS (FEAT_RNG) are supported.
+
+ @retval TRUE RNDR and RNDRRS are supported.
+ @retval FALSE RNDR and RNDRRS are not supported.
+
+**/
+BOOLEAN
+EFIAPI
+ArchIsRngSupported (
+ VOID
+ )
+{
+ return mRndrSupported;
+}
diff --git a/MdePkg/Library/BaseRngLib/BaseRng.c b/MdePkg/Library/BaseRngLib/BaseRng.c
index 7ad7aec9d38f..5b63d8f7146b 100644
--- a/MdePkg/Library/BaseRngLib/BaseRng.c
+++ b/MdePkg/Library/BaseRngLib/BaseRng.c
@@ -1,8 +1,10 @@
/** @file
- Random number generator services that uses RdRand instruction access
- to provide high-quality random numbers.
+ Random number generator services that uses CPU RNG instructions to
+ provide random numbers.

+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
@@ -10,46 +12,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>

-//
-// Bit mask used to determine if RdRand instruction is supported.
-//
-#define RDRAND_MASK BIT30
+#include "BaseRngLibInternals.h"

//
// Limited retry number when valid random data is returned.
// Uses the recommended value defined in Section 7.3.17 of "Intel 64 and IA-32
-// Architectures Software Developer's Mannual".
+// Architectures Software Developer's Manual".
//
-#define RDRAND_RETRY_LIMIT 10
+#define GETRANDOM_RETRY_LIMIT 10

-/**
- The constructor function checks whether or not RDRAND instruction is supported
- by the host hardware.
-
- The constructor function checks whether or not RDRAND instruction is supported.
- It will ASSERT() if RDRAND instruction is not supported.
- It will always return RETURN_SUCCESS.
-
- @retval RETURN_SUCCESS The constructor always returns EFI_SUCCESS.
-
-**/
-RETURN_STATUS
-EFIAPI
-BaseRngLibConstructor (
- VOID
- )
-{
- UINT32 RegEcx;
-
- //
- // Determine RDRAND support by examining bit 30 of the ECX register returned by
- // CPUID. A value of 1 indicates that processor support RDRAND instruction.
- //
- AsmCpuid (1, 0, 0, &RegEcx, 0);
- ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
-
- return RETURN_SUCCESS;
-}

/**
Generates a 16-bit random number.
@@ -72,11 +43,19 @@ GetRandomNumber16 (

ASSERT (Rand != NULL);

+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ if (!ArchIsRngSupported ()) {
+ return FALSE;
+ }
+
//
// A loop to fetch a 16 bit random value with a retry count limit.
//
- for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {
- if (AsmRdRand16 (Rand)) {
+ for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
+ if (ArchGetRandomNumber16 (Rand)) {
return TRUE;
}
}
@@ -105,11 +84,19 @@ GetRandomNumber32 (

ASSERT (Rand != NULL);

+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ if (!ArchIsRngSupported ()) {
+ return FALSE;
+ }
+
//
// A loop to fetch a 32 bit random value with a retry count limit.
//
- for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {
- if (AsmRdRand32 (Rand)) {
+ for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
+ if (ArchGetRandomNumber32 (Rand)) {
return TRUE;
}
}
@@ -138,11 +125,19 @@ GetRandomNumber64 (

ASSERT (Rand != NULL);

+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ if (!ArchIsRngSupported ()) {
+ return FALSE;
+ }
+
//
// A loop to fetch a 64 bit random value with a retry count limit.
//
- for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {
- if (AsmRdRand64 (Rand)) {
+ for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
+ if (ArchGetRandomNumber64 (Rand)) {
return TRUE;
}
}
@@ -169,6 +164,14 @@ GetRandomNumber128 (
{
ASSERT (Rand != NULL);

+ if (Rand == NULL) {
+ return FALSE;
+ }
+
+ if (!ArchIsRngSupported ()) {
+ return FALSE;
+ }
+
//
// Read first 64 bits
//
diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
new file mode 100644
index 000000000000..09fb875ac3f9
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
@@ -0,0 +1,131 @@
+/** @file
+ Random number generator services that uses RdRand instruction access
+ to provide high-quality random numbers.
+
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#include "BaseRngLibInternals.h"
+
+//
+// Bit mask used to determine if RdRand instruction is supported.
+//
+#define RDRAND_MASK BIT30
+
+
+STATIC BOOLEAN mRdRandSupported;
+
+/**
+ The constructor function checks whether or not RDRAND instruction is supported
+ by the host hardware.
+
+ The constructor function checks whether or not RDRAND instruction is supported.
+ It will ASSERT() if RDRAND instruction is not supported.
+ It will always return EFI_SUCCESS.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+BaseRngLibConstructor (
+ VOID
+ )
+{
+ UINT32 RegEcx;
+
+ //
+ // Determine RDRAND support by examining bit 30 of the ECX register returned by
+ // CPUID. A value of 1 indicates that processor support RDRAND instruction.
+ //
+ AsmCpuid (1, 0, 0, &RegEcx, 0);
+ ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
+
+ mRdRandSupported = ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Generates a 16-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ return AsmRdRand16 (Rand);
+}
+
+/**
+ Generates a 32-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ return AsmRdRand32 (Rand);
+}
+
+/**
+ Generates a 64-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ return AsmRdRand64 (Rand);
+}
+
+/**
+ Checks whether RDRAND is supported.
+
+ @retval TRUE RDRAND is supported.
+ @retval FALSE RDRAND is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+ArchIsRngSupported (
+ VOID
+ )
+{
+ /*
+ Existing software depends on this always returning TRUE, so for
+ now hard-code it.
+
+ return mRdRandSupported;
+ */
+ return TRUE;
+}
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S
new file mode 100644
index 000000000000..82a00d362212
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S
@@ -0,0 +1,31 @@
+#------------------------------------------------------------------------------
+#
+# ArmReadIdIsar0() for AArch64
+#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#------------------------------------------------------------------------------
+
+.text
+.p2align 2
+GCC_ASM_EXPORT(ArmReadIdIsar0)
+
+#/**
+# Reads the ID_AA64ISAR0 Register.
+#
+# @return The contents of the ID_AA64ISAR0 register.
+#
+#**/
+#UINT64
+#EFIAPI
+#ArmReadIdIsar0 (
+# VOID
+# );
+#
+ASM_PFX(ArmReadIdIsar0):
+ mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register
+ ret
+
+
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm
new file mode 100644
index 000000000000..1d9f9a808c0c
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm
@@ -0,0 +1,30 @@
+;------------------------------------------------------------------------------
+;
+; ArmReadIdIsar0() for AArch64
+;
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+ EXPORT ArmReadIdIsar0
+ AREA BaseLib_LowLevel, CODE, READONLY
+
+;/**
+; Reads the ID_AA64ISAR0 Register.
+;
+; @return The contents of the ID_AA64ISAR0 register.
+;
+;**/
+;UINT64
+;EFIAPI
+;ArmReadIdIsar0 (
+; VOID
+; );
+;
+ArmReadIdIsar0
+ mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register
+ ret
+
+ END
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
new file mode 100644
index 000000000000..4b9898dadc52
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
@@ -0,0 +1,61 @@
+#------------------------------------------------------------------------------
+#
+# ArmRndr() and ArmRndrrs() for AArch64
+#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#------------------------------------------------------------------------------
+
+#include "BaseRngLibInternals.h"
+
+.text
+.p2align 2
+GCC_ASM_EXPORT(ArmRndr)
+GCC_ASM_EXPORT(ArmRndrrs)
+
+#/**
+# Generates a random number using RNDR.
+# Returns TRUE on success; FALSE on failure.
+#
+# @param[out] Rand Buffer pointer to store the 64-bit random value.
+#
+# @retval TRUE Random number generated successfully.
+# @retval FALSE Failed to generate the random number.
+#
+#**/
+#BOOLEAN
+#EFIAPI
+#ArmRndr (
+# OUT UINT64 *Rand
+# );
+#
+ASM_PFX(ArmRndr):
+ mrs x1, RNDR
+ str x1, [x0]
+ cset x0, ne // RNDR sets NZCV to 0b0100 on failure
+ ret
+
+
+#/**
+# Generates a random number using RNDRRS
+# Returns TRUE on success; FALSE on failure.
+#
+# @param[out] Rand Buffer pointer to store the 64-bit random value.
+#
+# @retval TRUE Random number generated successfully.
+# @retval FALSE Failed to generate the random number.
+#
+#**/
+#BOOLEAN
+#EFIAPI
+#ArmRndrrs (
+# OUT UINT64 *Rand
+# );
+#
+ASM_PFX(ArmRndrrs):
+ mrs x1, RNDRRS
+ str x1, [x0]
+ cset x0, ne // RNDRRS sets NZCV to 0b0100 on failure
+ ret
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm
new file mode 100644
index 000000000000..e3feb56adbcf
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------
+;
+; ArmRndr() and ArmRndrrs() for AArch64
+;
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+#include "BaseRngLibInternals.h"
+
+ EXPORT ArmRndr
+ EXPORT ArmRndrrs
+ AREA BaseLib_LowLevel, CODE, READONLY
+
+
+;/**
+; Generates a random number using RNDR.
+; Returns TRUE on success; FALSE on failure.
+;
+; @param[out] Rand Buffer pointer to store the 64-bit random value.
+;
+; @retval TRUE Random number generated successfully.
+; @retval FALSE Failed to generate the random number.
+;
+;**/
+;BOOLEAN
+;EFIAPI
+;ArmRndr (
+; OUT UINT64 *Rand
+; );
+;
+ArmRndr
+ mrs x1, RNDR
+ str x1, [x0]
+ cset x0, ne // RNDR sets NZCV to 0b0100 on failure
+ ret
+
+ END
+
+;/**
+; Generates a random number using RNDRRS.
+; Returns TRUE on success; FALSE on failure.
+;
+; @param[out] Rand Buffer pointer to store the 64-bit random value.
+;
+; @retval TRUE Random number generated successfully.
+; @retval FALSE Failed to generate the random number.
+;
+;**/
+;BOOLEAN
+;EFIAPI
+;ArmRndrrs (
+; OUT UINT64 *Rand
+; );
+;
+ArmRndrrs
+ mrs x1, RNDRRS
+ str x1, [x0]
+ cset x0, ne // RNDRRS sets NZCV to 0b0100 on failure
+ ret
+
+ END
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.uni b/MdePkg/Library/BaseRngLib/BaseRngLib.uni
index f3ed954c5209..de5d4f9dd869 100644
--- a/MdePkg/Library/BaseRngLib/BaseRngLib.uni
+++ b/MdePkg/Library/BaseRngLib/BaseRngLib.uni
@@ -1,8 +1,8 @@
// /** @file
// Instance of RNG (Random Number Generator) Library.
//
-// BaseRng Library that uses CPU RdRand instruction access to provide
-// high-quality random numbers.
+// BaseRng Library that uses CPU RNG instructions to provide
+// random numbers.
//
// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
//
@@ -13,5 +13,5 @@

#string STR_MODULE_ABSTRACT #language en-US "Instance of RNG Library"

-#string STR_MODULE_DESCRIPTION #language en-US "BaseRng Library that uses CPU RdRand instruction access to provide high-quality random numbers"
+#string STR_MODULE_DESCRIPTION #language en-US "BaseRng Library that uses CPU RNG instructions to provide random numbers"

--
2.26.2


[PATCH v2 0/2] MdePkg,SecurityPkg: Add support to RngDxe and BaseRngLib for AARCH64 RNDR

Rebecca Cran <rebecca@...>
 

Update MdePkg BaseRngLib and SecurityPkg RngDxe to add support for
the AARCH64 RNDR instruction.

Changes from v1 to v2:

o Added a PCD, gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm to
specify which algorighm the platform supports.
o Moved ArmRndr() and ArmRndrrs() into BaseRngLib.
o Added Doxygen headers.
o Merged X64 and AARCH64 *GetBytes functions into a single RngGetBytes
function.
o Updated constructors to return EFI_STATUS instead of RETURN_STATUS.
o Added ArchIsRngSupported function that gets called before each call to
ArchGetRandomNumber*.

Rebecca Cran (2):
MdePkg/BaseRngLib: Add support for ARMv8.5 RNG instructions
SecurityPkg: Add support for RngDxe on AARCH64

MdePkg/MdePkg.dec | 9 +-
SecurityPkg/SecurityPkg.dec | 2 +
MdePkg/MdePkg.dsc | 4 +-
SecurityPkg/SecurityPkg.dsc | 11 +-
MdePkg/Library/BaseRngLib/BaseRngLib.inf | 23 ++-
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf | 24 ++-
MdePkg/Library/BaseRngLib/AArch64/ArmRng.h | 59 +++++++
MdePkg/Library/BaseRngLib/BaseRngLibInternals.h | 79 +++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h | 0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h | 17 --
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h | 117 ++++++++++++++
MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 139 ++++++++++++++++
MdePkg/Library/BaseRngLib/BaseRng.c | 87 +++++-----
MdePkg/Library/BaseRngLib/Rand/RdRand.c | 131 +++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c | 127 +++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c | 0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c | 45 +-----
SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c | 146 +++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c | 170 ++++++++------------
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S | 31 ++++
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm | 30 ++++
MdePkg/Library/BaseRngLib/AArch64/ArmRng.S | 61 +++++++
MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm | 64 ++++++++
MdePkg/Library/BaseRngLib/BaseRngLib.uni | 6 +-
24 files changed, 1152 insertions(+), 230 deletions(-)
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
create mode 100644 MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h (100%)
rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h (72%)
create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/Rndr.c
create mode 100644 MdePkg/Library/BaseRngLib/Rand/RdRand.c
create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c (100%)
rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c (71%)
create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
create mode 100644 MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm

--
2.26.2


Re: [PATCH RFC v2 09/28] OvmfPkg/VmgExitLib: Allow PMBASE register access in Dxe phase

Brijesh Singh
 

On 5/6/21 9:08 AM, Laszlo Ersek wrote:
On 04/30/21 13:51, Brijesh Singh wrote:
BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3275&;data=04%7C01%7Cbrijesh.singh%40amd.com%7C01d3e5c5268043c18bdf08d910987251%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637559069206222390%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=CN2hZrjsKzfSqMAxcQLtoHTUqBOlZmdDEO9vY9XT%2FTQ%3D&amp;reserved=0

Commit 85b8eac59b8c5bd9c7eb9afdb64357ce1aa2e803 added support to ensure
that MMIO is only performed against the un-encrypted memory. If MMIO
is performed against encrypted memory, a #GP is raised.

The VmgExitLib library depends on ApicTimerLib to get the APIC base
address so that it can exclude the APIC range from the un-encrypted
check. The OvmfPkg provides ApicTimerLib for the DXE phase. The
constructor AcpiTimerLibConstructor() used in the ApicTimerLib uses
the PciRead to get the PMBASE register. The PciRead() will cause an
MMIO access.

The AmdSevDxe driver clears the memory encryption attribute from the
MMIO ranges. However, if VmgExitLib is linked to AmdSevDxe driver then the
AcpiTimerLibConstructor() will be called before AmdSevDxe driver can
clear the encryption attributes for the MMIO regions.

Exclude the PMBASE register from the encrypted check so that we
can link VmgExitLib to the MemEncryptSevLib; which gets linked to
AmdSevDxe driver.
The above explanation is inexact. There are several typos ("APIC" is
incorrect, "ACPI" would be correct, for the TimerLib instance in
question), but that's really just a side observation.

The precise explanation is the following library instance dependency
chain:

OvmfPkg/AmdSevDxe/AmdSevDxe.inf
-----> MemEncryptSevLib class
-----> "OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf" instance
-[*]-> VmgExitLib class
-----> "OvmfPkg/Library/VmgExitLib/VmgExitLib.inf" instance
-----> LocalApicLib class
-----> "UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf" instance
-----> TimerLib class
-----> "OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf" instance
-----> PciLib class
-----> "OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf" instance
-----> PciExpressLib class
-----> "MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf" instance

The link (or dependency) marked with [*] is introduced in patch #26
("OvmfPkg/MemEncryptSevLib: Change the page state in the RMP table").
That's the change that triggers the symptom. (In combination with you
testing on Q35, because on i440fx, the DxePciLibI440FxQ35 lib instance
accesses PCI config space via the 0xCF8, 0xCFC IO Ports, and those are
unaffected by SEV-ES.)

The symptom is somewhat "unjustified", because at the end of the series,
the AmdSevDxe driver makes no calls to actual TimerLib APIs (I checked
-- I disassembled the "AmdSevDxe.debug" file with "objdump -S", and
there is no call to any API declared in the "TimerLib.h" class header).
However, the ECAM (MMCONFIG) access is still triggered, because the
AcpiTimerLibConstructor() function, in
"OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c", is the constructor for
the "OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf" instance, and
AcpiTimerLibConstructor() calls PciRead32().

If you check the "OvmfPkg/OvmfPkgX64.dsc" file, you'll find that the
PciLib class is resolved to
"MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf" by default, and to
"OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf" for the
following module types:

- DXE_DRIVER,
- DXE_RUNTIME_DRIVER,
- SMM_CORE,
- DXE_SMM_DRIVER,
- UEFI_DRIVER,
- UEFI_APPLICATION.

The consequence is that modules strictly after the DXE_CORE get
dynamically enabled extended config space access (ECAM) on Q35 via the
PciLib class, whereas all modules strictly before the DXE_CORE, and the
DXE_CORE itself, are restricted to normal config space (IO Ports 0xCF8 /
0xCFC) via the PciLib class.

AmdSevDxe is a DXE_DRIVER, so it used to get DxePciLibI440FxQ35 as well.

The solution should be simple. In the AmdSevDxe driver specifically, we
need no access to extended PCI config space. Accessing normal PCI config
space, via IO Ports 0xCF8 / 0xCFC, should suffice. That can be achieved
with the following module-scope override:
Thanks Laszlo, I was not aware of the module-scope override. I will go
with this approach and make sure it works after the inclusion of the
VmgExitLib.



diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 8d9a0a077601..45a02b236633 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -966,7 +966,10 @@ [Components]
!endif

OvmfPkg/PlatformDxe/Platform.inf
- OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+ OvmfPkg/AmdSevDxe/AmdSevDxe.inf {
+ <LibraryClasses>
+ PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+ }
OvmfPkg/IoMmuDxe/IoMmuDxe.inf
OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
(

For consistency, all DSC files that include
"OvmfPkg/AmdSevDxe/AmdSevDxe.inf" should be modified similarly:

- OvmfPkg/AmdSev/AmdSevX64.dsc
- OvmfPkg/Bhyve/BhyveX64.dsc
- OvmfPkg/OvmfPkgIa32X64.dsc
- OvmfPkg/OvmfPkgX64.dsc
- OvmfPkg/OvmfXen.dsc

)

Therefore, please try dropping this patch, and modifying patch#26
instead -- the above module-scope override (for 5 DSC files) should be
squashed into patch#26, *and* the explanation I provided above should be
included in the commit message of patch#26.

... Correction: you have an independent bug in the series that affects
my above analysis. Namely, you *seem* to add the VmgExitLib dependency
to the "OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf"
library instance, in patch#26. That's where you modify the INF file. But
that's wrong: in patch#21 ("OvmfPkg/MemEncryptSevLib: Add support to
validate system RAM"), you add a VmgInit() call to the same library
instance, via the new file
"OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c".

The bug in that patch is clear from the fact that you introduce an
#include <Library/VmgExitLib.h> directive, but that's not mirrored by an
appropriate [LibraryClasses] change in the "DxeMemEncryptSevLib.inf"
file. (The other two lib instance INF files, "SecMemEncryptSevLib.inf"
and "PeiMemEncryptSevLib.inf" *are* modified as needed.)

So you even need to move some stuff from patch#26 to patch#21, and
*then* squash the above module-scope override (and explanation) into
patch#21.

A significant amount of work is needed on this series. I'll stop
reviewing RFC v2 here, because I don't want to look at the remaining
patches deeply as long as code movements etc are going to affect them.
Please post the next version -- assuming no other reviewer would like to
finish reviewing this version first!

Sounds good. What's your thought if I take out patch 1 - 9 from this RFC
series and submit them as non-RFC for the further review and acceptance
? The patch# 1-9 are basically prepatch before we get into SNP specific
bits.


Thanks
Laszlo

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf | 4 ++
OvmfPkg/Library/VmgExitLib/VmgExitLib.inf | 7 +++
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 45 ++++++++++++++++++++
3 files changed, 56 insertions(+)

diff --git a/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf b/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
index e6f6ea7972..22435a0590 100644
--- a/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
+++ b/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
@@ -27,6 +27,7 @@
SecVmgExitVcHandler.c

[Packages]
+ MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
OvmfPkg/OvmfPkg.dec
UefiCpuPkg/UefiCpuPkg.dec
@@ -42,4 +43,7 @@
[FixedPcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress

+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
index c66c68726c..d3175c260e 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
@@ -27,6 +27,7 @@
PeiDxeVmgExitVcHandler.c

[Packages]
+ MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
OvmfPkg/OvmfPkg.dec
UefiCpuPkg/UefiCpuPkg.dec
@@ -37,4 +38,10 @@
DebugLib
LocalApicLib
MemEncryptSevLib
+ PcdLib

+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 24259060fd..01ac5d8c19 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -14,7 +14,10 @@
#include <Library/VmgExitLib.h>
#include <Register/Amd/Msr.h>
#include <Register/Intel/Cpuid.h>
+#include <IndustryStandard/Q35MchIch9.h>
+#include <IndustryStandard/I440FxPiix4.h>
#include <IndustryStandard/InstructionParsing.h>
+#include <Library/PcdLib.h>

#include "VmgExitVcHandler.h"

@@ -596,6 +599,40 @@ UnsupportedExit (
return Status;
}

+STATIC
+BOOLEAN
+IsPmbaBaseAddress (
+ IN UINTN Address
+ )
+{
+ UINT16 HostBridgeDevId;
+ UINTN Pmba;
+
+ //
+ // Query Host Bridge DID to determine platform type
+ //
+ HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);
+ switch (HostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+ break;
+ case INTEL_Q35_MCH_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
+ //
+ // Add the MMCONFIG base address to get the Pmba base access address
+ //
+ Pmba += FixedPcdGet64 (PcdPciExpressBaseAddress);
+ break;
+ default:
+ return FALSE;
+ }
+
+ // Round up the offset to page size
+ Pmba = Pmba & ~(SIZE_4KB - 1);
+
+ return (Address == Pmba);
+}
+
/**
Validate that the MMIO memory access is not to encrypted memory.

@@ -640,6 +677,14 @@ ValidateMmioMemory (
return 0;
}

+ //
+ // Allow PMBASE accesses (which will have the encryption bit set before
+ // AmdSevDxe runs in the DXE phase)
+ //
+ if (IsPmbaBaseAddress (Address)) {
+ return 0;
+ }
+
//
// Any state other than unencrypted is an error, issue a #GP.
//


Re: [PATCH v1 0/5] Dot graph generator for PPTT

Joey Gouly
 

From: Joey Gouly <joey.gouly@arm.com>
Sent: 07 May 2021 11:37

The changes can be seen at https://github.com/jgouly/edk2/tree/1484_pptt_dot_graph_v1
The CI on github showed some coding style issues with this series. I will fix those locally but wait for more review comments before I send a v2.

Thanks,
Joey


[PATCH v1 2/5] ShellPkg: add a helper function for getting a new file name

Joey Gouly
 

From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>

Bugzilla: 3378 (https://bugzilla.tianocore.org/show_bug.cgi?id=3378)

This new helper will not overwrite existing files, by appending a number
to the end of the filename.

Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h | 25 +++++-
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c | 80 ++++++++++++++++----
2 files changed, 91 insertions(+), 14 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h
index d5b95f5ee707de18be1879b3cd235d6c5db11d9f..ae8a67b7681033d66d068341ae489ded67de8b44 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h
@@ -1,12 +1,13 @@
/** @file
Header file for AcpiView

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#ifndef ACPIVIEW_H_
#define ACPIVIEW_H_
+#include <Library/ShellLib.h>

/**
A macro to define the max file name length
@@ -23,6 +24,28 @@
**/
#define RSDP_LENGTH_OFFSET 20

+/**
+ This function finds a filename not already used by adding a number in between
+ the BaseFileName and the extension.
+
+ Make sure the buffer FileName is big enough before calling the function. A
+ size of MAX_FILE_NAME_LEN is recommended.
+
+ @param [in] BaseFileName Start of the desired file name.
+ @param [in] Extension Extension of the desired file name
+ (without '.').
+ @param [in, out] FileName Preallocated buffer for the returned file
+ name.
+ @param [in] FileNameBufferLen Size of FileName buffer..
+**/
+EFI_STATUS
+GetNewFileName (
+ IN CONST CHAR16* BaseFileName,
+ IN CONST CHAR16* Extension,
+ IN OUT CHAR16* FileName,
+ IN UINT32 FileNameBufferLen
+ );
+
/**
This function resets the ACPI table error counter to Zero.
**/
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
index a4242ba9d99b05d07c829520c4011439445aadb0..db7b2e2a30525cc85a333b93f5eb97ec3a517b37 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
@@ -27,8 +27,55 @@
#include "Arm/SbbrValidator.h"
#endif

-STATIC UINT32 mTableCount;
-STATIC UINT32 mBinTableCount;
+STATIC UINT32 mTableCount;
+
+/**
+ This function finds a filename not already used by adding a number in between
+ The BaseFileName and the extension.
+
+ Make sure the buffer FileName is big enough before calling the function. A
+ size of MAX_FILE_NAME_LEN is recommended.
+
+ @param [in] BaseFileName Start of the desired file name.
+ @param [in] Extension Extension of the desired file name
+ (without '.').
+ @param [in, out] FileName Preallocated buffer for the returned file
+ name.
+ @param [in] FileNameBufferLen Size of FileName buffer..
+**/
+EFI_STATUS
+GetNewFileName (
+ IN CONST CHAR16* BaseFileName,
+ IN CONST CHAR16* Extension,
+ IN OUT CHAR16* FileName,
+ IN UINT32 FileNameBufferLen
+ )
+{
+ UINT16 Index;
+ EFI_STATUS Status;
+ SHELL_FILE_HANDLE tmpFileHandle;
+ for (Index = 0; Index <= 99; Index++) {
+ UnicodeSPrint(
+ FileName,
+ FileNameBufferLen,
+ L"%s%02d.%s",
+ BaseFileName,
+ Index,
+ Extension
+ );
+ Status = ShellOpenFileByName (
+ FileName,
+ &tmpFileHandle,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ if (Status == EFI_NOT_FOUND) {
+ return EFI_SUCCESS;
+ }
+ ShellCloseFile (&tmpFileHandle);
+ }
+ return EFI_OUT_OF_RESOURCES;
+}

/**
This function dumps the ACPI table to a file.
@@ -46,19 +93,27 @@ DumpAcpiTableToFile (
IN CONST UINTN Length
)
{
- CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
- UINTN TransferBytes;
- SELECTED_ACPI_TABLE *SelectedTable;
+ CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
+ UINTN TransferBytes;
+ EFI_STATUS Status;
+ SELECTED_ACPI_TABLE* SelectedTable;

GetSelectedAcpiTable (&SelectedTable);

- UnicodeSPrint (
- FileNameBuffer,
- sizeof (FileNameBuffer),
- L".\\%s%04d.bin",
- SelectedTable->Name,
- mBinTableCount++
- );
+ Status = GetNewFileName (
+ SelectedTable->Name,
+ L"bin",
+ FileNameBuffer,
+ sizeof (FileNameBuffer)
+ );
+ if (EFI_ERROR (Status)) {
+ Print (
+ L"Error: Could not open bin file for %s table:\n"
+ L"Could not get a file name.",
+ SelectedTable->Name
+ );
+ return FALSE;
+ }

Print (L"Dumping ACPI table to : %s ... ", FileNameBuffer);

@@ -207,7 +262,6 @@ AcpiView (

// Reset Table counts
mTableCount = 0;
- mBinTableCount = 0;

// Reset The error/warning counters
ResetErrorCount ();
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 1/5] ShellPkg: Replace 'Trace' parameter with 'ParseFlags'

Joey Gouly
 

From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>

Bugzilla: 3378 (https://bugzilla.tianocore.org/show_bug.cgi?id=3378)

This is preparation for adding a second flag to the parsers.

Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h | 77 +++++++++++---------
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h | 6 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c | 20 ++---
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c | 28 ++++---
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c | 10 +--
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Facs/FacsParser.c | 10 +--
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c | 27 ++++---
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c | 47 +++++++-----
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c | 10 +--
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c | 8 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c | 10 +--
20 files changed, 179 insertions(+), 146 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
index 0b7726b9d5807ad2f5c5447408c4c5451718938b..b078c0b99335ba28f7589cac6b0a4190d9a6c3b5 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
@@ -1,7 +1,7 @@
/** @file
Header file for ACPI parser

- Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

@@ -16,6 +16,16 @@
/// that allows us to process the log options.
#define RSDP_TABLE_INFO SIGNATURE_32('R', 'S', 'D', 'P')

+/**
+ Flags for the parser.
+*/
+#define PARSE_FLAGS_TRACE BIT0
+
+/**
+ Helper macros to test parser flags.
+*/
+#define IS_TRACE_FLAG_SET(Flags) (((Flags) & PARSE_FLAGS_TRACE) != 0)
+
/**
This function increments the ACPI table error counter.
**/
@@ -489,7 +499,7 @@ ParseAcpiAest (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -497,7 +507,7 @@ ParseAcpiAest (
VOID
EFIAPI
ParseAcpiBgrt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -510,7 +520,7 @@ ParseAcpiBgrt (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -518,7 +528,7 @@ ParseAcpiBgrt (
VOID
EFIAPI
ParseAcpiDbg2 (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -531,7 +541,7 @@ ParseAcpiDbg2 (
For the DSDT table only the ACPI header fields are parsed and
traced.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -539,7 +549,7 @@ ParseAcpiDbg2 (
VOID
EFIAPI
ParseAcpiDsdt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -552,7 +562,7 @@ ParseAcpiDsdt (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -560,7 +570,7 @@ ParseAcpiDsdt (
VOID
EFIAPI
ParseAcpiFacs (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -573,7 +583,7 @@ ParseAcpiFacs (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -581,7 +591,7 @@ ParseAcpiFacs (
VOID
EFIAPI
ParseAcpiFadt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -598,7 +608,7 @@ ParseAcpiFadt (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -606,7 +616,7 @@ ParseAcpiFadt (
VOID
EFIAPI
ParseAcpiGtdt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -653,7 +663,7 @@ ParseAcpiHmat (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -661,7 +671,7 @@ ParseAcpiHmat (
VOID
EFIAPI
ParseAcpiIort (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -682,7 +692,7 @@ ParseAcpiIort (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -690,7 +700,7 @@ ParseAcpiIort (
VOID
EFIAPI
ParseAcpiMadt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -703,7 +713,7 @@ ParseAcpiMadt (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -711,7 +721,7 @@ ParseAcpiMadt (
VOID
EFIAPI
ParseAcpiMcfg (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -746,7 +756,7 @@ ParseAcpiPcct (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -754,7 +764,7 @@ ParseAcpiPcct (
VOID
EFIAPI
ParseAcpiPptt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -769,7 +779,7 @@ ParseAcpiPptt (
This function also performs a RAW dump of the ACPI table and
validates the checksum.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -777,7 +787,7 @@ ParseAcpiPptt (
VOID
EFIAPI
ParseAcpiRsdp (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -793,7 +803,8 @@ ParseAcpiRsdp (
- Relative distance from System Locality at i*N+j is same as
j*N+i

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to
+ do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -801,7 +812,7 @@ ParseAcpiRsdp (
VOID
EFIAPI
ParseAcpiSlit (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -814,7 +825,7 @@ ParseAcpiSlit (

This function also performs validations of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -822,7 +833,7 @@ ParseAcpiSlit (
VOID
EFIAPI
ParseAcpiSpcr (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -841,7 +852,7 @@ ParseAcpiSpcr (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -849,7 +860,7 @@ ParseAcpiSpcr (
VOID
EFIAPI
ParseAcpiSrat (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -862,7 +873,7 @@ ParseAcpiSrat (
For the SSDT table only the ACPI header fields are
parsed and traced.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -870,7 +881,7 @@ ParseAcpiSrat (
VOID
EFIAPI
ParseAcpiSsdt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -882,7 +893,7 @@ ParseAcpiSsdt (

This function also performs validation of the XSDT table.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -890,7 +901,7 @@ ParseAcpiSsdt (
VOID
EFIAPI
ParseAcpiXsdt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
index 0ebf79fb653ae3a8190273aee452723c6213eb58..94ce0a4860e5296d99d398480655a8013ab0f240 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
@@ -1,7 +1,7 @@
/** @file
Header file for ACPI table parser

- Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

@@ -20,7 +20,7 @@
/**
A function that parses the ACPI table.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -28,7 +28,7 @@
typedef
VOID
(EFIAPI * PARSE_ACPI_TABLE_PROC) (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
index 4b618f131eac3957f4070a95e06c8cd157c3223c..ecb5d6339af37397c6ba1ba4c8f0d42a95811bf6 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
@@ -1,7 +1,7 @@
/** @file
ACPI table parser

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Glossary:
@@ -183,7 +183,7 @@ ProcessAcpiTable (
)
{
EFI_STATUS Status;
- BOOLEAN Trace;
+ UINT8 ParseFlags;
CONST UINT32* AcpiTableSignature;
CONST UINT32* AcpiTableLength;
CONST UINT8* AcpiTableRevision;
@@ -197,13 +197,13 @@ ProcessAcpiTable (
&AcpiTableRevision
);

- Trace = ProcessTableReportOptions (
- *AcpiTableSignature,
- Ptr,
- *AcpiTableLength
- );
+ ParseFlags = ProcessTableReportOptions (
+ *AcpiTableSignature,
+ Ptr,
+ *AcpiTableLength
+ );

- if (Trace) {
+ if (IS_TRACE_FLAG_SET (ParseFlags)) {
DumpRaw (Ptr, *AcpiTableLength);

// Do not process the ACPI table any further if the table length read
@@ -236,14 +236,14 @@ ProcessAcpiTable (
Status = GetParser (*AcpiTableSignature, &ParserProc);
if (EFI_ERROR (Status)) {
// No registered parser found, do default handling.
- if (Trace) {
+ if (IS_TRACE_FLAG_SET (ParseFlags)) {
DumpAcpiHeader (Ptr);
}
return;
}

ParserProc (
- Trace,
+ ParseFlags,
Ptr,
*AcpiTableLength,
*AcpiTableRevision
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
index 9a5b013fb234e2a09a12a690607b5b871dffde72..a4242ba9d99b05d07c829520c4011439445aadb0 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
@@ -1,6 +1,6 @@
/** @file

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Glossary:
@@ -73,9 +73,9 @@ DumpAcpiTableToFile (
@param [in] TablePtr Pointer to the ACPI table data.
@param [in] Length The length fo the ACPI table.

- @retval Returns TRUE if the ACPI table should be traced.
+ @retval Returns the ParseFlags for the ACPI table.
**/
-BOOLEAN
+UINT8
ProcessTableReportOptions (
IN CONST UINT32 Signature,
IN CONST UINT8* TablePtr,
@@ -84,7 +84,7 @@ ProcessTableReportOptions (
{
UINTN OriginalAttribute;
UINT8 *SignaturePtr;
- BOOLEAN Log;
+ UINT8 ParseFlags;
BOOLEAN HighLight;
SELECTED_ACPI_TABLE *SelectedTable;

@@ -93,17 +93,17 @@ ProcessTableReportOptions (
//
OriginalAttribute = 0;
SignaturePtr = (UINT8*)(UINTN)&Signature;
- Log = FALSE;
+ ParseFlags = 0;
HighLight = GetColourHighlighting ();
GetSelectedAcpiTable (&SelectedTable);

switch (GetReportOption ()) {
case ReportAll:
- Log = TRUE;
+ ParseFlags |= PARSE_FLAGS_TRACE;
break;
case ReportSelected:
if (Signature == SelectedTable->Type) {
- Log = TRUE;
+ ParseFlags |= PARSE_FLAGS_TRACE;
SelectedTable->Found = TRUE;
}
break;
@@ -143,7 +143,7 @@ ProcessTableReportOptions (
break;
} // switch

- if (Log) {
+ if (IS_TRACE_FLAG_SET (ParseFlags)) {
if (HighLight) {
OriginalAttribute = gST->ConOut->Mode->Attribute;
gST->ConOut->SetAttribute (
@@ -164,7 +164,7 @@ ProcessTableReportOptions (
}
}

- return Log;
+ return ParseFlags;
}


@@ -196,7 +196,7 @@ AcpiView (
UINT32 RsdpLength;
UINT8 RsdpRevision;
PARSE_ACPI_TABLE_PROC RsdpParserProc;
- BOOLEAN Trace;
+ UINT8 ParseFlags;
SELECTED_ACPI_TABLE *SelectedTable;

//
@@ -249,7 +249,11 @@ AcpiView (
// The RSDP length is 4 bytes starting at offset 20
RsdpLength = *(UINT32*)(RsdpPtr + RSDP_LENGTH_OFFSET);

- Trace = ProcessTableReportOptions (RSDP_TABLE_INFO, RsdpPtr, RsdpLength);
+ ParseFlags = ProcessTableReportOptions (
+ RSDP_TABLE_INFO,
+ RsdpPtr,
+ RsdpLength
+ );

Status = GetParser (RSDP_TABLE_INFO, &RsdpParserProc);
if (EFI_ERROR (Status)) {
@@ -260,7 +264,7 @@ AcpiView (
}

RsdpParserProc (
- Trace,
+ ParseFlags,
RsdpPtr,
RsdpLength,
RsdpRevision
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c
index 1a180271a4ebe47948b7f0b56d1cb6f81b5fdf13..6bd4c35bec85e038875ce3d9548c9139b1de2755 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c
@@ -1,7 +1,7 @@
/** @file
BGRT table parser

- Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -36,7 +36,7 @@ STATIC CONST ACPI_PARSER BgrtParser[] = {

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -44,18 +44,18 @@ STATIC CONST ACPI_PARSER BgrtParser[] = {
VOID
EFIAPI
ParseAcpiBgrt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
)
{
- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

ParseAcpi (
- Trace,
+ TRUE,
0,
"BGRT",
Ptr,
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c
index 9df111ecaa7d7a703a13a39c243ed78b9f12ee97..a22f8ab76b84432b2073bea6ca6d8245ea9df7fb 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c
@@ -1,7 +1,7 @@
/** @file
DBG2 table parser

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -212,7 +212,7 @@ DumpDbgDeviceInfo (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -220,7 +220,7 @@ DumpDbgDeviceInfo (
VOID
EFIAPI
ParseAcpiDbg2 (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -229,7 +229,7 @@ ParseAcpiDbg2 (
UINT32 Offset;
UINT32 Index;

- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c
index 6d43974f54d23fd9990fa7af721c96518bb96a36..609c17ef02d460be66f0c390203cae55ece653e3 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c
@@ -1,7 +1,7 @@
/** @file
DSDT table parser

- Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -20,7 +20,7 @@
For the DSDT table only the ACPI header fields are parsed and
traced.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -28,13 +28,13 @@
VOID
EFIAPI
ParseAcpiDsdt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
)
{
- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Facs/FacsParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Facs/FacsParser.c
index d6bea86bdbaa79aa35b86840c809394b3c7a3bf6..d7545b6161eadd24e986a7828910662f2f52b2ec 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Facs/FacsParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Facs/FacsParser.c
@@ -1,7 +1,7 @@
/** @file
FACS table parser

- Copyright (c) 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -42,7 +42,7 @@ STATIC CONST ACPI_PARSER FacsParser[] = {

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -50,18 +50,18 @@ STATIC CONST ACPI_PARSER FacsParser[] = {
VOID
EFIAPI
ParseAcpiFacs (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
)
{
- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

ParseAcpi (
- Trace,
+ TRUE,
0,
"FACS",
Ptr,
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c
index d86718bab67d45fd612bb7ac725b5eb3eeb7dfdc..8d0eb42ec3b361c1727184c542a757e39ef3da5c 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c
@@ -1,7 +1,7 @@
/** @file
FADT table parser

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -198,7 +198,7 @@ STATIC CONST ACPI_PARSER FadtParser[] = {

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -206,7 +206,7 @@ STATIC CONST ACPI_PARSER FadtParser[] = {
VOID
EFIAPI
ParseAcpiFadt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -219,6 +219,9 @@ ParseAcpiFadt (
UINT32 FacsLength;
UINT8 FacsRevision;
PARSE_ACPI_TABLE_PROC FacsParserProc;
+ BOOLEAN Trace;
+
+ Trace = IS_TRACE_FLAG_SET (ParseFlags);

ParseAcpi (
Trace,
@@ -253,7 +256,7 @@ ParseAcpiFadt (
// if HW_REDUCED_ACPI flag is not set, both FIRMWARE_CTRL and
// X_FIRMWARE_CTRL cannot be zero, and the FACS Table must be
// present.
- if ((Trace) &&
+ if (Trace &&
(Flags != NULL) &&
((*Flags & EFI_ACPI_6_3_HW_REDUCED_ACPI) != EFI_ACPI_6_3_HW_REDUCED_ACPI)) {
IncrementErrorCount ();
@@ -274,11 +277,15 @@ ParseAcpiFadt (
// The FACS version is 1 byte starting at offset 32.
FacsRevision = *(UINT8*)(FirmwareCtrlPtr + FACS_VERSION_OFFSET);

- Trace = ProcessTableReportOptions (
- FacsSignature,
- FirmwareCtrlPtr,
- FacsLength
- );
+ if (ProcessTableReportOptions (
+ FacsSignature,
+ FirmwareCtrlPtr,
+ FacsLength
+ )) {
+ ParseFlags |= PARSE_FLAGS_TRACE;
+ } else {
+ ParseFlags &= ~PARSE_FLAGS_TRACE;
+ }

Status = GetParser (FacsSignature, &FacsParserProc);
if (EFI_ERROR (Status)) {
@@ -289,7 +296,7 @@ ParseAcpiFadt (
}

FacsParserProc (
- Trace,
+ ParseFlags,
FirmwareCtrlPtr,
FacsLength,
FacsRevision
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c
index d02fc4929d6fa5e04672276810b19d3f4c62efd2..da93938771bfcf0da146fd46a025addeb05e71cc 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c
@@ -1,7 +1,7 @@
/** @file
GTDT table parser

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -254,7 +254,7 @@ DumpWatchdogTimer (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -262,7 +262,7 @@ DumpWatchdogTimer (
VOID
EFIAPI
ParseAcpiGtdt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -272,7 +272,7 @@ ParseAcpiGtdt (
UINT32 Offset;
UINT8* TimerPtr;

- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
index f7447947b2308d35d4d2890373778f0fd2f97f9e..2f659349499a02175820ee4faf3a84034c8ced76 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
@@ -1,7 +1,7 @@
/** @file
IORT table parser

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -612,7 +612,7 @@ DumpIortNodePmcg (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -620,7 +620,7 @@ DumpIortNodePmcg (
VOID
EFIAPI
ParseAcpiIort (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -630,7 +630,7 @@ ParseAcpiIort (
UINT32 Index;
UINT8* NodePtr;

- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
index 15aa2392b60cee9e3843c7c560b0ab84e0be4174..a29bf97a3985a74ff888f225eb0e5cfbcbea72b0 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
@@ -1,7 +1,7 @@
/** @file
MADT table parser

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -216,7 +216,7 @@ STATIC CONST ACPI_PARSER MadtInterruptControllerHeaderParser[] = {

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -224,7 +224,7 @@ STATIC CONST ACPI_PARSER MadtInterruptControllerHeaderParser[] = {
VOID
EFIAPI
ParseAcpiMadt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -236,7 +236,7 @@ ParseAcpiMadt (

GICDCount = 0;

- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c
index 9da4d60e849721ed3b635bfff8a3bd76728c0ade..febf8a2bd92d8e38bdc59a3f97a8c4485cdba5a5 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c
@@ -1,7 +1,7 @@
/** @file
MCFG table parser

- Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -42,7 +42,7 @@ STATIC CONST ACPI_PARSER PciCfgSpaceBaseAddrParser[] = {

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -50,7 +50,7 @@ STATIC CONST ACPI_PARSER PciCfgSpaceBaseAddrParser[] = {
VOID
EFIAPI
ParseAcpiMcfg (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -60,7 +60,7 @@ ParseAcpiMcfg (
UINT32 PciCfgOffset;
UINT8* PciCfgSpacePtr;

- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
index acd2b81bb3258c7322aa10d2c0e0d842d89e358b..538b6a69350d75ccbf36b86fff115255e77437c7 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
@@ -1,7 +1,7 @@
/** @file
PPTT table parser

- Copyright (c) 2019 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -241,13 +241,15 @@ STATIC CONST ACPI_PARSER IdStructureParser[] = {
/**
This function parses the Processor Hierarchy Node Structure (Type 0).

- @param [in] Ptr Pointer to the start of the Processor Hierarchy Node
- Structure data.
- @param [in] Length Length of the Processor Hierarchy Node Structure.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
+ @param [in] Ptr Pointer to the start of the Processor Hierarchy Node
+ Structure data.
+ @param [in] Length Length of the Processor Hierarchy Node Structure.
**/
STATIC
VOID
DumpProcessorHierarchyNodeStructure (
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT8 Length
)
@@ -257,7 +259,7 @@ DumpProcessorHierarchyNodeStructure (
CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];

Offset = ParseAcpi (
- TRUE,
+ IS_TRACE_FLAG_SET (ParseFlags),
2,
"Processor Hierarchy Node Structure",
Ptr,
@@ -315,18 +317,20 @@ DumpProcessorHierarchyNodeStructure (
/**
This function parses the Cache Type Structure (Type 1).

- @param [in] Ptr Pointer to the start of the Cache Type Structure data.
- @param [in] Length Length of the Cache Type Structure.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
+ @param [in] Ptr Pointer to the start of the Cache Type Structure data.
+ @param [in] Length Length of the Cache Type Structure.
**/
STATIC
VOID
DumpCacheTypeStructure (
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT8 Length
)
{
ParseAcpi (
- TRUE,
+ IS_TRACE_FLAG_SET (ParseFlags),
2,
"Cache Type Structure",
Ptr,
@@ -338,18 +342,20 @@ DumpCacheTypeStructure (
/**
This function parses the ID Structure (Type 2).

- @param [in] Ptr Pointer to the start of the ID Structure data.
- @param [in] Length Length of the ID Structure.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
+ @param [in] Ptr Pointer to the start of the ID Structure data.
+ @param [in] Length Length of the ID Structure.
**/
STATIC
VOID
DumpIDStructure (
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
- IN UINT8 Length
+ IN UINT8 Length
)
{
ParseAcpi (
- TRUE,
+ IS_TRACE_FLAG_SET (ParseFlags),
2,
"ID Structure",
Ptr,
@@ -370,7 +376,7 @@ DumpIDStructure (

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -378,7 +384,7 @@ DumpIDStructure (
VOID
EFIAPI
ParseAcpiPptt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -387,12 +393,12 @@ ParseAcpiPptt (
UINT32 Offset;
UINT8* ProcessorTopologyStructurePtr;

- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

Offset = ParseAcpi (
- TRUE,
+ IS_TRACE_FLAG_SET (ParseFlags),
0,
"PPTT",
Ptr,
@@ -440,24 +446,29 @@ ParseAcpiPptt (
return;
}

- PrintFieldName (2, L"* Structure Offset *");
- Print (L"0x%x\n", Offset);
+ if (IS_TRACE_FLAG_SET (ParseFlags)) {
+ PrintFieldName (2, L"* Structure Offset *");
+ Print (L"0x%x\n", Offset);
+ }

switch (*ProcessorTopologyStructureType) {
case EFI_ACPI_6_2_PPTT_TYPE_PROCESSOR:
DumpProcessorHierarchyNodeStructure (
+ ParseFlags,
ProcessorTopologyStructurePtr,
*ProcessorTopologyStructureLength
);
break;
case EFI_ACPI_6_2_PPTT_TYPE_CACHE:
DumpCacheTypeStructure (
+ ParseFlags,
ProcessorTopologyStructurePtr,
*ProcessorTopologyStructureLength
);
break;
case EFI_ACPI_6_2_PPTT_TYPE_ID:
DumpIDStructure (
+ ParseFlags,
ProcessorTopologyStructurePtr,
*ProcessorTopologyStructureLength
);
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c
index f4a8732a7db7c437031f2a3d2f266b80eff17b4b..c98bc62719c3aef3381152ff2436cb1a29f98362 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c
@@ -1,7 +1,7 @@
/** @file
RSDP table parser

- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -110,7 +110,7 @@ STATIC CONST ACPI_PARSER RsdpParser[] = {
This function also performs a RAW dump of the ACPI table and
validates the checksum.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -118,19 +118,19 @@ STATIC CONST ACPI_PARSER RsdpParser[] = {
VOID
EFIAPI
ParseAcpiRsdp (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
)
{
- if (Trace) {
+ if (IS_TRACE_FLAG_SET (ParseFlags)) {
DumpRaw (Ptr, AcpiTableLength);
VerifyChecksum (TRUE, Ptr, AcpiTableLength);
}

ParseAcpi (
- Trace,
+ IS_TRACE_FLAG_SET (ParseFlags),
0,
"RSDP",
Ptr,
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c
index e4625ee8b13907893a9b6990ecb956baf91cc3b9..20d2fb79a8ea6251b0e31b5370cc400be9e1478f 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c
@@ -1,7 +1,7 @@
/** @file
SLIT table parser

- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -42,7 +42,7 @@ STATIC CONST ACPI_PARSER SlitParser[] = {
- Relative distance from System Locality at i*N+j is same as
j*N+i

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -50,7 +50,7 @@ STATIC CONST ACPI_PARSER SlitParser[] = {
VOID
EFIAPI
ParseAcpiSlit (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -63,7 +63,7 @@ ParseAcpiSlit (
UINT8* LocalityPtr;
CHAR16 Buffer[80]; // Used for AsciiName param of ParseAcpi

- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c
index 3b06b05dee8c056c6e009b9e485ccd35d4194e95..99cffafa946979b79a06cd28f14257beaa6cafec 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c
@@ -1,7 +1,7 @@
/** @file
SPCR table parser

- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -114,7 +114,7 @@ STATIC CONST ACPI_PARSER SpcrParser[] = {

This function also performs validations of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -122,13 +122,13 @@ STATIC CONST ACPI_PARSER SpcrParser[] = {
VOID
EFIAPI
ParseAcpiSpcr (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
)
{
- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c
index b9b67820b89f7fc5560a1022e976663db7d9df2d..907856368fbe0ad9f140d8f27e51bd9460f35b1a 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c
@@ -1,7 +1,7 @@
/** @file
SRAT table parser

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -344,7 +344,7 @@ STATIC CONST ACPI_PARSER SratX2ApciAffinityParser[] = {

This function also performs validation of the ACPI table fields.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -352,7 +352,7 @@ STATIC CONST ACPI_PARSER SratX2ApciAffinityParser[] = {
VOID
EFIAPI
ParseAcpiSrat (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -375,7 +375,7 @@ ParseAcpiSrat (
ApicSapicAffinityIndex = 0;
X2ApicAffinityIndex = 0;

- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c
index f18664b8a6879b82dc9c55d9979ca21e01c4fc99..138a3159fb1a6121387f832621d23960c688ce30 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c
@@ -1,7 +1,7 @@
/** @file
SSDT table parser

- Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -20,7 +20,7 @@
For the SSDT table only the ACPI header fields are
parsed and traced.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -28,13 +28,13 @@
VOID
EFIAPI
ParseAcpiSsdt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
)
{
- if (!Trace) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags)) {
return;
}

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c
index e39061f8e2612f2cce4aebf51a511b63b703662b..bbd58d72ad9c676b4843d3b4f1d7c554a5abbd3f 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c
@@ -1,7 +1,7 @@
/** @file
XSDT table parser

- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

@par Reference(s):
@@ -40,7 +40,7 @@ GetAcpiXsdtHeaderInfo (

This function also performs validation of the XSDT table.

- @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] ParseFlags Flags describing what the parser needs to do.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
@@ -48,7 +48,7 @@ GetAcpiXsdtHeaderInfo (
VOID
EFIAPI
ParseAcpiXsdt (
- IN BOOLEAN Trace,
+ IN UINT8 ParseFlags,
IN UINT8* Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
@@ -61,7 +61,7 @@ ParseAcpiXsdt (
CHAR16 Buffer[32];

Offset = ParseAcpi (
- Trace,
+ IS_TRACE_FLAG_SET (ParseFlags),
0,
"XSDT",
Ptr,
@@ -71,7 +71,7 @@ ParseAcpiXsdt (

TableOffset = Offset;

- if (Trace) {
+ if (IS_TRACE_FLAG_SET (ParseFlags)) {
EntryIndex = 0;
TablePointer = (UINT64*)(Ptr + TableOffset);
while (Offset < AcpiTableLength) {
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 3/5] ShellPkg: add a Graph option to the Parser Flags

Joey Gouly
 

From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>

Bugzilla: 3378 (https://bugzilla.tianocore.org/show_bug.cgi?id=3378)

This option informs the parser to generate a dot graph of a table.
This can be useful to understand or debug a table, such as the PPTT
table.

Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h | 2 ++
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.h | 3 ++-
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c | 9 +++++++-
ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c | 24 +++++++++++++++++---
ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni | 9 ++++++--
5 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
index b078c0b99335ba28f7589cac6b0a4190d9a6c3b5..9a67fe084327434bf21b37b3089779468edfb0f1 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
@@ -20,11 +20,13 @@
Flags for the parser.
*/
#define PARSE_FLAGS_TRACE BIT0
+#define PARSE_FLAGS_GRAPH BIT1

/**
Helper macros to test parser flags.
*/
#define IS_TRACE_FLAG_SET(Flags) (((Flags) & PARSE_FLAGS_TRACE) != 0)
+#define IS_GRAPH_FLAG_SET(Flags) (((Flags) & PARSE_FLAGS_GRAPH) != 0)

/**
This function increments the ACPI table error counter.
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.h
index 2db4a65415d8f9e70686cb2cc432862ab4e4c2dd..262302a15cbbe04a228fd55e523930fb76bcf6a8 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.h
@@ -1,7 +1,7 @@
/** @file
Header file for 'acpiview' configuration.

- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

@@ -106,6 +106,7 @@ typedef enum {
ReportSelected, ///< Report Selected table.
ReportTableList, ///< Report List of tables.
ReportDumpBinFile, ///< Dump selected table to a file.
+ ReportDotGraph, ///< Create Dot Graph for selected compatible table.
ReportMax,
} EREPORT_OPTION;

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
index db7b2e2a30525cc85a333b93f5eb97ec3a517b37..1155b2f3f411247c866f635fb666dd76455f18a4 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
@@ -192,6 +192,12 @@ ProcessTableReportOptions (
DumpAcpiTableToFile (TablePtr, Length);
}
break;
+ case ReportDotGraph:
+ if (Signature == SelectedTable->Type) {
+ SelectedTable->Found = TRUE;
+ ParseFlags |= PARSE_FLAGS_GRAPH;
+ }
+ break;
case ReportMax:
// We should never be here.
// This case is only present to prevent compiler warning.
@@ -340,7 +346,8 @@ AcpiView (

ReportOption = GetReportOption ();
if (ReportTableList != ReportOption) {
- if (((ReportSelected == ReportOption) ||
+ if (((ReportSelected == ReportOption) ||
+ (ReportDotGraph == ReportOption) ||
(ReportDumpBinFile == ReportOption)) &&
(!SelectedTable->Found)) {
Print (L"\nRequested ACPI Table not found.\n");
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
index b30ed3fc8597b229dd15b6ad4f2aab2e3d0ca583..d837b390938f3c3bc5cb90c1161e2feeb1ed6a6b 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -1,7 +1,7 @@
/** @file
Main file for 'acpiview' Shell command function.

- Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

@@ -34,6 +34,7 @@ EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL;
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
{L"-q", TypeFlag},
{L"-d", TypeFlag},
+ {L"-g", TypeFlag},
{L"-h", TypeFlag},
{L"-l", TypeFlag},
{L"-s", TypeValue},
@@ -293,6 +294,18 @@ ShellCommandRunAcpiView (
L"-d"
);
ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (ShellCommandLineGetFlag (Package, L"-g") &&
+ !ShellCommandLineGetFlag (Package, L"-s")) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_MISSING_OPTION),
+ gShellAcpiViewHiiHandle,
+ L"acpiview",
+ L"-s",
+ L"-g"
+ );
} else {
// Turn on colour highlighting if requested
SetColourHighlighting (ShellCommandLineGetFlag (Package, L"-h"));
@@ -316,10 +329,15 @@ ShellCommandRunAcpiView (
SelectAcpiTable (SelectedTableName);
SetReportOption (ReportSelected);

- if (ShellCommandLineGetFlag (Package, L"-d")) {
+ if (ShellCommandLineGetFlag (Package, L"-d") ||
+ ShellCommandLineGetFlag (Package, L"-g")) {
// Create a temporary file to check if the media is writable.
CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
- SetReportOption (ReportDumpBinFile);
+ if (ShellCommandLineGetFlag (Package, L"-d")) {
+ SetReportOption (ReportDumpBinFile);
+ } else {
+ SetReportOption (ReportDotGraph);
+ }

UnicodeSPrint (
FileNameBuffer,
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
index 393110e0ee98d54b3be0309c2d297a121c258570..51f2bea10f7b768e5e67f930237207193cba4246 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
@@ -1,6 +1,6 @@
// /**
//
-// Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
+// Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// Module Name:
@@ -30,7 +30,7 @@
"Display ACPI Table information.\r\n"
".SH SYNOPSIS\r\n"
" \r\n"
-"ACPIVIEW [[-?] | [[[[-l] | [-s AcpiTable [-d]]] [-q] [-h]] [-r Spec]]]\r\n"
+"ACPIVIEW [[-?] | [[[[-l] | [-s AcpiTable [-d] [-g]]] [-q] [-h]] [-r Spec]]]\r\n"
" \r\n"
".SH OPTIONS\r\n"
" \r\n"
@@ -39,6 +39,7 @@
" invocation option.\r\n"
" AcpiTable : The required ACPI Table type.\r\n"
" -d - Generate a binary file dump of the specified AcpiTable.\r\n"
+" -g - Generate a dot graph of the specified AcpiTable.\r\n"
" -q - Quiet. Suppress errors and warnings. Disables consistency checks.\r\n"
" -h - Enable colour highlighting.\r\n"
" -r - Validate that all required ACPI tables are installed\r\n"
@@ -123,6 +124,10 @@
" in the current working directory:\r\n"
" fs0:\> acpiview -s DSDT -d\r\n"
" \r\n"
+" * To save a dot graph in the current working directory\r\n"
+" representing the processor architecture described in the PPTT table:\r\n"
+" fs0:\> acpiview -s PPTT -g\r\n"
+" \r\n"
" * To display contents of all ACPI tables:\r\n"
" fs0:\> acpiview\r\n"
" \r\n"
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 4/5] ShellPkg: add dot file generator functions

Joey Gouly
 

From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>

Bugzilla: 3378 (https://bugzilla.tianocore.org/show_bug.cgi?id=3378)

These can be used to generate dot files, that can be used to visualise
graphs in tables, such as PPTT.

Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf | 4 +-
ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.h | 97 +++++++
ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.c | 276 ++++++++++++++++++++
3 files changed, 376 insertions(+), 1 deletion(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
index 63fc5a1281a894841dac704484c3d4f9481edb46..ffe4979b3ac5d0120bcf678cf7823afac6674e4f 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
@@ -1,7 +1,7 @@
## @file
# Provides Shell 'acpiview' command functions
#
-# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
+# Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -27,6 +27,8 @@ [Sources.common]
AcpiView.h
AcpiViewConfig.c
AcpiViewConfig.h
+ DotGenerator.c
+ DotGenerator.h
Parsers/Aest/AestParser.c
Parsers/Bgrt/BgrtParser.c
Parsers/Dbg2/Dbg2Parser.c
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a8e2fdc2d2024ae54fdce963d751ab53a8a5758
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.h
@@ -0,0 +1,97 @@
+/** @file
+ Header file for Dot File Generation
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef DOT_GENERATOR_H_
+#define DOT_GENERATOR_H_
+
+#include <Protocol/Shell.h>
+
+#define DOT_COLOR_MASK 0b111
+// Flags for color of arrow or node.
+#define DOT_COLOR_BLACK 0b000 // default
+#define DOT_COLOR_GRAY 0b001
+#define DOT_COLOR_BLUE 0b010
+#define DOT_COLOR_YELLOW 0b011
+#define DOT_COLOR_RED 0b100
+
+#define DOT_ARROW_TYPE_MASK 0b1000
+// Flags for style of arrow.
+#define DOT_ARROW_FULL 0b0000 // default
+#define DOT_ARROW_DOTTED 0b1000
+
+// Flag for reversing how the nodes will be ranked and displayed.
+#define DOT_ARROW_RANK_REVERSE 0b10000
+
+#define DOT_BOX_TYPE_MASK 0b1100000
+// Flag for shape of box
+#define DOT_BOX_SQUARE 0b0000000 // default
+#define DOT_BOX_DIAMOND 0b0100000
+
+// Flag for adding the node's ID to the end of the label.
+#define DOT_BOX_ADD_ID_TO_LABEL 0b10000000
+
+// Valid flags for DotAddNode.
+#define DOT_BOX_FLAGS_MASK (DOT_COLOR_MASK |\
+ DOT_BOX_TYPE_MASK |\
+ DOT_BOX_ADD_ID_TO_LABEL)
+// Valid flags for DotAddLink.
+#define DOT_ARROW_FLAGS_MASK (DOT_COLOR_MASK |\
+ DOT_ARROW_TYPE_MASK |\
+ DOT_ARROW_RANK_REVERSE)
+
+
+/**
+ Opens a new dot file and writes a dot directional graph.
+
+ @param [in] FileName Null terminated unicode string.
+**/
+SHELL_FILE_HANDLE
+DotOpenNewFile (
+ IN CHAR16* FileName
+ );
+
+/**
+ Writes a dot graph footer and closes the dot file.
+**/
+VOID
+DotCloseFile (
+ SHELL_FILE_HANDLE DotFile
+ );
+
+/**
+ Writes a line in the previously opened dot file describing a
+ new node.
+
+ @param [in] Id A unique identifier for the node.
+ @param [in] Flags Flags describing the node's characteristics.
+ @param [in] Label Label to be shown on the graph node.
+**/
+VOID
+DotAddNode (
+ SHELL_FILE_HANDLE DotFile,
+ IN UINT32 Id,
+ IN UINT16 Flags,
+ IN CONST CHAR16* Label
+ );
+
+/**
+ Writes a line in the previously opened dot file describing a
+ new link between two nodes.
+
+ @param [in] IdSource An identifier for the source node of the link.
+ @param [in] IdTarget An identifier for the target node of the link.
+ @param [in] Flags Flags describing the node's characteristics.
+**/
+VOID
+DotAddLink (
+ SHELL_FILE_HANDLE DotFile,
+ IN UINT32 IdSource,
+ IN UINT32 IdTarget,
+ IN UINT16 Flags
+ );
+
+#endif // DOT_GENERATOR_H_
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c644d96af30ca4b1160bc892fe391ae1ff5211b
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.c
@@ -0,0 +1,276 @@
+/** @file
+ Dot File Generator
+
+ Copyright (c) 2021, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include "DotGenerator.h"
+#include "AcpiView.h"
+
+#define MAX_DOT_BUFFER_SIZE 128
+
+/**
+ Writes a Null terminated ASCII string to the dot file handle.
+
+ @param [in] String Null terminated ascii string.
+**/
+STATIC
+VOID
+DotWriteFile (
+ SHELL_FILE_HANDLE DotFileHandle,
+ IN CHAR8* String
+ )
+{
+ UINTN TransferBytes;
+ EFI_STATUS Status;
+
+ if (DotFileHandle == NULL) {
+ Print ("ERROR: Failed to write to dot file\n");
+ ASSERT (0);
+ return;
+ }
+
+ TransferBytes = AsciiStrLen (String);
+ Status = ShellWriteFile (
+ DotFileHandle,
+ &TransferBytes,
+ String
+ );
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (AsciiStrLen (String) == TransferBytes);
+}
+
+/**
+ Writes a new parameter to a previously started parameter list.
+
+ @param [in] Name Null terminated string of the parameter's name.
+ @param [in] Value Null terminated string of the parameter's value.
+ @param [in] Quoted True if value needs to be quoted.
+**/
+STATIC
+VOID
+DotAddParameter (
+ SHELL_FILE_HANDLE DotFileHandle,
+ IN CHAR16* Name,
+ IN CHAR16* Value,
+ IN BOOLEAN Quoted
+ )
+{
+ CHAR8 StringBuffer[MAX_DOT_BUFFER_SIZE];
+
+ ASSERT(DotFileHandle != NULL);
+
+ if (Quoted) {
+ AsciiSPrint (
+ StringBuffer,
+ sizeof (StringBuffer),
+ "[%s=\"%s\"]",
+ Name,
+ Value
+ );
+ } else {
+ AsciiSPrint (
+ StringBuffer,
+ sizeof (StringBuffer),
+ "[%s=%s]",
+ Name,
+ Value
+ );
+ }
+
+ DotWriteFile (DotFileHandle, StringBuffer);
+}
+
+/**
+ Writes the color argument of nodes or links according to flags.
+
+ @param [in] Flags Flags describing the color (one of DOT_COLOR_...)
+**/
+STATIC
+VOID
+WriteColor (
+ SHELL_FILE_HANDLE DotFileHandle,
+ IN UINT16 Flags
+ )
+{
+ ASSERT(DotFileHandle != NULL);
+
+ switch (Flags & DOT_COLOR_MASK) {
+ case DOT_COLOR_GRAY:
+ DotAddParameter (DotFileHandle, L"color", L"gray", FALSE);
+ break;
+ case DOT_COLOR_YELLOW:
+ DotAddParameter (DotFileHandle, L"color", L"yellow", FALSE);
+ break;
+ case DOT_COLOR_BLUE:
+ DotAddParameter (DotFileHandle, L"color", L"blue", FALSE);
+ break;
+ case DOT_COLOR_RED:
+ DotAddParameter (DotFileHandle, L"color", L"red", FALSE);
+ break;
+ case DOT_COLOR_BLACK:
+ default:
+ DotAddParameter (DotFileHandle, L"color", L"black", FALSE);
+ break;
+ }
+}
+
+/**
+ Opens a new dot file and writes a dot directional graph.
+
+ @param [in] FileName Null terminated unicode string.
+**/
+SHELL_FILE_HANDLE
+DotOpenNewFile (
+ IN CHAR16* FileName
+ )
+{
+ SHELL_FILE_HANDLE DotFileHandle;
+ EFI_STATUS Status;
+
+ Status = ShellOpenFileByName (
+ FileName,
+ &DotFileHandle,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ Print (L"ERROR: Couldn't open dot file");
+ return NULL;//Status;
+ }
+ Print (L"Creating DOT Graph in : %s... ", FileName);
+ DotWriteFile (DotFileHandle, "digraph {\n\trankdir=BT\n");
+ return DotFileHandle;
+}
+
+/**
+ Writes a dot graph footer and closes the dot file.
+**/
+VOID
+DotCloseFile (
+ SHELL_FILE_HANDLE DotFileHandle
+ )
+{
+ ASSERT(DotFileHandle != NULL);
+
+ DotWriteFile (DotFileHandle, "}\n");
+ ShellCloseFile (&DotFileHandle);
+ Print (L"Done.\n");
+}
+
+/**
+ Writes a line in the previously opened dot file describing a
+ new node.
+
+ @param [in] Id A unique identifier for the node.
+ @param [in] Flags Flags describing the node's characteristics.
+ @param [in] Label Label to be shown on the graph node.
+**/
+VOID
+DotAddNode (
+ SHELL_FILE_HANDLE DotFileHandle,
+ IN UINT32 Id,
+ IN UINT16 Flags,
+ IN CONST CHAR16* Label
+ )
+{
+ CHAR8 LineBuffer[64];
+ CHAR16 LabelBuffer[MAX_DOT_BUFFER_SIZE];
+
+ ASSERT ((Flags & ~DOT_BOX_FLAGS_MASK) == 0);
+ ASSERT(DotFileHandle != NULL);
+
+ AsciiSPrint (
+ LineBuffer,
+ sizeof (LineBuffer),
+ "\tx%x",
+ Id
+ );
+ DotWriteFile (DotFileHandle, LineBuffer);
+
+ switch (Flags & DOT_BOX_TYPE_MASK) {
+ case DOT_BOX_DIAMOND:
+ DotAddParameter (DotFileHandle, L"shape", L"diamond", FALSE);
+ break;
+ case DOT_BOX_SQUARE:
+ default:
+ DotAddParameter (DotFileHandle, L"shape", L"box", FALSE);
+ break;
+ }
+
+ if (Label != NULL) {
+ if ((Flags & DOT_BOX_ADD_ID_TO_LABEL) != 0) {
+ UnicodeSPrint (
+ LabelBuffer,
+ sizeof (LabelBuffer),
+ L"%s\\n0x%x",
+ Label,
+ Id
+ );
+ } else {
+ UnicodeSPrint (
+ LabelBuffer,
+ sizeof (LabelBuffer),
+ L"%s",
+ Label
+ );
+ }
+ DotAddParameter (DotFileHandle, L"label", LabelBuffer, TRUE);
+ }
+
+ WriteColor (DotFileHandle, Flags);
+ DotWriteFile (DotFileHandle, "\n");
+}
+
+/**
+ Writes a line in the previously opened dot file describing a
+ new link between two nodes.
+
+ @param [in] IdSource An identifier for the source node of the link.
+ @param [in] IdTarget An identifier for the target node of the link.
+ @param [in] Flags Flags describing the node's characteristics.
+**/
+VOID
+DotAddLink (
+ SHELL_FILE_HANDLE DotFileHandle,
+ IN UINT32 IdSource,
+ IN UINT32 IdTarget,
+ IN UINT16 Flags
+ )
+{
+ CHAR8 LineBuffer[64];
+
+ ASSERT(DotFileHandle != NULL);
+ ASSERT ((Flags & ~DOT_ARROW_FLAGS_MASK) == 0);
+
+ AsciiSPrint (
+ LineBuffer,
+ sizeof (LineBuffer),
+ "\tx%x -> x%x",
+ IdSource,
+ IdTarget
+ );
+ DotWriteFile (DotFileHandle, LineBuffer);
+
+ if ((Flags & DOT_ARROW_RANK_REVERSE) != 0) {
+ DotAddParameter (DotFileHandle, L"dir", L"back", FALSE);
+ }
+
+ switch (Flags & DOT_ARROW_TYPE_MASK) {
+ case DOT_ARROW_DOTTED:
+ DotAddParameter (DotFileHandle, L"style", L"dotted", FALSE);
+ break;
+ case DOT_ARROW_FULL:
+ default:
+ DotAddParameter (DotFileHandle, L"style", L"solid", FALSE);
+ break;
+ }
+
+ WriteColor (DotFileHandle, Flags);
+ DotWriteFile (DotFileHandle, "\n");
+}
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


[PATCH v1 0/5] Dot graph generator for PPTT

Joey Gouly
 

This series adds functionality to print a dot graph of a PPTT table.
This helps with understanding and debugging PPTT tables.
The dot graph generator functionality is generic and could be used by
other tables that would benefit from graph output.

Bugzilla: 3378 (https://bugzilla.tianocore.org/show_bug.cgi?id=3378)

The changes can be seen at https://github.com/jgouly/edk2/tree/1484_pptt_dot_graph_v1

Marc Moisson-Franckhauser (5):
ShellPkg: Replace 'Trace' parameter with 'ParseFlags'
ShellPkg: add a helper function for getting a new file name
ShellPkg: add a Graph option to the Parser Flags
ShellPkg: add dot file generator functions
ShellPkg: add PPTT dot file genration

.../UefiShellAcpiViewCommandLib.inf | 4 +-
.../UefiShellAcpiViewCommandLib/AcpiParser.h | 79 +++--
.../AcpiTableParser.h | 6 +-
.../UefiShellAcpiViewCommandLib/AcpiView.h | 25 +-
.../AcpiViewConfig.h | 3 +-
.../DotGenerator.h | 97 ++++++
.../AcpiTableParser.c | 20 +-
.../UefiShellAcpiViewCommandLib/AcpiView.c | 117 +++++--
.../DotGenerator.c | 276 +++++++++++++++++
.../Parsers/Bgrt/BgrtParser.c | 10 +-
.../Parsers/Dbg2/Dbg2Parser.c | 8 +-
.../Parsers/Dsdt/DsdtParser.c | 8 +-
.../Parsers/Facs/FacsParser.c | 10 +-
.../Parsers/Fadt/FadtParser.c | 27 +-
.../Parsers/Gtdt/GtdtParser.c | 8 +-
.../Parsers/Iort/IortParser.c | 8 +-
.../Parsers/Madt/MadtParser.c | 8 +-
.../Parsers/Mcfg/McfgParser.c | 8 +-
.../Parsers/Pptt/PpttParser.c | 285 +++++++++++++++---
.../Parsers/Rsdp/RsdpParser.c | 10 +-
.../Parsers/Slit/SlitParser.c | 8 +-
.../Parsers/Spcr/SpcrParser.c | 8 +-
.../Parsers/Srat/SratParser.c | 8 +-
.../Parsers/Ssdt/SsdtParser.c | 8 +-
.../Parsers/Xsdt/XsdtParser.c | 10 +-
.../UefiShellAcpiViewCommandLib.c | 24 +-
.../UefiShellAcpiViewCommandLib.uni | 9 +-
27 files changed, 903 insertions(+), 189 deletions(-)
create mode 100644 ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.h
create mode 100644 ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.c

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


[PATCH v1 5/5] ShellPkg: add PPTT dot file genration

Joey Gouly
 

From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>

Bugzilla: 3378 (https://bugzilla.tianocore.org/show_bug.cgi?id=3378)

This generates a dot file from the PPTT table that can be used to
visualise the topology of the CPUs and Caches.

Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c | 240 ++++++++++++++++++--
1 file changed, 218 insertions(+), 22 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
index 538b6a69350d75ccbf36b86fff115255e77437c7..b52bd532b846b9cec0ca315b043beff95df40bd5 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
@@ -15,11 +15,23 @@
#include "AcpiView.h"
#include "AcpiViewConfig.h"
#include "PpttParser.h"
+#include "DotGenerator.h"

// Local variables
STATIC CONST UINT8* ProcessorTopologyStructureType;
STATIC CONST UINT8* ProcessorTopologyStructureLength;
+
STATIC CONST UINT32* NumberOfPrivateResources;
+STATIC CONST UINT32* ProcessorHierarchyParent;
+STATIC CONST EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR_FLAGS* ProcStructFlags;
+STATIC CONST UINT32* NextLevelOfCache;
+STATIC CONST EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE_ATTRIBUTES* CacheAttributes;
+STATIC CONST UINT32* CacheSize;
+
+STATIC CONST UINT8* PpttStartPointer;
+
+STATIC SHELL_FILE_HANDLE mDotFileHandle;
+
STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;

/**
@@ -198,8 +210,9 @@ STATIC CONST ACPI_PARSER ProcessorHierarchyNodeStructureParser[] = {
{L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
{L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},

- {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
- {L"Parent", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 4, L"0x%x", NULL, (VOID**)&ProcStructFlags, NULL, NULL},
+ {L"Parent", 4, 8, L"0x%x", NULL,
+ (VOID**)&ProcessorHierarchyParent, NULL, NULL},
{L"ACPI Processor ID", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
{L"Number of private resources", 4, 16, L"%d", NULL,
(VOID**)&NumberOfPrivateResources, NULL, NULL}
@@ -214,11 +227,13 @@ STATIC CONST ACPI_PARSER CacheTypeStructureParser[] = {
{L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},

{L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
- {L"Next Level of Cache", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
- {L"Size", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Next Level of Cache", 4, 8, L"0x%x", NULL,
+ (VOID**)&NextLevelOfCache, NULL, NULL},
+ {L"Size", 4, 12, L"0x%x", NULL, (VOID**)&CacheSize, NULL, NULL},
{L"Number of sets", 4, 16, L"%d", NULL, NULL, ValidateCacheNumberOfSets, NULL},
{L"Associativity", 1, 20, L"%d", NULL, NULL, ValidateCacheAssociativity, NULL},
- {L"Attributes", 1, 21, L"0x%x", NULL, NULL, ValidateCacheAttributes, NULL},
+ {L"Attributes", 1, 21, L"0x%x", NULL, (VOID**)&CacheAttributes,
+ ValidateCacheAttributes, NULL},
{L"Line size", 2, 22, L"%d", NULL, NULL, ValidateCacheLineSize, NULL}
};

@@ -257,6 +272,7 @@ DumpProcessorHierarchyNodeStructure (
UINT32 Offset;
UINT32 Index;
CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
+ CONST UINT8* TypePtr;

Offset = ParseAcpi (
IS_TRACE_FLAG_SET (ParseFlags),
@@ -291,26 +307,67 @@ DumpProcessorHierarchyNodeStructure (
return;
}

- Index = 0;
+ if (IS_GRAPH_FLAG_SET (ParseFlags)) {
+ if (ProcStructFlags->ProcessorIsAThread) {
+ UnicodeSPrint(Buffer, sizeof (Buffer), L"Thread");
+ } else if (ProcStructFlags->NodeIsALeaf) {
+ UnicodeSPrint(Buffer, sizeof (Buffer), L"Core");
+ } else if (ProcStructFlags->PhysicalPackage) {
+ UnicodeSPrint(Buffer, sizeof (Buffer), L"Physical\\nPackage");
+ } else {
+ UnicodeSPrint(Buffer, sizeof (Buffer), L"Cluster");
+ }
+
+ DotAddNode (
+ mDotFileHandle,
+ (UINT32)(Ptr - PpttStartPointer),
+ DOT_BOX_SQUARE | DOT_COLOR_BLUE | DOT_BOX_ADD_ID_TO_LABEL,
+ Buffer
+ );
+
+ // Add link to parent node.
+ if (*ProcessorHierarchyParent != 0) {
+ DotAddLink (
+ mDotFileHandle,
+ (UINT32)(Ptr - PpttStartPointer),
+ *ProcessorHierarchyParent,
+ 0x0
+ );
+ }
+ }

// Parse the specified number of private resource references or the Processor
// Hierarchy Node length. Whichever is minimum.
- while (Index < *NumberOfPrivateResources) {
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"Private resources [%d]",
- Index
- );
+ for (Index = 0; Index < *NumberOfPrivateResources; Index++) {
+ if (IS_TRACE_FLAG_SET (ParseFlags)) {
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ L"Private resources [%d]",
+ Index
+ );

- PrintFieldName (4, Buffer);
- Print (
- L"0x%x\n",
- *((UINT32*)(Ptr + Offset))
- );
+ PrintFieldName (4, Buffer);
+ Print (
+ L"0x%x\n",
+ *((UINT32*)(Ptr + Offset))
+ );
+ }
+
+ if (IS_GRAPH_FLAG_SET (ParseFlags)) {
+ TypePtr = PpttStartPointer + *((UINT32*)(Ptr + Offset));
+ if (*TypePtr == EFI_ACPI_6_2_PPTT_TYPE_ID) {
+ continue;
+ }
+ DotAddLink (
+ mDotFileHandle,
+ *((UINT32*)(Ptr + Offset)),
+ (UINT32)(Ptr - PpttStartPointer),
+ DOT_ARROW_RANK_REVERSE
+ );
+ }

Offset += sizeof (UINT32);
- Index++;
}
}

@@ -329,6 +386,8 @@ DumpCacheTypeStructure (
IN UINT8 Length
)
{
+ CHAR16 LabelBuffer[64];
+
ParseAcpi (
IS_TRACE_FLAG_SET (ParseFlags),
2,
@@ -337,6 +396,88 @@ DumpCacheTypeStructure (
Length,
PARSER_PARAMS (CacheTypeStructureParser)
);
+
+ if (IS_GRAPH_FLAG_SET (ParseFlags)) {
+ // Create cache node
+
+ // Start node label with type of cache
+ switch (CacheAttributes->CacheType) {
+ case EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_DATA:
+ UnicodeSPrint (
+ LabelBuffer,
+ sizeof (LabelBuffer),
+ L"D-Cache\\n"
+ );
+ break;
+ case EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_INSTRUCTION:
+ UnicodeSPrint (
+ LabelBuffer,
+ sizeof (LabelBuffer),
+ L"I-Cache\\n"
+ );
+ break;
+ default:
+ UnicodeSPrint (
+ LabelBuffer,
+ sizeof (LabelBuffer),
+ L"Unified Cache\\n"
+ );
+ }
+
+ // Add size of cache to node label
+ if (((*CacheSize) & 0xfff00000) != 0) {
+ UnicodeSPrint (
+ LabelBuffer,
+ sizeof (LabelBuffer),
+ L"%s%dMiB",
+ LabelBuffer,
+ *CacheSize >> 20
+ );
+ }
+ if ((*CacheSize & 0xffc00) != 0) {
+ UnicodeSPrint (
+ LabelBuffer,
+ sizeof (LabelBuffer),
+ L"%s%dkiB",
+ LabelBuffer,
+ (*CacheSize >> 10) & 0x3ff
+ );
+ }
+ if ((*CacheSize & 0x3ff) != 0) {
+ UnicodeSPrint (
+ LabelBuffer,
+ sizeof (LabelBuffer),
+ L"%s%dB",
+ LabelBuffer,
+ *CacheSize & 0x3ff
+ );
+ }
+ if (*CacheSize == 0) {
+ UnicodeSPrint (
+ LabelBuffer,
+ sizeof (LabelBuffer),
+ L"%s0B",
+ LabelBuffer
+ );
+ }
+
+ //Add node to dot file
+ DotAddNode (
+ mDotFileHandle,
+ (UINT32)(Ptr - PpttStartPointer),
+ DOT_BOX_SQUARE | DOT_COLOR_YELLOW | DOT_BOX_ADD_ID_TO_LABEL,
+ LabelBuffer
+ );
+
+ if (*NextLevelOfCache != 0) {
+ DotAddLink (
+ mDotFileHandle,
+ *NextLevelOfCache,
+ (UINT32)(Ptr - PpttStartPointer),
+ DOT_ARROW_RANK_REVERSE | DOT_COLOR_GRAY
+ );
+ }
+ }
}

/**
@@ -390,13 +531,46 @@ ParseAcpiPptt (
IN UINT8 AcpiTableRevision
)
{
- UINT32 Offset;
- UINT8* ProcessorTopologyStructurePtr;
+ EFI_STATUS Status;
+ UINT32 Offset;
+ UINT8* ProcessorTopologyStructurePtr;
+ CHAR16 Buffer[128];
+ CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];

- if (!IS_TRACE_FLAG_SET (ParseFlags)) {
+ if (!IS_TRACE_FLAG_SET (ParseFlags) &&
+ !IS_GRAPH_FLAG_SET (ParseFlags)) {
return;
}

+ if (IS_GRAPH_FLAG_SET (ParseFlags)) {
+ Status = GetNewFileName (
+ L"PPTT",
+ L"dot",
+ FileNameBuffer,
+ sizeof (FileNameBuffer)
+ );
+
+ if (EFI_ERROR (Status)) {
+ Print (
+ L"Error: Could not open dot file for PPTT table:\n"
+ L"Could not get a file name."
+ );
+ // Abandonning creation of dot graph by unsetting the flag.
+ // We continue parsing in case trace is set.
+ ParseFlags &= ~PARSE_FLAGS_GRAPH;
+ } else {
+ mDotFileHandle = DotOpenNewFile (FileNameBuffer);
+ if (mDotFileHandle == NULL) {
+ Print (L"ERROR: Could not open dot file for PPTT table.\n");
+ // Abandonning creation of dot graph by unsetting the flag.
+ // We continue parsing in case trace is set.
+ ParseFlags &= ~PARSE_FLAGS_GRAPH;
+ }
+ }
+ }
+
+ PpttStartPointer = Ptr;
+
Offset = ParseAcpi (
IS_TRACE_FLAG_SET (ParseFlags),
0,
@@ -406,6 +580,24 @@ ParseAcpiPptt (
PARSER_PARAMS (PpttParser)
);

+ if (*(AcpiHdrInfo.Revision) < 2 &&
+ IS_GRAPH_FLAG_SET (ParseFlags)) {
+ Print (L"\nWARNING: Dot output may not be consistent for PPTT revisions < 2\n");
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ L"WARNING: PPTT table revision is %u.\\n" \
+ L"Revisions lower than 2 might lead to incorrect labelling",
+ *(AcpiHdrInfo.Revision)
+ );
+ DotAddNode (
+ mDotFileHandle,
+ 0,
+ DOT_COLOR_RED | DOT_BOX_SQUARE,
+ Buffer
+ );
+ }
+
ProcessorTopologyStructurePtr = Ptr + Offset;

while (Offset < AcpiTableLength) {
@@ -486,4 +678,8 @@ ParseAcpiPptt (
ProcessorTopologyStructurePtr += *ProcessorTopologyStructureLength;
Offset += *ProcessorTopologyStructureLength;
} // while
+
+ if (IS_GRAPH_FLAG_SET (ParseFlags)) {
+ DotCloseFile (mDotFileHandle);
+ }
}
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")

14941 - 14960 of 89692