Date   

[PATCH v3 0/5] SEV-ES TPM enablement fixes

Lendacky, Thomas
 

This patch series provides fixes for using TPM support with an SEV-ES
guest.

The fixes include:

- Decode ModRM byte for MOVZX and MOVSX opcodes.
- Add MMIO support for MOV opcodes 0xA0-0xA3.
- Create a new TPM MMIO ready PPI guid, gOvmfTpmMmioAccessiblePpiGuid
- Mark TPM MMIO range as un-encrypted during PEI phase for an SEV-ES
guest and install the TPM MMIO ready PPI guid.
- Update the Tcg2Config Depex to ensure the new PEIM runs before the
Tcg2Config PEIM

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

---

These patches are based on commit:
ab957f036f67 ("BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]")

Changes since:

v2:
- Update the TPM PEIM to only perform the mapping change when SEV-ES is
active (with a comment in the code to explain why).
- Update the TPM PEIM file header comment.
- Updates to the INF file (INF_VERSION, Packages, LibraryClasses, etc.).
- Updates to PEIM file order in DSC and FDF files.
- Split out Tcg2Config Depex change to a separate patch.

v1:
- Create a TPM PEIM that will map the TPM address range as unencrypted and
install a new PPI to indicate the mapping change is complete.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Stefan Berger <stefanb@linux.ibm.com>

Tom Lendacky (5):
OvfmPkg/VmgExitLib: Properly decode MMIO MOVZX and MOVSX opcodes
OvmfPkg/VmgExitLib: Add support for new MMIO MOV opcodes
OvmfPkg: Define a new PPI GUID to signal TPM MMIO accessability
OvmfPkg/Tcg2ConfigPei: Mark TPM MMIO range as unencrypted for SEV-ES
OvmfPkg/Tcg2ConfigPei: Update Depex for IA32 and X64

OvmfPkg/OvmfPkg.dec | 4 +
OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/AmdSev/AmdSevX64.fdf | 1 +
OvmfPkg/OvmfPkgIa32.fdf | 1 +
OvmfPkg/OvmfPkgIa32X64.fdf | 1 +
OvmfPkg/OvmfPkgX64.fdf | 1 +
OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf | 2 +-
OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf | 40 +++++++
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 120 +++++++++++++++++++-
OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c | 87 ++++++++++++++
13 files changed, 258 insertions(+), 3 deletions(-)
create mode 100644 OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
create mode 100644 OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c

--
2.31.0


Re: Problem: TPM 2.0 event log by OVMF is shown empty in Linux kernel versions after 5.8

Thore Sommer <public@...>
 

I think I found my problem.
The latest kernel from master probes if the table actually includes some values. This was introduced in 3dcd15665aca80197333500a4be3900948afccc1
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3dcd15665aca80197333500a4be3900948afccc1

This commit is not in the 5.12 release, but is in the latest master branch.

Thank you for helping me troubleshoot this problem.
I've learned a lot over the last few days.

Thore


Re: Problem: TPM 2.0 event log by OVMF is shown empty in Linux kernel versions after 5.8

Thore Sommer <public@...>
 

This is somewhat tricky to get right in grub, so you
can rule this out by booting ovmf to a shell and then executing vmlinuz
directly from the shell.
I've now tried this and unfortunately it produces the same result.
The ACPI "TPM2" table is there and the tpm eventlog is empty.

Thore


Re: 回复: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64

Rebecca Cran <rebecca@...>
 

On 4/28/21 7:13 PM, gaoliming wrote:
Rebecca:

-----邮件原件-----
发件人: Rebecca Cran <rebecca@nuviainc.com>
发送时间: 2021年4月29日 4:44
收件人: devel@edk2.groups.io
抄送: Rebecca Cran <rebecca@nuviainc.com>; Jiewen Yao
<jiewen.yao@intel.com>; Jian J Wang <jian.j.wang@intel.com>; Michael D
Kinney <michael.d.kinney@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Ard
Biesheuvel <ardb+tianocore@kernel.org>; Sami Mujawar
<Sami.Mujawar@arm.com>
主题: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64

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.dsc |
11 +-
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf |
19 +++-
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h |
37 ++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h |
0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h |
0
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h |
88 ++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c |
54 +++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c |
108 ++++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c |
0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c |
0
SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c |
120 ++++++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c |
117 ++++---------------
12 files changed, 450 insertions(+), 104 deletions(-)

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/SecureBootConfigD
xe.inf

@@ -334,11 +340,6 @@ [Components.IA32, Components.X64]

SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresence
Lib.inf

SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2Physic
alPresenceLib.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..c188b6076c00 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
@@ -26,15 +26,24 @@ [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
+ AArch64/Rndr.c
+ AArch64/Rndr.h

[Packages]
MdePkg/MdePkg.dec
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
new file mode 100644
index 000000000000..458faa834a3d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
@@ -0,0 +1,37 @@
+/** @file
+ Header for the RNDR APIs used by RNG DXE driver.
+
+ Support API definitions for RNDR instruction access.
+
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RNDR_H_
+#define RNDR_H_
+
+#include <Library/BaseLib.h>
+#include <Protocol/Rng.h>
+
+/**
+ Calls RNDR 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
+RndrGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ );
+
+#endif // RNDR_H_
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 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
new file mode 100644
index 000000000000..7e38fc2564f6
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
@@ -0,0 +1,88 @@
+/** @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_
+
+extern EFI_RNG_ALGORITHM *mSUpportedRngAlgorithms;
+
+/**
+ 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 the size of the RNG algorithms structure.
+
+ @return Size of the EFI_RNG_ALGORITHM list.
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithmsSize (
+ VOID
+ );
+
+#endif // RNGDXE_INTERNALS_H_
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
new file mode 100644
index 000000000000..36166a9cbc13
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
@@ -0,0 +1,54 @@
+/** @file
+ Support routines for RNDR instruction access.
+
+ 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/BaseMemoryLib.h>
+#include <Library/RngLib.h>
+
+#include "Rndr.h"
+
+/**
+ Calls RNDR 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
+RndrGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ )
+{
+ BOOLEAN IsRandom;
+ UINT64 TempRand;
+
+ while (Length > 0) {
+ IsRandom = GetRandomNumber64 (&TempRand);
+ if (!IsRandom) {
+ return EFI_NOT_READY;
+ }
+ if (Length >= sizeof (TempRand)) {
+ WriteUnaligned64 ((UINT64*)RandBuffer, TempRand);
+ RandBuffer += sizeof (UINT64);
+ Length -= sizeof (TempRand);
+ } else {
+ CopyMem (RandBuffer, &TempRand, Length);
+ Length = 0;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
Can this function be shared between X86 and AARCH64?
Yes. I've removed it, and will send out a v2 series.

--
Rebecca Cran


Re: [edk2][PATCH 1/1] MdeModulePkg/UefiBootManagerLib: Signal ReadyToBoot on platform recovery

Samer El-Haj-Mahmoud
 

All,

Please take a moment to add any comments to this UEFI ECR BZ. This is needed to UEFI Forum can make a decision and close the ECR.
https://bugzilla.tianocore.org/show_bug.cgi?id=3336


Thanks,
--Samer

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Samer
El-Haj-Mahmoud via groups.io
Sent: Tuesday, April 13, 2021 3:48 PM
To: devel@edk2.groups.io; pete@akeo.ie; Laszlo Ersek
<lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Ni, Ray
<ray.ni@intel.com>; zhichao.gao@intel.com
Cc: Andrei Warkentin (awarkentin@vmware.com)
<awarkentin@vmware.com>; Ard Biesheuvel <ardb+tianocore@kernel.org>;
Andrew Fish <afish@apple.com>; Michael D Kinney
<michael.d.kinney@intel.com>; Jian J Wang <jian.j.wang@intel.com>; Hao A
Wu <hao.a.wu@intel.com>; Sunny.Hsuanwen.Wang@gmail.com; Samer El-
Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>; Sunny Wang
<Sunny.Wang@arm.com>
Subject: Re: [edk2-devel] [edk2][PATCH 1/1]
MdeModulePkg/UefiBootManagerLib: Signal ReadyToBoot on platform
recovery

In order to make progress on this, I opened a code-first ECR against the UEFI
spec to clarify the language around the Boot#### options processing.

Code First ECR: https://bugzilla.tianocore.org/show_bug.cgi?id=3336

Feedback on the proposed language is appreciated. Please provide the
feedback directly in the BZ above.

I will update the thread/BZ with results from USWG.

Thanks,
--Samer

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Pete
Batard via groups.io
Sent: Thursday, February 25, 2021 5:55 AM
To: Wang, Sunny (HPS SW) <sunnywang@hpe.com>; Laszlo Ersek
<lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>;
devel@edk2.groups.io; Ni, Ray <ray.ni@intel.com>;
zhichao.gao@intel.com
Cc: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>; Andrei
Warkentin (awarkentin@vmware.com) <awarkentin@vmware.com>; Ard
Biesheuvel <ardb+tianocore@kernel.org>; Andrew Fish
<afish@apple.com>;
Michael D Kinney <michael.d.kinney@intel.com>; Jian J Wang
<jian.j.wang@intel.com>; Hao A Wu <hao.a.wu@intel.com>;
Sunny.Hsuanwen.Wang@gmail.com
Subject: Re: [edk2-devel] [edk2][PATCH 1/1]
MdeModulePkg/UefiBootManagerLib: Signal ReadyToBoot on platform
recovery

Hi Sunny,

I appreciate the input, but seeing that it is clear that no consensus
has been reached with regards to how the specs should be interpreted,
and that at least 4 separate people have now indicated that their
interpretation is different from the one you are putting forward (i.e.
you assert that the current code implementation is specs compliant
whereas we assert that the current code implementation is not specs
compliant), I believe that any further work on this will have to be
conditioned, first, by a specs update, that removes any ambiguity as
to the scope in which ReadyToBoot should apply.

Until that has happened, it seems very pointless to me to start
talking possible code workarounds, because we still can't appear to be
in agreement as to whether the current code implementation of
ReadyToBoot is specs compliant or not.

Now, even as I am the one proposing it, I'm afraid that I am not
planning to be the one opening a formal specs update request, since
there really is only so much more time I am willing to devote to this
matter. But I am hoping somebody else will.

Regards,

/Pete

On 2021.02.22 09:28, Wang, Sunny (HPS SW) wrote:
Hi all,

How about we signal ReadyToBoot ONLY for the default platform
recovery
option? The default platform recovery option here means the one
created by the code below in BdsEntry().
Status = EfiBootManagerInitializeLoadOption (
&PlatformDefaultBootOption,
LoadOptionNumberUnassigned,
LoadOptionTypePlatformRecovery,
LOAD_OPTION_ACTIVE,
L"Default PlatformRecovery",
FilePath,
NULL,
0
);

In other words, we just need to slightly update Pete's patch as the
following (adding the code below to EfiBootManagerProcessLoadOption()):

+ if ((LoadOption->OptionType == LoadOptionTypePlatformRecovery)
+ &&
StrCmp (LoadOption ->Description, L"Default
PlatformRecovery")) {
+ //
+ // Signal the EVT_SIGNAL_READY_TO_BOOT event when we are
about
to load and execute the boot option.
+ //
+ EfiSignalEventReadyToBoot ();

+ //
+ // Report Status Code to indicate ReadyToBoot was signalled
+ //
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE,
+ (EFI_SOFTWARE_DXE_BS_DRIVER |
+ EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
+ }

I think the existing platforms that have their platform-specific
PlatformRecovery option may also do either of the following things to
make the system have no chance to load the default platform recovery
option because they do have a better way to recover the boot options:
1. Make their PlatformRecovery option have higher priority than
the
default platform recovery option (has a lower number (####) than the
default platform recovery option)
2. Remove the default platform recovery option.
Therefore, if we only signal ReadyToBoot for the default platform
recovery
option, this may not affect the existing platforms because the code
may never be run on these platforms.





If the solution above doesn't work, I think the suggestion (Solution 2:
adding a new application as a PlatformRecovery####) I mentioned, in
the beginning, can be re-considered. The suggestion (solution 2) is
based on the thoughts below:
1. I think that processing/evaluating the Boot#### can be
interpreted as
the code after the comment " 6. Load EFI boot option to ImageHandle"
in
EfiBootManagerBoot() because these code are similar to the code in
EfiBootManagerProcessLoadOption(). Based on this, I think our current
implementation is compliant with the description below in the UEFI
spec. Of course, we can improve our implementation by moving the code
for processing/evaluating the Boot#### from EfiBootManagerBoot() to
EfiBootManagerProcessLoadOption() and make EfiBootManagerBoot() call
EfiBootManagerProcessLoadOption().
“After all SysPrep#### variables have been launched
and exited,
the platform shall notify EFI_EVENT_GROUP_READY_TO_BOOT event
group
and begin to evaluate Boot#### variables with Attributes set to
LOAD_OPTION_CATEGORY_BOOT according to the order defined by
BootOrder.
The FilePathList of variables marked LOAD_OPTION_CATEGORY_BOOT shall
not be evaluated prior to the completion of
EFI_EVENT_GROUP_READY_TO_BOOT event group processing."
2. Moreover, it looks like we want to process
PlatformRecovery####
option in the same way as Boot#### (do more things like setting
BootCurrent for PlatformRecovery####). If so, I would still prefer to
do what I suggest in the beginning to create a new application as a
new PlatformRecovery#### option for generating and launching a boot
option for the bootable image that is found by using a short-form File
Path Media Device Path so that we won't run into other difficulties.
At least, I already saw the difficulty of no connection between
BootCurrent variable and PlatformRecovery#### variable. Of course,
this application can be implemented without platform specific stuff,
so it can be commonly used by all platforms that need to load a boot image
discovered by using short-form File Path Media Device Path.




Regards,
Sunny Wang

-----Original Message-----
From: Laszlo Ersek <lersek@redhat.com>
Sent: Wednesday, February 17, 2021 10:26 PM
To: Pete Batard <pete@akeo.ie>; Leif Lindholm <leif@nuviainc.com>;
devel@edk2.groups.io
Cc: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>; Andrei
Warkentin (awarkentin@vmware.com) <awarkentin@vmware.com>;
Wang, Sunny
(HPS SW) <sunnywang@hpe.com>; zhichao.gao@intel.com;
ray.ni@intel.com;
Ard Biesheuvel <ardb+tianocore@kernel.org>; Andrew Fish
<afish@apple.com>; Michael D Kinney <michael.d.kinney@intel.com>;
Jian J Wang <jian.j.wang@intel.com>; Hao A Wu <hao.a.wu@intel.com>
Subject: Re: [EXTERNAL] Re: [edk2-devel] [edk2][PATCH 1/1]
MdeModulePkg/UefiBootManagerLib: Signal ReadyToBoot on platform
recovery

On 02/17/21 13:18, Pete Batard wrote:
Hi Leif,

Thanks for trying to resurrect this issue.

At this stage, and despite some initial pushback in the bugzilla
ticket, I believe we can all agree with the consensus that
UefiBootManagerLib is not in fact specs-compliant and therefore
needs to be fixed, one way or another, to make it specs-compliant.

My take on this is that, rather than propose a new patch, I'd much
rather have the current maintainers agree on the course of action
to fix the library (which, as Leif suggests, might very well be to
split the library into a specs-compliant and non-specs-compliant
version), as it would of course be better if the fix came from
people who have better understanding of the ramifications we might
face with trying to correct the current behaviour, and especially,
who have knowledge of the platforms that might be impacted from
making the lib specs-
compliant.

Especially, I don't think that the patch that I originally
submitted for this, or the additional proposals we made, are still
receivable, as they seem to fall short of fixing the issue in a
manner that all platforms can be happy with. And that is why I'd
like to hear from the maintainers on what their preferred approach
would be.

A new Feature PCD could satisfy both sets of platforms, could it not?

(Sorry if the original patch already had such a PCD; I don't
remember.)

Of course then we'd have a debate around the DEC default for the new
PCD
-- I'd say the default value of the PCD should match the
spec-mandated
behavior.

I don't recall any specifics, but a bug-compat pattern that's
sometimes used
is this:

if (BugCompatEnabled) {
//
// do the right thing in the wrong place, for legacy platforms' sake
//
Foo ();
}

//
// Do some stuff.
//
Bar ();

if (!BugCompatEnabled) {
//
// do the right thing in the right place, for conformant platforms
//
Foo ();
}

Not sure if it applies here.

Thanks
Laszlo


On 2021.02.17 11:42, Leif Lindholm wrote:
Hi Pete, +various

Resurrecting this old thread since Ard pointed out an issue I ran
into myself had already been encountered by Pete.
And the bugzilla ticket (directly below this reply) has had no
relevant progress since August.

Executive summary:
The current UefiBootManagerLib implementation of the
PlatformRecovery path does not notify the
EFI_EVENT_GROUP_READY_TO_BOOT event.

The argument has been made that since changing this would affect
an unnamed number of non-public platforms, the behaviour cannot be
changed even though it violates the UEFI specification.

I disagree with that statement. If we want to fork
UefiBootManagerLib into a BrokenLegacyUefiBootManagerLib and an
actually correct one, and have those platforms move to the
BrokenLegacy variant, I'm OK with that.

But using the default version should give specification-compliant
behaviour.

/
Leif

On Tue, Jun 30, 2020 at 18:17:10 +0100, Pete Batard wrote:
Please note that I have created a bug report
(https://bugzilla.tianocore.org/show_bug.cgi?id=2831) to address
the non-compliance issue was raised during the course of the
discussion below.

Regards,

/Pete


On 2020.06.17 18:06, Samer El-Haj-Mahmoud wrote:
I worked with Pete offline on this..

This code seems to be violating the UEFI Spec:

https://github.com/tianocore/edk2/blob/a56af23f066e2816c67b7c6e64d
e
7ddefcd70780/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c#L176
3


//
// 3. Signal the EVT_SIGNAL_READY_TO_BOOT event when we
are
about to load and execute
// the boot option.
//
if (BmIsBootManagerMenuFilePath (BootOption->FilePath)) {
DEBUG ((EFI_D_INFO, "[Bds] Booting Boot Manager Menu.\n"));
BmStopHotkeyService (NULL, NULL);
} else {
EfiSignalEventReadyToBoot();
//
// Report Status Code to indicate ReadyToBoot was signalled
//
REPORT_STATUS_CODE (EFI_PROGRESS_CODE,
(EFI_SOFTWARE_DXE_BS_DRIVER |
EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
//
// 4. Repair system through DriverHealth protocol
//
BmRepairAllControllers (0);
}

The UEFI Spec section 3.1.7 clearly states that Boot Options
(and their FilePathList) *shall not* be evaluated prior to the
completion of EFI_EVENT_GROUP_READY_TO_BOOT event group
processing:

"After all SysPrep#### variables have been launched and exited,
the platform shall notify EFI_EVENT_GROUP_READY_TO_BOOT
event
group and begin to evaluate Boot#### variables with Attributes
set to LOAD_OPTION_CATEGORY_BOOT according to the order
defined
by
BootOrder. The FilePathList of variables marked
LOAD_OPTION_CATEGORY_BOOT shall not be evaluated prior to
the
completion of EFI_EVENT_GROUP_READY_TO_BOOT event group
processing."

This is a prescriptive language that is stronger than the
language in section 7.1 which defines the ReadyToBoot event
group in a general way:

"EFI_EVENT_GROUP_RESET_SYSTEM
This event group is notified by the system when ResetSystem() is
invoked and the system is about to be reset. The event group is
only notified prior to ExitBootServices() invocation."

The EDK2 code in the else block above (to call
EfiSignalEventReadyToBoot() ) need to move before the code that
is processing BootOption->FilePath. In fact, why is this
signaling even a BootManager task? It should be a higher level
BDS task (after processing SysPrp and before processing Boot
options, per the
spec).
This would be somewhere around
https://github.com/tianocore/edk2/blob/b15646484eaffcf7cc464fdea02
1
4498f26addc2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c#L1007
where SysPrep is processed.

This should also take care of the issue Pete reported in this
thread, without the need for explicitly signaling ReadyToBoot
from PlatformRecovery (or changing the UEFI spec).

Thanks,
--Samer



From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
Samer El-Haj-Mahmoud via groups.io
Sent: Wednesday, June 17, 2020 12:42 PM
To: devel@edk2.groups.io; Andrei Warkentin
(awarkentin@vmware.com)
<awarkentin@vmware.com>; Wang, Sunny (HPS SW)
<sunnywang@hpe.com>;
pete@akeo.ie
Cc: zhichao.gao@intel.com; ray.ni@intel.com; Ard Biesheuvel
<Ard.Biesheuvel@arm.com>; leif@nuviainc.com; Samer El-Haj-
Mahmoud
<Samer.El-Haj-Mahmoud@arm.com>
Subject: Re: [edk2-devel] [edk2][PATCH 1/1]
MdeModulePkg/UefiBootManagerLib: Signal ReadyToBoot on
platform
recovery

The UEFI spec (3.1.7) says:

"After all SysPrep#### variables have been launched and exited,
the platform shall notify EFI_EVENT_GROUP_READY_TO_BOOT
event
group and begin to evaluate Boot#### variables with Attributes
set to LOAD_OPTION_CATEGORY_BOOT according to the order
defined
by
BootOrder. The FilePathList of variables marked
LOAD_OPTION_CATEGORY_BOOT shall not be evaluated prior to
the
completion of EFI_EVENT_GROUP_READY_TO_BOOT event group
processing."

The way I read this, I expect ReadyToBoot to be signaled after
SysPrep#### (if any) are processed, but before Boot#### are
processed. Is my understanding correct that this language
implies ReadyToBoot need to be signaled even if BootOrder does
not contain any Boot#### options marked as
LOAD_OPTION_CATEGORY_BOOT?
And if
so, is EDK2 not doing this, which leads us to this patch
(signaling it in PlatformRecovery?)



From: mailto:devel@edk2.groups.io
<mailto:devel@edk2.groups.io>
On
Behalf Of Andrei Warkentin via groups.io
Sent: Wednesday, June 17, 2020 12:37 PM
To: Wang, Sunny (HPS SW) <mailto:sunnywang@hpe.com>;
mailto:devel@edk2.groups.io; mailto:pete@akeo.ie
Cc: mailto:zhichao.gao@intel.com; mailto:ray.ni@intel.com; Ard
Biesheuvel <mailto:Ard.Biesheuvel@arm.com>;
mailto:leif@nuviainc.com
Subject: Re: [edk2-devel] [edk2][PATCH 1/1]
MdeModulePkg/UefiBootManagerLib: Signal ReadyToBoot on
platform
recovery

Thanks Pete.

I think the question I have, that I hope Tiano veterans can
chime in, is whether we are doing the right thing, or if we
should be overriding the boot mode? I.e. is it normal that we
boot up in recovery until options are saved?


A


________________________________________
From: mailto:devel@edk2.groups.io
<mailto:devel@edk2.groups.io>
on
behalf of Pete Batard via groups.io
<mailto:pete=akeo.ie@groups.io>
Sent: Wednesday, June 17, 2020 11:34 AM
To: Wang, Sunny (HPS SW) <mailto:sunnywang@hpe.com>;
mailto:devel@edk2.groups.io <mailto:devel@edk2.groups.io>
Cc: mailto:zhichao.gao@intel.com <mailto:zhichao.gao@intel.com>;
mailto:ray.ni@intel.com <mailto:ray.ni@intel.com>;
mailto:ard.biesheuvel@arm.com
<mailto:ard.biesheuvel@arm.com>;
mailto:leif@nuviainc.com <mailto:leif@nuviainc.com>
Subject: Re: [edk2-devel] [edk2][PATCH 1/1]
MdeModulePkg/UefiBootManagerLib: Signal ReadyToBoot on
platform
recovery

On 2020.06.17 14:04, Wang, Sunny (HPS SW) wrote:
Thanks for checking my comments, Pete.

Or is the "one more" the issue, meaning that it would get
signaled more than once?
[Sunny] Yeah, it would get signaled more than once if the
PlatformRecovery option (a UEFI application) calls
EfiBootManagerBoot() to launch the recovered boot option inside
of the application.
Okay.

One element that I'm going to point out is that, with the
current
EDK2 code (i.e. without this proposal applied), and after a user
goes into the setup to save their boot options in order for
regular boot options to get executed instead of PlaformRecovery,
the OnReadyToBoot event is actually called twice.

So my understanding is that, while we of course want to avoid
this and any patch proposal should actively try to prevent it,
it seems we already have behaviour in EDK2 that can lead to
OnReadyToBoot being signalled more than once.

At least the current Pi 4 platform does demonstrate this behaviour.
For instance, if you run DEBUG, you will see two instances of:

RemoveDtStdoutPath: could not retrieve DT blob - Not Found

which is a one-instance message generated from the
ConsolePrefDxe's
OnReadyToBoot() call. I've also confirmed more specifically that
OnReadyToBoot() is indeed called twice.

I don't recall us doing much of any special with regards to boot
options for the Pi platform, so my guess is that it's probably
not the only platform where OnReadyToBoot might be signalled
more
than
once, and that this might be tied to a default EDK2 behaviour.
Therefore I don't see having a repeated event as a major deal
breaker (though, again, if we can avoid that, we of course will
want to).

I don't mind trying an alternative approach, but I don't
understand how what you describe would help. Can you please
be
more specific about what you have in mind?
[Sunny] Sure. I added more information below. If it is still
not clear enough, feel free to let me know.
1. Create a UEFI application with the code to signal
ReadyToBoot and pick /efi/boot/bootaa64.efi from either SD or
USB and run it.
So that would basically be adding code that duplicates, in part,
what Platform Recovery already does.

I have to be honest: Even outside of the extra work this would
require, I don't really like the idea of having to write our own
application, as it will introduce new possible points of
failures and require extra maintenance (especially as we will
want to be able to handle network boot and other options, and
before long, I fear that we're going to have to write our own Pi
specific boot manager). Doing so simply because the current
Platform Recovery, which does suit our needs otherwise, is not
designed to call ReadyToBoot does not seem like the best course
of action in my book.

Instead, I still logically believe that any option that calls a
boot loader should signal ReadyToBoot, regardless of whether it
was launched from Boot Manager or Platform Recovery, and that it
shouldn't be left to each platform to work around that.

Of course, I understand that this would require a specs change,
and that it also may have ramifications for existing platforms
that interpret the current specs pedantically. But to me,
regardless of what the specs appear to be limiting it to right
now, the logic of a "ReadyToBoot"
event is that it should be signalled whenever a bootloader is
about to be executed, rather than only when a bootloader
happened to be launched through a formal Boot Manager option.

I would therefore appreciate if other people could weigh in on
this matter, to see if I'm the only one who believes that we
could ultimately have more to gain from signalling ReadyToBoot
with PlatformRecovery options than leaving things as they stand
right now...

2. Then, call EfiBootManagerInitializeLoadOption like
the following in a DXE driver or other places before "Default
PlatformRecovery" registration:
Status = EfiBootManagerInitializeLoadOption (
&LoadOption,

0,
-> 0 is the OptionNumber to let application be load before "
Default PlatformRecovery" option
LoadOptionTypePlatformRecovery,
LOAD_OPTION_ACTIVE,
L"Application for recovering boot options",

FilePath,
-> FilePath is the Application's device path,
NULL,
0
);


My reasoning is that, if PlatformRecovery#### can execute a
regular bootloader like /efi/boot/boot####.efi from
installation media, then it should go through the same kind of
initialization that happens for a regular boot option, and
that should include signaling the ReadyToBoot event.
[Sunny] Thanks for clarifying this, and Sorry about that I
missed your cover letter for this patch. I was just thinking
that we may not really need to make this behavior change in
both EDK II code and UEFI specification for solving the problem
specific to the case that OS is loaded by "Default
PlatformRecovery" option,
The way I see it is that the Pi platform is unlikely to be the
only one where PlatformRecovery is seen as a means to install an
OS.
Granted, this may seem like abusing the option, but since UEFI
doesn't provide an "Initial OS Install" mode, I would assert
that it as good a use of this option as any.

In other words, I don't think this improvement would only
benefit the Pi platform.

and I'm also not sure if it is worth making this change to
affect some of the system or BIOS vendors who have
implemented
their PlatformRecovery option.
That's a legitimate concern, and I would agree the one major
potential pitfall of this proposal, if there happens to exist a
system where an OnReadyToBoot even before running the
recovery
option can have adverse effects.

I don't really believe that such a system exists, because I
expect most recovery boot loaders to also work (or at least have
been designed to
work) as regular boot options. But I don't have enough
experience with platform recovery to know if that's a correct
assertion to make...

If the alternative approach I mentioned works for you, I think
that would be an easier solution.
Right now, even as the patch proposal has multiple issues that
require it to be amended (Don't signal ReadyToBoot except for
PlatformRecovery
+ Prevent situations where ReadyToBoot could be signalled
+ multiple
times) I still see it as both an easier solution than the
alternative, as well as one that *should* benefit people who
design Platform Recovery UEFI applications in the long run. So
that is why I am still trying to advocate for it.

But I very much hear your concerns, and I agree that specs
changes are better avoided when possible.

Thus, at this stage, even as I don't want to drag this
discussion much further, I don't feel like I want to commit to
one solution or the other before we have had a chance to hear
other people, who may have their own opinion on the matter,
express their views.

Regards,

/Pete



Regards,
Sunny Wang

-----Original Message-----
From: Pete Batard [mailto:pete@akeo.ie]
Sent: Wednesday, June 17, 2020 6:59 PM
To: Wang, Sunny (HPS SW) <mailto:sunnywang@hpe.com>;
mailto:devel@edk2.groups.io
Cc: mailto:zhichao.gao@intel.com; mailto:ray.ni@intel.com;
mailto:ard.biesheuvel@arm.com; mailto:leif@nuviainc.com
Subject: Re: [edk2-devel] [edk2][PATCH 1/1]
MdeModulePkg/UefiBootManagerLib: Signal ReadyToBoot on
platform
recovery

Hi Sunny, thanks for looking into this.

On 2020.06.17 09:16, Wang, Sunny (HPS SW) wrote:
Hi Pete.

Since the EfiBootManagerProcessLoadOption is called by
ProcessLoadOptions as well, your change would also cause some
unexpected behavior like:
1. Signal one more ReadyToBoot for the PlatformRecovery option
which is an application that calls EfiBootManagerBoot() to
launch its recovered boot option.
I'm not sure I understand how this part is unwanted.

The point of this patch is to ensure that ReadyToBoot is
signalled for the PlatformRecovery option, so isn't what you
describe above exactly what we want?

Or is the "one more" the issue, meaning that it would get
signalled more than once?


2. Signal ReadyToBoot for SysPrep#### or Driver#### that is
not really a "boot" option.
Yes, I've been wondering about that, because BdsEntry.c's
ProcessLoadOptions(), which calls
EfiBootManagerProcessLoadOption(),
mentions that it will load will load and start every
Driver####, SysPrep#### or PlatformRecovery####. But the
comment about the
while() loop in EfiBootManagerProcessLoadOption() only mentions
PlatformRecovery####.

If needed, I guess we could amend the patch to detect the type
of option and only signal ReadyToBoot for PlatformRecovery####.

To solve your problem, creating a PlatformRecovery option with
the smallest option number and using it instead of default one
(with short-form File Path Media Device Path) looks like a
simpler solution.
I don't mind trying an alternative approach, but I don't
understand how what you describe would help. Can you please be
more specific about what you have in mind?

Our main issue here is that we must have ReadyToBoot signalled
so that the ReadyToBoot() function callback from
EmbeddedPkg/Drivers/ConsolePrefDxe gets executed in order for
the
boot loader invoked from PlatformRecovery#### to use a
properly initialized graphical console. So I'm not sure I quite
get how switching from one PlatformRecovery#### option to
another would improve things.

If it helps, here is what we currently default to, in terms of
boot options, on a Raspberry Pi 4 platform with a newly build
firmware:

[Bds]=============Begin Load Options Dumping
...=============
Driver Options:
SysPrep Options:
Boot Options:
Boot0000: UiApp 0x0109
Boot0001: UEFI Shell 0x0000
PlatformRecovery Options:
PlatformRecovery0000: Default PlatformRecovery
0x0001 [Bds]=============End Load Options
Dumping=============

With this, PlatformRecovery0000 gets executed by default, which
is what we want, since it will pick /efi/boot/bootaa64.efi from
either SD or USB and run it, the only issue being that, because
ReadyToBoot has not been executed, the graphical console is not
operative so users can't interact with the OS installer.

So I'm really not sure how adding an extra PlatformRecovery####
would help. And I'm also not too familiar with how one would go
around to add such an entry...

By the way, I also checked the UEFI specification. It looks
making sense to only signal ReadyToBoot for boot option
(Boot####).

That's something I considered too, but I disagree with this
conclusion.

My reasoning is that, if PlatformRecovery#### can execute a
regular bootloader like /efi/boot/boot####.efi from
installation media, then it should go through the same kind of
initialization that happens for a regular boot option, and that
should include signalling the ReadyToBoot event.

If there was a special bootloader for PlatformRecovery#### (e.g.
/efi/boot/recovery####.efi) then I would agree with only
signalling ReadyToBoot for a formal Boot#### option. But that
isn't the case, so I think it is reasonable to want to have
ReadyToBoot also occur when a /efi/boot/boot####.efi
bootloader
is executed from PlatformRecovery####., especially when we
know
it can be crucial to ensuring that the end user can actually
use the
graphical console.

Therefore, your change may also require specification change.
Yes, I mentioned that in the cover letter for this patch
(https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%
2
Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F61327&amp;data=02%7C01%
7C
a
warkentin%40vmware.com%7C5f90d077bc7949c1122f08d812dc48d3%7Cb391
3
8
ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637280084611749324&amp;sdat
a
=
2%2B%2FcvMkrmZGTRRLDGSuMsKbiyDOGtwYwZ7qSqMyMicc%3D&amp;res
erved=0
), which also describes the issue we are trying to solve in
greater details. This is what I wrote:

---------------------------------------------------------------
--
-
------

Note however that this may require a specs update, as the
current UEFI specs for EFI_BOOT_SERVICES.CreateEventEx() have:

> EFI_EVENT_GROUP_READY_TO_BOOT
> This event group is notified by the system when the
Boot Manager
> is about to load and execute a boot option.

and, once this patch has been applied, we may want to update
this section to mention that it applies to both Boot Manager
and Platform Recovery.
---------------------------------------------------------------
--
-
------



Again, I don't have an issue with trying to use an alternate
approach to solve our problem (though I ultimately believe
that, if PlatformRecovery#### can launch a
/efi/boot/boot####.efi bootloader then we must update the
specs
and the code to have ReadyToBoot also signalled then, because
that's the logical thing to do). But right now, I'm not seeing
how to achieve that when PlatformRecovery#### is the option
that is used to launch the OS installation the bootloader. So
if you can provide mode details on how exactly you think
creating an alternate PlatformRecovery option would help, I would
appreciate it.

Regards,

/Pete


Regards,
Sunny Wang

-----Original Message-----
From: mailto:devel@edk2.groups.io
[mailto:devel@edk2.groups.io]
On Behalf Of Pete Batard
Sent: Tuesday, June 16, 2020 5:56 PM
To: mailto:devel@edk2.groups.io
Cc: mailto:zhichao.gao@intel.com; mailto:ray.ni@intel.com;
mailto:ard.biesheuvel@arm.com; mailto:leif@nuviainc.com
Subject: [edk2-devel] [edk2][PATCH 1/1]
MdeModulePkg/UefiBootManagerLib: Signal ReadyToBoot on
platform
recovery

Currently, the ReadyToBoot event is only signaled when a
formal Boot Manager option is executed (in BmBoot.c ->
EfiBootManagerBoot ()).

However, with the introduction of Platform Recovery in UEFI
2.5, which may lead to the execution of a boot loader that has
similar requirements to a regular one, yet is not launched as
a Boot Manager option, it also becomes necessary to signal
ReadyToBoot when a Platform Recovery boot loader runs.

Especially, this can be critical to ensuring that the
graphical console is actually usable during platform recovery,
as some platforms do rely on the ConsolePrefDxe driver, which
only performs console initialization after ReadyToBoot is
triggered.

This patch fixes that behaviour by calling
EfiSignalEventReadyToBoot () in
EfiBootManagerProcessLoadOption
(), which is the function that sets up the platform recovery
boot process.

Signed-off-by: Pete Batard <mailto:pete@akeo.ie>
---
MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c
| 9
+++++++++
1 file changed, 9 insertions(+)

diff --git
a/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c
b/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c
index 89372b3b97b8..117f1f5b124c 100644
---
a/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c
+++
b/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c
@@ -1376,6 +1376,15 @@ EfiBootManagerProcessLoadOption (
return EFI_SUCCESS;
}

+ //
+ // Signal the EVT_SIGNAL_READY_TO_BOOT event when we
are
+about
to load and execute the boot option.
+ //
+ EfiSignalEventReadyToBoot ();
+ //
+ // Report Status Code to indicate ReadyToBoot was signalled
+// REPORT_STATUS_CODE (EFI_PROGRESS_CODE,
(EFI_SOFTWARE_DXE_BS_DRIVER |
+ EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
+
//
// Load and start the load option.
//
--
2.21.0.windows.1




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

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





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



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


Re: [PATCH 3/3] Platform/RaspberryPi/AcpiTables: Correct _DMA consumer

Samer El-Haj-Mahmoud
 

Any further comments on the ACPI ECR documented in: https://bugzilla.tianocore.org/show_bug.cgi?id=3335 ?

 

I already have comments from Jeremey and Andrew saying it looks good. If there are no objections, I will let ASWG know to approve the ECR for future ACPI spec publication.

 

Thanks,

--Samer

 

 

 

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Samer El-Haj-Mahmoud via groups.io
Sent: Tuesday, April 13, 2021 12:45 PM
To: Andrei Warkentin (awarkentin@...) <awarkentin@...>; Jeremy Linton <Jeremy.Linton@...>; devel@edk2.groups.io
Cc: Ard Biesheuvel <Ard.Biesheuvel@...>; leif@...; pete@...; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: Re: [edk2-devel] [PATCH 3/3] Platform/RaspberryPi/AcpiTables: Correct _DMA consumer

 

I just got to this thread. Apologies for the delay.

 

I went through the ACPI spec. Here is what I see:

 

https://uefi.org/specs/ACPI/6.4/19_ASL_Reference/ACPI_Source_Language_Reference.html#qwordmemory-qword-memory-resource-descriptor-macro

 

ResourceUsage specifies whether the Memory range is consumed by this device (ResourceConsumer) or passed on to child devices (ResourceProducer). If nothing is specified, then ResourceConsumer is assumed.”
 
https://uefi.org/specs/ACPI/6.4/06_Device_Configuration/Device_Configuration.html#dma-direct-memory-access
 
“ It specifies the ranges the bus controller (bridge) decodes on the child-side of its interface. (This is analogous to the _CRS object, which describes the resources that the bus controller decodes on the parent-side of its interface.) Any ranges described in the resources of a _DMA object can be used by child devices for DMA or bus master transactions..”
 
The way I read the spec, this wording in the _DMA definition “Any ranges described in the resources of a _DMA object can be used by child devices..” suggests that this should be a ResourceProducer, per the QWordMemory resource descriptor definition above
 

The _DMA example in section 6.2.4 uses a “ResourceConsumer”, when it should really be “ResourceProducer” according to these definitions: It describes , the child devices view of the address range, so the "translation" added is the CPU's view of the same range.

 
I submitted a “code first” ECR to correct the ACPI spec example (here : https://bugzilla.tianocore.org/show_bug.cgi?id=3335). Please provide feedback on the BZ (or this thread) whether you agree or not, so we can take this to ASWG/UEFI Forum for discussion and approval
 
Thanks,
--Samer
 
 

 

From: Andrei Warkentin <awarkentin@...>
Sent: Thursday, April 8, 2021 10:24 AM
To: Jeremy Linton <Jeremy.Linton@...>; devel@edk2.groups.io
Cc: Ard Biesheuvel <Ard.Biesheuvel@...>; leif@...; pete@...; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: Re: [PATCH 3/3] Platform/RaspberryPi/AcpiTables: Correct _DMA consumer

 

I don't know... the ACPI spec is weird.

 

 

...lists ResourceConsumer for _DMA.

 

A

 


From: Jeremy Linton <jeremy.linton@...>
Sent: Thursday, April 8, 2021 12:58 AM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: ard.biesheuvel@... <ard.biesheuvel@...>; leif@... <leif@...>; pete@... <pete@...>; samer.el-haj-mahmoud@... <samer.el-haj-mahmoud@...>; Andrei Warkentin <awarkentin@...>; Jeremy Linton <jeremy.linton@...>
Subject: [PATCH 3/3] Platform/RaspberryPi/AcpiTables: Correct _DMA consumer

 

Bridge devices should be marked as producers so that their
children can consume the resources. In linux if this isn't
true then the translation gets ignored and the DMA values
are incorrect. This fixes DMA on all the devices that
need a translation.

Signed-off-by: Jeremy Linton <jeremy.linton@...>
---
 Platform/RaspberryPi/AcpiTables/Dsdt.asl | 2 +-
 Platform/RaspberryPi/AcpiTables/Emmc.asl | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Platform/RaspberryPi/AcpiTables/Dsdt.asl b/Platform/RaspberryPi/AcpiTables/Dsdt.asl
index d116f965e1..32cd5fc9f9 100644
--- a/Platform/RaspberryPi/AcpiTables/Dsdt.asl
+++ b/Platform/RaspberryPi/AcpiTables/Dsdt.asl
@@ -205,7 +205,7 @@ DefinitionBlock ("Dsdt.aml", "DSDT", 5, "RPIFDN", "RPI", 2)
         // Only the first GB is available.

         // Bus 0xC0000000 -> CPU 0x00000000.

         //

-        QWordMemory (ResourceConsumer,

+        QWordMemory (ResourceProducer,

           ,

           MinFixed,

           MaxFixed,

diff --git a/Platform/RaspberryPi/AcpiTables/Emmc.asl b/Platform/RaspberryPi/AcpiTables/Emmc.asl
index 179dd3ecdb..0fbc2a79ea 100644
--- a/Platform/RaspberryPi/AcpiTables/Emmc.asl
+++ b/Platform/RaspberryPi/AcpiTables/Emmc.asl
@@ -32,7 +32,7 @@ DefinitionBlock (__FILE__, "SSDT", 5, "RPIFDN", "RPI4EMMC", 2)
       }

 

       Name (_DMA, ResourceTemplate() {

-        QWordMemory (ResourceConsumer,

+        QWordMemory (ResourceProducer,

           ,

           MinFixed,

           MaxFixed,

--
2.13.7

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

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


Re: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64

Ard Biesheuvel
 

On Wed, 28 Apr 2021 at 22:44, Rebecca Cran <rebecca@nuviainc.com> wrote:

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.dsc | 11 +-
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf | 19 +++-
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h | 37 ++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h | 0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h | 0
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h | 88 ++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c | 54 +++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c | 108 ++++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c | 0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c | 0
SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c | 120 ++++++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c | 117 ++++---------------
12 files changed, 450 insertions(+), 104 deletions(-)

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..c188b6076c00 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
@@ -26,15 +26,24 @@ [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
+ AArch64/Rndr.c
+ AArch64/Rndr.h

[Packages]
MdePkg/MdePkg.dec
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
new file mode 100644
index 000000000000..458faa834a3d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
@@ -0,0 +1,37 @@
+/** @file
+ Header for the RNDR APIs used by RNG DXE driver.
+
+ Support API definitions for RNDR instruction access.
+
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RNDR_H_
+#define RNDR_H_
+
+#include <Library/BaseLib.h>
+#include <Protocol/Rng.h>
+
+/**
+ Calls RNDR 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
+RndrGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ );
+
+#endif // RNDR_H_
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 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
new file mode 100644
index 000000000000..7e38fc2564f6
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
@@ -0,0 +1,88 @@
+/** @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_
+
+extern EFI_RNG_ALGORITHM *mSUpportedRngAlgorithms;
+
+/**
+ 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 the size of the RNG algorithms structure.
+
+ @return Size of the EFI_RNG_ALGORITHM list.
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithmsSize (
+ VOID
+ );
+
+#endif // RNGDXE_INTERNALS_H_
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
new file mode 100644
index 000000000000..36166a9cbc13
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
@@ -0,0 +1,54 @@
+/** @file
+ Support routines for RNDR instruction access.
+
+ 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/BaseMemoryLib.h>
+#include <Library/RngLib.h>
+
+#include "Rndr.h"
+
+/**
+ Calls RNDR 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
+RndrGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ )
+{
+ BOOLEAN IsRandom;
+ UINT64 TempRand;
+
+ while (Length > 0) {
+ IsRandom = GetRandomNumber64 (&TempRand);
+ if (!IsRandom) {
+ return EFI_NOT_READY;
+ }
+ if (Length >= sizeof (TempRand)) {
+ WriteUnaligned64 ((UINT64*)RandBuffer, TempRand);
+ RandBuffer += sizeof (UINT64);
+ Length -= sizeof (TempRand);
+ } else {
+ CopyMem (RandBuffer, &TempRand, Length);
+ Length = 0;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
new file mode 100644
index 000000000000..18cca825e72d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
@@ -0,0 +1,108 @@
+/** @file
+ RNG Driver to produce the UEFI Random Number Generator protocol.
+
+ The driver will use the new RNDR 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 - Unsupported
+ - EFI_RNG_ALGORITHM_RAW - Supported
+ - 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) 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 "Rndr.h"
+
+//
+// Supported RNG Algorithms list by this driver.
+//
+EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
+ EFI_RNG_ALGORITHM_RAW

This is incorrect. Both flavors of RNDR return the output of a DRBG,
the only difference is how often they are reseeded.

We might need a PCD here to define which exact DRBG implementation is
used in the hardware, and set this accordingly. We could use a VOID*
PTR PCD type to carry the GUID itself, in which case we could reuse
the same code for x86 as well, if I am not mistaken.

--
Ard.


Re: Problem: TPM 2.0 event log by OVMF is shown empty in Linux kernel versions after 5.8

Thore Sommer <public@...>
 

So it looks like the empty acpi table theory doesn't fly.
What I meant was that the header of the tpm eventlog table is there, but table itself has no entries.
The ACPI "TPM2" table points to a valid tpm eventlog table.

I think my first attempt to create a OVMF debug output had not all information, so I attached a new one.

Thore


Re: [Patch V3 1/1] BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]

Bob Feng
 

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

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@intel.com>
Sent: Thursday, April 29, 2021 2:20 PM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>; Chen, Christine <yuwei.chen@intel.com>
Subject: [Patch V3 1/1] BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]

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

Update BaseTools to support new build targets, new tool chains, and new architectures declared in DSC file [BuildOptions] sections.

* Do not expand * when tools_def.txt is parsed. Only expand when
both tools_def.txt and DSC [BuilsOptions] sections have been parsed.
This also requires more flexible matching of tool keys that contain *
in tool key fields.

* Pre-scan the platform DSC file for FAMILY and TOOLCHAIN declarations
DSC in [BuildOptions] sections before the FAMILY and TOOLCHAIN need
to be known.

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.../Python/AutoGen/ModuleAutoGenHelper.py | 50 +++++---
.../Source/Python/AutoGen/PlatformAutoGen.py | 115 ++++++++++++++----
.../Python/Common/ToolDefClassObject.py | 19 +--
.../Python/GenFds/GenFdsGlobalVariable.py | 31 +++--
BaseTools/Source/Python/build/build.py | 111 ++++++++++++-----
5 files changed, 230 insertions(+), 96 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
index 7477b1d77fb8..167bb59d2315 100644
--- a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
+++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
@@ -173,17 +173,30 @@ class AutoGenInfo(object):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool in ToolDef and Family != "":
- FamilyIsNull = False
- if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
- continue
- else:
- if ToolDef[Tool].get(TAB_TOD_DEFINES_FAMILY, "") == "":
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
- continue
- FamilyMatch = True
+ if Family != "":
+ Found = False
+ if Tool in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_STAR in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if not Found:
+ continue
# expand any wildcard
if Target == TAB_STAR or Target == self.BuildTarget:
if Tag == TAB_STAR or Tag == self.ToolChain:
@@ -213,12 +226,19 @@ class AutoGenInfo(object):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool not in ToolDef or Family == "":
+ if Family == "":
continue
# option has been added before
- if TAB_TOD_DEFINES_FAMILY not in ToolDef[Tool]:
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = False
+ if Tool in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if TAB_STAR in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if not Found:
continue

# expand any wildcard
diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
index e2ef3256773e..21e72438e59e 100644
--- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
@@ -827,6 +827,33 @@ class PlatformAutoGen(AutoGen):
RetVal = RetVal + _SplitOption(Flags.strip())
return RetVal

+ ## Compute a tool defintion key priority value in range 0..15
+ #
+ # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE 15
+ # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE 14
+ # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE 13
+ # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE 12
+ # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE 11
+ # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE 10
+ # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE 9
+ # ******_*********_****_COMMANDTYPE_ATTRIBUTE 8
+ # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE 7
+ # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE 6
+ # TARGET_*********_ARCH_***********_ATTRIBUTE 5
+ # ******_*********_ARCH_***********_ATTRIBUTE 4
+ # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE 3
+ # ******_TOOLCHAIN_****_***********_ATTRIBUTE 2
+ # TARGET_*********_****_***********_ATTRIBUTE 1
+ # ******_*********_****_***********_ATTRIBUTE 0
+ #
+ def ToolDefinitionPriority (self,Key):
+ KeyList = Key.split('_')
+ Priority = 0
+ for Index in range (0, min(4, len(KeyList))):
+ if KeyList[Index] != '*':
+ Priority += (1 << Index)
+ return Priority
+
## Get tool chain definition
#
# Get each tool definition for given tool chain from tools_def.txt and platform @@ -839,8 +866,16 @@ class PlatformAutoGen(AutoGen):
ExtraData="[%s]" % self.MetaFile)
RetVal = OrderedDict()
DllPathList = set()
- for Def in ToolDefinition:
+
+ PrioritizedDefList = sorted(ToolDefinition.keys(), key=self.ToolDefinitionPriority, reverse=True)
+ for Def in PrioritizedDefList:
Target, Tag, Arch, Tool, Attr = Def.split("_")
+ if Target == TAB_STAR:
+ Target = self.BuildTarget
+ if Tag == TAB_STAR:
+ Tag = self.ToolChain
+ if Arch == TAB_STAR:
+ Arch = self.Arch
if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:
continue

@@ -850,9 +885,14 @@ class PlatformAutoGen(AutoGen):
DllPathList.add(Value)
continue

+ #
+ # ToolDefinition is sorted from highest priority to lowest priority.
+ # Only add the first(highest priority) match to RetVal
+ #
if Tool not in RetVal:
RetVal[Tool] = OrderedDict()
- RetVal[Tool][Attr] = Value
+ if Attr not in RetVal[Tool]:
+ RetVal[Tool][Attr] = Value

ToolsDef = ''
if GlobalData.gOptions.SilentMode and "MAKE" in RetVal:
@@ -860,9 +900,21 @@ class PlatformAutoGen(AutoGen):
RetVal["MAKE"]["FLAGS"] = ""
RetVal["MAKE"]["FLAGS"] += " -s"
MakeFlags = ''
- for Tool in RetVal:
- for Attr in RetVal[Tool]:
- Value = RetVal[Tool][Attr]
+
+ ToolList = list(RetVal.keys())
+ ToolList.sort()
+ for Tool in ToolList:
+ if Tool == TAB_STAR:
+ continue
+ AttrList = list(RetVal[Tool].keys())
+ if TAB_STAR in ToolList:
+ AttrList += list(RetVal[TAB_STAR])
+ AttrList.sort()
+ for Attr in AttrList:
+ if Attr in RetVal[Tool]:
+ Value = RetVal[Tool][Attr]
+ else:
+ Value = RetVal[TAB_STAR][Attr]
if Tool in self._BuildOptionWithToolDef(RetVal) and Attr in self._BuildOptionWithToolDef(RetVal)[Tool]:
# check if override is indicated
if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='):
@@ -877,7 +929,7 @@ class PlatformAutoGen(AutoGen):
if Attr == "PATH":
# Don't put MAKE definition in the file
if Tool != "MAKE":
- ToolsDef += "%s = %s\n" % (Tool, Value)
+ ToolsDef += "%s_%s = %s\n" % (Tool, Attr,
+ Value)
elif Attr != "DLL":
# Don't put MAKE definition in the file
if Tool == "MAKE":
@@ -1469,17 +1521,31 @@ class PlatformAutoGen(AutoGen):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool in ToolDef and Family != "":
- FamilyIsNull = False
- if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
- continue
- else:
- if ToolDef[Tool].get(TAB_TOD_DEFINES_FAMILY, "") == "":
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
- continue
- FamilyMatch = True
+ if Family != "":
+ Found = False
+ if Tool in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_STAR in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if not Found:
+ continue
+
# expand any wildcard
if Target == TAB_STAR or Target == self.BuildTarget:
if Tag == TAB_STAR or Tag == self.ToolChain:
@@ -1509,12 +1575,19 @@ class PlatformAutoGen(AutoGen):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool not in ToolDef or Family == "":
+ if Family == "":
continue
# option has been added before
- if TAB_TOD_DEFINES_FAMILY not in ToolDef[Tool]:
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = False
+ if Tool in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if TAB_STAR in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if not Found:
continue

# expand any wildcard
diff --git a/BaseTools/Source/Python/Common/ToolDefClassObject.py b/BaseTools/Source/Python/Common/ToolDefClassObject.py
index 8e70407cb9e9..2b4b23849196 100644
--- a/BaseTools/Source/Python/Common/ToolDefClassObject.py
+++ b/BaseTools/Source/Python/Common/ToolDefClassObject.py
@@ -1,7 +1,7 @@
## @file
# This file is used to define each component of tools_def.txt file # -# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights
+reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent #

@@ -86,23 +86,6 @@ class ToolDefClassObject(object):
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort()
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort()

- KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE]
- for Index in range(3, -1, -1):
- # make a copy of the keys to enumerate over to prevent issues when
- # adding/removing items from the original dict.
- for Key in list(self.ToolsDefTxtDictionary.keys()):
- List = Key.split('_')
- if List[Index] == TAB_STAR:
- for String in self.ToolsDefTxtDatabase[KeyList[Index]]:
- List[Index] = String
- NewKey = '%s_%s_%s_%s_%s' % tuple(List)
- if NewKey not in self.ToolsDefTxtDictionary:
- self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key]
- del self.ToolsDefTxtDictionary[Key]
- elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:
- del self.ToolsDefTxtDictionary[Key]
-
-
## IncludeToolDefFile
#
# Load target.txt file and parse it as if its contents were inside the main file diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
index 3019ec63c3bb..c31fc24870d5 100644
--- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -1,7 +1,7 @@
## @file
# Global variables for GenFds
#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights
+reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -875,14 +875,27 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
ToolOptionKey = None
KeyList = None
for tool_def in ToolDefinition.items():
- if NameGuid.lower() == tool_def[1].lower():
- KeyList = tool_def[0].split('_')
- Key = KeyList[0] + \
- '_' + \
- KeyList[1] + \
- '_' + \
- KeyList[2]
- if Key in KeyStringList and KeyList[4] == DataType.TAB_GUID:
+ KeyList = tool_def[0].split('_')
+ if len(KeyList) < 5:
+ continue
+ if KeyList[4] != DataType.TAB_GUID:
+ continue
+ if NameGuid.lower() != tool_def[1].lower():
+ continue
+ Key = KeyList[0] + \
+ '_' + \
+ KeyList[1] + \
+ '_' + \
+ KeyList[2]
+ for KeyString in KeyStringList:
+ KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
+ if KeyList[0] == DataType.TAB_STAR:
+ KeyList[0] = KeyStringBuildTarget
+ if KeyList[1] == DataType.TAB_STAR:
+ KeyList[1] = KeyStringToolChain
+ if KeyList[2] == DataType.TAB_STAR:
+ KeyList[2] = KeyStringArch
+ if KeyList[0] == KeyStringBuildTarget and KeyList[1] == KeyStringToolChain and KeyList[2] == KeyStringArch:
ToolPathKey = Key + '_' + KeyList[3] + '_PATH'
ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'
ToolPath = ToolDefinition.get(ToolPathKey) diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index c4cfe38ad96a..0570c29f1ada 100755
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -2,7 +2,7 @@
# build a platform or a module
#
# Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR> -# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights
+reserved.<BR>
# Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR> # Copyright (c) 2020, ARM Limited. All rights reserved.<BR> # @@ -889,6 +889,47 @@ class Build():
except:
return False, UNKNOWN_ERROR

+ ## Add TOOLCHAIN and FAMILY declared in DSC [BuildOptions] to ToolsDefTxtDatabase.
+ #
+ # Loop through the set of build targets, tool chains, and archs provided on either
+ # the command line or in target.txt to discover FAMILY and TOOLCHAIN delclarations
+ # in [BuildOptions] sections that may be within !if expressions that may use
+ # $(TARGET), $(TOOLCHAIN), $(TOOLCHAIN_TAG), or $(ARCH) operands.
+ #
+ def GetToolChainAndFamilyFromDsc (self, File):
+ for BuildTarget in self.BuildTargetList:
+ GlobalData.gGlobalDefines['TARGET'] = BuildTarget
+ for BuildToolChain in self.ToolChainList:
+ GlobalData.gGlobalDefines['TOOLCHAIN'] = BuildToolChain
+ GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = BuildToolChain
+ for BuildArch in self.ArchList:
+ GlobalData.gGlobalDefines['ARCH'] = BuildArch
+ dscobj = self.BuildDatabase[File, BuildArch]
+ for KeyFamily, Key, KeyCodeBase in dscobj.BuildOptions:
+ try:
+ Target, ToolChain, Arch, Tool, Attr = Key.split('_')
+ except:
+ continue
+ if ToolChain == TAB_STAR or Attr != TAB_TOD_DEFINES_FAMILY:
+ continue
+ try:
+ Family = dscobj.BuildOptions[(KeyFamily, Key, KeyCodeBase)]
+ Family = Family.strip().strip('=').strip()
+ except:
+ continue
+ if TAB_TOD_DEFINES_FAMILY not in self.ToolDef.ToolsDefTxtDatabase:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY] = {}
+ if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][ToolChain] = Family
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY not in self.ToolDef.ToolsDefTxtDatabase:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY] = {}
+ if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][ToolChain] = Family
+ if TAB_TOD_DEFINES_TOOL_CHAIN_TAG not in self.ToolDef.ToolsDefTxtDatabase:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = []
+ if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]:
+
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].appen
+ d(ToolChain)
+
## Load configuration
#
# This method will parse target.txt and get the build configurations.
@@ -910,6 +951,26 @@ class Build():
if self.ToolChainList is None or len(self.ToolChainList) == 0:
EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.\n")

+ if not self.PlatformFile:
+ PlatformFile = self.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_ACTIVE_PLATFORM]
+ if not PlatformFile:
+ # Try to find one in current directory
+ WorkingDirectory = os.getcwd()
+ FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc')))
+ FileNum = len(FileList)
+ if FileNum >= 2:
+ EdkLogger.error("build", OPTION_MISSING,
+ ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum, WorkingDirectory))
+ elif FileNum == 1:
+ PlatformFile = FileList[0]
+ else:
+ EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
+ ExtraData="No active platform
+ specified in target.txt or command line! Nothing can be built.\n")
+
+ self.PlatformFile = PathClass(NormFile(PlatformFile,
+ self.WorkspaceDir), self.WorkspaceDir)
+
+ self.GetToolChainAndFamilyFromDsc (self.PlatformFile)
+
# check if the tool chains are defined or not
NewToolChainList = []
for ToolChain in self.ToolChainList:
@@ -935,23 +996,6 @@ class Build():
ToolChainFamily.append(ToolDefinition[TAB_TOD_DEFINES_FAMILY][Tool])
self.ToolChainFamily = ToolChainFamily

- if not self.PlatformFile:
- PlatformFile = self.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_ACTIVE_PLATFORM]
- if not PlatformFile:
- # Try to find one in current directory
- WorkingDirectory = os.getcwd()
- FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc')))
- FileNum = len(FileList)
- if FileNum >= 2:
- EdkLogger.error("build", OPTION_MISSING,
- ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum, WorkingDirectory))
- elif FileNum == 1:
- PlatformFile = FileList[0]
- else:
- EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
- ExtraData="No active platform specified in target.txt or command line! Nothing can be built.\n")
-
- self.PlatformFile = PathClass(NormFile(PlatformFile, self.WorkspaceDir), self.WorkspaceDir)
self.ThreadNumber = ThreadNum()
## Initialize build configuration
#
@@ -2381,24 +2425,25 @@ class Build():
continue

for Arch in self.ArchList:
- # Build up the list of supported architectures for this build
- prefix = '%s_%s_%s_' % (BuildTarget, ToolChain, Arch)
-
# Look through the tool definitions for GUIDed tools
guidAttribs = []
for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.items():
- if attrib.upper().endswith('_GUID'):
- split = attrib.split('_')
- thisPrefix = '_'.join(split[0:3]) + '_'
- if thisPrefix == prefix:
- guid = self.ToolDef.ToolsDefTxtDictionary[attrib]
- guid = guid.lower()
- toolName = split[3]
- path = '_'.join(split[0:4]) + '_PATH'
- path = self.ToolDef.ToolsDefTxtDictionary[path]
- path = self.GetRealPathOfTool(path)
- guidAttribs.append((guid, toolName, path))
-
+ GuidBuildTarget, GuidToolChain, GuidArch, GuidTool, GuidAttr = attrib.split('_')
+ if GuidAttr.upper() == 'GUID':
+ if GuidBuildTarget == TAB_STAR:
+ GuidBuildTarget = BuildTarget
+ if GuidToolChain == TAB_STAR:
+ GuidToolChain = ToolChain
+ if GuidArch == TAB_STAR:
+ GuidArch = Arch
+ if GuidBuildTarget == BuildTarget and GuidToolChain == ToolChain and GuidArch == Arch:
+ path = '_'.join(attrib.split('_')[:-1]) + '_PATH'
+ if path in self.ToolDef.ToolsDefTxtDictionary:
+ path = self.ToolDef.ToolsDefTxtDictionary[path]
+ path = self.GetRealPathOfTool(path)
+ guidAttribs.append((value.lower(), GuidTool, path))
+ # Sort by GuidTool name
+ sorted (guidAttribs, key=lambda x: x[1])
# Write out GuidedSecTools.txt
toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt')
toolsFile = open(toolsFile, 'wt')
--
2.31.1.windows.1


[Patch V3 1/1] BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]

Michael D Kinney
 

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

Update BaseTools to support new build targets, new tool chains,
and new architectures declared in DSC file [BuildOptions] sections.

* Do not expand * when tools_def.txt is parsed. Only expand when
both tools_def.txt and DSC [BuilsOptions] sections have been parsed.
This also requires more flexible matching of tool keys that contain *
in tool key fields.

* Pre-scan the platform DSC file for FAMILY and TOOLCHAIN declarations
DSC in [BuildOptions] sections before the FAMILY and TOOLCHAIN need
to be known.

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.../Python/AutoGen/ModuleAutoGenHelper.py | 50 +++++---
.../Source/Python/AutoGen/PlatformAutoGen.py | 115 ++++++++++++++----
.../Python/Common/ToolDefClassObject.py | 19 +--
.../Python/GenFds/GenFdsGlobalVariable.py | 31 +++--
BaseTools/Source/Python/build/build.py | 111 ++++++++++++-----
5 files changed, 230 insertions(+), 96 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
index 7477b1d77fb8..167bb59d2315 100644
--- a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
+++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
@@ -173,17 +173,30 @@ class AutoGenInfo(object):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool in ToolDef and Family != "":
- FamilyIsNull = False
- if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
- continue
- else:
- if ToolDef[Tool].get(TAB_TOD_DEFINES_FAMILY, "") == "":
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
- continue
- FamilyMatch = True
+ if Family != "":
+ Found = False
+ if Tool in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_STAR in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if not Found:
+ continue
# expand any wildcard
if Target == TAB_STAR or Target == self.BuildTarget:
if Tag == TAB_STAR or Tag == self.ToolChain:
@@ -213,12 +226,19 @@ class AutoGenInfo(object):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool not in ToolDef or Family == "":
+ if Family == "":
continue
# option has been added before
- if TAB_TOD_DEFINES_FAMILY not in ToolDef[Tool]:
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = False
+ if Tool in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if TAB_STAR in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if not Found:
continue

# expand any wildcard
diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
index e2ef3256773e..21e72438e59e 100644
--- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
@@ -827,6 +827,33 @@ class PlatformAutoGen(AutoGen):
RetVal = RetVal + _SplitOption(Flags.strip())
return RetVal

+ ## Compute a tool defintion key priority value in range 0..15
+ #
+ # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE 15
+ # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE 14
+ # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE 13
+ # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE 12
+ # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE 11
+ # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE 10
+ # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE 9
+ # ******_*********_****_COMMANDTYPE_ATTRIBUTE 8
+ # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE 7
+ # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE 6
+ # TARGET_*********_ARCH_***********_ATTRIBUTE 5
+ # ******_*********_ARCH_***********_ATTRIBUTE 4
+ # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE 3
+ # ******_TOOLCHAIN_****_***********_ATTRIBUTE 2
+ # TARGET_*********_****_***********_ATTRIBUTE 1
+ # ******_*********_****_***********_ATTRIBUTE 0
+ #
+ def ToolDefinitionPriority (self,Key):
+ KeyList = Key.split('_')
+ Priority = 0
+ for Index in range (0, min(4, len(KeyList))):
+ if KeyList[Index] != '*':
+ Priority += (1 << Index)
+ return Priority
+
## Get tool chain definition
#
# Get each tool definition for given tool chain from tools_def.txt and platform
@@ -839,8 +866,16 @@ class PlatformAutoGen(AutoGen):
ExtraData="[%s]" % self.MetaFile)
RetVal = OrderedDict()
DllPathList = set()
- for Def in ToolDefinition:
+
+ PrioritizedDefList = sorted(ToolDefinition.keys(), key=self.ToolDefinitionPriority, reverse=True)
+ for Def in PrioritizedDefList:
Target, Tag, Arch, Tool, Attr = Def.split("_")
+ if Target == TAB_STAR:
+ Target = self.BuildTarget
+ if Tag == TAB_STAR:
+ Tag = self.ToolChain
+ if Arch == TAB_STAR:
+ Arch = self.Arch
if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:
continue

@@ -850,9 +885,14 @@ class PlatformAutoGen(AutoGen):
DllPathList.add(Value)
continue

+ #
+ # ToolDefinition is sorted from highest priority to lowest priority.
+ # Only add the first(highest priority) match to RetVal
+ #
if Tool not in RetVal:
RetVal[Tool] = OrderedDict()
- RetVal[Tool][Attr] = Value
+ if Attr not in RetVal[Tool]:
+ RetVal[Tool][Attr] = Value

ToolsDef = ''
if GlobalData.gOptions.SilentMode and "MAKE" in RetVal:
@@ -860,9 +900,21 @@ class PlatformAutoGen(AutoGen):
RetVal["MAKE"]["FLAGS"] = ""
RetVal["MAKE"]["FLAGS"] += " -s"
MakeFlags = ''
- for Tool in RetVal:
- for Attr in RetVal[Tool]:
- Value = RetVal[Tool][Attr]
+
+ ToolList = list(RetVal.keys())
+ ToolList.sort()
+ for Tool in ToolList:
+ if Tool == TAB_STAR:
+ continue
+ AttrList = list(RetVal[Tool].keys())
+ if TAB_STAR in ToolList:
+ AttrList += list(RetVal[TAB_STAR])
+ AttrList.sort()
+ for Attr in AttrList:
+ if Attr in RetVal[Tool]:
+ Value = RetVal[Tool][Attr]
+ else:
+ Value = RetVal[TAB_STAR][Attr]
if Tool in self._BuildOptionWithToolDef(RetVal) and Attr in self._BuildOptionWithToolDef(RetVal)[Tool]:
# check if override is indicated
if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='):
@@ -877,7 +929,7 @@ class PlatformAutoGen(AutoGen):
if Attr == "PATH":
# Don't put MAKE definition in the file
if Tool != "MAKE":
- ToolsDef += "%s = %s\n" % (Tool, Value)
+ ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)
elif Attr != "DLL":
# Don't put MAKE definition in the file
if Tool == "MAKE":
@@ -1469,17 +1521,31 @@ class PlatformAutoGen(AutoGen):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool in ToolDef and Family != "":
- FamilyIsNull = False
- if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
- continue
- else:
- if ToolDef[Tool].get(TAB_TOD_DEFINES_FAMILY, "") == "":
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
- continue
- FamilyMatch = True
+ if Family != "":
+ Found = False
+ if Tool in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_STAR in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if not Found:
+ continue
+
# expand any wildcard
if Target == TAB_STAR or Target == self.BuildTarget:
if Tag == TAB_STAR or Tag == self.ToolChain:
@@ -1509,12 +1575,19 @@ class PlatformAutoGen(AutoGen):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool not in ToolDef or Family == "":
+ if Family == "":
continue
# option has been added before
- if TAB_TOD_DEFINES_FAMILY not in ToolDef[Tool]:
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = False
+ if Tool in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if TAB_STAR in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if not Found:
continue

# expand any wildcard
diff --git a/BaseTools/Source/Python/Common/ToolDefClassObject.py b/BaseTools/Source/Python/Common/ToolDefClassObject.py
index 8e70407cb9e9..2b4b23849196 100644
--- a/BaseTools/Source/Python/Common/ToolDefClassObject.py
+++ b/BaseTools/Source/Python/Common/ToolDefClassObject.py
@@ -1,7 +1,7 @@
## @file
# This file is used to define each component of tools_def.txt file
#
-# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

@@ -86,23 +86,6 @@ class ToolDefClassObject(object):
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort()
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort()

- KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE]
- for Index in range(3, -1, -1):
- # make a copy of the keys to enumerate over to prevent issues when
- # adding/removing items from the original dict.
- for Key in list(self.ToolsDefTxtDictionary.keys()):
- List = Key.split('_')
- if List[Index] == TAB_STAR:
- for String in self.ToolsDefTxtDatabase[KeyList[Index]]:
- List[Index] = String
- NewKey = '%s_%s_%s_%s_%s' % tuple(List)
- if NewKey not in self.ToolsDefTxtDictionary:
- self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key]
- del self.ToolsDefTxtDictionary[Key]
- elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:
- del self.ToolsDefTxtDictionary[Key]
-
-
## IncludeToolDefFile
#
# Load target.txt file and parse it as if its contents were inside the main file
diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
index 3019ec63c3bb..c31fc24870d5 100644
--- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -1,7 +1,7 @@
## @file
# Global variables for GenFds
#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -875,14 +875,27 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
ToolOptionKey = None
KeyList = None
for tool_def in ToolDefinition.items():
- if NameGuid.lower() == tool_def[1].lower():
- KeyList = tool_def[0].split('_')
- Key = KeyList[0] + \
- '_' + \
- KeyList[1] + \
- '_' + \
- KeyList[2]
- if Key in KeyStringList and KeyList[4] == DataType.TAB_GUID:
+ KeyList = tool_def[0].split('_')
+ if len(KeyList) < 5:
+ continue
+ if KeyList[4] != DataType.TAB_GUID:
+ continue
+ if NameGuid.lower() != tool_def[1].lower():
+ continue
+ Key = KeyList[0] + \
+ '_' + \
+ KeyList[1] + \
+ '_' + \
+ KeyList[2]
+ for KeyString in KeyStringList:
+ KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
+ if KeyList[0] == DataType.TAB_STAR:
+ KeyList[0] = KeyStringBuildTarget
+ if KeyList[1] == DataType.TAB_STAR:
+ KeyList[1] = KeyStringToolChain
+ if KeyList[2] == DataType.TAB_STAR:
+ KeyList[2] = KeyStringArch
+ if KeyList[0] == KeyStringBuildTarget and KeyList[1] == KeyStringToolChain and KeyList[2] == KeyStringArch:
ToolPathKey = Key + '_' + KeyList[3] + '_PATH'
ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'
ToolPath = ToolDefinition.get(ToolPathKey)
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index c4cfe38ad96a..0570c29f1ada 100755
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -2,7 +2,7 @@
# build a platform or a module
#
# Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
-# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR>
# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
#
@@ -889,6 +889,47 @@ class Build():
except:
return False, UNKNOWN_ERROR

+ ## Add TOOLCHAIN and FAMILY declared in DSC [BuildOptions] to ToolsDefTxtDatabase.
+ #
+ # Loop through the set of build targets, tool chains, and archs provided on either
+ # the command line or in target.txt to discover FAMILY and TOOLCHAIN delclarations
+ # in [BuildOptions] sections that may be within !if expressions that may use
+ # $(TARGET), $(TOOLCHAIN), $(TOOLCHAIN_TAG), or $(ARCH) operands.
+ #
+ def GetToolChainAndFamilyFromDsc (self, File):
+ for BuildTarget in self.BuildTargetList:
+ GlobalData.gGlobalDefines['TARGET'] = BuildTarget
+ for BuildToolChain in self.ToolChainList:
+ GlobalData.gGlobalDefines['TOOLCHAIN'] = BuildToolChain
+ GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = BuildToolChain
+ for BuildArch in self.ArchList:
+ GlobalData.gGlobalDefines['ARCH'] = BuildArch
+ dscobj = self.BuildDatabase[File, BuildArch]
+ for KeyFamily, Key, KeyCodeBase in dscobj.BuildOptions:
+ try:
+ Target, ToolChain, Arch, Tool, Attr = Key.split('_')
+ except:
+ continue
+ if ToolChain == TAB_STAR or Attr != TAB_TOD_DEFINES_FAMILY:
+ continue
+ try:
+ Family = dscobj.BuildOptions[(KeyFamily, Key, KeyCodeBase)]
+ Family = Family.strip().strip('=').strip()
+ except:
+ continue
+ if TAB_TOD_DEFINES_FAMILY not in self.ToolDef.ToolsDefTxtDatabase:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY] = {}
+ if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][ToolChain] = Family
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY not in self.ToolDef.ToolsDefTxtDatabase:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY] = {}
+ if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][ToolChain] = Family
+ if TAB_TOD_DEFINES_TOOL_CHAIN_TAG not in self.ToolDef.ToolsDefTxtDatabase:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = []
+ if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].append(ToolChain)
+
## Load configuration
#
# This method will parse target.txt and get the build configurations.
@@ -910,6 +951,26 @@ class Build():
if self.ToolChainList is None or len(self.ToolChainList) == 0:
EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.\n")

+ if not self.PlatformFile:
+ PlatformFile = self.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_ACTIVE_PLATFORM]
+ if not PlatformFile:
+ # Try to find one in current directory
+ WorkingDirectory = os.getcwd()
+ FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc')))
+ FileNum = len(FileList)
+ if FileNum >= 2:
+ EdkLogger.error("build", OPTION_MISSING,
+ ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum, WorkingDirectory))
+ elif FileNum == 1:
+ PlatformFile = FileList[0]
+ else:
+ EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
+ ExtraData="No active platform specified in target.txt or command line! Nothing can be built.\n")
+
+ self.PlatformFile = PathClass(NormFile(PlatformFile, self.WorkspaceDir), self.WorkspaceDir)
+
+ self.GetToolChainAndFamilyFromDsc (self.PlatformFile)
+
# check if the tool chains are defined or not
NewToolChainList = []
for ToolChain in self.ToolChainList:
@@ -935,23 +996,6 @@ class Build():
ToolChainFamily.append(ToolDefinition[TAB_TOD_DEFINES_FAMILY][Tool])
self.ToolChainFamily = ToolChainFamily

- if not self.PlatformFile:
- PlatformFile = self.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_ACTIVE_PLATFORM]
- if not PlatformFile:
- # Try to find one in current directory
- WorkingDirectory = os.getcwd()
- FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc')))
- FileNum = len(FileList)
- if FileNum >= 2:
- EdkLogger.error("build", OPTION_MISSING,
- ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum, WorkingDirectory))
- elif FileNum == 1:
- PlatformFile = FileList[0]
- else:
- EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
- ExtraData="No active platform specified in target.txt or command line! Nothing can be built.\n")
-
- self.PlatformFile = PathClass(NormFile(PlatformFile, self.WorkspaceDir), self.WorkspaceDir)
self.ThreadNumber = ThreadNum()
## Initialize build configuration
#
@@ -2381,24 +2425,25 @@ class Build():
continue

for Arch in self.ArchList:
- # Build up the list of supported architectures for this build
- prefix = '%s_%s_%s_' % (BuildTarget, ToolChain, Arch)
-
# Look through the tool definitions for GUIDed tools
guidAttribs = []
for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.items():
- if attrib.upper().endswith('_GUID'):
- split = attrib.split('_')
- thisPrefix = '_'.join(split[0:3]) + '_'
- if thisPrefix == prefix:
- guid = self.ToolDef.ToolsDefTxtDictionary[attrib]
- guid = guid.lower()
- toolName = split[3]
- path = '_'.join(split[0:4]) + '_PATH'
- path = self.ToolDef.ToolsDefTxtDictionary[path]
- path = self.GetRealPathOfTool(path)
- guidAttribs.append((guid, toolName, path))
-
+ GuidBuildTarget, GuidToolChain, GuidArch, GuidTool, GuidAttr = attrib.split('_')
+ if GuidAttr.upper() == 'GUID':
+ if GuidBuildTarget == TAB_STAR:
+ GuidBuildTarget = BuildTarget
+ if GuidToolChain == TAB_STAR:
+ GuidToolChain = ToolChain
+ if GuidArch == TAB_STAR:
+ GuidArch = Arch
+ if GuidBuildTarget == BuildTarget and GuidToolChain == ToolChain and GuidArch == Arch:
+ path = '_'.join(attrib.split('_')[:-1]) + '_PATH'
+ if path in self.ToolDef.ToolsDefTxtDictionary:
+ path = self.ToolDef.ToolsDefTxtDictionary[path]
+ path = self.GetRealPathOfTool(path)
+ guidAttribs.append((value.lower(), GuidTool, path))
+ # Sort by GuidTool name
+ sorted (guidAttribs, key=lambda x: x[1])
# Write out GuidedSecTools.txt
toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt')
toolsFile = open(toolsFile, 'wt')
--
2.31.1.windows.1


Re: [Patch V2 1/1] BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]

Michael D Kinney
 

Hi Bob,

I found one issue with this latest patch. The elements of dscobj do not
provide the ToolChain value directly. It provides the key of the form:

TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE

+ dscobj = self.BuildDatabase[File, Arch]
+ for Family, ToolChain, CodeBase in dscobj.BuildOptions:
I have a V3 version of the patch that parses TOOLCHAIN and FAMILY strings from dscobj.

I will send that shortly.

Mike

-----Original Message-----
From: Feng, Bob C <bob.c.feng@intel.com>
Sent: Wednesday, April 28, 2021 6:12 PM
To: Kinney, Michael D <michael.d.kinney@intel.com>; devel@edk2.groups.io
Cc: Liming Gao <gaoliming@byosoft.com.cn>; Chen, Christine <yuwei.chen@intel.com>
Subject: RE: [Patch V2 1/1] BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]

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



-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@intel.com>
Sent: Thursday, April 29, 2021 7:35 AM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>; Chen, Christine <yuwei.chen@intel.com>
Subject: [Patch V2 1/1] BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]

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

Update BaseTools to support new build targets, new tool chains, and new architectures declared in DSC file [BuildOptions]
sections.

* Do not expand * when tools_def.txt is parsed. Only expand when
both tools_def.txt and DSC [BuilsOptions] sections have been parsed.
This also requires more flexible matching of tool keys that contain *
in tool key fields.

* Pre-scan the platform DSC file for FAMILY and TOOLCHAIN declarations
DSC in [BuildOptions] sections before the FAMILY and TOOLCHAIN need
to be known.

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.../Python/AutoGen/ModuleAutoGenHelper.py | 50 +++++---
.../Source/Python/AutoGen/PlatformAutoGen.py | 115 ++++++++++++++----
.../Python/Common/ToolDefClassObject.py | 19 +--
.../Python/GenFds/GenFdsGlobalVariable.py | 31 +++--
BaseTools/Source/Python/build/build.py | 100 ++++++++++-----
5 files changed, 219 insertions(+), 96 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
index 7477b1d77fb8..167bb59d2315 100644
--- a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
+++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
@@ -173,17 +173,30 @@ class AutoGenInfo(object):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool in ToolDef and Family != "":
- FamilyIsNull = False
- if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
- continue
- else:
- if ToolDef[Tool].get(TAB_TOD_DEFINES_FAMILY, "") == "":
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
- continue
- FamilyMatch = True
+ if Family != "":
+ Found = False
+ if Tool in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_STAR in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if not Found:
+ continue
# expand any wildcard
if Target == TAB_STAR or Target == self.BuildTarget:
if Tag == TAB_STAR or Tag == self.ToolChain:
@@ -213,12 +226,19 @@ class AutoGenInfo(object):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool not in ToolDef or Family == "":
+ if Family == "":
continue
# option has been added before
- if TAB_TOD_DEFINES_FAMILY not in ToolDef[Tool]:
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = False
+ if Tool in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if TAB_STAR in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if not Found:
continue

# expand any wildcard
diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
index e2ef3256773e..21e72438e59e 100644
--- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
@@ -827,6 +827,33 @@ class PlatformAutoGen(AutoGen):
RetVal = RetVal + _SplitOption(Flags.strip())
return RetVal

+ ## Compute a tool defintion key priority value in range 0..15
+ #
+ # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE 15
+ # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE 14
+ # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE 13
+ # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE 12
+ # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE 11
+ # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE 10
+ # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE 9
+ # ******_*********_****_COMMANDTYPE_ATTRIBUTE 8
+ # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE 7
+ # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE 6
+ # TARGET_*********_ARCH_***********_ATTRIBUTE 5
+ # ******_*********_ARCH_***********_ATTRIBUTE 4
+ # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE 3
+ # ******_TOOLCHAIN_****_***********_ATTRIBUTE 2
+ # TARGET_*********_****_***********_ATTRIBUTE 1
+ # ******_*********_****_***********_ATTRIBUTE 0
+ #
+ def ToolDefinitionPriority (self,Key):
+ KeyList = Key.split('_')
+ Priority = 0
+ for Index in range (0, min(4, len(KeyList))):
+ if KeyList[Index] != '*':
+ Priority += (1 << Index)
+ return Priority
+
## Get tool chain definition
#
# Get each tool definition for given tool chain from tools_def.txt and platform @@ -839,8 +866,16 @@ class
PlatformAutoGen(AutoGen):
ExtraData="[%s]" % self.MetaFile)
RetVal = OrderedDict()
DllPathList = set()
- for Def in ToolDefinition:
+
+ PrioritizedDefList = sorted(ToolDefinition.keys(), key=self.ToolDefinitionPriority, reverse=True)
+ for Def in PrioritizedDefList:
Target, Tag, Arch, Tool, Attr = Def.split("_")
+ if Target == TAB_STAR:
+ Target = self.BuildTarget
+ if Tag == TAB_STAR:
+ Tag = self.ToolChain
+ if Arch == TAB_STAR:
+ Arch = self.Arch
if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:
continue

@@ -850,9 +885,14 @@ class PlatformAutoGen(AutoGen):
DllPathList.add(Value)
continue

+ #
+ # ToolDefinition is sorted from highest priority to lowest priority.
+ # Only add the first(highest priority) match to RetVal
+ #
if Tool not in RetVal:
RetVal[Tool] = OrderedDict()
- RetVal[Tool][Attr] = Value
+ if Attr not in RetVal[Tool]:
+ RetVal[Tool][Attr] = Value

ToolsDef = ''
if GlobalData.gOptions.SilentMode and "MAKE" in RetVal:
@@ -860,9 +900,21 @@ class PlatformAutoGen(AutoGen):
RetVal["MAKE"]["FLAGS"] = ""
RetVal["MAKE"]["FLAGS"] += " -s"
MakeFlags = ''
- for Tool in RetVal:
- for Attr in RetVal[Tool]:
- Value = RetVal[Tool][Attr]
+
+ ToolList = list(RetVal.keys())
+ ToolList.sort()
+ for Tool in ToolList:
+ if Tool == TAB_STAR:
+ continue
+ AttrList = list(RetVal[Tool].keys())
+ if TAB_STAR in ToolList:
+ AttrList += list(RetVal[TAB_STAR])
+ AttrList.sort()
+ for Attr in AttrList:
+ if Attr in RetVal[Tool]:
+ Value = RetVal[Tool][Attr]
+ else:
+ Value = RetVal[TAB_STAR][Attr]
if Tool in self._BuildOptionWithToolDef(RetVal) and Attr in self._BuildOptionWithToolDef(RetVal)[Tool]:
# check if override is indicated
if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='):
@@ -877,7 +929,7 @@ class PlatformAutoGen(AutoGen):
if Attr == "PATH":
# Don't put MAKE definition in the file
if Tool != "MAKE":
- ToolsDef += "%s = %s\n" % (Tool, Value)
+ ToolsDef += "%s_%s = %s\n" % (Tool, Attr,
+ Value)
elif Attr != "DLL":
# Don't put MAKE definition in the file
if Tool == "MAKE":
@@ -1469,17 +1521,31 @@ class PlatformAutoGen(AutoGen):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool in ToolDef and Family != "":
- FamilyIsNull = False
- if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
- continue
- else:
- if ToolDef[Tool].get(TAB_TOD_DEFINES_FAMILY, "") == "":
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
- continue
- FamilyMatch = True
+ if Family != "":
+ Found = False
+ if Tool in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_STAR in ToolDef:
+ FamilyIsNull = False
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ FamilyMatch = True
+ Found = True
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ FamilyMatch = True
+ Found = True
+ if not Found:
+ continue
+
# expand any wildcard
if Target == TAB_STAR or Target == self.BuildTarget:
if Tag == TAB_STAR or Tag == self.ToolChain:
@@ -1509,12 +1575,19 @@ class PlatformAutoGen(AutoGen):
Family = Key[0]
Target, Tag, Arch, Tool, Attr = Key[1].split("_")
# if tool chain family doesn't match, skip it
- if Tool not in ToolDef or Family == "":
+ if Family == "":
continue
# option has been added before
- if TAB_TOD_DEFINES_FAMILY not in ToolDef[Tool]:
- continue
- if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = False
+ if Tool in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:
+ if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if TAB_STAR in ToolDef:
+ if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:
+ if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:
+ Found = True
+ if not Found:
continue

# expand any wildcard
diff --git a/BaseTools/Source/Python/Common/ToolDefClassObject.py b/BaseTools/Source/Python/Common/ToolDefClassObject.py
index 8e70407cb9e9..2b4b23849196 100644
--- a/BaseTools/Source/Python/Common/ToolDefClassObject.py
+++ b/BaseTools/Source/Python/Common/ToolDefClassObject.py
@@ -1,7 +1,7 @@
## @file
# This file is used to define each component of tools_def.txt file # -# Copyright (c) 2007 - 2019, Intel Corporation.
All rights reserved.<BR>
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights
+reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent #

@@ -86,23 +86,6 @@ class ToolDefClassObject(object):
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort()
self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort()

- KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH,
TAB_TOD_DEFINES_COMMAND_TYPE]
- for Index in range(3, -1, -1):
- # make a copy of the keys to enumerate over to prevent issues when
- # adding/removing items from the original dict.
- for Key in list(self.ToolsDefTxtDictionary.keys()):
- List = Key.split('_')
- if List[Index] == TAB_STAR:
- for String in self.ToolsDefTxtDatabase[KeyList[Index]]:
- List[Index] = String
- NewKey = '%s_%s_%s_%s_%s' % tuple(List)
- if NewKey not in self.ToolsDefTxtDictionary:
- self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key]
- del self.ToolsDefTxtDictionary[Key]
- elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:
- del self.ToolsDefTxtDictionary[Key]
-
-
## IncludeToolDefFile
#
# Load target.txt file and parse it as if its contents were inside the main file diff --git
a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
index 3019ec63c3bb..c31fc24870d5 100644
--- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -1,7 +1,7 @@
## @file
# Global variables for GenFds
#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights
+reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -875,14 +875,27 @@ def FindExtendTool(KeyStringList,
CurrentArchList, NameGuid):
ToolOptionKey = None
KeyList = None
for tool_def in ToolDefinition.items():
- if NameGuid.lower() == tool_def[1].lower():
- KeyList = tool_def[0].split('_')
- Key = KeyList[0] + \
- '_' + \
- KeyList[1] + \
- '_' + \
- KeyList[2]
- if Key in KeyStringList and KeyList[4] == DataType.TAB_GUID:
+ KeyList = tool_def[0].split('_')
+ if len(KeyList) < 5:
+ continue
+ if KeyList[4] != DataType.TAB_GUID:
+ continue
+ if NameGuid.lower() != tool_def[1].lower():
+ continue
+ Key = KeyList[0] + \
+ '_' + \
+ KeyList[1] + \
+ '_' + \
+ KeyList[2]
+ for KeyString in KeyStringList:
+ KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
+ if KeyList[0] == DataType.TAB_STAR:
+ KeyList[0] = KeyStringBuildTarget
+ if KeyList[1] == DataType.TAB_STAR:
+ KeyList[1] = KeyStringToolChain
+ if KeyList[2] == DataType.TAB_STAR:
+ KeyList[2] = KeyStringArch
+ if KeyList[0] == KeyStringBuildTarget and KeyList[1] == KeyStringToolChain and KeyList[2] == KeyStringArch:
ToolPathKey = Key + '_' + KeyList[3] + '_PATH'
ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'
ToolPath = ToolDefinition.get(ToolPathKey) diff --git a/BaseTools/Source/Python/build/build.py
b/BaseTools/Source/Python/build/build.py
index c4cfe38ad96a..cf988c00b8e0 100755
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -2,7 +2,7 @@
# build a platform or a module
#
# Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR> -# Copyright (c) 2007 - 2020, Intel Corporation.
All rights reserved.<BR>
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights
+reserved.<BR>
# Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR> # Copyright (c) 2020, ARM Limited. All rights
reserved.<BR> # @@ -889,6 +889,36 @@ class Build():
except:
return False, UNKNOWN_ERROR

+ ## Add TOOLCHAIN and FAMILY declared in DSC [BuildOptions] to ToolsDefTxtDatabase.
+ #
+ # Loop through the set of build targets, tool chains, and archs provided on either
+ # the command line or in target.txt to discover FAMILY and TOOLCHAIN delclarations
+ # in [BuildOptions] sections that may be within !if expressions that may use
+ # $(TARGET), $(TOOLCHAIN), $(TOOLCHAIN_TAG), or $(ARCH) operands.
+ #
+ def GetToolChainAndFamilyFromDsc (self, File):
+ for BuildTarget in self.BuildTargetList:
+ GlobalData.gGlobalDefines['TARGET'] = BuildTarget
+ for ToolChain in self.ToolChainList:
+ GlobalData.gGlobalDefines['TOOLCHAIN'] = ToolChain
+ GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = ToolChain
+ for Arch in self.ArchList:
+ GlobalData.gGlobalDefines['ARCH'] = Arch
+ dscobj = self.BuildDatabase[File, Arch]
+ for Family, ToolChain, CodeBase in dscobj.BuildOptions:
+ if TAB_TOD_DEFINES_FAMILY not in self.ToolDef.ToolsDefTxtDatabase:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY] = {}
+ if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][ToolChain] = Family
+ if TAB_TOD_DEFINES_BUILDRULEFAMILY not in self.ToolDef.ToolsDefTxtDatabase:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY] = {}
+ if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY]:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][ToolChain] = Family
+ if TAB_TOD_DEFINES_TOOL_CHAIN_TAG not in self.ToolDef.ToolsDefTxtDatabase:
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = []
+ if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]:
+
+ self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].appen
+ d(ToolChain)
+
## Load configuration
#
# This method will parse target.txt and get the build configurations.
@@ -910,6 +940,26 @@ class Build():
if self.ToolChainList is None or len(self.ToolChainList) == 0:
EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to
build.\n")

+ if not self.PlatformFile:
+ PlatformFile = self.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_ACTIVE_PLATFORM]
+ if not PlatformFile:
+ # Try to find one in current directory
+ WorkingDirectory = os.getcwd()
+ FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc')))
+ FileNum = len(FileList)
+ if FileNum >= 2:
+ EdkLogger.error("build", OPTION_MISSING,
+ ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum,
WorkingDirectory))
+ elif FileNum == 1:
+ PlatformFile = FileList[0]
+ else:
+ EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
+ ExtraData="No active platform
+ specified in target.txt or command line! Nothing can be built.\n")
+
+ self.PlatformFile = PathClass(NormFile(PlatformFile,
+ self.WorkspaceDir), self.WorkspaceDir)
+
+ self.GetToolChainAndFamilyFromDsc (self.PlatformFile)
+
# check if the tool chains are defined or not
NewToolChainList = []
for ToolChain in self.ToolChainList:
@@ -935,23 +985,6 @@ class Build():
ToolChainFamily.append(ToolDefinition[TAB_TOD_DEFINES_FAMILY][Tool])
self.ToolChainFamily = ToolChainFamily

- if not self.PlatformFile:
- PlatformFile = self.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_ACTIVE_PLATFORM]
- if not PlatformFile:
- # Try to find one in current directory
- WorkingDirectory = os.getcwd()
- FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc')))
- FileNum = len(FileList)
- if FileNum >= 2:
- EdkLogger.error("build", OPTION_MISSING,
- ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum,
WorkingDirectory))
- elif FileNum == 1:
- PlatformFile = FileList[0]
- else:
- EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
- ExtraData="No active platform specified in target.txt or command line! Nothing can be
built.\n")
-
- self.PlatformFile = PathClass(NormFile(PlatformFile, self.WorkspaceDir), self.WorkspaceDir)
self.ThreadNumber = ThreadNum()
## Initialize build configuration
#
@@ -2381,24 +2414,25 @@ class Build():
continue

for Arch in self.ArchList:
- # Build up the list of supported architectures for this build
- prefix = '%s_%s_%s_' % (BuildTarget, ToolChain, Arch)
-
# Look through the tool definitions for GUIDed tools
guidAttribs = []
for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.items():
- if attrib.upper().endswith('_GUID'):
- split = attrib.split('_')
- thisPrefix = '_'.join(split[0:3]) + '_'
- if thisPrefix == prefix:
- guid = self.ToolDef.ToolsDefTxtDictionary[attrib]
- guid = guid.lower()
- toolName = split[3]
- path = '_'.join(split[0:4]) + '_PATH'
- path = self.ToolDef.ToolsDefTxtDictionary[path]
- path = self.GetRealPathOfTool(path)
- guidAttribs.append((guid, toolName, path))
-
+ GuidBuildTarget, GuidToolChain, GuidArch, GuidTool, GuidAttr = attrib.split('_')
+ if GuidAttr.upper() == 'GUID':
+ if GuidBuildTarget == TAB_STAR:
+ GuidBuildTarget = BuildTarget
+ if GuidToolChain == TAB_STAR:
+ GuidToolChain = ToolChain
+ if GuidArch == TAB_STAR:
+ GuidArch = Arch
+ if GuidBuildTarget == BuildTarget and GuidToolChain == ToolChain and GuidArch == Arch:
+ path = '_'.join(attrib.split('_')[:-1]) + '_PATH'
+ if path in self.ToolDef.ToolsDefTxtDictionary:
+ path = self.ToolDef.ToolsDefTxtDictionary[path]
+ path = self.GetRealPathOfTool(path)
+ guidAttribs.append((value.lower(), GuidTool, path))
+ # Sort by GuidTool name
+ sorted (guidAttribs, key=lambda x: x[1])
# Write out GuidedSecTools.txt
toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt')
toolsFile = open(toolsFile, 'wt')
--
2.31.1.windows.1


Re: [Patch 1/1] EmulatorPkg: Temp remove IA32 GCC CI builds

Bob Feng
 

Yes. I agree to disable this CI tests temporarily.

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

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@intel.com>
Sent: Thursday, April 29, 2021 12:30 PM
To: devel@edk2.groups.io
Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Liming Gao <gaoliming@byosoft.com.cn>; Feng, Bob C <bob.c.feng@intel.com>; Chen, Christine <yuwei.chen@intel.com>; Andrew Fish <afish@apple.com>; Ni, Ray <ray.ni@intel.com>
Subject: [Patch 1/1] EmulatorPkg: Temp remove IA32 GCC CI builds

EmulatorPkg IA32 GCC builds are not working due to a failure to install the i386 library dependencies in Ubuntu 18.04.

Temporarily disable these specific CI tests until the issue can be resolved.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Yuwei Chen <yuwei.chen@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.../.azurepipelines/Ubuntu-GCC5.yml | 53 -------------------
1 file changed, 53 deletions(-)

diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
index faf57e7dd559..416c15e70840 100644
--- a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
+++ b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
@@ -47,27 +47,6 @@ jobs:
Build.Target: "NOOPT"
Run.Flags: $(run_flags)
Run: $(should_run)
- EmulatorPkg_IA32_DEBUG:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: ""
- Build.Target: "DEBUG"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_RELEASE:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: ""
- Build.Target: "RELEASE"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_NOOPT:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: ""
- Build.Target: "NOOPT"
- Run.Flags: $(run_flags)
- Run: $(should_run)
EmulatorPkg_X64_FULL_DEBUG:
Build.File: "$(package)/PlatformCI/PlatformBuild.py"
Build.Arch: "X64"
@@ -89,27 +68,6 @@ jobs:
Build.Target: "NOOPT"
Run.Flags: $(run_flags)
Run: $(should_run)
- EmulatorPkg_IA32_FULL_DEBUG:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE"
- Build.Target: "DEBUG"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_FULL_RELEASE:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE"
- Build.Target: "RELEASE"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_FULL_NOOPT:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE"
- Build.Target: "NOOPT"
- Run.Flags: $(run_flags)
- Run: $(should_run)

workspace:
clean: all
@@ -127,14 +85,3 @@ jobs:
build_file: $(Build.File)
build_flags: $(Build.Flags)
run_flags: $(Run.Flags)
- # Add steps to install some IA32 only dependencies
- extra_install_step:
- - bash: sudo dpkg --add-architecture i386
- displayName: Add i386 to dpkg
- condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
- - bash: sudo apt-get update
- displayName: do apt-get update
- condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
- - bash: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
- displayName: Add additional i386 packages
- condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
--
2.31.1.windows.1


Re: [Patch 1/1] EmulatorPkg: Temp remove IA32 GCC CI builds

Ni, Ray
 

Reviewed-by: Ray Ni <ray.ni@intel.com>

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@intel.com>
Sent: Thursday, April 29, 2021 12:30 PM
To: devel@edk2.groups.io
Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
<Bret.Barkelew@microsoft.com>; Liming Gao <gaoliming@byosoft.com.cn>;
Feng, Bob C <bob.c.feng@intel.com>; Chen, Christine
<yuwei.chen@intel.com>; Andrew Fish <afish@apple.com>; Ni, Ray
<ray.ni@intel.com>
Subject: [Patch 1/1] EmulatorPkg: Temp remove IA32 GCC CI builds

EmulatorPkg IA32 GCC builds are not working due to a failure
to install the i386 library dependencies in Ubuntu 18.04.

Temporarily disable these specific CI tests until the issue
can be resolved.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Yuwei Chen <yuwei.chen@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.../.azurepipelines/Ubuntu-GCC5.yml | 53 -------------------
1 file changed, 53 deletions(-)

diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
index faf57e7dd559..416c15e70840 100644
--- a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
+++ b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
@@ -47,27 +47,6 @@ jobs:
Build.Target: "NOOPT"
Run.Flags: $(run_flags)
Run: $(should_run)
- EmulatorPkg_IA32_DEBUG:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: ""
- Build.Target: "DEBUG"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_RELEASE:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: ""
- Build.Target: "RELEASE"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_NOOPT:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: ""
- Build.Target: "NOOPT"
- Run.Flags: $(run_flags)
- Run: $(should_run)
EmulatorPkg_X64_FULL_DEBUG:
Build.File: "$(package)/PlatformCI/PlatformBuild.py"
Build.Arch: "X64"
@@ -89,27 +68,6 @@ jobs:
Build.Target: "NOOPT"
Run.Flags: $(run_flags)
Run: $(should_run)
- EmulatorPkg_IA32_FULL_DEBUG:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE"
- Build.Target: "DEBUG"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_FULL_RELEASE:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE"
- Build.Target: "RELEASE"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_FULL_NOOPT:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE"
- Build.Target: "NOOPT"
- Run.Flags: $(run_flags)
- Run: $(should_run)

workspace:
clean: all
@@ -127,14 +85,3 @@ jobs:
build_file: $(Build.File)
build_flags: $(Build.Flags)
run_flags: $(Run.Flags)
- # Add steps to install some IA32 only dependencies
- extra_install_step:
- - bash: sudo dpkg --add-architecture i386
- displayName: Add i386 to dpkg
- condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'],
'IA32'), succeeded())
- - bash: sudo apt-get update
- displayName: do apt-get update
- condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'],
'IA32'), succeeded())
- - bash: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386
lib32gcc-7-dev
- displayName: Add additional i386 packages
- condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'],
'IA32'), succeeded())
--
2.31.1.windows.1


[Patch 1/1] EmulatorPkg: Temp remove IA32 GCC CI builds

Michael D Kinney
 

EmulatorPkg IA32 GCC builds are not working due to a failure
to install the i386 library dependencies in Ubuntu 18.04.

Temporarily disable these specific CI tests until the issue
can be resolved.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Yuwei Chen <yuwei.chen@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.../.azurepipelines/Ubuntu-GCC5.yml | 53 -------------------
1 file changed, 53 deletions(-)

diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
index faf57e7dd559..416c15e70840 100644
--- a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
+++ b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
@@ -47,27 +47,6 @@ jobs:
Build.Target: "NOOPT"
Run.Flags: $(run_flags)
Run: $(should_run)
- EmulatorPkg_IA32_DEBUG:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: ""
- Build.Target: "DEBUG"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_RELEASE:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: ""
- Build.Target: "RELEASE"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_NOOPT:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: ""
- Build.Target: "NOOPT"
- Run.Flags: $(run_flags)
- Run: $(should_run)
EmulatorPkg_X64_FULL_DEBUG:
Build.File: "$(package)/PlatformCI/PlatformBuild.py"
Build.Arch: "X64"
@@ -89,27 +68,6 @@ jobs:
Build.Target: "NOOPT"
Run.Flags: $(run_flags)
Run: $(should_run)
- EmulatorPkg_IA32_FULL_DEBUG:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE"
- Build.Target: "DEBUG"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_FULL_RELEASE:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE"
- Build.Target: "RELEASE"
- Run.Flags: $(run_flags)
- Run: $(should_run)
- EmulatorPkg_IA32_FULL_NOOPT:
- Build.File: "$(package)/PlatformCI/PlatformBuild.py"
- Build.Arch: "IA32"
- Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE"
- Build.Target: "NOOPT"
- Run.Flags: $(run_flags)
- Run: $(should_run)

workspace:
clean: all
@@ -127,14 +85,3 @@ jobs:
build_file: $(Build.File)
build_flags: $(Build.Flags)
run_flags: $(Run.Flags)
- # Add steps to install some IA32 only dependencies
- extra_install_step:
- - bash: sudo dpkg --add-architecture i386
- displayName: Add i386 to dpkg
- condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
- - bash: sudo apt-get update
- displayName: do apt-get update
- condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
- - bash: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
- displayName: Add additional i386 packages
- condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
--
2.31.1.windows.1


Re: 回复: [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86

Rebecca Cran <rebecca@...>
 

On 4/28/21 7:10 PM, gaoliming wrote:
Rebecca:

-----邮件原件-----
发件人: Rebecca Cran <rebecca@nuviainc.com>
发送时间: 2021年4月29日 4:44
收件人: devel@edk2.groups.io
抄送: Rebecca Cran <rebecca@nuviainc.com>; Jiewen Yao
<jiewen.yao@intel.com>; Jian J Wang <jian.j.wang@intel.com>; Michael D
Kinney <michael.d.kinney@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Ard
Biesheuvel <ardb+tianocore@kernel.org>; Sami Mujawar
<Sami.Mujawar@arm.com>
主题: [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in
addition to X86

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.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
MdePkg/MdePkg.dec | 9 +-
MdePkg/MdePkg.dsc | 4 +-
MdePkg/Library/BaseRngLib/BaseRngLib.inf | 16 ++-
MdePkg/Library/BaseRngLib/BaseRngLibInternals.h | 31 +++++
MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 121
++++++++++++++++++++
MdePkg/Library/BaseRngLib/BaseRng.c | 55 +++------
MdePkg/Library/BaseRngLib/Rand/RdRand.c | 103
+++++++++++++++++
MdePkg/Library/BaseRngLib/BaseRngLib.uni | 6 +-
8 files changed, 291 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.in
f

+[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..1dc3249a8c20 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 high-quality random numbers.
#
+# Copyright (c) 2020, 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,18 @@ [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

[Packages]
MdePkg/MdePkg.dec
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
new file mode 100644
index 000000000000..44fda69c9eec
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
@@ -0,0 +1,31 @@
+/** @file
+
+ Architecture specific interface to RNG functionality.
+
+Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef BASE_RNGLIB_INTERNALS_H_
+
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber16 (
+ OUT UINT16 *Rand
+ );
+
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber32 (
+ OUT UINT32 *Rand
+ );
+
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber64 (
+ OUT UINT64 *Rand
+ );
+
+#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..19643237923a
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
@@ -0,0 +1,121 @@
+/** @file
+ Random number generator service that uses the RNDR instruction
+ to provide high-quality random numbers.
+
+ Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/RngLib.h>
+
+#include "BaseRngLibInternals.h"
+
+//
+// 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 RETURN_SUCCESS.
+
+ @retval RETURN_SUCCESS The constructor always returns
EFI_SUCCESS.
+
+**/
+RETURN_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);
+ (void)Isar0;
+
What behavior for this statement "(void)Isar0;"?
It causes Isar0 to be 'used' in builds where ASSERT is compiled out, avoiding a warning/error.

--
Rebecca Cran


Re: [PATCH] BaseTools: Change non-ascii character of StructurePcd comment

Michael D Kinney
 

So this tool converts UNI file contents into DSC file contents?

The fix only addresses a single character issue for (R), which means we will keep getting errors.

Perhaps we should convert all non-ASCII characters to '?'. If the developer using the tool
does not like the '?' characters, then they can update the strings in the UNI file to
only use ASCII characters.

BTW...I did run into this type of issue a lot when converting documents to GitBook markdown.
I recall adding many special character conversion rules to get to ASCII markdown files.
This is why I know this approach has many problems.

Mike

-----Original Message-----
From: Chen, Christine <yuwei.chen@intel.com>
Sent: Wednesday, April 28, 2021 6:24 PM
To: gaoliming <gaoliming@byosoft.com.cn>; devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
Cc: Feng, Bob C <bob.c.feng@intel.com>
Subject: RE: [edk2-devel] [PATCH] BaseTools: Change non-ascii character of StructurePcd comment

Thanks for reminder~ : )
Thus personally think if do not want the non-ascii character in StructurePcd dsc file, the remove or change
operation should be covered by ConvertFceToStructurePcd.py

Thanks,
Christine
-----Original Message-----
From: gaoliming <gaoliming@byosoft.com.cn>
Sent: Thursday, April 29, 2021 9:18 AM
To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>; Kinney,
Michael D <michael.d.kinney@intel.com>
Cc: Feng, Bob C <bob.c.feng@intel.com>
Subject: 回复: [edk2-devel] [PATCH] BaseTools: Change non-ascii character of
StructurePcd comment

Christine:
FCE prints HII question information that is from HII driver UNI file. It may
have non-ascii character.

Thanks
Liming
-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Yuwei Chen
发送时间: 2021年4月29日 8:25
收件人: Kinney, Michael D <michael.d.kinney@intel.com>;
devel@edk2.groups.io
抄送: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>
主题: Re: [edk2-devel] [PATCH] BaseTools: Change non-ascii character of
StructurePcd comment

Hi Mike,

The StructurePcd dsc file generated by our tool will have the
non-ASCII character.
The input file of ConvertFceToStructurePcd.py is generated by FCE
tool, which has the circle R non-ASCII character. This patch change
this character to ACSII character when using
ConvertFceToStructurePcd.py to generate the StructurePcd dsc file.

Best Regards,
Christine

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@intel.com>
Sent: Thursday, April 29, 2021 12:10 AM
To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>;
Kinney,
Michael D <michael.d.kinney@intel.com>
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>
Subject: RE: [edk2-devel] [PATCH] BaseTools: Change non-ascii
character of StructurePcd comment

What file type contains the non-ASCII character?

I would prefer to see the source file with non ASCII character be
updated instead of building this conversion into the tools.

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
Yuwei Chen
Sent: Wednesday, April 28, 2021 1:45 AM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>
Subject: [edk2-devel] [PATCH] BaseTools: Change non-ascii
character of StructurePcd comment

Currently, the ConvertFceToStructurePcd.py tool generate
StructurePcd dsc file with comments including non-ascii character
circle R. This patch changes the non-ascii character circle R to
(R) when adding the comment.

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
---
BaseTools/Scripts/ConvertFceToStructurePcd.py | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/BaseTools/Scripts/ConvertFceToStructurePcd.py
b/BaseTools/Scripts/ConvertFceToStructurePcd.py
index 2052db8c4b..d029ed6a28 100644
--- a/BaseTools/Scripts/ConvertFceToStructurePcd.py
+++ b/BaseTools/Scripts/ConvertFceToStructurePcd.py
@@ -285,6 +285,10 @@ class Config(object):
comment_list = value_re.findall(line) # the string \\... in "Q...."
line
comment_list[0] = comment_list[0].replace('//', '')
comment = comment_list[0].strip()
+ comment_b = bytes(comment, encoding = "utf8")
+ if b"\xae" in comment_b:
+ comment_b = comment_b.replace(b"\xc2\xae", b"(R)") #
Change
the circle "R" character to ascii character
+ comment = str(comment_b, encoding = "utf-8")
line=value_re.sub('',line) #delete \\... in "Q...." line
list1=line.split(' ')
value=self.value_parser(list1)
--
2.26.1.windows.1








Re: [PATCH v2 4/4] OvmfPkg/Tcg2ConfigPei: Mark TPM MMIO range as unencrypted for SEV-ES

Lendacky, Thomas
 

On 4/28/21 2:43 PM, Tom Lendacky wrote:
On 4/28/21 12:51 PM, Laszlo Ersek via groups.io wrote:
I'm going to ask for v3 after all:

On 04/27/21 18:21, Lendacky, Thomas wrote:
From: Tom Lendacky <thomas.lendacky@amd.com>

BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D3345&;data=04%7C01%7Cthomas.lendacky%40amd.com%7C3c65ebfe044e4f3eb5b808d90a6e5455%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637552291252644310%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=G1GwQc6sZqRuNHWC5vbdb78gCOl4YkAq%2BHi0F0ceucg%3D&amp;reserved=0

During PEI, the MMIO range for the TPM is marked as encrypted when running
as an SEV guest. While this isn't an issue for an SEV guest because of
the way the nested page fault is handled, it does result in an SEV-ES
guest terminating because of a mitigation check in the #VC handler to
prevent MMIO to an encrypted address. For an SEV-ES guest, this range
must be marked as unencrypted.

Create a new x86 PEIM for TPM support that will map the TPM MMIO range as
unencrypted when SEV-ES is active. The gOvmfTpmMmioAccessiblePpiGuid PPI
will be unconditionally installed before exiting. The PEIM will exit with
the EFI_ABORTED status so that the PEIM does not stay resident.
...

+
+ //
+ // If SEV or SEV-ES is active, MMIO succeeds against an encrypted physical
+ // address because the nested page fault (NPF) that occurs on access does not
+ // include the encryption bit in the guest physical address provided to the
+ // hypervisor.
+ //
+ // However, if SEV-ES is active, before performing the actual MMIO, an
+ // additional MMIO mitigation check is performed in the #VC handler to ensure
+ // that MMIO is being done to an unencrypted address. To prevent guest
+ // termination in this scenario, mark the range unencrypted ahead of access.
+ //
Lovely comment, thanks!
I'm going to expand on this a bit more to really show the distinction
between SEV and SEV-ES when it comes to MMIO. Look for a bit more info in v3.

Thanks,
Tom


+ if (MemEncryptSevEsIsEnabled ()) {
+ DEBUG ((DEBUG_INFO, "%a: mapping TPM MMIO address range unencrypted\n", __FUNCTION__));
+
+ DecryptStatus = MemEncryptSevClearPageEncMask (
+ 0,
+ PcdGet64 (PcdTpmBaseAddress),
(11) The INF file says [FixedPcd], so it would be cleanest to say
FixedPcdGet64() here.
Will do.



(12) PcdLib is missing from both the [LibraryClasses] section and the
#include directives.
Right, I'll update that.



+ EFI_SIZE_TO_PAGES ((UINTN) 0x5000),
+ FALSE
+ );
+
+ if (RETURN_ERROR (DecryptStatus)) {
+ DEBUG ((DEBUG_INFO, "%a: failed to map TPM MMIO address range unencrypted\n", __FUNCTION__));
(13) Overlong line.
Ok, I'll change that. I though that was ok now since PatchCheck.py didn't
complain.



(14) Please report errors with DEBUG_ERROR.
Yup, will change.

Thanks,
Tom



+ ASSERT_RETURN_ERROR (DecryptStatus);
+ }
+ }
+
+ //
+ // MMIO range available
+ //
+ Status = PeiServicesInstallPpi (&mTpmMmioRangeAccessible);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_ABORTED;
+}
Thanks!
Laszlo






Re: [PATCH] BaseTools: Change non-ascii character of StructurePcd comment

Yuwei Chen
 

Thanks for reminder~ : )
Thus personally think if do not want the non-ascii character in StructurePcd dsc file, the remove or change operation should be covered by ConvertFceToStructurePcd.py

Thanks,
Christine

-----Original Message-----
From: gaoliming <gaoliming@byosoft.com.cn>
Sent: Thursday, April 29, 2021 9:18 AM
To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>; Kinney,
Michael D <michael.d.kinney@intel.com>
Cc: Feng, Bob C <bob.c.feng@intel.com>
Subject: 回复: [edk2-devel] [PATCH] BaseTools: Change non-ascii character of
StructurePcd comment

Christine:
FCE prints HII question information that is from HII driver UNI file. It may
have non-ascii character.

Thanks
Liming
-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Yuwei Chen
发送时间: 2021年4月29日 8:25
收件人: Kinney, Michael D <michael.d.kinney@intel.com>;
devel@edk2.groups.io
抄送: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>
主题: Re: [edk2-devel] [PATCH] BaseTools: Change non-ascii character of
StructurePcd comment

Hi Mike,

The StructurePcd dsc file generated by our tool will have the
non-ASCII character.
The input file of ConvertFceToStructurePcd.py is generated by FCE
tool, which has the circle R non-ASCII character. This patch change
this character to ACSII character when using
ConvertFceToStructurePcd.py to generate the StructurePcd dsc file.

Best Regards,
Christine

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@intel.com>
Sent: Thursday, April 29, 2021 12:10 AM
To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>;
Kinney,
Michael D <michael.d.kinney@intel.com>
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>
Subject: RE: [edk2-devel] [PATCH] BaseTools: Change non-ascii
character of StructurePcd comment

What file type contains the non-ASCII character?

I would prefer to see the source file with non ASCII character be
updated instead of building this conversion into the tools.

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
Yuwei Chen
Sent: Wednesday, April 28, 2021 1:45 AM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>
Subject: [edk2-devel] [PATCH] BaseTools: Change non-ascii
character of StructurePcd comment

Currently, the ConvertFceToStructurePcd.py tool generate
StructurePcd dsc file with comments including non-ascii character
circle R. This patch changes the non-ascii character circle R to
(R) when adding the comment.

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
---
BaseTools/Scripts/ConvertFceToStructurePcd.py | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/BaseTools/Scripts/ConvertFceToStructurePcd.py
b/BaseTools/Scripts/ConvertFceToStructurePcd.py
index 2052db8c4b..d029ed6a28 100644
--- a/BaseTools/Scripts/ConvertFceToStructurePcd.py
+++ b/BaseTools/Scripts/ConvertFceToStructurePcd.py
@@ -285,6 +285,10 @@ class Config(object):
comment_list = value_re.findall(line) # the string \\... in "Q...."
line
comment_list[0] = comment_list[0].replace('//', '')
comment = comment_list[0].strip()
+ comment_b = bytes(comment, encoding = "utf8")
+ if b"\xae" in comment_b:
+ comment_b = comment_b.replace(b"\xc2\xae", b"(R)") #
Change
the circle "R" character to ascii character
+ comment = str(comment_b, encoding = "utf-8")
line=value_re.sub('',line) #delete \\... in "Q...." line
list1=line.split(' ')
value=self.value_parser(list1)
--
2.26.1.windows.1








回复: [edk2-devel] [PATCH] BaseTools: Change non-ascii character of StructurePcd comment

gaoliming
 

Christine:
FCE prints HII question information that is from HII driver UNI file. It may have non-ascii character.

Thanks
Liming

-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Yuwei Chen
发送时间: 2021年4月29日 8:25
收件人: Kinney, Michael D <michael.d.kinney@intel.com>;
devel@edk2.groups.io
抄送: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>
主题: Re: [edk2-devel] [PATCH] BaseTools: Change non-ascii character of
StructurePcd comment

Hi Mike,

The StructurePcd dsc file generated by our tool will have the non-ASCII
character.
The input file of ConvertFceToStructurePcd.py is generated by FCE tool, which
has the circle R non-ASCII character. This patch change this character to ACSII
character when using ConvertFceToStructurePcd.py to generate the
StructurePcd dsc file.

Best Regards,
Christine

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@intel.com>
Sent: Thursday, April 29, 2021 12:10 AM
To: devel@edk2.groups.io; Chen, Christine <yuwei.chen@intel.com>;
Kinney,
Michael D <michael.d.kinney@intel.com>
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>
Subject: RE: [edk2-devel] [PATCH] BaseTools: Change non-ascii character of
StructurePcd comment

What file type contains the non-ASCII character?

I would prefer to see the source file with non ASCII character be updated
instead of building this conversion into the tools.

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yuwei
Chen
Sent: Wednesday, April 28, 2021 1:45 AM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>
Subject: [edk2-devel] [PATCH] BaseTools: Change non-ascii character of
StructurePcd comment

Currently, the ConvertFceToStructurePcd.py tool generate StructurePcd
dsc file with comments including non-ascii character circle R. This
patch changes the non-ascii character circle R to (R) when adding the
comment.

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Yuwei Chen <yuwei.chen@intel.com>
---
BaseTools/Scripts/ConvertFceToStructurePcd.py | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/BaseTools/Scripts/ConvertFceToStructurePcd.py
b/BaseTools/Scripts/ConvertFceToStructurePcd.py
index 2052db8c4b..d029ed6a28 100644
--- a/BaseTools/Scripts/ConvertFceToStructurePcd.py
+++ b/BaseTools/Scripts/ConvertFceToStructurePcd.py
@@ -285,6 +285,10 @@ class Config(object):
comment_list = value_re.findall(line) # the string \\... in "Q...."
line
comment_list[0] = comment_list[0].replace('//', '')
comment = comment_list[0].strip()
+ comment_b = bytes(comment, encoding = "utf8")
+ if b"\xae" in comment_b:
+ comment_b = comment_b.replace(b"\xc2\xae", b"(R)") #
Change
the circle "R" character to ascii character
+ comment = str(comment_b, encoding = "utf-8")
line=value_re.sub('',line) #delete \\... in "Q...." line
list1=line.split(' ')
value=self.value_parser(list1)
--
2.26.1.windows.1








回复: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64

gaoliming
 

Rebecca:

-----邮件原件-----
发件人: Rebecca Cran <rebecca@nuviainc.com>
发送时间: 2021年4月29日 4:44
收件人: devel@edk2.groups.io
抄送: Rebecca Cran <rebecca@nuviainc.com>; Jiewen Yao
<jiewen.yao@intel.com>; Jian J Wang <jian.j.wang@intel.com>; Michael D
Kinney <michael.d.kinney@intel.com>; Liming Gao
<gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Ard
Biesheuvel <ardb+tianocore@kernel.org>; Sami Mujawar
<Sami.Mujawar@arm.com>
主题: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64

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.dsc |
11 +-
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf |
19 +++-
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h |
37 ++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h |
0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h |
0
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h |
88 ++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c |
54 +++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c |
108 ++++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c |
0
SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c |
0
SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c |
120 ++++++++++++++++++++
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c |
117 ++++---------------
12 files changed, 450 insertions(+), 104 deletions(-)

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/SecureBootConfigD
xe.inf

@@ -334,11 +340,6 @@ [Components.IA32, Components.X64]

SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresence
Lib.inf

SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2Physic
alPresenceLib.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..c188b6076c00 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
@@ -26,15 +26,24 @@ [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
+ AArch64/Rndr.c
+ AArch64/Rndr.h

[Packages]
MdePkg/MdePkg.dec
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
new file mode 100644
index 000000000000..458faa834a3d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
@@ -0,0 +1,37 @@
+/** @file
+ Header for the RNDR APIs used by RNG DXE driver.
+
+ Support API definitions for RNDR instruction access.
+
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RNDR_H_
+#define RNDR_H_
+
+#include <Library/BaseLib.h>
+#include <Protocol/Rng.h>
+
+/**
+ Calls RNDR 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
+RndrGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ );
+
+#endif // RNDR_H_
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 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
new file mode 100644
index 000000000000..7e38fc2564f6
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
@@ -0,0 +1,88 @@
+/** @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_
+
+extern EFI_RNG_ALGORITHM *mSUpportedRngAlgorithms;
+
+/**
+ 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 the size of the RNG algorithms structure.
+
+ @return Size of the EFI_RNG_ALGORITHM list.
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithmsSize (
+ VOID
+ );
+
+#endif // RNGDXE_INTERNALS_H_
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
new file mode 100644
index 000000000000..36166a9cbc13
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
@@ -0,0 +1,54 @@
+/** @file
+ Support routines for RNDR instruction access.
+
+ 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/BaseMemoryLib.h>
+#include <Library/RngLib.h>
+
+#include "Rndr.h"
+
+/**
+ Calls RNDR 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
+RndrGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ )
+{
+ BOOLEAN IsRandom;
+ UINT64 TempRand;
+
+ while (Length > 0) {
+ IsRandom = GetRandomNumber64 (&TempRand);
+ if (!IsRandom) {
+ return EFI_NOT_READY;
+ }
+ if (Length >= sizeof (TempRand)) {
+ WriteUnaligned64 ((UINT64*)RandBuffer, TempRand);
+ RandBuffer += sizeof (UINT64);
+ Length -= sizeof (TempRand);
+ } else {
+ CopyMem (RandBuffer, &TempRand, Length);
+ Length = 0;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
Can this function be shared between X86 and AARCH64?

Thanks
Liming
diff --git
a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
new file mode 100644
index 000000000000..18cca825e72d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
@@ -0,0 +1,108 @@
+/** @file
+ RNG Driver to produce the UEFI Random Number Generator protocol.
+
+ The driver will use the new RNDR 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 - Unsupported
+ - EFI_RNG_ALGORITHM_RAW - Supported
+ - 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) 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 "Rndr.h"
+
+//
+// Supported RNG Algorithms list by this driver.
+//
+EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
+ EFI_RNG_ALGORITHM_RAW
+};
+
+/**
+ 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 = &gEfiRngAlgorithmRaw;
+ }
+
+ //
+ // The "raw" algorithm is intended to provide entropy directly
+ //
+ if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
+ Status = RndrGetBytes (RNGValueLength, RNGValue);
+ return Status;
+ }
+
+ //
+ // Other algorithms are unsupported by this driver.
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns the size of the RNG algorithms structure.
+
+ @return Size of the EFI_RNG_ALGORITHM list.
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithmsSize (
+ VOID
+ )
+{
+ return sizeof (mSupportedRngAlgorithms);
+}
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 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
new file mode 100644
index 000000000000..cf0bebd6a386
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
@@ -0,0 +1,120 @@
+/** @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"
+
+//
+// Supported RNG Algorithms list by this driver.
+//
+EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
+ EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
+ EFI_RNG_ALGORITHM_RAW
+};
+
+/**
+ 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;
+}
+
+/**
+ Returns the size of the RNG algorithms list.
+
+ @return Size of the EFI_RNG_ALGORIGM list.
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithmsSize (
+ VOID
+ )
+{
+ return sizeof (mSupportedRngAlgorithms);
+}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
index 13d3dbd0bfbe..0072e6b433e6 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
@@ -1,34 +1,38 @@
/** @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
+ 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/TimerLib.h>
+#include <Protocol/Rng.h>
+
+#include "RngDxeInternals.h"
+

//
// Supported RNG Algorithms list by this driver.
//
-EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
- EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
- EFI_RNG_ALGORITHM_RAW
-};
+
+extern EFI_RNG_ALGORITHM mSupportedRngAlgorithms[];

/**
Returns information about the random number generation
implementation.
@@ -68,7 +72,7 @@ RngGetInfo (
return EFI_INVALID_PARAMETER;
}

- RequiredSize = sizeof (mSupportedRngAlgorithms);
+ RequiredSize = ArchGetSupportedRngAlgorithmsSize ();
if (*RNGAlgorithmListSize < RequiredSize) {
Status = EFI_BUFFER_TOO_SMALL;
} else {
@@ -87,81 +91,6 @@ RngGetInfo (
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
//
--
2.26.2

15161 - 15180 of 89694