diff --git a/kernel/arch/cpuid.c b/kernel/arch/cpuid.c new file mode 100644 index 0000000..3215305 --- /dev/null +++ b/kernel/arch/cpuid.c @@ -0,0 +1,27 @@ +#include +#include +#include + +uint32_t cpuid_features_b, cpuid_features_c, cpuid_features_d; +uint32_t cpuid_featuresx_b, cpuid_featuresx_c, cpuid_featuresx_d; +uint32_t cpuid_signature; +uint32_t cpuid_max=0x0, cpuid_maxx=0x80000000; + + +void cpuid(uint32_t code, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) +{ + uint32_t scrap; + if(!a) a = &scrap; + if(!b) b = &scrap; + if(!c) c = &scrap; + if(!d) d = &scrap; + + if((code < CPUID_FUNCTIONX_VENDOR && code > cpuid_max) || code > cpuid_maxx) + { + *a = *b = *c = *d = -1; + return; + } + + asm volatile("cpuid" : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) : "a"(code)); +} + diff --git a/kernel/arch/msr.c b/kernel/arch/msr.c new file mode 100644 index 0000000..fa19495 --- /dev/null +++ b/kernel/arch/msr.c @@ -0,0 +1,13 @@ +#include + +uint64_t msr_read(uint32_t msr) +{ + uint64_t lo, hi; + asm volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); + return ((hi&0xFFFFFFFF) << 32) | (lo&0xFFFFFFFF); +} + +void msr_write(uint32_t msr, uint64_t value) +{ + asm volatile("wrmsr" : : "a" (value&0xFFFFFFFF), "d"(value>>32), "c"(msr)); +} diff --git a/kernel/boot/boot.S b/kernel/boot/boot.S index 03e7f8b..4c11ec1 100644 --- a/kernel/boot/boot.S +++ b/kernel/boot/boot.S @@ -1,5 +1,6 @@ .intel_syntax noprefix #include +#include .section .data // Some room to store the bootloader return values @@ -84,6 +85,26 @@ long_mode_start: mov rax, 0x0 mov [V2P(BootP4)], rax + // CPUID +#define CPUID(function) mov rax, (function); cpuid; +#define STORE(reg, variable) movabs r8, offset (variable); mov dword ptr [r8], (reg); + // Store max CPUID function numbers + CPUID(CPUID_FUNCTION_VENDOR) + STORE(eax, cpuid_max) + CPUID(CPUID_FUNCTIONX_VENDOR) + STORE(eax, cpuid_maxx) + // Store CPUID features + CPUID(CPUID_FUNCTION_FEATURES) + STORE(eax, cpuid_signature) + STORE(ebx, cpuid_features_b) + STORE(ecx, cpuid_features_c) + STORE(edx, cpuid_features_d) + // ...and extended features + CPUID(CPUID_FUNCTIONX_FEATURES) + STORE(ebx, cpuid_featuresx_b) + STORE(ecx, cpuid_featuresx_c) + STORE(edx, cpuid_featuresx_d) + // Get the saved bootloader data and pass to kmain movabs rax, MultiBootMagic mov rdi, rax diff --git a/kernel/boot/kmain.c b/kernel/boot/kmain.c index 311334d..e3eb89e 100644 --- a/kernel/boot/kmain.c +++ b/kernel/boot/kmain.c @@ -6,6 +6,7 @@ #include #include #include +#include void thread_function() { @@ -31,6 +32,11 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data) scheduler_init(); pic_init(); + debug_info("CPUID - max function number: Normal:%x, Extended:%x\n", cpuid_max, cpuid_maxx); + debug_info("CPUID - has MSR:%d\n", CPUID_FEATURE_MSR); + debug_info("CPUID - has APIC:%d\n", CPUID_FEATURE_APIC); + debug_info("CPUID - has SYSCALL:%d\n", CPUID_FEATURE_SYSCALL); + process_t *p1 = process_spawn(0); process_t *p2 = process_spawn(p1); @@ -52,7 +58,6 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data) scheduler_insert(t2); scheduler_insert(t3); - IRQ_UNMASK(IRQ_TIMER); asm("sti"); debug_info("BOOT COMPLETE\n"); schedule(); diff --git a/kernel/include/cpuid.h b/kernel/include/cpuid.h new file mode 100644 index 0000000..beeb4ce --- /dev/null +++ b/kernel/include/cpuid.h @@ -0,0 +1,29 @@ +#pragma once + +#define CPUID_FUNCTION_VENDOR 0x00000000 +#define CPUID_FUNCTION_FEATURES 0x00000001 +#define CPUID_FUNCTION_TLB 0x00000003 +#define CPUID_FUNCTION_SERIAL 0x00000004 + +#define CPUID_FUNCTIONX_VENDOR 0x80000000 +#define CPUID_FUNCTIONX_FEATURES 0x80000001 +#define CPUID_FUNCTIONX_BRAND0 0x80000002 +#define CPUID_FUNCTIONX_BRAND1 0x80000003 +#define CPUID_FUNCTIONX_BRAND2 0x80000004 + +#define CPUID_FEATURE_MSR (cpuid_features_d & 1<<5) +#define CPUID_FEATURE_APIC (cpuid_features_d & 1<<9) +#define CPUID_FEATURE_SYSCALL (cpuid_featuresx_d & 1<<11) + +#ifndef __ASSEMBLER__ + +#include + +void cpuid(uint32_t code, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d); + +extern uint32_t cpuid_features_b, cpuid_features_c, cpuid_features_d; +extern uint32_t cpuid_featuresx_b, cpuid_featuresx_c, cpuid_featuresx_d; +extern uint32_t cpuid_signature; +extern uint32_t cpuid_max, cpuid_maxx; + +#endif diff --git a/kernel/include/msr.h b/kernel/include/msr.h new file mode 100644 index 0000000..28ed9bd --- /dev/null +++ b/kernel/include/msr.h @@ -0,0 +1,17 @@ +#pragma once + +#define MSR_APIC_BASE 0x0000001B +#define MSR_REG_EFER 0xc0000080 +#define MSR_REG_STAR 0xc0000081 +#define MSR_REG_LSTAR 0xc0000082 +#define MSR_REG_FMASK 0xc0000084 +#define MSR_REG_USER_GS 0xc0000101 +#define MSR_REG_KERNEL_GS 0xc0000102 + +#ifndef __ASSEMBLER__ + +#include +uint64_t msr_read(uint32_t msr); +void msr_write(uint32_t msr, uint64_t value); + +#endif