This commit is contained in:
2026-09-14 02:50:35 +02:00
parent cf3f1f9e99
commit 9e5ed517bc
45 changed files with 210 additions and 212 deletions
+12 -7
View File
@@ -2,6 +2,9 @@
#include <kernel/clock.h> #include <kernel/clock.h>
#include <kernel/mmio.h> #include <kernel/mmio.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
#include <kernel/pmap.h>
#include <kernel/vas.h>
#include <kernel/virt.h>
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <x86_64/apic.h> #include <x86_64/apic.h>
@@ -12,11 +15,11 @@ static uint64_t lapic_read_reg(struct local_apic* lapic, uint32_t reg) {
if (lapic->xapic_regs) { if (lapic->xapic_regs) {
if (reg == APIC_REG_ICR) { if (reg == APIC_REG_ICR) {
uint64_t lo, hi; uint64_t lo, hi;
lo = lapic->xapic_regs[APIC_REG_ICR / sizeof(uint32_t)]; lo = mmio_read32(lapic->xapic_regs + APIC_REG_ICR);
hi = lapic->xapic_regs[APIC_REG_ICR_HI / sizeof(uint32_t)]; hi = mmio_read32(lapic->xapic_regs + APIC_REG_ICR_HI);
return (hi << 32) | lo; return (hi << 32) | lo;
} else { } else {
return lapic->xapic_regs[reg / sizeof(uint32_t)]; return mmio_read32(lapic->xapic_regs + reg);
} }
} else { } else {
return asm_rdmsr(0x800 + (reg >> 4)); return asm_rdmsr(0x800 + (reg >> 4));
@@ -26,10 +29,10 @@ static uint64_t lapic_read_reg(struct local_apic* lapic, uint32_t reg) {
static void lapic_write_reg(struct local_apic* lapic, uint32_t reg, uint64_t value) { static void lapic_write_reg(struct local_apic* lapic, uint32_t reg, uint64_t value) {
if (lapic->xapic_regs) { if (lapic->xapic_regs) {
if (reg == APIC_REG_ICR) { if (reg == APIC_REG_ICR) {
lapic->xapic_regs[APIC_REG_ICR_HI / sizeof(uint32_t)] = value >> 32; mmio_write32(lapic->xapic_regs + APIC_REG_ICR_HI, value >> 32);
lapic->xapic_regs[APIC_REG_ICR / sizeof(uint32_t)] = value & 0xFFFF'FFFF; mmio_write32(lapic->xapic_regs + APIC_REG_ICR, (uint32_t)value);
} else { } else {
lapic->xapic_regs[reg / sizeof(uint32_t)] = value & 0xFFFF'FFFF; mmio_write32(lapic->xapic_regs + reg, (uint32_t)value);
} }
} else { } else {
asm_wrmsr(0x800 + (reg >> 4), value); asm_wrmsr(0x800 + (reg >> 4), value);
@@ -44,7 +47,9 @@ void lapic_init(struct local_apic* lapic) {
if (cpuid.ecx & CPUID_1C_X2APIC) if (cpuid.ecx & CPUID_1C_X2APIC)
apic_msr |= 1 << 10; apic_msr |= 1 << 10;
else { else {
lapic->xapic_regs = mmio_new(apic_msr & 0xFFFF'F000, 0x1000); uintptr_t vaddr = vm_alloc(0x1000);
pmap_map(&kernel_vas.pmap, vaddr, apic_msr & 0xFFFF'F000, PTE_READ | PTE_WRITE, CACHE_MMIO);
lapic->xapic_regs = (void*)vaddr;
assert(lapic->xapic_regs, "Failed to allocate virtual memory!\n"); assert(lapic->xapic_regs, "Failed to allocate virtual memory!\n");
} }
+8 -2
View File
@@ -1,8 +1,10 @@
#include <common/utils.h> #include <common/utils.h>
#include <kernel/clock.h> #include <kernel/clock.h>
#include <kernel/cmdline.h> #include <kernel/cmdline.h>
#include <kernel/mmio.h> #include <kernel/pmap.h>
#include <kernel/print.h> #include <kernel/print.h>
#include <kernel/vas.h>
#include <kernel/virt.h>
#include <assert.h> #include <assert.h>
#include <uacpi/acpi.h> #include <uacpi/acpi.h>
#include <uacpi/status.h> #include <uacpi/status.h>
@@ -56,7 +58,11 @@ void hpet_init() {
assert(!uacpi_table_find_by_signature("HPET", &table), "HPET table not found!\n"); assert(!uacpi_table_find_by_signature("HPET", &table), "HPET table not found!\n");
struct acpi_hpet* hpet = table.ptr; struct acpi_hpet* hpet = table.ptr;
hpet_clock.regs = mmio_new(hpet->address.address, 0x1000);
uintptr_t vaddr = vm_alloc(0x1000);
pmap_map(&kernel_vas.pmap, vaddr, hpet->address.address, PTE_READ | PTE_WRITE, CACHE_MMIO);
hpet_clock.regs = (void*)vaddr;
uacpi_table_unref(&table); uacpi_table_unref(&table);
kprintf("HPET regs at %p\n", hpet_clock.regs); kprintf("HPET regs at %p\n", hpet_clock.regs);
-33
View File
@@ -1,33 +0,0 @@
#pragma once
#include <kernel/types.h>
#include <stddef.h>
#include <stdint.h>
static inline size_t arch_mem_page_size() {
return 1 << 12;
}
static inline size_t arch_mem_page_bits() {
return 12;
}
static inline size_t arch_mem_level_bits() {
return 9;
}
static inline size_t arch_mem_num_levels() {
return 4;
}
static inline uintptr_t arch_mem_hhdm_addr() {
return 0xFFFF'8000'0000'0000;
}
static inline uintptr_t arch_vm_pfndb_addr() {
return 0xFFFF'A000'0000'0000;
}
static inline uintptr_t arch_mem_mapping_addr() {
return 0xFFFF'C000'0000'0000;
}
-9
View File
@@ -6,12 +6,6 @@
#include <x86_64/gdt.h> #include <x86_64/gdt.h>
#include <x86_64/tss.h> #include <x86_64/tss.h>
static inline struct percpu* arch_percpu_get() {
struct percpu* result;
asm volatile("mov %0, gs:0" : "=r"(result)::"memory");
return result;
}
struct arch_percpu { struct arch_percpu {
struct gdt gdt; struct gdt gdt;
struct tss tss; struct tss tss;
@@ -22,6 +16,3 @@ struct arch_percpu {
void (*fpu_restore)(const void*); void (*fpu_restore)(const void*);
bool can_smap; bool can_smap;
}; };
void arch_percpu_bsp_init();
void arch_percpu_init();
+1 -1
View File
@@ -5,7 +5,7 @@
struct local_apic { struct local_apic {
uint32_t id; uint32_t id;
uint32_t ticks_per_10ms; uint32_t ticks_per_10ms;
volatile uint32_t* xapic_regs; void* xapic_regs;
}; };
enum apic_delivery_mode { enum apic_delivery_mode {
@@ -1,21 +1,19 @@
#pragma once
#include <stdint.h> #include <stdint.h>
#include <x86_64/defs.h> #include <x86_64/defs.h>
static inline bool arch_irq_get_state() { bool arch_irq_get_state() {
uint64_t flags; uint64_t flags;
asm volatile("pushf; pop %0" : "=r"(flags)::"memory"); asm volatile("pushf; pop %0" : "=r"(flags)::"memory");
return flags & RFLAGS_IF; return flags & RFLAGS_IF;
} }
static inline void arch_irq_set_state(bool state) { void arch_irq_set_state(bool state) {
if (state) if (state)
asm volatile("sti"); asm volatile("sti");
else else
asm volatile("cli"); asm volatile("cli");
} }
static inline void arch_irq_wait() { void arch_irq_wait() {
asm volatile("hlt"); asm volatile("hlt");
} }
+31
View File
@@ -0,0 +1,31 @@
#include <kernel/types.h>
#include <stddef.h>
#include <stdint.h>
size_t arch_mem_page_size() {
return 1 << 12;
}
size_t arch_mem_page_bits() {
return 12;
}
size_t arch_mem_level_bits() {
return 9;
}
size_t arch_mem_num_levels() {
return 4;
}
uintptr_t arch_mem_hhdm_addr() {
return 0xFFFF'8000'0000'0000;
}
uintptr_t arch_mem_pfndb_addr() {
return 0xFFFF'A000'0000'0000;
}
uintptr_t arch_mem_mapping_addr() {
return 0xFFFF'C000'0000'0000;
}
+2
View File
@@ -9,6 +9,8 @@ kernel_sources += files(
'gdt.c', 'gdt.c',
'hpet.c', 'hpet.c',
'idt.c', 'idt.c',
'irq.c',
'mem.c',
'percpu.c', 'percpu.c',
'pmap.c', 'pmap.c',
'sched.c', 'sched.c',
+9 -1
View File
@@ -10,6 +10,12 @@
#include <x86_64/syscall.h> #include <x86_64/syscall.h>
#include <x86_64/tsc.h> #include <x86_64/tsc.h>
struct percpu* arch_percpu_get() {
struct percpu* result;
asm volatile("mov %0, gs:0" : "=r"(result)::"memory");
return result;
}
void arch_percpu_bsp_init() { void arch_percpu_bsp_init() {
asm_wrmsr(MSR_GS_BASE, (uint64_t)&percpu_bsp); asm_wrmsr(MSR_GS_BASE, (uint64_t)&percpu_bsp);
asm_wrmsr(MSR_FS_BASE, 0); asm_wrmsr(MSR_FS_BASE, 0);
@@ -33,9 +39,9 @@ union ia32_star {
static_assert(sizeof(union ia32_star) == 8); static_assert(sizeof(union ia32_star) == 8);
static void setup_cpu(struct percpu* cpu) { static void setup_cpu(struct percpu* cpu) {
asm_wrmsr(MSR_KERNEL_GS_BASE, 0);
asm_wrmsr(MSR_GS_BASE, (uint64_t)cpu); asm_wrmsr(MSR_GS_BASE, (uint64_t)cpu);
asm_wrmsr(MSR_FS_BASE, 0); asm_wrmsr(MSR_FS_BASE, 0);
asm_wrmsr(MSR_KERNEL_GS_BASE, 0);
gdt_load(); gdt_load();
idt_load(); idt_load();
@@ -49,6 +55,8 @@ static void setup_cpu(struct percpu* cpu) {
asm_wrmsr(MSR_LSTAR, (uint64_t)arch_syscall_stub); asm_wrmsr(MSR_LSTAR, (uint64_t)arch_syscall_stub);
asm_wrmsr(MSR_SFMASK, RFLAGS_AC | RFLAGS_DF | RFLAGS_IF); asm_wrmsr(MSR_SFMASK, RFLAGS_AC | RFLAGS_DF | RFLAGS_IF);
// TODO: FRED
uint64_t cr0, cr4; uint64_t cr0, cr4;
asm volatile("mov %0, cr0" : "=r"(cr0)); asm volatile("mov %0, cr0" : "=r"(cr0));
asm volatile("mov %0, cr4" : "=r"(cr4)); asm volatile("mov %0, cr4" : "=r"(cr4));
+6 -5
View File
@@ -1,6 +1,7 @@
#include <zinnia/status.h> #include <zinnia/status.h>
#include <common/compiler.h> #include <common/compiler.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
#include <kernel/sched.h> #include <kernel/sched.h>
#include <kernel/virt.h> #include <kernel/virt.h>
@@ -53,8 +54,8 @@ static void perform_switch(uint64_t* old_rsp, uint64_t new_rsp) {
void arch_sched_switch(struct task* from, struct task* to) { void arch_sched_switch(struct task* from, struct task* to) {
struct arch_percpu* cpu = &percpu_get()->arch; struct arch_percpu* cpu = &percpu_get()->arch;
struct arch_task_context* from_ctx = &from->context; struct arch_task_context* from_ctx = &from->task_ctx;
struct arch_task_context* to_ctx = &to->context; struct arch_task_context* to_ctx = &to->task_ctx;
cpu->tss.rsp0 = to->kernel_stack + KERNEL_STACK_SIZE; cpu->tss.rsp0 = to->kernel_stack + KERNEL_STACK_SIZE;
@@ -119,7 +120,7 @@ zn_status_t arch_task_init(
if (is_user) { if (is_user) {
// Allocate FPU space. // Allocate FPU space.
const size_t fpu_size = cpu->fpu_size; const size_t fpu_size = cpu->fpu_size;
void* fpu_base = vm_alloc(fpu_size); uintptr_t fpu_base = vm_alloc(fpu_size);
if (!fpu_base) if (!fpu_base)
return ZN_ERR_NO_MEMORY; return ZN_ERR_NO_MEMORY;
for (size_t i = 0; i < fpu_size; i += arch_mem_page_size()) { for (size_t i = 0; i < fpu_size; i += arch_mem_page_size()) {
@@ -130,9 +131,9 @@ zn_status_t arch_task_init(
return s; return s;
} }
pmap_map(&kernel_vas.pmap, (uintptr_t)fpu_base, page, PTE_WRITE | PTE_READ, CACHE_WRITE_BACK); pmap_map(&kernel_vas.pmap, fpu_base, page, PTE_WRITE | PTE_READ, CACHE_WRITE_BACK);
} }
context->fpu_region = fpu_base; context->fpu_region = (void*)fpu_base;
context->ds = asm_read_ds(); context->ds = asm_read_ds();
context->es = asm_read_es(); context->es = asm_read_es();
+6 -1
View File
@@ -1,6 +1,7 @@
#include <zinnia/archctl.h> #include <zinnia/archctl.h>
#include <zinnia/status.h> #include <zinnia/status.h>
#include <common/compiler.h> #include <common/compiler.h>
#include <kernel/arch.h>
#include <kernel/init.h> #include <kernel/init.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
#include <x86_64/apic.h> #include <x86_64/apic.h>
@@ -9,7 +10,7 @@
#include <x86_64/gdt.h> #include <x86_64/gdt.h>
[[__init, __naked, __used]] [[__init, __naked, __used]]
void _start() { void arch_start() {
asm volatile( asm volatile(
"lea rsp, [rip + %0]\n" "lea rsp, [rip + %0]\n"
"jmp %1" "jmp %1"
@@ -25,6 +26,10 @@ zn_status_t arch_archctl(zn_archctl_t op, uintptr_t arg) {
case ZN_ARCHCTL_SET_FSBASE: case ZN_ARCHCTL_SET_FSBASE:
asm_wrmsr(MSR_FS_BASE, arg); asm_wrmsr(MSR_FS_BASE, arg);
return 0; return 0;
case ZN_ARCHCTL_SET_GSBASE:
// Slightly misleading, but KERNEL_GS_BASE is the currently inactive register.
asm_wrmsr(MSR_KERNEL_GS_BASE, arg);
return 0;
default: default:
return ZN_ERR_INVALID; return ZN_ERR_INVALID;
} }
+4 -53
View File
@@ -18,7 +18,7 @@ bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct us
// Setup regs for `rep movsb`. // Setup regs for `rep movsb`.
"xchg rcx, rdx\n" "xchg rcx, rdx\n"
"mov rax, [rip + %0]\n" "mov rax, [rip + %0]\n"
"mov [rdx], rax\n" "xchg [rdx], rax\n"
".global x86_64_read_start\n" ".global x86_64_read_start\n"
"x86_64_read_start:\n" "x86_64_read_start:\n"
@@ -35,7 +35,7 @@ bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct us
".global x86_64_read_fault\n" ".global x86_64_read_fault\n"
"x86_64_read_fault:\n" "x86_64_read_fault:\n"
"xor rax, rax\n" "xor rax, rax\n"
"mov [rdx], rax\n" "xchg [rdx], rax\n"
"clac\n" "clac\n"
"ret\n" "ret\n"
: :
@@ -61,7 +61,7 @@ bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct u
// Setup regs for `rep movsb`. // Setup regs for `rep movsb`.
"xchg rcx, rdx\n" "xchg rcx, rdx\n"
"mov rax, [rip + %0]\n" "mov rax, [rip + %0]\n"
"mov [rdx], rax\n" "xchg [rdx], rax\n"
".global x86_64_write_start\n" ".global x86_64_write_start\n"
"x86_64_write_start:\n" "x86_64_write_start:\n"
@@ -78,7 +78,7 @@ bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct u
".global x86_64_write_fault\n" ".global x86_64_write_fault\n"
"x86_64_write_fault:\n" "x86_64_write_fault:\n"
"xor rax, rax\n" "xor rax, rax\n"
"mov [rdx], rax\n" "xchg [rdx], rax\n"
"clac\n" "clac\n"
"ret\n" "ret\n"
: :
@@ -86,52 +86,3 @@ bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct u
: "memory" : "memory"
); );
} }
extern void x86_64_strlen_start();
extern void x86_64_strlen_end();
extern void x86_64_strlen_fault();
static const struct usercopy_region strlen_region = {
.start_ip = x86_64_strlen_start,
.end_ip = x86_64_strlen_end,
.fault_ip = x86_64_strlen_fault,
};
[[__naked]]
bool arch_usercopy_strlen(const __user char* str, size_t max, size_t* len, struct usercopy_region** region) {
asm volatile(
"stac\n"
"mov rax, [rip + %0]\n"
"mov [rcx], rax\n"
".global x86_64_strlen_start\n"
"x86_64_strlen_start:\n"
"xor r8, r8\n"
".Lloop:\n"
"cmp byte ptr [rdi + r8], 0\n"
"je .Lleave\n"
"inc r8\n"
"cmp rsi, r8\n"
"jne .Lloop\n"
".Lleave:\n"
"mov [rdx], r8\n"
".global x86_64_strlen_end\n"
"x86_64_strlen_end:\n"
"xor rax, rax\n"
"mov [rcx], rax\n"
"mov rax, 1\n"
"clac\n"
"ret\n"
".global x86_64_strlen_fault\n"
"x86_64_strlen_fault:\n"
"xor rax, rax\n"
"mov [rcx], rax\n"
"clac\n"
"ret\n"
:
: "i"(&strlen_region)
: "memory"
);
}
+1
View File
@@ -1,5 +1,6 @@
#include <common/compiler.h> #include <common/compiler.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/channel.h> #include <kernel/channel.h>
#include <kernel/clock.h> #include <kernel/clock.h>
#include <kernel/cmdline.h> #include <kernel/cmdline.h>
+1
View File
@@ -3,6 +3,7 @@
#include <common/elf.h> #include <common/elf.h>
#include <common/utils.h> #include <common/utils.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/elf.h> #include <kernel/elf.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
#include <kernel/pmap.h> #include <kernel/pmap.h>
+1
View File
@@ -1,3 +1,4 @@
#include <kernel/arch.h>
#include <kernel/irq.h> #include <kernel/irq.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
#include <stdatomic.h> #include <stdatomic.h>
+1
View File
@@ -1,3 +1,4 @@
#include <kernel/arch.h>
#include <kernel/irq.h> #include <kernel/irq.h>
#include <kernel/panic.h> #include <kernel/panic.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
+13
View File
@@ -1,4 +1,5 @@
#include <common/compiler.h> #include <common/compiler.h>
#include <kernel/arch.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
[[__used, __section(".percpu")]] [[__used, __section(".percpu")]]
@@ -12,3 +13,15 @@ struct percpu* percpu_new() {
// TODO // TODO
return nullptr; return nullptr;
} }
struct percpu* percpu_get() {
return arch_percpu_get();
}
void percpu_bsp_init() {
arch_percpu_bsp_init();
}
void percpu_init() {
arch_percpu_init();
}
+2 -2
View File
@@ -1,5 +1,6 @@
#include <zinnia/status.h> #include <zinnia/status.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/irq.h> #include <kernel/irq.h>
#include <kernel/list.h> #include <kernel/list.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
@@ -8,7 +9,6 @@
#include <kernel/spin.h> #include <kernel/spin.h>
#include <kernel/tailq.h> #include <kernel/tailq.h>
#include <assert.h> #include <assert.h>
#include <bits/irq.h>
#include <stdatomic.h> #include <stdatomic.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -125,7 +125,7 @@ zn_status_t task_create(
new_task->user_stack = 0; new_task->user_stack = 0;
// Initialize the arch-dependent parts. // Initialize the arch-dependent parts.
zn_status_t s = arch_task_init(&new_task->context, entry, arg0, new_task->kernel_stack + KERNEL_STACK_SIZE, true); zn_status_t s = arch_task_init(&new_task->task_ctx, entry, arg0, new_task->kernel_stack + KERNEL_STACK_SIZE, true);
if (s != ZN_OK) if (s != ZN_OK)
return s; return s;
+10 -2
View File
@@ -1,7 +1,11 @@
#include <common/utils.h> #include <common/utils.h>
#include <kernel/arch.h>
#include <kernel/init.h> #include <kernel/init.h>
#include <kernel/mmio.h> #include <kernel/mmio.h>
#include <kernel/pmap.h>
#include <kernel/print.h> #include <kernel/print.h>
#include <kernel/vas.h>
#include <kernel/virt.h>
#include <stdarg.h> #include <stdarg.h>
#include <uacpi/kernel_api.h> #include <uacpi/kernel_api.h>
#include <uacpi/status.h> #include <uacpi/status.h>
@@ -13,11 +17,15 @@ uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr* out_rsdp_address) {
} }
void* uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) { void* uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) {
return mmio_new(addr, len); uintptr_t vaddr = vm_alloc(len);
for (size_t i = 0; i < len; i += arch_mem_page_size()) {
pmap_map(&kernel_vas.pmap, vaddr, addr, PTE_READ | PTE_WRITE, CACHE_MMIO);
}
return (void*)vaddr;
} }
void uacpi_kernel_unmap(void* addr, uacpi_size len) { void uacpi_kernel_unmap(void* addr, uacpi_size len) {
mmio_free(addr, len); // TODO
} }
void uacpi_kernel_log(uacpi_log_level lvl, const uacpi_char* msg, ...) { void uacpi_kernel_log(uacpi_log_level lvl, const uacpi_char* msg, ...) {
+2 -12
View File
@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <zinnia/status.h> #include <zinnia/status.h>
#include <bits/mem.h> #include <kernel/types.h>
#include <stddef.h> #include <stddef.h>
enum alloc_flags { enum alloc_flags {
@@ -44,14 +44,4 @@ void slab_init();
void mem_phys_bootstrap(struct phys_mem* mem); void mem_phys_bootstrap(struct phys_mem* mem);
void mem_phys_init(struct phys_mem* map, size_t length); void mem_phys_init(struct phys_mem* map, size_t length);
uintptr_t arch_mem_hhdm_addr(); size_t mem_high_shift();
uintptr_t arch_vm_pfndb_addr();
uintptr_t arch_mem_mapping_addr();
size_t arch_mem_page_bits();
size_t arch_mem_page_size();
size_t arch_mem_level_bits();
size_t arch_mem_num_levels();
static inline size_t mem_high_shift() {
return arch_mem_level_bits() * arch_mem_num_levels() + arch_mem_page_bits();
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
void arch_start();
void arch_panic();
size_t arch_mem_page_size();
size_t arch_mem_page_bits();
size_t arch_mem_level_bits();
size_t arch_mem_num_levels();
uintptr_t arch_mem_hhdm_addr();
uintptr_t arch_mem_pfndb_addr();
uintptr_t arch_mem_mapping_addr();
#include <kernel/usercopy.h>
bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct usercopy_region** region);
bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct usercopy_region** region);
#include <kernel/irq.h>
void arch_irq_set_state(bool state);
bool arch_irq_get_state();
void arch_irq_wait();
#include <kernel/percpu.h>
struct percpu* arch_percpu_get();
void arch_percpu_bsp_init();
void arch_percpu_init();
-7
View File
@@ -1,7 +0,0 @@
#pragma once
#include <kernel/usercopy.h>
bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct usercopy_region** region);
bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct usercopy_region** region);
bool arch_usercopy_strlen(const __user char* str, size_t max, size_t* len, struct usercopy_region** region);
-5
View File
@@ -2,7 +2,6 @@
#include <common/compiler.h> #include <common/compiler.h>
#include <kernel/list.h> #include <kernel/list.h>
#include <bits/irq.h>
#include <stdint.h> #include <stdint.h>
enum irq_status : uint8_t { enum irq_status : uint8_t {
@@ -45,7 +44,3 @@ struct irq_percpu {
void irq_lock(); void irq_lock();
void irq_unlock(); void irq_unlock();
bool irq_set_interrupted(bool is_interrupted); bool irq_set_interrupted(bool is_interrupted);
void arch_irq_set_state(bool state);
bool arch_irq_get_state();
void arch_irq_wait();
+31 -4
View File
@@ -1,7 +1,34 @@
#pragma once #pragma once
#include <stdint.h>
#include <kernel/types.h> static inline uint8_t mmio_read8(void* ptr) {
#include <stddef.h> return *((volatile uint8_t*)ptr);
}
void* mmio_new(phys_t addr, size_t length); static inline uint16_t mmio_read16(void* ptr) {
void mmio_free(void* ptr, size_t length); return *((volatile uint16_t*)ptr);
}
static inline uint32_t mmio_read32(void* ptr) {
return *((volatile uint32_t*)ptr);
}
static inline uint64_t mmio_read64(void* ptr) {
return *((volatile uint64_t*)ptr);
}
static inline void mmio_write8(void* ptr, uint8_t value) {
*((volatile uint8_t*)ptr) = value;
}
static inline void mmio_write16(void* ptr, uint16_t value) {
*((volatile uint16_t*)ptr) = value;
}
static inline void mmio_write32(void* ptr, uint32_t value) {
*((volatile uint32_t*)ptr) = value;
}
static inline void mmio_write64(void* ptr, uint64_t value) {
*((volatile uint64_t*)ptr) = value;
}
+3 -9
View File
@@ -28,16 +28,10 @@ extern struct percpu percpu_bsp;
struct percpu* percpu_new(); struct percpu* percpu_new();
// Gets the per-CPU data on the current CPU. // Gets the per-CPU data on the current CPU.
static inline struct percpu* percpu_get() { struct percpu* percpu_get();
return arch_percpu_get();
}
// Initializes the bootstrap processor. // Initializes the bootstrap processor.
static inline void percpu_bsp_init() { void percpu_bsp_init();
arch_percpu_bsp_init();
}
// Initializes all processors. // Initializes all processors.
static inline void percpu_init() { void percpu_init();
arch_percpu_init();
}
+4 -6
View File
@@ -11,9 +11,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
ASSERT_TYPE(struct arch_context);
ASSERT_TYPE(struct arch_task_context);
enum task_state { enum task_state {
TASK_STATE_RUNNING, // Task is active and running. TASK_STATE_RUNNING, // Task is active and running.
TASK_STATE_READY, // Task is active, but not currently scheduled. TASK_STATE_READY, // Task is active, but not currently scheduled.
@@ -26,19 +23,20 @@ enum task_state {
// A task is the smallest unit of the scheduler. // A task is the smallest unit of the scheduler.
struct task { struct task {
tailq_link(struct task) next;
size_t id; size_t id;
char name[TASK_NAME_MAX]; char name[TASK_NAME_MAX];
struct vas* space; struct vas* space;
struct namespace* namespace; struct namespace* namespace;
enum task_state state; enum task_state state;
struct arch_task_context context; struct arch_task_context task_ctx;
struct arch_context ctx;
struct usercopy_region* usercopy_region; struct usercopy_region* usercopy_region;
uintptr_t kernel_stack; uintptr_t kernel_stack;
uintptr_t user_stack; uintptr_t user_stack;
size_t time_slice; size_t time_slice;
int8_t priority; int8_t priority;
tailq_link(struct task) next;
}; };
// Per-CPU data for scheduling. // Per-CPU data for scheduling.
-4
View File
@@ -1,7 +1,6 @@
#pragma once #pragma once
#include <common/compiler.h> #include <common/compiler.h>
#include <kernel/percpu.h>
#include <stddef.h> #include <stddef.h>
struct usercopy_region { struct usercopy_region {
@@ -15,6 +14,3 @@ bool usercopy_read(void* dst, const __user void* src, size_t len);
// Copies a block of data from kernel to user memory. // Copies a block of data from kernel to user memory.
bool usercopy_write(__user void* dst, const void* src, size_t len); bool usercopy_write(__user void* dst, const void* src, size_t len);
// Performs a strlen() on a user string.
bool usercopy_strlen(const __user char* str, size_t max, size_t* len);
-1
View File
@@ -8,7 +8,6 @@
// Virtual address space. // Virtual address space.
struct vas { struct vas {
// Architecture-specific virtual memory map implementation.
struct pmap pmap; struct pmap pmap;
}; };
-2
View File
@@ -22,8 +22,6 @@ struct vdso_kernel_data {
// Export a function under the current API version. // Export a function under the current API version.
#define VDSO_SYMBOL(fn) asm(".symver " #fn ",__vdso_" #fn "@@ZINNIA_0") #define VDSO_SYMBOL(fn) asm(".symver " #fn ",__vdso_" #fn "@@ZINNIA_0")
// Export a function as a symbol for an older API version.
#define VDSO_SYMBOL_LEGACY(fn, symbol, ver) asm(".symver " #fn ",__vdso_" #symbol "@ZINNIA_" ver)
extern const volatile struct vdso_kernel_data vdso_data; extern const volatile struct vdso_kernel_data vdso_data;
+2 -2
View File
@@ -21,8 +21,8 @@ struct page {
static_assert(0x1000 % sizeof(struct page) == 0, "struct must fit cleanly inside a page!"); static_assert(0x1000 % sizeof(struct page) == 0, "struct must fit cleanly inside a page!");
static_assert(sizeof(struct page) <= 64, "struct must be smaller than 64 bytes!"); static_assert(sizeof(struct page) <= 64, "struct must be smaller than 64 bytes!");
void* vm_alloc(size_t length); uintptr_t vm_alloc(size_t length);
void vm_free(void* addr, size_t length); void vm_free(uintptr_t addr, size_t length);
// Base address of the `struct page` array. // Base address of the `struct page` array.
extern struct page* vm_pfndb; extern struct page* vm_pfndb;
+1 -1
View File
@@ -1,4 +1,4 @@
ENTRY(_start) ENTRY(arch_start)
PHDRS { PHDRS {
text PT_LOAD FLAGS(5); text PT_LOAD FLAGS(5);
+5 -2
View File
@@ -2,6 +2,7 @@
#include <common/utils.h> #include <common/utils.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/init.h> #include <kernel/init.h>
#include <kernel/panic.h> #include <kernel/panic.h>
#include <kernel/print.h> #include <kernel/print.h>
@@ -141,7 +142,7 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_
const size_t num_pages = (map[i].length + pgsz - 1) / pgsz; const size_t num_pages = (map[i].length + pgsz - 1) / pgsz;
const size_t metadata_size = num_pages * sizeof(struct page); const size_t metadata_size = num_pages * sizeof(struct page);
const uintptr_t metadata_start_vaddr = arch_vm_pfndb_addr() + (map[i].address / pgsz * sizeof(struct page)); const uintptr_t metadata_start_vaddr = arch_mem_pfndb_addr() + (map[i].address / pgsz * sizeof(struct page));
const uintptr_t metadata_end_vaddr = metadata_start_vaddr + metadata_size; const uintptr_t metadata_end_vaddr = metadata_start_vaddr + metadata_size;
// Find the page-aligned boundaries that contain this metadata. // Find the page-aligned boundaries that contain this metadata.
@@ -156,7 +157,7 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_
pmap_map(&kernel_vas.pmap, vaddr + page, paddr, PTE_READ | PTE_WRITE, CACHE_NONE); pmap_map(&kernel_vas.pmap, vaddr + page, paddr, PTE_READ | PTE_WRITE, CACHE_NONE);
} }
} }
vm_pfndb = (struct page*)arch_vm_pfndb_addr(); vm_pfndb = (struct page*)arch_mem_pfndb_addr();
// We don't need the bootstrap allocator from this point on. // We don't need the bootstrap allocator from this point on.
// Initialize the real page allocator. // Initialize the real page allocator.
@@ -164,5 +165,7 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_
slab_init(); slab_init();
// TODO: Free `__init` memory.
kprintf("Memory initialization complete\n"); kprintf("Memory initialization complete\n");
} }
-1
View File
@@ -1,6 +1,5 @@
kernel_sources += files( kernel_sources += files(
'init.c', 'init.c',
'mmio.c',
'pmap.c', 'pmap.c',
'pmm.c', 'pmm.c',
'slab.c', 'slab.c',
-24
View File
@@ -1,24 +0,0 @@
// SPDX-License-Identifier: MIT
#include <kernel/mmio.h>
#include <kernel/pmap.h>
#include <kernel/vas.h>
#include <kernel/virt.h>
#include <bits/mem.h>
void* mmio_new(phys_t addr, size_t length) {
void* ptr = vm_alloc(length);
for (size_t i = 0; i < length; i += arch_mem_page_size()) {
if (pmap_map(&kernel_vas.pmap, (uintptr_t)ptr + i, addr + i, PTE_READ | PTE_WRITE, CACHE_MMIO)) {
vm_free(ptr, length);
return nullptr;
}
}
return ptr;
}
void mmio_free(void* ptr, size_t length) {
// TODO
}
+1
View File
@@ -2,6 +2,7 @@
#include <zinnia/status.h> #include <zinnia/status.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/pmap.h> #include <kernel/pmap.h>
#include <kernel/spin.h> #include <kernel/spin.h>
#include <kernel/vas.h> #include <kernel/vas.h>
+1
View File
@@ -2,6 +2,7 @@
#include <common/compiler.h> #include <common/compiler.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/panic.h> #include <kernel/panic.h>
#include <kernel/print.h> #include <kernel/print.h>
#include <kernel/spin.h> #include <kernel/spin.h>
+1
View File
@@ -3,6 +3,7 @@
#include <zinnia/status.h> #include <zinnia/status.h>
#include <common/compiler.h> #include <common/compiler.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/spin.h> #include <kernel/spin.h>
#include <string.h> #include <string.h>
+1 -5
View File
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
#include <kernel/bits/usercopy.h> #include <kernel/arch.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
#include <kernel/usercopy.h> #include <kernel/usercopy.h>
@@ -11,7 +11,3 @@ bool usercopy_read(void* dst, const __user void* src, size_t len) {
bool usercopy_write(__user void* dst, const void* src, size_t len) { bool usercopy_write(__user void* dst, const void* src, size_t len) {
return arch_usercopy_write(dst, src, len, &percpu_get()->sched.current->usercopy_region); return arch_usercopy_write(dst, src, len, &percpu_get()->sched.current->usercopy_region);
} }
bool usercopy_strlen(const __user char* str, size_t max, size_t* len) {
return arch_usercopy_strlen(str, max, len, &percpu_get()->sched.current->usercopy_region);
}
+1
View File
@@ -3,6 +3,7 @@
#include <zinnia/status.h> #include <zinnia/status.h>
#include <common/utils.h> #include <common/utils.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/vas.h> #include <kernel/vas.h>
#include <assert.h> #include <assert.h>
+8 -3
View File
@@ -2,6 +2,7 @@
#include <common/utils.h> #include <common/utils.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/virt.h> #include <kernel/virt.h>
#include <stdatomic.h> #include <stdatomic.h>
#include <stddef.h> #include <stddef.h>
@@ -12,17 +13,21 @@ struct page* vm_pfndb = nullptr;
static size_t mapping_offset = 0; static size_t mapping_offset = 0;
void* vm_alloc(size_t length) { uintptr_t vm_alloc(size_t length) {
uintptr_t base = arch_mem_mapping_addr(); uintptr_t base = arch_mem_mapping_addr();
size_t offset = atomic_fetch_add(&mapping_offset, ALIGN_UP(length, arch_mem_page_size())); size_t offset = atomic_fetch_add(&mapping_offset, ALIGN_UP(length, arch_mem_page_size()));
return (void*)(base + offset); return (base + offset);
} }
void vm_free(void* ptr, size_t length) { void vm_free(uintptr_t ptr, size_t length) {
// TODO // TODO
} }
uintptr_t vm_page_addr(struct page* page) { uintptr_t vm_page_addr(struct page* page) {
return (((uintptr_t)page - (uintptr_t)vm_pfndb) / sizeof(struct page)) * arch_mem_page_size(); return (((uintptr_t)page - (uintptr_t)vm_pfndb) / sizeof(struct page)) * arch_mem_page_size();
} }
size_t mem_high_shift() {
return arch_mem_level_bits() * arch_mem_num_levels() + arch_mem_page_bits();
}
+1
View File
@@ -3,6 +3,7 @@
#include <zinnia/status.h> #include <zinnia/status.h>
#include <common/utils.h> #include <common/utils.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/list.h> #include <kernel/list.h>
#include <kernel/virt.h> #include <kernel/virt.h>
#include <kernel/vmo.h> #include <kernel/vmo.h>
+1
View File
@@ -2,6 +2,7 @@
#include <zinnia/status.h> #include <zinnia/status.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/clock.h> #include <kernel/clock.h>
#include <kernel/console.h> #include <kernel/console.h>
#include <kernel/syscalls.h> #include <kernel/syscalls.h>
+1 -1
View File
@@ -101,7 +101,7 @@ zn_status_t syscall_thread_start(struct arch_context* ctx) {
// Re-initialize the task's arch context to enter user mode via sched_to_user_arg. // Re-initialize the task's arch context to enter user mode via sched_to_user_arg.
status = status =
arch_task_init(&task->context, sched_to_user, (uintptr_t)info, task->kernel_stack + KERNEL_STACK_SIZE, true); arch_task_init(&task->task_ctx, sched_to_user, (uintptr_t)info, task->kernel_stack + KERNEL_STACK_SIZE, true);
if (status != ZN_OK) { if (status != ZN_OK) {
mem_free(info); mem_free(info);
return status; return status;
+1
View File
@@ -4,6 +4,7 @@
#include <zinnia/status.h> #include <zinnia/status.h>
#include <common/utils.h> #include <common/utils.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/arch.h>
#include <kernel/namespace.h> #include <kernel/namespace.h>
#include <kernel/percpu.h> #include <kernel/percpu.h>
#include <kernel/print.h> #include <kernel/print.h>