Skip to content

Commit

Permalink
Get CPUid and capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
lubenard committed Feb 10, 2024
1 parent 686b310 commit cec4e44
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 28 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ IS_TEST = 0

SRC_FILES_ASM = kernel/boot.s \
kernel/gdt/gdt_asm.s \
drivers/cpu/cpu_asm.s \
kernel/idt/idt_asm.s \
kernel/isr/isr_asm.s \
kernel/memory/paging_asm.s \
Expand All @@ -33,6 +34,7 @@ SRC_FILES_ASM = kernel/boot.s \
SRC_FILES_C = kernel/kernel.c \
drivers/vga/vga.c \
drivers/PS2_keyboard/PS2_keyboard.c \
drivers/cpu/cpu.c \
kernel/gdt/gdt.c \
kernel/idt/idt.c \
kernel/isr/isr.c \
Expand Down
42 changes: 42 additions & 0 deletions srcs/drivers/cpu/cpu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "cpu.h"
#include "../../lib/iolib.h"

void check_cpu_features() {
check_cpu_id();
check_cpu_vendor();
get_cpu_features();
}

// Letters are stored as int
// Example:
// ebx might look this: 1970169159, which is actually translated to 1110101 01101110 01100101 01000111
// Each 8 bytes group can represent an Ascii letter.
// Once extracted, we need to put them in the right order to get the cpu vendor
// See here for more information:
// https://wiki.osdev.org/CPUID
void display_cpu_vendor(int ebx, int edx, int ecx) {
unsigned char ebx_l1 = ebx & 0xFF;
unsigned char ebx_l2 = (ebx >> 8) & 0xFF;
unsigned char ebx_l3 = (ebx >> 16) & 0xFF;
unsigned char ebx_l4 = (ebx >> 24) & 0xFF;

unsigned char edx_l1 = edx & 0xFF;
unsigned char edx_l2 = (edx >> 8) & 0xFF;
unsigned char edx_l3 = (edx >> 16) & 0xFF;
unsigned char edx_l4 = (edx >> 24) & 0xFF;

unsigned char ecx_l1 = ecx & 0xFF;
unsigned char ecx_l2 = (ecx >> 8) & 0xFF;
unsigned char ecx_l3 = (ecx >> 16) & 0xFF;
unsigned char ecx_l4 = (ecx >> 24) & 0xFF;

printd(KERN_INFO, "CPU is %c%c%c%c%c%c%c%c%c%c%c%c",
ebx_l1, ebx_l2, ebx_l3, ebx_l4,
edx_l1, edx_l2, edx_l3, edx_l4,
ecx_l1, ecx_l2, ecx_l3, ecx_l4
);
}

void display_cpu_features(int s1, int s2) {
printd(KERN_INFO, "CPU features are: %d %d", s1, s2);
}
58 changes: 58 additions & 0 deletions srcs/drivers/cpu/cpu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cpu.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: luca </var/spool/mail/luca> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/02 14:11:48 by luca #+# #+# */
/* Updated: 2024/02/02 14:11:48 by luca ### ########.fr */
/* */
/* ************************************************************************** */

#ifndef KFS_CPU_H
#define KFS_CPU_H

// Vendor strings from CPUs.
#define CPUID_VENDOR_AMD "AuthenticAMD"
#define CPUID_VENDOR_AMD_OLD "AMDisbetter!" // Early engineering samples of AMD K5 processor
#define CPUID_VENDOR_INTEL "GenuineIntel"
#define CPUID_VENDOR_VIA "VIA VIA VIA "
#define CPUID_VENDOR_TRANSMETA "GenuineTMx86"
#define CPUID_VENDOR_TRANSMETA_OLD "TransmetaCPU"
#define CPUID_VENDOR_CYRIX "CyrixInstead"
#define CPUID_VENDOR_CENTAUR "CentaurHauls"
#define CPUID_VENDOR_NEXGEN "NexGenDriven"
#define CPUID_VENDOR_UMC "UMC UMC UMC "
#define CPUID_VENDOR_SIS "SiS SiS SiS "
#define CPUID_VENDOR_NSC "Geode by NSC"
#define CPUID_VENDOR_RISE "RiseRiseRise"
#define CPUID_VENDOR_VORTEX "Vortex86 SoC"
#define CPUID_VENDOR_AO486 "MiSTer AO486"
#define CPUID_VENDOR_AO486_OLD "GenuineAO486"
#define CPUID_VENDOR_ZHAOXIN " Shanghai "
#define CPUID_VENDOR_HYGON "HygonGenuine"
#define CPUID_VENDOR_ELBRUS "E2K MACHINE "

// Vendor strings from hypervisors.
#define CPUID_VENDOR_QEMU "TCGTCGTCGTCG"
#define CPUID_VENDOR_KVM " KVMKVMKVM "
#define CPUID_VENDOR_VMWARE "VMwareVMware"
#define CPUID_VENDOR_VIRTUALBOX "VBoxVBoxVBox"
#define CPUID_VENDOR_XEN "XenVMMXenVMM"
#define CPUID_VENDOR_HYPERV "Microsoft Hv"
#define CPUID_VENDOR_PARALLELS " prl hyperv "
#define CPUID_VENDOR_PARALLELS_ALT " lrpepyh vr " // Sometimes Parallels incorrectly encodes "prl hyperv" as "lrpepyh vr" due to an endianness mismatch.
#define CPUID_VENDOR_BHYVE "bhyve bhyve "
#define CPUID_VENDOR_QNX " QNXQVMBSQG "

void check_cpu_features();
void display_cpu_vendor(int s1, int s2, int s3);
void display_cpu_features(int s1, int s2);

// ASM functions
extern void check_cpu_id();
extern void check_cpu_vendor();
extern void get_cpu_features();

#endif //KFS_CPU_H
76 changes: 76 additions & 0 deletions srcs/drivers/cpu/cpu_asm.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@

[GLOBAL check_cpu_id]
[GLOBAL check_cpu_vendor]
[GLOBAL get_cpu_features]

extern printd
extern display_cpu_vendor
extern display_cpu_features

cpuid_not_supported db 'CPUID is not supported', 0
cpuid_supported db 'CPUID is supported', 0

check_cpu_id:
push ebp ; Stack & Frame Setup and Save
mov ebp, esp

pushfd ; Save EFLAGS
pushfd ; Store EFLAGS
xor dword [esp],0x00200000 ; Invert the ID bit in stored EFLAGS
popfd ; Load stored EFLAGS (with ID bit inverted)
pushfd ; Store EFLAGS again (ID bit may or may not be inverted)
pop eax ; eax = modified EFLAGS (ID bit may or may not be inverted)
xor eax,[esp] ; eax = whichever bits were changed
popfd ; Restore original EFLAGS
and eax, 0x00200000 ; eax = zero if ID bit can't be changed, else non-zero
cmp eax, 0 ; Compare eax to 0
je id_not_supported ; if equal, jump to id_not_supported
jmp id_supported ; Else, jump to id_supported
ret

id_not_supported:
push 0x0 ; Push flags
push cpuid_not_supported ; Push String
push 0x3 ; Push Info Type
call printd ; Call printf
mov esp, ebp ; Stack & Frame Restore
pop ebp
ret

id_supported:
push 0x0 ; Push flags
push cpuid_supported ; Push String
push 0x0 ; Push Info Type
call printd ; Call printf
mov esp, ebp ; Stack & Frame Restore
pop ebp
ret

check_cpu_vendor:
push ebp ; Stack & Frame Setup and Save
mov ebp, esp

mov eax, 0x0 ; Get CPU Vendor ID String
cpuid ; Get Infos
push ecx ; Infos are returned in ebx, edx, ecx
push edx ; We push thoses on the stack to pass them to C function
push ebx
call display_cpu_vendor ; Call our C function

mov esp, ebp ; Stack & Frame Restore
pop ebp
ret

get_cpu_features:
push ebp ; Stack & Frame Setup and Save
mov ebp, esp

mov eax, 0x1 ; Get CPU Vendor ID String
cpuid
push ecx ; Infos are returned in edx, ecx
push edx ; We push thoses on the stack to pass them to C function
call display_cpu_features

mov esp, ebp ; Stack & Frame Restore
pop ebp
ret
6 changes: 2 additions & 4 deletions srcs/kernel/gdt/gdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static void setup_tss(uint32_t num, uint16_t ss0, uint32_t esp0) {
uint32_t limit = base + sizeof(tss_entry);

// Now, add our TSS descriptor's address to the GDT.
gdt_set_gate(num, base, limit, 0xE9, 0x00);
gdt_set_gate(num, base, limit, 0x89, 0x40);

// Ensure the descriptor is initially zero.
memset(&tss_entry, 0, sizeof(tss_entry));
Expand All @@ -62,9 +62,7 @@ static void setup_tss(uint32_t num, uint16_t ss0, uint32_t esp0) {
tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13;
}


void init_gdt()
{
void init_gdt() {
GDTDescriptor_t gdt_ptr;

// Disable interruptions
Expand Down
1 change: 1 addition & 0 deletions srcs/kernel/gdt/gdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ typedef struct GDTDescriptor GDTDescriptor_t;
/* Asm function */
extern void gdt_flush(uint32_t);
extern void tss_flush();
extern void check_kernel_long_mode();

/* Prototype to init GDT */
void init_gdt();
Expand Down
11 changes: 0 additions & 11 deletions srcs/kernel/idt/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
#include "../../lib/iolib.h"
#include "../../lib/memlib.h"
#include "../../io/io.h"
#include "../isr/irqs/irqs.h"
#include "../../io/shell/builtins/builtins.h"


struct idt_ptr_struct idt_ptr;
struct idt32 idt_entries[256];
Expand Down Expand Up @@ -123,13 +120,5 @@ void init_idt() {
idt_set_gate(80, (int32_t)syscalls, 0x08, 0x8E);

printk(KERN_INFO, "IDT has been initialised at %p", &idt_ptr);

// Init pit to get ticks
init_pit();

/* Init rtc to get date from bios */
init_rtc();

date(0);
}

16 changes: 14 additions & 2 deletions srcs/kernel/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "syscalls/syscalls.h"
#include "isr/irqs/irqs.h"
#include "../../tests/tests.h"
#include "../io/shell/builtins/builtins.h"
#include "../drivers/cpu/cpu.h"

/* Check if the compiler thinks you are targeting the wrong operating system. */
#if defined(__linux__)
Expand Down Expand Up @@ -65,8 +67,8 @@ int test_function1() {
//terminal_writestr("Hello from function test 1");
//sleep(2);
i++;
}
test_syscalls();*/
}*/
test_syscalls();
return 0;
}

Expand Down Expand Up @@ -96,12 +98,22 @@ void k_main(unsigned long magic, unsigned long addr) {

printd(KERN_INFO, "Screen & COM port init");

check_cpu_features();

/* Initialize GDT (Global descriptor table) */
init_gdt();

/* Initialize IDT (Interruptor descriptor table) */
init_idt();

// Init pit to get ticks
init_pit();

/* Init rtc to get date from bios */
init_rtc();

date(0);

/* Init kbd management */
init_kbd();

Expand Down
14 changes: 3 additions & 11 deletions srcs/kernel/processes/processes_asm.s
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,8 @@

GLOBAL switch_regs

extern printd

message:
db 'Ecx is %p', 0

switch_regs:
cli
; Debug message
;push dword [eax + 4]
;push message
;push 0x1
;call printd

; Move general registers
mov ecx, [eax + 4]
Expand All @@ -34,8 +24,10 @@ switch_regs:
mov edi, [eax + 28]
; Right now, eax, ebp, esp are not restored yet

; 0x23 is the User Data Segment
push 0x23
push esp
; Esp is the stack pointer
push dword [eax + 16]

; Push new eflags on the stack
push dword [eax + 32]
Expand Down

0 comments on commit cec4e44

Please sign in to comment.