mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
working sleep syscall
yes it turns out it was 100% completely broken before
This commit is contained in:
@@ -193,7 +193,9 @@ void stress_tester() {
|
||||
void user_task() {
|
||||
while (true) {
|
||||
putchar('h');
|
||||
__builtin_ia32_pause();
|
||||
putchar('i');
|
||||
putchar('\n');
|
||||
sleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ _syscall_entrypoint:
|
||||
; Do very complicated stuff here
|
||||
call syscall_impl
|
||||
|
||||
mov r11, 0x10016 ; TASK_POINTER->entry_ksp_val
|
||||
mov r11, 0x10016 ; TASK_POINTER->ret_sp_val
|
||||
mov rsp, [r11]
|
||||
mov rcx, r15
|
||||
o64 sysret
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
#include "misc.hpp"
|
||||
#include "tty.hpp"
|
||||
|
||||
// Don't forget the correct order
|
||||
// Shockingly, it doesn't immediately break and even something simple as putchar works
|
||||
// even with completely broken 16-bit segments somehow
|
||||
// But what happens with something more complex is completely bonkers
|
||||
struct STAR {
|
||||
unsigned ret_cs_ss : 16;
|
||||
unsigned call_cs_ss : 16;
|
||||
unsigned unused : 32;
|
||||
unsigned call_cs_ss : 16;
|
||||
unsigned ret_cs_ss : 16;
|
||||
} __attribute__((packed));
|
||||
|
||||
static_assert(sizeof(STAR) == 8);
|
||||
@@ -46,10 +50,17 @@ uint64_t syscall_putchar(char c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t syscall_sleep(uint64_t micros) {
|
||||
sleep_self(micros);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" uint64_t syscall_impl(uint64_t id_rdi, uint64_t a1_rsi, uint64_t a2_rdx, uint64_t a3_rcx) {
|
||||
switch (id_rdi) {
|
||||
case SYSCALL_PUTCHAR_ID:
|
||||
return syscall_putchar(a1_rsi);
|
||||
case SYSCALL_SLEEP_ID:
|
||||
return syscall_sleep(a1_rsi);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,11 @@ void sanity_check_frame(struct task_frame *cur_frame) {
|
||||
assert2((void *) cur_frame->ip != NULL, "Sanity check");
|
||||
assert2((void *) cur_frame->sp != NULL, "Sanity check");
|
||||
assert2(cur_frame->guard == IDT_GUARD, "IDT Guard wrong!");
|
||||
assert2((cur_frame->ss == GDTSEL(gdt_data) || cur_frame->ss == GDTSEL(gdt_data_user)) | 0x3, "SS wrong!");
|
||||
assert(cur_frame->ss != 0);
|
||||
assert(cur_frame->cs != 0);
|
||||
assert(cur_frame->sp != 0);
|
||||
assert2((cur_frame->ss == GDTSEL(gdt_data) || (cur_frame->ss == GDTSEL(gdt_data_user)) | 0x3), "SS wrong!");
|
||||
assert2((cur_frame->cs == GDTSEL(gdt_code) || (cur_frame->ss == GDTSEL(gdt_code_user)) | 0x3), "CS wrong!");
|
||||
}
|
||||
|
||||
std::atomic<uint64_t> max_pid = 0;
|
||||
@@ -158,8 +162,8 @@ struct Task *new_utask(void (*fn)(), const char *name) {
|
||||
assert((newt->entry_ksp_val & 0xFULL) == 0);
|
||||
|
||||
taskptr_real->taskptr = newt;
|
||||
taskptr_real->entry_ksp_val = &newt->entry_ksp_val;
|
||||
taskptr_real->ret_sp = 0xFEFE;
|
||||
taskptr_real->entry_ksp_val = newt->entry_ksp_val;
|
||||
taskptr_real->ret_sp = 0x0;
|
||||
|
||||
void *ustack = newt->vma->mmap_mem(NULL, TASK_SS, 0, PAGE_RW | PAGE_USER);
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ struct Task {
|
||||
|
||||
struct task_pointer {
|
||||
Task *taskptr;
|
||||
uint64_t *entry_ksp_val;
|
||||
uint64_t entry_ksp_val;
|
||||
uint64_t ret_sp;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
@@ -22,8 +22,7 @@ void VMA::mark_taken(void *addr, size_t length) {
|
||||
|
||||
void VMA::map_kern() {
|
||||
LockGuard l(space_lock);
|
||||
for (uintptr_t i = (uint64_t) (0xFFFF800000000000ULL >> 39) & 0x01FF; i < 512; i++) {
|
||||
assert(i >= 256);
|
||||
for (uintptr_t i = 256; i < 512; i++) {
|
||||
space->get_cr3()[i] = KERN_AddressSpace->get_cr3()[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define SYSCALL_PUTCHAR_ID 1
|
||||
#define SYSCALL_SLEEP_ID 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -13,4 +13,14 @@ uint64_t putchar(char c) {
|
||||
: "Di"(id), "Si"(c)
|
||||
: "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
uint64_t sleep(uint64_t micros) {
|
||||
uint64_t res;
|
||||
uint64_t id = SYSCALL_SLEEP_ID;
|
||||
asm("syscall"
|
||||
: "=r"(res)
|
||||
: "Di"(id), "Si"(micros)
|
||||
: "memory");
|
||||
return res;
|
||||
}
|
||||
@@ -13,6 +13,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
uint64_t putchar(char c);
|
||||
uint64_t sleep(uint64_t micros);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user