Files
termOS/kernel/src/arch/x86_64/cpuinfo.c
T
Karina 55ea8fc533 feat(userspace): userspace support
build: updated CMakeLists to build and copy to initramfs

wip(syscalls): initial syscalls

chore(ksh/kfetch): minor changes

chore(gitignore): added initramfs/*
2026-01-29 21:25:45 +04:00

72 lines
2.2 KiB
C

// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include "types.h"
#include <cpuinfo.h>
#define MSR_GS_BASE 0xC0000101
#define MSR_KERNEL_GS_BASE 0xC0000102
cpu_info g_cpu = {0};
static inline void cpuid(u32 leaf, u32 subleaf, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) {
__asm__ volatile("cpuid"
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
: "a"(leaf), "c"(subleaf)
);
}
static inline void wrmsr(u32 msr, u64 val) {
u32 low = (u32)val;
u32 high = (u32)(val >> 32);
__asm__ volatile("wrmsr" :: "a"(low), "d"(high), "c"(msr));
}
void cpuinfo_init(u64 kernel_stack_top) {
g_cpu.kernel_rsp = kernel_stack_top;
g_cpu.self = (u64)&g_cpu;
wrmsr(MSR_KERNEL_GS_BASE, (u64)&g_cpu);
u32 eax, ebx, ecx, edx;
cpuid(0, 0, &eax, &ebx, &ecx, &edx);
u32* vendor_ptr = (u32*)g_cpu.vendor;
vendor_ptr[0] = ebx;
vendor_ptr[1] = edx;
vendor_ptr[2] = ecx;
g_cpu.vendor[12] = '\0';
cpuid(1, 0, &eax, &ebx, &ecx, &edx);
g_cpu.family = (eax >> 8) & 0xF;
g_cpu.model = (eax >> 4) & 0xF;
if (g_cpu.family == 6 || g_cpu.family == 15) {
g_cpu.model += ((eax >> 16) & 0xF) << 4;
}
if (edx & (1 << 0)) g_cpu.features |= CPU_FEAT_FPU;
if (edx & (1 << 4)) g_cpu.features |= CPU_FEAT_TSC;
if (edx & (1 << 5)) g_cpu.features |= CPU_FEAT_MSR;
if (edx & (1 << 6)) g_cpu.features |= CPU_FEAT_PAE;
if (edx & (1 << 9)) g_cpu.features |= CPU_FEAT_APIC;
if (edx & (1 << 12)) g_cpu.features |= CPU_FEAT_MTRR;
if (edx & (1 << 25)) g_cpu.features |= CPU_FEAT_SSE;
if (edx & (1 << 26)) g_cpu.features |= CPU_FEAT_SSE2;
if (ecx & (1 << 0)) g_cpu.features |= CPU_FEAT_SSE3;
if (ecx & (1 << 9)) g_cpu.features |= CPU_FEAT_SSSE3;
if (ecx & (1 << 19)) g_cpu.features |= CPU_FEAT_SSE4_1;
if (ecx & (1 << 20)) g_cpu.features |= CPU_FEAT_SSE4_2;
if (ecx & (1 << 28)) g_cpu.features |= CPU_FEAT_AVX;
if (ecx & (1 << 29)) g_cpu.features |= CPU_FEAT_F16C;
if (ecx & (1 << 30)) g_cpu.features |= CPU_FEAT_RDRAND;
if (ecx & (1 << 31)) g_cpu.features |= CPU_FEAT_HYPERVISOR;
}
bool cpu_has(u64 feature) {
return (g_cpu.features & feature) != 0;
}