forked from PoliEcho-holding-org/kern
native features!
This commit is contained in:
+4
-2
@@ -30,6 +30,9 @@ __noreturn void _start(void) {
|
||||
cpuid(&eax, (void*)&s[0], (void*)&s[8], (void*)&s[4]);
|
||||
pr_info("[kernel] CPUID_GETVENDORID: %s\n", s);
|
||||
|
||||
// enable processor extensions
|
||||
detect_processor_features();
|
||||
|
||||
// System init
|
||||
if ((err = gdt_init()) < 0)
|
||||
panic(NULL, "Failed to initalize GDT. (%d)", err);
|
||||
@@ -43,8 +46,7 @@ __noreturn void _start(void) {
|
||||
if ((err = pag_init()) < 0)
|
||||
panic(NULL, "Failed to initalize Paging. (%d)", err);
|
||||
|
||||
// random number generation
|
||||
rand_init();
|
||||
|
||||
// test random number generation
|
||||
printk("Random number generation test:\n");
|
||||
for (uint8_t i = 0; i <= 16; i++) {
|
||||
|
||||
+3
-5
@@ -25,18 +25,16 @@ uint64_t rand_software() {
|
||||
return LFSR;
|
||||
}
|
||||
|
||||
void rand_init() {
|
||||
uint32_t eax = 1, ebx = 0, ecx = 0, edx = 0;
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
void rand_init(bool rdrand, bool rdseed) {
|
||||
|
||||
// check for RDRAND
|
||||
if ((ecx >> 30) & 1) {
|
||||
if (rdrand) {
|
||||
get_random_number = rand_rdrand;
|
||||
} else {
|
||||
printk("[\e[33mWARNING\e[0m] RDRAND not available falling back "
|
||||
"to software\n");
|
||||
// check for RDSEED
|
||||
if ((ebx >> 18) & 1) {
|
||||
if (rdseed) {
|
||||
asm(".intel_syntax noprefix\n"
|
||||
"rdseed %0\n"
|
||||
".att_syntax prefix\n"
|
||||
|
||||
+60
-19
@@ -1,52 +1,93 @@
|
||||
#include "types.h"
|
||||
#include <kernel.h>
|
||||
#include <random.h>
|
||||
#include <system.h>
|
||||
|
||||
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
|
||||
__asm__ volatile ("cpuid"
|
||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||
: "a"(*eax)
|
||||
: "memory");
|
||||
__asm__ volatile("cpuid"
|
||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||
: "a"(*eax)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
void iowait(void) {
|
||||
outb(0x80, 0);
|
||||
}
|
||||
void iowait(void) { outb(0x80, 0); }
|
||||
|
||||
uint8_t inb(uint16_t port) {
|
||||
uint8_t r;
|
||||
__asm__ volatile ("inb %1, %0" : "=a"(r) : "dN"(port));
|
||||
__asm__ volatile("inb %1, %0" : "=a"(r) : "dN"(port));
|
||||
return r;
|
||||
}
|
||||
|
||||
void outb(uint16_t port, uint8_t data) {
|
||||
__asm__ volatile ("outb %1, %0" :: "dN"(port), "a"(data));
|
||||
__asm__ volatile("outb %1, %0" ::"dN"(port), "a"(data));
|
||||
}
|
||||
|
||||
uint16_t inw(uint16_t port) {
|
||||
uint16_t r;
|
||||
__asm__ volatile ("inw %1, %0" : "=a"(r) : "dN"(port));
|
||||
__asm__ volatile("inw %1, %0" : "=a"(r) : "dN"(port));
|
||||
return r;
|
||||
}
|
||||
|
||||
void outw(uint16_t port, uint16_t data) {
|
||||
__asm__ volatile ("outw %1, %0" :: "dN"(port), "a"(data));
|
||||
__asm__ volatile("outw %1, %0" ::"dN"(port), "a"(data));
|
||||
}
|
||||
|
||||
uint32_t inl(uint16_t port) {
|
||||
uint32_t r;
|
||||
__asm__ volatile ("inl %1, %0" : "=a"(r) : "dN"(port));
|
||||
__asm__ volatile("inl %1, %0" : "=a"(r) : "dN"(port));
|
||||
return r;
|
||||
}
|
||||
|
||||
void outl(uint16_t port, uint32_t data) {
|
||||
__asm__ volatile ("outl %1, %0" :: "dN"(port), "a"(data));
|
||||
__asm__ volatile("outl %1, %0" ::"dN"(port), "a"(data));
|
||||
}
|
||||
|
||||
void cli(void) {
|
||||
__asm__ volatile ("cli");
|
||||
void cli(void) { __asm__ volatile("cli"); }
|
||||
|
||||
void sti(void) { __asm__ volatile("sti"); }
|
||||
|
||||
uint8_t (*popcountll)(uint64_t num);
|
||||
|
||||
extern uint8_t popcountll_native(uint64_t num);
|
||||
asm(".intel_syntax noprefix\n"
|
||||
".global popcountll_native\n"
|
||||
"popcountll_native:"
|
||||
" popcnt rax, rdi\n"
|
||||
" ret\n"
|
||||
".att_syntax prefix\n");
|
||||
|
||||
// I have no idea how this works but it is apperently called SWAR
|
||||
uint8_t popcountll_software(uint64_t num) {
|
||||
num = num - ((num >> 1) & 0x5555555555555555ULL);
|
||||
num = (num & 0x3333333333333333ULL) +
|
||||
((num >> 2) & 0x3333333333333333ULL);
|
||||
num = (num + (num >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
|
||||
return (int)((num * 0x0101010101010101ULL) >> 56);
|
||||
}
|
||||
|
||||
void sti(void) {
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
void detect_processor_features() {
|
||||
// leaf 1
|
||||
uint32_t eax = 1, ebx = 0, ecx = 0, edx = 0;
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
|
||||
bool rdrand = false;
|
||||
if (ecx & CPUID_FEAT_ECX_RDRAND) {
|
||||
rdrand = true;
|
||||
}
|
||||
|
||||
if (ecx & CPUID_FEAT_ECX_POPCNT) {
|
||||
popcountll = popcountll_native;
|
||||
} else {
|
||||
popcountll = popcountll_software;
|
||||
}
|
||||
|
||||
// leaf 7
|
||||
eax = 7, ebx = 0, ecx = 0, edx = 0;
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
bool rdseed = false;
|
||||
if (ebx & CPUID_FEAT_EBX_RDSEED) {
|
||||
rdseed = true;
|
||||
}
|
||||
|
||||
// init rng
|
||||
rand_init(rdrand, rdseed);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user