cleanup
This commit is contained in:
+17
-4
@@ -1,19 +1,32 @@
|
|||||||
#include <zinnia/errno.h>
|
#include <zinnia/errno.h>
|
||||||
|
#include <zinnia/syscall.h>
|
||||||
#include <arch/archctl.h>
|
#include <arch/archctl.h>
|
||||||
|
#include <arch/mem.h>
|
||||||
#include <uapi/archctl.h>
|
#include <uapi/archctl.h>
|
||||||
#include <x86_64/asm.h>
|
#include <x86_64/asm.h>
|
||||||
#include <x86_64/defs.h>
|
#include <x86_64/defs.h>
|
||||||
|
|
||||||
errno_t arch_archctl(uintptr_t op, uintptr_t arg) {
|
struct syscall_ret arch_archctl(uintptr_t op, uintptr_t arg) {
|
||||||
|
struct syscall_ret ret = {};
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case __ARCHCTL_SET_FSBASE:
|
case __ARCHCTL_SET_FSBASE:
|
||||||
|
if (!arch_mem_addr_is_user(arg)) {
|
||||||
|
ret.errno = EINVAL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
asm_wrmsr(MSR_FS_BASE, arg);
|
asm_wrmsr(MSR_FS_BASE, arg);
|
||||||
return 0;
|
return ret;
|
||||||
case __ARCHCTL_SET_GSBASE:
|
case __ARCHCTL_SET_GSBASE:
|
||||||
|
if (!arch_mem_addr_is_user(arg)) {
|
||||||
|
ret.errno = EINVAL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
// Update the inactive GSBASE MSR, not ours.
|
// Update the inactive GSBASE MSR, not ours.
|
||||||
asm_wrmsr(MSR_KERNEL_GS_BASE, arg);
|
asm_wrmsr(MSR_KERNEL_GS_BASE, arg);
|
||||||
return 0;
|
return ret;
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
ret.errno = EINVAL;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -4,10 +4,11 @@
|
|||||||
#include <x86_64/asm.h>
|
#include <x86_64/asm.h>
|
||||||
#include <x86_64/defs.h>
|
#include <x86_64/defs.h>
|
||||||
#include <x86_64/gdt.h>
|
#include <x86_64/gdt.h>
|
||||||
|
#include <x86_64/percpu.h>
|
||||||
#include <x86_64/tss.h>
|
#include <x86_64/tss.h>
|
||||||
|
|
||||||
static const struct gdt main_gdt = {
|
static const struct gdt main_gdt = {
|
||||||
.null = {.val = 0},
|
.null = {0},
|
||||||
.kernel_code32 = {.val = 0x00cf9b000000ffff},
|
.kernel_code32 = {.val = 0x00cf9b000000ffff},
|
||||||
.kernel_data32 = {.val = 0x00cf93000000ffff},
|
.kernel_data32 = {.val = 0x00cf93000000ffff},
|
||||||
.kernel_code64 = {.val = 0x00a09b0000000000},
|
.kernel_code64 = {.val = 0x00a09b0000000000},
|
||||||
@@ -24,10 +25,10 @@ static const struct gdt main_gdt = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void gdt_load() {
|
void gdt_load() {
|
||||||
struct gdt* gdt = &percpu_get()->arch.gdt;
|
struct gdt* gdt = &percpu_ref(arch_data)->gdt;
|
||||||
memcpy(gdt, &main_gdt, sizeof(main_gdt));
|
memcpy(gdt, &main_gdt, sizeof(main_gdt));
|
||||||
|
|
||||||
struct tss* tss = &percpu_get()->arch.tss;
|
struct tss* tss = &percpu_ref(arch_data)->tss;
|
||||||
tss->iopb = sizeof(struct tss);
|
tss->iopb = sizeof(struct tss);
|
||||||
|
|
||||||
uintptr_t tss_addr = (uintptr_t)tss;
|
uintptr_t tss_addr = (uintptr_t)tss;
|
||||||
|
|||||||
+4
-2
@@ -12,6 +12,7 @@
|
|||||||
#include <x86_64/apic.h>
|
#include <x86_64/apic.h>
|
||||||
#include <x86_64/defs.h>
|
#include <x86_64/defs.h>
|
||||||
#include <x86_64/gdt.h>
|
#include <x86_64/gdt.h>
|
||||||
|
#include <x86_64/percpu.h>
|
||||||
|
|
||||||
struct [[__packed]] idt_entry {
|
struct [[__packed]] idt_entry {
|
||||||
uint16_t base0;
|
uint16_t base0;
|
||||||
@@ -34,6 +35,7 @@ static_assert(sizeof(struct idtr) == 10);
|
|||||||
|
|
||||||
void interrupt_handler(struct arch_context* ctx) {
|
void interrupt_handler(struct arch_context* ctx) {
|
||||||
struct percpu* cpu = percpu_get();
|
struct percpu* cpu = percpu_get();
|
||||||
|
struct arch_percpu* arch_cpu = percpu_ref(arch_data);
|
||||||
bool old = irq_set_interrupted(true);
|
bool old = irq_set_interrupted(true);
|
||||||
|
|
||||||
uint64_t isr = ctx->isr;
|
uint64_t isr = ctx->isr;
|
||||||
@@ -46,12 +48,12 @@ void interrupt_handler(struct arch_context* ctx) {
|
|||||||
case IDT_IPI_RESCHED:
|
case IDT_IPI_RESCHED:
|
||||||
arch_sched_preempt_disable();
|
arch_sched_preempt_disable();
|
||||||
if (arch_sched_preempt_enable()) {
|
if (arch_sched_preempt_enable()) {
|
||||||
lapic_eoi(&cpu->arch.lapic);
|
lapic_eoi(&arch_cpu->lapic);
|
||||||
sched_reschedule(&cpu->sched);
|
sched_reschedule(&cpu->sched);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
struct irq_line* line = cpu->arch.irq_lines[isr - 0x20];
|
struct irq_line* line = arch_cpu->irq_lines[isr - 0x20];
|
||||||
assert(line, "Unhandled interrupt on ISR %lu\n", isr);
|
assert(line, "Unhandled interrupt on ISR %lu\n", isr);
|
||||||
// TODO: irq_raise(line);
|
// TODO: irq_raise(line);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,3 +16,5 @@ struct arch_percpu {
|
|||||||
void (*fpu_restore)(const void*);
|
void (*fpu_restore)(const void*);
|
||||||
bool can_smap;
|
bool can_smap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct arch_percpu arch_data;
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <zinnia/types.h>
|
#include <zinnia/types.h>
|
||||||
|
#include <arch/mem.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@@ -29,3 +30,7 @@ uintptr_t arch_mem_pfndb_addr() {
|
|||||||
uintptr_t arch_mem_mapping_addr() {
|
uintptr_t arch_mem_mapping_addr() {
|
||||||
return 0xFFFF'C000'0000'0000;
|
return 0xFFFF'C000'0000'0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool arch_mem_addr_is_user(uintptr_t addr) {
|
||||||
|
return addr < 0x0000'8000'0000'0000;
|
||||||
|
}
|
||||||
|
|||||||
+16
-10
@@ -8,6 +8,7 @@
|
|||||||
#include <x86_64/gdt.h>
|
#include <x86_64/gdt.h>
|
||||||
#include <x86_64/hpet.h>
|
#include <x86_64/hpet.h>
|
||||||
#include <x86_64/idt.h>
|
#include <x86_64/idt.h>
|
||||||
|
#include <x86_64/percpu.h>
|
||||||
#include <x86_64/syscall.h>
|
#include <x86_64/syscall.h>
|
||||||
#include <x86_64/tsc.h>
|
#include <x86_64/tsc.h>
|
||||||
|
|
||||||
@@ -39,11 +40,16 @@ union ia32_star {
|
|||||||
|
|
||||||
static_assert(sizeof(union ia32_star) == 8);
|
static_assert(sizeof(union ia32_star) == 8);
|
||||||
|
|
||||||
|
[[__percpu]]
|
||||||
|
struct arch_percpu arch_data = {0};
|
||||||
|
|
||||||
static void setup_cpu(struct percpu* cpu) {
|
static void setup_cpu(struct percpu* cpu) {
|
||||||
asm_wrmsr(MSR_KERNEL_GS_BASE, 0);
|
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);
|
||||||
|
|
||||||
|
struct arch_percpu* arch_cpu = percpu_ref(arch_data);
|
||||||
|
|
||||||
gdt_load();
|
gdt_load();
|
||||||
|
|
||||||
// TODO: not if FRED
|
// TODO: not if FRED
|
||||||
@@ -88,13 +94,13 @@ static void setup_cpu(struct percpu* cpu) {
|
|||||||
|
|
||||||
asm_wrxcr(0, xcr0);
|
asm_wrxcr(0, xcr0);
|
||||||
|
|
||||||
cpu->arch.fpu_size = cpuid13.ecx;
|
arch_cpu->fpu_size = cpuid13.ecx;
|
||||||
cpu->arch.fpu_save = asm_xsave;
|
arch_cpu->fpu_save = asm_xsave;
|
||||||
cpu->arch.fpu_restore = asm_xrstor;
|
arch_cpu->fpu_restore = asm_xrstor;
|
||||||
} else {
|
} else {
|
||||||
cpu->arch.fpu_size = 512;
|
arch_cpu->fpu_size = 512;
|
||||||
cpu->arch.fpu_save = asm_fxsave;
|
arch_cpu->fpu_save = asm_fxsave;
|
||||||
cpu->arch.fpu_restore = asm_fxrstor;
|
arch_cpu->fpu_restore = asm_fxrstor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpuid7.ecx & CPUID_7C_UMIP)
|
if (cpuid7.ecx & CPUID_7C_UMIP)
|
||||||
@@ -105,16 +111,16 @@ static void setup_cpu(struct percpu* cpu) {
|
|||||||
|
|
||||||
if (cpuid7.ebx & CPUID_7B_SMAP) {
|
if (cpuid7.ebx & CPUID_7B_SMAP) {
|
||||||
cr4 |= CR4_SMAP;
|
cr4 |= CR4_SMAP;
|
||||||
cpu->arch.can_smap = true;
|
arch_cpu->can_smap = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpuid7.ebx & CPUID_7B_FSGSBASE)
|
if (cpuid7.ebx & CPUID_7B_FSGSBASE)
|
||||||
cr4 |= CR4_FSGSBASE;
|
cr4 |= CR4_FSGSBASE;
|
||||||
|
|
||||||
asm volatile("mov %0, cr0" : "=r"(cr0));
|
asm volatile("mov cr0, %0" ::"r"(cr0));
|
||||||
asm volatile("mov %0, cr4" : "=r"(cr4));
|
asm volatile("mov cr4, %0" ::"r"(cr4));
|
||||||
|
|
||||||
lapic_init(&cpu->arch.lapic);
|
lapic_init(&arch_cpu->lapic);
|
||||||
cpu->online = true;
|
cpu->online = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -13,6 +13,7 @@
|
|||||||
#include <x86_64/defs.h>
|
#include <x86_64/defs.h>
|
||||||
#include <x86_64/gdt.h>
|
#include <x86_64/gdt.h>
|
||||||
#include <x86_64/idt.h>
|
#include <x86_64/idt.h>
|
||||||
|
#include <x86_64/percpu.h>
|
||||||
|
|
||||||
// The task frame consists of registers that the C ABI marks as callee-saved.
|
// The task frame consists of registers that the C ABI marks as callee-saved.
|
||||||
// If we don't save them, these registers are lost during a context switch.
|
// If we don't save them, these registers are lost during a context switch.
|
||||||
@@ -53,7 +54,7 @@ static struct task* perform_switch(uint64_t* old_rsp, uint64_t new_rsp, struct t
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct task* arch_sched_switch(struct task* from, struct task* to) {
|
struct task* arch_sched_switch(struct task* from, struct task* to) {
|
||||||
struct arch_percpu* cpu = &percpu_get()->arch;
|
struct arch_percpu* cpu = percpu_ref(arch_data);
|
||||||
struct arch_task_context* from_ctx = &from->context;
|
struct arch_task_context* from_ctx = &from->context;
|
||||||
struct arch_task_context* to_ctx = &to->context;
|
struct arch_task_context* to_ctx = &to->context;
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ errno_t arch_task_init(
|
|||||||
uintptr_t stack_start,
|
uintptr_t stack_start,
|
||||||
bool is_user
|
bool is_user
|
||||||
) {
|
) {
|
||||||
struct arch_percpu* cpu = &percpu_get()->arch;
|
struct arch_percpu* cpu = percpu_ref(arch_data);
|
||||||
|
|
||||||
// Prepare a dummy stack with an entry point function to return to.
|
// Prepare a dummy stack with an entry point function to return to.
|
||||||
struct task_frame* frame = (struct task_frame*)stack_start - 1;
|
struct task_frame* frame = (struct task_frame*)stack_start - 1;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <bits/sched.h>
|
#include <bits/sched.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <x86_64/defs.h>
|
#include <x86_64/defs.h>
|
||||||
|
#include <x86_64/gdt.h>
|
||||||
|
|
||||||
// TODO: Refactor to only push callee-saved registers.
|
// TODO: Refactor to only push callee-saved registers.
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -1,8 +1,8 @@
|
|||||||
|
#include <zinnia/cmdline.h>
|
||||||
|
#include <zinnia/init.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <zinnia/cmdline.h>
|
|
||||||
#include <zinnia/init.h>
|
|
||||||
|
|
||||||
// Defined in linker script.
|
// Defined in linker script.
|
||||||
extern const struct cmdline_option* __ld_cmdline_start[];
|
extern const struct cmdline_option* __ld_cmdline_start[];
|
||||||
@@ -12,6 +12,9 @@ static char cmdline_buf[0x1000];
|
|||||||
|
|
||||||
[[__init]]
|
[[__init]]
|
||||||
void cmdline_parse(const char* cmdline) {
|
void cmdline_parse(const char* cmdline) {
|
||||||
|
if (cmdline == nullptr)
|
||||||
|
cmdline = "";
|
||||||
|
|
||||||
const size_t len = strnlen(cmdline, sizeof(cmdline_buf) - 1);
|
const size_t len = strnlen(cmdline, sizeof(cmdline_buf) - 1);
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
memcpy(cmdline_buf, cmdline, len);
|
memcpy(cmdline_buf, cmdline, len);
|
||||||
|
|||||||
+2
-1
@@ -82,7 +82,8 @@ SECTIONS
|
|||||||
/* Per-CPU data block. MUST always come last. */
|
/* Per-CPU data block. MUST always come last. */
|
||||||
.percpu ALIGN(CONSTANT(MAXPAGESIZE)) : {
|
.percpu ALIGN(CONSTANT(MAXPAGESIZE)) : {
|
||||||
__ld_percpu_start = .;
|
__ld_percpu_start = .;
|
||||||
KEEP(*(.percpu))
|
KEEP(*(.percpu.init .percpu.init*))
|
||||||
|
KEEP(*(.percpu.data .percpu.data*))
|
||||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||||
__ld_percpu_end = .;
|
__ld_percpu_end = .;
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -1,9 +1,9 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <zinnia/alloc.h>
|
#include <zinnia/alloc.h>
|
||||||
#include <zinnia/cmdline.h>
|
#include <zinnia/cmdline.h>
|
||||||
#include <zinnia/init.h>
|
#include <zinnia/init.h>
|
||||||
#include <zinnia/print.h>
|
#include <zinnia/print.h>
|
||||||
#include <zinnia/utils.h>
|
#include <zinnia/utils.h>
|
||||||
|
#include <string.h>
|
||||||
#include "limine.h"
|
#include "limine.h"
|
||||||
|
|
||||||
[[__initdata_sorted("limine.0")]]
|
[[__initdata_sorted("limine.0")]]
|
||||||
@@ -89,5 +89,3 @@ void kernel_entry() {
|
|||||||
|
|
||||||
kernel_main(&info);
|
kernel_main(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
phys_t rsdp_addr;
|
|
||||||
|
|||||||
+9
-1
@@ -15,6 +15,10 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if CONFIG_ACPI
|
||||||
|
#include <zinnia/acpi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char zinnia_banner[] = "Zinnia " ZINNIA_VERSION " " CONFIG_KERNEL_FLAVOR " (" ZINNIA_ARCH
|
static const char zinnia_banner[] = "Zinnia " ZINNIA_VERSION " " CONFIG_KERNEL_FLAVOR " (" ZINNIA_ARCH
|
||||||
", " ZINNIA_COMPILER_ID ", " ZINNIA_LINKER_ID ")";
|
", " ZINNIA_COMPILER_ID ", " ZINNIA_LINKER_ID ")";
|
||||||
|
|
||||||
@@ -74,10 +78,14 @@ void kernel_main(struct boot_info* info) {
|
|||||||
kprintf("\ec");
|
kprintf("\ec");
|
||||||
|
|
||||||
mem_init(info->mem_map, info->num_mem_maps, info->virt_base, info->phys_base, info->hhdm_base);
|
mem_init(info->mem_map, info->num_mem_maps, info->virt_base, info->phys_base, info->hhdm_base);
|
||||||
rsdp_addr = info->rsdp; // TODO
|
|
||||||
percpu_init();
|
percpu_init();
|
||||||
sched_init(&percpu_get()->sched);
|
sched_init(&percpu_get()->sched);
|
||||||
|
|
||||||
|
#if CONFIG_ACPI
|
||||||
|
acpi_init(info);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct task* main_task;
|
struct task* main_task;
|
||||||
task_create("main", &kernel_vma, kernel_main_task, (uintptr_t)info, &main_task);
|
task_create("main", &kernel_vma, kernel_main_task, (uintptr_t)info, &main_task);
|
||||||
sched_add_task(&percpu_get()->sched, main_task);
|
sched_add_task(&percpu_get()->sched, main_task);
|
||||||
|
|||||||
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
|
#include <zinnia/compiler.h>
|
||||||
|
#include <zinnia/utils.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <zinnia/compiler.h>
|
|
||||||
#include <zinnia/utils.h>
|
|
||||||
|
|
||||||
[[__hot]]
|
[[__hot]]
|
||||||
size_t strlen(const char* str) {
|
size_t strlen(const char* str) {
|
||||||
@@ -25,8 +25,8 @@ size_t strnlen(const char* str, size_t len) {
|
|||||||
[[__hot]]
|
[[__hot]]
|
||||||
int memcmp(const void* s1, const void* s2, size_t size) {
|
int memcmp(const void* s1, const void* s2, size_t size) {
|
||||||
int diff = 0;
|
int diff = 0;
|
||||||
char* s1ptr = (char*)s1;
|
const uint8_t* s1ptr = s1;
|
||||||
char* s2ptr = (char*)s2;
|
const uint8_t* s2ptr = s2;
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
if (s1ptr[i] != s2ptr[i])
|
if (s1ptr[i] != s2ptr[i])
|
||||||
|
|||||||
@@ -13,4 +13,3 @@ kernel_sources += files(
|
|||||||
subdir('lib')
|
subdir('lib')
|
||||||
subdir('mem')
|
subdir('mem')
|
||||||
subdir('sched')
|
subdir('sched')
|
||||||
subdir('syscalls')
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
#include <zinnia/percpu.h>
|
#include <zinnia/percpu.h>
|
||||||
#include <arch/percpu.h>
|
#include <arch/percpu.h>
|
||||||
|
|
||||||
[[__percpu]]
|
[[__used, __section(".percpu.init")]]
|
||||||
struct percpu percpu_bsp = {
|
struct percpu percpu_bsp = {
|
||||||
.self = &percpu_bsp,
|
.self = &percpu_bsp,
|
||||||
.id = 0,
|
.id = 0,
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
#include <zinnia/syscall.h>
|
|
||||||
#include <arch/archctl.h>
|
|
||||||
|
|
||||||
void sys_archctl(struct arch_context* ctx) {
|
|
||||||
ctx->ARCH_CTX_RET0 = arch_archctl(ctx->ARCH_CTX_A0, ctx->ARCH_CTX_A1);
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#include <zinnia/spin.h>
|
|
||||||
#include <zinnia/syscall.h>
|
|
||||||
#include <zinnia/usercopy.h>
|
|
||||||
#include <config.h>
|
|
||||||
#include <uapi/utsname.h>
|
|
||||||
|
|
||||||
static struct spinlock uname_lock = {};
|
|
||||||
|
|
||||||
static struct utsname uname_buf = {
|
|
||||||
.sysname = "Zinnia",
|
|
||||||
.release = ZINNIA_VERSION,
|
|
||||||
.version = CONFIG_KERNEL_FLAVOR,
|
|
||||||
.nodename = "localhost",
|
|
||||||
.machine = ZINNIA_ARCH,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct syscall_ret sys_getuname(__user struct utsname* ptr) {
|
|
||||||
struct syscall_ret ret = {};
|
|
||||||
|
|
||||||
if (!ptr) {
|
|
||||||
ret.errno = EINVAL;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock(&uname_lock);
|
|
||||||
|
|
||||||
if (!usercopy_write(ptr, &uname_buf, sizeof(uname_buf)))
|
|
||||||
ret.errno = EFAULT;
|
|
||||||
|
|
||||||
spin_unlock(&uname_lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <zinnia/init.h>
|
||||||
|
#include <zinnia/types.h>
|
||||||
|
|
||||||
|
void acpi_init(struct boot_info* info);
|
||||||
|
|
||||||
|
extern phys_t acpi_rsdp_addr;
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#include <zinnia/acpi.h>
|
||||||
|
#include <zinnia/print.h>
|
||||||
|
#include <zinnia/types.h>
|
||||||
|
|
||||||
|
phys_t acpi_rsdp_addr = 0;
|
||||||
|
|
||||||
|
void acpi_init(struct boot_info* info) {
|
||||||
|
if (!info->rsdp) {
|
||||||
|
log("acpi: No RSDP was passed, unable to start ACPI subsystem!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
acpi_rsdp_addr = info->rsdp;
|
||||||
|
}
|
||||||
+10
-9
@@ -1,15 +1,16 @@
|
|||||||
uacpi = subproject('uacpi')
|
uacpi = subproject('uacpi')
|
||||||
|
|
||||||
kernel_sources += uacpi.get_variable('sources')
|
kernel_sources += uacpi.get_variable('sources')
|
||||||
kernel_includes += uacpi.get_variable('includes')
|
|
||||||
kernel_c_args += [
|
|
||||||
'-DUACPI_FORMATTED_LOGGING',
|
|
||||||
'-DUACPI_BAREBONES_MODE', # TODO
|
|
||||||
'-DUACPI_OVERRIDE_TYPES',
|
|
||||||
]
|
|
||||||
# For uacpi_types.h
|
|
||||||
kernel_includes += include_directories('include')
|
|
||||||
|
|
||||||
kernel_sources += files(
|
kernel_sources += files(
|
||||||
|
'init.c',
|
||||||
'uacpi_glue.c',
|
'uacpi_glue.c',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
kernel_includes += uacpi.get_variable('includes')
|
||||||
|
kernel_includes += include_directories('include')
|
||||||
|
|
||||||
|
kernel_c_args += [
|
||||||
|
'-DUACPI_FORMATTED_LOGGING',
|
||||||
|
'-DUACPI_BAREBONES_MODE', # TODO: Remove
|
||||||
|
'-DUACPI_OVERRIDE_TYPES',
|
||||||
|
]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <zinnia/acpi.h>
|
||||||
#include <zinnia/console.h>
|
#include <zinnia/console.h>
|
||||||
#include <zinnia/init.h>
|
#include <zinnia/init.h>
|
||||||
#include <zinnia/mmio.h>
|
#include <zinnia/mmio.h>
|
||||||
@@ -6,17 +7,22 @@
|
|||||||
#include <zinnia/utils.h>
|
#include <zinnia/utils.h>
|
||||||
#include <zinnia/virt.h>
|
#include <zinnia/virt.h>
|
||||||
#include <zinnia/vma.h>
|
#include <zinnia/vma.h>
|
||||||
|
#include <arch/mem.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>
|
||||||
#include <uacpi/types.h>
|
#include <uacpi/types.h>
|
||||||
|
|
||||||
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr* out_rsdp_address) {
|
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr* out_rsdp_address) {
|
||||||
*out_rsdp_address = (uacpi_phys_addr)rsdp_addr;
|
*out_rsdp_address = (uacpi_phys_addr)acpi_rsdp_addr;
|
||||||
return UACPI_STATUS_OK;
|
return UACPI_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) {
|
void* uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) {
|
||||||
|
uintptr_t aligned_addr = ALIGN_DOWN(addr, arch_mem_page_size());
|
||||||
|
uintptr_t difference = addr - aligned_addr;
|
||||||
|
size_t aligned_len = ALIGN_UP(len + difference, arch_mem_page_size());
|
||||||
|
|
||||||
uintptr_t vaddr = vm_alloc(len);
|
uintptr_t vaddr = vm_alloc(len);
|
||||||
for (size_t i = 0; i < len; i += arch_mem_page_size()) {
|
for (size_t i = 0; i < len; i += arch_mem_page_size()) {
|
||||||
pmap_map(&kernel_vma.pmap, vaddr + i, addr + i, PROT_READ | PROT_WRITE, CACHE_ANY);
|
pmap_map(&kernel_vma.pmap, vaddr + i, addr + i, PROT_READ | PROT_WRITE, CACHE_ANY);
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
#include <zinnia/errno.h>
|
#include <zinnia/errno.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
errno_t arch_archctl(uintptr_t op, uintptr_t value);
|
struct syscall_ret arch_archctl(uintptr_t op, uintptr_t value);
|
||||||
|
|||||||
@@ -3,10 +3,26 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
[[gnu::pure]]
|
||||||
|
bool arch_mem_addr_is_user(uintptr_t addr);
|
||||||
|
|
||||||
|
[[gnu::pure]]
|
||||||
size_t arch_mem_page_size();
|
size_t arch_mem_page_size();
|
||||||
|
|
||||||
|
[[gnu::pure]]
|
||||||
size_t arch_mem_page_bits();
|
size_t arch_mem_page_bits();
|
||||||
|
|
||||||
|
[[gnu::pure]]
|
||||||
size_t arch_mem_level_bits();
|
size_t arch_mem_level_bits();
|
||||||
|
|
||||||
|
[[gnu::pure]]
|
||||||
size_t arch_mem_num_levels();
|
size_t arch_mem_num_levels();
|
||||||
|
|
||||||
|
[[gnu::pure]]
|
||||||
uintptr_t arch_mem_hhdm_addr();
|
uintptr_t arch_mem_hhdm_addr();
|
||||||
|
|
||||||
|
[[gnu::pure]]
|
||||||
uintptr_t arch_mem_pfndb_addr();
|
uintptr_t arch_mem_pfndb_addr();
|
||||||
|
|
||||||
|
[[gnu::pure]]
|
||||||
uintptr_t arch_mem_mapping_addr();
|
uintptr_t arch_mem_mapping_addr();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#ifndef __ZINNIA_UAPI_UTSNAME_H
|
#ifndef __ZINNIA_UAPI_UTSNAME_H
|
||||||
#define __ZINNIA_UAPI_UTSNAME_H
|
#define __ZINNIA_UAPI_UTSNAME_H
|
||||||
|
|
||||||
struct utsname {
|
struct __utsname {
|
||||||
char sysname[65];
|
char sysname[65];
|
||||||
char nodename[65];
|
char nodename[65];
|
||||||
char release[65];
|
char release[65];
|
||||||
|
|||||||
+5
-14
@@ -9,22 +9,13 @@ typedef enum memory_order {
|
|||||||
ATOMIC_SEQ_CST = __ATOMIC_SEQ_CST
|
ATOMIC_SEQ_CST = __ATOMIC_SEQ_CST
|
||||||
} memory_order;
|
} memory_order;
|
||||||
|
|
||||||
#define atomic(T) _Atomic(T)
|
#define atomic(T) _Atomic(T)
|
||||||
|
#define atomic_store(ptr, des, order) __atomic_store_n(ptr, des, order)
|
||||||
#define atomic_store(ptr, des, order) __atomic_store_n(ptr, des, order)
|
#define atomic_load(ptr, order) __atomic_load_n(ptr, order)
|
||||||
|
|
||||||
#define atomic_load(ptr, order) __atomic_load_n(ptr, order)
|
|
||||||
|
|
||||||
#define atomic_exchange(ptr, des, order) __atomic_exchange_n(ptr, des, order)
|
#define atomic_exchange(ptr, des, order) __atomic_exchange_n(ptr, des, order)
|
||||||
|
|
||||||
#define atomic_fetch_add(ptr, op, order) __atomic_fetch_add(ptr, op, order)
|
#define atomic_fetch_add(ptr, op, order) __atomic_fetch_add(ptr, op, order)
|
||||||
|
|
||||||
#define atomic_fetch_sub(ptr, op, order) __atomic_fetch_sub(ptr, op, order)
|
#define atomic_fetch_sub(ptr, op, order) __atomic_fetch_sub(ptr, op, order)
|
||||||
|
#define atomic_fetch_or(ptr, op, order) __atomic_fetch_or(ptr, op, order)
|
||||||
#define atomic_fetch_or(ptr, op, order) __atomic_fetch_or(ptr, op, order)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor(ptr, op, order) __atomic_fetch_xor(ptr, op, order)
|
#define atomic_fetch_xor(ptr, op, order) __atomic_fetch_xor(ptr, op, order)
|
||||||
|
|
||||||
#define atomic_fetch_and(ptr, op, order) __atomic_fetch_and(ptr, op, order)
|
#define atomic_fetch_and(ptr, op, order) __atomic_fetch_and(ptr, op, order)
|
||||||
|
#define atomic_thread_fence(order) __atomic_thread_fence(order)
|
||||||
#define atomic_thread_fence(order) __atomic_thread_fence(order)
|
|
||||||
|
|||||||
@@ -12,13 +12,11 @@
|
|||||||
#define __used gnu::used
|
#define __used gnu::used
|
||||||
#define __unused gnu::unused
|
#define __unused gnu::unused
|
||||||
#define __format(like, ...) gnu::format(like, __VA_ARGS__)
|
#define __format(like, ...) gnu::format(like, __VA_ARGS__)
|
||||||
#define __likely(x) __builtin_expect(!!(x), 1)
|
|
||||||
#define __unlikely(x) __builtin_expect(!!(x), 0)
|
|
||||||
#define __always_inline gnu::always_inline
|
#define __always_inline gnu::always_inline
|
||||||
#define __visibility gnu::visibility
|
#define __visibility gnu::visibility
|
||||||
|
|
||||||
// Only clang has these hints, GCC will throw a warning here.
|
// Only clang has these hints, GCC would throw a warning here.
|
||||||
// They also don't support the C23 attribute format.
|
// clang::noderef also don't support the C23 attribute format.
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#define __user __attribute__((noderef, address_space(1)))
|
#define __user __attribute__((noderef, address_space(1)))
|
||||||
#define __phys __attribute__((noderef, address_space(2)))
|
#define __phys __attribute__((noderef, address_space(2)))
|
||||||
@@ -26,3 +24,6 @@
|
|||||||
#define __user
|
#define __user
|
||||||
#define __phys
|
#define __phys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define __likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#define __unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <zinnia/compiler.h>
|
#include <zinnia/compiler.h>
|
||||||
#include <zinnia/types.h>
|
#include <zinnia/types.h>
|
||||||
#include <zinnia/utils.h>
|
#include <zinnia/utils.h>
|
||||||
|
#include <config.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@@ -25,16 +26,21 @@ struct boot_info {
|
|||||||
uintptr_t hhdm_base;
|
uintptr_t hhdm_base;
|
||||||
struct boot_file* files;
|
struct boot_file* files;
|
||||||
size_t num_files;
|
size_t num_files;
|
||||||
|
#if CONFIG_OF
|
||||||
|
void* dtb;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_ACPI
|
||||||
phys_t rsdp;
|
phys_t rsdp;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct boot_info boot_info;
|
||||||
|
|
||||||
[[__visibility("hidden")]]
|
[[__visibility("hidden")]]
|
||||||
extern uint8_t __ld_stack_top[];
|
extern uint8_t __ld_stack_top[];
|
||||||
[[__visibility("hidden")]]
|
[[__visibility("hidden")]]
|
||||||
extern uint8_t __ld_stack_bottom[];
|
extern uint8_t __ld_stack_bottom[];
|
||||||
|
|
||||||
extern phys_t rsdp_addr;
|
|
||||||
|
|
||||||
// Entry point for the kernel after arch-specific setup has finished.
|
// Entry point for the kernel after arch-specific setup has finished.
|
||||||
void kernel_entry();
|
void kernel_entry();
|
||||||
|
|
||||||
|
|||||||
+24
-28
@@ -4,41 +4,37 @@
|
|||||||
#include <zinnia/irq.h>
|
#include <zinnia/irq.h>
|
||||||
#include <zinnia/sched.h>
|
#include <zinnia/sched.h>
|
||||||
#include <zinnia/usercopy.h>
|
#include <zinnia/usercopy.h>
|
||||||
#include <bits/percpu.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
ASSERT_TYPE(struct arch_percpu); // bits/percpu.h
|
// # On using per-CPU data
|
||||||
|
//
|
||||||
|
// Defining variables with `[[__percpu]]` will put them in a special section.
|
||||||
|
// This section is unique for every CPU. To access the correct memory of the
|
||||||
|
// caller's CPU, use `percpu_ref`.
|
||||||
|
//
|
||||||
|
// ## Example
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// [[__percpu]]
|
||||||
|
// int my_cpu_data = 0;
|
||||||
|
//
|
||||||
|
// int get_foo() {
|
||||||
|
// return *percpu_ref(my_cpu_data);
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
|
||||||
/*
|
#define __percpu __used, __section(".percpu.data")
|
||||||
On using per-CPU data
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Defining variables with `[[__percpu]]` will put them in a special section.
|
|
||||||
This section is unique for every CPU. To access the correct memory of the
|
|
||||||
caller's CPU, use `percpu_ref`.
|
|
||||||
|
|
||||||
# Example
|
|
||||||
|
|
||||||
[[__percpu]]
|
|
||||||
int my_cpu_data = 0;
|
|
||||||
int get_foo() {
|
|
||||||
return *percpu_ref(my_cpu_data);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __percpu __used, __section(".percpu")
|
|
||||||
#define percpu_ref(x) ((typeof(&(x)))((void*)percpu_get() + ((void*)&(x) - (void*)&percpu_bsp)))
|
#define percpu_ref(x) ((typeof(&(x)))((void*)percpu_get() + ((void*)&(x) - (void*)&percpu_bsp)))
|
||||||
|
|
||||||
// CPU-relative information.
|
// CPU-relative information.
|
||||||
struct percpu {
|
struct percpu {
|
||||||
struct percpu* self; // A pointer to this structure.
|
struct percpu* self; // A pointer to this structure.
|
||||||
size_t id; // The virtual ID of this CPU.
|
size_t id; // The virtual ID of this CPU.
|
||||||
bool online; // Whether this CPU is initialized and active.
|
bool online; // Whether this CPU is initialized and active.
|
||||||
uintptr_t kernel_stack; // The kernel mode stack.
|
uintptr_t kernel_stack; // The kernel mode stack.
|
||||||
uintptr_t user_stack; // The user mode stack.
|
uintptr_t user_stack; // The user mode stack.
|
||||||
struct arch_percpu arch; // Architecture-specific fields.
|
struct irq_percpu irq; // IRQ information.
|
||||||
struct irq_percpu irq; // IRQ information.
|
struct scheduler sched; // Scheduler information.
|
||||||
struct scheduler sched; // Scheduler information.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct percpu* percpu_new();
|
struct percpu* percpu_new();
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
// SYSCALL_DECLARE(0, exit, -1)
|
// SYSCALL_DECLARE(0, exit, -1)
|
||||||
// SYSCALL_DECLARE(1, syslog, -1)
|
// SYSCALL_DECLARE(1, syslog, -1)
|
||||||
SYSCALL_DECLARE(2, getuname, -1)
|
SYSCALL_DECLARE(2, getuname, 1)
|
||||||
// SYSCALL_DECLARE(3, setuname, -1)
|
// SYSCALL_DECLARE(3, setuname, -1)
|
||||||
SYSCALL_DECLARE(4, archctl, -1)
|
SYSCALL_DECLARE(4, archctl, 2)
|
||||||
// SYSCALL_DECLARE(5, reboot, -1)
|
// SYSCALL_DECLARE(5, reboot, -1)
|
||||||
// SYSCALL_DECLARE(6, mmap, -1)
|
// SYSCALL_DECLARE(6, mmap, -1)
|
||||||
// SYSCALL_DECLARE(7, munmap, -1)
|
// SYSCALL_DECLARE(7, munmap, -1)
|
||||||
|
|||||||
+14
-14
@@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
#define tailq_link(type) \
|
#define tailq_link(type) \
|
||||||
struct { \
|
struct { \
|
||||||
type* tqe_next; \
|
type* tql_next; \
|
||||||
type** tqe_prev; \
|
type** tql_prev; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define tailq_init(head) \
|
#define tailq_init(head) \
|
||||||
@@ -20,33 +20,33 @@
|
|||||||
|
|
||||||
#define tailq_first(head) ((head)->tqh_first)
|
#define tailq_first(head) ((head)->tqh_first)
|
||||||
|
|
||||||
#define tailq_next(elm, field) ((elm)->field.tqe_next)
|
#define tailq_next(elm, field) ((elm)->field.tql_next)
|
||||||
|
|
||||||
#define tailq_empty(head) (tailq_first(head) == nullptr)
|
#define tailq_empty(head) (tailq_first(head) == nullptr)
|
||||||
|
|
||||||
#define tailq_insert_tail(head, elm, field) \
|
#define tailq_insert_tail(head, elm, field) \
|
||||||
do { \
|
do { \
|
||||||
(elm)->field.tqe_next = nullptr; \
|
(elm)->field.tql_next = nullptr; \
|
||||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
(elm)->field.tql_prev = (head)->tqh_last; \
|
||||||
*(head)->tqh_last = (elm); \
|
*(head)->tqh_last = (elm); \
|
||||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
(head)->tqh_last = &(elm)->field.tql_next; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define tailq_insert_head(head, elm, field) \
|
#define tailq_insert_head(head, elm, field) \
|
||||||
do { \
|
do { \
|
||||||
if (((elm)->field.tqe_next = (head)->tqh_first) != nullptr) \
|
if (((elm)->field.tql_next = (head)->tqh_first) != nullptr) \
|
||||||
(head)->tqh_first->field.tqe_prev = &(elm)->field.tqe_next; \
|
(head)->tqh_first->field.tql_prev = &(elm)->field.tql_next; \
|
||||||
else \
|
else \
|
||||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
(head)->tqh_last = &(elm)->field.tql_next; \
|
||||||
(head)->tqh_first = (elm); \
|
(head)->tqh_first = (elm); \
|
||||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
(elm)->field.tql_prev = &(head)->tqh_first; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define tailq_remove(head, elm, field) \
|
#define tailq_remove(head, elm, field) \
|
||||||
do { \
|
do { \
|
||||||
if (((elm)->field.tqe_next) != nullptr) \
|
if (((elm)->field.tql_next) != nullptr) \
|
||||||
(elm)->field.tqe_next->field.tqe_prev = (elm)->field.tqe_prev; \
|
(elm)->field.tql_next->field.tql_prev = (elm)->field.tql_prev; \
|
||||||
else \
|
else \
|
||||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
(head)->tqh_last = (elm)->field.tql_prev; \
|
||||||
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
*(elm)->field.tql_prev = (elm)->field.tql_next; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|||||||
+12
-7
@@ -2,7 +2,7 @@ project(
|
|||||||
'zinnia',
|
'zinnia',
|
||||||
license: 'ISC',
|
license: 'ISC',
|
||||||
version: '0.1.0',
|
version: '0.1.0',
|
||||||
meson_version: '>=1.3.0',
|
meson_version: '>=1.5.0',
|
||||||
default_options: [
|
default_options: [
|
||||||
'c_std=gnu23',
|
'c_std=gnu23',
|
||||||
'werror=true',
|
'werror=true',
|
||||||
@@ -18,7 +18,7 @@ if get_option('headers_only')
|
|||||||
subdir_done()
|
subdir_done()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
add_languages('c', native: false)
|
add_languages('c', native: false, required: true)
|
||||||
|
|
||||||
# Check if we're using a sane compiler.
|
# Check if we're using a sane compiler.
|
||||||
c_compiler = meson.get_compiler('c')
|
c_compiler = meson.get_compiler('c')
|
||||||
@@ -77,7 +77,7 @@ foreach k, v : kconfig
|
|||||||
endif
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
kernel_c_args = []
|
kernel_c_args = ['-DIN_KERNEL']
|
||||||
|
|
||||||
kernel_lds = meson.current_source_dir() / 'boot' / 'kernel.ld'
|
kernel_lds = meson.current_source_dir() / 'boot' / 'kernel.ld'
|
||||||
kernel_link_args = [
|
kernel_link_args = [
|
||||||
@@ -91,10 +91,11 @@ kernel_includes = []
|
|||||||
kernel_sources = []
|
kernel_sources = []
|
||||||
modules = {}
|
modules = {}
|
||||||
|
|
||||||
# Goes first so we can add arch-specific flags to drivers.
|
# These dirs go first so we can add arch-specific flags to drivers.
|
||||||
subdir('arch' / target_machine.cpu_family())
|
subdir('arch' / target_machine.cpu_family())
|
||||||
subdir('boot')
|
subdir('boot')
|
||||||
subdir('core')
|
subdir('core')
|
||||||
|
subdir('syscalls')
|
||||||
|
|
||||||
# Device and file system drivers.
|
# Device and file system drivers.
|
||||||
subdir('dev')
|
subdir('dev')
|
||||||
@@ -141,7 +142,11 @@ foreach name, v : modules
|
|||||||
kernel_link_args += mod_link_args
|
kernel_link_args += mod_link_args
|
||||||
endif
|
endif
|
||||||
|
|
||||||
mod_summary += {name: is_modular}
|
if is_modular
|
||||||
|
mod_summary += {name: 'mod'}
|
||||||
|
else
|
||||||
|
mod_summary += {name: 'builtin'}
|
||||||
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
# Kernel
|
# Kernel
|
||||||
@@ -151,7 +156,7 @@ executable(
|
|||||||
common_includes,
|
common_includes,
|
||||||
kernel_includes,
|
kernel_includes,
|
||||||
],
|
],
|
||||||
c_args: ['-DIN_KERNEL', kernel_c_args],
|
c_args: [kernel_c_args],
|
||||||
link_args: kernel_link_args,
|
link_args: kernel_link_args,
|
||||||
link_depends: kernel_lds,
|
link_depends: kernel_lds,
|
||||||
sources: kernel_sources,
|
sources: kernel_sources,
|
||||||
@@ -161,5 +166,5 @@ executable(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Print a summary
|
# Print a summary
|
||||||
summary(mod_summary, bool_yn: true, section: 'Driver configuration')
|
summary(mod_summary, section: 'Driver configuration')
|
||||||
summary(kconfig, bool_yn: true, section: 'Kernel configuration')
|
summary(kconfig, bool_yn: true, section: 'Kernel configuration')
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include <zinnia/syscall.h>
|
||||||
|
#include <arch/archctl.h>
|
||||||
|
|
||||||
|
struct syscall_ret sys_archctl(uintptr_t op, uintptr_t arg) {
|
||||||
|
return arch_archctl(op, arg);
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ const struct syscall syscall_table[256] = {
|
|||||||
#include <zinnia/syscall_list.inc>
|
#include <zinnia/syscall_list.inc>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: Implement this
|
||||||
[[gnu::no_caller_saved_registers]]
|
[[gnu::no_caller_saved_registers]]
|
||||||
struct syscall_ret syscall_dispatch_fast(
|
struct syscall_ret syscall_dispatch_fast(
|
||||||
uintptr_t a0,
|
uintptr_t a0,
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
kernel_sources += files(
|
kernel_sources += files(
|
||||||
'archctl.c',
|
'archctl.c',
|
||||||
'dispatch.c',
|
'dispatch.c',
|
||||||
'getuname.c',
|
'uname.c',
|
||||||
)
|
)
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#include <zinnia/spin.h>
|
||||||
|
#include <zinnia/syscall.h>
|
||||||
|
#include <zinnia/usercopy.h>
|
||||||
|
#include <config.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <uapi/utsname.h>
|
||||||
|
|
||||||
|
static struct spinlock uname_lock = {};
|
||||||
|
|
||||||
|
static struct __utsname uname_buf = {
|
||||||
|
.sysname = "Zinnia",
|
||||||
|
.release = ZINNIA_VERSION,
|
||||||
|
.version = CONFIG_KERNEL_FLAVOR,
|
||||||
|
.nodename = "localhost",
|
||||||
|
.machine = ZINNIA_ARCH,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct syscall_ret sys_setuname(__user const struct __utsname* ptr) {
|
||||||
|
struct syscall_ret ret = {};
|
||||||
|
|
||||||
|
if (!ptr) {
|
||||||
|
ret.errno = EINVAL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: User has to be root to do this.
|
||||||
|
|
||||||
|
struct __utsname read_buf;
|
||||||
|
if (!usercopy_read(&read_buf, ptr, sizeof(read_buf))) {
|
||||||
|
ret.errno = EFAULT;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&uname_lock);
|
||||||
|
|
||||||
|
strncpy(uname_buf.sysname, read_buf.sysname, sizeof(uname_buf.sysname));
|
||||||
|
strncpy(uname_buf.release, read_buf.release, sizeof(uname_buf.release));
|
||||||
|
strncpy(uname_buf.version, read_buf.version, sizeof(uname_buf.version));
|
||||||
|
strncpy(uname_buf.nodename, read_buf.nodename, sizeof(uname_buf.nodename));
|
||||||
|
strncpy(uname_buf.machine, read_buf.machine, sizeof(uname_buf.machine));
|
||||||
|
|
||||||
|
spin_unlock(&uname_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct syscall_ret sys_getuname(__user struct __utsname* ptr) {
|
||||||
|
struct syscall_ret ret = {};
|
||||||
|
|
||||||
|
if (!ptr) {
|
||||||
|
ret.errno = EINVAL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&uname_lock);
|
||||||
|
|
||||||
|
if (!usercopy_write(ptr, &uname_buf, sizeof(uname_buf)))
|
||||||
|
ret.errno = EFAULT;
|
||||||
|
|
||||||
|
spin_unlock(&uname_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user