native features!

This commit is contained in:
2026-09-27 21:10:28 +02:00
parent ffa23b1dba
commit 6dd0823c93
6 changed files with 73 additions and 28 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ Low-Level Hardware & Interrupts
[x] IDT
[x] Basic IRQs (Internal/Legacy)
[x] Proper fault handling (Exceptions, Page Faults, #GP)
[ ] Check for features with CPUID (NX-bit, SSE, AVX)
[-] Check for features with CPUID (NX-bit, SSE, AVX)
[ ] APIC driver (Local APIC & I/O APIC)
[ ] ACPI driver (Parsing RSDP/MADT for multi-core/APIC)
[ ] HPET driver (High precision timing)
+1 -1
View File
@@ -2,7 +2,7 @@
#define _RANDOM_H
#include <types.h>
void rand_init();
void rand_init(bool rdrand, bool rdseed);
extern uint64_t (*get_random_number)();
#endif
+4
View File
@@ -9,6 +9,8 @@
* CPUID
*/
enum {
CPUID_FEAT_EBX_RDSEED = 1 << 18,
CPUID_FEAT_ECX_SSE3 = 1 << 0,
CPUID_FEAT_ECX_PCLMUL = 1 << 1,
CPUID_FEAT_ECX_DTES64 = 1 << 2,
@@ -87,4 +89,6 @@ void outl(uint16_t port, uint32_t data);
void cli(void);
void sti(void);
extern uint8_t (*popcountll)(uint64_t num);
void detect_processor_features();
#endif
+4 -2
View File
@@ -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
View File
@@ -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"
+57 -16
View File
@@ -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"
__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);
}