summaryrefslogtreecommitdiffstats
path: root/src/interface
diff options
context:
space:
mode:
authorSimon Rettberg2019-02-15 10:38:49 +0100
committerSimon Rettberg2019-02-15 10:38:49 +0100
commita58276abdde401bae19525c7c5895c6fbbfc22e2 (patch)
treeebc3ec62e571c1c8f8d7a7ed557cb4c23ec32534 /src/interface
parentMerge branch 'master' into openslx (diff)
downloadipxe-a58276abdde401bae19525c7c5895c6fbbfc22e2.tar.gz
ipxe-a58276abdde401bae19525c7c5895c6fbbfc22e2.tar.xz
ipxe-a58276abdde401bae19525c7c5895c6fbbfc22e2.zip
[efi] Add very ugly hack to use HW RNG on EFI
This is just added in the completely wrong spot, but makes very slow initialization on efi go away.
Diffstat (limited to 'src/interface')
-rw-r--r--src/interface/efi/efi_entropy.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/interface/efi/efi_entropy.c b/src/interface/efi/efi_entropy.c
index 2a2fc9054..2dd231b22 100644
--- a/src/interface/efi/efi_entropy.c
+++ b/src/interface/efi/efi_entropy.c
@@ -30,6 +30,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/Rng.h>
+#if defined(__i386) || defined(__x86_64)
+#include <ipxe/cpuid.h>
+static char have_hwrnd = 0;
+#endif
+
/** @file
*
* EFI entropy source
@@ -120,6 +125,28 @@ static int efi_entropy_tick ( void ) {
EFI_STATUS efirc;
int rc;
+#if defined(__i386) || defined(__x86_64)
+ if ( have_hwrnd == 0 ) {
+ struct x86_features features;
+ x86_features( &features );
+ if ( features.intel.ecx & ( 1 << 30 ) ) {
+ have_hwrnd = 1;
+ } else {
+ have_hwrnd = 2;
+ }
+ DBGC( &tick, "Have RDRAND: %s\n", ( have_hwrnd == 1 ? "YES!" : "NO :-(" ) );
+ }
+ if ( have_hwrnd == 1 ) {
+ int ret, retries = 10;
+ char ok;
+ while ( --retries > 0 ) {
+ __asm__ volatile ( "rdrand %0; setc %1" : "=r" ( ret ), "=qm" ( ok ) );
+ if ( ok )
+ return ret & 0x7fffffff;
+ }
+ }
+#endif
+
/* Wait for next timer tick */
if ( ( efirc = bs->SetTimer ( tick, TimerRelative,
EFI_ENTROPY_TRIGGER_TIME ) ) != 0 ) {