mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 08:54:58 +00:00

About half of the Processor code is common across architectures, so let's share it with a templated base class. Also, other code that can be shared in some ways, like FPUState and TrapFrame functions, is adjusted here. Functions which cannot be shared trivially (without internal refactoring) are left alone for now.
91 lines
3 KiB
C++
91 lines
3 KiB
C++
/*
|
|
* Copyright (c) 2021, Owen Smith <yeeetari@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/API/Syscall.h>
|
|
#include <Kernel/Arch/Processor.h>
|
|
#include <Kernel/Arch/TrapFrame.h>
|
|
#include <Kernel/Arch/x86_64/DescriptorTable.h>
|
|
#include <Kernel/Library/Assertions.h>
|
|
#include <Kernel/Library/Panic.h>
|
|
#include <Kernel/Tasks/Process.h>
|
|
#include <Kernel/Tasks/Scheduler.h>
|
|
#include <Kernel/Tasks/Thread.h>
|
|
#include <Kernel/Tasks/ThreadTracer.h>
|
|
|
|
using namespace Kernel;
|
|
|
|
extern "C" void syscall_entry();
|
|
extern "C" [[gnu::naked]] void syscall_entry()
|
|
{
|
|
// clang-format off
|
|
asm(
|
|
// Store the user stack, then switch to the kernel stack.
|
|
" movq %%rsp, %%gs:%c[user_stack] \n"
|
|
" movq %%gs:%c[kernel_stack], %%rsp \n"
|
|
|
|
// Build RegisterState.
|
|
" pushq $0x1b \n" // User ss
|
|
" pushq %%gs:%c[user_stack] \n" // User rsp
|
|
" sti \n" // It's now safe to enable interrupts, but we can't index into gs after this point
|
|
" pushq %%r11 \n" // The CPU preserves the user rflags in r11
|
|
" pushq $0x23 \n" // User cs
|
|
" pushq %%rcx \n" // The CPU preserves the user IP in rcx
|
|
" pushq $0 \n"
|
|
" pushq %%r15 \n"
|
|
" pushq %%r14 \n"
|
|
" pushq %%r13 \n"
|
|
" pushq %%r12 \n"
|
|
" pushq %%r11 \n"
|
|
" pushq %%r10 \n"
|
|
" pushq %%r9 \n"
|
|
" pushq %%r8 \n"
|
|
" pushq %%rax \n"
|
|
" pushq %%rcx \n"
|
|
" pushq %%rdx \n"
|
|
" pushq %%rbx \n"
|
|
" pushq %%rsp \n"
|
|
" pushq %%rbp \n"
|
|
" pushq %%rsi \n"
|
|
" pushq %%rdi \n"
|
|
|
|
" pushq %%rsp \n" // TrapFrame::regs
|
|
" subq $" __STRINGIFY(TRAP_FRAME_SIZE - 8) ", %%rsp \n"
|
|
" movq %%rsp, %%rdi \n"
|
|
" call enter_trap_no_irq \n"
|
|
" movq %%rsp, %%rdi \n"
|
|
" call syscall_handler \n"
|
|
" movq %%rsp, %%rdi \n"
|
|
" call exit_trap \n"
|
|
" addq $" __STRINGIFY(TRAP_FRAME_SIZE) ", %%rsp \n" // Pop TrapFrame
|
|
|
|
" popq %%rdi \n"
|
|
" popq %%rsi \n"
|
|
" popq %%rbp \n"
|
|
" addq $8, %%rsp \n" // Skip restoring kernel rsp
|
|
" popq %%rbx \n"
|
|
" popq %%rdx \n"
|
|
" popq %%rcx \n"
|
|
" popq %%rax \n"
|
|
" popq %%r8 \n"
|
|
" popq %%r9 \n"
|
|
" popq %%r10 \n"
|
|
" popq %%r11 \n"
|
|
" popq %%r12 \n"
|
|
" popq %%r13 \n"
|
|
" popq %%r14 \n"
|
|
" popq %%r15 \n"
|
|
" addq $8, %%rsp \n"
|
|
" popq %%rcx \n"
|
|
" addq $16, %%rsp \n"
|
|
|
|
// Disable interrupts before we restore the user stack pointer. sysret will re-enable interrupts when it restores
|
|
// rflags.
|
|
" cli \n"
|
|
" popq %%rsp \n"
|
|
" sysretq \n"
|
|
:: [user_stack] "i"(Kernel::Processor::user_stack_offset()), [kernel_stack] "i"(Kernel::Processor::kernel_stack_offset()));
|
|
// clang-format on
|
|
}
|