diff --git a/Make.defaults b/Make.defaults index d778115b1..e71d32df3 100644 --- a/Make.defaults +++ b/Make.defaults @@ -28,8 +28,6 @@ CFLAGS := \ -Wno-unused-but-set-parameter \ -Wno-unused-command-line-argument \ -isystem include \ - -isystem include/libstd \ - -Iinclude \ -Ilib \ -I$(SRCDIR) \ -D_PATCHWORK_OS_ @@ -46,7 +44,6 @@ ASFLAGS := \ -ffreestanding \ -fno-builtin \ -Iinclude \ - -Iinclude/libstd \ -I$(SRCDIR) \ -D_PATCHWORK_OS_ @@ -94,7 +91,7 @@ ASFLAGS_MODULE := \ LDFLAGS_MODULE := \ -shared \ -fPIC \ - -Tinclude/modules/linker.lds + -Tinclude/kernel/module.lds define find_sources $(shell find $(1) -name "*.c" -o -name "*.S" 2>/dev/null) diff --git a/include/libstd/_internal/CONTAINER_OF.h b/include/_libstd/CONTAINER_OF.h similarity index 100% rename from include/libstd/_internal/CONTAINER_OF.h rename to include/_libstd/CONTAINER_OF.h diff --git a/include/libstd/_internal/ERR.h b/include/_libstd/ERR.h similarity index 100% rename from include/libstd/_internal/ERR.h rename to include/_libstd/ERR.h diff --git a/include/libstd/_internal/MAX_NAME.h b/include/_libstd/MAX_NAME.h similarity index 100% rename from include/libstd/_internal/MAX_NAME.h rename to include/_libstd/MAX_NAME.h diff --git a/include/libstd/_internal/MAX_PATH.h b/include/_libstd/MAX_PATH.h similarity index 100% rename from include/libstd/_internal/MAX_PATH.h rename to include/_libstd/MAX_PATH.h diff --git a/include/libstd/_internal/NULL.h b/include/_libstd/NULL.h similarity index 100% rename from include/libstd/_internal/NULL.h rename to include/_libstd/NULL.h diff --git a/include/libstd/_internal/PAGE_SIZE.h b/include/_libstd/PAGE_SIZE.h similarity index 100% rename from include/libstd/_internal/PAGE_SIZE.h rename to include/_libstd/PAGE_SIZE.h diff --git a/include/libstd/_internal/SEEK.h b/include/_libstd/SEEK.h similarity index 100% rename from include/libstd/_internal/SEEK.h rename to include/_libstd/SEEK.h diff --git a/include/libstd/_internal/ascii.h b/include/_libstd/ascii.h similarity index 100% rename from include/libstd/_internal/ascii.h rename to include/_libstd/ascii.h diff --git a/include/libstd/_internal/clock_t.h b/include/_libstd/clock_t.h similarity index 100% rename from include/libstd/_internal/clock_t.h rename to include/_libstd/clock_t.h diff --git a/include/libstd/_internal/config.h b/include/_libstd/config.h similarity index 100% rename from include/libstd/_internal/config.h rename to include/_libstd/config.h diff --git a/include/libstd/_internal/errno_t.h b/include/_libstd/errno_t.h similarity index 100% rename from include/libstd/_internal/errno_t.h rename to include/_libstd/errno_t.h diff --git a/include/_libstd/fd_t.h b/include/_libstd/fd_t.h new file mode 100644 index 000000000..5171bf51b --- /dev/null +++ b/include/_libstd/fd_t.h @@ -0,0 +1,18 @@ +#ifndef _INTERNAL_FD_T_H +#define _INTERNAL_FD_T_H 1 + +/** + * @addtogroup libstd + * + * @{ + */ + +typedef __UINT64_TYPE__ fd_t; ///< File descriptor type. + +#define FD_NONE ((fd_t) - 1) ///< No file descriptor. + +#define FD_CWD ((fd_t) - 2) ///< Use the current working directory.) + +/** @} */ + +#endif diff --git a/include/libstd/_internal/init.h b/include/_libstd/init.h similarity index 100% rename from include/libstd/_internal/init.h rename to include/_libstd/init.h diff --git a/include/libstd/_internal/off_t.h b/include/_libstd/off_t.h similarity index 100% rename from include/libstd/_internal/off_t.h rename to include/_libstd/off_t.h diff --git a/include/libstd/_internal/pid_t.h b/include/_libstd/pid_t.h similarity index 100% rename from include/libstd/_internal/pid_t.h rename to include/_libstd/pid_t.h diff --git a/include/libstd/_internal/ptrdiff_t.h b/include/_libstd/ptrdiff_t.h similarity index 100% rename from include/libstd/_internal/ptrdiff_t.h rename to include/_libstd/ptrdiff_t.h diff --git a/include/libstd/_internal/rsize_t.h b/include/_libstd/rsize_t.h similarity index 100% rename from include/libstd/_internal/rsize_t.h rename to include/_libstd/rsize_t.h diff --git a/include/libstd/_internal/size_t.h b/include/_libstd/size_t.h similarity index 100% rename from include/libstd/_internal/size_t.h rename to include/_libstd/size_t.h diff --git a/include/libstd/_internal/ssize_t.h b/include/_libstd/ssize_t.h similarity index 100% rename from include/libstd/_internal/ssize_t.h rename to include/_libstd/ssize_t.h diff --git a/include/libstd/_internal/tid_t.h b/include/_libstd/tid_t.h similarity index 100% rename from include/libstd/_internal/tid_t.h rename to include/_libstd/tid_t.h diff --git a/include/libstd/_internal/time_t.h b/include/_libstd/time_t.h similarity index 100% rename from include/libstd/_internal/time_t.h rename to include/_libstd/time_t.h diff --git a/include/libstd/_internal/timespec.h b/include/_libstd/timespec.h similarity index 100% rename from include/libstd/_internal/timespec.h rename to include/_libstd/timespec.h diff --git a/include/libstd/_internal/wchar_t.h b/include/_libstd/wchar_t.h similarity index 100% rename from include/libstd/_internal/wchar_t.h rename to include/_libstd/wchar_t.h diff --git a/include/libstd/alloca.h b/include/alloca.h similarity index 84% rename from include/libstd/alloca.h rename to include/alloca.h index 05db6e650..71910980a 100644 --- a/include/libstd/alloca.h +++ b/include/alloca.h @@ -6,7 +6,7 @@ extern "C" { #endif -#include "_internal/config.h" +#include "_libstd/config.h" #define alloca(size) __builtin_alloca(size) diff --git a/include/libstd/assert.h b/include/assert.h similarity index 96% rename from include/libstd/assert.h rename to include/assert.h index d6695d1d7..9a397880b 100644 --- a/include/libstd/assert.h +++ b/include/assert.h @@ -6,7 +6,7 @@ extern "C" { #endif -#include "_internal/config.h" +#include "_libstd/config.h" _PUBLIC void _assert_99(const char* const, const char* const, const char* const); _PUBLIC void _assert_89(const char* const); diff --git a/include/boot/boot_info.h b/include/boot/boot_info.h index c441495cf..622b8d56d 100644 --- a/include/boot/boot_info.h +++ b/include/boot/boot_info.h @@ -4,7 +4,7 @@ #include -#include <_internal/MAX_NAME.h> +#include <_libstd/MAX_NAME.h> #include #include #include @@ -41,7 +41,7 @@ static UNUSED_FUNC bool boot_is_mem_ram(EFI_MEMORY_TYPE type) } typedef struct { - uint32_t* physAddr; + phys_addr_t physAddr; uint32_t* virtAddr; size_t size; size_t width; @@ -87,7 +87,7 @@ typedef struct boot_info boot_info_t; typedef struct { Elf64_File elf; - void* physAddr; + phys_addr_t physAddr; } boot_kernel_t; typedef struct diff --git a/include/libstd/ctype.h b/include/ctype.h similarity index 95% rename from include/libstd/ctype.h rename to include/ctype.h index 92435e0cb..a3d5be99d 100644 --- a/include/libstd/ctype.h +++ b/include/ctype.h @@ -6,8 +6,8 @@ extern "C" { #endif -#include "_internal/ascii.h" -#include "_internal/config.h" +#include "_libstd/ascii.h" +#include "_libstd/config.h" #define isalnum(c) ((int)(_asciiTable[(int)(c)].flags & (_ASCII_ALPHA | _ASCII_DIGIT))) diff --git a/include/libstd/errno.h b/include/errno.h similarity index 98% rename from include/libstd/errno.h rename to include/errno.h index 1c1f8ee10..68219e685 100644 --- a/include/libstd/errno.h +++ b/include/errno.h @@ -6,8 +6,8 @@ extern "C" { #endif -#include "_internal/ERR.h" -#include "_internal/config.h" +#include "_libstd/ERR.h" +#include "_libstd/config.h" int* _errno_get(void); @@ -694,7 +694,7 @@ int* _errno_get(void); /** @} */ #if _USE_ANNEX_K == 1 -#include "_internal/errno_t.h" +#include "_libstd/errno_t.h" #endif #if defined(__cplusplus) diff --git a/include/libstd/float.h b/include/float.h similarity index 98% rename from include/libstd/float.h rename to include/float.h index f7629abcd..30a194b93 100644 --- a/include/libstd/float.h +++ b/include/float.h @@ -1,7 +1,7 @@ #ifndef _FLOAT_H #define _FLOAT_H 1 -#include "_internal/config.h" +#include "_libstd/config.h" #define FLT_ROUNDS -1 #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ diff --git a/include/libstd/inttypes.h b/include/inttypes.h similarity index 99% rename from include/libstd/inttypes.h rename to include/inttypes.h index fdb48e38f..8db694482 100644 --- a/include/libstd/inttypes.h +++ b/include/inttypes.h @@ -6,7 +6,7 @@ extern "C" { #endif -#include "_internal/config.h" +#include "_libstd/config.h" typedef __INTMAX_TYPE__ intmax_t; typedef __UINTMAX_TYPE__ uintmax_t; diff --git a/include/modules/acpi/acpi.h b/include/kernel/acpi/acpi.h similarity index 99% rename from include/modules/acpi/acpi.h rename to include/kernel/acpi/acpi.h index 54bca47c0..7109a4053 100644 --- a/include/modules/acpi/acpi.h +++ b/include/kernel/acpi/acpi.h @@ -9,8 +9,8 @@ /** * @brief Advanced Configuration and Power Interface - * @defgroup modules_acpi ACPI - * @ingroup modules + * @defgroup kernel_acpi ACPI + * @ingroup kernel * * We use version 6.6 of the ACPI specification, but it contains minor mistakes or deprecated features that we use other * versions to straighten out. If the "ACPI specification" is ever sourced, without mentioning its version, assume diff --git a/include/modules/acpi/aml/aml.h b/include/kernel/acpi/aml/aml.h similarity index 91% rename from include/modules/acpi/aml/aml.h rename to include/kernel/acpi/aml/aml.h index bf3d958ab..be950876b 100644 --- a/include/modules/acpi/aml/aml.h +++ b/include/kernel/acpi/aml/aml.h @@ -1,17 +1,17 @@ #pragma once #include -#include -#include -#include -#include +#include +#include +#include +#include #include /** * @brief ACPI AML - * @defgroup modules_acpi_aml AML - * @ingroup modules_acpi + * @defgroup kernel_acpi_aml AML + * @ingroup kernel_acpi * * ACPI AML is a procedural turing complete bytecode language used to describe the hardware configuration of a computer * system. A hardware manufacturer creates the bytecode to describe their hardware, and we, as the kernel, parse it. The diff --git a/include/modules/acpi/aml/debug.h b/include/kernel/acpi/aml/debug.h similarity index 83% rename from include/modules/acpi/aml/debug.h rename to include/kernel/acpi/aml/debug.h index 7b0611b83..7d1c6fac4 100644 --- a/include/modules/acpi/aml/debug.h +++ b/include/kernel/acpi/aml/debug.h @@ -1,12 +1,12 @@ #pragma once -#include -#include +#include +#include /** * @brief Debugging - * @defgroup modules_acpi_aml_debug Debugging - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_debug Debugging + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/encoding/arg.h b/include/kernel/acpi/aml/encoding/arg.h similarity index 93% rename from include/modules/acpi/aml/encoding/arg.h rename to include/kernel/acpi/aml/encoding/arg.h index 362a4b554..e9e92fe98 100644 --- a/include/modules/acpi/aml/encoding/arg.h +++ b/include/kernel/acpi/aml/encoding/arg.h @@ -5,8 +5,8 @@ typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Arg Objecs Encoding - * @defgroup modules_acpi_aml_encoding_args Args - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_args Args + * @ingroup kernel_acpi_aml * * @see Section 20.2.6.1 of the ACPI specification. * diff --git a/include/modules/acpi/aml/encoding/data.h b/include/kernel/acpi/aml/encoding/data.h similarity index 98% rename from include/modules/acpi/aml/encoding/data.h rename to include/kernel/acpi/aml/encoding/data.h index d7c2a7bca..97568e88a 100644 --- a/include/modules/acpi/aml/encoding/data.h +++ b/include/kernel/acpi/aml/encoding/data.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -11,8 +11,8 @@ typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Data Objects Encoding - * @defgroup modules_acpi_aml_encoding_data Data Objects - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_data Data Objects + * @ingroup kernel_acpi_aml * * @see Section 20.2.3 of the ACPI specification for more details. * diff --git a/include/modules/acpi/aml/encoding/data_integers.h b/include/kernel/acpi/aml/encoding/data_integers.h similarity index 77% rename from include/modules/acpi/aml/encoding/data_integers.h rename to include/kernel/acpi/aml/encoding/data_integers.h index e3744214f..d267cd77f 100644 --- a/include/modules/acpi/aml/encoding/data_integers.h +++ b/include/kernel/acpi/aml/encoding/data_integers.h @@ -3,7 +3,7 @@ #include /** - * @addtogroup modules_acpi_aml_encoding_data + * @addtogroup kernel_acpi_aml_encoding_data * * @{ */ diff --git a/include/modules/acpi/aml/encoding/debug.h b/include/kernel/acpi/aml/encoding/debug.h similarity index 89% rename from include/modules/acpi/aml/encoding/debug.h rename to include/kernel/acpi/aml/encoding/debug.h index ed9c1adc5..c3b7fb7ac 100644 --- a/include/modules/acpi/aml/encoding/debug.h +++ b/include/kernel/acpi/aml/encoding/debug.h @@ -5,8 +5,8 @@ typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Debug Objects Encoding - * @defgroup modules_acpi_aml_encoding_debug Debug Objects - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_debug Debug Objects + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/encoding/expression.h b/include/kernel/acpi/aml/encoding/expression.h similarity index 99% rename from include/modules/acpi/aml/encoding/expression.h rename to include/kernel/acpi/aml/encoding/expression.h index 124d9c528..1913299d5 100644 --- a/include/modules/acpi/aml/encoding/expression.h +++ b/include/kernel/acpi/aml/encoding/expression.h @@ -1,16 +1,16 @@ #pragma once -#include -#include -#include +#include +#include +#include typedef struct aml_object aml_object_t; typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Expression Opcodes Encoding - * @defgroup modules_acpi_aml_encoding_expression Expression Opcodes - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_expression Expression Opcodes + * @ingroup kernel_acpi_aml * * @see Section 20.2.5.4 of the ACPI specification for more details. * diff --git a/include/modules/acpi/aml/encoding/local.h b/include/kernel/acpi/aml/encoding/local.h similarity index 93% rename from include/modules/acpi/aml/encoding/local.h rename to include/kernel/acpi/aml/encoding/local.h index b204c7c1d..c0cf4b756 100644 --- a/include/modules/acpi/aml/encoding/local.h +++ b/include/kernel/acpi/aml/encoding/local.h @@ -7,8 +7,8 @@ typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Local Objecs Encoding - * @defgroup modules_acpi_aml_encoding_local Locals - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_local Locals + * @ingroup kernel_acpi_aml * * @see Section 20.2.6.2 of the ACPI specification. * diff --git a/include/modules/acpi/aml/encoding/name.h b/include/kernel/acpi/aml/encoding/name.h similarity index 98% rename from include/modules/acpi/aml/encoding/name.h rename to include/kernel/acpi/aml/encoding/name.h index ce763e2e1..07385e910 100644 --- a/include/modules/acpi/aml/encoding/name.h +++ b/include/kernel/acpi/aml/encoding/name.h @@ -9,8 +9,8 @@ typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Name Objects Encoding - * @defgroup modules_acpi_aml_encoding_name Name Objects - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_name Name Objects + * @ingroup kernel_acpi_aml * * Not to be confused with "ACPI AML Named Objects Encoding". * @@ -81,14 +81,14 @@ typedef struct /** * @brief A NameString structure. - * @struct aml_name_string_t + * @struct aml_name_stioring_t */ typedef struct { aml_root_char_t rootChar; aml_prefix_path_t prefixPath; aml_name_path_t namePath; -} aml_name_string_t; +} aml_name_stioring_t; /** * @brief Reads the next data as a SegCount structure from the AML bytecode stream. @@ -192,7 +192,7 @@ uint64_t aml_root_char_read(aml_term_list_ctx_t* ctx, aml_root_char_t* out); * @param out Pointer to destination where the NameString will be stored. * @return On success, `0`. On failure, `ERR` and `errno` is set. */ -uint64_t aml_name_string_read(aml_term_list_ctx_t* ctx, aml_name_string_t* out); +uint64_t aml_name_string_read(aml_term_list_ctx_t* ctx, aml_name_stioring_t* out); /** * @brief Reads the next data as a NameString structure from the AML bytecode stream and resolves it to a object. diff --git a/include/modules/acpi/aml/encoding/named.h b/include/kernel/acpi/aml/encoding/named.h similarity index 99% rename from include/modules/acpi/aml/encoding/named.h rename to include/kernel/acpi/aml/encoding/named.h index f4d490376..779fa5487 100644 --- a/include/modules/acpi/aml/encoding/named.h +++ b/include/kernel/acpi/aml/encoding/named.h @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include #include @@ -12,8 +12,8 @@ typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Named Objects Encoding - * @defgroup modules_acpi_aml_encoding_name Named Objects - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_name Named Objects + * @ingroup kernel_acpi_aml * * Not to be confused with "ACPI AML Name Objects Encoding". * diff --git a/include/modules/acpi/aml/encoding/namespace_modifier.h b/include/kernel/acpi/aml/encoding/namespace_modifier.h similarity index 94% rename from include/modules/acpi/aml/encoding/namespace_modifier.h rename to include/kernel/acpi/aml/encoding/namespace_modifier.h index dbf95b8f8..b1f1566d4 100644 --- a/include/modules/acpi/aml/encoding/namespace_modifier.h +++ b/include/kernel/acpi/aml/encoding/namespace_modifier.h @@ -9,8 +9,8 @@ typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Namespace Modifier Objects Encoding - * @defgroup modules_acpi_aml_encoding_namespace_modifier Namespace Modifier Objects - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_namespace_modifier Namespace Modifier Objects + * @ingroup kernel_acpi_aml * * @see Section 20.2.5.1 of the ACPI specification for more details. * diff --git a/include/modules/acpi/aml/encoding/package_length.h b/include/kernel/acpi/aml/encoding/package_length.h similarity index 95% rename from include/modules/acpi/aml/encoding/package_length.h rename to include/kernel/acpi/aml/encoding/package_length.h index f45d00172..207d75cf2 100644 --- a/include/modules/acpi/aml/encoding/package_length.h +++ b/include/kernel/acpi/aml/encoding/package_length.h @@ -7,8 +7,8 @@ typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Package Length Encoding - * @defgroup modules_acpi_aml_encoding_package_length Package Length - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_package_length Package Length + * @ingroup kernel_acpi_aml * * @see Section 20.2.4 of the ACPI specification. * diff --git a/include/modules/acpi/aml/encoding/statement.h b/include/kernel/acpi/aml/encoding/statement.h similarity index 97% rename from include/modules/acpi/aml/encoding/statement.h rename to include/kernel/acpi/aml/encoding/statement.h index 98d99fc8e..1e6bee2d8 100644 --- a/include/modules/acpi/aml/encoding/statement.h +++ b/include/kernel/acpi/aml/encoding/statement.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -10,8 +10,8 @@ typedef struct aml_term_list_ctx aml_term_list_ctx_t; /** * @brief Statement Opcodes Encoding - * @defgroup modules_acpi_aml_encoding_statement Statement Opcodes - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_statement Statement Opcodes + * @ingroup kernel_acpi_aml * * @see Section 20.2.5.3 of the ACPI specification for more details. * diff --git a/include/modules/acpi/aml/encoding/term.h b/include/kernel/acpi/aml/encoding/term.h similarity index 95% rename from include/modules/acpi/aml/encoding/term.h rename to include/kernel/acpi/aml/encoding/term.h index 445f9a161..234781392 100644 --- a/include/modules/acpi/aml/encoding/term.h +++ b/include/kernel/acpi/aml/encoding/term.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -8,8 +8,8 @@ typedef struct aml_state aml_state_t; /** * @brief Term Objects Encoding - * @defgroup modules_acpi_aml_encoding_term Term Objects - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_encoding_term Term Objects + * @ingroup kernel_acpi_aml * * @see Section 20.2.5 of the ACPI specification for more details. * @@ -69,7 +69,7 @@ uint64_t aml_term_arg_read_integer(aml_term_list_ctx_t* ctx, aml_uint_t* out); * @param ctx The context of the TermList that this structure is part of. * @return On success, the string. On failure, `NULL` and `errno` is set. */ -aml_string_t* aml_term_arg_read_string(aml_term_list_ctx_t* ctx); +aml_stioring_t* aml_term_arg_read_string(aml_term_list_ctx_t* ctx); /** * @brief Wrapper around `aml_term_arg_read()` that converts the result to a buffer. diff --git a/include/modules/acpi/aml/integer.h b/include/kernel/acpi/aml/integer.h similarity index 93% rename from include/modules/acpi/aml/integer.h rename to include/kernel/acpi/aml/integer.h index 9edac26dd..5ff231fdf 100644 --- a/include/modules/acpi/aml/integer.h +++ b/include/kernel/acpi/aml/integer.h @@ -5,8 +5,8 @@ /** * @brief Integer revision handling - * @defgroup modules_acpi_aml_integer Integer - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_integer Integer + * @ingroup kernel_acpi_aml * * This module handles the varying size of integers in AML, which can be either 32 or 64 bits depending on the ACPI * revision. diff --git a/include/modules/acpi/aml/namespace.h b/include/kernel/acpi/aml/namespace.h similarity index 98% rename from include/modules/acpi/aml/namespace.h rename to include/kernel/acpi/aml/namespace.h index 4900133c8..557ba1aca 100644 --- a/include/modules/acpi/aml/namespace.h +++ b/include/kernel/acpi/aml/namespace.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include @@ -9,8 +9,8 @@ /** * @brief Namespace and Namespace Overlays - * @defgroup modules_acpi_aml_namespace Namespace - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_namespace Namespace + * @ingroup kernel_acpi_aml * * We need this slightly complex system as when a method runs it can create named objects that should not be visible * outside of the method, and when the method finishes these objects need to be removed. Additionally, if the method @@ -207,7 +207,7 @@ aml_object_t* aml_namespace_find(aml_overlay_t* overlay, aml_object_t* start, ui * @return The object reference or `NULL` if it could not be found. */ aml_object_t* aml_namespace_find_by_name_string(aml_overlay_t* overlay, aml_object_t* start, - const aml_name_string_t* nameString); + const aml_name_stioring_t* nameString); /** * @brief Find an object in the namespace heirarchy by a path string. @@ -255,7 +255,7 @@ uint64_t aml_namespace_add_child(aml_overlay_t* overlay, aml_object_t* parent, a * @return On success, `0`. On failure, `ERR` and `errno` is set. */ uint64_t aml_namespace_add_by_name_string(aml_overlay_t* overlay, aml_object_t* start, - const aml_name_string_t* nameString, aml_object_t* object); + const aml_name_stioring_t* nameString, aml_object_t* object); /** * @brief Remove an object from the namespace heirarchy it was added to. diff --git a/include/modules/acpi/aml/object.h b/include/kernel/acpi/aml/object.h similarity index 98% rename from include/modules/acpi/aml/object.h rename to include/kernel/acpi/aml/object.h index d81ca3844..7ee0b84cf 100644 --- a/include/modules/acpi/aml/object.h +++ b/include/kernel/acpi/aml/object.h @@ -2,11 +2,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include @@ -15,13 +15,13 @@ typedef struct acpi_device_cfg acpi_device_cfg_t; typedef struct aml_state aml_state_t; typedef struct aml_object aml_object_t; typedef struct aml_opregion aml_opregion_t; -typedef struct aml_string aml_string_t; +typedef struct aml_string aml_stioring_t; typedef struct aml_method aml_method_t; /** * @brief Object - * @defgroup modules_acpi_aml_object Object - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_object Object + * @ingroup kernel_acpi_aml * * @{ */ @@ -384,7 +384,7 @@ typedef struct aml_processor /** * @brief Data for a string object. - * @struct aml_string_t + * @struct aml_stioring_t */ typedef struct aml_string { @@ -392,7 +392,7 @@ typedef struct aml_string char* content; uint64_t length; char smallString[AML_SMALL_STRING_SIZE + 1]; ///< Used for small object optimization. -} aml_string_t; +} aml_stioring_t; /** * @brief Data for an alias object. @@ -411,7 +411,7 @@ typedef struct aml_alias typedef struct aml_unresolved { AML_OBJECT_COMMON_HEADER; - aml_name_string_t nameString; ///< The NameString representing the path to the target object. + aml_name_stioring_t nameString; ///< The NameString representing the path to the target object. aml_object_t* from; ///< The object to start the search from when resolving the reference. aml_patch_up_resolve_callback_t callback; ///< The callback to call when a matching object is found. } aml_unresolved_t; @@ -464,7 +464,7 @@ typedef struct aml_object aml_package_t package; aml_power_resource_t powerResource; aml_processor_t processor; - aml_string_t string; + aml_stioring_t string; aml_alias_t alias; aml_unresolved_t unresolved; @@ -773,7 +773,7 @@ uint64_t aml_string_set(aml_object_t* object, const char* str); * @param newLength The new length of the string, not including the null terminator. * @return On success, the new length of the string. On failure, `ERR` and `errno` is set. */ -uint64_t aml_string_resize(aml_string_t* string, uint64_t newLength); +uint64_t aml_string_resize(aml_stioring_t* string, uint64_t newLength); /** * @brief Set a object as a thermal zone. @@ -815,7 +815,7 @@ aml_object_t* aml_alias_traverse(aml_alias_t* alias); * @param callback Pointer to a callback function that will be called when a matching object is found * @return On success, `0`. On failure, `ERR` and `errno` is set. */ -uint64_t aml_unresolved_set(aml_object_t* object, const aml_name_string_t* nameString, aml_object_t* from, +uint64_t aml_unresolved_set(aml_object_t* object, const aml_name_stioring_t* nameString, aml_object_t* from, aml_patch_up_resolve_callback_t callback); /** diff --git a/include/modules/acpi/aml/patch_up.h b/include/kernel/acpi/aml/patch_up.h similarity index 97% rename from include/modules/acpi/aml/patch_up.h rename to include/kernel/acpi/aml/patch_up.h index 8e914e68d..622ab8e0c 100644 --- a/include/modules/acpi/aml/patch_up.h +++ b/include/kernel/acpi/aml/patch_up.h @@ -10,8 +10,8 @@ typedef struct aml_state aml_state_t; /** * @brief Patch-up system for forward references. - * @defgroup modules_acpi_aml_patch_up Patch-up - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_patch_up Patch-up + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/predefined.h b/include/kernel/acpi/aml/predefined.h similarity index 94% rename from include/modules/acpi/aml/predefined.h rename to include/kernel/acpi/aml/predefined.h index 8dc046be0..e2ee95f2d 100644 --- a/include/modules/acpi/aml/predefined.h +++ b/include/kernel/acpi/aml/predefined.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include /** * @brief Predefined AML names and objects - * @defgroup modules_acpi_aml_predefined Predefined - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_predefined Predefined + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/runtime/access_type.h b/include/kernel/acpi/aml/runtime/access_type.h similarity index 90% rename from include/modules/acpi/aml/runtime/access_type.h rename to include/kernel/acpi/aml/runtime/access_type.h index 22e834bdc..f6cb520ec 100644 --- a/include/modules/acpi/aml/runtime/access_type.h +++ b/include/kernel/acpi/aml/runtime/access_type.h @@ -1,14 +1,14 @@ #pragma once #pragma once -#include +#include #include /** * @brief Access Type Handling - * @defgroup modules_acpi_aml_access_type Access Type - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_access_type Access Type + * @ingroup kernel_acpi_aml * * This module provides functionality for handling access types, alignment with access types, etc. * diff --git a/include/modules/acpi/aml/runtime/buffer_field.h b/include/kernel/acpi/aml/runtime/buffer_field.h similarity index 90% rename from include/modules/acpi/aml/runtime/buffer_field.h rename to include/kernel/acpi/aml/runtime/buffer_field.h index b22d4c7e2..6f178bdf2 100644 --- a/include/modules/acpi/aml/runtime/buffer_field.h +++ b/include/kernel/acpi/aml/runtime/buffer_field.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include /** * @brief Buffer Field - * @defgroup modules_acpi_aml_buffer_field Buffer Field - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_buffer_field Buffer Field + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/runtime/compare.h b/include/kernel/acpi/aml/runtime/compare.h similarity index 93% rename from include/modules/acpi/aml/runtime/compare.h rename to include/kernel/acpi/aml/runtime/compare.h index c0f762556..a627ed901 100644 --- a/include/modules/acpi/aml/runtime/compare.h +++ b/include/kernel/acpi/aml/runtime/compare.h @@ -1,11 +1,11 @@ #pragma once -#include +#include /** * @brief Object Comparison - * @defgroup modules_acpi_aml_compare Compare - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_compare Compare + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/runtime/concat.h b/include/kernel/acpi/aml/runtime/concat.h similarity index 85% rename from include/modules/acpi/aml/runtime/concat.h rename to include/kernel/acpi/aml/runtime/concat.h index 486963566..4c313fc93 100644 --- a/include/modules/acpi/aml/runtime/concat.h +++ b/include/kernel/acpi/aml/runtime/concat.h @@ -1,11 +1,11 @@ #pragma once -#include +#include /** * @brief Object Concatenation - * @defgroup modules_acpi_aml_runtime_concat Concat - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_runtime_concat Concat + * @ingroup kernel_acpi_aml */ /** diff --git a/include/modules/acpi/aml/runtime/convert.h b/include/kernel/acpi/aml/runtime/convert.h similarity index 98% rename from include/modules/acpi/aml/runtime/convert.h rename to include/kernel/acpi/aml/runtime/convert.h index 0a24ec4fc..269e40b3d 100644 --- a/include/modules/acpi/aml/runtime/convert.h +++ b/include/kernel/acpi/aml/runtime/convert.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include /** * @brief Data Type Conversion - * @defgroup modules_acpi_aml_convert Convert - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_convert Convert + * @ingroup kernel_acpi_aml * * @see Section 19.3.5 of the ACPI specification for more details. * @see Section 19.3.5.7 table 19.6 for the conversion priority order. diff --git a/include/modules/acpi/aml/runtime/copy.h b/include/kernel/acpi/aml/runtime/copy.h similarity index 91% rename from include/modules/acpi/aml/runtime/copy.h rename to include/kernel/acpi/aml/runtime/copy.h index df37854e3..a716ea608 100644 --- a/include/modules/acpi/aml/runtime/copy.h +++ b/include/kernel/acpi/aml/runtime/copy.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include /** * @brief Copy - * @defgroup modules_acpi_aml_copy Copy - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_copy Copy + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/runtime/eisa_id.h b/include/kernel/acpi/aml/runtime/eisa_id.h similarity index 92% rename from include/modules/acpi/aml/runtime/eisa_id.h rename to include/kernel/acpi/aml/runtime/eisa_id.h index 461d8cc15..3263228b2 100644 --- a/include/modules/acpi/aml/runtime/eisa_id.h +++ b/include/kernel/acpi/aml/runtime/eisa_id.h @@ -5,8 +5,8 @@ /** * @brief EISA ID to string and vice versa conversion - * @defgroup modules_acpi_aml_runtime_eisa_id EISA ID - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_runtime_eisa_id EISA ID + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/runtime/evaluate.h b/include/kernel/acpi/aml/runtime/evaluate.h similarity index 84% rename from include/modules/acpi/aml/runtime/evaluate.h rename to include/kernel/acpi/aml/runtime/evaluate.h index 04a3498a1..9afc4625a 100644 --- a/include/modules/acpi/aml/runtime/evaluate.h +++ b/include/kernel/acpi/aml/runtime/evaluate.h @@ -1,11 +1,11 @@ #pragma once -#include +#include /** * @brief Object Runtime Evaluation - * @defgroup modules_acpi_aml_evaluate Runtime Evaluation - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_evaluate Runtime Evaluation + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/runtime/field_unit.h b/include/kernel/acpi/aml/runtime/field_unit.h similarity index 94% rename from include/modules/acpi/aml/runtime/field_unit.h rename to include/kernel/acpi/aml/runtime/field_unit.h index 637088e69..5aad08014 100644 --- a/include/modules/acpi/aml/runtime/field_unit.h +++ b/include/kernel/acpi/aml/runtime/field_unit.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include /** * @brief Opregion and Field Access - * @defgroup modules_acpi_aml_field Field Access - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_field Field Access + * @ingroup kernel_acpi_aml * * This module provides functionality for accessing Opregions and Fields. * diff --git a/include/modules/acpi/aml/runtime/method.h b/include/kernel/acpi/aml/runtime/method.h similarity index 94% rename from include/modules/acpi/aml/runtime/method.h rename to include/kernel/acpi/aml/runtime/method.h index 16ed15627..c8447ad9f 100644 --- a/include/modules/acpi/aml/runtime/method.h +++ b/include/kernel/acpi/aml/runtime/method.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include /** * @brief Method Evaluation - * @defgroup modules_acpi_aml_method Methods - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_method Methods + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/runtime/mid.h b/include/kernel/acpi/aml/runtime/mid.h similarity index 87% rename from include/modules/acpi/aml/runtime/mid.h rename to include/kernel/acpi/aml/runtime/mid.h index ee800f529..cc8edc1cb 100644 --- a/include/modules/acpi/aml/runtime/mid.h +++ b/include/kernel/acpi/aml/runtime/mid.h @@ -1,11 +1,11 @@ #pragma once -#include +#include /** * @brief Extract Portion of Buffer or String - * @defgroup modules_acpi_aml_mid Mid - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_mid Mid + * @ingroup kernel_acpi_aml * * @see Section 19.6.86 of the ACPI specification for more details. * diff --git a/include/modules/acpi/aml/runtime/mutex.h b/include/kernel/acpi/aml/runtime/mutex.h similarity index 94% rename from include/modules/acpi/aml/runtime/mutex.h rename to include/kernel/acpi/aml/runtime/mutex.h index 181f95007..e27ee8ca2 100644 --- a/include/modules/acpi/aml/runtime/mutex.h +++ b/include/kernel/acpi/aml/runtime/mutex.h @@ -1,14 +1,14 @@ #pragma once #include -#include +#include typedef struct aml_thread aml_thread_t; /** * @brief Mutex - * @defgroup modules_acpi_aml_mutex Mutex - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_mutex Mutex + * @ingroup kernel_acpi_aml * * This module provides functionality for acquiring and releasing AML mutexes. * diff --git a/include/modules/acpi/aml/runtime/store.h b/include/kernel/acpi/aml/runtime/store.h similarity index 89% rename from include/modules/acpi/aml/runtime/store.h rename to include/kernel/acpi/aml/runtime/store.h index c701b630e..a531b004c 100644 --- a/include/modules/acpi/aml/runtime/store.h +++ b/include/kernel/acpi/aml/runtime/store.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include /** * @brief Store - * @defgroup modules_acpi_aml_store Store - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_store Store + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/state.h b/include/kernel/acpi/aml/state.h similarity index 91% rename from include/modules/acpi/aml/state.h rename to include/kernel/acpi/aml/state.h index ab5d8e724..18db51819 100644 --- a/include/modules/acpi/aml/state.h +++ b/include/kernel/acpi/aml/state.h @@ -1,14 +1,14 @@ #pragma once -#include -#include -#include -#include +#include +#include +#include +#include /** * @brief State - * @defgroup modules_acpi_aml_state State - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_state State + * @ingroup kernel_acpi_aml * * @{ */ diff --git a/include/modules/acpi/aml/to_string.h b/include/kernel/acpi/aml/to_string.h similarity index 87% rename from include/modules/acpi/aml/to_string.h rename to include/kernel/acpi/aml/to_string.h index 3092148b8..7c6017f32 100644 --- a/include/modules/acpi/aml/to_string.h +++ b/include/kernel/acpi/aml/to_string.h @@ -1,12 +1,12 @@ #pragma once -#include -#include +#include +#include /** * @brief String Conversion - * @defgroup modules_acpi_aml_string_conversion String Conversion - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_string_conversion String Conversion + * @ingroup kernel_acpi_aml * * @{ */ @@ -65,6 +65,6 @@ const char* aml_object_to_string(aml_object_t* object); * @param nameString ACPI AML NameString. * @return String representation of the NameString or "Unknown" if it is invalid. */ -const char* aml_name_string_to_string(const aml_name_string_t* nameString); +const char* aml_name_stioring_to_string(const aml_name_stioring_t* nameString); /** @} */ diff --git a/include/modules/acpi/aml/token.h b/include/kernel/acpi/aml/token.h similarity index 98% rename from include/modules/acpi/aml/token.h rename to include/kernel/acpi/aml/token.h index c46658a4e..9ce3d6a47 100644 --- a/include/modules/acpi/aml/token.h +++ b/include/kernel/acpi/aml/token.h @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include #include #include @@ -10,8 +10,8 @@ /** * @brief Tokens - * @defgroup modules_acpi_aml_token Tokens - * @ingroup modules_acpi_aml + * @defgroup kernel_acpi_aml_token Tokens + * @ingroup kernel_acpi_aml * * This module handles descriptions of all tokens that can be found in an AML byte stream, storing them and their * properties. diff --git a/include/modules/acpi/devices.h b/include/kernel/acpi/devices.h similarity index 97% rename from include/modules/acpi/devices.h rename to include/kernel/acpi/devices.h index fb066bf1e..e31ee8096 100644 --- a/include/modules/acpi/devices.h +++ b/include/kernel/acpi/devices.h @@ -1,16 +1,16 @@ #pragma once -#include #include -#include -#include +#include +#include +#include -#include +#include /** * @brief Device and Power Management - * @defgroup modules_acpi_devices Devices - * @ingroup modules_acpi + * @defgroup kernel_acpi_devices Devices + * @ingroup kernel_acpi * * Handles enumeration and configuration of ACPI devices, along with dynamic loading of device drivers. * diff --git a/include/modules/acpi/resources.h b/include/kernel/acpi/resources.h similarity index 99% rename from include/modules/acpi/resources.h rename to include/kernel/acpi/resources.h index 61dff7911..31a7ca61d 100644 --- a/include/modules/acpi/resources.h +++ b/include/kernel/acpi/resources.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include #include /** * @brief ACPI resource settings. - * @defgroup modules_acpi_resources Resources - * @ingroup modules_acpi + * @defgroup kernel_acpi_resources Resources + * @ingroup kernel_acpi * * In the AML namespace heirarchy each device uses a buffer object, usually returned by their `_CRS` method, to describe * the resources they require, for example IO ports, IRQs, DMA channels, etc. diff --git a/include/modules/acpi/tables.h b/include/kernel/acpi/tables.h similarity index 98% rename from include/modules/acpi/tables.h rename to include/kernel/acpi/tables.h index ab85a711f..f3870e132 100644 --- a/include/modules/acpi/tables.h +++ b/include/kernel/acpi/tables.h @@ -1,11 +1,11 @@ #pragma once -#include +#include /** * @brief System Description Tables - * @defgroup modules_acpi_tables Tables - * @ingroup modules_acpi + * @defgroup kernel_acpi_tables Tables + * @ingroup kernel_acpi * * This module defines the ACPI tables found in the ACPI specification, tables defined outside of the specification, for * example, MCFG is defined in their own files. diff --git a/include/kernel/config.h b/include/kernel/config.h index 2806d60e7..87d8dfa6f 100644 --- a/include/kernel/config.h +++ b/include/kernel/config.h @@ -1,8 +1,15 @@ #pragma once /** - * @brief Interrupt stack configuration. + * @brief Kernel configuration. * @ingroup kernel + * @defgroup kernel_config Configuration + * + * @{ + */ + +/** + * @brief Interrupt stack configuration. * @def CONFIG_INTERRUPT_STACK_PAGES * * The `CONFIG_INTERRUPT_STACK_PAGES` constant defines the amount of pages that are allocated for the per-CPU interrupt, @@ -15,7 +22,6 @@ /** * @brief Kernel stack configuration. - * @ingroup kernel * @def CONFIG_MAX_KERNEL_STACK_PAGES * * The `CONFIG_MAX_KERNEL_STACK_PAGES` constant defines the maximum amount of pages that are allowed to be allocated for @@ -27,7 +33,6 @@ /** * @brief User stack configuration. - * @ingroup kernel * @def CONFIG_MAX_USER_STACK_PAGES * * The `CONFIG_MAX_USER_STACK_PAGES` constant defines the maximum amount of pages that are allowed to be allocated for a @@ -38,7 +43,6 @@ /** * @brief Maximum file descriptor configuration. - * @ingroup kernel * @def CONFIG_MAX_FD * * The `CONFIG_MAX_FD` constant defines the maximum amount of file descriptors that a process is allowed to have open. @@ -48,7 +52,6 @@ /** * @brief Serial logging configuration. - * @ingroup kernel * @def CONFIG_LOG_SERIAL * * The `CONFIG_LOG_SERIAL` constant defines if to output logged strings via serial. @@ -58,7 +61,6 @@ /** * @brief Maximum note queue configuration. - * @ingroup kernel * @def CONFIG_MAX_NOTES * * The `CONFIG_MAX_NOTES` constant defines the maximum length of a threads note queue. @@ -68,7 +70,6 @@ /** * @brief Maximum argument vector configuration. - * @ingroup kernel * @def CONFIG_MAX_ARGC * * The `CONFIG_MAX_ARGC` constant defines the maximum amount of arguments that can be passed to a process via its @@ -79,7 +80,6 @@ /** * @brief Minimum timer timeout configuration. - * @ingroup kernel * @def CONFIG_MIN_TIMER_TIMEOUT * * The `CONFIG_MIN_TIMER_TIMEOUT` constant defines the minimum timeout that can be set for timers. @@ -89,7 +89,6 @@ /** * @brief Time slice configuration. - * @ingroup kernel * @def CONFIG_TIME_SLICE * * The `CONFIG_TIME_SLICE` constant defines the default time slice given to threads when they are scheduled. @@ -99,7 +98,6 @@ /** * @brief Cache hot threshold configuration. - * @ingroup kernel * @def CONFIG_CACHE_HOT_THRESHOLD * * The `CONFIG_CACHE_HOT_THRESHOLD` constant defines the threshold below which a time duration is considered "cache @@ -110,7 +108,6 @@ /** * @brief Maximum mutex slow spin configuration. - * @ingroup kernel * @def CONFIG_MUTEX_MAX_SLOW_SPIN * * The `CONFIG_MUTEX_MAX_SLOW_SPIN` constant defines the maximum number of iterations a thread will spin before blocking @@ -121,7 +118,6 @@ /** * @brief Maximum screen lines configuration. - * @ingroup kernel * @def CONFIG_SCREEN_MAX_LINES * * The `CONFIG_SCREEN_MAX_LINES` constant defines the maximum number of lines that the logging system will display. @@ -131,7 +127,6 @@ /** * @brief Maximum bitmap allocator address. - * @ingroup kernel * @def CONFIG_PMM_BITMAP_MAX_ADDR * * The `CONFIG_PMM_BITMAP_MAX_ADDR` constant defines the maximum address below which pages will be handled by the bitmap @@ -142,7 +137,6 @@ /** * @brief Process reaper interval configuration. - * @ingroup kernel * @def CONFIG_PROCESS_REAPER_INTERVAL * * The `CONFIG_PROCESS_REAPER_INTERVAL` constant defines the minimum interval at which the process reaper runs to clean @@ -153,7 +147,6 @@ /** * @brief Maximum environment variables configuration. - * @ingroup kernel * @def CONFIG_MAX_ENV_VARS * * The `CONFIG_MAX_ENV_VARS` constant defines the maximum number of environment variables that a process can have. @@ -163,7 +156,6 @@ /** * @brief Kernel log buffer size configuration. - * @ingroup kernel * @def CONFIG_LOG_KLOG_BUFFER_SIZE * * The `CONFIG_LOG_KLOG_BUFFER_SIZE` constant defines the size of the buffer used for the `/dev/klog` file. @@ -173,7 +165,6 @@ /** * @brief Per-CPU data size configuration. - * @ingroup kernel * @def CONFIG_PERCPU_SIZE * * The `CONFIG_PERCPU_SIZE` constant defines the size allocated for per-CPU data. @@ -183,11 +174,31 @@ /** * @brief Maximum wait queues configuration. - * @ingroup kernel * @def CONFIG_MAX_WAIT_QUEUES * * The `CONFIG_MAX_WAIT_QUEUES` constant defines the maximum amount of wait queues that a thread can wait on * simultaneously. * */ -#define CONFIG_MAX_WAIT_QUEUES 64 \ No newline at end of file +#define CONFIG_MAX_WAIT_QUEUES 64 + +/** + * @brief Maximum rings configuration. + * @def CONFIG_MAX_RINGS + * + * The `CONFIG_MAX_RINGS` constant defines the maximum amount of asynchronous rings that each process can have. + * + */ +#define CONFIG_MAX_RINGS 8 + +/** + * @brief Maximum async ring pages configuration. + * @def CONFIG_MAX_RINGS_PAGES + * + * The `CONFIG_MAX_RINGS_PAGES` constant defines the maximum amount of pages that can be allocated for a async rings + * buffer. + * + */ +#define CONFIG_MAX_RINGS_PAGES 1024 + +/** @} */ \ No newline at end of file diff --git a/include/kernel/cpu/cpu.h b/include/kernel/cpu/cpu.h index 857904c6a..7b585c6a5 100644 --- a/include/kernel/cpu/cpu.h +++ b/include/kernel/cpu/cpu.h @@ -14,7 +14,7 @@ typedef struct cpu cpu_t; /** * @brief CPU - * @defgroup kernel_cpu CPU + * @defgroup kernel_cpu CPU Management * @ingroup kernel * * @{ diff --git a/include/kernel/cpu/ipi.h b/include/kernel/cpu/ipi.h index bf6a0c2f1..8feb6da14 100644 --- a/include/kernel/cpu/ipi.h +++ b/include/kernel/cpu/ipi.h @@ -166,7 +166,7 @@ uint64_t ipi_chip_amount(void); * - `EBUSY`: The target CPU's IPI queue is full, some or all IPIs could not be sent. * - Other errors returned by the IPI chip's `notify` function. */ -uint64_t ipi_send(cpu_t* cpu, ipi_flags_t flags, ipi_func_t func, void* data); +uint64_t ipi_send(cpu_t* cpu, ipi_flags_t flags, ipi_func_t func, void* data); /** * @brief Wake up one or more CPUs. diff --git a/include/kernel/cpu/irq.h b/include/kernel/cpu/irq.h index c818d01a5..27c67ab4f 100644 --- a/include/kernel/cpu/irq.h +++ b/include/kernel/cpu/irq.h @@ -229,7 +229,7 @@ uint64_t irq_virt_set_affinity(irq_virt_t virt, cpu_t* cpu); * - `ENOMEM`: Memory allocation failed. * - Other errors as returned by the IRQ chip's `enable` function. */ -uint64_t irq_chip_register(irq_chip_t* chip, irq_phys_t start, irq_phys_t end, void* data); +uint64_t irq_chip_register(irq_chip_t* chip, irq_phys_t start, irq_phys_t end, void* data); /** * @brief Unregister all instances of the given IRQ chip within the specified range. @@ -265,7 +265,7 @@ uint64_t irq_chip_amount(void); * - `ENOMEM`: Memory allocation failed. * - Other errors as returned by the IRQ chip's `enable` function. */ -uint64_t irq_handler_register(irq_virt_t virt, irq_func_t func, void* data); +uint64_t irq_handler_register(irq_virt_t virt, irq_func_t func, void* data); /** * @brief Unregister an IRQ handler. diff --git a/include/kernel/cpu/io.h b/include/kernel/cpu/port.h similarity index 84% rename from include/kernel/cpu/io.h rename to include/kernel/cpu/port.h index e1e97cb39..027a954bf 100644 --- a/include/kernel/cpu/io.h +++ b/include/kernel/cpu/port.h @@ -5,7 +5,7 @@ /** * @brief I/O port operations and reservations - * @defgroup kernel_cpu_io Port I/O + * @defgroup kernel_cpu_port Port I/O * @ingroup kernel_cpu * * The CPU can communicate with certain hardware through I/O ports, these ports are accessed using special opcodes. @@ -13,8 +13,8 @@ * ## Reserving I/O Ports * * To avoid conflicts between different subsystems or drivers trying to use the same I/O ports, we provide a simple - * reservation mechanism. Before a range of I/O ports is used, it should be reserved using `io_reserve()`. Once the - * ports are no longer needed, they should be released using `io_release()`. + * reservation mechanism. Before a range of I/O ports is used, it should be reserved using `port_reserve()`. Once the + * ports are no longer needed, they should be released using `port_release()`. * * There is no strict enforcement of I/O port reservations at the hardware level, so we have no choice but to hope that * everyone is on their best behaviour. @@ -30,7 +30,7 @@ typedef uint16_t port_t; /** * @brief Maximum I/O port number */ -#define IO_PORT_MAX UINT16_MAX +#define PORT_MAX UINT16_MAX /** * @brief Find and reserve a range of I/O ports if available. @@ -52,7 +52,7 @@ typedef uint16_t port_t; * - `EOVERFLOW`: The requested range overflows. * - `ENOSPC`: No suitable range of I/O ports available. */ -uint64_t io_reserve(port_t* out, port_t minBase, port_t maxBase, uint64_t alignment, uint64_t length, +uint64_t port_reserve(port_t* out, port_t minBase, port_t maxBase, uint64_t alignment, uint64_t length, const char* owner); /** @@ -61,7 +61,7 @@ uint64_t io_reserve(port_t* out, port_t minBase, port_t maxBase, uint64_t alignm * @param base The base I/O port address of the reserved range. * @param length The amount of contiguous I/O ports to release. */ -void io_release(port_t base, uint64_t length); +void port_release(port_t base, uint64_t length); /** * @brief Write an 8-bit value to an I/O port. @@ -69,7 +69,7 @@ void io_release(port_t base, uint64_t length); * @param port The I/O port to write to. * @param val The value to write. */ -static inline void io_out8(port_t port, uint8_t val) +static inline void out8(port_t port, uint8_t val) { ASM("outb %0, %1" : : "a"(val), "Nd"(port) : "memory"); } @@ -80,7 +80,7 @@ static inline void io_out8(port_t port, uint8_t val) * @param port The I/O port to read from. * @return The value read from the port. */ -static inline uint8_t io_in8(port_t port) +static inline uint8_t in8(port_t port) { uint8_t ret; ASM("inb %1, %0" : "=a"(ret) : "Nd"(port) : "memory"); @@ -93,7 +93,7 @@ static inline uint8_t io_in8(port_t port) * @param port The I/O port to write to. * @param val The value to write. */ -static inline void io_out16(port_t port, uint16_t val) +static inline void out16(port_t port, uint16_t val) { ASM("outw %0, %1" : : "a"(val), "Nd"(port) : "memory"); } @@ -104,7 +104,7 @@ static inline void io_out16(port_t port, uint16_t val) * @param port The I/O port to read from. * @return The value read from the port. */ -static inline uint16_t io_in16(port_t port) +static inline uint16_t in16(port_t port) { uint16_t ret; ASM("inw %1, %0" : "=a"(ret) : "Nd"(port) : "memory"); @@ -117,7 +117,7 @@ static inline uint16_t io_in16(port_t port) * @param port The I/O port to write to. * @param val The value to write. */ -static inline uint32_t io_in32(port_t port) +static inline uint32_t in32(port_t port) { uint32_t ret; ASM("inl %1, %0" : "=a"(ret) : "Nd"(port) : "memory"); @@ -130,7 +130,7 @@ static inline uint32_t io_in32(port_t port) * @param port The I/O port to read from. * @return The value read from the port. */ -static inline void io_out32(port_t port, uint32_t val) +static inline void out32(port_t port, uint32_t val) { ASM("outl %0, %1" : : "a"(val), "Nd"(port) : "memory"); } diff --git a/include/kernel/cpu/syscall.h b/include/kernel/cpu/syscall.h index 633865020..9b9833bc6 100644 --- a/include/kernel/cpu/syscall.h +++ b/include/kernel/cpu/syscall.h @@ -102,6 +102,9 @@ typedef enum SYS_MOUNT, SYS_UNMOUNT, SYS_ARCH_PRCTL, + SYS_SETUP, + SYS_TEARDOWN, + SYS_ENTER, SYS_TOTAL_AMOUNT } syscall_number_t; diff --git a/include/kernel/drivers/abstract/fb.h b/include/kernel/drivers/abstract/fb.h index 9cb44c6a2..d76d5453f 100644 --- a/include/kernel/drivers/abstract/fb.h +++ b/include/kernel/drivers/abstract/fb.h @@ -1,6 +1,6 @@ #pragma once -#include <_internal/MAX_PATH.h> +#include <_libstd/MAX_PATH.h> #include #include @@ -89,7 +89,7 @@ typedef struct fb * @param private Private data for the framebuffer. * @return On success, the new framebuffer. On failure, `NULL` and `errno` is set. */ -fb_t* fb_new(const char* name, const fb_ops_t* ops, void* data); +fb_t* fb_new(const char* name, const fb_ops_t* ops, void* data); /** * @brief Frees a framebuffer. diff --git a/include/modules/drivers/apic/apic_timer.h b/include/kernel/drivers/apic/apic_timer.h similarity index 92% rename from include/modules/drivers/apic/apic_timer.h rename to include/kernel/drivers/apic/apic_timer.h index 7531e3f2f..21cac0b42 100644 --- a/include/modules/drivers/apic/apic_timer.h +++ b/include/kernel/drivers/apic/apic_timer.h @@ -4,8 +4,8 @@ /** * @brief Advanced Programmable Interrupt Controller Timer. - * @defgroup modules_drivers_apic_timer APIC Timer - * @ingroup modules_drivers_apic + * @defgroup kernel_drivers_apic_timer APIC Timer + * @ingroup kernel_drivers_apic * * Each local APIC is associated with a timer which can be used to generate interrupts at specific intervals, or as we * use it, to generate a single interrupt after a specified time. diff --git a/include/modules/drivers/apic/ioapic.h b/include/kernel/drivers/apic/ioapic.h similarity index 98% rename from include/modules/drivers/apic/ioapic.h rename to include/kernel/drivers/apic/ioapic.h index c5c267bce..4ac4b6ce0 100644 --- a/include/modules/drivers/apic/ioapic.h +++ b/include/kernel/drivers/apic/ioapic.h @@ -5,8 +5,8 @@ /** * @brief Input / Output Advanced Programmable Interrupt Controller. - * @defgroup modules_drivers_apic_ioapic IO APIC - * @ingroup modules_drivers_apic + * @defgroup kernel_drivers_apic_ioapic IO APIC + * @ingroup kernel_drivers_apic * * The IO APICs are used to route external interrupts to a CPUs local APIC. Each IO APIC handles a range of Global * System Interrupts (GSIs) or in PatchworkOS terms, physical IRQs, which it receives from external devices such as a diff --git a/include/modules/drivers/apic/lapic.h b/include/kernel/drivers/apic/lapic.h similarity index 98% rename from include/modules/drivers/apic/lapic.h rename to include/kernel/drivers/apic/lapic.h index 4d1fd2b85..2780df1f7 100644 --- a/include/modules/drivers/apic/lapic.h +++ b/include/kernel/drivers/apic/lapic.h @@ -8,8 +8,8 @@ /** * @brief Local Advanced Programmable Interrupt Controller. - * @defgroup modules_drivers_apic_lapic Local APIC - * @ingroup modules_drivers_apic + * @defgroup kernel_drivers_apic_lapic Local APIC + * @ingroup kernel_drivers_apic * * ## Local APICs * diff --git a/include/modules/drivers/pci/config.h b/include/kernel/drivers/pci/config.h similarity index 96% rename from include/modules/drivers/pci/config.h rename to include/kernel/drivers/pci/config.h index 65b530081..1aac638e6 100644 --- a/include/modules/drivers/pci/config.h +++ b/include/kernel/drivers/pci/config.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include /** * @brief PCI configuration space - * @defgroup modules_drivers_pci_config PCI Configuration Space - * @ingroup modules_drivers_pci + * @defgroup kernel_drivers_pci_config PCI Configuration Space + * @ingroup kernel_drivers_pci * * Id like to use the PCI Firmware Specification as a reference for this, but unfortunately, its not freely available. * So we use the OSDev Wiki instead. diff --git a/include/modules/drivers/pci/pci.h b/include/kernel/drivers/pci/pci.h similarity index 58% rename from include/modules/drivers/pci/pci.h rename to include/kernel/drivers/pci/pci.h index 1bff6eaa1..db683b9ae 100644 --- a/include/modules/drivers/pci/pci.h +++ b/include/kernel/drivers/pci/pci.h @@ -2,8 +2,8 @@ /** * @brief Peripheral Component Interconnect (PCI) - * @defgroup modules_drivers_pci PCI - * @ingroup modules_drivers + * @defgroup kernel_drivers_pci PCI + * @ingroup kernel_drivers * * @{ */ diff --git a/include/kernel/fs/dentry.h b/include/kernel/fs/dentry.h index 8e8a2eaae..d868a3de6 100644 --- a/include/kernel/fs/dentry.h +++ b/include/kernel/fs/dentry.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include #include #include #include @@ -10,12 +10,12 @@ #include #include -#include +#include #include typedef struct dentry dentry_t; typedef struct dentry_ops dentry_ops_t; -typedef struct inode inode_t; +typedef struct vnode vnode_t; typedef struct superblock superblock_t; typedef struct dir_ctx dir_ctx_t; @@ -25,7 +25,7 @@ typedef struct dir_ctx dir_ctx_t; * @ingroup kernel_fs * * A dentry represents the actual name in the filesystem hierarchy. It can be either positive, meaning it has an - * associated inode, or negative, meaning it does not have an associated inode. + * associated vnode, or negative, meaning it does not have an associated vnode. * * ## Mountpoints and Root Dentries * @@ -64,31 +64,31 @@ typedef uint64_t dentry_id_t; * @param dentry The dentry to check. * @return true if the dentry is positive, false if it is negative. */ -#define DENTRY_IS_POSITIVE(dentry) ((dentry)->inode != NULL) +#define DENTRY_IS_POSITIVE(dentry) ((dentry)->vnode != NULL) /** - * @brief Check if the inode associated with a dentry is a file. + * @brief Check if the vnode associated with a dentry is a regular file. * * @param dentry The dentry to check. - * @return true if the dentry is a file, false otherwise or if the dentry is negative. + * @return true if the dentry is a regular file, false otherwise or if the dentry is negative. */ -#define DENTRY_IS_FILE(dentry) (DENTRY_IS_POSITIVE(dentry) && (dentry)->inode->type == INODE_FILE) +#define DENTRY_IS_REGULAR(dentry) (DENTRY_IS_POSITIVE(dentry) && (dentry)->vnode->type == VREG) /** - * @brief Check if the inode associated with a dentry is a directory. + * @brief Check if the vnode associated with a dentry is a directory. * * @param dentry The dentry to check. * @return true if the dentry is a directory, false otherwise or if the dentry is negative. */ -#define DENTRY_IS_DIR(dentry) (DENTRY_IS_POSITIVE(dentry) && (dentry)->inode->type == INODE_DIR) +#define DENTRY_IS_DIR(dentry) (DENTRY_IS_POSITIVE(dentry) && (dentry)->vnode->type == VDIR) /** - * @brief Check if the inode associated with a dentry is a symbolic link. + * @brief Check if the vnode associated with a dentry is a symbolic link. * * @param dentry The dentry to check. * @return true if the dentry is a symbolic link, false otherwise or if the dentry is negative. */ -#define DENTRY_IS_SYMLINK(dentry) (DENTRY_IS_POSITIVE(dentry) && (dentry)->inode->type == INODE_SYMLINK) +#define DENTRY_IS_SYMLINK(dentry) (DENTRY_IS_POSITIVE(dentry) && (dentry)->vnode->type == VSYMLINK) /** * @brief Directory context used to iterate over directory entries. @@ -104,14 +104,14 @@ typedef struct dir_ctx * * @param ctx The directory context. * @param name The name of the entry. - * @param number The inode number of the entry. - * @param type The inode type of the entry. + * @param number The vnode number of the entry. + * @param type The vnode type of the entry. * @return `true` to continue iterating, `false` to stop. */ - bool (*emit)(dir_ctx_t* ctx, const char* name, ino_t number, itype_t type); - size_t pos; ///< The current position in the directory, can be used to skip entries. - void* data; ///< Private data that the filesystem can use to conveniently pass data. - size_t index; ///< An index that the filesystem can use for its own purposes. + bool (*emit)(dir_ctx_t* ctx, const char* name, vtype_t type); + size_t pos; ///< The current position in the directory, can be used to skip entries. + void* data; ///< Private data that the filesystem can use to conveniently pass data. + size_t index; ///< An index that the filesystem can use for its own purposes. } dir_ctx_t; /** @@ -148,7 +148,7 @@ typedef struct dentry_ops * @brief Directory entry structure. * @struct dentry_t * - * A dentry structure is protected by the mutex of its inode. Note that since move and rename are not supported in favor + * A dentry structure is protected by the mutex of its vnode. Note that since move and rename are not supported in favor * of link and remove, the parent of a dentry will never change after creation which allows some optimizations. */ typedef struct dentry @@ -156,7 +156,7 @@ typedef struct dentry ref_t ref; dentry_id_t id; char name[MAX_NAME]; ///< The name of the dentry, immutable after creation. - inode_t* inode; ///< Will be `NULL` if the dentry is negative, once positive it will never be modified. + vnode_t* vnode; ///< Will be `NULL` if the dentry is negative, once positive it will never be modified. dentry_t* parent; ///< The parent dentry, will be itself if this is the root dentry, immutable after creation. list_entry_t siblingEntry; list_t children; @@ -224,14 +224,14 @@ dentry_t* dentry_rcu_get(const dentry_t* parent, const char* name, size_t length dentry_t* dentry_lookup(dentry_t* parent, const char* name, size_t length); /** - * @brief Make a dentry positive by associating it with an inode. + * @brief Make a dentry positive by associating it with an vnode. * - * This function is expected to be protected by the parent inode's mutex. + * This function is expected to be protected by the parent vnode's mutex. * * @param dentry The dentry to make positive, or `NULL` for no-op. - * @param inode The inode to associate with the dentry, or `NULL` for no-op. + * @param vnode The vnode to associate with the dentry, or `NULL` for no-op. */ -void dentry_make_positive(dentry_t* dentry, inode_t* inode); +void dentry_make_positive(dentry_t* dentry, vnode_t* vnode); /** * @brief The amount of special entries "." and ".." that `dentry_iterate_dots()` emits. diff --git a/include/kernel/fs/devfs.h b/include/kernel/fs/devfs.h index bd4f521d2..3572f11d7 100644 --- a/include/kernel/fs/devfs.h +++ b/include/kernel/fs/devfs.h @@ -1,8 +1,8 @@ #pragma once #include -#include -#include +#include +#include typedef struct file file_t; typedef struct file_ops file_ops_t; @@ -35,35 +35,35 @@ void devfs_init(void); * * @param parent The parent directory, if `NULL` then the root is used. * @param name The name of the new directory. - * @param inodeOps The inode operations for the new directory, can be `NULL`. - * @param private Private data to store in the inode of the new directory, can be `NULL`. + * @param vnodeOps The vnode operations for the new directory, can be `NULL`. + * @param private Private data to store in the vnode of the new directory, can be `NULL`. * @return On success, the new devfs directory. On failure, `NULL` and `errno` is set. */ -dentry_t* devfs_dir_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* data); +dentry_t* devfs_dir_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, void* data); /** * @brief Create a new file inside a mounted devfs instance. * * @param parent The parent directory, if `NULL` then the root is used. * @param name The name of the new file. - * @param inodeOps The inode operations for the new file, can be `NULL`. + * @param vnodeOps The vnode operations for the new file, can be `NULL`. * @param fileOps The file operations for the new file, can be `NULL`. - * @param private Private data to store in the inode of the new file, can be `NULL`. + * @param private Private data to store in the vnode of the new file, can be `NULL`. * @return On success, the new devfs file. On failure, `NULL` and `errno` is set. */ -dentry_t* devfs_file_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, const file_ops_t* fileOps, - void* data); +dentry_t* devfs_file_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, const file_ops_t* fileOps, + void* data); /** * @brief Create a new symbolic link inside a mounted devfs instance. * * @param parent The parent directory, if `NULL` then the root is used. * @param name The name of the new symbolic link. - * @param inodeOps The inode operations for the new symbolic link. - * @param private Private data to store in the inode of the new symbolic link, can be `NULL`. + * @param vnodeOps The vnode operations for the new symbolic link. + * @param private Private data to store in the vnode of the new symbolic link, can be `NULL`. * @return On success, the new devfs symbolic link. On failure, `NULL` and `errno` is set. */ -dentry_t* devfs_symlink_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* data); +dentry_t* devfs_symlink_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, void* data); /** * @brief Descriptor for batch file creation. @@ -72,9 +72,9 @@ dentry_t* devfs_symlink_new(dentry_t* parent, const char* name, const inode_ops_ typedef struct devfs_file_desc { const char* name; ///< Name of the file, `NULL` marks end of array. - const inode_ops_t* inodeOps; ///< Inode operations, can be `NULL`. + const vnode_ops_t* vnodeOps; ///< Vnode operations, can be `NULL`. const file_ops_t* fileOps; ///< File operations, can be `NULL`. - void* data; ///< Private data to store in the inode of the file. + void* data; ///< Private data to store in the vnode of the file. } devfs_file_desc_t; /** diff --git a/include/kernel/fs/file.h b/include/kernel/fs/file.h index fd4587f8a..0d8cb8d17 100644 --- a/include/kernel/fs/file.h +++ b/include/kernel/fs/file.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include typedef struct wait_queue wait_queue_t; @@ -14,7 +14,7 @@ typedef struct wait_queue wait_queue_t; typedef struct file file_t; typedef struct file_ops file_ops_t; typedef struct dentry dentry_t; -typedef struct inode inode_t; +typedef struct vnode vnode_t; typedef struct poll_file poll_file_t; /** @@ -32,7 +32,7 @@ typedef struct poll_file poll_file_t; * @brief File structure. * @struct file_t * - * A file structure is protected by the mutex of its inode. + * A file structure is protected by the mutex of its vnode. * */ typedef struct file @@ -40,7 +40,7 @@ typedef struct file ref_t ref; size_t pos; mode_t mode; - inode_t* inode; + vnode_t* vnode; path_t path; const file_ops_t* ops; void* data; diff --git a/include/kernel/fs/filesystem.h b/include/kernel/fs/filesystem.h index 180aae5c5..440bbc492 100644 --- a/include/kernel/fs/filesystem.h +++ b/include/kernel/fs/filesystem.h @@ -3,15 +3,15 @@ #include #include #include -#include #include #include #include +#include #include #include #include -#include +#include #include #include #include @@ -65,7 +65,7 @@ typedef struct filesystem * @param private Private data for the filesystem's mount function. * @return On success, the root dentry of the mounted filesystem. On failure, `NULL` and `errno` is set. */ - dentry_t* (*mount)(filesystem_t* fs, const char* details, void* data); + dentry_t* (*mount)(filesystem_t* fs, const char* details, void* data); } filesystem_t; /**s diff --git a/include/kernel/fs/inode.h b/include/kernel/fs/inode.h deleted file mode 100644 index 1c3be5781..000000000 --- a/include/kernel/fs/inode.h +++ /dev/null @@ -1,214 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -typedef struct inode inode_t; -typedef struct inode_ops inode_ops_t; -typedef struct superblock superblock_t; -typedef struct file_ops file_ops_t; -typedef struct dentry dentry_t; - -/** - * @brief Index node. - * @defgroup kernel_fs_inode Inode - * @ingroup kernel_fs - * - * A inode represents the actual data and metadata of a file. It is referenced by dentries, which represent the name or - * "location" of the file but a inode can appear in multiple dentries due to hardlinks or mounts. - * - * @note Despite the name inodes are in no way "nodes" in any kind of tree structure, that would be the dentries. - * - * ## Synchronization - * - * Inodes have an additional purpose within the Virtual File System (VFS) as they act as the primary means of - * synchronization. All dentries synchronize upon their inodes mutex, open files synchronize upon the mutex of the - * underlying inode and operations like create, remove, etc synchronize upon the inode mutex of the parent directory. - * - * @todo Implement actually writing/syncing dirty inodes, for now inodes should use the notify functions but they will - * never actually be "cleaned." - * - * @{ - */ - -/** - * @brief Inode structure. - * @struct inode_t - * - * Inodes are owned by the filesystem, not the VFS. - */ -typedef struct inode -{ - ref_t ref; - ino_t number; - itype_t type; - _Atomic(uint64_t) dentryCount; ///< The number of dentries pointing to this inode. - size_t size; - size_t blocks; - time_t accessTime; ///< Unix time stamp for the last inode access. - time_t modifyTime; ///< Unix time stamp for last file content alteration. - time_t changeTime; ///< Unix time stamp for the last file metadata alteration. - time_t createTime; ///< Unix time stamp for the inode creation. - void* data; - superblock_t* superblock; - const inode_ops_t* ops; - const file_ops_t* fileOps; - rcu_entry_t rcu; - mutex_t mutex; -} inode_t; - -/** - * @brief Inode operations structure. - * @struct inode_ops_t - * - * Note that the inodes mutex will be acquired by the vfs. - */ -typedef struct inode_ops -{ - /** - * @brief Look up a dentry in a directory inode. - * - * Should set the target dentry to be positive (give it an inode), if the entry does not exist the operation - * should still return success but leave the dentry negative. - * - * @param dir The directory inode to look in. - * @param target The dentry to look up. - * @return On success, `0`. On failure, returns `ERR` and `errno` is set. - */ - uint64_t (*lookup)(inode_t* dir, dentry_t* target); - /** - * @brief Handles both directories and files depending on mode. - * - * Takes in a negative dentry and creates the corresponding inode to make the dentry positive. - * - * @param dir The directory inode to create the entry in. - * @param target The negative dentry to create. - * @param mode The mode to create the entry with. - * @return On success, `0`. On failure, returns `ERR` and `errno` is set. - */ - uint64_t (*create)(inode_t* dir, dentry_t* target, mode_t mode); - /** - * @brief Set the inode size to zero. - * - * @param target The inode to truncate. - */ - void (*truncate)(inode_t* target); - /** - * @brief Make the same file inode appear twice in the filesystem. - * - * @param dir The directory inode to create the link in. - * @param old The existing dentry containing the inode to link to. - * @param new The negative dentry to store the same inode as old. - * @return On success, `0`. On failure, returns `ERR` and `errno` is set. - */ - uint64_t (*link)(inode_t* dir, dentry_t* old, dentry_t* new); - /** - * @brief Retrieve the path of the symbolic link. - * - * @param inode The symbolic link inode. - * @param buffer The buffer to store the path in. - * @param size The size of the buffer. - * @return On success, the number of bytes read. On failure, returns `ERR` and `errno` is set. - */ - uint64_t (*readlink)(inode_t* inode, char* buffer, uint64_t size); - /** - * @brief Create a symbolic link. - * - * @param dir The directory inode to create the symbolic link in. - * @param target The negative dentry to create. - * @param dest The path to which the symbolic link will point. - * @return On success, `0`. On failure, returns `ERR` and `errno` is set. - */ - uint64_t (*symlink)(inode_t* dir, dentry_t* target, const char* dest); - /** - * @brief Remove a file or directory. - * - * @param dir The directory inode containing the target. - * @param target The dentry to remove. - * @return On success, `0`. On failure, returns `ERR` and `errno` is set. - */ - uint64_t (*remove)(inode_t* dir, dentry_t* target); - /** - * @brief Cleanup function called when the inode is being freed. - * - * @param inode The inode being freed. - */ - void (*cleanup)(inode_t* inode); -} inode_ops_t; - -/** - * @brief Create a new inode. - * - * This DOES add the inode to the inode cache. It also does not associate the inode with a dentry, that is done when a - * dentry is made positive with `dentry_make_positive()`. - * - * There is no `inode_free()` instead use `UNREF()`. - * - * @param superblock The superblock the inode belongs to. - * @param number The inode number, for a generic filesystem `vfs_id_get()` can be used. - * @param type The inode type. - * @param ops The inode operations. - * @param fileOps The file operations for files opened on this inode. - * @return On success, the new inode. On failure, returns `NULL` and `errno` is set. - */ -inode_t* inode_new(superblock_t* superblock, ino_t number, itype_t type, const inode_ops_t* ops, - const file_ops_t* fileOps); - -/** - * @brief Notify the inode that it has been accessed. - * - * This updates the access time. - * - * @param inode The inode to notify. - */ -void inode_notify_access(inode_t* inode); - -/** - * @brief Notify the inode that its content has been modified. - * - * This updates the modify time and change time. - * - * @param inode The inode to notify. - */ -void inode_notify_modify(inode_t* inode); - -/** - * @brief Notify the inode that its metadata has changed. - * - * This updates the change time. - * - * @param inode The inode to notify. - */ -void inode_notify_change(inode_t* inode); - -/** - * @brief Truncate the inode. - * - * The filesystem should implement the actual truncation in the inode ops truncate function, this is just a helper to - * call it. - * - * @param inode The inode to truncate. - */ -void inode_truncate(inode_t* inode); - -/** - * @brief Helper to generate a consistent inode number for an entry in a directory. - * - * This is useful for in-memory filesystems or filesystem that dont provide native inode numbers. - * - * @param parentNumber The inode number of the parent directory. - * @param name The name of the entry. - * @return The generated inode number. - */ -ino_t ino_gen(ino_t parentNumber, const char* name); - -/** @} */ diff --git a/include/kernel/fs/key.h b/include/kernel/fs/key.h index 8eeba9498..847ccc593 100644 --- a/include/kernel/fs/key.h +++ b/include/kernel/fs/key.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include /** diff --git a/include/kernel/fs/namespace.h b/include/kernel/fs/namespace.h index 3d496ed4b..a5956aa23 100644 --- a/include/kernel/fs/namespace.h +++ b/include/kernel/fs/namespace.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include typedef struct namespace namespace_t; @@ -136,7 +136,7 @@ bool namespace_rcu_traverse(namespace_t* ns, mount_t** mount, dentry_t** dentry) * - Other errors as returned by the filesystem's `mount()` operation or `mount_new()`. */ mount_t* namespace_mount(namespace_t* ns, path_t* target, filesystem_t* fs, const char* options, mode_t mode, - void* data); + void* data); /** * @brief Bind a source path to a target path in a namespace. diff --git a/include/kernel/fs/netfs.h b/include/kernel/fs/netfs.h index 290fc8687..7a5bc6fce 100644 --- a/include/kernel/fs/netfs.h +++ b/include/kernel/fs/netfs.h @@ -7,7 +7,7 @@ #include #include -#include +#include #include typedef struct netfs_family netfs_family_t; diff --git a/include/kernel/fs/path.h b/include/kernel/fs/path.h index f2f9a89b1..91c5fe4d8 100644 --- a/include/kernel/fs/path.h +++ b/include/kernel/fs/path.h @@ -6,12 +6,13 @@ #include #include #include -#include +#include typedef struct path path_t; typedef struct mount mount_t; typedef struct dentry dentry_t; typedef struct namespace namespace_t; +typedef struct file file_t; // clang-format off /** diff --git a/include/kernel/fs/superblock.h b/include/kernel/fs/superblock.h index 929a3b89c..611f828c1 100644 --- a/include/kernel/fs/superblock.h +++ b/include/kernel/fs/superblock.h @@ -1,17 +1,18 @@ #pragma once #include +#include #include #include -#include +#include #include typedef struct filesystem filesystem_t; typedef struct superblock superblock_t; typedef struct superblock_ops superblock_ops_t; typedef struct dentry_ops dentry_ops_t; -typedef struct inode inode_t; +typedef struct vnode vnode_t; typedef struct dentry dentry_t; /** @@ -39,6 +40,7 @@ typedef struct superblock dentry_t* root; ///< Root dentry of the filesystem, should not take a reference. const superblock_ops_t* ops; const dentry_ops_t* dentryOps; + const irp_vtable_t* vtable; filesystem_t* fs; /** * The number of mounts of this superblock. diff --git a/include/kernel/fs/sysfs.h b/include/kernel/fs/sysfs.h index 9657516ac..781e5fc77 100644 --- a/include/kernel/fs/sysfs.h +++ b/include/kernel/fs/sysfs.h @@ -1,8 +1,8 @@ #pragma once #include -#include -#include +#include +#include typedef struct file file_t; typedef struct file_ops file_ops_t; @@ -40,35 +40,35 @@ void sysfs_init(void); * * @param parent The parent directory, if `NULL` then the root is used. * @param name The name of the new directory. - * @param inodeOps The inode operations for the new directory, can be `NULL`. - * @param private Private data to store in the inode of the new directory, can be `NULL`. + * @param vnodeOps The vnode operations for the new directory, can be `NULL`. + * @param private Private data to store in the vnode of the new directory, can be `NULL`. * @return On success, the new sysfs directory. On failure, `NULL` and `errno` is set. */ -dentry_t* sysfs_dir_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* data); +dentry_t* sysfs_dir_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, void* data); /** * @brief Create a new file inside a mounted sysfs instance. * * @param parent The parent directory, if `NULL` then the root is used. * @param name The name of the new file. - * @param inodeOps The inode operations for the new file, can be `NULL`. + * @param vnodeOps The vnode operations for the new file, can be `NULL`. * @param fileOps The file operations for the new file, can be `NULL`. - * @param private Private data to store in the inode of the new file, can be `NULL`. + * @param private Private data to store in the vnode of the new file, can be `NULL`. * @return On success, the new sysfs file. On failure, `NULL` and `errno` is set. */ -dentry_t* sysfs_file_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, const file_ops_t* fileOps, - void* data); +dentry_t* sysfs_file_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, const file_ops_t* fileOps, + void* data); /** * @brief Create a new symbolic link inside a mounted sysfs instance. * * @param parent The parent directory, if `NULL` then the root is used. * @param name The name of the new symbolic link. - * @param inodeOps The inode operations for the new symbolic link. - * @param private Private data to store in the inode of the new symbolic link, can be `NULL`. + * @param vnodeOps The vnode operations for the new symbolic link. + * @param private Private data to store in the vnode of the new symbolic link, can be `NULL`. * @return On success, the new sysfs symbolic link. On failure, `NULL` and `errno` is set. */ -dentry_t* sysfs_symlink_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* data); +dentry_t* sysfs_symlink_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, void* data); /** * @brief Descriptor for batch file creation. @@ -77,9 +77,9 @@ dentry_t* sysfs_symlink_new(dentry_t* parent, const char* name, const inode_ops_ typedef struct sysfs_file_desc { const char* name; ///< Name of the file, `NULL` marks end of array. - const inode_ops_t* inodeOps; ///< Inode operations, can be `NULL`. + const vnode_ops_t* vnodeOps; ///< Vnode operations, can be `NULL`. const file_ops_t* fileOps; ///< File operations, can be `NULL`. - void* data; ///< Private data to store in the inode of the file. + void* data; ///< Private data to store in the vnode of the file. } sysfs_file_desc_t; /** diff --git a/include/kernel/fs/tmpfs.h b/include/kernel/fs/tmpfs.h index ac8447b07..7c2732a1b 100644 --- a/include/kernel/fs/tmpfs.h +++ b/include/kernel/fs/tmpfs.h @@ -1,12 +1,12 @@ #pragma once #include -#include #include +#include #include -#include +#include #include /** diff --git a/include/kernel/fs/vfs.h b/include/kernel/fs/vfs.h index 178da66f8..5932b6435 100644 --- a/include/kernel/fs/vfs.h +++ b/include/kernel/fs/vfs.h @@ -3,15 +3,15 @@ #include #include #include -#include #include #include #include +#include #include #include #include -#include +#include #include #include #include @@ -24,6 +24,9 @@ * The Virtual File System (VFS) provides a single unified interface for any and all filesystems, including virtual * filesystems used to expose kernel resources to user space. * + * @todo Most of this is going to be removed when the new IRP system is fully implemented, but for now its usefull to + * keep it around during the refactor. + * * @{ */ @@ -159,13 +162,13 @@ uint64_t vfs_link(const pathname_t* oldPathname, const pathname_t* newPathname, /** * @brief Read the path in a symbolic link. * - * @param symlink The symbolic link inode. + * @param symlink The symbolic link vnode. * @param buffer The buffer to store the path in. * @param size The size of the buffer. * @param process The process performing the readlink. * @return On success, the number of bytes read. On failure, `ERR` and `errno` is set. */ -size_t vfs_readlink(inode_t* symlink, char* buffer, size_t size); +size_t vfs_readlink(vnode_t* symlink, char* buffer, size_t size); /** * @brief Create a symbolic link. diff --git a/include/kernel/fs/vnode.h b/include/kernel/fs/vnode.h new file mode 100644 index 000000000..1aa6b048f --- /dev/null +++ b/include/kernel/fs/vnode.h @@ -0,0 +1,167 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +typedef struct vnode vnode_t; +typedef struct vnode_ops vnode_ops_t; +typedef struct superblock superblock_t; +typedef struct file_ops file_ops_t; +typedef struct dentry dentry_t; + +/** + * @brief Virtual node. + * @defgroup kernel_fs_vnode Vnode + * @ingroup kernel_fs + * + * A vnode represents the actual data and metadata of a file. It is referenced by dentries, which represent the name or + * "location" of the file but a vnode can appear in multiple dentries due to hardlinks or mounts. + * + * @note Despite the name vnodes are in no way "nodes" in any kind of tree structure, that would be the dentries. + * + * ## Synchronization + * + * Vnodes have an additional purpose within the Virtual File System (VFS) as they act as the primary means of + * synchronization. All dentries synchronize upon their vnodes mutex, open files synchronize upon the mutex of the + * underlying vnode and operations like create, remove, etc synchronize upon the vnode mutex of the parent directory. + * + * @{ + */ + +/** + * @brief vnode structure. + * @struct vnode_t + * + * vnodes are owned by the filesystem, not the VFS. + */ +typedef struct vnode +{ + ref_t ref; + vtype_t type; + _Atomic(uint64_t) dentryCount; ///< The number of dentries pointing to this vnode. + void* data; ///< Filesystem defined data. + uint64_t size; ///< Used for convenience by certain filesystems, does not represent the file size. + superblock_t* superblock; + const vnode_ops_t* ops; + const file_ops_t* fileOps; + const irp_vtable_t* vtable; + rcu_entry_t rcu; + mutex_t mutex; +} vnode_t; + +/** + * @brief vnode operations structure. + * @struct vnode_ops_t + * + * Note that the vnodes mutex will be acquired by the vfs. + */ +typedef struct vnode_ops +{ + /** + * @brief Look up a dentry in a directory vnode. + * + * Should set the target dentry to be positive (give it an vnode), if the entry does not exist the operation + * should still return success but leave the dentry negative. + * + * @param dir The directory vnode to look in. + * @param target The dentry to look up. + * @return On success, `0`. On failure, returns `ERR` and `errno` is set. + */ + uint64_t (*lookup)(vnode_t* dir, dentry_t* target); + /** + * @brief Handles both directories and files depending on mode. + * + * Takes in a negative dentry and creates the corresponding vnode to make the dentry positive. + * + * @param dir The directory vnode to create the entry in. + * @param target The negative dentry to create. + * @param mode The mode to create the entry with. + * @return On success, `0`. On failure, returns `ERR` and `errno` is set. + */ + uint64_t (*create)(vnode_t* dir, dentry_t* target, mode_t mode); + /** + * @brief Set the vnode size to zero. + * + * @param target The vnode to truncate. + */ + void (*truncate)(vnode_t* target); + /** + * @brief Make the same file vnode appear twice in the filesystem. + * + * @param dir The directory vnode to create the link in. + * @param old The existing dentry containing the vnode to link to. + * @param new The negative dentry to store the same vnode as old. + * @return On success, `0`. On failure, returns `ERR` and `errno` is set. + */ + uint64_t (*link)(vnode_t* dir, dentry_t* old, dentry_t* new); + /** + * @brief Retrieve the path of the symbolic link. + * + * @param vnode The symbolic link vnode. + * @param buffer The buffer to store the path in. + * @param size The size of the buffer. + * @return On success, the number of bytes read. On failure, returns `ERR` and `errno` is set. + */ + uint64_t (*readlink)(vnode_t* vnode, char* buffer, uint64_t size); + /** + * @brief Create a symbolic link. + * + * @param dir The directory vnode to create the symbolic link in. + * @param target The negative dentry to create. + * @param dest The path to which the symbolic link will point. + * @return On success, `0`. On failure, returns `ERR` and `errno` is set. + */ + uint64_t (*symlink)(vnode_t* dir, dentry_t* target, const char* dest); + /** + * @brief Remove a file or directory. + * + * @param dir The directory vnode containing the target. + * @param target The dentry to remove. + * @return On success, `0`. On failure, returns `ERR` and `errno` is set. + */ + uint64_t (*remove)(vnode_t* dir, dentry_t* target); + /** + * @brief Cleanup function called when the vnode is being freed. + * + * @param vnode The vnode being freed. + */ + void (*cleanup)(vnode_t* vnode); +} vnode_ops_t; + +/** + * @brief Create a new vnode. + * + * Does not associate the vnode with a dentry, that is done when a dentry is made positive with + * `dentry_make_positive()`. + * + * There is no `vnode_free()` instead use `UNREF()`. + * + * @param superblock The superblock the vnode belongs to. + * @param type The vnode type. + * @param ops The vnode operations. + * @param fileOps The file operations for files opened on this vnode. + * @return On success, the new vnode. On failure, returns `NULL` and `errno` is set. + */ +vnode_t* vnode_new(superblock_t* superblock, vtype_t type, const vnode_ops_t* ops, const file_ops_t* fileOps); + +/** + * @brief Truncate the vnode. + * + * The filesystem should implement the actual truncation in the vnode ops truncate function, this is just a helper to + * call it. + * + * @param vnode The vnode to truncate. + */ +void vnode_truncate(vnode_t* vnode); + +/** @} */ diff --git a/include/kernel/io/io.h b/include/kernel/io/io.h new file mode 100644 index 000000000..a15cddbd0 --- /dev/null +++ b/include/kernel/io/io.h @@ -0,0 +1,10 @@ +#pragma once + +/** + * @brief I/O Subsystem. + * @defgroup kernel_io I/O Subsystem + * @ingroup kernel + * + * The I/O subsystem is responsible for asynchronous input and output operations within PatchworkOS. + * + */ \ No newline at end of file diff --git a/include/kernel/io/irp.h b/include/kernel/io/irp.h new file mode 100644 index 000000000..943604a68 --- /dev/null +++ b/include/kernel/io/irp.h @@ -0,0 +1,572 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct file file_t; +typedef struct process process_t; +typedef struct vnode vnode_t; + +typedef struct irp irp_t; + +/** + * @brief I/O Request Packet. + * @defgroup kernel_io_irp I/O Request Packet + * @ingroup kernel_io + * + * The I/O Request Packet (IRP) is a lock-less, self-contained, layered, continuation-passing request that acts as the + * primary primitive used by the kernel for asynchronous operations. + * + * The IRP is designed to be generic enough to be used by any system in the kernel, however it is primarily used by the I/O ring system. + * + * @warning While the cancellation or completion of an IRP is thread safe, the setup of an IRP is not (as in pushing + * layers to it). It is assumed that only one thread is manipulating an IRP during its setup. + * + * ## Completion + * + * @todo Write the IRP documentation. + * + * ## Cancellation + * + * Cancelling an IRP can intuitively be considered equivalent to forcing the last completion to fail, thus resulting in + * all the other completions to fail as well. + * + * The current owner of a IRP is responsible for handling cancellation by specifying a cancellation callback via + * `irp_set_cancel()`. The current owner being the last target of a `irp_call()` or `irp_call_direct()`. + * + * When an IRP is cancelled or timed out the cancellation callback will be invoked and atomically exchanged with a + * `IRP_CANCELLED` sentinel value. At which point the owner should perform whatever logic is needed to cancel the IRP, + * if it is not possible immediately cancel the IRP it should return `ERR`. + * + * Below is an example of how to implement a completion with an associated cancellation callback: + * + * ``` + * void my_completion(irp_t* irp, void* ctx) + * { + * // Do stuff... + * + * irp_complete(irp); + * } + * + * uint64_t my_cancel(irp_t* irp) + * { + * // Cancellation callback is automatically cleared. + * + * if (irp->err == ETIMEDOUT) + * { + * // We timed out. + * } + * if (irp->err == ECANCELED) + * { + * // We were explicitly cancelled. + * } + * + * // Do stuff... + * + * uint64_t result = ...; + * if (result == ERR) // If an error occurs we can reassign the cancellation callback. + * { + * irp_set_cancel(irp, my_cancel); + * return ERR; + * } + * + * return 0; + * } + * ``` + * + * ## Error Values + * + * The IRP system uses the `err` field to indicate both the current state of the IRP as well as any error that may have + * occurred during its processing. + * + * Included below are a list of "special" values which the IRP system will set: + * + * - `EOK`: Operation completed successfully. + * - `ECANCELED`: Operation was cancelled. + * - `ETIMEDOUT`: Operation timed out. + * + * @see kernel_io for the ring system. + * @see [Wikipedia](https://en.wikipedia.org/wiki/I/O_request_packet) for more information about IRPs. + * @see [Microsoft _IRP](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_irp) for information + * on how Windows NT implements IRPs. + * @{ + */ + +/** + * @brief IRP complete callback type. + * + * @param irp The IRP. + * @param ctx The contxt pointer from the `irp_frame_t` structure. + */ +typedef void (*irp_complete_t)(irp_t* irp, void* ctx); + +/** + * @brief IRP cancellation callback type. + * + * @param irp The IRP. + * @return On success, `0`. On failure, `ERR`. + */ +typedef uint64_t (*irp_cancel_t)(irp_t* irp); + +/** + * @brief Sentinel value indicating that the IRP has been cancelled. + */ +#define IRP_CANCELLED ((irp_cancel_t)1) + +typedef uint16_t irp_major_t; +#define IRP_MJ_READ 0 +#define IRP_MJ_WRITE 1 +#define IRP_MJ_POLL 2 +#define IRP_MJ_MAX 3 + +typedef uint16_t irp_minor_t; +#define IRP_MN_NORMAL 0 + +#define IRP_ARGS_MAX 4 ///< The maximum number of 64-bit arguments in an `irp_frame_t`. + +/** + * @brief IRP stack frame structure. + * @struct irp_frame_t + */ +typedef struct irp_frame +{ + irp_major_t major; ///< Major function number. + irp_minor_t minor; ///< Minor function number. + uint8_t _reserved[4]; + irp_complete_t complete; ///< Completion callback. + void* ctx; ///< Local context. + vnode_t* vnode; ///< Vnode associated with the operation. + union { + struct + { + mdl_t* buffer; + uint64_t off; + void* data; + uint32_t len; + mode_t mode; + } read; + struct + { + mdl_t* buffer; + uint64_t off; + void* data; + uint32_t len; + mode_t mode; + } write; + uint64_t args[IRP_ARGS_MAX]; ///< Generic arguments. + }; +} irp_frame_t; + +static_assert(sizeof(irp_frame_t) == 64, "irp_frame_t is not 64 bytes"); + +#define IRP_FRAME_MAX 5 ///< The maximum number of frames in a IRP stack. + +/** + * @brief I/O Request Packet structure. + * @struct irp_t + * + * The I/O Request Packet structure is designed to preallocate as much as possible such that in the common case there is + * no need for any allocation beyond the allocation of the IRP itself. This does require careful consideration of + * padding, alignment and field sizes to keep it within a reasonable size. + * + * @see kernel_io for more information for each possible verb. + */ +typedef struct ALIGNED(64) irp +{ + list_entry_t entry; ///< Used to store the IRP in various lists. + list_entry_t timeoutEntry; ///< Used to store the IRP in the timeout queue. + _Atomic(irp_cancel_t) cancel; ///< Cancellation callback, must be atomic to ensure an IRP is only cancelled once. + clock_t deadline; ///< The time at which the IRP will be removed from a timeout queue. + union { + size_t read; + size_t write; + uint64_t _raw; + } res; + mdl_t mdl; ///< A preallocated memory descriptor list for use by the IRP. + pool_idx_t index; ///< Index of the IRP in its pool. + pool_idx_t next; ///< Index of the next IRP in a chain or in the free list. + cpu_id_t cpu; ///< The CPU whose timeout queue the IRP is in. + uint8_t err; ///< The error code of the operation, also used to specify its current state. + uint8_t frame; ///< The index of the current frame in the stack. + irp_frame_t stack[IRP_FRAME_MAX]; ///< The frame stack, grows downwards. + sqe_t sqe; // A copy of the submission queue entry associated with this IRP. + uint8_t reserved[8]; +} irp_t; + +static_assert(sizeof(irp_t) == 512, "irp_t is not 512 bytes"); + +/** + * @brief Request pool structure. + * @struct irp_pool + */ +typedef struct irp_pool +{ + void* ctx; + process_t* process; ///< Will only hold a reference if there is at least one active IRP. + atomic_size_t active; + pool_t pool; + irp_t irps[]; +} irp_pool_t; + +/** + * @brief IRP function type. + */ +typedef void (*irp_func_t)(irp_t* irp); + +/** + * @brief IRP vtable structure. + * @struct irp_vtable_t + */ +typedef struct irp_vtable +{ + irp_func_t funcs[IRP_MJ_MAX]; +} irp_vtable_t; + +/** + * @brief Allocate a new IRP pool. + * + * @param size The amount of requests to allocate. + * @param process The process that will own the IRPs allocated from this pool. + * @param ctx The context of the IRP pool. + * @return On success, a pointer to the new IRP pool. On failure, `NULL` and `errno` is set. + */ +irp_pool_t* irp_pool_new(size_t size, process_t* process, void* ctx); + +/** + * @brief Free a IRP pool. + * + * @param pool The IRP pool to free. + */ +void irp_pool_free(irp_pool_t* pool); + +/** + * @brief Add an IRP to a per-CPU timeout queue. + * + * @param irp The IRP to add. + * @param timeout The timeout of the IRP. + */ +void irp_timeout_add(irp_t* irp, clock_t timeout); + +/** + * @brief Remove an IRP from its per-CPU timeout queue. + * + * @param irp The IRP to remove. + */ +void irp_timeout_remove(irp_t* irp); + +/** + * @brief Check and handle expired IRP timeouts on the current CPU. + */ +void irp_timeouts_check(void); + +/** + * @brief Allocate a new IRP from a pool. + * + * The pool that the IRP was allocated from, and its context, can be retrieved using the `irp_get_pool()` + * function. + * + * @param pool The IRP pool. + * @return On success, a pointer to the allocated IRP. On failure, `NULL` and `errno` is set. + */ +irp_t* irp_new(irp_pool_t* pool); + +/** + * @brief Retrieve a memory descriptor list and associate it with an IRP. + * + * All MDLs associated with a IRP will be cleaned up when finished. + * + * @param irp The IRP to associate the MDL with. + * @param addr The virtual address of the memory region to add to the MDL, or `NULL` for a blank MDL. + * @param size The size of the memory region. + * @return On success, a pointer to the MDL. On failure, `NULL` and `errno` is set. + */ +mdl_t* irp_get_mdl(irp_t* irp, const void* addr, size_t size); + +/** + * @brief Retrieve the IRP pool that an IRP was allocated from. + * + * @param irp The IRP. + * @return The IRP pool. + */ +static inline irp_pool_t* irp_get_pool(irp_t* irp) +{ + return CONTAINER_OF(irp, irp_pool_t, irps[irp->index]); +} + +/** + * @brief Retrieve the context of the IRP pool that an IRP was allocated from. + * + * @param irp The IRP. + * @return The context. + */ +static inline void* irp_get_ctx(irp_t* irp) +{ + return irp_get_pool(irp)->ctx; +} + +/** + * @brief Retrieve the process that owns an IRP. + * + * @param irp The IRP. + * @return The process. + */ +static inline process_t* irp_get_process(irp_t* irp) +{ + return irp_get_pool(irp)->process; +} + +/** + * @brief Retrieve the next IRP in a chain and advance the chain. + * + * @param irp The current IRP. + * @return The next IRP, or `NULL` if there is no next IRP. + */ +static inline irp_t* irp_chain_next(irp_t* irp) +{ + irp_pool_t* pool = irp_get_pool(irp); + if (irp->next == POOL_IDX_MAX) + { + return NULL; + } + + irp_t* next = &pool->irps[irp->next]; + irp->next = next->next; + next->next = POOL_IDX_MAX; + return next; +} + +/** + * @brief Attempt to cancel an IRP. + * + * @param irp The IRP to cancel. + * @return On success, `0`. On failure, `ERR` and `errno` is set. + */ +uint64_t irp_cancel(irp_t* irp); + +/** + * @brief Set the cancellation callback for an IRP. + * + * @param irp The IRP. + * @param cancel The cancellation callback. + * @return The previous cancellation callback. + */ +static inline irp_cancel_t irp_set_cancel(irp_t* irp, irp_cancel_t cancel) +{ + irp_cancel_t expected = atomic_load(&irp->cancel); + while (expected != IRP_CANCELLED) + { + if (atomic_compare_exchange_weak(&irp->cancel, &expected, cancel)) + { + return expected; + } + } + return IRP_CANCELLED; +} + +/** + * @brief Retrieve the current frame in the IRP stack. + * + * @param irp The IRP to retrieve the frame from. + * @return The current frame. + */ +static inline irp_frame_t* irp_current(irp_t* irp) +{ + assert(irp->frame < IRP_FRAME_MAX); + return &irp->stack[irp->frame]; +} + +/** + * @brief Retrieve the next frame in the IRP stack. + * + * @param irp The IRP to retrieve the frame from. + * @return The next frame, or `NULL` if we are at the bottom of the stack. + */ +static inline irp_frame_t* irp_next(irp_t* irp) +{ + if (irp->frame == 0) + { + return NULL; + } + return &irp->stack[irp->frame - 1]; +} + +/** + * @brief Copy the current frame in the IRP stack to the next. + * + * @param irp The IRP. + */ +static inline void irp_copy_to_next(irp_t* irp) +{ + irp_frame_t* current = irp_current(irp); + irp_frame_t* next = irp_next(irp); + + if (next->vnode != NULL) + { + UNREF(next->vnode); + next->vnode = NULL; + } + + *next = *current; + next->vnode = NULL; + next->complete = NULL; + next->ctx = NULL; +} + +/** + * @brief Skip the current stack frame, meaning the next call will run in the same stack frame. + * + * @param irp The IRP. + */ +static inline void irp_skip(irp_t* irp) +{ + irp_frame_t* frame = irp_current(irp); + if (frame->vnode != NULL) + { + UNREF(frame->vnode); + frame->vnode = NULL; + } + assert(irp->frame < IRP_FRAME_MAX); + irp->frame++; +} + +/** + * @brief Send an IRP to a specified vnode. + * + * Will advance the IRP stack. + * + * @param irp The IRP to send. + * @param vnode The vnode to associated with the next IRP stack frame. + */ +void irp_call(irp_t* irp, vnode_t* vnode); + +/** + * @brief Send an IRP to a specified function directly. + * + * Will advance the IRP stack. + * + * @param irp The IRP to send. + * @param func The function to call. + */ +void irp_call_direct(irp_t* irp, irp_func_t func); + +/** + * @brief Complete the current frame in the IRP stack. + * + * If the current frame does not have a completion, it will automatically complete the next frame in the stack. + * + * If the last frame is reached, the IRP is considered finished. Which will causing its resources to be freed and for + * the IRP to be returned to its pool. + * + * @param irp The IRP to complete. + */ +void irp_complete(irp_t* irp); + +/** + * @brief Set the completion callback and context for the next frame in the IRP stack. + * + * @param irp The IRP to set. + * @param complete The completion callback. + * @param ctx The context pointer to pass to the completion callback. + */ +static inline void irp_set_complete(irp_t* irp, irp_complete_t complete, void* ctx) +{ + irp_frame_t* next = irp_next(irp); + next->complete = complete; + next->ctx = ctx; +} + +/** + * @brief Helper to set an error code and complete the IRP. + * + * @param irp The IRP to error. + * @param err The error code to set. + */ +static inline void irp_error(irp_t* irp, uint8_t err) +{ + irp->err = err; + irp_complete(irp); +} + +/** + * @brief Prepares the next IRP stack frame for a generic operation. + * + * @param irp The IRP. + * @param major The major function number. + * @param arg0 Generic argument 0. + * @param arg1 Generic argument 1. + * @param arg2 Generic argument 2. + * @param arg3 Generic argument 3. + */ +static inline void irp_prepare_generic(irp_t* irp, irp_major_t major, uint64_t arg0, uint64_t arg1, uint64_t arg2, + uint64_t arg3) +{ + irp_frame_t* next = irp_next(irp); + assert(next != NULL); + + next->major = major; + next->args[0] = arg0; + next->args[1] = arg1; + next->args[2] = arg2; + next->args[3] = arg3; +} + +/** + * @brief Prepares the next IRP stack frame for a read operation. + * + * @param irp The IRP. + * @param buffer The memory descriptor list to read into. + * @param data The buffer to read into. + * @param off The offset in the file to read from. + * @param len The number of bytes to read. + * @param mode The mode. + */ +static inline void irp_prepare_read(irp_t* irp, mdl_t* buffer, void* data, uint64_t off, uint32_t len, mode_t mode) +{ + irp_frame_t* next = irp_next(irp); + assert(next != NULL); + + next->major = IRP_MJ_READ; + next->read.buffer = buffer; + next->read.data = data; + next->read.off = off; + next->read.len = len; + next->read.mode = mode; +} + +/** + * @brief Prepares the next IRP stack frame for a write operation. + * + * @param irp The IRP. + * @param buffer The memory descriptor list to write from. + * @param data The buffer to write from. + * @param off The offset in the file to write to. + * @param len The number of bytes to write. + * @param mode The mode. + */ +static inline void irp_prepare_write(irp_t* irp, mdl_t* buffer, void* data, uint64_t off, uint32_t len, mode_t mode) +{ + irp_frame_t* next = irp_next(irp); + assert(next != NULL); + + next->major = IRP_MJ_WRITE; + next->write.buffer = buffer; + next->write.data = data; + next->write.off = off; + next->write.len = len; + next->write.mode = mode; +} + +/** @} */ \ No newline at end of file diff --git a/include/kernel/io/ring.h b/include/kernel/io/ring.h new file mode 100644 index 000000000..3f0bf361c --- /dev/null +++ b/include/kernel/io/ring.h @@ -0,0 +1,216 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/** + * @brief Programmable submission/completion interface. + * @defgroup kernel_io_ring Kernel-side I/O Ring Interface + * @ingroup kernel_io + * + * @todo The I/O ring system is primarily a design document for now as it remains very work in progress and subject to + * change, currently being mostly unimplemented. + * + * @todo Rewrite the Kernel-side I/O Ring Interface documentation to match the new system. + * + * The I/O ring provides the core of all interfaces in PatchworkOS, where user-space submits Submission Queue Entries + * (SQEs) and receives Completion Queue Entries (CQEs) from it, all within shared memory. Allowing for highly efficient + * and asynchronous I/O operations, especially since PatchworkOS is designed to be natively asynchronous. + * + * Each SQE specifies a verb (the operation to perform) and a set of up to `SQE_MAX_ARG` arguments, while each CQE + * returns the result of a previously submitted SQE. + * + * Synchronous operations are implemented on top of this API in userspace. + * + * @see libstd_sys_ioring for the userspace interface to the asynchronous ring. + * @see [Wikipedia](https://en.wikipedia.org/wiki/Io_uring) for information about `io_uring`, the inspiration for this + * system. + * @see [Manpages](https://man7.org/linux/man-pages/man7/io_uring.7.html) for more information about `io_uring`. + * + * ## Syncronization + * + * The I/O ring structure is designed to be safe under the assumption that there is a single producer (one user-space + * thread) and a single consumer (the kernel). + * + * If an I/O ring needs multiple producers (needs to be accessed by multiple threads) it is the responsibility of + * the caller to ensure proper synchronization. + * + * @note The reason for this limitation is optimization for the common case, as the syncronization logic for multiple + * producers would add significant overhead. Additionally, it is rather straight forward for user-space to protect the + * ring with a mutex should it need to. + * + * Regarding the I/O ring structure itself, the structure can only be torndown as long as nothing is using it and there + * are no pending operations. + * + * ## Registers + * + * Operations performed on a I/O ring can load arguments from, and save their results to, seven 64-bit general purpose + * registers. All registers are stored in the shared control area of the I/O ring structure (`ioring_ctrl_t`), as such + * they can be inspected and modified by user space. + * + * When a SQE is processed, the kernel will check six register specifiers in the SQE flags, one for each argument and + * one for the result. Each specifier is stored as three bits, with a `SQE_REG_NONE` value indicating no-op and any + * other value representing the n-th register. The offset of the specifier specifies its meaning, for example, bits + * `0-2` specify the register to load into the first argument, bits `3-5` specify the register to load into the second + * argument, and so on until bits `15-17` which specify the register to save the result into. + * + * This system, when combined with `SQE_LINK`, allows for multiple operations to be performed at once, for example, it + * would be possible to open a file, read from it, seek to a new position, write to it, and finally close the file, with + * a single `enter()` call. + * + * @see `sqe_flags_t` for more information about register specifiers and their formatting. + * + * ## Arguments + * + * Arguments within a SQE are stored in five 64-bit values, `arg1` through `arg5`. For convenience, each argument value + * is stored as a union with various types. + * + * To avoid nameing conflicts and to avoid having to define new arguments for each verb, we define a convention to be + * used for the arguments. + * + * - `arg0`: The noun or subject of the verb, for example, a `fd_t` for file operations. + * - `arg1`: The source or payload of the verb, for example, a buffer or path. + * - `arg2`: The magnitude of the operation, for example, a size or encoding. + * - `arg3`: The location or a modifier to the operation, for example, an offset or flags. + * - `arg4`: An auxiliary argument, for example, additional flags or options. + * + * It may not always be possible for a verb to follow these conventions, but they should be followed whenever + * reasonable. + * + * @note The kernels internal I/O Request Packet structure uses a similar system but with the kernel equivalents + * of the arguments, for example, a `file_t*` instead of a `fd_t`. + * + * ## Results + * + * The result of a SQE is stored in its corresponding CQE using a single 64-bit value. For convenience, the result is + * stored as a union of various types. Note that this does not actually change the stored value, just how it is + * interpreted. + * + * If a SQE fails, the error code will be stored separately from the result and the result it self may be undefined. + * Some verbs may allow partial failures in which case the result may still be valid even if an error code is present. + * + * @todo Decide if partial failures are a good idea or not. + * + * ## Errors + * + * The majority of errors are returned in the CQEs, certain errors (such as `ENOMEM`) may be + * reported directly from the `enter()` call. + * + * Error values that may be returned in a CQE include: + * - `EOK`: Success. + * - `ECANCELED`: The verb was cancelled. + * - `ETIMEDOUT`: The verb timed out. + * - Other values may be returned depending on the verb. + * + * ## Verbs + * + * Included below is a list of all currently implemented verbs. + * + * The arguments of each verb is specified in order as `arg0`, `arg1`, `arg2`, `arg3`, `arg4`. + * + * ### `VERB_NOP` + * + * A no-operation verb that does nothing but is useful for implementing sleeping. + * + * @param arg0 Unused + * @param arg1 Unused + * @param arg2 Unused + * @param arg3 Unused + * @param arg4 Unused + * @result None + * + * ### `VERB_READ` + * + * Reads data from a file descriptor. + * + * @param fd The file descriptor to read from. + * @param buffer The buffer to read the data into. + * @param count The number of bytes to read. + * @param offset The offset to read from, or `IO_CUR` to use the current position. + * @param arg4 Unused + * @result The number of bytes read. + * + * ### `VERB_WRITE` + * + * Writes data to a file descriptor. + * + * @param fd The file descriptor to write to. + * @param buffer The buffer to write the data from. + * @param count The number of bytes to write. + * @param offset The offset to write to, or `IO_CUR` to use the current position. + * @param arg4 Unused + * @result The number of bytes written. + * + * ### `VERB_POLL` + * + * Polls a file descriptor for events. + * + * @param fd The file descriptor to poll. + * @param events The events to wait for. + * @param arg2 Unused + * @param arg3 Unused + * @param arg4 Unused + * @result The events that occurred. + * + * @{ + */ + +/** + * @brief Ring context flags. + * @enum ioring_ctx_flags_t + */ +typedef enum +{ + IORING_CTX_NONE = 0, ///< No flags set. + IORING_CTX_BUSY = 1 << 0, ///< Context is currently being used, used for fast locking. + IORING_CTX_MAPPED = 1 << 1, ///< Context is currently mapped into userspace. +} ioring_ctx_flags_t; + +/** + * @brief The kernel-side ring context structure. + * @struct ioring_ctx_t + */ +typedef struct ioring_ctx +{ + ioring_t ring; ///< The kernel-side ring structure. + irp_pool_t* irps; ///< Pool of preallocated IRPs. + void* userAddr; ///< Userspace address of the ring. + void* kernelAddr; ///< Kernel address of the ring. + size_t pageAmount; ///< Amount of pages mapped for the ring. + wait_queue_t waitQueue; ///< Wait queue for completions. + _Atomic(ioring_ctx_flags_t) flags; +} ioring_ctx_t; + +/** + * @brief Initialize a I/O context. + * + * @param ctx Pointer to the context to initialize. + */ +void ioring_ctx_init(ioring_ctx_t* ctx); + +/** + * @brief Deinitialize a I/O context. + * + * @param ctx Pointer to the context to deinitialize. + */ +void ioring_ctx_deinit(ioring_ctx_t* ctx); + +/** + * @brief Notify the context of new SQEs. + * + * @param ctx Pointer to the context. + * @param amount The number of SQEs to process. + * @param wait The minimum number of CQEs to wait for. + * @return On success, the number of SQEs processed. On failure, `ERR` and `errno` is set. + */ +uint64_t ioring_ctx_notify(ioring_ctx_t* ctx, size_t amount, size_t wait); + +/** @} */ \ No newline at end of file diff --git a/include/kernel/ipc/note.h b/include/kernel/ipc/note.h index d9d4bb76a..f6cc7f5e9 100644 --- a/include/kernel/ipc/note.h +++ b/include/kernel/ipc/note.h @@ -5,7 +5,7 @@ #include #include -#include +#include #include typedef struct cpu cpu_t; diff --git a/include/kernel/kernel.h b/include/kernel/kernel.h index 7e54d726e..13d337141 100644 --- a/include/kernel/kernel.h +++ b/include/kernel/kernel.h @@ -1,5 +1,7 @@ /** - * @brief The kernel of PatchworkOS. + * @brief The modular of PatchworkOS. * @defgroup kernel Kernel + * + * The kernel and its associated modules is responsible for managing system resources and providing hardware abstractions. */ \ No newline at end of file diff --git a/include/kernel/log/log.h b/include/kernel/log/log.h index 1e89c8534..315a6713b 100644 --- a/include/kernel/log/log.h +++ b/include/kernel/log/log.h @@ -7,13 +7,13 @@ #include #include #include -#include +#include #include #include /** - * @brief Logging - * @defgroup kernel_log Logging + * @brief Kernel logging and debugging. + * @defgroup kernel_log Logging Subsystem * @ingroup kernel * * @{ diff --git a/include/kernel/mem/mdl.h b/include/kernel/mem/mdl.h new file mode 100644 index 000000000..cc9a05fc7 --- /dev/null +++ b/include/kernel/mem/mdl.h @@ -0,0 +1,205 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +typedef struct process process_t; + +/** + * @brief Memory Descriptor List. + * @defgroup kernel_mem_mdl Memory Descriptor List + * @ingroup kernel_mem + * + * The Memory Descriptor List (MDL) is a structure used to describe non-contiguous physical memory, allowing it be + * accessed as a single contiguous block regardless of the loaded address space. + * + * ## I/O Operations + * + * The MDL structure is primarily used to describe memory regions for I/O operations. For example, if a process + * specifies a buffer to write to but that I/O operation is later completed while a different address space is loaded, + * the kernel would be unable to access the buffer directly. + * + * Instead, the kernel can create an MDL for the buffer, which describes the physical memory pages backing that buffer, + * allowing the I/O operation to be completed regardless of the currently loaded address space. + * + * @{ + */ + +/** + * @brief Amount of memory segments statically allocated for small MDLs. + */ +#define MDL_SEGS_SMALL_MAX 2 + +/** + * @brief Memory Descriptor List Segment structure. + * @struct mdl_seg_t + */ +typedef struct mdl_seg +{ + pfn_t pfn; ///< Page frame number. + uint32_t size; ///< Size of the segment in bytes. + uint32_t offset; ///< Offset in bytes within the first page. +} mdl_seg_t; + +/** + * @brief Memory Descriptor List structure. + * @struct mdl_t + */ +typedef struct mdl +{ + struct mdl* next; ///< Pointer to the next MDL. + mdl_seg_t small[MDL_SEGS_SMALL_MAX]; ///< Statically allocated segments for small regions. + mdl_seg_t* segments; ///< Pointer to segments array. + uint32_t amount; ///< Number of memory segments. + uint32_t capacity; ///< Capacity of the `large` array. +} mdl_t; + +/** + * @brief Initialize a Memory Descriptor List. + * + * @param next Pointer to the MDL. + * @param prev Pointer to the previous MDL in the chain, or `NULL` if none. + */ +static inline void mdl_init(mdl_t* next, mdl_t* prev) +{ + if (prev != NULL) + { + prev->next = next; + } + next->next = NULL; + next->segments = next->small; + next->amount = 0; + next->capacity = MDL_SEGS_SMALL_MAX; +} + +/** + * @brief Deinitialize a Memory Descriptor List. + * + * @param mdl Pointer to the MDL. + */ +void mdl_deinit(mdl_t* mdl); + +/** + * @brief Free a Memory Descriptor List chain. + * + * Will traverse the entire chain to deinitialize and free each MDL structure using the provided `free` function. + * + * @param mdl Pointer to the first MDL in the chain. + * @param free Function to free the MDL structure itself, or `NULL` to only deinitialize. + */ +void mdl_free_chain(mdl_t* mdl, void (*free)(void*)); + +/** + * @brief Initialize a Memory Descriptor List from a memory region. + * + * @param mdl Pointer to the MDL. + * @param prev Pointer to the previous MDL in the chain, or `NULL` if none. + * @param space The address space of the region. + * @param addr The virtual address of the memory region. + * @param size The size of the memory region in bytes. + * @return On success, `0`. On failure, `ERR` and `errno` is set: + * - See `mdl_add()` for possible error codes. + */ +uint64_t mdl_from_region(mdl_t* mdl, mdl_t* prev, space_t* space, const void* addr, size_t size); + +/** + * @brief Add a memory region to the Memory Descriptor List. + * + * @param mdl Pointer to the MDL. + * @param space The address space of the user process. + * @param addr The virtual address of the memory region. + * @param size The size of the memory region in bytes. + * @return On success, `0`. On failure, `ERR` and `errno` is set to: + * - See `mdl_add()` for possible error codes. + */ +uint64_t mdl_add(mdl_t* mdl, space_t* space, const void* addr, size_t size); + +/** + * @brief Read from a Memory Descriptor List into a buffer. + * + * @param mdl The MDL to read from. + * @param buffer The buffer to read into. + * @param count Number of bytes to read. + * @param offset Offset within the MDL to start reading from. + * @return The number of bytes read. + */ +uint64_t mdl_read(mdl_t* mdl, void* buffer, size_t count, size_t offset); + +/** + * @brief Write to a Memory Descriptor List from a buffer. + * + * @param mdl The MDL to write to. + * @param buffer The buffer to write from. + * @param count Number of bytes to write. + * @param offset Offset within the MDL to start writing to. + * @return The number of bytes written. + */ +uint64_t mdl_write(mdl_t* mdl, const void* buffer, size_t count, size_t offset); + +/** + * @brief Memory Descriptor List Iterator structure. + * @struct mdl_iter_t + */ +typedef struct +{ + mdl_t* mdl; + size_t segIndex; + size_t segOffset; +} mdl_iter_t; + +/** + * @brief Create a Memory Descriptor List Iterator initializer. + * + * @param _mdl Pointer to the MDL to iterate over. + * @return MDL Iterator initializer. + */ +#define MDL_ITER_CREATE(_mdl) \ + { \ + .mdl = (_mdl), \ + .segIndex = 0, \ + .segOffset = 0, \ + } + +/** + * @brief Get the next byte from a Memory Descriptor List Iterator. + * + * @param iter Pointer to the MDL Iterator. + * @param byte Pointer to store the retrieved byte. + * @return `true` if a byte was retrieved, `false` if the end of the MDL was reached. + */ +static inline bool mdl_iter_next(mdl_iter_t* iter, uint8_t* byte) +{ + if (iter->segIndex >= iter->mdl->amount) + { + return false; + } + + mdl_seg_t* seg = &iter->mdl->segments[iter->segIndex]; + uint8_t* addr = PFN_TO_VIRT(seg->pfn) + seg->offset + iter->segOffset; + *byte = *(addr); + + iter->segOffset++; + if (iter->segOffset >= seg->size) + { + iter->segIndex++; + iter->segOffset = 0; + } + + return true; +} + +/** + * @brief Iterate over bytes within a Memory Descriptor List. + * + * @param _byte The iterator variable. + * @param _mdl Pointer to the MDL. + */ +#define MDL_FOR_EACH(_byte, _mdl) for (mdl_iter_t _iter = MDL_ITER_CREATE(_mdl); mdl_iter_next(&_iter, (_byte));) + +/** @} */ \ No newline at end of file diff --git a/include/kernel/mem/mem.h b/include/kernel/mem/mem.h index 5b66f3175..1815e5bd3 100644 --- a/include/kernel/mem/mem.h +++ b/include/kernel/mem/mem.h @@ -1,6 +1,6 @@ /** * @brief Memory management. - * @defgroup kernel_mem Memory + * @defgroup kernel_mem Memory Subsystem * @ingroup kernel * */ \ No newline at end of file diff --git a/include/kernel/mem/paging.h b/include/kernel/mem/paging.h index c1922c3ae..756febaca 100644 --- a/include/kernel/mem/paging.h +++ b/include/kernel/mem/paging.h @@ -3,7 +3,7 @@ #include #include -#include <_internal/PAGE_SIZE.h> +#include <_libstd/PAGE_SIZE.h> #include #include #include @@ -21,47 +21,29 @@ * our changes are detected we must invalidate this cache using `invlpg` or if many pages are changed, a full TLB flush * by reloading CR3. * - * @param virtAddr The virtual address of the page to invalidate. + * @param addr The starting virtual address of the region. + * @param amount The number of pages to invalidate. */ -static inline void tlb_invalidate(void* virtAddr, uint64_t pageCount) +static inline void tlb_invalidate(void* addr, size_t amount) { - if (pageCount == 0) + if (amount == 0) { return; } - if (pageCount > 16) + if (amount > 16) { cr3_write(cr3_read()); } else { - for (uint64_t i = 0; i < pageCount; i++) + for (uint64_t i = 0; i < amount; i++) { - ASM("invlpg (%0)" ::"r"(virtAddr + i * PAGE_SIZE) : "memory"); + ASM("invlpg (%0)" ::"r"(addr + (i * PAGE_SIZE)) : "memory"); } } } -/** - * @brief Retrieves the address from a page table entry and converts it to an accessible address. - * - * The accessible address depends on if we are in the kernel or the bootloader as the bootloader has physical memory - * identity mapped to the higher half of the address space, while the kernel does not and instead has the higher half - * mapped to the lower half of the address space. - * - * @param entry The page table entry. - * @return The accessible address contained in the entry. - */ -static inline uintptr_t pml_accessible_addr(pml_entry_t entry) -{ -#ifdef _BOOT_ - return entry.addr << PML_ADDR_OFFSET_BITS; -#else - return PML_LOWER_TO_HIGHER(entry.addr << PML_ADDR_OFFSET_BITS); -#endif -} - /** * @brief Checks if a page table level is empty (all entries are 0). * @@ -91,11 +73,12 @@ static inline bool pml_is_empty(pml_t* pml) */ static inline uint64_t pml_new(page_table_t* table, pml_t** outPml) { - pml_t* pml; - if (table->allocPages((void**)&pml, 1) == ERR) + pfn_t pfn; + if (table->allocPages(&pfn, 1) == ERR) { return ERR; } + pml_t* pml = PFN_TO_VIRT(pfn); memset(pml, 0, PAGE_SIZE); *outPml = pml; return 0; @@ -125,16 +108,17 @@ static inline void pml_free(page_table_t* table, pml_t* pml, pml_level_t level) if (level > PML1) { - pml_free(table, (pml_t*)pml_accessible_addr(*entry), level - 1); + pml_free(table, PFN_TO_VIRT(entry->pfn), level - 1); } else if (entry->owned) { - void* addr = (void*)pml_accessible_addr(*entry); - table->freePages(&addr, 1); + pfn_t pfn = entry->pfn; + table->freePages(&pfn, 1); } } - table->freePages((void**)&pml, 1); + pfn_t pfn = VIRT_TO_PFN(pml); + table->freePages(&pfn, 1); } /** @@ -189,31 +173,32 @@ static inline void page_table_load(page_table_t* table) * set, it returns `ERR`. * * @param table The page table. - * @param currentPml The current page table level. + * @param current The current page table level. * @param index The index within the current page table level. * @param flags The flags to assign to a newly allocated page table level, if applicable. - * @param outPml Will be filled with the retrieved or newly allocated page table level. + * @param out Will be filled with the retrieved or newly allocated page table level. * @return On success, `0`. On failure, `ERR`. */ -static inline uint64_t page_table_get_pml(page_table_t* table, pml_t* currentPml, pml_index_t index, pml_flags_t flags, - pml_t** outPml) +static inline uint64_t page_table_get_pml(page_table_t* table, pml_t* current, pml_index_t index, pml_flags_t flags, + pml_t** out) { - pml_entry_t* entry = ¤tPml->entries[index]; + pml_entry_t* entry = ¤t->entries[index]; if (entry->present) { - *outPml = (pml_t*)pml_accessible_addr(*entry); + *out = PFN_TO_VIRT(entry->pfn); return 0; } if (flags & PML_PRESENT) { - pml_t* nextPml; - if (pml_new(table, &nextPml) == ERR) + pml_t* next; + if (pml_new(table, &next) == ERR) { return ERR; } - currentPml->entries[index].raw = (flags & PML_FLAGS_MASK) | (PML_ENSURE_LOWER_HALF(nextPml) & PML_ADDR_MASK); - *outPml = nextPml; + current->entries[index].raw = flags & PML_FLAGS_MASK; + current->entries[index].pfn = VIRT_TO_PFN(next); + *out = next; return 0; } @@ -262,15 +247,15 @@ typedef struct * * @param table The page table. * @param traverse The helper structure used to cache each layer. - * @param virtAddr The target virtual address. + * @param addr The target virtual address. * @param flags The flags to assigned to newly allocated levels, if the present flag is not set then dont allocate new * levels. * @return On success, `0`. On failure, `ERR`. */ -static inline uint64_t page_table_traverse(page_table_t* table, page_table_traverse_t* traverse, uintptr_t virtAddr, +static inline uint64_t page_table_traverse(page_table_t* table, page_table_traverse_t* traverse, const void* addr, pml_flags_t flags) { - pml_index_t newIdx3 = PML_ADDR_TO_INDEX(virtAddr, PML4); + pml_index_t newIdx3 = PML_ADDR_TO_INDEX(addr, PML4); if (!traverse->pml3Valid || traverse->oldIdx3 != newIdx3) { if (page_table_get_pml(table, table->pml4, newIdx3, (flags | PML_WRITE | PML_USER) & ~PML_GLOBAL, @@ -282,7 +267,7 @@ static inline uint64_t page_table_traverse(page_table_t* table, page_table_trave traverse->pml2Valid = false; // Invalidate cache for lower levels } - pml_index_t newIdx2 = PML_ADDR_TO_INDEX(virtAddr, PML3); + pml_index_t newIdx2 = PML_ADDR_TO_INDEX(addr, PML3); if (!traverse->pml2Valid || traverse->oldIdx2 != newIdx2) { if (page_table_get_pml(table, traverse->pml3, newIdx2, flags | PML_WRITE | PML_USER, &traverse->pml2) == ERR) @@ -293,7 +278,7 @@ static inline uint64_t page_table_traverse(page_table_t* table, page_table_trave traverse->pml1Valid = false; // Invalidate cache for lower levels } - pml_index_t newIdx1 = PML_ADDR_TO_INDEX(virtAddr, PML2); + pml_index_t newIdx1 = PML_ADDR_TO_INDEX(addr, PML2); if (!traverse->pml1Valid || traverse->oldIdx1 != newIdx1) { if (page_table_get_pml(table, traverse->pml2, newIdx1, flags | PML_WRITE | PML_USER, &traverse->pml1) == ERR) @@ -303,28 +288,26 @@ static inline uint64_t page_table_traverse(page_table_t* table, page_table_trave traverse->oldIdx1 = newIdx1; } - traverse->entry = &traverse->pml1->entries[PML_ADDR_TO_INDEX(virtAddr, PML1)]; + traverse->entry = &traverse->pml1->entries[PML_ADDR_TO_INDEX(addr, PML1)]; return 0; } /** * @brief Retrieves the physical address mapped to a given virtual address. * - * If the virtual address is not mapped, the function returns `ERR`. - * * @param table The page table. - * @param virtAddr The virtual address to look up. - * @param outPhysAddr Will be filled with the corresponding physical address on success. + * @param addr The virtual address to look up. + * @param out Will be filled with the corresponding physical address on success. * @return On success, `0`. On failure, `ERR`. */ -static inline uint64_t page_table_get_phys_addr(page_table_t* table, const void* virtAddr, void** outPhysAddr) +static inline uint64_t page_table_get_phys_addr(page_table_t* table, void* addr, phys_addr_t* out) { - uint64_t offset = ((uint64_t)virtAddr) % PAGE_SIZE; - virtAddr = (void*)ROUND_DOWN(virtAddr, PAGE_SIZE); + size_t offset = ((uintptr_t)addr) % PAGE_SIZE; + addr = (void*)ROUND_DOWN(addr, PAGE_SIZE); page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - if (page_table_traverse(table, &traverse, (uintptr_t)virtAddr, PML_NONE) == ERR) + if (page_table_traverse(table, &traverse, addr, PML_NONE) == ERR) { return ERR; } @@ -334,7 +317,7 @@ static inline uint64_t page_table_get_phys_addr(page_table_t* table, const void* return ERR; } - *outPhysAddr = (void*)((traverse.entry->addr << PML_ADDR_OFFSET_BITS) + offset); + *out = PFN_TO_PHYS(traverse.entry->pfn) + offset; return 0; } @@ -344,16 +327,16 @@ static inline uint64_t page_table_get_phys_addr(page_table_t* table, const void* * If any page in the range is not mapped, the function returns `false`. * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param pageAmount The number of pages to check. + * @param addr The starting virtual address. + * @param amount The number of pages to check. * @return `true` if the entire range is mapped, `false` otherwise. */ -static inline bool page_table_is_mapped(page_table_t* table, const void* virtAddr, size_t pageAmount) +static inline bool page_table_is_mapped(page_table_t* table, const void* addr, size_t amount) { page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - if (page_table_traverse(table, &traverse, (uintptr_t)virtAddr + i * PAGE_SIZE, PML_NONE) == ERR) + if (page_table_traverse(table, &traverse, addr + i * PAGE_SIZE, PML_NONE) == ERR) { return false; } @@ -373,17 +356,17 @@ static inline bool page_table_is_mapped(page_table_t* table, const void* virtAdd * If any page in the range is mapped, the function returns `false`. * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param pageAmount The number of pages to check. + * @param addr The starting virtual address. + * @param amount The number of pages to check. * @return `true` if the entire range is unmapped, `false` otherwise. */ -static inline bool page_table_is_unmapped(page_table_t* table, const void* virtAddr, size_t pageAmount) +static inline bool page_table_is_unmapped(page_table_t* table, void* addr, size_t amount) { page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - if (page_table_traverse(table, &traverse, (uintptr_t)virtAddr + i * PAGE_SIZE, PML_NONE) == ERR) + if (page_table_traverse(table, &traverse, addr + i * PAGE_SIZE, PML_NONE) == ERR) { continue; } @@ -403,14 +386,14 @@ static inline bool page_table_is_unmapped(page_table_t* table, const void* virtA * If any page in the range is already mapped, the function will fail and return `ERR`. * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param physAddr The starting physical address. - * @param pageAmount The number of pages to map. + * @param addr The starting virtual address. + * @param phys The starting physical address. + * @param amount The number of pages to map. * @param flags The flags to set for the mapped pages. Must include `PML_PRESENT`. * @param callbackId The callback ID to associate with the mapped pages or `PML_CALLBACK_NONE`. * @return On success, `0`. On failure, `ERR`. */ -static inline uint64_t page_table_map(page_table_t* table, void* virtAddr, void* physAddr, size_t pageAmount, +static inline uint64_t page_table_map(page_table_t* table, void* addr, phys_addr_t phys, size_t amount, pml_flags_t flags, pml_callback_id_t callbackId) { if (!(flags & PML_PRESENT)) @@ -420,9 +403,9 @@ static inline uint64_t page_table_map(page_table_t* table, void* virtAddr, void* page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - if (page_table_traverse(table, &traverse, (uintptr_t)virtAddr, flags) == ERR) + if (page_table_traverse(table, &traverse, addr, flags) == ERR) { return ERR; } @@ -433,12 +416,12 @@ static inline uint64_t page_table_map(page_table_t* table, void* virtAddr, void* } traverse.entry->raw = flags; - traverse.entry->addr = ((uintptr_t)PML_ENSURE_LOWER_HALF(physAddr)) >> PML_ADDR_OFFSET_BITS; + traverse.entry->pfn = PHYS_TO_PFN(phys); traverse.entry->lowCallbackId = callbackId & 1; traverse.entry->highCallbackId = callbackId >> 1; - physAddr = (void*)((uintptr_t)physAddr + PAGE_SIZE); - virtAddr = (void*)((uintptr_t)virtAddr + PAGE_SIZE); + phys += PAGE_SIZE; + addr += PAGE_SIZE; } return 0; @@ -450,14 +433,14 @@ static inline uint64_t page_table_map(page_table_t* table, void* virtAddr, void* * If any page in the range is already mapped, the function will fail and return `ERR`. * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param pages Array of physical page addresses to map. - * @param pageAmount The number of pages in the array to map. + * @param addr The starting virtual address. + * @param pfns Array of page frame numbers to map. + * @param amount The number of pages in the array to map. * @param flags The flags to set for the mapped pages. Must include `PML_PRESENT`. * @param callbackId The callback ID to associate with the mapped pages or `PML_CALLBACK_NONE`. * @return On success, `0`. On failure, `ERR`. */ -static inline uint64_t page_table_map_pages(page_table_t* table, void* virtAddr, void** pages, size_t pageAmount, +static inline uint64_t page_table_map_pages(page_table_t* table, void* addr, const pfn_t* pfns, size_t amount, pml_flags_t flags, pml_callback_id_t callbackId) { if (!(flags & PML_PRESENT)) @@ -467,9 +450,9 @@ static inline uint64_t page_table_map_pages(page_table_t* table, void* virtAddr, page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - if (page_table_traverse(table, &traverse, (uintptr_t)virtAddr, flags) == ERR) + if (page_table_traverse(table, &traverse, addr, flags) == ERR) { return ERR; } @@ -480,11 +463,11 @@ static inline uint64_t page_table_map_pages(page_table_t* table, void* virtAddr, } traverse.entry->raw = flags; - traverse.entry->addr = ((uintptr_t)PML_ENSURE_LOWER_HALF(pages[i])) >> PML_ADDR_OFFSET_BITS; + traverse.entry->pfn = pfns[i]; traverse.entry->lowCallbackId = callbackId & 1; traverse.entry->highCallbackId = callbackId >> 1; - virtAddr = (void*)((uintptr_t)virtAddr + PAGE_SIZE); + addr = (void*)((uintptr_t)addr + PAGE_SIZE); } return 0; @@ -500,16 +483,16 @@ static inline uint64_t page_table_map_pages(page_table_t* table, void* virtAddr, * free owned pages separately. * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param pageAmount The number of pages to unmap. + * @param addr The starting virtual address. + * @param amount The number of pages to unmap. */ -static inline void page_table_unmap(page_table_t* table, void* virtAddr, size_t pageAmount) +static inline void page_table_unmap(page_table_t* table, void* addr, size_t amount) { page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - if (page_table_traverse(table, &traverse, (uintptr_t)virtAddr + i * PAGE_SIZE, PML_NONE) == ERR) + if (page_table_traverse(table, &traverse, addr + i * PAGE_SIZE, PML_NONE) == ERR) { continue; } @@ -522,7 +505,7 @@ static inline void page_table_unmap(page_table_t* table, void* virtAddr, size_t traverse.entry->present = 0; } - tlb_invalidate(virtAddr, pageAmount); + tlb_invalidate(addr, amount); } /** @@ -531,8 +514,8 @@ static inline void page_table_unmap(page_table_t* table, void* virtAddr, size_t */ typedef struct { - void* pages[PML_PAGE_BUFFER_SIZE]; - uint64_t pageCount; + pfn_t pfns[PML_PAGE_BUFFER_SIZE]; + uint64_t amount; } page_table_page_buffer_t; /** @@ -546,13 +529,13 @@ typedef struct */ static inline void page_table_page_buffer_push(page_table_t* table, page_table_page_buffer_t* buffer, void* address) { - buffer->pages[buffer->pageCount] = address; - buffer->pageCount++; + buffer->pfns[buffer->amount] = VIRT_TO_PFN(address); + buffer->amount++; - if (buffer->pageCount >= PML_PAGE_BUFFER_SIZE) + if (buffer->amount >= PML_PAGE_BUFFER_SIZE) { - table->freePages(buffer->pages, buffer->pageCount); - buffer->pageCount = 0; + table->freePages(buffer->pfns, buffer->amount); + buffer->amount = 0; } } @@ -566,10 +549,10 @@ static inline void page_table_page_buffer_push(page_table_t* table, page_table_p */ static inline void page_table_page_buffer_flush(page_table_t* table, page_table_page_buffer_t* buffer) { - if (buffer->pageCount > 0) + if (buffer->amount > 0) { - table->freePages(buffer->pages, buffer->pageCount); - buffer->pageCount = 0; + table->freePages(buffer->pfns, buffer->amount); + buffer->amount = 0; } } @@ -614,22 +597,20 @@ static inline void page_table_clear_pml1_pml2_pml3(page_table_t* table, page_tab * All unskipped entries will be fully cleared (set to 0). * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param pageAmount The number of pages to clear. + * @param addr The starting virtual address. + * @param amount The number of pages to clear. */ -static inline void page_table_clear(page_table_t* table, void* virtAddr, size_t pageAmount) +static inline void page_table_clear(page_table_t* table, void* addr, size_t amount) { - page_table_page_buffer_t pageBuffer = {.pageCount = 0}; + page_table_page_buffer_t pageBuffer = {0}; page_table_traverse_t prevTraverse = PAGE_TABLE_TRAVERSE_CREATE; page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - uintptr_t currentVirtAddr = (uintptr_t)virtAddr + i * PAGE_SIZE; - page_table_clear_pml1_pml2_pml3(table, &prevTraverse, &traverse, &pageBuffer); - if (page_table_traverse(table, &traverse, currentVirtAddr, PML_NONE) == ERR) + if (page_table_traverse(table, &traverse, addr + i * PAGE_SIZE, PML_NONE) == ERR) { prevTraverse.pml1Valid = false; prevTraverse.pml2Valid = false; @@ -645,7 +626,7 @@ static inline void page_table_clear(page_table_t* table, void* virtAddr, size_t if (traverse.entry->owned) { - page_table_page_buffer_push(table, &pageBuffer, (void*)pml_accessible_addr(*traverse.entry)); + page_table_page_buffer_push(table, &pageBuffer, PFN_TO_VIRT(traverse.entry->pfn)); } traverse.entry->raw = 0; @@ -659,18 +640,17 @@ static inline void page_table_clear(page_table_t* table, void* virtAddr, size_t * @brief Collects the number of pages associated with each callback ID in the specified range. * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param pageAmount The number of pages to check. + * @param addr The starting virtual address. + * @param amount The number of pages to check. * @param callbacks An array of size `PML_MAX_CALLBACK` that will be filled with the occurrences of each callback ID. */ -static inline void page_table_collect_callbacks(page_table_t* table, void* virtAddr, size_t pageAmount, - uint64_t* callbacks) +static inline void page_table_collect_callbacks(page_table_t* table, void* addr, size_t amount, uint64_t* callbacks) { page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - if (page_table_traverse(table, &traverse, (uintptr_t)virtAddr + i * PAGE_SIZE, PML_NONE) == ERR) + if (page_table_traverse(table, &traverse, addr + i * PAGE_SIZE, PML_NONE) == ERR) { continue; } @@ -694,18 +674,18 @@ static inline void page_table_collect_callbacks(page_table_t* table, void* virtA * If a page is not currently mapped, it is skipped. * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param pageAmount The number of pages to update. + * @param addr The starting virtual address. + * @param amount The number of pages to update. * @param flags The new flags to set. The `PML_OWNED` flag is preserved. * @return On success, `0`. On failure, `ERR`. */ -static inline uint64_t page_table_set_flags(page_table_t* table, void* virtAddr, size_t pageAmount, pml_flags_t flags) +static inline uint64_t page_table_set_flags(page_table_t* table, void* addr, size_t amount, pml_flags_t flags) { page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - if (page_table_traverse(table, &traverse, (uintptr_t)virtAddr + i * PAGE_SIZE, PML_NONE) == ERR) + if (page_table_traverse(table, &traverse, addr + i * PAGE_SIZE, PML_NONE) == ERR) { continue; } @@ -724,7 +704,7 @@ static inline uint64_t page_table_set_flags(page_table_t* table, void* virtAddr, traverse.entry->raw = (traverse.entry->raw & ~PML_FLAGS_MASK) | (flags & PML_FLAGS_MASK); } - tlb_invalidate(virtAddr, pageAmount); + tlb_invalidate(addr, amount); return 0; } @@ -740,13 +720,13 @@ static inline uint64_t page_table_set_flags(page_table_t* table, void* virtAddr, * @param table The page table. * @param startAddr The start address to begin searching (inclusive). * @param endAddr The end address of the search range (exclusive). - * @param pageAmount The number of consecutive unmapped pages needed. + * @param amount The number of consecutive unmapped pages needed. * @param alignment The required alignment for the region in bytes. * @param outAddr Will be filled with the start address of the unmapped region if found. * @return On success, `0`. If no suitable region is found, `ERR`. */ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void* startAddr, void* endAddr, - size_t pageAmount, size_t alignment, void** outAddr) + size_t amount, size_t alignment, void** outAddr) { uintptr_t currentAddr = ROUND_DOWN((uintptr_t)startAddr, PAGE_SIZE); uintptr_t end = (uintptr_t)endAddr; @@ -756,7 +736,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void alignment = PAGE_SIZE; } - if (pageAmount >= (PML3_SIZE / PAGE_SIZE)) + if (amount >= (PML3_SIZE / PAGE_SIZE)) { while (currentAddr < end) { @@ -777,7 +757,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void continue; } - pml_t* pml3 = (pml_t*)pml_accessible_addr(*entry4); + pml_t* pml3 = PFN_TO_VIRT(entry4->pfn); pml_entry_t* entry3 = &pml3->entries[idx3]; if (!entry3->present) @@ -796,7 +776,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void return ERR; } - if (pageAmount >= (PML2_SIZE / PAGE_SIZE)) + if (amount >= (PML2_SIZE / PAGE_SIZE)) { while (currentAddr < end) { @@ -816,7 +796,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void continue; } - pml_t* pml3 = (pml_t*)pml_accessible_addr(*entry4); + pml_t* pml3 = PFN_TO_VIRT(entry4->pfn); pml_index_t idx3 = PML_ADDR_TO_INDEX(currentAddr, PML3); pml_entry_t* entry3 = &pml3->entries[idx3]; @@ -833,7 +813,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void continue; } - pml_t* pml2 = (pml_t*)pml_accessible_addr(*entry3); + pml_t* pml2 = PFN_TO_VIRT(entry3->pfn); pml_index_t idx2 = PML_ADDR_TO_INDEX(currentAddr, PML2); pml_entry_t* entry2 = &pml2->entries[idx2]; @@ -872,7 +852,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void uint64_t skippedPages = (MIN(skipTo, end) - currentAddr) / PAGE_SIZE; consecutiveUnmapped += skippedPages; - if (consecutiveUnmapped >= pageAmount) + if (consecutiveUnmapped >= amount) { *outAddr = (void*)regionStart; return 0; @@ -882,7 +862,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void continue; } - pml_t* pml3 = (pml_t*)pml_accessible_addr(*entry4); + pml_t* pml3 = PFN_TO_VIRT(entry4->pfn); pml_index_t idx3 = PML_ADDR_TO_INDEX(currentAddr, PML3); pml_entry_t* entry3 = &pml3->entries[idx3]; @@ -905,7 +885,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void consecutiveUnmapped += skippedPages; } - if (consecutiveUnmapped >= pageAmount) + if (consecutiveUnmapped >= amount) { *outAddr = (void*)regionStart; return 0; @@ -915,7 +895,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void continue; } - pml_t* pml2 = (pml_t*)pml_accessible_addr(*entry3); + pml_t* pml2 = PFN_TO_VIRT(entry3->pfn); pml_index_t idx2 = PML_ADDR_TO_INDEX(currentAddr, PML2); pml_entry_t* entry2 = &pml2->entries[idx2]; @@ -938,7 +918,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void consecutiveUnmapped += skippedPages; } - if (consecutiveUnmapped >= pageAmount) + if (consecutiveUnmapped >= amount) { *outAddr = (void*)regionStart; return 0; @@ -948,7 +928,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void continue; } - pml_t* pml1 = (pml_t*)pml_accessible_addr(*entry2); + pml_t* pml1 = PFN_TO_VIRT(entry2->pfn); pml_index_t idx1 = PML_ADDR_TO_INDEX(currentAddr, PML1); for (; idx1 < PML_INDEX_AMOUNT && currentAddr < end; idx1++, currentAddr += PAGE_SIZE) @@ -969,7 +949,7 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void consecutiveUnmapped++; } - if (consecutiveUnmapped >= pageAmount) + if (consecutiveUnmapped >= amount) { *outAddr = (void*)regionStart; return 0; @@ -989,16 +969,16 @@ static inline uint64_t page_table_find_unmapped_region(page_table_t* table, void * @brief Checks if any page in a range is pinned. * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param pageAmount The number of pages to check. + * @param addr The starting virtual address. + * @param amount The number of pages to check. * @return `true` if any page in the range us pinned, `false` otherwise. */ -static inline bool page_table_is_pinned(page_table_t* table, const void* virtAddr, size_t pageAmount) +static inline bool page_table_is_pinned(page_table_t* table, void* addr, size_t amount) { page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - if (page_table_traverse(table, &traverse, (uintptr_t)virtAddr + i * PAGE_SIZE, PML_NONE) == ERR) + if (page_table_traverse(table, &traverse, addr + i * PAGE_SIZE, PML_NONE) == ERR) { continue; } @@ -1024,57 +1004,56 @@ static inline bool page_table_is_pinned(page_table_t* table, const void* virtAdd * `PML_PRESENT | PML_USER | PML_OWNED` flags set. * * @param table The page table. - * @param virtAddr The starting virtual address. - * @param pageAmount The number of pages to check. + * @param addr The starting virtual address. + * @param amount The number of pages to check. * @param flags The flags to check for. * @return The number of pages with the specified flags set. */ -static inline uint64_t page_table_count_pages_with_flags(page_table_t* table, void* virtAddr, size_t pageAmount, +static inline uint64_t page_table_count_pages_with_flags(page_table_t* table, void* addr, size_t amount, pml_flags_t flags) { uint64_t count = 0; - while (pageAmount > 0) + while (amount > 0) { - pml_index_t idx4 = PML_ADDR_TO_INDEX((uintptr_t)virtAddr, PML4); + pml_index_t idx4 = PML_ADDR_TO_INDEX((uintptr_t)addr, PML4); pml_entry_t* entry4 = &table->pml4->entries[idx4]; if (!entry4->present) { - uint64_t skipPages = MIN(pageAmount, (PML_INDEX_TO_ADDR(idx4 + 1, PML4) - (uintptr_t)virtAddr) / PAGE_SIZE); - virtAddr = (void*)((uintptr_t)virtAddr + skipPages * PAGE_SIZE); - pageAmount -= skipPages; + uint64_t skipPages = MIN(amount, (PML_INDEX_TO_ADDR(idx4 + 1, PML4) - (uintptr_t)addr) / PAGE_SIZE); + addr = (void*)((uintptr_t)addr + skipPages * PAGE_SIZE); + amount -= skipPages; continue; } - pml_t* pml3 = (pml_t*)pml_accessible_addr(*entry4); - pml_index_t idx3 = PML_ADDR_TO_INDEX((uintptr_t)virtAddr, PML3); + pml_t* pml3 = PFN_TO_VIRT(entry4->pfn); + pml_index_t idx3 = PML_ADDR_TO_INDEX((uintptr_t)addr, PML3); pml_entry_t* entry3 = &pml3->entries[idx3]; if (!entry3->present) { - uint64_t skipPages = MIN(pageAmount, (PML_INDEX_TO_ADDR(idx3 + 1, PML3) - (uintptr_t)virtAddr) / PAGE_SIZE); - virtAddr = (void*)((uintptr_t)virtAddr + skipPages * PAGE_SIZE); - pageAmount -= skipPages; + uint64_t skipPages = MIN(amount, (PML_INDEX_TO_ADDR(idx3 + 1, PML3) - (uintptr_t)addr) / PAGE_SIZE); + addr = (void*)((uintptr_t)addr + skipPages * PAGE_SIZE); + amount -= skipPages; continue; } - pml_t* pml2 = (pml_t*)pml_accessible_addr(*entry3); - pml_index_t idx2 = PML_ADDR_TO_INDEX((uintptr_t)virtAddr, PML2); + pml_t* pml2 = PFN_TO_VIRT(entry3->pfn); + pml_index_t idx2 = PML_ADDR_TO_INDEX((uintptr_t)addr, PML2); pml_entry_t* entry2 = &pml2->entries[idx2]; if (!entry2->present) { - uint64_t skipPages = MIN(pageAmount, (PML_INDEX_TO_ADDR(idx2 + 1, PML2) - (uintptr_t)virtAddr) / PAGE_SIZE); - virtAddr = (void*)((uintptr_t)virtAddr + skipPages * PAGE_SIZE); - pageAmount -= skipPages; + uint64_t skipPages = MIN(amount, (PML_INDEX_TO_ADDR(idx2 + 1, PML2) - (uintptr_t)addr) / PAGE_SIZE); + addr = (void*)((uintptr_t)addr + skipPages * PAGE_SIZE); + amount -= skipPages; continue; } - pml_t* pml1 = (pml_t*)pml_accessible_addr(*entry2); - pml_index_t idx1 = PML_ADDR_TO_INDEX((uintptr_t)virtAddr, PML1); + pml_t* pml1 = PFN_TO_VIRT(entry2->pfn); + pml_index_t idx1 = PML_ADDR_TO_INDEX((uintptr_t)addr, PML1); - for (; idx1 < PML_INDEX_AMOUNT && pageAmount > 0; - idx1++, virtAddr = (void*)((uintptr_t)virtAddr + PAGE_SIZE), pageAmount--) + for (; idx1 < PML_INDEX_AMOUNT && amount > 0; idx1++, addr = (void*)((uintptr_t)addr + PAGE_SIZE), amount--) { pml_entry_t* entry1 = &pml1->entries[idx1]; if (!entry1->present) diff --git a/include/kernel/mem/paging_types.h b/include/kernel/mem/paging_types.h index 74205f767..10250d964 100644 --- a/include/kernel/mem/paging_types.h +++ b/include/kernel/mem/paging_types.h @@ -1,8 +1,8 @@ #pragma once -#include <_internal/size_t.h> #include #include +#include #include /** @@ -31,6 +31,61 @@ * @{ */ +/** + * @brief Page Frame Number type. + */ +typedef size_t pfn_t; + +/** + * @brief Physical address type. + */ +typedef uintptr_t phys_addr_t; + +/** + * @brief Invalid physical address. + */ +#define PHYS_ADDR_INVALID ((phys_addr_t)(UINTPTR_MAX)) + +/** + * @brief Convert a PFN to its physical address. + * + * @param _pfn The Page Frame Number. + * @return The physical address of the page. + */ +#define PFN_TO_PHYS(_pfn) ((phys_addr_t)(_pfn) * PAGE_SIZE) + +/** + * @brief Convert a physical address to its PFN. + * + * @param _addr The physical address. + * @return The Page Frame Number of the page. + */ +#define PHYS_TO_PFN(_addr) ((pfn_t)(_addr) / PAGE_SIZE) + +/** + * @brief Convert a PFN to its identity mapped higher half virtual address. + * + * @param _pfn The Page Frame Number. + * @return The higher half virtual address of the page. + */ +#ifndef _BOOT_ +#define PFN_TO_VIRT(_pfn) ((void*)PML_LOWER_TO_HIGHER((uintptr_t)(_pfn) * PAGE_SIZE)) +#else +#define PFN_TO_VIRT(_pfn) ((void*)PFN_TO_PHYS(_pfn)) +#endif + +/** + * @brief Convert a identity mapped higher half virtual address to its PFN. + * + * @param _addr The higher half virtual address. + * @return The Page Frame Number of the page. + */ +#ifndef _BOOT_ +#define VIRT_TO_PFN(_addr) ((pfn_t)(PML_HIGHER_TO_LOWER(_addr) / PAGE_SIZE)) +#else +#define VIRT_TO_PFN(_pfn) PHYS_TO_PFN(_pfn) +#endif + /** * @brief One entry in a page table. * @typedef pml_entry_t @@ -77,7 +132,7 @@ typedef struct * Check the virtual memory manager for more information. (Defined by PatchworkOS) */ uint64_t lowCallbackId : 1; - uint64_t addr : 40; ///< The address contained in the entry, note that this is shifted right by 12 bits. + pfn_t pfn : 40; ///< The physical frame number (physical address >> 12). /** * The high bits of the callback ID associated with this page. * @@ -272,7 +327,7 @@ typedef enum * @return The address in the lower half of the address space. */ #define PML_ENSURE_LOWER_HALF(addr) \ - ((uintptr_t)(addr) >= PML_HIGHER_HALF_START ? PML_HIGHER_TO_LOWER(addr) : (uintptr_t)(addr)) + ((phys_addr_t)(addr) >= PML_HIGHER_HALF_START ? PML_HIGHER_TO_LOWER(addr) : (phys_addr_t)(addr)) /** * @brief Ensures that the given address is in the higher half of the address space. @@ -353,14 +408,14 @@ typedef struct * * Used to allow both the kernel and bootloader to provide their own page allocation functions. */ -typedef uint64_t (*pml_alloc_pages_t)(void**, size_t); +typedef uint64_t (*pml_alloc_pages_t)(pfn_t*, size_t); /** * @brief Generic page free function type. * * Used to allow both the kernel and bootloader to provide their own page free functions. */ -typedef void (*pml_free_pages_t)(void**, size_t); +typedef void (*pml_free_pages_t)(pfn_t*, size_t); /** * @brief Size of the page buffer used to batch page allocations and frees. diff --git a/include/kernel/mem/pmm.h b/include/kernel/mem/pmm.h index 14e36902f..ab65d3a07 100644 --- a/include/kernel/mem/pmm.h +++ b/include/kernel/mem/pmm.h @@ -2,120 +2,174 @@ #include +#include + /** * @brief Physical Memory Manager (PMM). * @defgroup kernel_mem_pmm PMM * @ingroup kernel_mem * - * The Physical Memory Manager (PMM) is responsible for managing physical memory pages. It uses a free stack for - * allocating single pages in constant-time, and for more specialized allocations (requiring a specific address range - * or alignment) a bitmap allocator is used. The bitmap allocator should only be used when no other option is available. + * The Physical Memory Manager (PMM) is responsible for allocating and freeing physical memory pages. + * + * ## The Free Page Stack + * + * For most allocations, the PMM uses a fast `O(1)` stack-based allocator to manage free pages, with the limitation that + * only single pages can be allocated or freed at a time. + * + * ## The Bitmap Allocator * - * All physical memory is identity mapped to the beginning of the higher half of the address space. This means that for - * example `NULL` is always an invalid address and that the PMM returns addresses in the higher half. + * For larger, contiguous or aligned allocations, the PMM uses a bitmap allocator. This allocator is slower (`O(n)`) but + * is usefull for more specialized allocations. * - * The free stack provides some advantages over for instance a free list, mainly due to cache improvements. + * ## Reference Counting + * + * All allocations from the PMM are referenced counted, meaning that a page is only freed when its reference count + * reaches zero. This allows pages to be passed around between subsystems without fear of double frees or + * use-after-frees. + * + * @see kernel_mem_mem_desc * * @{ */ /** - * @brief Initializes the Physical Memory Manager. + * @brief Page metadata structure. + * @struct page_t + * + * Used internally by the PMM. + */ +typedef struct +{ + uint16_t ref; +} page_t; + +/** + * @brief Maximum number of free pages that can be stored in a free page. + */ +#define FREE_PAGE_MAX (PAGE_SIZE / sizeof(pfn_t) - 1) + +/** + * @brief Stored in free pages to form a stack of free pages. + * @struct page_stack_t + */ +typedef struct page_stack +{ + struct page_stack* next; + pfn_t pages[FREE_PAGE_MAX]; +} page_stack_t; + +static_assert(sizeof(page_stack_t) == PAGE_SIZE, "page_stack_t must be exactly one page in size"); + +/** + * @brief Read the boot info memory map and initialize the PMM. */ void pmm_init(void); /** - * @brief Allocates a single physical page. + * @brief Allocate a single page of physical memory. * - * The returned page will not be zeroed. + * Will by default use the free stack allocator, but if no pages are available there, it will fall back to the bitmap + * allocator. * - * @return On success, returns the higher half physical address of the allocated page. On failure, returns `NULL`. + * @return On success, the PFN of the allocated page. On failure, `ERR`. */ -void* pmm_alloc(void); +pfn_t pmm_alloc(void); /** - * @brief Allocates multiple physical pages. + * @brief Allocate multiple pages of physical memory. * - * The `pmm_alloc_pages` function allocates `count` non-contiguous physical pages from the free stack, by using this - * function its possible to avoid holding the lock for each page allocation, improving performance when allocating many - * pages at once. + * Usefull for reducing overhead from locking when allocating many pages. * - * The returned pages will not be zeroed. - * - * @param addresses An array where the higher half physical addresses of the allocated pages will be stored. - * @param count The number of pages to allocate. - * @return On success, `0`. On failure, `ERR` and `errno` is set. + * @param pfns Array to store the allocated page PFNs. + * @param count Number of pages to allocate. + * @return On success, `0`. On failure, `ERR` and no pages are allocated. */ -uint64_t pmm_alloc_pages(void** addresses, size_t count); +uint64_t pmm_alloc_pages(pfn_t* pfns, size_t count); /** - * @brief Allocates a contiguous region of physical pages managed by the bitmap. + * @brief Allocate a contiguous region of physical memory using the bitmap. * - * The `pmm_alloc_bitmap` function allocates a contiguous block of `count` physical pages from the memory region - * managed by the bitmap. It also enforces a maximum address and alignment for the allocation. + * @param count Number of pages to allocate. + * @param maxPfn Maximum PFN to allocate up to (exclusive). + * @param alignPfn Alignment of the region in pages. + * @return On success, the PFN of the first page of the allocated region. On failure, `ERR`. + */ +pfn_t pmm_alloc_bitmap(size_t count, pfn_t maxPfn, pfn_t alignPfn); + +/** + * @brief Free a single page of physical memory. * - * The returned pages will not be zeroed. + * The page will only be reclaimed if its reference count reaches zero. * - * @param count The number of contiguous pages to allocate. - * @param maxAddr The maximum physical address (exclusive) for the allocation. - * @param alignment The required alignment for the allocated region, in bytes. - * @return On success, returns the higher half physical address of the allocated region. On failure, returns `NULL`. + * @param pfn The PFN of the page to free. */ -void* pmm_alloc_bitmap(size_t count, uintptr_t maxAddr, uint64_t alignment); +void pmm_free(pfn_t pfn); /** - * @brief Frees a single physical page. + * @brief Free multiple pages of physical memory. + * + * Useful for reducing overhead from locking when freeing many pages. * - * The `pmm_free` function frees a page returning ownership of it to the PMM. The PMM will determine based on the - * address if it's owned by the bitmap or the free stack. + * The pages will only be reclaimed if its reference count reaches zero. * - * @param address The higher half physical address of the page to free. + * @param pfns Array of PFNs to free. + * @param count Number of pages to free. */ -void pmm_free(void* address); +void pmm_free_pages(pfn_t* pfns, size_t count); /** - * @brief Frees multiple physical pages. + * @brief Free a contiguous region of physical memory. * - * The `pmm_free_pages` function frees `count` physical pages returning ownership of them to the PMM. The PMM will - * determine based on the addresses if they're owned by the bitmap or the free stack. + * The pages will only be reclaimed if its reference count reaches zero. * - * @param addresses An array containing the higher half physical addresses of the pages to free. - * @param count The number of pages to free. + * @param pfn The PFN of the first page of the region to free. + * @param count Number of pages to free. */ -void pmm_free_pages(void** addresses, size_t count); +void pmm_free_region(pfn_t pfn, size_t count); /** - * @brief Frees a contiguous region of physical pages. + * @brief Increment the reference count of a physical region. * - * The `pmm_free_region` function frees a contiguous block of `count` physical pages, returning ownership of them to the - * PMM. The PMM will determine based on the address if it's owned by the bitmap or the free stack. + * Will fail if any of the pages are not allocated. * - * @param address The higher half physical address of the first page in the region to free. - * @param count The number of pages to free. + * @param pfn The PFN of the first physical page. + * @param count Number of pages to increment the reference count of. + * @return On success, the new reference count. On failure, `ERR`. */ -void pmm_free_region(void* address, size_t count); +uint64_t pmm_ref_inc(pfn_t pfn, size_t count); /** - * @brief Retrieves the total amount of physical memory managed by the PMM. + * @brief Decrement the reference count of a physical region. + * + * If the reference count reaches zero, the pages will be freed. * - * @return The total amount of physical memory in pages. + * @param pfn The PFN of the first physical page. + * @param count Number of pages to decrement the reference count of. */ -size_t pmm_total_amount(void); +static inline void pmm_ref_dec(pfn_t pfn, size_t count) +{ + pmm_free_region(pfn, count); +} /** - * @brief Retrieves the amount of free physical memory. + * @brief Get the total number of physical pages. * - * @return The amount of currently free physical memory in pages. + * @return Total number of physical pages. */ -size_t pmm_free_amount(void); +size_t pmm_total_pages(void); /** - * @brief Retrieves the amount of reserved physical memory. + * @brief Get the number of available physical pages. * - * Reserved memory includes memory that is not available for allocation (e.g., kernel code, hardware regions). + * @return Number of available physical pages. + */ +size_t pmm_avail_pages(void); + +/** + * @brief Get the number of used physical pages. * - * @return The amount of reserved physical memory in pages. + * @return Number of used physical pages. */ -size_t pmm_used_amount(void); +size_t pmm_used_pages(void); /** @} */ diff --git a/include/kernel/mem/pmm_bitmap.h b/include/kernel/mem/pmm_bitmap.h deleted file mode 100644 index 4f1fd8308..000000000 --- a/include/kernel/mem/pmm_bitmap.h +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include -#include - -/** - * @brief A generic bitmap page allocator. - * @defgroup kernel_mem_pmm_bitmap PMM Bitmap - * @ingroup kernel_mem - * - * The PMM bitmap provides a flexible allocator for more specific allocations, for example it can handle contiguous - * pages, specific alignments and allocating below some specified address. This flexibility comes at the cost of - * performance, so the bitmap should only be used when necessary. - * - * @{ - */ - -/** - * @brief Represents a bitmap allocator's state. - */ -typedef struct -{ - /** - * @brief The underlying bitmap used for tracking page status. - */ - bitmap_t bitmap; - /** - * @brief The number of free pages in the bitmap. - */ - uint64_t free; - /** - * @brief The total number of pages managed by the bitmap. - */ - uint64_t total; - /** - * @brief The maximum address managed by the bitmap. - */ - uintptr_t maxAddr; -} pmm_bitmap_t; - -/** - * @brief Initializes a PMM bitmap. - * - * @param bitmap The bitmap to initialize. - * @param buffer The buffer to use for the bitmap data. - * @param size The number of pages to manage. - * @param maxAddr The maximum address to manage. - */ -void pmm_bitmap_init(pmm_bitmap_t* bitmap, void* buffer, uint64_t size, uintptr_t maxAddr); - -/** - * @brief Allocates a contiguous region of pages from the bitmap. - * - * @param bitmap The bitmap to allocate from. - * @param count The number of pages to allocate. - * @param maxAddr The maximum address for the allocation. - * @param alignment The required alignment for the allocation. - * @return On success, a pointer to the allocated region. On failure `NULL` and errno is set. - */ -void* pmm_bitmap_alloc(pmm_bitmap_t* bitmap, uint64_t count, uintptr_t maxAddr, uint64_t alignment); - -/** - * @brief Frees a region of pages, returning them to the bitmap. - * - * @param bitmap The bitmap to free to. - * @param address The address of the region to free. - * @param count The number of pages to free. - */ -void pmm_bitmap_free(pmm_bitmap_t* bitmap, void* address, uint64_t count); - -/** @} */ diff --git a/include/kernel/mem/pmm_stack.h b/include/kernel/mem/pmm_stack.h deleted file mode 100644 index f6c371226..000000000 --- a/include/kernel/mem/pmm_stack.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -/** - * @brief A generic free stack page allocator. - * @defgroup kernel_mem_pmm_stack PMM Stack - * @ingroup kernel_mem - * - * The PMM stack provides a fast, O(1) allocator for single pages. It uses freed pages to store metadata about other - * free pages, forming a stack of page buffers. - * - * @{ - */ - -/** - * @brief Structure for a page buffer in the PMM stack. - * - * The `page_buffer_t` structure is stored in free pages and keeps track of pages that are currently freed. - */ -typedef struct page_buffer -{ - /** - * @brief Pointer to the previous page buffer in the stack. - */ - struct page_buffer* prev; - /** - * @brief Flexible array member to store free physical pages. - */ - void* pages[]; -} page_buffer_t; - -/** - * @brief The maximum number of pages that can be stored in a `page_buffer_t`. - */ -#define PMM_BUFFER_MAX ((PAGE_SIZE - sizeof(page_buffer_t)) / sizeof(void*)) - -/** - * @brief PMM stack structure for managing higher physical memory. - */ -typedef struct -{ - /** - * @brief Pointer to the last page buffer in the stack. - */ - page_buffer_t* last; - /** - * @brief Current index within the `pages` array of the `last` page buffer. - */ - uint64_t index; - /** - * @brief The number of free pages in the stack. - */ - uint64_t free; -} pmm_stack_t; - -/** - * @brief Initializes a PMM stack. - * - * @param stack The stack to initialize. - */ -void pmm_stack_init(pmm_stack_t* stack); - -/** - * @brief Allocates a single page from the stack. - * - * @param stack The stack to allocate from. - * @return On success, a pointer to the allocated page. On failure `NULL` and errno is set. - */ -void* pmm_stack_alloc(pmm_stack_t* stack); - -/** - * @brief Frees a single page, returning it to the stack. - * - * @param stack The stack to free to. - * @param address The address of the page to free. - */ -void pmm_stack_free(pmm_stack_t* stack, void* address); - -/** @} */ diff --git a/include/kernel/mem/pool.h b/include/kernel/mem/pool.h new file mode 100644 index 000000000..ac2be2323 --- /dev/null +++ b/include/kernel/mem/pool.h @@ -0,0 +1,74 @@ +#pragma once + +#include +#include +#include + +#include + +/** + * @brief Lock-free memory pool. + * @defgroup kernel_mem_pool Pool + * @ingroup kernel_mem + * + * The memory pool system provides a lock-free allocator using a pre-allocated array. Its intended to be used for + * performance-critical structures and as a even more specialized alternative to the Object Cache. + * + * In addition to its performance advantages, since the pool uses an array to store its objects, it is possible for + * certain structures to avoid storing full pointers to objects allocated from a pool instead using a `pool_idx_t` thus + * saving memory or allowing better caching. + * + * @{ + */ + +/** + * @brief Pool index type. + */ +typedef uint16_t pool_idx_t; + +#define POOL_IDX_MAX UINT16_MAX ///< The maximum index value for pool. + +#define POOL_TAG_INC ((uint64_t)(POOL_IDX_MAX) + 1) ///< The amount to increment the tag by in the tagged free list. + +/** + * @brief Pool structure. + * @struct pool_t + */ +typedef struct +{ + atomic_size_t used; ///< Number of used elements. + atomic_uint64_t free; ///< The tagged head of the free list. + void* elements; ///< Pointer to the elements array. + size_t elementSize; ///< Size of each element. + size_t nextOffset; ///< Offset of a `pool_idx_t` variable within each element used for the free list. + size_t capacity; ///< Maximum number of elements. +} pool_t; + +/** + * @brief Initialize a pool. + * + * @param pool Pointer to the pool structure to initialize. + * @param elements Pointer to the elements array. + * @param capacity Maximum number of elements. + * @param elementSize Size of each element. + * @param nextOffset Offset of a `pool_idx_t` variable within each element used for the free list. + */ +void pool_init(pool_t* pool, void* elements, size_t capacity, size_t elementSize, size_t nextOffset); + +/** + * @brief Allocate an element from the pool. + * + * @param pool Pointer to the pool to allocate from. + * @return The index of the allocated element, or `POOL_IDX_MAX` if the pool is full. + */ +pool_idx_t pool_alloc(pool_t* pool); + +/** + * @brief Free an element back to the pool. + * + * @param pool Pointer to the pool to free to. + * @param idx The index of the element to free. + */ +void pool_free(pool_t* pool, pool_idx_t idx); + +/** @} */ \ No newline at end of file diff --git a/include/kernel/mem/space.h b/include/kernel/mem/space.h index b6780e5b0..467864169 100644 --- a/include/kernel/mem/space.h +++ b/include/kernel/mem/space.h @@ -39,7 +39,7 @@ typedef enum /** * @brief Space callback function. */ -typedef void (*space_callback_func_t)( void* data); +typedef void (*space_callback_func_t)(void* data); /** * @brief Space callback structure. @@ -214,7 +214,7 @@ uint64_t space_check_access(space_t* space, const void* addr, size_t length); typedef struct { void* virtAddr; - void* physAddr; + phys_addr_t physAddr; size_t pageAmount; pml_flags_t flags; } space_mapping_t; @@ -234,7 +234,7 @@ typedef struct * @param space The target address space. * @param mapping Will be filled with parsed information about the mapping. * @param virtAddr The virtual address the mapping will apply to. Can be `NULL` to let the kernel choose an address. - * @param physAddr The physical address to map from. Can be `NULL`. + * @param physAddr The physical address to map from. Can be `PHYS_ADDR_INVALID`. * @param length The length of the virtual memory region to modify, in bytes. * @param alignment The required alignment for the virtual memory region in bytes. * @param flags The page table flags for the mapping. @@ -244,8 +244,8 @@ typedef struct * - `EFAULT`: The addresses are outside the allowed range. * - `ENOMEM`: Not enough memory. */ -uint64_t space_mapping_start(space_t* space, space_mapping_t* mapping, void* virtAddr, void* physAddr, size_t length, - size_t alignment, pml_flags_t flags); +uint64_t space_mapping_start(space_t* space, space_mapping_t* mapping, void* virtAddr, phys_addr_t physAddr, + size_t length, size_t alignment, pml_flags_t flags); /** * @brief Allocate a callback. @@ -261,7 +261,7 @@ uint64_t space_mapping_start(space_t* space, space_mapping_t* mapping, void* vir * @param private Private data to pass to the callback function. * @return On success, returns the callback ID. On failure, returns `PML_MAX_CALLBACK`. */ -pml_callback_id_t space_alloc_callback(space_t* space, size_t pageAmount, space_callback_func_t func, void* data); +pml_callback_id_t space_alloc_callback(space_t* space, size_t pageAmount, space_callback_func_t func, void* data); /** * @brief Free a callback. @@ -308,4 +308,15 @@ bool space_is_mapped(space_t* space, const void* virtAddr, size_t length); */ uint64_t space_user_page_count(space_t* space); +/** + * @brief Translate a virtual address to a physical address in the address space. + * + * @param space The target address space. + * @param virtAddr The virtual address to translate. + * @return On success, `0`. On failure, `ERR` and `errno` is set to: + * - `EINVAL`: Invalid parameters. + * - `EFAULT`: The virtual address is not mapped. + */ +phys_addr_t space_virt_to_phys(space_t* space, const void* virtAddr); + /** @} */ diff --git a/include/kernel/mem/vmm.h b/include/kernel/mem/vmm.h index 474993a13..02d3cc577 100644 --- a/include/kernel/mem/vmm.h +++ b/include/kernel/mem/vmm.h @@ -44,7 +44,7 @@ * at `VMM_KERNEL_HEAP_MIN` and grows up towards `VMM_KERNEL_HEAP_MAX`. This section takes up 2 indices in the * page table and is mapped identically for all processes. * - * Fourthly (is fourthly really a word?), we have the identity mapped physical memory. All physical memory will be + * Fourthly, we have the identity mapped physical memory. All physical memory will be * mapped here by simply taking the original physical address and adding `0xFFFF800000000000` to it. This means that the * physical address `0x123456` will be mapped to the virtual address `0xFFFF800000123456`. This section takes up all * remaining indices below the kernel heap to the end of the higher half and is mapped identically for all processes. @@ -119,8 +119,9 @@ typedef struct */ typedef enum { - VMM_ALLOC_OVERWRITE = 0 << 0, ///< If any page is already mapped, overwrite the mapping. - VMM_ALLOC_FAIL_IF_MAPPED = 1 << 0 ///< If set and any page is already mapped, fail and set `errno` to `EEXIST`. + VMM_ALLOC_OVERWRITE = 0 << 0, ///< If any page is already mapped, overwrite the mapping. + VMM_ALLOC_FAIL_IF_MAPPED = 1 << 0, ///< If set and any page is already mapped, fail and set `errno` to `EEXIST`. + VMM_ALLOC_ZERO = 1 << 1 ///< If set, atomically zero the allocated pages. } vmm_alloc_flags_t; /** @@ -181,7 +182,7 @@ void* vmm_alloc(space_t* space, void* virtAddr, size_t length, size_t alignment, * * @param space The target address space, if `NULL`, the kernel space is used. * @param virtAddr The desired virtual address to map to, if `NULL`, the kernel chooses an available address. - * @param physAddr The physical address to map from. Must not be `NULL`. + * @param physAddr The physical address to map from. Must not be `PHYS_ADDR_INVALID`. * @param length The length of the memory region to map, in bytes. * @param flags The page table flags for the mapping, must have `PML_PRESENT` set. * @param func The callback function to call when the mapped memory is unmapped or the address space is freed. If @@ -194,8 +195,8 @@ void* vmm_alloc(space_t* space, void* virtAddr, size_t length, size_t alignment, * - `ENOMEM`: Not enough memory. * - Other values from `space_mapping_start()`. */ -void* vmm_map(space_t* space, void* virtAddr, void* physAddr, size_t length, pml_flags_t flags, - space_callback_func_t func, void* data); +void* vmm_map(space_t* space, void* virtAddr, phys_addr_t physAddr, size_t length, pml_flags_t flags, + space_callback_func_t func, void* data); /** * @brief Maps an array of physical pages to virtual memory in a given address space. @@ -206,8 +207,8 @@ void* vmm_map(space_t* space, void* virtAddr, void* physAddr, size_t length, pml * * @param space The target address space, if `NULL`, the kernel space is used. * @param virtAddr The desired virtual address to map to, if `NULL`, the kernel chooses an available address. - * @param pages An array of physical page addresses to map. - * @param pageAmount The number of physical pages in the `pages` array, must not be zero. + * @param pfns An array of page frame numbers to map from. + * @param amount The number of pages to map. * @param flags The page table flags for the mapping, must have `PML_PRESENT` set. * @param func The callback function to call when the mapped memory is unmapped or the address space is freed. If * `NULL`, then no callback will be called. @@ -219,8 +220,8 @@ void* vmm_map(space_t* space, void* virtAddr, void* physAddr, size_t length, pml * - `ENOMEM`: Not enough memory. * - Other values from `space_mapping_start()`. */ -void* vmm_map_pages(space_t* space, void* virtAddr, void** pages, size_t pageAmount, pml_flags_t flags, - space_callback_func_t func, void* data); +void* vmm_map_pages(space_t* space, void* virtAddr, pfn_t* pfns, size_t amount, pml_flags_t flags, + space_callback_func_t func, void* data); /** * @brief Unmaps virtual memory from a given address space. diff --git a/include/modules/linker.lds b/include/kernel/module.lds similarity index 100% rename from include/modules/linker.lds rename to include/kernel/module.lds diff --git a/include/kernel/module/module.h b/include/kernel/module/module.h index f3664ff28..5e8eaabcd 100644 --- a/include/kernel/module/module.h +++ b/include/kernel/module/module.h @@ -1,16 +1,16 @@ #pragma once -#include <_internal/MAX_PATH.h> +#include <_libstd/MAX_PATH.h> #include #include #include #include #include #include -#include +#include #include -#include +#include #include typedef struct module module_t; diff --git a/include/kernel/proc/process.h b/include/kernel/proc/process.h index 3c093d4d0..aaaf8fab0 100644 --- a/include/kernel/proc/process.h +++ b/include/kernel/proc/process.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,7 @@ /** * @brief Process management. - * @defgroup kernel_proc Process + * @defgroup kernel_proc Process Subsystem * @ingroup kernel * * Processes store the shared resources for threads of execution, for example the address space and open files. @@ -87,6 +88,7 @@ typedef struct process file_table_t fileTable; futex_ctx_t futexCtx; perf_process_ctx_t perf; + ioring_ctx_t rings[CONFIG_MAX_RINGS]; note_handler_t noteHandler; wait_queue_t suspendQueue; wait_queue_t dyingQueue; diff --git a/include/kernel/sched/timer.h b/include/kernel/sched/timer.h index a5bab73f1..7944a8dd9 100644 --- a/include/kernel/sched/timer.h +++ b/include/kernel/sched/timer.h @@ -113,10 +113,10 @@ uint64_t timer_source_amount(void); * @note Will never set the timeout to be less than `CONFIG_MIN_TIMER_TIMEOUT` to avoid spamming the CPU with timer * interrupts. * - * @param uptime The time since boot, we need to specify this as an argument to avoid inconsistency in the + * @param now The time since boot, we need to specify this as an argument to avoid inconsistency in the * timeout/deadline calculations. * @param deadline The desired deadline. */ -void timer_set(clock_t uptime, clock_t deadline); +void timer_set(clock_t now, clock_t deadline); /** @} */ diff --git a/include/kernel/sched/wait.h b/include/kernel/sched/wait.h index 75afdb51d..3d9f4f9aa 100644 --- a/include/kernel/sched/wait.h +++ b/include/kernel/sched/wait.h @@ -32,7 +32,7 @@ typedef struct wait wait_t; * @note Generally its preferred to use the `WAIT_BLOCK*` macros instead of directly calling the functions provided by * this subsystem. * - * @todo Replace with `epoll()` style system? + * @todo Replace with a more optimized system for async stuff. * * @{ */ diff --git a/include/kernel/sync/rcu.h b/include/kernel/sync/rcu.h index b5d5c71a2..126045b60 100644 --- a/include/kernel/sync/rcu.h +++ b/include/kernel/sync/rcu.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -40,10 +40,11 @@ typedef struct rcu_entry rcu_entry_t; * `rcu_entry_t` member and a callback function that will free the structure. * * To access RCU protected data, a read-side critical section must be created using `rcu_read_lock()` and - * `rcu_read_unlock()`, or the `RCU_READ_SCOPE()` macro. + * `rcu_read_unlock()`, or the `RCU_READ_SCOPE()` macro. * * @see [Wikipedia](https://en.wikipedia.org/wiki/Read-copy-update) for more information about RCU. - * @see [kernel.org](https://www.kernel.org/doc/Documentation/RCU/whatisRCU.txt) for a explanation of RCU in the Linux kernel. + * @see [kernel.org](https://www.kernel.org/doc/Documentation/RCU/whatisRCU.txt) for a explanation of RCU in the Linux + * kernel. * * @{ */ diff --git a/include/kernel/sync/sync.h b/include/kernel/sync/sync.h index a4be76aae..10647f6b6 100644 --- a/include/kernel/sync/sync.h +++ b/include/kernel/sync/sync.h @@ -1,6 +1,6 @@ /** * @brief Locks and concurrency primitives. - * @defgroup kernel_sync Synchronization + * @defgroup kernel_sync Syncronization Primitives * @ingroup kernel */ \ No newline at end of file diff --git a/include/kernel/utils/fifo.h b/include/kernel/utils/fifo.h index 40823146a..014ce2ab0 100644 --- a/include/kernel/utils/fifo.h +++ b/include/kernel/utils/fifo.h @@ -51,14 +51,24 @@ typedef struct fifo * @param buffer Pointer to the buffer memory. * @param size The size of the buffer in bytes. */ -void fifo_init(fifo_t* fifo, uint8_t* buffer, size_t size); +static inline void fifo_init(fifo_t* fifo, uint8_t* buffer, size_t size) +{ + fifo->buffer = buffer; + fifo->size = size; + fifo->head = 0; + fifo->tail = 0; +} /** * @brief Reset a fifo buffer. * * @param fifo Pointer to the fifo buffer structure. */ -void fifo_reset(fifo_t* fifo); +static inline void fifo_reset(fifo_t* fifo) +{ + fifo->head = 0; + fifo->tail = 0; +} /** * @brief Return the number of bytes available for reading in a fifo buffer. @@ -66,7 +76,15 @@ void fifo_reset(fifo_t* fifo); * @param fifo Pointer to the fifo buffer structure. * @return The number of bytes used. */ -size_t fifo_bytes_readable(const fifo_t* fifo); +static inline size_t fifo_bytes_readable(const fifo_t* fifo) +{ + if (fifo->head >= fifo->tail) + { + return fifo->head - fifo->tail; + } + + return fifo->size - (fifo->tail - fifo->head); +} /** * @brief Return the number of bytes available for writing in a fifo buffer. @@ -74,7 +92,15 @@ size_t fifo_bytes_readable(const fifo_t* fifo); * @param fifo Pointer to the fifo buffer structure. * @return The number of bytes available for writing. */ -size_t fifo_bytes_writeable(const fifo_t* fifo); +static inline size_t fifo_bytes_writeable(const fifo_t* fifo) +{ + if (fifo->tail > fifo->head) + { + return fifo->tail - fifo->head - 1; + } + + return fifo->size - (fifo->head - fifo->tail) - 1; +} /** * @brief Read data from a fifo buffer at a specific offset. @@ -84,7 +110,37 @@ size_t fifo_bytes_writeable(const fifo_t* fifo); * @param count The number of bytes to read. * @return The number of bytes read. */ -size_t fifo_read(fifo_t* fifo, void* buffer, size_t count); +static inline size_t fifo_read(fifo_t* fifo, void* buffer, size_t count) +{ + size_t readable = fifo_bytes_readable(fifo); + if (readable == 0) + { + return 0; + } + + if (count > readable) + { + count = readable; + } + + size_t firstSize = fifo->size - fifo->tail; + if (firstSize > count) + { + firstSize = count; + } + + memcpy(buffer, fifo->buffer + fifo->tail, firstSize); + fifo->tail = (fifo->tail + firstSize) % fifo->size; + + size_t remaining = count - firstSize; + if (remaining > 0) + { + memcpy((uint8_t*)buffer + firstSize, fifo->buffer + fifo->tail, remaining); + fifo->tail = (fifo->tail + remaining) % fifo->size; + } + + return count; +} /** * @brief Write data to the fifo buffer. @@ -96,7 +152,32 @@ size_t fifo_read(fifo_t* fifo, void* buffer, size_t count); * @param count The number of bytes to write. * @return The number of bytes written. */ -size_t fifo_write(fifo_t* fifo, const void* buffer, size_t count); +static inline size_t fifo_write(fifo_t* fifo, const void* buffer, size_t count) +{ + size_t writeable = fifo_bytes_writeable(fifo); + if (count > writeable) + { + count = writeable; + } + + size_t firstSize = fifo->size - fifo->head; + if (firstSize > count) + { + firstSize = count; + } + + memcpy(fifo->buffer + fifo->head, buffer, firstSize); + fifo->head = (fifo->head + firstSize) % fifo->size; + + size_t remaining = count - firstSize; + if (remaining > 0) + { + memcpy(fifo->buffer + fifo->head, (uint8_t*)buffer + firstSize, remaining); + fifo->head = (fifo->head + remaining) % fifo->size; + } + + return count; +} /** * @brief Advance the head of the fifo buffer. @@ -104,7 +185,10 @@ size_t fifo_write(fifo_t* fifo, const void* buffer, size_t count); * @param fifo Pointer to the fifo buffer structure. * @param count The number of bytes to advance the head by. */ -void fifo_advance_head(fifo_t* fifo, size_t count); +static inline void fifo_advance_head(fifo_t* fifo, size_t count) +{ + fifo->head = (fifo->head + count) % fifo->size; +} /** * @brief Advance the tail of the fifo buffer. @@ -112,6 +196,9 @@ void fifo_advance_head(fifo_t* fifo, size_t count); * @param fifo Pointer to the fifo buffer structure. * @param count The number of bytes to advance the tail by. */ -void fifo_advance_tail(fifo_t* fifo, size_t count); +static inline void fifo_advance_tail(fifo_t* fifo, size_t count) +{ + fifo->tail = (fifo->tail + count) % fifo->size; +} /** @} */ diff --git a/include/kernel/utils/map.h b/include/kernel/utils/map.h index 255c9ce90..180d8a8b9 100644 --- a/include/kernel/utils/map.h +++ b/include/kernel/utils/map.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include typedef struct map_key map_key_t; typedef struct map_entry map_entry_t; diff --git a/include/libstd/libstd.h b/include/libstd.h similarity index 100% rename from include/libstd/libstd.h rename to include/libstd.h diff --git a/include/libstd/_internal/fd_t.h b/include/libstd/_internal/fd_t.h deleted file mode 100644 index 267f18fea..000000000 --- a/include/libstd/_internal/fd_t.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _INTERNAL_FD_T_H -#define _INTERNAL_FD_T_H 1 - -/** - * @brief A file descriptor. - * @ingroup libstd - * - * The `fd_t` type represents a file descriptor, which is a index into the processes files table. We also define the - * special value `FD_NONE` which is equal to `UINT64_MAX` to represent no file descriptor. - * - */ -typedef __UINT64_TYPE__ fd_t; - -/** - * @brief No file descriptor constant. - * @ingroup libstd - * @def FD_NONE - * - * The `FD_NONE` value represents no file descriptor. - * - */ -#define FD_NONE __UINT64_MAX__ - -#endif diff --git a/include/libstd/limits.h b/include/limits.h similarity index 96% rename from include/libstd/limits.h rename to include/limits.h index c2bf5be61..2a9bc4f35 100644 --- a/include/libstd/limits.h +++ b/include/limits.h @@ -6,7 +6,7 @@ extern "C" { #endif -#include "_internal/config.h" +#include "_libstd/config.h" /* TODO: Defined to 1 as multibyte characters are not supported yet. */ #define MB_LEN_MAX 1 diff --git a/include/libstd/locale.h b/include/locale.h similarity index 98% rename from include/libstd/locale.h rename to include/locale.h index 370284302..ed5708926 100644 --- a/include/libstd/locale.h +++ b/include/locale.h @@ -6,7 +6,7 @@ extern "C" { #endif -#include "_internal/config.h" +#include "_libstd/config.h" struct lconv { diff --git a/include/libstd/math.h b/include/math.h similarity index 99% rename from include/libstd/math.h rename to include/math.h index a4230edc1..caea9defd 100644 --- a/include/libstd/math.h +++ b/include/math.h @@ -6,7 +6,7 @@ extern "C" { #endif -#include "_internal/config.h" +#include "_libstd/config.h" #define M_PI 3.14159265358979323846 #define M_PI_2 1.57079632679489661923 diff --git a/include/libpatchwork/cmd.h b/include/patchwork/cmd.h similarity index 99% rename from include/libpatchwork/cmd.h rename to include/patchwork/cmd.h index d41b604e9..f0344180b 100644 --- a/include/libpatchwork/cmd.h +++ b/include/patchwork/cmd.h @@ -8,7 +8,7 @@ #include "surface.h" #include -#include +#include #include #if defined(__cplusplus) diff --git a/include/libpatchwork/config.h b/include/patchwork/config.h similarity index 100% rename from include/libpatchwork/config.h rename to include/patchwork/config.h diff --git a/include/libpatchwork/display.h b/include/patchwork/display.h similarity index 100% rename from include/libpatchwork/display.h rename to include/patchwork/display.h diff --git a/include/libpatchwork/drawable.h b/include/patchwork/drawable.h similarity index 100% rename from include/libpatchwork/drawable.h rename to include/patchwork/drawable.h diff --git a/include/libpatchwork/element.h b/include/patchwork/element.h similarity index 99% rename from include/libpatchwork/element.h rename to include/patchwork/element.h index 9eea29d9c..ba6af8fe0 100644 --- a/include/libpatchwork/element.h +++ b/include/patchwork/element.h @@ -98,7 +98,7 @@ typedef struct * @return On success, a pointer to the new element. On failure, `NULL` and `errno` is set. */ element_t* element_new(element_t* parent, element_id_t id, const rect_t* rect, const char* text, element_flags_t flags, - procedure_t procedure, void* data); + procedure_t procedure, void* data); /** * @brief Deinitialize and free an element and all its children. @@ -126,7 +126,7 @@ element_t* element_find(element_t* elem, element_id_t id); * @param elem The element. * @param private Pointer to the private data. */ -void element_set_private(element_t* elem, void* data); +void element_set_private(element_t* elem, void* data); /** * @brief Get private data for an element. diff --git a/include/libpatchwork/element_id.h b/include/patchwork/element_id.h similarity index 100% rename from include/libpatchwork/element_id.h rename to include/patchwork/element_id.h diff --git a/include/libpatchwork/event.h b/include/patchwork/event.h similarity index 99% rename from include/libpatchwork/event.h rename to include/patchwork/event.h index 650adb249..49af016b1 100644 --- a/include/libpatchwork/event.h +++ b/include/patchwork/event.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include #if defined(__cplusplus) diff --git a/include/libpatchwork/font.h b/include/patchwork/font.h similarity index 100% rename from include/libpatchwork/font.h rename to include/patchwork/font.h diff --git a/include/libpatchwork/image.h b/include/patchwork/image.h similarity index 100% rename from include/libpatchwork/image.h rename to include/patchwork/image.h diff --git a/include/libpatchwork/patchwork.h b/include/patchwork/patchwork.h similarity index 100% rename from include/libpatchwork/patchwork.h rename to include/patchwork/patchwork.h diff --git a/include/libpatchwork/pixel.h b/include/patchwork/pixel.h similarity index 100% rename from include/libpatchwork/pixel.h rename to include/patchwork/pixel.h diff --git a/include/libpatchwork/point.h b/include/patchwork/point.h similarity index 100% rename from include/libpatchwork/point.h rename to include/patchwork/point.h diff --git a/include/libpatchwork/polygon.h b/include/patchwork/polygon.h similarity index 100% rename from include/libpatchwork/polygon.h rename to include/patchwork/polygon.h diff --git a/include/libpatchwork/popup.h b/include/patchwork/popup.h similarity index 100% rename from include/libpatchwork/popup.h rename to include/patchwork/popup.h diff --git a/include/libpatchwork/procedure.h b/include/patchwork/procedure.h similarity index 100% rename from include/libpatchwork/procedure.h rename to include/patchwork/procedure.h diff --git a/include/libpatchwork/rect.h b/include/patchwork/rect.h similarity index 100% rename from include/libpatchwork/rect.h rename to include/patchwork/rect.h diff --git a/include/libpatchwork/surface.h b/include/patchwork/surface.h similarity index 98% rename from include/libpatchwork/surface.h rename to include/patchwork/surface.h index ff25c62b9..726e3cb64 100644 --- a/include/libpatchwork/surface.h +++ b/include/patchwork/surface.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #if defined(__cplusplus) extern "C" diff --git a/include/libpatchwork/theme.h b/include/patchwork/theme.h similarity index 100% rename from include/libpatchwork/theme.h rename to include/patchwork/theme.h diff --git a/include/libpatchwork/widgets.h b/include/patchwork/widgets.h similarity index 100% rename from include/libpatchwork/widgets.h rename to include/patchwork/widgets.h diff --git a/include/libpatchwork/window.h b/include/patchwork/window.h similarity index 99% rename from include/libpatchwork/window.h rename to include/patchwork/window.h index c79e112db..6c1f89f6a 100644 --- a/include/libpatchwork/window.h +++ b/include/patchwork/window.h @@ -61,7 +61,7 @@ typedef enum window_flags * @return On success, the new window. On failure, returns `NULL` and `errno` is set. */ window_t* window_new(display_t* disp, const char* name, const rect_t* rect, surface_type_t type, window_flags_t flags, - procedure_t procedure, void* data); + procedure_t procedure, void* data); /** * @brief Free a window. diff --git a/include/libstd/setjmp.h b/include/setjmp.h similarity index 94% rename from include/libstd/setjmp.h rename to include/setjmp.h index eeb3a2380..101fb8457 100644 --- a/include/libstd/setjmp.h +++ b/include/setjmp.h @@ -6,7 +6,7 @@ extern "C" { #endif -#include "_internal/config.h" +#include "_libstd/config.h" /** * @brief Setjmp/Longjmp functions. diff --git a/include/libstd/signal.h b/include/signal.h similarity index 96% rename from include/libstd/signal.h rename to include/signal.h index 39ecd82c8..442f34107 100644 --- a/include/libstd/signal.h +++ b/include/signal.h @@ -8,7 +8,7 @@ extern "C" #include -#include "_internal/config.h" +#include "_libstd/config.h" /** * @brief Wrappers around "notes" for ANSI C signal handling. diff --git a/include/libstd/stdarg.h b/include/stdarg.h similarity index 100% rename from include/libstd/stdarg.h rename to include/stdarg.h diff --git a/include/libstd/stdatomic.h b/include/stdatomic.h similarity index 100% rename from include/libstd/stdatomic.h rename to include/stdatomic.h diff --git a/include/libstd/stdbool.h b/include/stdbool.h similarity index 100% rename from include/libstd/stdbool.h rename to include/stdbool.h diff --git a/include/libstd/stddef.h b/include/stddef.h similarity index 51% rename from include/libstd/stddef.h rename to include/stddef.h index 7701fe94b..9a3bbf63f 100644 --- a/include/libstd/stddef.h +++ b/include/stddef.h @@ -6,17 +6,17 @@ extern "C" { #endif -#include "_internal/ERR.h" -#include "_internal/NULL.h" -#include "_internal/config.h" -#include "_internal/ptrdiff_t.h" -#include "_internal/size_t.h" -#include "_internal/wchar_t.h" +#include "_libstd/ERR.h" +#include "_libstd/NULL.h" +#include "_libstd/config.h" +#include "_libstd/ptrdiff_t.h" +#include "_libstd/size_t.h" +#include "_libstd/wchar_t.h" #define offsetof(type, member) ((size_t)&(((type*)0)->member)) #if _USE_ANNEX_K == 1 -#include "_internal/rsize_t.h" +#include "_libstd/rsize_t.h" #endif #if defined(__cplusplus) diff --git a/include/libstd/stdint.h b/include/stdint.h similarity index 100% rename from include/libstd/stdint.h rename to include/stdint.h diff --git a/include/libstd/stdio.h b/include/stdio.h similarity index 95% rename from include/libstd/stdio.h rename to include/stdio.h index 3d7bb8093..684b5128c 100644 --- a/include/libstd/stdio.h +++ b/include/stdio.h @@ -8,12 +8,12 @@ extern "C" { #endif -#include "_internal/MAX_PATH.h" -#include "_internal/NULL.h" -#include "_internal/SEEK.h" -#include "_internal/config.h" -#include "_internal/fd_t.h" -#include "_internal/size_t.h" +#include "_libstd/MAX_PATH.h" +#include "_libstd/NULL.h" +#include "_libstd/SEEK.h" +#include "_libstd/config.h" +#include "_libstd/fd_t.h" +#include "_libstd/size_t.h" #define _IOFBF (1u << 0) #define _IOLBF (1u << 1) @@ -129,8 +129,8 @@ _PUBLIC void perror(const char* s); #define L_tmpnam_s L_tmpnam #define TMP_MAX_S TMP_MAX -#include "_internal/errno_t.h" -#include "_internal/rsize_t.h" +#include "_libstd/errno_t.h" +#include "_libstd/rsize_t.h" _PUBLIC errno_t tmpfile_s(FILE * _RESTRICT * _RESTRICT streamptr); diff --git a/include/libstd/stdlib.h b/include/stdlib.h similarity index 95% rename from include/libstd/stdlib.h rename to include/stdlib.h index 2e29679fc..bf4ec8f8a 100644 --- a/include/libstd/stdlib.h +++ b/include/stdlib.h @@ -6,9 +6,9 @@ extern "C" { #endif -#include "_internal/NULL.h" -#include "_internal/config.h" -#include "_internal/size_t.h" +#include "_libstd/NULL.h" +#include "_libstd/config.h" +#include "_libstd/size_t.h" _PUBLIC char* lltoa(long long number, char* str, int base); #define ltoa(number, str, base) lltoa(number, str, base) @@ -97,8 +97,8 @@ int system(const char* command); #if _USE_ANNEX_K == 1 -#include "_internal/errno_t.h" -#include "_internal/rsize_t.h" +#include "_libstd/errno_t.h" +#include "_libstd/rsize_t.h" typedef void (*constraint_handler_t)(const char* _RESTRICT msg, void* _RESTRICT ptr, errno_t err); diff --git a/include/libstd/string.h b/include/string.h similarity index 94% rename from include/libstd/string.h rename to include/string.h index cda7ff2b1..e12eba0b9 100644 --- a/include/libstd/string.h +++ b/include/string.h @@ -6,9 +6,9 @@ extern "C" { #endif -#include "_internal/NULL.h" -#include "_internal/config.h" -#include "_internal/size_t.h" +#include "_libstd/NULL.h" +#include "_libstd/config.h" +#include "_libstd/size_t.h" _PUBLIC void* memcpy(void* _RESTRICT s1, const void* _RESTRICT s2, size_t n); @@ -61,8 +61,8 @@ char* strdup(const char* src); #if (__STDC_WANT_LIB_EXT1__ + 0) != 0 -#include "_internal/errno_t.h" -#include "_internal/rsize_t.h" +#include "_libstd/errno_t.h" +#include "_libstd/rsize_t.h" _PUBLIC errno_t memcpy_s(void* _RESTRICT s1, rsize_t s1max, const void* _RESTRICT s2, rsize_t n); diff --git a/include/libstd/strings.h b/include/strings.h similarity index 73% rename from include/libstd/strings.h rename to include/strings.h index aaf8dceb0..370f119af 100644 --- a/include/libstd/strings.h +++ b/include/strings.h @@ -6,9 +6,9 @@ extern "C" { #endif -#include "_internal/NULL.h" -#include "_internal/config.h" -#include "_internal/size_t.h" +#include "_libstd/NULL.h" +#include "_libstd/config.h" +#include "_libstd/size_t.h" int strcasecmp(const char* s1, const char* s2); int strncasecmp(const char* s1, const char* s2, size_t n); diff --git a/include/libstd/sys/9p.h b/include/sys/9p.h similarity index 100% rename from include/libstd/sys/9p.h rename to include/sys/9p.h diff --git a/include/libstd/sys/argsplit.h b/include/sys/argsplit.h similarity index 98% rename from include/libstd/sys/argsplit.h rename to include/sys/argsplit.h index 0c9d4e0f2..ecbfdfa3b 100644 --- a/include/libstd/sys/argsplit.h +++ b/include/sys/argsplit.h @@ -8,7 +8,7 @@ extern "C" { #endif -#include "_internal/config.h" +#include "_libstd/config.h" /** * @brief Standardized argument parsing diff --git a/include/libstd/sys/bitmap.h b/include/sys/bitmap.h similarity index 92% rename from include/libstd/sys/bitmap.h rename to include/sys/bitmap.h index 09e06e068..9ce03b36c 100644 --- a/include/libstd/sys/bitmap.h +++ b/include/sys/bitmap.h @@ -84,6 +84,16 @@ typedef struct uint64_t name##Buffer[BITMAP_BITS_TO_QWORDS(bits)] = {0}; \ bitmap_t name = {.firstZeroIdx = 0, .length = (bits), .buffer = name##Buffer} +/** + * @brief Define and create a one-initialized bitmap and its buffer. + * + * @param name Name of the bitmap. + * @param bits Length of the bitmap in bits. + */ +#define BITMAP_CREATE_ONE(name, bits) \ + uint64_t name##Buffer[BITMAP_BITS_TO_QWORDS(bits)] = {-1ULL}; \ + bitmap_t name = {.firstZeroIdx = 0, .length = (bits), .buffer = name##Buffer} + /** * @brief Define a bitmap and its buffer. * @@ -311,7 +321,8 @@ static inline uint64_t bitmap_find_first_clear(bitmap_t* map, uint64_t startIdx, uint64_t maskedQword = qword | ((1ULL << bitIdx) - 1); if (maskedQword != ~0ULL) { - return qwordIdx * 64 + __builtin_ctzll(~maskedQword); + uint64_t res = qwordIdx * 64 + __builtin_ctzll(~maskedQword); + return res < endIdx ? res : map->length; } qwordIdx++; } @@ -320,7 +331,8 @@ static inline uint64_t bitmap_find_first_clear(bitmap_t* map, uint64_t startIdx, { if (map->buffer[i] != ~0ULL) { - return i * 64 + __builtin_ctzll(~map->buffer[i]); + uint64_t res = i * 64 + __builtin_ctzll(~map->buffer[i]); + return res < endIdx ? res : map->length; } } @@ -356,7 +368,8 @@ static inline uint64_t bitmap_find_first_set(bitmap_t* map, uint64_t startIdx, u if (qword != 0) { - return startQwordIdx * 64 + __builtin_ctzll(qword); + uint64_t res = startQwordIdx * 64 + __builtin_ctzll(qword); + return res < endIdx ? res : map->length; } startQwordIdx++; @@ -376,8 +389,8 @@ static inline uint64_t bitmap_find_first_set(bitmap_t* map, uint64_t startIdx, u * @param alignment Alignment of the region. * @return Starting index of the found region, or `map->length` if not found. */ -static inline uint64_t bitmap_find_clear_region_and_set(bitmap_t* map, uint64_t minIdx, uintptr_t maxIdx, uint64_t length, - uint64_t alignment) +static inline uint64_t bitmap_find_clear_region_and_set(bitmap_t* map, uint64_t minIdx, uintptr_t maxIdx, + uint64_t length, uint64_t alignment) { if (length == 0 || minIdx >= maxIdx || maxIdx > map->length) { diff --git a/include/libstd/sys/cpuid.h b/include/sys/cpuid.h similarity index 100% rename from include/libstd/sys/cpuid.h rename to include/sys/cpuid.h diff --git a/include/libstd/sys/defs.h b/include/sys/defs.h similarity index 98% rename from include/libstd/sys/defs.h rename to include/sys/defs.h index 7f41a45ab..faa9af476 100644 --- a/include/libstd/sys/defs.h +++ b/include/sys/defs.h @@ -75,10 +75,6 @@ * @return The concatenated token. */ #define CONCAT(a, b) CONCAT_INNER(a, b) - -/** - * @brief Inner helper macro for token concatenation. - */ #define CONCAT_INNER(a, b) a##b /** diff --git a/include/libstd/sys/elf.h b/include/sys/elf.h similarity index 99% rename from include/libstd/sys/elf.h rename to include/sys/elf.h index 6675836a7..3fe500278 100644 --- a/include/libstd/sys/elf.h +++ b/include/sys/elf.h @@ -896,7 +896,7 @@ void elf64_load_segments(const Elf64_File* elf, Elf64_Addr base, Elf64_Off offse * @return On success, `0`. On failure, `ERR`. */ uint64_t elf64_relocate(const Elf64_File* elf, Elf64_Addr base, Elf64_Off offset, - void* (*resolve_symbol)(const char* name, void* data), void* data); + void* (*resolve_symbol)(const char* name, void* data), void* data); /** * @brief Get a string from the string table section at the given offset diff --git a/include/libstd/sys/io.h b/include/sys/fs.h similarity index 94% rename from include/libstd/sys/io.h rename to include/sys/fs.h index c7a811dce..07a3b60b0 100644 --- a/include/libstd/sys/io.h +++ b/include/sys/fs.h @@ -13,20 +13,20 @@ extern "C" { #endif -#include "_internal/ERR.h" -#include "_internal/MAX_NAME.h" -#include "_internal/MAX_PATH.h" -#include "_internal/NULL.h" -#include "_internal/SEEK.h" -#include "_internal/clock_t.h" -#include "_internal/config.h" -#include "_internal/fd_t.h" -#include "_internal/ssize_t.h" -#include "_internal/time_t.h" - -/** - * @brief System IO header. - * @defgroup libstd_sys_io System IO +#include "_libstd/ERR.h" +#include "_libstd/MAX_NAME.h" +#include "_libstd/MAX_PATH.h" +#include "_libstd/NULL.h" +#include "_libstd/SEEK.h" +#include "_libstd/clock_t.h" +#include "_libstd/config.h" +#include "_libstd/fd_t.h" +#include "_libstd/ssize_t.h" +#include "_libstd/time_t.h" + +/** + * @brief Filesystem header. + * @defgroup libstd_sys_fs Filesystem IO * @ingroup libstd * * @{ @@ -335,29 +335,40 @@ uint64_t poll(pollfd_t* fds, uint64_t amount, clock_t timeout); poll_events_t poll1(fd_t fd, poll_events_t events, clock_t timeout); /** - * @brief Inode type enum. - * @enum itype_t + * @brief Vnode type enum. + * @enum vtype_t */ typedef enum { - INODE_FILE, ///< Is a file. - INODE_DIR, ///< Is a directory. - INODE_SYMLINK, ///< Is a symbolic link. -} itype_t; + VREG, ///< Is a regular file. + VDIR, ///< Is a directory. + VSYMLINK, ///< Is a symbolic link. +} vtype_t; /** - * @brief A inode number that uniquely identifies the inode within its filesystem. + * @brief A suberblock identifier that uniquely identifies a superblock within the system. * - * When combined with a superblock ID, this can uniquely identify an inode within the entire system. + * When combined with a vnode number, this can uniquely identify an vnode within the entire system. */ -typedef uint64_t ino_t; +typedef uint64_t sbid_t; /** - * @brief A suberblock identifier that uniquely identifies a superblock within the system. - * - * When combined with a inode number, this can uniquely identify an inode within the entire system. + * @brief Vnode attributes structure. + * @struct vattr_t */ -typedef uint64_t sbid_t; +typedef struct vattr +{ + vtype_t type; + uint64_t nlink; + uint64_t id; + uint64_t size; + uint64_t blocks; + uint64_t blockSize; + time_t atime; + time_t mtime; + time_t ctime; + uint8_t padding[64]; ///< Padding to leave space for future expansion. +} vattr_t; /** * @brief Stat type. @@ -366,17 +377,17 @@ typedef uint64_t sbid_t; typedef struct { sbid_t sbid; ///< The superblock ID of the filesystem containing the entry. - ino_t number; ///< The number of the entries inode. - itype_t type; ///< The type of the entries inode. + uint64_t number; ///< The number of the entries vnode. + vtype_t type; ///< The type of the entries vnode. uint64_t size; ///< The size of the file that is visible outside the filesystem. uint64_t blocks; ///< The amount of blocks used on disk to store the file. uint64_t blockSize; ///< The preferred block size of the filesystem. uint64_t maxFileSize; ///< The maximum size of a file on this filesystem. - uint64_t linkAmount; ///< The amount of times the inode appears in dentries. - time_t accessTime; ///< Unix time stamp for the last inode access. + uint64_t linkAmount; ///< The amount of times the vnode appears in dentries. + time_t accessTime; ///< Unix time stamp for the last vnode access. time_t modifyTime; ///< Unix time stamp for last file content alteration. time_t changeTime; ///< Unix time stamp for the last file metadata alteration. - time_t createTime; ///< Unix time stamp for the creation of the inode. + time_t createTime; ///< Unix time stamp for the creation of the vnode. char name[MAX_PATH]; ///< The name of the entry, not the full filepath. Includes the flags of the paths mount. uint8_t padding[64]; ///< Padding to leave space for future expansion. } stat_t; @@ -442,8 +453,7 @@ typedef enum */ typedef struct { - ino_t number; - itype_t type; + vtype_t type; dirent_flags_t flags; char path[MAX_PATH]; ///< The relative path of the entry. char mode[MAX_PATH]; ///< The flags of the paths mount. diff --git a/include/sys/ioring.h b/include/sys/ioring.h new file mode 100644 index 000000000..36e359eae --- /dev/null +++ b/include/sys/ioring.h @@ -0,0 +1,301 @@ +#ifndef _SYS_IORING_H +#define _SYS_IORING_H 1 + +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#include "_libstd/MAX_NAME.h" +#include "_libstd/MAX_PATH.h" +#include "_libstd/clock_t.h" +#include "_libstd/errno_t.h" +#include "_libstd/fd_t.h" +#include "_libstd/ssize_t.h" + +/** + * @addtogroup kernel_io + * @{ + */ + +#define IO_OFF_CUR ((ssize_t) - 1) ///< Use the current file offset. + +typedef uint64_t io_whence_t; ///< Seek origin type. +#define IO_SEEK_SET (1) ///< Use the start of the file. +#define IO_SEEK_END (2) ///< Use the end of the file. +#define IO_SEEK_CUR (3) ///< Use the current file offset. + +typedef uint64_t io_events_t; ///< Poll events type. +#define IO_POLL_READ (1 << 0) ///< File descriptor is ready to read. +#define IO_POLL_WRITE (1 << 1) ///< File descriptor is ready to write +#define IO_POLL_ERROR (1 << 2) ///< File descriptor caused an error. +#define IO_POLL_HUP (1 << 3) ///< File descriptor is closed. +#define IO_POLL_NVAL (1 << 4) ///< Invalid file descriptor. + +typedef uint32_t io_op_t; ///< I/O operation code type. +#define IO_OP_NOP 0 ///< No-op operation. +#define IO_OP_READ 1 ///< Read operation. +#define IO_OP_WRITE 2 ///< Write operation. +#define IO_OP_POLL 3 ///< Poll operation. +#define IO_OP_MAX 4 ///< The maximum number of operation. + +typedef uint32_t sqe_flags_t; ///< Submission queue entry (SQE) flags. +#define SQE_REG0 (0) ///< The first register. +#define SQE_REG1 (1) ///< The second register. +#define SQE_REG2 (2) ///< The third register. +#define SQE_REG3 (3) ///< The fourth register. +#define SQE_REG4 (4) ///< The fifth register. +#define SQE_REG5 (5) ///< The sixth register. +#define SQE_REG6 (6) ///< The seventh register. +#define SQE_REG_NONE (7) ///< No register. +#define SQE_REGS_MAX (7) ///< The maximum number of registers. +#define SQE_REG_SHIFT (3) ///< The bitshift for each register specifier in a `sqe_flags_t`. +#define SQE_REG_MASK (0b111) ///< The bitmask for a register specifier in a `sqe_flags_t`. + +#define SQE_LOAD0 (0) ///< The offset to specify the register to load into the first argument. +#define SQE_LOAD1 (SQE_LOAD0 + SQE_REG_SHIFT) ///< The offset to specify the register to load into the second argument. +#define SQE_LOAD2 (SQE_LOAD1 + SQE_REG_SHIFT) ///< The offset to specify the register to load into the third argument. +#define SQE_LOAD3 (SQE_LOAD2 + SQE_REG_SHIFT) ///< The offset to specify the register to load into the fourth argument. +#define SQE_LOAD4 (SQE_LOAD3 + SQE_REG_SHIFT) ///< The offset to specify the register to load into the fifth argument. +#define SQE_SAVE (SQE_LOAD4 + SQE_REG_SHIFT) ///< The offset to specify the register to save the result into. + +#define _SQE_FLAGS (SQE_SAVE + SQE_REG_SHIFT) ///< The bitshift for where bit flags start in a `sqe_flags_t`. + +/** + * Only process the next SQE when this one completes successfully) only applies within one `enter()` call. + */ +#define SQE_LINK (1 << (_SQE_FLAGS)) +/** + * Like `SQE_LINK` but will process the next SQE even if this one fails. + */ +#define SQE_HARDLINK (1 << (_SQE_FLAGS + 1)) + +/** + * @brief Asynchronous submission queue entry (SQE). + * @struct sqe_t + * + * @warning It is the responsibility of userspace to ensure that any pointers + * passed to the kernel remain valid until the operation is complete. + * + * @see kernel_io for more information for each possible operation. + */ +typedef struct sqe +{ + clock_t timeout; ///< Timeout for the operation, `CLOCKS_NEVER` for no timeout. + void* data; ///< Private data for the operation, will be returned in the completion entry. + io_op_t op; ///< The operation to perform. + sqe_flags_t flags; ///< Submission flags. + union { + uint64_t arg0; + fd_t fd; + }; + union { + uint64_t arg1; + void* buffer; + io_events_t events; + }; + union { + uint64_t arg2; + size_t count; + }; + union { + uint64_t arg3; + ssize_t offset; + }; + union { + uint64_t arg4; + }; +} sqe_t; + +#ifdef static_assert +static_assert(sizeof(sqe_t) == 64, "sqe_t is not 64 bytes"); +#endif + +/** + * @brief Macro to create an asynchronous submission queue entry (SQE). + * + * @param _op The operation to perform. + * @param _flags Submission flags. + * @param _timeout Timeout for the operation, `CLOCKS_NEVER` for no timeout. + * @param _data Private data for the operation. + */ +#define SQE_CREATE(_op, _flags, _timeout, _data) \ + { \ + .op = (_op), \ + .flags = (_flags), \ + .timeout = (_timeout), \ + .data = (void*)(_data), \ + } + +/** + * @brief Asynchronous completion queue entry (CQE). + * @struct cqe_t + * + * @see kernel_io for more information on the possible operations. + */ +typedef struct cqe +{ + io_op_t op; ///< The operation that was performed. + errno_t error; ///< Error code, if not equal to `EOK` an error occurred. + void* data; ///< Private data from the submission entry. + union { + fd_t fd; + size_t count; + void* ptr; + io_events_t events; + uint64_t _result; + }; + uint64_t _padding[1]; +} cqe_t; + +#ifdef static_assert +static_assert(sizeof(cqe_t) == 32, "cqe_t is not 32 bytes"); +#endif + +/** + * @brief Shared ring control structure. + * @struct ioring_ctrl_t + * + * Used as the intermediate between userspace and the kernel. + * + * @note The structure is aligned in such a way to reduce false sharing. + * + */ +typedef struct ALIGNED(64) ioring_ctrl +{ + atomic_uint32_t shead; ///< Submission head index, updated by the kernel. + atomic_uint32_t ctail; ///< Completion tail index, updated by the kernel. + uint8_t _padding0[64 - sizeof(atomic_uint32_t) * 2]; + atomic_uint32_t stail; ///< Submission tail index, updated by userspace. + atomic_uint32_t chead; ///< Completion head index, updated by userspace. + uint8_t _padding1[64 - sizeof(atomic_uint32_t) * 2]; + atomic_uint64_t regs[SQE_REGS_MAX] ALIGNED(64); ///< General purpose registers. + uint8_t _reserved[8]; +} ioring_ctrl_t; + +/** + * @} + * @brief Programmable submission/completion interface. + * @defgroup libstd_sys_ioring User-side I/O Ring Interface + * @ingroup libstd + * + * The ring interface acts as the interface for all asynchronous operations in the kernel. + * + * @see kernel_io for more information about the I/O ring system. + * + * @{ + */ + +typedef uint64_t ioring_id_t; ///< I/O ring ID type. + +/** + * @brief User I/O ring structure. + * @struct ioring_t + * + * The kernel and userspace will have their own instances of this structure. + */ +typedef struct ioring +{ + ioring_ctrl_t* ctrl; ///< Pointer to the shared control structure. + ioring_id_t id; ///< The ID of the ring. + sqe_t* squeue; ///< Pointer to the submission queue. + size_t sentries; ///< Number of entries in the submission queue. + size_t smask; ///< Bitmask for submission queue (sentries - 1). + cqe_t* cqueue; ///< Pointer to the completion queue. + size_t centries; ///< Number of entries in the completion queue. + size_t cmask; ///< Bitmask for completion queue (centries - 1). +} ioring_t; + +/** + * @brief System call to initialize the I/O ring. + * + * This system call will populate the given structure with the necessary pointers and metadata for the submission and + * completion ring. + * + * @param ring Pointer to the ring structure to populate. + * @param address Desired address to allocate the ring, or `NULL` to let the kernel choose. + * @param sentries Number of entires to allocate for the submission queue, must be a power of two. + * @param centries Number of entries to allocate for the completion queue, must be a power of two. + * @return On success, the ID of the new I/O ring. On failure, `ERR` and `errno` is set. + */ +ioring_id_t ioring_setup(ioring_t* ring, void* address, size_t sentries, size_t centries); + +/** + * @brief System call to deinitialize the I/O ring. + * + * @param id The ID of the I/O ring to teardown. + * @return On success, `0`. On failure, `ERR` and `errno` is set. + */ +uint64_t ioring_teardown(ioring_id_t id); + +/** + * @brief System call to notify the kernel of new submission queue entries (SQEs). + * + * @param id The ID of the I/O ring to notify. + * @param amount The number of SQEs that the kernel should process. + * @param wait The minimum number of completion queue entries (CQEs) to wait for. + * @return On success, the number of SQEs successfully processed. On failure, `ERR` and `errno` is set. + */ +uint64_t ioring_enter(ioring_id_t id, size_t amount, size_t wait); + +/** + * @brief Pushes a submission queue entry (SQE) to the submission queue. + * + * After pushing SQEs, `enter()` must be called to notify the kernel of the new entries. + * + * @param ring Pointer to the I/O ring structure. + * @param sqe Pointer to the SQE to push. + * @return `true` if the SQE was pushed, `false` if the submission queue is full. + */ +static inline bool sqe_push(ioring_t* ring, sqe_t* sqe) +{ + uint32_t tail = atomic_load_explicit(&ring->ctrl->stail, memory_order_relaxed); + uint32_t head = atomic_load_explicit(&ring->ctrl->shead, memory_order_acquire); + + if ((tail - head) >= ring->sentries) + { + return false; + } + + ring->squeue[tail & ring->smask] = *sqe; + atomic_store_explicit(&ring->ctrl->stail, tail + 1, memory_order_release); + + return true; +} + +/** + * @brief Pops a completion queue entry (CQE) from the completion queue. + * + * @param ring Pointer to the I/O ring structure. + * @param cqe Pointer to the CQE to pop. + * @return `true` if a CQE was popped, `false` if the completion queue is empty. + */ +static inline bool cqe_pop(ioring_t* ring, cqe_t* cqe) +{ + uint32_t head = atomic_load_explicit(&ring->ctrl->chead, memory_order_relaxed); + uint32_t tail = atomic_load_explicit(&ring->ctrl->ctail, memory_order_acquire); + + if (head == tail) + { + return false; + } + + *cqe = ring->cqueue[head & ring->cmask]; + atomic_store_explicit(&ring->ctrl->chead, head + 1, memory_order_release); + + return true; +} + +/** @} */ + +#if defined(__cplusplus) +} +#endif + +#endif \ No newline at end of file diff --git a/include/libstd/sys/kbd.h b/include/sys/kbd.h similarity index 99% rename from include/libstd/sys/kbd.h rename to include/sys/kbd.h index 9c894119f..a9c244a50 100644 --- a/include/libstd/sys/kbd.h +++ b/include/sys/kbd.h @@ -8,7 +8,7 @@ extern "C" { #endif -#include "_internal/clock_t.h" +#include "_libstd/clock_t.h" /** * @brief Keyboard keycodes. diff --git a/include/libstd/sys/list.h b/include/sys/list.h similarity index 98% rename from include/libstd/sys/list.h rename to include/sys/list.h index f2745d75e..d8b440790 100644 --- a/include/libstd/sys/list.h +++ b/include/sys/list.h @@ -1,13 +1,13 @@ #ifndef _SYS_LIST_H #define _SYS_LIST_H 1 -#include "_internal/CONTAINER_OF.h" -#include "_internal/NULL.h" +#include "_libstd/CONTAINER_OF.h" +#include "_libstd/NULL.h" #include +#include #include #include -#include /** * @brief Doubly linked list header. @@ -18,7 +18,7 @@ * * Given a entry within a structure, the `CONTAINER_OF()` macro can be used to get a pointer to the structure from the * list entry pointer. - * + * * @warning If a list is protected with RCU, the `list_*_rcu()` functions must be used. * * @{ @@ -247,10 +247,10 @@ static inline void list_add_rcu(list_entry_t* prev, list_entry_t* next, list_ent assert(prev != NULL); assert(next != NULL); assert(entry != NULL); - // For RCU we allow adding an entry that is already in a list + // For RCU we allow adding an entry that is already in a list // as we cant properly remove it until all readers are done. - //assert(entry->next == entry && entry->prev == entry); - //assert(prev->next == next && next->prev == prev); + // assert(entry->next == entry && entry->prev == entry); + // assert(prev->next == next && next->prev == prev); next->prev = entry; entry->next = next; @@ -299,7 +299,8 @@ static inline void list_remove(list_entry_t* entry) /** * @brief Removes a list entry from its current list in a RCU-safe manner. * - * @warning After calling this function the entry will still be connected to the list, but iteration over the list will not find it. + * @warning After calling this function the entry will still be connected to the list, but iteration over the list will + * not find it. * * @param entry A pointer to the `list_entry_t` to remove. */ diff --git a/include/libstd/sys/math.h b/include/sys/math.h similarity index 100% rename from include/libstd/sys/math.h rename to include/sys/math.h diff --git a/include/libstd/sys/proc.h b/include/sys/proc.h similarity index 98% rename from include/libstd/sys/proc.h rename to include/sys/proc.h index de9dc0782..91ad38731 100644 --- a/include/libstd/sys/proc.h +++ b/include/sys/proc.h @@ -10,15 +10,15 @@ extern "C" { #endif -#include "_internal/ERR.h" -#include "_internal/NULL.h" -#include "_internal/PAGE_SIZE.h" -#include "_internal/clock_t.h" -#include "_internal/config.h" -#include "_internal/fd_t.h" +#include "_libstd/ERR.h" +#include "_libstd/NULL.h" +#include "_libstd/PAGE_SIZE.h" +#include "_libstd/clock_t.h" +#include "_libstd/config.h" +#include "_libstd/fd_t.h" -#include "_internal/pid_t.h" -#include "_internal/tid_t.h" +#include "_libstd/pid_t.h" +#include "_libstd/tid_t.h" /** * @brief Process management header. @@ -351,7 +351,7 @@ typedef enum /** * @brief System call for setting architecture specific thread data. - * + * * @param op The operation to perform. * @param addr If getting data, a pointer to store the retrieved address. If setting data, the address to set. * @return On success, `0`. On failure, `ERR` and `errno` is set. diff --git a/include/libstd/threads.h b/include/threads.h similarity index 94% rename from include/libstd/threads.h rename to include/threads.h index 589bff1fc..fdf248346 100644 --- a/include/libstd/threads.h +++ b/include/threads.h @@ -8,10 +8,10 @@ extern "C" { #endif -#include "_internal/config.h" -#include "_internal/pid_t.h" -#include "_internal/tid_t.h" -#include "_internal/timespec.h" +#include "_libstd/config.h" +#include "_libstd/pid_t.h" +#include "_libstd/tid_t.h" +#include "_libstd/timespec.h" #include diff --git a/include/libstd/time.h b/include/time.h similarity index 84% rename from include/libstd/time.h rename to include/time.h index 295aa6453..141be80f3 100644 --- a/include/libstd/time.h +++ b/include/time.h @@ -8,12 +8,12 @@ extern "C" { #endif -#include "_internal/NULL.h" -#include "_internal/clock_t.h" -#include "_internal/config.h" -#include "_internal/size_t.h" -#include "_internal/time_t.h" -#include "_internal/timespec.h" +#include "_libstd/NULL.h" +#include "_libstd/clock_t.h" +#include "_libstd/config.h" +#include "_libstd/size_t.h" +#include "_libstd/time_t.h" +#include "_libstd/timespec.h" #define TIME_UTC 1 @@ -55,8 +55,8 @@ _PUBLIC size_t strftime(char* _RESTRICT s, size_t maxsize, const char* _RESTRICT #if (__STDC_WANT_LIB_EXT1__ + 0) != 0 -#include "_internal/errno_t.h" -#include "_internal/rsize_t.h" +#include "_libstd/errno_t.h" +#include "_libstd/rsize_t.h" _PUBLIC errno_t asctime_s(char* s, rsize_t maxsize, const struct tm* timeptr); diff --git a/lib/OVMFbin/OVMF_VARS-pure-efi.fd b/lib/OVMFbin/OVMF_VARS-pure-efi.fd index 92201fe8b..840e8790c 100644 Binary files a/lib/OVMFbin/OVMF_VARS-pure-efi.fd and b/lib/OVMFbin/OVMF_VARS-pure-efi.fd differ diff --git a/meta/doxy/Doxyfile b/meta/doxy/Doxyfile index 2441f4e20..d715df518 100644 --- a/meta/doxy/Doxyfile +++ b/meta/doxy/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = "PatchworkOS" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "9ec3d2a3-dirty" +PROJECT_NUMBER = "66c809ea-dirty" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewers a diff --git a/meta/doxy/DoxygenLayout.xml b/meta/doxy/DoxygenLayout.xml index 9bb18a73f..c16f22492 100644 --- a/meta/doxy/DoxygenLayout.xml +++ b/meta/doxy/DoxygenLayout.xml @@ -192,7 +192,7 @@ - + diff --git a/src/boot/main.c b/src/boot/main.c index a6299472e..6c00b1450 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -194,7 +194,7 @@ static EFI_STATUS gop_init(boot_gop_t* buffer) } #endif - buffer->physAddr = (uint32_t*)gop->Mode->FrameBufferBase; + buffer->physAddr = gop->Mode->FrameBufferBase; buffer->virtAddr = (uint32_t*)PML_LOWER_TO_HIGHER(gop->Mode->FrameBufferBase); buffer->size = gop->Mode->FrameBufferSize; buffer->width = gop->Mode->Info->HorizontalResolution; @@ -284,7 +284,7 @@ _NORETURN static void panic_halt(panic_code_t code) { for (size_t x = 0; x < gop->width; x++) { - gop->physAddr[x + (y * gop->stride)] = color; + ((uint32_t*)gop->physAddr)[x + (y * gop->stride)] = color; } } } @@ -404,18 +404,21 @@ static EFI_STATUS mem_allocator_init(void) /** * @brief Allocate pages from the basic allocator. * - * @param pages Output pointer to store the allocated pages. + * @param pfns Pointer to store allocated page PFNs. * @param amount Number of pages to allocate. * @return Always returns `0`. */ -static uint64_t basic_allocator_alloc_pages(void** pages, size_t amount) +static uint64_t basic_allocator_alloc_pages(pfn_t* pfns, size_t amount) { if (basicAllocator.pagesAllocated + amount > basicAllocator.maxPages) { panic_halt(PANIC_ALLOCATOR_EXHAUSTED); } - *pages = (void*)(uintptr_t)(basicAllocator.buffer + (basicAllocator.pagesAllocated * PAGE_SIZE)); + for (size_t i = 0; i < amount; i++) + { + pfns[i] = PHYS_TO_PFN(basicAllocator.buffer + ((basicAllocator.pagesAllocated + i) * PAGE_SIZE)); + } basicAllocator.pagesAllocated += amount; return 0; @@ -465,7 +468,7 @@ static void mem_page_table_init(page_table_t* table, boot_memory_map_t* map, boo panic_halt(PANIC_HIGHER_HALF_INVALID); } - if (page_table_map(table, (void*)desc->VirtualStart, (void*)desc->PhysicalStart, desc->NumberOfPages, + if (page_table_map(table, (void*)desc->VirtualStart, desc->PhysicalStart, desc->NumberOfPages, PML_WRITE | PML_PRESENT, PML_CALLBACK_NONE) == ERR) { panic_halt(PANIC_HIGHER_HALF_MAP); @@ -483,7 +486,7 @@ static void mem_page_table_init(page_table_t* table, boot_memory_map_t* map, boo panic_halt(PANIC_KERNEL_MAP); } - if (page_table_map(table, (void*)gop->virtAddr, (void*)gop->physAddr, BYTES_TO_PAGES(gop->size), + if (page_table_map(table, (void*)gop->virtAddr, gop->physAddr, BYTES_TO_PAGES(gop->size), PML_WRITE | PML_PRESENT | PML_WRITE_THROUGH, PML_CALLBACK_NONE) == ERR) { panic_halt(PANIC_GOP_MAP); @@ -876,7 +879,7 @@ static EFI_STATUS kernel_load(boot_kernel_t* kernel, EFI_FILE* rootHandle) Print(L" Loading kernel...\n"); elf64_load_segments(&kernel->elf, kernelPhys, minVaddr); - kernel->physAddr = (void*)kernelPhys; + kernel->physAddr = kernelPhys; Print(L" Entry Code: "); for (size_t i = 0; i < 16; i++) diff --git a/src/boxes/apps/calculator/main.c b/src/boxes/apps/calculator/main.c index 39b7cb8b0..c9c054fb8 100644 --- a/src/boxes/apps/calculator/main.c +++ b/src/boxes/apps/calculator/main.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/boxes/apps/clock/main.c b/src/boxes/apps/clock/main.c index a62070828..514c05ea7 100644 --- a/src/boxes/apps/clock/main.c +++ b/src/boxes/apps/clock/main.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/boxes/apps/terminal/ansi.h b/src/boxes/apps/terminal/ansi.h index 54a9e2b5f..0e63d8112 100644 --- a/src/boxes/apps/terminal/ansi.h +++ b/src/boxes/apps/terminal/ansi.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/src/boxes/apps/terminal/terminal.c b/src/boxes/apps/terminal/terminal.c index ea6ac836a..f9d94ef1b 100644 --- a/src/boxes/apps/terminal/terminal.c +++ b/src/boxes/apps/terminal/terminal.c @@ -1,11 +1,11 @@ #include "terminal.h" #include "ansi.h" -#include +#include #include #include #include -#include +#include #include #include #include diff --git a/src/boxes/apps/terminal/terminal.h b/src/boxes/apps/terminal/terminal.h index 75d78dc30..05f70012d 100644 --- a/src/boxes/apps/terminal/terminal.h +++ b/src/boxes/apps/terminal/terminal.h @@ -2,9 +2,9 @@ #include "ansi.h" -#include +#include #include -#include +#include #include #include diff --git a/src/boxes/apps/tetris/main.c b/src/boxes/apps/tetris/main.c index 8bfeee948..17da98f6a 100644 --- a/src/boxes/apps/tetris/main.c +++ b/src/boxes/apps/tetris/main.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/src/boxes/core/cursor/main.c b/src/boxes/core/cursor/main.c index 62c64bdac..668240e37 100644 --- a/src/boxes/core/cursor/main.c +++ b/src/boxes/core/cursor/main.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/boxes/core/dwm/client.h b/src/boxes/core/dwm/client.h index f466f42ea..bef94d28f 100644 --- a/src/boxes/core/dwm/client.h +++ b/src/boxes/core/dwm/client.h @@ -2,9 +2,9 @@ #include "surface.h" -#include -#include -#include +#include +#include +#include #include #define CLIENT_RECV_BUFFER_SIZE (sizeof(cmd_buffer_t) + 128) diff --git a/src/boxes/core/dwm/dwm.c b/src/boxes/core/dwm/dwm.c index 4bb9c3083..3a92a4cdc 100644 --- a/src/boxes/core/dwm/dwm.c +++ b/src/boxes/core/dwm/dwm.c @@ -7,11 +7,11 @@ #include "surface.h" #include -#include +#include #include #include #include -#include +#include #include #include #include diff --git a/src/boxes/core/dwm/dwm.h b/src/boxes/core/dwm/dwm.h index 9a890d9fe..d2a631ce5 100644 --- a/src/boxes/core/dwm/dwm.h +++ b/src/boxes/core/dwm/dwm.h @@ -2,8 +2,8 @@ #include "surface.h" -#include -#include +#include +#include #include /** diff --git a/src/boxes/core/dwm/kbd.h b/src/boxes/core/dwm/kbd.h index c99663852..c5f738b92 100644 --- a/src/boxes/core/dwm/kbd.h +++ b/src/boxes/core/dwm/kbd.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include keycode_t kbd_translate(keycode_t code); diff --git a/src/boxes/core/dwm/region.h b/src/boxes/core/dwm/region.h index 076f48075..26121e070 100644 --- a/src/boxes/core/dwm/region.h +++ b/src/boxes/core/dwm/region.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/src/boxes/core/dwm/screen.c b/src/boxes/core/dwm/screen.c index d65536cde..ec5043aa0 100644 --- a/src/boxes/core/dwm/screen.c +++ b/src/boxes/core/dwm/screen.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include static uint64_t width; diff --git a/src/boxes/core/dwm/surface.c b/src/boxes/core/dwm/surface.c index 4212b519d..fe5aad8eb 100644 --- a/src/boxes/core/dwm/surface.c +++ b/src/boxes/core/dwm/surface.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include static surface_id_t newId = 0; diff --git a/src/boxes/core/dwm/surface.h b/src/boxes/core/dwm/surface.h index 93de56d6e..a3ae7929a 100644 --- a/src/boxes/core/dwm/surface.h +++ b/src/boxes/core/dwm/surface.h @@ -1,11 +1,11 @@ #pragma once -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include typedef struct client client_t; diff --git a/src/boxes/core/taskbar/main.c b/src/boxes/core/taskbar/main.c index 3f0f6bb38..7f880f926 100644 --- a/src/boxes/core/taskbar/main.c +++ b/src/boxes/core/taskbar/main.c @@ -1,6 +1,6 @@ #include "taskbar.h" -#include +#include #include #include diff --git a/src/boxes/core/taskbar/start_menu.c b/src/boxes/core/taskbar/start_menu.c index 63a5b9353..fa35d6f32 100644 --- a/src/boxes/core/taskbar/start_menu.c +++ b/src/boxes/core/taskbar/start_menu.c @@ -2,12 +2,12 @@ #include "taskbar.h" -#include +#include #include #include #include #include -#include +#include #include #define START_ENTRY_MAX 16 diff --git a/src/boxes/core/taskbar/start_menu.h b/src/boxes/core/taskbar/start_menu.h index 8253ff158..c67e719f9 100644 --- a/src/boxes/core/taskbar/start_menu.h +++ b/src/boxes/core/taskbar/start_menu.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #define START_BUTTON_HEIGHT 32 diff --git a/src/boxes/core/taskbar/taskbar.c b/src/boxes/core/taskbar/taskbar.c index eb57507cf..a8d239af1 100644 --- a/src/boxes/core/taskbar/taskbar.c +++ b/src/boxes/core/taskbar/taskbar.c @@ -1,10 +1,10 @@ #include "taskbar.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include diff --git a/src/boxes/core/taskbar/taskbar.h b/src/boxes/core/taskbar/taskbar.h index d3291f718..4f378cda8 100644 --- a/src/boxes/core/taskbar/taskbar.h +++ b/src/boxes/core/taskbar/taskbar.h @@ -2,8 +2,8 @@ #include "start_menu.h" -#include -#include +#include +#include #include #define START_WIDTH 100 diff --git a/src/boxes/core/wall/main.c b/src/boxes/core/wall/main.c index 6d0b4fbd0..3215af388 100644 --- a/src/boxes/core/wall/main.c +++ b/src/boxes/core/wall/main.c @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/kernel/cpu/interrupt.c b/src/kernel/cpu/interrupt.c index 1ff14a766..8dcb2da37 100644 --- a/src/kernel/cpu/interrupt.c +++ b/src/kernel/cpu/interrupt.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -220,6 +221,7 @@ void interrupt_handler(interrupt_frame_t* frame) } note_handle_pending(frame); + irp_timeouts_check(); wait_check_timeouts(frame); sched_do(frame); diff --git a/src/kernel/cpu/ipi.c b/src/kernel/cpu/ipi.c index 5cdc10987..6a31058c0 100644 --- a/src/kernel/cpu/ipi.c +++ b/src/kernel/cpu/ipi.c @@ -107,7 +107,7 @@ uint64_t ipi_chip_amount(void) return registeredChip != NULL ? 1 : 0; } -static uint64_t ipi_push(cpu_t* cpu, ipi_func_t func, void* data) +static uint64_t ipi_push(cpu_t* cpu, ipi_func_t func, void* data) { if (registeredChip == NULL) { diff --git a/src/kernel/cpu/irq.c b/src/kernel/cpu/irq.c index deabc209f..2c2a30ecc 100644 --- a/src/kernel/cpu/irq.c +++ b/src/kernel/cpu/irq.c @@ -325,7 +325,7 @@ uint64_t irq_virt_set_affinity(irq_virt_t virt, cpu_t* cpu) return 0; } -uint64_t irq_chip_register(irq_chip_t* chip, irq_phys_t start, irq_phys_t end, void* data) +uint64_t irq_chip_register(irq_chip_t* chip, irq_phys_t start, irq_phys_t end, void* data) { if (chip == NULL || chip->enable == NULL || chip->disable == NULL || start >= end) { @@ -420,7 +420,7 @@ uint64_t irq_chip_amount(void) return list_size(&domains); } -uint64_t irq_handler_register(irq_virt_t virt, irq_func_t func, void* data) +uint64_t irq_handler_register(irq_virt_t virt, irq_func_t func, void* data) { if (func == NULL) { diff --git a/src/kernel/cpu/io.c b/src/kernel/cpu/port.c similarity index 78% rename from src/kernel/cpu/io.c rename to src/kernel/cpu/port.c index 33db453df..273abafda 100644 --- a/src/kernel/cpu/io.c +++ b/src/kernel/cpu/port.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -9,10 +9,11 @@ #include #include -static BITMAP_CREATE(ports, IO_PORT_MAX + 1); +static BITMAP_CREATE(ports, PORT_MAX + 1); static lock_t lock = LOCK_CREATE(); -uint64_t io_reserve(port_t* out, port_t minBase, port_t maxBase, uint64_t alignment, uint64_t length, const char* owner) +uint64_t port_reserve(port_t* out, port_t minBase, port_t maxBase, uint64_t alignment, uint64_t length, + const char* owner) { UNUSED(owner); @@ -40,7 +41,7 @@ uint64_t io_reserve(port_t* out, port_t minBase, port_t maxBase, uint64_t alignm return 0; } -void io_release(port_t base, uint64_t length) +void port_release(port_t base, uint64_t length) { if (length == 0 || base + length < base || base + length > ports.length) { diff --git a/src/kernel/cpu/simd.c b/src/kernel/cpu/simd.c index ec80441c6..c31d9d243 100644 --- a/src/kernel/cpu/simd.c +++ b/src/kernel/cpu/simd.c @@ -122,12 +122,12 @@ PERCPU_DEFINE_CTOR(static void, pcpu_simd) uint64_t simd_ctx_init(simd_ctx_t* ctx) { - ctx->buffer = pmm_alloc(); - if (ctx->buffer == NULL) + pfn_t pfn = pmm_alloc(); + if (pfn == ERR) { return ERR; } - + ctx->buffer = PFN_TO_VIRT(pfn); memcpy(ctx->buffer, initCtx, PAGE_SIZE); return 0; @@ -135,7 +135,8 @@ uint64_t simd_ctx_init(simd_ctx_t* ctx) void simd_ctx_deinit(simd_ctx_t* ctx) { - pmm_free(ctx->buffer); + pfn_t pfn = VIRT_TO_PFN(ctx->buffer); + pmm_free(pfn); } void simd_ctx_save(simd_ctx_t* ctx) diff --git a/src/kernel/cpu/syscall.c b/src/kernel/cpu/syscall.c index a66a858a4..11831b781 100644 --- a/src/kernel/cpu/syscall.c +++ b/src/kernel/cpu/syscall.c @@ -43,7 +43,7 @@ static int syscall_descriptor_cmp(const void* a, const void* b) { const syscall_descriptor_t* sysA = (const syscall_descriptor_t*)a; const syscall_descriptor_t* sysB = (const syscall_descriptor_t*)b; - return sysA->number - sysB->number; + return (int32_t)sysA->number - (int32_t)sysB->number; } void syscall_table_init(void) diff --git a/src/kernel/drivers/abstract/fb.c b/src/kernel/drivers/abstract/fb.c index 5a37a1d47..af176bbce 100644 --- a/src/kernel/drivers/abstract/fb.c +++ b/src/kernel/drivers/abstract/fb.c @@ -17,7 +17,7 @@ static dentry_t* dir = NULL; static size_t fb_name_read(file_t* file, void* buffer, size_t count, size_t* offset) { - fb_t* fb = file->inode->data; + fb_t* fb = file->vnode->data; assert(fb != NULL); uint64_t length = strlen(fb->name); @@ -30,7 +30,7 @@ static file_ops_t nameOps = { static size_t fb_data_read(file_t* file, void* buffer, size_t count, size_t* offset) { - fb_t* fb = file->inode->data; + fb_t* fb = file->vnode->data; assert(fb != NULL); if (fb->ops->read == NULL) @@ -44,7 +44,7 @@ static size_t fb_data_read(file_t* file, void* buffer, size_t count, size_t* off static size_t fb_data_write(file_t* file, const void* buffer, size_t count, size_t* offset) { - fb_t* fb = file->inode->data; + fb_t* fb = file->vnode->data; assert(fb != NULL); if (fb->ops->write == NULL) @@ -58,7 +58,7 @@ static size_t fb_data_write(file_t* file, const void* buffer, size_t count, size static void* fb_data_mmap(file_t* file, void* addr, size_t length, size_t* offset, pml_flags_t flags) { - fb_t* fb = file->inode->data; + fb_t* fb = file->vnode->data; assert(fb != NULL); if (fb->ops->mmap == NULL) @@ -78,7 +78,7 @@ static file_ops_t dataOps = { static size_t fb_info_read(file_t* file, void* buffer, size_t count, size_t* offset) { - fb_t* fb = file->inode->data; + fb_t* fb = file->vnode->data; assert(fb != NULL); if (fb->ops->info == NULL) @@ -115,9 +115,9 @@ static file_ops_t infoOps = { .read = fb_info_read, }; -static void fb_dir_cleanup(inode_t* inode) +static void fb_dir_cleanup(vnode_t* vnode) { - fb_t* fb = inode->data; + fb_t* fb = vnode->data; if (fb->ops->cleanup != NULL) { @@ -127,11 +127,11 @@ static void fb_dir_cleanup(inode_t* inode) free(fb); } -static inode_ops_t dirInodeOps = { +static vnode_ops_t dirVnodeOps = { .cleanup = fb_dir_cleanup, }; -fb_t* fb_new(const char* name, const fb_ops_t* ops, void* data) +fb_t* fb_new(const char* name, const fb_ops_t* ops, void* data) { if (name == NULL || ops == NULL) { @@ -169,7 +169,7 @@ fb_t* fb_new(const char* name, const fb_ops_t* ops, void* data) return NULL; } - fb->dir = devfs_dir_new(dir, id, &dirInodeOps, fb); + fb->dir = devfs_dir_new(dir, id, &dirVnodeOps, fb); if (fb->dir == NULL) { free(fb); @@ -179,19 +179,19 @@ fb_t* fb_new(const char* name, const fb_ops_t* ops, void* data) devfs_file_desc_t files[] = { { .name = "name", - .inodeOps = NULL, + .vnodeOps = NULL, .fileOps = &nameOps, .data = fb, }, { .name = "info", - .inodeOps = NULL, + .vnodeOps = NULL, .fileOps = &infoOps, .data = fb, }, { .name = "data", - .inodeOps = NULL, + .vnodeOps = NULL, .fileOps = &dataOps, .data = fb, }, diff --git a/src/kernel/drivers/abstract/kbd.c b/src/kernel/drivers/abstract/kbd.c index 30d6d6231..99eb276c9 100644 --- a/src/kernel/drivers/abstract/kbd.c +++ b/src/kernel/drivers/abstract/kbd.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include @@ -24,7 +24,7 @@ static atomic_uint64_t newId = ATOMIC_VAR_INIT(0); static size_t kbd_name_read(file_t* file, void* buffer, size_t count, size_t* offset) { - kbd_t* kbd = file->inode->data; + kbd_t* kbd = file->vnode->data; assert(kbd != NULL); size_t length = strlen(kbd->name); @@ -37,7 +37,7 @@ static file_ops_t nameOps = { static uint64_t kbd_events_open(file_t* file) { - kbd_t* kbd = file->inode->data; + kbd_t* kbd = file->vnode->data; assert(kbd != NULL); kbd_client_t* client = calloc(1, sizeof(kbd_client_t)); @@ -59,7 +59,7 @@ static uint64_t kbd_events_open(file_t* file) static void kbd_events_close(file_t* file) { - kbd_t* kbd = file->inode->data; + kbd_t* kbd = file->vnode->data; assert(kbd != NULL); kbd_client_t* client = file->data; @@ -84,7 +84,7 @@ static size_t kbd_events_read(file_t* file, void* buffer, size_t count, size_t* return 0; } - kbd_t* kbd = file->inode->data; + kbd_t* kbd = file->vnode->data; assert(kbd != NULL); kbd_client_t* client = file->data; assert(client != NULL); @@ -110,7 +110,7 @@ static size_t kbd_events_read(file_t* file, void* buffer, size_t count, size_t* static wait_queue_t* kbd_events_poll(file_t* file, poll_events_t* revents) { - kbd_t* kbd = file->inode->data; + kbd_t* kbd = file->vnode->data; assert(kbd != NULL); kbd_client_t* client = file->data; assert(client != NULL); @@ -131,9 +131,9 @@ static file_ops_t eventsOps = { .poll = kbd_events_poll, }; -static void kbd_dir_cleanup(inode_t* inode) +static void kbd_dir_cleanup(vnode_t* vnode) { - kbd_t* kbd = inode->data; + kbd_t* kbd = vnode->data; if (kbd == NULL) { return; @@ -143,7 +143,7 @@ static void kbd_dir_cleanup(inode_t* inode) free(kbd); } -static inode_ops_t dirInodeOps = { +static vnode_ops_t dirVnodeOps = { .cleanup = kbd_dir_cleanup, }; @@ -187,7 +187,7 @@ kbd_t* kbd_new(const char* name) return NULL; } - kbd->dir = devfs_dir_new(dir, id, &dirInodeOps, kbd); + kbd->dir = devfs_dir_new(dir, id, &dirVnodeOps, kbd); if (kbd->dir == NULL) { wait_queue_deinit(&kbd->waitQueue); diff --git a/src/kernel/drivers/abstract/mouse.c b/src/kernel/drivers/abstract/mouse.c index 42edf6285..86bf00ed3 100644 --- a/src/kernel/drivers/abstract/mouse.c +++ b/src/kernel/drivers/abstract/mouse.c @@ -18,7 +18,7 @@ static atomic_uint64_t newId = ATOMIC_VAR_INIT(0); static size_t mouse_name_read(file_t* file, void* buffer, size_t count, size_t* offset) { - mouse_t* mouse = file->inode->data; + mouse_t* mouse = file->vnode->data; assert(mouse != NULL); size_t length = strlen(mouse->name); @@ -31,7 +31,7 @@ static file_ops_t nameOps = { static uint64_t mouse_events_open(file_t* file) { - mouse_t* mouse = file->inode->data; + mouse_t* mouse = file->vnode->data; assert(mouse != NULL); mouse_client_t* client = calloc(1, sizeof(mouse_client_t)); @@ -53,7 +53,7 @@ static uint64_t mouse_events_open(file_t* file) static void mouse_events_close(file_t* file) { - mouse_t* mouse = file->inode->data; + mouse_t* mouse = file->vnode->data; assert(mouse != NULL); mouse_client_t* client = file->data; @@ -78,7 +78,7 @@ static size_t mouse_events_read(file_t* file, void* buffer, size_t count, size_t return 0; } - mouse_t* mouse = file->inode->data; + mouse_t* mouse = file->vnode->data; assert(mouse != NULL); mouse_client_t* client = file->data; assert(client != NULL); @@ -104,7 +104,7 @@ static size_t mouse_events_read(file_t* file, void* buffer, size_t count, size_t static wait_queue_t* mouse_events_poll(file_t* file, poll_events_t* revents) { - mouse_t* mouse = file->inode->data; + mouse_t* mouse = file->vnode->data; assert(mouse != NULL); mouse_client_t* client = file->data; assert(client != NULL); @@ -125,9 +125,9 @@ static file_ops_t eventsOps = { .poll = mouse_events_poll, }; -static void mouse_dir_cleanup(inode_t* inode) +static void mouse_dir_cleanup(vnode_t* vnode) { - mouse_t* mouse = inode->data; + mouse_t* mouse = vnode->data; if (mouse == NULL) { return; @@ -137,7 +137,7 @@ static void mouse_dir_cleanup(inode_t* inode) free(mouse); } -static inode_ops_t dirInodeOps = { +static vnode_ops_t dirVnodeOps = { .cleanup = mouse_dir_cleanup, }; @@ -181,7 +181,7 @@ mouse_t* mouse_new(const char* name) return NULL; } - mouse->dir = devfs_dir_new(dir, id, &dirInodeOps, mouse); + mouse->dir = devfs_dir_new(dir, id, &dirVnodeOps, mouse); if (mouse->dir == NULL) { wait_queue_deinit(&mouse->waitQueue); diff --git a/src/kernel/drivers/com.c b/src/kernel/drivers/com.c index eb9893d04..bd3678d96 100644 --- a/src/kernel/drivers/com.c +++ b/src/kernel/drivers/com.c @@ -1,4 +1,4 @@ -#include +#include #include void com_init(com_port_t port) @@ -31,10 +31,10 @@ void com_write(com_port_t port, uint8_t value) uint8_t com_reg_read(com_port_t port, com_reg_t reg) { - return io_in8(port + reg); + return in8(port + reg); } void com_reg_write(com_port_t port, com_reg_t reg, uint8_t value) { - io_out8(port + reg, value); + out8(port + reg, value); } diff --git a/src/kernel/drivers/perf.c b/src/kernel/drivers/perf.c index b38b255a0..0adc9d8e3 100644 --- a/src/kernel/drivers/perf.c +++ b/src/kernel/drivers/perf.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -116,8 +116,8 @@ static size_t perf_mem_read(file_t* file, void* buffer, size_t count, size_t* of return ERR; } - int length = sprintf(string, "total_pages %lu\nfree_pages %lu\nused_pages %lu", pmm_total_amount(), - pmm_free_amount(), pmm_used_amount()); + int length = sprintf(string, "total_pages %lu\nfree_pages %lu\nused_pages %lu", pmm_total_pages(), + pmm_avail_pages(), pmm_used_pages()); if (length < 0) { free(string); diff --git a/src/kernel/drivers/pic.c b/src/kernel/drivers/pic.c index 91a3f2dbc..48be515b2 100644 --- a/src/kernel/drivers/pic.c +++ b/src/kernel/drivers/pic.c @@ -2,12 +2,12 @@ #include #include -#include +#include #include static void pic_wait(void) { - io_out8(0x80, 0); + out8(0x80, 0); } void pic_disable(void) @@ -15,39 +15,39 @@ void pic_disable(void) // We initialize the PIC before we then mask all interrupts. // Probably not needed but it ensures that the PIC is in a known state before we disable it. - uint8_t a1 = io_in8(PIC1_DATA); + uint8_t a1 = in8(PIC1_DATA); pic_wait(); - uint8_t a2 = io_in8(PIC2_DATA); + uint8_t a2 = in8(PIC2_DATA); pic_wait(); - io_out8(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); + out8(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); pic_wait(); - io_out8(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + out8(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); pic_wait(); - io_out8(PIC1_DATA, VECTOR_EXTERNAL_START); + out8(PIC1_DATA, VECTOR_EXTERNAL_START); pic_wait(); - io_out8(PIC2_DATA, VECTOR_EXTERNAL_START + 0x8); + out8(PIC2_DATA, VECTOR_EXTERNAL_START + 0x8); pic_wait(); - io_out8(PIC1_DATA, 4); + out8(PIC1_DATA, 4); pic_wait(); - io_out8(PIC2_DATA, 2); + out8(PIC2_DATA, 2); pic_wait(); - io_out8(PIC1_DATA, ICW4_8086); + out8(PIC1_DATA, ICW4_8086); pic_wait(); - io_out8(PIC2_DATA, ICW4_8086); + out8(PIC2_DATA, ICW4_8086); pic_wait(); - io_out8(PIC1_DATA, a1); + out8(PIC1_DATA, a1); pic_wait(); - io_out8(PIC2_DATA, a2); + out8(PIC2_DATA, a2); pic_wait(); // Mask all interrupts. - io_out8(PIC1_DATA, 0xFF); - io_out8(PIC2_DATA, 0xFF); + out8(PIC1_DATA, 0xFF); + out8(PIC2_DATA, 0xFF); LOG_INFO("pic disabled\n"); } diff --git a/src/kernel/fs/dentry.c b/src/kernel/fs/dentry.c index 3712de65f..358fe0c8c 100644 --- a/src/kernel/fs/dentry.c +++ b/src/kernel/fs/dentry.c @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include #include #include @@ -80,11 +80,11 @@ static void dentry_free(dentry_t* dentry) if (!DENTRY_IS_ROOT(dentry)) { assert(dentry->parent != NULL); - assert(dentry->parent->inode != NULL); + assert(dentry->parent->vnode != NULL); - mutex_acquire(&dentry->parent->inode->mutex); + mutex_acquire(&dentry->parent->vnode->mutex); list_remove(&dentry->siblingEntry); - mutex_release(&dentry->parent->inode->mutex); + mutex_release(&dentry->parent->vnode->mutex); UNREF(dentry->parent); dentry->parent = NULL; @@ -96,11 +96,11 @@ static void dentry_free(dentry_t* dentry) } dentry->data = NULL; - if (dentry->inode != NULL) + if (dentry->vnode != NULL) { - atomic_fetch_sub_explicit(&dentry->inode->dentryCount, 1, memory_order_relaxed); - UNREF(dentry->inode); - dentry->inode = NULL; + atomic_fetch_sub_explicit(&dentry->vnode->dentryCount, 1, memory_order_relaxed); + UNREF(dentry->vnode); + dentry->vnode = NULL; } UNREF(dentry->superblock); @@ -116,7 +116,7 @@ static void dentry_ctor(void* ptr) dentry->ref = (ref_t){0}; dentry->id = vfs_id_get(); dentry->name[0] = '\0'; - dentry->inode = NULL; + dentry->vnode = NULL; dentry->parent = NULL; list_entry_init(&dentry->siblingEntry); list_init(&dentry->children); @@ -262,7 +262,7 @@ dentry_t* dentry_lookup(dentry_t* parent, const char* name, size_t length) assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); - inode_t* dir = parent->inode; + vnode_t* dir = parent->vnode; if (dir->ops == NULL || dir->ops->lookup == NULL) { return dentry; // Leave it as negative. @@ -286,15 +286,15 @@ dentry_t* dentry_lookup(dentry_t* parent, const char* name, size_t length) return dentry; } -void dentry_make_positive(dentry_t* dentry, inode_t* inode) +void dentry_make_positive(dentry_t* dentry, vnode_t* vnode) { - if (dentry == NULL || inode == NULL) + if (dentry == NULL || vnode == NULL) { return; } - atomic_fetch_add_explicit(&inode->dentryCount, 1, memory_order_relaxed); - dentry->inode = REF(inode); + atomic_fetch_add_explicit(&vnode->dentryCount, 1, memory_order_relaxed); + dentry->vnode = REF(vnode); if (!DENTRY_IS_ROOT(dentry)) { list_push_back(&dentry->parent->children, &dentry->siblingEntry); @@ -305,7 +305,7 @@ bool dentry_iterate_dots(dentry_t* dentry, dir_ctx_t* ctx) { if (ctx->index++ >= ctx->pos) { - if (!ctx->emit(ctx, ".", dentry->inode->number, dentry->inode->type)) + if (!ctx->emit(ctx, ".", dentry->vnode->type)) { return false; } @@ -313,7 +313,7 @@ bool dentry_iterate_dots(dentry_t* dentry, dir_ctx_t* ctx) if (ctx->index++ >= ctx->pos) { - if (!ctx->emit(ctx, "..", dentry->parent->inode->number, dentry->parent->inode->type)) + if (!ctx->emit(ctx, "..", dentry->parent->vnode->type)) { return false; } @@ -335,7 +335,7 @@ uint64_t dentry_generic_iterate(dentry_t* dentry, dir_ctx_t* ctx) if (ctx->index++ >= ctx->pos) { assert(DENTRY_IS_POSITIVE(child)); - if (!ctx->emit(ctx, child->name, child->inode->number, child->inode->type)) + if (!ctx->emit(ctx, child->name, child->vnode->type)) { return 0; } diff --git a/src/kernel/fs/devfs.c b/src/kernel/fs/devfs.c index 986774023..336fcdc4f 100644 --- a/src/kernel/fs/devfs.c +++ b/src/kernel/fs/devfs.c @@ -3,12 +3,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -19,20 +19,16 @@ #include #include #include -#include +#include #include static dentry_t* root = NULL; -static file_ops_t dirOps = { - .seek = file_generic_seek, -}; - static dentry_ops_t dentryOps = { .iterate = dentry_generic_iterate, }; -static dentry_t* devfs_mount(filesystem_t* fs, const char* options, void* data) +static dentry_t* devfs_mount(filesystem_t* fs, const char* options, void* data) { UNUSED(fs); UNUSED(data); @@ -65,12 +61,12 @@ void devfs_init(void) } UNREF_DEFER(superblock); - inode_t* inode = inode_new(superblock, vfs_id_get(), INODE_DIR, NULL, &dirOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(superblock, VDIR, NULL, NULL); + if (vnode == NULL) { - panic(NULL, "Failed to create devfs root inode"); + panic(NULL, "Failed to create devfs root vnode"); } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); dentry_t* dentry = dentry_new(superblock, NULL, NULL); if (dentry == NULL) @@ -78,12 +74,12 @@ void devfs_init(void) panic(NULL, "Failed to create devfs root dentry"); } - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); superblock->root = dentry; root = dentry; } -dentry_t* devfs_dir_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* data) +dentry_t* devfs_dir_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, void* data) { if (name == NULL) { @@ -109,21 +105,21 @@ dentry_t* devfs_dir_new(dentry_t* parent, const char* name, const inode_ops_t* i } UNREF_DEFER(dir); - inode_t* inode = inode_new(parent->superblock, vfs_id_get(), INODE_DIR, inodeOps, &dirOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(parent->superblock, VDIR, vnodeOps, NULL); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); - inode->data = data; + UNREF_DEFER(vnode); + vnode->data = data; - dentry_make_positive(dir, inode); + dentry_make_positive(dir, vnode); return REF(dir); } -dentry_t* devfs_file_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, const file_ops_t* fileOps, - void* data) +dentry_t* devfs_file_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, const file_ops_t* fileOps, + void* data) { if (name == NULL) { @@ -149,22 +145,22 @@ dentry_t* devfs_file_new(dentry_t* parent, const char* name, const inode_ops_t* } UNREF_DEFER(dentry); - inode_t* inode = inode_new(parent->superblock, vfs_id_get(), INODE_FILE, inodeOps, fileOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(parent->superblock, VREG, vnodeOps, fileOps); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); - inode->data = data; + UNREF_DEFER(vnode); + vnode->data = data; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return REF(dentry); } -dentry_t* devfs_symlink_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* data) +dentry_t* devfs_symlink_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, void* data) { - if (parent == NULL || name == NULL || inodeOps == NULL) + if (parent == NULL || name == NULL || vnodeOps == NULL) { errno = EINVAL; return NULL; @@ -183,15 +179,15 @@ dentry_t* devfs_symlink_new(dentry_t* parent, const char* name, const inode_ops_ } UNREF_DEFER(dentry); - inode_t* inode = inode_new(parent->superblock, vfs_id_get(), INODE_SYMLINK, inodeOps, NULL); - if (inode == NULL) + vnode_t* vnode = vnode_new(parent->superblock, VSYMLINK, vnodeOps, NULL); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); - inode->data = data; + UNREF_DEFER(vnode); + vnode->data = data; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return REF(dentry); } @@ -220,7 +216,7 @@ uint64_t devfs_files_new(list_t* out, dentry_t* parent, const devfs_file_desc_t* uint64_t count = 0; for (const devfs_file_desc_t* desc = descs; desc->name != NULL; desc++) { - dentry_t* file = devfs_file_new(parent, desc->name, desc->inodeOps, desc->fileOps, desc->data); + dentry_t* file = devfs_file_new(parent, desc->name, desc->vnodeOps, desc->fileOps, desc->data); if (file == NULL) { while (!list_is_empty(&createdList)) diff --git a/src/kernel/fs/file.c b/src/kernel/fs/file.c index 110683ab8..c02cdc882 100644 --- a/src/kernel/fs/file.c +++ b/src/kernel/fs/file.c @@ -1,10 +1,15 @@ #include #include -#include +#include #include #include +#include +#include +#include #include +#include +#include #include #include @@ -23,8 +28,8 @@ static void file_free(file_t* file) file->ops->close(file); } - UNREF(file->inode); - file->inode = NULL; + UNREF(file->vnode); + file->vnode = NULL; path_put(&file->path); cache_free(file); @@ -61,16 +66,16 @@ file_t* file_new(const path_t* path, mode_t mode) ref_init(&file->ref, file_free); file->pos = 0; file->mode = mode; - file->inode = REF(path->dentry->inode); + file->vnode = REF(path->dentry->vnode); file->path = PATH_CREATE(path->mount, path->dentry); - file->ops = path->dentry->inode->fileOps; + file->ops = path->dentry->vnode->fileOps; file->data = NULL; return file; } size_t file_generic_seek(file_t* file, ssize_t offset, seek_origin_t origin) { - MUTEX_SCOPE(&file->inode->mutex); + MUTEX_SCOPE(&file->vnode->mutex); size_t newPos; switch (origin) @@ -82,7 +87,7 @@ size_t file_generic_seek(file_t* file, ssize_t offset, seek_origin_t origin) newPos = file->pos + offset; break; case SEEK_END: - newPos = file->inode->size + offset; + newPos = file->vnode->size + offset; break; default: errno = EINVAL; @@ -91,4 +96,4 @@ size_t file_generic_seek(file_t* file, ssize_t offset, seek_origin_t origin) file->pos = newPos; return newPos; -} +} \ No newline at end of file diff --git a/src/kernel/fs/filesystem.c b/src/kernel/fs/filesystem.c index 9fb4b28aa..7c9b12f65 100644 --- a/src/kernel/fs/filesystem.c +++ b/src/kernel/fs/filesystem.c @@ -4,12 +4,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include static dentry_t* dir = NULL; @@ -44,7 +44,7 @@ static map_key_t filesystem_key(const char* name) static size_t superblock_read(file_t* file, void* buffer, size_t count, size_t* offset) { - superblock_t* sb = file->inode->data; + superblock_t* sb = file->vnode->data; assert(sb != NULL); char info[MAX_PATH]; @@ -58,27 +58,27 @@ static size_t superblock_read(file_t* file, void* buffer, size_t count, size_t* return BUFFER_READ(buffer, count, offset, info, (size_t)length); } -static void superblock_cleanup(inode_t* inode) +static void superblock_cleanup(vnode_t* vnode) { - superblock_t* sb = inode->data; + superblock_t* sb = vnode->data; if (sb == NULL) { return; } UNREF(sb); - inode->data = NULL; + vnode->data = NULL; } static file_ops_t sbFileOps = { .read = superblock_read, }; -static inode_ops_t sbInodeOps = { +static vnode_ops_t sbVnodeOps = { .cleanup = superblock_cleanup, }; -static uint64_t filesystem_lookup(inode_t* dir, dentry_t* dentry) +static uint64_t filesystem_lookup(vnode_t* dir, dentry_t* dentry) { filesystem_t* fs = dir->data; assert(fs != NULL); @@ -99,14 +99,13 @@ static uint64_t filesystem_lookup(inode_t* dir, dentry_t* dentry) continue; } - inode_t* inode = - inode_new(dentry->superblock, ino_gen(dir->number, dentry->name), INODE_FILE, NULL, &sbFileOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(dentry->superblock, VREG, NULL, &sbFileOps); + if (vnode == NULL) { return ERR; } - inode->data = REF(sb); - dentry_make_positive(dentry, inode); + vnode->data = REF(sb); + dentry_make_positive(dentry, vnode); return 0; } @@ -120,7 +119,7 @@ static uint64_t filesystem_iterate(dentry_t* dentry, dir_ctx_t* ctx) return 0; } - filesystem_t* fs = dentry->inode->data; + filesystem_t* fs = dentry->vnode->data; assert(fs != NULL); RWLOCK_READ_SCOPE(&fs->lock); @@ -136,7 +135,7 @@ static uint64_t filesystem_iterate(dentry_t* dentry, dir_ctx_t* ctx) char name[MAX_NAME]; snprintf(name, MAX_NAME, "%llu", sb->id); - if (!ctx->emit(ctx, name, ino_gen(dentry->inode->number, name), INODE_FILE)) + if (!ctx->emit(ctx, name, VREG)) { return 0; } @@ -145,7 +144,7 @@ static uint64_t filesystem_iterate(dentry_t* dentry, dir_ctx_t* ctx) return 0; } -static inode_ops_t fsInodeOps = { +static vnode_ops_t fsVnodeOps = { .lookup = filesystem_lookup, }; @@ -153,8 +152,10 @@ static dentry_ops_t fsDentryOps = { .iterate = filesystem_iterate, }; -static uint64_t filesystem_dir_lookup(inode_t* dir, dentry_t* dentry) +static uint64_t filesystem_dir_lookup(vnode_t* dir, dentry_t* dentry) { + UNUSED(dir); + RWLOCK_READ_SCOPE(&lock); map_key_t key = filesystem_key(dentry->name); @@ -164,16 +165,16 @@ static uint64_t filesystem_dir_lookup(inode_t* dir, dentry_t* dentry) return 0; } - inode_t* inode = inode_new(dentry->superblock, ino_gen(dir->number, fs->name), INODE_DIR, &fsInodeOps, NULL); - if (inode == NULL) + vnode_t* vnode = vnode_new(dentry->superblock, VDIR, &fsVnodeOps, NULL); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); - inode->data = fs; + UNREF_DEFER(vnode); + vnode->data = fs; dentry->ops = &fsDentryOps; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return 0; } @@ -194,7 +195,7 @@ static uint64_t filesystem_dir_iterate(dentry_t* dentry, dir_ctx_t* ctx) continue; } - if (!ctx->emit(ctx, fs->name, ino_gen(dentry->inode->number, fs->name), INODE_DIR)) + if (!ctx->emit(ctx, fs->name, VDIR)) { return 0; } @@ -203,7 +204,7 @@ static uint64_t filesystem_dir_iterate(dentry_t* dentry, dir_ctx_t* ctx) return 0; } -static inode_ops_t dirInodeOps = { +static vnode_ops_t dirVnodeOps = { .lookup = filesystem_dir_lookup, }; @@ -221,7 +222,7 @@ void filesystem_expose(void) return; } - dir = sysfs_dir_new(NULL, "fs", &dirInodeOps, NULL); + dir = sysfs_dir_new(NULL, "fs", &dirVnodeOps, NULL); if (dir == NULL) { panic(NULL, "failed to expose filesystem sysfs directory"); @@ -320,7 +321,7 @@ filesystem_t* filesystem_get_by_path(const char* path, process_t* process) return NULL; } - return target.dentry->inode->data; + return target.dentry->vnode->data; } bool options_next(const char** iter, char* buffer, size_t size, char** key, char** value) diff --git a/src/kernel/fs/inode.c b/src/kernel/fs/inode.c deleted file mode 100644 index 3ba31d3ed..000000000 --- a/src/kernel/fs/inode.c +++ /dev/null @@ -1,147 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -#include - -static void inode_free(inode_t* inode) -{ - if (inode == NULL) - { - return; - } - - if (inode->ops != NULL && inode->ops->cleanup != NULL) - { - inode->ops->cleanup(inode); - } - inode->data = NULL; - - if (inode->superblock != NULL) - { - UNREF(inode->superblock); - inode->superblock = NULL; - } - - rcu_call(&inode->rcu, rcu_call_cache_free, inode); -} - -static void inode_ctor(void* ptr) -{ - inode_t* inode = (inode_t*)ptr; - - inode->ref = (ref_t){0}; - inode->number = 0; - inode->type = 0; - atomic_init(&inode->dentryCount, 0); - inode->size = 0; - inode->blocks = 0; - inode->accessTime = 0; - inode->modifyTime = 0; - inode->changeTime = 0; - inode->createTime = 0; - inode->data = NULL; - inode->superblock = NULL; - inode->ops = NULL; - inode->fileOps = NULL; - inode->rcu = (rcu_entry_t){0}; - mutex_init(&inode->mutex); -} - -static cache_t cache = CACHE_CREATE(cache, "inode", sizeof(inode_t), CACHE_LINE, inode_ctor, NULL); - -inode_t* inode_new(superblock_t* superblock, ino_t number, itype_t type, const inode_ops_t* ops, - const file_ops_t* fileOps) -{ - if (superblock == NULL) - { - errno = EINVAL; - return NULL; - } - - inode_t* inode = cache_alloc(&cache); - if (inode == NULL) - { - errno = ENOMEM; - return NULL; - } - - ref_init(&inode->ref, inode_free); - inode->number = number; - inode->type = type; - inode->superblock = REF(superblock); - inode->ops = ops; - inode->fileOps = fileOps; - return inode; -} - -void inode_notify_access(inode_t* inode) -{ - if (inode == NULL) - { - return; - } - - MUTEX_SCOPE(&inode->mutex); - - inode->accessTime = clock_epoch(); -} - -void inode_notify_modify(inode_t* inode) -{ - if (inode == NULL) - { - return; - } - - MUTEX_SCOPE(&inode->mutex); - inode->modifyTime = clock_epoch(); - inode->changeTime = inode->modifyTime; -} - -void inode_notify_change(inode_t* inode) -{ - if (inode == NULL) - { - return; - } - - MUTEX_SCOPE(&inode->mutex); - inode->changeTime = clock_epoch(); -} - -void inode_truncate(inode_t* inode) -{ - if (inode == NULL) - { - return; - } - - if (inode->ops != NULL && inode->ops->truncate != NULL) - { - MUTEX_SCOPE(&inode->mutex); - assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); - inode->ops->truncate(inode); - } -} - -ino_t ino_gen(ino_t parentNumber, const char* name) -{ - uint64_t hash = 0xcbf29ce484222325; - const uint64_t prime = 0x100000001b3; - - hash ^= parentNumber; - hash *= prime; - - while (*name != '\0') - { - hash ^= (uint8_t)*name++; - hash *= prime; - } - - return hash; -} \ No newline at end of file diff --git a/src/kernel/fs/namespace.c b/src/kernel/fs/namespace.c index b222ae2d5..cc0413cdf 100644 --- a/src/kernel/fs/namespace.c +++ b/src/kernel/fs/namespace.c @@ -16,7 +16,7 @@ #include #include -#include +#include #include static map_key_t mount_key(mount_id_t parentId, dentry_id_t mountpointId) @@ -385,7 +385,7 @@ bool namespace_rcu_traverse(namespace_t* ns, mount_t** mount, dentry_t** dentry) } mount_t* namespace_mount(namespace_t* ns, path_t* target, filesystem_t* fs, const char* options, mode_t mode, - void* data) + void* data) { if (ns == NULL || fs == NULL) { diff --git a/src/kernel/fs/netfs.c b/src/kernel/fs/netfs.c index 1b019bba9..70cf82aae 100644 --- a/src/kernel/fs/netfs.c +++ b/src/kernel/fs/netfs.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include static list_t families = LIST_CREATE(families); @@ -72,7 +72,7 @@ typedef struct socket_file static uint64_t netfs_data_open(file_t* file) { - socket_t* sock = file->inode->data; + socket_t* sock = file->vnode->data; assert(sock != NULL); file->data = REF(sock); @@ -160,7 +160,7 @@ static file_ops_t dataOps = { static uint64_t netfs_accept_open(file_t* file) { - socket_t* sock = file->inode->data; + socket_t* sock = file->vnode->data; assert(sock != NULL); if (sock->family->accept == NULL) @@ -203,7 +203,7 @@ static uint64_t netfs_ctl_bind(file_t* file, uint64_t argc, const char** argv) { UNUSED(argc); - socket_t* sock = file->inode->data; + socket_t* sock = file->vnode->data; assert(sock != NULL); if (sock->family->bind == NULL) @@ -252,7 +252,7 @@ static uint64_t netfs_ctl_listen(file_t* file, uint64_t argc, const char** argv) } } - socket_t* sock = file->inode->data; + socket_t* sock = file->vnode->data; assert(sock != NULL); if (sock->family->listen == NULL) @@ -282,7 +282,7 @@ static uint64_t netfs_ctl_connect(file_t* file, uint64_t argc, const char** argv { UNUSED(argc); - socket_t* sock = file->inode->data; + socket_t* sock = file->vnode->data; assert(sock != NULL); if (sock->family->connect == NULL) @@ -325,7 +325,7 @@ static socket_file_t socketFiles[] = { {.name = "ctl", .fileOps = &ctlOps}, }; -static uint64_t netfs_socket_lookup(inode_t* dir, dentry_t* dentry) +static uint64_t netfs_socket_lookup(vnode_t* dir, dentry_t* dentry) { for (size_t i = 0; i < ARRAY_SIZE(socketFiles); i++) { @@ -334,25 +334,24 @@ static uint64_t netfs_socket_lookup(inode_t* dir, dentry_t* dentry) continue; } - inode_t* inode = inode_new(dir->superblock, ino_gen(dir->number, socketFiles[i].name), INODE_FILE, NULL, - socketFiles[i].fileOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(dir->superblock, VREG, NULL, socketFiles[i].fileOps); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); - inode->data = dir->data; // No reference + UNREF_DEFER(vnode); + vnode->data = dir->data; // No reference - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return 0; } return 0; } -static void netfs_socket_cleanup(inode_t* inode) +static void netfs_socket_cleanup(vnode_t* vnode) { - socket_t* socket = (socket_t*)inode->data; + socket_t* socket = (socket_t*)vnode->data; if (socket == NULL) { return; @@ -375,7 +374,7 @@ static uint64_t netfs_socket_iterate(dentry_t* dentry, dir_ctx_t* ctx) continue; } - if (!ctx->emit(ctx, socketFiles[i].name, ino_gen(dentry->inode->number, socketFiles[i].name), INODE_FILE)) + if (!ctx->emit(ctx, socketFiles[i].name, VREG)) { return 0; } @@ -384,7 +383,7 @@ static uint64_t netfs_socket_iterate(dentry_t* dentry, dir_ctx_t* ctx) return 0; } -static inode_ops_t socketInodeOps = { +static vnode_ops_t socketVnodeOps = { .lookup = netfs_socket_lookup, .cleanup = netfs_socket_cleanup, }; @@ -414,9 +413,9 @@ static void socket_weak_ptr_callback(void* arg) static uint64_t netfs_factory_open(file_t* file) { - netfs_family_file_ctx_t* ctx = file->inode->data; + netfs_family_file_ctx_t* ctx = file->vnode->data; assert(ctx != NULL); - dentry_t* root = file->inode->superblock->root; + dentry_t* root = file->vnode->superblock->root; assert(root != NULL); socket_t* socket = socket_new(ctx->family, ctx->fileInfo->type); @@ -473,7 +472,7 @@ static file_ops_t factoryFileOps = { static size_t netfs_addrs_read(file_t* file, void* buffer, size_t count, size_t* offset) { - netfs_family_file_ctx_t* ctx = file->inode->data; + netfs_family_file_ctx_t* ctx = file->vnode->data; assert(ctx != NULL); RWMUTEX_READ_SCOPE(&ctx->family->mutex); @@ -525,23 +524,23 @@ static netfs_family_file_t familyFiles[] = { {.name = "addrs", .type = 0, .fileOps = &addrsFileOps}, }; -static void netfs_file_cleanup(inode_t* inode) +static void netfs_file_cleanup(vnode_t* vnode) { - netfs_family_file_ctx_t* ctx = inode->data; + netfs_family_file_ctx_t* ctx = vnode->data; if (ctx == NULL) { return; } free(ctx); - inode->data = NULL; + vnode->data = NULL; } -static inode_ops_t familyFileInodeOps = { +static vnode_ops_t familyFileVnodeOps = { .cleanup = netfs_file_cleanup, }; -static uint64_t netfs_family_lookup(inode_t* dir, dentry_t* dentry) +static uint64_t netfs_family_lookup(vnode_t* dir, dentry_t* dentry) { netfs_family_t* family = dir->data; assert(family != NULL); @@ -553,13 +552,12 @@ static uint64_t netfs_family_lookup(inode_t* dir, dentry_t* dentry) continue; } - inode_t* inode = inode_new(dir->superblock, ino_gen(dir->number, familyFiles[i].name), INODE_FILE, - &familyFileInodeOps, familyFiles[i].fileOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(dir->superblock, VREG, &familyFileVnodeOps, familyFiles[i].fileOps); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); netfs_family_file_ctx_t* ctx = malloc(sizeof(netfs_family_file_ctx_t)); if (ctx == NULL) @@ -568,9 +566,9 @@ static uint64_t netfs_family_lookup(inode_t* dir, dentry_t* dentry) } ctx->family = family; ctx->fileInfo = &familyFiles[i]; - inode->data = ctx; + vnode->data = ctx; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return 0; } @@ -608,17 +606,17 @@ static uint64_t netfs_family_lookup(inode_t* dir, dentry_t* dentry) continue; } - inode_t* inode = inode_new(dir->superblock, ino_gen(dir->number, socket->id), INODE_DIR, &socketInodeOps, NULL); - if (inode == NULL) + vnode_t* vnode = vnode_new(dir->superblock, VDIR, &socketVnodeOps, NULL); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); - inode->data = REF(socket); + UNREF_DEFER(vnode); + vnode->data = REF(socket); dentry->ops = &socketDentryOps; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return 0; } @@ -627,7 +625,7 @@ static uint64_t netfs_family_lookup(inode_t* dir, dentry_t* dentry) static uint64_t netfs_family_iterate(dentry_t* dentry, dir_ctx_t* ctx) { - netfs_family_t* family = dentry->inode->data; + netfs_family_t* family = dentry->vnode->data; assert(family != NULL); if (!dentry_iterate_dots(dentry, ctx)) @@ -642,7 +640,7 @@ static uint64_t netfs_family_iterate(dentry_t* dentry, dir_ctx_t* ctx) continue; } - if (!ctx->emit(ctx, familyFiles[i].name, ino_gen(dentry->inode->number, familyFiles[i].name), INODE_FILE)) + if (!ctx->emit(ctx, familyFiles[i].name, VREG)) { return 0; } @@ -682,7 +680,7 @@ static uint64_t netfs_family_iterate(dentry_t* dentry, dir_ctx_t* ctx) continue; } - if (!ctx->emit(ctx, socket->id, ino_gen(dentry->inode->number, socket->id), INODE_DIR)) + if (!ctx->emit(ctx, socket->id, VDIR)) { return 0; } @@ -691,7 +689,7 @@ static uint64_t netfs_family_iterate(dentry_t* dentry, dir_ctx_t* ctx) return 0; } -static inode_ops_t familyInodeOps = { +static vnode_ops_t familyVnodeOps = { .lookup = netfs_family_lookup, }; @@ -699,7 +697,7 @@ static dentry_ops_t familyDentryOps = { .iterate = netfs_family_iterate, }; -static uint64_t netfs_lookup(inode_t* dir, dentry_t* dentry) +static uint64_t netfs_lookup(vnode_t* dir, dentry_t* dentry) { RWMUTEX_READ_SCOPE(&familiesMutex); @@ -711,18 +709,17 @@ static uint64_t netfs_lookup(inode_t* dir, dentry_t* dentry) continue; } - inode_t* inode = - inode_new(dir->superblock, ino_gen(dir->number, family->name), INODE_DIR, &familyInodeOps, NULL); - if (inode == NULL) + vnode_t* vnode = vnode_new(dir->superblock, VDIR, &familyVnodeOps, NULL); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); - inode->data = family; + UNREF_DEFER(vnode); + vnode->data = family; dentry->ops = &familyDentryOps; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return 0; } @@ -746,7 +743,7 @@ static uint64_t netfs_iterate(dentry_t* dentry, dir_ctx_t* ctx) continue; } - if (!ctx->emit(ctx, family->name, ino_gen(dentry->inode->number, family->name), INODE_DIR)) + if (!ctx->emit(ctx, family->name, VDIR)) { return 0; } @@ -755,7 +752,7 @@ static uint64_t netfs_iterate(dentry_t* dentry, dir_ctx_t* ctx) return 0; } -static inode_ops_t netInodeOps = { +static vnode_ops_t netVnodeOps = { .lookup = netfs_lookup, }; @@ -763,7 +760,7 @@ static dentry_ops_t netDentryOps = { .iterate = netfs_iterate, }; -static dentry_t* netfs_mount(filesystem_t* fs, const char* options, void* data) +static dentry_t* netfs_mount(filesystem_t* fs, const char* options, void* data) { UNUSED(data); @@ -780,12 +777,12 @@ static dentry_t* netfs_mount(filesystem_t* fs, const char* options, void* data) } UNREF_DEFER(superblock); - inode_t* inode = inode_new(superblock, 0, INODE_DIR, &netInodeOps, NULL); - if (inode == NULL) + vnode_t* vnode = vnode_new(superblock, VDIR, &netVnodeOps, NULL); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); dentry_t* dentry = dentry_new(superblock, NULL, NULL); if (dentry == NULL) @@ -794,7 +791,7 @@ static dentry_t* netfs_mount(filesystem_t* fs, const char* options, void* data) } dentry->ops = &netDentryOps; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); superblock->root = dentry; return superblock->root; diff --git a/src/kernel/fs/path.c b/src/kernel/fs/path.c index 04e13d3cd..61e37d7fd 100644 --- a/src/kernel/fs/path.c +++ b/src/kernel/fs/path.c @@ -1,4 +1,4 @@ -#include <_internal/MAX_PATH.h> +#include <_libstd/MAX_PATH.h> #include #include @@ -432,7 +432,7 @@ static uint64_t path_rcu_symlink(path_walk_ctx_t* ctx, dentry_t* symlink) } char symlinkPath[MAX_PATH]; - size_t readCount = vfs_readlink(symlink->inode, symlinkPath, MAX_PATH - 1); + size_t readCount = vfs_readlink(symlink->vnode, symlinkPath, MAX_PATH - 1); path_walk_release(ctx); diff --git a/src/kernel/fs/procfs.c b/src/kernel/fs/procfs.c index da3b38a4b..4ea66d5d5 100644 --- a/src/kernel/fs/procfs.c +++ b/src/kernel/fs/procfs.c @@ -1,16 +1,16 @@ -#include <_internal/MAX_NAME.h> +#include <_libstd/MAX_NAME.h> #include #include #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -24,14 +24,14 @@ #include #include #include -#include +#include #include static uint64_t procfs_revalidate_hide(dentry_t* dentry) { process_t* current = process_current(); assert(current != NULL); - process_t* process = dentry->inode->data; + process_t* process = dentry->vnode->data; assert(process != NULL); namespace_t* currentNs = process_get_ns(current); @@ -63,7 +63,7 @@ static dentry_ops_t hideDentryOps = { static size_t procfs_prio_read(file_t* file, void* buffer, size_t count, size_t* offset) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; priority_t priority = atomic_load(&process->priority); @@ -76,7 +76,7 @@ static size_t procfs_prio_write(file_t* file, const void* buffer, size_t count, { UNUSED(offset); - process_t* process = file->inode->data; + process_t* process = file->vnode->data; char prioStr[MAX_NAME]; if (count >= MAX_NAME) @@ -111,7 +111,7 @@ static file_ops_t prioOps = { static size_t procfs_cwd_read(file_t* file, void* buffer, size_t count, size_t* offset) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; namespace_t* ns = process_get_ns(process); if (ns == NULL) @@ -137,7 +137,7 @@ static size_t procfs_cwd_write(file_t* file, const void* buffer, size_t count, s { UNUSED(offset); - process_t* process = file->inode->data; + process_t* process = file->vnode->data; char cwdStr[MAX_PATH]; if (count >= MAX_PATH) @@ -193,7 +193,7 @@ static file_ops_t cwdOps = { static size_t procfs_cmdline_read(file_t* file, void* buffer, size_t count, size_t* offset) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; if (process->argv == NULL || process->argc == 0) { @@ -250,7 +250,7 @@ static size_t procfs_note_write(file_t* file, const void* buffer, size_t count, return ERR; } - process_t* process = file->inode->data; + process_t* process = file->vnode->data; RCU_READ_SCOPE(); @@ -289,7 +289,7 @@ static size_t procfs_notegroup_write(file_t* file, const void* buffer, size_t co errno = EINVAL; return ERR; } - process_t* process = file->inode->data; + process_t* process = file->vnode->data; char string[NOTE_MAX] = {0}; memcpy_s(string, NOTE_MAX, buffer, count); @@ -307,7 +307,7 @@ static file_ops_t notegroupOps = { static uint64_t procfs_group_open(file_t* file) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; group_t* group = group_get(&process->group); if (group == NULL) @@ -338,7 +338,7 @@ static file_ops_t groupOps = { static size_t procfs_pid_read(file_t* file, void* buffer, size_t count, size_t* offset) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; char pidStr[MAX_NAME]; uint32_t length = snprintf(pidStr, MAX_NAME, "%llu", process->id); @@ -351,7 +351,7 @@ static file_ops_t pidOps = { static size_t procfs_wait_read(file_t* file, void* buffer, size_t count, size_t* offset) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; if (WAIT_BLOCK(&process->dyingQueue, atomic_load(&process->flags) & PROCESS_DYING) == ERR) { @@ -366,7 +366,7 @@ static size_t procfs_wait_read(file_t* file, void* buffer, size_t count, size_t* static wait_queue_t* procfs_wait_poll(file_t* file, poll_events_t* revents) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; if (atomic_load(&process->flags) & PROCESS_DYING) { *revents |= POLLIN; @@ -383,7 +383,7 @@ static file_ops_t waitOps = { static size_t procfs_perf_read(file_t* file, void* buffer, size_t count, size_t* offset) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; size_t userPages = space_user_page_count(&process->space); RCU_READ_SCOPE(); @@ -413,7 +413,7 @@ static file_ops_t perfOps = { static uint64_t procfs_ns_open(file_t* file) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; namespace_t* ns = process_get_ns(process); if (ns == NULL) @@ -449,7 +449,7 @@ static uint64_t procfs_ctl_close(file_t* file, uint64_t argc, const char** argv) return ERR; } - process_t* process = file->inode->data; + process_t* process = file->vnode->data; if (argc == 2) { @@ -498,7 +498,7 @@ static uint64_t procfs_ctl_dup2(file_t* file, uint64_t argc, const char** argv) return ERR; } - process_t* process = file->inode->data; + process_t* process = file->vnode->data; fd_t oldFd; if (sscanf(argv[1], "%lld", &oldFd) != 1) @@ -530,7 +530,7 @@ static uint64_t procfs_ctl_bind(file_t* file, uint64_t argc, const char** argv) return ERR; } - process_t* process = file->inode->data; + process_t* process = file->vnode->data; process_t* writing = process_current(); pathname_t targetName; @@ -593,7 +593,7 @@ static uint64_t procfs_ctl_mount(file_t* file, uint64_t argc, const char** argv) } process_t* writing = process_current(); - process_t* process = file->inode->data; + process_t* process = file->vnode->data; pathname_t mountname; if (pathname_init(&mountname, argv[1]) == ERR) @@ -640,7 +640,7 @@ static uint64_t procfs_ctl_touch(file_t* file, uint64_t argc, const char** argv) return ERR; } - process_t* process = file->inode->data; + process_t* process = file->vnode->data; pathname_t pathname; if (pathname_init(&pathname, argv[1]) == ERR) @@ -667,7 +667,7 @@ static uint64_t procfs_ctl_start(file_t* file, uint64_t argc, const char** argv) return ERR; } - process_t* process = file->inode->data; + process_t* process = file->vnode->data; atomic_fetch_and(&process->flags, ~PROCESS_SUSPENDED); wait_unblock(&process->suspendQueue, WAIT_ALL, EOK); @@ -679,7 +679,7 @@ static uint64_t procfs_ctl_kill(file_t* file, uint64_t argc, const char** argv) { UNUSED(argv); - process_t* process = file->inode->data; + process_t* process = file->vnode->data; if (argc == 2) { @@ -700,7 +700,7 @@ static uint64_t procfs_ctl_setns(file_t* file, uint64_t argc, const char** argv) return ERR; } - process_t* process = file->inode->data; + process_t* process = file->vnode->data; fd_t fd; if (sscanf(argv[1], "%llu", &fd) != 1) @@ -741,7 +741,7 @@ static uint64_t procfs_ctl_setgroup(file_t* file, uint64_t argc, const char** ar return ERR; } - process_t* process = file->inode->data; + process_t* process = file->vnode->data; fd_t fd; if (sscanf(argv[1], "%llu", &fd) != 1) @@ -790,7 +790,7 @@ CTL_STANDARD_OPS_DEFINE(ctlOps, static size_t procfs_env_read(file_t* file, void* buffer, size_t count, size_t* offset) { - process_t* process = file->inode->data; + process_t* process = file->vnode->data; const char* value = env_get(&process->env, file->path.dentry->name); if (value == NULL) @@ -806,7 +806,7 @@ static size_t procfs_env_write(file_t* file, const void* buffer, size_t count, s { UNUSED(offset); - process_t* process = file->inode->data; + process_t* process = file->vnode->data; char value[MAX_NAME]; if (count >= MAX_NAME) @@ -831,7 +831,7 @@ static file_ops_t envVarOps = { .write = procfs_env_write, }; -static uint64_t procfs_env_lookup(inode_t* dir, dentry_t* target) +static uint64_t procfs_env_lookup(vnode_t* dir, dentry_t* target) { UNUSED(target); @@ -843,20 +843,20 @@ static uint64_t procfs_env_lookup(inode_t* dir, dentry_t* target) return 0; } - inode_t* inode = inode_new(dir->superblock, ino_gen(dir->number, target->name), INODE_FILE, NULL, &envVarOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(dir->superblock, VREG, NULL, &envVarOps); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); - inode->data = process; // No reference + UNREF_DEFER(vnode); + vnode->data = process; // No reference - dentry_make_positive(target, inode); + dentry_make_positive(target, vnode); return 0; } -static uint64_t procfs_env_create(inode_t* dir, dentry_t* target, mode_t mode) +static uint64_t procfs_env_create(vnode_t* dir, dentry_t* target, mode_t mode) { if (mode & MODE_DIRECTORY) { @@ -872,19 +872,19 @@ static uint64_t procfs_env_create(inode_t* dir, dentry_t* target, mode_t mode) return ERR; } - inode_t* inode = inode_new(dir->superblock, ino_gen(dir->number, target->name), INODE_FILE, NULL, &envVarOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(dir->superblock, VREG, NULL, &envVarOps); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); - inode->data = process; // No reference + UNREF_DEFER(vnode); + vnode->data = process; // No reference - dentry_make_positive(target, inode); + dentry_make_positive(target, vnode); return 0; } -static uint64_t procfs_env_remove(inode_t* dir, dentry_t* target) +static uint64_t procfs_env_remove(vnode_t* dir, dentry_t* target) { process_t* process = dir->data; assert(process != NULL); @@ -897,7 +897,7 @@ static uint64_t procfs_env_remove(inode_t* dir, dentry_t* target) return 0; } -static inode_ops_t envInodeOps = { +static vnode_ops_t envVnodeOps = { .lookup = procfs_env_lookup, .create = procfs_env_create, .remove = procfs_env_remove, @@ -910,7 +910,7 @@ static uint64_t procfs_env_iterate(dentry_t* dentry, dir_ctx_t* ctx) return 0; } - process_t* process = dentry->inode->data; + process_t* process = dentry->vnode->data; assert(process != NULL); MUTEX_SCOPE(&process->env.mutex); @@ -922,8 +922,7 @@ static uint64_t procfs_env_iterate(dentry_t* dentry, dir_ctx_t* ctx) continue; } - if (!ctx->emit(ctx, process->env.vars[i].key, ino_gen(dentry->inode->number, process->env.vars[i].key), - INODE_FILE)) + if (!ctx->emit(ctx, process->env.vars[i].key, VREG)) { return 0; } @@ -937,9 +936,9 @@ static dentry_ops_t envDentryOps = { .revalidate = procfs_revalidate_hide, }; -static uint64_t procfs_self_readlink(inode_t* inode, char* buffer, uint64_t count) +static uint64_t procfs_self_readlink(vnode_t* vnode, char* buffer, uint64_t count) { - UNUSED(inode); + UNUSED(vnode); process_t* process = process_current(); int ret = snprintf(buffer, count, "%llu", process->id); @@ -951,15 +950,15 @@ static uint64_t procfs_self_readlink(inode_t* inode, char* buffer, uint64_t coun return ret; } -static inode_ops_t selfOps = { +static vnode_ops_t selfOps = { .readlink = procfs_self_readlink, }; typedef struct { const char* name; - itype_t type; - const inode_ops_t* inodeOps; + vtype_t type; + const vnode_ops_t* vnodeOps; const file_ops_t* fileOps; const dentry_ops_t* dentryOps; } procfs_entry_t; @@ -967,70 +966,70 @@ typedef struct static const procfs_entry_t pidEntries[] = { { .name = "prio", - .type = INODE_FILE, + .type = VREG, .fileOps = &prioOps, .dentryOps = &hideDentryOps, }, { .name = "cwd", - .type = INODE_FILE, + .type = VREG, .fileOps = &cwdOps, .dentryOps = &hideDentryOps, }, { .name = "cmdline", - .type = INODE_FILE, + .type = VREG, .fileOps = &cmdlineOps, }, { .name = "note", - .type = INODE_FILE, + .type = VREG, .fileOps = ¬eOps, .dentryOps = &hideDentryOps, }, { .name = "notegroup", - .type = INODE_FILE, + .type = VREG, .fileOps = ¬egroupOps, .dentryOps = &hideDentryOps, }, { .name = "group", - .type = INODE_FILE, + .type = VREG, .fileOps = &groupOps, .dentryOps = &hideDentryOps, }, { .name = "pid", - .type = INODE_FILE, + .type = VREG, .fileOps = &pidOps, }, { .name = "wait", - .type = INODE_FILE, + .type = VREG, .fileOps = &waitOps, }, { .name = "perf", - .type = INODE_FILE, + .type = VREG, .fileOps = &perfOps, }, { .name = "ns", - .type = INODE_FILE, + .type = VREG, .fileOps = &nsOps, .dentryOps = &hideDentryOps, }, { .name = "ctl", - .type = INODE_FILE, + .type = VREG, .fileOps = &ctlOps, .dentryOps = &hideDentryOps, }, { .name = "env", - .type = INODE_DIR, - .inodeOps = &envInodeOps, + .type = VDIR, + .vnodeOps = &envVnodeOps, .dentryOps = &envDentryOps, }, }; @@ -1038,13 +1037,13 @@ static const procfs_entry_t pidEntries[] = { static procfs_entry_t procEntries[] = { { .name = "self", - .type = INODE_SYMLINK, - .inodeOps = &selfOps, + .type = VSYMLINK, + .vnodeOps = &selfOps, .fileOps = NULL, }, }; -static uint64_t procfs_pid_lookup(inode_t* dir, dentry_t* target) +static uint64_t procfs_pid_lookup(vnode_t* dir, dentry_t* target) { process_t* process = dir->data; assert(process != NULL); @@ -1056,37 +1055,36 @@ static uint64_t procfs_pid_lookup(inode_t* dir, dentry_t* target) continue; } - inode_t* inode = inode_new(dir->superblock, ino_gen(dir->number, pidEntries[i].name), pidEntries[i].type, - pidEntries[i].inodeOps, pidEntries[i].fileOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(dir->superblock, pidEntries[i].type, pidEntries[i].vnodeOps, pidEntries[i].fileOps); + if (vnode == NULL) { return 0; } - UNREF_DEFER(inode); - inode->data = process; // No reference + UNREF_DEFER(vnode); + vnode->data = process; // No reference if (pidEntries[i].dentryOps != NULL) { target->ops = pidEntries[i].dentryOps; } - dentry_make_positive(target, inode); + dentry_make_positive(target, vnode); return 0; } return 0; } -static void procfs_pid_cleanup(inode_t* inode) +static void procfs_pid_cleanup(vnode_t* vnode) { - process_t* process = inode->data; + process_t* process = vnode->data; if (process == NULL) { return; } UNREF(process); - inode->data = NULL; + vnode->data = NULL; } static uint64_t procfs_pid_iterate(dentry_t* dentry, dir_ctx_t* ctx) @@ -1097,7 +1095,7 @@ static uint64_t procfs_pid_iterate(dentry_t* dentry, dir_ctx_t* ctx) } process_t* current = process_current(); - process_t* process = dentry->inode->data; + process_t* process = dentry->vnode->data; assert(process != NULL); for (size_t i = 0; i < ARRAY_SIZE(pidEntries); i++) @@ -1121,7 +1119,7 @@ static uint64_t procfs_pid_iterate(dentry_t* dentry, dir_ctx_t* ctx) continue; } - if (!ctx->emit(ctx, pidEntries[i].name, ino_gen(dentry->inode->number, pidEntries[i].name), pidEntries[i].type)) + if (!ctx->emit(ctx, pidEntries[i].name, pidEntries[i].type)) { return 0; } @@ -1130,7 +1128,7 @@ static uint64_t procfs_pid_iterate(dentry_t* dentry, dir_ctx_t* ctx) return 0; } -static inode_ops_t pidInodeOps = { +static vnode_ops_t pidVnodeOps = { .lookup = procfs_pid_lookup, .cleanup = procfs_pid_cleanup, }; @@ -1139,7 +1137,7 @@ static dentry_ops_t pidDentryOps = { .iterate = procfs_pid_iterate, }; -static uint64_t procfs_lookup(inode_t* dir, dentry_t* target) +static uint64_t procfs_lookup(vnode_t* dir, dentry_t* target) { for (size_t i = 0; i < ARRAY_SIZE(procEntries); i++) { @@ -1148,15 +1146,15 @@ static uint64_t procfs_lookup(inode_t* dir, dentry_t* target) continue; } - inode_t* inode = inode_new(dir->superblock, ino_gen(dir->number, target->name), procEntries[i].type, - procEntries[i].inodeOps, procEntries[i].fileOps); - if (inode == NULL) + vnode_t* vnode = + vnode_new(dir->superblock, procEntries[i].type, procEntries[i].vnodeOps, procEntries[i].fileOps); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); - dentry_make_positive(target, inode); + dentry_make_positive(target, vnode); return 0; } @@ -1173,17 +1171,17 @@ static uint64_t procfs_lookup(inode_t* dir, dentry_t* target) } UNREF_DEFER(process); - inode_t* inode = inode_new(dir->superblock, ino_gen(dir->number, target->name), INODE_DIR, &pidInodeOps, NULL); - if (inode == NULL) + vnode_t* vnode = vnode_new(dir->superblock, VDIR, &pidVnodeOps, NULL); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); - inode->data = REF(process); + UNREF_DEFER(vnode); + vnode->data = REF(process); target->ops = &pidDentryOps; - dentry_make_positive(target, inode); + dentry_make_positive(target, vnode); return 0; } @@ -1201,8 +1199,7 @@ static uint64_t procfs_iterate(dentry_t* dentry, dir_ctx_t* ctx) continue; } - if (!ctx->emit(ctx, procEntries[i].name, ino_gen(dentry->inode->number, procEntries[i].name), - procEntries[i].type)) + if (!ctx->emit(ctx, procEntries[i].name, procEntries[i].type)) { return 0; } @@ -1220,7 +1217,7 @@ static uint64_t procfs_iterate(dentry_t* dentry, dir_ctx_t* ctx) char name[MAX_NAME]; snprintf(name, sizeof(name), "%llu", process->id); - if (!ctx->emit(ctx, name, ino_gen(dentry->inode->number, name), INODE_DIR)) + if (!ctx->emit(ctx, name, VDIR)) { return 0; } @@ -1229,7 +1226,7 @@ static uint64_t procfs_iterate(dentry_t* dentry, dir_ctx_t* ctx) return 0; } -static inode_ops_t procInodeOps = { +static vnode_ops_t procVnodeOps = { .lookup = procfs_lookup, }; @@ -1237,7 +1234,7 @@ static dentry_ops_t procDentryOps = { .iterate = procfs_iterate, }; -static dentry_t* procfs_mount(filesystem_t* fs, const char* options, void* data) +static dentry_t* procfs_mount(filesystem_t* fs, const char* options, void* data) { UNUSED(data); @@ -1254,12 +1251,12 @@ static dentry_t* procfs_mount(filesystem_t* fs, const char* options, void* data } UNREF_DEFER(superblock); - inode_t* inode = inode_new(superblock, 0, INODE_DIR, &procInodeOps, NULL); - if (inode == NULL) + vnode_t* vnode = vnode_new(superblock, VDIR, &procVnodeOps, NULL); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); dentry_t* dentry = dentry_new(superblock, NULL, NULL); if (dentry == NULL) @@ -1268,7 +1265,7 @@ static dentry_t* procfs_mount(filesystem_t* fs, const char* options, void* data } dentry->ops = &procDentryOps; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); superblock->root = dentry; return superblock->root; diff --git a/src/kernel/fs/superblock.c b/src/kernel/fs/superblock.c index f25ccb264..a69dd9848 100644 --- a/src/kernel/fs/superblock.c +++ b/src/kernel/fs/superblock.c @@ -54,6 +54,7 @@ superblock_t* superblock_new(filesystem_t* fs, const superblock_ops_t* ops, cons superblock->root = NULL; superblock->ops = ops; superblock->dentryOps = dentryOps; + superblock->vtable = NULL; superblock->fs = fs; atomic_init(&superblock->mountCount, 0); diff --git a/src/kernel/fs/sysfs.c b/src/kernel/fs/sysfs.c index a3018ee34..7369abcd7 100644 --- a/src/kernel/fs/sysfs.c +++ b/src/kernel/fs/sysfs.c @@ -3,12 +3,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -19,20 +19,16 @@ #include #include #include -#include +#include #include static dentry_t* root = NULL; -static file_ops_t dirOps = { - .seek = file_generic_seek, -}; - static dentry_ops_t dentryOps = { .iterate = dentry_generic_iterate, }; -static dentry_t* sysfs_mount(filesystem_t* fs, const char* options, void* data) +static dentry_t* sysfs_mount(filesystem_t* fs, const char* options, void* data) { UNUSED(fs); UNUSED(data); @@ -65,12 +61,12 @@ void sysfs_init(void) } UNREF_DEFER(superblock); - inode_t* inode = inode_new(superblock, vfs_id_get(), INODE_DIR, NULL, &dirOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(superblock, VDIR, NULL, NULL); + if (vnode == NULL) { - panic(NULL, "Failed to create sysfs root inode"); + panic(NULL, "Failed to create sysfs root vnode"); } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); dentry_t* dentry = dentry_new(superblock, NULL, NULL); if (dentry == NULL) @@ -78,7 +74,7 @@ void sysfs_init(void) panic(NULL, "Failed to create sysfs root dentry"); } - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); superblock->root = dentry; root = dentry; @@ -115,7 +111,7 @@ void sysfs_init(void) LOG_INFO("sysfs mounted to '/sys'\n"); } -dentry_t* sysfs_dir_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* data) +dentry_t* sysfs_dir_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, void* data) { if (name == NULL) { @@ -141,21 +137,21 @@ dentry_t* sysfs_dir_new(dentry_t* parent, const char* name, const inode_ops_t* i } UNREF_DEFER(dir); - inode_t* inode = inode_new(parent->superblock, vfs_id_get(), INODE_DIR, inodeOps, &dirOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(parent->superblock, VDIR, vnodeOps, NULL); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); - inode->data = data; + UNREF_DEFER(vnode); + vnode->data = data; - dentry_make_positive(dir, inode); + dentry_make_positive(dir, vnode); return REF(dir); } -dentry_t* sysfs_file_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, const file_ops_t* fileOps, - void* data) +dentry_t* sysfs_file_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, const file_ops_t* fileOps, + void* data) { if (name == NULL) { @@ -181,22 +177,22 @@ dentry_t* sysfs_file_new(dentry_t* parent, const char* name, const inode_ops_t* } UNREF_DEFER(dentry); - inode_t* inode = inode_new(parent->superblock, vfs_id_get(), INODE_FILE, inodeOps, fileOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(parent->superblock, VREG, vnodeOps, fileOps); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); - inode->data = data; + UNREF_DEFER(vnode); + vnode->data = data; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return REF(dentry); } -dentry_t* sysfs_symlink_new(dentry_t* parent, const char* name, const inode_ops_t* inodeOps, void* data) +dentry_t* sysfs_symlink_new(dentry_t* parent, const char* name, const vnode_ops_t* vnodeOps, void* data) { - if (parent == NULL || name == NULL || inodeOps == NULL) + if (parent == NULL || name == NULL || vnodeOps == NULL) { errno = EINVAL; return NULL; @@ -215,15 +211,15 @@ dentry_t* sysfs_symlink_new(dentry_t* parent, const char* name, const inode_ops_ } UNREF_DEFER(dentry); - inode_t* inode = inode_new(parent->superblock, vfs_id_get(), INODE_SYMLINK, inodeOps, NULL); - if (inode == NULL) + vnode_t* vnode = vnode_new(parent->superblock, VSYMLINK, vnodeOps, NULL); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); - inode->data = data; + UNREF_DEFER(vnode); + vnode->data = data; - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return REF(dentry); } @@ -252,7 +248,7 @@ uint64_t sysfs_files_new(list_t* out, dentry_t* parent, const sysfs_file_desc_t* uint64_t count = 0; for (const sysfs_file_desc_t* desc = descs; desc->name != NULL; desc++) { - dentry_t* file = sysfs_file_new(parent, desc->name, desc->inodeOps, desc->fileOps, desc->data); + dentry_t* file = sysfs_file_new(parent, desc->name, desc->vnodeOps, desc->fileOps, desc->data); if (file == NULL) { while (!list_is_empty(&createdList)) diff --git a/src/kernel/fs/tmpfs.c b/src/kernel/fs/tmpfs.c index 980aba2a1..e4f06e77a 100644 --- a/src/kernel/fs/tmpfs.c +++ b/src/kernel/fs/tmpfs.c @@ -4,11 +4,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -21,13 +21,13 @@ #include #include #include -#include +#include #include #include static bool initialized = false; -static inode_t* tmpfs_inode_new(superblock_t* superblock, itype_t type, void* buffer, uint64_t size); +static vnode_t* tmpfs_vnode_new(superblock_t* superblock, vtype_t type, void* buffer, uint64_t size); static void tmpfs_dentry_add(dentry_t* dentry) { @@ -53,34 +53,34 @@ static void tmpfs_dentry_remove(dentry_t* dentry) static size_t tmpfs_read(file_t* file, void* buffer, size_t count, size_t* offset) { - MUTEX_SCOPE(&file->inode->mutex); + MUTEX_SCOPE(&file->vnode->mutex); - if (file->inode->data == NULL) + if (file->vnode->data == NULL) { return 0; } - return BUFFER_READ(buffer, count, offset, file->inode->data, file->inode->size); + return BUFFER_READ(buffer, count, offset, file->vnode->data, file->vnode->size); } static size_t tmpfs_write(file_t* file, const void* buffer, size_t count, size_t* offset) { - MUTEX_SCOPE(&file->inode->mutex); + MUTEX_SCOPE(&file->vnode->mutex); size_t requiredSize = *offset + count; - if (requiredSize > file->inode->size) + if (requiredSize > file->vnode->size) { - void* newData = realloc(file->inode->data, requiredSize); + void* newData = realloc(file->vnode->data, requiredSize); if (newData == NULL) { return ERR; } - memset(newData + file->inode->size, 0, requiredSize - file->inode->size); - file->inode->data = newData; - file->inode->size = requiredSize; + memset(newData + file->vnode->size, 0, requiredSize - file->vnode->size); + file->vnode->data = newData; + file->vnode->size = requiredSize; } - return BUFFER_WRITE(buffer, count, offset, file->inode->data, file->inode->size); + return BUFFER_WRITE(buffer, count, offset, file->vnode->data, file->vnode->size); } static file_ops_t fileOps = { @@ -89,86 +89,86 @@ static file_ops_t fileOps = { .seek = file_generic_seek, }; -static uint64_t tmpfs_create(inode_t* dir, dentry_t* target, mode_t mode) +static uint64_t tmpfs_create(vnode_t* dir, dentry_t* target, mode_t mode) { MUTEX_SCOPE(&dir->mutex); - inode_t* inode = tmpfs_inode_new(dir->superblock, mode & MODE_DIRECTORY ? INODE_DIR : INODE_FILE, NULL, 0); - if (inode == NULL) + vnode_t* vnode = tmpfs_vnode_new(dir->superblock, mode & MODE_DIRECTORY ? VDIR : VREG, NULL, 0); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); - dentry_make_positive(target, inode); + dentry_make_positive(target, vnode); tmpfs_dentry_add(target); return 0; } -static void tmpfs_truncate(inode_t* inode) +static void tmpfs_truncate(vnode_t* vnode) { - MUTEX_SCOPE(&inode->mutex); + MUTEX_SCOPE(&vnode->mutex); - if (inode->data != NULL) + if (vnode->data != NULL) { - free(inode->data); - inode->data = NULL; + free(vnode->data); + vnode->data = NULL; } - inode->size = 0; + vnode->size = 0; } -static uint64_t tmpfs_link(inode_t* dir, dentry_t* old, dentry_t* target) +static uint64_t tmpfs_link(vnode_t* dir, dentry_t* old, dentry_t* target) { MUTEX_SCOPE(&dir->mutex); - dentry_make_positive(target, old->inode); + dentry_make_positive(target, old->vnode); tmpfs_dentry_add(target); return 0; } -static uint64_t tmpfs_readlink(inode_t* inode, char* buffer, uint64_t count) +static uint64_t tmpfs_readlink(vnode_t* vnode, char* buffer, uint64_t count) { - MUTEX_SCOPE(&inode->mutex); + MUTEX_SCOPE(&vnode->mutex); - if (inode->data == NULL) + if (vnode->data == NULL) { errno = EINVAL; return ERR; } - uint64_t copySize = MIN(count, inode->size); - memcpy(buffer, inode->data, copySize); + uint64_t copySize = MIN(count, vnode->size); + memcpy(buffer, vnode->data, copySize); return copySize; } -static uint64_t tmpfs_symlink(inode_t* dir, dentry_t* target, const char* dest) +static uint64_t tmpfs_symlink(vnode_t* dir, dentry_t* target, const char* dest) { MUTEX_SCOPE(&dir->mutex); - inode_t* inode = tmpfs_inode_new(dir->superblock, INODE_SYMLINK, (void*)dest, strlen(dest)); - if (inode == NULL) + vnode_t* vnode = tmpfs_vnode_new(dir->superblock, VSYMLINK, (void*)dest, strlen(dest)); + if (vnode == NULL) { return ERR; } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); - dentry_make_positive(target, inode); + dentry_make_positive(target, vnode); tmpfs_dentry_add(target); return 0; } -static uint64_t tmpfs_remove(inode_t* dir, dentry_t* target) +static uint64_t tmpfs_remove(vnode_t* dir, dentry_t* target) { MUTEX_SCOPE(&dir->mutex); - if (target->inode->type == INODE_FILE || target->inode->type == INODE_SYMLINK) + if (target->vnode->type == VREG || target->vnode->type == VSYMLINK) { tmpfs_dentry_remove(target); } - else if (target->inode->type == INODE_DIR) + else if (target->vnode->type == VDIR) { if (!list_is_empty(&target->children)) { @@ -182,24 +182,24 @@ static uint64_t tmpfs_remove(inode_t* dir, dentry_t* target) return 0; } -static void tmpfs_inode_cleanup(inode_t* inode) +static void tmpfs_vnode_cleanup(vnode_t* vnode) { - if (inode->data != NULL) + if (vnode->data != NULL) { - free(inode->data); - inode->data = NULL; - inode->size = 0; + free(vnode->data); + vnode->data = NULL; + vnode->size = 0; } } -static inode_ops_t inodeOps = { +static vnode_ops_t vnodeOps = { .create = tmpfs_create, .truncate = tmpfs_truncate, .link = tmpfs_link, .readlink = tmpfs_readlink, .symlink = tmpfs_symlink, .remove = tmpfs_remove, - .cleanup = tmpfs_inode_cleanup, + .cleanup = tmpfs_vnode_cleanup, }; static dentry_ops_t dentryOps = { @@ -228,14 +228,14 @@ static dentry_t* tmpfs_load_file(superblock_t* superblock, dentry_t* parent, con tmpfs_dentry_add(dentry); - inode_t* inode = tmpfs_inode_new(superblock, INODE_FILE, in->data, in->size); - if (inode == NULL) + vnode_t* vnode = tmpfs_vnode_new(superblock, VREG, in->data, in->size); + if (vnode == NULL) { - panic(NULL, "Failed to create tmpfs file inode"); + panic(NULL, "Failed to create tmpfs file vnode"); } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); return REF(dentry); } @@ -251,15 +251,15 @@ static dentry_t* tmpfs_load_dir(superblock_t* superblock, dentry_t* parent, cons } UNREF_DEFER(dentry); - inode_t* inode = tmpfs_inode_new(superblock, INODE_DIR, NULL, 0); - if (inode == NULL) + vnode_t* vnode = tmpfs_vnode_new(superblock, VDIR, NULL, 0); + if (vnode == NULL) { - panic(NULL, "Failed to create tmpfs inode"); + panic(NULL, "Failed to create tmpfs vnode"); } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); tmpfs_dentry_add(dentry); - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); boot_file_t* file; LIST_FOR_EACH(file, &in->files, entry) @@ -276,7 +276,7 @@ static dentry_t* tmpfs_load_dir(superblock_t* superblock, dentry_t* parent, cons return REF(dentry); } -static dentry_t* tmpfs_mount(filesystem_t* fs, const char* options, void* data) +static dentry_t* tmpfs_mount(filesystem_t* fs, const char* options, void* data) { UNUSED(data); @@ -327,48 +327,46 @@ static dentry_t* tmpfs_mount(filesystem_t* fs, const char* options, void* data) } UNREF_DEFER(dentry); - inode_t* inode = tmpfs_inode_new(superblock, INODE_DIR, NULL, 0); - if (inode == NULL) + vnode_t* vnode = tmpfs_vnode_new(superblock, VDIR, NULL, 0); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); tmpfs_dentry_add(dentry); - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); superblock->root = dentry; return REF(superblock->root); } -static inode_t* tmpfs_inode_new(superblock_t* superblock, itype_t type, void* buffer, uint64_t size) +static vnode_t* tmpfs_vnode_new(superblock_t* superblock, vtype_t type, void* buffer, uint64_t size) { - inode_t* inode = inode_new(superblock, vfs_id_get(), type, &inodeOps, &fileOps); - if (inode == NULL) + vnode_t* vnode = vnode_new(superblock, type, &vnodeOps, &fileOps); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); - - inode->blocks = 0; + UNREF_DEFER(vnode); if (buffer != NULL) { - inode->data = malloc(size); - if (inode->data == NULL) + vnode->data = malloc(size); + if (vnode->data == NULL) { return NULL; } - memcpy(inode->data, buffer, size); - inode->size = size; + memcpy(vnode->data, buffer, size); + vnode->size = size; } else { - inode->data = NULL; - inode->size = 0; + vnode->data = NULL; + vnode->size = 0; } - return REF(inode); + return REF(vnode); } static filesystem_t tmpfs = { diff --git a/src/kernel/fs/vfs.c b/src/kernel/fs/vfs.c index 986c8e4f0..72abc2769 100644 --- a/src/kernel/fs/vfs.c +++ b/src/kernel/fs/vfs.c @@ -1,4 +1,4 @@ -#include <_internal/MAX_PATH.h> +#include <_libstd/MAX_PATH.h> #include #include @@ -6,10 +6,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include static uint64_t vfs_create(path_t* path, const pathname_t* pathname, namespace_t* ns) @@ -101,7 +101,7 @@ static uint64_t vfs_create(path_t* path, const pathname_t* pathname, namespace_t return ERR; } - inode_t* dir = parent.dentry->inode; + vnode_t* dir = parent.dentry->vnode; if (dir->ops == NULL || dir->ops->create == NULL) { errno = EPERM; @@ -200,9 +200,9 @@ uint64_t vfs_open2(const pathname_t* pathname, file_t* files[2], process_t* proc return ERR; } - if (pathname->mode & MODE_TRUNCATE && files[0]->inode->type == INODE_FILE) + if (pathname->mode & MODE_TRUNCATE && files[0]->vnode->type == VREG) { - inode_truncate(files[0]->inode); + vnode_truncate(files[0]->vnode); } if (files[0]->ops != NULL && files[0]->ops->open2 != NULL) @@ -217,7 +217,6 @@ uint64_t vfs_open2(const pathname_t* pathname, file_t* files[2], process_t* proc } } - inode_notify_access(files[0]->inode); return 0; } @@ -258,9 +257,9 @@ file_t* vfs_openat(const path_t* from, const pathname_t* pathname, process_t* pr return NULL; } - if (pathname->mode & MODE_TRUNCATE && file->inode->type == INODE_FILE) + if (pathname->mode & MODE_TRUNCATE && file->vnode->type == VREG) { - inode_truncate(file->inode); + vnode_truncate(file->vnode); } if (file->ops != NULL && file->ops->open != NULL) @@ -274,7 +273,6 @@ file_t* vfs_openat(const path_t* from, const pathname_t* pathname, process_t* pr } } - inode_notify_access(file->inode); return file; } @@ -286,7 +284,7 @@ size_t vfs_read(file_t* file, void* buffer, size_t count) return ERR; } - if (file->inode->type == INODE_DIR) + if (file->vnode->type == VDIR) { errno = EISDIR; return ERR; @@ -309,11 +307,6 @@ size_t vfs_read(file_t* file, void* buffer, size_t count) size_t result = file->ops->read(file, buffer, count, &offset); file->pos = offset; - if (result != ERR) - { - inode_notify_access(file->inode); - } - return result; } @@ -325,7 +318,7 @@ size_t vfs_write(file_t* file, const void* buffer, size_t count) return ERR; } - if (file->inode->type == INODE_DIR) + if (file->vnode->type == VDIR) { errno = EISDIR; return ERR; @@ -356,11 +349,6 @@ size_t vfs_write(file_t* file, const void* buffer, size_t count) size_t result = file->ops->write(file, buffer, count, &offset); file->pos = offset; - if (result != ERR) - { - inode_notify_modify(file->inode); - } - return result; } @@ -390,7 +378,7 @@ uint64_t vfs_ioctl(file_t* file, uint64_t request, void* argp, size_t size) return ERR; } - if (file->inode->type == INODE_DIR) + if (file->vnode->type == VDIR) { errno = EISDIR; return ERR; @@ -403,12 +391,7 @@ uint64_t vfs_ioctl(file_t* file, uint64_t request, void* argp, size_t size) } assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); - uint64_t result = file->ops->ioctl(file, request, argp, size); - if (result != ERR) - { - inode_notify_access(file->inode); - } - return result; + return file->ops->ioctl(file, request, argp, size); } void* vfs_mmap(file_t* file, void* address, size_t length, pml_flags_t flags) @@ -419,7 +402,7 @@ void* vfs_mmap(file_t* file, void* address, size_t length, pml_flags_t flags) return NULL; } - if (file->inode->type == INODE_DIR) + if (file->vnode->type == VDIR) { errno = EISDIR; return NULL; @@ -436,7 +419,6 @@ void* vfs_mmap(file_t* file, void* address, size_t length, pml_flags_t flags) void* result = file->ops->mmap(file, address, length, &offset, flags); if (result != NULL) { - inode_notify_access(file->inode); file->pos = offset; } return result; @@ -534,7 +516,7 @@ uint64_t vfs_poll(poll_file_t* files, uint64_t amount, clock_t timeout) return ERR; } - if (files[i].file->inode->type == INODE_DIR) + if (files[i].file->vnode->type == VDIR) { errno = EISDIR; return ERR; @@ -612,7 +594,7 @@ typedef struct namespace_t* ns; } vfs_dir_ctx_t; -static bool vfs_dir_emit(dir_ctx_t* ctx, const char* name, ino_t number, itype_t type) +static bool vfs_dir_emit(dir_ctx_t* ctx, const char* name, vtype_t type) { vfs_dir_ctx_t* vctx = (vfs_dir_ctx_t*)ctx; if (vctx->written + sizeof(dirent_t) > vctx->count) @@ -631,8 +613,7 @@ static bool vfs_dir_emit(dir_ctx_t* ctx, const char* name, ino_t number, itype_t dentry_t* dentry = child; if (namespace_rcu_traverse(vctx->ns, &mount, &dentry)) { - number = dentry->inode->number; - type = dentry->inode->type; + type = dentry->vnode->type; mode = mount->mode; flags |= DIRENT_MOUNTED; } @@ -641,7 +622,6 @@ static bool vfs_dir_emit(dir_ctx_t* ctx, const char* name, ino_t number, itype_t rcu_read_unlock(); dirent_t* d = (dirent_t*)((uint8_t*)vctx->buffer + vctx->written); - d->number = number; d->type = type; d->flags = flags; strncpy(d->path, name, MAX_PATH - 1); @@ -718,8 +698,7 @@ static uint64_t vfs_getdents_recursive_step(path_t* path, mode_t mode, getdents_ } ctx->currentOffset += sizeof(dirent_t); - if ((d->type == INODE_DIR || d->type == INODE_SYMLINK) && strcmp(d->path, ".") != 0 && - strcmp(d->path, "..") != 0) + if ((d->type == VDIR || d->type == VSYMLINK) && strcmp(d->path, ".") != 0 && strcmp(d->path, "..") != 0) { path_t childPath = PATH_CREATE(path->mount, path->dentry); PATH_DEFER(&childPath); @@ -769,12 +748,11 @@ static uint64_t vfs_remove_recursive(path_t* path, process_t* process) if (!DENTRY_IS_DIR(path->dentry)) { - inode_t* dir = path->dentry->parent->inode; + vnode_t* dir = path->dentry->parent->vnode; if (dir->ops->remove(dir, path->dentry) == ERR) { return ERR; } - inode_notify_modify(dir); return 0; } @@ -847,7 +825,7 @@ static uint64_t vfs_remove_recursive(path_t* path, process_t* process) free(buf); - inode_t* dir = path->dentry->parent->inode; + vnode_t* dir = path->dentry->parent->vnode; if (dir->ops == NULL || dir->ops->remove == NULL) { errno = EPERM; @@ -861,7 +839,6 @@ static uint64_t vfs_remove_recursive(path_t* path, process_t* process) return ERR; } - inode_notify_modify(dir); return 0; } @@ -873,7 +850,7 @@ size_t vfs_getdents(file_t* file, dirent_t* buffer, size_t count) return ERR; } - if (file->inode == NULL || file->inode->type != INODE_DIR) + if (file->vnode == NULL || file->vnode->type != VDIR) { errno = ENOTDIR; return ERR; @@ -907,7 +884,7 @@ size_t vfs_getdents(file_t* file, dirent_t* buffer, size_t count) } UNREF_DEFER(ns); - MUTEX_SCOPE(&file->inode->mutex); + MUTEX_SCOPE(&file->vnode->mutex); if (file->mode & MODE_RECURSIVE) { @@ -940,7 +917,6 @@ size_t vfs_getdents(file_t* file, dirent_t* buffer, size_t count) if (result != ERR) { - inode_notify_access(file->inode); return ctx.written; } return result; @@ -983,17 +959,18 @@ uint64_t vfs_stat(const pathname_t* pathname, stat_t* buffer, process_t* process return ERR; } - inode_t* inode = path.dentry->inode; - mutex_acquire(&inode->mutex); - buffer->number = inode->number; - buffer->type = inode->type; - buffer->size = inode->size; - buffer->blocks = inode->blocks; - buffer->linkAmount = atomic_load(&inode->dentryCount); - buffer->accessTime = inode->accessTime; - buffer->modifyTime = inode->modifyTime; - buffer->changeTime = inode->changeTime; - buffer->createTime = inode->createTime; + /// @todo Reimplement this after the async system. + vnode_t* vnode = path.dentry->vnode; + mutex_acquire(&vnode->mutex); + buffer->number = 0; + buffer->type = vnode->type; + buffer->size = vnode->size; + buffer->blocks = 0; + buffer->linkAmount = atomic_load(&vnode->dentryCount); + buffer->accessTime = 0; + buffer->modifyTime = 0; + buffer->changeTime = 0; + buffer->createTime = 0; char mode[MAX_PATH]; if (mode_to_string(path.mount->mode, mode, MAX_PATH) == ERR) @@ -1007,7 +984,7 @@ uint64_t vfs_stat(const pathname_t* pathname, stat_t* buffer, process_t* process return ERR; } - mutex_release(&inode->mutex); + mutex_release(&vnode->mutex); return 0; } @@ -1073,7 +1050,7 @@ uint64_t vfs_link(const pathname_t* oldPathname, const pathname_t* newPathname, return ERR; } - if (newParent.dentry->inode->ops == NULL || newParent.dentry->inode->ops->link == NULL) + if (newParent.dentry->vnode->ops == NULL || newParent.dentry->vnode->ops->link == NULL) { errno = EPERM; return ERR; @@ -1092,18 +1069,15 @@ uint64_t vfs_link(const pathname_t* oldPathname, const pathname_t* newPathname, } assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); - if (newParent.dentry->inode->ops->link(newParent.dentry->inode, old.dentry, new.dentry) == ERR) + if (newParent.dentry->vnode->ops->link(newParent.dentry->vnode, old.dentry, new.dentry) == ERR) { return ERR; } - inode_notify_modify(newParent.dentry->inode); - inode_notify_change(old.dentry->inode); - return 0; } -size_t vfs_readlink(inode_t* symlink, char* buffer, size_t count) +size_t vfs_readlink(vnode_t* symlink, char* buffer, size_t count) { if (symlink == NULL || buffer == NULL || count == 0) { @@ -1111,7 +1085,7 @@ size_t vfs_readlink(inode_t* symlink, char* buffer, size_t count) return ERR; } - if (symlink->type != INODE_SYMLINK) + if (symlink->type != VSYMLINK) { errno = EINVAL; return ERR; @@ -1124,12 +1098,7 @@ size_t vfs_readlink(inode_t* symlink, char* buffer, size_t count) } assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); - size_t result = symlink->ops->readlink(symlink, buffer, count); - if (result != ERR) - { - inode_notify_access(symlink); - } - return result; + return symlink->ops->readlink(symlink, buffer, count); } uint64_t vfs_symlink(const pathname_t* oldPathname, const pathname_t* newPathname, process_t* process) @@ -1172,7 +1141,7 @@ uint64_t vfs_symlink(const pathname_t* oldPathname, const pathname_t* newPathnam return ERR; } - if (newParent.dentry->inode->ops == NULL || newParent.dentry->inode->ops->symlink == NULL) + if (newParent.dentry->vnode->ops == NULL || newParent.dentry->vnode->ops->symlink == NULL) { errno = EPERM; return ERR; @@ -1185,13 +1154,7 @@ uint64_t vfs_symlink(const pathname_t* oldPathname, const pathname_t* newPathnam } assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); - if (newParent.dentry->inode->ops->symlink(newParent.dentry->inode, new.dentry, oldPathname->string) == ERR) - { - return ERR; - } - - inode_notify_modify(newParent.dentry->inode); - return 0; + return newParent.dentry->vnode->ops->symlink(newParent.dentry->vnode, new.dentry, oldPathname->string); } uint64_t vfs_remove(const pathname_t* pathname, process_t* process) @@ -1258,7 +1221,7 @@ uint64_t vfs_remove(const pathname_t* pathname, process_t* process) return vfs_remove_recursive(&target, process); } - inode_t* dir = parent.dentry->inode; + vnode_t* dir = parent.dentry->vnode; if (dir->ops == NULL || dir->ops->remove == NULL) { errno = EPERM; @@ -1267,13 +1230,7 @@ uint64_t vfs_remove(const pathname_t* pathname, process_t* process) assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); - if (dir->ops->remove(dir, target.dentry) == ERR) - { - return ERR; - } - - inode_notify_modify(dir); - return 0; + return dir->ops->remove(dir, target.dentry); } uint64_t vfs_id_get(void) @@ -1651,7 +1608,7 @@ SYSCALL_DEFINE(SYS_READLINK, uint64_t, const char* pathString, char* buffer, uin { return ERR; } - uint64_t result = vfs_readlink(path.dentry->inode, buffer, count); + uint64_t result = vfs_readlink(path.dentry->vnode, buffer, count); space_unpin(&process->space, buffer, count); return result; } @@ -1688,4 +1645,4 @@ SYSCALL_DEFINE(SYS_REMOVE, uint64_t, const char* pathString) } return vfs_remove(&pathname, process); -} \ No newline at end of file +} diff --git a/src/kernel/fs/vnode.c b/src/kernel/fs/vnode.c new file mode 100644 index 000000000..c49c067e6 --- /dev/null +++ b/src/kernel/fs/vnode.c @@ -0,0 +1,88 @@ +#include + +#include +#include +#include +#include +#include + +#include + +static void vnode_free(vnode_t* vnode) +{ + if (vnode == NULL) + { + return; + } + + if (vnode->ops != NULL && vnode->ops->cleanup != NULL) + { + vnode->ops->cleanup(vnode); + } + vnode->data = NULL; + + if (vnode->superblock != NULL) + { + UNREF(vnode->superblock); + vnode->superblock = NULL; + } + + rcu_call(&vnode->rcu, rcu_call_cache_free, vnode); +} + +static void vnode_ctor(void* ptr) +{ + vnode_t* vnode = (vnode_t*)ptr; + + vnode->ref = (ref_t){0}; + vnode->type = 0; + atomic_init(&vnode->dentryCount, 0); + vnode->data = NULL; + vnode->size = 0; + vnode->superblock = NULL; + vnode->ops = NULL; + vnode->fileOps = NULL; + vnode->rcu = (rcu_entry_t){0}; + mutex_init(&vnode->mutex); +} + +static cache_t cache = CACHE_CREATE(cache, "vnode", sizeof(vnode_t), CACHE_LINE, vnode_ctor, NULL); + +vnode_t* vnode_new(superblock_t* superblock, vtype_t type, const vnode_ops_t* ops, const file_ops_t* fileOps) +{ + if (superblock == NULL) + { + errno = EINVAL; + return NULL; + } + + vnode_t* vnode = cache_alloc(&cache); + if (vnode == NULL) + { + errno = ENOMEM; + return NULL; + } + + ref_init(&vnode->ref, vnode_free); + vnode->type = type; + vnode->superblock = REF(superblock); + vnode->ops = ops; + vnode->fileOps = fileOps; + vnode->vtable = NULL; + return vnode; +} + +void vnode_truncate(vnode_t* vnode) +{ + if (vnode == NULL) + { + return; + } + + if (vnode->ops != NULL && vnode->ops->truncate != NULL) + { + MUTEX_SCOPE(&vnode->mutex); + assert(rflags_read() & RFLAGS_INTERRUPT_ENABLE); + vnode->ops->truncate(vnode); + } +} \ No newline at end of file diff --git a/src/kernel/init/boot_info.c b/src/kernel/init/boot_info.c index 7cac165a5..9dad33d18 100644 --- a/src/kernel/init/boot_info.c +++ b/src/kernel/init/boot_info.c @@ -67,7 +67,7 @@ static void boot_dir_to_higher_half(boot_dir_t* dir) void boot_info_to_higher_half(void) { - bootInfo->gop.physAddr = (void*)PML_ENSURE_HIGHER_HALF(bootInfo->gop.physAddr); + bootInfo->gop.physAddr = PML_ENSURE_HIGHER_HALF(bootInfo->gop.physAddr); bootInfo->gop.virtAddr = (void*)PML_ENSURE_HIGHER_HALF(bootInfo->gop.virtAddr); bootInfo->rsdp = (void*)PML_ENSURE_HIGHER_HALF(bootInfo->rsdp); @@ -77,7 +77,7 @@ void boot_info_to_higher_half(void) bootInfo->disk.root = (boot_dir_t*)PML_ENSURE_HIGHER_HALF(bootInfo->disk.root); boot_dir_to_higher_half(bootInfo->disk.root); - bootInfo->kernel.physAddr = (void*)PML_ENSURE_HIGHER_HALF(bootInfo->kernel.physAddr); + bootInfo->kernel.physAddr = PML_ENSURE_HIGHER_HALF(bootInfo->kernel.physAddr); bootInfo->memory.map.descriptors = (EFI_MEMORY_DESCRIPTOR*)PML_ENSURE_HIGHER_HALF(bootInfo->memory.map.descriptors); @@ -103,13 +103,13 @@ void boot_info_free(void) if (desc->Type == EfiLoaderData) { - LOG_INFO("free boot memory [0x%016lx-0x%016lx]\n", desc->VirtualStart, + LOG_INFO("free boot memory [%p-%p]\n", desc->VirtualStart, (uintptr_t)desc->VirtualStart + (desc->NumberOfPages * PAGE_SIZE)); #ifndef NDEBUG // Clear the memory to deliberately cause corruption if the memory is actually being used. memset((void*)desc->VirtualStart, 0xCC, desc->NumberOfPages * PAGE_SIZE); #endif - pmm_free_region((void*)desc->VirtualStart, desc->NumberOfPages); + pmm_free_region(VIRT_TO_PFN(desc->VirtualStart), desc->NumberOfPages); } } diff --git a/src/kernel/init/init.c b/src/kernel/init/init.c index d9420dc8e..ee02f1814 100644 --- a/src/kernel/init/init.c +++ b/src/kernel/init/init.c @@ -34,7 +34,7 @@ #include -#include +#include <_libstd/init.h> #ifdef _TESTING_ #include @@ -63,6 +63,8 @@ void init_early(void) vmm_kernel_space_load(); + syscall_table_init(); + _std_init(); PERCPU_INIT(); @@ -104,8 +106,6 @@ static void init_finalize(void) perf_init(); - syscall_table_init(); - boot_info_t* bootInfo = boot_info_get(); if (bootInfo->gop.virtAddr != NULL) @@ -152,7 +152,7 @@ static void init_finalize(void) panic(NULL, "No IPI chip registered, most likely no IPI chips with a provided driver was found"); } - LOG_INFO("kernel initalized using %llu kb of memory\n", pmm_used_amount() * PAGE_SIZE / 1024); + LOG_INFO("kernel initalized using %llu kb of memory\n", pmm_used_pages() * PAGE_SIZE / 1024); } static inline void init_process_spawn(void) diff --git a/src/kernel/io/irp.c b/src/kernel/io/irp.c new file mode 100644 index 000000000..185819377 --- /dev/null +++ b/src/kernel/io/irp.c @@ -0,0 +1,362 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef struct irp_ctx +{ + list_t timeouts; + lock_t lock; +} irp_ctx_t; + +PERCPU_DEFINE_CTOR(irp_ctx_t, pcpu_irps) +{ + irp_ctx_t* ctx = SELF_PTR(pcpu_irps); + + list_init(&ctx->timeouts); + lock_init(&ctx->lock); +} + +irp_pool_t* irp_pool_new(size_t size, process_t* process, void* ctx) +{ + if (size == 0 || process == NULL || size >= POOL_IDX_MAX) + { + errno = EINVAL; + return NULL; + } + + irp_pool_t* pool = malloc(sizeof(irp_pool_t) + (sizeof(irp_t) * size)); + if (pool == NULL) + { + errno = ENOMEM; + return NULL; + } + + pool->ctx = ctx; + pool->process = process; + atomic_init(&pool->active, 0); + memset(&pool->irps, 0, sizeof(irp_t) * size); + for (size_t i = 0; i < size; i++) + { + irp_t* irp = &pool->irps[i]; + irp->index = i; + } + + pool_init(&pool->pool, pool->irps, size, sizeof(irp_t), offsetof(irp_t, next)); + + return pool; +} + +void irp_pool_free(irp_pool_t* pool) +{ + free(pool); +} + +void irp_timeout_add(irp_t* irp, clock_t timeout) +{ + if (timeout == CLOCKS_NEVER) + { + return; + } + + irp_ctx_t* ctx = SELF_PTR(pcpu_irps); + LOCK_SCOPE(&ctx->lock); + + irp->cpu = SELF->id; + + clock_t now = clock_uptime(); + irp->deadline = CLOCKS_DEADLINE(timeout, now); + + irp_t* entry; + LIST_FOR_EACH(entry, &ctx->timeouts, timeoutEntry) + { + if (irp->deadline < entry->deadline) + { + list_prepend(&entry->timeoutEntry, &irp->timeoutEntry); + timer_set(now, irp->deadline); + return; + } + } + + list_push_back(&ctx->timeouts, &irp->timeoutEntry); + timer_set(now, irp->deadline); +} + +void irp_timeout_remove(irp_t* irp) +{ + cpu_id_t cpu = irp->cpu; + if (cpu == CPU_ID_INVALID) + { + return; + } + + irp_ctx_t* ctx = CPU_PTR(cpu, pcpu_irps); + assert(ctx != NULL); + + LOCK_SCOPE(&ctx->lock); + if (irp->cpu != cpu) // Check for race condition + { + return; + } + + list_remove(&irp->timeoutEntry); + irp->cpu = CPU_ID_INVALID; +} + +static void irp_perform_completion(irp_t* irp) +{ + while (irp->frame < IRP_FRAME_MAX) + { + irp_frame_t* frame = irp_current(irp); + irp->frame++; + + if (irp->frame == IRP_FRAME_MAX) + { + irp_timeout_remove(irp); + } + + if (frame->vnode != NULL) + { + UNREF(frame->vnode); + frame->vnode = NULL; + } + + if (frame->complete != NULL) + { + frame->complete(irp, frame->ctx); + return; + } + } + + assert(irp->frame == IRP_FRAME_MAX); + assert(irp->next == POOL_IDX_MAX); + assert(irp->cpu == CPU_ID_INVALID); + + mdl_t* next = irp->mdl.next; + mdl_deinit(&irp->mdl); + mdl_free_chain(next, free); + + irp_pool_t* pool = irp_get_pool(irp); + pool_free(&pool->pool, irp->index); + + if (atomic_fetch_sub(&pool->active, 1) == 1) + { + UNREF(pool->process); + } +} + +void irp_timeouts_check(void) +{ + irp_ctx_t* ctx = SELF_PTR(pcpu_irps); + assert(ctx != NULL); + + clock_t now = clock_uptime(); + + lock_acquire(&ctx->lock); + + irp_t* irp; + while (true) + { + irp = CONTAINER_OF_SAFE(list_first(&ctx->timeouts), irp_t, timeoutEntry); + if (irp == NULL) + { + break; + } + + if (irp->deadline > now) + { + timer_set(now, irp->deadline); + break; + } + + list_remove(&irp->timeoutEntry); + irp->deadline = CLOCKS_NEVER; + irp->cpu = CPU_ID_INVALID; + irp_cancel_t handler = atomic_exchange(&irp->cancel, IRP_CANCELLED); + lock_release(&ctx->lock); + + if (handler == IRP_CANCELLED) + { + // Already cancelled + } + else if (handler != NULL) + { + irp->err = ETIMEDOUT; + handler(irp); + irp_perform_completion(irp); + } + else + { + atomic_store(&irp->cancel, NULL); + } + + lock_acquire(&ctx->lock); + } + + lock_release(&ctx->lock); +} + +irp_t* irp_new(irp_pool_t* pool) +{ + pool_idx_t idx = pool_alloc(&pool->pool); + if (idx == POOL_IDX_MAX) + { + errno = ENOSPC; + return NULL; + } + + if (atomic_fetch_add(&pool->active, 1) == 0) + { + REF(pool->process); + } + + irp_t* irp = &pool->irps[idx]; + assert(irp->index == idx); + + list_entry_init(&irp->entry); + list_entry_init(&irp->timeoutEntry); + atomic_init(&irp->cancel, NULL); + irp->deadline = CLOCKS_NEVER; + irp->res._raw = 0; + mdl_init(&irp->mdl, NULL); + irp->next = POOL_IDX_MAX; + irp->cpu = CPU_ID_INVALID; + irp->err = EOK; + irp->frame = IRP_FRAME_MAX; + return irp; +} + +mdl_t* irp_get_mdl(irp_t* irp, const void* addr, size_t size) +{ + if (irp == NULL) + { + errno = EINVAL; + return NULL; + } + + process_t* process = irp_get_process(irp); + if (process == NULL) + { + errno = EINVAL; + return NULL; + } + + mdl_t* mdl = &irp->mdl; + while (mdl->amount > 0) + { + if (mdl->next != NULL) + { + mdl = mdl->next; + continue; + } + + mdl_t* next = malloc(sizeof(mdl_t)); + if (next == NULL) + { + errno = ENOMEM; + return NULL; + } + mdl_init(next, mdl); + mdl = next; + } + + if (mdl_add(mdl, &process->space, addr, size) == ERR) + { + return NULL; + } + + return mdl; +} + +void irp_call(irp_t* irp, vnode_t* vnode) +{ + assert(irp->frame > 0); + irp->frame--; + + irp_frame_t* frame = irp_current(irp); + if (UNLIKELY(frame->major >= IRP_MJ_MAX)) + { + irp_error(irp, EINVAL); + return; + } + + if (vnode == NULL || vnode->vtable == NULL) + { + irp_error(irp, EINVAL); + return; + } + + irp_func_t func = vnode->vtable->funcs[frame->major]; + if (func == NULL) + { + irp_error(irp, ENOSYS); + return; + } + + atomic_store_explicit(&irp->cancel, NULL, memory_order_relaxed); + frame->vnode = REF(vnode); + + func(irp); +} + +void irp_call_direct(irp_t* irp, irp_func_t func) +{ + assert(irp->frame > 0); + irp->frame--; + + irp_frame_t* frame = irp_current(irp); + + if (frame->vnode != NULL) + { + UNREF(frame->vnode); + frame->vnode = NULL; + } + + atomic_store_explicit(&irp->cancel, NULL, memory_order_relaxed); + func(irp); +} + +uint64_t irp_cancel(irp_t* irp) +{ + irp_cancel_t handler = atomic_exchange(&irp->cancel, IRP_CANCELLED); + if (handler == IRP_CANCELLED) + { + errno = EBUSY; + return ERR; + } + + if (handler == NULL) + { + atomic_store(&irp->cancel, NULL); + errno = EBUSY; + return ERR; + } + + irp_timeout_remove(irp); + + irp->err = ECANCELED; + uint64_t result = handler(irp); + irp_perform_completion(irp); + return result; +} + +void irp_complete(irp_t* irp) +{ + if (irp_set_cancel(irp, NULL) == IRP_CANCELLED) + { + return; + } + irp_perform_completion(irp); +} \ No newline at end of file diff --git a/src/kernel/io/ring.c b/src/kernel/io/ring.c new file mode 100644 index 000000000..0165fa95d --- /dev/null +++ b/src/kernel/io/ring.c @@ -0,0 +1,494 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static inline uint64_t ioring_ctx_acquire(ioring_ctx_t* ctx) +{ + ioring_ctx_flags_t expected = atomic_load(&ctx->flags); + if (!(expected & IORING_CTX_BUSY) && atomic_compare_exchange_strong(&ctx->flags, &expected, expected | IORING_CTX_BUSY)) + { + return 0; + } + + return ERR; +} + +static inline void ioring_ctx_release(ioring_ctx_t* ctx) +{ + atomic_fetch_and(&ctx->flags, ~IORING_CTX_BUSY); +} + +static inline uint64_t ioring_ctx_map(ioring_ctx_t* ctx, process_t* process, ioring_id_t id, ioring_t* userRing, void* address, + size_t sentries, size_t centries) +{ + ioring_t* kernelRing = &ctx->ring; + + size_t pageAmount = BYTES_TO_PAGES(sizeof(ioring_ctrl_t) + (sentries * sizeof(sqe_t)) + (centries * sizeof(cqe_t))); + if (pageAmount >= CONFIG_MAX_RINGS_PAGES) + { + errno = ENOMEM; + return ERR; + } + + if (centries >= POOL_IDX_MAX) + { + errno = EINVAL; + return ERR; + } + + pfn_t pages[CONFIG_MAX_RINGS_PAGES]; + if (pmm_alloc_pages(pages, pageAmount) == ERR) + { + errno = ENOMEM; + return ERR; + } + + for (size_t i = 0; i < pageAmount; i++) + { + memset(PFN_TO_VIRT(pages[i]), 0, PAGE_SIZE); + } + + // PML_OWNED means that the pages will be freed when unmapped. + void* kernelAddr = vmm_map_pages(NULL, NULL, pages, pageAmount, PML_WRITE | PML_PRESENT | PML_OWNED, NULL, NULL); + if (kernelAddr == NULL) + { + pmm_free_pages(pages, pageAmount); + return ERR; + } + + void* userAddr = + vmm_map_pages(&process->space, address, pages, pageAmount, PML_WRITE | PML_PRESENT | PML_USER, NULL, NULL); + if (userAddr == NULL) + { + vmm_unmap(NULL, kernelAddr, pageAmount * PAGE_SIZE); + return ERR; + } + + irp_pool_t* irps = irp_pool_new(centries, process, ctx); + if (irps == NULL) + { + vmm_unmap(&process->space, userAddr, pageAmount * PAGE_SIZE); + vmm_unmap(NULL, kernelAddr, pageAmount * PAGE_SIZE); + return ERR; + } + + ioring_ctrl_t* ctrl = (ioring_ctrl_t*)kernelAddr; + atomic_init(&ctrl->shead, 0); + atomic_init(&ctrl->stail, 0); + atomic_init(&ctrl->ctail, 0); + atomic_init(&ctrl->chead, 0); + for (size_t i = 0; i < SQE_REGS_MAX; i++) + { + atomic_init(&ctrl->regs[i], 0); + } + + userRing->ctrl = userAddr; + userRing->id = id; + userRing->squeue = (sqe_t*)((uintptr_t)userAddr + sizeof(ioring_ctrl_t)); + userRing->sentries = sentries; + userRing->smask = sentries - 1; + userRing->cqueue = (cqe_t*)((uintptr_t)userAddr + sizeof(ioring_ctrl_t) + (sentries * sizeof(sqe_t))); + userRing->centries = centries; + userRing->cmask = centries - 1; + + kernelRing->ctrl = kernelAddr; + kernelRing->id = id; + kernelRing->squeue = (sqe_t*)((uintptr_t)kernelAddr + sizeof(ioring_ctrl_t)); + kernelRing->sentries = sentries; + kernelRing->smask = sentries - 1; + kernelRing->cqueue = (cqe_t*)((uintptr_t)kernelAddr + sizeof(ioring_ctrl_t) + (sentries * sizeof(sqe_t))); + kernelRing->centries = centries; + kernelRing->cmask = centries - 1; + + ctx->irps = irps; + ctx->userAddr = userAddr; + ctx->kernelAddr = kernelAddr; + ctx->pageAmount = pageAmount; + + atomic_fetch_or(&ctx->flags, IORING_CTX_MAPPED); + return 0; +} + +static inline uint64_t ioring_ctx_unmap(ioring_ctx_t* ctx) +{ + vmm_unmap(&ctx->irps->process->space, ctx->userAddr, ctx->pageAmount * PAGE_SIZE); + vmm_unmap(NULL, ctx->kernelAddr, ctx->pageAmount * PAGE_SIZE); + + irp_pool_free(ctx->irps); + ctx->irps = NULL; + + atomic_fetch_and(&ctx->flags, ~IORING_CTX_MAPPED); + return 0; +} + +static inline uint64_t ioring_ctx_avail_cqes(ioring_ctx_t* ctx) +{ + ioring_t* ring = &ctx->ring; + uint32_t ctail = atomic_load_explicit(&ring->ctrl->ctail, memory_order_relaxed); + uint32_t chead = atomic_load_explicit(&ring->ctrl->chead, memory_order_acquire); + return ctail - chead; +} + +void ioring_ctx_init(ioring_ctx_t* ctx) +{ + if (ctx == NULL) + { + return; + } + + ctx->ring = (ioring_t){0}; + ctx->irps = NULL; + ctx->userAddr = NULL; + ctx->kernelAddr = NULL; + ctx->pageAmount = 0; + wait_queue_init(&ctx->waitQueue); + atomic_init(&ctx->flags, IORING_CTX_NONE); +} + +void ioring_ctx_deinit(ioring_ctx_t* ctx) +{ + if (ctx == NULL) + { + return; + } + + if (ioring_ctx_acquire(ctx) == ERR) + { + panic(NULL, "failed to acquire async context for deinitialization"); + } + + if (atomic_load(&ctx->flags) & IORING_CTX_MAPPED) + { + if (ioring_ctx_unmap(ctx) == ERR) + { + panic(NULL, "failed to deinitialize async context"); + } + } + + ioring_ctx_release(ctx); + wait_queue_deinit(&ctx->waitQueue); +} + +static void ioring_ctx_dispatch(irp_t* irp); + +static void ioring_ctx_complete(irp_t* irp, void* _ptr) +{ + UNUSED(_ptr); + + ioring_ctx_t* ctx = irp_get_ctx(irp); + ioring_t* ring = &ctx->ring; + + sqe_flags_t reg = (irp->sqe.flags >> SQE_SAVE) & SQE_REG_MASK; + if (reg != SQE_REG_NONE) + { + atomic_store_explicit(&ring->ctrl->regs[reg], irp->res._raw, memory_order_release); + } + + uint32_t tail = atomic_load_explicit(&ring->ctrl->ctail, memory_order_relaxed); + uint32_t head = atomic_load_explicit(&ring->ctrl->chead, memory_order_acquire); + + if ((tail - head) >= ring->centries) + { + /// @todo Handle overflow properly. + panic(NULL, "Async completion queue overflow"); + } + + cqe_t* cqe = &ring->cqueue[tail & ring->cmask]; + cqe->op = irp->sqe.op; + cqe->error = irp->err; + cqe->data = irp->sqe.data; + cqe->_result = irp->res._raw; + + atomic_store_explicit(&ring->ctrl->ctail, tail + 1, memory_order_release); + wait_unblock(&ctx->waitQueue, WAIT_ALL, EOK); + + if (irp->err != EOK && !(irp->sqe.flags & SQE_HARDLINK)) + { + while (true) + { + irp_t* next = irp_chain_next(irp); + if (next == NULL) + { + break; + } + + irp_complete(next); + } + } + else + { + irp_t* next = irp_chain_next(irp); + if (next != NULL) + { + irp_set_complete(next, ioring_ctx_complete, NULL); + irp_call_direct(next, ioring_ctx_dispatch); + } + } + + irp_complete(irp); +} + +static uint64_t nop_cancel(irp_t* irp) +{ + irp_complete(irp); + return 0; +} + +static void ioring_ctx_dispatch(irp_t* irp) +{ + ioring_ctx_t* ctx = irp_get_ctx(irp); + ioring_t* ring = &ctx->ring; + + // Ugly but the alternative is a super messy SQE structure. + + sqe_flags_t reg = (irp->sqe.flags >> SQE_LOAD0) & SQE_REG_MASK; + if (reg != SQE_REG_NONE) + { + irp->sqe.arg0 = atomic_load_explicit(&ring->ctrl->regs[reg], memory_order_acquire); + } + + reg = (irp->sqe.flags >> SQE_LOAD1) & SQE_REG_MASK; + if (reg != SQE_REG_NONE) + { + irp->sqe.arg1 = atomic_load_explicit(&ring->ctrl->regs[reg], memory_order_acquire); + } + + reg = (irp->sqe.flags >> SQE_LOAD2) & SQE_REG_MASK; + if (reg != SQE_REG_NONE) + { + irp->sqe.arg2 = atomic_load_explicit(&ring->ctrl->regs[reg], memory_order_acquire); + } + + reg = (irp->sqe.flags >> SQE_LOAD3) & SQE_REG_MASK; + if (reg != SQE_REG_NONE) + { + irp->sqe.arg3 = atomic_load_explicit(&ring->ctrl->regs[reg], memory_order_acquire); + } + + reg = (irp->sqe.flags >> SQE_LOAD4) & SQE_REG_MASK; + if (reg != SQE_REG_NONE) + { + irp->sqe.arg4 = atomic_load_explicit(&ring->ctrl->regs[reg], memory_order_acquire); + } + + switch (irp->sqe.op) + { + case IO_OP_NOP: + irp_set_cancel(irp, nop_cancel); + irp_timeout_add(irp, irp->sqe.timeout); + break; + default: + irp_error(irp, EINVAL); + break; + } +} + +typedef struct +{ + list_t irps; + irp_t* link; +} ioring_ctx_notify_ctx_t; + +static uint64_t ioring_ctx_sqe_pop(ioring_ctx_t* ctx, ioring_ctx_notify_ctx_t* notify) +{ + ioring_t* ring = &ctx->ring; + + uint32_t stail = atomic_load_explicit(&ring->ctrl->stail, memory_order_acquire); + uint32_t shead = atomic_load_explicit(&ring->ctrl->shead, memory_order_relaxed); + + if (shead == stail) + { + errno = EAGAIN; + return ERR; + } + + irp_t* irp = irp_new(ctx->irps); + if (irp == NULL) + { + return ERR; + } + irp->sqe = ring->squeue[shead & ring->smask]; + + atomic_store_explicit(&ring->ctrl->shead, shead + 1, memory_order_release); + + if (notify->link != NULL) + { + notify->link->next = irp->index; + notify->link = NULL; + } + else + { + list_push_back(¬ify->irps, &irp->entry); + } + + if (irp->sqe.flags & SQE_LINK || irp->sqe.flags & SQE_HARDLINK) + { + notify->link = irp; + } + + return 0; +} + +uint64_t ioring_ctx_notify(ioring_ctx_t* ctx, size_t amount, size_t wait) +{ + if (amount == 0) + { + return 0; + } + + if (ioring_ctx_acquire(ctx) == ERR) + { + errno = EBUSY; + return ERR; + } + + if (!(atomic_load(&ctx->flags) & IORING_CTX_MAPPED)) + { + ioring_ctx_release(ctx); + errno = EINVAL; + return ERR; + } + + ioring_ctx_notify_ctx_t notify = { + .irps = LIST_CREATE(notify.irps), + .link = NULL, + }; + + size_t processed = 0; + while (processed < amount) + { + if (ioring_ctx_sqe_pop(ctx, ¬ify) == ERR) + { + break; + } + processed++; + } + + while (!list_is_empty(¬ify.irps)) + { + irp_t* irp = CONTAINER_OF(list_pop_front(¬ify.irps), irp_t, entry); + + irp_set_complete(irp, ioring_ctx_complete, NULL); + irp_call_direct(irp, ioring_ctx_dispatch); + } + + if (wait == 0) + { + ioring_ctx_release(ctx); + return processed; + } + + if (WAIT_BLOCK(&ctx->waitQueue, ioring_ctx_avail_cqes(ctx) >= wait) == ERR) + { + ioring_ctx_release(ctx); + return processed > 0 ? processed : ERR; + } + + ioring_ctx_release(ctx); + return processed; +} + +SYSCALL_DEFINE(SYS_SETUP, ioring_id_t, ioring_t* userRing, void* address, size_t sentries, size_t centries) +{ + if (userRing == NULL || sentries == 0 || centries == 0 || !IS_POW2(sentries) || !IS_POW2(centries)) + { + errno = EINVAL; + return ERR; + } + + process_t* process = process_current(); + + ioring_ctx_t* ctx = NULL; + ioring_id_t id = 0; + for (id = 0; id < ARRAY_SIZE(process->rings); id++) + { + ioring_ctx_flags_t expected = IORING_CTX_NONE; + if (atomic_compare_exchange_strong(&process->rings[id].flags, &expected, IORING_CTX_BUSY)) + { + ctx = &process->rings[id]; + break; + } + } + + if (ctx == NULL) + { + errno = EMFILE; + return ERR; + } + + if (ioring_ctx_map(ctx, process, id, userRing, address, sentries, centries) == ERR) + { + ioring_ctx_release(ctx); + return ERR; + } + + ioring_ctx_release(ctx); + return id; +} + +SYSCALL_DEFINE(SYS_TEARDOWN, uint64_t, ioring_id_t id) +{ + process_t* process = process_current(); + if (id >= ARRAY_SIZE(process->rings)) + { + errno = EINVAL; + return ERR; + } + + ioring_ctx_t* ctx = &process->rings[id]; + if (ioring_ctx_acquire(ctx) == ERR) + { + errno = EBUSY; + return ERR; + } + + if (!(atomic_load(&ctx->flags) & IORING_CTX_MAPPED)) + { + ioring_ctx_release(ctx); + errno = EINVAL; + return ERR; + } + + if (ctx->irps != NULL && atomic_load(&ctx->irps->pool.used) != 0) + { + ioring_ctx_release(ctx); + errno = EBUSY; + return ERR; + } + + if (ioring_ctx_unmap(ctx) == ERR) + { + ioring_ctx_release(ctx); + return ERR; + } + + ioring_ctx_release(ctx); + return 0; +} + +SYSCALL_DEFINE(SYS_ENTER, uint64_t, ioring_id_t id, size_t amount, size_t wait) +{ + process_t* process = process_current(); + if (id >= ARRAY_SIZE(process->rings)) + { + errno = EINVAL; + return ERR; + } + + ioring_ctx_t* ctx = &process->rings[id]; + return ioring_ctx_notify(ctx, amount, wait); +} \ No newline at end of file diff --git a/src/kernel/linker.lds b/src/kernel/linker.lds index 9fb35ad2a..641c8491f 100644 --- a/src/kernel/linker.lds +++ b/src/kernel/linker.lds @@ -100,6 +100,14 @@ SECTIONS _syscall_table_end = .; } :data + . = ALIGN(4K); + ._irp_table : AT(ADDR(._irp_table) - KERNEL_START) + { + _irp_table_start = .; + KEEP(*(._irp_table)) + _irp_table_end = .; + } :data + . = ALIGN(4K); _kernel_end = .; diff --git a/src/kernel/log/log.c b/src/kernel/log/log.c index 0b536a7bf..b841999d9 100644 --- a/src/kernel/log/log.c +++ b/src/kernel/log/log.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/kernel/log/panic.c b/src/kernel/log/panic.c index 89a64cc58..5db7b214d 100644 --- a/src/kernel/log/panic.c +++ b/src/kernel/log/panic.c @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -343,8 +343,8 @@ void panic(const interrupt_frame_t* frame, const char* format, ...) LOG_PANIC("last errno: %d (%s)\n", err, strerror(err)); - uint64_t freePages = pmm_free_amount(); - uint64_t reservedPages = pmm_used_amount(); + uint64_t freePages = pmm_avail_pages(); + uint64_t reservedPages = pmm_used_pages(); uint64_t totalPages = freePages + reservedPages; LOG_PANIC("memory: %lluK/%lluK available (%lluK kernel code/data, %lluK reserved)\n", @@ -457,7 +457,7 @@ void panic(const interrupt_frame_t* frame, const char* format, ...) LOG_PANIC("!!! Please restart your machine !!!\n"); #ifdef QEMU_EXIT_ON_PANIC - io_out8(QEMU_EXIT_ON_PANIC_PORT, -1); + out8(QEMU_EXIT_ON_PANIC_PORT, -1); #endif while (true) diff --git a/src/kernel/mem/mdl.c b/src/kernel/mem/mdl.c new file mode 100644 index 000000000..2566b3860 --- /dev/null +++ b/src/kernel/mem/mdl.c @@ -0,0 +1,229 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +void mdl_deinit(mdl_t* mdl) +{ + if (mdl == NULL) + { + return; + } + + mdl->next = NULL; + + for (size_t i = 0; i < mdl->amount; i++) + { + pmm_ref_dec(mdl->segments[i].pfn, BYTES_TO_PAGES(mdl->segments[i].offset + mdl->segments[i].size)); + } + mdl->amount = 0; + + if (mdl->segments != mdl->small) + { + free(mdl->segments); + } + mdl->segments = NULL; + mdl->capacity = 0; +} + +void mdl_free_chain(mdl_t* mdl, void (*free)(void*)) +{ + while (mdl != NULL) + { + mdl_t* next = mdl->next; + mdl_deinit(mdl); + if (free != NULL) + { + free(mdl); + } + mdl = next; + } +} + +uint64_t mdl_from_region(mdl_t* mdl, mdl_t* prev, space_t* space, const void* addr, size_t size) +{ + if (mdl == NULL) + { + errno = EINVAL; + return ERR; + } + mdl_init(mdl, prev); + + if (mdl_add(mdl, space, addr, size) == ERR) + { + mdl_deinit(mdl); + return ERR; + } + + return 0; +} + +static uint64_t mdl_push(mdl_t* mdl, phys_addr_t phys, size_t size) +{ + if (size > UINT32_MAX) + { + errno = EOVERFLOW; + return ERR; + } + + if (mdl == NULL) + { + errno = EINVAL; + return ERR; + } + + if (mdl->amount == mdl->capacity) + { + uint32_t newCapacity = mdl->capacity + 4; + mdl_seg_t* newSegments; + + if (mdl->segments == mdl->small) + { + newSegments = malloc(newCapacity * sizeof(mdl_seg_t)); + if (newSegments != NULL) + { + memcpy(newSegments, mdl->small, sizeof(mdl->small)); + } + } + else + { + newSegments = realloc(mdl->segments, newCapacity * sizeof(mdl_seg_t)); + } + + if (newSegments == NULL) + { + errno = ENOMEM; + return ERR; + } + + mdl->segments = newSegments; + mdl->capacity = newCapacity; + } + + mdl_seg_t* seg = &mdl->segments[mdl->amount]; + pfn_t pfn = PHYS_TO_PFN(phys); + uint32_t offset = phys % PAGE_SIZE; + if (pmm_ref_inc(pfn, BYTES_TO_PAGES(offset + size)) == ERR) + { + errno = EFAULT; + return ERR; + } + + seg->pfn = pfn; + seg->size = size; + seg->offset = offset; + + mdl->amount++; + return 0; +} + +uint64_t mdl_add(mdl_t* mdl, space_t* space, const void* addr, size_t size) +{ + const uint8_t* ptr = addr; + size_t remaining = size; + + while (remaining > 0) + { + phys_addr_t phys = space_virt_to_phys(space, ptr); + if (phys == ERR) + { + return ERR; + } + + size_t offset = phys % PAGE_SIZE; + size_t len = MIN(remaining, PAGE_SIZE - offset); + + if (mdl_push(mdl, phys, len) == ERR) + { + return ERR; + } + + ptr += len; + remaining -= len; + } + + return 0; +} + +uint64_t mdl_read(mdl_t* mdl, void* buffer, size_t count, size_t offset) +{ + if (mdl == NULL || buffer == NULL) + { + return 0; + } + + size_t start = 0; + size_t i = 0; + for (; i < mdl->amount; i++) + { + mdl_seg_t* seg = &mdl->segments[i]; + if (start + seg->size > offset) + { + break; + } + start += seg->size; + } + + uint8_t* ptr = buffer; + size_t remaining = count; + + size_t segOffset = offset - start; + while (remaining > 0 && i < mdl->amount) + { + mdl_seg_t* seg = &mdl->segments[i]; + size_t toRead = MIN(remaining, seg->size - segOffset); + void* addr = PFN_TO_VIRT(seg->pfn) + seg->offset + segOffset; + memcpy(ptr, addr, toRead); + + ptr += toRead; + remaining -= toRead; + segOffset = 0; + i++; + } + + return count - remaining; +} + +uint64_t mdl_write(mdl_t* mdl, const void* buffer, size_t count, size_t offset) +{ + if (mdl == NULL || buffer == NULL) + { + return 0; + } + + size_t start = 0; + size_t i = 0; + for (; i < mdl->amount; i++) + { + mdl_seg_t* seg = &mdl->segments[i]; + if (start + seg->size > offset) + { + break; + } + start += seg->size; + } + + const uint8_t* ptr = buffer; + size_t remaining = count; + + size_t segOffset = offset - start; + while (remaining > 0 && i < mdl->amount) + { + mdl_seg_t* seg = &mdl->segments[i]; + size_t toWrite = MIN(remaining, seg->size - segOffset); + void* addr = PFN_TO_VIRT(seg->pfn) + seg->offset + segOffset; + memcpy(addr, ptr, toWrite); + + ptr += toWrite; + remaining -= toWrite; + segOffset = 0; + i++; + } + + return count - remaining; +} \ No newline at end of file diff --git a/src/kernel/mem/pmm.c b/src/kernel/mem/pmm.c index 091e993ca..f7af0fbd4 100644 --- a/src/kernel/mem/pmm.c +++ b/src/kernel/mem/pmm.c @@ -1,23 +1,22 @@ +#include #include #include #include #include #include -#include -#include #include #include +#include +#include +#include #include #include #include #include -extern char _kernel_start; -extern char _kernel_end; - static const char* efiMemTypeToString[] = { "reserved", "loader code", @@ -36,19 +35,20 @@ static const char* efiMemTypeToString[] = { "persistent", }; -#define PMM_BITMAP_SIZE (CONFIG_PMM_BITMAP_MAX_ADDR / PAGE_SIZE) +static page_t* pages = NULL; -static pmm_stack_t stack; -static pmm_bitmap_t bitmap; +static page_stack_t* stack = NULL; +static size_t location = FREE_PAGE_MAX; -// Stores the bitmap data -static uint64_t bitmapBuffer[BITMAP_BITS_TO_QWORDS(PMM_BITMAP_SIZE)]; +BITMAP_CREATE_ONE(bitmap, CONFIG_PMM_BITMAP_MAX_ADDR / PAGE_SIZE); -static uint64_t pageAmount = 0; +static pfn_t highest = 0; +static size_t total = 0; +static size_t avail = 0; static lock_t lock = LOCK_CREATE(); -static bool pmm_is_efi_mem_available(EFI_MEMORY_TYPE type) +static bool pmm_is_mem_avail(EFI_MEMORY_TYPE type) { if (!boot_is_mem_ram(type)) { @@ -68,50 +68,84 @@ static bool pmm_is_efi_mem_available(EFI_MEMORY_TYPE type) } } -static void pmm_free_unlocked(void* address) +static inline void pmm_stack_push(pfn_t pfn) { - if (address >= (void*)PML_LOWER_TO_HIGHER(CONFIG_PMM_BITMAP_MAX_ADDR)) + if (stack == NULL || location == 0) { - pmm_stack_free(&stack, address); + page_stack_t* page = PFN_TO_VIRT(pfn); + page->next = stack; + stack = page; + location = FREE_PAGE_MAX; + + return; } - else if (address >= (void*)PML_LOWER_TO_HIGHER(0)) + + stack->pages[--location] = pfn; +} + +static inline pfn_t pmm_stack_pop(void) +{ + if (location == FREE_PAGE_MAX) { - pmm_bitmap_free(&bitmap, address, 1); + if (stack == NULL) + { + return ERR; + } + + page_stack_t* page = stack; + stack = stack->next; + location = (stack == NULL) ? FREE_PAGE_MAX : 0; + return VIRT_TO_PFN(page); } - else + + return stack->pages[location++]; +} + +static inline pfn_t pmm_bitmap_set(size_t count, pfn_t maxPfn, pfn_t alignPfn) +{ + alignPfn = MAX(alignPfn, 1); + maxPfn = MIN(maxPfn, CONFIG_PMM_BITMAP_MAX_ADDR / PAGE_SIZE); + + size_t index = bitmap_find_clear_region_and_set(&bitmap, 0, maxPfn, count, alignPfn); + if (index == bitmap.length) { - panic(NULL, "pmm: attempt to free lower half address %p", address); + return ERR; } + + return (pfn_t)index; } -static void pmm_free_pages_unlocked(void* address, size_t count) +static inline void pmm_bitmap_clear(pfn_t pfn, size_t pageAmount) { - address = (void*)ROUND_DOWN(address, PAGE_SIZE); - - uintptr_t physStart = PML_HIGHER_TO_LOWER(address); - uintptr_t physEnd = physStart + count * PAGE_SIZE; + bitmap_clear_range(&bitmap, pfn, pfn + pageAmount); +} - if (physEnd <= CONFIG_PMM_BITMAP_MAX_ADDR) +static void pmm_free_unlocked(pfn_t pfn) +{ + page_t* page = &pages[pfn]; + assert(page->ref > 0); + if (--page->ref > 0) { - pmm_bitmap_free(&bitmap, address, count); + return; } - else if (physStart < CONFIG_PMM_BITMAP_MAX_ADDR) - { - size_t bitmapPageCount = (CONFIG_PMM_BITMAP_MAX_ADDR - physStart) / PAGE_SIZE; - pmm_bitmap_free(&bitmap, address, bitmapPageCount); - uintptr_t stackAddr = PML_LOWER_TO_HIGHER(CONFIG_PMM_BITMAP_MAX_ADDR); - for (size_t i = 0; i < count - bitmapPageCount; i++) - { - pmm_stack_free(&stack, (void*)(stackAddr + i * PAGE_SIZE)); - } + if (pfn >= CONFIG_PMM_BITMAP_MAX_ADDR / PAGE_SIZE) + { + pmm_stack_push(pfn); } else { - for (size_t i = 0; i < count; i++) - { - pmm_stack_free(&stack, (void*)((uintptr_t)address + i * PAGE_SIZE)); - } + pmm_bitmap_clear(pfn, 1); + } + + avail++; +} + +static void pmm_free_region_unlocked(pfn_t pfn, size_t count) +{ + for (size_t i = 0; i < count; i++) + { + pmm_free_unlocked(pfn + i); } } @@ -125,37 +159,81 @@ static void pmm_detect_memory(const boot_memory_map_t* map) if (boot_is_mem_ram(desc->Type)) { - pageAmount += desc->NumberOfPages; + total += desc->NumberOfPages; } + + pfn_t endPfn = VIRT_TO_PFN(desc->VirtualStart) + desc->NumberOfPages; + highest = MAX(highest, endPfn); } - LOG_INFO("page amount %llu\n", pageAmount); + LOG_INFO("page amount %llu\n", total); +} + +static void pmm_init_refs(const boot_memory_map_t* map) +{ + size_t size = highest * sizeof(page_t); + for (size_t i = 0; i < map->length; i++) + { + const EFI_MEMORY_DESCRIPTOR* desc = BOOT_MEMORY_MAP_GET_DESCRIPTOR(map, i); + if (desc->Type == EfiConventionalMemory && desc->NumberOfPages >= BYTES_TO_PAGES(size)) + { + pages = (page_t*)desc->VirtualStart; + LOG_INFO("pages [%p-%p]\n", pages, (uintptr_t)pages + size); + return; + } + } + + panic(NULL, "Failed to allocate pmm refs array"); } static void pmm_load_memory(const boot_memory_map_t* map) { + pfn_t pagesPfn = VIRT_TO_PFN(pages); + for (size_t i = 0; i < map->length; i++) { const EFI_MEMORY_DESCRIPTOR* desc = BOOT_MEMORY_MAP_GET_DESCRIPTOR(map, i); - if (pmm_is_efi_mem_available(desc->Type)) + pfn_t pfn = VIRT_TO_PFN(desc->VirtualStart); + size_t amount = desc->NumberOfPages; + + if (pfn == pagesPfn) + { + // Skip the pages array. + size_t toSkip = BYTES_TO_PAGES(highest * sizeof(page_t)); + pfn += toSkip; + amount -= toSkip; + } + + if (pmm_is_mem_avail(desc->Type)) { #ifndef NDEBUG - // Clear the memory to deliberatly cause corruption if the memory is actually being used. - memset((void*)desc->VirtualStart, 0xCC, desc->NumberOfPages * PAGE_SIZE); + // Clear the memory to deliberately cause corruption if the memory is actually being used. + memset(PFN_TO_VIRT(pfn), 0xCC, amount * PAGE_SIZE); #endif - pmm_free_pages_unlocked((void*)desc->VirtualStart, desc->NumberOfPages); + for (size_t j = 0; j < amount; j++) + { + page_t* page = &pages[pfn + j]; + page->ref = 1; + } + + pmm_free_region_unlocked(pfn, amount); } else { - LOG_INFO("reserve [0x%016lx-0x%016lx] pages=%d type=%s\n", desc->VirtualStart, - (uint64_t)desc->VirtualStart + desc->NumberOfPages * PAGE_SIZE, desc->NumberOfPages, + for (size_t j = 0; j < amount; j++) + { + page_t* page = &pages[pfn + j]; + page->ref = UINT16_MAX; + } + + LOG_INFO("reserve [%p-%p] pages=%d type=%s\n", PFN_TO_VIRT(pfn), PFN_TO_VIRT(pfn + amount), amount, efiMemTypeToString[desc->Type]); } } - LOG_INFO("memory %llu MB (usable %llu MB reserved %llu MB)\n", (pageAmount * PAGE_SIZE) / 1000000, - (pmm_free_amount() * PAGE_SIZE) / 1000000, ((pageAmount - pmm_free_amount()) * PAGE_SIZE) / 1000000); + LOG_INFO("memory %llu MB (usable %llu MB reserved %llu MB)\n", (total * PAGE_SIZE) / 1000000, + (pmm_avail_pages() * PAGE_SIZE) / 1000000, ((total - pmm_avail_pages()) * PAGE_SIZE) / 1000000); } void pmm_init(void) @@ -164,97 +242,168 @@ void pmm_init(void) const boot_memory_map_t* map = &bootInfo->memory.map; pmm_detect_memory(map); - - pmm_stack_init(&stack); - pmm_bitmap_init(&bitmap, bitmapBuffer, PMM_BITMAP_SIZE, CONFIG_PMM_BITMAP_MAX_ADDR); - + pmm_init_refs(map); pmm_load_memory(map); } -void* pmm_alloc(void) +pfn_t pmm_alloc(void) { - LOCK_SCOPE(&lock); - void* address = pmm_stack_alloc(&stack); - if (address == NULL) + lock_acquire(&lock); + pfn_t pfn = pmm_stack_pop(); + if (pfn == ERR) { - LOG_WARN("failed to allocate single page, there are %llu pages left\n", stack.free); - errno = ENOMEM; - return NULL; + pfn = pmm_bitmap_set(1, CONFIG_PMM_BITMAP_MAX_ADDR / PAGE_SIZE, 1); } - return address; + + if (pfn != ERR) + { + page_t* page = &pages[pfn]; + assert(page->ref == 0); + page->ref = 1; + avail--; + } + lock_release(&lock); + + if (pfn == ERR) + { + LOG_WARN("out of memory in pmm_alloc()\n"); + } + + return pfn; } -uint64_t pmm_alloc_pages(void** addresses, size_t count) +uint64_t pmm_alloc_pages(pfn_t* pfns, size_t count) { - LOCK_SCOPE(&lock); + lock_acquire(&lock); for (size_t i = 0; i < count; i++) { - void* address = pmm_stack_alloc(&stack); - if (address == NULL) + pfns[i] = pmm_stack_pop(); + if (pfns[i] == ERR) { - LOG_WARN("failed to allocate page %llu of %llu, there are %llu pages left\n", i, count, stack.free); - // Free previously allocated pages. + pfns[i] = pmm_bitmap_set(1, CONFIG_PMM_BITMAP_MAX_ADDR / PAGE_SIZE, 1); + } + + if (pfns[i] == ERR) + { + LOG_WARN("out of memory in pmm_alloc_pages()\n"); for (size_t j = 0; j < i; j++) { - pmm_stack_free(&stack, addresses[j]); - addresses[j] = NULL; + if (pfns[j] >= CONFIG_PMM_BITMAP_MAX_ADDR / PAGE_SIZE) + { + pmm_stack_push(pfns[j]); + } + else + { + pmm_bitmap_clear(pfns[j], 1); + } } - errno = ENOMEM; + lock_release(&lock); return ERR; } - addresses[i] = address; } + + for (size_t i = 0; i < count; i++) + { + page_t* page = &pages[pfns[i]]; + assert(page->ref == 0); + page->ref = 1; + } + + avail -= count; + lock_release(&lock); return 0; } -void* pmm_alloc_bitmap(size_t count, uintptr_t maxAddr, uint64_t alignment) +pfn_t pmm_alloc_bitmap(size_t count, pfn_t maxPfn, pfn_t alignPfn) { - LOCK_SCOPE(&lock); - void* address = pmm_bitmap_alloc(&bitmap, count, maxAddr, alignment); - if (address == NULL) + lock_acquire(&lock); + pfn_t pfn = pmm_bitmap_set(count, maxPfn, alignPfn); + if (pfn != ERR) { - LOG_WARN("failed to allocate %llu pages from bitmap, there are %llu bitmap pages left\n", count, bitmap.free); - errno = ENOMEM; - return NULL; + for (size_t i = 0; i < count; i++) + { + page_t* page = &pages[pfn + i]; + assert(page->ref == 0); + page->ref = 1; + } + avail -= count; } - return address; + lock_release(&lock); + + if (pfn == ERR) + { + LOG_WARN("out of memory in pmm_alloc_bitmap()\n"); + } + + return pfn; } -void pmm_free(void* address) +void pmm_free(pfn_t pfn) { - LOCK_SCOPE(&lock); - pmm_free_unlocked(address); + lock_acquire(&lock); + pmm_free_unlocked(pfn); + lock_release(&lock); } -void pmm_free_pages(void** addresses, size_t count) +void pmm_free_pages(pfn_t* pfns, size_t count) { - LOCK_SCOPE(&lock); + lock_acquire(&lock); for (size_t i = 0; i < count; i++) { - pmm_free_unlocked(addresses[i]); + pmm_free_unlocked(pfns[i]); } + lock_release(&lock); } -void pmm_free_region(void* address, size_t count) +void pmm_free_region(pfn_t pfn, size_t count) { - LOCK_SCOPE(&lock); - pmm_free_pages_unlocked(address, count); + lock_acquire(&lock); + pmm_free_region_unlocked(pfn, count); + lock_release(&lock); } -size_t pmm_total_amount(void) +uint64_t pmm_ref_inc(pfn_t pfn, size_t count) { - LOCK_SCOPE(&lock); - return pageAmount; + lock_acquire(&lock); + for (size_t i = 0; i < count; i++) + { + page_t* page = &pages[pfn + i]; + if (page->ref == 0 || page->ref == UINT16_MAX) + { + for (size_t j = 0; j < i; j++) + { + pages[pfn + j].ref--; + } + lock_release(&lock); + return ERR; + } + page->ref++; + } + uint64_t ret = pages[pfn].ref; + lock_release(&lock); + return ret; } -size_t pmm_free_amount(void) +size_t pmm_total_pages(void) { - LOCK_SCOPE(&lock); - return stack.free + bitmap.free; + lock_acquire(&lock); + size_t ret = total; + lock_release(&lock); + return ret; } -size_t pmm_used_amount(void) +size_t pmm_avail_pages(void) { - LOCK_SCOPE(&lock); - return pageAmount - (stack.free + bitmap.free); + lock_acquire(&lock); + size_t ret = avail; + lock_release(&lock); + return ret; } + +size_t pmm_used_pages(void) +{ + lock_acquire(&lock); + size_t ret = total - avail; + lock_release(&lock); + return ret; +} \ No newline at end of file diff --git a/src/kernel/mem/pmm_bitmap.c b/src/kernel/mem/pmm_bitmap.c deleted file mode 100644 index 0b5506b4c..000000000 --- a/src/kernel/mem/pmm_bitmap.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -#include -#include - -void pmm_bitmap_init(pmm_bitmap_t* bitmap, void* buffer, uint64_t size, uintptr_t maxAddr) -{ - assert(size >= maxAddr / PAGE_SIZE); - bitmap_init(&bitmap->bitmap, buffer, size); - bitmap->free = 0; - bitmap->total = maxAddr / PAGE_SIZE; - bitmap->maxAddr = maxAddr; -} - -void* pmm_bitmap_alloc(pmm_bitmap_t* bitmap, uint64_t count, uintptr_t maxAddr, uint64_t alignment) -{ - alignment = MAX(ROUND_UP(alignment, PAGE_SIZE), PAGE_SIZE); - maxAddr = MIN(maxAddr, bitmap->maxAddr); - - uint64_t index = - bitmap_find_clear_region_and_set(&bitmap->bitmap, 0, maxAddr / PAGE_SIZE, count, alignment / PAGE_SIZE); - if (index == bitmap->bitmap.length) - { - return NULL; - } - - bitmap->free -= count; - return (void*)(index * PAGE_SIZE + PML_HIGHER_HALF_START); -} - -void pmm_bitmap_free(pmm_bitmap_t* bitmap, void* address, uint64_t count) -{ - address = (void*)ROUND_DOWN(address, PAGE_SIZE); - - uint64_t index = (uint64_t)PML_HIGHER_TO_LOWER(address) / PAGE_SIZE; - assert(index < bitmap->maxAddr / PAGE_SIZE); - - bitmap_clear_range(&bitmap->bitmap, index, index + count); - bitmap->free += count; -} diff --git a/src/kernel/mem/pmm_stack.c b/src/kernel/mem/pmm_stack.c deleted file mode 100644 index 8c3e21549..000000000 --- a/src/kernel/mem/pmm_stack.c +++ /dev/null @@ -1,59 +0,0 @@ -#include - -#include - -void pmm_stack_init(pmm_stack_t* stack) -{ - stack->last = NULL; - stack->index = 0; - stack->free = 0; -} - -void* pmm_stack_alloc(pmm_stack_t* stack) -{ - if (stack->last == NULL) - { - return NULL; - } - - void* address; - if (stack->index == 0) - { - address = stack->last; - stack->last = stack->last->prev; - stack->index = PMM_BUFFER_MAX; - } - else - { - address = stack->last->pages[--stack->index]; - } - - stack->free--; - - return address; -} - -void pmm_stack_free(pmm_stack_t* stack, void* address) -{ - address = (void*)ROUND_DOWN(address, PAGE_SIZE); - - if (stack->last == NULL) - { - stack->last = address; - stack->last->prev = NULL; - stack->index = 0; - } - else if (stack->index == PMM_BUFFER_MAX) - { - page_buffer_t* next = address; - next->prev = stack->last; - stack->last = next; - stack->index = 0; - } - else - { - stack->last->pages[stack->index++] = address; - } - - stack->free++; -} diff --git a/src/kernel/mem/pool.c b/src/kernel/mem/pool.c new file mode 100644 index 000000000..348d3cf7a --- /dev/null +++ b/src/kernel/mem/pool.c @@ -0,0 +1,67 @@ +#include + +void pool_init(pool_t* pool, void* elements, size_t capacity, size_t elementSize, size_t nextOffset) +{ + atomic_init(&pool->used, 0); + atomic_init(&pool->free, 0); + pool->elements = elements; + pool->elementSize = elementSize; + pool->nextOffset = nextOffset; + pool->capacity = capacity; + + for (size_t i = 0; i < capacity; i++) + { + void* element = (void*)((uintptr_t)elements + (i * elementSize)); + pool_idx_t* next = (pool_idx_t*)((uintptr_t)element + nextOffset); + *next = (i == capacity - 1) ? POOL_IDX_MAX : (pool_idx_t)(i + 1); + } +} + +pool_idx_t pool_alloc(pool_t* pool) +{ + pool_idx_t idx; + while (true) + { + uint64_t head = atomic_load_explicit(&pool->free, memory_order_acquire); + idx = (pool_idx_t)(head & POOL_IDX_MAX); + if (idx == POOL_IDX_MAX) + { + return POOL_IDX_MAX; + } + + void* element = (void*)((uintptr_t)pool->elements + (idx * pool->elementSize)); + pool_idx_t next = *(pool_idx_t*)((uintptr_t)element + pool->nextOffset); + + uint64_t newHead = ((head & ~POOL_IDX_MAX) + POOL_TAG_INC) | next; + if (atomic_compare_exchange_weak_explicit(&pool->free, &head, newHead, memory_order_acquire, + memory_order_relaxed)) + { + break; + } + ASM("pause"); + } + + atomic_fetch_add_explicit(&pool->used, 1, memory_order_relaxed); + return idx; +} + +void pool_free(pool_t* pool, pool_idx_t idx) +{ + void* element = (void*)((uintptr_t)pool->elements + (idx * pool->elementSize)); + pool_idx_t* next = (pool_idx_t*)((uintptr_t)element + pool->nextOffset); + + while (true) + { + uint64_t head = atomic_load_explicit(&pool->free, memory_order_relaxed); + *next = (pool_idx_t)(head & POOL_IDX_MAX); + uint64_t newHead = ((head & ~POOL_IDX_MAX) + POOL_TAG_INC) | idx; + + if (atomic_compare_exchange_weak_explicit(&pool->free, &head, newHead, memory_order_release, + memory_order_relaxed)) + { + break; + } + ASM("pause"); + } + atomic_fetch_sub_explicit(&pool->used, 1, memory_order_relaxed); +} \ No newline at end of file diff --git a/src/kernel/mem/space.c b/src/kernel/mem/space.c index 633901b08..a7808c3f0 100644 --- a/src/kernel/mem/space.c +++ b/src/kernel/mem/space.c @@ -17,20 +17,20 @@ #include #include -static uint64_t space_pmm_bitmap_alloc_pages(void** pages, size_t pageAmount) +static uint64_t space_pmm_bitmap_alloc_pages(pfn_t* pfns, size_t pageAmount) { for (size_t i = 0; i < pageAmount; i++) { - void* page = pmm_alloc_bitmap(1, UINT32_MAX, 0); - if (page == NULL) + pfn_t pfn = pmm_alloc_bitmap(1, UINT32_MAX, 0); + if (pfn == ERR) { for (size_t j = 0; j < i; j++) { - pmm_free(pages[j]); + pmm_free(pfns[j]); } return ERR; } - pages[i] = page; + pfns[i] = pfn; } return 0; } @@ -172,16 +172,16 @@ static uint64_t space_populate_user_region(space_t* space, const void* buffer, s continue; } - void* page = pmm_alloc(); - if (page == NULL) + pfn_t pfn = pmm_alloc(); + if (pfn == ERR) { return ERR; } - if (page_table_map(&space->pageTable, (void*)addr, page, 1, PML_PRESENT | PML_USER | PML_WRITE | PML_OWNED, - PML_CALLBACK_NONE) == ERR) + if (page_table_map(&space->pageTable, (void*)addr, PFN_TO_PHYS(pfn), 1, + PML_PRESENT | PML_USER | PML_WRITE | PML_OWNED, PML_CALLBACK_NONE) == ERR) { - pmm_free(page); + pmm_free(pfn); return ERR; } } @@ -189,14 +189,14 @@ static uint64_t space_populate_user_region(space_t* space, const void* buffer, s return 0; } -static void space_pin_depth_dec(space_t* space, const void* address, uint64_t pageAmount) +static void space_pin_depth_dec(space_t* space, const void* address, uint64_t amount) { address = (void*)ROUND_DOWN((uintptr_t)address, PAGE_SIZE); page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - uintptr_t addr = (uintptr_t)address + (i * PAGE_SIZE); + const void* addr = address + (i * PAGE_SIZE); if (page_table_traverse(&space->pageTable, &traverse, addr, PML_NONE) == ERR) { continue; @@ -207,7 +207,7 @@ static void space_pin_depth_dec(space_t* space, const void* address, uint64_t pa continue; } - map_key_t key = map_key_uint64(addr); + map_key_t key = map_key_uint64((uintptr_t)addr); map_entry_t* entry = map_get(&space->pinnedPages, &key); if (entry == NULL) // Not pinned more then once { @@ -226,14 +226,14 @@ static void space_pin_depth_dec(space_t* space, const void* address, uint64_t pa } } -static inline uint64_t space_pin_depth_inc(space_t* space, const void* address, uint64_t pageAmount) +static inline uint64_t space_pin_depth_inc(space_t* space, const void* address, uint64_t amount) { address = (void*)ROUND_DOWN((uintptr_t)address, PAGE_SIZE); page_table_traverse_t traverse = PAGE_TABLE_TRAVERSE_CREATE; - for (uint64_t i = 0; i < pageAmount; i++) + for (uint64_t i = 0; i < amount; i++) { - uintptr_t addr = (uintptr_t)address + (i * PAGE_SIZE); + const void* addr = address + (i * PAGE_SIZE); if (page_table_traverse(&space->pageTable, &traverse, addr, PML_NONE) == ERR) { continue; @@ -250,7 +250,7 @@ static inline uint64_t space_pin_depth_inc(space_t* space, const void* address, continue; } - map_key_t key = map_key_uint64(addr); + map_key_t key = map_key_uint64((uintptr_t)addr); map_entry_t* entry = map_get(&space->pinnedPages, &key); if (entry != NULL) // Already pinned more than once { @@ -491,8 +491,8 @@ static void* space_find_free_region(space_t* space, uint64_t pageAmount, uint64_ return NULL; } -uint64_t space_mapping_start(space_t* space, space_mapping_t* mapping, void* virtAddr, void* physAddr, size_t length, - size_t alignment, pml_flags_t flags) +uint64_t space_mapping_start(space_t* space, space_mapping_t* mapping, void* virtAddr, phys_addr_t physAddr, + size_t length, size_t alignment, pml_flags_t flags) { if (space == NULL || mapping == NULL || length == 0) { @@ -508,7 +508,7 @@ uint64_t space_mapping_start(space_t* space, space_mapping_t* mapping, void* vir } uintptr_t physOverflow = (uintptr_t)physAddr + length; - if (physAddr != NULL && physOverflow < (uintptr_t)physAddr) + if (physAddr != PHYS_ADDR_INVALID && physOverflow < (uintptr_t)physAddr) { errno = EOVERFLOW; return ERR; @@ -554,13 +554,13 @@ uint64_t space_mapping_start(space_t* space, space_mapping_t* mapping, void* vir } mapping->virtAddr = virtAddr; - if (physAddr != NULL) + if (physAddr != PHYS_ADDR_INVALID) { - mapping->physAddr = (void*)PML_ENSURE_LOWER_HALF(ROUND_DOWN(physAddr, PAGE_SIZE)); + mapping->physAddr = PML_ENSURE_LOWER_HALF(ROUND_DOWN(physAddr, PAGE_SIZE)); } else { - mapping->physAddr = NULL; + mapping->physAddr = PHYS_ADDR_INVALID; } mapping->flags = flags; @@ -568,7 +568,7 @@ uint64_t space_mapping_start(space_t* space, space_mapping_t* mapping, void* vir return 0; // We return with the lock still acquired. } -pml_callback_id_t space_alloc_callback(space_t* space, size_t pageAmount, space_callback_func_t func, void* data) +pml_callback_id_t space_alloc_callback(space_t* space, size_t pageAmount, space_callback_func_t func, void* data) { if (space == NULL) { @@ -666,3 +666,22 @@ uint64_t space_user_page_count(space_t* space) return page_table_count_pages_with_flags(&space->pageTable, (void*)VMM_USER_SPACE_MIN, BYTES_TO_PAGES(VMM_USER_SPACE_MAX - VMM_USER_SPACE_MIN), PML_PRESENT | PML_USER | PML_OWNED); } + +phys_addr_t space_virt_to_phys(space_t* space, const void* virtAddr) +{ + if (space == NULL) + { + errno = EINVAL; + return ERR; + } + + phys_addr_t physAddr; + LOCK_SCOPE(&space->lock); + if (page_table_get_phys_addr(&space->pageTable, (void*)virtAddr, &physAddr) == ERR) + { + errno = EFAULT; + return ERR; + } + + return physAddr; +} \ No newline at end of file diff --git a/src/kernel/mem/vmm.c b/src/kernel/mem/vmm.c index c128b47f0..b277e0053 100644 --- a/src/kernel/mem/vmm.c +++ b/src/kernel/mem/vmm.c @@ -57,11 +57,11 @@ void vmm_init(void) } LOG_DEBUG("address space layout:\n"); - LOG_DEBUG(" kernel binary: 0x%016lx-0x%016lx\n", VMM_KERNEL_BINARY_MIN, VMM_KERNEL_BINARY_MAX); - LOG_DEBUG(" kernel stacks: 0x%016lx-0x%016lx\n", VMM_KERNEL_STACKS_MIN, VMM_KERNEL_STACKS_MAX); - LOG_DEBUG(" kernel heap: 0x%016lx-0x%016lx\n", VMM_KERNEL_HEAP_MIN, VMM_KERNEL_HEAP_MAX); - LOG_DEBUG(" identity map: 0x%016lx-0x%016lx\n", VMM_IDENTITY_MAPPED_MIN, VMM_IDENTITY_MAPPED_MAX); - LOG_DEBUG(" user space: 0x%016lx-0x%016lx\n", VMM_USER_SPACE_MIN, VMM_USER_SPACE_MAX); + LOG_DEBUG(" kernel binary: %p-%p\n", VMM_KERNEL_BINARY_MIN, VMM_KERNEL_BINARY_MAX); + LOG_DEBUG(" kernel stacks: %p-%p\n", VMM_KERNEL_STACKS_MIN, VMM_KERNEL_STACKS_MAX); + LOG_DEBUG(" kernel heap: %p-%p\n", VMM_KERNEL_HEAP_MIN, VMM_KERNEL_HEAP_MAX); + LOG_DEBUG(" identity map: %p-%p\n", VMM_IDENTITY_MAPPED_MIN, VMM_IDENTITY_MAPPED_MAX); + LOG_DEBUG(" user space: %p-%p\n", VMM_USER_SPACE_MIN, VMM_USER_SPACE_MAX); LOG_INFO("kernel pml4 allocated at 0x%lx\n", kernelSpace.pageTable.pml4); @@ -76,18 +76,18 @@ void vmm_init(void) const EFI_MEMORY_DESCRIPTOR* desc = BOOT_MEMORY_MAP_GET_DESCRIPTOR(&memory->map, i); if (desc->VirtualStart < PML_HIGHER_HALF_START) { - panic(NULL, "Memory descriptor %d has invalid virtual address 0x%016lx", i, desc->VirtualStart); + panic(NULL, "Memory descriptor %d has invalid virtual address %p", i, desc->VirtualStart); } if (desc->PhysicalStart > PML_LOWER_HALF_END) { - panic(NULL, "Memory descriptor %d has invalid physical address 0x%016lx", i, desc->PhysicalStart); + panic(NULL, "Memory descriptor %d has invalid physical address %p", i, desc->PhysicalStart); } - if (page_table_map(&kernelSpace.pageTable, (void*)desc->VirtualStart, (void*)desc->PhysicalStart, - desc->NumberOfPages, PML_WRITE | PML_GLOBAL | PML_PRESENT, PML_CALLBACK_NONE) == ERR) + if (page_table_map(&kernelSpace.pageTable, (void*)desc->VirtualStart, desc->PhysicalStart, desc->NumberOfPages, + PML_WRITE | PML_GLOBAL | PML_PRESENT, PML_CALLBACK_NONE) == ERR) { - panic(NULL, "Failed to map memory descriptor %d (phys=0x%016lx-0x%016lx virt=0x%016lx)", i, - desc->PhysicalStart, desc->PhysicalStart + desc->NumberOfPages * PAGE_SIZE, desc->VirtualStart); + panic(NULL, "Failed to map memory descriptor %d (phys=%p-%p virt=%p)", i, desc->PhysicalStart, + desc->PhysicalStart + desc->NumberOfPages * PAGE_SIZE, desc->VirtualStart); } } @@ -96,17 +96,17 @@ void vmm_init(void) elf64_get_loadable_bounds(&kernel->elf, &minVaddr, &maxVaddr); uint64_t kernelPageAmount = BYTES_TO_PAGES(maxVaddr - minVaddr); - LOG_INFO("kernel virt=[0x%016lx-0x%016lx] phys=[0x%016lx-0x%016lx]\n", minVaddr, maxVaddr, - (uintptr_t)kernel->physAddr, (uintptr_t)kernel->physAddr + kernelPageAmount * PAGE_SIZE); + LOG_INFO("kernel virt=[%p-%p] phys=[%p-%p]\n", minVaddr, maxVaddr, (uintptr_t)kernel->physAddr, + (uintptr_t)kernel->physAddr + kernelPageAmount * PAGE_SIZE); if (page_table_map(&kernelSpace.pageTable, (void*)minVaddr, kernel->physAddr, kernelPageAmount, PML_WRITE | PML_PRESENT, PML_CALLBACK_NONE) == ERR) { panic(NULL, "Failed to map kernel memory"); } - LOG_INFO("GOP virt=[0x%016lx-0x%016lx] phys=[0x%016lx-0x%016lx]\n", gop->virtAddr, gop->virtAddr + gop->size, - gop->physAddr, gop->physAddr + gop->size); - if (page_table_map(&kernelSpace.pageTable, (void*)gop->virtAddr, (void*)gop->physAddr, BYTES_TO_PAGES(gop->size), + LOG_INFO("GOP virt=[%p-%p] phys=[%p-%p]\n", gop->virtAddr, gop->virtAddr + gop->size, gop->physAddr, + gop->physAddr + gop->size); + if (page_table_map(&kernelSpace.pageTable, (void*)gop->virtAddr, gop->physAddr, BYTES_TO_PAGES(gop->size), PML_WRITE | PML_GLOBAL | PML_PRESENT, PML_CALLBACK_NONE) == ERR) { panic(NULL, "Failed to map GOP memory"); @@ -165,7 +165,8 @@ void* vmm_alloc(space_t* space, void* virtAddr, size_t length, size_t alignment, } space_mapping_t mapping; - if (space_mapping_start(space, &mapping, virtAddr, NULL, length, alignment, pmlFlags | PML_OWNED) == ERR) + if (space_mapping_start(space, &mapping, virtAddr, PHYS_ADDR_INVALID, length, alignment, pmlFlags | PML_OWNED) == + ERR) { return NULL; } @@ -189,18 +190,26 @@ void* vmm_alloc(space_t* space, void* virtAddr, size_t length, size_t alignment, uint64_t remainingPages = mapping.pageAmount; while (remainingPages != 0) { - uintptr_t currentVirtAddr = (uintptr_t)mapping.virtAddr + (mapping.pageAmount - remainingPages) * PAGE_SIZE; + void* currentVirtAddr = mapping.virtAddr + (mapping.pageAmount - remainingPages) * PAGE_SIZE; - void* addresses[maxBatchSize]; + pfn_t pages[maxBatchSize]; uint64_t batchSize = MIN(remainingPages, maxBatchSize); - if (pmm_alloc_pages(addresses, batchSize) == ERR) + if (pmm_alloc_pages(pages, batchSize) == ERR) { // Page table will free the previously allocated pages as they are owned by the Page table. vmm_page_table_unmap_with_shootdown(space, mapping.virtAddr, mapping.pageAmount - remainingPages); return space_mapping_end(space, &mapping, ENOMEM); } - if (page_table_map_pages(&space->pageTable, (void*)currentVirtAddr, addresses, batchSize, mapping.flags, + if (allocFlags & VMM_ALLOC_ZERO) + { + for (uint64_t i = 0; i < batchSize; i++) + { + memset(PFN_TO_VIRT(pages[i]), 0, PAGE_SIZE); + } + } + + if (page_table_map_pages(&space->pageTable, currentVirtAddr, pages, batchSize, mapping.flags, PML_CALLBACK_NONE) == ERR) { // Page table will free the previously allocated pages as they are owned by the Page table. @@ -214,10 +223,10 @@ void* vmm_alloc(space_t* space, void* virtAddr, size_t length, size_t alignment, return space_mapping_end(space, &mapping, EOK); } -void* vmm_map(space_t* space, void* virtAddr, void* physAddr, size_t length, pml_flags_t flags, - space_callback_func_t func, void* data) +void* vmm_map(space_t* space, void* virtAddr, phys_addr_t physAddr, size_t length, pml_flags_t flags, + space_callback_func_t func, void* data) { - if (physAddr == NULL || length == 0 || !(flags & PML_PRESENT)) + if (physAddr == PHYS_ADDR_INVALID || length == 0 || !(flags & PML_PRESENT)) { errno = EINVAL; return NULL; @@ -269,10 +278,10 @@ void* vmm_map(space_t* space, void* virtAddr, void* physAddr, size_t length, pml return space_mapping_end(space, &mapping, EOK); } -void* vmm_map_pages(space_t* space, void* virtAddr, void** pages, size_t pageAmount, pml_flags_t flags, - space_callback_func_t func, void* data) +void* vmm_map_pages(space_t* space, void* virtAddr, pfn_t* pfns, size_t amount, pml_flags_t flags, + space_callback_func_t func, void* data) { - if (pages == NULL || pageAmount == 0 || !(flags & PML_PRESENT)) + if (pfns == NULL || amount == 0 || !(flags & PML_PRESENT)) { errno = EINVAL; return NULL; @@ -284,7 +293,7 @@ void* vmm_map_pages(space_t* space, void* virtAddr, void** pages, size_t pageAmo } space_mapping_t mapping; - if (space_mapping_start(space, &mapping, virtAddr, NULL, pageAmount * PAGE_SIZE, 1, flags) == ERR) + if (space_mapping_start(space, &mapping, virtAddr, PHYS_ADDR_INVALID, amount * PAGE_SIZE, 1, flags) == ERR) { return NULL; } @@ -297,7 +306,7 @@ void* vmm_map_pages(space_t* space, void* virtAddr, void** pages, size_t pageAmo pml_callback_id_t callbackId = PML_CALLBACK_NONE; if (func != NULL) { - callbackId = space_alloc_callback(space, pageAmount, func, data); + callbackId = space_alloc_callback(space, amount, func, data); if (callbackId == PML_MAX_CALLBACK) { return space_mapping_end(space, &mapping, ENOSPC); @@ -309,7 +318,7 @@ void* vmm_map_pages(space_t* space, void* virtAddr, void** pages, size_t pageAmo vmm_page_table_unmap_with_shootdown(space, mapping.virtAddr, mapping.pageAmount); } - if (page_table_map_pages(&space->pageTable, mapping.virtAddr, pages, mapping.pageAmount, mapping.flags, + if (page_table_map_pages(&space->pageTable, mapping.virtAddr, pfns, mapping.pageAmount, mapping.flags, callbackId) == ERR) { if (callbackId != PML_CALLBACK_NONE) @@ -338,7 +347,7 @@ void* vmm_unmap(space_t* space, void* virtAddr, size_t length) } space_mapping_t mapping; - if (space_mapping_start(space, &mapping, virtAddr, NULL, length, 1, PML_NONE) == ERR) + if (space_mapping_start(space, &mapping, virtAddr, PHYS_ADDR_INVALID, length, 1, PML_NONE) == ERR) { return NULL; } @@ -405,7 +414,7 @@ void* vmm_protect(space_t* space, void* virtAddr, size_t length, pml_flags_t fla } space_mapping_t mapping; - if (space_mapping_start(space, &mapping, virtAddr, NULL, length, 1, flags) == ERR) + if (space_mapping_start(space, &mapping, virtAddr, PHYS_ADDR_INVALID, length, 1, flags) == ERR) { return NULL; } diff --git a/src/kernel/module/module.c b/src/kernel/module/module.c index 7c1c80b39..af0795b72 100644 --- a/src/kernel/module/module.c +++ b/src/kernel/module/module.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include static module_info_t fakeKernelModuleInfo = { @@ -46,7 +46,7 @@ static bool cacheValid = false; static mutex_t lock = MUTEX_CREATE(lock); -static void* module_resolve_symbol_callback(const char* name, void* data); +static void* module_resolve_symbol_callback(const char* name, void* data); #define MODULE_SYMBOL_ALLOWED(type, binding, name) \ (((type) == STT_OBJECT || (type) == STT_FUNC) && ((binding) == STB_GLOBAL) && \ @@ -624,7 +624,7 @@ static uint64_t module_cache_build(void) for (uint64_t i = 0; i < readCount / sizeof(dirent_t); i++) { - if (buffer[i].path[0] == '.' || buffer[i].type != INODE_FILE) + if (buffer[i].path[0] == '.' || buffer[i].type != VREG) { continue; } @@ -909,7 +909,7 @@ static uint64_t module_load_dependency(module_load_ctx_t* ctx, const char* symbo return 0; } -static void* module_resolve_symbol_callback(const char* symbolName, void* data) +static void* module_resolve_symbol_callback(const char* symbolName, void* data) { module_load_ctx_t* ctx = data; diff --git a/src/kernel/proc/group.c b/src/kernel/proc/group.c index d9e791640..a05370787 100644 --- a/src/kernel/proc/group.c +++ b/src/kernel/proc/group.c @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include #include #include diff --git a/src/kernel/proc/process.c b/src/kernel/proc/process.c index 9659d6dd1..90235bf09 100644 --- a/src/kernel/proc/process.c +++ b/src/kernel/proc/process.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -109,9 +110,13 @@ static void process_free(process_t* process) UNREF(process->nspace); } space_deinit(&process->space); + futex_ctx_deinit(&process->futexCtx); + for (uint64_t i = 0; i < ARRAY_SIZE(process->rings); i++) + { + ioring_ctx_deinit(&process->rings[i]); + } wait_queue_deinit(&process->dyingQueue); wait_queue_deinit(&process->suspendQueue); - futex_ctx_deinit(&process->futexCtx); env_deinit(&process->env); rcu_call(&process->rcu, rcu_call_cache_free, process); @@ -149,6 +154,10 @@ process_t* process_new(priority_t priority, group_member_t* group, namespace_t* file_table_init(&process->fileTable); futex_ctx_init(&process->futexCtx); perf_process_ctx_init(&process->perf); + for (uint64_t i = 0; i < ARRAY_SIZE(process->rings); i++) + { + ioring_ctx_init(&process->rings[i]); + } note_handler_init(&process->noteHandler); wait_queue_init(&process->suspendQueue); wait_queue_init(&process->dyingQueue); diff --git a/src/kernel/sched/timer.c b/src/kernel/sched/timer.c index 0253511df..f4dcd0379 100644 --- a/src/kernel/sched/timer.c +++ b/src/kernel/sched/timer.c @@ -136,7 +136,7 @@ uint64_t timer_source_amount(void) return amount; } -void timer_set(clock_t uptime, clock_t deadline) +void timer_set(clock_t now, clock_t deadline) { if (deadline == CLOCKS_NEVER) { @@ -145,7 +145,7 @@ void timer_set(clock_t uptime, clock_t deadline) RWLOCK_READ_SCOPE(&sourcesLock); - deadline = MAX(deadline, uptime + CONFIG_MIN_TIMER_TIMEOUT); + deadline = MAX(deadline, now + CONFIG_MIN_TIMER_TIMEOUT); if (pcpu_timer->deadline <= deadline) { @@ -155,6 +155,6 @@ void timer_set(clock_t uptime, clock_t deadline) if (bestSource != NULL) { - bestSource->set(VECTOR_TIMER, uptime, deadline - uptime); + bestSource->set(VECTOR_TIMER, now, deadline - now); } } \ No newline at end of file diff --git a/src/kernel/utils/fifo.c b/src/kernel/utils/fifo.c deleted file mode 100644 index 0dcf11a40..000000000 --- a/src/kernel/utils/fifo.c +++ /dev/null @@ -1,108 +0,0 @@ -#include - -#include -#include -#include - -void fifo_init(fifo_t* fifo, uint8_t* buffer, size_t size) -{ - fifo->buffer = buffer; - fifo->size = size; - fifo->head = 0; - fifo->tail = 0; -} - -void fifo_reset(fifo_t* fifo) -{ - fifo->head = 0; - fifo->tail = 0; -} - -size_t fifo_bytes_readable(const fifo_t* fifo) -{ - if (fifo->head >= fifo->tail) - { - return fifo->head - fifo->tail; - } - - return fifo->size - (fifo->tail - fifo->head); -} - -size_t fifo_bytes_writeable(const fifo_t* fifo) -{ - if (fifo->tail > fifo->head) - { - return fifo->tail - fifo->head - 1; - } - - return fifo->size - (fifo->head - fifo->tail) - 1; -} - -size_t fifo_read(fifo_t* fifo, void* buffer, size_t count) -{ - size_t readable = fifo_bytes_readable(fifo); - if (readable == 0) - { - return 0; - } - - if (count > readable) - { - count = readable; - } - - size_t firstSize = fifo->size - fifo->tail; - if (firstSize > count) - { - firstSize = count; - } - - memcpy(buffer, fifo->buffer + fifo->tail, firstSize); - fifo->tail = (fifo->tail + firstSize) % fifo->size; - - size_t remaining = count - firstSize; - if (remaining > 0) - { - memcpy((uint8_t*)buffer + firstSize, fifo->buffer + fifo->tail, remaining); - fifo->tail = (fifo->tail + remaining) % fifo->size; - } - - return count; -} - -size_t fifo_write(fifo_t* fifo, const void* buffer, size_t count) -{ - size_t writeable = fifo_bytes_writeable(fifo); - if (count > writeable) - { - count = writeable; - } - - size_t firstSize = fifo->size - fifo->head; - if (firstSize > count) - { - firstSize = count; - } - - memcpy(fifo->buffer + fifo->head, buffer, firstSize); - fifo->head = (fifo->head + firstSize) % fifo->size; - - size_t remaining = count - firstSize; - if (remaining > 0) - { - memcpy(fifo->buffer + fifo->head, (uint8_t*)buffer + firstSize, remaining); - fifo->head = (fifo->head + remaining) % fifo->size; - } - - return count; -} - -void fifo_advance_head(fifo_t* fifo, size_t count) -{ - fifo->head = (fifo->head + count) % fifo->size; -} - -void fifo_advance_tail(fifo_t* fifo, size_t count) -{ - fifo->tail = (fifo->tail + count) % fifo->size; -} diff --git a/src/libpatchwork/config.c b/src/libpatchwork/config.c index 5e3aaa53a..17aa2ba06 100644 --- a/src/libpatchwork/config.c +++ b/src/libpatchwork/config.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include typedef struct config_pair diff --git a/src/libpatchwork/element.c b/src/libpatchwork/element.c index b79cf0bc5..db452e7b7 100644 --- a/src/libpatchwork/element.c +++ b/src/libpatchwork/element.c @@ -16,7 +16,7 @@ static uint64_t element_send_init(element_t* elem) } static element_t* element_new_raw(element_id_t id, const rect_t* rect, const char* text, element_flags_t flags, - procedure_t procedure, void* data) + procedure_t procedure, void* data) { element_t* elem = malloc(sizeof(element_t)); if (elem == NULL) @@ -46,7 +46,7 @@ static element_t* element_new_raw(element_id_t id, const rect_t* rect, const cha } element_t* element_new(element_t* parent, element_id_t id, const rect_t* rect, const char* text, element_flags_t flags, - procedure_t procedure, void* data) + procedure_t procedure, void* data) { if (parent == NULL || rect == NULL || text == NULL || procedure == NULL) { @@ -74,7 +74,7 @@ element_t* element_new(element_t* parent, element_id_t id, const rect_t* rect, c } element_t* element_new_root(window_t* win, element_id_t id, const rect_t* rect, const char* text, element_flags_t flags, - procedure_t procedure, void* data) + procedure_t procedure, void* data) { if (win == NULL || rect == NULL || text == NULL || procedure == NULL) { @@ -160,7 +160,7 @@ element_t* element_find(element_t* elem, element_id_t id) return NULL; } -void element_set_private(element_t* elem, void* data) +void element_set_private(element_t* elem, void* data) { if (elem == NULL) { diff --git a/src/libpatchwork/font.c b/src/libpatchwork/font.c index b4759ffea..4a052fcda 100644 --- a/src/libpatchwork/font.c +++ b/src/libpatchwork/font.c @@ -2,7 +2,7 @@ #include #include -#include +#include font_t* font_default(display_t* disp) { diff --git a/src/libpatchwork/internal.h b/src/libpatchwork/internal.h index 0326f0cf3..fdf791bbc 100644 --- a/src/libpatchwork/internal.h +++ b/src/libpatchwork/internal.h @@ -1,6 +1,6 @@ -#include +#include -#include +#include #include #include @@ -38,7 +38,7 @@ typedef struct element } element_t; element_t* element_new_root(window_t* win, element_id_t id, const rect_t* rect, const char* text, element_flags_t flags, - procedure_t procedure, void* data); + procedure_t procedure, void* data); typedef struct window { diff --git a/src/libpatchwork/polygon.c b/src/libpatchwork/polygon.c index 08ed953e8..a2d0d6d01 100644 --- a/src/libpatchwork/polygon.c +++ b/src/libpatchwork/polygon.c @@ -1,4 +1,4 @@ -#include +#include #include void polygon_rotate(point_t* points, uint64_t pointCount, double angle, point_t center) diff --git a/src/libpatchwork/theme.c b/src/libpatchwork/theme.c index ce9bda19e..214cb50af 100644 --- a/src/libpatchwork/theme.c +++ b/src/libpatchwork/theme.c @@ -1,7 +1,7 @@ #include "internal.h" -#include -#include +#include +#include #include #include #include diff --git a/src/libpatchwork/window.c b/src/libpatchwork/window.c index 8f72b7e21..a80467e1f 100644 --- a/src/libpatchwork/window.c +++ b/src/libpatchwork/window.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include #define __STDC_WANT_LIB_EXT1__ 1 #include "internal.h" @@ -311,7 +311,7 @@ static uint64_t window_deco_procedure(window_t* win, element_t* elem, const even } window_t* window_new(display_t* disp, const char* name, const rect_t* rect, surface_type_t type, window_flags_t flags, - procedure_t procedure, void* data) + procedure_t procedure, void* data) { if (disp == NULL || name == NULL || rect == NULL || procedure == NULL || strnlen_s(name, MAX_NAME + 1) >= MAX_NAME) { diff --git a/src/libstd/common/ascii_table.c b/src/libstd/common/ascii_table.c index 527f1f4d0..44d9a1566 100644 --- a/src/libstd/common/ascii_table.c +++ b/src/libstd/common/ascii_table.c @@ -1,4 +1,4 @@ -#include <_internal/ascii.h> +#include <_libstd/ascii.h> #include _ascii_entry_t _asciiTable[UINT8_MAX + 1] = { diff --git a/src/libstd/common/digits.h b/src/libstd/common/digits.h index b4e011976..2b7053616 100644 --- a/src/libstd/common/digits.h +++ b/src/libstd/common/digits.h @@ -1,6 +1,6 @@ #pragma once -#include <_internal/ascii.h> +#include <_libstd/ascii.h> #include extern const char _digits[]; diff --git a/src/libstd/common/heap.c b/src/libstd/common/heap.c index 8eda4dd65..8c1be803e 100644 --- a/src/libstd/common/heap.c +++ b/src/libstd/common/heap.c @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/libstd/common/init.c b/src/libstd/common/init.c index 3042e1fb9..402b077e2 100644 --- a/src/libstd/common/init.c +++ b/src/libstd/common/init.c @@ -1,4 +1,4 @@ -#include "libstd/_internal/init.h" +#include "_libstd/init.h" #include "constraint_handler.h" #include "heap.h" @@ -8,7 +8,7 @@ #include "user/user.h" #endif -#include +#include void _std_init(void) { diff --git a/src/libstd/common/print.h b/src/libstd/common/print.h index c0422a5ac..9300ea5ee 100644 --- a/src/libstd/common/print.h +++ b/src/libstd/common/print.h @@ -614,7 +614,7 @@ static inline int _print_format(_print_ctx_t* ctx) return ret; } -static inline int _print(const char* _RESTRICT format, size_t n, va_list arg, void* data) +static inline int _print(const char* _RESTRICT format, size_t n, va_list arg, void* data) { assert(format != NULL); diff --git a/src/libstd/common/scan.h b/src/libstd/common/scan.h index daf5636cc..d29428c93 100644 --- a/src/libstd/common/scan.h +++ b/src/libstd/common/scan.h @@ -663,7 +663,7 @@ static inline int _scan_format(_scan_ctx_t* ctx) return ret; } -static inline int _scan(const char* _RESTRICT format, va_list arg, void* data) +static inline int _scan(const char* _RESTRICT format, va_list arg, void* data) { assert(format != NULL); diff --git a/src/libstd/functions/elf/elf64_relocate.c b/src/libstd/functions/elf/elf64_relocate.c index 04bc2fe70..ab5d4525b 100644 --- a/src/libstd/functions/elf/elf64_relocate.c +++ b/src/libstd/functions/elf/elf64_relocate.c @@ -1,7 +1,7 @@ #include "common/elf.h" uint64_t elf64_relocate(const Elf64_File* elf, Elf64_Addr base, Elf64_Off offset, - void* (*resolve_symbol)(const char* name, void* data), void* data) + void* (*resolve_symbol)(const char* name, void* data), void* data) { for (uint64_t i = 0; i < elf->header->e_shnum; i++) { diff --git a/src/libstd/user/common/file.c b/src/libstd/user/common/file.c index c80a71007..bd438999d 100644 --- a/src/libstd/user/common/file.c +++ b/src/libstd/user/common/file.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include static list_t files; static mtx_t filesMtx; diff --git a/src/libstd/user/common/std_streams.c b/src/libstd/user/common/std_streams.c index a2f2e09ac..abb10bde1 100644 --- a/src/libstd/user/common/std_streams.c +++ b/src/libstd/user/common/std_streams.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include static uint8_t _stdin_buff[BUFSIZ]; static uint8_t _stdout_buff[BUFSIZ]; diff --git a/src/libstd/user/common/syscalls.h b/src/libstd/user/common/syscalls.h index ea6e0fe8b..2c398b43b 100644 --- a/src/libstd/user/common/syscalls.h +++ b/src/libstd/user/common/syscalls.h @@ -3,7 +3,8 @@ #include #include -#include +#include +#include #include #include @@ -283,4 +284,19 @@ static inline uint64_t _syscall_umount(const char* mountpoint) static inline uint64_t _syscall_arch_prctl(arch_prctl_t code, uintptr_t addr) { return _SYSCALL2(uint64_t, SYS_ARCH_PRCTL, arch_prctl_t, code, uintptr_t, addr); +} + +static inline uint64_t _syscall_setup(ioring_t* ring, void* address, size_t sentries, size_t centries) +{ + return _SYSCALL4(uint64_t, SYS_SETUP, ioring_t*, ring, void*, address, size_t, sentries, size_t, centries); +} + +static inline uint64_t _syscall_teardown(ioring_id_t id) +{ + return _SYSCALL1(uint64_t, SYS_TEARDOWN, ioring_id_t, id); +} + +static inline uint64_t _syscall_enter(ioring_id_t id, size_t amount, size_t wait) +{ + return _SYSCALL3(uint64_t, SYS_ENTER, ioring_id_t, id, size_t, amount, size_t, wait); } \ No newline at end of file diff --git a/src/libstd/user/common/threading.h b/src/libstd/user/common/threading.h index 228dbd4dc..8c1a97dd3 100644 --- a/src/libstd/user/common/threading.h +++ b/src/libstd/user/common/threading.h @@ -10,11 +10,11 @@ * @brief Threading. * @defgroup libstd_common_user_threading Threading * @ingroup libstd_common_user - * + * * @todo Write threading documentation. - * + * * @todo Implement Thread Local Storage (TLS). - * + * * @{ */ diff --git a/src/libstd/user/functions/io/bind.c b/src/libstd/user/functions/fs/bind.c similarity index 91% rename from src/libstd/user/functions/io/bind.c rename to src/libstd/user/functions/fs/bind.c index cc4c4ba15..f469b9070 100644 --- a/src/libstd/user/functions/io/bind.c +++ b/src/libstd/user/functions/fs/bind.c @@ -1,4 +1,4 @@ -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/chdir.c b/src/libstd/user/functions/fs/chdir.c similarity index 92% rename from src/libstd/user/functions/io/chdir.c rename to src/libstd/user/functions/fs/chdir.c index 84343232a..66dfdb74a 100644 --- a/src/libstd/user/functions/io/chdir.c +++ b/src/libstd/user/functions/fs/chdir.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/claim.c b/src/libstd/user/functions/fs/claim.c similarity index 91% rename from src/libstd/user/functions/io/claim.c rename to src/libstd/user/functions/fs/claim.c index eff018a30..c7d425e73 100644 --- a/src/libstd/user/functions/io/claim.c +++ b/src/libstd/user/functions/fs/claim.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/close.c b/src/libstd/user/functions/fs/close.c similarity index 92% rename from src/libstd/user/functions/io/close.c rename to src/libstd/user/functions/fs/close.c index 1d76782a1..5a577f1d3 100644 --- a/src/libstd/user/functions/io/close.c +++ b/src/libstd/user/functions/fs/close.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/dup.c b/src/libstd/user/functions/fs/dup.c similarity index 92% rename from src/libstd/user/functions/io/dup.c rename to src/libstd/user/functions/fs/dup.c index cfbb75a0f..1ac7ee1a8 100644 --- a/src/libstd/user/functions/io/dup.c +++ b/src/libstd/user/functions/fs/dup.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/dup2.c b/src/libstd/user/functions/fs/dup2.c similarity index 93% rename from src/libstd/user/functions/io/dup2.c rename to src/libstd/user/functions/fs/dup2.c index a1454645d..6323909f6 100644 --- a/src/libstd/user/functions/io/dup2.c +++ b/src/libstd/user/functions/fs/dup2.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/getdents.c b/src/libstd/user/functions/fs/getdents.c similarity index 93% rename from src/libstd/user/functions/io/getdents.c rename to src/libstd/user/functions/fs/getdents.c index 401e1578a..21713a81c 100644 --- a/src/libstd/user/functions/io/getdents.c +++ b/src/libstd/user/functions/fs/getdents.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/ioctl.c b/src/libstd/user/functions/fs/ioctl.c similarity index 94% rename from src/libstd/user/functions/io/ioctl.c rename to src/libstd/user/functions/fs/ioctl.c index b3b40968a..9fbeecfb0 100644 --- a/src/libstd/user/functions/io/ioctl.c +++ b/src/libstd/user/functions/fs/ioctl.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/link.c b/src/libstd/user/functions/fs/link.c similarity index 93% rename from src/libstd/user/functions/io/link.c rename to src/libstd/user/functions/fs/link.c index b1f9d3d4d..e02c0f6c8 100644 --- a/src/libstd/user/functions/io/link.c +++ b/src/libstd/user/functions/fs/link.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/mkdir.c b/src/libstd/user/functions/fs/mkdir.c similarity index 93% rename from src/libstd/user/functions/io/mkdir.c rename to src/libstd/user/functions/fs/mkdir.c index cfa816891..e213e68ae 100644 --- a/src/libstd/user/functions/io/mkdir.c +++ b/src/libstd/user/functions/fs/mkdir.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/mount.c b/src/libstd/user/functions/fs/mount.c similarity index 92% rename from src/libstd/user/functions/io/mount.c rename to src/libstd/user/functions/fs/mount.c index c43c8e6b3..6a7734fcb 100644 --- a/src/libstd/user/functions/io/mount.c +++ b/src/libstd/user/functions/fs/mount.c @@ -1,4 +1,4 @@ -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/open.c b/src/libstd/user/functions/fs/open.c similarity index 92% rename from src/libstd/user/functions/io/open.c rename to src/libstd/user/functions/fs/open.c index ad4fa54fd..28a891b95 100644 --- a/src/libstd/user/functions/io/open.c +++ b/src/libstd/user/functions/fs/open.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/open2.c b/src/libstd/user/functions/fs/open2.c similarity index 93% rename from src/libstd/user/functions/io/open2.c rename to src/libstd/user/functions/fs/open2.c index 3a9ab1e3d..8e3cf0c5f 100644 --- a/src/libstd/user/functions/io/open2.c +++ b/src/libstd/user/functions/fs/open2.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/openat.c b/src/libstd/user/functions/fs/openat.c similarity index 92% rename from src/libstd/user/functions/io/openat.c rename to src/libstd/user/functions/fs/openat.c index a30a39e3d..d5890b08d 100644 --- a/src/libstd/user/functions/io/openat.c +++ b/src/libstd/user/functions/fs/openat.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/poll.c b/src/libstd/user/functions/fs/poll.c similarity index 93% rename from src/libstd/user/functions/io/poll.c rename to src/libstd/user/functions/fs/poll.c index e1eb8df70..ef9988702 100644 --- a/src/libstd/user/functions/io/poll.c +++ b/src/libstd/user/functions/fs/poll.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/poll1.c b/src/libstd/user/functions/fs/poll1.c similarity index 94% rename from src/libstd/user/functions/io/poll1.c rename to src/libstd/user/functions/fs/poll1.c index b8988f4b1..125c5544d 100644 --- a/src/libstd/user/functions/io/poll1.c +++ b/src/libstd/user/functions/fs/poll1.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/read.c b/src/libstd/user/functions/fs/read.c similarity index 93% rename from src/libstd/user/functions/io/read.c rename to src/libstd/user/functions/fs/read.c index 5498067e7..fc530c067 100644 --- a/src/libstd/user/functions/io/read.c +++ b/src/libstd/user/functions/fs/read.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/readdir.c b/src/libstd/user/functions/fs/readdir.c similarity index 98% rename from src/libstd/user/functions/io/readdir.c rename to src/libstd/user/functions/fs/readdir.c index 268355d07..cffe3c163 100644 --- a/src/libstd/user/functions/io/readdir.c +++ b/src/libstd/user/functions/fs/readdir.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/readfile.c b/src/libstd/user/functions/fs/readfile.c similarity index 94% rename from src/libstd/user/functions/io/readfile.c rename to src/libstd/user/functions/fs/readfile.c index 23b9f962d..75a715239 100644 --- a/src/libstd/user/functions/io/readfile.c +++ b/src/libstd/user/functions/fs/readfile.c @@ -1,4 +1,4 @@ -#include +#include size_t readfile(const char* path, void* buffer, size_t count, size_t offset) { diff --git a/src/libstd/user/functions/io/readlink.c b/src/libstd/user/functions/fs/readlink.c similarity index 93% rename from src/libstd/user/functions/io/readlink.c rename to src/libstd/user/functions/fs/readlink.c index e0d6c3781..2416767dd 100644 --- a/src/libstd/user/functions/io/readlink.c +++ b/src/libstd/user/functions/fs/readlink.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/rmdir.c b/src/libstd/user/functions/fs/rmdir.c similarity index 87% rename from src/libstd/user/functions/io/rmdir.c rename to src/libstd/user/functions/fs/rmdir.c index b40239a89..bc05ae556 100644 --- a/src/libstd/user/functions/io/rmdir.c +++ b/src/libstd/user/functions/fs/rmdir.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include uint64_t rmdir(const char* path) { diff --git a/src/libstd/user/functions/io/scan.c b/src/libstd/user/functions/fs/scan.c similarity index 92% rename from src/libstd/user/functions/io/scan.c rename to src/libstd/user/functions/fs/scan.c index 78130d52c..72f4c825d 100644 --- a/src/libstd/user/functions/io/scan.c +++ b/src/libstd/user/functions/fs/scan.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include uint64_t scan(fd_t fd, const char* format, ...) { diff --git a/src/libstd/user/functions/io/scanfile.c b/src/libstd/user/functions/fs/scanfile.c similarity index 92% rename from src/libstd/user/functions/io/scanfile.c rename to src/libstd/user/functions/fs/scanfile.c index c4feff69b..c804b5dc9 100644 --- a/src/libstd/user/functions/io/scanfile.c +++ b/src/libstd/user/functions/fs/scanfile.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include uint64_t scanfile(const char* path, const char* format, ...) { diff --git a/src/libstd/user/functions/io/seek.c b/src/libstd/user/functions/fs/seek.c similarity index 93% rename from src/libstd/user/functions/io/seek.c rename to src/libstd/user/functions/fs/seek.c index 47e97471d..a7f4e89ee 100644 --- a/src/libstd/user/functions/io/seek.c +++ b/src/libstd/user/functions/fs/seek.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/share.c b/src/libstd/user/functions/fs/share.c similarity index 92% rename from src/libstd/user/functions/io/share.c rename to src/libstd/user/functions/fs/share.c index c2c4dd81a..ceaeaea5d 100644 --- a/src/libstd/user/functions/io/share.c +++ b/src/libstd/user/functions/fs/share.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/sharefile.c b/src/libstd/user/functions/fs/sharefile.c similarity index 93% rename from src/libstd/user/functions/io/sharefile.c rename to src/libstd/user/functions/fs/sharefile.c index 50a9d61e8..ebff87515 100644 --- a/src/libstd/user/functions/io/sharefile.c +++ b/src/libstd/user/functions/fs/sharefile.c @@ -1,5 +1,5 @@ #include -#include +#include uint64_t sharefile(char* key, uint64_t size, const char* path, clock_t timeout) { diff --git a/src/libstd/user/functions/io/sread.c b/src/libstd/user/functions/fs/sread.c similarity index 98% rename from src/libstd/user/functions/io/sread.c rename to src/libstd/user/functions/fs/sread.c index df4d29027..7fc60da04 100644 --- a/src/libstd/user/functions/io/sread.c +++ b/src/libstd/user/functions/fs/sread.c @@ -1,6 +1,6 @@ #include #include -#include +#include char* reads(fd_t fd) { diff --git a/src/libstd/user/functions/io/sreadfile.c b/src/libstd/user/functions/fs/sreadfile.c similarity index 89% rename from src/libstd/user/functions/io/sreadfile.c rename to src/libstd/user/functions/fs/sreadfile.c index ef17cffe4..8bc51bcf2 100644 --- a/src/libstd/user/functions/io/sreadfile.c +++ b/src/libstd/user/functions/fs/sreadfile.c @@ -1,4 +1,4 @@ -#include +#include char* readfiles(const char* path) { diff --git a/src/libstd/user/functions/io/stat.c b/src/libstd/user/functions/fs/stat.c similarity index 93% rename from src/libstd/user/functions/io/stat.c rename to src/libstd/user/functions/fs/stat.c index ab8555072..9d736ba97 100644 --- a/src/libstd/user/functions/io/stat.c +++ b/src/libstd/user/functions/fs/stat.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/swrite.c b/src/libstd/user/functions/fs/swrite.c similarity index 87% rename from src/libstd/user/functions/io/swrite.c rename to src/libstd/user/functions/fs/swrite.c index b88c1ae51..d648f82ea 100644 --- a/src/libstd/user/functions/io/swrite.c +++ b/src/libstd/user/functions/fs/swrite.c @@ -1,5 +1,5 @@ #include -#include +#include size_t writes(fd_t fd, const char* string) { diff --git a/src/libstd/user/functions/io/swritefile.c b/src/libstd/user/functions/fs/swritefile.c similarity index 92% rename from src/libstd/user/functions/io/swritefile.c rename to src/libstd/user/functions/fs/swritefile.c index 874fdebad..b02d92b28 100644 --- a/src/libstd/user/functions/io/swritefile.c +++ b/src/libstd/user/functions/fs/swritefile.c @@ -1,5 +1,5 @@ #include -#include +#include size_t writefiles(const char* path, const char* string) { diff --git a/src/libstd/user/functions/io/symlink.c b/src/libstd/user/functions/fs/symlink.c similarity index 93% rename from src/libstd/user/functions/io/symlink.c rename to src/libstd/user/functions/fs/symlink.c index 580f4fe03..07deeb250 100644 --- a/src/libstd/user/functions/io/symlink.c +++ b/src/libstd/user/functions/fs/symlink.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/unlink.c b/src/libstd/user/functions/fs/unlink.c similarity index 91% rename from src/libstd/user/functions/io/unlink.c rename to src/libstd/user/functions/fs/unlink.c index 475548bad..1de2ade46 100644 --- a/src/libstd/user/functions/io/unlink.c +++ b/src/libstd/user/functions/fs/unlink.c @@ -1,4 +1,4 @@ -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/unmount.c b/src/libstd/user/functions/fs/unmount.c similarity index 91% rename from src/libstd/user/functions/io/unmount.c rename to src/libstd/user/functions/fs/unmount.c index f171bd0c5..8b7b9c8cd 100644 --- a/src/libstd/user/functions/io/unmount.c +++ b/src/libstd/user/functions/fs/unmount.c @@ -1,4 +1,4 @@ -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/vscan.c b/src/libstd/user/functions/fs/vscan.c similarity index 97% rename from src/libstd/user/functions/io/vscan.c rename to src/libstd/user/functions/fs/vscan.c index 7f127c137..d68698df9 100644 --- a/src/libstd/user/functions/io/vscan.c +++ b/src/libstd/user/functions/fs/vscan.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #define _SCAN_GET(ctx) \ ({ \ diff --git a/src/libstd/user/functions/io/vscanfile.c b/src/libstd/user/functions/fs/vscanfile.c similarity index 93% rename from src/libstd/user/functions/io/vscanfile.c rename to src/libstd/user/functions/fs/vscanfile.c index 6d37c78a6..052a62b2c 100644 --- a/src/libstd/user/functions/io/vscanfile.c +++ b/src/libstd/user/functions/fs/vscanfile.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include uint64_t vscanfile(const char* path, const char* format, va_list args) { diff --git a/src/libstd/user/functions/io/write.c b/src/libstd/user/functions/fs/write.c similarity index 93% rename from src/libstd/user/functions/io/write.c rename to src/libstd/user/functions/fs/write.c index 593d5f533..06fbbabe7 100644 --- a/src/libstd/user/functions/io/write.c +++ b/src/libstd/user/functions/fs/write.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/io/writefile.c b/src/libstd/user/functions/fs/writefile.c similarity index 94% rename from src/libstd/user/functions/io/writefile.c rename to src/libstd/user/functions/fs/writefile.c index a1639a1fb..cce3c1841 100644 --- a/src/libstd/user/functions/io/writefile.c +++ b/src/libstd/user/functions/fs/writefile.c @@ -1,4 +1,4 @@ -#include +#include size_t writefile(const char* path, const void* buffer, size_t count, size_t offset) { diff --git a/src/libstd/user/functions/ioring/ioring_enter.c b/src/libstd/user/functions/ioring/ioring_enter.c new file mode 100644 index 000000000..a6dcfda7c --- /dev/null +++ b/src/libstd/user/functions/ioring/ioring_enter.c @@ -0,0 +1,13 @@ +#include + +#include "user/common/syscalls.h" + +uint64_t ioring_enter(ioring_id_t id, size_t amount, size_t wait) +{ + uint64_t result = _syscall_enter(id, amount, wait); + if (result == ERR) + { + errno = _syscall_errno(); + } + return result; +} \ No newline at end of file diff --git a/src/libstd/user/functions/ioring/ioring_setup.c b/src/libstd/user/functions/ioring/ioring_setup.c new file mode 100644 index 000000000..07cb85dcd --- /dev/null +++ b/src/libstd/user/functions/ioring/ioring_setup.c @@ -0,0 +1,13 @@ +#include + +#include "user/common/syscalls.h" + +ioring_id_t ioring_setup(ioring_t* ring, void* address, size_t sentries, size_t centries) +{ + ioring_id_t result = _syscall_setup(ring, address, sentries, centries); + if (result == ERR) + { + errno = _syscall_errno(); + } + return result; +} \ No newline at end of file diff --git a/src/libstd/user/functions/ioring/ioring_teardown.c b/src/libstd/user/functions/ioring/ioring_teardown.c new file mode 100644 index 000000000..d56c0ddba --- /dev/null +++ b/src/libstd/user/functions/ioring/ioring_teardown.c @@ -0,0 +1,13 @@ +#include + +#include "user/common/syscalls.h" + +uint64_t ioring_teardown(ioring_id_t id) +{ + uint64_t result = _syscall_teardown(id); + if (result == ERR) + { + errno = _syscall_errno(); + } + return result; +} \ No newline at end of file diff --git a/src/libstd/user/functions/proc/arch_prctl.c b/src/libstd/user/functions/proc/arch_prctl.c index 4f5a809a9..0ec152890 100644 --- a/src/libstd/user/functions/proc/arch_prctl.c +++ b/src/libstd/user/functions/proc/arch_prctl.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/proc/futex.c b/src/libstd/user/functions/proc/futex.c index 65d665795..a733da021 100644 --- a/src/libstd/user/functions/proc/futex.c +++ b/src/libstd/user/functions/proc/futex.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/proc/getpid.c b/src/libstd/user/functions/proc/getpid.c index 6465f746e..e0e6657bc 100644 --- a/src/libstd/user/functions/proc/getpid.c +++ b/src/libstd/user/functions/proc/getpid.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/proc/gettid.c b/src/libstd/user/functions/proc/gettid.c index eb0853da6..436179752 100644 --- a/src/libstd/user/functions/proc/gettid.c +++ b/src/libstd/user/functions/proc/gettid.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/proc/kill.c b/src/libstd/user/functions/proc/kill.c index 0e779cb93..ceb6e30ba 100644 --- a/src/libstd/user/functions/proc/kill.c +++ b/src/libstd/user/functions/proc/kill.c @@ -1,4 +1,4 @@ -#include +#include #include uint64_t kill(pid_t pid) diff --git a/src/libstd/user/functions/proc/mmap.c b/src/libstd/user/functions/proc/mmap.c index 6788e393f..e4e176636 100644 --- a/src/libstd/user/functions/proc/mmap.c +++ b/src/libstd/user/functions/proc/mmap.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/proc/mprotect.c b/src/libstd/user/functions/proc/mprotect.c index f806cefdf..b187f8b96 100644 --- a/src/libstd/user/functions/proc/mprotect.c +++ b/src/libstd/user/functions/proc/mprotect.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/proc/munmap.c b/src/libstd/user/functions/proc/munmap.c index 58628a21b..84fe0b6a2 100644 --- a/src/libstd/user/functions/proc/munmap.c +++ b/src/libstd/user/functions/proc/munmap.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/proc/nanosleep.c b/src/libstd/user/functions/proc/nanosleep.c index 54ba3e9d9..9f5867897 100644 --- a/src/libstd/user/functions/proc/nanosleep.c +++ b/src/libstd/user/functions/proc/nanosleep.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/proc/spawn.c b/src/libstd/user/functions/proc/spawn.c index b762f5e7d..5c674ce89 100644 --- a/src/libstd/user/functions/proc/spawn.c +++ b/src/libstd/user/functions/proc/spawn.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/proc/uptime.c b/src/libstd/user/functions/proc/uptime.c index 367edc36a..9f1fee05e 100644 --- a/src/libstd/user/functions/proc/uptime.c +++ b/src/libstd/user/functions/proc/uptime.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/stdio/fseek.c b/src/libstd/user/functions/stdio/fseek.c index 41c92cad6..e7340a709 100644 --- a/src/libstd/user/functions/stdio/fseek.c +++ b/src/libstd/user/functions/stdio/fseek.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/file.h" diff --git a/src/libstd/user/functions/stdio/remove.c b/src/libstd/user/functions/stdio/remove.c index 62678bda8..9491b20ba 100644 --- a/src/libstd/user/functions/stdio/remove.c +++ b/src/libstd/user/functions/stdio/remove.c @@ -1,5 +1,5 @@ #include -#include +#include #include "user/common/syscalls.h" diff --git a/src/libstd/user/functions/stdlib/system.c b/src/libstd/user/functions/stdlib/system.c index 2db9b3981..6c4760027 100644 --- a/src/libstd/user/functions/stdlib/system.c +++ b/src/libstd/user/functions/stdlib/system.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include int system(const char* command) diff --git a/src/libstd/user/user.c b/src/libstd/user/user.c index 41739f1a2..f9d01d3bc 100644 --- a/src/libstd/user/user.c +++ b/src/libstd/user/user.c @@ -7,7 +7,7 @@ #include "user/common/file.h" #include "user/common/note.h" -#include +#include #include static void _populate_std_descriptors(void) diff --git a/src/modules/acpi/acpi.c b/src/modules/acpi/acpi.c index d74b9dc73..06a3c4573 100644 --- a/src/modules/acpi/acpi.c +++ b/src/modules/acpi/acpi.c @@ -1,9 +1,9 @@ #include -#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -69,8 +69,8 @@ void acpi_reclaim_memory(const boot_memory_map_t* map) if (desc->Type == EfiACPIReclaimMemory) { - pmm_free_region((void*)PML_LOWER_TO_HIGHER(desc->PhysicalStart), desc->NumberOfPages); - LOG_INFO("reclaim memory [0x%016lx-0x%016lx]\n", desc->PhysicalStart, + pmm_free_region(PHYS_TO_PFN(desc->PhysicalStart), desc->NumberOfPages); + LOG_INFO("reclaim memory [%p-%p]\n", desc->PhysicalStart, ((uintptr_t)desc->PhysicalStart) + desc->NumberOfPages * PAGE_SIZE); } } diff --git a/src/modules/acpi/aml/aml.c b/src/modules/acpi/aml/aml.c index de66a4e4b..0cc12ec5f 100644 --- a/src/modules/acpi/aml/aml.c +++ b/src/modules/acpi/aml/aml.c @@ -1,14 +1,14 @@ -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/src/modules/acpi/aml/debug.c b/src/modules/acpi/aml/debug.c index d41a22583..eba1de7df 100644 --- a/src/modules/acpi/aml/debug.c +++ b/src/modules/acpi/aml/debug.c @@ -1,8 +1,8 @@ -#include +#include #include #include -#include +#include static void aml_debug_dump_print_line(const uint8_t* start, uint64_t lineStart, uint64_t lineEnd) { diff --git a/src/modules/acpi/aml/encoding/arg.c b/src/modules/acpi/aml/encoding/arg.c index cb50e0891..4c7e290ba 100644 --- a/src/modules/acpi/aml/encoding/arg.c +++ b/src/modules/acpi/aml/encoding/arg.c @@ -1,9 +1,9 @@ -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include aml_object_t* aml_arg_obj_read(aml_term_list_ctx_t* ctx) { diff --git a/src/modules/acpi/aml/encoding/data.c b/src/modules/acpi/aml/encoding/data.c index cfe7281a0..9a75a8d40 100644 --- a/src/modules/acpi/aml/encoding/data.c +++ b/src/modules/acpi/aml/encoding/data.c @@ -1,14 +1,14 @@ -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -349,7 +349,7 @@ uint64_t aml_package_element_read(aml_term_list_ctx_t* ctx, aml_object_t* out) if (token.props->type == AML_TOKEN_TYPE_NAME) { - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); diff --git a/src/modules/acpi/aml/encoding/debug.c b/src/modules/acpi/aml/encoding/debug.c index 0e4c9287b..414ee70aa 100644 --- a/src/modules/acpi/aml/encoding/debug.c +++ b/src/modules/acpi/aml/encoding/debug.c @@ -1,7 +1,7 @@ -#include +#include -#include -#include +#include +#include aml_object_t* aml_debug_obj_read(aml_term_list_ctx_t* ctx) { diff --git a/src/modules/acpi/aml/encoding/expression.c b/src/modules/acpi/aml/encoding/expression.c index ea88f3a2a..5a7f34de4 100644 --- a/src/modules/acpi/aml/encoding/expression.c +++ b/src/modules/acpi/aml/encoding/expression.c @@ -1,24 +1,24 @@ -#include +#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/src/modules/acpi/aml/encoding/local.c b/src/modules/acpi/aml/encoding/local.c index 6a549e9ab..acb017a1a 100644 --- a/src/modules/acpi/aml/encoding/local.c +++ b/src/modules/acpi/aml/encoding/local.c @@ -1,9 +1,9 @@ -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include aml_object_t* aml_local_obj_read(aml_term_list_ctx_t* ctx) { diff --git a/src/modules/acpi/aml/encoding/name.c b/src/modules/acpi/aml/encoding/name.c index 3acb5ba64..4996c4af6 100644 --- a/src/modules/acpi/aml/encoding/name.c +++ b/src/modules/acpi/aml/encoding/name.c @@ -1,12 +1,12 @@ -#include +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include @@ -186,12 +186,12 @@ uint64_t aml_root_char_read(aml_term_list_ctx_t* ctx, aml_root_char_t* out) return 0; } -uint64_t aml_name_string_read(aml_term_list_ctx_t* ctx, aml_name_string_t* out) +uint64_t aml_name_string_read(aml_term_list_ctx_t* ctx, aml_name_stioring_t* out) { aml_token_t token; aml_token_peek(ctx, &token); - aml_name_string_t nameString = {0}; + aml_name_stioring_t nameString = {0}; // Starts with either rootchar or prefixpath. switch (token.num) { @@ -226,7 +226,7 @@ uint64_t aml_name_string_read(aml_term_list_ctx_t* ctx, aml_name_string_t* out) aml_object_t* aml_name_string_read_and_resolve(aml_term_list_ctx_t* ctx) { - aml_name_string_t nameStringLocal; + aml_name_stioring_t nameStringLocal; if (aml_name_string_read(ctx, &nameStringLocal) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); diff --git a/src/modules/acpi/aml/encoding/named.c b/src/modules/acpi/aml/encoding/named.c index db20a0452..2b53efeac 100644 --- a/src/modules/acpi/aml/encoding/named.c +++ b/src/modules/acpi/aml/encoding/named.c @@ -1,16 +1,16 @@ -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include uint64_t aml_bank_value_read(aml_term_list_ctx_t* ctx, aml_uint_t* out) { @@ -73,7 +73,7 @@ uint64_t aml_def_opregion_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -104,7 +104,7 @@ uint64_t aml_def_opregion_read(aml_term_list_ctx_t* ctx) aml_object_t* newObject = aml_object_new(); if (newObject == NULL) { - AML_DEBUG_ERROR(ctx, "Failed to create object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to create object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } UNREF_DEFER(newObject); @@ -112,7 +112,7 @@ uint64_t aml_def_opregion_read(aml_term_list_ctx_t* ctx) if (aml_operation_region_set(newObject, regionSpace, regionOffset, regionLen) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -554,7 +554,7 @@ uint64_t aml_def_method_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -580,7 +580,7 @@ uint64_t aml_def_method_read(aml_term_list_ctx_t* ctx) if (aml_method_set(newObject, methodFlags, ctx->current, end, NULL) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -607,7 +607,7 @@ uint64_t aml_def_device_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -626,7 +626,7 @@ uint64_t aml_def_device_read(aml_term_list_ctx_t* ctx) if (aml_device_set(device) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, device) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -668,7 +668,7 @@ uint64_t aml_def_mutex_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -692,7 +692,7 @@ uint64_t aml_def_mutex_read(aml_term_list_ctx_t* ctx) if (aml_mutex_set(newObject, syncFlags) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -746,7 +746,7 @@ uint64_t aml_def_processor_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -786,7 +786,7 @@ uint64_t aml_def_processor_read(aml_term_list_ctx_t* ctx) if (aml_processor_set(processor, procId, pblkAddr, pblkLen) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, processor) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -859,7 +859,7 @@ uint64_t aml_def_create_bit_field_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -876,7 +876,7 @@ uint64_t aml_def_create_bit_field_read(aml_term_list_ctx_t* ctx) if (aml_buffer_field_set(newObject, sourceBuff, bitIndex, 1) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -909,7 +909,7 @@ static inline uint64_t aml_def_create_field_read_helper(aml_term_list_ctx_t* ctx return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -926,7 +926,7 @@ static inline uint64_t aml_def_create_field_read_helper(aml_term_list_ctx_t* ctx if (aml_buffer_field_set(newObject, sourceBuff, byteIndex * 8, fieldWidth) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -961,7 +961,7 @@ uint64_t aml_def_event_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -978,7 +978,7 @@ uint64_t aml_def_event_read(aml_term_list_ctx_t* ctx) if (aml_event_set(newObject) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -1002,7 +1002,7 @@ uint64_t aml_def_thermal_zone_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -1021,7 +1021,7 @@ uint64_t aml_def_thermal_zone_read(aml_term_list_ctx_t* ctx) if (aml_thermal_zone_set(thermalZone) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, thermalZone) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -1072,7 +1072,7 @@ uint64_t aml_def_power_res_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -1105,7 +1105,7 @@ uint64_t aml_def_power_res_read(aml_term_list_ctx_t* ctx) if (aml_power_resource_set(powerResource, systemLevel, resourceOrder) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, powerResource) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -1162,7 +1162,7 @@ uint64_t aml_def_create_field_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -1179,7 +1179,7 @@ uint64_t aml_def_create_field_read(aml_term_list_ctx_t* ctx) if (aml_buffer_field_set(newObject, sourceBuff, bitIndex, numBits) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -1194,14 +1194,14 @@ uint64_t aml_def_data_region_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t regionName; + aml_name_stioring_t regionName; if (aml_name_string_read(ctx, ®ionName) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read RegionName"); return ERR; } - aml_string_t* signature = aml_term_arg_read_string(ctx); + aml_stioring_t* signature = aml_term_arg_read_string(ctx); if (signature == NULL) { AML_DEBUG_ERROR(ctx, "Failed to read Signature"); @@ -1209,7 +1209,7 @@ uint64_t aml_def_data_region_read(aml_term_list_ctx_t* ctx) } UNREF_DEFER(signature); - aml_string_t* oemId = aml_term_arg_read_string(ctx); + aml_stioring_t* oemId = aml_term_arg_read_string(ctx); if (oemId == NULL) { AML_DEBUG_ERROR(ctx, "Failed to read OemId"); @@ -1217,7 +1217,7 @@ uint64_t aml_def_data_region_read(aml_term_list_ctx_t* ctx) } UNREF_DEFER(oemId); - aml_string_t* oemTableId = aml_term_arg_read_string(ctx); + aml_stioring_t* oemTableId = aml_term_arg_read_string(ctx); if (oemTableId == NULL) { AML_DEBUG_ERROR(ctx, "Failed to read OemTableId"); @@ -1285,7 +1285,7 @@ uint64_t aml_def_data_region_read(aml_term_list_ctx_t* ctx) if (aml_operation_region_set(newObject, AML_REGION_SYSTEM_MEMORY, (uint64_t)table, table->length) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, ®ionName, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(®ionName)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(®ionName)); return ERR; } diff --git a/src/modules/acpi/aml/encoding/namespace_modifier.c b/src/modules/acpi/aml/encoding/namespace_modifier.c index 948937820..2f0fe6a74 100644 --- a/src/modules/acpi/aml/encoding/namespace_modifier.c +++ b/src/modules/acpi/aml/encoding/namespace_modifier.c @@ -1,14 +1,14 @@ -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include @@ -31,7 +31,7 @@ uint64_t aml_def_alias_read(aml_term_list_ctx_t* ctx) } UNREF_DEFER(source); - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read or resolve target NameString"); @@ -48,7 +48,7 @@ uint64_t aml_def_alias_read(aml_term_list_ctx_t* ctx) if (aml_alias_set(newObject, source) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add alias object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add alias object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } @@ -63,7 +63,7 @@ uint64_t aml_def_name_read(aml_term_list_ctx_t* ctx) return ERR; } - aml_name_string_t nameString; + aml_name_stioring_t nameString; if (aml_name_string_read(ctx, &nameString) == ERR) { AML_DEBUG_ERROR(ctx, "Failed to read NameString"); @@ -80,7 +80,7 @@ uint64_t aml_def_name_read(aml_term_list_ctx_t* ctx) if (aml_data_ref_object_read(ctx, newObject) == ERR || aml_namespace_add_by_name_string(&ctx->state->overlay, ctx->scope, &nameString, newObject) == ERR) { - AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_string_to_string(&nameString)); + AML_DEBUG_ERROR(ctx, "Failed to add object '%s'", aml_name_stioring_to_string(&nameString)); return ERR; } diff --git a/src/modules/acpi/aml/encoding/package_length.c b/src/modules/acpi/aml/encoding/package_length.c index 1a814879f..48d57874b 100644 --- a/src/modules/acpi/aml/encoding/package_length.c +++ b/src/modules/acpi/aml/encoding/package_length.c @@ -1,8 +1,8 @@ -#include +#include -#include -#include -#include +#include +#include +#include #include #include diff --git a/src/modules/acpi/aml/encoding/statement.c b/src/modules/acpi/aml/encoding/statement.c index e852d6fbd..4ab52a985 100644 --- a/src/modules/acpi/aml/encoding/statement.c +++ b/src/modules/acpi/aml/encoding/statement.c @@ -1,11 +1,11 @@ -#include +#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include diff --git a/src/modules/acpi/aml/encoding/term.c b/src/modules/acpi/aml/encoding/term.c index 509b5f15d..71b2c730d 100644 --- a/src/modules/acpi/aml/encoding/term.c +++ b/src/modules/acpi/aml/encoding/term.c @@ -1,16 +1,16 @@ -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -82,7 +82,7 @@ uint64_t aml_term_arg_read_integer(aml_term_list_ctx_t* ctx, aml_uint_t* out) return 0; } -aml_string_t* aml_term_arg_read_string(aml_term_list_ctx_t* ctx) +aml_stioring_t* aml_term_arg_read_string(aml_term_list_ctx_t* ctx) { aml_object_t* temp = aml_term_arg_read(ctx, AML_STRING); if (temp == NULL) diff --git a/src/modules/acpi/aml/integer.c b/src/modules/acpi/aml/integer.c index f567e4f5f..e423b9da1 100644 --- a/src/modules/acpi/aml/integer.c +++ b/src/modules/acpi/aml/integer.c @@ -1,7 +1,7 @@ -#include +#include #include -#include +#include static uint8_t integerByteSize = 0; diff --git a/src/modules/acpi/aml/namespace.c b/src/modules/acpi/aml/namespace.c index efbc48596..100a12ea2 100644 --- a/src/modules/acpi/aml/namespace.c +++ b/src/modules/acpi/aml/namespace.c @@ -1,13 +1,13 @@ -#include +#include #include #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include @@ -235,7 +235,7 @@ aml_object_t* aml_namespace_find(aml_overlay_t* overlay, aml_object_t* start, ui } aml_object_t* aml_namespace_find_by_name_string(aml_overlay_t* overlay, aml_object_t* start, - const aml_name_string_t* nameString) + const aml_name_stioring_t* nameString) { if (nameString == NULL) { @@ -447,7 +447,7 @@ uint64_t aml_namespace_add_child(aml_overlay_t* overlay, aml_object_t* parent, a } uint64_t aml_namespace_add_by_name_string(aml_overlay_t* overlay, aml_object_t* start, - const aml_name_string_t* nameString, aml_object_t* object) + const aml_name_stioring_t* nameString, aml_object_t* object) { if (nameString == NULL || nameString->namePath.segmentCount == 0) { @@ -470,7 +470,7 @@ uint64_t aml_namespace_add_by_name_string(aml_overlay_t* overlay, aml_object_t* return aml_namespace_add_child(overlay, parent, targetName, object); } - aml_name_string_t parentNameString = *nameString; + aml_name_stioring_t parentNameString = *nameString; parentNameString.namePath.segmentCount--; aml_object_t* parent = aml_namespace_find_by_name_string(overlay, start, &parentNameString); diff --git a/src/modules/acpi/aml/object.c b/src/modules/acpi/aml/object.c index 13ecfc2ac..b1d411a50 100644 --- a/src/modules/acpi/aml/object.c +++ b/src/modules/acpi/aml/object.c @@ -1,11 +1,11 @@ -#include +#include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -227,7 +227,7 @@ void aml_object_clear(aml_object_t* object) UNREF(object->unresolved.from); } object->unresolved.from = NULL; - object->unresolved.nameString = (aml_name_string_t){0}; + object->unresolved.nameString = (aml_name_stioring_t){0}; object->unresolved.callback = NULL; break; case AML_PREDEFINED_SCOPE: @@ -1062,7 +1062,7 @@ uint64_t aml_string_set(aml_object_t* object, const char* str) return 0; } -uint64_t aml_string_resize(aml_string_t* string, uint64_t newLength) +uint64_t aml_string_resize(aml_stioring_t* string, uint64_t newLength) { if (string == NULL) { @@ -1169,7 +1169,7 @@ aml_object_t* aml_alias_traverse(aml_alias_t* alias) return current; } -uint64_t aml_unresolved_set(aml_object_t* object, const aml_name_string_t* nameString, aml_object_t* from, +uint64_t aml_unresolved_set(aml_object_t* object, const aml_name_stioring_t* nameString, aml_object_t* from, aml_patch_up_resolve_callback_t callback) { if (object == NULL || nameString == NULL || callback == NULL) diff --git a/src/modules/acpi/aml/patch_up.c b/src/modules/acpi/aml/patch_up.c index b10bd1f92..3bf80dd32 100644 --- a/src/modules/acpi/aml/patch_up.c +++ b/src/modules/acpi/aml/patch_up.c @@ -1,10 +1,10 @@ -#include +#include #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -74,7 +74,7 @@ uint64_t aml_patch_up_resolve_all(void) aml_namespace_find_by_name_string(&state.overlay, entry->unresolved->from, &entry->unresolved->nameString); if (match == NULL) { - LOG_DEBUG("Still could not resolve '%s'\n", aml_name_string_to_string(&entry->unresolved->nameString)); + LOG_DEBUG("Still could not resolve '%s'\n", aml_name_stioring_to_string(&entry->unresolved->nameString)); errno = EOK; continue; } diff --git a/src/modules/acpi/aml/predefined.c b/src/modules/acpi/aml/predefined.c index 25f289219..1f1c71125 100644 --- a/src/modules/acpi/aml/predefined.c +++ b/src/modules/acpi/aml/predefined.c @@ -1,9 +1,9 @@ -#include +#include #include -#include -#include -#include +#include +#include +#include #include diff --git a/src/modules/acpi/aml/runtime/access_type.c b/src/modules/acpi/aml/runtime/access_type.c index 63b322df7..e5c33b68b 100644 --- a/src/modules/acpi/aml/runtime/access_type.c +++ b/src/modules/acpi/aml/runtime/access_type.c @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/src/modules/acpi/aml/runtime/buffer_field.c b/src/modules/acpi/aml/runtime/buffer_field.c index dff6e210a..401f5716a 100644 --- a/src/modules/acpi/aml/runtime/buffer_field.c +++ b/src/modules/acpi/aml/runtime/buffer_field.c @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/src/modules/acpi/aml/runtime/compare.c b/src/modules/acpi/aml/runtime/compare.c index aae432b94..1b33ef182 100644 --- a/src/modules/acpi/aml/runtime/compare.c +++ b/src/modules/acpi/aml/runtime/compare.c @@ -1,7 +1,7 @@ -#include +#include #include -#include +#include static inline aml_uint_t aml_compare_integers(aml_uint_t a, aml_uint_t b, aml_compare_operation_t operation) { diff --git a/src/modules/acpi/aml/runtime/concat.c b/src/modules/acpi/aml/runtime/concat.c index 2fef644e9..b15536c11 100644 --- a/src/modules/acpi/aml/runtime/concat.c +++ b/src/modules/acpi/aml/runtime/concat.c @@ -1,7 +1,7 @@ -#include +#include #include -#include +#include #include diff --git a/src/modules/acpi/aml/runtime/convert.c b/src/modules/acpi/aml/runtime/convert.c index abf212830..806bdc910 100644 --- a/src/modules/acpi/aml/runtime/convert.c +++ b/src/modules/acpi/aml/runtime/convert.c @@ -1,12 +1,12 @@ -#include +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include @@ -261,10 +261,10 @@ static aml_convert_entry_t packageConverters[AML_TYPE_AMOUNT] = { {AML_PACKAGE, AML_DEBUG_OBJECT, aml_package_to_debug_object}, }; -static uint64_t aml_string_to_integer(aml_state_t* state, aml_object_t* string, aml_object_t* dest) +static uint64_t aml_stioring_to_integer(aml_state_t* state, aml_object_t* string, aml_object_t* dest) { UNUSED(state); - aml_string_t* stringData = &string->string; + aml_stioring_t* stringData = &string->string; uint64_t value = 0; uint64_t maxChars = MIN(stringData->length, aml_integer_byte_size() * 2); // Two hex chars per byte @@ -287,10 +287,10 @@ static uint64_t aml_string_to_integer(aml_state_t* state, aml_object_t* string, return aml_integer_set(dest, value); } -static uint64_t aml_string_to_buffer(aml_state_t* state, aml_object_t* string, aml_object_t* dest) +static uint64_t aml_stioring_to_buffer(aml_state_t* state, aml_object_t* string, aml_object_t* dest) { UNUSED(state); - aml_string_t* stringData = &string->string; + aml_stioring_t* stringData = &string->string; // Regarding zero-length strings the spec says "... the string is treated as a buffer, with each // ASCII string character copied to one buffer byte, including the null @@ -325,7 +325,7 @@ static uint64_t aml_string_to_buffer(aml_state_t* state, aml_object_t* string, a return 0; } -static uint64_t aml_string_to_debug_object(aml_state_t* state, aml_object_t* string, aml_object_t* dest) +static uint64_t aml_stioring_to_debug_object(aml_state_t* state, aml_object_t* string, aml_object_t* dest) { UNUSED(state); UNUSED(dest); @@ -340,9 +340,9 @@ static uint64_t aml_string_to_debug_object(aml_state_t* state, aml_object_t* str } static aml_convert_entry_t stringConverters[AML_TYPE_AMOUNT] = { - {AML_STRING, AML_INTEGER, aml_string_to_integer}, - {AML_STRING, AML_BUFFER, aml_string_to_buffer}, - {AML_STRING, AML_DEBUG_OBJECT, aml_string_to_debug_object}, + {AML_STRING, AML_INTEGER, aml_stioring_to_integer}, + {AML_STRING, AML_BUFFER, aml_stioring_to_buffer}, + {AML_STRING, AML_DEBUG_OBJECT, aml_stioring_to_debug_object}, }; static aml_convert_entry_t* aml_converters_get(aml_type_t srcType) @@ -639,7 +639,7 @@ uint64_t aml_convert_to_buffer(aml_state_t* state, aml_object_t* src, aml_object } else if (src->type == AML_STRING) { - if (aml_string_to_buffer(state, src, temp) == ERR) + if (aml_stioring_to_buffer(state, src, temp) == ERR) { return ERR; } @@ -881,7 +881,7 @@ uint64_t aml_convert_to_integer(aml_state_t* state, aml_object_t* src, aml_objec if (src->type == AML_STRING) { - aml_string_t* stringData = &src->string; + aml_stioring_t* stringData = &src->string; if (stringData->length == 0 || stringData->content == NULL) { errno = EILSEQ; diff --git a/src/modules/acpi/aml/runtime/copy.c b/src/modules/acpi/aml/runtime/copy.c index 644d565ad..663c2e05f 100644 --- a/src/modules/acpi/aml/runtime/copy.c +++ b/src/modules/acpi/aml/runtime/copy.c @@ -1,10 +1,10 @@ -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include #include diff --git a/src/modules/acpi/aml/runtime/eisa_id.c b/src/modules/acpi/aml/runtime/eisa_id.c index 411cff8df..6899ed1db 100644 --- a/src/modules/acpi/aml/runtime/eisa_id.c +++ b/src/modules/acpi/aml/runtime/eisa_id.c @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/modules/acpi/aml/runtime/evaluate.c b/src/modules/acpi/aml/runtime/evaluate.c index d247b773e..6044baed7 100644 --- a/src/modules/acpi/aml/runtime/evaluate.c +++ b/src/modules/acpi/aml/runtime/evaluate.c @@ -1,9 +1,9 @@ -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include aml_object_t* aml_evaluate(aml_state_t* state, aml_object_t* object, aml_type_t targetTypes) { diff --git a/src/modules/acpi/aml/runtime/field_unit.c b/src/modules/acpi/aml/runtime/field_unit.c index 3e3fd8587..0c254ba0f 100644 --- a/src/modules/acpi/aml/runtime/field_unit.c +++ b/src/modules/acpi/aml/runtime/field_unit.c @@ -1,16 +1,15 @@ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include +#include #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -31,7 +30,7 @@ static void* aml_ensure_mem_is_mapped(uint64_t address, aml_bit_size_t accessSiz for (uint64_t page = 0; page < (crossesBoundary ? 2 : 1); page++) { - void* physAddr = (void*)((uintptr_t)address + page * PAGE_SIZE); + phys_addr_t physAddr = (phys_addr_t)address + page * PAGE_SIZE; void* virtAddt = (void*)PML_LOWER_TO_HIGHER(physAddr); if (vmm_map(NULL, virtAddt, physAddr, PAGE_SIZE, PML_GLOBAL | PML_WRITE | PML_PRESENT, NULL, NULL) == NULL) { @@ -137,13 +136,13 @@ static uint64_t aml_system_io_read(aml_state_t* state, aml_opregion_t* opregion, switch (accessSize) { case 8: - *out = io_in8(address); + *out = in8(address); break; case 16: - *out = io_in16(address); + *out = in16(address); break; case 32: - *out = io_in32(address); + *out = in32(address); break; default: LOG_ERR("unable to read opregion with access size %u\n", accessSize); @@ -162,13 +161,13 @@ static uint64_t aml_system_io_write(aml_state_t* state, aml_opregion_t* opregion switch (accessSize) { case 8: - io_out8(address, (uint8_t)value); + out8(address, (uint8_t)value); break; case 16: - io_out16(address, (uint16_t)value); + out16(address, (uint16_t)value); break; case 32: - io_out32(address, (uint32_t)value); + out32(address, (uint32_t)value); break; default: LOG_ERR("unable to write opregion with access size %u\n", accessSize); diff --git a/src/modules/acpi/aml/runtime/method.c b/src/modules/acpi/aml/runtime/method.c index 039d649c1..461aee613 100644 --- a/src/modules/acpi/aml/runtime/method.c +++ b/src/modules/acpi/aml/runtime/method.c @@ -1,10 +1,10 @@ -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include #include diff --git a/src/modules/acpi/aml/runtime/mid.c b/src/modules/acpi/aml/runtime/mid.c index ce31155a2..4dcd444c9 100644 --- a/src/modules/acpi/aml/runtime/mid.c +++ b/src/modules/acpi/aml/runtime/mid.c @@ -1,4 +1,4 @@ -#include +#include aml_object_t* aml_mid(aml_state_t* state, aml_object_t* bufferString, aml_uint_t index, aml_uint_t length) { diff --git a/src/modules/acpi/aml/runtime/mutex.c b/src/modules/acpi/aml/runtime/mutex.c index 6c06bd16a..b000e08df 100644 --- a/src/modules/acpi/aml/runtime/mutex.c +++ b/src/modules/acpi/aml/runtime/mutex.c @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/modules/acpi/aml/runtime/store.c b/src/modules/acpi/aml/runtime/store.c index ca3ebffd8..734b7f466 100644 --- a/src/modules/acpi/aml/runtime/store.c +++ b/src/modules/acpi/aml/runtime/store.c @@ -1,9 +1,9 @@ -#include +#include #include -#include -#include -#include +#include +#include +#include #include diff --git a/src/modules/acpi/aml/state.c b/src/modules/acpi/aml/state.c index a029182d1..959324abe 100644 --- a/src/modules/acpi/aml/state.c +++ b/src/modules/acpi/aml/state.c @@ -1,7 +1,7 @@ -#include +#include -#include -#include +#include +#include #include diff --git a/src/modules/acpi/aml/tests.c b/src/modules/acpi/aml/tests.c index fefeaa8d2..0b98171e4 100644 --- a/src/modules/acpi/aml/tests.c +++ b/src/modules/acpi/aml/tests.c @@ -6,13 +6,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/modules/acpi/aml/to_string.c b/src/modules/acpi/aml/to_string.c index a7510ab35..c02edfeb3 100644 --- a/src/modules/acpi/aml/to_string.c +++ b/src/modules/acpi/aml/to_string.c @@ -1,4 +1,4 @@ -#include +#include #include @@ -251,7 +251,7 @@ const char* aml_object_to_string(aml_object_t* object) } } -const char* aml_name_string_to_string(const aml_name_string_t* nameString) +const char* aml_name_stioring_to_string(const aml_name_stioring_t* nameString) { static char buffer[256]; memset(buffer, 0, sizeof(buffer)); diff --git a/src/modules/acpi/aml/token.c b/src/modules/acpi/aml/token.c index 49d2e73c0..4ace9e66e 100644 --- a/src/modules/acpi/aml/token.c +++ b/src/modules/acpi/aml/token.c @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/src/modules/acpi/devices.c b/src/modules/acpi/devices.c index 2c4c38170..f19ebec83 100644 --- a/src/modules/acpi/devices.c +++ b/src/modules/acpi/devices.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include @@ -8,15 +8,15 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -336,7 +336,7 @@ static void acpi_device_cfg_free(acpi_device_cfg_t* cfg) for (uint64_t i = 0; i < cfg->ioCount; i++) { - io_release(cfg->ios[i].base, cfg->ios[i].length); + port_release(cfg->ios[i].base, cfg->ios[i].length); } free(cfg->irqs); @@ -451,7 +451,7 @@ static uint64_t acpi_device_configure(const char* name) cfg->ios = newIos; port_t base; - if (io_reserve(&base, desc->minBase, desc->maxBase, desc->alignment, desc->length, name) == ERR) + if (port_reserve(&base, desc->minBase, desc->maxBase, desc->alignment, desc->length, name) == ERR) { LOG_ERR("failed to reserve IO ports for ACPI device '%s' due to '%s'\n", name, strerror(errno)); goto error; diff --git a/src/modules/acpi/resources.c b/src/modules/acpi/resources.c index 9e116e7f0..240ac860c 100644 --- a/src/modules/acpi/resources.c +++ b/src/modules/acpi/resources.c @@ -1,21 +1,21 @@ -#include -#include +#include +#include -#include -#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/modules/acpi/tables.c b/src/modules/acpi/tables.c index 2f8d55422..cbfbd5c8a 100644 --- a/src/modules/acpi/tables.c +++ b/src/modules/acpi/tables.c @@ -1,12 +1,12 @@ #include -#include +#include #include #include #include #include #include -#include +#include #include @@ -29,7 +29,7 @@ static uint64_t acpi_table_read(file_t* file, void* buffer, size_t count, size_t return ERR; } - sdt_header_t* table = file->inode->data; + sdt_header_t* table = file->vnode->data; if (table == NULL) { errno = EINVAL; @@ -132,7 +132,7 @@ static uint64_t acpi_tables_push(sdt_header_t* table) } cachedTables[tableAmount++].table = cachedTable; - LOG_INFO("%.*s 0x%016lx 0x%06x v%02X %.*s\n", SDT_SIGNATURE_LENGTH, cachedTable->signature, cachedTable, + LOG_INFO("%.*s %p 0x%06x v%02X %.*s\n", SDT_SIGNATURE_LENGTH, cachedTable->signature, cachedTable, cachedTable->length, cachedTable->revision, SDT_OEM_ID_LENGTH, cachedTable->oemId); return 0; } @@ -200,7 +200,7 @@ uint64_t acpi_tables_init(rsdp_t* rsdp) } xsdt_t* xsdt = (xsdt_t*)PML_ENSURE_HIGHER_HALF(rsdp->xsdtAddress); - LOG_INFO("located XSDT at 0x%016lx\n", rsdp->xsdtAddress); + LOG_INFO("located XSDT at %p\n", rsdp->xsdtAddress); if (acpi_tables_load_from_xsdt(xsdt) == ERR) { diff --git a/src/modules/drivers/apic/apic.c b/src/modules/drivers/apic/apic.c index 30abc5d7e..3e6105f6c 100644 --- a/src/modules/drivers/apic/apic.c +++ b/src/modules/drivers/apic/apic.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include @@ -11,8 +11,8 @@ /** * @brief Advanced Programmable Interrupt Controller. - * @defgroup modules_drivers_apic APIC - * @ingroup modules_drivers + * @defgroup kernel_drivers_apic APIC + * @ingroup kernel_drivers * * This module implements the Advanced Programmable Interrupt Controller (APIC) driver, which includes the per-CPU * local APICs, the IO APICs and the APIC timer. diff --git a/src/modules/drivers/apic/apic_timer.c b/src/modules/drivers/apic/apic_timer.c index 8bab1679e..fae6a35c1 100644 --- a/src/modules/drivers/apic/apic_timer.c +++ b/src/modules/drivers/apic/apic_timer.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #include diff --git a/src/modules/drivers/apic/ioapic.c b/src/modules/drivers/apic/ioapic.c index 6df70f682..cc9d9500a 100644 --- a/src/modules/drivers/apic/ioapic.c +++ b/src/modules/drivers/apic/ioapic.c @@ -1,12 +1,12 @@ -#include -#include +#include +#include #include #include #include #include #include -#include +#include #include #include @@ -106,9 +106,9 @@ uint64_t ioapic_all_init(void) continue; } - void* physAddr = (void*)(uint64_t)ioapic->ioApicAddress; - void* virtAddr = (void*)PML_LOWER_TO_HIGHER(physAddr); - if (vmm_map(NULL, virtAddr, physAddr, PAGE_SIZE, PML_WRITE | PML_GLOBAL | PML_PRESENT, NULL, NULL) == NULL) + void* virtAddr = (void*)PML_LOWER_TO_HIGHER(ioapic->ioApicAddress); + if (vmm_map(NULL, virtAddr, ioapic->ioApicAddress, PAGE_SIZE, PML_WRITE | PML_GLOBAL | PML_PRESENT, NULL, + NULL) == NULL) { LOG_ERR("failed to map io apic\n"); return ERR; diff --git a/src/modules/drivers/apic/lapic.c b/src/modules/drivers/apic/lapic.c index bc1b5550d..6a6f6915b 100644 --- a/src/modules/drivers/apic/lapic.c +++ b/src/modules/drivers/apic/lapic.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -99,15 +99,14 @@ uint64_t lapic_global_init(void) } lapicBase = PML_LOWER_TO_HIGHER(madt->localInterruptControllerAddress); - if (vmm_map(NULL, (void*)lapicBase, (void*)(uintptr_t)madt->localInterruptControllerAddress, PAGE_SIZE, + if (vmm_map(NULL, (void*)lapicBase, madt->localInterruptControllerAddress, PAGE_SIZE, PML_WRITE | PML_GLOBAL | PML_PRESENT, NULL, NULL) == NULL) { LOG_ERR("failed to map local apic\n"); return ERR; } - LOG_INFO("local apic mapped base=0x%016lx phys=0x%016lx\n", lapicBase, - (uintptr_t)madt->localInterruptControllerAddress); + LOG_INFO("local apic mapped base=%p phys=%p\n", lapicBase, (uintptr_t)madt->localInterruptControllerAddress); if (ipi_chip_register(&lapicIpiChip) == ERR) { diff --git a/src/modules/drivers/const/const.c b/src/modules/drivers/const/const.c index 5b6d445da..fa92df1f4 100644 --- a/src/modules/drivers/const/const.c +++ b/src/modules/drivers/const/const.c @@ -12,8 +12,8 @@ /** * @brief Constant devices - * @defgroup modules_drivers_const Constant Devices - * @ingroup modules_drivers + * @defgroup kernel_drivers_const Constant Devices + * @ingroup kernel_drivers * * This module provides the constant devices which provide user space with its primary means of allocating memory and * obtaining constant data. diff --git a/src/modules/drivers/drivers.h b/src/modules/drivers/drivers.h index 5ccaed0bb..4f646dfd2 100644 --- a/src/modules/drivers/drivers.h +++ b/src/modules/drivers/drivers.h @@ -2,6 +2,6 @@ /** * @brief Drivers. - * @defgroup modules_drivers Drivers - * @ingroup modules + * @defgroup kernel_drivers Drivers + * @ingroup kernel */ \ No newline at end of file diff --git a/src/modules/drivers/gop/gop.c b/src/modules/drivers/gop/gop.c index a090c6919..ee27c5526 100644 --- a/src/modules/drivers/gop/gop.c +++ b/src/modules/drivers/gop/gop.c @@ -16,8 +16,8 @@ /** * @brief GOP (Graphics Output Protocol) driver. - * @defgroup modules_drivers_gop GOP Driver - * @ingroup modules_drivers + * @defgroup kernel_drivers_gop GOP Driver + * @ingroup kernel_drivers * * This module provides a framebuffer device for the GOP framebuffer provided by the bootloader. * @@ -67,14 +67,14 @@ static void* gop_mmap(fb_t* fb, void* addr, size_t length, size_t* offset, pml_f process_t* process = process_current(); uintptr_t physAddr = (uintptr_t)gop.physAddr + *offset; - uintptr_t endAddr = physAddr + length; - if (endAddr > (uintptr_t)gop.physAddr + (gop.stride * gop.height * sizeof(uint32_t))) + phys_addr_t endAddr = physAddr + length; + if (endAddr > gop.physAddr + (gop.stride * gop.height * sizeof(uint32_t))) { errno = EINVAL; return NULL; } - return vmm_map(&process->space, addr, (void*)physAddr, length, flags, NULL, NULL); + return vmm_map(&process->space, addr, physAddr, length, flags, NULL, NULL); } static fb_ops_t ops = { diff --git a/src/modules/drivers/hpet/hpet.c b/src/modules/drivers/hpet/hpet.c index 55eb15475..f66aef45d 100644 --- a/src/modules/drivers/hpet/hpet.c +++ b/src/modules/drivers/hpet/hpet.c @@ -10,12 +10,12 @@ #include #include #include -#include +#include /** * @brief High Precision Event Timer - * @defgroup modules_drivers_hpet HPET - * @ingroup modules_drivers + * @defgroup kernel_drivers_hpet HPET + * @ingroup kernel_drivers * * @note Since the HPET might be 32bit it could overflow rather quickly, so we implement a system for checking roughly * when it will overflow and accumulate the counter into a 64 bit nanosecond counter. @@ -218,10 +218,10 @@ static uint64_t hpet_init(void) } address = (uintptr_t)PML_LOWER_TO_HIGHER(hpet->address); - if (vmm_map(NULL, (void*)address, (void*)hpet->address, PAGE_SIZE, PML_WRITE | PML_GLOBAL | PML_PRESENT, NULL, - NULL) == NULL) + if (vmm_map(NULL, (void*)address, hpet->address, PAGE_SIZE, PML_WRITE | PML_GLOBAL | PML_PRESENT, NULL, NULL) == + NULL) { - LOG_ERR("failed to map HPET memory at 0x%016lx\n", hpet->address); + LOG_ERR("failed to map HPET memory at %p\n", hpet->address); return ERR; } @@ -234,7 +234,7 @@ static uint64_t hpet_init(void) return ERR; } - LOG_INFO("started HPET timer phys=0x%016lx virt=0x%016lx period=%lluns timers=%u %s-bit\n", hpet->address, address, + LOG_INFO("started HPET timer phys=%p virt=%p period=%lluns timers=%u %s-bit\n", hpet->address, address, period / (HPET_FEMTOSECONDS_PER_SECOND / CLOCKS_PER_SEC), hpet->comparatorCount + 1, hpet->counterIs64Bit ? "64" : "32"); diff --git a/src/modules/drivers/pci/config.c b/src/modules/drivers/pci/config.c index 8c2990bb2..11fd9d19a 100644 --- a/src/modules/drivers/pci/config.c +++ b/src/modules/drivers/pci/config.c @@ -1,8 +1,8 @@ -#include +#include #include #include -#include +#include static uint64_t entryCount; static mcfg_t* mcfg; @@ -43,14 +43,13 @@ static uint64_t pci_config_init(void) uint64_t length = busCount * 256 * 4096; void* virtAddr = (void*)PML_LOWER_TO_HIGHER(entry->base); - if (vmm_map(NULL, virtAddr, (void*)entry->base, length, PML_WRITE | PML_GLOBAL | PML_PRESENT, NULL, NULL) == - NULL) + if (vmm_map(NULL, virtAddr, entry->base, length, PML_WRITE | PML_GLOBAL | PML_PRESENT, NULL, NULL) == NULL) { - LOG_ERR("failed to map PCI-e configuration space at 0x%016lx\n", entry->base); + LOG_ERR("failed to map PCI-e configuration space at %p\n", entry->base); return ERR; } - LOG_INFO("mapped PCI-e config space 0x%016lx (segment=%u bus=%u-%u)\n", entry->base, entry->segmentGroup, + LOG_INFO("mapped PCI-e config space %p (segment=%u bus=%u-%u)\n", entry->base, entry->segmentGroup, entry->startBus, entry->endBus); } diff --git a/src/modules/drivers/ps2/ps2.c b/src/modules/drivers/ps2/ps2.c index 843771955..4dde416e0 100644 --- a/src/modules/drivers/ps2/ps2.c +++ b/src/modules/drivers/ps2/ps2.c @@ -9,10 +9,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -325,9 +325,9 @@ static uint64_t ps2_devices_test(void) void ps2_drain(void) { clock_wait(PS2_SMALL_DELAY); - while ((io_in8(statusPort)) & PS2_STATUS_OUT_FULL) + while ((in8(statusPort)) & PS2_STATUS_OUT_FULL) { - io_in8(dataPort); + in8(dataPort); clock_wait(PS2_SMALL_DELAY); } } @@ -335,7 +335,7 @@ void ps2_drain(void) uint64_t ps2_wait_until_set(ps2_status_bits_t status) { uint64_t startTime = clock_uptime(); - while ((io_in8(statusPort) & status) == 0) + while ((in8(statusPort) & status) == 0) { if ((clock_uptime() - startTime) > PS2_WAIT_TIMEOUT) { @@ -350,7 +350,7 @@ uint64_t ps2_wait_until_set(ps2_status_bits_t status) uint64_t ps2_wait_until_clear(ps2_status_bits_t status) { uint64_t startTime = clock_uptime(); - while ((io_in8(statusPort) & status) != 0) + while ((in8(statusPort) & status) != 0) { if ((clock_uptime() - startTime) > PS2_WAIT_TIMEOUT) { @@ -369,18 +369,18 @@ uint64_t ps2_read(void) errno = ETIMEDOUT; return ERR; } - return io_in8(dataPort); + return in8(dataPort); } uint64_t ps2_read_no_wait(void) { - if (!(io_in8(statusPort) & PS2_STATUS_OUT_FULL)) + if (!(in8(statusPort) & PS2_STATUS_OUT_FULL)) { errno = EAGAIN; return ERR; } - return io_in8(dataPort); + return in8(dataPort); } uint64_t ps2_write(uint8_t data) @@ -390,7 +390,7 @@ uint64_t ps2_write(uint8_t data) errno = ETIMEDOUT; return ERR; } - io_out8(dataPort, data); + out8(dataPort, data); return 0; } @@ -401,7 +401,7 @@ uint64_t ps2_cmd(ps2_cmd_t command) errno = ETIMEDOUT; return ERR; } - io_out8(commandPort, command); + out8(commandPort, command); return 0; } diff --git a/src/modules/drivers/ps2/ps2.h b/src/modules/drivers/ps2/ps2.h index 8ba201ce4..96ed40ae8 100644 --- a/src/modules/drivers/ps2/ps2.h +++ b/src/modules/drivers/ps2/ps2.h @@ -1,15 +1,15 @@ #pragma once -#include - #include +#include + #include #include /** * @brief IBM Personal Computer/2 ports. - * @defgroup modules_drivers_ps2 PS/2 - * @ingroup modules_drivers + * @defgroup kernel_drivers_ps2 PS/2 + * @ingroup kernel_drivers * * @see https://wiki.osdev.org/I8042_PS/2_Controller * @see https://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Keyboard%20Protocol.htm @@ -206,7 +206,7 @@ typedef struct irq_virt_t irq; ///< IRQ assigned to the device by ACPI. bool attached; ///< The device has been attached from ACPI. bool initialized; ///< The device has been initialized. - void* data; ///< Driver-specific private data. + void* data; ///< Driver-specific private data. } ps2_device_info_t; /** diff --git a/src/modules/drivers/ps2/ps2_kbd.h b/src/modules/drivers/ps2/ps2_kbd.h index bf0c9b8f8..196271790 100644 --- a/src/modules/drivers/ps2/ps2_kbd.h +++ b/src/modules/drivers/ps2/ps2_kbd.h @@ -7,7 +7,7 @@ /** * @brief PS/2 Keyboard Driver. * @defgroup module_drivers_ps2_kbd PS/2 Keyboard Driver - * @ingroup modules_drivers_ps2 + * @ingroup kernel_drivers_ps2 * * @{ */ diff --git a/src/modules/drivers/ps2/ps2_mouse.h b/src/modules/drivers/ps2/ps2_mouse.h index 9bf94580b..9013610b7 100644 --- a/src/modules/drivers/ps2/ps2_mouse.h +++ b/src/modules/drivers/ps2/ps2_mouse.h @@ -7,7 +7,7 @@ /** * @brief PS/2 Mouse Driver. * @defgroup module_drivers_ps2_mouse PS/2 Mouse Driver - * @ingroup modules_drivers_ps2 + * @ingroup kernel_drivers_ps2 * * @todo Implement scrolling and buttons 4 and 5. * diff --git a/src/modules/drivers/ps2/ps2_scanmap.h b/src/modules/drivers/ps2/ps2_scanmap.h index a09a2714b..304103d22 100644 --- a/src/modules/drivers/ps2/ps2_scanmap.h +++ b/src/modules/drivers/ps2/ps2_scanmap.h @@ -7,7 +7,7 @@ /** * @brief PS/2 Scanmap. * @defgroup module_drivers_ps2_scanmap PS/2 Scanmap - * @ingroup modules_drivers_ps2 + * @ingroup kernel_drivers_ps2 * * @{ */ diff --git a/src/modules/drivers/rtc/rtc.c b/src/modules/drivers/rtc/rtc.c index 658acf25e..2bdd5c55d 100644 --- a/src/modules/drivers/rtc/rtc.c +++ b/src/modules/drivers/rtc/rtc.c @@ -1,11 +1,11 @@ -#include +#include #include #include #include -#include -#include - #include +#include +#include + #include /** @@ -28,8 +28,8 @@ static lock_t lock = LOCK_CREATE(); static uint8_t rtc_read(uint8_t reg) { - io_out8(addressPort, reg | 0x80); // Force NMI disable - return io_in8(dataPort); + out8(addressPort, reg | 0x80); // Force NMI disable + return in8(dataPort); } static int rtc_update_in_progress(void) diff --git a/src/modules/fs/9p/9p.c b/src/modules/fs/9p/9p.c index bce207130..c2aaa227d 100644 --- a/src/modules/fs/9p/9p.c +++ b/src/modules/fs/9p/9p.c @@ -8,8 +8,8 @@ /** * @brief 9P Filesystems. - * @defgroup modules_fs_9p 9P Filesystem - * @ingroup modules_fs + * @defgroup kernel_fs_9p 9P Filesystem + * @ingroup kernel_fs * * This module provides an implementation of the 9P filesystem protocol where the kernel acts as a client to a 9P * server, allowing the 9P server to be mounted as a filesystem within the kernel's VFS. @@ -49,7 +49,7 @@ static superblock_ops_t superOps = { .cleanup = ninep_super_cleanup, }; -static dentry_t* ninep_mount(filesystem_t* fs, const char* options, void* data) +static dentry_t* ninep_mount(filesystem_t* fs, const char* options, void* data) { UNUSED(data); @@ -130,12 +130,12 @@ static dentry_t* ninep_mount(filesystem_t* fs, const char* options, void* data) superblock->data = ninep; - inode_t* inode = inode_new(superblock, 0, INODE_DIR, NULL, NULL); - if (inode == NULL) + vnode_t* vnode = vnode_new(superblock, VDIR, NULL, NULL); + if (vnode == NULL) { return NULL; } - UNREF_DEFER(inode); + UNREF_DEFER(vnode); dentry_t* dentry = dentry_new(superblock, NULL, NULL); if (dentry == NULL) @@ -143,7 +143,7 @@ static dentry_t* ninep_mount(filesystem_t* fs, const char* options, void* data) return NULL; } - dentry_make_positive(dentry, inode); + dentry_make_positive(dentry, vnode); superblock->root = dentry; return superblock->root; diff --git a/src/modules/fs/fs.h b/src/modules/fs/fs.h index adc03e657..37c853bfd 100644 --- a/src/modules/fs/fs.h +++ b/src/modules/fs/fs.h @@ -2,6 +2,6 @@ /** * @brief Filesystem Modules. - * @defgroup modules_fs Filesystem Modules - * @ingroup modules + * @defgroup kernel_fs Filesystem Modules + * @ingroup kernel */ \ No newline at end of file diff --git a/src/modules/ipc/ipc.h b/src/modules/ipc/ipc.h index 5f9c7f4fc..3cea58537 100644 --- a/src/modules/ipc/ipc.h +++ b/src/modules/ipc/ipc.h @@ -2,6 +2,6 @@ /** * @brief Inter-Process Communication. - * @defgroup modules_ipc IPC Modules - * @ingroup modules + * @defgroup kernel_ipc IPC Modules + * @ingroup kernel */ \ No newline at end of file diff --git a/src/modules/ipc/pipe/pipe.c b/src/modules/ipc/pipe/pipe.c index b8a635d73..322e8a57f 100644 --- a/src/modules/ipc/pipe/pipe.c +++ b/src/modules/ipc/pipe/pipe.c @@ -11,13 +11,13 @@ #include #include -#include +#include #include /** * @brief Pipes. - * @defgroup modules_ipc_pipe Pipes - * @ingroup modules_ipc + * @defgroup kernel_ipc_pipe Pipes + * @ingroup kernel_ipc * * Pipes are exposed in the `/dev/pipe` directory. Pipes are unidirectional communication channels that can be used for * inter-process communication (IPC). @@ -59,7 +59,7 @@ static uint64_t pipe_open(file_t* file) { return ERR; } - data->buffer = pmm_alloc(); + data->buffer = malloc(PAGE_SIZE); if (data->buffer == NULL) { free(data); @@ -84,7 +84,7 @@ static uint64_t pipe_open2(file_t* files[2]) { return ERR; } - data->buffer = pmm_alloc(); + data->buffer = malloc(PAGE_SIZE); if (data->buffer == NULL) { free(data); @@ -122,7 +122,7 @@ static void pipe_close(file_t* file) { lock_release(&data->lock); wait_queue_deinit(&data->waitQueue); - pmm_free(data->buffer); + free(data->buffer); free(data); return; } diff --git a/src/modules/ipc/shmem/shmem.c b/src/modules/ipc/shmem/shmem.c index 6dc4262ed..c5cefc11b 100644 --- a/src/modules/ipc/shmem/shmem.c +++ b/src/modules/ipc/shmem/shmem.c @@ -17,8 +17,8 @@ #include /** * @brief Shared Memory - * @defgroup modules_ipc_shmem Shared Memory - * @ingroup modules_ipc + * @defgroup kernel_ipc_shmem Shared Memory + * @ingroup kernel_ipc * * Shared memory is exposed in the `/dev/shmem` directory. Shared memory allows multiple processes to share a section of * memory for inter-process communication (IPC). @@ -44,7 +44,7 @@ typedef struct { ref_t ref; uint64_t pageAmount; - void** pages; + pfn_t* pages; lock_t lock; } shmem_object_t; @@ -86,7 +86,7 @@ static shmem_object_t* shmem_object_new(void) return shmem; } -static void shmem_vmm_callback( void* data) +static void shmem_vmm_callback(void* data) { shmem_object_t* shmem = data; if (shmem == NULL) @@ -100,7 +100,7 @@ static void shmem_vmm_callback( void* data) static void* shmem_object_allocate_pages(shmem_object_t* shmem, uint64_t pageAmount, space_t* space, void* address, pml_flags_t flags) { - shmem->pages = malloc(sizeof(void*) * pageAmount); + shmem->pages = malloc(sizeof(pfn_t) * pageAmount); if (shmem->pages == NULL) { return NULL; @@ -110,7 +110,7 @@ static void* shmem_object_allocate_pages(shmem_object_t* shmem, uint64_t pageAmo for (uint64_t i = 0; i < pageAmount; i++) { shmem->pages[i] = pmm_alloc(); - if (shmem->pages[i] == NULL) + if (shmem->pages[i] == ERR) { for (uint64_t j = 0; j < i; j++) { @@ -197,27 +197,25 @@ static void* shmem_mmap(file_t* file, void* address, size_t length, size_t* offs assert(shmem->pages == NULL); return shmem_object_allocate_pages(shmem, pageAmount, space, address, flags); } - else - { - assert(shmem->pages != NULL); - if (*offset >= shmem->pageAmount * PAGE_SIZE) - { - errno = EINVAL; - return NULL; - } + assert(shmem->pages != NULL); - if (*offset % PAGE_SIZE != 0) - { - errno = EINVAL; - return NULL; - } + if (*offset >= shmem->pageAmount * PAGE_SIZE) + { + errno = EINVAL; + return NULL; + } - uint64_t pageOffset = *offset / PAGE_SIZE; - uint64_t availablePages = shmem->pageAmount - pageOffset; - return vmm_map_pages(space, address, &shmem->pages[pageOffset], MIN(pageAmount, availablePages), flags, - shmem_vmm_callback, REF(shmem)); + if (*offset % PAGE_SIZE != 0) + { + errno = EINVAL; + return NULL; } + + uint64_t pageOffset = *offset / PAGE_SIZE; + uint64_t availablePages = shmem->pageAmount - pageOffset; + return vmm_map_pages(space, address, &shmem->pages[pageOffset], MIN(pageAmount, availablePages), flags, + shmem_vmm_callback, REF(shmem)); } static file_ops_t fileOps = { diff --git a/src/modules/modules.h b/src/modules/modules.h index 3abbacd98..260c85851 100644 --- a/src/modules/modules.h +++ b/src/modules/modules.h @@ -2,6 +2,6 @@ /** * @brief Kernel Modules. - * @defgroup modules Modules + * @defgroup kernel Modules * */ \ No newline at end of file diff --git a/src/modules/net/local/local.c b/src/modules/net/local/local.c index b8e696148..81cdc4eeb 100644 --- a/src/modules/net/local/local.c +++ b/src/modules/net/local/local.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include static local_listen_t* local_socket_get_listen(local_socket_t* data) diff --git a/src/modules/net/local/local.h b/src/modules/net/local/local.h index 15fe7ff17..5988d7c14 100644 --- a/src/modules/net/local/local.h +++ b/src/modules/net/local/local.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include typedef struct local_listen local_listen_t; diff --git a/src/modules/net/local/local_conn.h b/src/modules/net/local/local_conn.h index 8c1e387fa..6c0fe4fbd 100644 --- a/src/modules/net/local/local_conn.h +++ b/src/modules/net/local/local_conn.h @@ -5,7 +5,7 @@ #include #include -#include +#include #include typedef struct local_listen local_listen_t; diff --git a/src/modules/net/local/local_listen.h b/src/modules/net/local/local_listen.h index 950a306f7..ed90161db 100644 --- a/src/modules/net/local/local_listen.h +++ b/src/modules/net/local/local_listen.h @@ -1,6 +1,6 @@ #pragma once -#include <_internal/MAX_PATH.h> +#include <_libstd/MAX_PATH.h> #include #include #include @@ -8,7 +8,7 @@ #include #include -#include +#include #include typedef struct socket_family socket_family_t; diff --git a/src/modules/net/net.h b/src/modules/net/net.h index 7f93fc181..1cc3e81f0 100644 --- a/src/modules/net/net.h +++ b/src/modules/net/net.h @@ -3,5 +3,5 @@ /** * @brief Networking protocols. * @defgroup module_net Networking Protocols - * @ingroup modules + * @ingroup kernel */ \ No newline at end of file diff --git a/src/modules/smp/smp.c b/src/modules/smp/smp.c index 1115a0252..41c42d918 100644 --- a/src/modules/smp/smp.c +++ b/src/modules/smp/smp.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -15,8 +15,8 @@ /** * @brief Symmetric Multiprocessing support via APIC. - * @defgroup modules_smp SMP - * @ingroup modules + * @defgroup kernel_smp SMP + * @ingroup kernel * * Symmetric Multiprocessing (SMP) support is implemented using the Advanced Programmable Interrupt Controller (APIC) * system. diff --git a/src/modules/smp/trampoline.c b/src/modules/smp/trampoline.c index e99b13e74..f9d8adfe2 100644 --- a/src/modules/smp/trampoline.c +++ b/src/modules/smp/trampoline.c @@ -23,22 +23,24 @@ static atomic_bool cpuReadyFlag = ATOMIC_VAR_INIT(false); void trampoline_init(void) { - backupBuffer = pmm_alloc(); - if (backupBuffer == NULL) + pfn_t pfn = pmm_alloc(); + if (pfn == ERR) { panic(NULL, "Failed to allocate memory for trampoline backup"); } + backupBuffer = PFN_TO_VIRT(pfn); - trampolineStack = pmm_alloc(); - if (trampolineStack == NULL) + pfn = pmm_alloc(); + if (pfn == ERR) { panic(NULL, "Failed to allocate memory for trampoline stack"); } + trampolineStack = PFN_TO_VIRT(pfn); assert(TRAMPOLINE_SIZE < PAGE_SIZE); - if (vmm_map(NULL, (void*)TRAMPOLINE_BASE_ADDR, (void*)TRAMPOLINE_BASE_ADDR, PAGE_SIZE, PML_WRITE | PML_PRESENT, - NULL, NULL) == NULL) + if (vmm_map(NULL, (void*)TRAMPOLINE_BASE_ADDR, TRAMPOLINE_BASE_ADDR, PAGE_SIZE, PML_WRITE | PML_PRESENT, NULL, + NULL) == NULL) { panic(NULL, "Failed to map trampoline"); } @@ -63,9 +65,9 @@ void trampoline_deinit(void) vmm_unmap(NULL, (void*)TRAMPOLINE_BASE_ADDR, PAGE_SIZE); - pmm_free(backupBuffer); + pmm_free(VIRT_TO_PFN(backupBuffer)); backupBuffer = NULL; - pmm_free(trampolineStack); + pmm_free(VIRT_TO_PFN(trampolineStack)); trampolineStack = NULL; LOG_DEBUG("trampoline deinitialized\n"); diff --git a/src/modules/smp/trampoline.h b/src/modules/smp/trampoline.h index c3fe1a15d..b22752ba7 100644 --- a/src/modules/smp/trampoline.h +++ b/src/modules/smp/trampoline.h @@ -3,7 +3,7 @@ #ifndef __ASSEMBLER__ #include -#include +#include #include #include @@ -11,8 +11,8 @@ /** * @brief Trampoline for CPU initialization - * @defgroup modules_smp_trampoline Trampoline - * @ingroup modules_smp + * @defgroup kernel_smp_trampoline Trampoline + * @ingroup kernel_smp * * The trampoline is a small piece of code used during the initialization of other CPUs in a multiprocessor system. The * code itself must be position-independent and fit within a single memory page, this is why we do all the weird offset diff --git a/src/programs/core/boxd/main.c b/src/programs/core/boxd/main.c index 58d6ed433..414dad2b7 100644 --- a/src/programs/core/boxd/main.c +++ b/src/programs/core/boxd/main.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include /** diff --git a/src/programs/core/boxd/manifest.c b/src/programs/core/boxd/manifest.c index 7622d240d..99fbede53 100644 --- a/src/programs/core/boxd/manifest.c +++ b/src/programs/core/boxd/manifest.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/programs/core/boxspawn/main.c b/src/programs/core/boxspawn/main.c index 1cffc263c..9f8354600 100644 --- a/src/programs/core/boxspawn/main.c +++ b/src/programs/core/boxspawn/main.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/programs/core/init/main.c b/src/programs/core/init/main.c index 52a378f2b..448080849 100644 --- a/src/programs/core/init/main.c +++ b/src/programs/core/init/main.c @@ -1,9 +1,9 @@ #include -#include +#include #include #include #include -#include +#include #include #include #include @@ -74,7 +74,7 @@ static uint64_t init_socket_addr_wait(const char* family, const char* addr) free((void*)data); - if (uptime() - start > CLOCKS_PER_SEC * 10) + if ((uptime() - start) >= CLOCKS_PER_SEC * 10) { close(addrs); return ERR; @@ -149,7 +149,7 @@ static void init_create_pkg_links(void) for (uint64_t i = 0; i < amount; i++) { - if (dirents[i].type != INODE_DIR || dirents[i].path[0] == '.') + if (dirents[i].type != VDIR || dirents[i].path[0] == '.') { continue; } diff --git a/src/programs/core/shell/builtin.c b/src/programs/core/shell/builtin.c index 9deb3d7b4..359aeb5bc 100644 --- a/src/programs/core/shell/builtin.c +++ b/src/programs/core/shell/builtin.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include static uint64_t builtin_cd(uint64_t argc, const char** argv); diff --git a/src/programs/core/shell/interactive.c b/src/programs/core/shell/interactive.c index 036ec8a6c..53ad1b174 100644 --- a/src/programs/core/shell/interactive.c +++ b/src/programs/core/shell/interactive.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/programs/core/shell/main.c b/src/programs/core/shell/main.c index 596f80e08..d6166b579 100644 --- a/src/programs/core/shell/main.c +++ b/src/programs/core/shell/main.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include static uint64_t cmdline_read(char* buffer, uint64_t size) diff --git a/src/programs/core/shell/pipeline.c b/src/programs/core/shell/pipeline.c index 79ffd27e8..2cc60ad55 100644 --- a/src/programs/core/shell/pipeline.c +++ b/src/programs/core/shell/pipeline.c @@ -1,13 +1,13 @@ #include "pipeline.h" #include "builtin.h" -#include <_internal/MAX_PATH.h> +#include <_libstd/MAX_PATH.h> #include #include #include #include #include -#include +#include #include uint64_t pipeline_init(pipeline_t* pipeline, const char* cmdline, fd_t stdin, fd_t stdout, fd_t stderr) @@ -341,7 +341,7 @@ static pid_t pipeline_execute_cmd(cmd_t* cmd) else if (strchr(argv[0], '/') != NULL) { stat_t info; - if (stat(argv[0], &info) != ERR && info.type != INODE_DIR) + if (stat(argv[0], &info) != ERR && info.type != VDIR) { result = spawn(argv, SPAWN_STDIO_FDS); } @@ -369,7 +369,7 @@ static pid_t pipeline_execute_cmd(cmd_t* cmd) if (snprintf(path, MAX_PATH, "%s/%s", token, argv[0]) < MAX_PATH) { stat_t info; - if (stat(path, &info) != ERR && info.type != INODE_DIR) + if (stat(path, &info) != ERR && info.type != VDIR) { const char* newArgv[argc + 1]; newArgv[0] = path; diff --git a/src/programs/core/shell/pipeline.h b/src/programs/core/shell/pipeline.h index e95d3550d..ccfe70351 100644 --- a/src/programs/core/shell/pipeline.h +++ b/src/programs/core/shell/pipeline.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/include/programs/programs.h b/src/programs/programs.h similarity index 100% rename from include/programs/programs.h rename to src/programs/programs.h diff --git a/src/programs/utils/benchmark/main.c b/src/programs/utils/benchmark/main.c index 84a9d7135..29709b884 100644 --- a/src/programs/utils/benchmark/main.c +++ b/src/programs/utils/benchmark/main.c @@ -7,7 +7,7 @@ #define GETPID_ITER 100000 #ifdef _PATCHWORK_OS_ -#include +#include #include static fd_t zeroDev; diff --git a/src/programs/utils/cat/main.c b/src/programs/utils/cat/main.c index b563ad057..e90927f58 100644 --- a/src/programs/utils/cat/main.c +++ b/src/programs/utils/cat/main.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #define BUFFER_SIZE 1024 diff --git a/src/programs/utils/echo/main.c b/src/programs/utils/echo/main.c index e4e57ae80..119d0f12f 100644 --- a/src/programs/utils/echo/main.c +++ b/src/programs/utils/echo/main.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include int main(int argc, char** argv) { diff --git a/src/programs/utils/link/main.c b/src/programs/utils/link/main.c index 01826985a..71fc99921 100644 --- a/src/programs/utils/link/main.c +++ b/src/programs/utils/link/main.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include int main(int argc, char** argv) { diff --git a/src/programs/utils/ls/main.c b/src/programs/utils/ls/main.c index 181cfc10c..2b4792a66 100644 --- a/src/programs/utils/ls/main.c +++ b/src/programs/utils/ls/main.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include static bool showAll = false; static bool showFlags = false; @@ -131,7 +131,7 @@ static uint64_t print_dir(const char* path) for (uint64_t i = 0; i < count; i++) { uint64_t len = strlen(entries[i].path); - if (entries[i].type == INODE_DIR || entries[i].type == INODE_SYMLINK) + if (entries[i].type == VDIR || entries[i].type == VSYMLINK) { len++; } @@ -175,12 +175,12 @@ static uint64_t print_dir(const char* path) int len = strlen(name); const char* modifier = (ent->flags & DIRENT_MOUNTED) ? "\033[4m" : ""; - if (ent->type == INODE_DIR) + if (ent->type == VDIR) { printf("%s\033[34m%s%s\033[0m/", modifier, name, showFlags ? ent->mode : ""); len++; } - else if (ent->type == INODE_SYMLINK) + else if (ent->type == VSYMLINK) { printf("%s\033[36m%s%s\033[0m@", modifier, name, showFlags ? ent->mode : ""); len++; diff --git a/src/programs/utils/mv/main.c b/src/programs/utils/mv/main.c index e610de448..56e2deb24 100644 --- a/src/programs/utils/mv/main.c +++ b/src/programs/utils/mv/main.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include int main(int argc, char** argv) { diff --git a/src/programs/utils/readlink/main.c b/src/programs/utils/readlink/main.c index e66121d1f..a1d8c5fe2 100644 --- a/src/programs/utils/readlink/main.c +++ b/src/programs/utils/readlink/main.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include int main(int argc, char** argv) { diff --git a/src/programs/utils/ringtest/main.c b/src/programs/utils/ringtest/main.c new file mode 100644 index 000000000..b4a8cb8ce --- /dev/null +++ b/src/programs/utils/ringtest/main.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +#define SENTRIES 64 +#define CENTRIES 128 + +int main() +{ + printf("setting up ring test...\n"); + ioring_t ring; + ioring_id_t id = ioring_setup(&ring, NULL, SENTRIES, CENTRIES); + if (id == ERR) + { + printf("failed to set up ring\n"); + return errno; + } + + memset(&ring.ctrl->regs, -1, sizeof(ring.ctrl->regs)); + + printf("pushing nop sqe to ring %llu...\n", ring.id); + sqe_t sqe = SQE_CREATE(IO_OP_NOP, SQE_HARDLINK | (SQE_REG0 << SQE_SAVE), CLOCKS_PER_SEC, 0x1234); + sqe_push(&ring, &sqe); + + printf("pushing nop sqe to ring %llu...\n", ring.id); + sqe = (sqe_t)SQE_CREATE(IO_OP_NOP, SQE_LINK, CLOCKS_PER_SEC, 0x5678); + sqe_push(&ring, &sqe); + + printf("entering ring...\n"); + if (ioring_enter(id, 2, 2) == ERR) + { + printf("failed to enter ring\n"); + return errno; + } + + cqe_t cqe; + while (cqe_pop(&ring, &cqe)) + { + printf("cqe:\n"); + + printf("cqe data: %p\n", cqe.data); + printf("cqe op: %d\n", cqe.op); + printf("cqe error: %s\n", strerror(cqe.error)); + printf("cqe result: %llu\n", cqe._result); + } + + printf("registers:\n"); + for (uint64_t i = 0; i < SQE_REGS_MAX; i++) + { + printf("reg[%llu]: %llu\n", i, ring.ctrl->regs[i]); + } + + printf("tearing down ring...\n"); + ioring_teardown(id); + return 0; +} diff --git a/src/programs/utils/ringtest/ringtest.mk b/src/programs/utils/ringtest/ringtest.mk new file mode 100644 index 000000000..d03e4494c --- /dev/null +++ b/src/programs/utils/ringtest/ringtest.mk @@ -0,0 +1,11 @@ +include Make.defaults + +TARGET := $(BINDIR)/$(PROGRAM) + +LDFLAGS += + +all: $(TARGET) + +.PHONY: all + +include Make.rules diff --git a/src/programs/utils/rm/main.c b/src/programs/utils/rm/main.c index f2dec29d2..43b08f3b5 100644 --- a/src/programs/utils/rm/main.c +++ b/src/programs/utils/rm/main.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include int main(int argc, char** argv) { diff --git a/src/programs/utils/stat/main.c b/src/programs/utils/stat/main.c index b85d36a1d..f320e302d 100644 --- a/src/programs/utils/stat/main.c +++ b/src/programs/utils/stat/main.c @@ -3,18 +3,18 @@ #include #include #include -#include +#include #include -static const char* type_to_string(itype_t type) +static const char* type_to_string(vtype_t type) { switch (type) { - case INODE_FILE: + case VREG: return "file"; - case INODE_DIR: + case VDIR: return "directory"; - case INODE_SYMLINK: + case VSYMLINK: return "symlink"; default: return "unknown"; @@ -33,7 +33,7 @@ static void print_stat(const char* path) printf(" File: %s\n", path); printf(" Size: %llu\t\tBlocks: %llu\t IO Block: %llu %s\n", buffer.size, buffer.blocks, buffer.blockSize, type_to_string(buffer.type)); - printf("Superblock: %llu\tInode: %llu\tLinks: %llu\n", buffer.sbid, buffer.number, buffer.linkAmount); + printf("Superblock: %llu\tVnode: %llu\tLinks: %llu\n", buffer.sbid, buffer.number, buffer.linkAmount); printf(" Max: %llu\n", buffer.maxFileSize); printf(" Name: %s\n", buffer.name); printf("Access: %s", ctime(&buffer.accessTime)); diff --git a/src/programs/utils/symlink/main.c b/src/programs/utils/symlink/main.c index 676f27f39..3628e6755 100644 --- a/src/programs/utils/symlink/main.c +++ b/src/programs/utils/symlink/main.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include int main(int argc, char** argv) { diff --git a/src/programs/utils/tail/main.c b/src/programs/utils/tail/main.c index 40d3dc122..b7a916961 100644 --- a/src/programs/utils/tail/main.c +++ b/src/programs/utils/tail/main.c @@ -1,10 +1,10 @@ -#include <_internal/clock_t.h> +#include <_libstd/clock_t.h> #include #include #include #include #include -#include +#include int main(int argc, char* argv[]) { diff --git a/src/programs/utils/top/main.c b/src/programs/utils/top/main.c index 621732acc..3f6ed7f74 100644 --- a/src/programs/utils/top/main.c +++ b/src/programs/utils/top/main.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/programs/utils/touch/main.c b/src/programs/utils/touch/main.c index d2ffac5f2..03d35cdd4 100644 --- a/src/programs/utils/touch/main.c +++ b/src/programs/utils/touch/main.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include int main(int argc, char** argv) {