diff --git a/kernel/KernelMapper.cpp b/kernel/KernelMapper.cpp index 51261c4a..82783396 100644 --- a/kernel/KernelMapper.cpp +++ b/kernel/KernelMapper.cpp @@ -105,12 +105,16 @@ KernelMapper::Symbol* KernelMapper::get_symbol(size_t location) { printf("Add -DADD_KERNEL_DEBUG_SYMBOLS:BOOL=ON to your CMake arguments to compile with debug symbols.\n"); void KernelMapper::print_stacktrace() { + print_stacktrace((size_t) __builtin_frame_address(0)); +} + +void KernelMapper::print_stacktrace(size_t ebp) { #ifdef DUCKOS_KERNEL_DEBUG_SYMBOLS if(!symbols) printf("[Symbols not available yet]\n"); //Start walking the stack - auto* stk = (uint32_t*) __builtin_frame_address(0); + auto* stk = (uint32_t*) ebp; for(unsigned int frame = 0; stk && frame < 4096; frame++) { if(!MM.kernel_page_directory.is_mapped((VirtualAddress) stk, false)) diff --git a/kernel/KernelMapper.h b/kernel/KernelMapper.h index a5efd942..6c39eba2 100644 --- a/kernel/KernelMapper.h +++ b/kernel/KernelMapper.h @@ -31,6 +31,7 @@ class KernelMapper { static void load_map(); static Symbol* get_symbol(size_t location); static void print_stacktrace(); + static void print_stacktrace(size_t ebp); static void print_userspace_stacktrace(); }; diff --git a/kernel/StackWalker.cpp b/kernel/StackWalker.cpp index 274057cc..a0dca41f 100644 --- a/kernel/StackWalker.cpp +++ b/kernel/StackWalker.cpp @@ -12,7 +12,7 @@ StackWalker::Frame* StackWalker::walk_stack(const kstd::Arc& thread, uin else if (thread == TaskManager::current_thread()) cur_frame = (Frame*) __builtin_frame_address(0); else - cur_frame = ((Frame*) (thread->in_signal_handler() ? thread->signal_registers.esp : thread->registers.esp))->next_frame; + cur_frame = ((Frame*) (thread->in_signal_handler() ? thread->signal_registers.gp.esp : thread->registers.gp.esp))->next_frame; size_t count = 0; @@ -38,4 +38,4 @@ StackWalker::Frame* StackWalker::walk_stack(const kstd::Arc& thread, uin } return cur_frame; -} \ No newline at end of file +} diff --git a/kernel/arch/i386/registers.h b/kernel/arch/i386/registers.h new file mode 100644 index 00000000..7dfe96b2 --- /dev/null +++ b/kernel/arch/i386/registers.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* Copyright © 2016-2023 Byteduck */ + +#pragma once + +#include + +struct GPRegisters { + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; +}; + +struct SegmentRegisters { + uint32_t gs, fs, es, ds; +}; + +struct InterruptFrame { + uint32_t eip, cs, eflags, esp, ss; +}; + +struct ISRRegisters { + SegmentRegisters segment_registers; + GPRegisters registers; + uint32_t isr_num, err_code; + InterruptFrame interrupt_frame; +}; + +struct IRQRegisters { + SegmentRegisters segment_registers; + GPRegisters registers; + uint32_t irq_num, err_code; + InterruptFrame interrupt_frame; +}; + +struct ThreadRegisters { + SegmentRegisters seg; + GPRegisters gp; + InterruptFrame iret; +}; diff --git a/kernel/asm/syscall.s b/kernel/asm/syscall.s index 06179d83..dc9aade3 100644 --- a/kernel/asm/syscall.s +++ b/kernel/asm/syscall.s @@ -2,8 +2,6 @@ [extern syscall_handler] global asm_syscall_handler asm_syscall_handler: - push 0 ;fake num and err_code in Registers struct - push 0 pusha push ds push es @@ -22,5 +20,4 @@ asm_syscall_handler: pop es pop ds popa - add esp, 8 iret diff --git a/kernel/device/AC97Device.cpp b/kernel/device/AC97Device.cpp index 0d444614..6b05550d 100644 --- a/kernel/device/AC97Device.cpp +++ b/kernel/device/AC97Device.cpp @@ -139,7 +139,7 @@ ssize_t AC97Device::write(FileDescriptor& fd, size_t, SafePointer buffe return n_written; } -void AC97Device::handle_irq(Registers *regs) { +void AC97Device::handle_irq(IRQRegisters *regs) { //Read the status auto status_byte = IO::inw(m_output_channel + ChannelRegisters::STATUS); BufferStatus status = {.value = status_byte}; diff --git a/kernel/device/AC97Device.h b/kernel/device/AC97Device.h index 894015ec..151bc4d7 100644 --- a/kernel/device/AC97Device.h +++ b/kernel/device/AC97Device.h @@ -102,7 +102,7 @@ class AC97Device: public CharacterDevice, public IRQHandler { ssize_t write(FileDescriptor& fd, size_t offset, SafePointer buffer, size_t count) override; //IRQHandler - void handle_irq(Registers* regs) override; + void handle_irq(IRQRegisters* regs) override; private: explicit AC97Device(PCI::Address address); diff --git a/kernel/device/KeyboardDevice.cpp b/kernel/device/KeyboardDevice.cpp index 78c51512..c6b917f0 100644 --- a/kernel/device/KeyboardDevice.cpp +++ b/kernel/device/KeyboardDevice.cpp @@ -73,7 +73,7 @@ void KeyboardDevice::set_handler(KeyboardHandler *handler) { _handler = handler; } -void KeyboardDevice::handle_irq(Registers *regs) { +void KeyboardDevice::handle_irq(IRQRegisters *regs) { I8042::inst().handle_irq(); } @@ -136,4 +136,4 @@ void KeyboardDevice::set_key_state(uint8_t scancode, bool pressed) { if(_event_buffer.size() == _event_buffer.capacity()) _event_buffer.pop_front(); _event_buffer.push_back(event); -} \ No newline at end of file +} diff --git a/kernel/device/KeyboardDevice.h b/kernel/device/KeyboardDevice.h index 70f328f7..e6596813 100644 --- a/kernel/device/KeyboardDevice.h +++ b/kernel/device/KeyboardDevice.h @@ -52,7 +52,7 @@ class KeyboardDevice: public CharacterDevice, public IRQHandler { //IRQHandler void set_handler(KeyboardHandler* handler); - void handle_irq(Registers* regs) override; + void handle_irq(IRQRegisters* regs) override; //I8042 void handle_byte(uint8_t byte); diff --git a/kernel/device/MouseDevice.cpp b/kernel/device/MouseDevice.cpp index 76dccf6e..b18f1f7c 100644 --- a/kernel/device/MouseDevice.cpp +++ b/kernel/device/MouseDevice.cpp @@ -98,7 +98,7 @@ ssize_t MouseDevice::write(FileDescriptor &fd, size_t offset, SafePointer buffer, size_t count) override; //IRQHandler - void handle_irq(Registers* regs) override; + void handle_irq(IRQRegisters* regs) override; private: PATADevice(PCI::Address addr, Channel channel, DriveType drive, bool use_pio); diff --git a/kernel/interrupt/IRQHandler.cpp b/kernel/interrupt/IRQHandler.cpp index d9704545..c78391e3 100644 --- a/kernel/interrupt/IRQHandler.cpp +++ b/kernel/interrupt/IRQHandler.cpp @@ -25,7 +25,7 @@ IRQHandler::IRQHandler() { } -void IRQHandler::handle(Registers* regs) { +void IRQHandler::handle(IRQRegisters* regs) { _sent_eoi = false; handle_irq(regs); } diff --git a/kernel/interrupt/IRQHandler.h b/kernel/interrupt/IRQHandler.h index ac0556b6..d9d83efb 100644 --- a/kernel/interrupt/IRQHandler.h +++ b/kernel/interrupt/IRQHandler.h @@ -20,15 +20,16 @@ #pragma once #include +#include class IRQHandler { public: - void handle(Registers* regs); + void handle(IRQRegisters* regs); bool sent_eoi(); virtual bool mark_in_irq(); protected: - virtual void handle_irq(Registers* regs) = 0; + virtual void handle_irq(IRQRegisters* regs) = 0; explicit IRQHandler(); IRQHandler(int irq); void set_irq(int irq); diff --git a/kernel/interrupt/irq.cpp b/kernel/interrupt/irq.cpp index 18387bba..9882c6fe 100644 --- a/kernel/interrupt/irq.cpp +++ b/kernel/interrupt/irq.cpp @@ -80,19 +80,22 @@ namespace Interrupt { idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E); } - void irq_handler(struct Registers *r){ - auto handler = handlers[r->num - 0x20]; + void irq_handler(IRQRegisters* regs){ + regs->irq_num -= 0x20; + if (regs->irq_num >= (sizeof(handlers) / sizeof(handlers[0]))) + PANIC("INVALID_IRQ", "Attempted to handle invalid IRQ %d", regs->irq_num); + auto handler = handlers[regs->irq_num]; if(handler) { //Mark that we're in an interrupt so that yield will be async if it occurs _in_interrupt = handler->mark_in_irq(); //Handle the IRQ - handler->handle(r); + handler->handle(regs); } //Send EOI if we haven't already if(!handler || !handler->sent_eoi()) - send_eoi(r->num - 0x20); + send_eoi(regs->irq_num); //If we need to yield asynchronously after the interrupt because we called TaskManager::yield() during it, do so TaskManager::do_yield_async(); diff --git a/kernel/interrupt/irq.h b/kernel/interrupt/irq.h index 07f38080..87b545b3 100644 --- a/kernel/interrupt/irq.h +++ b/kernel/interrupt/irq.h @@ -19,6 +19,8 @@ #pragma once +#include + #define PIC1 0x20 #define PIC2 0xA0 #define PIC1_COMMAND PIC1 @@ -45,7 +47,7 @@ namespace Interrupt { extern "C" void irq13(); extern "C" void irq14(); extern "C" void irq15(); - extern "C" void irq_handler(struct Registers *r); + extern "C" void irq_handler(IRQRegisters* regs); void irq_set_handler(int irq, IRQHandler* handler); void irq_remove_handler(int irq); diff --git a/kernel/interrupt/isr.cpp b/kernel/interrupt/isr.cpp index e43caaa7..fba02943 100644 --- a/kernel/interrupt/isr.cpp +++ b/kernel/interrupt/isr.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include namespace Interrupt { void isr_init(){ @@ -64,57 +66,48 @@ namespace Interrupt { idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E); } - void handle_fault(const char* err, const char* panic_msg, uint32_t sig){ - if(!TaskManager::enabled() || TaskManager::current_thread()->is_kernel_mode() || TaskManager::is_preempting()){ - PANIC(err, panic_msg); + void handle_fault(const char* err, const char* panic_msg, uint32_t sig, ISRRegisters* regs) { + if(!TaskManager::enabled() || TaskManager::current_thread()->is_kernel_mode() || TaskManager::is_preempting()) { + PANIC(err, "%s\nFault %d at 0x%x", panic_msg, regs->isr_num, regs->interrupt_frame.eip); } else { TaskManager::current_process()->kill(sig); } } - void fault_handler(struct Registers *r){ - if(r->num < 32){ - switch(r->num){ + void fault_handler(ISRRegisters* regs){ + if(regs->isr_num < 32){ + switch(regs->isr_num){ case 0: - handle_fault("DIVIDE_BY_ZERO", "Please don't do that.", SIGILL); + handle_fault("DIVIDE_BY_ZERO", "Please don't do that.", SIGILL, regs); break; case 13: //GPF - handle_fault("GENERAL_PROTECTION_FAULT", "How did you manage to do that?", SIGILL); + handle_fault("GENERAL_PROTECTION_FAULT", "How did you manage to do that?", SIGILL, regs); break; case 14: //Page fault if(!TaskManager::current_thread() || TaskManager::current_thread()->is_kernel_mode() || TaskManager::is_preempting()) { - MemoryManager::inst().page_fault_handler(r); + MemoryManager::inst().page_fault_handler(regs); } else { size_t err_pos; asm volatile ("mov %%cr2, %0" : "=r" (err_pos)); PageFault::Type type; - if(r->err_code == FAULT_USER_READ) + if(regs->err_code == FAULT_USER_READ) type = PageFault::Type::Read; - else if(r->err_code == FAULT_USER_WRITE) + else if(regs->err_code == FAULT_USER_WRITE) type = PageFault::Type::Write; else type = PageFault::Type::Unknown; TaskManager::current_thread()->handle_pagefault({ err_pos, - r->eip, + regs, }); } break; default: - handle_fault("UNKNOWN_FAULT", "What did you do?", SIGILL); + handle_fault("UNKNOWN_FAULT", "What did you do?", SIGILL, regs); } } } } - -void print_regs(struct Registers *r){ - asm volatile("mov %%ss, %%eax":"=a"(r->ss)); - printf("eip:0x%X err:%d\n", r->eip, r->err_code); - printf("cs:0x%X ds:0x%X es:0x%X gs:0x%X fs:0x%X ss:0x%X\n",r->cs,r->ds,r->es,r->gs,r->fs,r->ss); - printf("eax:0x%X ebx:0x%X ecx:0x%X edx:0x%X\n",r->eax,r->ebx,r->ecx,r->edx); - printf("edi: 0x%X esi: 0x%X ebp: 0x%X esp:0x%X\n",r->edi,r->esi,r->ebp,r->esp); - printf("EFLAGS: 0x%X",r->eflags); -} diff --git a/kernel/interrupt/isr.h b/kernel/interrupt/isr.h index 4029b749..5fb82071 100644 --- a/kernel/interrupt/isr.h +++ b/kernel/interrupt/isr.h @@ -20,6 +20,7 @@ #pragma once #include +#include #define FAULT_KERNEL_READ 0 #define FAULT_KERNEL_READ_GPF 1 @@ -66,7 +67,5 @@ namespace Interrupt { void isr_init(); - extern "C" void fault_handler(struct Registers *r); + extern "C" void fault_handler(ISRRegisters *r); } - -void print_regs(struct Registers *r); diff --git a/kernel/kstd/kstddef.h b/kernel/kstd/kstddef.h index 8a3db262..065e6b67 100644 --- a/kernel/kstd/kstddef.h +++ b/kernel/kstd/kstddef.h @@ -24,13 +24,6 @@ #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) -struct Registers { - unsigned int gs, fs, es, ds; - unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; - unsigned int num, err_code; - unsigned int eip, cs, eflags, useresp, ss; -}; - void *operator new(size_t size); void *operator new(size_t size, void* ptr); void *operator new[](size_t size); diff --git a/kernel/memory/Memory.h b/kernel/memory/Memory.h index 829a671c..ed3aac31 100644 --- a/kernel/memory/Memory.h +++ b/kernel/memory/Memory.h @@ -5,6 +5,7 @@ #include "../kstd/kstddef.h" #include "../api/page_size.h" +#include #define PAGING_4KiB 0 #define PAGING_4MiB 1 @@ -46,8 +47,8 @@ struct VirtualRange { struct PageFault { public: VirtualAddress address; - VirtualAddress instruction_pointer; + ISRRegisters* registers; enum class Type { Read, Write, Execute, Unknown } type; -}; \ No newline at end of file +}; diff --git a/kernel/memory/MemoryManager.cpp b/kernel/memory/MemoryManager.cpp index 33536a74..271c4150 100644 --- a/kernel/memory/MemoryManager.cpp +++ b/kernel/memory/MemoryManager.cpp @@ -147,11 +147,11 @@ void MemoryManager::load_page_directory(PageDirectory& page_directory) { asm volatile("movl %0, %%cr3" :: "r"(page_directory.entries_physaddr())); } -void MemoryManager::page_fault_handler(struct Registers *r) { +void MemoryManager::page_fault_handler(ISRRegisters* regs) { TaskManager::ScopedCritical critical; uint32_t err_pos; asm volatile ("mov %%cr2, %0" : "=r" (err_pos)); - switch (r->err_code) { + switch (regs->err_code) { case FAULT_KERNEL_READ: PANIC("KRNL_READ_NONPAGED_AREA", "0x%x", err_pos); case FAULT_KERNEL_READ_GPF: diff --git a/kernel/memory/MemoryManager.h b/kernel/memory/MemoryManager.h index 5142db97..f12c170c 100644 --- a/kernel/memory/MemoryManager.h +++ b/kernel/memory/MemoryManager.h @@ -29,6 +29,7 @@ #include "VMSpace.h" #include #include "Memory.h" +#include "kernel/arch/i386/registers.h" /** * The basic premise of how the memory allocation in duckOS is as follows: @@ -96,7 +97,7 @@ class MemoryManager { * Called when the CPU encounters a page fault in the kernel. * @param r the Registers struct from the isr. */ - void page_fault_handler(struct Registers *r); + void page_fault_handler(ISRRegisters* regs); /** Gets a reference to the given physical page (indexed by page number, NOT address.) **/ PhysicalPage& get_physical_page(size_t page_number) const { diff --git a/kernel/syscall/fork.cpp b/kernel/syscall/fork.cpp index bd23500f..b60503ec 100644 --- a/kernel/syscall/fork.cpp +++ b/kernel/syscall/fork.cpp @@ -4,10 +4,10 @@ #include "../tasking/Process.h" #include "../tasking/TaskManager.h" -pid_t Process::sys_fork(Registers& regs) { +pid_t Process::sys_fork(ThreadRegisters& regs) { auto* new_proc = new Process(this, regs); // If the process execs before sys_fork finishes, pid would be -1 so we save it here auto pid = new_proc->pid(); TaskManager::add_process(new_proc->_self_ptr); return pid; -} \ No newline at end of file +} diff --git a/kernel/syscall/syscall.cpp b/kernel/syscall/syscall.cpp index dd2f0e01..9a3c0ca6 100644 --- a/kernel/syscall/syscall.cpp +++ b/kernel/syscall/syscall.cpp @@ -23,13 +23,13 @@ #include #include "kernel/memory/SafePointer.h" -void syscall_handler(Registers& regs){ +void syscall_handler(ThreadRegisters& regs){ TaskManager::current_thread()->enter_syscall(); - regs.eax = handle_syscall(regs, regs.eax, regs.ebx, regs.ecx, regs.edx); + regs.gp.eax = handle_syscall(regs, regs.gp.eax, regs.gp.ebx, regs.gp.ecx, regs.gp.edx); TaskManager::current_thread()->leave_syscall(); } -int handle_syscall(Registers& regs, uint32_t call, uint32_t arg1, uint32_t arg2, uint32_t arg3) { +int handle_syscall(ThreadRegisters& regs, uint32_t call, uint32_t arg1, uint32_t arg2, uint32_t arg3) { auto cur_proc = TaskManager::current_thread()->process(); switch(call) { case SYS_EXIT: diff --git a/kernel/syscall/syscall.h b/kernel/syscall/syscall.h index 5c51d3e5..4ba361d5 100644 --- a/kernel/syscall/syscall.h +++ b/kernel/syscall/syscall.h @@ -19,8 +19,9 @@ #pragma once -#include "syscall_numbers.h" #include "../kstd/kstddef.h" +#include "syscall_numbers.h" +#include "../arch/i386/registers.h" -extern "C" void syscall_handler(Registers& regs); -int handle_syscall(Registers& regs, uint32_t call, uint32_t arg1, uint32_t arg2, uint32_t arg3); \ No newline at end of file +extern "C" void syscall_handler(ThreadRegisters& regs); +int handle_syscall(ThreadRegisters& regs, uint32_t call, uint32_t arg1, uint32_t arg2, uint32_t arg3); diff --git a/kernel/tasking/Process.cpp b/kernel/tasking/Process.cpp index 1e952235..76d4a46e 100644 --- a/kernel/tasking/Process.cpp +++ b/kernel/tasking/Process.cpp @@ -200,7 +200,7 @@ Process::Process(const kstd::string& name, size_t entry_point, bool kernel, Proc insert_thread(kstd::Arc(main_thread)); } -Process::Process(Process *to_fork, Registers ®s): _user(to_fork->_user), _self_ptr(this) { +Process::Process(Process *to_fork, ThreadRegisters& regs): _user(to_fork->_user), _self_ptr(this) { if(to_fork->_kernel_mode) PANIC("KRNL_PROCESS_FORK", "Kernel processes cannot be forked."); @@ -403,4 +403,4 @@ void Process::alert_thread_continued(Thread* thread) { if(_state != STOPPED) return; _state = ALIVE; -} \ No newline at end of file +} diff --git a/kernel/tasking/Process.h b/kernel/tasking/Process.h index 31102033..d04df51e 100644 --- a/kernel/tasking/Process.h +++ b/kernel/tasking/Process.h @@ -98,7 +98,7 @@ class Process { void sys_exit(int status); ssize_t sys_read(int fd, UserspacePointer buf, size_t count); ssize_t sys_write(int fd, UserspacePointer buf, size_t count); - pid_t sys_fork(Registers& regs); + pid_t sys_fork(ThreadRegisters& regs); int exec(const kstd::string& filename, ProcessArgs* args); int sys_execve(UserspacePointer filename, UserspacePointer argv, UserspacePointer envp); int sys_open(UserspacePointer filename, int options, int mode); @@ -172,7 +172,7 @@ class Process { friend class Thread; friend class Reaper; Process(const kstd::string& name, size_t entry_point, bool kernel, ProcessArgs* args, pid_t pid, pid_t ppid); - Process(Process* to_fork, Registers& regs); + Process(Process* to_fork, ThreadRegisters& regs); void alert_thread_died(kstd::Arc thread); void recalculate_pmem_total(); diff --git a/kernel/tasking/TaskManager.cpp b/kernel/tasking/TaskManager.cpp index d509388e..349a121d 100644 --- a/kernel/tasking/TaskManager.cpp +++ b/kernel/tasking/TaskManager.cpp @@ -149,7 +149,7 @@ void TaskManager::init(){ //Preempt cur_thread = kernel_process->get_thread(kernel_process->pid()); - preempt_init_asm(cur_thread->registers.esp); + preempt_init_asm(cur_thread->registers.gp.esp); } kstd::vector* TaskManager::process_list() { @@ -317,14 +317,14 @@ void TaskManager::preempt(){ bool should_preempt = old_thread != next_thread; //If we were just in a signal handler, don't save the esp to old_proc->registers - unsigned int* old_esp; - unsigned int dummy_esp; + uint32_t* old_esp; + uint32_t dummy_esp; if(!old_thread) { old_esp = &dummy_esp; } if(old_thread->in_signal_handler()) { - old_esp = &old_thread->signal_registers.esp; + old_esp = &old_thread->signal_registers.gp.esp; } else { - old_esp = &old_thread->registers.esp; + old_esp = &old_thread->registers.gp.esp; } //If we just finished handling a signal, set in_signal_handler to false. @@ -342,12 +342,12 @@ void TaskManager::preempt(){ } //If we're switching to a process in a signal handler, use the esp from signal_registers - unsigned int* new_esp; + uint32_t* new_esp; if(next_thread->in_signal_handler()) { - new_esp = &next_thread->signal_registers.esp; + new_esp = &next_thread->signal_registers.gp.esp; tss.esp0 = (size_t) next_thread->signal_stack_top(); } else { - new_esp = &next_thread->registers.esp; + new_esp = &next_thread->registers.gp.esp; tss.esp0 = (size_t) next_thread->kernel_stack_top(); } diff --git a/kernel/tasking/TaskManager.h b/kernel/tasking/TaskManager.h index 0a293687..f408a346 100644 --- a/kernel/tasking/TaskManager.h +++ b/kernel/tasking/TaskManager.h @@ -105,7 +105,7 @@ namespace TaskManager { extern "C" void preempt(); extern "C" void preempt_finish(); extern "C" void __attribute((cdecl)) preempt_init_asm(unsigned int new_esp); - extern "C" void __attribute((cdecl)) preempt_asm(unsigned int *old_esp, unsigned int *new_esp, uint32_t new_cr3); + extern "C" void __attribute((cdecl)) preempt_asm(uint32_t *old_esp, uint32_t *new_esp, uint32_t new_cr3); extern "C" void proc_first_preempt(); }; diff --git a/kernel/tasking/Thread.cpp b/kernel/tasking/Thread.cpp index 873622cc..3435a383 100644 --- a/kernel/tasking/Thread.cpp +++ b/kernel/tasking/Thread.cpp @@ -58,26 +58,26 @@ Thread::Thread(Process* process, tid_t tid, size_t entry_point, ProcessArgs* arg } //Setup registers - registers.eflags = 0x202; - registers.cs = _process->_kernel_mode ? 0x8 : 0x1B; - registers.eip = entry_point; - registers.eax = 0; - registers.ebx = 0; - registers.ecx = 0; - registers.edx = 0; - registers.ebp = user_stack.real_stackptr(); - registers.edi = 0; - registers.esi = 0; + 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.ds = 0x10; // ds - registers.es = 0x10; // es - registers.fs = 0x10; // fs - registers.gs = 0x10; // gs + registers.seg.ds = 0x10; // ds + registers.seg.es = 0x10; // es + registers.seg.fs = 0x10; // fs + registers.seg.gs = 0x10; // gs } else { - registers.ds = 0x23; // ds - registers.es = 0x23; // es - registers.fs = 0x23; // fs - registers.gs = 0x23; // gs + registers.seg.ds = 0x23; // ds + registers.seg.es = 0x23; // es + registers.seg.fs = 0x23; // fs + registers.seg.gs = 0x23; // gs } //Set up the user stack for the program arguments @@ -90,7 +90,7 @@ Thread::Thread(Process* process, tid_t tid, size_t entry_point, ProcessArgs* arg setup_kernel_stack(kernel_stack, user_stack.real_stackptr(), registers); } -Thread::Thread(Process* process, tid_t tid, Registers& regs): +Thread::Thread(Process* process, tid_t tid, ThreadRegisters& regs): _process(process), _tid(tid), registers(regs), @@ -101,9 +101,9 @@ Thread::Thread(Process* process, tid_t tid, Registers& regs): _kernel_stack_region = MM.alloc_kernel_region(THREAD_KERNEL_STACK_SIZE); //Setup registers and stack - registers.eax = 0; // fork() in child returns zero + 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.useresp, registers); + setup_kernel_stack(stack, regs.iret.esp, registers); } Thread::Thread(Process* process, tid_t tid, void* (*entry_func)(void* (*)(void*), void*), void* (* thread_func)(void*), void* arg): @@ -135,26 +135,26 @@ Thread::Thread(Process* process, tid_t tid, void* (*entry_func)(void* (*)(void*) } //Setup registers - registers.eflags = 0x202; - registers.cs = _process->_kernel_mode ? 0x8 : 0x1B; - registers.eip = (size_t) entry_func; - registers.eax = 0; - registers.ebx = 0; - registers.ecx = 0; - registers.edx = 0; - registers.ebp = user_stack.real_stackptr(); - registers.edi = 0; - registers.esi = 0; + 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.ds = 0x10; // ds - registers.es = 0x10; // es - registers.fs = 0x10; // fs - registers.gs = 0x10; // gs + registers.seg.ds = 0x10; // ds + registers.seg.es = 0x10; // es + registers.seg.fs = 0x10; // fs + registers.seg.gs = 0x10; // gs } else { - registers.ds = 0x23; // ds - registers.es = 0x23; // es - registers.fs = 0x23; // fs - registers.gs = 0x23; // gs + registers.seg.ds = 0x23; // ds + registers.seg.es = 0x23; // es + registers.seg.fs = 0x23; // fs + registers.seg.gs = 0x23; // gs } //Set up the user stack for the thread arguments @@ -439,26 +439,26 @@ bool Thread::call_signal_handler(int signal) { user_stack.push(SIGNAL_RETURN_FAKE_ADDR); //Setup signal registers - signal_registers.eflags = 0x202; - signal_registers.cs = _process->_kernel_mode ? 0x8 : 0x1B; - signal_registers.eip = signal_loc; - signal_registers.eax = 0; - signal_registers.ebx = 0; - signal_registers.ecx = 0; - signal_registers.edx = 0; - signal_registers.ebp = user_stack.real_stackptr(); - signal_registers.edi = 0; - signal_registers.esi = 0; + 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.ds = 0x10; // ds - signal_registers.es = 0x10; // es - signal_registers.fs = 0x10; // fs - signal_registers.gs = 0x10; // gs + 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.ds = 0x23; // ds - signal_registers.es = 0x23; // es - signal_registers.fs = 0x23; // fs - signal_registers.gs = 0x23; // gs + signal_registers.seg.ds = 0x23; // ds + signal_registers.seg.es = 0x23; // es + signal_registers.seg.fs = 0x23; // fs + signal_registers.seg.gs = 0x23; // gs } //Set up the stack @@ -511,10 +511,10 @@ void Thread::handle_pagefault(PageFault fault) { //Otherwise, try CoW and kill the process if it doesn't work if(m_vm_space->try_pagefault(fault).is_error()) { - if(fault.instruction_pointer > 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.instruction_pointer); + 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); } - KLog::warn("Thread", "PID %d thread %d made illegal memory access at 0x%x (eip: 0x%x)", _process->pid(), _tid, fault.address, fault.instruction_pointer); + KLog::warn("Thread", "PID %d thread %d made illegal memory access at 0x%x (eip: 0x%x)", _process->pid(), _tid, fault.address, fault.registers->interrupt_frame.eip); _process->kill(SIGSEGV); } } @@ -537,41 +537,41 @@ Thread* Thread::next_thread() { return next; } -void Thread::setup_kernel_stack(Stack& kernel_stack, size_t user_stack_ptr, Registers& regs) { +void Thread::setup_kernel_stack(Stack& kernel_stack, size_t user_stack_ptr, ThreadRegisters& regs) { //If usermode, push ss and useresp if(__builtin_expect(!is_kernel_mode(), true)) { - kernel_stack.push(0x23); - kernel_stack.push(user_stack_ptr); + kernel_stack.push(0x23); //ss + kernel_stack.push(user_stack_ptr); //esp } //Push EFLAGS, CS, and EIP for iret - kernel_stack.push(regs.eflags); // eflags - kernel_stack.push(regs.cs); // cs - kernel_stack.push(regs.eip); // eip - - kernel_stack.push(regs.eax); - kernel_stack.push(regs.ebx); - kernel_stack.push(regs.ecx); - kernel_stack.push(regs.edx); - kernel_stack.push(regs.ebp); - kernel_stack.push(regs.edi); - kernel_stack.push(regs.esi); - kernel_stack.push(regs.ds); - kernel_stack.push(regs.es); - kernel_stack.push(regs.fs); - kernel_stack.push(regs.gs); + kernel_stack.push(regs.iret.eflags); // eflags + kernel_stack.push(regs.iret.cs); // cs + kernel_stack.push(regs.iret.eip); // eip + + kernel_stack.push(regs.gp.eax); + kernel_stack.push(regs.gp.ebx); + kernel_stack.push(regs.gp.ecx); + kernel_stack.push(regs.gp.edx); + kernel_stack.push(regs.gp.ebp); + kernel_stack.push(regs.gp.edi); + kernel_stack.push(regs.gp.esi); + kernel_stack.push(regs.seg.ds); + kernel_stack.push(regs.seg.es); + kernel_stack.push(regs.seg.fs); + kernel_stack.push(regs.seg.gs); if(_process->pid() != 0 || _tid != 0) { kernel_stack.push((size_t) TaskManager::proc_first_preempt); kernel_stack.push(0x2u); /* Kernel eflags: We don't want interrupts enabled */ - kernel_stack.push(regs.ebx); /* Kernel ebx */ - kernel_stack.push(regs.esi); /* Kernel esi */ - kernel_stack.push(regs.edi); /* Kernel edi */ + kernel_stack.push(regs.gp.ebx); /* Kernel ebx */ + kernel_stack.push(regs.gp.esi); /* Kernel esi */ + kernel_stack.push(regs.gp.edi); /* Kernel edi */ kernel_stack.push(0); //Fake popped EBP } - regs.esp = (size_t) kernel_stack.stackptr(); - regs.useresp = (size_t) user_stack_ptr; + regs.gp.esp = (size_t) kernel_stack.stackptr(); + regs.iret.esp = (size_t) user_stack_ptr; } void Thread::exit(void* return_value) { diff --git a/kernel/tasking/Thread.h b/kernel/tasking/Thread.h index a91495e2..3e5c89fd 100644 --- a/kernel/tasking/Thread.h +++ b/kernel/tasking/Thread.h @@ -29,6 +29,7 @@ #include "../memory/PageDirectory.h" #include "../kstd/queue.hpp" #include "kernel/kstd/circular_queue.hpp" +#include #define THREAD_STACK_SIZE 1048576 //1024KiB #define THREAD_KERNEL_STACK_SIZE 524288 //512KiB @@ -48,7 +49,7 @@ class Thread: public kstd::ArcSelf { }; Thread(Process* process, tid_t tid, size_t entry_point, ProcessArgs* args); - Thread(Process* process, tid_t tid, Registers& regs); + Thread(Process* process, tid_t tid, ThreadRegisters& regs); Thread(Process* process, tid_t tid, void* (*entry_func)(void* (*)(void*), void*), void* (*thread_func)(void*), void* arg); ~Thread(); @@ -99,14 +100,14 @@ class Thread: public kstd::ArcSelf { Thread* next_thread(); uint8_t fpu_state[512] __attribute__((aligned(16))); - Registers registers = {}; - Registers signal_registers = {}; + ThreadRegisters registers = {}; + ThreadRegisters signal_registers = {}; private: friend class Process; friend class Reaper; - void setup_kernel_stack(Stack& kernel_stack, size_t user_stack_ptr, Registers& regs); + void setup_kernel_stack(Stack& kernel_stack, size_t user_stack_ptr, ThreadRegisters& regs); void exit(void* return_value); void reap(); diff --git a/kernel/time/PIT.cpp b/kernel/time/PIT.cpp index 2eac6768..b1e5c179 100644 --- a/kernel/time/PIT.cpp +++ b/kernel/time/PIT.cpp @@ -36,7 +36,7 @@ PIT::PIT(TimeManager* manager): TimeKeeper(manager), IRQHandler(PIT_IRQ) { write((divisor >> 8u) & 0xffu, 0); } -void PIT::handle_irq(Registers* regs) { +void PIT::handle_irq(IRQRegisters* regs) { TimeKeeper::tick(); } diff --git a/kernel/time/PIT.h b/kernel/time/PIT.h index 7a9e6a11..6ba72d48 100644 --- a/kernel/time/PIT.h +++ b/kernel/time/PIT.h @@ -35,7 +35,7 @@ class PIT: public TimeKeeper, public IRQHandler { PIT(TimeManager* manager); ///IRQHandler - void handle_irq(Registers* regs) override; + void handle_irq(IRQRegisters* regs) override; bool mark_in_irq() override; ///TimeHandler diff --git a/kernel/time/RTC.cpp b/kernel/time/RTC.cpp index 870f8ec3..b0fd731d 100644 --- a/kernel/time/RTC.cpp +++ b/kernel/time/RTC.cpp @@ -75,7 +75,7 @@ time_t RTC::timestamp() { return secs; } -void RTC::handle_irq(Registers* regs) { +void RTC::handle_irq(IRQRegisters* regs) { CMOS::read(0x8C); TimeKeeper::tick(); } diff --git a/kernel/time/RTC.h b/kernel/time/RTC.h index 08331d3b..083b7a9f 100644 --- a/kernel/time/RTC.h +++ b/kernel/time/RTC.h @@ -55,7 +55,7 @@ class RTC: public IRQHandler, public TimeKeeper { static time_t timestamp(); ///IRQHandler - void handle_irq(Registers* regs) override; + void handle_irq(IRQRegisters* regs) override; bool mark_in_irq() override; ///TimeHandler