diff --git a/.github/workflows/build-os.yml b/.github/workflows/build-os.yml index bcc34da4..c3228977 100644 --- a/.github/workflows/build-os.yml +++ b/.github/workflows/build-os.yml @@ -49,18 +49,18 @@ jobs: - name: Build duckOS (Release) run: | - cd build/i386 - cmake ../.. -DCMAKE_TOOLCHAIN_FILE=build/i386/CMakeToolchain.txt -DCMAKE_BUILD_TYPE=Release + cd build/i686 + cmake ../.. -DCMAKE_TOOLCHAIN_FILE=build/i686/CMakeToolchain.txt -DCMAKE_BUILD_TYPE=Release make install - name: Make image run: | - cd build/i386 + cd build/i686 make image - name: Upload image uses: actions/upload-artifact@v3 with: name: Disk Image - path: build/i386/duckOS.img + path: build/i686/duckOS.img diff --git a/kernel/KernelMapper.cpp b/kernel/KernelMapper.cpp index 1586b3d3..eb0fa4a5 100644 --- a/kernel/KernelMapper.cpp +++ b/kernel/KernelMapper.cpp @@ -136,9 +136,9 @@ void KernelMapper::print_stacktrace(size_t ebp) { //Finally, get the symbol name and print auto* sym = KernelMapper::get_symbol(stk[1]); if(sym) - printf("0x%x %s\n", stk[1], sym->name); + printf("0x%lx %s\n", stk[1], sym->name); else - printf("0x%x\n", stk[1]); + printf("0x%lx\n", stk[1]); //Continue walking the stack stk = (size_t*) stk[0]; diff --git a/kernel/api/registers.h b/kernel/api/registers.h index 40dc0aec..368b9844 100644 --- a/kernel/api/registers.h +++ b/kernel/api/registers.h @@ -4,6 +4,8 @@ #pragma once #include "types.h" +#if defined(__i386__) + __DECL_BEGIN struct ptrace_registers { @@ -30,4 +32,5 @@ union PTraceRegisters { }; }; -#endif \ No newline at end of file +#endif +#endif // TODO: aarch64 \ No newline at end of file diff --git a/kernel/arch/aarch64/PageDirectory.cpp b/kernel/arch/aarch64/PageDirectory.cpp index d1f9e0a8..b18dde72 100644 --- a/kernel/arch/aarch64/PageDirectory.cpp +++ b/kernel/arch/aarch64/PageDirectory.cpp @@ -3,17 +3,9 @@ #include "kernel/kstd/vector.hpp" #include "kernel/tasking/TaskManager.h" -#include "kernel/kstd/defines.h" -#include "kernel/Atomic.h" #include "kernel/memory/MemoryManager.h" -#include "kernel/kstd/KLog.h" -#include "kernel/KernelMapper.h" -#include "kernel/kstd/cstring.h" #include "PageDirectory.h" -#include -#include "rpi/MMIO.h" - using namespace Aarch64; __attribute__((aligned(4096))) MMU::TableDescriptor __kernel_pgd[512]; @@ -21,15 +13,6 @@ __attribute__((aligned(4096))) MMU::TableDescriptor __kernel_pgd[512]; void PageDirectory::init_paging() { setup_kernel_map(); - auto map_range = [&](VirtualAddress vstart, VirtualAddress pstart, size_t size, VMProt prot, bool dev) { - size_t start_vpage = vstart / PAGE_SIZE; - size_t start_ppage = pstart / PAGE_SIZE; - size_t num_pages = ((vstart + size) / PAGE_SIZE) - start_vpage; - for(size_t i = 0; i < num_pages; i++) - if(MM.kernel_page_directory.map_page(start_vpage + i, start_ppage + i, prot, dev).is_error()) - PANIC("PAGING_INIT_FAIL", "Could not map the kernel when setting up paging."); - }; - map_range(RPi::MMIO::phys_base, RPi::MMIO::phys_base, RPi::MMIO::phys_size, VMProt::RW, true); asm volatile( "msr ttbr1_el1, %0 \n" diff --git a/kernel/arch/aarch64/Processor.cpp b/kernel/arch/aarch64/Processor.cpp index 57e7724b..a303e870 100644 --- a/kernel/arch/aarch64/Processor.cpp +++ b/kernel/arch/aarch64/Processor.cpp @@ -2,6 +2,7 @@ /* Copyright © 2016-2024 Byteduck */ #include "Processor.h" +#include void Processor::init() { @@ -44,3 +45,108 @@ void Processor::disable_interrupts() { void Processor::enable_interrupts() { } + +extern "C" void thread_first_entry() { + asm volatile ( + "ldp x0, x1, [sp, #0x00] \n" + "ldp x2, x3, [sp, #0x10] \n" + "ldp x4, x5, [sp, #0x20] \n" + "ldp x6, x7, [sp, #0x30] \n" + "ldp x8, x9, [sp, #0x40] \n" + "ldp x10, x11, [sp, #0x50] \n" + "ldp x12, x13, [sp, #0x60] \n" + "ldp x14, x15, [sp, #0x70] \n" + "ldp x16, x17, [sp, #0x80] \n" + "ldp x18, x19, [sp, #0x90] \n" + "ldp x20, x21, [sp, #0xa0] \n" + "ldp x22, x23, [sp, #0xb0] \n" + "ldp x24, x25, [sp, #0xc0] \n" + "ldp x26, x27, [sp, #0xd0] \n" + "ldp x28, x29, [sp, #0xe0] \n" + "ldr x30, [sp, #0xf0] \n" + "add sp, sp, #248 \n"); + printf("Cool!\n"); + while(1); +} + +ThreadRegisters Processor::initial_thread_registers(bool kernel, size_t entry, size_t sp) { + ThreadRegisters ret {}; + ret.elr_el1 = (size_t) thread_first_entry; + ret.gp.x30 = entry; + return ret; +} + +void Processor::switch_threads(Thread* old_thread, Thread* new_thread) { + asm volatile ( + "sub sp, sp, #248 \n" // Store GP + "stp x0, x1, [sp, #0x00] \n" + "stp x2, x3, [sp, #0x10] \n" + "stp x4, x5, [sp, #0x20] \n" + "stp x6, x7, [sp, #0x30] \n" + "stp x8, x9, [sp, #0x40] \n" + "stp x10, x11, [sp, #0x50] \n" + "stp x12, x13, [sp, #0x60] \n" + "stp x14, x15, [sp, #0x70] \n" + "stp x16, x17, [sp, #0x80] \n" + "stp x18, x19, [sp, #0x90] \n" + "stp x20, x21, [sp, #0xa0] \n" + "stp x22, x23, [sp, #0xb0] \n" + "stp x24, x25, [sp, #0xc0] \n" + "stp x26, x27, [sp, #0xd0] \n" + "stp x28, x29, [sp, #0xe0] \n" + "str x30, [sp, #0xf0] \n" + + "mov x0, sp \n" // Switch stacks + "str x0, %[old_sp] \n" + "ldr x0, =1f \n" + "str x0, %[old_ip] \n" + "ldr x0, %[new_sp] \n" + "mov sp, x0 \n" + + "ldr x0, %[new_ip] \n" + "br x0 \n" + + "1: \n" + "ldp x0, x1, [sp, #0x00] \n" // Load GP + "ldp x2, x3, [sp, #0x10] \n" + "ldp x4, x5, [sp, #0x20] \n" + "ldp x6, x7, [sp, #0x30] \n" + "ldp x8, x9, [sp, #0x40] \n" + "ldp x10, x11, [sp, #0x50] \n" + "ldp x12, x13, [sp, #0x60] \n" + "ldp x14, x15, [sp, #0x70] \n" + "ldp x16, x17, [sp, #0x80] \n" + "ldp x18, x19, [sp, #0x90] \n" + "ldp x20, x21, [sp, #0xa0] \n" + "ldp x22, x23, [sp, #0xb0] \n" + "ldp x24, x25, [sp, #0xc0] \n" + "ldp x26, x27, [sp, #0xd0] \n" + "ldp x28, x29, [sp, #0xe0] \n" + "ldr x30, [sp, #0xf0] \n" + "add sp, sp, #248 \n" + + : + "=m"(old_thread), + "=m"(new_thread), + [old_ip] "=m"(old_thread->registers.elr_el1), + [old_sp] "=m"(old_thread->registers.sp) + + : + [old_thread] "m"(old_thread), + [new_thread] "m"(new_thread), + [new_ip] "m" (new_thread->registers.elr_el1), + [new_sp] "m" (new_thread->registers.sp) + + : "memory", "x0"); +} + +void Processor::start_initial_thread(Thread* thread) { + asm volatile ( + "ldr x0, %[new_sp] \n" + "mov sp, x0 \n" + "ldr x0, =thread_first_entry \n" + "br x0 \n" + + :: [new_sp] "m"(thread->registers.sp) : "x0"); + ASSERT(false); +} diff --git a/kernel/arch/aarch64/Processor.h b/kernel/arch/aarch64/Processor.h index e3bcb552..97d31621 100644 --- a/kernel/arch/aarch64/Processor.h +++ b/kernel/arch/aarch64/Processor.h @@ -4,6 +4,9 @@ #pragma once #include +#include + +class Thread; class Processor { public: @@ -18,4 +21,7 @@ class Processor { static void send_eoi(int irq); static void disable_interrupts(); static void enable_interrupts(); + static ThreadRegisters initial_thread_registers(bool kernel, size_t entry, size_t user_stack); + static void switch_threads(Thread* old_thread, Thread* new_thread); + static void start_initial_thread(Thread* thread); }; \ No newline at end of file diff --git a/kernel/arch/aarch64/registers.h b/kernel/arch/aarch64/registers.h index ac03401f..737d2ec6 100644 --- a/kernel/arch/aarch64/registers.h +++ b/kernel/arch/aarch64/registers.h @@ -97,5 +97,57 @@ namespace Aarch64::Regs { return ret; } }; + + union GPRegisters { + uint64_t regs[31]; + struct { + uint64_t x0; + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + }; + }; } + +struct ISRRegisters {}; +struct ThreadRegisters { + Aarch64::Regs::GPRegisters gp; + uint64_t sp; + uint64_t spsr_el1; + uint64_t elr_el1; + uint64_t tpidr_el0; + uint64_t ttbr0_el1; +}; +struct IRQRegisters {}; +struct TrapFrame { + TrapFrame* prev; +}; + #endif \ No newline at end of file diff --git a/kernel/arch/i386/Processor.cpp b/kernel/arch/i386/Processor.cpp index 535dbe7e..e584e58f 100644 --- a/kernel/arch/i386/Processor.cpp +++ b/kernel/arch/i386/Processor.cpp @@ -8,6 +8,7 @@ #include "isr.h" #include "irq.h" #include "idt.h" +#include char Processor::s_vendor[sizeof(uint32_t) * 3 + 1]; CPUFeatures Processor::s_features = {}; @@ -90,3 +91,29 @@ void Processor::disable_interrupts() { void Processor::enable_interrupts() { asm volatile ("sti"); } + +ThreadRegisters Processor::initial_thread_registers(bool kernel, size_t entry, size_t user_stack) { + ThreadRegisters registers; + registers.iret.eflags = 0x202; + registers.iret.cs = kernel ? 0x8 : 0x1B; + registers.iret.eip = entry; + registers.gp.eax = 0; + registers.gp.ebx = 0; + registers.gp.ecx = 0; + registers.gp.edx = 0; + registers.gp.ebp = user_stack; + registers.gp.edi = 0; + registers.gp.esi = 0; + if (kernel) { + registers.seg.ds = 0x10; // ds + registers.seg.es = 0x10; // es + registers.seg.fs = 0x10; // fs + registers.seg.gs = 0x10; // gs + } else { + registers.seg.ds = 0x23; // ds + registers.seg.es = 0x23; // es + registers.seg.fs = 0x23; // fs + registers.seg.gs = 0x23; // gs + } + return registers; +} \ No newline at end of file diff --git a/kernel/arch/i386/Processor.h b/kernel/arch/i386/Processor.h index bbd6ae6a..72a2044d 100644 --- a/kernel/arch/i386/Processor.h +++ b/kernel/arch/i386/Processor.h @@ -5,8 +5,11 @@ #include "../../api/stdint.h" #include "CPUID.h" +#include "registers.h" +#include class IRQHandler; +class Thread; class Processor { public: @@ -25,6 +28,7 @@ class Processor { static void send_eoi(int irq); static void disable_interrupts(); static void enable_interrupts(); + static ThreadRegisters initial_thread_registers(bool kernel, size_t entry, size_t user_stack); private: diff --git a/kernel/arch/i386/isr.cpp b/kernel/arch/i386/isr.cpp index 3e38c17d..129c0eb3 100644 --- a/kernel/arch/i386/isr.cpp +++ b/kernel/arch/i386/isr.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include namespace Interrupt { TSS fault_tss; diff --git a/kernel/arch/registers.h b/kernel/arch/registers.h index 01261a0d..a258a9d6 100644 --- a/kernel/arch/registers.h +++ b/kernel/arch/registers.h @@ -5,4 +5,6 @@ #if defined(__i386__) #include "i386/registers.h" +#elif defined(__aarch64__) +#include "aarch64/registers.h" #endif \ No newline at end of file diff --git a/kernel/interrupt/IRQHandler.h b/kernel/interrupt/IRQHandler.h index d9d83efb..d7f4e876 100644 --- a/kernel/interrupt/IRQHandler.h +++ b/kernel/interrupt/IRQHandler.h @@ -20,7 +20,7 @@ #pragma once #include -#include +#include class IRQHandler { public: diff --git a/kernel/memory/Memory.h b/kernel/memory/Memory.h index 4d301a14..ff38cd96 100644 --- a/kernel/memory/Memory.h +++ b/kernel/memory/Memory.h @@ -5,7 +5,7 @@ #include "../kstd/kstddef.h" #include "../api/page_size.h" -#include +#include #if defined(__i386__) #define HIGHER_HALF 0xC0000000 diff --git a/kernel/memory/MemoryManager.cpp b/kernel/memory/MemoryManager.cpp index 8817441f..87a9b035 100644 --- a/kernel/memory/MemoryManager.cpp +++ b/kernel/memory/MemoryManager.cpp @@ -23,12 +23,15 @@ #include "MemoryManager.h" #include #include "AnonymousVMObject.h" -#include #include #include #include #include +#if defined(__i386__) +#include +#endif + size_t used_kheap_mem; uint8_t early_kheap_memory[0x200000]; // 2MiB @@ -148,8 +151,6 @@ void MemoryManager::page_fault_handler(ISRRegisters* regs) { uint32_t err_pos; #if defined(__i386__) asm volatile ("mov %%cr2, %0" : "=r" (err_pos)); -#endif - // TODO: aarch64 switch (regs->err_code) { case FAULT_KERNEL_READ: PANIC("KRNL_READ_NONPAGED_AREA", "0x%x", err_pos); @@ -170,6 +171,8 @@ void MemoryManager::page_fault_handler(ISRRegisters* regs) { default: PANIC("UNKNOWN_PAGE_FAULT", "0x%x", err_pos); } +#endif + // TODO: aarch64 } void MemoryManager::invlpg(void* vaddr) { diff --git a/kernel/memory/MemoryManager.h b/kernel/memory/MemoryManager.h index af2dca3a..8904161a 100644 --- a/kernel/memory/MemoryManager.h +++ b/kernel/memory/MemoryManager.h @@ -27,7 +27,7 @@ #include "VMSpace.h" #include #include "Memory.h" -#include "kernel/arch/i386/registers.h" +#include "kernel/arch/registers.h" #include /** diff --git a/kernel/syscall/ptrace.cpp b/kernel/syscall/ptrace.cpp index cd8058bc..b5d9e642 100644 --- a/kernel/syscall/ptrace.cpp +++ b/kernel/syscall/ptrace.cpp @@ -47,6 +47,7 @@ int Process::sys_ptrace(UserspacePointer args_ptr) { switch (args.request) { case PTRACE_GETREGS: { +#if defined(__i386__) auto frame = tracer->tracee_thread()->cur_trap_frame(); if (!frame) return -EFAULT; @@ -75,6 +76,9 @@ int Process::sys_ptrace(UserspacePointer args_ptr) { break; } return SUCCESS; +#elif defined(__aarch64__) + return ENOTSUP; // TODO: aarch64 +#endif } case PTRACE_CONT: diff --git a/kernel/syscall/syscall.cpp b/kernel/syscall/syscall.cpp index 5d613778..dfeff6a5 100644 --- a/kernel/syscall/syscall.cpp +++ b/kernel/syscall/syscall.cpp @@ -24,12 +24,14 @@ #include "kernel/memory/SafePointer.h" void syscall_handler(ThreadRegisters& regs){ +#if defined(__i386__) TrapFrame frame { nullptr, TrapFrame::Syscall, ®s }; TaskManager::current_thread()->enter_trap_frame(&frame); TaskManager::current_thread()->enter_syscall(); regs.gp.eax = handle_syscall(regs, regs.gp.eax, regs.gp.ebx, regs.gp.ecx, regs.gp.edx); TaskManager::current_thread()->leave_syscall(); TaskManager::current_thread()->exit_trap_frame(); +#endif // TODO: aarch64 } int handle_syscall(ThreadRegisters& regs, size_t call, size_t arg1, size_t arg2, size_t arg3) { diff --git a/kernel/syscall/syscall.h b/kernel/syscall/syscall.h index 2c70c0d8..ded7fbee 100644 --- a/kernel/syscall/syscall.h +++ b/kernel/syscall/syscall.h @@ -21,7 +21,7 @@ #include "../kstd/kstddef.h" #include "syscall_numbers.h" -#include "../arch/i386/registers.h" +#include "../arch/registers.h" extern "C" void syscall_handler(ThreadRegisters& regs); int handle_syscall(ThreadRegisters& regs, size_t call, size_t arg1, size_t arg2, size_t arg3); diff --git a/kernel/tasking/TaskManager.cpp b/kernel/tasking/TaskManager.cpp index 8cbe64dd..4962c16e 100644 --- a/kernel/tasking/TaskManager.cpp +++ b/kernel/tasking/TaskManager.cpp @@ -183,6 +183,8 @@ void TaskManager::init(){ // TODO: AARCH64 #if defined (__i686__) preempt_init_asm(cur_thread->registers.gp.esp); +#elif defined(__aarch64__) + Processor::start_initial_thread(cur_thread.get()); #endif } @@ -277,12 +279,6 @@ bool TaskManager::yield() { } } -bool TaskManager::yield_if_not_preempting() { - if(!preempting) - return yield(); - return true; -} - bool TaskManager::yield_if_idle() { if(!kernel_process) return false; @@ -356,9 +352,15 @@ void TaskManager::preempt(){ if(!old_thread) { old_esp = &dummy_esp; } if(old_thread->in_signal_handler()) { + // TODO: aarch64 +#if defined (__i386__) old_esp = &old_thread->signal_registers.gp.esp; +#endif } else { + // TODO: aarch64 +#if defined (__i386__) old_esp = &old_thread->registers.gp.esp; +#endif } //If we just finished handling a signal, set in_signal_handler to false. @@ -378,10 +380,16 @@ void TaskManager::preempt(){ //If we're switching to a process in a signal handler, use the esp from signal_registers uint32_t* new_esp; if(next_thread->in_signal_handler()) { + // TODO: aarch64 +#if defined (__i386__) new_esp = &next_thread->signal_registers.gp.esp; +#endif tss.esp0 = (size_t) next_thread->signal_stack_top(); } else { + // TODO: aarch64 +#if defined (__i386__) new_esp = &next_thread->registers.gp.esp; +#endif tss.esp0 = (size_t) next_thread->kernel_stack_top(); } @@ -405,6 +413,8 @@ void TaskManager::preempt(){ // TODO: AARCH64 #if defined(__i386__) preempt_asm(old_esp, new_esp, cur_thread->page_directory()->entries_physaddr()); +#elif defined(__aarch64__) + Processor::switch_threads(old_thread.get(), cur_thread.get()); #endif Processor::load_fpu_state((void*&) cur_thread->fpu_state); } diff --git a/kernel/tasking/TaskManager.h b/kernel/tasking/TaskManager.h index 83f64ede..55fd05d2 100644 --- a/kernel/tasking/TaskManager.h +++ b/kernel/tasking/TaskManager.h @@ -72,7 +72,6 @@ namespace TaskManager { void kill_pgid(pid_t pgid, int sig); bool yield(); - bool yield_if_not_preempting(); bool yield_if_idle(); void do_yield_async(); void tick(); diff --git a/kernel/tasking/Thread.cpp b/kernel/tasking/Thread.cpp index ad4035e2..f8628531 100644 --- a/kernel/tasking/Thread.cpp +++ b/kernel/tasking/Thread.cpp @@ -29,6 +29,7 @@ #include "../memory/AnonymousVMObject.h" #include "Reaper.h" #include "WaitBlocker.h" +#include Thread::Thread(Process* process, tid_t tid, size_t entry_point, ProcessArgs* args): _tid(tid), @@ -58,27 +59,7 @@ Thread::Thread(Process* process, tid_t tid, size_t entry_point, ProcessArgs* arg } //Setup registers - registers.iret.eflags = 0x202; - registers.iret.cs = _process->_kernel_mode ? 0x8 : 0x1B; - registers.iret.eip = entry_point; - registers.gp.eax = 0; - registers.gp.ebx = 0; - registers.gp.ecx = 0; - registers.gp.edx = 0; - registers.gp.ebp = user_stack.real_stackptr(); - registers.gp.edi = 0; - registers.gp.esi = 0; - if(_process->_kernel_mode) { - registers.seg.ds = 0x10; // ds - registers.seg.es = 0x10; // es - registers.seg.fs = 0x10; // fs - registers.seg.gs = 0x10; // gs - } else { - registers.seg.ds = 0x23; // ds - registers.seg.es = 0x23; // es - registers.seg.fs = 0x23; // fs - registers.seg.gs = 0x23; // gs - } + registers = Processor::initial_thread_registers(_process->_kernel_mode, entry_point, user_stack.real_stackptr()); //Set up the user stack for the program arguments args->setup_stack(user_stack); @@ -101,9 +82,13 @@ Thread::Thread(Process* process, tid_t tid, ThreadRegisters& regs): _kernel_stack_region = MM.alloc_kernel_stack_region(THREAD_KERNEL_STACK_SIZE); //Setup registers and stack +#if defined(__i386__) registers.gp.eax = 0; // fork() in child returns zero Stack stack((void*) (_kernel_stack_region->start() + _kernel_stack_region->size())); setup_kernel_stack(stack, regs.iret.esp, registers); +#elif defined(__aarch64__) + // TODO: aarch64 +#endif } Thread::Thread(Process* process, tid_t tid, void* (*entry_func)(void* (*)(void*), void*), void* (* thread_func)(void*), void* arg): @@ -135,27 +120,7 @@ Thread::Thread(Process* process, tid_t tid, void* (*entry_func)(void* (*)(void*) } //Setup registers - registers.iret.eflags = 0x202; - registers.iret.cs = _process->_kernel_mode ? 0x8 : 0x1B; - registers.iret.eip = (size_t) entry_func; - registers.gp.eax = 0; - registers.gp.ebx = 0; - registers.gp.ecx = 0; - registers.gp.edx = 0; - registers.gp.ebp = user_stack.real_stackptr(); - registers.gp.edi = 0; - registers.gp.esi = 0; - if(_process->_kernel_mode) { - registers.seg.ds = 0x10; // ds - registers.seg.es = 0x10; // es - registers.seg.fs = 0x10; // fs - registers.seg.gs = 0x10; // gs - } else { - registers.seg.ds = 0x23; // ds - registers.seg.es = 0x23; // es - registers.seg.fs = 0x23; // fs - registers.seg.gs = 0x23; // gs - } + registers = Processor::initial_thread_registers(_process->_kernel_mode, (size_t) entry_func, user_stack.real_stackptr()); //Set up the user stack for the thread arguments user_stack.push((size_t) arg); @@ -452,27 +417,7 @@ bool Thread::call_signal_handler(int signal) { user_stack.push(SIGNAL_RETURN_FAKE_ADDR); //Setup signal registers - signal_registers.iret.eflags = 0x202; - signal_registers.iret.cs = _process->_kernel_mode ? 0x8 : 0x1B; - signal_registers.iret.eip = signal_loc; - signal_registers.gp.eax = 0; - signal_registers.gp.ebx = 0; - signal_registers.gp.ecx = 0; - signal_registers.gp.edx = 0; - signal_registers.gp.ebp = user_stack.real_stackptr(); - signal_registers.gp.edi = 0; - signal_registers.gp.esi = 0; - if(_process->_kernel_mode) { - signal_registers.seg.ds = 0x10; // ds - signal_registers.seg.es = 0x10; // es - signal_registers.seg.fs = 0x10; // fs - signal_registers.seg.gs = 0x10; // gs - } else { - signal_registers.seg.ds = 0x23; // ds - signal_registers.seg.es = 0x23; // es - signal_registers.seg.fs = 0x23; // fs - signal_registers.seg.gs = 0x23; // gs - } + signal_registers = Processor::initial_thread_registers(_process->_kernel_mode, signal_loc, user_stack.real_stackptr()); //Set up the stack setup_kernel_stack(kernel_stack, user_stack.real_stackptr(), signal_registers); @@ -523,6 +468,7 @@ void Thread::handle_pagefault(PageFault fault) { auto space = fault.address >= HIGHER_HALF ? MM.kernel_space() : m_vm_space; //Otherwise, try CoW and kill the process if it doesn't work +#if defined(__i386__) if(space->try_pagefault(fault).is_error()) { if(fault.registers->interrupt_frame.eip > HIGHER_HALF) { PANIC("SYSCALL_PAGEFAULT", "A page fault occurred in the kernel (pid: %d, tid: %d, ptr: 0x%x, ip: 0x%x).", _process->pid(), _tid, fault.address, fault.registers->interrupt_frame.eip); @@ -531,6 +477,8 @@ void Thread::handle_pagefault(PageFault fault) { fault.address, fault.registers->interrupt_frame.eip); _process->kill(SIGSEGV); } +#endif + // TODO: aarch64 } void Thread::enqueue_thread(Thread* thread) { @@ -576,6 +524,7 @@ void Thread::trace_detach() { } void Thread::setup_kernel_stack(Stack& kernel_stack, size_t user_stack_ptr, ThreadRegisters& regs) { +#if defined(__i386__) //If usermode, push ss and useresp if(__builtin_expect(!is_kernel_mode(), true)) { kernel_stack.push(0x23); //ss @@ -610,6 +559,12 @@ void Thread::setup_kernel_stack(Stack& kernel_stack, size_t user_stack_ptr, Thre regs.gp.esp = (size_t) kernel_stack.stackptr(); regs.iret.esp = (size_t) user_stack_ptr; +#elif defined(__aarch64__) + // Push GP registers + for (auto i = 0; i < 31; i++) + kernel_stack.push(regs.gp.regs[i]); + regs.sp = (size_t) kernel_stack.stackptr(); +#endif } void Thread::exit(void* return_value) { diff --git a/kernel/tasking/Thread.h b/kernel/tasking/Thread.h index a316fbbb..898e8f2e 100644 --- a/kernel/tasking/Thread.h +++ b/kernel/tasking/Thread.h @@ -31,7 +31,7 @@ #include "kernel/kstd/circular_queue.hpp" #include "../kstd/KLog.h" #include "Tracer.h" -#include +#include #define THREAD_STACK_SIZE 1048576 //1024KiB #define THREAD_KERNEL_STACK_SIZE 524288 //512KiB