diff options
Diffstat (limited to 'include/apos')
| -rw-r--r-- | include/apos/atomic.h | 20 | ||||
| -rw-r--r-- | include/apos/attrs.h | 54 | ||||
| -rw-r--r-- | include/apos/bits.h | 205 | ||||
| -rw-r--r-- | include/apos/builtin.h | 8 | ||||
| -rw-r--r-- | include/apos/conf.h | 14 | ||||
| -rw-r--r-- | include/apos/debug.h | 138 | ||||
| -rw-r--r-- | include/apos/dmem.h | 45 | ||||
| -rw-r--r-- | include/apos/elf.h | 554 | ||||
| -rw-r--r-- | include/apos/initrd.h | 26 | ||||
| -rw-r--r-- | include/apos/mem.h | 281 | ||||
| -rw-r--r-- | include/apos/mem_nodes.h | 25 | ||||
| -rw-r--r-- | include/apos/mem_regions.h | 19 | ||||
| -rw-r--r-- | include/apos/sizes.h | 278 | ||||
| -rw-r--r-- | include/apos/sp_tree.h | 14 | ||||
| -rw-r--r-- | include/apos/tcb.h | 2 | ||||
| -rw-r--r-- | include/apos/types.h | 182 | ||||
| -rw-r--r-- | include/apos/utils.h | 20 |
17 files changed, 1480 insertions, 405 deletions
diff --git a/include/apos/atomic.h b/include/apos/atomic.h index 006b4a6..84e0f0f 100644 --- a/include/apos/atomic.h +++ b/include/apos/atomic.h @@ -157,7 +157,7 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t; * @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) +#define atomic_init(PTR, VAL) atomic_store_explicit(PTR, VAL, __ATOMIC_RELAXED) /** * Kill dependency. @@ -166,7 +166,7 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t; * @param y Value whose dependencies should be killed. * @return \c y */ -#define kill_dependency(y) (y) +#define kill_dependency(y) (y) /** * Check if given type is lock free. @@ -182,10 +182,10 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t; #endif /** Whether \ref atomic_bool is lock free. \see CMPLR_LOCK_FREE(). */ -#define ATOMIC_BOOL_LOCK_FREE CMPLR_LOCK_FREE(BOOL) +#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) +#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) @@ -194,22 +194,22 @@ typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t; #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) +#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) +#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) +#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) +#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) +#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) +#define ATOMIC_POINTER_LOCK_FREE CMPLR_LOCK_FREE(POINTER) /** * Helper macro for creating builtin symbols. diff --git a/include/apos/attrs.h b/include/apos/attrs.h index 3825ece..9729000 100644 --- a/include/apos/attrs.h +++ b/include/apos/attrs.h @@ -6,20 +6,56 @@ * Attribute shorthands. */ -/* TODO: figure out which attributes are necessary and which are good to have */ +/** + * 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))) -#define __fmt(x, y) __attribute__((format(__printf__, x, y))) -#define __aligned(a) __attribute__((aligned(a))) -#define __noinline __attribute__((noinline)) -#define __noreturn __attribute__((noreturn)) -#define __packed __attribute__((packed)) -#define __weak __attribute__((weak)) -#define __main __section(".kernel.start") __noinline -#define __init __section(".init.start") __noinline +/** + * 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))) + +/** + * 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 index f99d5b4..69ab9b4 100644 --- a/include/apos/bits.h +++ b/include/apos/bits.h @@ -9,14 +9,92 @@ #include <apos/types.h> #include <apos/builtin.h> -#define is_set(x, y) ((x) & (y)) -#define set_bit(x, y) ((x) |= (y)) -#define clear_bit(x, y) ((x) &= ~(y)) +/** @name Arithmetic integer bit manipulation. */ +/** @{ */ -#define is_nset(x, y) (is_set((x), 1UL << (y))) -#define set_nbit(x, y) (set_bit((x), 1UL << (y))) +/** + * 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; @@ -25,6 +103,12 @@ static inline bool bitmap_is_set(void *bmap, size_t n) 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; @@ -33,6 +117,12 @@ static inline void bitmap_set(void *bmap, size_t n) 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; @@ -41,8 +131,30 @@ static inline void bitmap_clear(void *bmap, size_t n) clear_nbit(bitmap[i], r); } +/** @} */ + +/** + * 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) @@ -58,22 +170,104 @@ uint64_t __bswap64(uint64_t u); #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) @@ -89,6 +283,7 @@ uint64_t __bswap64(uint64_t u); #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 index b6ce0e0..6869361 100644 --- a/include/apos/builtin.h +++ b/include/apos/builtin.h @@ -10,6 +10,14 @@ * 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 diff --git a/include/apos/conf.h b/include/apos/conf.h index c2653cd..5b9bf10 100644 --- a/include/apos/conf.h +++ b/include/apos/conf.h @@ -9,7 +9,21 @@ #include <apos/types.h> +/** + * 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. + * \see __thread_stack_size. + * \global + * @todo This should probably also be a function instead. + */ extern size_t __call_stack_size; #endif /* APOS_CONF_H */ diff --git a/include/apos/debug.h b/include/apos/debug.h index 5935f60..6263ea2 100644 --- a/include/apos/debug.h +++ b/include/apos/debug.h @@ -18,7 +18,7 @@ /** Long integer prefix. Approximate, but probably good enough */ #if _LP64 -#define __PRI64_PREFIX "l" +#define __PRI64_PREFIX "l" #else #define __PRI64_PREFIX "ll" #endif @@ -36,19 +36,19 @@ /** @{ */ /** Decimal format specifief for \ref int8_t */ -#define PRId8 "d" +#define PRId8 "d" /** Decimal format specifier for \ref int16_t */ -#define PRId16 "d" +#define PRId16 "d" /** Decimal format specifier for \ref int32_t */ -#define PRId32 "d" +#define PRId32 "d" /** Decimal format specifier for int16_t */ -#define PRId64 __PRI64_PREFIX "d" +#define PRId64 __PRI64_PREFIX "d" /** Decimal format specifier for \ref int_least8_t. */ -#define PRIdLEAST8 "d" +#define PRIdLEAST8 "d" /** Decimal format specifier for \ref int_least16_t. */ #define PRIdLEAST16 "d" @@ -60,22 +60,22 @@ #define PRIdLEAST64 __PRI64_PREFIX "d" /** Decimal format specifier for \ref int_fast8_t. */ -#define PRIdFAST8 "d" +#define PRIdFAST8 "d" /** Decimal format specifier for \ref int_fast16_t. */ -#define PRIdFAST16 __PRIPTR_PREFIX "d" +#define PRIdFAST16 __PRIPTR_PREFIX "d" /** Decimal format specifier for \ref int_fast32_t. */ -#define PRIdFAST32 __PRIPTR_PREFIX "d" +#define PRIdFAST32 __PRIPTR_PREFIX "d" /** Decimal format specifier for \ref int_fast64_t. */ -#define PRIdFAST64 __PRI64_PREFIX "d" +#define PRIdFAST64 __PRI64_PREFIX "d" /** Decimal format specifier for \ref intmax_t. */ -#define PRIdMAX __PRI64_PREFIX "d" +#define PRIdMAX __PRI64_PREFIX "d" /** Decimal format specifier for \ref intptr_t. */ -#define PRIdPTR __PRIPTR_PREFIX "d" +#define PRIdPTR __PRIPTR_PREFIX "d" /** @} */ @@ -83,19 +83,19 @@ /** @{ */ /** Integer format specifier for \ref int8_t. */ -#define PRIi8 "i" +#define PRIi8 "i" /** Integer format specifier for \ref int16_t. */ -#define PRIi16 "i" +#define PRIi16 "i" /** Integer format specifier for \ref int32_t. */ -#define PRIi32 "i" +#define PRIi32 "i" /** Integer format specifier for \ref int64_t. */ -#define PRIi64 __PRI64_PREFIX "i" +#define PRIi64 __PRI64_PREFIX "i" /** Integer format specifier for \ref int_least8_t. */ -#define PRIiLEAST8 "i" +#define PRIiLEAST8 "i" /** Integer format specifier for \ref int_least16_t. */ #define PRIiLEAST16 "i" @@ -107,22 +107,22 @@ #define PRIiLEAST64 __PRI64_PREFIX "i" /** Integer format specifier for \ref int_fast8_t. */ -#define PRIiFAST8 "i" +#define PRIiFAST8 "i" /** Integer format specifier for \ref int_fast16_t. */ -#define PRIiFAST16 __PRIPTR_PREFIX "i" +#define PRIiFAST16 __PRIPTR_PREFIX "i" /** Integer format specifier for \ref int_fast32_t. */ -#define PRIiFAST32 __PRIPTR_PREFIX "i" +#define PRIiFAST32 __PRIPTR_PREFIX "i" /** Integer format specifier for \ref int_fast64_t. */ -#define PRIiFAST64 __PRI64_PREFIX "i" +#define PRIiFAST64 __PRI64_PREFIX "i" /** Integer format specifier for \ref intmax_t. */ -#define PRIiMAX __PRI64_PREFIX "i" +#define PRIiMAX __PRI64_PREFIX "i" /** Integer format specifier for \ref intptr_t. */ -#define PRIiPTR __PRIPTR_PREFIX "i" +#define PRIiPTR __PRIPTR_PREFIX "i" /** @} */ @@ -130,19 +130,19 @@ /** @{ */ /** Octal format specifier for \ref int8_t. */ -#define PRIo8 "o" +#define PRIo8 "o" /** Octal format specifier for \ref int16_t. */ -#define PRIo16 "o" +#define PRIo16 "o" /** Octal format specifier for \ref int32_t. */ -#define PRIo32 "o" +#define PRIo32 "o" /** Octal format specifier for \ref int64_t. */ -#define PRIo64 __PRI64_PREFIX "o" +#define PRIo64 __PRI64_PREFIX "o" /** Octal format specifier for \ref int_least8_t. */ -#define PRIoLEAST8 "o" +#define PRIoLEAST8 "o" /** Octal format specifier for \ref int_least16_t. */ #define PRIoLEAST16 "o" @@ -154,22 +154,22 @@ #define PRIoLEAST64 __PRI64_PREFIX "o" /** Octal format specifier for \ref int_fast8_t. */ -#define PRIoFAST8 "o" +#define PRIoFAST8 "o" /** Octal format specifier for \ref int_fast16_t. */ -#define PRIoFAST16 __PRIPTR_PREFIX "o" +#define PRIoFAST16 __PRIPTR_PREFIX "o" /** Octal format specifier for \ref int_fast32_t. */ -#define PRIoFAST32 __PRIPTR_PREFIX "o" +#define PRIoFAST32 __PRIPTR_PREFIX "o" /** Octal format specifier for \ref int_fast64_t. */ -#define PRIoFAST64 __PRI64_PREFIX "o" +#define PRIoFAST64 __PRI64_PREFIX "o" /** Octal format specifier for \ref uintmax_t. */ -#define PRIoMAX __PRI64_PREFIX "o" +#define PRIoMAX __PRI64_PREFIX "o" /** Octal format specifier for \ref uintptr_t. */ -#define PRIoPTR __PRIPTR_PREFIX "o" +#define PRIoPTR __PRIPTR_PREFIX "o" /** @} */ @@ -177,19 +177,19 @@ /** @{ */ /** Unsigned decimal format specifier for \ref uint8_t. */ -#define PRIu8 "u" +#define PRIu8 "u" /** Unsigned decimal format specifier for \ref uint16_t. */ -#define PRIu16 "u" +#define PRIu16 "u" /** Unsigned decimal format specifier for \ref uint32_t. */ -#define PRIu32 "u" +#define PRIu32 "u" /** Unsigned decimal format specifier for \ref uint64_t. */ -#define PRIu64 __PRI64_PREFIX "u" +#define PRIu64 __PRI64_PREFIX "u" /** Unsigned decimal format specifier for \ref uint_least8_t. */ -#define PRIuLEAST8 "u" +#define PRIuLEAST8 "u" /** Unsigned decimal format specifier for \ref uint_least16_t. */ #define PRIuLEAST16 "u" @@ -201,22 +201,22 @@ #define PRIuLEAST64 __PRI64_PREFIX "u" /** Unsigned decimal format specifier for \ref uint_fast8_t. */ -#define PRIuFAST8 "u" +#define PRIuFAST8 "u" /** Unsigned decimal format specifier for \ref uint_fast16_t. */ -#define PRIuFAST16 __PRIPTR_PREFIX "u" +#define PRIuFAST16 __PRIPTR_PREFIX "u" /** Unsigned decimal format specifier for \ref uint_fast32_t. */ -#define PRIuFAST32 __PRIPTR_PREFIX "u" +#define PRIuFAST32 __PRIPTR_PREFIX "u" /** Unsigned decimal format specifier for \ref uint_fast64_t. */ -#define PRIuFAST64 __PRI64_PREFIX "u" +#define PRIuFAST64 __PRI64_PREFIX "u" /** Unsigned decimal format specifier for \ref uintmax_t. */ -#define PRIuMAX __PRI64_PREFIX "u" +#define PRIuMAX __PRI64_PREFIX "u" /** Unsigned decimal format specifier for \ref uintptr_t. */ -#define PRIuPTR __PRIPTR_PREFIX "u" +#define PRIuPTR __PRIPTR_PREFIX "u" /** @} */ @@ -224,19 +224,19 @@ /** @{ */ /** Hex format specifier for \ref uint8_t. */ -#define PRIx8 "x" +#define PRIx8 "x" /** Hex format specifier for \ref uint16_t. */ -#define PRIx16 "x" +#define PRIx16 "x" /** Hex format specifier for \ref uint32_t. */ -#define PRIx32 "x" +#define PRIx32 "x" /** Hex format specifier for \ref uint64_t. */ -#define PRIx64 __PRI64_PREFIX "x" +#define PRIx64 __PRI64_PREFIX "x" /** Hex format specifier for \ref uint_least8_t. */ -#define PRIxLEAST8 "x" +#define PRIxLEAST8 "x" /** Hex format specifier for \ref uint_least16_t. */ #define PRIxLEAST16 "x" @@ -248,22 +248,22 @@ #define PRIxLEAST64 __PRI64_PREFIX "x" /** Hex format specifier for \ref uint_fast8_t. */ -#define PRIxFAST8 "x" +#define PRIxFAST8 "x" /** Hex format specifier for \ref uint_fast16_t. */ -#define PRIxFAST16 __PRIPTR_PREFIX "x" +#define PRIxFAST16 __PRIPTR_PREFIX "x" /** Hex format specifier for \ref uint_fast32_t. */ -#define PRIxFAST32 __PRIPTR_PREFIX "x" +#define PRIxFAST32 __PRIPTR_PREFIX "x" /** Hex format specifier for \ref uint_fast64_t. */ -#define PRIxFAST64 __PRI64_PREFIX "x" +#define PRIxFAST64 __PRI64_PREFIX "x" /** Hex format specifier for \ref uintmax_t. */ -#define PRIxMAX __PRI64_PREFIX "x" +#define PRIxMAX __PRI64_PREFIX "x" /** Hex format specifier for \ref uintptr_t. */ -#define PRIxPTR __PRIPTR_PREFIX "x" +#define PRIxPTR __PRIPTR_PREFIX "x" /** @} */ @@ -271,19 +271,19 @@ /** @{ */ /** Binary format specifier for \ref uint8_t. */ -#define PRIX8 "X" +#define PRIX8 "X" /** Binary format specifier for \ref uint16_t. */ -#define PRIX16 "X" +#define PRIX16 "X" /** Binary format specifier for \ref uint32_t. */ -#define PRIX32 "X" +#define PRIX32 "X" /** Binary format specifier for \ref uint64_t. */ -#define PRIX64 __PRI64_PREFIX "X" +#define PRIX64 __PRI64_PREFIX "X" /** Binary format specifier for \ref uint_least8_t. */ -#define PRIXLEAST8 "X" +#define PRIXLEAST8 "X" /** Binary format specifier for \ref uint_least16_t. */ #define PRIXLEAST16 "X" @@ -295,22 +295,22 @@ #define PRIXLEAST64 __PRI64_PREFIX "X" /** Binary format specifier for \ref uint_fast8_t. */ -#define PRIXFAST8 "X" +#define PRIXFAST8 "X" /** Binary format specifier for \ref uint_fast16_t. */ -#define PRIXFAST16 __PRIPTR_PREFIX "X" +#define PRIXFAST16 __PRIPTR_PREFIX "X" /** Binary format specifier for \ref uint_fast32_t. */ -#define PRIXFAST32 __PRIPTR_PREFIX "X" +#define PRIXFAST32 __PRIPTR_PREFIX "X" /** Binary format specifier for \ref uint_fast64_t. */ -#define PRIXFAST64 __PRI64_PREFIX "X" +#define PRIXFAST64 __PRI64_PREFIX "X" /** Binary format specifier for \ref uintmax_t. */ -#define PRIXMAX __PRI64_PREFIX "X" +#define PRIXMAX __PRI64_PREFIX "X" /** Binary format specifier for \ref uintptr_t. */ -#define PRIXPTR __PRIPTR_PREFIX "X" +#define PRIXPTR __PRIPTR_PREFIX "X" /** @} */ @@ -354,7 +354,7 @@ void setup_io_dbg(struct vmem *vmem); * Format to append to helper debugging classes. * See \ref bug(), \ref warn(), \ref info() and \ref error(). */ -#define COMMON_FORMAT "[%s] %s:%d\n\t" +#define COMMON_FORMAT "[%s] %s:%d\n\t" /** * Helper for helper classes. @@ -369,7 +369,7 @@ void setup_io_dbg(struct vmem *vmem); * * @param fmt Message, integer subset of regular printf. */ -#define bug(fmt, ...) dbg(COMMON_FORMAT fmt, COMMON_ARGS("BUG"),##__VA_ARGS__) +#define bug(fmt, ...) dbg(COMMON_FORMAT fmt, COMMON_ARGS("BUG"),##__VA_ARGS__) /** * Print a warning message to the serial lines. diff --git a/include/apos/dmem.h b/include/apos/dmem.h index 38476ec..dace5f9 100644 --- a/include/apos/dmem.h +++ b/include/apos/dmem.h @@ -4,23 +4,56 @@ /** * @file dmem.h * Device memory handling, i.e. anything outside of RAM. + * @todo Make global parameters functions instead. */ #include <apos/types.h> #include <apos/vmem.h> +/** 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); -vm_t alloc_devmem(struct tcb *t, pm_t dev_start, size_t bytes, vmflags_t flags); -stat_t free_devmem(struct tcb *t, vm_t dev_start); -stat_t dev_free_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order t, void *); -stat_t dev_alloc_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order t, void *); +/** + * 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 index e6936a3..ad5c4da 100644 --- a/include/apos/elf.h +++ b/include/apos/elf.h @@ -12,188 +12,612 @@ #include <apos/types.h> #include <apos/vmem.h> -#define EI_MAGIC 0x7f454c46 +/** @name Magic. */ +/** @{ */ -#define ELFCLASSNONE 0x0 -#define ELFCLASS32 0x1 -#define ELFCLASS64 0x2 +/** Magic ELF header bytes. */ +#define EI_MAGIC 0x7f454c46 -#define ELFDATANONE 0x0 -#define ELFDATA2LSB 0x1 -#define ELFDATA2MSB 0x2 +/** @} */ -#define ELFOSABI_NONE 0x0 -#define ELFOSABI_SYSV 0x0 -#define ELFOSABI_NETBSD 0x2 -#define ELFOSABI_LINUX 0x3 -#define ELFOSABI_HURD 0x4 +/** @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 -#define ET_NONE 0x0 -#define ET_REL 0x1 -#define ET_EXEC 0x2 -#define ET_DYN 0x3 -#define ET_CORE 0x4 +/** @} */ + +/** @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 -#define EM_RISCV 0xf3 +/** 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; }; -#define PT_NULL 0x0 -#define PT_LOAD 0x1 +/** @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 -#define PT_INTERP 0x3 -#define PT_NOTE 0x4 -#define PT_SHLIB 0x5 -#define PT_PHDR 0x6 -#define PT_TLS 0x7 -#define PT_LOOS 0x60000000 -#define PT_HIOS 0x6fffffff -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7fffffff -#define PF_X (1 << 0) -#define PF_W (1 << 1) -#define PF_R (1 << 2) +/** 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; }; -#define SHT_NULL 0x0 -#define SH_PROGBITS 0x1 -#define SHT_SYMTAB 0x2 -#define SHT_STRTAB 0x3 -#define SHT_RELA 0x4 -#define SHT_HASH 0x5 -#define SHT_DYNAMIC 0x6 -#define SHT_NOTE 0x7 -#define SHT_NOBITS 0x8 -#define SHT_REL 0x9 -#define SHT_SHLIB 0x0a -#define SHT_DYNSYM 0x0b -#define SHT_INIT_ARRAY 0x0e -#define SHT_FINI_ARRAY 0x0f -#define SHT_PREINIT_ARRAY 0x10 -#define SHT_GROUP 0x11 -#define SHT_SYMTAB_SHNDX 0x12 -#define SHT_NUM 0x13 +/** @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 -#define SHF_WRITE 0x1 -#define SHF_ALLOC 0x2 -#define SHF_EXECINSTR 0x4 -#define SHF_MERGE 0x10 -#define SHF_STRINGS 0x20 -#define SHF_INFO_LINK 0x40 -#define SHF_LINK_ODER 0x80 +/** 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 -#define SHF_GROUP 0x200 -#define SHF_TLS 0x400 -#define SHF_MASKOS 0x0ff00000 -#define SHF_MASKPROC 0xf0000000 +/** 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; }; -#define elf_indent(e) ((struct elf_ident *)e) -#define elf64_header(e) ((struct elf64_header *)e) -#define elf32_header(e) ((struct elf32_header *)e) +/** + * 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) -vm_t load_elf(struct tcb *t, vm_t binary, vm_t interp); +/** + * 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 index 5644106..d38e669 100644 --- a/include/apos/initrd.h +++ b/include/apos/initrd.h @@ -10,10 +10,36 @@ #include <apos/pmem.h> #include <apos/vmem.h> +/** + * 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); #endif /* APOS_INITRD_H */ diff --git a/include/apos/mem.h b/include/apos/mem.h index af0ac89..a0f32f5 100644 --- a/include/apos/mem.h +++ b/include/apos/mem.h @@ -9,82 +9,285 @@ #include <apos/utils.h> #include <apos/types.h> +/** Helper macro for getting bit width of \ref mm_info_t. */ #define MM_OINFO_WIDTH (sizeof(mm_info_t) * 8) +/** + * Extract index of page order \c order from base page index \c pnum. + * + * @param pnum Base page order index. + * @param order Order page index to convert to. + * @return Index of page order \c order. + */ #define pnum_to_index(pnum, order) \ - (((pnum) >> __o_offset(order)) & (__o_width(order) - 1)) -#define pm_to_index(paddr, \ - order) (pnum_to_index(pm_to_pnum(paddr), (order))) -#define pm_to_pnum(paddr) ((paddr) >> __mm_page_shift) -#define pnum_to_paddr(pnum) ((pnum) << __mm_page_shift) + (((pnum) >> order_offset(order)) & (order_width(order) - 1)) -#define move_forward(var, num) (((var) += (num)) - (num)) +/** + * Convert physical memory address \c paddr to index of page order \c order. + * + * @param paddr Physical memory address. + * @param order Order page index to convert to. + * @return Index of page order \c order. + */ +#define pm_to_index(paddr, order) \ + (pnum_to_index(pm_to_pnum(paddr), (order))) -#define move_paddr(paddr, base, offset) ((((pm_t)(paddr)) - (base)) + (offset)) -#define num_elems(num) (((num) + MM_OINFO_WIDTH - 1) / \ - MM_OINFO_WIDTH) -#define num_indexes(num) ((num) / MM_OINFO_WIDTH) -#define index_elems(num) ((num) / MM_OINFO_WIDTH) -#define state_elems(num) (sizeof(mm_info_t) * (num_elems(num))) -#define next_elems(num) (sizeof(void *) * (num)) -#define max_index(order) (__o_width(order) - 1) +/** + * Convert physical memory address \c paddr to corresponding page number. + * + * @param paddr Physical memory address. + * @return Corresponding page number. + */ +#define pm_to_pnum(paddr) ((paddr) >> __mm_page_shift) -#define __o_offset(order) (__mm_shifts[order]) -#define __o_width(order) (__mm_widths[order]) -#define __o_size(order) (__mm_sizes[order]) -#define __o_elems(order) (__mm_widths[order] / MM_OINFO_WIDTH) +/** + * Convert page number to physical address. + * Note that since a page number is the base page an address lies in, + * @code pnum_to_pm(pm_to_pnum(p)) != p @endcode + * + * @param pnum Page number. + * @return Corresponding physical address. + */ +#define pnum_to_pm(pnum) ((pnum) << __mm_page_shift) + +/** + * Add \c num to \c var and return value before addition. + * + * @param var Variable to add \c num to. + * @param num Number to add to \c var. + * @return Value of \c var before addition. + */ +#define move_forward(var, num) (((var) += (num)) - (num)) -#define __o_container(idx) ((idx) / MM_OINFO_WIDTH) -#define __o_bit(idx) ((idx) & (MM_OINFO_WIDTH - 1)) +/** + * Helper for calculating highest index of elements in order info map. + * Since the number of entries is stored with the granularity of \c MM_OINFO_WIDTH, + * the highest index element is \c num rounded up to the nearest index multiple + * of \c MM_OINFO_WIDTH. This is due to some data access optimizations over in + * common/pmem.c. + * + * @param num Number of entries in map. + * @return Highest index of element in map. + */ +#define num_elems(num) \ + (((num) + MM_OINFO_WIDTH - 1) / MM_OINFO_WIDTH) +/** + * Helper for calculating starting index of element. + * + * @param num Number of starting entry. + * @return Index of starting element in which entry resides. + */ +#define num_indexes(num) ((num) / MM_OINFO_WIDTH) + +/** + * Helper for calculating index of element from entry number. + * + * @param num Entry number. + * @return Index of element in which entry resides. + */ +#define index_elems(num) ((num) / MM_OINFO_WIDTH) + +/** + * Helper for calculating size of state for storing elements in. + * + * @param num Number of entries. + * @return Size of element state buffer. + */ +#define state_elems(num) (sizeof(mm_info_t) * (num_elems(num))) -#define __va(x) (void *)(((uintptr_t)(x)) + VM_DMAP - \ - RAM_BASE) -#define __pa(x) (void *)(((uintptr_t)(x)) - VM_DMAP + \ - RAM_BASE) -#define __page(x) ((x) / BASE_PAGE_SIZE) -#define __addr(x) ((x)*BASE_PAGE_SIZE) +/** + * Helper for calculating size of pointer buffer. + * + * @param num Number of entries. + * @return Size of pointer buffer. + */ +#define next_elems(num) (sizeof(void *) * (num)) + +/** + * 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_offset(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 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) + +/** + * Entry index within the element that contains it. + * + * @param idx Index of entry. + * @return Index of entry within its containing element. + */ +#define order_bit(idx) ((idx) & (MM_OINFO_WIDTH - 1)) + +/** + * 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. + * + * @todo Isn't this the same as \ref pnum_to_pm()? + * + * @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)) -#define __bytes(x) (__addr(x)) + +/** @name Memory region flags. */ +/** @{ */ /** Memory region is used. */ -#define MR_USED (1 << 8) +#define MR_USED (1 << 8) /** Memory region is shared. */ -#define MR_SHARED (1 << 9) +#define MR_SHARED (1 << 9) /** Owner of shared region. */ -#define MR_OWNED (1 << 10) +#define MR_OWNED (1 << 10) /** Copy on write. */ -#define MR_COW (1 << 11) +#define MR_COW (1 << 11) /** Don't free memory on flush. */ -#define MR_KEEP (1 << 12) +#define MR_KEEP (1 << 12) + +/** @} */ -extern size_t __mm_shifts[10]; -extern size_t __mm_widths[10]; -extern size_t __mm_sizes[10]; +/** Maximum number of page orders allowed. Likely massively overkill. */ +#define NUM_ORDERS 10 + +/** 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 size_t __mm_max_order; -#define NUM_ORDERS 10 +/** Give names to page orders. */ enum mm_order { + /** Base order. */ MM_O0, + + /** Order 1. */ MM_O1, + + /** Order 2. */ MM_O2, + + /** Order 3. */ MM_O3, + + /** Order 4. */ MM_O4, + + /** Order 5. */ MM_O5, + + /** Order 6. */ MM_O6, + + /** Order 7. */ MM_O7, + + /** Order 8. */ MM_O8, + + /** Order 9. */ MM_O9, }; +/** Page number. */ typedef ssize_t pnum_t; + +/** + * 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); -enum mm_mode get_mmode(void *fdt); -#define BASE_PAGE_SIZE (__o_size(BASE_PAGE)) -#define BASE_PAGE (MM_O0) + +/** 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 index f0d1361..866915d 100644 --- a/include/apos/mem_nodes.h +++ b/include/apos/mem_nodes.h @@ -9,10 +9,31 @@ #include <apos/vmem.h> #include <apos/nodes.h> -void init_mem_blocks(); -void destroy_mem_blocks(); +/** + * 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 index 54e4e2b..38629f2 100644 --- a/include/apos/mem_regions.h +++ b/include/apos/mem_regions.h @@ -13,7 +13,7 @@ #include <arch/vmem.h> #define mem_container(ptr) container_of(ptr, struct mem_region, sp_n) -#define is_region_used(r) is_set(r->flags, MR_USED) +#define is_region_used(r) is_set(r->flags, MR_USED) #define is_region_owned(r) is_set(r->flags, MR_OWNED) #define is_region_shared(r) is_set(r->flags, MR_SHARED) #define is_region_kept(r) is_set(r->flags, MR_KEEP) @@ -52,7 +52,22 @@ struct mem_region *find_closest_used_region(struct mem_region_root *r, struct mem_region *find_free_region(struct mem_region_root *r, size_t size, size_t *align); -typedef stat_t region_callback_t(struct vmem *b, pm_t *offset, vm_t vaddr, +/** + * 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); diff --git a/include/apos/sizes.h b/include/apos/sizes.h index 2ac48c7..2a4d4c3 100644 --- a/include/apos/sizes.h +++ b/include/apos/sizes.h @@ -6,120 +6,218 @@ * Shorthands for some power-of-two sizes. */ -#if defined(__ASSEMBLER__) +#if !defined(__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 +/* value format used by the compiler. */ -#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 +/** 1 byte. */ +#define SZ_1 0x000000000001UL -#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 +/** 2 bytes. */ +#define SZ_2 0x000000000002UL -#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 +/** 4 bytes. */ +#define SZ_4 0x000000000004UL -#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 +/** 8 bytes. */ +#define SZ_8 0x000000000008UL -#else +/** 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 -#define SZ_1 0x000000000001UL -#define SZ_2 0x000000000002UL -#define SZ_4 0x000000000004UL -#define SZ_8 0x000000000008UL -#define SZ_16 0x000000000010UL -#define SZ_32 0x000000000020UL -#define SZ_64 0x000000000040UL -#define SZ_128 0x000000000080UL -#define SZ_256 0x000000000100UL -#define SZ_512 0x000000000200UL +/** 1KiB. */ +#define SZ_1K 0x000000000400UL -#define SZ_1K 0x000000000400UL -#define SZ_2K 0x000000000800UL -#define SZ_4K 0x000000001000UL -#define SZ_8K 0x000000002000UL -#define SZ_16K 0x000000004000UL -#define SZ_32K 0x000000008000UL -#define SZ_64K 0x000000010000UL +/** 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 -#define SZ_1M 0x000000100000UL -#define SZ_2M 0x000000200000UL -#define SZ_4M 0x000000400000UL -#define SZ_8M 0x000000800000UL -#define SZ_16M 0x000001000000UL -#define SZ_32M 0x000002000000UL -#define SZ_64M 0x000004000000UL +/** 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 -#define SZ_1G 0x000040000000UL -#define SZ_2G 0x000080000000UL -#define SZ_4G 0x000100000000UL -#define SZ_8G 0x000200000000UL -#define SZ_16G 0x000400000000UL -#define SZ_32G 0x000800000000UL -#define SZ_64G 0x000400000000UL +/** 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 0x000400000000UL + +/** 128GiB. */ #define SZ_128G 0x000800000000UL + +/** 256GiB. */ #define SZ_256G 0x001000000000UL + +/** 512GiB. */ #define SZ_512G 0x002000000000UL -#define SZ_1T 0x004000000000UL -#define SZ_2T 0x008000000000UL -#define SZ_4T 0x010000000000UL -#define SZ_8T 0x020000000000UL -#define SZ_16T 0x040000000000UL -#define SZ_32T 0x080000000000UL -#define SZ_64T 0x100000000000UL +/** 1TiB. */ +#define SZ_1T 0x004000000000UL + +/** 2TiB. */ +#define SZ_2T 0x008000000000UL + +/** 4TiB. */ +#define SZ_4T 0x010000000000UL + +/** 8TiB. */ +#define SZ_8T 0x020000000000UL + +/** 16TiB. */ +#define SZ_16T 0x040000000000UL + +/** 32TiB. */ +#define SZ_32T 0x080000000000UL + +/** 64TiB. */ +#define SZ_64T 0x100000000000UL + +/** 128TiB. */ #define SZ_128T 0x200000000000UL + +/** 256TiB. */ #define SZ_256T 0x400000000000UL + +/** 512TiB. */ #define SZ_512T 0x800000000000UL +#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 index 1df781b..22b67cf 100644 --- a/include/apos/sp_tree.h +++ b/include/apos/sp_tree.h @@ -8,13 +8,13 @@ #include <apos/types.h> -#define sp_root(r) ((r)->sp_r) -#define sp_left(n) ((n)->left) -#define sp_right(n) ((n)->right) -#define sp_rparen(n) (sp_right(n)->parent) -#define sp_lparen(n) (sp_left(n)->parent) -#define sp_paren(n) ((n)->parent) -#define sp_gparen(n) ((n)->parent->parent) +#define sp_root(r) ((r)->sp_r) +#define sp_left(n) ((n)->left) +#define sp_right(n) ((n)->right) +#define sp_rparen(n) (sp_right(n)->parent) +#define sp_lparen(n) (sp_left(n)->parent) +#define sp_paren(n) ((n)->parent) +#define sp_gparen(n) ((n)->parent->parent) #define sp_has_gparen(n) (sp_paren(n) && sp_gparen(n)) struct sp_node { diff --git a/include/apos/tcb.h b/include/apos/tcb.h index 7abd432..1a633be 100644 --- a/include/apos/tcb.h +++ b/include/apos/tcb.h @@ -42,6 +42,7 @@ struct tcb { vm_t thread_stack; vm_t thread_stack_top; + vm_t thread_storage; struct tcb_ctx proc; struct tcb_ctx rpc; @@ -61,6 +62,7 @@ stat_t attach_proc(struct tcb *r, struct tcb *t); stat_t detach_proc(struct tcb *r, struct tcb *t); struct tcb *cur_tcb(); +struct tcb *cur_proc(); void use_tcb(struct tcb *); struct tcb *get_tcb(id_t tid); diff --git a/include/apos/types.h b/include/apos/types.h index 5f35ee8..7f2a51b 100644 --- a/include/apos/types.h +++ b/include/apos/types.h @@ -125,36 +125,36 @@ typedef int32_t ssize_t; #endif /** Expands to integer constant of type \ref int8_t. */ -#define INT8_C __INT8_C +#define INT8_C __INT8_C /** Expands to integer constant of type \ref int16_t. */ -#define INT16_C __INT16_C +#define INT16_C __INT16_C /** Expands to integer constant of type \ref int32_t. */ -#define INT32_C __INT32_C +#define INT32_C __INT32_C /** Expands to integer constant of type \ref int64_t. */ -#define INT64_C __INT64_C +#define INT64_C __INT64_C /** Expands to integer constant of type \ref uint8_t. */ -#define UINT8_C __UINT8_C +#define UINT8_C __UINT8_C /** Expands to integer constant of type \ref uint16_t. */ -#define UINT16_C __UINT16_C +#define UINT16_C __UINT16_C /** Expands to integer constant of type \ref uint32_t. */ -#define UINT32_C __UINT32_C +#define UINT32_C __UINT32_C /** Expands to integer constant of type \ref uint64_t. */ -#define UINT64_C __UINT64_C +#define UINT64_C __UINT64_C /** Expands to integer constant of type \ref intmax_t. */ -#define INTMAX_C __INTMAX_C +#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__ +#define CHAR_BIT __CHAR_BIT__ /** Largest value a signed char can have. */ #define SCHAR_MAX __SCHAR_MAX__ @@ -183,232 +183,232 @@ typedef int32_t ssize_t; * Maximum number of bytes in a multibyte character. * Arbitrary, as far as I can tell. */ -#define MB_LEN_MAX 16 +#define MB_LEN_MAX 16 /** Largest value a signed short can have. */ -#define SHRT_MAX __SHRT_MAX__ +#define SHRT_MAX __SHRT_MAX__ /** Smallest value a signed short can have. */ -#define SHRT_MIN (-__SHRT_MAX - 1) +#define SHRT_MIN (-__SHRT_MAX - 1) /** Largest value an unsigned short can have. */ -#define USHRT_MAX (2 * __SHRT_MAX + 1) +#define USHRT_MAX (2 * __SHRT_MAX + 1) /** Largest value a signed int can have. */ -#define INT_MAX __INT_MAX__ +#define INT_MAX __INT_MAX__ /** Smallest value a signed int can have. */ -#define INT_MIN (-__INT_MAX__ - 1) +#define INT_MIN (-__INT_MAX__ - 1) /** Largest value an unsigned int can have. */ -#define UINT_MAX (2 * __INT_MAX__ + 1) +#define UINT_MAX (2 * __INT_MAX__ + 1) /** Largest value a signed long can have. */ -#define LONG_MAX __LONG__MAX__ +#define LONG_MAX __LONG__MAX__ /** Smallest value a signed long can have. */ -#define LONG_MIN (-__LONG_MAX__ - 1) +#define LONG_MIN (-__LONG_MAX__ - 1) /** Largest value an unsigned long can have. */ -#define ULONG_MAX (2 * __INT_MAX__ + 1) +#define ULONG_MAX (2 * __INT_MAX__ + 1) /** Largest value a signed long long can have. */ -#define LLONG_MAX __LONG_LONG_MAX__ +#define LLONG_MAX __LONG_LONG_MAX__ /** Smallest value a signed long long can have. */ -#define LLONG_MIN (-__LONG_LONG_MAX__ - 1) +#define LLONG_MIN (-__LONG_LONG_MAX__ - 1) /** Largest value an unsigned long long can have. */ -#define ULLONG_MAX (2 * __LONG_LONG_MAX__ + 1) +#define ULLONG_MAX (2 * __LONG_LONG_MAX__ + 1) /** Largest value an \ref int8_t can have. */ -#define INT8_MAX __INT8_MAX__ +#define INT8_MAX __INT8_MAX__ /** Smallest value an \ref int8_t can have. */ -#define INT8_MIN (-__INT8_MAX__ - 1) +#define INT8_MIN (-__INT8_MAX__ - 1) /** Largest value an \ref int8_t can have. */ -#define UINT8_MAX __UINT8_MAX__ +#define UINT8_MAX __UINT8_MAX__ /** Largest value an \ref int16_t can have. */ -#define INT16_MAX __INT16_MAX__ +#define INT16_MAX __INT16_MAX__ /** Smallest value an \ref int16_t can have. */ -#define INT16_MIN (-__INT16_MAX__ - 1) +#define INT16_MIN (-__INT16_MAX__ - 1) /** Largest value an \ref uint16_t can have. */ -#define UINT16_MAX __UINT16_MAX__ +#define UINT16_MAX __UINT16_MAX__ /** Largest value an \ref int32_t can have. */ -#define INT32_MAX __INT32_MAX__ +#define INT32_MAX __INT32_MAX__ /** Smallest value an \ref int32_t can have. */ -#define INT32_MIN (-__INT32_MAX__ - 1) +#define INT32_MIN (-__INT32_MAX__ - 1) /** Largest value a \ref uint16_t can have. */ -#define UINT32_MAX __UINT32_MAX__ +#define UINT32_MAX __UINT32_MAX__ /** Largest value an \ref int64_t can have. */ -#define INT64_MAX __INT64_MAX__ +#define INT64_MAX __INT64_MAX__ /** Smallest value an \ref int64_t can have. */ -#define INT64_MIN (-__INT64_MAX__ - 1) +#define INT64_MIN (-__INT64_MAX__ - 1) /** Largest value an \ref uint64_t can have. */ -#define UINT64_MAX __UINT64_MAX__ +#define UINT64_MAX __UINT64_MAX__ /** Largest value an \ref int_least8_t can have. */ -#define INT_LEAST8_MAX __INT_LEAST8_MAX__ +#define INT_LEAST8_MAX __INT_LEAST8_MAX__ /** Smallest value an \ref int_least8_t can have. */ -#define INT_LEAST8_MIN (-__INT_LEAST8_MAX__ - 1) +#define INT_LEAST8_MIN (-__INT_LEAST8_MAX__ - 1) /** Largest value an \ref int_least8_t can have. */ -#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__ +#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__ /** Largest value an \ref int_least16_t can have. */ -#define INT_LEAST16_MAX __INT_LEAST16_MAX__ +#define INT_LEAST16_MAX __INT_LEAST16_MAX__ /** Smallest value an \ref int_least16_t can have. */ -#define INT_LEAST16_MIN (-__INT_LEAST16_MAX__ - 1) +#define INT_LEAST16_MIN (-__INT_LEAST16_MAX__ - 1) /** Largest value an \ref int_least16_t can have. */ -#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__ +#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__ /** Largest value an \ref int_least32_t can have. */ -#define INT_LEAST32_MAX __INT_LEAST32_MAX__ +#define INT_LEAST32_MAX __INT_LEAST32_MAX__ /** Smallest value an \ref int_least32_t can have. */ -#define INT_LEAST32_MIN (-__INT_LEAST32_MAX__ - 1) +#define INT_LEAST32_MIN (-__INT_LEAST32_MAX__ - 1) /** Largest value a \ref uint_least32_t can have. */ -#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__ +#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__ /** Largest value an \ref int_least64_t can have. */ -#define INT_LEAST64_MAX __INT_LEAST64_MAX__ +#define INT_LEAST64_MAX __INT_LEAST64_MAX__ /** Smallest value an \ref int_least64_t can have. */ -#define INT_LEAST64_MIN (-__INT_LEAST64_MAX__ - 1) +#define INT_LEAST64_MIN (-__INT_LEAST64_MAX__ - 1) /** Largest value a \ref uint_least64_t can have. */ -#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__ +#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__ /** Largest value an \ref int_fast8_t can have. */ -#define INT_FAST8_MAX __INT_FAST8_MAX__ +#define INT_FAST8_MAX __INT_FAST8_MAX__ /** Smallest value an \ref int_fast8_t can have. */ -#define INT_FAST8_MIN (-__INT_FAST8_MAX__ - 1) +#define INT_FAST8_MIN (-__INT_FAST8_MAX__ - 1) /** Largest value a \ref uint_fast8_t can have. */ -#define UINT_FAST8_MAX __UINT_FAST8_MAX__ +#define UINT_FAST8_MAX __UINT_FAST8_MAX__ /** Largest value an \ref int_fast16_t can have. */ -#define INT_FAST16_MAX __INT_FAST16_MAX__ +#define INT_FAST16_MAX __INT_FAST16_MAX__ /** Smallest value an \ref int_fast16_t can have. */ -#define INT_FAST16_MIN (-__INT_FAST16_MAX__ - 1) +#define INT_FAST16_MIN (-__INT_FAST16_MAX__ - 1) /** Largest value a \ref uint_fast16_t can have. */ -#define UINT_FAST16_MAX __UINT_FAST16_MAX__ +#define UINT_FAST16_MAX __UINT_FAST16_MAX__ /** Largest value an \ref int_fast32_t can have. */ -#define INT_FAST32_MAX __INT_FAST32_MAX__ +#define INT_FAST32_MAX __INT_FAST32_MAX__ /** Smallest value an \ref int_fast32_t can have. */ -#define INT_FAST32_MIN (-__INT_FAST32_MAX__ - 1) +#define INT_FAST32_MIN (-__INT_FAST32_MAX__ - 1) /** Largest value a \ref int_fast32_t can have. */ -#define UINT_FAST32_MAX __UINT_FAST32_MAX__ +#define UINT_FAST32_MAX __UINT_FAST32_MAX__ /** Largest value an \ref int_fast64_t can have. */ -#define INT_FAST64_MAX __INT_FAST64_MAX__ +#define INT_FAST64_MAX __INT_FAST64_MAX__ /** Smallest value an \ref int_fast64_t can have. */ -#define INT_FAST64_MIN (-__INT_FAST64_MAX__ - 1) +#define INT_FAST64_MIN (-__INT_FAST64_MAX__ - 1) /** Largest value a \ref int_fast64_t can have. */ -#define UINT_FAST64_MAX __UINT_FAST64_MAX__ +#define UINT_FAST64_MAX __UINT_FAST64_MAX__ /** Largest value an \ref intptr_t can have. */ -#define INTPTR_MAX __INTPTR_MAX__ +#define INTPTR_MAX __INTPTR_MAX__ /** Smallest value an \ref intptr_t can have. */ -#define INTPTR_MIN (-__INTPTR_MAX__ - 1) +#define INTPTR_MIN (-__INTPTR_MAX__ - 1) /** Largest value a \ref uintptr_t can have. */ -#define UINTPTR_MAX __UINTPTR_MAX__ +#define UINTPTR_MAX __UINTPTR_MAX__ /** Largest value an \ref intmax_t can have. */ -#define INTMAX_MAX __INTMAX_MAX__ +#define INTMAX_MAX __INTMAX_MAX__ /** Smallest value an \ref intmax_t can have. */ -#define INTMAX_MIN (-__INTMAX_MAX__ - 1) +#define INTMAX_MIN (-__INTMAX_MAX__ - 1) /** Largest value a \ref uintmax_t can have. */ -#define UINTMAX_MAX __UINTMAX_MAX__ +#define UINTMAX_MAX __UINTMAX_MAX__ /** Width of \ref int8_t. */ -#define INT8_WIDTH 8 +#define INT8_WIDTH 8 /** Width of \ref int16_t. */ -#define INT16_WIDTH 16 +#define INT16_WIDTH 16 /** Width of \ref int32_t. */ -#define INT32_WIDTH 32 +#define INT32_WIDTH 32 /** Width of \ref int64_t. */ -#define INT64_WIDTH 64 +#define INT64_WIDTH 64 /** Width of \ref uint8_t. */ -#define UINT8_WIDTH 8 +#define UINT8_WIDTH 8 /** Width of \ref uint16_t. */ -#define UINT16_WIDTH 16 +#define UINT16_WIDTH 16 /** Width of \ref uint32_t. */ -#define UINT32_WIDTH 32 +#define UINT32_WIDTH 32 /** Width of \ref uint64_t. */ -#define UINT64_WIDTH 64 +#define UINT64_WIDTH 64 /** Width of \ref int_fast8_t. */ -#define INT_FAST8_WIDTH __INT_FAST8_WIDTH__ +#define INT_FAST8_WIDTH __INT_FAST8_WIDTH__ /** Width of \ref int_fast16_t. */ -#define INT_FAST16_WIDTH __INT_FAST16_WIDTH__ +#define INT_FAST16_WIDTH __INT_FAST16_WIDTH__ /** Width of \ref int_fast32_t. */ -#define INT_FAST32_WIDTH __INT_FAST32_WIDTH__ +#define INT_FAST32_WIDTH __INT_FAST32_WIDTH__ /** Width of \ref int_fast64_t. */ -#define INT_FAST64_WIDTH __INT_FAST64_WIDTH__ +#define INT_FAST64_WIDTH __INT_FAST64_WIDTH__ /** Width of \ref uint_fast8_t. */ -#define UINT_FAST8_WIDTH __INT_FAST8_WIDTH__ +#define UINT_FAST8_WIDTH __INT_FAST8_WIDTH__ /** Width of \ref uint_fast16_t. */ -#define UINT_FAST16_WIDTH __INT_FAST16_WIDTH__ +#define UINT_FAST16_WIDTH __INT_FAST16_WIDTH__ /** Width of \ref uint_fast32_t. */ -#define UINT_FAST32_WIDTH __INT_FAST32_WIDTH__ +#define UINT_FAST32_WIDTH __INT_FAST32_WIDTH__ /** Width of \ref uint_fast64_t. */ -#define UINT_FAST64_WIDTH __INT_FAST64_WIDTH__ +#define UINT_FAST64_WIDTH __INT_FAST64_WIDTH__ /** Width of \ref int_least8_t. */ -#define INT_LEAST8_WIDTH __INT_LEAST8_WIDTH__ +#define INT_LEAST8_WIDTH __INT_LEAST8_WIDTH__ /** Width of \ref int_least16_t. */ -#define INT_LEAST16_WIDTH __INT_LEAST16_WIDTH__ +#define INT_LEAST16_WIDTH __INT_LEAST16_WIDTH__ /** Width of \ref int_least32_t. */ -#define INT_LEAST32_WIDTH __INT_LEAST32_WIDTH__ +#define INT_LEAST32_WIDTH __INT_LEAST32_WIDTH__ /** Width of \ref int_least64_t. */ -#define INT_LEAST64_WIDTH __INT_LEAST64_WIDTH__ +#define INT_LEAST64_WIDTH __INT_LEAST64_WIDTH__ /** Width of \ref uint_least8_t. */ -#define UINT_LEAST8_WIDTH __INT_LEAST8_WIDTH__ +#define UINT_LEAST8_WIDTH __INT_LEAST8_WIDTH__ /** Width of \ref uint_least16_t. */ #define UINT_LEAST16_WIDTH __INT_LEAST16_WIDTH__ @@ -420,19 +420,19 @@ typedef int32_t ssize_t; #define UINT_LEAST64_WIDTH __INT_LEAST64_WIDTH__ /** Width of \ref intptr_t. */ -#define INTPTR_WIDTH __INTPTR_WIDTH__ +#define INTPTR_WIDTH __INTPTR_WIDTH__ /** Width of \ref intmax_t. */ -#define INTMAX_WIDTH __INTMAX_WIDTH__ +#define INTMAX_WIDTH __INTMAX_WIDTH__ /** Width of \ref uintptr_t. */ -#define UINTPTR_WIDTH __INTPTR_WIDTH__ +#define UINTPTR_WIDTH __INTPTR_WIDTH__ /** Width of \ref uintmax_t. */ -#define UINTMAX_WIDTH __INTMAX_WIDTH__ +#define UINTMAX_WIDTH __INTMAX_WIDTH__ /** Null. */ -#define NULL 0 +#define NULL 0 /* some common types used throughout the kernel */ /** Status, used with codes in \ref status_codes. */ diff --git a/include/apos/utils.h b/include/apos/utils.h index d2b81c0..24a67f6 100644 --- a/include/apos/utils.h +++ b/include/apos/utils.h @@ -6,27 +6,27 @@ * Misc utils and helpers. */ -#define ABS(a) (a < 0 ? -a : a) +#define ABS(a) (a < 0 ? -a : a) -#define MAX(a, b) ((a) >= (b) ? (a) : (b)) +#define MAX(a, b) ((a) >= (b) ? (a) : (b)) #define MAX3(a, b, c) (MAX(a, b) >= MAX(b, c) ? MAX(a, b) : MAX(b, c)) #define MAX4(a, b, c, d) \ (MAX3(a, b, c) >= MAX3(b, c, d) ? MAX3(a, b, c) : MAX3(b, c, d)) /* etc... */ -#define MIN(a, b) ((a) <= (b) ? (a) : (b)) +#define MIN(a, b) ((a) <= (b) ? (a) : (b)) #define MIN3(a, b, c) (MIN(a, b) <= MIN(b, c) ? MIN(a, b) : MIN(b, c)) #define MIN4(a, b, c, d) \ (MIN3(a, b, c) <= MIN3(b, c, d) ? MIN3(a, b, c) : MIN3(b, c, d)) /* etc... */ #define GLUE2(x, y) x##y -#define GLUE(x, y) GLUE2(x, y) +#define GLUE(x, y) GLUE2(x, y) -#define QUOTE2(x) #x -#define QUOTE(x) QUOTE2(x) +#define QUOTE2(x) #x +#define QUOTE(x) QUOTE2(x) -#define UNUSED(x) ((void)(x)) +#define UNUSED(x) ((void)(x)) #define MAYBE_UNUSED(x) UNUSED(x) #include <apos/builtin.h> @@ -38,10 +38,10 @@ #endif #if __has_builtin(__builtin_expect) -#define likely(x) __builtin_expect(!!(x), 1) +#define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else -#define likely(x) (x) +#define likely(x) (x) #define unlikely(x) (x) #endif @@ -51,7 +51,7 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define ALIGNED(x, a) ((x) % a == 0) -#define ptradd(x, y) (((vm_t)(x)) + ((vm_t)(y))) +#define ptradd(x, y) (((vm_t)(x)) + ((vm_t)(y))) #include <apos/types.h> |
