Date
1 - 6 of 6
[PATCH v2 3/8] ArmPkg: Add Arm Firmware TRNG library
Sami Mujawar
Bugzilla: 3668 (https://bugzilla.tianocore.org/show_bug.cgi?id=3668)
The Arm True Random Number Generator Firmware, Interface 1.0, Platform Design Document (https://developer.arm.com/documentation/den0098/latest/) defines an interface between an Operating System (OS) executing at EL1 and Firmware (FW) exposing a conditioned entropy source that is provided by a TRNG back end. The conditioned entropy, that is provided by the TRNG FW interface, is commonly used to seed deterministic random number generators. This patch adds a TrngLib library that implements the Arm TRNG firmware interface. Signed-off-by: Sami Mujawar <sami.mujawar@...> --- Notes: v2: - MdePkg\Include\Library\TrngLib.h is base type [LIMING] library. It can use RETURN_STATUS instead of EFI_STATUS. - Replaced EFI_STATUS with RETURN_STATUS. [SAMI] - MdePkg\Include\Library\TrngLib.h API parameter [LIMING] doesn't require CONST. CONST means the value specified by the input pointer will not be changed in API implementation. - Removed the use of constant pointers in the [SAMI] TRNG API. ArmPkg/ArmPkg.dsc | 1 + ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h | 64 +++ ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c | 483 ++++++++++++++++++++ ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf | 34 ++ 4 files changed, 582 insertions(+) diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 59fd8f295d4f614cc68ee1021e691f94e279ab81..23df68c5eb53df11de5d96bde4949f3c833c9b2c 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -156,6 +156,7 @@ [Components.common] ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf + ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf diff --git a/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h new file mode 100644 index 0000000000000000000000000000000000000000..42236e743d972df0df205b1565496afeff5785f3 --- /dev/null +++ b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h @@ -0,0 +1,64 @@ +/** @file + Arm Firmware TRNG definitions. + + Copyright (c) 2021, Arm Limited. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] Arm True Random Number Generator Firmware, Interface 1.0, + Platform Design Document. + (https://developer.arm.com/documentation/den0098/latest/) + + @par Glossary: + - TRNG - True Random Number Generator + - FID - Function ID +**/ + +#ifndef ARM_FW_TRNG_DEFS_H_ +#define ARM_FW_TRNG_DEFS_H_ + +// Firmware TRNG interface Function IDs +#define FID_TRNG_VERSION 0x84000050 +#define FID_TRNG_FEATURES 0x84000051 +#define FID_TRNG_GET_UUID 0x84000052 +#define FID_TRNG_RND_AARCH32 0x84000053 +#define FID_TRNG_RND_AARCH64 0xC4000053 + +// Firmware TRNG revision mask and shift +#define TRNG_REV_MAJOR_MASK 0x7FFF +#define TRNG_REV_MINOR_MASK 0xFFFF +#define TRNG_REV_MAJOR_SHIFT 16 +#define TRNG_REV_MINOR_SHIFT 0 + +// Firmware TRNG status codes +#define TRNG_STATUS_SUCCESS (INT32)(0) +#define TRNG_NOT_SUPPORTED (INT32)(-1) +#define TRNG_INVALID_PARAMETER (INT32)(-2) +#define TRNG_NO_ENTROPY (INT32)(-3) + +#if defined (MDE_CPU_ARM) +/** FID to use on AArch32 platform to request entropy. +*/ +#define FID_TRNG_RND FID_TRNG_RND_AARCH32 + +/** Maximum bits of entropy supported on AArch32. +*/ +#define MAX_ENTROPY_BITS 96 +#elif defined (MDE_CPU_AARCH64) +/** FID to use on AArch64 platform to request entropy. +*/ +#define FID_TRNG_RND FID_TRNG_RND_AARCH64 + +/** Maximum bits of entropy supported on AArch64. +*/ +#define MAX_ENTROPY_BITS 192 +#else +#error "Firmware TRNG not supported. Unknown chipset." +#endif + +/** Typedef for SMC or HVC arguments. +*/ +typedef ARM_SMC_ARGS ARM_MONITOR_ARGS; + +#endif // ARM_FW_TRNG_DEFS_H_ diff --git a/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c new file mode 100644 index 0000000000000000000000000000000000000000..314e7ffbc232ae90bbb77306f9c7113ce63012c8 --- /dev/null +++ b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c @@ -0,0 +1,483 @@ +/** @file + Arm Firmware TRNG interface library. + + Copyright (c) 2021, Arm Limited. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] Arm True Random Number Generator Firmware, Interface 1.0, + Platform Design Document. + (https://developer.arm.com/documentation/den0098/latest/) + - [2] NIST Special Publication 800-90A Revision 1, June 2015, Recommendation + for Random Number Generation Using Deterministic Random Bit Generators. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [3] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [4] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + + @par Glossary: + - TRNG - True Random Number Generator + - FID - Function ID +**/ + +#include <Base.h> +#include <Library/ArmHvcLib.h> +#include <Library/ArmLib.h> +#include <Library/ArmSmcLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> + +#include "ArmFwTrngDefs.h" + +/** Convert TRNG status codes to EFI status codes. + + @param [in] TrngStatus TRNG status code. + + @retval RETURN_SUCCESS Success. + @retval RETURN_UNSUPPORTED Function not implemented. + @retval RETURN_INVALID_PARAMETER A parameter is invalid. + @retval RETURN_NOT_READY No Entropy available. +**/ +STATIC +RETURN_STATUS +TrngStatusToEfiStatus ( + IN INT32 TrngStatus + ) +{ + switch (TrngStatus) { + case TRNG_NOT_SUPPORTED: + return RETURN_UNSUPPORTED; + + case TRNG_INVALID_PARAMETER: + return RETURN_INVALID_PARAMETER; + + case TRNG_NO_ENTROPY: + return RETURN_NOT_READY; + + case TRNG_STATUS_SUCCESS: + default: + return RETURN_SUCCESS; + } +} + +/** Invoke the monitor call using the appropriate conduit. + If PcdMonitorConduitHvc is TRUE use the HVC conduit else use SMC conduit. + + @param [in, out] Args Arguments passed to and returned from the monitor. + + @return VOID +**/ +STATIC +VOID +ArmCallMonitor ( + IN OUT ARM_MONITOR_ARGS *Args + ) +{ + if (FeaturePcdGet (PcdMonitorConduitHvc)) { + ArmCallHvc ((ARM_HVC_ARGS*)Args); + } else { + ArmCallSmc ((ARM_SMC_ARGS*)Args); + } +} + +/** Get the version of the TRNG backend. + + A TRNG may be implemented by the system firmware, in which case this + function shall return the version of the TRNG backend. + The implementation must return NOT_SUPPORTED if a Back end is not present. + + @param [out] MajorRevision Major revision. + @param [out] MinorRevision Minor revision. + + @retval RETURN_SUCCESS The function completed successfully. + @retval RETURN_INVALID_PARAMETER Invalid parameter. + @retval RETURN_UNSUPPORTED Backend not present. +**/ +RETURN_STATUS +EFIAPI +GetTrngVersion ( + OUT UINT16 *MajorRevision, + OUT UINT16 *MinorRevision + ) +{ + RETURN_STATUS Status; + ARM_MONITOR_ARGS Parameters; + INT32 Revision; + + if ((MajorRevision == NULL) || (MinorRevision == NULL)) { + return RETURN_INVALID_PARAMETER; + } + + ZeroMem (&Parameters, sizeof (Parameters)); + + /* + Cf. [1], 2.1 TRNG_VERSION + Function ID (W0) 0x8400_0050 + Parameters + W1-W7 Reserved (MBZ) + Returns + Success (W0 > 0) W0[31] MBZ + W0[30:16] Major revision + W0[15:0] Minor revision + W1 - W3 Reserved (MBZ) + Error (W0 < 0) + NOT_SUPPORTED Function not implemented + */ + Parameters.Arg0 = FID_TRNG_VERSION; + ArmCallMonitor (&Parameters); + + Revision = (INT32)Parameters.Arg0; + // Convert status codes to EFI status codes. + Status = TrngStatusToEfiStatus (Revision); + if (EFI_ERROR (Status)) { + return Status; + } + + *MinorRevision = (Revision & TRNG_REV_MINOR_MASK); + *MajorRevision = ((Revision >> TRNG_REV_MAJOR_SHIFT) & TRNG_REV_MAJOR_MASK); + return RETURN_SUCCESS; +} + +#ifndef MDEPKG_NDEBUG +/** Get the features supported by the TRNG backend. + + The caller can determine if functions defined in the TRNG ABI are + present in the ABI implementation. + + @param [in] FunctionId Function Id. + @param [out] Capability Function specific capability if present + otherwise Zero is returned. + + @retval RETURN_SUCCESS The function completed successfully. + @retval RETURN_INVALID_PARAMETER Invalid parameter. + @retval RETURN_UNSUPPORTED Function not implemented. +**/ +STATIC +RETURN_STATUS +EFIAPI +GetTrngFeatures ( + IN CONST UINT32 FunctionId, + OUT UINT32 *Capability OPTIONAL + ) +{ + ARM_MONITOR_ARGS Parameters; + + ZeroMem (&Parameters, sizeof (Parameters)); + + /* + Cf. [1], Section 2.2 TRNG_FEATURES + Function ID (W0) 0x8400_0051 + Parameters + W1 trng_func_id + W2-W7 Reserved (MBZ) + Returns + Success (W0 >= 0) + SUCCESS Function is implemented. + > 0 Function is implemented and + has specific capabilities, + see function definition. + Error (W0 < 0) + NOT_SUPPORTED Function with FID=trng_func_id + is not implemented + */ + Parameters.Arg0 = FID_TRNG_FEATURES; + Parameters.Arg1 = FunctionId; + ArmCallMonitor (&Parameters); + if (Parameters.Arg0 < TRNG_STATUS_SUCCESS) { + return RETURN_UNSUPPORTED; + } + + if (Capability != NULL) { + *Capability = Parameters.Arg0; + } + + return RETURN_SUCCESS; +} +#endif //MDEPKG_NDEBUG + +/** Get the UUID of the TRNG backend. + + A TRNG may be implemented by the system firmware, in which case this + function shall return the UUID of the TRNG backend. + Returning the TRNG UUID is optional and if not implemented, RETURN_UNSUPPORTED + shall be returned. + + Note: The caller must not rely on the returned UUID as a trustworthy TRNG + Back end identity + + @param [out] Guid UUID of the TRNG backend. + + @retval RETURN_SUCCESS The function completed successfully. + @retval RETURN_INVALID_PARAMETER Invalid parameter. + @retval RETURN_UNSUPPORTED Function not implemented. +**/ +RETURN_STATUS +EFIAPI +GetTrngUuid ( + OUT GUID *Guid + ) +{ + RETURN_STATUS Status; + ARM_MONITOR_ARGS Parameters; + + ZeroMem (&Parameters, sizeof (Parameters)); + + /* + Cf. [1], Section 2.3 TRNG_GET_UUID + Function ID (W0) 0x8400_0052 + Parameters + W1-W7 Reserved (MBZ) + Returns + Success (W0 != -1) + W0 UUID[31:0] + W1 UUID[63:32] + W2 UUID[95:64] + W3 UUID[127:96] + Error (W0 = -1) + W0 NOT_SUPPORTED + */ + Parameters.Arg0 = FID_TRNG_GET_UUID; + ArmCallMonitor (&Parameters); + + // Convert status codes to EFI status codes. + Status = TrngStatusToEfiStatus ((INT32)Parameters.Arg0); + if (EFI_ERROR (Status)) { + return Status; + } + + Guid->Data1 = (Parameters.Arg0 & MAX_UINT32); + Guid->Data2 = (Parameters.Arg1 & MAX_UINT16); + Guid->Data3 = ((Parameters.Arg1 >> 16) & MAX_UINT16); + + Guid->Data4[0] = (Parameters.Arg2 & MAX_UINT8); + Guid->Data4[1] = ((Parameters.Arg2 >> 8) & MAX_UINT8); + Guid->Data4[2] = ((Parameters.Arg2 >> 16) & MAX_UINT8); + Guid->Data4[3] = ((Parameters.Arg2 >> 24) & MAX_UINT8); + + Guid->Data4[4] = (Parameters.Arg3 & MAX_UINT8); + Guid->Data4[5] = ((Parameters.Arg3 >> 8) & MAX_UINT8); + Guid->Data4[6] = ((Parameters.Arg3 >> 16) & MAX_UINT8); + Guid->Data4[7] = ((Parameters.Arg3 >> 24) & MAX_UINT8); + + DEBUG ((DEBUG_INFO, "FW-TRNG: UUID %g\n", Guid)); + + return RETURN_SUCCESS; +} + +/** Returns maximum number of entropy bits that can be returned in a single + call. + + @return Returns the maximum number of Entropy bits that can be returned + in a single call to GetEntropy(). +**/ +UINTN +EFIAPI +GetTrngMaxSupportedEntropyBits ( + VOID + ) +{ + return MAX_ENTROPY_BITS; +} + +/** Returns N bits of conditioned entropy. + + See [3] Section 2.3.1 GetEntropy: An Interface to the Entropy Source + GetEntropy + Input: + bits_of_entropy: the requested amount of entropy + Output: + entropy_bitstring: The string that provides the requested entropy. + status: A Boolean value that is TRUE if the request has been satisfied, + and is FALSE otherwise. + + Note: In this implementation this function returns a status code instead + of a boolean value. + This is also compatible with the definition of Get_Entropy, see [2] + Section 7.4 Entropy Source Calls. + (status, entropy_bitstring) = Get_Entropy ( + requested_entropy, + max_length + ) + + @param [in] EntropyBits Number of entropy bits requested. + @param [out] Buffer Buffer to return the entropy bits. + @param [in] BufferSize Size of the Buffer in bytes. + + @retval RETURN_SUCCESS The function completed successfully. + @retval RETURN_INVALID_PARAMETER Invalid parameter. + @retval RETURN_UNSUPPORTED Function not implemented. + @retval RETURN_BAD_BUFFER_SIZE Buffer size is too small. + @retval RETURN_NOT_READY No Entropy available. +**/ +RETURN_STATUS +EFIAPI +GetEntropy ( + IN CONST UINTN EntropyBits, + OUT UINT8 *Buffer, + IN CONST UINTN BufferSize + ) +{ + RETURN_STATUS Status; + ARM_MONITOR_ARGS Parameters; + UINTN EntropyBytes; + UINTN LastValidBits; + UINTN ArgSelector; + UINTN BytesToClear; + + // [1] Section 2.4.3 Caller responsibilities. + // The caller cannot request more than MAX_BITS bits of conditioned + // entropy per call. + if ((EntropyBits == 0) || (EntropyBits > MAX_ENTROPY_BITS)) { + return RETURN_INVALID_PARAMETER; + } + + EntropyBytes = (EntropyBits + 7) >> 3; + if (EntropyBytes > BufferSize) { + return RETURN_BAD_BUFFER_SIZE; + } + + ZeroMem (Buffer, BufferSize); + ZeroMem (&Parameters, sizeof (Parameters)); + + /* + Cf. [1], Section 2.4 TRNG_RND + Function ID (W0) 0x8400_0053 + 0xC400_0053 + SMC32 Parameters + W1 N bits of entropy (1 6 N 6 96) + W2-W7 Reserved (MBZ) + SMC64 Parameters + X1 N bits of entropy (1 6 N 6 192) + X2-X7 Reserved (MBZ) + SMC32 Returns + Success (W0 = 0): + W0 MBZ + W1 Entropy[95:64] + W2 Entropy[63:32] + W3 Entropy[31:0] + Error (W0 < 0) + W0 NOT_SUPPORTED + NO_ENTROPY + INVALID_PARAMETERS + W1 - W3 Reserved (MBZ) + SMC64 Returns + Success (X0 = 0): + X0 MBZ + X1 Entropy[191:128] + X2 Entropy[127:64] + X3 Entropy[63:0] + Error (X0 < 0) + X0 NOT_SUPPORTED + NO_ENTROPY + INVALID_PARAMETERS + X1 - X3 Reserved (MBZ) + */ + Parameters.Arg0 = FID_TRNG_RND; + Parameters.Arg1 = EntropyBits; + ArmCallMonitor (&Parameters); + + // Convert status codes to EFI status codes. + Status = TrngStatusToEfiStatus ((INT32)Parameters.Arg0); + if (EFI_ERROR (Status)) { + return Status; + } + + // Extract Data + // ArgSelector = ((EntropyBytes + 3) >> 2); for AArch32 + // ArgSelector = ((EntropyBytes + 7) >> 3); for AArch64 + // ((sizeof (UINTN) >> 2) + 1) is 3 or 2 depending on size of UINTN + ArgSelector = ((EntropyBytes + (sizeof (UINTN) - 1)) >> + ((sizeof (UINTN) >> 2) + 1)); + + switch (ArgSelector) { + case 3: + CopyMem (&Buffer[(sizeof (UINTN) * 2)], &Parameters.Arg1, sizeof (UINTN)); + + case 2: + CopyMem (&Buffer[sizeof (UINTN)], &Parameters.Arg2, sizeof (UINTN)); + + case 1: + CopyMem (&Buffer[0], &Parameters.Arg3, sizeof (UINTN)); + break; + + default: + ASSERT (0); + return RETURN_INVALID_PARAMETER; + } // switch + + + // [1] Section 2.4.3 Caller responsibilities. + // The caller must ensure that only the value in Entropy[N-1:0] is consumed + // and that the remaining bits in Entropy[MAX_BITS-1:N] are ignored. + // Therefore, Clear the unused upper bytes. + BytesToClear = (sizeof (UINTN) * ArgSelector) - EntropyBytes; + if (BytesToClear != 0) { + ZeroMem (&Buffer[EntropyBytes], BytesToClear); + } + + // Clear the unused MSB bits of the last byte. + LastValidBits = EntropyBits & 0x7; + if (LastValidBits != 0) { + Buffer[EntropyBytes - 1] &= (0xFF >> (8 - LastValidBits)); + } + + return Status; +} + +/** The constructor checks that the FW-TRNG interface is supported + by the host firmware. + + It will ASSERT() if FW-TRNG is not supported. + It will always return RETURN_SUCCESS. + + @retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS. +**/ +RETURN_STATUS +EFIAPI +ArmFwTrngLibConstructor ( + VOID + ) +{ + RETURN_STATUS Status; + UINT16 MajorRev; + UINT16 MinorRev; + GUID Guid; + + Status = GetTrngVersion (&MajorRev, &MinorRev); + if (EFI_ERROR (Status)) { + return RETURN_SUCCESS; + } + +#ifndef MDEPKG_NDEBUG + // Check that the required features are present. + Status = GetTrngFeatures (FID_TRNG_RND, NULL); + if (EFI_ERROR (Status)) { + return RETURN_SUCCESS; + } + + // Check if TRNG UUID is supported and if so trace the GUID. + Status = GetTrngFeatures (FID_TRNG_GET_UUID, NULL); + if (EFI_ERROR (Status)) { + return RETURN_SUCCESS; + } +#endif + + Status = GetTrngUuid (&Guid); + if (EFI_ERROR (Status)) { + return RETURN_SUCCESS; + } + + DEBUG (( + DEBUG_INFO, + "FW-TRNG: Version %d.%d, GUID {%g}\n", + MajorRev, + MinorRev, + Guid + )); + + return RETURN_SUCCESS; +} diff --git a/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf new file mode 100644 index 0000000000000000000000000000000000000000..4b2c58251fbe8fbcb5af308736db014e8d954720 --- /dev/null +++ b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf @@ -0,0 +1,34 @@ +## @file +# Arm Firmware TRNG interface library. +# +# Copyright (c) 2021, Arm Limited. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = ArmFwTrngLib + FILE_GUID = 10DE97C9-28E4-4C9B-A53E-8D7D1B0DD4E0 + VERSION_STRING = 1.0 + MODULE_TYPE = BASE + LIBRARY_CLASS = TrngLib + CONSTRUCTOR = ArmFwTrngLibConstructor + +[Sources] + ArmFwTrngDefs.h + ArmFwTrngLib.c + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmSmcLib + ArmHvcLib + BaseLib + BaseMemoryLib + +[Pcd] + gArmTokenSpaceGuid.PcdMonitorConduitHvc + -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' |
|
Leif Lindholm <leif@...>
Hi Sami,
On Tue, Nov 16, 2021 at 11:32:55 +0000, Sami Mujawar wrote: Bugzilla: 3668 (https://bugzilla.tianocore.org/show_bug.cgi?id=3668)Do these belong in ArmStdSmc.h? +And the rest of the stuff to here, really? +#if defined (MDE_CPU_ARM)Should this be in (a potentially renamed) ArmSmcLib? +I have a comment on the placement of API descriptions further down. + Parameters.Arg0 = FID_TRNG_VERSION;I have a comment on the placement of API descriptions further down. + Parameters.Arg0 = FID_TRNG_FEATURES;Comment is redundant, code is clearer without it. + if ((EntropyBits == 0) || (EntropyBits > MAX_ENTROPY_BITS)) {Not for later: we're verifying the value of EntropyBytes here - if there are more aspects of it that need verifying, that should also be done here. + return RETURN_BAD_BUFFER_SIZE;The above comment block completely wrecks the readability of the function. Would suggest putting it in the header file describing the monitor call. For our SIP SVC calls, we've done this in the following form: /* * SMC call to retrieve number of CPUs present in the system. * Input values: * x0: NUVIA_SIP_GET_NUM_CPUS * Return values: * x0: SMC_OK * x1: Number of CPUs present */ #define NUVIA_SIP_GET_NUM_CPUS SIP_FUNCTION_ID(0x20) (Where SIP_FUNCTION_ID is one of a set of macros I should submit for addition to ArmStdSmc.h) + Parameters.Arg0 = FID_TRNG_RND;Function name already says this, comment redundant. + Status = TrngStatusToEfiStatus ((INT32)Parameters.Arg0);From here + // Extract Datato here ... I'm not convinced you yourself would be able to read or explain this code a few months down the line. Is there a strong reason for why Buffer cannot be a UINTN *? I think what this code is doing can equally be written as: Buffer[0] = Parameters.Arg3; if ((EntropyBytes / sizeof (UINTN)) > 1) { Buffer[1] = Parameters.Arg2; } if ((EntropyBytes / sizeof (UINTN)) > 2) { Buffer[2] = Parameters.Arg1; } +This is source code, not the specification. // Mask off any unused top bytes, in accordance with specification is sufficient as a comment. / Leif + BytesToClear = (sizeof (UINTN) * ArgSelector) - EntropyBytes; |
|
Sami Mujawar
Hi Leif,
Thank you for the feedback. Please find my response inline marked [SAMI]. Regards, Sami Mujawar On 24/11/2021 01:01 PM, Leif Lindholm wrote: Hi Sami,[SAMI] I will fix this in the next version. [SAMI] I will fix this in the next version.+And the rest of the stuff to here, really? [SAMI] Looking at ArmSmcLib and ArmHvcLib libraries there is not much difference in the code other than the SMC/HVC call. Please let me know if I should submit a patch to unify these in ArmMonitorLib?+#if defined (MDE_CPU_ARM)Should this be in (a potentially renamed) ArmSmcLib? The ArmCall<Smc|Hvc> APIs would still remain the same but moved to ArmMonitorLib. [SAMI] The specification allows to request minimum 1 bit of entropy (although I don't think there would be a use case for this). Therefore, I selected UINT8.+I have a comment on the placement of API descriptions further down. However, I agree the logic is complex. I will simplify this code. [SAMI] I will fix this and the other comments in the next revision.
|
|
PierreGondois
On 11/25/21 16:23, Sami Mujawar via groups.io wrote:
Hi Leif,[...] Hello Leif,[SAMI] Looking at ArmSmcLib and ArmHvcLib libraries there is not much+Should this be in (a potentially renamed) ArmSmcLib? About your comment, I am not sure I understand it correctly. Assuming the function allowing to choose the conduit looks like: VOID EFIAPI ArmConduitCall (UINT8 Conduit) { if (Conduit == 0) { ArmCallHvc ((ARM_HVC_ARGS*)Args); } else if (Conduit == 1) { ArmCallSmc ((ARM_SMC_ARGS*)Args); } else { ASSERT (FALSE); } } Do you suggest to: 1. Make ArmSmcLib dependent on ArmHvcLib and add ArmConduitCall() in ArmSmcLib (or do the opposite with the ArmHvcLib) 2. Merge ArmSmcLib and ArmHvcLib in a new ArmConduitLibrary and add ArmConduitCall() in this new library. 3. Add an ArmConduitLibrary, relying on ArmSmcLib and ArmHvcLib, and having only one function: ArmConduitCall() 2. would make the Hvc and Smc calls really tied together. 3. would avoid creating new dependencies on existing libraries (i.e. a platform only using the ArmSmcLib would not require to have a NULL instance of ArmHvcLib). I assume you meant 3. Regards, Pierre |
|
PierreGondois
(Replacing Leif's mail address to the @quicinc.com one)
toggle quoted message
Show quoted text
On 3/24/22 10:46, Pierre Gondois wrote:
On 11/25/21 16:23, Sami Mujawar via groups.io wrote:Hi Leif,[...] |
|
Leif Lindholm
On Thu, Mar 24, 2022 at 15:56:32 +0100, Pierre Gondois wrote:
I think 2 and 3 both capture the spirit of my request.Hello Leif,[SAMI] Looking at ArmSmcLib and ArmHvcLib libraries there is not much+/** Invoke the monitor call using the appropriate conduit.Should this be in (a potentially renamed) ArmSmcLib? 2 could potentially be achieved with a FixedPcd and conditionals in asm (less sure about the armasm/vs situation). I guess the question is if we think it plausible that a platform might both want to use this new ArmConduitCall *and* directly make use of ArmHvcLib/ArmSmcLib. Best Regards, Leif |
|