From 59df7bdadbfd50bfaf95cde442c7380cce535254 Mon Sep 17 00:00:00 2001 From: Quinn Stephens Date: Thu, 7 Mar 2024 13:35:04 -0500 Subject: kern: sched: Refactor queue and ctx switch code Signed-off-by: Quinn Stephens Signed-off-by: Ian Moffett --- sys/kern/kern_sched.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index f61c592..266ce39 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -97,13 +97,11 @@ sched_dequeue_td(void) spinlock_acquire(&tdq_lock); - if (TAILQ_EMPTY(&td_queue)) { - goto done; + if (!TAILQ_EMPTY(&td_queue)) { + td = TAILQ_FIRST(&td_queue); + TAILQ_REMOVE(&td_queue, td, link); } - td = TAILQ_FIRST(&td_queue); - TAILQ_REMOVE(&td_queue, td, link); -done: spinlock_release(&tdq_lock); return td; } @@ -174,11 +172,9 @@ sched_context_switch(struct trapframe *tf) * If we have no threads, we should not * preempt at all. */ - if (nthread == 0) { - goto done; - } else if ((next_td = sched_dequeue_td()) == NULL) { - /* Empty */ - goto done; + if (nthread == 0 || (next_td = sched_dequeue_td()) == NULL) { + sched_oneshot(); + return; } if (state->td != NULL) { @@ -196,7 +192,7 @@ sched_context_switch(struct trapframe *tf) if (td != NULL) { sched_enqueue_td(td); } -done: + sched_oneshot(); } -- cgit v1.2.3 From 39ed0640f0e33b8a48ba82334de219e9fe4ed0e6 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 7 Mar 2024 22:47:49 -0500 Subject: kernel: sched: Add support for user threads Signed-off-by: Ian Moffett --- Makefile.in | 12 +++- sys/include/arch/amd64/frame.h | 7 ++ sys/include/sys/proc.h | 2 + sys/kern/kern_sched.c | 153 +++++++++++++++++++++++++++++++++++++---- usr.sbin/init/init | Bin 944 -> 0 bytes 5 files changed, 157 insertions(+), 17 deletions(-) delete mode 100755 usr.sbin/init/init (limited to 'sys') diff --git a/Makefile.in b/Makefile.in index daa0cf9..5e99728 100644 --- a/Makefile.in +++ b/Makefile.in @@ -69,16 +69,22 @@ override KERNEL_ASMOBJECTS = $(KERNEL_ASMFILES:.S=.S.o) override KERNEL_HEADER_DEPS = $(KERNEL_CFILES:.c=.d) .PHONY: all -all: base init lib base/usr/lib/ld.so base/boot/hyra-kernel +all: base lib userland base/usr/lib/ld.so base/boot/hyra-kernel rm -f sys/include/machine rm -rf iso_root -base/boot/init: usr.sbin/init/ +base/usr/sbin/init: cd usr.sbin/; make CC=$(CC) LD=$(LD) - cp usr.sbin/init/init base/boot/ + mv usr.sbin/init/init base/usr/sbin/ + +# TODO: Make this more flexible +.PHONY: userland +userland: base/usr/sbin/init base: mkdir -p base/usr/lib/ + mkdir -p base/usr/sbin/ + mkdir -p base/boot/ lib: lib/mlibc base/usr/lib/ld.so diff --git a/sys/include/arch/amd64/frame.h b/sys/include/arch/amd64/frame.h index a2e1a05..298a836 100644 --- a/sys/include/arch/amd64/frame.h +++ b/sys/include/arch/amd64/frame.h @@ -67,5 +67,12 @@ struct trapframe { (FRAME)->rsp = SP; \ (FRAME)->ss = 0x10; \ +#define init_frame_user(FRAME, IP, SP) \ + (FRAME)->rip = IP; \ + (FRAME)->cs = 0x18 | 3; \ + (FRAME)->rflags = 0x202; \ + (FRAME)->rsp = SP; \ + (FRAME)->ss = 0x20 | 3; \ + #endif /* !defined(__ASSEMBLER__) */ #endif /* !_AMD64_FRAME_H_ */ diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index f45e4c6..0d3b45e 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -34,6 +34,7 @@ #include #include #include +#include /* * A task running on the CPU e.g., a process or @@ -43,6 +44,7 @@ struct proc { pid_t pid; struct cpu_info *cpu; struct trapframe *tf; + struct vas addrsp; TAILQ_ENTRY(proc) link; }; diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 266ce39..9231ea2 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -34,10 +34,20 @@ #include #include #include +#include +#include +#include #include +#include +#include +#include +#include #include #include +#define STACK_PAGES 8 +#define STACK_SIZE (STACK_PAGES*vm_get_page_size()) + /* * Thread ready queue - all threads ready to be * scheduled should be added to this queue. @@ -119,12 +129,99 @@ sched_enter(void) } } +static uintptr_t +sched_init_stack(void *stack_top, char *argvp[], char *envp[], struct auxval auxv) +{ + uintptr_t *sp = stack_top; + size_t envp_len, argv_len, len; + uintptr_t old_sp = 0; + uintptr_t ret; + + for (envp_len = 0; envp[envp_len] != NULL; ++envp_len) { + len = strlen(envp[envp_len]); + sp = (void *)((uintptr_t)sp - len - 1); + memcpy(sp, envp[envp_len], len); + } + + for (argv_len = 0; argvp[argv_len] != NULL; ++argv_len) { + len = strlen(argvp[argv_len]); + sp = (void *)((uintptr_t)sp - len - 1); + memcpy(sp, argvp[envp_len], len); + } + + sp = (uint64_t *)(((uintptr_t)sp / 16) * 16); + if (((argv_len + envp_len + 1) & 1) != 0) { + sp--; + } + + *--sp = 0; + *--sp = 0; + *--sp = auxv.at_entry; + *--sp = AT_ENTRY; + *--sp = auxv.at_phent; + *--sp = AT_PHENT; + *--sp = auxv.at_phnum; + *--sp = AT_PHNUM; + *--sp = auxv.at_phdr; + *--sp = AT_PHDR; + + old_sp = (uintptr_t)sp; + + /* End of envp */ + *--sp = 0; + sp -= envp_len; + for (int i = 0; i < envp_len; ++i) { + old_sp -= strlen(envp[i]) + 1; + sp[i] = old_sp; + } + + /* End of argvp */ + *--sp = 0; + sp -= argv_len; + for (int i = 0; i < argv_len; ++i) { + old_sp -= strlen(argvp[i]) + 1; + sp[i] = old_sp; + } + + /* Argc */ + *--sp = argv_len; + + ret = (uintptr_t)stack_top; + ret -= (ret - (uintptr_t)sp); + return ret; +} + +static uintptr_t +sched_create_stack(struct vas vas, bool user) +{ + int status; + uintptr_t user_stack; + const vm_prot_t USER_STACK_PROT = PROT_WRITE | PROT_USER; + + if (!user) { + return (uintptr_t)dynalloc(STACK_SIZE); + } + + user_stack = vm_alloc_pageframe(STACK_PAGES); + + status = vm_map_create(vas, user_stack, user_stack, USER_STACK_PROT, + STACK_SIZE); + + if (status != 0) { + return 0; + } + + memset(PHYS_TO_VIRT(user_stack), 0, STACK_SIZE); + return user_stack; +} + static struct proc * -sched_create_td(uintptr_t rip) +sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, + struct vas vas, bool is_user) { - const size_t STACK_SIZE = 0x100000; /* 1 MiB */ struct proc *td; - void *stack; + uintptr_t stack, sp; + void *stack_virt; struct trapframe *tf; tf = dynalloc(sizeof(struct trapframe)); @@ -132,29 +229,37 @@ sched_create_td(uintptr_t rip) return NULL; } - stack = dynalloc(STACK_SIZE); - if (stack == NULL) { + stack = sched_create_stack(vas, is_user); + if (stack == 0) { dynfree(tf); return NULL; } + stack_virt = (is_user) ? PHYS_TO_VIRT(stack) : (void *)stack; + td = dynalloc(sizeof(struct proc)); if (td == NULL) { + /* TODO: Free stack */ dynfree(tf); - dynfree(stack); return NULL; } memset(tf, 0, sizeof(struct trapframe)); - memset(stack, 0, STACK_SIZE); + sp = sched_init_stack((void *)((uintptr_t)stack_virt + STACK_SIZE), + argvp, envp, auxv); /* Setup process itself */ td->pid = 0; /* Don't assign PID until enqueued */ td->cpu = NULL; /* Not yet assigned a core */ td->tf = tf; + td->addrsp = vas; /* Setup trapframe */ - init_frame(tf, rip, (uintptr_t)stack + STACK_SIZE - 1); + if (!is_user) { + init_frame(tf, rip, sp); + } else { + init_frame_user(tf, rip, VIRT_TO_PHYS(sp)); + } return td; } @@ -193,20 +298,40 @@ sched_context_switch(struct trapframe *tf) sched_enqueue_td(td); } + pmap_switch_vas(vm_get_ctx(), next_td->addrsp); sched_oneshot(); } void sched_init(void) { + struct proc *init; + struct auxval auxv = {0}; + struct vas vas = pmap_create_vas(vm_get_ctx()); + const char *init_bin; + + int status; + char *ld_path; + char *argv[] = {"/boot/init", NULL}; + char *envp[] = {NULL}; + TAILQ_INIT(&td_queue); - /* - * TODO: Create init with sched_create_td() - * and enqueue with sched_enqueue_td() - */ - (void)sched_create_td; - (void)sched_enqueue_td; + if ((init_bin = initramfs_open("/boot/init")) == NULL) { + panic("Could not open /boot/init\n"); + } + + status = loader_load(vas, init_bin, &auxv, 0, &ld_path); + if (status != 0) { + panic("Could not load init\n"); + } + + init = sched_create_td((uintptr_t)auxv.at_entry, argv, envp, auxv, vas, true); + if (init == NULL) { + panic("Failed to create thread for init\n"); + } + + sched_enqueue_td(init); } /* diff --git a/usr.sbin/init/init b/usr.sbin/init/init deleted file mode 100755 index 8b83844..0000000 Binary files a/usr.sbin/init/init and /dev/null differ -- cgit v1.2.3 From 02b190f4c97758f7871d1301a68eb6a0bff2f365 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 8 Mar 2024 11:34:30 -0500 Subject: kernel: fs: Fix logic bug in initramfs code Return NULL if hdr is NULL, Before, if the file is not found, 0x200 would be returned instead of NULL. Signed-off-by: Ian Moffett --- sys/fs/initramfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c index c0eaa0c..dad3763 100644 --- a/sys/fs/initramfs.c +++ b/sys/fs/initramfs.c @@ -221,7 +221,7 @@ initramfs_open(const char *path) } hdr = initramfs_from_path((void *)initramfs, path); - return hdr_to_contents(hdr); + return (hdr == NULL) ? NULL : hdr_to_contents(hdr); } struct vfsops g_initramfs_ops = { -- cgit v1.2.3 From 2d0d7a6f61899fa7263edf63c019e53a0278928a Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sat, 9 Mar 2024 22:55:58 -0500 Subject: kernel: vm_map: Account for address misalignment Signed-off-by: Ian Moffett --- sys/vm/vm_map.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 0d27738..f65bad2 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -78,12 +78,13 @@ int vm_map_create(struct vas vas, vaddr_t va, paddr_t pa, vm_prot_t prot, size_t bytes) { size_t granule = vm_get_page_size(); + size_t misalign = va & (granule - 1); int s; struct vm_ctx *ctx = vm_get_ctx(); /* We want bytes to be aligned by the granule */ - bytes = __ALIGN_UP(bytes, granule); + bytes = __ALIGN_UP(bytes + misalign, granule); /* Align VA/PA by granule */ va = __ALIGN_DOWN(va, granule); @@ -115,10 +116,11 @@ vm_map_destroy(struct vas vas, vaddr_t va, size_t bytes) { struct vm_ctx *ctx = vm_get_ctx(); size_t granule = vm_get_page_size(); + size_t misalign = va & (granule - 1); int s; /* We want bytes to be aligned by the granule */ - bytes = __ALIGN_UP(bytes, granule); + bytes = __ALIGN_UP(bytes + misalign, granule); /* Align VA by granule */ va = __ALIGN_DOWN(va, granule); -- cgit v1.2.3 From 991f1167df58616f4275c290fd0aa14baf7861f8 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sun, 10 Mar 2024 19:55:30 -0400 Subject: kernel/amd64: trap: Add stack-segment fault ISR Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/machdep.c | 1 + sys/arch/amd64/amd64/trap.S | 10 ++++++++++ sys/arch/amd64/amd64/trap.c | 10 ++++++++-- sys/include/arch/amd64/trap.h | 2 ++ 4 files changed, 21 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 6342aab..e5fe83e 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -78,6 +78,7 @@ interrupts_init(void) idt_set_desc(0x8, IDT_TRAP_GATE_FLAGS, ISR(double_fault), 0); idt_set_desc(0xA, IDT_TRAP_GATE_FLAGS, ISR(invl_tss), 0); idt_set_desc(0xB, IDT_TRAP_GATE_FLAGS, ISR(segnp), 0); + idt_set_desc(0xC, IDT_TRAP_GATE_FLAGS, ISR(ss_fault), 0); idt_set_desc(0xD, IDT_TRAP_GATE_FLAGS, ISR(general_prot), 0); idt_set_desc(0xE, IDT_TRAP_GATE_FLAGS, ISR(page_fault), 0); idt_load(); diff --git a/sys/arch/amd64/amd64/trap.S b/sys/arch/amd64/amd64/trap.S index 5a77955..66dd2a9 100644 --- a/sys/arch/amd64/amd64/trap.S +++ b/sys/arch/amd64/amd64/trap.S @@ -144,3 +144,13 @@ nmi: /* TODO */ cli hlt + +.globl ss_fault +ss_fault: + push_trapframe_ec $TRAP_SS + + handle_trap + + /* TODO */ + cli + hlt diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index b73048d..c1cff56 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -44,7 +44,8 @@ static const char *trap_type[] = { [TRAP_SEGNP] = "segment not present", [TRAP_PROTFLT] = "general protection", [TRAP_PAGEFLT] = "page fault", - [TRAP_NMI] = "non-maskable interrupt" + [TRAP_NMI] = "non-maskable interrupt", + [TRAP_SS] = "stack-segment fault" }; static const int TRAP_COUNT = __ARRAY_COUNT(trap_type); @@ -54,12 +55,17 @@ dbg_errcode(struct trapframe *tf) { uint64_t ec = tf->error_code; - if (tf->trapno == TRAP_PAGEFLT) { + switch (tf->trapno) { + case TRAP_PAGEFLT: kprintf("bits (pwui): %c%c%c%c\n", __TEST(ec, __BIT(0)) ? 'p' : '-', __TEST(ec, __BIT(1)) ? 'w' : '-', __TEST(ec, __BIT(2)) ? 'u' : '-', __TEST(ec, __BIT(4)) ? 'i' : '-'); + break; + case TRAP_SS: + kprintf("ss: 0x%x\n", ec); + break; } } diff --git a/sys/include/arch/amd64/trap.h b/sys/include/arch/amd64/trap.h index 1019999..c75fa28 100644 --- a/sys/include/arch/amd64/trap.h +++ b/sys/include/arch/amd64/trap.h @@ -47,6 +47,7 @@ #define TRAP_PROTFLT 9 /* General protection */ #define TRAP_PAGEFLT 10 /* Page fault */ #define TRAP_NMI 11 /* Non-maskable interrupt */ +#define TRAP_SS 12 /* Stack-segment fault */ /* Trap is coming from user mode */ #define TRAP_USER 0x100 @@ -65,6 +66,7 @@ void segnp(void *sf); void general_prot(void *sf); void page_fault(void *sf); void nmi(void *sf); +void ss_fault(void *sf); void trap_handler(struct trapframe *tf); #else .macro handle_trap -- cgit v1.2.3 From 9211231b616354537aa447708cb2f90123b8f092 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sun, 10 Mar 2024 20:09:28 -0400 Subject: kernel: loader: Cleanup Signed-off-by: Ian Moffett --- sys/kern/kern_loader.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) (limited to 'sys') diff --git a/sys/kern/kern_loader.c b/sys/kern/kern_loader.c index 53ba8c2..23249ea 100644 --- a/sys/kern/kern_loader.c +++ b/sys/kern/kern_loader.c @@ -61,12 +61,10 @@ int loader_load(struct vas vas, const void *dataptr, struct auxval *auxv, vm_prot_t prot = PROT_USER; uintptr_t physmem; - uintptr_t max_addr, map_addr; - size_t misalign, page_count; - + size_t misalign, page_count, map_len; int status; - const size_t GRANULE = vm_get_page_size(); + const size_t GRANULE = vm_get_page_size(); void *tmp_ptr; if (auxv == NULL) { @@ -93,26 +91,8 @@ int loader_load(struct vas vas, const void *dataptr, struct auxval *auxv, misalign = phdr->p_vaddr & (GRANULE - 1); page_count = __DIV_ROUNDUP(phdr->p_memsz + misalign, GRANULE); - max_addr = phdr->p_vaddr + (GRANULE * page_count); - - /* - * We are assuming this is a user program that we are loading. - * All user programs should be on the lower half of the address - * space. We will check that before we begin doing anything here. - * - * We are also going to check if the virtual address the program - * header refers to overflows into the higher half. If anything - * goes into the higher half, we won't simply drop the phdr, - * we'll instead assume caller error and return -EINVAL. - */ - if (phdr->p_vaddr >= VM_HIGHER_HALF) { - return -EINVAL; - } else if (max_addr >= VM_HIGHER_HALF) { - /* Overflows into higher half */ - return -EINVAL; - } - physmem = vm_alloc_pageframe(page_count); + map_len = page_count * GRANULE; /* Do we not have enough page frames? */ if (physmem == 0) { @@ -121,14 +101,9 @@ int loader_load(struct vas vas, const void *dataptr, struct auxval *auxv, return -ENOMEM; } - map_addr = phdr->p_vaddr + load_base; - status = vm_map_create(vas, map_addr, physmem, prot, page_count*GRANULE); + status = vm_map_create(vas, phdr->p_vaddr + load_base, physmem, prot, map_len); if (status != 0) { - DBG("Failed to map 0x%p - 0x%p\n", - phdr->p_vaddr + load_base, - (phdr->p_vaddr + load_base) + (page_count * GRANULE)); - return status; } -- cgit v1.2.3 From 50bf5cc0bca1b0cb9dbaf461a41b80725baabba1 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Mon, 11 Mar 2024 12:51:40 -0400 Subject: kernel/amd64: Add control register r/w helpers Signed-off-by: Ian Moffett --- sys/include/arch/amd64/cpu.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'sys') diff --git a/sys/include/arch/amd64/cpu.h b/sys/include/arch/amd64/cpu.h index e2ed851..1968569 100644 --- a/sys/include/arch/amd64/cpu.h +++ b/sys/include/arch/amd64/cpu.h @@ -110,6 +110,34 @@ amd64_read_gs_base(void) return rdmsr(IA32_KERNEL_GS_BASE); } +static inline uint64_t +amd64_read_cr0(void) +{ + uint64_t cr0; + __ASMV("mov %%cr0, %0" : "=r" (cr0) :: "memory"); + return cr0; +} + +static inline void +amd64_write_cr0(uint64_t val) +{ + __ASMV("mov %0, %%cr0" :: "r" (val) : "memory"); +} + +static inline uint64_t +amd64_read_cr4(void) +{ + uint64_t cr4; + __ASMV("mov %%cr4, %0" : "=r" (cr4) :: "memory"); + return cr4; +} + +static inline void +amd64_write_cr4(uint64_t val) +{ + __ASMV("mov %0, %%cr4" :: "r" (val) : "memory"); +} + struct cpu_info *amd64_this_cpu(void); #endif /* !_AMD64_CPU_H_ */ -- cgit v1.2.3 From 27cd9535664a83e7c9986dc8a1b0e1a80aee1629 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Mon, 11 Mar 2024 12:56:50 -0400 Subject: kernel/amd64: machdep: Enable SSE/SSE2 per core Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/machdep.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index e5fe83e..d936912 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,15 @@ interrupts_init(void) idt_load(); } +static bool +is_sse_supported(void) +{ + uint32_t edx, unused; + + __CPUID(0x00000001, unused, unused, unused, edx); + return __TEST(edx, __BIT(25)) && __TEST(edx, __BIT(26)); +} + void processor_halt(void) { @@ -150,6 +160,7 @@ processor_init(void) { /* Indicates what doesn't need to be init anymore */ static uint8_t init_flags = 0; + static uint64_t reg_tmp; struct cpu_info *cur_cpu; /* Create our cpu_info structure */ @@ -160,6 +171,21 @@ processor_init(void) /* Set %GS to cpu_info */ amd64_write_gs_base((uintptr_t)cur_cpu); + if (is_sse_supported) { + /* Enable SSE/SSE2 */ + reg_tmp = amd64_read_cr0(); + reg_tmp &= ~(__BIT(2)); + reg_tmp |= __BIT(1); + amd64_write_cr0(reg_tmp); + + /* Enable FXSAVE/FXRSTOR */ + reg_tmp = amd64_read_cr4(); + reg_tmp |= 3 << 9; + amd64_write_cr4(reg_tmp); + } else { + panic("SSE/SSE2 not supported!\n"); + } + CPU_INFO_LOCK(cur_cpu); init_tss(cur_cpu); -- cgit v1.2.3 From 5c9366f3e5f7448811e03d4ee5671a3408353e41 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 19:00:08 -0400 Subject: kernel/amd64: machdep: Fix typo Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index d936912..c24f484 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -171,7 +171,7 @@ processor_init(void) /* Set %GS to cpu_info */ amd64_write_gs_base((uintptr_t)cur_cpu); - if (is_sse_supported) { + if (is_sse_supported()) { /* Enable SSE/SSE2 */ reg_tmp = amd64_read_cr0(); reg_tmp &= ~(__BIT(2)); -- cgit v1.2.3 From 2cfcba7e6ed64a00ca01dcc7247ecfc5edacfdb2 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 21:08:50 -0400 Subject: kernel: sched: Improve stack init code Signed-off-by: Ian Moffett --- sys/include/sys/loader.h | 27 +++++---- sys/kern/kern_sched.c | 139 +++++++++++++++++++++++++---------------------- 2 files changed, 91 insertions(+), 75 deletions(-) (limited to 'sys') diff --git a/sys/include/sys/loader.h b/sys/include/sys/loader.h index c1aa426..74a325c 100644 --- a/sys/include/sys/loader.h +++ b/sys/include/sys/loader.h @@ -33,17 +33,22 @@ #include #include -#define AT_NULL 0 -#define AT_IGNORE 1 -#define AT_EXECFD 2 -#define AT_PHDR 3 -#define AT_PHENT 4 -#define AT_PHNUM 5 -#define AT_PAGESZ 6 -#define AT_BASE 7 -#define AT_FLAGS 8 -#define AT_ENTRY 9 -#define AT_SECURE 10 +/* DANGER!: DO NOT CHANGE THESE DEFINES */ +#define AT_NULL 0 +#define AT_ENTRY 1 +#define AT_PHDR 2 +#define AT_PHENT 3 +#define AT_PHNUM 4 +#define AT_EXECPATH 5 +#define AT_SECURE 6 +#define AT_RANDOM 7 +#define AT_EXECFN 8 + +#define STACK_PUSH(ptr, val) *(--ptr) = val +#define AUXVAL(ptr, tag, val) __extension__ ({ \ + STACK_PUSH(ptr, val); \ + STACK_PUSH(ptr, tag); \ +}); /* Auxiliary Vector */ struct auxval { diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 9231ea2..7be8241 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -48,6 +48,20 @@ #define STACK_PAGES 8 #define STACK_SIZE (STACK_PAGES*vm_get_page_size()) +/* + * The PHYS_TO_VIRT/VIRT_TO_PHYS macros convert + * addresses to lower and higher half addresses. + * Userspace addresses are on the lower half, + * therefore, we can just wrap over these to + * keep things simple. + * + * XXX: TODO: This won't work when not identity mapping + * lowerhalf addresses. Once that is updated, + * get rid of this. + */ +#define USER_TO_KERN(user) PHYS_TO_VIRT(user) +#define KERN_TO_USER(kern) VIRT_TO_PHYS(kern) + /* * Thread ready queue - all threads ready to be * scheduled should be added to this queue. @@ -133,86 +147,87 @@ static uintptr_t sched_init_stack(void *stack_top, char *argvp[], char *envp[], struct auxval auxv) { uintptr_t *sp = stack_top; - size_t envp_len, argv_len, len; - uintptr_t old_sp = 0; - uintptr_t ret; - - for (envp_len = 0; envp[envp_len] != NULL; ++envp_len) { - len = strlen(envp[envp_len]); - sp = (void *)((uintptr_t)sp - len - 1); - memcpy(sp, envp[envp_len], len); + void *env_ptr = NULL, *argv_ptr = NULL; + size_t argc, envc, len; + + /* Copy argument and environment strings */ + for (envc = 0; envp[envc] != NULL; ++envc) { + len = strlen(envp[envc]); + sp -= len - 1; + memcpy(sp, envp[envc], len); } - for (argv_len = 0; argvp[argv_len] != NULL; ++argv_len) { - len = strlen(argvp[argv_len]); - sp = (void *)((uintptr_t)sp - len - 1); - memcpy(sp, argvp[envp_len], len); - } + __assert(envc >= 1); + env_ptr = sp; - sp = (uint64_t *)(((uintptr_t)sp / 16) * 16); - if (((argv_len + envp_len + 1) & 1) != 0) { - sp--; + for (argc = 0; argvp[argc] != NULL; ++argc) { + len = strlen(argvp[argc]); + sp -= len - 1; + memcpy(sp, argvp[argc], len); } - *--sp = 0; - *--sp = 0; - *--sp = auxv.at_entry; - *--sp = AT_ENTRY; - *--sp = auxv.at_phent; - *--sp = AT_PHENT; - *--sp = auxv.at_phnum; - *--sp = AT_PHNUM; - *--sp = auxv.at_phdr; - *--sp = AT_PHDR; - - old_sp = (uintptr_t)sp; - - /* End of envp */ - *--sp = 0; - sp -= envp_len; - for (int i = 0; i < envp_len; ++i) { - old_sp -= strlen(envp[i]) + 1; - sp[i] = old_sp; + __assert(argc >= 1); + argv_ptr = sp; + + /* Ensure the stack is aligned */ + sp = (void *)__ALIGN_DOWN((uintptr_t)sp, 16); + if (((argc + envc + 1) & 1) != 0) + --sp; + + AUXVAL(sp, AT_NULL, 0x0); + AUXVAL(sp, AT_SECURE, 0x0); + AUXVAL(sp, AT_ENTRY, auxv.at_entry); + AUXVAL(sp, AT_PHDR, auxv.at_phdr); + AUXVAL(sp, AT_PHNUM, auxv.at_phnum); + STACK_PUSH(sp, 0); + + /* Push environment string pointers */ + for (int i = 0; i < envc; ++i) { + len = strlen(env_ptr); + sp -= len; + + *sp = (uintptr_t)KERN_TO_USER((uintptr_t)env_ptr); + env_ptr = (char *)env_ptr + len; } - /* End of argvp */ - *--sp = 0; - sp -= argv_len; - for (int i = 0; i < argv_len; ++i) { - old_sp -= strlen(argvp[i]) + 1; - sp[i] = old_sp; + /* Push argument string pointers */ + STACK_PUSH(sp, 0); + for (int i = 0; i < argc; ++i) { + len = strlen(argv_ptr); + sp -= len; + + *sp = (uintptr_t)KERN_TO_USER((uintptr_t)argv_ptr); + argv_ptr = (char *)argv_ptr + len; } - /* Argc */ - *--sp = argv_len; + STACK_PUSH(sp, argc); - ret = (uintptr_t)stack_top; - ret -= (ret - (uintptr_t)sp); - return ret; + return (uintptr_t)sp; } static uintptr_t -sched_create_stack(struct vas vas, bool user) +sched_create_stack(struct vas vas, bool user, char *argvp[], + char *envp[], struct auxval auxv) { int status; - uintptr_t user_stack; + uintptr_t stack; const vm_prot_t USER_STACK_PROT = PROT_WRITE | PROT_USER; if (!user) { - return (uintptr_t)dynalloc(STACK_SIZE); + stack = (uintptr_t)dynalloc(STACK_SIZE); + return sched_init_stack((void *)(stack + STACK_SIZE), argvp, envp, auxv); } - user_stack = vm_alloc_pageframe(STACK_PAGES); - - status = vm_map_create(vas, user_stack, user_stack, USER_STACK_PROT, - STACK_SIZE); + stack = vm_alloc_pageframe(STACK_PAGES); + status = vm_map_create(vas, stack, stack, USER_STACK_PROT, STACK_SIZE); if (status != 0) { return 0; } - memset(PHYS_TO_VIRT(user_stack), 0, STACK_SIZE); - return user_stack; + memset(USER_TO_KERN(stack), 0, STACK_SIZE); + stack = sched_init_stack((void *)USER_TO_KERN(stack + STACK_SIZE), argvp, envp, auxv); + return stack; } static struct proc * @@ -220,8 +235,7 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, struct vas vas, bool is_user) { struct proc *td; - uintptr_t stack, sp; - void *stack_virt; + uintptr_t stack; struct trapframe *tf; tf = dynalloc(sizeof(struct trapframe)); @@ -229,14 +243,12 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, return NULL; } - stack = sched_create_stack(vas, is_user); + stack = sched_create_stack(vas, is_user, argvp, envp, auxv); if (stack == 0) { dynfree(tf); return NULL; } - stack_virt = (is_user) ? PHYS_TO_VIRT(stack) : (void *)stack; - td = dynalloc(sizeof(struct proc)); if (td == NULL) { /* TODO: Free stack */ @@ -245,8 +257,7 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, } memset(tf, 0, sizeof(struct trapframe)); - sp = sched_init_stack((void *)((uintptr_t)stack_virt + STACK_SIZE), - argvp, envp, auxv); + memset(td, 0, sizeof(struct proc)); /* Setup process itself */ td->pid = 0; /* Don't assign PID until enqueued */ @@ -256,9 +267,9 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, /* Setup trapframe */ if (!is_user) { - init_frame(tf, rip, sp); + init_frame(tf, rip, (uintptr_t)stack); } else { - init_frame_user(tf, rip, VIRT_TO_PHYS(sp)); + init_frame_user(tf, rip, KERN_TO_USER(stack)); } return td; } -- cgit v1.2.3 From 10e2fc7e3c6a924923664cf2919393b7f7b37326 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 21:20:25 -0400 Subject: kernel/amd64: spectre: Log only once Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/spectre.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/spectre.c b/sys/arch/amd64/amd64/spectre.c index 1247607..05aa557 100644 --- a/sys/arch/amd64/amd64/spectre.c +++ b/sys/arch/amd64/amd64/spectre.c @@ -62,13 +62,18 @@ __weak int try_spectre_mitigate(void) { uint64_t tmp; + static bool should_log = true; if (!__can_mitigate_spectre()) { KINFO("IBRS not supported; spectre mitigation NOT enabled\n"); return EXIT_FAILURE; } - KINFO("IBRS supported; spectre mitigation enabled\n"); + /* This is called per processor, only log once */ + if (should_log) { + KINFO("IBRS supported; spectre mitigation enabled\n"); + should_log = false; + } tmp = rdmsr(IA32_SPEC_CTL); tmp |= __BIT(0); /* IBRS */ -- cgit v1.2.3 From 73a209c0f7e350d819ce4b98374d4f2b83f7300d Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 21:20:53 -0400 Subject: kernel/amd64: cpu: Add fxsave/fxrstor helpers Signed-off-by: Ian Moffett --- sys/include/arch/amd64/cpu.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'sys') diff --git a/sys/include/arch/amd64/cpu.h b/sys/include/arch/amd64/cpu.h index 1968569..ee9bad7 100644 --- a/sys/include/arch/amd64/cpu.h +++ b/sys/include/arch/amd64/cpu.h @@ -138,6 +138,18 @@ amd64_write_cr4(uint64_t val) __ASMV("mov %0, %%cr4" :: "r" (val) : "memory"); } +static inline void +amd64_fxsave(void *area) +{ + __ASMV("fxsave (%0)" :: "r" (area) : "memory"); +} + +static inline void +amd64_fxrstor(void *area) +{ + __ASMV("fxrstor (%0)" :: "r" (area) : "memory"); +} + struct cpu_info *amd64_this_cpu(void); #endif /* !_AMD64_CPU_H_ */ -- cgit v1.2.3 From b40d31b6f6e56fdf3f3c4f4b4be36681fb829c6b Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 21:24:43 -0400 Subject: kernel/amd64: trap: Update panic message We have a scheduler now, this old message does not make sense. So it is replaced. Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/trap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index c1cff56..f1e58f1 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -121,5 +121,5 @@ trap_handler(struct trapframe *tf) } regdump(tf); - panic("Caught pre-sched exception\n"); + panic("Halted\n"); } -- cgit v1.2.3 From 12d4b76edec3006c8dd131ee797e110d6f76cac9 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 21:26:15 -0400 Subject: kernel/amd64: machdep: Remove extra whitespace Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/machdep.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index c24f484..809e395 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -100,7 +100,6 @@ processor_halt(void) __ASMV("cli; hlt"); } - /* * Send char to serial for debugging purposes. */ -- cgit v1.2.3 From 8b68f956154b43b2b2fe2b8783ae6f23bf90d47b Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 21:31:25 -0400 Subject: kernel: proc: Add Process Control Block structure This is to be implemented per arch and has arch specific thread information. For example, on the AMD64 port, this can contain things like an x87 FPU save area Signed-off-by: Ian Moffett --- sys/include/arch/amd64/pcb.h | 39 +++++++++++++++++++++++++++++++++++++++ sys/include/sys/proc.h | 2 ++ 2 files changed, 41 insertions(+) create mode 100644 sys/include/arch/amd64/pcb.h (limited to 'sys') diff --git a/sys/include/arch/amd64/pcb.h b/sys/include/arch/amd64/pcb.h new file mode 100644 index 0000000..0e0aab8 --- /dev/null +++ b/sys/include/arch/amd64/pcb.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _AMD64_PCB_H_ +#define _AMD64_PCB_H_ + +#include + +struct pcb { + uint8_t *fpu_state; +}; + +#endif /* !_AMD64_PCB_H_ */ diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index 0d3b45e..34a5037 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -34,6 +34,7 @@ #include #include #include +#include #include /* @@ -44,6 +45,7 @@ struct proc { pid_t pid; struct cpu_info *cpu; struct trapframe *tf; + struct pcb pcb; struct vas addrsp; TAILQ_ENTRY(proc) link; }; -- cgit v1.2.3 From fc9c7bab5bb64dd2242e9e9dff98060d64af2a32 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 21:27:39 -0400 Subject: kernel/amd64: machdep: Add pcb init code This commit adds a processor specific routine which sets up the Process Control Block for a thread Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/machdep.c | 25 +++++++++++++++++++++++++ sys/include/sys/machdep.h | 2 ++ sys/kern/kern_sched.c | 2 ++ 3 files changed, 29 insertions(+) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 809e395..0789f5a 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -154,6 +154,31 @@ intr_unmask(void) __ASMV("sti"); } +int +processor_init_pcb(struct proc *proc) +{ + struct pcb *pcb = &proc->pcb; + const uint16_t FPU_FCW = 0x33F; + const uint32_t SSE_MXCSR = 0x1F80; + + /* Allocate FPU save area, aligned on a 16 byte boundary */ + pcb->fpu_state = PHYS_TO_VIRT(vm_alloc_pageframe(1)); + if (pcb->fpu_state == 0) { + return -1; + } + + /* + * Setup x87 FPU control word and SSE MXCSR bits + * as per the sysv ABI + */ + __ASMV("fldcw %0\n" + "ldmxcsr %1" + :: "m" (FPU_FCW), + "m" (SSE_MXCSR) : "memory"); + + amd64_fxsave(pcb->fpu_state); + return 0; +} void processor_init(void) { diff --git a/sys/include/sys/machdep.h b/sys/include/sys/machdep.h index 713b7db..151d5f8 100644 --- a/sys/include/sys/machdep.h +++ b/sys/include/sys/machdep.h @@ -32,11 +32,13 @@ #include #include +#include #if defined(_KERNEL) #define MAXCPUS 32 +int processor_init_pcb(struct proc *proc); void processor_init(void); void processor_halt(void); void intr_mask(void); diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 7be8241..f8f09c4 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -264,6 +265,7 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, td->cpu = NULL; /* Not yet assigned a core */ td->tf = tf; td->addrsp = vas; + processor_init_pcb(td); /* Setup trapframe */ if (!is_user) { -- cgit v1.2.3 From 39d4aa3a106f898d09b98e41ef44fb4891eda1ce Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 21:40:06 -0400 Subject: kernel/amd64: machdep: Add context switch helper Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/machdep.c | 13 +++++++++++++ sys/include/sys/machdep.h | 1 + sys/kern/kern_sched.c | 4 ++++ 3 files changed, 18 insertions(+) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 0789f5a..5327189 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -179,6 +179,19 @@ processor_init_pcb(struct proc *proc) amd64_fxsave(pcb->fpu_state); return 0; } + +void +processor_switch_to(struct proc *old_td, struct proc *new_td) +{ + struct pcb *old_pcb = (old_td != NULL) ? &old_td->pcb : NULL; + struct pcb *new_pcb = &new_td->pcb; + + if (old_pcb != NULL) { + amd64_fxsave(old_pcb->fpu_state); + } + amd64_fxrstor(new_pcb->fpu_state); +} + void processor_init(void) { diff --git a/sys/include/sys/machdep.h b/sys/include/sys/machdep.h index 151d5f8..b6edf14 100644 --- a/sys/include/sys/machdep.h +++ b/sys/include/sys/machdep.h @@ -39,6 +39,7 @@ #define MAXCPUS 32 int processor_init_pcb(struct proc *proc); +void processor_switch_to(struct proc *old_td, struct proc *new_td); void processor_init(void); void processor_halt(void); void intr_mask(void); diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index f8f09c4..bc96146 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -311,6 +311,10 @@ sched_context_switch(struct trapframe *tf) sched_enqueue_td(td); } + /* Do architecture specific context switch logic */ + processor_switch_to(td, next_td); + + /* Done, switch out our vas and oneshot */ pmap_switch_vas(vm_get_ctx(), next_td->addrsp); sched_oneshot(); } -- cgit v1.2.3 From 86ee5ee30e2f98137da80434af788bf928f49d55 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 23:28:44 -0400 Subject: kernel/amd64: machdep: Check for NULL instead of 0 Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 5327189..7ad3e6a 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -163,7 +163,7 @@ processor_init_pcb(struct proc *proc) /* Allocate FPU save area, aligned on a 16 byte boundary */ pcb->fpu_state = PHYS_TO_VIRT(vm_alloc_pageframe(1)); - if (pcb->fpu_state == 0) { + if (pcb->fpu_state == NULL) { return -1; } -- cgit v1.2.3 From a2b2dbaa71278769e9dbf5ca611cd0d5f3b896ed Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 13 Mar 2024 23:30:21 -0400 Subject: kernel/amd64: machdep: Add processor_free_pcb() Add routine to deallocate resources within the process control block. Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/machdep.c | 13 +++++++++++++ sys/include/sys/machdep.h | 1 + 2 files changed, 14 insertions(+) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 7ad3e6a..fa6c1f5 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -180,6 +180,19 @@ processor_init_pcb(struct proc *proc) return 0; } +int +processor_free_pcb(struct proc *proc) +{ + struct pcb *pcb = &proc->pcb; + + if (pcb->fpu_state == NULL) { + return -1; + } + + vm_free_pageframe(VIRT_TO_PHYS(pcb->fpu_state), 1); + return 0; +} + void processor_switch_to(struct proc *old_td, struct proc *new_td) { diff --git a/sys/include/sys/machdep.h b/sys/include/sys/machdep.h index b6edf14..0c06374 100644 --- a/sys/include/sys/machdep.h +++ b/sys/include/sys/machdep.h @@ -39,6 +39,7 @@ #define MAXCPUS 32 int processor_init_pcb(struct proc *proc); +int processor_free_pcb(struct proc *proc); void processor_switch_to(struct proc *old_td, struct proc *new_td); void processor_init(void); void processor_halt(void); -- cgit v1.2.3 From 5a8915f5b36cf3b21c843ef7959c24ac39318aca Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 14 Mar 2024 20:51:39 -0400 Subject: kernel: vm: Add routine to get kernel vas Signed-off-by: Ian Moffett --- sys/include/vm/vm.h | 1 + sys/vm/vm_init.c | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'sys') diff --git a/sys/include/vm/vm.h b/sys/include/vm/vm.h index 2a24d76..48e1b8f 100644 --- a/sys/include/vm/vm.h +++ b/sys/include/vm/vm.h @@ -61,5 +61,6 @@ vm_get_page_size(void) void vm_init(void); struct vm_ctx *vm_get_ctx(void); +struct vas vm_get_kvas(void); #endif /* !_VM_H_ */ diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c index f15cb0b..6096059 100644 --- a/sys/vm/vm_init.c +++ b/sys/vm/vm_init.c @@ -59,6 +59,15 @@ vm_get_ctx(void) return &bsp_vm_ctx; } +/* + * Return the kernel VAS. + */ +struct vas +vm_get_kvas(void) +{ + return kernel_vas; +} + void vm_init(void) { -- cgit v1.2.3 From 7a32267fcc81af31d595373884911d503b0a9df8 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 14 Mar 2024 20:55:54 -0400 Subject: kernel: sched: Keep track of stack and privilege Signed-off-by: Ian Moffett --- sys/include/sys/proc.h | 2 ++ sys/kern/kern_sched.c | 16 ++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index 34a5037..7181ecb 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -47,6 +47,8 @@ struct proc { struct trapframe *tf; struct pcb pcb; struct vas addrsp; + uintptr_t stack_base; + uint8_t is_user; TAILQ_ENTRY(proc) link; }; diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index bc96146..f985f62 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -208,7 +208,7 @@ sched_init_stack(void *stack_top, char *argvp[], char *envp[], struct auxval aux static uintptr_t sched_create_stack(struct vas vas, bool user, char *argvp[], - char *envp[], struct auxval auxv) + char *envp[], struct auxval auxv, struct proc *td) { int status; uintptr_t stack; @@ -216,10 +216,12 @@ sched_create_stack(struct vas vas, bool user, char *argvp[], if (!user) { stack = (uintptr_t)dynalloc(STACK_SIZE); + td->stack_base = (uintptr_t)stack; return sched_init_stack((void *)(stack + STACK_SIZE), argvp, envp, auxv); } stack = vm_alloc_pageframe(STACK_PAGES); + td->stack_base = stack; status = vm_map_create(vas, stack, stack, USER_STACK_PROT, STACK_SIZE); if (status != 0) { @@ -244,16 +246,17 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, return NULL; } - stack = sched_create_stack(vas, is_user, argvp, envp, auxv); - if (stack == 0) { + td = dynalloc(sizeof(struct proc)); + if (td == NULL) { + /* TODO: Free stack */ dynfree(tf); return NULL; } - td = dynalloc(sizeof(struct proc)); - if (td == NULL) { - /* TODO: Free stack */ + stack = sched_create_stack(vas, is_user, argvp, envp, auxv, td); + if (stack == 0) { dynfree(tf); + dynfree(td); return NULL; } @@ -265,6 +268,7 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, td->cpu = NULL; /* Not yet assigned a core */ td->tf = tf; td->addrsp = vas; + td->is_user = is_user; processor_init_pcb(td); /* Setup trapframe */ -- cgit v1.2.3 From 3e3ff0acccfbb1d251a9b9bacbf0851c9de69561 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 14 Mar 2024 21:02:10 -0400 Subject: kernel/amd64: pmap: Add pmap_free_vas() Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/pmap.c | 13 +++++++++++++ sys/include/vm/pmap.h | 6 ++++++ 2 files changed, 19 insertions(+) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index 2760532..54d4ca3 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -228,6 +228,19 @@ pmap_switch_vas(struct vm_ctx *ctx, struct vas vas) : "memory"); } +/* + * TODO: During the mapping of a virtual address, a level + * may be allocated. This function does not handle the + * freeing of allocated levels. We should keep track + * of levels allocated and free them here. + */ +int +pmap_free_vas(struct vm_ctx *ctx, struct vas vas) +{ + vm_free_pageframe(vas.top_level, 1); + return 0; +} + struct vas pmap_read_vas(void) { diff --git a/sys/include/vm/pmap.h b/sys/include/vm/pmap.h index ebabd32..3380199 100644 --- a/sys/include/vm/pmap.h +++ b/sys/include/vm/pmap.h @@ -89,6 +89,12 @@ struct vas pmap_read_vas(void); */ int pmap_map(struct vm_ctx *, struct vas, vaddr_t, paddr_t, vm_prot_t); +/* + * Get rid of a virtual address space and free + * resources. + */ +int pmap_free_vas(struct vm_ctx *, struct vas); + /* * Unmap a page. */ -- cgit v1.2.3 From d0f81e3d2afdf7a89fd466799f2d900da9f2ac40 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 14 Mar 2024 20:57:12 -0400 Subject: kernel: sched: Add exit routine Signed-off-by: Ian Moffett --- sys/include/sys/sched.h | 1 + sys/kern/kern_sched.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) (limited to 'sys') diff --git a/sys/include/sys/sched.h b/sys/include/sys/sched.h index d803df0..f06c104 100644 --- a/sys/include/sys/sched.h +++ b/sys/include/sys/sched.h @@ -38,6 +38,7 @@ #include void sched_init(void); +void sched_exit(void); void sched_context_switch(struct trapframe *tf); __noreturn diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index f985f62..c3d1e09 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -280,6 +280,50 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, return td; } +static void +sched_destroy_td(struct proc *td) +{ + processor_free_pcb(td); + + /* + * User stacks are allocated with vm_alloc_pageframe(), + * while kernel stacks are allocated with dynalloc(). + * We want to check if we are a user program or kernel + * program to perform the proper deallocation method. + */ + if (td->is_user) { + vm_free_pageframe(td->stack_base, STACK_PAGES); + } else { + dynfree((void *)td->stack_base); + } + + pmap_free_vas(vm_get_ctx(), td->addrsp); + dynfree(td); +} + +void +sched_exit(void) +{ + struct sched_state *state; + struct cpu_info *ci; + struct proc *td; + struct vas kvas = vm_get_kvas(); + + intr_mask(); + + /* Get the thread running on the current processor */ + ci = this_cpu(); + state = &ci->sched_state; + td = state->td; + + /* Switch back to the kernel address space and destroy ourself */ + pmap_switch_vas(vm_get_ctx(), kvas); + sched_destroy_td(td); + + intr_unmask(); + sched_enter(); +} + /* * Thread context switch routine */ -- cgit v1.2.3 From cec19cdab21e1eda7ae149792d1529bb03c0714b Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 14 Mar 2024 21:47:23 -0400 Subject: kernel: Add support for syscalls Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/machdep.c | 3 +++ sys/arch/amd64/amd64/syscall.S | 43 +++++++++++++++++++++++++++++++ sys/arch/amd64/amd64/syscall.c | 51 +++++++++++++++++++++++++++++++++++++ sys/include/sys/syscall.h | 58 ++++++++++++++++++++++++++++++++++++++++++ sys/kern/kern_syscall.c | 50 ++++++++++++++++++++++++++++++++++++ 5 files changed, 205 insertions(+) create mode 100644 sys/arch/amd64/amd64/syscall.S create mode 100644 sys/arch/amd64/amd64/syscall.c create mode 100644 sys/include/sys/syscall.h create mode 100644 sys/kern/kern_syscall.c (limited to 'sys') diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index fa6c1f5..47d6dd0 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -57,6 +57,8 @@ __KERNEL_META("$Hyra$: machdep.c, Ian Marco Moffett, " #define INIT_FLAG_IOAPIC 0x00000001U #define INIT_FLAG_ACPI 0x00000002U +void syscall_isr(void); + static inline void init_tss(struct cpu_info *cur_cpu) { @@ -82,6 +84,7 @@ interrupts_init(void) idt_set_desc(0xC, IDT_TRAP_GATE_FLAGS, ISR(ss_fault), 0); idt_set_desc(0xD, IDT_TRAP_GATE_FLAGS, ISR(general_prot), 0); idt_set_desc(0xE, IDT_TRAP_GATE_FLAGS, ISR(page_fault), 0); + idt_set_desc(0x80, IDT_INT_GATE_USER, ISR(syscall_isr), 0); idt_load(); } diff --git a/sys/arch/amd64/amd64/syscall.S b/sys/arch/amd64/amd64/syscall.S new file mode 100644 index 0000000..fe70523 --- /dev/null +++ b/sys/arch/amd64/amd64/syscall.S @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + #include + #include + +__KERNEL_META "$Hyra$: syscall.S, Ian Marco Moffett, \ + Syscall ISR code" + +.text +.globl syscall_isr +syscall_isr: + push_trapframe $0 + mov %rsp, %rdi + call __syscall + pop_trapframe + iretq diff --git a/sys/arch/amd64/amd64/syscall.c b/sys/arch/amd64/amd64/syscall.c new file mode 100644 index 0000000..9b1f988 --- /dev/null +++ b/sys/arch/amd64/amd64/syscall.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +void +__syscall(struct trapframe *tf) +{ + struct syscall_args args = { + .code = tf->rax, + .arg0 = tf->rdi, + .arg1 = tf->rsi, + .arg2 = tf->rcx, + .arg3 = tf->r8, + .arg4 = tf->r9, + .sp = tf->rsp, + .ret = tf->rax, + }; + + if (args.code < __MAX_SYSCALLS) { + g_syscall_table[tf->rax](&args); + } + + tf->rax = args.ret; +} diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h new file mode 100644 index 0000000..98a57f2 --- /dev/null +++ b/sys/include/sys/syscall.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_SYSCALL_H_ +#define _SYS_SYSCALL_H_ + +#include +#if defined(_KERNEL) +#include +#endif + +/* Do not reorder */ +enum { + SYS_debug = 0, + SYS_exit, + __MAX_SYSCALLS +}; + +struct syscall_args { + uint64_t code; + uint64_t arg0, arg1, arg2, arg3, arg4; + uint64_t ip; + uint64_t sp; + uint64_t ret; +}; + +#if defined(_KERNEL) +extern void(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args); +void __syscall(struct trapframe *tf); +#endif + +#endif diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c new file mode 100644 index 0000000..2c7215c --- /dev/null +++ b/sys/kern/kern_syscall.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +static void +sys_debug(struct syscall_args *args) +{ + /* TODO */ +} + +__noreturn static void +sys_exit(struct syscall_args *args) +{ + sched_exit(); + __builtin_unreachable(); +} + +void(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args) = { + sys_debug, + sys_exit, +}; -- cgit v1.2.3 From 3c7958f1df0eefa5a567761f5838d5ed772998e6 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 14 Mar 2024 22:03:47 -0400 Subject: kernel: sched: Rework sched_init() Signed-off-by: Ian Moffett --- sys/kern/kern_sched.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index c3d1e09..fca3e17 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -371,27 +371,30 @@ void sched_init(void) { struct proc *init; - struct auxval auxv = {0}; + struct auxval auxv = {0}, ld_auxv = {0}; struct vas vas = pmap_create_vas(vm_get_ctx()); - const char *init_bin; + const char *init_bin, *ld_bin; - int status; char *ld_path; - char *argv[] = {"/boot/init", NULL}; - char *envp[] = {NULL}; + char *argv[] = {"/usr/sbin/init", NULL}; + char *envp[] = {"", NULL}; TAILQ_INIT(&td_queue); - if ((init_bin = initramfs_open("/boot/init")) == NULL) { - panic("Could not open /boot/init\n"); + if ((init_bin = initramfs_open("/usr/sbin/init")) == NULL) { + panic("Could not open /usr/boot/init\n"); } - - status = loader_load(vas, init_bin, &auxv, 0, &ld_path); - if (status != 0) { + if (loader_load(vas, init_bin, &auxv, 0, &ld_path) != 0) { panic("Could not load init\n"); } + if ((ld_bin = initramfs_open(ld_path)) == NULL) { + panic("Could not open %s\n", ld_path); + } + if (loader_load(vas, ld_bin, &ld_auxv, 0x00, NULL) != 0) { + panic("Could not load %s\n", ld_path); + } - init = sched_create_td((uintptr_t)auxv.at_entry, argv, envp, auxv, vas, true); + init = sched_create_td((uintptr_t)ld_auxv.at_entry, argv, envp, ld_auxv, vas, true); if (init == NULL) { panic("Failed to create thread for init\n"); } -- cgit v1.2.3 From 34e2731df268bf44af1e9bb050bae55c94a244db Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 14 Mar 2024 22:21:30 -0400 Subject: kernel: sched: Remove useless declaration Signed-off-by: Ian Moffett --- sys/kern/kern_sched.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'sys') diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index fca3e17..117e0c1 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -76,9 +76,6 @@ static size_t nthread = 0; */ static struct spinlock tdq_lock = {0}; -/* In sys///switch.S */ -void __sched_switch_to(struct trapframe *tf); - static inline void sched_oneshot(void) { -- cgit v1.2.3 From 735b519d0c5cf704a992972829ab7a36afa95685 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 15 Mar 2024 10:24:55 -0400 Subject: kernel: initramfs: Fix indent Signed-off-by: Ian Moffett --- sys/fs/initramfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c index dad3763..817e6a1 100644 --- a/sys/fs/initramfs.c +++ b/sys/fs/initramfs.c @@ -149,8 +149,8 @@ static char * get_module(const char *path, uint64_t *size) { for (uint64_t i = 0; i < mod_req.response->module_count; ++i) { if (strcmp(mod_req.response->modules[i]->path, path) == 0) { - *size = mod_req.response->modules[i]->size; - return mod_req.response->modules[i]->address; + *size = mod_req.response->modules[i]->size; + return mod_req.response->modules[i]->address; } } -- cgit v1.2.3 From 49b44f6346df4e25a6e001e7d71534efc197a445 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 15 Mar 2024 10:27:42 -0400 Subject: kernel: vfs: Fix typo in comment Signed-off-by: Ian Moffett --- sys/kern/vfs_lookup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 748d5e2..7d20bd2 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -33,7 +33,7 @@ #include /* - * Fetches the filename within a past at + * Fetches the filename within a path at * the nth index denoted by `idx' * * Returns memory allocated by dynalloc() -- cgit v1.2.3 From 5338af63451bee4a6ff100ea926368875c6b0a9d Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 15 Mar 2024 11:58:56 -0400 Subject: kernel: initramfs: Fix vtype logic bug Signed-off-by: Ian Moffett --- sys/fs/initramfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c index 817e6a1..2a501a1 100644 --- a/sys/fs/initramfs.c +++ b/sys/fs/initramfs.c @@ -103,7 +103,7 @@ vop_vget(struct vnode *parent, const char *name, struct vnode **vp) return -ENOENT; } - if (hdr->type != TAR_TYPEFLAG_DIR) { + if (hdr->type == TAR_TYPEFLAG_DIR) { vtype = VDIR; } -- cgit v1.2.3 From 81e963b81a99f6b1176b2e316308cebe5f86d3c2 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 15 Mar 2024 12:04:46 -0400 Subject: kernel: vfs: Allow optional fs store within vnode Signed-off-by: Ian Moffett --- sys/include/sys/vnode.h | 1 + sys/kern/vfs_init.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/include/sys/vnode.h b/sys/include/sys/vnode.h index f584356..545e38f 100644 --- a/sys/include/sys/vnode.h +++ b/sys/include/sys/vnode.h @@ -47,6 +47,7 @@ struct vnode { struct mount *mp; /* Ptr to vfs vnode is in */ struct vops *vops; struct vnode *parent; + struct fs_info *fs; /* Filesystem this vnode belongs to, can be NULL */ void *data; /* Filesystem specific data */ }; diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index 18ab3ac..0d8d194 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -40,8 +40,10 @@ __MODULE_NAME("vfs"); __KERNEL_META("$Hyra$: vfs.c, Ian Marco Moffett, " "Hyra Virtual File System"); +#define INITRAMFS_ID 0 + static struct fs_info filesystems[] = { - { "initramfs", &g_initramfs_ops } + [INITRAMFS_ID] = { "initramfs", &g_initramfs_ops } }; struct vnode *g_root_vnode = NULL; @@ -76,4 +78,5 @@ vfs_init(void) } g_root_vnode->vops = &g_initramfs_vops; + g_root_vnode->fs = &filesystems[INITRAMFS_ID]; } -- cgit v1.2.3 From 45547c3a0056ab5732c4ea1e01deee10749ecbcb Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 15 Mar 2024 12:06:40 -0400 Subject: kernel: vfs: Add fs capabilties Signed-off-by: Ian Moffett --- sys/fs/initramfs.c | 1 + sys/include/sys/mount.h | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'sys') diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c index 2a501a1..6da0929 100644 --- a/sys/fs/initramfs.c +++ b/sys/fs/initramfs.c @@ -173,6 +173,7 @@ static int initramfs_init(struct fs_info *info) { initramfs = get_module("/boot/initramfs.tar", &initramfs_size); + info->caps = FSCAP_FULLPATH; if (initramfs == NULL) { panic("Failed to load initramfs\n"); diff --git a/sys/include/sys/mount.h b/sys/include/sys/mount.h index 3ac7ec7..209fa3e 100644 --- a/sys/include/sys/mount.h +++ b/sys/include/sys/mount.h @@ -33,6 +33,7 @@ #include #include #include +#include #define FS_NAME_MAX 16 /* Max length of FS type name including nul */ @@ -54,8 +55,14 @@ struct fs_info { char name[FS_NAME_MAX]; /* Filesystem type name */ struct vfsops *vfsops; /* Filesystem operations */ struct mount *mp_root; + uint16_t caps; }; +/* + * Filesystem capabilities + */ +#define FSCAP_FULLPATH __BIT(0) /* Requires full path per lookup */ + /* * Mount flags */ -- cgit v1.2.3 From ec2da40e65346bd5d3055777a76852892da21ea7 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 15 Mar 2024 12:18:16 -0400 Subject: kernel: vfs: Implement vfs_path_to_node() Signed-off-by: Ian Moffett --- sys/include/sys/vfs.h | 2 +- sys/kern/vfs_lookup.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/include/sys/vfs.h b/sys/include/sys/vfs.h index a684c3f..c1bef53 100644 --- a/sys/include/sys/vfs.h +++ b/sys/include/sys/vfs.h @@ -42,7 +42,7 @@ void vfs_init(void); struct fs_info *vfs_byname(const char *name); int vfs_vget(struct vnode *parent, const char *name, struct vnode **vp); -struct vnode *vfs_path_to_node(const char *path); +int vfs_path_to_node(const char *path, struct vnode **vp); char *vfs_get_fname_at(const char *path, size_t idx); int vfs_rootname(const char *path, char **new_path); bool vfs_is_valid_path(const char *path); diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 7d20bd2..1398964 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -29,6 +29,8 @@ #include #include +#include +#include #include #include @@ -115,9 +117,58 @@ vfs_get_fname_at(const char *path, size_t idx) return ret; } -struct vnode * -vfs_path_to_node(const char *path) +/* + * Fetches a vnode from a path. + * + * @path: Path to fetch vnode from. + * @vp: Output var for fetched vnode. + * + * Returns 0 on success. + */ +int +vfs_path_to_node(const char *path, struct vnode **vp) { - /* TODO */ - return NULL; + struct vnode *vnode = g_root_vnode; + struct fs_info *fs; + char *name; + int s = 0, fs_caps = 0; + + if (strcmp(path, "/") == 0 || !vfs_is_valid_path(path)) { + return -1; + } else if (*path != '/') { + return -1; + } + + /* Fetch filesystem capabilities if we can */ + if (vnode->fs != NULL) { + fs = vnode->fs; + fs_caps = fs->caps; + } + + /* + * If the filesystem requires full-path lookups, we can try + * throwing the full path at the filesystem to see if + * it'll give us a vnode. + */ + if (__TEST(fs_caps, FSCAP_FULLPATH)) { + s = vfs_vget(g_root_vnode, path, &vnode); + goto done; + } + + for (size_t i = 0;; ++i) { + name = vfs_get_fname_at(path, i); + if (name == NULL) break; + + s = vfs_vget(vnode, name, &vnode); + dynfree(name); + + if (s != 0) break; + } + +done: + if (vp != NULL && s == 0) { + *vp = vnode; + } + + return s; } -- cgit v1.2.3 From 1e7a1c0d90f6eb339e3e68c7b91bb21e81e06d5c Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 15 Mar 2024 18:39:47 -0400 Subject: kernel: sched: Add routine to get current thread Signed-off-by: Ian Moffett --- sys/include/sys/sched.h | 1 + sys/kern/kern_sched.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) (limited to 'sys') diff --git a/sys/include/sys/sched.h b/sys/include/sys/sched.h index f06c104..1fa947e 100644 --- a/sys/include/sys/sched.h +++ b/sys/include/sys/sched.h @@ -37,6 +37,7 @@ #include #include +struct proc *this_td(void); void sched_init(void); void sched_exit(void); void sched_context_switch(struct trapframe *tf); diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 117e0c1..d775e5a 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -321,6 +321,20 @@ sched_exit(void) sched_enter(); } +/* + * Get the current running thread. + */ +struct proc * +this_td(void) +{ + struct sched_state *state; + struct cpu_info *ci; + + ci = this_cpu(); + state = &ci->sched_state; + return state->td; +} + /* * Thread context switch routine */ -- cgit v1.2.3 From ca74cc263f2e7cc94e0216c775a09a52a970d235 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 15 Mar 2024 18:40:43 -0400 Subject: kernel: sched: Use this_td() to get thread Signed-off-by: Ian Moffett --- sys/kern/kern_sched.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index d775e5a..bd59e41 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -301,17 +301,12 @@ sched_destroy_td(struct proc *td) void sched_exit(void) { - struct sched_state *state; - struct cpu_info *ci; struct proc *td; struct vas kvas = vm_get_kvas(); intr_mask(); - /* Get the thread running on the current processor */ - ci = this_cpu(); - state = &ci->sched_state; - td = state->td; + td = this_td(); /* Switch back to the kernel address space and destroy ourself */ pmap_switch_vas(vm_get_ctx(), kvas); -- cgit v1.2.3 From dd0a88b94744053653a032149ba7d6eb1f392021 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 15 Mar 2024 19:54:43 -0400 Subject: kernel: Add basic file descriptor support Signed-off-by: Ian Moffett --- sys/include/sys/filedesc.h | 53 +++++++++++++++++++ sys/include/sys/proc.h | 4 ++ sys/kern/kern_filedesc.c | 123 +++++++++++++++++++++++++++++++++++++++++++++ sys/kern/kern_sched.c | 11 ++++ 4 files changed, 191 insertions(+) create mode 100644 sys/include/sys/filedesc.h create mode 100644 sys/kern/kern_filedesc.c (limited to 'sys') diff --git a/sys/include/sys/filedesc.h b/sys/include/sys/filedesc.h new file mode 100644 index 0000000..ef74fb1 --- /dev/null +++ b/sys/include/sys/filedesc.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_FILEDESC_H_ +#define _SYS_FILEDESC_H_ + +#include +#include +#include + +struct proc; + +struct filedesc { + int fdno; + off_t offset; + bool is_dir; + struct vnode *vnode; + struct spinlock lock; +}; + +#if defined(_KERNEL) +struct filedesc *fd_alloc(struct proc *td); +struct filedesc *fd_from_fdnum(const struct proc *td, int fdno); +void fd_close_fdnum(struct proc *td, int fdno); +#endif + +#endif diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index 7181ecb..c6046d7 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -32,11 +32,14 @@ #include #include +#include #include #include #include #include +#define PROC_MAX_FDS 256 + /* * A task running on the CPU e.g., a process or * a thread. @@ -49,6 +52,7 @@ struct proc { struct vas addrsp; uintptr_t stack_base; uint8_t is_user; + struct filedesc *fds[PROC_MAX_FDS]; TAILQ_ENTRY(proc) link; }; diff --git a/sys/kern/kern_filedesc.c b/sys/kern/kern_filedesc.c new file mode 100644 index 0000000..a943714 --- /dev/null +++ b/sys/kern/kern_filedesc.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +/* + * Allocate a file descriptor. + * + * @td: Thread to allocate from, NULL for current thread. + */ +struct filedesc * +fd_alloc(struct proc *td) +{ + struct filedesc *fd; + + if (td == NULL) { + td = this_td(); + __assert(td != NULL); + } + + for (size_t i = 0; i < PROC_MAX_FDS; ++i) { + if (td->fds[i] != NULL) { + continue; + } + + fd = dynalloc(sizeof(struct filedesc)); + memset(fd, 0, sizeof(struct filedesc)); + + if (fd == NULL) { + return NULL; + } + + fd->fdno = i; + td->fds[i] = fd; + return fd; + } + + return NULL; +} + +/* + * Fetch a file descriptor from a file descriptor + * number. + * + * @td: Thread to fetch from, NULL for current thread. + * @fdno: File descriptor to fetch + */ +struct filedesc * +fd_from_fdnum(const struct proc *td, int fdno) +{ + if (td == NULL) { + td = this_td(); + __assert(td != NULL); + } + + if (fdno < 0 || fdno > PROC_MAX_FDS) { + return NULL; + } + + for (size_t i = 0; i < PROC_MAX_FDS; ++i) { + if (i == fdno && td->fds[i] != NULL) { + return td->fds[i]; + } + } + + return NULL; +} + +/* + * Close a file descriptor from its fd number. + * + * @td: Thread to fetch from, NULL for current thread. + * @fdno: File descriptor number to close. + */ +void +fd_close_fdnum(struct proc *td, int fdno) +{ + struct filedesc *fd; + + if (td == NULL) { + td = this_td(); + __assert(td != NULL); + } + + fd = fd_from_fdnum(td, fdno); + if (fd == NULL) { + return; + } + + dynfree(fd); + td->fds[fdno] = NULL; +} diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index bd59e41..77aab54 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -268,6 +269,11 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, td->is_user = is_user; processor_init_pcb(td); + /* Allocate standard file descriptors */ + __assert(fd_alloc(td) != NULL); /* STDIN */ + __assert(fd_alloc(td) != NULL); /* STDOUT */ + __assert(fd_alloc(td) != NULL); /* STDERR */ + /* Setup trapframe */ if (!is_user) { init_frame(tf, rip, (uintptr_t)stack); @@ -294,6 +300,11 @@ sched_destroy_td(struct proc *td) dynfree((void *)td->stack_base); } + /* Close all of the file descriptors */ + for (size_t i = 0; i < PROC_MAX_FDS; ++i) { + fd_close_fdnum(td, i); + } + pmap_free_vas(vm_get_ctx(), td->addrsp); dynfree(td); } -- cgit v1.2.3 From 51a3988ec0ea1de35e47a999a76c14df05737a34 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sat, 16 Mar 2024 09:42:03 -0400 Subject: kernel: sched: Cleanup context switch comments Signed-off-by: Ian Moffett --- sys/kern/kern_sched.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 77aab54..7b3776d 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -360,18 +360,23 @@ sched_context_switch(struct trapframe *tf) return; } + /* + * If we have a thread currently running and we are switching + * to another, we shall save our current register state + * by copying the trapframe. + */ if (state->td != NULL) { - /* Save our trapframe */ td = state->td; memcpy(td->tf, tf, sizeof(struct trapframe)); } - /* Copy to stack */ + /* Copy over the next thread's register state to us */ memcpy(tf, next_td->tf, sizeof(struct trapframe)); td = state->td; state->td = next_td; + /* Re-enqueue the previous thread if it exists */ if (td != NULL) { sched_enqueue_td(td); } -- cgit v1.2.3 From 3db86a30644d3eb3a964202dbfd7e91c432bda7b Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sat, 16 Mar 2024 12:42:25 -0400 Subject: kernel: syscall: Remove syscall_args.ret It is better to just return a value within the syscall handler and have that passed down to __syscall() like that Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/syscall.c | 7 ++----- sys/include/sys/syscall.h | 3 +-- sys/kern/kern_syscall.c | 8 +++++--- 3 files changed, 8 insertions(+), 10 deletions(-) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/syscall.c b/sys/arch/amd64/amd64/syscall.c index 9b1f988..e80fe94 100644 --- a/sys/arch/amd64/amd64/syscall.c +++ b/sys/arch/amd64/amd64/syscall.c @@ -39,13 +39,10 @@ __syscall(struct trapframe *tf) .arg2 = tf->rcx, .arg3 = tf->r8, .arg4 = tf->r9, - .sp = tf->rsp, - .ret = tf->rax, + .sp = tf->rsp }; if (args.code < __MAX_SYSCALLS) { - g_syscall_table[tf->rax](&args); + tf->rax = g_syscall_table[tf->rax](&args); } - - tf->rax = args.ret; } diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h index 98a57f2..03eda0b 100644 --- a/sys/include/sys/syscall.h +++ b/sys/include/sys/syscall.h @@ -47,11 +47,10 @@ struct syscall_args { uint64_t arg0, arg1, arg2, arg3, arg4; uint64_t ip; uint64_t sp; - uint64_t ret; }; #if defined(_KERNEL) -extern void(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args); +extern uint64_t(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args); void __syscall(struct trapframe *tf); #endif diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c index 2c7215c..5a88bbb 100644 --- a/sys/kern/kern_syscall.c +++ b/sys/kern/kern_syscall.c @@ -30,21 +30,23 @@ #include #include #include +#include -static void +static uint64_t sys_debug(struct syscall_args *args) { /* TODO */ + return 0; } -__noreturn static void +__noreturn static uint64_t sys_exit(struct syscall_args *args) { sched_exit(); __builtin_unreachable(); } -void(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args) = { +uint64_t(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args) = { sys_debug, sys_exit, }; -- cgit v1.2.3 From f166b2303a96a5e65e235139291df93b2b24bc3e Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sat, 16 Mar 2024 13:03:19 -0400 Subject: kernel,libc: syscall: Improve syscall code - Remove the SYS_debug syscall - First syscall starts at 1 Signed-off-by: Ian Moffett --- lib/libc/include/sys/syscall.h | 1 - sys/arch/amd64/amd64/syscall.c | 5 +++-- sys/include/sys/syscall.h | 3 +-- sys/kern/kern_syscall.c | 8 -------- 4 files changed, 4 insertions(+), 13 deletions(-) (limited to 'sys') diff --git a/lib/libc/include/sys/syscall.h b/lib/libc/include/sys/syscall.h index b5e5fc2..34f762d 100644 --- a/lib/libc/include/sys/syscall.h +++ b/lib/libc/include/sys/syscall.h @@ -34,7 +34,6 @@ #include #endif -#define SYS_debug 0 #define SYS_exit 1 #if !defined(__ASSEMBLER__) diff --git a/sys/arch/amd64/amd64/syscall.c b/sys/arch/amd64/amd64/syscall.c index e80fe94..68235d5 100644 --- a/sys/arch/amd64/amd64/syscall.c +++ b/sys/arch/amd64/amd64/syscall.c @@ -42,7 +42,8 @@ __syscall(struct trapframe *tf) .sp = tf->rsp }; - if (args.code < __MAX_SYSCALLS) { - tf->rax = g_syscall_table[tf->rax](&args); + if (args.code < __MAX_SYSCALLS && args.code > 0) { + args.code -= 1; + tf->rax = g_syscall_table[args.code](&args); } } diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h index 03eda0b..66dc5f3 100644 --- a/sys/include/sys/syscall.h +++ b/sys/include/sys/syscall.h @@ -37,8 +37,7 @@ /* Do not reorder */ enum { - SYS_debug = 0, - SYS_exit, + SYS_exit = 1, __MAX_SYSCALLS }; diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c index 5a88bbb..b6e31d1 100644 --- a/sys/kern/kern_syscall.c +++ b/sys/kern/kern_syscall.c @@ -32,13 +32,6 @@ #include #include -static uint64_t -sys_debug(struct syscall_args *args) -{ - /* TODO */ - return 0; -} - __noreturn static uint64_t sys_exit(struct syscall_args *args) { @@ -47,6 +40,5 @@ sys_exit(struct syscall_args *args) } uint64_t(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args) = { - sys_debug, sys_exit, }; -- cgit v1.2.3