74 lines
1.3 KiB
C++
74 lines
1.3 KiB
C++
#define MODULE "rand"
|
|
|
|
#include "rand/Init.h"
|
|
#include "config.h"
|
|
#include "cpu/CPU.h"
|
|
#include "io/IO.h"
|
|
#include "log/Log.h"
|
|
#include "rand/Mersenne.h"
|
|
|
|
static uint64_t state = 0xf5026f5ae96319e9;
|
|
|
|
static bool has_rdrand = false;
|
|
static bool has_rdseed = false;
|
|
|
|
extern "C" int asm_test_rdseed();
|
|
|
|
static uint64_t rdtsc()
|
|
{
|
|
uint64_t result1;
|
|
uint64_t result2;
|
|
asm volatile("rdtsc" : "=a"(result1), "=d"(result2));
|
|
return result2 << 32 | result1;
|
|
}
|
|
|
|
static uint64_t rdseed()
|
|
{
|
|
uint64_t result;
|
|
asm volatile("rdseed %0" : "=r"(result));
|
|
return result;
|
|
}
|
|
|
|
static uint64_t rdrand()
|
|
{
|
|
uint64_t result;
|
|
asm volatile("rdrand %0" : "=r"(result));
|
|
return result;
|
|
}
|
|
|
|
void Mersenne::init()
|
|
{
|
|
kdbgln("Preparing random number generator");
|
|
|
|
has_rdrand = CPU::has_feature(CPU::Features::RDRAND);
|
|
has_rdseed = asm_test_rdseed();
|
|
|
|
state ^= (0x45fe1024UL + __moon_version_major()) * (__moon_version_minor() ^ 200UL);
|
|
|
|
state ^= 0xe0e4f5332ea75b;
|
|
|
|
reseed();
|
|
|
|
state ^= Mersenne::get() * 0xffe3;
|
|
|
|
state ^= rdtsc();
|
|
|
|
Mersenne::seed(state);
|
|
}
|
|
|
|
void Mersenne::reseed()
|
|
{
|
|
state ^= rdtsc();
|
|
|
|
if (has_rdrand) { state ^= rdrand(); }
|
|
|
|
if (has_rdseed) { state ^= rdseed(); }
|
|
|
|
state ^= rdtsc();
|
|
|
|
state ^= IO::inb(0x40);
|
|
|
|
state ^= rdtsc();
|
|
|
|
Mersenne::seed(state);
|
|
} |