Kernel: Use syscall/sysret for syscalls in x86_64
This commit is contained in:
44
kernel/include/kernel/API/Syscall.h
Normal file
44
kernel/include/kernel/API/Syscall.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/Attributes.h>
|
||||
#include <kernel/IDT.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
ALWAYS_INLINE long syscall(int syscall, uintptr_t arg1 = 0, uintptr_t arg2 = 0, uintptr_t arg3 = 0, uintptr_t arg4 = 0, uintptr_t arg5 = 0)
|
||||
{
|
||||
long ret;
|
||||
#if ARCH(x86_64)
|
||||
register uintptr_t r10 asm("r10") = arg3;
|
||||
register uintptr_t r8 asm( "r8") = arg4;
|
||||
register uintptr_t r9 asm( "r9") = arg5;
|
||||
asm volatile(
|
||||
"syscall"
|
||||
: "=a"(ret)
|
||||
, "+D"(syscall)
|
||||
, "+S"(arg1)
|
||||
, "+d"(arg2)
|
||||
, "+r"(r10)
|
||||
, "+r"(r8)
|
||||
, "+r"(r9)
|
||||
:: "rcx", "r11", "memory");
|
||||
#elif ARCH(i686)
|
||||
asm volatile(
|
||||
"int %[irq]"
|
||||
: "=a"(ret)
|
||||
: [irq]"i"(static_cast<int>(IRQ_SYSCALL)) // WTF GCC 15
|
||||
, "a"(syscall)
|
||||
, "b"(arg1)
|
||||
, "c"(arg2)
|
||||
, "d"(arg3)
|
||||
, "S"(arg4)
|
||||
, "D"(arg5)
|
||||
: "memory");
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -151,8 +151,8 @@ namespace Kernel
|
||||
|
||||
private:
|
||||
#if ARCH(x86_64)
|
||||
BAN::Array<SegmentDescriptor, 7> m_gdt; // null, kernel code, kernel data, user code, user data, tss low, tss high
|
||||
static constexpr uint16_t m_tss_offset = 0x28;
|
||||
BAN::Array<SegmentDescriptor, 8> m_gdt; // null, kernel code, kernel data, user code (32 bit), user data, user code (64 bit), tss low, tss high
|
||||
static constexpr uint16_t m_tss_offset = 0x30;
|
||||
#elif ARCH(i686)
|
||||
BAN::Array<SegmentDescriptor, 9> m_gdt; // null, kernel code, kernel data, user code, user data, processor data, fsbase, gsbase, tss
|
||||
static constexpr uint16_t m_tss_offset = 0x40;
|
||||
|
||||
@@ -18,7 +18,10 @@ namespace Kernel
|
||||
|
||||
constexpr uint8_t IRQ_VECTOR_BASE = 0x20;
|
||||
constexpr uint8_t IRQ_MSI_BASE = 0x80;
|
||||
constexpr uint8_t IRQ_MSI_END = 0xF0;
|
||||
#if ARCH(i686)
|
||||
constexpr uint8_t IRQ_SYSCALL = 0xF0;
|
||||
#endif
|
||||
constexpr uint8_t IRQ_YIELD = 0xF1;
|
||||
constexpr uint8_t IRQ_IPI = 0xF2;
|
||||
constexpr uint8_t IRQ_TIMER = 0xF3;
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace Kernel::PCI
|
||||
void initialize_impl();
|
||||
|
||||
private:
|
||||
static constexpr uint8_t m_msi_count = IRQ_SYSCALL - IRQ_MSI_BASE;
|
||||
static constexpr uint8_t m_msi_count = IRQ_MSI_END - IRQ_MSI_BASE;
|
||||
using PCIBus = BAN::Array<BAN::Array<Device, 8>, 32>;
|
||||
BAN::Array<PCIBus, 256> m_buses;
|
||||
BAN::Array<paddr_t, 256> m_bus_pcie_paddr;
|
||||
|
||||
@@ -102,6 +102,8 @@ namespace Kernel
|
||||
uintptr_t stack_bottom() const { return reinterpret_cast<uintptr_t>(m_stack); }
|
||||
uintptr_t stack_top() const { return stack_bottom() + s_stack_size; }
|
||||
|
||||
static void set_thread_syscall_stack(vaddr_t vaddr) { write_gs_sized<vaddr_t>(offsetof(Processor, m_thread_syscall_stack), vaddr); }
|
||||
|
||||
static GDT& gdt() { return *read_gs_sized<GDT*>(offsetof(Processor, m_gdt)); }
|
||||
static IDT& idt() { return *read_gs_sized<IDT*>(offsetof(Processor, m_idt)); }
|
||||
|
||||
@@ -137,6 +139,13 @@ namespace Kernel
|
||||
static void initialize_smp();
|
||||
static void initialize_shared_page();
|
||||
|
||||
static void dummy()
|
||||
{
|
||||
#if ARCH(x86_64)
|
||||
static_assert(offsetof(Processor, m_thread_syscall_stack) == 8, "This is hardcoded in Syscall.S");
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T read_gs_sized(uintptr_t offset) requires(sizeof(T) <= 8)
|
||||
{
|
||||
@@ -180,6 +189,8 @@ namespace Kernel
|
||||
ProcessorID m_id { 0 };
|
||||
uint8_t m_index { 0xFF };
|
||||
|
||||
vaddr_t m_thread_syscall_stack;
|
||||
|
||||
static constexpr size_t s_stack_size { 4096 };
|
||||
void* m_stack { nullptr };
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/Attributes.h>
|
||||
#include <kernel/IDT.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
ALWAYS_INLINE long syscall(int syscall, uintptr_t arg1 = 0, uintptr_t arg2 = 0, uintptr_t arg3 = 0, uintptr_t arg4 = 0, uintptr_t arg5 = 0)
|
||||
{
|
||||
long ret;
|
||||
asm volatile("int %[irq]"
|
||||
: "=a"(ret)
|
||||
: [irq]"i"(static_cast<int>(IRQ_SYSCALL)) // WTF GCC 15
|
||||
, "a"(syscall)
|
||||
, "b"((uintptr_t)arg1)
|
||||
, "c"((uintptr_t)arg2)
|
||||
, "d"((uintptr_t)arg3)
|
||||
, "S"((uintptr_t)arg4)
|
||||
, "D"((uintptr_t)arg5)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user