forked from Bananymous/banan-os
Kernel: Implement super simple PRNG
This commit is contained in:
parent
ff49d8b84f
commit
b45d27593f
|
@ -64,6 +64,7 @@ set(KERNEL_SOURCES
|
||||||
kernel/PCI.cpp
|
kernel/PCI.cpp
|
||||||
kernel/PIC.cpp
|
kernel/PIC.cpp
|
||||||
kernel/Process.cpp
|
kernel/Process.cpp
|
||||||
|
kernel/Random.cpp
|
||||||
kernel/Scheduler.cpp
|
kernel/Scheduler.cpp
|
||||||
kernel/Semaphore.cpp
|
kernel/Semaphore.cpp
|
||||||
kernel/SpinLock.cpp
|
kernel/SpinLock.cpp
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace Kernel
|
||||||
|
{
|
||||||
|
|
||||||
|
class Random
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void initialize();
|
||||||
|
static uint32_t get_u32();
|
||||||
|
static uint64_t get_u64();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include <kernel/Debug.h>
|
||||||
|
#include <kernel/CPUID.h>
|
||||||
|
#include <kernel/Random.h>
|
||||||
|
|
||||||
|
namespace Kernel
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// Constants and algorithm from https://en.wikipedia.org/wiki/Permuted_congruential_generator
|
||||||
|
|
||||||
|
static uint64_t s_rand_seed = 0x4d595df4d0f33173;
|
||||||
|
static constexpr uint64_t s_rand_multiplier = 6364136223846793005;
|
||||||
|
static constexpr uint64_t s_rand_increment = 1442695040888963407;
|
||||||
|
|
||||||
|
void Random::initialize()
|
||||||
|
{
|
||||||
|
uint32_t ecx, edx;
|
||||||
|
CPUID::get_features(ecx, edx);
|
||||||
|
|
||||||
|
if (ecx & CPUID::ECX_RDRND)
|
||||||
|
asm volatile("rdrand %0" : "=a"(s_rand_seed));
|
||||||
|
else
|
||||||
|
dprintln("No RDRAND available");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Random::get_u32()
|
||||||
|
{
|
||||||
|
auto rotr32 = [](uint32_t x, unsigned r) { return x >> r | x << (-r & 31); };
|
||||||
|
|
||||||
|
uint64_t x = s_rand_seed;
|
||||||
|
unsigned count = (unsigned)(x >> 59);
|
||||||
|
|
||||||
|
s_rand_seed = x * s_rand_multiplier + s_rand_increment;
|
||||||
|
x ^= x >> 18;
|
||||||
|
|
||||||
|
return rotr32(x >> 27, count) % UINT32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Random::get_u64()
|
||||||
|
{
|
||||||
|
return ((uint64_t)get_u32() << 32) | get_u32();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
#include <kernel/PCI.h>
|
#include <kernel/PCI.h>
|
||||||
#include <kernel/PIC.h>
|
#include <kernel/PIC.h>
|
||||||
#include <kernel/Process.h>
|
#include <kernel/Process.h>
|
||||||
|
#include <kernel/Random.h>
|
||||||
#include <kernel/Scheduler.h>
|
#include <kernel/Scheduler.h>
|
||||||
#include <kernel/Syscall.h>
|
#include <kernel/Syscall.h>
|
||||||
#include <kernel/Terminal/Serial.h>
|
#include <kernel/Terminal/Serial.h>
|
||||||
|
@ -153,6 +154,9 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
||||||
dprintln("Virtual TTY initialized");
|
dprintln("Virtual TTY initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Random::initialize();
|
||||||
|
dprintln("RNG initialized");
|
||||||
|
|
||||||
MUST(Scheduler::initialize());
|
MUST(Scheduler::initialize());
|
||||||
dprintln("Scheduler initialized");
|
dprintln("Scheduler initialized");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue