diff --git a/GNUmakefile b/GNUmakefile index 6ff16cd..5745a01 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -203,7 +203,8 @@ $(IMAGE_NAME).iso: limine/limine kernel @mkdir -p iso_root/boot/limine @cp -v limine.conf iso_root/boot/limine/ @mkdir -p iso_root/EFI/BOOT - @cp -v initramfs.tar iso_root/ + @cp -v testing/sk-hello.elf iso_root/ +# @cp -v initramfs.tar iso_root/ ifeq ($(ARCH),x86_64) @cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/ @cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/ diff --git a/README.md b/README.md index 94c4a72..f6fbc5b 100755 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ The Soaplin kernel is a new Unix-like operating system kernel. * Simple pre-emptive scheduler * Ring 3 (user mode) support * ELF loader +* ACPI ## In the works * Virtual File System @@ -28,4 +29,9 @@ To build Soaplin, you must ensure you have these: * A compiler (In the future, a custom toolchain would be built.) * A linker -Clone the repo, and run "make" in it! \ No newline at end of file +Clone the repo, and run "make" in it! + +## Acknowledgements +Thanks to all these people :heart: +* Kevin Alavik (kevinalavik): VMAs implementation +* Astrido (asterd-og): IOAPIC/LAPIC (from ZanOS) \ No newline at end of file diff --git a/kernel/src/sys/arch/arch.h b/kernel/src/arch/arch.h similarity index 100% rename from kernel/src/sys/arch/arch.h rename to kernel/src/arch/arch.h diff --git a/kernel/src/sys/arch/x86_64/cpuid.h b/kernel/src/arch/x86_64/cpuid.h similarity index 100% rename from kernel/src/sys/arch/x86_64/cpuid.h rename to kernel/src/arch/x86_64/cpuid.h diff --git a/kernel/src/sys/arch/x86_64/fpu.c b/kernel/src/arch/x86_64/fpu.c similarity index 100% rename from kernel/src/sys/arch/x86_64/fpu.c rename to kernel/src/arch/x86_64/fpu.c diff --git a/kernel/src/sys/arch/x86_64/fpu.h b/kernel/src/arch/x86_64/fpu.h similarity index 100% rename from kernel/src/sys/arch/x86_64/fpu.h rename to kernel/src/arch/x86_64/fpu.h diff --git a/kernel/src/sys/arch/x86_64/gdt.c b/kernel/src/arch/x86_64/gdt.c similarity index 98% rename from kernel/src/sys/arch/x86_64/gdt.c rename to kernel/src/arch/x86_64/gdt.c index 61b6ae4..5f18fb0 100644 --- a/kernel/src/sys/arch/x86_64/gdt.c +++ b/kernel/src/arch/x86_64/gdt.c @@ -1,7 +1,7 @@ // #include "sys/log.h" +#include #include #include -#include #include gdt_table def_table = {{ diff --git a/kernel/src/sys/arch/x86_64/gdt.h b/kernel/src/arch/x86_64/gdt.h similarity index 100% rename from kernel/src/sys/arch/x86_64/gdt.h rename to kernel/src/arch/x86_64/gdt.h diff --git a/kernel/src/sys/arch/x86_64/interrupts.asm b/kernel/src/arch/x86_64/idt.asm similarity index 98% rename from kernel/src/sys/arch/x86_64/interrupts.asm rename to kernel/src/arch/x86_64/idt.asm index 860dc37..c7b8f8e 100755 --- a/kernel/src/sys/arch/x86_64/interrupts.asm +++ b/kernel/src/arch/x86_64/idt.asm @@ -42,7 +42,7 @@ isr_stub_%+%1: mov rdi, rsp - call exception_handler + call idt_int_handler popall @@ -58,7 +58,7 @@ isr_stub_%+%1: mov rdi, rsp - call exception_handler + call idt_int_handler popall @@ -66,7 +66,7 @@ isr_stub_%+%1: iretq %endmacro -extern exception_handler +extern idt_int_handler isr_no_err_stub 0 isr_no_err_stub 1 isr_no_err_stub 2 diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c new file mode 100644 index 0000000..2e7ab3f --- /dev/null +++ b/kernel/src/arch/x86_64/idt.c @@ -0,0 +1,83 @@ +// #include "sys/log.h" +#include "dev/ioapic.h" +#include "dev/lapic.h" +#include "mm/vmm.h" +#include "arch/x86_64/smp.h" +#include "sys/errhnd/panic.h" +#include +#include +#include + +__attribute__((aligned(0x10))) static idt_entry_t idt[256]; + +static idtr_t idtr; +static int vectors[256]; +extern void *isr_stub_table[]; +idt_irq_handler_t irq_handler_table[256 - 32]; + +void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) { + idt_entry_t *descriptor = &idt[vector]; + + descriptor->isr_low = (uint64_t)isr & 0xFFFF; + descriptor->kernel_cs = 0x28; + descriptor->ist = 0; + descriptor->attributes = flags; + descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; + descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; + descriptor->reserved = 0; +} + +void idt_register_irq(uint8_t vector, void *isr) { + if (vector <= 14) + ioapic_redirect_irq(bootstrap_lapic_id, vector + 32, vector, false); + + irq_handler_table[vector] = isr; + vectors[vector <= 14 ? vector + 32 : vector] = IDT_VT_IRQ; +} + +void idt_init() { + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; + + for (uint16_t vector = 0; vector < 32; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + vectors[vector] = IDT_VT_EXCEPTION; + } + + for (uint16_t vector = 32; vector < 256; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + vectors[vector] = IDT_VT_UNDEFINED; + } + + // Do not use the legacy PIC. + //pic_init(); + //pic_unmask_irq(1); + //pic_unmask_irq(8); + + __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT + __asm__ volatile("sti"); // set the interrupt flag + + log("idt - initialized\n"); +} + + +void idt_int_handler(registers_t *regs) { + vmm_load_pagemap(vmm_kernel_pm); + //log("kernel - Interrupt %d\n", regs->int_no); + + if (regs->int_no < 32) { + panic_ctx("A CPU exception occured.", regs); + } + + int vec = regs->int_no; + if (vec >= 32 && vec < 47) + vec -= 32; + + if (vectors[regs->int_no] == IDT_VT_IRQ) { + idt_irq_handler_t i = irq_handler_table[vec]; + i(regs); + } + + lapic_eoi(); + //pic_ack(regs->int_no - 32); +} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.h b/kernel/src/arch/x86_64/idt.h similarity index 85% rename from kernel/src/sys/arch/x86_64/idt.h rename to kernel/src/arch/x86_64/idt.h index 015a379..32569f2 100644 --- a/kernel/src/sys/arch/x86_64/idt.h +++ b/kernel/src/arch/x86_64/idt.h @@ -2,6 +2,11 @@ #include +// VT = Vector type +#define IDT_VT_UNDEFINED 0 +#define IDT_VT_EXCEPTION 1 +#define IDT_VT_IRQ 2 + typedef struct { uint64_t r15; uint64_t r14; @@ -50,5 +55,8 @@ typedef struct { uint64_t base; } __attribute__((packed)) idtr_t; +typedef void(*idt_irq_handler_t)(registers_t *regs); + +void idt_register_irq(uint8_t vector, void *isr); void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags); void idt_init(void); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/io.c b/kernel/src/arch/x86_64/io.c similarity index 100% rename from kernel/src/sys/arch/x86_64/io.c rename to kernel/src/arch/x86_64/io.c diff --git a/kernel/src/sys/arch/x86_64/io.h b/kernel/src/arch/x86_64/io.h similarity index 100% rename from kernel/src/sys/arch/x86_64/io.h rename to kernel/src/arch/x86_64/io.h diff --git a/kernel/src/arch/x86_64/msr.h b/kernel/src/arch/x86_64/msr.h new file mode 100644 index 0000000..1761298 --- /dev/null +++ b/kernel/src/arch/x86_64/msr.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#define IA32_GS_MSR 0xC0000101 +#define IA32_GS_KERNEL_MSR 0xC0000102 + +static inline void wrmsr(uint64_t msr, uint64_t value) +{ + uint32_t low = value & 0xFFFFFFFF; + uint32_t high = value >> 32; + asm volatile ( + "wrmsr" + : + : "c"(msr), "a"(low), "d"(high) + ); +} + +static inline uint64_t rdmsr(uint64_t msr) +{ + uint32_t low, high; + asm volatile ( + "rdmsr" + : "=a"(low), "=d"(high) + : "c"(msr) + ); + return ((uint64_t)high << 32) | low; +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pit.c b/kernel/src/arch/x86_64/pit.c new file mode 100644 index 0000000..bc64f81 --- /dev/null +++ b/kernel/src/arch/x86_64/pit.c @@ -0,0 +1,29 @@ +#include "arch//x86_64/idt.h" +#include "sched/sched.h" +#include +#include +#include +#include + +uint32_t tick = 0; + +void pit_handler(registers_t *regs) { + //log("PIT"); + tick++; + schedule(regs); +} + +void pit_init() { + outb(0x43, 0x36); + uint16_t div = (uint16_t)(1193180 / 1000); + outb(0x40, (uint8_t)div); + outb(0x40, (uint8_t)(div >> 8)); + idt_register_irq(0, pit_handler); +} + +void pit_sleep(uint32_t ms) { + uint64_t start = tick; + while (tick - start < ms) { + __asm__ volatile ("nop"); + } +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pit.h b/kernel/src/arch/x86_64/pit.h new file mode 100755 index 0000000..1884a1e --- /dev/null +++ b/kernel/src/arch/x86_64/pit.h @@ -0,0 +1,12 @@ +#ifndef PIT_H +#define PIT_H + +#include +#include + +extern uint32_t tick; + +void pit_init(); +void pit_sleep(uint32_t ms); + +#endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/rtc.c b/kernel/src/arch/x86_64/rtc.c similarity index 100% rename from kernel/src/sys/arch/x86_64/rtc.c rename to kernel/src/arch/x86_64/rtc.c diff --git a/kernel/src/sys/arch/x86_64/rtc.h b/kernel/src/arch/x86_64/rtc.h similarity index 100% rename from kernel/src/sys/arch/x86_64/rtc.h rename to kernel/src/arch/x86_64/rtc.h diff --git a/kernel/src/arch/x86_64/smp.c b/kernel/src/arch/x86_64/smp.c new file mode 100644 index 0000000..2355478 --- /dev/null +++ b/kernel/src/arch/x86_64/smp.c @@ -0,0 +1,49 @@ +#include "arch//x86_64/smp.h" +#include "lib/spinlock.h" +#include "sys/log.h" +#include "limine.h" +#include + +__attribute__(( + used, + section(".limine_requests"))) static volatile struct limine_mp_request + smp_request = {.id = LIMINE_MP_REQUEST, .revision = 0}; + +uint32_t bootstrap_lapic_id = 0; +uint32_t smp_cpu_count = 0; // Number of processors +spinlock_t smp_lock = { 0 }; + +uint32_t ctr = 0; + +void smp_entry(struct limine_mp_info* smp_info) { + //spinlock_acquire(&smp_lock); + + log("smp - CPU %d started (LAPIC ID: %d)\n", smp_info->processor_id, smp_info->lapic_id); + __atomic_fetch_add(&ctr, 1, __ATOMIC_SEQ_CST); + + while (1) + ;; + //spinlock_release(&smp_lock); +} + +void smp_init() { + bootstrap_lapic_id = smp_request.response->bsp_lapic_id; + smp_cpu_count = smp_request.response->cpu_count; + + log("smp - detected %d CPUs\n", smp_cpu_count); + + for (uint64_t i = 0; i < smp_cpu_count; i++) { + if (smp_request.response->cpus[i]->lapic_id != bootstrap_lapic_id) { + uint32_t old_ctr = __atomic_load_n(&ctr, __ATOMIC_SEQ_CST); + + __atomic_store_n(&smp_request.response->cpus[i]->goto_address, smp_entry, __ATOMIC_SEQ_CST); + + while (__atomic_load_n(&ctr, __ATOMIC_SEQ_CST) == old_ctr) + ; + } else { + log("smp - CPU %d is the bootstrap processor (LAPIC ID: %d)\n", i, smp_request.response->cpus[i]->lapic_id); + } + } + + log("smp - initialized\n"); +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/smp.h b/kernel/src/arch/x86_64/smp.h new file mode 100644 index 0000000..b375f5f --- /dev/null +++ b/kernel/src/arch/x86_64/smp.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +extern uint32_t bootstrap_lapic_id; + +void smp_init(); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/sse.c b/kernel/src/arch/x86_64/sse.c similarity index 97% rename from kernel/src/sys/arch/x86_64/sse.c rename to kernel/src/arch/x86_64/sse.c index 2f3f021..1fe79ce 100644 --- a/kernel/src/sys/arch/x86_64/sse.c +++ b/kernel/src/arch/x86_64/sse.c @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/kernel/src/sys/arch/x86_64/sse.h b/kernel/src/arch/x86_64/sse.h similarity index 100% rename from kernel/src/sys/arch/x86_64/sse.h rename to kernel/src/arch/x86_64/sse.h diff --git a/kernel/src/arch/x86_64/syscall.asm b/kernel/src/arch/x86_64/syscall.asm new file mode 100644 index 0000000..de88abe --- /dev/null +++ b/kernel/src/arch/x86_64/syscall.asm @@ -0,0 +1,53 @@ +bits 64 + +section .text + global syscall_entry + extern syscall_handle + +syscall_entry: + swapgs ; switch + mov [gs:0], rsp + mov rsp, [gs:8] + + push 0 + push 0 + push rax + push rcx + push rdx + push rbx + push rbp + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + mov rdi, rsp + call syscall_handle + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rbp + pop rbx + pop rdx + pop rcx + pop rax + add rsp, 16 + + mov [gs:8], rsp + mov rsp, [gs:0] + swapgs + o64 sysret diff --git a/kernel/src/arch/x86_64/syscall.c b/kernel/src/arch/x86_64/syscall.c new file mode 100644 index 0000000..34e7df3 --- /dev/null +++ b/kernel/src/arch/x86_64/syscall.c @@ -0,0 +1,18 @@ +#include +#include +#include + +extern void syscall_entry(); + +void __x86_64_syscall_init() { + uint64_t efer = rdmsr(IA32_EFER); + efer |= (1 << 0); + wrmsr(IA32_EFER, efer); + uint64_t star = 0; + star |= ((uint64_t)0x28 << 32); // kernel cs + star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x38, 24 for SS=0x40) + wrmsr(IA32_STAR, star); + wrmsr(IA32_LSTAR, (uint64_t)syscall_entry); + wrmsr(IA32_CSTAR, 0x0); + wrmsr(IA32_CSTAR + 1, 0x200); +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscall.h b/kernel/src/arch/x86_64/syscall.h new file mode 100644 index 0000000..c64911c --- /dev/null +++ b/kernel/src/arch/x86_64/syscall.h @@ -0,0 +1,7 @@ +#pragma once + +#define IA32_EFER 0xC0000080 +#define IA32_STAR 0xC0000081 +#define IA32_LSTAR 0xC0000082 +#define IA32_CSTAR 0xC0000083 +#define IA32_SFMASK 0xC0000084 diff --git a/kernel/src/dev/ioapic.c b/kernel/src/dev/ioapic.c new file mode 100644 index 0000000..8c216ce --- /dev/null +++ b/kernel/src/dev/ioapic.c @@ -0,0 +1,105 @@ +#include "sys/acpi/madt.h" +#include +#include +#include + +void ioapic_init() { + madt_ioapic* ioapic = acpi_madt_ioapic_list[0]; + + uint32_t val = ioapic_read(ioapic, IOAPIC_VER); + uint32_t count = ((val >> 16) & 0xFF); + + if ((ioapic_read(ioapic, 0) >> 24) != ioapic->apic_id) { + return; + } + + for (uint8_t i = 0; i <= count; ++i) { + ioapic_write(ioapic, IOAPIC_REDTBL+2*i, 0x00010000 | (32 + i)); + ioapic_write(ioapic, IOAPIC_REDTBL+2*i+1, 0); + } + + log("ioapic - initialized\n"); +} + +void ioapic_write(madt_ioapic* ioapic, uint8_t reg, uint32_t val) { + *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = reg; + *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)) = val; +} + +uint32_t ioapic_read(madt_ioapic* ioapic, uint8_t reg) { + *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = reg; + return *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)); +} + +void ioapic_set_entry(madt_ioapic* ioapic, uint8_t idx, uint64_t data) { + ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2), (uint32_t)data); + ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2 + 1), (uint32_t)(data >> 32)); +} + + +uint64_t ioapic_gsi_count(madt_ioapic* ioapic) { + return (ioapic_read(ioapic, 1) & 0xff0000) >> 16; +} + +madt_ioapic* ioapic_get_gsi(uint32_t gsi) { + for (uint64_t i = 0; i < acpi_madt_ioapic_length; i++) { + madt_ioapic* ioapic = acpi_madt_ioapic_list[i]; + if (ioapic->gsi_base <= gsi && ioapic->gsi_base + ioapic_gsi_count(ioapic) > gsi) + return ioapic; + } + return (madt_ioapic*)0; +} + +void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, uint16_t flags, bool mask) { + madt_ioapic* ioapic = ioapic_get_gsi(gsi); + + uint64_t redirect = vec; + + if ((flags & (1 << 1)) != 0) { + redirect |= (1 << 13); + } + + if ((flags & (1 << 3)) != 0) { + redirect |= (1 << 15); + } + + if (mask) redirect |= (1 << 16); + else redirect &= ~(1 << 16); + + redirect |= (uint64_t)lapic_id << 56; + + uint32_t redir_table = (gsi - ioapic->gsi_base) * 2 + 16; + ioapic_write(ioapic, redir_table, (uint32_t)redirect); + ioapic_write(ioapic, redir_table + 1, (uint32_t)(redirect >> 32)); +} + +void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask) { + uint8_t idx = 0; + madt_iso* iso = (madt_iso*)0; + + while (idx < acpi_madt_iso_length) { + iso = acpi_madt_iso_list[idx]; + if (iso->irq_src == irq) { + ioapic_redirect_gsi(lapic_id, vec, iso->gsi, iso->flags, mask); + return; + } + idx++; + } + + ioapic_redirect_gsi(lapic_id, vec, irq, 0, mask); +} + +uint32_t ioapic_get_redirect_irq(uint8_t irq) { + uint8_t idx = 0; + madt_iso* iso; + + while (idx < acpi_madt_iso_length) { + iso = acpi_madt_iso_list[idx]; + if (iso->irq_src == irq) { + return iso->gsi; + } + idx++; + } + + return irq; +} \ No newline at end of file diff --git a/kernel/src/dev/ioapic.h b/kernel/src/dev/ioapic.h new file mode 100644 index 0000000..a5c1793 --- /dev/null +++ b/kernel/src/dev/ioapic.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +#define IOAPIC_REGSEL 0x0 +#define IOAPIC_IOWIN 0x10 + +#define IOAPIC_ID 0x0 +#define IOAPIC_VER 0x01 +#define IOAPIC_ARB 0x02 +#define IOAPIC_REDTBL 0x10 + + +void ioapic_write(madt_ioapic* ioapic, uint8_t reg, uint32_t val); +uint32_t ioapic_read(madt_ioapic* ioapic, uint8_t reg); + +void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask); +uint32_t ioapic_get_redirect_irq(uint8_t irq); + +void ioapic_set_entry(madt_ioapic* ioapic, uint8_t idx, uint64_t data); + +void ioapic_init(); \ No newline at end of file diff --git a/kernel/src/dev/lapic.c b/kernel/src/dev/lapic.c new file mode 100644 index 0000000..8b3c83f --- /dev/null +++ b/kernel/src/dev/lapic.c @@ -0,0 +1,64 @@ +#include "mm/pmm.h" +#include +#include + +uint64_t apic_ticks = 0; + +void lapic_init() { + lapic_write(0xf0, 0x1ff); + log("lapic - initialized\n"); +} + +void lapic_stop_timer() { + // We do this to avoid overlapping oneshots + lapic_write(LAPIC_TIMER_INITCNT, 0); + lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE); +} + +void lapic_oneshot(uint8_t vec, uint64_t ms) { + lapic_stop_timer(); + lapic_write(LAPIC_TIMER_DIV, 0); + lapic_write(LAPIC_TIMER_LVT, vec); + lapic_write(LAPIC_TIMER_INITCNT, apic_ticks * ms); +} + +void lapic_calibrate_timer() { + lapic_stop_timer(); + lapic_write(LAPIC_TIMER_DIV, 0); + lapic_write(LAPIC_TIMER_LVT, (1 << 16) | 0xff); + lapic_write(LAPIC_TIMER_INITCNT, 0xFFFFFFFF); + //pit_sleep(1); // 1 ms + lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE); + uint32_t ticks = 0xFFFFFFFF - lapic_read(LAPIC_TIMER_CURCNT); + apic_ticks = ticks; + lapic_stop_timer(); +} + +void lapic_write(uint32_t reg, uint32_t val) { + *((volatile uint32_t*)(HIGHER_HALF(0xfee00000) + reg)) = val; +} + +uint32_t lapic_read(uint32_t reg) { + return *((volatile uint32_t*)(HIGHER_HALF(0xfee00000) + reg)); +} + +void lapic_eoi() { + lapic_write((uint8_t)0xb0, 0x0); +} + +void lapic_ipi(uint32_t id, uint8_t dat) { + lapic_write(LAPIC_ICRHI, id << LAPIC_ICDESTSHIFT); + lapic_write(LAPIC_ICRLO, dat); +} + +void lapic_send_all_int(uint32_t id, uint32_t vec) { + lapic_ipi(id, vec | LAPIC_ICRAIS); +} + +void lapic_send_others_int(uint32_t id, uint32_t vec) { + lapic_ipi(id, vec | LAPIC_ICRAES); +} + +uint32_t lapic_get_id() { + return lapic_read(0x0020) >> LAPIC_ICDESTSHIFT; +} \ No newline at end of file diff --git a/kernel/src/dev/lapic.h b/kernel/src/dev/lapic.h new file mode 100644 index 0000000..a4b5fed --- /dev/null +++ b/kernel/src/dev/lapic.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include + +#define LAPIC_PPR 0x00a0 + +#define LAPIC_ICRLO 0x0300 +#define LAPIC_ICRHI 0x0310 + +#define LAPIC_ICINI 0x0500 +#define LAPIC_ICSTR 0x0600 + +#define LAPIC_ICEDGE 0x0000 + +#define LAPIC_ICPEND 0x00001000 +#define LAPIC_ICPHYS 0x00000000 +#define LAPIC_ICASSR 0x00004000 +#define LAPIC_ICSHRTHND 0x00000000 +#define LAPIC_ICDESTSHIFT 24 + +#define LAPIC_ICRAIS 0x00080000 +#define LAPIC_ICRAES 0x000c0000 + +// Timer + +#define LAPIC_TIMER_DIV 0x3E0 +#define LAPIC_TIMER_INITCNT 0x380 +#define LAPIC_TIMER_LVT 0x320 +#define LAPIC_TIMER_DISABLE 0x10000 +#define LAPIC_TIMER_CURCNT 0x390 +#define LAPIC_TIMER_PERIODIC 0x20000 + +void lapic_init(); + +void lapic_stop_timer(); +void lapic_oneshot(uint8_t vec, uint64_t ms); +void lapic_calibrate_timer(); + +void lapic_write(uint32_t reg, uint32_t val); +uint32_t lapic_read(uint32_t reg); + +void lapic_eoi(); + +void lapic_ipi(uint32_t id, uint8_t dat); + +void lapic_send_all_int(uint32_t id, uint32_t vec); +void lapic_send_others_int(uint32_t id, uint32_t vec); + +void lapic_init_cpu(uint32_t id); +void lapic_start_cpu(uint32_t id, uint32_t vec); +uint32_t lapic_get_id(); \ No newline at end of file diff --git a/kernel/src/lib/spinlock.h b/kernel/src/lib/spinlock.h index 894ff5b..49229f7 100644 --- a/kernel/src/lib/spinlock.h +++ b/kernel/src/lib/spinlock.h @@ -1,17 +1,31 @@ #pragma once +#include #include typedef struct spinlock { - volatile int locked; + volatile int locked; } spinlock_t; -inline void spinlock_acquire(spinlock_t *lock) { - while (__sync_lock_test_and_set(&(lock)->locked, 1)) - while ((lock)->locked) - __asm__ volatile("pause"); +static inline void spinlock_acquire(spinlock_t *lock) { + //uint64_t timeout = 1000000; // Adjust this value based on your needs + + for (;;) { + if (__atomic_exchange_n(&lock->locked, 1, __ATOMIC_ACQUIRE) == 0) { + return; + } + + while (__atomic_load_n(&lock->locked, __ATOMIC_RELAXED)) { + /**if (--timeout == 0) { + // Force unlock after too many attempts + __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); + continue; + }**/ + __asm__ volatile("pause" ::: "memory"); + } + } } -inline void spinlock_release(spinlock_t *lock) { - __sync_lock_release(&(lock)->locked); +static inline void spinlock_release(spinlock_t *lock) { + __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); } \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index 3b47f50..746aab4 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,3 +1,5 @@ +#include "dev/ioapic.h" +#include "dev/lapic.h" #include "exec/elf.h" #include "exec/exec.h" #include "mm/liballoc/liballoc.h" @@ -6,8 +8,10 @@ #include "mm/vmm.h" #include "sched/sched.h" #include "sys/acpi.h" -#include "sys/arch/x86_64/pit.h" -#include "sys/arch/x86_64/sse.h" +#include "sys/acpi/madt.h" +#include "arch//x86_64/pit.h" +#include "arch//x86_64/smp.h" +#include "arch//x86_64/sse.h" #include "sys/syscall.h" #include #include @@ -15,9 +19,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -69,7 +73,7 @@ void kmain(void) { VGA8, 8, 16, 0, 0, 0, 0); } - printf("\n Soaplin 1.0-sild is booting up your computer...\n\n"); + printf("\n Soaplin 0.7-sild is booting up your computer...\n\n"); gdt_init(&kstack[8192]); idt_init(); @@ -85,16 +89,26 @@ void kmain(void) { } acpi_init(); + madt_init(); + ioapic_init(); + lapic_init(); + pit_init(); + smp_init(); + syscall_init(); - //pit_init(1000); - //sched_init(); + sched_init(); //vfs_init(); - panic("No working initialization program found. (This is normal due to " - "Soaplin's current state, so please do not report this as a bug)"); + //panic("No working initialization program found. (This is normal due to " + // "Soaplin's current state, so please do not report this as a bug)"); + + program_t *p = elf_load(module_request.response->modules[0]->address, 1); + + sched_process *proc = sched_create("Test", p->entry, p->pm, + SCHED_USER_PROCESS); log("kernel - Soaplin initialized sucessfully.\n"); diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c index f16f6b6..3ebb371 100644 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -1,11 +1,13 @@ #include "sched/sched.h" +#include "arch/x86_64/msr.h" #include "mm/memop.h" #include "mm/pmm.h" #include "mm/vmm.h" -#include "sys/arch/x86_64/idt.h" +#include "arch//x86_64/idt.h" #include "sys/log.h" #include #include +#include sched_process *proc_list; sched_process *curr_proc; @@ -31,7 +33,7 @@ void sched_init() { // We must initialize the process list. // By default, sched_create will append to this list. - proc_list = pmm_request_page(); + proc_list = malloc(sizeof(sched_process)); memcpy(proc_list->name, "System\0", 7); proc_list->pid = -1; proc_list->type = SCHED_EMPTY; @@ -49,7 +51,7 @@ void sched_init() { sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, uint32_t flags) { - sched_process *proc = pmm_request_page(); + sched_process *proc = malloc(sizeof(sched_process)); memset(proc, 0, sizeof(sched_process)); memcpy(proc->name, name, strlen(name) > 128 ? 128 : strlen(name)); @@ -64,10 +66,12 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, proc->pm = pm; uint64_t *stack_phys = pmm_request_page(); + uint64_t *kstack_phys = pmm_request_page(); uint64_t *stack_virt = (uint64_t *)0x40000000; + proc->kernel_stack = HIGHER_HALF(kstack_phys) + PMM_PAGE_SIZE; if (flags == SCHED_KERNEL_PROCESS) { - proc->stack_base = stack_phys; + proc->stack_base = HIGHER_HALF(stack_phys); proc->stack_base_physical = stack_phys; proc->stack_end = proc->stack_base + PMM_PAGE_SIZE; } else if (flags == SCHED_USER_PROCESS) { @@ -110,6 +114,7 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, "disabled.\n"); } + log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, proc->pid, proc->regs.rip); return proc; @@ -152,5 +157,7 @@ void schedule(registers_t *regs) { memcpy(regs, &curr_proc->regs, sizeof(registers_t)); + wrmsr(IA32_GS_KERNEL_MSR, (uint64_t)curr_proc); + //log("sched - proc %d\n", curr_proc->pid); vmm_load_pagemap(curr_proc->pm); } \ No newline at end of file diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h index f328d7a..4a05629 100644 --- a/kernel/src/sched/sched.h +++ b/kernel/src/sched/sched.h @@ -1,7 +1,7 @@ #pragma once #include "mm/vmm.h" -#include "sys/arch/x86_64/idt.h" +#include "arch/x86_64/idt.h" #define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode. #define SCHED_USER_PROCESS \ @@ -11,6 +11,9 @@ typedef enum { SCHED_RUNNING, SCHED_DIED, SCHED_EMPTY } sched_proc_type; typedef struct _sched_process { + uint64_t *stack_base; + uint64_t *kernel_stack; // Kernel-mode stack used for "syscall" + char name[128]; int pid; int type; @@ -20,7 +23,6 @@ typedef struct _sched_process { pagemap_t *pm; uint64_t *stack_end; - uint64_t *stack_base; uint64_t *stack_base_physical; struct _sched_process *next; diff --git a/kernel/src/sys/acpi/madt.c b/kernel/src/sys/acpi/madt.c new file mode 100644 index 0000000..f41dc04 --- /dev/null +++ b/kernel/src/sys/acpi/madt.c @@ -0,0 +1,42 @@ +#include "sys/acpi.h" +#include +#include +#include +#include + +madt_ioapic* acpi_madt_ioapic_list[256] = {0}; +madt_iso* acpi_madt_iso_list[256] = {0}; + +uint32_t acpi_madt_ioapic_length = 0; +uint32_t acpi_madt_iso_length = 0; + +uint64_t* acpi_lapic_addr = 0; + +void madt_init() { + void *addr = acpi_find_table("APIC"); + if (!addr) + panic("madt: Failed to find MADT table!"); + + acpi_madt *madt = (acpi_madt *)addr; + + uint64_t offset = 0; + int i = 0; + + while (1) { + if (offset > madt->sdt.len - sizeof(acpi_madt)) + break; + + madt_entry* entry = (madt_entry*)(madt->table + offset); + + if (entry->type == 0) + i++; + else if (entry->type == 1) + acpi_madt_ioapic_list[acpi_madt_ioapic_length++] = (madt_ioapic*)entry; + else if (entry->type == 2) + acpi_madt_iso_list[acpi_madt_iso_length++] = (madt_iso*)entry; + else if (entry->type == 5) + acpi_lapic_addr = (uint64_t*)((madt_lapic_addr*)entry)->phys_lapic; + + offset += entry->length; + } +} \ No newline at end of file diff --git a/kernel/src/sys/acpi/madt.h b/kernel/src/sys/acpi/madt.h new file mode 100644 index 0000000..1ce1138 --- /dev/null +++ b/kernel/src/sys/acpi/madt.h @@ -0,0 +1,56 @@ +#pragma once + +#include "sys/acpi.h" +#include +typedef struct { + acpi_sdt sdt; + + uint32_t lapic_address; + uint32_t flags; + + char table[]; +} acpi_madt; + +typedef struct { + uint8_t type; + uint8_t length; +} madt_entry; + +typedef struct { + madt_entry un; + uint8_t cpu_id; + uint8_t apic_id; + uint32_t flags; +} madt_cpu_lapic; + +typedef struct { + madt_entry un; + uint8_t apic_id; + uint8_t reserved; + uint32_t apic_addr; + uint32_t gsi_base; +} madt_ioapic; + +typedef struct { + madt_entry un; + uint8_t bus_src; + uint8_t irq_src; + uint32_t gsi; + uint16_t flags; +} madt_iso; + +typedef struct { + madt_entry un; + uint16_t reserved; + uint64_t phys_lapic; +} madt_lapic_addr; + +extern madt_ioapic* acpi_madt_ioapic_list[256]; +extern madt_iso* acpi_madt_iso_list[256]; + +extern uint32_t acpi_madt_ioapic_length; +extern uint32_t acpi_madt_iso_length; + +extern uint64_t* acpi_lapic_addr; + +void madt_init(); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.c b/kernel/src/sys/arch/x86_64/idt.c deleted file mode 100644 index 55d4f52..0000000 --- a/kernel/src/sys/arch/x86_64/idt.c +++ /dev/null @@ -1,51 +0,0 @@ -// #include "sys/log.h" -#include "sys/arch/x86_64/pic.h" -#include -#include - -__attribute__((aligned(0x10))) static idt_entry_t idt[256]; - -static idtr_t idtr; - -void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) { - idt_entry_t *descriptor = &idt[vector]; - - descriptor->isr_low = (uint64_t)isr & 0xFFFF; - descriptor->kernel_cs = 0x28; - descriptor->ist = 0; - descriptor->attributes = flags; - descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; - descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; - descriptor->reserved = 0; -} - -static int vectors[256]; - -extern void *isr_stub_table[]; - -void idt_init() { - idtr.base = (uintptr_t)&idt[0]; - idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; - - for (uint16_t vector = 0; vector <= 256; vector++) { - if (vector == 0x80) - continue; // We skip the syscall handler, since it should be called from - // user space. - idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); - vectors[vector] = 1; - } - - uint16_t vector = 0x80; - idt_set_descriptor(vector, isr_stub_table[vector], 0xEE); - vectors[vector] = 1; - - // Do not use the legacy PIC. - //pic_init(); - //pic_unmask_irq(1); - //pic_unmask_irq(8); - - __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT - __asm__ volatile("sti"); // set the interrupt flag - - log("idt - initialized\n"); -} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/interrupts.c b/kernel/src/sys/arch/x86_64/interrupts.c deleted file mode 100644 index 6d7e3d1..0000000 --- a/kernel/src/sys/arch/x86_64/interrupts.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "mm/pmm.h" -#include "mm/vmm.h" -#include "sched/sched.h" -#include "sys/arch/x86_64/pic.h" -#include "sys/arch/x86_64/rtc.h" -#include "sys/log.h" -#include "sys/syscall.h" -#include -#include -#include -#include - -int pit_millis = 0; -int pit_secs = 0; -extern int vmm_kernel_pm_exists; - -void pit_handler(registers_t *regs); - -void exception_handler(registers_t *regs) { - vmm_load_pagemap(vmm_kernel_pm); - - if (regs->int_no < 32) { - - // Should only be called if the exception is unrecoverable. - panic_ctx("A CPU exception occured.", regs); - //log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, - // regs->err_code); - - //if (regs->int_no == 0xe && vmm_kernel_pm_exists) { - // uint64_t cr2; - // asm("mov %%cr2, %0" : "=r"(cr2)); - // log("ints - PF: Faulting location: %p (%p)\n", cr2, - // virt_to_phys(vmm_current_pm, cr2)); - // log("ints - PF: Faulting page flags: %p\n", - // vmm_get_flags(vmm_current_pm, cr2)); - // log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm)); - //} - - //asm("cli"); - //while (1) - // asm("hlt"); - } - - if (regs->int_no == 1 + 32) { - if (inb(0x60) & 0x80) { - pic_ack(regs->int_no - 32); - return; - } - - log("ints - keyboard\n"); - } else if (regs->int_no == 32 + 8) { - log("rtc\n"); - } else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) { - pit_handler(regs); - } else if (regs->int_no == 0x80) { - syscall_handle(regs); - } - - pic_ack(regs->int_no - 32); -} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pic.c b/kernel/src/sys/arch/x86_64/pic.c deleted file mode 100644 index 53ce230..0000000 --- a/kernel/src/sys/arch/x86_64/pic.c +++ /dev/null @@ -1,76 +0,0 @@ -// #include "sys/log.h" -#include -// #include -#include - -void pic_init() { - // if (acpi_available) - // return; - - uint8_t a1, a2; - - a1 = inb(PIC1_DATA); - a2 = inb(PIC2_DATA); - - outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); - io_wait(); - outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); - io_wait(); - outb(PIC1_DATA, 0x20); - io_wait(); - outb(PIC2_DATA, 8); - io_wait(); - outb(PIC1_DATA, 4); - io_wait(); - outb(PIC2_DATA, 2); - io_wait(); - outb(PIC1_DATA, ICW4_8086); - io_wait(); - outb(PIC2_DATA, ICW4_8086); - io_wait(); - - outb(PIC1_DATA, a1); - outb(PIC2_DATA, a2); -} - -void pic_ack(int intno) { - if (intno >= 8) { - outb(PIC2_COMMAND, 0x20); - } - - outb(PIC1_COMMAND, 0x20); -} - -void pic_disable() // if we want APIC -{ - outb(PIC2_DATA, 0xff); - outb(PIC1_DATA, 0xff); -} - -void pic_mask_irq(uint8_t irq) { - uint16_t port; - uint8_t value; - - if (irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - value = inb(port) | (1 << irq); - outb(port, value); -} - -void pic_unmask_irq(uint8_t irq) { - uint16_t port; - uint8_t value; - - if (irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - value = inb(port) & ~(1 << irq); - outb(port, value); -} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pic.h b/kernel/src/sys/arch/x86_64/pic.h deleted file mode 100755 index 8365bbc..0000000 --- a/kernel/src/sys/arch/x86_64/pic.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2024 Sipaa Projects -// This code is part of the Soaplin kernel and is licensed under the terms of -// the MIT License. - -#pragma once - -#include - -#define PIC1_COMMAND 0x20 -#define PIC1_DATA 0x21 -#define PIC2_COMMAND 0xA0 -#define PIC2_DATA 0xA1 -#define PIC_EOI 0x20 - -#define ICW1_INIT 0x10 -#define ICW1_ICW4 0x01 -#define ICW4_8086 0x01 - -void pic_init(); -void pic_ack(int intno); -void pic_disable(); // if we want APIC -void pic_mask_irq(uint8_t irq); -void pic_unmask_irq(uint8_t irq); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pit.c b/kernel/src/sys/arch/x86_64/pit.c deleted file mode 100644 index 32b60c3..0000000 --- a/kernel/src/sys/arch/x86_64/pit.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "sched/sched.h" -#include "sys/arch/x86_64/idt.h" -#include "sys/arch/x86_64/pic.h" -#include -#include -#ifdef __x86_64__ - -#include -#include -// #include - -uint32_t tick = 0; - -void pit_handler(registers_t *regs) { - tick++; - - schedule(regs); - // Scheduler_Schedule(regs); -} - -void pit_init(uint32_t frequency) { - uint32_t divisor = PIT_FREQUENCY / frequency; - outb(0x43, 0x34); - outb(0x40, (uint8_t)(divisor & 0xFF)); - outb(0x40, (uint8_t)((divisor >> 8) & 0xFF)); - - pic_unmask_irq(0); -} - -void sleep(uint32_t seconds) { - uint32_t eticks = tick + seconds * HZ; - while (tick < eticks) { - __asm__ __volatile__("hlt"); - } -} - -void sleep_ms(uint32_t milliseconds) { - uint32_t eticks = tick + (milliseconds * HZ) / 1000; - while (tick < eticks) { - __asm__ __volatile__("hlt"); - } -} - -// todo: unistd: add usleep function -void usleep(uint32_t usecs) { - uint32_t eticks = tick + (usecs * HZ); - while (tick < eticks) { - __asm__ __volatile__("hlt"); - } -} - -#endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pit.h b/kernel/src/sys/arch/x86_64/pit.h deleted file mode 100755 index 0131be8..0000000 --- a/kernel/src/sys/arch/x86_64/pit.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef PIT_H -#define PIT_H - -#include -#include - -#define PIT_FREQUENCY 1193182 -#define HZ 1000 - -extern uint32_t tick; - -void pit_init(uint32_t frequency); -void sleep(uint32_t seconds); -void sleep_ms(uint32_t milliseconds); -void usleep(uint32_t usecs); - -#endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/smp.c b/kernel/src/sys/arch/x86_64/smp.c deleted file mode 100644 index 33183b6..0000000 --- a/kernel/src/sys/arch/x86_64/smp.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "sys/arch/x86_64/smp.h" -#include "limine.h" - -void smp_init() {} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/smp.h b/kernel/src/sys/arch/x86_64/smp.h deleted file mode 100644 index a5c81cb..0000000 --- a/kernel/src/sys/arch/x86_64/smp.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void smp_init(); \ No newline at end of file diff --git a/kernel/src/sys/errhnd/panic.c b/kernel/src/sys/errhnd/panic.c index e6e770e..dd71a1b 100644 --- a/kernel/src/sys/errhnd/panic.c +++ b/kernel/src/sys/errhnd/panic.c @@ -1,4 +1,5 @@ -#include "sys/arch/x86_64/idt.h" +#include "arch//x86_64/idt.h" +#include "lib/spinlock.h" #include #include @@ -49,6 +50,39 @@ static void __panic_dump_regs() { __panic_regdump.ss = 0; } +static void __panic_display_page_fault(registers_t *regs) { + if (regs->int_no != 14) // 14 is the page fault interrupt number + return; + + uint64_t cr2; + asm volatile("mov %%cr2, %0" : "=r"(cr2)); + + log("Page Fault Details:\n"); + log("Faulting Address (CR2): 0x%lx\n", cr2); + log("Error Code: %d\n", regs->err_code); + log("Flags:\n"); + if (!(regs->err_code & (1 << 0))) + log(" - Page Not Present\n"); + else + log(" - Protection Violation\n"); + + if (regs->err_code & (1 << 1)) + log(" - Write Access\n"); + else + log(" - Read Access\n"); + + if (regs->err_code & (1 << 2)) + log(" - User-Mode Access\n"); + else + log(" - Kernel-Mode Access\n"); + + if (regs->err_code & (1 << 3)) + log(" - Reserved Bits Set\n"); + + if (regs->err_code & (1 << 4)) + log(" - Instruction Fetch\n"); +} + static void __panic_display_regs(registers_t *regs) { log("-- REGISTER DUMP --\n"); log("RDI: %p, RSI: %p, RDX: %p, RCX: %p, R8: %p, R9: %p\n", @@ -59,10 +93,13 @@ static void __panic_display_regs(registers_t *regs) { regs->r10, regs->r11, regs->r12); log("R13: %p, R14: %p, R15: %p\n", regs->r13, regs->r14, regs->r15); - log("RIP: %p, CS: %d, SS: %d, RFLAGS: %d, INTERRUPT: %d, ERROR CODE: %d\n", + log("RIP: %p, CS: %x, SS: %x, RFLAGS: %d, INTERRUPT: %d, ERROR CODE: %d\n", regs->rip, regs->cs, regs->ss, regs->rflags, regs->int_no, regs->err_code); log("RSP: %p\n", regs->rsp); + + if (regs->int_no == 14) // If it's a page fault + __panic_display_page_fault(regs); } void __panic_display_ascii_art() { @@ -104,6 +141,8 @@ void panic_ctx(char *msg, registers_t *regs) { else log("No register context provided.\n"); + + log("System halted: Please restart your computer manually.\n"); asm("cli"); diff --git a/kernel/src/sys/errhnd/panic.h b/kernel/src/sys/errhnd/panic.h index 5e84ca5..147263b 100644 --- a/kernel/src/sys/errhnd/panic.h +++ b/kernel/src/sys/errhnd/panic.h @@ -1,5 +1,5 @@ #pragma once -#include "sys/arch/x86_64/idt.h" +#include "arch/x86_64/idt.h" void panic(char *msg); void panic_ctx(char *msg, registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/log.c b/kernel/src/sys/log.c index 20bd1b0..e6f3988 100644 --- a/kernel/src/sys/log.c +++ b/kernel/src/sys/log.c @@ -1,4 +1,4 @@ -#include "sys/arch/x86_64/io.h" +#include "arch//x86_64/io.h" #include "sys/gfx/flanterm/flanterm.h" #include #include @@ -10,10 +10,11 @@ extern struct flanterm_context *ft_ctx; static spinlock_t log_lock = {0}; void log(char *format, ...) { - // spinlock_acquire(&log_lock); - // TODO: replace this call with a call to printf() when the RTC is // implemented. + + //spinlock_acquire(&log_lock); + char *date = "1970-01-01 00:00:00 | "; if (ft_ctx) flanterm_write(ft_ctx, date, strlen(date)); @@ -40,6 +41,6 @@ void log(char *format, ...) { outb(0xE9, buf[i]); } - - // spinlock_release(&log_lock); + + //spinlock_release(&log_lock); } \ No newline at end of file diff --git a/kernel/src/sys/syscall.c b/kernel/src/sys/syscall.c index 0a3567c..c132998 100644 --- a/kernel/src/sys/syscall.c +++ b/kernel/src/sys/syscall.c @@ -8,6 +8,8 @@ static syscall syscall_table[1024]; static int syscall_initialized = 0; +extern void __x86_64_syscall_init(); + // Stub function for undefined syscalls. static uint64_t __syscall_undefined() { return 0; } @@ -30,6 +32,8 @@ void syscall_handle(registers_t *regs) { return; } + log("Hello!\n"); + regs->rax = syscall_table[regs->rax](regs->rdi, regs->rsi, regs->rdx, regs->rcx, regs->r8, regs->r9); return; @@ -48,9 +52,11 @@ void syscall_register(int id, syscall handler) { extern void syscall_exit(int exit_code); -void syscall_init() { +void syscall_init() { for (int i = 0; i < 1024; i++) syscall_table[i] = (syscall)__syscall_undefined; syscall_register(0, (syscall)syscall_exit); + + __x86_64_syscall_init(); } \ No newline at end of file diff --git a/kernel/src/sys/syscall.h b/kernel/src/sys/syscall.h index 5fce348..1d0f3f0 100644 --- a/kernel/src/sys/syscall.h +++ b/kernel/src/sys/syscall.h @@ -1,6 +1,6 @@ #pragma once -#include "sys/arch/x86_64/idt.h" +#include "arch//x86_64/idt.h" #include /// A function that defines a system call. diff --git a/limine.conf b/limine.conf index fd0bd86..df98d06 100755 --- a/limine.conf +++ b/limine.conf @@ -6,4 +6,4 @@ verbose: yes protocol: limine path: boot():/boot/soaplin - module_path: boot():/initramfs.tar \ No newline at end of file + module_path: boot():/sk-hello.elf \ No newline at end of file diff --git a/testing/sk-hello.elf b/testing/sk-hello.elf index b36d9a6..257f986 100755 Binary files a/testing/sk-hello.elf and b/testing/sk-hello.elf differ diff --git a/testing/test.asm b/testing/test.asm index 14e2f8a..31ef8b4 100644 --- a/testing/test.asm +++ b/testing/test.asm @@ -3,7 +3,6 @@ section .text global _start _start: - mov rax, 10 -.hey: - add rax, 1 - jmp .hey \ No newline at end of file + syscall +.loop: + jmp .loop \ No newline at end of file diff --git a/testing/test.bin b/testing/test.bin new file mode 100644 index 0000000..4cb5c50 --- /dev/null +++ b/testing/test.bin @@ -0,0 +1 @@ +λώ \ No newline at end of file diff --git a/testing/test.o b/testing/test.o index b3d93e1..c668451 100644 Binary files a/testing/test.o and b/testing/test.o differ