mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
working syscalls!!!!!
This commit is contained in:
@@ -10,4 +10,6 @@
|
||||
#define KERN_STACK_SIZE (1024 * 1024)
|
||||
extern uint64_t KERN_stack[KERN_STACK_SIZE] __attribute__((aligned(16)));
|
||||
|
||||
#define TASK_POINTER 0x10000
|
||||
|
||||
#endif//OS1_GLOBALS_H
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "mutex.hpp"
|
||||
#include "rand.h"
|
||||
#include "syscalls.hpp"
|
||||
#include "syscalls_interface.h"
|
||||
#include "task.hpp"
|
||||
#include "timer.hpp"
|
||||
#include "tty.hpp"
|
||||
@@ -191,7 +192,7 @@ void stress_tester() {
|
||||
|
||||
void user_task() {
|
||||
while (true) {
|
||||
asm("syscall");
|
||||
putchar('h');
|
||||
__builtin_ia32_pause();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,22 @@
|
||||
[BITS 64]
|
||||
|
||||
extern syscall_impl
|
||||
|
||||
section .text
|
||||
global _syscall_entrypoint:function (_syscall_entrypoint.end - _syscall_entrypoint)
|
||||
_syscall_entrypoint:
|
||||
sysret
|
||||
; TODO: make it synced somehow
|
||||
mov r11, 0x10016 ; TASK_POINTER->ret_sp_val
|
||||
mov [r11], rsp
|
||||
mov r11, 0x10008 ; TASK_POINTER->entry_ksp_val
|
||||
mov rsp, [r11]
|
||||
mov r15, rcx
|
||||
|
||||
; Do very complicated stuff here
|
||||
call syscall_impl
|
||||
|
||||
mov r11, 0x10016 ; TASK_POINTER->entry_ksp_val
|
||||
mov rsp, [r11]
|
||||
mov rcx, r15
|
||||
o64 sysret
|
||||
.end:
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
//
|
||||
|
||||
#include "syscalls.hpp"
|
||||
#include "syscalls_defs.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "asserts.hpp"
|
||||
#include "gdt.hpp"
|
||||
#include "misc.hpp"
|
||||
#include "tty.hpp"
|
||||
|
||||
struct STAR {
|
||||
unsigned ret_cs_ss : 16;
|
||||
@@ -37,4 +39,18 @@ void setup_syscalls() {
|
||||
wrmsr(0xc0000084, 0);
|
||||
|
||||
wrmsr(0xC0000080, rdmsr(0xC0000080) | 0b1);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t syscall_putchar(char c) {
|
||||
all_tty_putchar(c);
|
||||
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);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
#ifndef OS2_SYSCALLS_HPP
|
||||
#define OS2_SYSCALLS_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
void setup_syscalls();
|
||||
|
||||
extern "C" void _syscall_entrypoint();
|
||||
extern "C" uint64_t syscall_impl(uint64_t id_rdi, uint64_t a1_rsi, uint64_t a2_rdx, uint64_t a3_rcx);
|
||||
|
||||
#endif//OS2_SYSCALLS_HPP
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
%include "task.inc.asm"
|
||||
|
||||
extern switch_task
|
||||
extern gdt_code
|
||||
extern gdt_null
|
||||
extern gdt_data
|
||||
|
||||
; FIXME: 75% chance this leaks stack or something
|
||||
section .text
|
||||
@@ -14,12 +11,8 @@ _yield_self_kern:
|
||||
pop rsi ; save the return ip
|
||||
mov r8, rsp ; save cur sp
|
||||
|
||||
mov r10, gdt_null
|
||||
mov r9, gdt_data
|
||||
mov r11, gdt_code
|
||||
|
||||
sub r9, r10
|
||||
sub r11, r10
|
||||
mov r9, ss
|
||||
mov r11, cs
|
||||
|
||||
PUSH r9; Push data segment
|
||||
push r8 ; current sp
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "VMA.hpp"
|
||||
#include "asserts.hpp"
|
||||
#include "gdt.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "kmem.hpp"
|
||||
#include "misc.hpp"
|
||||
#include "mutex.hpp"
|
||||
@@ -20,7 +21,8 @@
|
||||
char temp_fxsave[512] __attribute__((aligned(16)));
|
||||
|
||||
void sanity_check_frame(struct task_frame *cur_frame) {
|
||||
assert((((uintptr_t) cur_frame) & 0xFULL) == 0);
|
||||
// TODO: This makes sense to check when entering, but not when switching
|
||||
// assert((((uintptr_t) cur_frame) & 0xFULL) == 0);
|
||||
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!");
|
||||
@@ -125,7 +127,7 @@ struct Task *new_ktask(void (*fn)(), const char *name) {
|
||||
return newt;
|
||||
}
|
||||
struct Task *new_utask(void (*fn)(), const char *name) {
|
||||
struct Task *newt = static_cast<Task *>(kmalloc(sizeof(struct Task)));
|
||||
Task *newt = static_cast<Task *>(kmalloc(sizeof(struct Task)));
|
||||
newt->kstack = static_cast<uint64_t *>(kmalloc(TASK_SS));
|
||||
newt->name = static_cast<char *>(kmalloc(strlen(name) + 1));
|
||||
newt->fxsave = static_cast<char *>(kmalloc(512));
|
||||
@@ -146,7 +148,20 @@ struct Task *new_utask(void (*fn)(), const char *name) {
|
||||
newt->pid = max_pid.fetch_add(1);
|
||||
newt->used_time = 0;
|
||||
|
||||
void *ustack = newt->vma->mmap_mem_any(TASK_SS, 0, 0);
|
||||
task_pointer *taskptr = static_cast<task_pointer *>(newt->vma->mmap_mem(reinterpret_cast<void *>(TASK_POINTER), sizeof(task_pointer), 0, PAGE_RW));
|
||||
assert((uintptr_t) taskptr == TASK_POINTER);
|
||||
|
||||
task_pointer *taskptr_real = reinterpret_cast<task_pointer *>(HHDM_P2V(newt->addressSpace->virt2real(taskptr)));
|
||||
|
||||
newt->entry_ksp_val = ((((uintptr_t) newt->kstack) + (TASK_SS - 9) - 1) & (~0xFULL));// Ensure 16byte alignment
|
||||
// It should be aligned before call, therefore it actually should be aligned here
|
||||
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;
|
||||
|
||||
void *ustack = newt->vma->mmap_mem(NULL, TASK_SS, 0, PAGE_RW | PAGE_USER);
|
||||
|
||||
newt->frame.sp = ((((uintptr_t) ustack) + (TASK_SS - 17) - 1) & (~0xFULL)) + 8;// Ensure 16byte alignment
|
||||
// It should be aligned before call, therefore on function entry it should be misaligned by 8 bytes
|
||||
@@ -212,9 +227,7 @@ void sleep_self(uint64_t diff) {
|
||||
void yield_self() {
|
||||
if (!RunningTask) return;
|
||||
NO_INT(
|
||||
if (RunningTask->val->mode == TASKMODE_KERN) {
|
||||
_yield_self_kern();
|
||||
})
|
||||
_yield_self_kern();)
|
||||
}
|
||||
|
||||
static void task_waker() {
|
||||
|
||||
@@ -28,6 +28,7 @@ struct AddressSpace;
|
||||
class VMA;
|
||||
|
||||
struct Task {
|
||||
uint64_t entry_ksp_val;
|
||||
struct task_frame frame;
|
||||
uint64_t pid;
|
||||
std::atomic<uint64_t> used_time;
|
||||
@@ -41,6 +42,12 @@ struct Task {
|
||||
enum TaskState state;
|
||||
};
|
||||
|
||||
struct task_pointer {
|
||||
Task *taskptr;
|
||||
uint64_t *entry_ksp_val;
|
||||
uint64_t ret_sp;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct Task *cur_task();
|
||||
List<Task *>::Node *extract_running_task_node();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
target_include_directories(kernel.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_sources(kernel.elf PRIVATE mutex.cpp cppsupport.cpp Spinlock.cpp LockGuard.cpp rand.cpp VMA.cpp asserts.cpp)
|
||||
target_sources(kernel.elf PRIVATE mutex.cpp cppsupport.cpp Spinlock.cpp LockGuard.cpp rand.cpp VMA.cpp asserts.cpp syscalls_interface.c)
|
||||
|
||||
add_subdirectory(templates)
|
||||
@@ -38,21 +38,25 @@ void *VMA::mmap_phys(void *v_addr, void *real_addr, size_t length, int flags) {
|
||||
return v_addr;
|
||||
}
|
||||
|
||||
void *VMA::mmap_mem_any(size_t length, int prot, int flags) {
|
||||
if ((length & PAGE_SIZE) != 0) {
|
||||
void *VMA::mmap_mem(void *v_addr, size_t length, int prot, int flags) {
|
||||
if ((length & (PAGE_SIZE - 1)) != 0) {
|
||||
length += PAGE_SIZE - 1;
|
||||
length &= ~PAGE_SIZE;
|
||||
length &= ~(PAGE_SIZE - 1);
|
||||
}
|
||||
assert((length & PAGE_SIZE) == 0);
|
||||
assert((length & (PAGE_SIZE - 1)) == 0);
|
||||
uint64_t page_len = length / PAGE_SIZE;
|
||||
|
||||
std::optional<ListEntry> found;
|
||||
{
|
||||
LockGuard l(regions_lock);
|
||||
|
||||
for (auto &n: regions) {
|
||||
if (n.data.available && n.data.length >= length) {
|
||||
found = n.data;
|
||||
if (v_addr) {
|
||||
found = regions.find((uintptr_t) v_addr)->data;
|
||||
} else {
|
||||
for (auto &n: regions) {
|
||||
if (n.data.available && n.data.length >= length) {
|
||||
found = n.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) return nullptr;
|
||||
@@ -65,7 +69,7 @@ void *VMA::mmap_mem_any(size_t length, int prot, int flags) {
|
||||
void *p = get4k();
|
||||
{
|
||||
LockGuard l(space_lock);
|
||||
space->map(reinterpret_cast<void *>(found->begin + i * PAGE_SIZE), (void *) HHDM_V2P(p), PAGE_RW | PAGE_USER);
|
||||
space->map(reinterpret_cast<void *>(found->begin + i * PAGE_SIZE), (void *) HHDM_V2P(p), flags);
|
||||
}
|
||||
}
|
||||
return reinterpret_cast<void *>(found->begin);
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
/// By linking them to same entries as kernel
|
||||
void map_kern();
|
||||
void *mmap_phys(void *v_addr, void *real_addr, size_t length, int flags);
|
||||
void *mmap_mem_any(size_t length, int prot, int flags);
|
||||
void *mmap_mem(void *v_addr, size_t length, int prot, int flags);
|
||||
int munmap(void *addr, size_t length);
|
||||
|
||||
private:
|
||||
|
||||
21
src/kernel/syscalls_defs.h
Normal file
21
src/kernel/syscalls_defs.h
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 26.10.2023.
|
||||
//
|
||||
|
||||
#ifndef OS2_SYSCALLS_DEFS_H
|
||||
#define OS2_SYSCALLS_DEFS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
extern "C" {
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define SYSCALL_PUTCHAR_ID 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//OS2_SYSCALLS_DEFS_H
|
||||
16
src/kernel/syscalls_interface.c
Normal file
16
src/kernel/syscalls_interface.c
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 26.10.2023.
|
||||
//
|
||||
|
||||
#include "syscalls_interface.h"
|
||||
#include "syscalls_defs.h"
|
||||
|
||||
uint64_t putchar(char c) {
|
||||
uint64_t res;
|
||||
uint64_t id = SYSCALL_PUTCHAR_ID;
|
||||
asm("syscall"
|
||||
: "=r"(res)
|
||||
: "Di"(id), "Si"(c)
|
||||
: "memory");
|
||||
return res;
|
||||
}
|
||||
21
src/kernel/syscalls_interface.h
Normal file
21
src/kernel/syscalls_interface.h
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 26.10.2023.
|
||||
//
|
||||
|
||||
#ifndef OS2_SYSCALLS_INTERFACE_H
|
||||
#define OS2_SYSCALLS_INTERFACE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
extern "C" {
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
uint64_t putchar(char c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//OS2_SYSCALLS_INTERFACE_H
|
||||
Reference in New Issue
Block a user