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