Kernel/syscalls.h
2023-06-10 13:11:25 +03:00

452 lines
13 KiB
C

/*
BSD 3-Clause License
Copyright (c) 2023, EnderIce2
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __FENNIX_KERNEL_SYSCALLS_LIST_H__
#define __FENNIX_KERNEL_SYSCALLS_LIST_H__
#include <stddef.h>
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
enum MemoryMapFlags
{
MAP_PRESENT = 1 << 0,
MAP_WRITABLE = 1 << 1,
MAP_USER = 1 << 2,
};
enum KCtl
{
KCTL_NULL,
KCTL_GET_PID,
KCTL_GET_TID,
KCTL_GET_UID,
KCTL_GET_GID,
/**
* @brief Get the page size
*/
KCTL_GET_PAGE_SIZE,
/**
* @brief Check whether the current thread is critical
*/
KCTL_IS_CRITICAL,
/**
* @brief Register an ELF library
* @fn int RegisterELFLib(char *Identifier, char *Path)
*/
KCTL_REGISTER_ELF_LIB,
/**
* @brief Get an ELF library
* @fn uintptr_t GetELFLib(char *Identifier);
*/
KCTL_GET_ELF_LIB_MEMORY_IMAGE,
/**
* @brief Get the absolute path of a library file
* @fn int GetAbsolutePath(char *Identifier, char *Buffer, size_t BufferSize)
*/
KCTL_GET_ABSOLUTE_PATH,
};
/**
* @enum NativeSyscalls
* Enumeration of all the native syscalls available in the kernel
*/
enum NativeSyscalls
{
/**
*
* Basic syscalls
*
*/
/** @brief Exit the process.
* @fn int Exit(int Code)
* This syscall is used to exit the current process with the provided exit code.
*/
_Exit = 0,
/** @brief Print a message to the kernel console
* @fn int Print(char Char, int Index)
* This syscall is used to print a message to the kernel console.
*/
_Print,
/**
*
* Memory syscalls
*
*/
/** @brief Request pages of memory
* @fn uintptr_t RequestPages(size_t Count)
* This syscall is used to request a specific number of pages of memory from the kernel.
*/
_RequestPages,
/** @brief Free pages of memory
* @fn int FreePages(uintptr_t Address, size_t Count)
* This syscall is used to free a specific number of pages of memory that were previously requested.
*/
_FreePages,
/** @brief Detach memory address
* @fn int DetachAddress(uintptr_t Address)
* This syscall is used to detach a specific memory address from the current process.
*/
_DetachAddress,
/**
* @brief Map memory address
* @fn int MapAddress(uintptr_t VirtualAddress, uintptr_t PhysicalAddress, size_t Size, enum MemoryMapFlags Flags)
* This syscall is used to map a specific memory address to the current process.
*
* @param Size The size of the memory region to map. Not pages.
*/
_MemoryMap,
/** @brief Unmap memory address
* @fn int UnmapAddress(uintptr_t VirtualAddress, size_t Size)
* This syscall is used to unmap a specific memory address from the current process.
*
* @param Size The size of the memory region to unmap. Not pages.
*/
_MemoryUnmap,
/**
*
* Kernel Control syscalls
*
*/
/** @brief Kernel Control
* @fn uintptr_t KernelCTL(enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
* This syscall is used to control certain aspects of the kernel or get information about it.
*/
_KernelCTL,
/**
*
* File syscalls
*
*/
/** @brief Open a file
* @fn void *FileOpen(const char *Path, uint64_t Flags)
* This syscall is used to open a file with the provided path and flags.
*/
_FileOpen,
/** @brief Close a file
* @fn int FileClose(void *KernelPrivate)
* This syscall is used to close a file that was previously opened.
*/
_FileClose,
/** @brief Read from a file
* @fn uint64_t FileRead(void *KernelPrivate, uint8_t *Buffer, uint64_t Size)
* This syscall is used to read a specific number of bytes from a file at a specific offset.
*/
_FileRead,
/** @brief Write to a file
* @fn uint64_t FileWrite(void *KernelPrivate, uint8_t *Buffer, uint64_t Size)
* This syscall is used to write a specific number of bytes to a file at a specific offset.
*/
_FileWrite,
/** @brief Seek in a file
* @fn off_t FileSeek(void *KernelPrivate, off_t Offset, int Whence)
* This syscall is used to change the current offset in a file.
*/
_FileSeek,
/** @brief Get file status
* @fn
* This syscall is used to retrieve information about a file such as its size, permissions, etc.
*/
_FileStatus,
/**
*
* Process syscalls
*
*/
/**
* @brief Creates/Reads/Writes/Deletes an IPC Pipe/Shared Memory/Message Queue/etc.
* @fn int IPC(enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size)
* This syscall is used to create, read, write or delete an IPC Pipe/Shared Memory/Message Queue/etc.
*/
_IPC,
/** @brief Sleep for a specific amount of time
* @fn int Sleep(uint64_t Milliseconds)
* This syscall is used to sleep the current thread for a specific amount of time.
*/
_Sleep,
/** @brief Fork the current process
* @fn int Fork()
* This syscall is used to create a new process that is a copy of the current process.
*/
_Fork,
/** @brief Wait for a process or a thread
* @fn
* This syscall is used to wait for a specific process or thread to terminate. It returns the exit code of the process or thread.
*/
_Wait,
/** @brief Kill a process or a thread
* @fn
* This syscall is used to send a termination signal to a specific process or thread
*/
_Kill,
/** @brief Spawn a new process
* @fn
* This syscall is used to create a new process with the provided path and arguments.
*/
_Spawn,
/** @brief Spawn a new thread
* @fn int SpawnThread(uint64_t InstructionPointer)
* This syscall is used to create a new thread within the current process with the provided function and arguments.
*/
_SpawnThread,
/** @brief Get thread list of a process
* @fn
* This syscall is used to retrieve a list of all the threads within a specific process.
*/
_GetThreadListOfProcess,
/** @brief Get current process
* @fn
* This syscall is used to retrieve information about the current process.
*/
_GetCurrentProcess,
/** @brief Get current thread
* @fn
* This syscall is used to retrieve information about the current thread.
*/
_GetCurrentThread,
/** @brief Get current process ID
* @fn int GetCurrentProcessID()
* This syscall is used to retrieve information about the current process.
*/
_GetCurrentProcessID,
/** @brief Get current thread ID
* @fn int GetCurrentThreadID()
* This syscall is used to retrieve information about the current thread.
*/
_GetCurrentThreadID,
/** @brief Get process by PID
* @fn
* This syscall is used to retrieve information about a specific process by its PID.
*/
_GetProcessByPID,
/** @brief Get thread by TID
* @fn
* This syscall is used to retrieve information about a specific thread by its TID.
*/
_GetThreadByTID,
/** @brief Kill a process
* @fn
* This syscall is used to send a termination signal to a specific process.
*/
_KillProcess,
/** @brief Kill a thread
* @fn
* This syscall is used to send a termination signal to a specific thread.
*/
_KillThread,
/** @brief Reserved syscall */
_SysReservedCreateProcess,
/** @brief Reserved syscall */
_SysReservedCreateThread,
/** @brief Not a real syscall */
_MaxSyscall
};
/**
* @enum SyscallsErrorCodes
* Enumeration of all the error codes that can be returned by a syscall
*/
enum SyscallsErrorCodes
{
/**
* @brief Access denied
* This error code is returned when the current thread does not have the required permissions to perform the requested operation.
*/
SYSCALL_ACCESS_DENIED = -0xDEADACC,
/**
* @brief Invalid argument
* This error code is returned when an invalid argument is passed to a syscall.
*/
SYSCALL_INVALID_ARGUMENT = -0xBADAEE,
/**
* @brief Invalid syscall
* This error code is returned when an invalid syscall number is passed to the syscall handler.
*/
SYSCALL_INVALID_SYSCALL = -0xBAD55CA,
/**
* @brief Internal error
* This error code is returned when an internal error occurs in the syscall handler.
*/
SYSCALL_INTERNAL_ERROR = -0xBADBAD5,
/**
* @brief Not implemented
* This error code is returned when a syscall is not implemented.
*/
SYSCALL_NOT_IMPLEMENTED = -0xBAD5EED,
/**
* @brief Generic error
* This error code is returned when a syscall fails for an unknown reason.
*/
SYSCALL_ERROR = -1,
/**
* @brief Success
* This error code is returned when a syscall succeeds.
*/
SYSCALL_OK = 0,
};
static inline bool IsSyscallError(long ret)
{
return ret < 0;
}
static inline long syscall0(long syscall)
{
long ret;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall)
: "rcx", "r11", "memory");
return ret;
}
static inline long syscall1(long syscall, long arg1)
{
long ret;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1)
: "rcx", "r11", "memory");
return ret;
}
static inline long syscall2(long syscall, long arg1, long arg2)
{
long ret;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2)
: "rcx", "r11", "memory");
return ret;
}
static inline long syscall3(long syscall, long arg1, long arg2, long arg3)
{
long ret;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3)
: "rcx", "r11", "memory");
return ret;
}
static inline long syscall4(long syscall, long arg1, long arg2, long arg3, long arg4)
{
long ret;
register long r10 __asm__("r10") = arg4;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
: "rcx", "r11", "memory");
return ret;
}
static inline long syscall5(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5)
{
long ret;
register long r10 __asm__("r10") = arg4;
register long r8 __asm__("r8") = arg5;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
: "rcx", "r11", "memory");
return ret;
}
static inline long syscall6(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
{
long ret;
register long r10 __asm__("r10") = arg4;
register long r8 __asm__("r8") = arg5;
register long r9 __asm__("r9") = arg6;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9)
: "rcx", "r11", "memory");
return ret;
}
#endif // !__FENNIX_KERNEL_SYSCALLS_LIST_H__