feat/kernel: I dont remember but i did stuff regarding SMP
This commit is contained in:
parent
7ad2167e9d
commit
d0e4149de5
8 changed files with 47 additions and 29 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -22,7 +22,8 @@
|
||||||
"smp.h": "c",
|
"smp.h": "c",
|
||||||
"string_view": "c",
|
"string_view": "c",
|
||||||
"lapic.h": "c",
|
"lapic.h": "c",
|
||||||
"spinlock.h": "c"
|
"spinlock.h": "c",
|
||||||
|
"fb.h": "c"
|
||||||
},
|
},
|
||||||
"editor.formatOnPaste": true,
|
"editor.formatOnPaste": true,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
|
|
|
@ -51,6 +51,7 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CPPFLAGS := -I../external -I$(SRCDIR) -MMD -MP -DLIMINE_API_REVISION=3
|
CPPFLAGS := -I../external -I$(SRCDIR) -MMD -MP -DLIMINE_API_REVISION=3
|
||||||
|
CFLAGS += -std=c99
|
||||||
|
|
||||||
IMPLICIT_SRCS :=
|
IMPLICIT_SRCS :=
|
||||||
ifneq ($(MAKECMDGOALS),menuconfig)
|
ifneq ($(MAKECMDGOALS),menuconfig)
|
||||||
|
|
|
@ -21,13 +21,13 @@ static inline void wrmsr(uint64_t msr, uint64_t value)
|
||||||
{
|
{
|
||||||
uint32_t low = value & 0xFFFFFFFF;
|
uint32_t low = value & 0xFFFFFFFF;
|
||||||
uint32_t high = value >> 32;
|
uint32_t high = value >> 32;
|
||||||
asm volatile("wrmsr" : : "c"(msr), "a"(low), "d"(high));
|
__asm__ volatile("wrmsr" : : "c"(msr), "a"(low), "d"(high));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t rdmsr(uint64_t msr)
|
static inline uint64_t rdmsr(uint64_t msr)
|
||||||
{
|
{
|
||||||
uint32_t low, high;
|
uint32_t low, high;
|
||||||
asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr));
|
__asm__ volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr));
|
||||||
return ((uint64_t)high << 32) | low;
|
return ((uint64_t)high << 32) | low;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,9 @@ void smp_entry(struct limine_mp_info *smp_info)
|
||||||
set_cpu_local(cpu);
|
set_cpu_local(cpu);
|
||||||
atomic_fetch_add(&started_cpus, 1);
|
atomic_fetch_add(&started_cpus, 1);
|
||||||
|
|
||||||
|
log_early("CPU %d is up", cpu->cpu_index);
|
||||||
|
|
||||||
|
cpu->ready = true;
|
||||||
while (1)
|
while (1)
|
||||||
__asm__ volatile("hlt");
|
__asm__ volatile("hlt");
|
||||||
}
|
}
|
||||||
|
@ -67,21 +70,37 @@ void smp_init(void)
|
||||||
memset(&cpu_locals[i], 0, sizeof(cpu_local_t));
|
memset(&cpu_locals[i], 0, sizeof(cpu_local_t));
|
||||||
cpu_locals[i].lapic_id = info->lapic_id;
|
cpu_locals[i].lapic_id = info->lapic_id;
|
||||||
cpu_locals[i].cpu_index = i;
|
cpu_locals[i].cpu_index = i;
|
||||||
|
cpu_locals[i].ready = false;
|
||||||
|
|
||||||
if (info->lapic_id == bootstrap_lapic_id)
|
if (info->lapic_id == bootstrap_lapic_id)
|
||||||
{
|
{
|
||||||
set_cpu_local(&cpu_locals[i]);
|
set_cpu_local(&cpu_locals[i]);
|
||||||
log_early("CPU %u (LAPIC %u) is the bootstrap processor", i, info->lapic_id);
|
log_early("CPU %u is the bootstrap processor", i);
|
||||||
atomic_fetch_add(&started_cpus, 1);
|
atomic_fetch_add(&started_cpus, 1);
|
||||||
|
cpu_locals[i].ready = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
atomic_store((_Atomic(void **))&info->goto_address, smp_entry);
|
__atomic_store_n(&info->goto_address, smp_entry, __ATOMIC_SEQ_CST);
|
||||||
while (atomic_load(&started_cpus) < (i + 1))
|
while (atomic_load(&started_cpus) < (i + 1))
|
||||||
__asm__ volatile("pause");
|
__asm__ volatile("pause");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (atomic_load(&started_cpus) < cpu_count)
|
bool all_ready = false;
|
||||||
|
while (!all_ready)
|
||||||
|
{
|
||||||
|
all_ready = true;
|
||||||
|
for (uint32_t i = 0; i < cpu_count; i++)
|
||||||
|
{
|
||||||
|
if (!cpu_locals[i].ready)
|
||||||
|
{
|
||||||
|
all_ready = false;
|
||||||
__asm__ volatile("pause");
|
__asm__ volatile("pause");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_early("All CPUs are ready");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#define SMP_H
|
#define SMP_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
extern uint32_t bootstrap_lapic_id;
|
extern uint32_t bootstrap_lapic_id;
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
uint32_t lapic_id;
|
uint32_t lapic_id;
|
||||||
uint32_t cpu_index;
|
uint32_t cpu_index;
|
||||||
|
bool ready;
|
||||||
} cpu_local_t;
|
} cpu_local_t;
|
||||||
|
|
||||||
void smp_init();
|
void smp_init();
|
||||||
|
|
|
@ -35,4 +35,6 @@ extern struct limine_mp_response *mp_response;
|
||||||
extern struct flanterm_context *ft_ctx;
|
extern struct flanterm_context *ft_ctx;
|
||||||
#endif // FLANTERM_SUPPORT
|
#endif // FLANTERM_SUPPORT
|
||||||
|
|
||||||
|
#define LOG_SEPARATOR "----------------------------------------"
|
||||||
|
|
||||||
#endif // EMK_H
|
#endif // EMK_H
|
|
@ -86,6 +86,7 @@ void emk_entry(void)
|
||||||
|
|
||||||
log_early("Experimental Micro Kernel (EMK) 1.0 Copytright (c) 2025 Piraterna");
|
log_early("Experimental Micro Kernel (EMK) 1.0 Copytright (c) 2025 Piraterna");
|
||||||
log_early("Compiled at %s %s, emk1.0-%s, flanterm support: %s", __TIME__, __DATE__, BUILD_MODE, FLANTERM_SUPPORT ? "yes" : "no");
|
log_early("Compiled at %s %s, emk1.0-%s, flanterm support: %s", __TIME__, __DATE__, BUILD_MODE, FLANTERM_SUPPORT ? "yes" : "no");
|
||||||
|
log_early("%s", LOG_SEPARATOR);
|
||||||
|
|
||||||
if (!LIMINE_BASE_REVISION_SUPPORTED)
|
if (!LIMINE_BASE_REVISION_SUPPORTED)
|
||||||
{
|
{
|
||||||
|
@ -94,9 +95,16 @@ void emk_entry(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
gdt_init();
|
gdt_init();
|
||||||
log_early("Initialized GDT");
|
|
||||||
idt_init();
|
idt_init();
|
||||||
log_early("Initialized IDT");
|
|
||||||
|
/* Setup SMP */
|
||||||
|
if (!mp_request.response)
|
||||||
|
{
|
||||||
|
kpanic(NULL, "Failed to get MP request");
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_response = mp_request.response;
|
||||||
|
smp_init();
|
||||||
|
|
||||||
/* Setup physical memory*/
|
/* Setup physical memory*/
|
||||||
if (!hhdm_request.response)
|
if (!hhdm_request.response)
|
||||||
|
@ -111,7 +119,6 @@ void emk_entry(void)
|
||||||
|
|
||||||
memmap = memmap_request.response;
|
memmap = memmap_request.response;
|
||||||
hhdm_offset = hhdm_request.response->offset;
|
hhdm_offset = hhdm_request.response->offset;
|
||||||
log_early("HHDM Offset: %llx", hhdm_offset);
|
|
||||||
pmm_init();
|
pmm_init();
|
||||||
|
|
||||||
/* Test allocate a single physical page */
|
/* Test allocate a single physical page */
|
||||||
|
@ -120,9 +127,7 @@ void emk_entry(void)
|
||||||
kpanic(NULL, "Failed to allocate single physical page");
|
kpanic(NULL, "Failed to allocate single physical page");
|
||||||
|
|
||||||
*a = 32;
|
*a = 32;
|
||||||
log_early("Allocated 1 physical page @ %llx", (uint64_t)a);
|
|
||||||
pfree(a, 1);
|
pfree(a, 1);
|
||||||
log_early("Initialized physical page manager");
|
|
||||||
|
|
||||||
/* Setup virtual memory */
|
/* Setup virtual memory */
|
||||||
if (!kernel_address_request.response)
|
if (!kernel_address_request.response)
|
||||||
|
@ -133,7 +138,6 @@ void emk_entry(void)
|
||||||
kvirt = kernel_address_request.response->virtual_base;
|
kvirt = kernel_address_request.response->virtual_base;
|
||||||
kphys = kernel_address_request.response->physical_base;
|
kphys = kernel_address_request.response->physical_base;
|
||||||
paging_init();
|
paging_init();
|
||||||
log_early("Initialized paging");
|
|
||||||
|
|
||||||
/* Kernel Virtual Memory Context, not to be confused with KVM */
|
/* Kernel Virtual Memory Context, not to be confused with KVM */
|
||||||
kvm_ctx = vinit(kernel_pagemap, 0x1000);
|
kvm_ctx = vinit(kernel_pagemap, 0x1000);
|
||||||
|
@ -149,9 +153,7 @@ void emk_entry(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
*b = 32;
|
*b = 32;
|
||||||
log_early("Allocated 1 virtual page @ %llx", (uint64_t)b);
|
|
||||||
vfree(kvm_ctx, b);
|
vfree(kvm_ctx, b);
|
||||||
log_early("Initialized virtual page manager");
|
|
||||||
|
|
||||||
/* Setup kernel heap */
|
/* Setup kernel heap */
|
||||||
heap_init();
|
heap_init();
|
||||||
|
@ -162,21 +164,12 @@ void emk_entry(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
*c = 32;
|
*c = 32;
|
||||||
log_early("Allocated 1 byte @ %llx", (uint64_t)c);
|
|
||||||
kfree(c);
|
kfree(c);
|
||||||
log_early("Initialized kernel heap");
|
|
||||||
|
|
||||||
/* Setup SMP */
|
/* Finished */
|
||||||
if (!mp_request.response)
|
log_early("%s", LOG_SEPARATOR);
|
||||||
{
|
uint32_t uptime = 0;
|
||||||
kpanic(NULL, "Failed to get MP request");
|
log_early("Finished initializing EMK v1.0, took %d seconds", uptime); /* Still not usermode, so keep using log_early */
|
||||||
}
|
|
||||||
|
|
||||||
mp_response = mp_request.response;
|
|
||||||
smp_init();
|
|
||||||
log_early("Initialized SMP");
|
|
||||||
|
|
||||||
__asm__ volatile("int $0x01");
|
|
||||||
|
|
||||||
hlt();
|
hlt();
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@ static inline void spinlock_acquire(spinlock_t *lock)
|
||||||
{
|
{
|
||||||
while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE))
|
while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE))
|
||||||
{
|
{
|
||||||
asm volatile("pause" ::: "memory");
|
__asm__ volatile("pause" ::: "memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue