Luna/kernel/src/rand/Init.cpp

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);
}