[edk2-devel] [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions

Rebecca Cran rebecca at nuviainc.com
Wed Apr 28 20:44:13 UTC 2021


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

Signed-off-by: Rebecca Cran <rebecca at nuviainc.com>
---
 MdePkg/Library/BaseLib/BaseLib.inf                |  4 ++
 MdePkg/Include/Library/BaseLib.h                  | 47 +++++++++++++++++
 MdePkg/Library/BaseLib/BaseLibInternals.h         |  6 +++
 MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S   | 29 +++++++++++
 MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm | 28 ++++++++++
 MdePkg/Library/BaseLib/AArch64/ArmRng.S           | 51 ++++++++++++++++++
 MdePkg/Library/BaseLib/AArch64/ArmRng.asm         | 55 ++++++++++++++++++++
 7 files changed, 220 insertions(+)

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index b76f3af380ea..7f582079d786 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -380,6 +380,8 @@ [Sources.AARCH64]
   AArch64/SetJumpLongJump.S         | GCC
   AArch64/CpuBreakpoint.S           | GCC
   AArch64/SpeculationBarrier.S      | GCC
+  AArch64/ArmRng.S                  | GCC
+  AArch64/ArmReadIdIsar0.S          | GCC
 
   AArch64/MemoryFence.asm           | MSFT
   AArch64/SwitchStack.asm           | MSFT
@@ -389,6 +391,8 @@ [Sources.AARCH64]
   AArch64/SetJumpLongJump.asm       | MSFT
   AArch64/CpuBreakpoint.asm         | MSFT
   AArch64/SpeculationBarrier.asm    | MSFT
+  AArch64/ArmRng.asm                | MSFT
+  AArch64/ArmReadIdIsar0.asm        | MSFT
 
 [Sources.RISCV64]
   Math64.c
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 7253997a6f8c..60cf559b0849 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7519,4 +7519,51 @@ PatchInstructionX86 (
   );
 
 #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+
+#if defined (MDE_CPU_AARCH64)
+
+/**
+  Reads the ID_AA64ISAR0 Register.
+
+  @return The contents of the ID_AA64ISAR0 Register
+
+**/
+UINT64
+EFIAPI
+ArmReadIdIsar0 (
+  VOID
+  );
+
+/**
+  Generates a random number using the RNDR instruction.
+
+  @param[out]  The generated random number
+
+  @retval TRUE  Success: a random number was successfully generated
+  @retval FALSE Failure: a random number was unable to be generated
+
+**/
+BOOLEAN
+EFIAPI
+ArmRndr (
+  OUT UINT64 *Rand
+  );
+
+/**
+  Generates a random number using the RNDRRS instruction.
+
+  @param[out]  The generated random number
+
+  @retval TRUE  Success: a random number was successfully generated
+  @retval FALSE Failure: a random number was unable to be generated
+
+**/
+BOOLEAN
+EFIAPI
+ArmRndrrs (
+  OUT UINT64 *Rand
+  );
+
+#endif // defined (MDE_CPU_AARCH64)
+
 #endif // !defined (__BASE_LIB__)
diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h b/MdePkg/Library/BaseLib/BaseLibInternals.h
index 6837d67d90cf..4ae79a4e7ab4 100644
--- a/MdePkg/Library/BaseLib/BaseLibInternals.h
+++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
@@ -862,6 +862,12 @@ InternalX86RdRand64  (
   OUT     UINT64                    *Rand
   );
 
+#elif defined (MDE_CPU_AARCH64)
+
+// RNDR, Random Number
+#define RNDR      S3_3_C2_C4_0
+#define RNDRRS    S3_3_C2_C4_1
+
 #else
 
 #endif
diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
new file mode 100644
index 000000000000..b31e565c7955
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
@@ -0,0 +1,29 @@
+#------------------------------------------------------------------------------
+#
+# ArmReadIdIsar0() for AArch64
+#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#------------------------------------------------------------------------------
+
+.text
+.p2align 2
+GCC_ASM_EXPORT(ArmReadIdIsar0)
+
+#/**
+#  Reads the ID_AA64ISAR0 Register.
+#
+#**/
+#UINT64
+#EFIAPI
+#ArmReadIdIsar0 (
+#  VOID
+#  );
+#
+ASM_PFX(ArmReadIdIsar0):
+  mrs  x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register
+  ret
+
+
diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm
new file mode 100644
index 000000000000..1f1d15626cc2
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm
@@ -0,0 +1,28 @@
+;------------------------------------------------------------------------------
+;
+; ArmReadIdIsar0() for AArch64
+;
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+  EXPORT ArmReadIdIsar0
+  AREA BaseLib_LowLevel, CODE, READONLY
+
+;/**
+;  Reads the ID_AA64ISAR0 Register.
+;
+;**/
+;UINT64
+;EFIAPI
+;ArmReadIdIsar0 (
+;  VOID
+;  );
+;
+ArmReadIdIsar0
+  mrs  x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register
+  ret
+
+  END
diff --git a/MdePkg/Library/BaseLib/AArch64/ArmRng.S b/MdePkg/Library/BaseLib/AArch64/ArmRng.S
new file mode 100644
index 000000000000..fc2adb660d21
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmRng.S
@@ -0,0 +1,51 @@
+#------------------------------------------------------------------------------
+#
+# ArmRndr() and ArmRndrrs() for AArch64
+#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#------------------------------------------------------------------------------
+
+#include "BaseLibInternals.h"
+
+.text
+.p2align 2
+GCC_ASM_EXPORT(ArmRndr)
+GCC_ASM_EXPORT(ArmRndrrs)
+
+#/**
+#  Generates a random number using RNDR.
+#  Returns TRUE on success; FALSE on failure.
+#
+#**/
+#BOOLEAN
+#EFIAPI
+#ArmRndr (
+#  OUT UINT64 *Rand
+#  );
+#
+ASM_PFX(ArmRndr):
+  mrs  x1, RNDR
+  str  x1, [x0]
+  cset x0, ne    // RNDR sets NZCV to 0b0100 on failure
+  ret
+
+
+#/**
+# Generates a random number using RNDRRS
+# Returns TRUE on success; FALSE on failure.
+#
+#**/
+#BOOLEAN
+#EFIAPI
+#ArmRndrrs (
+#  OUT UINT64 *Rand
+#  );
+#
+ASM_PFX(ArmRndrrs):
+  mrs  x1, RNDRRS
+  str  x1, [x0]
+  cset x0, ne    // RNDRRS sets NZCV to 0b0100 on failure
+  ret
diff --git a/MdePkg/Library/BaseLib/AArch64/ArmRng.asm b/MdePkg/Library/BaseLib/AArch64/ArmRng.asm
new file mode 100644
index 000000000000..ed8d1a81bdfe
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmRng.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; ArmRndr() and ArmRndrrs() for AArch64
+;
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+#include "BaseLibInternals.h"
+
+  EXPORT ArmRndr
+  EXPORT ArmRndrrs
+  AREA BaseLib_LowLevel, CODE, READONLY
+
+
+;/**
+;  Generates a random number using RNDR.
+;  Returns TRUE on success; FALSE on failure.
+;
+;**/
+;BOOLEAN
+;EFIAPI
+;ArmRndr (
+;  OUT UINT64 *Rand
+;  );
+;
+ArmRndr
+  mrs  x1, RNDR
+  str  x1, [x0]
+  cset x0, ne    // RNDR sets NZCV to 0b0100 on failure
+  ret
+
+  END
+
+;/**
+;  Generates a random number using RNDRRS.
+;  Returns TRUE on success; FALSE on failure.
+;
+;**/
+;BOOLEAN
+;EFIAPI
+;ArmRndrrs (
+;  OUT UINT64 *Rand
+;  );
+;
+ArmRndrrs
+  mrs  x1, RNDRRS
+  str  x1, [x0]
+  cset x0, ne    // RNDRRS sets NZCV to 0b0100 on failure
+  ret
+
+  END
+
-- 
2.26.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#74579): https://edk2.groups.io/g/devel/message/74579
Mute This Topic: https://groups.io/mt/82440610/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list