Revision: 18785
          http://sourceforge.net/p/edk2/code/18785
Author:   vanjeff
Date:     2015-11-16 06:38:00 +0000 (Mon, 16 Nov 2015)
Log Message:
-----------
MdePkg: Add CPU RdRand access APIs for random number generation

Add AsmRdRand16/32/64 APIs for RdRand instruction access to generate
high-quality random number.

(Sync patch r18518 from main trunk.)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Qin Long <[email protected]>
Reviewed-by: Michael Kinney <[email protected]>
Reviewed-by: Liming Gao <[email protected]>

Revision Links:
--------------
    http://sourceforge.net/p/edk2/code/18518

Modified Paths:
--------------
    branches/UDK2015/MdePkg/Include/Library/BaseLib.h
    branches/UDK2015/MdePkg/Library/BaseLib/BaseLib.inf

Added Paths:
-----------
    branches/UDK2015/MdePkg/Library/BaseLib/Ia32/RdRand.S
    branches/UDK2015/MdePkg/Library/BaseLib/Ia32/RdRand.asm
    branches/UDK2015/MdePkg/Library/BaseLib/X64/RdRand.S
    branches/UDK2015/MdePkg/Library/BaseLib/X64/RdRand.asm

Modified: branches/UDK2015/MdePkg/Include/Library/BaseLib.h
===================================================================
--- branches/UDK2015/MdePkg/Include/Library/BaseLib.h   2015-11-16 05:29:49 UTC 
(rev 18784)
+++ branches/UDK2015/MdePkg/Include/Library/BaseLib.h   2015-11-16 06:38:00 UTC 
(rev 18785)
@@ -7647,6 +7647,57 @@
   IN OUT  THUNK_CONTEXT             *ThunkContext
   );
 
+/**
+  Generates a 16-bit random number through RDRAND instruction.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out]  Rand     Buffer pointer to store the random result.
+
+  @retval TRUE          RDRAND call was successful.
+  @retval FALSE         Failed attempts to call RDRAND.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdRand16 (
+  OUT     UINT16                    *Rand
+  );
+
+/**
+  Generates a 32-bit random number through RDRAND instruction.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out]  Rand     Buffer pointer to store the random result.
+
+  @retval TRUE          RDRAND call was successful.
+  @retval FALSE         Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdRand32 (
+  OUT     UINT32                    *Rand
+  );
+
+/**
+  Generates a 64-bit random number through RDRAND instruction.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out]  Rand     Buffer pointer to store the random result.
+
+  @retval TRUE          RDRAND call was successful.
+  @retval FALSE         Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdRand64  (
+  OUT     UINT64                    *Rand
+  );
+
 #endif
 #endif
 

Modified: branches/UDK2015/MdePkg/Library/BaseLib/BaseLib.inf
===================================================================
--- branches/UDK2015/MdePkg/Library/BaseLib/BaseLib.inf 2015-11-16 05:29:49 UTC 
(rev 18784)
+++ branches/UDK2015/MdePkg/Library/BaseLib/BaseLib.inf 2015-11-16 06:38:00 UTC 
(rev 18785)
@@ -159,6 +159,7 @@
   Ia32/EnablePaging64.asm | MSFT
   Ia32/EnableCache.c | MSFT
   Ia32/DisableCache.c | MSFT
+  Ia32/RdRand.asm | MSFT
 
   Ia32/Wbinvd.asm | INTEL 
   Ia32/WriteMm7.asm | INTEL 
@@ -252,6 +253,7 @@
   Ia32/EnablePaging64.asm | INTEL
   Ia32/EnableCache.asm | INTEL
   Ia32/DisableCache.asm | INTEL
+  Ia32/RdRand.asm | INTEL
 
   Ia32/GccInline.c | GCC
   Ia32/Thunk16.nasm | GCC 
@@ -279,6 +281,7 @@
   Ia32/LShiftU64.S | GCC 
   Ia32/EnableCache.S | GCC
   Ia32/DisableCache.S | GCC
+  Ia32/RdRand.S | GCC
 
   Ia32/DivS64x64Remainder.c
   Ia32/InternalSwitchStack.c | MSFT
@@ -383,10 +386,12 @@
   X64/CpuBreakpoint.c | MSFT 
   X64/WriteMsr64.c | MSFT 
   X64/ReadMsr64.c | MSFT 
+  X64/RdRand.asm | MSFT
 
   X64/CpuBreakpoint.asm | INTEL 
   X64/WriteMsr64.asm | INTEL 
   X64/ReadMsr64.asm | INTEL 
+  X64/RdRand.asm | INTEL
 
   X64/Non-existing.c
   Math64.c
@@ -417,6 +422,7 @@
   X64/CpuIdEx.S | GCC 
   X64/EnableCache.S | GCC
   X64/DisableCache.S | GCC
+  X64/RdRand.S | GCC
   ChkStkGcc.c  | GCC 
 
 [Sources.IPF]

Added: branches/UDK2015/MdePkg/Library/BaseLib/Ia32/RdRand.S
===================================================================
--- branches/UDK2015/MdePkg/Library/BaseLib/Ia32/RdRand.S                       
        (rev 0)
+++ branches/UDK2015/MdePkg/Library/BaseLib/Ia32/RdRand.S       2015-11-16 
06:38:00 UTC (rev 18785)
@@ -0,0 +1,80 @@
+#------------------------------------------------------------------------------
 ;
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD 
License
+# which accompanies this distribution.  The full text of the license may be 
found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+#   RdRand.S
+#
+# Abstract:
+#
+#   Generates random number through CPU RdRand instruction under 32-bit 
platform.
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+//  Generates a 16 bit random number through RDRAND instruction.
+//  Return TRUE if Rand generated successfully, or FALSE if not.
+//
+//  BOOLEAN EFIAPI AsmRdRand16 (UINT16 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand16)
+ASM_PFX(AsmRdRand16):
+    .byte  0x0f, 0xc7, 0xf0        // rdrand r16: "0f c7 /6  ModRM:r/m(w)"
+    jc     rn16_ok                 // jmp if CF=1
+    xor    %eax, %eax              // reg=0 if CF=0
+    ret                            // return with failure status
+rn16_ok:
+    mov    0x4(%esp), %edx
+    mov    %ax, (%edx)
+    mov    $0x1, %eax
+    ret
+
+//------------------------------------------------------------------------------
+//  Generates a 32 bit random number through RDRAND instruction.
+//  Return TRUE if Rand generated successfully, or FALSE if not.
+//
+//  BOOLEAN EFIAPI AsmRdRand32 (UINT32 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand32)
+ASM_PFX(AsmRdRand32):
+    .byte  0x0f, 0xc7, 0xf0        // rdrand r32: "0f c7 /6  ModRM:r/m(w)"
+    jc     rn32_ok                 // jmp if CF=1
+    xor    %eax, %eax              // reg=0 if CF=0
+    ret                            // return with failure status
+rn32_ok:
+    mov    0x4(%esp), %edx
+    mov    %eax, (%edx)
+    mov    $0x1, %eax
+    ret
+
+//------------------------------------------------------------------------------
+//  Generates a 64 bit random number through RDRAND instruction.
+//  Return TRUE if Rand generated successfully, or FALSE if not.
+//
+//  BOOLEAN EFIAPI AsmRdRand64 (UINT64 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand64)
+ASM_PFX(AsmRdRand64):
+    .byte  0x0f, 0xc7, 0xf0        // rdrand r32: "0f c7 /6  ModRM:r/m(w)"
+    jnc    rn64_ret                // jmp if CF=0
+    mov    0x4(%esp), %edx
+    mov    %eax, (%edx)
+
+    .byte  0x0f, 0xc7, 0xf0        // generate another 32 bit RN
+    jnc    rn64_ret                // jmp if CF=0
+    mov    %eax, 0x4(%edx)
+
+    mov    $0x1, %eax
+    ret
+rn64_ret:
+    xor    %eax, %eax
+    ret                            // return with failure status

Added: branches/UDK2015/MdePkg/Library/BaseLib/Ia32/RdRand.asm
===================================================================
--- branches/UDK2015/MdePkg/Library/BaseLib/Ia32/RdRand.asm                     
        (rev 0)
+++ branches/UDK2015/MdePkg/Library/BaseLib/Ia32/RdRand.asm     2015-11-16 
06:38:00 UTC (rev 18785)
@@ -0,0 +1,94 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD 
License
+; which accompanies this distribution.  The full text of the license may be 
found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+;   RdRand.asm
+;
+; Abstract:
+;
+;   Generates random number through CPU RdRand instruction under 32-bit 
platform.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+.686P
+.model flat, C
+
+.code
+
+;------------------------------------------------------------------------------
+;  Generates a 16 bit random number through RDRAND instruction.
+;  Return TRUE if Rand generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI AsmRdRand16 (UINT16 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand16  PROC
+    ; rdrand   ax                  ; generate a 16 bit RN into ax
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0fh, 0c7h, 0f0h         ; rdrand r16: "0f c7 /6  ModRM:r/m(w)"
+    jc     rn16_ok                 ; jmp if CF=1
+    xor    eax, eax                ; reg=0 if CF=0
+    ret                            ; return with failure status
+rn16_ok:
+    mov    edx, dword ptr [esp + 4]
+    mov    [edx], ax
+    mov    eax,  1
+    ret
+AsmRdRand16 ENDP
+
+;------------------------------------------------------------------------------
+;  Generates a 32 bit random number through RDRAND instruction.
+;  Return TRUE if Rand generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI AsmRdRand32 (UINT32 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand32  PROC
+    ; rdrand   eax                 ; generate a 32 bit RN into eax
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0fh, 0c7h, 0f0h         ; rdrand r32: "0f c7 /6  ModRM:r/m(w)"
+    jc     rn32_ok                 ; jmp if CF=1
+    xor    eax, eax                ; reg=0 if CF=0
+    ret                            ; return with failure status
+rn32_ok:
+    mov    edx, dword ptr [esp + 4]
+    mov    [edx], eax
+    mov    eax,  1
+    ret
+AsmRdRand32 ENDP
+
+;------------------------------------------------------------------------------
+;  Generates a 64 bit random number through RDRAND instruction.
+;  Return TRUE if Rand generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI AsmRdRand64 (UINT64 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand64  PROC
+    ; rdrand   eax                 ; generate a 32 bit RN into eax
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0fh, 0c7h, 0f0h         ; rdrand r32: "0f c7 /6  ModRM:r/m(w)"
+    jnc    rn64_ret                ; jmp if CF=0
+    mov    edx, dword ptr [esp + 4]
+    mov    [edx], eax
+
+    db     0fh, 0c7h, 0f0h         ; generate another 32 bit RN
+    jnc    rn64_ret                ; jmp if CF=0
+    mov    [edx + 4], eax
+
+    mov    eax,  1
+    ret
+rn64_ret:
+    xor    eax, eax
+    ret                            ; return with failure status
+AsmRdRand64 ENDP
+
+    END

Added: branches/UDK2015/MdePkg/Library/BaseLib/X64/RdRand.S
===================================================================
--- branches/UDK2015/MdePkg/Library/BaseLib/X64/RdRand.S                        
        (rev 0)
+++ branches/UDK2015/MdePkg/Library/BaseLib/X64/RdRand.S        2015-11-16 
06:38:00 UTC (rev 18785)
@@ -0,0 +1,72 @@
+#------------------------------------------------------------------------------
 ;
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD 
License
+# which accompanies this distribution.  The full text of the license may be 
found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+#   RdRand.S
+#
+# Abstract:
+#
+#   Generates random number through CPU RdRand instruction under 64-bit 
platform.
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+//  Generates a 16 bit random number through RDRAND instruction.
+//  Return TRUE if Rand generated successfully, or FALSE if not.
+//
+//  BOOLEAN EFIAPI AsmRdRand16 (UINT16 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand16)
+ASM_PFX(AsmRdRand16):
+    .byte  0x0f, 0xc7, 0xf0        // rdrand r16: "0f c7 /6  ModRM:r/m(w)"
+    jc     rn16_ok                 // jmp if CF=1
+    xor    %rax, %rax              // reg=0 if CF=0
+    ret                            // return with failure status
+rn16_ok:
+    mov    %ax, (%rcx)
+    mov    $0x1, %rax
+    ret
+
+//------------------------------------------------------------------------------
+//  Generates a 32 bit random number through RDRAND instruction.
+//  Return TRUE if Rand generated successfully, or FALSE if not.
+//
+//  BOOLEAN EFIAPI AsmRdRand32 (UINT32 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand32)
+ASM_PFX(AsmRdRand32):
+    .byte  0x0f, 0xc7, 0xf0        // rdrand r32: "0f c7 /6  ModRM:r/m(w)"
+    jc     rn32_ok                 // jmp if CF=1
+    xor    %rax, %rax              // reg=0 if CF=0
+    ret                            // return with failure status
+rn32_ok:
+    mov    %eax, (%rcx)
+    mov    $0x1, %rax
+    ret
+
+//------------------------------------------------------------------------------
+//  Generates a 64 bit random number through RDRAND instruction.
+//  Return TRUE if Rand generated successfully, or FALSE if not.
+//
+//  BOOLEAN EFIAPI AsmRdRand64 (UINT64 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand64)
+ASM_PFX(AsmRdRand64):
+    .byte  0x48, 0x0f, 0xc7, 0xf0  // rdrand r64: "REX.W + 0f c7 /6 
ModRM:r/m(w)"
+    jc     rn64_ok                 // jmp if CF=1
+    xor    %rax, %rax              // reg=0 if CF=0
+    ret                            // return with failure status
+rn64_ok:
+    mov    %rax, (%rcx)
+    mov    $0x1, %rax
+    ret

Added: branches/UDK2015/MdePkg/Library/BaseLib/X64/RdRand.asm
===================================================================
--- branches/UDK2015/MdePkg/Library/BaseLib/X64/RdRand.asm                      
        (rev 0)
+++ branches/UDK2015/MdePkg/Library/BaseLib/X64/RdRand.asm      2015-11-16 
06:38:00 UTC (rev 18785)
@@ -0,0 +1,83 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD 
License
+; which accompanies this distribution.  The full text of the license may be 
found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+;   RdRand.asm
+;
+; Abstract:
+;
+;   Generates random number through CPU RdRand instruction under 64-bit 
platform.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+    .code
+
+;------------------------------------------------------------------------------
+;  Generates a 16 bit random number through RDRAND instruction.
+;  Return TRUE if Rand generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI AsmRdRand16 (UINT16 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand16  PROC
+    ; rdrand   ax                  ; generate a 16 bit RN into eax,
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0fh, 0c7h, 0f0h         ; rdrand r16: "0f c7 /6  ModRM:r/m(w)"
+    jc     rn16_ok                 ; jmp if CF=1
+    xor    rax, rax                ; reg=0 if CF=0
+    ret                            ; return with failure status
+rn16_ok:
+    mov    [rcx], ax
+    mov    rax,  1
+    ret
+AsmRdRand16 ENDP
+
+;------------------------------------------------------------------------------
+;  Generates a 32 bit random number through RDRAND instruction.
+;  Return TRUE if Rand generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI AsmRdRand32 (UINT32 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand32  PROC
+    ; rdrand   eax                 ; generate a 32 bit RN into eax,
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0fh, 0c7h, 0f0h         ; rdrand r32: "0f c7 /6  ModRM:r/m(w)"
+    jc     rn32_ok                 ; jmp if CF=1
+    xor    rax, rax                ; reg=0 if CF=0
+    ret                            ; return with failure status
+rn32_ok:
+    mov    [rcx], eax
+    mov    rax,  1
+    ret
+AsmRdRand32 ENDP
+
+;------------------------------------------------------------------------------
+;  Generates a 64 bit random number through one RDRAND instruction.
+;  Return TRUE if Rand generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI AsmRdRand64 (UINT64 *Random);
+;------------------------------------------------------------------------------
+AsmRdRand64  PROC
+    ; rdrand   rax                 ; generate a 64 bit RN into rax,
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     048h, 0fh, 0c7h, 0f0h   ; rdrand r64: "REX.W + 0f c7 /6 
ModRM:r/m(w)"
+    jc     rn64_ok                 ; jmp if CF=1
+    xor    rax, rax                ; reg=0 if CF=0
+    ret                            ; return with failure status
+rn64_ok:
+    mov    [rcx], rax
+    mov    rax, 1
+    ret
+AsmRdRand64 ENDP
+
+    END


------------------------------------------------------------------------------
Presto, an open source distributed SQL query engine for big data, initially
developed by Facebook, enables you to easily query your data on Hadoop in a 
more interactive manner. Teradata is also now providing full enterprise
support for Presto. Download a free open source copy now.
http://pubads.g.doubleclick.net/gampad/clk?id=250295911&iu=/4140
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to