From ea5ebe0809fb31b9f125ac0689f706cc5f3f078f Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sun, 30 Apr 2023 17:06:02 +0300 Subject: rename to kmi --- include/apos/assert.h | 85 ----- include/apos/atomic.h | 548 ------------------------------- include/apos/attrs.h | 68 ---- include/apos/bits.h | 364 --------------------- include/apos/builtin.h | 28 -- include/apos/canary.h | 27 -- include/apos/caps.h | 88 ----- include/apos/conf.h | 52 --- include/apos/debug.h | 429 ------------------------ include/apos/dmem.h | 62 ---- include/apos/elf.h | 626 ----------------------------------- include/apos/initrd.h | 57 ---- include/apos/ipi.h | 37 --- include/apos/lock.h | 55 ---- include/apos/mem.h | 223 ------------- include/apos/mem_nodes.h | 42 --- include/apos/mem_regions.h | 303 ----------------- include/apos/nodes.h | 94 ------ include/apos/pmem.h | 71 ---- include/apos/power.h | 38 --- include/apos/proc.h | 37 --- include/apos/sizes.h | 220 ------------- include/apos/sp_tree.h | 156 --------- include/apos/string.h | 310 ------------------ include/apos/syscalls.h | 142 -------- include/apos/tcb.h | 417 ------------------------ include/apos/timer.h | 136 -------- include/apos/types.h | 494 ---------------------------- include/apos/uapi.h | 792 --------------------------------------------- include/apos/unaligned.h | 255 --------------- include/apos/utils.h | 671 -------------------------------------- include/apos/vmem.h | 287 ---------------- 32 files changed, 7214 deletions(-) delete mode 100644 include/apos/assert.h delete mode 100644 include/apos/atomic.h delete mode 100644 include/apos/attrs.h delete mode 100644 include/apos/bits.h delete mode 100644 include/apos/builtin.h delete mode 100644 include/apos/canary.h delete mode 100644 include/apos/caps.h delete mode 100644 include/apos/conf.h delete mode 100644 include/apos/debug.h delete mode 100644 include/apos/dmem.h delete mode 100644 include/apos/elf.h delete mode 100644 include/apos/initrd.h delete mode 100644 include/apos/ipi.h delete mode 100644 include/apos/lock.h delete mode 100644 include/apos/mem.h delete mode 100644 include/apos/mem_nodes.h delete mode 100644 include/apos/mem_regions.h delete mode 100644 include/apos/nodes.h delete mode 100644 include/apos/pmem.h delete mode 100644 include/apos/power.h delete mode 100644 include/apos/proc.h delete mode 100644 include/apos/sizes.h delete mode 100644 include/apos/sp_tree.h delete mode 100644 include/apos/string.h delete mode 100644 include/apos/syscalls.h delete mode 100644 include/apos/tcb.h delete mode 100644 include/apos/timer.h delete mode 100644 include/apos/types.h delete mode 100644 include/apos/uapi.h delete mode 100644 include/apos/unaligned.h delete mode 100644 include/apos/utils.h delete mode 100644 include/apos/vmem.h (limited to 'include/apos') diff --git a/include/apos/assert.h b/include/apos/assert.h deleted file mode 100644 index 09b9f13..0000000 --- a/include/apos/assert.h +++ /dev/null @@ -1,85 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_ASSERT_H -#define APOS_ASSERT_H - -/** - * @file assert.h - * Assertions. Note that contrary to how assertios usually function, apos has - * three different levels of assertions: Catastrophic, hard and soft. - * - * Soft assertions merely warn about something that might cause issues, but let - * the execution continue normally. - * - * Hard assertions warn about the assertion not holding and returns from the - * function. - * - * Catastrophic assertions warn about the assertion and crash the kernel. - */ - -#include -#include - -/** \todo should this exit or do something explosive like that? */ -#if !defined(DNDEBUG) - -/** - * The kernel is in an irrepairable state, just give up. - * - * @param x Condition to check for. - */ -#define catastrophic_assert(x) \ - do { \ - if (unlikely(!(x))) { \ - error("catastrophic assertion failed: " QUOTE(x) "\n"); \ - while (1) { \ - } \ - } \ - } while (0); - -/** - * The function cannot continue without this assertion, but doesn't necessarily - * mean that the kernel is borked. - * - * @warning Implicit return. - * - * @param x Condition to check for. - * @param r Return value on failed check. - */ -#define hard_assert(x, r) \ - { \ - if (unlikely(!(x))) { \ - warn("hard assertion failed: " QUOTE(x) "\n"); \ - return r; \ - } \ - } - -/** - * Unexpected case, but not likely to cause problems, likely a bug. - * - * @param x Condition to check for. - */ -#define soft_assert(x) \ - do { \ - if (unlikely(!(x))) { \ - info("soft assertion failed: " QUOTE(x) "\n"); \ - } \ - } while (0); -#else -#define catastrophic_assert(x) -#define hard_assert(x, r) -#define soft_assert(x) -#endif - -/** - * Use when return value doesn't exist. - * - * Example: - * @code{.c} - * void func() { hard_assert(x, RETURN_VOID); } - * @endcode - */ -#define RETURN_VOID - -#endif /* APOS_ASSERT_H */ diff --git a/include/apos/atomic.h b/include/apos/atomic.h deleted file mode 100644 index 2a1a621..0000000 --- a/include/apos/atomic.h +++ /dev/null @@ -1,548 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef ATOMIC_H -#define ATOMIC_H - -/** - * @file atomic.h - * Atomics, closely modeled after C17 stdatomic.h. Largely dependent on the - * compiler at the moment, if I run into an architecture that required the OS' - * help to implement these I'll have to look into how to do that, but for now - * this is probably good enough. - */ - -#include /* GLUE */ - -/** - * Memory ordering modes. - * - * @remark Look up details somewhere elsewhere, as I'm not an expert on memory ordering. - * Would like to be, though. - */ -typedef enum { - /** Relaxed memory ordering. */ - memory_order_relaxed = __ATOMIC_RELAXED, - /** Consume memory ordering. */ - memory_order_consume = __ATOMIC_CONSUME, - /** Acquire memory ordering. */ - memory_order_acquire = __ATOMIC_ACQUIRE, - /** Release memory ordering. */ - memory_order_release = __ATOMIC_RELEASE, - /** Acquire and release memory ordering. */ - memory_order_acq_rel = __ATOMIC_ACQ_REL, - /** Sequential memory ordering. */ - memory_order_seq_cst = __ATOMIC_SEQ_CST -} memory_order; - -/** Atomic boolean. */ -typedef _Atomic _Bool atomic_bool; - -/** Atomic char. */ -typedef _Atomic char atomic_char; - -/** Atomic signed char. */ -typedef _Atomic signed char atomic_schar; - -/** Atomic unsigned char. */ -typedef _Atomic unsigned char atomic_uchar; - -/** Atomic signed short. */ -typedef _Atomic short atomic_short; - -/** Atomic unsigned short. */ -typedef _Atomic unsigned short atomic_ushort; - -/** Atomic signed int. */ -typedef _Atomic int atomic_int; - -/** Atomic unsigned int. */ -typedef _Atomic unsigned int atomic_uint; - -/** Atomic signed long. */ -typedef _Atomic long atomic_long; - -/** Atomic unsigned long. */ -typedef _Atomic unsigned long atomic_ulong; - -/** Atomic signed long long. */ -typedef _Atomic long long atomic_llong; - -/** Atomic unsigned long long. */ -typedef _Atomic unsigned long long atomic_ullong; - -/** Atomic 16bit char. */ -typedef _Atomic __CHAR16_TYPE__ atomic_char16_t; - -/** Atomic 32bit char. */ -typedef _Atomic __CHAR32_TYPE__ atomic_char32_t; - -/** Atomic \ref wchar_t. */ -typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t; - -/** Atomic \ref int_least8_t. */ -typedef _Atomic __INT_LEAST8_TYPE__ atomic_int_least8_t; - -/** Atomic \ref uint_least8_t. */ -typedef _Atomic __UINT_LEAST8_TYPE__ atomic_uint_least8_t; - -/** Atomic \ref int_least16_t. */ -typedef _Atomic __INT_LEAST16_TYPE__ atomic_int_least16_t; - -/** Atomic \ref uint_least16_t. */ -typedef _Atomic __UINT_LEAST16_TYPE__ atomic_uint_least16_t; - -/** Atomic \ref int_least32_t. */ -typedef _Atomic __INT_LEAST32_TYPE__ atomic_int_least32_t; - -/** Atomic \ref uint_least32_t. */ -typedef _Atomic __UINT_LEAST32_TYPE__ atomic_uint_least32_t; - -/** Atomic \ref int_least64_t. */ -typedef _Atomic __INT_LEAST64_TYPE__ atomic_int_least64_t; - -/** Atomic \ref uint_least64_t. */ -typedef _Atomic __UINT_LEAST64_TYPE__ atomic_uint_least64_t; - -/** Atomic \ref int_fast8_t. */ -typedef _Atomic __INT_FAST8_TYPE__ atomic_int_fast8_t; - -/** Atomic \ref uint_fast8_t. */ -typedef _Atomic __UINT_FAST8_TYPE__ atomic_uint_fast8_t; - -/** Atomic \ref int_fast16_t. */ -typedef _Atomic __INT_FAST16_TYPE__ atomic_int_fast16_t; - -/** Atomic \ref uint_fast16_t. */ -typedef _Atomic __UINT_FAST16_TYPE__ atomic_uint_fast16_t; - -/** Atomic \ref int_fast32_t. */ -typedef _Atomic __INT_FAST32_TYPE__ atomic_int_fast32_t; - -/** Atomic \ref uint_fast32_t. */ -typedef _Atomic __UINT_FAST32_TYPE__ atomic_uint_fast32_t; - -/** Atomic \ref int_fast64_t. */ -typedef _Atomic __INT_FAST64_TYPE__ atomic_int_fast64_t; - -/** Atomic \ref uint_fast64_t. */ -typedef _Atomic __UINT_FAST64_TYPE__ atomic_uint_fast64_t; - -/** Atomic \ref intptr_t. */ -typedef _Atomic __INTPTR_TYPE__ atomic_intptr_t; - -/** Atomic \ref uintptr_t. */ -typedef _Atomic __UINTPTR_TYPE__ atomic_uintptr_t; - -/** Atomic \ref size_t. */ -typedef _Atomic __SIZE_TYPE__ atomic_size_t; - -/** Atomic \ref ptrdiff_t. */ -typedef _Atomic __PTRDIFF_TYPE__ atomic_ptrdiff_t; - -/** Atomic \ref intmax_t. */ -typedef _Atomic __INTMAX_TYPE__ atomic_intmax_t; - -/** Atomic \ref uintmax_t. */ -typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t; - -/** - * Atomic variable initialization. Can safely be ignored. - * - * @param VALUE Value to be used in initialization. - * @return \c VALUE - */ -#define ATOMIC_VAR_INIT(VALUE) (VALUE) - -/** - * Atomic pointer initialization. - * - * @param PTR Pointer to where value should be stored. - * @param VAL Value to store. - */ -#define atomic_init(PTR, VAL) atomic_store_explicit(PTR, VAL, __ATOMIC_RELAXED) - -/** - * Kill dependency. - * \todo Figure out what it means. - * - * @param y Value whose dependencies should be killed. - * @return \c y - */ -#define kill_dependency(y) (y) - -/** - * Check if given type is lock free. - * - * @param x Type to check. - * @return \c 0 if never lock free, \c 1 if sometimes lock free, \c 2 if always lock - * free. - */ -#if defined(__GNUC__) -#define CMPLR_LOCK_FREE(x) GLUE(__GCC_ATOMIC_, x)##_LOCK_FREE -#elif defined(__clang__) -#define CMPLR_LOCK_FREE(x) GLUE(__CLANG_ATOMIC_, x)##_LOCK_FREE -#endif - -/** Whether \ref atomic_bool is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_BOOL_LOCK_FREE CMPLR_LOCK_FREE(BOOL) - -/** Whether \ref atomic_char is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_CHAR_LOCK_FREE CMPLR_LOCK_FREE(CHAR) - -/** Whether \ref atomic_char16_t is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_CHAR16_T_LOCK_FREE CMPLR_LOCK_FREE(CHAR16_T) - -/** Whether \ref atomic_char32_t is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_CHAR32_T_LOCK_FREE CMPLR_LOCK_FREE(CHAR32_T) - -/** Whether \ref atomic_wchar_t is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_WCHAR_T_LOCK_FREE CMPLR_LOCK_FREE(WCHAR32_T) - -/** Whether \ref atomic_short is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_SHORT_LOCK_FREE CMPLR_LOCK_FREE(SHORT) - -/** Whether \ref atomic_int is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_INT_LOCK_FREE CMPLR_LOCK_FREE(INT) - -/** Whether \ref atomic_long is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_LONG_LOCK_FREE CMPLR_LOCK_FREE(LONG) - -/** Whether \ref atomic_llong is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_LLONG_LOCK_FREE CMPLR_LOCK_FREE(LLONG) - -/** Whether atomic pointers are lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_POINTER_LOCK_FREE CMPLR_LOCK_FREE(POINTER) - -/** - * Helper macro for creating builtin symbols. - * - * @param x Base name of symbol. - */ -#if defined(__GNUC__) -#define C11_ATOMIC(x) GLUE(__atomic_, x) -#elif defined(__clang__) -#define C11_ATOMIC(x) GLUE(__c11_atomic_, x) -#endif - -/* no libc, so fences aren't used here (unless implemented, but I don't see that - * to be necessary) - * - * void atomic_thread_fence(memory_order); - * void atomic_signal_fence(memory_order); - */ - -/** - * Atomic thread fence. - * - * @param order Memory ordering. \see memory_order. - */ -#define atomic_thread_fence(order) C11_ATOMIC(thread_fence)(order) - -/** - * Atomic signal fence. - * - * @param order Memory ordering. \see memory_order. - */ -#define atomic_signal_fence(order) C11_ATOMIC(signal_fence)(order) - -/** - * Whether object is lock free. - * - * @param obj Object to check. - * @return \ref true if the object is lock free, \ref false otherwise. - */ -#if defined(__GNUC__) -#define atomic_is_lock_free(obj) C11_ATOMIC(is_lock_free)(sizeof(*(obj)), (obj)) -#elif defined(__clang__) -#define atomic_is_lock_free(obj) C11_ATOMIC(is_lock_free)(sizeof(*(obj))) -#endif - -/** - * Helper macro for creating some more builtin symbols. - * GCC uses \c _n suffixes for functions for equivalent functions in Clang, and - * this macro automatically appends \c _n when needed. - * - * @param x Base name of symbol. - */ -#if defined(__GNUC__) -#define N_ATOMIC(x) GLUE(C11_ATOMIC(x), _n) -#elif defined(__clang__) -#define N_ATOMIC(x) C11_ATOMIC(x) -#endif - -/** - * Explicit memory ordering for atomic store. - * - * @param obj Pointer to store destination. - * @param val Value to be stored. - * @param mode Memory ordering. \see memory_order. - */ -#define atomic_store_explicit(obj, val, mode) N_ATOMIC(store)(obj, val, mode) - -/** - * Atomic memory store with implicit strongest memory ordering. - * - * @param obj Pointer to store destination. - * @param val Value to be stored. - */ -#define atomic_store(obj, val) \ - atomic_store_explicit(obj, val, __ATOMIC_SEQ_CST); - -/** - * Explicit memory ordering for atomic load. - * Type is deduced from \c obj. - * - * @param obj Pointer to load source. - * @param mode Memory ordering. \see memory_order. - * @return Value at \c obj. - */ -#define atomic_load_explicit(obj, mode) N_ATOMIC(load)(obj, mode) - -/** - * Atomic memory load with implicit strongest memory ordering. - * Type is deduced from \c obj. - * - * @param obj Pointer to load source. - * @return Value at \c obj. - */ -#define atomic_load(obj) \ - atomic_load_explicit(obj, __ATOMIC_SEQ_CST) - -/** - * Explicit memory ordering for atomic exchange. - * Type is deduced from \c obj. - * - * @param obj Pointer to exchange destination. - * @param val Value to be inserted at \c obj. - * @param mode Memory ordering. \see memory_order. - * @return Value at \c obj. - */ -#define atomic_exchange_explicit(obj, val, mode) \ - N_ATOMIC(exchange)(obj, val, mode) - -/** - * Atomic memory exchange with implicit strongest memory ordering. - * Type is deduced from \c obj. - * - * @param obj Pointer to exchange destination. - * @param val Value to be inserted at \c obj. - * @return Value at \c obj. - */ -#define atomic_exchange(obj, val) \ - atomic_exchange_explicit(obj, val, __ATOMIC_SEQ_CST) - -/** - * Explicit strong memory compare and exchange. - * If \c obj and \c val are equal, the contents of \c obj are replaced with \c - * des. Otherwise, the contents of \c des is replaced with the contents of \c - * obj. The exchange is not allowed to spuriously fail. - * Type is deduced from \c obj. - * - * @param obj Pointer to object to be compared. - * @param val Value to be compared against. - * @param des Value to be copied if \c obj and \c val equal. - * @param suc Memory ordering of succesful exchange. \see memory_order. - * @param fail Memory ordering of unsuccesful exchange. \see memory_order. - * @return \ref true if \c obj and \c val equal, \ref false otherwise. - */ -#if defined(__GNUC__) -#define atomic_compare_exchange_strong_explicit(obj, val, des, suc, fail) \ - N_ATOMIC(compare_exchange)(obj, val, des, 0, suc, fail) -#elif defined(__clang__) -#define atomic_compare_exchange_strong_explicit(obj, val, des, suc, fail) \ - N_ATOMIC(compare_exchange_strong)(obj, val, des, suc, fail) -#endif - -/** - * Strong memory compare and exchange with implicit strongest ordering. \see - * atomic_compare_exchange_strong_explicit(). - * Type is deduced from \c obj. - * - * @param obj Pointer to object to be compared. - * @param val Value to be compared agains. - * @param des Value to be copied if \c obj and \c val equal. - * @return \ref true if \c obj and \c val equal, \ref false otherwise. - */ -#define atomic_compare_exchange_strong(obj, val, des) \ - atomic_compare_exchange_strong_explicit( \ - obj, val, des, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) - -/** - * Explicit weak memory compare and exchange. - * If \c obj and \c val are equal, the contents of \c obj are replaced with \c - * des. Otherwise, the contents of \c des is replaced with the contents of \c - * obj. The exchange is allowed to spuriously fail. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to be compared against. - * @param des Value to be copied if \c obj and \c val equal. - * @param suc Memory ordering on succesful exchange. \see memory_order. - * @param fail Memory ordering on unsuccesful exchange. \see memory_order. - * @return \ref true if \c obj and \c val equal and exchange was succesful, \ref - * false otherwise. - */ -#if defined(__GNUC__) -#define atomic_compare_exchange_weak_explicit(obj, val, des, suc, fail) \ - N_ATOMIC(compare_exchange)(obj, val, des, 1, suc, fail) -#elif defined(__clang__) -#define atomic_compare_exchange_weak_explicit(obj, val, des, suc, fail) \ - N_ATOMIC(compare_exchange_weak)(obj, val, des, suc, fail) -#endif - -/** - * Weak memory compare and exchange with implicit strongest ordering. - * \see atomic_compare_exchange_weak_explicit(). - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to be compared against. - * @param des Value to be copied if \c obj and \c val equal. - * @return \ref true if \c obj and \c val equal and exchange was succesful, \ref - * false otherwise. - */ -#define atomic_compare_exchange_weak(obj, val, des) \ - atomic_compare_exchange_weak_explicit(obj, val, des, __ATOMIC_SEQ_CST, \ - __ATOMIC_SEQ_CST) - -/** - * Explicit atomic in-place addition. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to be added to object. - * @param mode Memory ordering. \see memory_order. - * @return Contents of \c obj before addition. - */ -#define atomic_fetch_add_explicit(obj, val, mode) \ - C11_ATOMIC(fetch_add)(obj, val, mode) - -/** - * Atomic in-place addition with implicit strongest memory ordering. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to be added to object. - * @return Contents of \c obj before addition. - */ -#define atomic_fetch_add(obj, val) \ - atomic_fetch_add_explicit(obj, val, __ATOMIC_SEQ_CST) - -/** - * Explicit atomic in-place subtraction. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to be subtracted from object. - * @param mode Memory ordering. \see memory_order. - * @return Contents of \c obj before subtraction. - */ -#define atomic_fetch_sub_explicit(obj, val, mode) \ - C11_ATOMIC(fetch_sub)(obj, val, mode) - -/** - * Atomic in-place subtraction with implicit strongest memory ordering. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to be subtracted from object. - * @return Contents of \c obj before subtraction. - */ -#define atomic_fetch_sub(obj, val) \ - atomic_fetch_sub_explicit(obj, val, __ATOMIC_SEQ_CST) - -/** - * Explicit atomic in-place bitwise \c AND. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to bitwise \c AND with contents of object. - * @param mode Memory ordering. \see memory_order. - * @return Contents of \c obj before bitwise \c AND. - */ -#define atomic_fetch_and_explicit(obj, val, mode) \ - C11_ATOMIC(fetch_and)(obj, val, mode) - -/** - * Atomic in-place bitwise \c AND with implicit strongest memory ordering. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to bitwise \c AND with contents of object. - * @return Contents of \c obj before bitwise \c AND. - */ -#define atomic_fetch_and(obj, val) \ - atomic_fetch_and_explicit(obj, val, __ATOMIC_SEQ_CST) - -/** - * Explicit atomic in-place bitwise \c XOR. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to bitwise \c XOR with contents of object. - * @param mode Memory ordering. \see memory_order. - * @return Contents of \c obj before bitwise \c XOR. - */ -#define atomic_fetch_xor_explicit(obj, val, mode) \ - C11_ATOMIC(fetch_xor)(obj, val, mode) - -/** - * Atomic in-place bitwise \c XOR with implicit strongest memory ordering. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to bitwise \c XOR with contents of object. - * @return Contents of \c obj before bitwise \c XOR. - */ -#define atomic_fetch_xor(obj, val) \ - atomic_fetch_xor_explicit(obj, val, __ATOMIC_SEQ_CST) - -/** - * Explicit atomic in-place bitwise \c OR. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to bitwise \c OR with contents of object. - * @param mode Memory ordering. \see memory_order. - * @return Contents of \c obj before bitwise \c OR. - */ -#define atomic_fetch_or_explicit(obj, val, mode) \ - C11_ATOMIC(fetch_or)(obj, val, mode) - -/** - * Atomic in-place bitwise \c OR with implicit strongest memory ordering. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to bitwise \c OR with contents of object. - * @return Contents of \c obj before bitwise \c OR. - */ -#define atomic_fetch_or(obj, val) \ - atomic_fetch_or_explicit(obj, val, __ATOMIC_SEQ_CST) - -/** - * Explicit atomic in-place bitwise \c NAND. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to bitwise \c OR with contents of object. - * @param mode Memory ordering. \see memory_order. - * @return Contents of \c obj before bitwise \c NAND. - */ -#define atomic_fetch_nand_explicit(obj, val, mode) \ - C11_ATOMIC(fetch_nand)(obj, val, mode) - -/** - * Atomic in-place bitwise \c NAND with implicit strongest memory ordering. - * Type is deduced from \c obj. - * - * @param obj Pointer to object. - * @param val Value to bitwise \c NAND with contents of object. - * @return Contents of \c obj before bitwise \c NAND. - */ -#define atomic_fetch_nand(obj, val) \ - atomic_fetch_nand_explicit(obj, val, __ATOMIC_SEQ_CST) - -/* skip atomic flags, probably not needed */ -#endif /* ATOMIC_H */ diff --git a/include/apos/attrs.h b/include/apos/attrs.h deleted file mode 100644 index a2591af..0000000 --- a/include/apos/attrs.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_COMPILER_ATTRIBUTES_H -#define APOS_COMPILER_ATTRIBUTES_H - -/** - * @file attrs.h - * Attribute shorthands. - */ - -/** - * Ask the preprocessor if specified attribute is available. - * Currently unused, but I really should use it. - * - * @param x Attribute whose existence should be checked. - * @return Non-zero when available, \c 0 when not available. - * \todo Figure out which attributes are necessary and which are good to have - */ -#if !defined(__has_attribute) -#define __has_attribute(x) 0 -#endif - -/** - * Place object into section. - * - * @param section Section name to place the object in. - */ -#define __section(section) __attribute__((__section__(section))) - -/** - * Inform the compiler that the function uses printf formatting. - * - * @param x Index of the format string. - * @param y Index of variadic arguments. - */ -#define __fmt(x, y) __attribute__((format(__printf__, x, y))) - - -/** Printf formatting attribute to not confuse doxygen. */ -#define __printf __fmt(1, 2) - -/** - * Align object. - * - * @param a Value to which object should be aligned. - */ -#define __aligned(a) __attribute__((aligned(a))) - -/** Don't inline function. */ -#define __noinline __attribute__((noinline)) - -/** Function should not return. */ -#define __noreturn __attribute__((noreturn)) - -/** Pack structure. */ -#define __packed __attribute__((packed)) - -/** Weak linkage. */ -#define __weak __attribute__((weak)) - -/** Main entry point of kernel proper. */ -#define __main __section(".kernel.start") __noinline - -/** Entry point of kernel loader. */ -#define __init __section(".init.start") __noinline - -#endif /* APOS_COMPILER_ATTRIBUTES_H */ diff --git a/include/apos/bits.h b/include/apos/bits.h deleted file mode 100644 index adb8e85..0000000 --- a/include/apos/bits.h +++ /dev/null @@ -1,364 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_BITS_H -#define APOS_BITS_H - -/** - * @file bits.h - * Bit manipulations. - */ - -#include -#include - -/** @name Arithmetic integer bit manipulation. */ -/** @{ */ -/** - * Find first set bit in \c int. - * - * @param v Integer to find first set bit in. - * @return Index of least significant bit + 1 or 0 if \p v is 0. - */ -#if __has_builtin(__builtin_ffs) -#define ffs(v) __builtin_ffs(v) -#else -int ffs(int v); -#endif - -/** - * Check if bits are set. - * - * @param x Value to check in. - * @param y Mask of bits to check. - * @return \c 0 if none of the bits aren't set, non-zero otherwise. - */ -#define is_set(x, y) ((x) & (y)) - -/** - * Set bits. - * - * @param x Value to set in. - * @param y Mask of bits to set. - */ -#define set_bits(x, y) ((x) |= (y)) - -/** - * Clear bits. - * - * @param x Value to clear in. - * @param y Mask of bits to clear. - */ -#define clear_bits(x, y) ((x) &= ~(y)) - -/** - * Set bit. - * Wrapper around \ref set_bits() for when only one bit is changed, - * mostly just for readability purposes. - * - * @param x Value to set in. - * @param y Mask of bit to set. - */ -#define set_bit(x, y) set_bits(x, y) - -/** Clear bit. - * Wrapper around \ref clear_bits() for when only one bit is - * changed, mostly just for readability purposes. - * - * @param x Value to clear in. - * @param y Mask of bit to clear. - */ -#define clear_bit(x, y) clear_bits(x, y) - -/** - * Is nth bit set. - * - * @param x Value to check in. - * @param y Index of bit to check. - * @return \c 0 if bit is not set, non-zero otherwise. - */ -#define is_nset(x, y) (is_set((x), 1UL << (y))) - -/** - * Set nth bit. - * - * @param x Value to set in. - * @param y Index of bit to set. - */ -#define set_nbit(x, y) (set_bit((x), 1UL << (y))) - -/** Clear nth bit. - * - * @param x Value to clear in. - * @param y Index of bit to clear. - */ -#define clear_nbit(x, y) (clear_bit((x), 1UL << (y))) - -/** @} */ - -/** - * @name Bitmap manipulation. - * A bitmap can be any number of bits in an array-like structure. - */ -/** @{ */ - -/** - * Is nth bit set in bitmap. - * - * @param bmap Pointer to bitmap. - * @param n Index of bit to check. - * @return \c 0 if bit is not set, non-zero otherwise. - */ -static inline bool bitmap_is_set(void *bmap, size_t n) -{ - uint8_t *bitmap = bmap; - size_t i = n / 8; - size_t r = n - (i * 8); - return is_nset(bitmap[i], r); -} - -/** - * Set nth bit in bitmap. - * - * @param bmap Bitmap. - * @param n Index of bit to set. - */ -static inline void bitmap_set(void *bmap, size_t n) -{ - uint8_t *bitmap = bmap; - size_t i = n / 8; - size_t r = n - (i * 8); - set_nbit(bitmap[i], r); -} - -/** - * Clear nth bit in bitmap. - * - * @param bmap Bitmap. - * @param n Index of bit to clear. - */ -static inline void bitmap_clear(void *bmap, size_t n) -{ - uint8_t *bitmap = bmap; - size_t i = n / 8; - size_t r = n - (i * 8); - clear_nbit(bitmap[i], r); -} - -/** - * Find first bit, either set or unset, in bitmap. - * - * @param bmap Bitmap. - * @param n Size of bitmap in bits. - * @param set Wether to seek for set or unset bits. - * @return Index of found bit + 1 or \p n + 1 if no bit was found. - */ -static inline size_t bitmap_find_first(void *bmap, size_t n, bool set) -{ - size_t i = n / (sizeof(int) * 8); - - size_t c = 0; - int *imap = (int *)bmap; - - int target = set ? 0 : -1; - for (; c < i; ++c) - if (imap[c] != target) - break; - - size_t b = c * sizeof(int) * 8; - int check = set ? imap[c] : ~imap[c]; - if (c != i) - return b + ffs(check) - 1; - - size_t r = n - (i * sizeof(int) * 8); - if (!r) - return n + 1; - - bool comp = set ? true : false; - for (size_t a = 0; a < r; ++a) - if (bitmap_is_set(bmap, b + a) == comp) - return b + a; - - return n + 1; -} - -/** - * Convenience wrapper around bitmap_find_first(). - * - * @param bmap \see bitmap_find_first(). - * @param n \see bitmap_find_first(). - * @return \see bitmap_find_first(). - */ -static inline size_t bitmap_find_first_unset(void *bmap, size_t n) -{ - return bitmap_find_first(bmap, n, false); -} - -/** - * Convenience wrapper around bitmap_find_first(). - * - * @param bmap \see bitmap_find_first(). - * @param n \see bitmap_find_first(). - * @return \see bitmap_find_first(). - */ -static inline size_t bitmap_find_first_set(void *bmap, size_t n) -{ - return bitmap_find_first(bmap, n, true); -} - -/** @} */ - -/** - * Swap byte order in \ref uint16_t. - * - * @param u \ref uint16_t to swap. - * @return \c u with its byte order swapper. - */ -uint16_t __bswap16(uint16_t u); - -/** - * Swap byte order in \ref uint32_t. - * - * @param u \ref uint32_t to swap. - * @return \c u with its byte order swapped. - */ -uint32_t __bswap32(uint32_t u); - -/** - * Swap byte order in \ref uint64_t. - * - * @param u \ref uint64_t to swap. - * @return \c u with its byte order swapped. - */ -uint64_t __bswap64(uint64_t u); - -#if __has_builtin(__builtin_bswap16) -#define __bswap16(x) __builtin_bswap16(x) -#endif - -#if __has_builtin(__builtin_bswap32) -#define __bswap32(x) __builtin_bswap32(x) -#endif - -#if __has_builtin(__builtin_bswap64) -#define __bswap64(x) __builtin_bswap64(x) -#endif - -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - -/** - * Convert big endian \ref uint16_t to cpu endianness. - * - * @param x \ref uint16_t to convert. - * @return \c x in cpu endianness. - */ -#define be16_to_cpu(x) __bswap16(x) - -/** - * Convert big endian \ref uint32_t to cpu endianness. - * - * @param x \ref uint32_t to convert. - * @return \c x in cpu endianness. - */ -#define be32_to_cpu(x) __bswap32(x) - -/** - * Convert big endian \ref uint64_t to cpu endianness. - * - * @param x \ref uint64_t to convert. - * @return \c x in cpu endianness. - */ -#define be64_to_cpu(x) __bswap64(x) - -/** - * Convert cpu endian \ref uint16_t to big endian. - * - * @param x \ref uint16_t to convert. - * @return \c x in big endian. - */ -#define cpu_to_be16(x) __bswap16(x) - -/** - * Convert cpu endian \ref uint32_t to big endian. - * - * @param x \ref uint32_t to convert. - * @return \c x in big endian. - */ -#define cpu_to_be32(x) __bswap32(x) - -/** - * Convert cpu endian to \ref uint64_t to big endian. - * - * @param x \ref uint64_t to convert. - * @return \c x in big endian. - */ -#define cpu_to_be64(x) __bswap64(x) - -/** - * Convert little endian \ref uint16_t to cpu endianness. - * - * @param x \ref uint16_t to convert. - * @return \c x in cpu endianness. - */ -#define le16_to_cpu(x) (x) - -/** - * Convert little endian \ref uint32_t to cpu endianness. - * - * @param x \ref uint32_t to convert. - * @return \c x in cpu endianness. - */ -#define le32_to_cpu(x) (x) - -/** - * Convert little endian \ref uint64_t to cpu endianness. - * - * @param x \ref uint64_t to convert. - * @return \c x in cpu endianness. - */ -#define le64_to_cpu(x) (x) - -/** - * Convert cpu endian \ref uint16_t to little endian. - * - * @param x \ref uint16_t to convert. - * @return \c x in little endian. - */ -#define cpu_to_le16(x) (x) - -/** - * Convert cpu endian \ref uint32_t to little endian. - * - * @param x \ref uint32_t to convert. - * @return \c x in little endian. - */ -#define cpu_to_le32(x) (x) - -/** Convert cpu endian \ref uint64_t to little endian. - * - * @param x \ref uint64_t to convert. - * @return \c x in little endian. - */ -#define cpu_to_le64(x) (x) - -#else - -#define be16_to_cpu(x) (x) -#define be32_to_cpu(x) (x) -#define be64_to_cpu(x) (x) - -#define cpu_to_be16(x) (x) -#define cpu_to_be32(x) (x) -#define cpu_to_be64(x) (x) - -#define le16_to_cpu(x) __bswap16(x) -#define le32_to_cpu(x) __bswap32(x) -#define le64_to_cpu(x) __bswap64(x) - -#define cpu_to_le16(x) __bswap16(x) -#define cpu_to_le32(x) __bswap32(x) -#define cpu_to_le64(x) __bswap64(x) - -#endif - -#endif /* APOS_BITS_H */ diff --git a/include/apos/builtin.h b/include/apos/builtin.h deleted file mode 100644 index 6d7039e..0000000 --- a/include/apos/builtin.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_BUILTIN_H -#define APOS_BUILTIN_H - -/** - * @file builtin.h - * Defines __has_builtin, if the compiler doesn't support it. - * - * Technically we only support clang and gcc at the moment, and they both - * support __has_builtin, but if some interesting compiler comes along then - * we'll be golden. - */ - -/** - * Check whether compiler supports the builtin. - * Note that this definition is only for when the compiler doesn't provide it - * automatically. - * - * @param x Base name of builtin to check for. - * @return \c 0 when not supported, non-zero when supported. - */ -#ifndef __has_builtin -#define __has_builtin(x) (0) -#endif - -#endif /* APOS_BUILTIN_H */ diff --git a/include/apos/canary.h b/include/apos/canary.h deleted file mode 100644 index 30a3dd2..0000000 --- a/include/apos/canary.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef APOS_CANARY_H -#define APOS_CANARY_H - -/** - * @file canary.h - * Kernel stack canary handling. - */ - -#include -#include - -/** - * Place canary at end of kernel stack. - * - * @param t \ref tcb whose kernel stack to place canary in. - */ -void set_canary(struct tcb *t); - -/** - * Check that canary hasn't been accidentally overwritten. - * - * @param t \ref tcb whose kernel stack canary to check. - * @return \ref true if overwritten, \ref false otherwise. - */ -bool check_canary(struct tcb *t); - -#endif /* APOS_CANARY_H */ diff --git a/include/apos/caps.h b/include/apos/caps.h deleted file mode 100644 index e762d0f..0000000 --- a/include/apos/caps.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef APOS_CAPS_H -#define APOS_CAPS_H - -/** - * @file caps.h - * Capabilities of threads. - * \todo The list of capabilities should maybe be placed in some other file so - * as to easier extract it into userspace programs. - * - * @todo is it realistic to assume we will never need more than 32 capabilities? - * If so, we can remove the offset nonsense. - */ - -#include - -/** Helper typedef for capabilities. */ -typedef unsigned char capflags_t; - -enum { - /** Thread is allowed to set capabilities of other threads. */ - CAP_CAPS = (1 << 0), - - /** Thread is allowed to modify process statuses, create/exec/fork/etc. */ - CAP_PROC = (1 << 1), - - /** Thread is allowed to force interrupt to callback in other thread. */ - CAP_CALL = (1 << 2), - - /** Thread is allowed to shut down system. */ - CAP_POWER = (1 << 3), - - /** Thread is allowed to access configuration parameters. */ - CAP_CONF = (1 << 4), -}; - -/** - * Check that offset is OK. - * - * @param o Offset to check. - * @return \ref true is OK, \ref false otherwise. - */ -#define cap_off_ok(o) (o == 0) - -/** - * Set capabilities. - * - * @param x Capabilities to modify. - * @param o Offset. - * @param c Capabilities to set. - */ -#define set_caps(x, o, c) set_bits(x, c) - -/** - * Clear capabilities. - * - * @param x Capabilities to modify. - * @param o Offset. - * @param c Capabilities to set. - */ -#define clear_caps(x, o, c) clear_bits(x, c) - -/** - * Copy capabilities. - * - * @param x Capabilities to copy to. - * @param y Capabilities to copy from. - */ -#define copy_caps(x, y) (x = y) - -/** - * Get capabilities at offset \p o. - * - * @param x Capabilities to get from. - * @param o Offset to get capabilities from. - * @return Capabilities at offset \p o. - */ -#define get_caps(x, o) (x) - -/** - * Check if something has capability. - * - * @param x Capabilities to check in. - * @param c Capability to check for. - * @return \ref true if \p x has \p c, \ref false otherwise. - */ -#define has_cap(x, c) (x & c) - -#endif /* APOS_CAPS_H */ diff --git a/include/apos/conf.h b/include/apos/conf.h deleted file mode 100644 index ef6a641..0000000 --- a/include/apos/conf.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_CONF_H -#define APOS_CONF_H - -/** - * @file conf.h - * Global configuration file, gives extern access to runtime configuration - * parameters when they're implemented. - */ - -#include - -/** - * Provides access to the runtime global parameter. - * \remark Note that runtime parameter passing is not yet implemented, and I might - * implement per-thread stack sizes as well. - * \global - * \todo This should probably be a function instead. - */ -extern size_t __thread_stack_size; - -/** - * Provides access to the runtime global parameter. - * Must be at most RPC_STACK_TOP - RPC_STACK_BASE. - * - * \see __thread_stack_size. - * \global - * \todo This should probably also be a function instead. - */ -extern size_t __call_stack_size; - -/** - * Provides access to the runtime global parameter. This sets the maximum size - * a single rpc stack instance can be. - * - * Must be at most a fourth of \ref __call_stack_size? - * (that way we can maybe pretty quickly check that we're running out of memory - * for stack stuff and can return an error about it) - * - * \global - */ -extern size_t __rpc_stack_size; - -/** - * Convenience macro for requirement of ratio between \ref __rpc_stack_size and - * \ref __call_stack_size. - */ -#define RPC_STACK_RATIO 4 - -#endif /* APOS_CONF_H */ diff --git a/include/apos/debug.h b/include/apos/debug.h deleted file mode 100644 index 0d8ec26..0000000 --- a/include/apos/debug.h +++ /dev/null @@ -1,429 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_DEBUG_H -#define APOS_DEBUG_H - -/** - * @file debug.h - * Debug printing. - * - * Note that 'Integer format specifier' means "%i", which is identical to "%d" - * in the context of outputting integers. - */ - -#include -#include -#include - -/** @name Internal. */ -/** @{ */ - -/** Long integer prefix. Approximate, but probably good enough */ -#if _LP64 -#define __PRI64_PREFIX "l" -#else -#define __PRI64_PREFIX "ll" -#endif - -/** Long pointer in integer type prefix. */ -#if _LP64 -#define __PRIPTR_PREFIX "l" -#else -#define __PRIPTR_PREFIX -#endif - -/** @} */ - -/** @name Decimal format specifiers. */ -/** @{ */ - -/** Decimal format specifief for \ref int8_t */ -#define PRId8 "d" - -/** Decimal format specifier for \ref int16_t */ -#define PRId16 "d" - -/** Decimal format specifier for \ref int32_t */ -#define PRId32 "d" - -/** Decimal format specifier for int16_t */ -#define PRId64 __PRI64_PREFIX "d" - -/** Decimal format specifier for \ref int_least8_t. */ -#define PRIdLEAST8 "d" - -/** Decimal format specifier for \ref int_least16_t. */ -#define PRIdLEAST16 "d" - -/** Decimal format specifier for \ref int_least32_t. */ -#define PRIdLEAST32 "d" - -/** Decimal format specifier for \ref int_least64_t. */ -#define PRIdLEAST64 __PRI64_PREFIX "d" - -/** Decimal format specifier for \ref int_fast8_t. */ -#define PRIdFAST8 "d" - -/** Decimal format specifier for \ref int_fast16_t. */ -#define PRIdFAST16 __PRIPTR_PREFIX "d" - -/** Decimal format specifier for \ref int_fast32_t. */ -#define PRIdFAST32 __PRIPTR_PREFIX "d" - -/** Decimal format specifier for \ref int_fast64_t. */ -#define PRIdFAST64 __PRI64_PREFIX "d" - -/** Decimal format specifier for \ref intmax_t. */ -#define PRIdMAX __PRI64_PREFIX "d" - -/** Decimal format specifier for \ref intptr_t. */ -#define PRIdPTR __PRIPTR_PREFIX "d" - -/** @} */ - -/** @name Integer format specifiers. */ -/** @{ */ - -/** Integer format specifier for \ref int8_t. */ -#define PRIi8 "i" - -/** Integer format specifier for \ref int16_t. */ -#define PRIi16 "i" - -/** Integer format specifier for \ref int32_t. */ -#define PRIi32 "i" - -/** Integer format specifier for \ref int64_t. */ -#define PRIi64 __PRI64_PREFIX "i" - -/** Integer format specifier for \ref int_least8_t. */ -#define PRIiLEAST8 "i" - -/** Integer format specifier for \ref int_least16_t. */ -#define PRIiLEAST16 "i" - -/** Integer format specifier for \ref int_least32_t. */ -#define PRIiLEAST32 "i" - -/** Integer format specifier for \ref int_least64_t. */ -#define PRIiLEAST64 __PRI64_PREFIX "i" - -/** Integer format specifier for \ref int_fast8_t. */ -#define PRIiFAST8 "i" - -/** Integer format specifier for \ref int_fast16_t. */ -#define PRIiFAST16 __PRIPTR_PREFIX "i" - -/** Integer format specifier for \ref int_fast32_t. */ -#define PRIiFAST32 __PRIPTR_PREFIX "i" - -/** Integer format specifier for \ref int_fast64_t. */ -#define PRIiFAST64 __PRI64_PREFIX "i" - -/** Integer format specifier for \ref intmax_t. */ -#define PRIiMAX __PRI64_PREFIX "i" - -/** Integer format specifier for \ref intptr_t. */ -#define PRIiPTR __PRIPTR_PREFIX "i" - -/** @} */ - -/** @name Octal format specifiers. */ -/** @{ */ - -/** Octal format specifier for \ref int8_t. */ -#define PRIo8 "o" - -/** Octal format specifier for \ref int16_t. */ -#define PRIo16 "o" - -/** Octal format specifier for \ref int32_t. */ -#define PRIo32 "o" - -/** Octal format specifier for \ref int64_t. */ -#define PRIo64 __PRI64_PREFIX "o" - -/** Octal format specifier for \ref int_least8_t. */ -#define PRIoLEAST8 "o" - -/** Octal format specifier for \ref int_least16_t. */ -#define PRIoLEAST16 "o" - -/** Octal format specifier for \ref int_least32_t. */ -#define PRIoLEAST32 "o" - -/** Octal format specifier for \ref int_least64_t. */ -#define PRIoLEAST64 __PRI64_PREFIX "o" - -/** Octal format specifier for \ref int_fast8_t. */ -#define PRIoFAST8 "o" - -/** Octal format specifier for \ref int_fast16_t. */ -#define PRIoFAST16 __PRIPTR_PREFIX "o" - -/** Octal format specifier for \ref int_fast32_t. */ -#define PRIoFAST32 __PRIPTR_PREFIX "o" - -/** Octal format specifier for \ref int_fast64_t. */ -#define PRIoFAST64 __PRI64_PREFIX "o" - -/** Octal format specifier for \ref uintmax_t. */ -#define PRIoMAX __PRI64_PREFIX "o" - -/** Octal format specifier for \ref uintptr_t. */ -#define PRIoPTR __PRIPTR_PREFIX "o" - -/** @} */ - -/** @name Unsigned decimal format specifiers. */ -/** @{ */ - -/** Unsigned decimal format specifier for \ref uint8_t. */ -#define PRIu8 "u" - -/** Unsigned decimal format specifier for \ref uint16_t. */ -#define PRIu16 "u" - -/** Unsigned decimal format specifier for \ref uint32_t. */ -#define PRIu32 "u" - -/** Unsigned decimal format specifier for \ref uint64_t. */ -#define PRIu64 __PRI64_PREFIX "u" - -/** Unsigned decimal format specifier for \ref uint_least8_t. */ -#define PRIuLEAST8 "u" - -/** Unsigned decimal format specifier for \ref uint_least16_t. */ -#define PRIuLEAST16 "u" - -/** Unsigned decimal format specifier for \ref uint_least32_t. */ -#define PRIuLEAST32 "u" - -/** Unsigned decimal format specifier for \ref uint_least64_t. */ -#define PRIuLEAST64 __PRI64_PREFIX "u" - -/** Unsigned decimal format specifier for \ref uint_fast8_t. */ -#define PRIuFAST8 "u" - -/** Unsigned decimal format specifier for \ref uint_fast16_t. */ -#define PRIuFAST16 __PRIPTR_PREFIX "u" - -/** Unsigned decimal format specifier for \ref uint_fast32_t. */ -#define PRIuFAST32 __PRIPTR_PREFIX "u" - -/** Unsigned decimal format specifier for \ref uint_fast64_t. */ -#define PRIuFAST64 __PRI64_PREFIX "u" - -/** Unsigned decimal format specifier for \ref uintmax_t. */ -#define PRIuMAX __PRI64_PREFIX "u" - -/** Unsigned decimal format specifier for \ref uintptr_t. */ -#define PRIuPTR __PRIPTR_PREFIX "u" - -/** @} */ - -/** @name Hex format specifiers. */ -/** @{ */ - -/** Hex format specifier for \ref uint8_t. */ -#define PRIx8 "x" - -/** Hex format specifier for \ref uint16_t. */ -#define PRIx16 "x" - -/** Hex format specifier for \ref uint32_t. */ -#define PRIx32 "x" - -/** Hex format specifier for \ref uint64_t. */ -#define PRIx64 __PRI64_PREFIX "x" - -/** Hex format specifier for \ref uint_least8_t. */ -#define PRIxLEAST8 "x" - -/** Hex format specifier for \ref uint_least16_t. */ -#define PRIxLEAST16 "x" - -/** Hex format specifier for \ref uint_least32_t. */ -#define PRIxLEAST32 "x" - -/** Hex format specifier for \ref uint_least64_t. */ -#define PRIxLEAST64 __PRI64_PREFIX "x" - -/** Hex format specifier for \ref uint_fast8_t. */ -#define PRIxFAST8 "x" - -/** Hex format specifier for \ref uint_fast16_t. */ -#define PRIxFAST16 __PRIPTR_PREFIX "x" - -/** Hex format specifier for \ref uint_fast32_t. */ -#define PRIxFAST32 __PRIPTR_PREFIX "x" - -/** Hex format specifier for \ref uint_fast64_t. */ -#define PRIxFAST64 __PRI64_PREFIX "x" - -/** Hex format specifier for \ref uintmax_t. */ -#define PRIxMAX __PRI64_PREFIX "x" - -/** Hex format specifier for \ref uintptr_t. */ -#define PRIxPTR __PRIPTR_PREFIX "x" - -/** @} */ - -/** @name Binary notation */ -/** @{ */ - -/** Binary format specifier for \ref uint8_t. */ -#define PRIX8 "X" - -/** Binary format specifier for \ref uint16_t. */ -#define PRIX16 "X" - -/** Binary format specifier for \ref uint32_t. */ -#define PRIX32 "X" - -/** Binary format specifier for \ref uint64_t. */ -#define PRIX64 __PRI64_PREFIX "X" - -/** Binary format specifier for \ref uint_least8_t. */ -#define PRIXLEAST8 "X" - -/** Binary format specifier for \ref uint_least16_t. */ -#define PRIXLEAST16 "X" - -/** Binary format specifier for \ref uint_least32_t. */ -#define PRIXLEAST32 "X" - -/** Binary format specifier for \ref uint_least64_t. */ -#define PRIXLEAST64 __PRI64_PREFIX "X" - -/** Binary format specifier for \ref uint_fast8_t. */ -#define PRIXFAST8 "X" - -/** Binary format specifier for \ref uint_fast16_t. */ -#define PRIXFAST16 __PRIPTR_PREFIX "X" - -/** Binary format specifier for \ref uint_fast32_t. */ -#define PRIXFAST32 __PRIPTR_PREFIX "X" - -/** Binary format specifier for \ref uint_fast64_t. */ -#define PRIXFAST64 __PRI64_PREFIX "X" - -/** Binary format specifier for \ref uintmax_t. */ -#define PRIXMAX __PRI64_PREFIX "X" - -/** Binary format specifier for \ref uintptr_t. */ -#define PRIXPTR __PRIPTR_PREFIX "X" - -/** @} */ - -#if defined(DEBUG) -/** Serial devices supported. */ -enum serial_dev { - /** NS16550A and compatible. Currently the only supported serial device. */ - NS16550A, -}; - -/** - * dbg, apos equivalent of printf. - * - * @param fmt Format string. Integer subset of normal printf formatting. - */ -void dbg(const char *fmt, ...) __printf; - -/** - * Initialize debugging, set up serial driver etc. - * - * @param fdt Pointer to global FDT. - */ -void init_dbg(const void *fdt); - -/** - * Setup debugging in direct mapping context. - */ -void setup_dmap_dbg(); - -/** - * Setup debugging in virtual memory context. - * Both maps the debugging region and sets the UART subsystem to use - * the mapped region. - * - * @param vmem Virtual memory space to use. - */ -void setup_io_dbg(struct vmem *vmem); - -/** - * Map debugging into virtual memory context. - * - * @param vmem Virtual memory space to use. - * @return Virtual address of mapped region. - */ -vm_t map_io_dbg(struct vmem *vmem); - -/** @name Internal. */ -/** @{ */ - -/** - * Format to append to helper debugging classes. - * See \ref bug(), \ref warn(), \ref info() and \ref error(). - */ -#define COMMON_FORMAT "[%s] %s: " - -/** - * Helper for helper classes. - * See \ref bug(), \ref warn(), \ref info(), \ref error(). - */ -#define COMMON_ARGS(s) s, __FILE__ ":" QUOTE( __LINE__) - -/** @} */ - -/** - * Print a bug message to the serial lines. - * - * @param fmt Message, integer subset of regular printf. - */ -#define bug(fmt, ...) dbg(COMMON_FORMAT fmt, COMMON_ARGS("BUG"),##__VA_ARGS__) - -/** - * Print a warning message to the serial lines. - * - * @param fmt Message, integer subset of regular printf. - */ -#define warn(fmt, ...) dbg(COMMON_FORMAT fmt, COMMON_ARGS("WARN"),##__VA_ARGS__) - -/** - * Print an informational message to the serial lines. - * - * @param fmt Message, integer subset of regular printf. - */ -#define info(fmt, ...) dbg(COMMON_FORMAT fmt, COMMON_ARGS("INFO"),##__VA_ARGS__) - -/** - * Prnt an error message to the serial lines. - * - * @param fmt Message, integer subset of regular printf. - */ -#define error(fmt, ...) \ - dbg(COMMON_FORMAT fmt, COMMON_ARGS("ERROR"),##__VA_ARGS__) - -#else - -/* already documented in previous #if block, let's hope Doxygen doesn't start - * complaining :) */ -#define dbg(...) -#define dbg_init(...) -#define dbg_from_fdt(...) - -#define init_dbg(...) -#define setup_dmap_dbg(...) -#define setup_io_dbg(...) -#define map_io_dbg(...) - -#define bug(...) -#define warn(...) -#define info(...) -#define error(...) - -#endif /* DEBUG */ - -#endif /* APOS_DEBUG_H */ diff --git a/include/apos/dmem.h b/include/apos/dmem.h deleted file mode 100644 index 00f4892..0000000 --- a/include/apos/dmem.h +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_DEV_H -#define APOS_DEV_H - -/** - * @file dmem.h - * Device memory handling, i.e. anything outside of RAM. - * \todo Make global parameters functions instead. - */ - -#include -#include - -/** Provides access to the global parameter. \global */ -extern pm_t __pre_base; - -/** Provides access to the global parameter. \global */ -extern pm_t __pre_top; - -/** Provides access to the global parameter. \global */ -extern pm_t __post_base; - -/** Provides access to the global parameter. \global */ -extern pm_t __post_top; - -/** - * Initialize device memory. - * @note Currently I assume there is only one RAM region. This may not be the - * case with NUMA. - * - * @param ram_base Start of RAM. - * @param ram_top Top of RAM. - * @return stat_t \ref OK on success, nothing else at the moment. - */ -stat_t init_devmem(pm_t ram_base, pm_t ram_top); - -/** - * Allocate direct device mapping. - * @note Returned address might not be the same as the requested address. The - * caller is responsible for passing the returned address to \ref free_devmem(), not - * the requested address. - * - * @param p Process to allocate device mapping to. - * @param dev_start Start of physical address where device is mapped to. - * @param bytes Minimum size of direct memory allocation. - * @param flags Access flags of allocation. - * @return Address to start of allocation if succesful, \c 0 otherwise. - */ -vm_t alloc_devmem(struct tcb *p, pm_t dev_start, size_t bytes, vmflags_t flags); - -/** - * Free direct device mapping. - * - * @param p Process to free mapping from. - * @param dev_start Start of allocation. - * @return \ref OK when succesful, \c ERR_NF when mapping not found. - */ -stat_t free_devmem(struct tcb *p, vm_t dev_start); - -#endif /* APOS_DEV_H */ diff --git a/include/apos/elf.h b/include/apos/elf.h deleted file mode 100644 index 5c97b80..0000000 --- a/include/apos/elf.h +++ /dev/null @@ -1,626 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_ELF_H -#define APOS_ELF_H - -/** - * @file elf.h - * ELF file handling. - * - * \todo Other file formats? - */ - -#include -#include -#include - -/** @name Magic. */ -/** @{ */ - -/** Magic ELF header bytes. */ -#define EI_MAGIC 0x7f454c46 - -/** @} */ - -/** @name ELF classification. */ -/** @{ */ - -/** ELF class none, likely invalid binary. */ -#define ELFCLASSNONE 0x0 - -/** ELF class 32, 32bit binary. */ -#define ELFCLASS32 0x1 - -/** ELF class 64, 64bit binary. */ -#define ELFCLASS64 0x2 - -/** @} */ - -/** @name ELF data formats. */ -/** @{ */ - -/** ELF data none, likely invalid binary. */ -#define ELFDATANONE 0x0 - -/** ELF data little endian. */ -#define ELFDATA2LSB 0x1 - -/** ELF data big endian. */ -#define ELFDATA2MSB 0x2 - -/** @} */ - -/** - * @name ELF ABIs. - * Missing apos, of course, not sure which of these I should use instead. Some - * BSD? - */ -/** @{ */ - -/** ELF operating system ABI none. Likely standalone binary. */ -#define ELFOSABI_NONE 0x0 - -/** ELF UNIX SystemV ABI. */ -#define ELFOSABI_SYSV 0x0 - -/** ELF NetBSD ABI. */ -#define ELFOSABI_NETBSD 0x2 - -/** ELF Linux ABI. */ -#define ELFOSABI_LINUX 0x3 - -/** ELF GNU Hurd ABI. */ -#define ELFOSABI_HURD 0x4 - -/** ELF FreeBSD ABI. */ -#define ELFOSABI_FREEBSD 0x9 - -/** ELF OpenBSD ABI. */ -#define ELFOSABI_OPENBSD 0xc - -/** @} */ - -/** @name ELF binary types. */ -/** @{ */ - -/** Binary type none. Likely invalid binary. */ -#define ET_NONE 0x0 - -/** Relocatable file. */ -#define ET_REL 0x1 - -/** Executable file. */ -#define ET_EXEC 0x2 - -/** Shared object file. */ -#define ET_DYN 0x3 - -/** Core file. */ -#define ET_CORE 0x4 - -/** @} */ - -/** - * @name Machine architecture. - * Currently only RISCV supported. - */ -/** @{ */ - -/** Riscv. */ -#define EM_RISCV 0xf3 - -/** @} */ - -/** ELF identification data. */ -struct __packed elf_ident { - /** Magic. \see EI_MAGIC. */ - uint32_t ei_magic; - - /** ELF class. \see ELFCLASSNONE, ELFCLASS32, ELFCLASS64. */ - uint8_t ei_class; - - /** ELF data formats. \see ELFDATANONE, ELFDATA2LSB, ELFDATA2MSB. */ - uint8_t ei_data; - - /** ELF version. \c 1 for current, \c 0 for undefined. */ - uint8_t ei_version; - - /** ELF ABI. \see ELFOSABI_NONE, ELFOSABI_SYSV, ELFOSABI_NETBSD, - * ELFOSABI_LINUX, ELFOSABI_HURD, ELFOSABI_FREEBSD. */ - uint8_t ei_osabi; - - /** ELF ABI version. Depends on \c ei_osabi. */ - uint8_t ei_abiversion; - - /** Padding. */ - uint8_t ei_pad[7]; -}; - -/** ELF32 header for ELF binaries of class \ref ELFCLASS32. */ -struct __packed elf32_header { - /** Common identity header. */ - struct elf_ident e_ident; - - /** ELF type. \see ET_NONE, ET_REL, ET_EXEC, ET_DYN, ET_CORE. */ - uint16_t e_type; - - /** Machine architecture. \see EM_RISCV. */ - uint16_t e_machine; - - /** ELF version. \c 1 for current, \c 0 for undefined. */ - uint32_t e_version; - - /** Entrypoint virtual address. */ - uint32_t e_entry; - - /** Start of program header table within binary image. */ - uint32_t e_phoff; - - /** Start of section header table within binary image. */ - uint32_t e_shoff; - - /** Architecture dependent flags. */ - uint32_t e_flags; - - /** Size of this header. 52 bytes for ELF32. */ - uint16_t e_ehsize; - - /** Size of one program header table entry. */ - uint16_t e_phentsize; - - /** Number of program header table entries. */ - uint16_t e_phnum; - - /** Size of one section header table entry. */ - uint16_t e_shentsize; - - /** Number of section header table entries. */ - uint16_t e_shnum; - - /** Index into section header table where section names are kept. */ - uint16_t e_shstrndx; -}; - -/** ELF64 header for ELF binaries of class \ref ELFCLASS64. */ -struct __packed elf64_header { - /** Common identity header. */ - struct elf_ident e_ident; - - /** ELF type. \see ET_NONE, ET_REL, ET_EXEC, ET_DYN, ET_CORE. */ - uint16_t e_type; - - /** Machine architecture. \see EM_RISCV. */ - uint16_t e_machine; - - /** ELF version. \c 1 for current, \c 0 for undefined. */ - uint32_t e_version; - - /** Entrypoint virtual address. */ - uint64_t e_entry; - - /** Start of program header table within binary image. */ - uint64_t e_phoff; - - /** Start of section header table within binary image. */ - uint64_t e_shoff; - - /** Architecture dependent flags. */ - uint32_t e_flags; - - /** Size of this header. 64 bytes for ELF64. */ - uint16_t e_ehsize; - - /** Size of one program header table entry. */ - uint16_t e_phentsize; - - /** Number of program header table entries. */ - uint16_t e_phnum; - - /** Size of one section header table entry. */ - uint16_t e_shentsize; - - /** Number of section header table entries. */ - uint16_t e_shnum; - - /** Index into section header table where section names are kept. */ - uint16_t e_shstrndx; -}; - -/** @name Program header table entry types. */ -/** @{ */ - -/** Null header type. */ -#define PT_NULL 0x0 - -/** Load header type. */ -#define PT_LOAD 0x1 - -/** Dynamic header type. */ -#define PT_DYNAMIC 0x2 - -/** Interpreter header type. */ -#define PT_INTERP 0x3 - -/** Note header type. */ -#define PT_NOTE 0x4 - -/** Reserved, unsepcifier header type. */ -#define PT_SHLIB 0x5 - -/** Program header table header type. */ -#define PT_PHDR 0x6 - -/** Thread local storage header type. */ -#define PT_TLS 0x7 - -/** Operating system specific low fence. */ -#define PT_LOOS 0x60000000 - -/** Operating system specific high fence. */ -#define PT_HIOS 0x6fffffff - -/** Processor specific low fence. */ -#define PT_LOPROC 0x70000000 - -/** Processor specific high fence. */ -#define PT_HIPROC 0x7fffffff - -/** @} */ - -/** @name Program header entry access types. */ -/** @{ */ - -/** Executable. */ -#define PF_X (1 << 0) - -/** Writable. */ -#define PF_W (1 << 1) - -/** Readable. */ -#define PF_R (1 << 2) - -/** @} */ - -/** ELF32 program header table entry. \see ELFCLASS32. */ -struct __packed program32_header { - /** Program header entry type. \see PT_NULL, PT_LOAD, PT_DYNAMIC, - * PT_INTERP, PT_NOTE, PT_SHLIB, PT_PHDR, PT_TLS, PT_LOOS, PT_HIOS, - * PT_LOPROC, PT_HIPROC. */ - uint32_t p_type; - - /** Offset in the binary image where the associated segment lies. */ - uint32_t p_offset; - - /** Virtual address to first byte in segment. */ - uint32_t p_vaddr; - - /** Physical address to first byte in segment. Currently ignored. */ - uint32_t p_paddr; - - /** Segment size as bytes in binary image. */ - uint32_t p_filesz; - - /** Segment size as bytes in memory. */ - uint32_t p_memsz; - - /** Access flags for segment. \see PF_X, PF_W, PF_R. */ - uint32_t p_flags; - - /** Alignment of segment. */ - uint32_t p_align; -}; - -/** ELF64 program header table entry. \see ELFCLASS64. */ -struct __packed program64_header { - /** Program header entry type. \see PT_NULL, PT_LOAD, PT_DYNAMIC, - * PT_INTERP, PT_NOTE, PT_SHLIB, PT_PHDR, PT_TLS, PT_LOOS, PT_HIOS, - * PT_LOPROC, PT_HIPROC. */ - uint32_t p_type; - - /** Access flags for segment. \see PF_X, PF_W, PF_R. */ - uint32_t p_flags; - - /** Offset in the binary image where the associated segment lies. */ - uint64_t p_offset; - - /** Virtual address to first byte in segment. */ - uint64_t p_vaddr; - - /** Physical address to first byte in segment. Currently ignored. */ - uint64_t p_paddr; - - /** Segment size as bytes in binary image. */ - uint64_t p_filesz; - - /** Segment size as bytes in memory. */ - uint64_t p_memsz; - - /** Alignment of segment. */ - uint64_t p_align; -}; - -/** @name Section header types. */ -/** @{ */ - -/** Null type. */ -#define SHT_NULL 0x0 - -/** Section contains information defined by the program. */ -#define SHT_PROGBITS 0x1 - -/** Section contains symbol table. */ -#define SHT_SYMTAB 0x2 - -/** Section contains string table. */ -#define SHT_STRTAB 0x3 - -/** Section contains relocation table with explicit addends. */ -#define SHT_RELA 0x4 - -/** Section contains hashes. */ -#define SHT_HASH 0x5 - -/** Section contains dynamic linking information. */ -#define SHT_DYNAMIC 0x6 - -/** Section contains notes. */ -#define SHT_NOTE 0x7 - -/** Section occupies no space in binary image. */ -#define SHT_NOBITS 0x8 - -/** Section contains relocation table. */ -#define SHT_REL 0x9 - -/** Reserved, unspecified semantincs. */ -#define SHT_SHLIB 0x0a - -/** Sections hold symbol table. */ -#define SHT_DYNSYM 0x0b - -/** Section contains array of pointers to initialization functions. */ -#define SHT_INIT_ARRAY 0x0e - -/** Section contains array of pointers to finalization functions. */ -#define SHT_FINI_ARRAY 0x0f - -/** Section contains array of pointers to preinitialization functions. */ -#define SHT_PREINIT_ARRAY 0x10 - -/** Section group. */ -#define SHT_GROUP 0x11 - -/** Section contains extended symbol table index. */ -#define SHT_SYMTAB_SHNDX 0x12 - -/** Number of reserved SHT_* values. */ -#define SHT_NUM 0x13 - -/** @} */ - -/** @name Section header flags. */ -/** @{ */ - -/** Section should be writable during execution. */ -#define SHF_WRITE 0x1 - -/** Section occupies memory during execution. */ -#define SHF_ALLOC 0x2 - -/** Section contains executable machine instructions. */ -#define SHF_EXECINSTR 0x4 - -/** Section might be merged. */ -#define SHF_MERGE 0x10 - -/** Section contains null-terminated strings. */ -#define SHF_STRINGS 0x20 - -/** Section contains section header table index. */ -#define SHF_INFO_LINK 0x40 - -/** Preserve order after combining. */ -#define SHF_LINK_ORDER 0x80 - -/** Non-standard OS specific handling. */ -#define SHF_OS_NONCONFORMING 0x100 - -/** Section is a member of group. */ -#define SHF_GROUP 0x200 - -/** Section hold thread local data. */ -#define SHF_TLS 0x400 - -/** Operating system mask. */ -#define SHF_MASKOS 0x0ff00000 - -/** Processor mask. */ -#define SHF_MASKPROC 0xf0000000 - -/** @} */ - -/** ELF32 section header table entry. \see ELFCLASS32. */ -struct __packed section32_header { - /** Section header name. */ - uint32_t sh_name; - - /** Section header type. \see SHT_NULL, SHT_PROGBITS, SHT_SYMTAB, - * SHT_STRTAB, SHT_RELA, SHT_HASH, SHT_DYNAMIC, SHT_NOTE, SHT_NOBITS, - * SHT_REL, SHT_SHLIB, SHT_DYNSYM, SHT_INIT_ARRAY, SHT_FINI_ARRAY, - * SHT_PREINIT_ARRAY, SHT_GROUP, SHT_SYMTAB_SHNDX, SHT_NUM. */ - uint32_t sh_type; - - /** Section header flags. \see SHF_WRITE, SHF_ALLOC, SHF_EXECINSTR, - * SHF_MERGE, SHF_STRINGS, SHF_INFO_LINK, SHF_LINK_ORDER, - * SHF_OS_NONCONFORMING, SHF_GROUP, SHF_TLS, SHF_MASKOS, SHF_MASKPROC. - */ - uint32_t sh_flags; - - /** Section virtual address. */ - uint32_t sh_addr; - - /** Offset of section in binary image. */ - uint32_t sh_offset; - - /** Size as bytes in binary image. */ - uint32_t sh_size; - - /** Interpretation depends on section header type. */ - uint32_t sh_link; - - /** Interpretation depends on section header type. */ - uint32_t sh_info; - - /** Alignment of section address. */ - uint32_t sh_addralign; - - /** If section holds an array, each entry is of this size. */ - uint32_t sh_entsize; -}; - -/** ELF64 section header table entry. \see ELFCLASS64. */ -struct __packed section64_header { - /** Section header name. */ - uint32_t sh_name; - - /** Section header type. \see SHT_NULL, SHT_PROGBITS, SHT_SYMTAB, - * SHT_STRTAB, SHT_RELA, SHT_HASH, SHT_DYNAMIC, SHT_NOTE, SHT_NOBITS, - * SHT_REL, SHT_SHLIB, SHT_DYNSYM, SHT_INIT_ARRAY, SHT_FINI_ARRAY, - * SHT_PREINIT_ARRAY, SHT_GROUP, SHT_SYMTAB_SHNDX, SHT_NUM. */ - uint32_t sh_type; - - /** Section header flags. \see SHF_WRITE, SHF_ALLOC, SHF_EXECINSTR, - * SHF_MERGE, SHF_STRINGS, SHF_INFO_LINK, SHF_LINK_ORDER, - * SHF_OS_NONCONFORMING, SHF_GROUP, SHF_TLS, SHF_MASKOS, SHF_MASKPROC. - */ - uint64_t sh_flags; - - /** Section virtual address. */ - uint64_t sh_addr; - - /** Offset of section in binary image. */ - uint64_t sh_offset; - - /** Size as bytes in binary image. */ - uint64_t sh_size; - - /** Interpretation depends on section header type. */ - uint32_t sh_link; - - /** Interpretation depends on section header type. */ - uint32_t sh_info; - - /** Alignment of section address. */ - uint64_t sh_addralign; - - /** If section holds an array, each entry is of this size. */ - uint64_t s_entsize; -}; - -/** - * Get ELF identity from pointer. - * - * @param e Pointer to ELF identity. - * @return \c e as ELF identity. - * \see elf_ident. - */ -#define elf_indent(e) ((struct elf_ident *)e) - -/** - * Get ELF64 header from pointer. - * - * @param e Pointer to ELF64 header. - * @return \c e as ELF64 header. - * \see elf64_header. - */ -#define elf64_header(e) ((struct elf64_header *)e) - -/** - * Get ELF32 header from pointer. - * - * @param e Pointer to ELF32 header. - * @return \c e as ELF32 header. - * \see elf32_header. - */ -#define elf32_header(e) ((struct elf32_header *)e) - -/** Get ELF64 program header from pointer. - * - * @param p Pointer to ELF64 program header. - * @return \c p as ELF64 program header. - * \see program64_header. - */ -#define program64_header(p) ((struct program64_header *)p) - -/** - * Get ELF32 program header from pointer. - * - * @param p Pointer to ELF32 program header. - * @return \c p as ELF32 program header. - * \see program32_header. - */ -#define program32_header(p) ((struct program32_header *)p) - -/** - * Get ELF64 section header from pointer. - * - * @param s Pointer to ELF64 section header. - * @return \c s as ELF64 section header. - * \see section64_header. - */ -#define section64_header(s) ((struct section64_header *)s) - -/** - * Get ELF32 section header from pointer. - * - * @param s Pointer to ELF32 section header. - * @return \c s as ELF32 section header. - * \see section32_header. - */ -#define section32_header(s) ((struct section32_header *)s) - -/** - * Get either ELF32 or ELF64 header property, depending on the class. - * - * @param c ELF class. \see ELFCLASS32, ELFCLASS64. - * @param e ELF header. \see elf32_header, elf64_header. - * @param p Property to get. - * @return \c p - */ -#define elf_header_prop(c, e, p) \ - (c == ELFCLASS64 ? elf64_header(e)->p : elf32_header(e)->p) - -/** - * Get Either ELF32 or ELF64 program header property, depending on the class. - * - * @param c ELF class. \see ELFCLASS32, ELFCLASS64. - * @param e ELF program header. \see program32_header, program64_header. - * @param p Property to get. - * @return \c p. - */ -#define program_header_prop(c, e, p) \ - (c == ELFCLASS64 ? program64_header(e)->p : program32_header(e)->p) - -/** - * Get either ELF32 or ELF64 section header property, depending on the class. - * - * @param c ELF class. \see ELFCLASS32, ELFCLASS64. - * @param e ELF section header. \see section32_header, section64_header. - * @param p Property to get. - * @return \c p. - */ -#define section_header_prop(c, e, p) \ - (c == ELFCLASS64 ? section64_header(e)->p : section32_header(e)->p) - -/** - * Build up ELF memory image from binary image. - * - * @param p Process space in which to build the memory image. - * @param binary Virtual address of binary. - * @param interp Virtual address of optional interpreter. - * @return Virtual address of entry point. - */ -vm_t load_elf(struct tcb *p, vm_t binary, vm_t interp); - -#endif /* APOS_ELF_H */ diff --git a/include/apos/initrd.h b/include/apos/initrd.h deleted file mode 100644 index bd930d2..0000000 --- a/include/apos/initrd.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_INITRD_H -#define APOS_INITRD_H - -/** - * @file initrd.h - * Initrd handling. - */ - -#include -#include -#include - -/** - * Get \c init program size in bytes. - * - * @param fdt Global FDT pointer. - * @return Size of \c init in bytes. - */ -size_t get_init_size(const void *fdt); - -/** - * Get \c init program base address. - * - * @param fdt Global FDT pointer. - * @return Start of \c init. - */ -vm_t get_init_base(const void *fdt); - -/** - * Get \c initrd top address. - * - * @param fdt Global FDT pointer. - * @return Top address of \c initrd. - */ -pm_t get_initrdtop(const void *fdt); - -/** - * Get \c initrd base address. - * - * @param fdt Global FDT pointer. - * @return Base address of \c initrd. - */ -pm_t get_initrdbase(const void *fdt); - -/** - * Move \c init program to some other region in memory. - * - * @param fdt Global FDT pointer. - * @param target Where to move to. - * @return OK on success. - */ -stat_t move_init(const void *fdt, void *target); - -#endif /* APOS_INITRD_H */ diff --git a/include/apos/ipi.h b/include/apos/ipi.h deleted file mode 100644 index c895d58..0000000 --- a/include/apos/ipi.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef APOS_IPI_H -#define APOS_IPI_H - -/** - * @file ipi.h - * - * IPI function definitions. - */ - -#include -#include -#include - -/** - * Clear potential IPI in \p t, and return its value. - * - * @param t \ref tcb to clear possible IPI status of. - * @return \ref true if \p was interrupted by IPI, \ref false otherwise. - */ -bool clear_ipi(struct tcb *t); - -/** - * Send IPI to \p t. Assumes \c running(t). - * - * @param t \ref tcb to send IPI to. - */ -void send_ipi(struct tcb *t); - -/** - * Handle IPI. - * - * @param t Thread who was interrupted by IPI. - * @return Possible arguments to IPI. - */ -struct sys_ret handle_ipi(struct tcb *t); - -#endif /* APOS_IPI_H */ diff --git a/include/apos/lock.h b/include/apos/lock.h deleted file mode 100644 index a841d4b..0000000 --- a/include/apos/lock.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_LOCK_H -#define APOS_LOCK_H - -/** - * @file lock.h - * Atomic locks, currently only \ref spin_lock() and \ref spin_unlock(). Mutex is - * probably overkill for this project. - */ - -#include -#include - -/** - * Typedef for atomic_int. - * - * In apos, spinlocks are implemented with compiler-intrinsic atomic integers, - * that essentially just contain some flags. Currently all spinlocks - * enable/disable irqs. - * - * \todo irq contexts? - */ -typedef atomic_int spinlock_t; - -#include - -/** - * Lock a spinlock. - * - * @param lck Pointer to lock. - */ -static inline void spin_lock(spinlock_t *lck) -{ - disable_irq(); - do { - while (atomic_load_explicit(lck, memory_order_acquire)) - optional_pause(); - - } while (atomic_exchange_explicit(lck, 1, memory_order_acq_rel)); -} - -/** - * Unlock a spinlock. - * - * @param lck Pointer to lock. - */ -static inline void spin_unlock(spinlock_t *lck) -{ - atomic_store_explicit(lck, 0, memory_order_release); - enable_irq(); -} - -#endif /* APOS_LOCK_H */ diff --git a/include/apos/mem.h b/include/apos/mem.h deleted file mode 100644 index ea61aba..0000000 --- a/include/apos/mem.h +++ /dev/null @@ -1,223 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_MEM_H -#define APOS_MEM_H - -/** - * @file mem.h - * Generic memory, common to both physical and virtual memory. - */ - -#include -#include - -/** - * Convert physical memory address \c paddr to index of page order \c order. - * - * @param p Physical memory address. - * @param order Order page index to convert to. - * @return Index of page order \c order. - */ -#define pm_to_index(p, order) \ - ((p >> order_shift(order)) & (order_width(order) - 1)) - -/** - * Get highest possible index in an order. - * - * @param order Order to query. - * @return Highest possible index in the order \c order. - */ -#define max_index(order) (order_width(order) - 1) - -/** - * Get starting offset of order bits in address. - * - * @param order Order to query. - * @return Starting offset of order bits. - */ -#define order_shift(order) (__mm_shifts[order]) - -/** - * Get number of order bits in an address. - * - * @param order Order to query. - * @return Width in bits of order bits. - */ -#define order_width(order) (__mm_widths[order]) - -/** - * Get size of order, as in how many pages of one order lower it can contain. - * - * @param order Order to query. - * @return Number of pages of one order lower this order can contain. - */ -#define order_size(order) (__mm_sizes[order]) - -/** - * Get highest order supported by the current configuration. - * - * @return Max supported order. - */ -#define max_order() (__mm_max_order) - -/** - * Get base page shift. - * - * @return Page shift. - */ -#define page_shift() (__mm_page_shift) - -/** - * Get number of elements needed to represent this order. - * - * @param order Order to query. - * @return Number of elements needed to represent this order. - */ -#define order_elems(order) (__mm_widths[order] / MM_OINFO_WIDTH) - -/** - * Entry index to element index that contains the entry. - * - * @param idx Index of entry. - * @return Index of element. - */ -#define order_container(idx) ((idx) / MM_OINFO_WIDTH) - -/** \todo Get rid of slightly ugly __* syntax, as these aren't static. */ - -/** - * Convert physical address to virtual address in direct mapping. - * - * @param x Physical address. - * @return Corresponding virtual address. - */ -#define __va(x) (void *)(((uintptr_t)(x)) + VM_DMAP - RAM_BASE) - -/** - * Convert virtual address to physical address in direct mapping. - * - * @param x Virtual address. - * @return Corresponding physical address. - */ -#define __pa(x) (void *)(((uintptr_t)(x)) - VM_DMAP + RAM_BASE) - -/** - * Get page number of physical address. - * - * @param x Physical address. - * @return Corresponding page number. - */ -#define __page(x) ((x) / BASE_PAGE_SIZE) - -/** - * Get physical address of page number. - * - * @param x Page number. - * @return Corresponding physical address. - */ -#define __addr(x) ((x) * BASE_PAGE_SIZE) - -/** - * Convert bytes to number of base pages. - * - * @param x Number of bytes. - * @return Corresponding number of page pages. - */ -#define __pages(x) \ - (is_aligned((x), BASE_PAGE_SIZE) ? __page((x)) : \ - __page((x) + BASE_PAGE_SIZE)) - -/** @name Memory region flags. */ -/** @{ */ - -/** Memory region is used. */ -#define MR_USED (1 << 8) -/** Don't free memory on clear. */ -#define MR_KEEP (1 << 9) - -/** @} */ - -/** Maximum number of page orders allowed. Likely massively overkill. */ -#define NUM_ORDERS 10 - -/** Give names to page orders. */ -enum mm_order { - /** NULL marker. */ - MM_MIN = -1, - - /** Base order. */ - MM_O0 = 0, - - /** Order 1. */ - MM_O1 = 1, - - /** Order 2. */ - MM_O2 = 2, - - /** Order 3. */ - MM_O3 = 3, - - /** Order 4. */ - MM_O4 = 4, - - /** Order 5. */ - MM_O5 = 5, - - /** Order 6. */ - MM_O6 = 6, - - /** Order 7. */ - MM_O7 = 7, - - /** Order 8. */ - MM_O8 = 8, - - /** Order 9. */ - MM_O9 = 9, - - /** Number of orders */ - MM_NUM, -}; - -/** Gives access to global page order shift information. \global */ -extern size_t __mm_shifts[NUM_ORDERS]; - -/** Gives access to global page order width information. \global */ -extern size_t __mm_widths[NUM_ORDERS]; - -/** Gives access to global page order size information. \global */ -extern size_t __mm_sizes[NUM_ORDERS]; - -/** Gives access to global base page shift. \global */ -extern size_t __mm_page_shift; - -/** Gives access to global maximum order size. \global */ -extern enum mm_order __mm_max_order; - -/** - * Find nearest order to size. - * - * @param size Size to map to an order. - * @return Nearest order larger than \p size. - */ -enum mm_order nearest_order(size_t size); - -/** - * Initialize memory subsystem data. Populates __mm_* with data given. - * - * @param max_order Maximum order the current system supports. - * @param shifts Offsets to start of each memory order in address. - * @param page_shift Width in bits of base page size. - * \todo Should likely also be stat_t? - */ -void init_mem(size_t max_order, size_t shifts[10], size_t page_shift); - - -/** Base page size. */ -#define BASE_PAGE_SIZE (order_size(BASE_PAGE)) - -/** Base page order. */ -#define BASE_PAGE (MM_O0) - -#endif /* APOS_MEM_H */ diff --git a/include/apos/mem_nodes.h b/include/apos/mem_nodes.h deleted file mode 100644 index 164d04a..0000000 --- a/include/apos/mem_nodes.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_MM_NODES_H -#define APOS_MM_NODES_H - -/** - * @file mem_nodes.h - * Memory node subsystem. Used by the memory region subsystem. - */ - -#include -#include - -/** - * Initialize memory node subsystem. - * - * @pre Physical memory subsystem has been initialized. - */ -void init_mem_nodes(); - -/** - * Destroy memory node subsystem. - * Free all associated allocations. - */ -void destroy_mem_nodes(); - -/** - * Fetch a new memory node. - * - * @return Pointer to \ref mem_region node on success, \c NULL otherwise. - */ -struct mem_region *get_mem_node(); - -/** - * Free a memory node. - * - * @param m Pointer to \ref mem_region node to free. - */ -void free_mem_node(struct mem_region *m); - -#endif /* APOS_MM_NODES_H */ diff --git a/include/apos/mem_regions.h b/include/apos/mem_regions.h deleted file mode 100644 index 6fdb5b4..0000000 --- a/include/apos/mem_regions.h +++ /dev/null @@ -1,303 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_MEM_REGIONS_H -#define APOS_MEM_REGIONS_H - -/** - * @file mem_regions.h - * Memory region subsytem. Mainly used by the virtual memory subsytems, i.e. device and - * user memory. - */ - -#include -#include -#include -#include - -/** - * Get \ref mem_region container of \c ptr. - * - * @param ptr Pointer to \c sp_n member in \ref mem_region. - * @return Parent \ref mem_region. - */ -#define mem_container(ptr) container_of(ptr, struct mem_region, sp_n) - -/** - * Check if memory region is used. - * - * @param r Memory region to check. - * @return \c 0 if not used, non-zero otherwise. - */ -#define is_region_used(r) is_set(r->flags, MR_USED) - -/** - * Check if region should be kept during clear. - * - * @param r Memory region to check. - * @return \c 0 if not kept, non-zero otherwise. - */ -#define is_region_kept(r) is_set(r->flags, MR_KEEP) - -/** Root of memory region. */ -struct mem_region_root { - /** Sp-tree of free regions. */ - struct sp_root free_regions; - - /** Sp-tree of used region. */ - struct sp_root used_regions; -}; - -/** - * Memory region. - * Regions can have two states, used or free. There are two sp-trees, which keep - * track of free and used regions, respectively. All regions are chained - * together with a doubly linked list, so that the next region's start address - * should be the current region's end address. - */ -struct mem_region { - /** Sp-tree node slot. */ - struct sp_node sp_n; - - /** Next memory region by start address. */ - struct mem_region *next; - - /** Previous memory region by end address. */ - struct mem_region *prev; - - /** Memory region flags, both access as well as metadata. \see MR_USED, - * MR_SHARED, MR_OWNED, MR_COW, MR_KEEP. */ - vmflags_t flags; - - /** End address of memory region. */ - vm_t end; - - /** Start address of memory region. */ - vm_t start; - - /** In shared regions, mark the other pid that shared the region. */ - id_t pid; - - /** In shared regions, this is the address associated with region in the - * other process. */ - vm_t alt_va; -}; - -/** - * Initialize memory region subsystem instance. - * - * @param r Memory region root to initialize. - * @param start Start of memory arena. - * @param arena_size Size of memory arena. - * @return \ref OK on success. - * \todo Document error codes when I actually implement them properly. - */ -stat_t init_region(struct mem_region_root *r, vm_t start, size_t arena_size); - -/** - * Destroy memory region subsystem instance. - * - * @param r Memory region root to destroy. - * @return \ref OK on success. - */ -stat_t destroy_region(struct mem_region_root *r); - -/** - * Allocate memory region. - * Will allocate region of at least \c size bytes, with best possible location. - * - * @param r Memory region root. - * @param size Size of region to allocate. - * @param actual_size Size of region that was allocated. - * @param flags Memory flags. - * @return Address of allocated region on success, otherwise \c NULL. - */ -vm_t alloc_region(struct mem_region_root *r, size_t size, size_t *actual_size, - vmflags_t flags); - -/** - * Allocate memory region and associate it with some other process. - * Will allocate region of at least \c size bytes, with best possible location. - * - * @param r Memory region root. - * @param size Size of region to allocate. - * @param actual_size Size of region that was allocated. - * @param flags Memory flags. - * @param pid Process to associate with region. - * @return Address of allocated region on success, otherwise \c NULL. - */ -vm_t alloc_shared_region(struct mem_region_root *r, size_t size, - size_t *actual_size, - vmflags_t flags, id_t pid); - -/** - * Allocate fixed memory region. - * Will allocate region that is at least \c size bytes, and includes \c start. - * \note The address returned might not be the address requested, and the caller - * must keep track of which address it was given, so it can cleanly give it to - * \ref free_region() when finished with the allocation. - * - * @param r Memory region root. - * @param start Address that must be within region to allocate. - * @param size Size of region to allocate. - * @param actual_size Size of region that was allocated. - * @param flags Memory flags. - * @return Address of allocated region on success, otherwise \c NULL. - */ -vm_t alloc_fixed_region(struct mem_region_root *r, vm_t start, size_t size, - size_t *actual_size, vmflags_t flags); - -/** - * Free memory region. - * - * @param r Memory region root. - * @param start Address of region to free. - * @return \ref OK on success, \ref ERR_ALIGN if \c start is misaligned and \ref - * ERR_NF if the memory region is not found. - */ -stat_t free_region(struct mem_region_root *r, vm_t start); - -/** - * Free memory region through a direct pointer to the memory region. - * Mainly useful if you look up a region beforehand, do something with it and - * then free it. Skips looking up the start address. - * - * @param r Memory region root. - * @param m Memory region to free. - * @return \ref OK. - * \todo Improve error checking. - */ -stat_t free_known_region(struct mem_region_root *r, struct mem_region *m); - -/** - * Find the memory region with lowest starting address. - * This region will also be the first node in the linked list. - * Useful when you need to iterate over all regions. - * - * @param r Memory region root. - * @return First memory region when succesful, otherwise \c NULL. - */ -struct mem_region *find_first_region(struct mem_region_root *r); - -/** - * Find used memory region at address \c start. - * - * @param r Memory region root. - * @param start Address at which a used region should exist. - * @return Pointer to requested memory region when succesful, \c NULL otherwise. - */ -struct mem_region *find_used_region(struct mem_region_root *r, vm_t start); - -/** - * Find used memory region closest to \c start. - * Useful when you don't necessarily need the exact region, just something close - * by. - * - * @param r Memory region root. - * @param start Address region should be closest to. - * @return Pointer to memory region closest to \c start when succesful, \c NULL - * otherwise. - */ -struct mem_region *find_closest_used_region(struct mem_region_root *r, - vm_t start); - -/** - * Find best region that fulfills requested parameters. - * - * @param r Memory region root. - * @param size Size of free region. - * @param align Recommended offset into this region from where the allocation - * should be carved. - * @return Pointer to suitable \c memory_region when succesful, \c NULL - * otherwise. - */ -struct mem_region *find_free_region(struct mem_region_root *r, size_t size, - size_t *align); - -/** - * Helper functions for converting between memory regions and page - * mappings. Called by \ref map_fill_region(). - * \see map_fill_region() for further explanation. - * - * @param vmem Virtual memory space in which the operation is to be done. - * @param offset Offset from where to start looking for next physical page. \see - * alloc_page(). - * @param vaddr Current virtual address. - * @param flags Virtual memory allocation flags. - * @param order Order of physical page. - * @param data Custom data. - * @return \ref OK if succesful, \c INFO_TRGN if page order should be decreased, - * anything else means error. - */ -typedef stat_t region_callback_t(struct vmem *vmem, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order order, - void *data); - -/** - * Query flags of region that contains \c va. - * - * @param r Memory region root. - * @param va Address that is within memory region. - * @param flags Memory region flags. - * @return \ref OK when succesful. - * \todo Implement. - */ -stat_t stat_region(struct mem_region_root *r, vm_t va, vmflags_t *flags); - -/** - * Modify flags of region that contains \c va. - * - * @param r Memory region root. - * @param va Address that is within memory region. - * @param flags New flags of region. - * @return \ref OK when succesful. - * \todo Implement. - */ -stat_t mod_region(struct mem_region_root *r, vm_t va, vmflags_t flags); - -/** - * Set alternate virtual address associated with shared memory region in other process. - * - * @param r Memory region root. - * @param va Virtual address in \p r. - * @param alt_va Virtual address in other process. - */ -void set_alt_region_addr(struct mem_region_root *r, vm_t va, vm_t alt_va); - -/** - * Conversion function between abstract memory region and actual page mappings. - * Assumes that pages of some order are mappable at multiples of their size, and - * tries to fit as many and as high order pages as it can into the region. - * Heavily utilizes \c mem_handler, to which it gives a suggestion for how to - * map a page. If this suggestion is accepted and succesfully executed, \c mem_handler - * returns \ref OK. If the suggestion is not possible, for example no higher - * order pages are available, \c mem_handler returns \ref INFO_TRGN to tell \c - * map_fill_region() to give it some other suggestion. Any error value stops the - * conversion. - * - * This 'algorithm' also works quite nicely for freeing a region, but in - * reverse, i.e. it is given a suggestion and checks if that suggestion was - * executed when the region was mapped. If the suggestion was executed, then the - * same suggestion is freed, else \ref INFO_TRGN is returned and a new - * suggestion is requested until all pages have been freed. - * - * There are some more technicalities, for example currently \c - * map_fill_region() gives up trying to map higher order pages as soon as its - * first suggestion is rejected, which gives us quick conversion times but - * probably less than ideal mappings. - * - * @param vmem Virtual memory inside which to map the region. - * @param mem_handler Worker handler callback. - * @param offset Offset at which the physical memory availability map should - * start searching. - * @param start Start address of memory region. - * @param bytes Size of memory region. - * @param flags Memory flags. - * @param data User-specified data. - * @return \c start when succesful, \c 0 otherwise. - */ -vm_t map_fill_region(struct vmem *vmem, region_callback_t *mem_handler, - pm_t offset, vm_t start, size_t bytes, vmflags_t flags, - void *data); - -#endif /* APOS_MEM_REGIONS_H */ diff --git a/include/apos/nodes.h b/include/apos/nodes.h deleted file mode 100644 index f1d4501..0000000 --- a/include/apos/nodes.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_NODES_H -#define APOS_NODES_H - -/** - * @file nodes.h - * Node subsystem. Used by a number of subsystems for allocating specific sizes - * of memory nodes smaller than memory pages. - */ - -#include - -/** Node slot status. */ -enum node_status { - /** Free. */ - FREE = 0, - - /** Used. */ - USED = 1 -}; - -/** Header for a region in memory with node slots. */ -struct node_region { - /** Number of used slots in this region. - * \note Total number of slots is calculated on an instance basis. */ - size_t used_nodes; - - /** Next node region in free list. */ - struct node_region *av_next; - - /** Previous node region in free list. */ - struct node_region *av_prev; - - /** Next node slot region. */ - struct node_region *next; - - /** Previous slot node region. */ - struct node_region *prev; -}; - -/** Node subsystem instance. */ -struct node_root { - /** Size of each node. */ - size_t node_size; - /** Maximum number of node slots in one region. */ - size_t max_nodes; - - /** Offset of node slot state bitmap from start of region. */ - ptrdiff_t bitmap; - - /** Offset of first node from start of region. */ - ptrdiff_t first_node; - - /** List of all node regions. */ - struct node_region *head; - - /** List of node regions with free slots. */ - struct node_region *av_head; -}; - -/** - * Initialize node subsystem instance. - * - * @param r Node region root. - * @param node_size Size of one node. - */ -void init_nodes(struct node_root *r, size_t node_size); - -/** - * Destroy node subsystem instance. - * - * @param r Node region root. - */ -void destroy_nodes(struct node_root *r); - -/** - * Allocate a new node. - * - * @param r Node region root. - * @return Pointer to allocated node when succesful, \c 0 otherwise. - */ -void *get_node(struct node_root *r); - -/** - * Free a node. - * - * @param r Node region root. - * @param p Pointer to node to free. - */ -void free_node(struct node_root *r, void *p); - -#endif /* APOS_NODES_H */ diff --git a/include/apos/pmem.h b/include/apos/pmem.h deleted file mode 100644 index 6278b57..0000000 --- a/include/apos/pmem.h +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_PMEM_H -#define APOS_PMEM_H - -/** - * @file pmem.h - * Physical memory subsystem. Used to allocate and free physical memory pages. - */ - -#include -#include -#include - -/** - * Free physical page. - * - * @param order Order of page to free. - * @param addr Physical address of page. - */ -void free_page(enum mm_order order, pm_t addr); - -/** - * Mark page used. - * - * @param order Order of page to mark. - * @param addr Physical address of page. - */ -void mark_used(enum mm_order order, pm_t addr); - -/** - * Allocate physical page. - * Allows the user to specify a hint as to which address to start looking for. - * Useful for allocating many pages for one virtual allocation, for example, and - * allows us to skip already checked pages when allocating a second page. - * - * @param order Order of page to allocate. - * @return pm_t Physical address of page when succesful, else \c NULL. - */ -pm_t alloc_page(enum mm_order order); - -/** - * Populate physical RAM usage map. - * In theory we could easily implement NUMA nodes by just using different orders - * of usage maps, but for now we assume all RAM is contiguous. - * - * @param ram_base Base physical address of RAM. - * @param ram_size Size of phsyical RAM. - * @param cont Physical address where to place the map. - * @return Size of physical map. Check that is matches with \ref probe_pmap(). - */ -pm_t populate_pmap(pm_t ram_base, size_t ram_size, pm_t cont); - -/** - * Probe size of RAM usage map. - * - * @param ram_size Size of physical RAM. - * @return Size of physical map. Check that it matches with \ref - * populate_pmap(). - */ -pm_t probe_pmap(size_t ram_size); - -/** - * Initialize physical memory subsystem. - * - * @param fdt Global FDT pointer. - */ -void init_pmem(void *fdt); - -#endif /* APOS_PMEM_H */ diff --git a/include/apos/power.h b/include/apos/power.h deleted file mode 100644 index b239d5b..0000000 --- a/include/apos/power.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_POWER_H -#define APOS_POWER_H - -/** - * @file power.h - * Power subsystem. Will hopefully eventually be used to restart and shutdown - * host machines. - */ - -#include -#include - -/** Types of powering off. Still unclear what difference there is between warm - * and cold reboot. */ -enum poweroff_type { - /** Shut down. */ - SHUTDOWN, - - /** Cold or complete reboot. */ - COLD_REBOOT, - - /** Warm or partial reboot. */ - WARM_REBOOT -}; - -/** - * Power off the system. - * - * @param type Type of powering off. \see poweroff_type. - * @return Nothing on success (system shuts down), \ref ERR_INVAL on invalid - * poweroff type or ERR_MISC if studown was not succesful. - */ -stat_t poweroff(enum poweroff_type type); - -#endif diff --git a/include/apos/proc.h b/include/apos/proc.h deleted file mode 100644 index cca7969..0000000 --- a/include/apos/proc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_PROC_H -#define APOS_PROC_H - -/** - * @file proc.h - * Process handling subsystem, should likely be merged into \ref - * include/apos/tcb.h. - */ - -#include -#include - -/** - * Set up binary. Currently only supports ELF, not sure if other formats should - * be supported. - * - * @param t Thread space to set up process in. - * @param bin Address of binary to load. - * @param interp Optional interpreter, mainly for PIE ELF binaries. - * @return \ref OK on success, \ref ERR_INVAL if loading binary failed. - * \todo Handle out of memory better? - */ -stat_t prepare_proc(struct tcb *t, vm_t bin, vm_t interp); - -/** - * Initialize process handling subsystem and setup \c init program. - * - * @param fdt Global FDT pointer. - * @return \ref ERR_OOMEM when out of memory, \ref ERR_INVAL if loading \c init - * failed, \ref OK otherwise. - */ -stat_t init_proc(void *fdt); - -#endif /* APOS_PROC_H */ diff --git a/include/apos/sizes.h b/include/apos/sizes.h deleted file mode 100644 index 40c3590..0000000 --- a/include/apos/sizes.h +++ /dev/null @@ -1,220 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_SIZES_H -#define APOS_SIZES_H - -/** - * @file sizes.h - * Shorthands for some power-of-two sizes. - */ - -#if !defined(__ASSEMBLER__) - -/* value format used by the compiler. */ - -/** 1 byte. */ -#define SZ_1 0x000000000001UL - -/** 2 bytes. */ -#define SZ_2 0x000000000002UL - -/** 4 bytes. */ -#define SZ_4 0x000000000004UL - -/** 8 bytes. */ -#define SZ_8 0x000000000008UL - -/** 16 bytes. */ -#define SZ_16 0x000000000010UL - -/** 32 bytes. */ -#define SZ_32 0x000000000020UL - -/** 64 bytes. */ -#define SZ_64 0x000000000040UL - -/** 128 bytes. */ -#define SZ_128 0x000000000080UL - -/** 256 bytes. */ -#define SZ_256 0x000000000100UL - -/** 512 bytes. */ -#define SZ_512 0x000000000200UL - -/** 1KiB. */ -#define SZ_1K 0x000000000400UL - -/** 2KiB. */ -#define SZ_2K 0x000000000800UL - -/** 4KiB. */ -#define SZ_4K 0x000000001000UL - -/** 8KiB. */ -#define SZ_8K 0x000000002000UL - -/** 16KiB. */ -#define SZ_16K 0x000000004000UL - -/** 32KiB. */ -#define SZ_32K 0x000000008000UL - -/** 64KiB. */ -#define SZ_64K 0x000000010000UL - -/** 128KiB. */ -#define SZ_128K 0x000000020000UL - -/** 256KiB. */ -#define SZ_256K 0x000000040000UL - -/** 512KiB. */ -#define SZ_512K 0x000000080000UL - -/** 1MiB. */ -#define SZ_1M 0x000000100000UL - -/** 2MiB. */ -#define SZ_2M 0x000000200000UL - -/** 4MiB. */ -#define SZ_4M 0x000000400000UL - -/** 8MiB. */ -#define SZ_8M 0x000000800000UL - -/** 16MiB. */ -#define SZ_16M 0x000001000000UL - -/** 32MiB. */ -#define SZ_32M 0x000002000000UL - -/** 64MiB. */ -#define SZ_64M 0x000004000000UL - -/** 128MiB. */ -#define SZ_128M 0x000008000000UL - -/** 256MiB. */ -#define SZ_256M 0x000010000000UL - -/** 512MiB. */ -#define SZ_512M 0x000020000000UL - -/** 1GiB. */ -#define SZ_1G 0x000040000000UL - -/** 2GiB. */ -#define SZ_2G 0x000080000000UL - -/** 4GiB. */ -#define SZ_4G 0x000100000000UL - -/** 8GiB. */ -#define SZ_8G 0x000200000000UL - -/** 16GiB. */ -#define SZ_16G 0x000400000000UL - -/** 32GiB. */ -#define SZ_32G 0x000800000000UL - -/** 64GiB. */ -#define SZ_64G 0x001000000000UL - -/** 128GiB. */ -#define SZ_128G 0x002000000000UL - -/** 256GiB. */ -#define SZ_256G 0x004000000000UL - -/** 512GiB. */ -#define SZ_512G 0x008000000000UL - -/** 1TiB. */ -#define SZ_1T 0x010000000000UL - -/** 2TiB. */ -#define SZ_2T 0x020000000000UL - -/** 4TiB. */ -#define SZ_4T 0x040000000000UL - -/** 8TiB. */ -#define SZ_8T 0x080000000000UL - -/** 16TiB. */ -#define SZ_16T 0x100000000000UL - -/** 32TiB. */ -#define SZ_32T 0x200000000000UL - -/** 64TiB. */ -#define SZ_64T 0x400000000000UL - -/** 128TiB. */ -#define SZ_128T 0x8000000000000UL - -#else - -/* value format used by the assembler. */ -#define SZ_1 0x000000000001 -#define SZ_2 0x000000000002 -#define SZ_4 0x000000000004 -#define SZ_8 0x000000000008 -#define SZ_16 0x000000000010 -#define SZ_32 0x000000000020 -#define SZ_64 0x000000000040 -#define SZ_128 0x000000000080 -#define SZ_256 0x000000000100 -#define SZ_512 0x000000000200 - -#define SZ_1K 0x000000000400 -#define SZ_2K 0x000000000800 -#define SZ_4K 0x000000001000 -#define SZ_8K 0x000000002000 -#define SZ_16K 0x000000004000 -#define SZ_32K 0x000000008000 -#define SZ_64K 0x000000010000 -#define SZ_128K 0x000000020000 -#define SZ_256K 0x000000040000 -#define SZ_512K 0x000000080000 - -#define SZ_1M 0x000000100000 -#define SZ_2M 0x000000200000 -#define SZ_4M 0x000000400000 -#define SZ_8M 0x000000800000 -#define SZ_16M 0x000001000000 -#define SZ_32M 0x000002000000 -#define SZ_64M 0x000004000000 -#define SZ_128M 0x000008000000 -#define SZ_256M 0x000010000000 -#define SZ_512M 0x000020000000 - -#define SZ_1G 0x000040000000 -#define SZ_2G 0x000080000000 -#define SZ_4G 0x000100000000 -#define SZ_8G 0x000200000000 -#define SZ_16G 0x000400000000 -#define SZ_32G 0x000800000000 -#define SZ_64G 0x000400000000 -#define SZ_128G 0x000800000000 -#define SZ_256G 0x001000000000 -#define SZ_512G 0x002000000000 - -#define SZ_1T 0x004000000000 -#define SZ_2T 0x008000000000 -#define SZ_4T 0x010000000000 -#define SZ_8T 0x020000000000 -#define SZ_16T 0x040000000000 -#define SZ_32T 0x080000000000 -#define SZ_64T 0x100000000000 -#define SZ_128T 0x200000000000 -#define SZ_256T 0x400000000000 -#define SZ_512T 0x800000000000 - -#endif - -#endif /* APOS_SIZES_H */ diff --git a/include/apos/sp_tree.h b/include/apos/sp_tree.h deleted file mode 100644 index 7701f52..0000000 --- a/include/apos/sp_tree.h +++ /dev/null @@ -1,156 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef SP_TREE_H -#define SP_TREE_H - -/** - * @file sp_tree.h - * sp_trees, a type of binary search trees. - */ - -#include - -/** - * Get root of tree from \ref sp_root. - * - * @param r Instance of \ref sp_root. - * @return Actual root of tree. - */ -#define sp_root(r) ((r)->sp_r) - -/** - * Get left node. - * - * @param n Node to read. - * @return Left node of read node. - * \see sp_right(). - */ -#define sp_left(n) ((n)->left) - -/** - * Get right node. - * - * @param n Node to read. - * @return Right node of read node. - * \see sp_left(). - */ -#define sp_right(n) ((n)->right) - -/** - * Get parent of right node. - * In most situations should point back towards the node it started from, but - * when in the middle of updating the tree it might temporarily point somewhere else. - * - * @param n Node to read. - * @return Parent of right node of read node. - * \see sp_lparen(). - */ -#define sp_rparen(n) (sp_right(n)->parent) - -/** - * Get parent of left node. - * - * @param n Node to read. - * @return Parent of left node of read node. - * \see sp_rparen(). - */ -#define sp_lparen(n) (sp_left(n)->parent) - -/** - * Get parent of node. - * - * @param n Node to read. - * @return Parent of read node. - */ -#define sp_paren(n) ((n)->parent) - -/** - * Get grandparent (parent of parent) of node. - * - * @param n Node to read. - * @return Grandparent of read node. - * \see sp_has_gparen(). - */ -#define sp_gparen(n) ((n)->parent->parent) - -/** Check if node has grandparent. - * - * @param n Node to read. - * @return Non-zero if node has grandparent, \c 0 otherwise. - * \see sp_gparen(). - */ -#define sp_has_gparen(n) (sp_paren(n) && sp_gparen(n)) - -/** Tree node. - * Embed this structure in structures you want to build a tree of. - * \see common/mem_region.c, for example. - */ -struct sp_node { - /** Hint. Approximate maximum tree height up to the current node. */ - int_fast16_t hint; - - /** Lefthand node. */ - struct sp_node *left; - - /** Righthand node. */ - struct sp_node *right; - - /** Parent node. Technically speaking not necessary, but in this case I - * went with time over space. */ - struct sp_node *parent; -}; - -/** Convenience structure for trees. */ -struct sp_root { - /** Pointer to actual root of tree. */ - struct sp_node *sp_r; -}; - -/** Which side of the parent node a new node should be inserted to. */ -enum sp_dir { - /** Left side. */ - LEFT, - - /** Right side. */ - RIGHT -}; - -/** - * Get first, leftmost node under specified node. - * - * @param n Node to start with. - * @return Leftmost node under \c n, or \c n if there are none. - */ -struct sp_node *sp_first(struct sp_node *n); - -/** - * Get last, rightmost node under specified node. - * - * @param n Node to start with. - * @return Rightmost node under \c n, or \c n if there are none. - */ -struct sp_node *sp_last(struct sp_node *n); - -/** - * Insert new node into tree. - * Does not allocate any memory. - * - * @param root Root of tree. - * @param p Parent of new node. - * @param n New node. - * @param d Which side of the parent node the new node should be on. - */ -void sp_insert(struct sp_node **root, struct sp_node *p, struct sp_node *n, - enum sp_dir d); - -/** - * Remove node from tree. - * Does not free any memory. - * - * @param root Root of tree. - * @param n Node to remove. - */ -void sp_remove(struct sp_node **root, struct sp_node *n); - -#endif /* SP_TREE_H */ diff --git a/include/apos/string.h b/include/apos/string.h deleted file mode 100644 index 5e97444..0000000 --- a/include/apos/string.h +++ /dev/null @@ -1,310 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_STRING_H -#define APOS_STRING_H - -/** - * @file string.h - * String handling, similar to cstdlib's string.h. - */ - -#include -#include - -/* follow C library functions, drop location and error functions */ - -/** - * Copy \c NULL -terminated string. - * \c dst may not overlap \c src. - * - * @param dst Destination of copy. - * @param src Source of copy. - * @return \c dst. - */ -char *strcpy(char * restrict dst, const char * restrict src); - -/** - * Copy \c NULL -terminated string, or first \c num characters. - * \c dst may not overlap \c src. - * - * @param dst Destination of copy. - * @param src Source of copy. - * @param num Maximum number of bytes to copy. - * @return \c dst. - */ -char *strncpy(char * restrict dst, const char * restrict src, size_t num); - -/** - * Concatenate \c NULL -terminated strings, placing \c src after \c dst. - * \c dst may not overlap \c src. - * - * @param dst Destination of concatenation. - * @param src String to append to \c dst. - * @return \c dst. - */ -char *strcat(char * restrict dst, const char * restrict src); - -/** - * Concatenate \c NULL -terminated strings, max \c num characters, placing \c - * src after \c dst. - * \c dst may not overlap \c src. - * - * @param dst Destination of concatenation. - * @param src String to append to \c dst. - * @param num Max number of characters to concatenate. - * @return \c dst. - */ -char *strncat(char * restrict dst, const char * restrict src, size_t num); - -/** - * Compare two \c NULL -terminated strings. - * - * @param str1 First string to compare. - * @param str2 Second string to compare. - * @return \c 0 if strings are equal, else \code str1[i] - str2[i] \endcode for - * first differing character. - */ -int strcmp(const char *str1, const char *str2); - -/** - * Compare two \c NULL -terminated strings, max \c num characters. - * - * @param str1 First string to compare. - * @param str2 Second string to compare. - * @param num Maximum number of characters to compare. - * @return \c 0 if strings are equal, else \code str[i] - str2[i] \endcode for - * first differint character. - */ -int strncmp(const char *str1, const char *str2, size_t num); - -/** - * Find first character occurence of \c chr in \c str. - * - * @param str String to look in. - * @param chr Character to look for. - * @return Pointer to first \c chr in \c str, else \c 0. - */ -char *strchr(const char *str, int chr); - -/** - * Tokenize string at delimiters. Each stop character is replaced with a \c - * NULL. Each following call after the initial found should be a \c NULL. Note - * that this kernel's implementation is not thread safe. - * - * @param str String to look in. - * @param delims String of characters to stop on. - * @return Start of found token, \c NULL otherwise. - */ -char *strtok(char * restrict str, const char * restrict delims); - -/** - * Find first occurence of \c str2 in \c str1. - * - * @param str1 String to look in. - * @param str2 String to look for. - * @return Pointer to start of first occurence, \c NULL otherwise. - */ -char *strstr(const char *str1, const char *str2); - -/** - * Find last occurence of \c chr in \c str. - * - * @param str String to look in. - * @param chr Character to look for. - * @return Pointer to last occurence. - */ -char *strrchr(const char *str, int chr); - -/** - * Find first occurence in \c str1 of any of characters in \c str2. - * - * @param str1 String to look in. - * @param str2 String of characters to look for. - * @return Pointer to first occurence. - */ -char *strpbrk(const char *str1, const char *str2); - -/** - * Get span of characters in \c str2 in \c str1. - * - * @param str1 String to look in. - * @param str2 String of characters to look for. - * @return Number of characters at start of \c str1 that are also in \c str2. - */ -size_t strspn(const char *str1, const char *str2); - -/** - * Get span of characters not in \c str2 in \c str1. - * - * @param str1 String to look in. - * @param str2 String of characters to look out for. - * @return Number of characters at start of \c str1 that are not in \c str2. - */ -size_t strcspn(const char *str1, const char *str2); - -/** - * Length of \c NULL-terminated string. - * - * @param str String. - * @return Length of \c str. - */ -size_t strlen(const char *str); -/** - * Length of \c NULL-terminated string, max \c num. - * Only addition on top of functions found in libc. - * - * @param str String. - * @param num Max number of characters to count. - * @return Length of \c str or \c num. - */ -size_t strnlen(const char *str, size_t num); - -/** - * Initialize memory to some value. - * - * @param ptr Pointer to memory to initialize. - * @param value Value to initialize to. \note Will be truncated to byte. - * @param num Number of bytes to initialize. - * @return \c ptr. - */ -void *memset(void *ptr, int value, size_t num); - -/** - * Look for value in memory. - * - * @param ptr Pointer to memory to look in. - * @param val Value to look for. \note Will be truncated to byte. - * @param num Number of bytes to look. - * @return Pointer to first occurence of \c val. - */ -void *memchr(const void *ptr, int val, size_t num); - -/** - * Copy memory byte for byte. - * \c dst may not overlap \c src. - * - * @param dst Destination of copy. - * @param src Source of copy. - * @param num Number of bytes to copy. - * @return \c dst. - */ -void *memcpy(void * restrict dst, const void * restrict src, size_t num); - -/** - * Move memory byte by byte. - * \note Essentially identical to \ref memcpy(), but the memory regions may - * overlap. - * - * @param dst Destination of move. - * @param src Source of move. - * @param num Number of bytes to move. - * @return \c dst. - */ -void *memmove(void *dst, const void *src, size_t num); - -/** - * Compare memory byte by byte. - * - * @param ptr1 Memory to compare 1. - * @param ptr2 Memory to compare 2. - * @param num Bytes to compare. - * @return \c 0 when equal, else - * \code (unsigned char *)ptr1[i] - (unsigned char *)ptr2[i] \endcode - * at first differing byte. - */ -int memcmp(const void *ptr1, const void *ptr2, size_t num); - -/* Honorable mentions: - * - * char *strerror(int err); - * int strcoll(const char *str1, const char *str2); - * int strxfrm(char *dest, const char *src, size_t num); - * - */ - -/* provide macros for builtin functions. The compiler is always allowed to - * replace a __builtin_* with a regular call to the function, which is why we - * still need to define the functions. - * - * Does mean we can't take the address of any of these, but I suppose that's not - * an issue. - */ - -#if __has_builtin(__builtin_memcpy) -#define memcpy(dst, src, num) __builtin_memcpy(dst, src, num) -#endif - -#if __has_builtin(__builtin_memmove) -#define memmove(dst, src, num) __builtin_memmove(dst, src, num) -#endif - -#if __has_builtin(__builtin_strcpy) -#define strcpy(dst, src) __builtin_strcpy(dst, src) -#endif - -#if __has_builtin(__builtin_strncpy) -#define strncpy(dst, src, num) __builtin_strncpy(dst, src, num) -#endif - -#if __has_builtin(__builtin_strcat) -#define strcat(dst, src) __builtin_strcat(dst, src) -#endif - -#if __has_builtin(__builtin_strncat) -#define strncat(dst, src, num) __builtin_strncat(dst, src, num) -#endif - -#if __has_builtin(__builtin_memcmp) -#define memcmp(p1, p2, num) __builtin_memcmp(p1, p2, num) -#endif - -#if __has_builtin(__builtin_strcmp) -#define strcmp(s1, s2) __builtin_strcmp(s1, s2) -#endif - -#if __has_builtin(__builtin_strncmp) -#define strncmp(s1, s2, num) __builtin_strncmp(s1, s2, num) -#endif - -#if __has_builtin(__builtin_strncmp) -#define memchr(ptr, val, num) __builtin_memchr(ptr, val, num) -#endif - -#if __has_builtin(__builtin_strchr) -#define strchr(str, chr) __builtin_strchr(str, chr) -#endif - -#if __has_builtin(__builtin_strcspn) -#define strcspn(s1, s2) __builtin_strcspn(s1, s2) -#endif - -#if __has_builtin(__builtin_strpbrk) -#define strpbrk(s1, s2) __builtin_strpbrk(s1, s2) -#endif - -#if __has_builtin(__builtin_strchr) -#define strrchr(s1, s2) __builtin_strrchr(s1, s2) -#endif - -#if __has_builtin(__builtin_strspn) -#define strspn(s1, s2) __builtin_strspn(s1, s2) -#endif - -#if __has_builtin(__builtin_strstr) -#define strstr(s1, s2) __builtin_strstr(s1, s2) -#endif - -#if __has_builtin(__builtin_strtok) -#define strtok(s1, s2) __builtin_strtok(s1, s2) -#endif - -#if __has_builtin(__builtin_memset) -#define memset(p, v, n) __builtin_memset(p, v, n) -#endif - -#if __has_builtin(__builtin_strlen) -#define strlen(s) __builtin_strlen(s) -#endif - -#endif /* APOS_STRING_H */ diff --git a/include/apos/syscalls.h b/include/apos/syscalls.h deleted file mode 100644 index 40e6504..0000000 --- a/include/apos/syscalls.h +++ /dev/null @@ -1,142 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_SYSCALLS_H -#define APOS_SYSCALLS_H - -/** - * @file syscalls.h - * Table of system calls. - */ - -/** enum for now, possibly macros in the future once I get an approximate idea of - * which syscalls are necessary etc. */ -enum { - /** - * @name Misc. - * Implementation in \ref dispatch.c instead of a separate file, as I - * consider them 'internal' and not intended for users. - */ - /** @{ */ - /** Noop, mainly for testing syscall subsystem and sanity checking. */ - SYS_NOOP, - - /** - * Put a single character to the serial lines. - * Do not rely on this actually working, as the serial drivers are only - * included on debugging kernels. - * - * \todo Should serial drivers be always included and debugging mode - * turned into whether \ref info is turned on or off or something? - */ - SYS_PUTCH, - - /** @} */ - - /* @name Memory management. */ - /** @{ */ - /** Request memory from anywhere. */ - SYS_REQ_MEM, - - /** Request physical page from ram. */ - SYS_REQ_PAGE, - - /** Request memory with physical address. */ - SYS_REQ_PMEM, - - /** Request memory at fixed virtual address. */ - SYS_REQ_FIXMEM, - - /** Request shared memory. */ - SYS_REQ_SHAREDMEM, - - /** Free memory. */ - SYS_FREE_MEM, - /** @} */ - - /** @name Timers */ - /** @{ */ - /** Get accuracy of clock in Hertz. */ - SYS_TIMEBASE, - - /** Get current ticks. */ - SYS_TICKS, - - /** Request relative timer (number of ticks from now). */ - SYS_REQ_REL_TIMER, - - /** Request absolute timer (timepoint in ticks). */ - SYS_REQ_ABS_TIMER, - - /** Remove timer. */ - SYS_FREE_TIMER, - /** @} */ - - /** @name IPC. */ - /** @{ */ - /** Inform kernel that process should be treated as server. */ - SYS_IPC_SERVER, - - /** Send IPC request as client. */ - SYS_IPC_REQ, /* IPC request to server */ - - /** Forward IPC request from client. */ - SYS_IPC_FWD, - - /** IPC response from server. */ - SYS_IPC_RESP, - - /** IPC notify thread, essentially interrupt or signal. */ - SYS_IPC_NOTIFY, - /** @} */ - - /** @name Process management. */ - /** @{ */ - /** Create new thread. */ - SYS_CREATE, - - /** Duplicate process. */ - SYS_FORK, - - /** Execute new binary in process space. */ - SYS_EXEC, - - /** Execute new binary in new process space. */ - SYS_SPAWN, - - /** Kill thread. */ - SYS_KILL, - - /** Switch running process. */ - SYS_SWAP, - - /** @} */ - - /** @name Kernel management. */ - /** @{ */ - /** Configure system parameters (stack size etc.). */ - SYS_CONF_SET, - - /** Get system parameters. */ - SYS_CONF_GET, - - /** Set capability of thread. */ - SYS_SET_CAP, - - /** Get capabilities of thread. */ - SYS_GET_CAP, - - /** Clear capability of thread. */ - SYS_CLEAR_CAP, - - /** Shutdown, reboot, etc. */ - SYS_POWEROFF, - /** @} */ - - SYS_NUM, -}; - -/* function declarations should be somewhere else, this file could be used in - * userspace applications as well */ - -#endif /* APOS_SYSCALLS_H */ diff --git a/include/apos/tcb.h b/include/apos/tcb.h deleted file mode 100644 index 8f3be3d..0000000 --- a/include/apos/tcb.h +++ /dev/null @@ -1,417 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_TCB_H -#define APOS_TCB_H - -/** - * @file tcb.h - * Process/thread handling. - */ - -#include -#include -#include -#include /* arch-specific data */ - -/** - * Check if thread is process thread. - * - * @param t Thread to check. - * @return \c true if thread is process thread, \c false otherwise. - */ -#define is_proc(t) (t->rid == t->tid) - -/** - * Check if thread is in RPC. - * - * @param t Thread to check. - * @return \c true if thread is in RPC, \c false otherwise. - */ -#define is_rpc(t) (t->rid != t->pid) - -/** - * Get the effective process thread of current thread. - * - * @param t Thread whose effective process thread to get. - * @return The process thread of the current thread. - */ -#define get_proc(t) (get_tcb(t->eid)) - -/** - * Alias for \ref get_proc(), to make it more obvious that we're accessing the - * effective process. Might be useful in some situations. - */ -#define get_eproc(t) get_proc(t) - -/** - * Get the current process thread of current thread. - * - * @param t Thread whose current process thread to get. - * @return The current process thread of the current thread. - */ -#define get_cproc(t) (get_tcb(t->pid)) - -/** - * Get the root process thread of current thread. - * - * @param t Thread whose root process thread to get. - * @return The root process thread of the current thread. - */ -#define get_rproc(t) (get_tcb(t->rid)) - -/* forward declaration */ -struct tcb; - -/** Convenience structure for \ref tcb. */ -struct tcb_ctx { - /** Virtual address space of context. */ - struct vmem *vmem; - - /** Next thread in context. */ - struct tcb *next; - - /** Previous thread in context. */ - struct tcb *prev; -}; - -/** Enum for notification states. */ -enum tcb_notify { - /** Thread is free to be notified. */ - NOTIFY_WAITING = 0, - - /** Thread has notifcations queued. */ - NOTIFY_QUEUED, - - /** Thread is running notification handler. */ - NOTIFY_RUNNING, -}; - -/** Thread control block. Main way to handle threads. */ -struct tcb { - /** Execution continuation point. Important that it is first. */ - vm_t exec; - - /** - * Address where to save registers. - * @note his address is the top of the register save structure. - */ - vm_t regs; - - /** Arch-specific data. */ - struct arch_tcbd tcbd; - - /** Memory mapping data. */ - struct mem_region_root sp_r; - - /** - * Effective process ID. - * - * This is the ID on which globally visible stuff should occur, such as - * memory allocations etc. - * - * When a thread is in an RPC, and a \ref SYS_IPC_FWD request occurs, the \c - * eid of the thread remains the same, whereas in a regular \c - * SYS_IPC_REQ the \c eid if replaced with the \ref pid of the - * process the thread is visiting. - */ - id_t eid; - - /** - * Actual process ID. - * - * This, along with \ref eid, creates the backbone of the IPC process ID - * handling. - */ - id_t pid; - - /** - * Root process ID. - * - * ID of the process that spawned the thread, and the process the thread - * should belong to when not in an RPC. - */ - id_t rid; - - /** Thread ID. @note all ids associated with threads use a signed type, - * but are always larger than zero. This is mirroring Linux behavior, - * and signed types are probably large enough. */ - id_t tid; - - /** \todo implement cpu_id to hardware cpu ID translation, first in - * riscv. */ - /** Cpu currently executing this thread. */ - id_t cpu_id; - - /** Address of callback function in servers. */ - vm_t callback; - - /** Capabilities of thread. */ - capflags_t caps; - - /** Address of this thread's stack base. */ - vm_t thread_stack; - - /** Address of this thread's stack top. */ - vm_t thread_stack_top; - - /** Current address of usable rpc stack. */ - vm_t rpc_stack; - - /** \todo Check if each thread should be allowed more than just one - * region of thread local storage. */ - /** Possible thread local storage. */ - vm_t thread_storage; - - /** Process context of thread. */ - struct tcb_ctx proc; - - /** RPC context of thread. */ - struct tcb_ctx rpc; - - /** - * RPC server context of thread. When a thread attaches itself to this - * process, its \ref rpc member is added to the list maintained in this - * variable. This allows the original thread to do rpc calls without - * messing up other threads' rpc status. - * - * I think, more testing required. - */ - struct tcb_ctx server; - - /** Notifcation state of thread. */ - enum tcb_notify notify_state; - - /** Whether thread has gotten an IPI */ - bool ipi; -}; - -/** - * Initialize thread control subsystem. - */ -void init_tcbs(); - -/** - * Destroy thread control subsystem. - */ -void destroy_tcbs(); - -/** - * Create a new thread. - * - * If \c p is \c NULL, then a new process context is created for the thread. - * Otherwise, the thread is inserted into \c p. - * - * The thread is allocated a virtual address space, as well as a kernel stack - * and the \ref tcb structure itself with a unique thread ID. If in a new - * process context, a new process address space is created as well. - * - * Userspace stack is allocated with \ref alloc_stack(). - * - * \todo Thread local storage? - * - * @param p Process context within to create the thread. - * @return Pointer to created \ref tcb. - */ -struct tcb *create_thread(struct tcb *p); - -/** - * Create a new process. - * - * Sets up a new thread in a new process context. If there is a parent thread, - * its memory regions are copied. - * \see create_thread(). - * - * @param p Parent process. - * @return Pointer to created \ref tcb. - */ -struct tcb *create_proc(struct tcb *p); - -/** - * Destroy a thread. - * - * Frees data associated with thread and frees up the thread ID. - * At least currently does not allow \c t to be a process thread. - * - * \todo Other return values? - * - * @param t Thread to destroy. - * @return \ref OK on success, \ref ERR_NOINIT if called without initializing - * subsystem and \ref ERR_INVAL if called with a process thread. - */ -stat_t destroy_thread(struct tcb *t); - -/** - * Destroy a process. - * - * Frees all data associated with the process and destroys all threads within - * it. - * - * @param p Process to destroy. - * @return \ref OK on success, \ref ERR_NOINIT if called without initializing - * subsystem and \ref ERR_INVAL if called without a process thread. - */ -stat_t destroy_proc(struct tcb *p); - -/** - * Attach a thread to an RPC context. - * - * Essentially inserts thread \c t into the process \c r, with access to the - * same memory except for the RPC stack. - * - * @param r Process to attach to. - * @param t Thread to attach. - * @return \ref OK on success, \ref ERR_INVAL if pointers are the same. - */ -stat_t attach_rpc(struct tcb *r, struct tcb *t); - -/** - * Detach a thread from an RPC context. - * - * \see attach_rpc(). - * - * @param r Process to detach from. - * @param t Thread to detach. - * @return \ref OK on success, \ref ERR_INVAL if pointers are the same. - * - * \todo Should probably check that thread exists in the process? - */ -stat_t detach_rpc(struct tcb *r, struct tcb *t); - -/** - * Attach a thread in a process context. - * - * @param r Process to attach to. - * @param t Thread to attach. - * @return \ref OK on success, \ref ERR_INVAL if pointers are the same. - */ -stat_t attach_proc(struct tcb *r, struct tcb *t); - -/** - * Detach a thread from a process context. - * - * @param r Process to detach from. - * @param t Thread to detach. - * @return \ref OK on success, \ref ERR_INVAL if pointers are the same. - */ -stat_t detach_proc(struct tcb *r, struct tcb *t); - -/** - * Get currently executing thread. - * - * @return Current \ref tcb. - */ -struct tcb *cur_tcb(); - -/** - * Get thread currently running on cpu \p cpu_id. - * - * @param cpu_id CPU whose currently running thread to get. - * @return \ref tcb running on cpu. - */ -struct tcb *cpu_tcb(id_t cpu_id); - -/** - * Get currently executing process. - * - * @return Effective process \ref tcb. - */ -struct tcb *cur_proc(); - -/** - * Get currently executing process. - * - * @return Effective process \ref tcb. - */ -struct tcb *eff_proc(); - -/** - * Set \c t as current \ref tcb. - * - * Also updates the current cpu id of the tcb. - * - * @param t Thread to mark as current. - */ -void use_tcb(struct tcb *t); - -/** - * Get \ref tcb corresponding to thread with ID \c tid. - * - * @param tid Thread ID. - * @return Corresponding \ref tcb or \c NULL if not found. - */ -struct tcb *get_tcb(id_t tid); - -/** - * Clone process context memory mappings. - * - * Essentially make sure all threads in the process have identical memory - * mappings. - * - * @param p Process whose memory mappings to clone. - * @return \ref OK on success, something else otherwise. - * \todo Check up on return codes. - */ -stat_t clone_proc_maps(struct tcb *p); - -/** - * Clone RPC context memory mappings. - * - * \see clone_proc_maps(). - * - * @param r Server whose memory mappings to clone to threads in RPC to it. - * @return \ref OK on success, something else otherwise. - * \todo Check up on return codes. - */ -stat_t clone_rpc_maps(struct tcb *r); - -/** - * Allocate stacks for thread. - * - * Both user stack and RPC stack. - * - * @param t Thread whose stacks to allocate. - * @return \ref OK on success, \ref ERR_OOMEM if out of memory. - */ -stat_t alloc_stack(struct tcb *t); - -/** - * Set address to jump to when returning to userspace. - * - * @param t Thread return address to set. - * @param r Address to jump to. - */ -void set_return(struct tcb *t, vm_t r); - -/** - * Check whether \p t is currently running on some cpu. - * - * @param t \ref tcb to check. - * @return \c true if it is running, \c false otherwise. - */ -bool running(struct tcb *t); - -/** - * Save thread context for rpc call. - * Assumes t->rpc is pointing to the correct virtual memory. - * - * @param t Thread whose context to save. - */ -void enter_rpc(struct tcb *t); - -/** - * Load thread context from rpc call. - * - * @param t Thread whose context to restore. - */ -void leave_rpc(struct tcb *t); - -/** - * Check that we have enough rpc stack. - * - * @param t Thread whose rpc stack to check. - * @return \ref true if we have enough, \ref false otherwise. - */ -bool enough_rpc_stack(struct tcb *t); - -#endif /* APOS_TCB_H */ diff --git a/include/apos/timer.h b/include/apos/timer.h deleted file mode 100644 index 6f83d23..0000000 --- a/include/apos/timer.h +++ /dev/null @@ -1,136 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_TIMER_H -#define APOS_TIMER_H - -/** - * @file timer.h - * Timer handling. - * - * \todo Document exceptions and return values better. - */ - -#include - -/** - * ticks_t typedef, use unsigned 64bit integer on all platforms. - * - * GCC will compile uint64_t even on 32bit platforms, just with some runtime - * overhead, should be fine. This will allow us to have a reasonable time range - * even with nanosecond clocks. (138 years with ~4.2 Hz clock) - */ -typedef uint64_t ticks_t; - -/** - * tunit_t typedef, whichever time unit we're dealing with. - */ -typedef size_t tunit_t; - -/** - * Timer structure. - */ -struct timer { - /** tid. Thread ID of whoever scheduled the timer. */ - id_t tid; - /** cid. Control ID, used to differentiate timers. */ - id_t cid; - - /** ticks. Absolute number of ticks, essentially a timepoint for when - * the timer should trigger. */ - ticks_t ticks; -}; - -/** - * Initialize timers. - * - * @param fdt Pointer to global FDT - */ -void init_timer(const void *fdt); - -/** - * Set up timer interrupt ticks from now. - * - * @param tid Thread id for callback. - * @param ticks Ticks from \ref current_ticks(). - * @return Id of created timer. - */ -id_t new_rel_timer(id_t tid, ticks_t ticks); - -/** - * Set up timer interrupt at ticks. - * - * @param tid Thread id for callback. - * @param ticks Ticks from \ref current_ticks(). - * @return Id of created timer. - */ -id_t new_abs_timer(id_t tid, ticks_t ticks); - -/** - * Return a pointer to the newest timer, i.e. the one that is closest to - * triggering. - * - * @return Pointer to a timer or NULL if queue is empty. - */ -struct timer *newest_timer(); - -/** - * Find a timer associated with a specific control ID. - * - * @param cid Control ID to find. - * @return Pointer to associated timer if found, else NULL. - */ -struct timer *find_timer(id_t cid); - -/** - * Remove a timer. - * - * @param timer Pointer to timer to remove. - * @return OK on success. - */ -stat_t remove_timer(struct timer *timer); - -/** - * Convert nanoseconds to ticks. - * - * @param nsecs Number of nanoseconds to represent as ticks. - * @return Equivalent ticks to nsecs. - */ -ticks_t nsecs_to_ticks(tunit_t nsecs); - -/** - * Convert microseconds to ticks. - * - * @param usecs Number of microseconds to represent as ticks. - * @return Equivalent ticks to usecs. - */ -static inline ticks_t usecs_to_ticks(tunit_t usecs) -{ - return nsecs_to_ticks(usecs * 1000); -} - -/** - * Convert milliseconds to ticks. - * - * @param msecs Number of milliseconds to represent as ticks. - * @return Equivalent ticks to msecs. - */ -static inline ticks_t msecs_to_ticks(tunit_t msecs) -{ - return usecs_to_ticks(msecs * 1000); -} - -/** - * Convert seconds to ticks. - * - * @param secs Number of seconds to represent as ticks. - * @return Equivalent ticks to secs. - */ -static inline ticks_t secs_to_ticks(tunit_t secs) -{ - /** \todo likely not a problem on 64bit systems, not sure how to handle situation on - * 32bit */ - return msecs_to_ticks(secs * 1000); -} - -#endif /* APOS_TIMER_H */ diff --git a/include/apos/types.h b/include/apos/types.h deleted file mode 100644 index 36e918e..0000000 --- a/include/apos/types.h +++ /dev/null @@ -1,494 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_TYPES_H -#define APOS_TYPES_H - -/** - * @file types.h - * Shorthands for types, similar to stdint.h. - * - * Implementation detail: Note that according to the C spec, intX_t are optional. - * Will have to keep an eye out for architectures where they aren't implemented, - * but for now this is likely good enough. - */ - -/** Bool. */ -typedef _Bool bool; -/** True. */ -#define true 1 -/** False. */ -#define false 0 - -/** Type capable of holding the difference between two pointers. */ -typedef __PTRDIFF_TYPE__ ptrdiff_t; - -/** Type capable of holding a wide char. Unused by the kernel. */ -typedef __WCHAR_TYPE__ wchar_t; - -/** Type capable of holding a \ref wchar_t and WEOF. Unused by the kernel. */ -typedef __WINT_TYPE__ wint_t; - -/** Maximum width signed integer type. */ -typedef __INTMAX_TYPE__ intmax_t; - -/** Maximum width unsigned integer type. */ -typedef __UINTMAX_TYPE__ uintmax_t; - -/** 8bit signed integer type. */ -typedef __INT8_TYPE__ int8_t; - -/** 16bit signed integer type. */ -typedef __INT16_TYPE__ int16_t; - -/** 32bit signed integer type. */ -typedef __INT32_TYPE__ int32_t; - -/** 64bit signed integer type. */ -typedef __INT64_TYPE__ int64_t; - -/** 8bit unsigned integer type. */ -typedef __UINT8_TYPE__ uint8_t; - -/** 16bit unsigned integer type. */ -typedef __UINT16_TYPE__ uint16_t; - -/** 32bit unsigned integer type. */ -typedef __UINT32_TYPE__ uint32_t; - -/** 64bit unsigned integer type. */ -typedef __UINT64_TYPE__ uint64_t; - -/** Smallest signed integer type at least 8 bits wide. */ -typedef __INT_LEAST8_TYPE__ int_least8_t; - -/** Smallest signed integer type at least 16 bits wide. */ -typedef __INT_LEAST16_TYPE__ int_least16_t; - -/** Smallest signed integer type at least 32 bits wide. */ -typedef __INT_LEAST32_TYPE__ int_least32_t; - -/** Smallest signed integer type at least 64 bits wide. */ -typedef __INT_LEAST64_TYPE__ int_least64_t; - -/** Smallest unsigned integer type at least 8 bits wide. */ -typedef __UINT_LEAST8_TYPE__ uint_least8_t; - -/** Smallest unsigned integer type at least 16 bits wide. */ -typedef __UINT_LEAST16_TYPE__ uint_least16_t; - -/** Smallest unsigned integer type at least 32 bits wide. */ -typedef __UINT_LEAST32_TYPE__ uint_least32_t; - -/** Smallest unsigned integer type at least 64 bits wide. */ -typedef __UINT_LEAST64_TYPE__ uint_least64_t; - -/** Fastest signed integer type at least 8 bits wide. */ -typedef __INT_FAST8_TYPE__ int_fast8_t; - -/** Fastest signed integer type at least 16 bits wide. */ -typedef __INT_FAST16_TYPE__ int_fast16_t; - -/** Fastest signed integer type at least 32 bits wide. */ -typedef __INT_FAST32_TYPE__ int_fast32_t; - -/** Fastest signed integer type at least 64 bits wide. */ -typedef __INT_FAST64_TYPE__ int_fast64_t; - -/** Fastest unsigned integer type at least 8 bits wide. */ -typedef __UINT_FAST8_TYPE__ uint_fast8_t; - -/** Fastest unsigned integer type at least 16 bits wide. */ -typedef __UINT_FAST16_TYPE__ uint_fast16_t; - -/** Fastest unsigned integer type at least 32 bits wide. */ -typedef __UINT_FAST32_TYPE__ uint_fast32_t; - -/** Fastest unsigned integer type at least 64 bits wide. */ -typedef __UINT_FAST64_TYPE__ uint_fast64_t; - -/** Signed integer type capable of holding a pointer. */ -typedef __INTPTR_TYPE__ intptr_t; - -/** Unsigned integer type capable of holding a pointer. */ -typedef __UINTPTR_TYPE__ uintptr_t; - -#if __SIZE_WIDTH__ == 64 -/** Largest possible unsigned index an array could use. */ -typedef uint64_t size_t; - -/** Largest possible signed index an array could use. */ -typedef int64_t ssize_t; -#else -/** Largest possible unsigned index an array could use. */ -typedef uint32_t size_t; - -/** Largest possible signed index an array could use. */ -typedef int32_t ssize_t; -#endif - -/** Expands to integer constant of type \ref int8_t. */ -#define INT8_C __INT8_C - -/** Expands to integer constant of type \ref int16_t. */ -#define INT16_C __INT16_C - -/** Expands to integer constant of type \ref int32_t. */ -#define INT32_C __INT32_C -/** Expands to integer constant of type \ref int64_t. */ -#define INT64_C __INT64_C - -/** Expands to integer constant of type \ref uint8_t. */ -#define UINT8_C __UINT8_C - -/** Expands to integer constant of type \ref uint16_t. */ -#define UINT16_C __UINT16_C - -/** Expands to integer constant of type \ref uint32_t. */ -#define UINT32_C __UINT32_C - -/** Expands to integer constant of type \ref uint64_t. */ -#define UINT64_C __UINT64_C - -/** Expands to integer constant of type \ref intmax_t. */ -#define INTMAX_C __INTMAX_C - -/** Expands to integer constant of type \ref uintmax_t. */ -#define UINTMAX_C __UINTMAX_C - -/** Number of bits in a byte. */ -#define CHAR_BIT __CHAR_BIT__ - -/** Largest value a signed char can have. */ -#define SCHAR_MAX __SCHAR_MAX__ - -/** Smallest value a signed char can have. */ -#define SCHAR_MIN (-__SCHAR_MAX - 1) - -/** Largest value an unsigned char can have. */ -#define UCHAR_MAX (2 * __SCHAR_MAX__ - 1) - -#if defined(__CHAR_UNSIGNED__) -/** Smallest value a char can have. */ -#define CHAR_MIN 0 - -/** Largest value a char can have. */ -#define CHAR_MAX UCHAR_MAX -#else -/** Smallest value a char can have. */ -#define CHAR_MIN SCHAR_MIN - -/** Largest value a char can have. */ -#define CHAR_MAX SCHAR_MAX -#endif - -/** - * Maximum number of bytes in a multibyte character. - * Arbitrary, as far as I can tell. - */ -#define MB_LEN_MAX 16 - -/** Largest value a signed short can have. */ -#define SHRT_MAX __SHRT_MAX__ - -/** Smallest value a signed short can have. */ -#define SHRT_MIN (-__SHRT_MAX - 1) - -/** Largest value an unsigned short can have. */ -#define USHRT_MAX (2 * __SHRT_MAX + 1) - -/** Largest value a signed int can have. */ -#define INT_MAX __INT_MAX__ - -/** Smallest value a signed int can have. */ -#define INT_MIN (-__INT_MAX__ - 1) - -/** Largest value an unsigned int can have. */ -#define UINT_MAX (2 * __INT_MAX__ + 1) - -/** Largest value a signed long can have. */ -#define LONG_MAX __LONG__MAX__ - -/** Smallest value a signed long can have. */ -#define LONG_MIN (-__LONG_MAX__ - 1) - -/** Largest value an unsigned long can have. */ -#define ULONG_MAX (2 * __INT_MAX__ + 1) - -/** Largest value a signed long long can have. */ -#define LLONG_MAX __LONG_LONG_MAX__ - -/** Smallest value a signed long long can have. */ -#define LLONG_MIN (-__LONG_LONG_MAX__ - 1) - -/** Largest value an unsigned long long can have. */ -#define ULLONG_MAX (2 * __LONG_LONG_MAX__ + 1) - -/** Largest value an \ref int8_t can have. */ -#define INT8_MAX __INT8_MAX__ - -/** Smallest value an \ref int8_t can have. */ -#define INT8_MIN (-__INT8_MAX__ - 1) - -/** Largest value an \ref int8_t can have. */ -#define UINT8_MAX __UINT8_MAX__ - -/** Largest value an \ref int16_t can have. */ -#define INT16_MAX __INT16_MAX__ - -/** Smallest value an \ref int16_t can have. */ -#define INT16_MIN (-__INT16_MAX__ - 1) - -/** Largest value an \ref uint16_t can have. */ -#define UINT16_MAX __UINT16_MAX__ - -/** Largest value an \ref int32_t can have. */ -#define INT32_MAX __INT32_MAX__ - -/** Smallest value an \ref int32_t can have. */ -#define INT32_MIN (-__INT32_MAX__ - 1) - -/** Largest value a \ref uint16_t can have. */ -#define UINT32_MAX __UINT32_MAX__ - -/** Largest value an \ref int64_t can have. */ -#define INT64_MAX __INT64_MAX__ - -/** Smallest value an \ref int64_t can have. */ -#define INT64_MIN (-__INT64_MAX__ - 1) - -/** Largest value an \ref uint64_t can have. */ -#define UINT64_MAX __UINT64_MAX__ - -/** Largest value an \ref int_least8_t can have. */ -#define INT_LEAST8_MAX __INT_LEAST8_MAX__ - -/** Smallest value an \ref int_least8_t can have. */ -#define INT_LEAST8_MIN (-__INT_LEAST8_MAX__ - 1) - -/** Largest value an \ref int_least8_t can have. */ -#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__ - -/** Largest value an \ref int_least16_t can have. */ -#define INT_LEAST16_MAX __INT_LEAST16_MAX__ - -/** Smallest value an \ref int_least16_t can have. */ -#define INT_LEAST16_MIN (-__INT_LEAST16_MAX__ - 1) - -/** Largest value an \ref int_least16_t can have. */ -#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__ - -/** Largest value an \ref int_least32_t can have. */ -#define INT_LEAST32_MAX __INT_LEAST32_MAX__ - -/** Smallest value an \ref int_least32_t can have. */ -#define INT_LEAST32_MIN (-__INT_LEAST32_MAX__ - 1) - -/** Largest value a \ref uint_least32_t can have. */ -#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__ - -/** Largest value an \ref int_least64_t can have. */ -#define INT_LEAST64_MAX __INT_LEAST64_MAX__ - -/** Smallest value an \ref int_least64_t can have. */ -#define INT_LEAST64_MIN (-__INT_LEAST64_MAX__ - 1) - -/** Largest value a \ref uint_least64_t can have. */ -#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__ - -/** Largest value an \ref int_fast8_t can have. */ -#define INT_FAST8_MAX __INT_FAST8_MAX__ - -/** Smallest value an \ref int_fast8_t can have. */ -#define INT_FAST8_MIN (-__INT_FAST8_MAX__ - 1) - -/** Largest value a \ref uint_fast8_t can have. */ -#define UINT_FAST8_MAX __UINT_FAST8_MAX__ - -/** Largest value an \ref int_fast16_t can have. */ -#define INT_FAST16_MAX __INT_FAST16_MAX__ - -/** Smallest value an \ref int_fast16_t can have. */ -#define INT_FAST16_MIN (-__INT_FAST16_MAX__ - 1) - -/** Largest value a \ref uint_fast16_t can have. */ -#define UINT_FAST16_MAX __UINT_FAST16_MAX__ - -/** Largest value an \ref int_fast32_t can have. */ -#define INT_FAST32_MAX __INT_FAST32_MAX__ - -/** Smallest value an \ref int_fast32_t can have. */ -#define INT_FAST32_MIN (-__INT_FAST32_MAX__ - 1) - -/** Largest value a \ref int_fast32_t can have. */ -#define UINT_FAST32_MAX __UINT_FAST32_MAX__ - -/** Largest value an \ref int_fast64_t can have. */ -#define INT_FAST64_MAX __INT_FAST64_MAX__ - -/** Smallest value an \ref int_fast64_t can have. */ -#define INT_FAST64_MIN (-__INT_FAST64_MAX__ - 1) - -/** Largest value a \ref int_fast64_t can have. */ -#define UINT_FAST64_MAX __UINT_FAST64_MAX__ - -/** Largest value an \ref intptr_t can have. */ -#define INTPTR_MAX __INTPTR_MAX__ - -/** Smallest value an \ref intptr_t can have. */ -#define INTPTR_MIN (-__INTPTR_MAX__ - 1) - -/** Largest value a \ref uintptr_t can have. */ -#define UINTPTR_MAX __UINTPTR_MAX__ - -/** Largest value an \ref intmax_t can have. */ -#define INTMAX_MAX __INTMAX_MAX__ - -/** Smallest value an \ref intmax_t can have. */ -#define INTMAX_MIN (-__INTMAX_MAX__ - 1) - -/** Largest value a \ref uintmax_t can have. */ -#define UINTMAX_MAX __UINTMAX_MAX__ - -/** Width of \ref int8_t. */ -#define INT8_WIDTH 8 - -/** Width of \ref int16_t. */ -#define INT16_WIDTH 16 - -/** Width of \ref int32_t. */ -#define INT32_WIDTH 32 - -/** Width of \ref int64_t. */ -#define INT64_WIDTH 64 - -/** Width of \ref uint8_t. */ -#define UINT8_WIDTH 8 - -/** Width of \ref uint16_t. */ -#define UINT16_WIDTH 16 - -/** Width of \ref uint32_t. */ -#define UINT32_WIDTH 32 - -/** Width of \ref uint64_t. */ -#define UINT64_WIDTH 64 - -/** Width of \ref int_fast8_t. */ -#define INT_FAST8_WIDTH __INT_FAST8_WIDTH__ - -/** Width of \ref int_fast16_t. */ -#define INT_FAST16_WIDTH __INT_FAST16_WIDTH__ - -/** Width of \ref int_fast32_t. */ -#define INT_FAST32_WIDTH __INT_FAST32_WIDTH__ - -/** Width of \ref int_fast64_t. */ -#define INT_FAST64_WIDTH __INT_FAST64_WIDTH__ - -/** Width of \ref uint_fast8_t. */ -#define UINT_FAST8_WIDTH __INT_FAST8_WIDTH__ - -/** Width of \ref uint_fast16_t. */ -#define UINT_FAST16_WIDTH __INT_FAST16_WIDTH__ - -/** Width of \ref uint_fast32_t. */ -#define UINT_FAST32_WIDTH __INT_FAST32_WIDTH__ - -/** Width of \ref uint_fast64_t. */ -#define UINT_FAST64_WIDTH __INT_FAST64_WIDTH__ - -/** Width of \ref int_least8_t. */ -#define INT_LEAST8_WIDTH __INT_LEAST8_WIDTH__ - -/** Width of \ref int_least16_t. */ -#define INT_LEAST16_WIDTH __INT_LEAST16_WIDTH__ - -/** Width of \ref int_least32_t. */ -#define INT_LEAST32_WIDTH __INT_LEAST32_WIDTH__ - -/** Width of \ref int_least64_t. */ -#define INT_LEAST64_WIDTH __INT_LEAST64_WIDTH__ - -/** Width of \ref uint_least8_t. */ -#define UINT_LEAST8_WIDTH __INT_LEAST8_WIDTH__ - -/** Width of \ref uint_least16_t. */ -#define UINT_LEAST16_WIDTH __INT_LEAST16_WIDTH__ - -/** Width of \ref uint_least32_t. */ -#define UINT_LEAST32_WIDTH __INT_LEAST32_WIDTH__ - -/** Width of \ref uint_least64_t. */ -#define UINT_LEAST64_WIDTH __INT_LEAST64_WIDTH__ - -/** Width of \ref intptr_t. */ -#define INTPTR_WIDTH __INTPTR_WIDTH__ - -/** Width of \ref intmax_t. */ -#define INTMAX_WIDTH __INTMAX_WIDTH__ - -/** Width of \ref uintptr_t. */ -#define UINTPTR_WIDTH __INTPTR_WIDTH__ - -/** Width of \ref uintmax_t. */ -#define UINTMAX_WIDTH __INTMAX_WIDTH__ - -/** Null. */ -#define NULL 0 - -/* some common types used throughout the kernel */ -/** Status, used with codes in \ref status_codes. */ -typedef int_fast8_t stat_t; - -/** ID of something. @todo should this be signed? Linux etc seems to assume it - * is with pids */ -typedef int_fast32_t id_t; - -/** Maximum ID number. */ -#define ID_MAX INT_FAST32_MAX - -/** Memory region flags. */ -typedef uint_fast16_t vmflags_t; - -/** - * Status codes. - * Negative error codes are reserved for general usage, positive error codes are - * allowed to be function-specific, although that's sort of difficult to keep - * track of. - */ -/* should this enum be somewhere else? */ -enum status_codes { - /** Permission error. */ - ERR_PERM = -10, - /** Internal error, should probably halt */ - ERR_INT = -9, - /** Something went wrong :/ */ - ERR_MISC = -8, - /** Not initialized. */ - ERR_NOINIT = -7, - /** Invalid value. */ - ERR_INVAL = -6, - /** Already exists. */ - ERR_EXT = -5, - /** Out of memory. */ - ERR_OOMEM = -4, - /** Illegal address. */ - ERR_ADDR = -3, - /** Wrong alignment. */ - ERR_ALIGN = -2, - /** Not found. */ - ERR_NF = -1, - /** OK. */ - OK = 0, - /** Try again. */ - INFO_TRGN = 1, - /** Side effects. */ - INFO_SEFF = 2, - /** Continue. */ - INFO_CONT = 3, -}; - -#include /* arch-specific type definitions (pm_t/vm_t etc) */ - -#endif /* APOS_TYPES_H */ diff --git a/include/apos/uapi.h b/include/apos/uapi.h deleted file mode 100644 index fefd1bf..0000000 --- a/include/apos/uapi.h +++ /dev/null @@ -1,792 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_UAPI_H -#define APOS_UAPI_H - -/** - * @file uapi.h - * Userspace api, syscall declarations. - */ - -#include -#include - -/** - * Syscall function type. - * Let's start with five arguments and see where that goes - */ -typedef void (*sys_t)(struct tcb *t, long, long, long, long, long); - -/** - * Syscall argument type. - * - * \todo: Should this be arch specific? should be the size of an integer - * register. - */ -typedef long sys_arg_t; - -/** - * Return structure of syscall. - * \note Field names are generic, and can be used for whatever, - * check documentation of whatever you're doing. - * @todo should this be placed into syscalls.h? - */ -struct sys_ret { - /** Status. */ - sys_arg_t s; - - /** First argument. */ - sys_arg_t ar0; - - /** Second argument. */ - sys_arg_t ar1; - - /** Third argument. */ - sys_arg_t ar2; - - /** Fourth argument. */ - sys_arg_t ar3; - - /** Fifth argument. */ - sys_arg_t ar4; -}; - -/** Helper for returning sys_ret with 0 arguments. */ -#define SYS_RET0() (struct sys_ret){0, 0, 0, 0, 0, 0} - -/** Helper for returning sys_ret with 1 arguments. */ -#define SYS_RET1(a) (struct sys_ret){a, 0, 0, 0, 0, 0} - -/** Helper for returning sys_ret with 2 arguments. */ -#define SYS_RET2(a, b) (struct sys_ret){a, b, 0, 0, 0, 0} - -/** Helper for returning sys_ret with 3 arguments. */ -#define SYS_RET3(a, b, c) (struct sys_ret){a, b, c, 0, 0, 0} - -/** Helper for returning sys_ret with 4 arguments. */ -#define SYS_RET4(a, b, c, d) (struct sys_ret){a, b, c, d, 0, 0} - -/** Helper for returning sys_ret with 5 arguments. */ -#define SYS_RET5(a, b, c, d, e) (struct sys_ret){a, b, c, d, e, 0} - -/** Helper for returning sys_ret with 6 arguments. */ -#define SYS_RET6(a, b, c, d, e, f) (struct sys_ret){a, b, c, d, e, f} - -/** - * Helper macro for declaring syscalls with zero arguments. - * - * The idea is that all syscalls externally have the same amount of arguments, - * but then by using some helper macros (see below) we can make actually - * implementing the syscall more intuitive and less noisy. - * - * @param name Name of syscall. - */ -#define SYSCALL_DECLARE0(name) \ - void sys_##name(struct tcb *t, \ - sys_arg_t a, \ - sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, \ - sys_arg_t e); - -/** - * Helper macro for declaring syscalls with one argument. - * - * @param name Name of syscall. - * @param a Name of argument. - */ -#define SYSCALL_DECLARE1(name, a) \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e); - -/** - * Helper macro for declaring syscalls with two arguments. - * - * @param name Name of syscall. - * @param a Name of first argument. - * @param b Name of second argument. - */ -#define SYSCALL_DECLARE2(name, a, b) \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e); - -/** - * Helper macro for declaring syscalls with three arguments. - * - * @param name Name of syscall. - * @param a Name of first argument. - * @param b Name of second argument. - * @param c Name of third argument. - */ -#define SYSCALL_DECLARE3(name, a, b, c) \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e); - -/** - * Helper macro for declaring syscalls with four arguments. - * - * @param name Name of syscall. - * @param a Name of first argument. - * @param b Name of second argument. - * @param c Name of third argument. - * @param d Name of fourth argument. - */ -#define SYSCALL_DECLARE4(name, a, b, c, d) \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e); - -/** - * Helper macro for declaring syscalls with five arguments. - * - * @param name Name of syscall. - * @param a Name of first argument. - * @param b Name of second argument. - * @param c Name of third argument. - * @param d Name of fourth argument. - * @param e Name of fifth argument. - */ -#define SYSCALL_DECLARE5(name, a, b, c, d, e) \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e); - -/** - * Helper macro for defining syscall with zero arguments. - * - * @param name Name of syscall. - */ -#define SYSCALL_DEFINE0(name) \ - static inline void __##name(struct tcb *t); \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e) \ - { \ - UNUSED(a); \ - UNUSED(b); \ - UNUSED(c); \ - UNUSED(d); \ - UNUSED(e); \ - __##name(t); \ - } \ - static inline void __##name - -/** - * Helper macro for defining syscall with one argument. - * - * @param name Name of syscall. - */ -#define SYSCALL_DEFINE1(name) \ - static inline void __##name(struct tcb *, sys_arg_t); \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e) \ - { \ - UNUSED(b); \ - UNUSED(c); \ - UNUSED(d); \ - UNUSED(e); \ - __##name(t, a); \ - } \ - static inline void __##name - -/** - * Helper macro for defining syscall with two arguments. - * - * @param name Name of syscall. - */ -#define SYSCALL_DEFINE2(name) \ - static inline void __##name(struct tcb *, sys_arg_t, \ - sys_arg_t); \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e) \ - { \ - UNUSED(c); \ - UNUSED(d); \ - UNUSED(e); \ - __##name(t, a, b); \ - } \ - static inline void __##name - -/** - * Helper macro for defining syscall with three arguments. - * - * @param name Name of syscall. - */ -#define SYSCALL_DEFINE3(name) \ - static inline void __##name(struct tcb *, sys_arg_t, \ - sys_arg_t, \ - sys_arg_t); \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e) \ - { \ - UNUSED(d); \ - UNUSED(e); \ - __##name(t, a, b, c); \ - } \ - static inline void __##name - -/** - * Helper macro for defining syscall with four arguments. - * - * @param name Name of syscall. - */ -#define SYSCALL_DEFINE4(name) \ - static inline void __##name(struct tcb *, sys_arg_t, \ - sys_arg_t, sys_arg_t, \ - sys_arg_t); \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e) \ - { \ - UNUSED(e); \ - __##name(t, a, b, c, d); \ - } \ - static inline void __##name - -/** - * Helper macro for defining syscall with five arguments. - * - * @param name Name of syscall. - */ -#define SYSCALL_DEFINE5(name) \ - static inline void __##name(struct tcb *, sys_arg_t, \ - sys_arg_t, sys_arg_t, \ - sys_arg_t, sys_arg_t); \ - void sys_##name(struct tcb *t, sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d, sys_arg_t e) \ - { \ - __##name(t, a, b, c, d, e); \ - } \ - static void __##name - -/** @name Misc syscalls. */ -/** @{ */ - -/** - * Noop syscall. - * - * @param t Current tcb. - * @param a Unused. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and 0. - */ -SYSCALL_DECLARE0(noop); - -/** - * Putch syscall. - * - * @param t Current tcb. - * @param ch Character to put. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and 0. - */ -SYSCALL_DECLARE1(putch, ch); - -/** @} */ - -/* @name Memory handling syscalls. */ -/** @{ */ -/** - * Request memory syscall. - * - * Allocates at least the specified size of allocation to current effective - * process. - * - * @param t Current tcb. - * @param size Size of allocation. - * @param flags Flags of allocation. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and start of memory allocation. - */ -SYSCALL_DECLARE2(req_mem, size, flags); - -/** - * Request one page of memory. The nearest fitting size is chosen. - * - * This might be better implemented as some number of adjacent physical pages, - * but the underlying physical page allocator doesn't really handle it very - * well. This weird design decision is because I don't know if there are devices - * whose drivers need multiple adjacent physical pages, only that at least - * virtio devices need to be able to access the physical address of a single - * page. Basic adjacent physical pages can be made from higher order pages, - * just with a massive overhead. Still, probably good eough for now. - * - * For example, if you need two adjacent 4K pages, you pass size = 8K and you - * get back a 2M page, if one is available. - * - * @param t Current tcb. - * @param size Required size of region. - * @param flags Mapping flags to use. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref ERR_OOMEM if no page is available, otherwise \c OK, virtual - * address, actual size, physical size in that order. - */ -SYSCALL_DECLARE2(req_page, size, flags); - -/** - * Request physical memory syscall. - * - * Allocates at least the specified size of allocation which includes the - * physical start address somewhere in the allocation to the current effective - * process. - * - * @param t Current tcb. - * @param paddr Start of physical allocation. - * @param size Size of physical allocation. - * @param flags Flags of physical allocation. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and start of memory allocation. - */ -SYSCALL_DECLARE3(req_pmem, paddr, size, flags); - -/** - * Request fixed memory syscall. - * - * Allocates at least the specified size of allocation which includes the start - * address of allocation to the current effective process. - * - * @param t Current tcb. - * @param start Start of allocation. - * @param size Size of allocation. - * @param flags Flags of allocation. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and start of memory allocation. - */ -SYSCALL_DECLARE3(req_fixmem, start, size, flags); - -/** - * Request shared memory syscall. - * - * Allocates a region that can be shared between different processes, that is at - * least the specified size of allocation. When clients are freeing memory, the - * underlying physical allocation will not be freed unless the owning reference - * (server) frees it. - * - * @param t Current tcb. - * @param tid Thread to share memory with. - * @param size Size of allocation. - * @param sflags Flags of allocation for server, that is \p t. - * @param cflags Flags of allocation for client, that is \p tid. - * @param e Unused. - * - * Returns \ref OK and start of memory allocation. - */ -SYSCALL_DECLARE4(req_sharedmem, tid, size, sflags, cflags); - -/** - * Free memory syscall. - * - * Frees the memory region pointed to. - * - * @param t Current tcb. - * @param start Start of memory. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and 0. - */ -SYSCALL_DECLARE1(free_mem, start); -/** @} */ - -/** @name Timer syscalls. */ -/** @{ */ -/** - * Get timer accuracy in Hertz syscall. - * - * @param t Current tcb. - * @param a Unused. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and frequency. - * \todo Should this be some kind of config request instead of a separate - * syscall? - */ -SYSCALL_DECLARE0(timebase); - -/** - * Get current ticks. - * - * @param t Current tcb. - * @param a Unused. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns current ticks. - */ -SYSCALL_DECLARE0(ticks); - -/** - * Request relative timer syscall. - * - * Request timer that triggers a number of ticks in the future. - * - * @param t Current tcb. - * @param ticks Number of ticks from now. - * @param mult Number of times to trigger. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and ID of timer. - */ -SYSCALL_DECLARE2(req_rel_timer, ticks, mult); - -/** - * Request absolute timer syscall. - * - * Request timer that triggers at some absolute timepoint. - * - * @param t Current tcb. - * @param ticks Timepoint. - * @param mult Multiplier. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and ID of timer. - * \todo Check repeat value. - */ -SYSCALL_DECLARE2(req_abs_timer, ticks, mult); - -/** - * Free timer syscall. - * - * @param t Current tcb. - * @param cid ID of timer to free. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK. - */ -SYSCALL_DECLARE1(free_timer, cid); -/** @} */ - -/** @name IPC syscalls. */ -/** @{ */ -/** - * Report process status as server syscall. - * - * @param t Current tcb. - * @param callback Callback to request handler. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK. - */ -SYSCALL_DECLARE1(ipc_server, callback); - -/** - * Request syscall. - * - * @param t Current tcb. - * @param pid Request target process. - * @param d0 First request argument. - * @param d1 Second request argument. - * @param d2 Third forwarding argument. - * @param d3 Fourth forwarding argument. - * - * Returns \ref OK and whatever the server sends back on success, otherwise some - * other status value. - */ -SYSCALL_DECLARE5(ipc_req, pid, d0, d1, d2, d3); - -/** - * Forwarding syscall. - * - * In a server request handler, do a request to some other server on behalf of - * whoever called us up. - * - * @param t Current tcb. - * @param pid Forwarding target process. - * @param d0 First forwarding argument. - * @param d1 Second forwarding argument. - * @param d2 Third forwarding argument. - * @param d3 Fourth forwarding argument. - * - * Returns \ref OK and whatever the server sends back on success, otherwise some - * other status value. - */ -SYSCALL_DECLARE5(ipc_fwd, pid, d0, d1, d2, d3); - -/** - * Response syscall. - * - * @param t Current tcb. - * @param d0 First response argument. - * @param d1 Second response argument. - * @param d2 Third response argument. - * @param d3 Fourth response argument. - * @param e Unused. - * - * Returns \c d0 and \c d1. - */ -SYSCALL_DECLARE4(ipc_resp, d0, d1, d2, d3); - -/** - * Notify thread syscall. - * - * @param t Current tcb. - * @param tid Thread ID to notify. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and 0. - */ -SYSCALL_DECLARE1(ipc_notify, tid); -/** @} */ - -/** @name Process handling syscalls. */ -/** @{ */ -/** - * Create thread syscall. - * - * Creates thread in current effective process context. - * - * @param t Current tcb. - * @param func Function to call on startup. - * @param d0 Argument 0. - * @param d1 Argument 1. - * @param d2 Argument 2. - * @param d3 Argument 3. - * - * Returns \ref OK and 0. - * \todo Should this take stack size etc? - */ -SYSCALL_DECLARE5(create, func, d0, d1, d2, d3); - -/** - * Fork process syscall. - * - * Forks a process, much like in *nix systems. - * - * @param t Current tcb. - * @param a Unused. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and 0. - */ -SYSCALL_DECLARE0(fork); - -/** - * Execute binary syscall. - * - * Executes a new binary in existing process space. - * - * @param t Current tcb. - * @param bin Address of binary. - * @param interp Optional address of interpreter. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and 0. - * \todo Check other return codes. - */ -SYSCALL_DECLARE2(exec, bin, interp); - -/** - * Spawn binary syscall. Try to prefer over unixy fork/exec. - * - * Executes a new binary in new process space. - * - * @param t Current tcb. - * @param bin Address of binary. - * @param interp Optional address of interpreter. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Retuns \ref OK and 0. - * \todo Check other return codes. - */ -SYSCALL_DECLARE2(spawn, bin, interp); - -/** - * Kill syscall. - * - * @param t Current tcb. - * @param tid Thread ID to kill. 0 if self. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK if not called on itself, otherwise doesn't return. - */ -SYSCALL_DECLARE1(kill, tid); - -/** - * Swap syscall. - * - * Swap currently running thread. - * - * @param t Current tcb. - * @param tid Thread to swap to. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and 0. - */ -SYSCALL_DECLARE1(swap, tid); - -/** @} */ - -/** @name Configuration syscalls. */ -/** @{ */ -/** - * Set configuration syscall. - * - * Set some runtime parameter. - * - * @param t Current tcb. - * @param param Parameter to set. - * @param val Value to set parameter to. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK and 0. - */ -SYSCALL_DECLARE2(conf_set, param, val); - -/** - * Get configuration syscall. - * - * Get some runtime parameter. - * - * @param t Current tcb. - * @param param Parameter to get. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK. - */ -SYSCALL_DECLARE1(conf_get, param); - -/** - * Set capabilities. - * - * @param t Current tcb. - * @param tid Thread ID whose capabilities to set. - * @param off Offset of capability, multiple of \c bits(cap). - * @param caps Mask of capabilities to set. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK on success, \ref ERR_INVAL on invalid input. - */ -SYSCALL_DECLARE3(set_cap, tid, off, caps); - -/** - * Get capabilities. - * - * @param t Current tcb. - * @param tid Thread ID whose capabilities to get. - * @param off Offset of capability, multiple of \c bits(cap). - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK, capabilities. - */ -SYSCALL_DECLARE2(get_cap, tid, off); - -/** - * Clear capabilities. - * - * @param t Current tcb. - * @param tid Thread ID whose capabilities to clear. - * @param off Offset of capability, multiple of \c bits(cap). - * @param cap Mask of capabilities to clear. - * @param d Unused. - * @param e Unused. - * - * Returns \ref OK. - */ -SYSCALL_DECLARE3(clear_cap, tid, off, cap); - -/** - * Power off syscall. - * - * Either shut down or reboot system. - * - * @param t Current tcb. - * @param type Type of shutdown. \see poweroff_type. - * @param b Unused. - * @param c Unused. - * @param d Unused. - * @param e Unused. - * - * Shouldn't return at all. - */ -SYSCALL_DECLARE1(poweroff, type); -/** @} */ - -/** - * Dispatch to correct syscall handler. - * - * @param syscall Syscall number. - * @param a Syscall argument 0. - * @param b Syscall argument 1. - * @param c Syscall argument 2. - * @param d Syscall argument 3. - * @param e Syscall argument 4. - * @param t Current tcb. - * Returns whatever the specified syscall returns. - */ -void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, - sys_arg_t c, sys_arg_t d, sys_arg_t e, struct tcb *t); - -/** \todo Should I add variable names as well, to make the documentation a bit - * more readable? */ - -#include -#define return_args(t, x) {set_args((t), (x)); return;} - -#endif /* APOS_UAPI_H */ diff --git a/include/apos/unaligned.h b/include/apos/unaligned.h deleted file mode 100644 index 316a5d4..0000000 --- a/include/apos/unaligned.h +++ /dev/null @@ -1,255 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_UNALIGNED_H -#define APOS_UNALIGNED_H - -/** - * @file unaligned.h - * Helpers for unaligned memory accesses. Largely lifted from Linux. - */ - -#include -#include - -/** - * Get unaligned value. Type of value is deduced from pointer type. - * - * @param ptr Pointer to possibly unaligned value to read. - * @return Value pointed to by \c ptr. - */ -#define get_unaligned(ptr) \ - _Generic(*(ptr), \ - uint8_t: get_unaligned_uint8_t, \ - uint16_t: get_unaligned_uint16_t, \ - uint32_t: get_unaligned_uint32_t, \ - uint64_t: get_unaligned_uint64_t, \ - \ - int8_t: get_unaligned_int8_t, \ - int16_t: get_unaligned_int16_t, \ - int32_t: get_unaligned_int32_t, \ - int64_t: get_unaligned_int64_t)((void *)ptr) - -/** - * Put unaligned value. Type of value is deduced from pointer type. - * - * @param val Value to write to memory. - * @param ptr Pointer to possibly unaligned address. - */ -#define put_unaligned(val, ptr) \ - _Generic(*(ptr), \ - uint8_t: put_unaligned_uint8_t, \ - uint16_t: put_unaligned_uint16_t, \ - uint32_t: put_unaligned_uint32_t, \ - uint64_t: put_unaligned_uint64_t, \ - \ - int8_t: put_unaligned_int8_t, \ - int16_t: put_unaligned_int16_t, \ - int32_t: put_unaligned_int32_t, \ - int64_t: put_unaligned_int64_t)(val, (void *)ptr) - -/** - * Helper macro for defining an unaligned value reader. - * - * @param type Type of value reader to define. - */ -#define DEFINE_GET(type) \ - static inline type get_unaligned_##type(void *ptr) \ - { \ - const struct __packed { \ - type x; \ - } *__pptr = ptr; \ - return __pptr->x; \ - } - -/** - * Read possibly unaligned \ref uint8_t. - * - * Technically speaking a byte can't be unaligned, but this is just here for - * cohesion. - * - * @warning Prefer using \ref get_unaligned(). - * - * @param ptr Pointer to \ref uint8_t to read. - * @return Value pointed to by \c ptr. - */ -DEFINE_GET(uint8_t); - -/** - * Read possibly unaligned \ref uint16_t. - * - * @warning Prefer using \ref get_unaligned(). - * - * @param ptr Pointer to \ref uint16_t to read. - * @return Value pointed to by \c ptr. - */ -DEFINE_GET(uint16_t); - -/** - * Read possibly unaligned \ref uint32_t. - * - * @warning Prefer using \ref get_unaligned(). - * - * @param ptr Pointer to \ref uint32_t to read. - * @return Value pointed to by \c ptr. - */ -DEFINE_GET(uint32_t); - -/** - * Read possibly unaligned \ref uint64_t. - * - * @warning Prefer using \ref get_unaligned(). - * - * @param ptr Pointer to \ref uint64_t to read. - * @return Value pointed to by \c ptr. - */ -DEFINE_GET(uint64_t); - -/** - * Read possibly unaligned \ref int8_t. - * - * Technically speaking a byte can't be unaligned, but this is just here for - * cohesion. - * - * @warning Prefer using \ref get_unaligned(). - * - * @param ptr Pointer to \ref int8_t to read. - * @return Value pointed to by \c ptr. - */ -DEFINE_GET(int8_t); - -/** - * Read possibly unaligned \ref int16_t. - * - * @warning Prefer using \ref get_unaligned(). - * - * @param ptr Pointer to \ref int16_t to read. - * @return Value pointed to by \c ptr. - */ -DEFINE_GET(int16_t); - -/** - * Read possibly unaligned \ref int32_t. - * - * @warning Prefer using \ref get_unaligned(). - * - * @param ptr Pointer to \ref int32_t to read. - * @return Value pointed to by \c ptr. - */ -DEFINE_GET(int32_t); - -/** - * Read possibly unaligned \ref int64_t. - * - * @warning Prefer using \ref get_unaligned(). - * - * @param ptr Pointer to \ref int64_t to read. - * @return Value pointed to by \c ptr. - */ -DEFINE_GET(int64_t); - -#undef DEFINE_GET - -/** - * Helper macro for defining an unaligned writer. - * - * @param type Type of value to write. - */ -#define DEFINE_PUT(type) \ - static inline void put_unaligned_##type(type val, void *ptr) \ - { \ - struct __packed { \ - type x; \ - } *__pptr = ptr; \ - __pptr->x = val; \ - } - -/** - * Write possibly unaligned \ref uint8_t. - * - * Technically speaking a byte can't be unaligned, but this is just here for - * cohesion. - * - * @warning Prefer using \ref put_unaligned(). - * - * @param val Value to write. - * @param ptr Address to write to. - */ -DEFINE_PUT(uint8_t); - -/** - * Write possibly unaligned \ref uint16_t. - * - * @warning Prefer using \ref put_unaligned(). - * - * @param val Value to write. - * @param ptr Address to write to. - */ -DEFINE_PUT(uint16_t); - -/** - * Write possibly unaligned \ref uint32_t. - * - * @warning Prefer using \ref put_unaligned(). - * - * @param val Value to write. - * @param ptr Address to write to. - */ -DEFINE_PUT(uint32_t); - -/** - * Write possibly unaligned \ref uint64_t. - * - * @warning Prefer using \ref put_unaligned(). - * - * @param val Value to write. - * @param ptr Address to write to. - */ -DEFINE_PUT(uint64_t); - -/** - * Write possibly unaligned \ref int8_t. - * - * Technically speaking a byte can't be unaligned, but this is just here for - * cohesion. - * - * @warning Prefer using \ref put_unaligned(). - * - * @param val Value to write. - * @param ptr Address to write to. - */ -DEFINE_PUT(int8_t); - -/** - * Write possibly unaligned \ref int16_t. - * - * @warning Prefer using \ref put_unaligned(). - * - * @param val Value to write. - * @param ptr Address to write to. - */ -DEFINE_PUT(int16_t); - -/** - * Write possibly unaligned \ref int32_t. - * - * @warning Prefer using \ref put_unaligned(). - * - * @param val Value to write. - * @param ptr Address to write to. - */ -DEFINE_PUT(int32_t); - -/** - * Write possibly unaligned \ref int64_t. - * - * @warning Prefer using \ref put_unaligned(). - * - * @param val Value to write. - * @param ptr Address to write to. - */ -DEFINE_PUT(int64_t); - -#undef DEFINE_PUT - -#endif /* APOS_UNALIGNED_H */ diff --git a/include/apos/utils.h b/include/apos/utils.h deleted file mode 100644 index 378f3a0..0000000 --- a/include/apos/utils.h +++ /dev/null @@ -1,671 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_UTILS_H -#define APOS_UTILS_H - -/** - * @file utils.h - * Misc utils and helpers. - */ - -/** - * Get absolute value of expression. - * - * @param a Value to take the absolute value of. - * @return \c a if \c a >= 0, \c -a otherwise. - * \sideeffects - */ -#define ABS(a) (a < 0 ? -a : a) - -/** - * Get the larger of two values. - * - * @param a First value. - * @param b Second value. - * @return \c a if \code a >= b \endcode, \c b otherwise. - * \sideeffects - */ -#define MAX(a, b) ((a) >= (b) ? (a) : (b)) - -/** - * Get the largest of three values. - * - * @param a First value. - * @param b Second value. - * @param c Third value. - * @return Largest of the three values. - * \sideeffects - */ -#define MAX3(a, b, c) (MAX(a, b) >= MAX(b, c) ? MAX(a, b) : MAX(b, c)) - -/** - * Get the largest of four values. - * - * @param a First value. - * @param b Second value. - * @param c Third value. - * @param d Fourth value. - * @return Largest of the four values. - * \sideeffects - */ -#define MAX4(a, b, c, d) \ - (MAX3(a, b, c) >= MAX3(b, c, d) ? MAX3(a, b, c) : MAX3(b, c, d)) -/* etc... */ - -/** - * Get the smaller of two values. - * - * @param a First value. - * @param b Second value. - * @return The larger of the two values. - * \sideeffects - */ -#define MIN(a, b) ((a) <= (b) ? (a) : (b)) - -/** - * Get the smallest of three values. - * - * @param a First value. - * @param b Second value. - * @param c Third value. - * @return The largest of the three values. - * \sideeffects - */ -#define MIN3(a, b, c) (MIN(a, b) <= MIN(b, c) ? MIN(a, b) : MIN(b, c)) - -/** - * Get the largest of four values. - * - * @param a First value. - * @param b Second value. - * @param c Third value. - * @param d Fourth value. - * @return The largest of the three values. - * \sideeffects - */ -#define MIN4(a, b, c, d) \ - (MIN3(a, b, c) <= MIN3(b, c, d) ? MIN3(a, b, c) : MIN3(b, c, d)) -/* etc... */ - -/** - * Helper for \ref GLUE(). - * Makes sure any macros are expanded all the way. - * - * @param x Head part of the string. - * @param y Tail part of the string. - * \see GLUE(). - */ -#define GLUE2(x, y) x##y - -/** - * Glue two strings together. - * - * @param x Head part of the string. - * @param y Tail part of the string. - */ -#define GLUE(x, y) GLUE2(x, y) - -/** - * Helper for \ref QUOTE(). - * Makes sure any macros are expanded all the way. - * - * @param x String to be quoted. - * \see QUOTE(). - */ -#define QUOTE2(x) #x - -/** - * Quote string. - * - * @param x String to be quoted. - */ -#define QUOTE(x) QUOTE2(x) - -/** - * Silence warnings about unused parameters. - * - * @param x Parameter that is unused. - */ -#define UNUSED(x) ((void)(x)) - -/** - * Semantic wrapper around \ref UNUSED(). - * If something might be unused, depending on the configuration, it's more - * accurate to say that it might be unused rather than stating that it is - * unused. - * - * @param x Symbol that might be unused. - */ -#define MAYBE_UNUSED(x) UNUSED(x) - -#include - -/** - * Get offset of member inside structure. - * - * @param type Structure to look in. - * @param member Member whose offset to get. - * @return Offset of \c member in \c type. - */ -#if __has_builtin(__builtin_offsetof) -#define offsetof(type, member) __builtin_offsetof(type, member) -#else -#define offsetof(type, member) ((uintptr_t) &((type *)0)->member) -#endif - -/** - * Signal to the compiler that some expression is likely to be true. - * Might aid in optimisation and branch prediction manipulation. - * - * @param x Expression that is likely to be true. - * @return Value of \c x. - * - * Example: - * \code if (likely(x)) { ... } \endcode - * - * \see unlikely() - */ -#if __has_builtin(__builtin_expect) -#define likely(x) __builtin_expect(!!(x), 1) -#else -#define likely(x) (x) -#endif - -/** - * Signal to the compiler that some expression is unlikely to be true. - * - * @param x Expression that is unlikely to be true. - * @return Value of \c x. - * - * \see likely(). - */ -#if __has_builtin(__builtin_expect) -#define unlikely(x) __builtin_expect(!!(x), 0) -#else -#define unlikely(x) (x) -#endif - -/** - * Signal to the compiler that some region is unreachable. - * Mainly used for debugging with instrumentation, though it could provide some - * micro-optimisations. - */ -#if __has_builtin(__builtin_unreachable) -#define unreachable() __builtin_unreachable() -#else -#define unreachable() -#endif - -/** - * Get container of some member. - * - * @param ptr Pointer to member in some structure. - * @param type Structure member is part of. - * @param member Member pointer is pointing to. - * @return Pointer to structure itself instead of member. - */ -#define container_of(ptr, type, member) \ - ((type *)((char *)(ptr)-offsetof(type, member))) - -/** - * Get array size in number of elements. - * - * @param x Array whose size should be calculated. - * @return Number of elements in array. - */ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -/** - * Check if value is aligned to some other value. - * - * @param x Value whose alignment to check. - * @param a Value to check alignment to. - * @return \ref true if \c x is aligned, \ref false otherwise. - */ -#define ALIGNED(x, a) ((x) % a == 0) - -/** - * Add value to pointer in bytes instead of elements. - * - * @param x Pointer to add value to. - * @param y Value to add to pointer. - * @return \c x with \c y added to it. - */ -#define ptradd(x, y) (((vm_t)(x)) + ((vm_t)(y))) - -#include - -/* clang-format doesn't like _Generic, but I guess that's fine. - * Uncrustify just ignores it, as far as I can tell. */ -/** - * Align value upwards. - * Type is deduced from \c x. - * - * @param x Value to align up. - * @param y Value to align to. - * @return \c x aligned to \c y. - */ -#define align_up(x, y) \ - _Generic((x), signed char \ - : align_up_c, signed short \ - : align_up_s, signed int \ - : align_up_i, signed long \ - : align_up_l, signed long long \ - : align_up_ll, \ - \ - unsigned char \ - : align_up_uc, unsigned short \ - : align_up_us, unsigned int \ - : align_up_ui, unsigned long \ - : align_up_ul, unsigned long long \ - : align_up_ull)((x), (y)) - -/** - * Helper macro for defining type specific aligning. - * - * @param name Name of type in function name. - * @param type Actual type. - */ -#define DEFINE_ALIGN_UP(name, type) \ - static inline type align_up_##name(type val, type a) \ - { \ - if (!a) { \ - return val; \ - } \ - \ - type rem = val % a; \ - \ - if (rem == 0) { \ - return val; \ - } \ - \ - return val + a - rem; \ - } - -/** - * Align signed char up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(c, signed char); - -/** - * Align signed short up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(s, signed short); - -/** - * Align signed int up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(i, signed int); - -/** - * Align signed long up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(l, signed long); - -/** - * Align signed long long up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(ll, signed long long); - -/** - * Align unsigned char up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(uc, unsigned char); - -/** - * Align unsigned short up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(us, unsigned short); - -/** - * Align unsigned int up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(ui, unsigned int); - -/** - * Align unsigned long up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(ul, unsigned long); - -/** - * Align unsigned long long up. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned up to nearest multiple of \c a. - */ -DEFINE_ALIGN_UP(ull, unsigned long long); - -/** - * Align value downwards. - * Type is deduced from \c x. - * - * @param x Value to align. - * @param y Value to align to. - * @return \c x aligned to down \c y. - */ -#define align_down(x, y) \ - _Generic((x), signed char \ - : align_down_c, signed short \ - : align_down_s, signed int \ - : align_down_i, signed long \ - : align_down_l, signed long long \ - : align_down_ll, \ - \ - unsigned char \ - : align_down_uc, unsigned short \ - : align_down_us, unsigned int \ - : align_down_ui, unsigned long \ - : align_down_ul, unsigned long long \ - : align_down_ull)((x), (y)) - -/** - * Helper macro for defining type specific aligning. - * - * @param name Name of type in function name. - * @param type Actual type. - */ -#define DEFINE_ALIGN_DOWN(name, type) \ - static inline type align_down_##name(type val, type a) \ - { \ - if (!a) { \ - return val; \ - } \ - \ - return val - (val % a); \ - } - -/** - * Align signed char down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(c, signed char); - -/** - * Align signed short down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(s, signed short); - -/** - * Align signed int down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(i, signed int); - -/** - * Align signed long down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(l, signed long); - -/** - * Align signed long long down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(ll, signed long long); - -/** - * Align unsigned char down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(uc, unsigned char); - -/** - * Align unsigned short down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(us, unsigned short); - -/** - * Align unsigned int down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(ui, unsigned int); - -/** - * Align unsigned long down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(ul, unsigned long); - -/** - * Align unsigned long long down. - * - * @param val Value to align. - * @param a Value to align to. - * @return \c val aligned down to nearest multiple of \c a. - */ -DEFINE_ALIGN_DOWN(ull, unsigned long long); - -/** - * Check if value is aligned. - * - * @param x Value to check. - * @param y Alignment to check to. - * @return \ref true if \c x is aligned to \c y, \ref false otherwise. - */ -#define is_aligned(x, y) \ - _Generic((x), signed char \ - : is_aligned_c, signed short \ - : is_aligned_s, signed int \ - : is_aligned_i, signed long \ - : is_aligned_l, signed long long \ - : is_aligned_ll, \ - \ - unsigned char \ - : is_aligned_uc, unsigned short \ - : is_aligned_us, unsigned int \ - : is_aligned_ui, unsigned long \ - : is_aligned_ul, unsigned long long \ - : is_aligned_ll)((x), (y)) - -/** - * Helper macro for defining type specific alignment checks. - * - * @param name Name of type in function name. - * @param type Actual type. - */ -#define DEFINE_ALIGNED(name, type) \ - static inline bool is_aligned_##name(type val, type a) \ - { \ - if (!a) { \ - return true; \ - } \ - \ - return val % a == 0; \ - } - -/** - * Check if signed char is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(c, signed char); - -/** - * Check if signed short is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(s, signed short); - -/** - * Check if signed int is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(i, signed int); - -/** - * Check if signed long is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(l, signed long); - -/** - * Check if signed long long is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(ll, signed long long); - -/** - * Check if unsigned char is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(uc, unsigned char); - -/** - * Check if unsigned short is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(us, unsigned short); - -/** - * Check if unsigned int is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(ui, unsigned int); - -/** - * Check if unsigned long is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(ul, unsigned long); - -/** - * Check if unsigned long long is aligned. - * - * @param val Value to check. - * @param a Alignment to check to. - * @return \ref true if \c val is aligned to \c a, \ref false otherwise. - */ -DEFINE_ALIGNED(ull, unsigned long long); - -/** - * Get numeric value of ASCII character. - * - * @param c Character representing a number. - * @return Corresponding number. -1 if parsing failed. - */ -static inline int asciinum(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - else if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - else if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - else - return -1; -} - -/** - * Convert string representing number to actual number. - * - * @param c String representing number. - * @param len Length of \c str. - * @param base Base of number. - * @return Corresponding number. - */ -static inline uintmax_t convnum(const char *c, size_t len, size_t base) -{ - size_t multiplier = 1; - size_t sum = 0; - for (size_t i = 0; i < len; ++i) { - sum += asciinum(c[len - 1 - i]) * multiplier; - multiplier *= base; - } - - return sum; -} - -#endif /* APOS_UTILS_H */ diff --git a/include/apos/vmem.h b/include/apos/vmem.h deleted file mode 100644 index 5cbe7db..0000000 --- a/include/apos/vmem.h +++ /dev/null @@ -1,287 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ - -#ifndef APOS_VMEM_H -#define APOS_VMEM_H - -/** - * @file vmem.h - * Virtual memory handling. - */ - -#include -#include -#include -#include - -/** - * Allocate user virtual memory. - * - * Virtual memory start address is chosen according to best fit with regard to - * size. - * - * @param r Process to allocate memory in. - * @param size Minimum size of allocation. - * @param flags Flags of allocation. - * @return Start of allocation when succesful, \c NULL otherwise. - */ -vm_t alloc_uvmem(struct tcb *r, size_t size, vmflags_t flags); - -/** - * Allocate one physical page for user virtual memory. - * - * @param r Process to allocate memory in. - * @param size Minimum size of allocation. - * @param flags Flags of allocation. - * @param asize Where to write actual size of allocation. - * @param paddr Where to write physical address of page. - * @return Start of allocation when succesful, \c NULL otherwise. - */ -vm_t alloc_uvpage(struct tcb *r, size_t size, vmflags_t flags, - size_t *asize, pm_t *paddr); - -/** - * Allocate fixed user virtual memory. - * - * Virtual memory start address is chosen so that \c start is within the - * allocation and the allocation after \c start is at least \c size bytes large. - * It is unspecified how many bytes are between the start of the allocation and - * \c start. - * - * @param r Process to allocate memory in. - * @param start Address that should be in allocation. - * @param size Minimum size of allocation. - * @param flags Flags of allocation. - * @return Start of allocation when succesful, \c NULL otherwise. - */ -vm_t alloc_fixed_uvmem(struct tcb *r, vm_t start, size_t size, vmflags_t flags); - -/** - * Allocate shared user virtual memory. - * - * @param s First process to allocate memory in. - * @param c Second process to allocate memory in. - * @param size Minimum size of allocation. - * @param sflags Flags of allocation for \p s. - * @param cflags Flags of allocation for \p c. - * @param sstart Start of allocation for \p s. - * @param cstart Start of allocation for \p c. - * @return Status of allocation. - */ -stat_t alloc_shared_uvmem(struct tcb *s, struct tcb *c, size_t size, - vmflags_t sflags, vmflags_t cflags, - vm_t *sstart, vm_t *cstart); - -/** - * Reference shared user virtual memory. - * - * Only callable by clients. - * - * @param r1 Process in which shared memory resides. - * @param r2 Process to reference shared memory in. - * @param va Virtual address of shared memory in \c r1. - * @param flags Flags of reference in \c r2. - * @return Start of reference in \c r2 when succesful, \c NULL otherwise. - */ -vm_t ref_shared_uvmem(struct tcb *r1, struct tcb *r2, vm_t va, vmflags_t flags); - -/** - * Free all user virtual memory allocations not marked with \ref MR_KEEP. - * - * @param r Process in which to clear user virtual memory. - * @return \ref OK. - */ -stat_t clear_uvmem(struct tcb *r); - -/** - * Free all user virtual memory allocations, even if marked with \ref MR_KEEP. - * - * @param r Process in which to clear user virtual memory. - * @return \ref OK. - */ -stat_t purge_uvmem(struct tcb *r); - -/** - * Free one user virtual memory allocation. - * - * @param r Process in which to clear user virtual memory. - * @param va Start of user virtual memory allocation to free. - * @return \ref OK. - */ -stat_t free_uvmem(struct tcb *r, vm_t va); - -/** - * Initialize user virtual memory instance. - * - * This assumes the user virtual memory is contiguous, with no holes between \c - * base and \c top. - * - * @param r Process in which to initialize user virtual memory. - * @param base Start of user virtual memory. - * @param top Top of user virtual memory. - * @return \see init_region(). - */ -stat_t init_uvmem(struct tcb *r, vm_t base, vm_t top); - -/** - * Destroy user virtual memory instance. - * - * @param r Process in which to destroy user virtual memory. - * @return \see destroy_region(). - */ -stat_t destroy_uvmem(struct tcb *r); - -/** - * Clone process memory. - * - * @param d Destination tcb. - * @param s Source tcb. - * @return OK. - * - * @todo Come up with better name. clone_uvmem() is taken, but should it be - * renamed to clone_mapping() or something? - */ -stat_t clone_mem_regions(struct tcb *d, struct tcb *s); - -/** - * User virtual memory worker callback for \ref map_fill_region(). - * - * \c data is a pointer to \ref stat_t, which is set to \ref INFO_SEFF if all - * threads in process should sync their memory mappings. This occurs when the - * top level page table is modified. - * - * @param b Virtual memory to work in. - * @param offset Hint for \ref alloc_page(). - * @param vaddr Current virtual address. - * @param flags Flags of region. - * @param order Suggested page order. - * @param data Pointer to \ref stat_t. - * @return \c OK when suggested order if acceptable, \c INFO_TRGN if suggested - * order not acceptable. Error otherwise. - * again - */ -stat_t alloc_uvmem_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order order, void *data); - -/** - * Shared user virtual memory worker callback for \ref map_fill_region(). - * - * @param b Virtual memory to work in. - * @param offset Hint for \ref alloc_page(). - * @param vaddr Current virtual address. - * @param flags Flags of region. - * @param order Suggested page order. - * @param data Pointer to \ref stat_t. - * @return \see alloc_uvmem_wrapper(). - * - * \see alloc_uvmem_wrapper(). - */ -stat_t alloc_shared_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order order, void *data); - -/** - * User virtual memory copying worker callback for \ref map_fill_region(). - * - * Currently unused, but intention is to set up copy of some other virtual - * memory region, likely passed through \c data? - * - * @param b Virtual memory to work in. - * @param offset Hint for \ref alloc_page(). - * @param vaddr Current virtual address. - * @param flags Flags of region. - * @param order Suggested page order. - * @param data Pointer to \ref vmem to clone from. - * @return \see alloc_uvmem_wrapper(). - * - * \see alloc_uvmem_wraper(). - * \todo Implement. - */ -stat_t copy_allocd_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order order, void *data); - -/** - * User virtual memory freeing worker callback for \ref map_fill_region(). - * - * @param b Virtual memory to work in. - * @param offset Hint for \ref alloc_page(). - * @param vaddr Current virtual address. - * @param flags Flags of region. - * @param order Suggested page order. - * @param data Pointer to \ref stat_t. - * @return \see alloc_uvmem_wrapper(). - * - * \see alloc_uvmem_wrapper(). - */ -stat_t free_uvmem_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order order, void *data); - -/** - * Convenience wrapper for \ref map_fill_region() when mapping an allocated - * region. - * - * @param b Virtual memory to work in. - * @param start Start of virtual memory region to map. - * @param bytes Size of virtual memory region. - * @param flags Flags of virtual memory region. - * @param data Pointer to \c stat_t. - * @return \see map_fill_region(). - */ -#define map_allocd_region(b, start, bytes, flags, data) \ - map_fill_region(b, &alloc_uvmem_wrapper, 0, start, bytes, flags, data) - -/** - * Convenience wrapper for \ref map_fill_region() when mapping a shared region. - * - * @param b Virtual memory to work in. - * @param start Start of virtual memory region to map. - * @param bytes Size of virtual memory region. - * @param flags Flags of virtual memory region. - * @param data Pointer to \c stat_t. - * @return \see map_fill_region(). - */ -#define map_shared_region(b, start, bytes, flags, data) \ - map_fill_region(b, &alloc_shared_wrapper, 0, start, bytes, flags, data) - -/** - * Convenience wrapper for \ref map_fill_region() when copying a region. - * - * @param b Virtual memory to work in. - * @param start Start of virtual memory region to map. - * @param bytes Size of virtual memory region. - * @param flags Flags of virtual memory region. - * @param data Pointer to \c vmem to clone. - * @return \see map_fill_region(). - */ -#define copy_allocd_region(b, start, bytes, flags, data) \ - map_fill_region(b, ©_allocd_wrapper, 0, start, bytes, flags, data) - -/** - * Convenience wrapper for \ref map_fill_region() when freeing region. - * - * @param b Virtual memory to work in. - * @param start Start of virtual memory region to unmap. - * @param bytes Size of virtual memory region. - * @param flags Flags of virtual memory region. Technically unused? - * @param data Pointer to \c stat_t. - * @return \see map_fill_region(). - */ -#define unmap_freed_region(b, start, bytes, flags, data) \ - map_fill_region(b, &free_uvmem_wrapper, 0, start, bytes, flags, data) - -/** - * Extract virtual memory flags (MR_XXX). - * - * @param x Flags to extract virtual memory region flags from. - * @return Virtual memory region flags. - */ -#define vm_flags(x) ((x) & ~0xff) - -/** - * Extract physical memory page flags (VM_XXX). - * - * @param x Flags to extract physical memory page flags from. - * @return Physical memory page flags. - */ -#define vp_flags(x) ((x) & 0xff) - -#endif /* APOS_VMEM_H */ -- cgit v1.3